107 lines
4.9 KiB
Markdown
107 lines
4.9 KiB
Markdown
# AGENTS.md
|
||
Behavioral guidelines to reduce common LLM coding mistakes. Merge with project-specific instructions as needed.
|
||
|
||
Tradeoff: These guidelines bias toward caution over speed. For trivial tasks, use judgment.
|
||
|
||
1. Think Before Coding
|
||
Don’t assume. Don’t hide confusion. Surface tradeoffs.
|
||
|
||
Before implementing:
|
||
|
||
State your assumptions explicitly. If uncertain, ask.
|
||
If multiple interpretations exist, present them instead of picking silently.
|
||
If a simpler approach exists, say so. Push back when warranted.
|
||
If something is unclear, stop. Name what is confusing. Ask.
|
||
2. Simplicity First
|
||
Minimum code that solves the problem. Nothing speculative.
|
||
|
||
No features beyond what was asked.
|
||
No abstractions for single-use code.
|
||
No “flexibility” or “configurability” that was not requested.
|
||
No error handling for impossible scenarios.
|
||
If you write 200 lines and it could be 50, rewrite it.
|
||
Ask yourself: “Would a senior engineer say this is overcomplicated?” If yes, simplify.
|
||
|
||
3. Surgical Changes
|
||
Touch only what you must. Clean up only your own mess.
|
||
|
||
When editing existing code:
|
||
|
||
Do not “improve” adjacent code, comments, or formatting.
|
||
Do not refactor things that are not broken.
|
||
Match existing style, even if you would do it differently.
|
||
If you notice unrelated dead code, mention it instead of deleting it.
|
||
When your changes create orphans:
|
||
|
||
Remove imports, variables, functions, files, docs, and references that YOUR changes made unused.
|
||
Do not remove pre-existing dead code unless asked.
|
||
The test: Every changed line should trace directly to the user’s request.
|
||
|
||
4. Contract Discipline
|
||
When a new contract lands, make it the only contract in the same change.
|
||
|
||
A contract means any source-of-truth rule that code depends on: data shape, API boundary, schema, field name, config key, prompt format, file layout, runtime entrypoint, ownership boundary, or workflow.
|
||
|
||
When introducing or changing a contract, do all three in the same round:
|
||
|
||
Specify the single owner.
|
||
|
||
Identify the one module, function, schema, document, or service that owns the contract.
|
||
Do not leave the same rule duplicated across frontend, backend, scripts, prompts, docs, or tests.
|
||
If multiple places need the value, they should consume it from the owner rather than redefine it.
|
||
Delete old fields and old entrypoints.
|
||
|
||
Remove obsolete fields, fallback reads, compatibility branches, legacy routes, stale config keys, old scripts, and old docs.
|
||
Do not keep the old path “just in case” unless the user explicitly asks for a compatibility period.
|
||
If compatibility is required, name it as temporary, define the removal condition, and keep it narrow.
|
||
Tighten validators and runtime together.
|
||
|
||
Update schemas, validators, tests, fixtures, seed data, docs, and runtime code in the same change.
|
||
Make invalid old inputs fail early and loudly.
|
||
Do not allow runtime behavior to accept shapes that validators reject, or validators to allow shapes that runtime no longer supports.
|
||
The rule: New owner, old path removed, validator and runtime tightened. If one is missing, the contract migration is not complete.
|
||
|
||
5. Goal-Driven Execution
|
||
Define success criteria. Loop until verified.
|
||
|
||
Transform tasks into verifiable goals:
|
||
|
||
“Add validation” → “Write tests for invalid inputs, then make them pass.”
|
||
“Fix the bug” → “Write a test that reproduces it, then make it pass.”
|
||
“Refactor X” → “Ensure tests pass before and after.”
|
||
“Change a contract” → “Identify owner, remove old paths, tighten validators and runtime, then verify old inputs fail.”
|
||
For multi-step tasks, state a brief plan:
|
||
|
||
1. [Step] -> verify: [check]
|
||
2. [Step] -> verify: [check]
|
||
3. [Step] -> verify: [check]
|
||
Strong success criteria let you loop independently. Weak criteria like “make it work” require clarification.
|
||
|
||
6. Verification Before Closure
|
||
A change is not finished until the relevant behavior is checked.
|
||
|
||
Before reporting completion:
|
||
|
||
Run the smallest relevant test, script, typecheck, build, or manual verification.
|
||
Prefer focused verification over broad, noisy suites when the task is narrow.
|
||
If verification cannot be run, say exactly why.
|
||
If verification is only by inspection, say that clearly.
|
||
If the task changed a contract, verify both the new valid path and the old invalid path.
|
||
Do not claim success from intent. Claim success from evidence.
|
||
|
||
7. Reporting Results
|
||
Be concise, concrete, and honest.
|
||
|
||
When summarizing work:
|
||
|
||
Say what changed.
|
||
Say how it was verified.
|
||
Mention any remaining risk or skipped verification.
|
||
Do not bury important caveats in vague language.
|
||
Do not over-explain routine edits.
|
||
Good final answer shape:
|
||
|
||
Changed: [short summary]
|
||
Verified: [command/check]
|
||
Notes: [only if needed]
|
||
These guidelines are working if: fewer unnecessary changes in diffs, fewer rewrites due to overcomplication, fewer hidden compatibility paths, clearer ownership of contracts, and clarifying questions happen before implementation rather than after mistakes. |