Files
boxmaker/AGENTS.md
T
kyleandClaude Fable 5.1 2be8581a0c Review M2b: accept with one follow-up task; record lessons
All ten tasks pass the checklist, the gate, the audit and the device
checks, including a four-turn conversation with a loopd restart and no
cache loss. Reading and probing found four low defects: the busy guard
is released before the final frame on the main path but not on the
three error paths, its Drop skips a poisoned lock, an unreadable
core.md is treated as missing, and bxctl's interactive loop exits on a
failed turn. Task 11 carries the fixes with two new tests, checked
against a fixed copy of the branch.

The Model column is filled in (all Ornith) and one malformed row is
repaired. Two rules are promoted to AGENTS.md.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-18 20:47:03 -07:00

5.5 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

  1. 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.
  2. Do the steps in order. Where a step shows a command and its expected output, run it and compare.
  3. Do not read docs/design.md or other plans unless the task tells you to. The task file quotes what you need.
  4. 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.md with status stopped, say what you tried and what happened, commit only that file, and tell the owner. A later session that finishes the task adds a new done row; it never edits the stopped row, because the record of the stop is part of the log.

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". No unsafe. No async runtime.
  • No dependency that the task file does not name. All external dependencies are declared in the root Cargo.toml under [workspace.dependencies], used with name.workspace = true, and have a row in docs/dependencies.md.
  • proto depends on no workspace crate. Every other crate depends on proto only, 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, or as casts that can lose data on untrusted values. Tests may use them.
  • Errors are plain enums that implement std::fmt::Display and std::error::Error. No anyhow, no thiserror.
  • 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.
  • Formats we define (config, grants, IPC messages, log records) reject unknown fields. Formats another program defines (the inference server's JSON, later Mattermost's) ignore them: those programs send fields we do not use and add more over time. Each task says which kind it handles.
  • Everything read from a socket is bounded, and a number that came from a peer is never used to index, allocate or cast without a check.
  • Comments say why, not what. Match the amount of commenting you see in the task's examples.

Lessons from earlier reviews

These come from defects found in review. The evidence is in docs/implementer-lessons.md.

  • When a rule says "every" or "everywhere", finish by listing each place it could apply (every struct and enum in the file, every script, every branch) and check them one by one. An example in a task shows one place; the rule covers all of them.
  • A check must fail when it cannot do its job: missing input, unreadable file, a tool that errors. Never throw errors away with 2>/dev/null, || true or an ignored Result.
  • Report every problem you find, not only the first.
  • Log every attempt, including one you abandon.
  • Never end a turn by describing what you are about to do. Do it, then report.
  • If a tool you were told to use does not exist, stop and say so. Do not invent a command in its place.
  • A read returns as soon as it has any data to give and blocks only when it has none.
  • A rule about one path applies to every path that does the same thing, including early returns and error paths the task did not walk through.
  • A file that exists but cannot be read is an error. Only a missing file may count as absent.

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/. Run cargo fmt --all before the gate; rustfmt decides the order of mod and use lines, not you. 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> .... Never git add -A or git 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: OpenCode session (model recorded in docs/implementer-log.md)

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
Model Write ?. The owner fills this in.