One file (AGENTS.md) that bootstraps the rest: rules, the file map to create, what belongs in each file, the first-session interview order, and the list of anti-patterns that killed the previous map (1,308-line guide, 63 task files, narrative history inline, sessions skimming 56k tokens of context). Separates four kinds of content by read frequency: rules/invariants -> AGENTS.md (every session) subsystem truth -> docs/ai/<topic>.md (only the matching one) lookups -> environment.md (grepped, never read) retired decisions -> decisions.md (only when re-opening one) Caps are enforced, not promised: scripts/verify.sh checks doc budgets before the build, so a commit that pads a capped file fails. Proven both ways — it passes clean and exits 1 on an over-cap file. scripts/scope-check.sh blocks edits outside the declared file list. templates/ holds fill-in skeletons for the seven files a project must create. CC0: copy it, rename it, sell it, no attribution needed.
146 lines
8.0 KiB
Markdown
146 lines
8.0 KiB
Markdown
# AGENTS — bootstrap
|
||
|
||
You are starting this project's memory from nothing. This file is self-contained: it gives you
|
||
the rules, the file map you must create, what belongs in each file, and the order to do it in.
|
||
|
||
Two standing orders:
|
||
|
||
1. **This file is the only mandatory read at session start.** Everything else is read on demand.
|
||
2. **Finish work; do not manage it.** A session that produces task lists, re-prioritisation or
|
||
documentation of work instead of working has failed, even if the docs are good.
|
||
|
||
---
|
||
|
||
## 1. Rules — non-negotiable
|
||
|
||
**Delivery**
|
||
- One unit = one behaviour = **one test** = one commit. If a request needs several tests, pick the
|
||
one the user cares about and finish it before the next.
|
||
- No feature branches pre-1.0. Work lands on `main`, committed per unit.
|
||
- Commit every unit without asking. **Push only at checkpoints the user names.**
|
||
- Declare the exact file list before editing. No "while I'm here" edits, no drive-by refactors.
|
||
Anything spotted outside the list becomes a one-line follow-up in `HANDOFF.md`.
|
||
- One pre-commit gate for code: clean build at **0 warnings**, full tests, scope check, doc budgets
|
||
(`scripts/verify.sh "<files>"`). Docs-only units run the scope check alone.
|
||
|
||
**Reading**
|
||
- Session start, in this order, and stop: `HANDOFF.md` → `ai.md` → **the one** `docs/ai/<topic>.md`
|
||
that matches the task → `<dir>/index.md` for the code you will touch.
|
||
- `TASKS.md` is read when the question is "what's next" — never as a prerequisite to code.
|
||
- Never read the whole map "for context". If the map is a required read, the map is wrong.
|
||
|
||
**Memory**
|
||
- The map is corrected by the change that **falsifies** it — in the same commit. It is not a unit
|
||
of its own; no "docs backfill" commits unless asked.
|
||
- Three kinds of truth, three homes: rules/invariants → this file; subsystem detail →
|
||
`docs/ai/<topic>.md`; lookups (paths, ports, hosts, credential locations) → one cheat sheet.
|
||
History and abandoned decisions → a decisions log, never inline in the docs.
|
||
- `HANDOFF.md` is current state only, **overwritten not appended**, hard-capped.
|
||
- A fact recorded once ends the re-derivation loop: paths, traps and recipes go in the map the
|
||
first time they cost a hunt. **Grep the recipes file before re-deriving anything.**
|
||
|
||
**Behaviour**
|
||
- Do the work, then report what changed and what's next. No plans, pros/cons tables or "pitfalls"
|
||
sections unless asked.
|
||
- Nothing here is novel: scan externally before building anything new, cite the reference in the
|
||
commit. A **second** failed fix for the same symptom is a research trigger, not a persistence
|
||
trigger — stop and find the established answer.
|
||
- Follow the codebase's existing conventions; don't add comments the code doesn't need; don't
|
||
invent work items.
|
||
|
||
---
|
||
|
||
## 2. Files you must create
|
||
|
||
| File | Role | Cap | Written by |
|
||
|---|---|---|---|
|
||
| `AGENTS.md` | This file: rules + the project's invariants | 210 lines | you, rarely |
|
||
| `ai.md` | **Router**: what the product is, build commands, architecture table, where truth lives | 100 lines | you, rarely |
|
||
| `HANDOFF.md` | Current state: branch, in flight, next action, landmines | 40 lines | every session, overwritten |
|
||
| `TASKS.md` | The active queue, one line per live item | 120 lines | on status change |
|
||
| `TASKS/archive.md` | Everything done, as a dated snapshot | unbounded | at trim time |
|
||
| `docs/ai/<topic>.md` | Subsystem truth — one file per subsystem | unbounded | as that subsystem changes |
|
||
| `docs/ai/index.md` | Routing table: file ↔ what it covers ↔ when to read it | — | as files are added |
|
||
| `docs/ai/decisions.md` | Retired paths + cause of death, and the permanent out-of-scope list | — | when a decision dies |
|
||
| `docs/ai/environment.md` | Lookups: hosts, ports, paths, build/run/test commands, suite map | — | when a fact costs a hunt |
|
||
| `MyMistakes.md` | Failure log + **recipes registry** (grep-first) | — | when something is learned the hard way |
|
||
| `schema.md` | The conventions above, restated for this repo | — | once |
|
||
| `<dir>/index.md` | One per code directory: file list + one-line purpose + links out | — | when layout changes |
|
||
|
||
If a file is over cap: **move detail out, never pad** — the gate fails padding.
|
||
|
||
---
|
||
|
||
## 3. What goes in each file
|
||
|
||
**`HANDOFF.md`** (≤40)
|
||
```
|
||
# HANDOFF — <date> (<one-line state>)
|
||
## State branch, worktree, unpushed commits
|
||
## Next action the single next unit, and why it is next
|
||
## Landmines live traps only — paths, flaky tests, do-not-touch rules
|
||
## Pending what is blocked on the user (checks, decisions, takes)
|
||
```
|
||
|
||
**`ai.md`** (≤100) — `# <Product> — AI guide & router`, then:
|
||
- `## What it is` — five lines max.
|
||
- `## Build, run, test` — the actual commands, plus the pointer to `environment.md`.
|
||
- `## Architecture` — one table row per top-level directory: path → role.
|
||
- `## Where the truth lives` — table: subsystem → doc → "read when".
|
||
- `## Current state` → a one-line pointer to `HANDOFF.md`. Nothing else.
|
||
|
||
**`docs/ai/<topic>.md`** — open with one line of "read when". Then observed reality only:
|
||
how it works, the traps that cost time, the measurements that settled an argument, and the
|
||
guard test that protects each rule. Date contested facts. Never re-tell the product pitch.
|
||
|
||
**`TASKS.md`** — `## Next up` (the one unit, 5 lines) · `## Queue` (one table row per item:
|
||
id, status ☐🔶⏳⏸❌, one-line scope, detail link) · `## Pending the user` · `## Release gates`.
|
||
|
||
**`decisions.md`** — one dated line per decision that no longer governs, with the reason it died,
|
||
plus the permanent out-of-scope list. Read only when about to re-open one.
|
||
|
||
**`MyMistakes.md`** — `## Recipes` first (how-to, verbatim commands, traps). Then dated failure
|
||
entries: symptom → wrong guess → actual cause → the rule that prevents it.
|
||
|
||
---
|
||
|
||
## 4. Create the gate
|
||
|
||
`scripts/scope-check.sh` — fails if any changed file is outside the declared list.
|
||
`scripts/verify.sh "<files>"` — in this order:
|
||
|
||
1. **Doc budgets**: `wc -l` every capped file, fail with "move the detail out, do not pad".
|
||
2. **Clean build**: clean first, then build; any warning fails. (Incremental "0 warnings" lies.)
|
||
3. **Tests**: full suite; a whitelist of known-flaky names, everything else is a regression.
|
||
4. **Scope check** with the passed file list.
|
||
|
||
A budget that is not a failing gate gets eaten by the next append. This is the load-bearing part.
|
||
|
||
---
|
||
|
||
## 5. First session — do this, in order
|
||
|
||
1. Ask the user for: what the product is in one paragraph, the architecture's top-level
|
||
directories, the build/run/test commands, the deployment target, and anything that must never
|
||
be violated (legal, data-loss, output-corrupting). **One question at a time.**
|
||
2. Write `AGENTS.md` §1 rules as-is, then add **the invariants**: 10–20 lines, each stating a rule
|
||
and pointing at the doc that explains it. An invariant earns its line only if violating it
|
||
breaks output, destroys user data, or creates a legal/trust breach.
|
||
3. Write `ai.md` router, `HANDOFF.md`, `TASKS.md` (empty queue), `docs/ai/index.md`,
|
||
`docs/ai/environment.md`, `decisions.md` skeleton, `MyMistakes.md` with an empty Recipes
|
||
section, `schema.md`, and `<dir>/index.md` for each directory.
|
||
4. Write the two scripts and prove the gate fires (create an over-cap file, watch it fail).
|
||
5. Commit once: "docs: project memory map + gate". Then **stop mapping and start working**.
|
||
|
||
---
|
||
|
||
## 6. Anti-patterns that killed the last map
|
||
|
||
- Appending instead of replacing — the file only grows, and stale facts outlive the code.
|
||
- One task file per task, with paragraph-length status prose — a second, worse source of truth.
|
||
- Cross-references like "TASK 3 item 17" — numbers rot; cite a path or a feature name.
|
||
- Narrative history kept inline "for context" — it is 30% of the file and read by nobody.
|
||
- Splitting into more files without a router — discovery cost just moved.
|
||
- Docs commits as units of work — the cheapest thing to produce, so it replaces real progress.
|
||
- Reading the whole map every session — a tax that trains sessions to skim.
|