Seven task files for the implementing model under docs/plans/M1/, with the test files, byte-exact fixtures, Makefile, deny.toml and gate-script self-test they copy into place. All of it was verified against a private reference implementation: the gate passes after every task in order. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
3.6 KiB
AGENTS.md
Boxmaker is a personal agent harness in Rust: a Cargo workspace of small daemons that talk over Unix sockets. You are implementing it one task at a time.
How you work
- The owner gives you one task file,
docs/plans/M<n>/NN-name.md. Read it fully. Do that task and nothing else. Do not start the next task. - Do the steps in order. Where a step shows a command and its expected output, run it and compare.
- Do not read
docs/design.mdor other plans unless the task tells you to. The task file quotes what you need. - If something in the task is impossible, contradictory, or fails twice in the same way, stop.
Do not improvise, do not change a test, do not weaken a check. Add your row to
docs/implementer-log.mdwith statusstopped, say what you tried and what happened, commit only that file, and tell the owner.
Files you must never edit
docs/design.md,docs/decisions.md,docs/inference-contract.md,docs/specs/,docs/plans/- Anything a task told you to copy from
docs/plans/**/files/: tests, fixtures,Makefile,deny.toml,scripts/test-gate-scripts.sh. If a copied test fails, your code is wrong. AGENTS.md,CLAUDE.md
Code rules
- Rust stable, edition 2024,
rust-version = "1.95". Nounsafe. No async runtime. - No dependency that the task file does not name. All external dependencies are declared in the
root
Cargo.tomlunder[workspace.dependencies], used withname.workspace = true, and have a row indocs/dependencies.md. protodepends on no workspace crate. Every other crate depends onprotoonly, never on another role crate.- No source file over 500 lines.
- Library code never panics on input: no
unwrap,expect,panic!, indexing that can go out of bounds, orascasts that can lose data on untrusted values. Tests may use them. - Errors are plain enums that implement
std::fmt::Displayandstd::error::Error. Noanyhow, nothiserror. - Do not silence a lint with
#[allow(...)]unless the task says so. Fix the code. - Keep struct fields and enum variants in the order the task gives. The order is the wire format.
- Comments say why, not what. Match the amount of commenting you see in the task's examples.
The gate
make gate must print gate: ok before a task is done. It runs offline: rustfmt, clippy with
warnings denied, all tests, cargo-deny, and the scripts in scripts/. After you add a dependency,
run cargo build once so that Cargo.lock is updated, then run the gate.
Useful while working: cargo test -p <crate> --test <file> runs one test file, and
cargo test -p <crate> <name> runs tests whose name contains <name>.
Git
- Work on the branch the task names. One task is one commit.
- Stage only the paths the task lists:
git add <path> .... Nevergit add -Aorgit add .. - Never push, amend, rebase, reset, or switch to another branch.
- Commit message: the subject line the task gives, a blank line, then this trailer:
Implemented-By: Laguna S 2.1 (OpenCode)
The implementer log
Before you commit, add one row to the table in docs/implementer-log.md and include the file in
the commit. Be honest: the log is how the owner judges the process, and a wrong row is worse than a
bad one.
| Column | What to write |
|---|---|
| Task | The task file name, for example M1/03-proto-wire |
| Date | Today's date, YYYY-MM-DD |
| Status | done or stopped |
| Gate runs | How many times you ran make gate |
| First gate | pass or fail for the first run |
| Deviations | Anything you did that the task did not say, or none |
| Notes | Problems you hit and how you solved them, in one or two sentences |