add llm anti-patterns to context files

name the LLM-default constructs this project forbids in
explicit before/after tables. catching the trap by pattern
match is more reliable than expecting a general rule to be
applied at write time. backend table covers PHP traps
(arrow fns, inline FQCNs, default params, stored refs, em
dashes, short names); frontend table covers JS/template/
cypress traps.
This commit is contained in:
Yisroel Baum 2026-05-02 22:15:23 +03:00
parent b07b1e2666
commit 5d6c9f7ec9
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9
2 changed files with 34 additions and 0 deletions

View file

@ -43,3 +43,22 @@ ValueObjects) into Entities, DTOs, Repositories, Use Cases, and Fakes
Run `php-cs-fixer fix` on worked-on directories before committing (uses the
existing `.php-cs-fixer.dist.php` config).
## LLM anti-patterns
Constructs LLMs default to that this project forbids. Name the trap
explicitly so you catch yourself before writing it.
| Anti-pattern | Forbidden | Required |
|---|---|---|
| Arrow function | `fn ($x) => $x->getId()` | `function ($x) { return $x->getId(); }` |
| Inline FQCN type | `function f(): \Psr\Http\Message\ResponseInterface` | `use Psr\Http\Message\ResponseInterface;` then `function f(): ResponseInterface` |
| Inline `::class` | `Container::get(\App\Foo\Bar::class)` | `use App\Foo\Bar;` then `Container::get(Bar::class)` |
| Default param | `function f(int $count = 10)` | `function f(int $count)` |
| Default in fake | `public function create(Dto $dto, bool $strict = true)` | no default; every caller passes a value |
| Lookup returns stored ref | `return $this->items[$id] ?? null;` | rebuild a new instance with the stored fields |
| Short variable name | `$t`, `$n`, `$res`, `$req`, `$e` | `$text`, `$node`, `$response`, `$request`, `$exception` |
| Em dash | `// fetches user — by email` | `// fetches user - by email` |
When generating code, scan the diff for these patterns before writing it
to disk. If you catch one mid-write, rewrite that line.

View file

@ -31,3 +31,18 @@ with surrounding files. (TODO: wire up format/lint when added.)
Frontend changes are often a template plus its page-level JS counterpart -
commit them together as a single logical unit, per the "one logical change
per commit" rule in `shared.md`.
## LLM anti-patterns
Constructs LLMs default to that this project forbids on the frontend.
| Anti-pattern | Forbidden | Required |
|---|---|---|
| Short variable name | `t`, `n`, `res`, `req`, `e`, `el`, `ev` | `text`, `node`, `response`, `request`, `submitEvent`, `element`, `clickEvent` |
| Em dash in code/comments | `// loads texts — owner only` | `// loads texts - owner only` |
| Inline `<script>` in templates | `<script>doStuff()</script>` in a `.php` template | put logic in `public/js/<page>.js`, load via `<script src=...>` |
| Hardcoded admin URLs in user-facing JS | `fetch('/api/admin/...')` from a non-admin page JS | call user-scoped endpoints from user pages, admin endpoints only from admin pages |
| Cypress test logging in as the wrong role | `cy.loginAsAdmin()` in a non-admin spec | match the role to the page under test (`loginAsUser` for `/home`, `/texts`; `loginAsAdmin` for `/admin/*`) |
When generating code, scan the diff for these patterns before writing it
to disk.