diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..8ce3ee5 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,42 @@ +# Agent Guidelines + +## Code and tooling + +- All code must remain compatible with PHP 7.4, and PHPStan and PHP-CS-Fixer + must be run against PHP 7.4. +- Always pass an explicit character list to `trim()`, `ltrim()`, and `rtrim()`; + never rely on the default characters. +- Handle `preg_*` engine failures: when the result is used as data, test for + `false` or `null` and throw a `\RuntimeException` including + `preg_last_error_msg()`; boolean validation guards must compare strictly, such + as `=== 1`, so an engine failure can only ever fail closed. +- Anchor validation patterns to the true end of input with the `D` modifier or + `\z`; a bare `$` accepts a trailing newline. +- Never embed raw control bytes in exception messages and other diagnostics; + escape or redact the offending value first. +- Helper classes that expose only public static methods are `final` and have a + private constructor. +- Resist native PHP serialization when a class holds live state (streams, + resources, handles, callbacks, credentials); plain data holders remain + serializable. +- To resist, `__serialize()` and `__unserialize()` both throw + `\LogicException(static::class.' should never be serialized')` and its + unserialized counterpart, via the `@internal` `NonSerializableTrait`. +- In general, numeric inputs should not accept non-finite floats. In situations + where they are accepted and we need to cast to a string, we should branch on + `\is_finite($value)`, using `(string) $value` for the finite case and + `\is_nan($value) ? 'NAN' : ($value > 0 ? 'INF' : '-INF')` otherwise. +- Changes in behavior need a `CHANGELOG.md` entry in the unreleased section of + the target branch and an `UPGRADING.md` note when the behavior differs between + major versions. + +## Documentation + +- Wrap markdown prose and PHPDoc text to 80 columns using greedy wrapping. Never + split a markdown link or an inline code span across a line break; a line that + cannot be broken may exceed the limit. Avoid em dashes. +- Keep PHPDoc and the corresponding `docs/` pages in sync: shared prose is + deliberately word-for-word identical, including boilerplate copied verbatim + between related functions, so apply the same edit to every copy. Only + formatting and linking may differ, such as a docs link becoming a PHPDoc + `@see` tag; the wording must never drift. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..43c994c --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md