mecha
AGENTS.md8 starsChanged 31 days agoMITView on GitHub
Instructions for AI coding agents working in this repository. Read CLAUDE.md first, in full. It holds the cross-cutting invariants any session needs on any run, and this file deliberately does not duplicate it. **docs/ARCHITECTURE.md records why each subsystem is shaped the way it is** — the incident behind each invariant, and the bug that reappears when one is undone; read its section before changing a subsystem. That reasoning is what you need in order to change something safely, and it…
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,439 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
The file
We split this AGENTS.md into the rules it gives an agent
3 rules. About 0 are common, 1 is distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Distinctive: line 91
Verify a fix by making it fail on the old behaviour.
- Very specific: line 115
Do not edit website/docs/changelog.md — it is generated from CHANGELOG.md at build time and gitignored.
- Very specific: line 124
If you learn something that would have saved you an hour, write it down.
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AGENTS.md
Instructions for AI coding agents working in this repository.
Read CLAUDE.md first, in full. It holds the cross-cutting
invariants any session needs on any run, and this file deliberately does not
duplicate it. docs/ARCHITECTURE.md records why
each subsystem is shaped the way it is — the incident behind each invariant,
and the bug that reappears when one is undone; read its section before
changing a subsystem. That reasoning is what you need in order to change
something safely, and it is not recoverable from the code alone.
CONTRIBUTING.md covers build commands, the testing layers,
and pull request expectations.
Orientation
mecha-core/ the library; knows nothing about any CLI or application
mecha-cli/ the `mecha` binary; thin, all logic belongs in core
mecha-mail/ library plus three MCP binaries for mail and calendar
mecha-slack/ the Slack transport; has no mecha-core dependency, and must
never gain one — that is why it is a crate and not a module
eval/ the case set and its fixtures
website/ the Docusaurus documentation site
docs/ design and research notes, not user documentation
results/ local only (untracked since 2026-10-04): run output and scorecards, on the operator's diskFour workspace members, all published to crates.io. A new one that anything published depends on must be added to the release workflow's publish list in the same change that introduces it.
Before you start
cargo build --workspace --all-targets
cargo test --workspaceBoth should pass on a clean checkout. If they do not, fix that before making changes — you cannot tell your breakage from pre-existing breakage otherwise.
Before you finish
cargo fmt --all
cargo clippy --all-targets --all-features
cargo test --workspaceCI treats warnings as errors, so a clippy warning will fail the build.
The traps
Each of these is a real bug this project has already shipped once. They share a shape: the code compiles, every test stays green, and the failure appears somewhere else entirely.
Adding a field to Config without adding it to ConfigLayer. The TOML
table becomes a parse error that kills startup, while every unit test passes
because tests build the types directly. This is exactly how hooks shipped
unreachable.
Calling fs::* on a path from tool input. It must go through
ToolCtx::resolve first. That function is the path jail.
Resetting taint at a turn boundary. Taint lives on agent::Conversation
because a turn boundary is not a security boundary. Keep the history and you
keep the taint.
Marking a tool's output as external when the harness generated it. Taint
keys off ToolOutput::external, not off the capability. A refusal produced by
our own guard, labelled as third-party content, makes the model invent
explanations for its own harness.
Making something that failed closed fail open. pre_tool hooks, sandbox
preflight, outbox staging and provenance classification all deny on error,
timeout, or ambiguity. A layer that cannot run and quietly allows is worse than
no layer at all, because everything downstream still believes it ran.
Matching on a provider name inside agent.rs. The loop must not know which
provider is behind it, or where a tool came from. Both are trait objects.
Reordering the tool registry. It is a BTreeMap because the tool list is
the front of the cached prompt prefix; reordering invalidates the cache every
turn.
Testing guidance
Verify a fix by making it fail on the old behaviour. A test that passes both before and after your change has measured nothing.
ScriptedProvider in agent.rs replays a fixed list of turns, so you can test
loop behaviour without network access. Know its limit: it replays what we
believe providers do, which makes it structurally blind to a provider
violating that belief. That blindness is where this project's expensive bugs
came from.
Integration tests skip themselves when a sandbox backend is missing. Set
MECHA_TEST_REQUIRE_BACKENDS=1 to turn every skip into a failure — a silently
skipped test reads exactly like a passing one.
Documentation
docs/README.md is the map — which document holds what,
and a decision rule for where a given piece of writing goes. Read it before
adding to any of them; most new writing belongs in a file that already exists.
The short version: CLAUDE.md is the cross-cutting invariants and
docs/ARCHITECTURE.md the per-subsystem ones,
docs/HANDOFF.md is current state and open work only, docs/HISTORY.md is
what shipped and what was learned, website/docs/ is for users, and
CHANGELOG.md gets the ## [Unreleased] entry for anything user-visible.
Do not edit website/docs/changelog.md — it is generated from CHANGELOG.md
at build time and gitignored.
At the end of a session that changed behaviour, run the handoff skill
(.claude/skills/handoff/). It is the procedure for verifying which open items
actually shipped, moving them into docs/HISTORY.md, and re-checking the facts
that rot. Its one rule is worth internalising even if you never invoke it:
verify against source, never against a commit message — including your own.
If you learn something that would have saved you an hour, write it down. A
lesson with a general rule attached goes in docs/HISTORY.md under "Traps
already hit"; an invariant that would otherwise look like an improvement to
remove goes in docs/ARCHITECTURE.md (that subsystem's section), or in
CLAUDE.md only if it cuts across subsystems.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

