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>
6.5 KiB
M1 task 01: workspace and gate
Branch: m1 (create it: git switch -c m1)
Commit subject: Add Cargo workspace, crate skeletons and the gate
Goal
Create the Cargo workspace with seven empty crates, and the gate that every later task must pass.
At the end make gate prints gate: ok.
Context
From the design brief: "Rust stable, Cargo workspace. Crates: proto (shared types), loopd,
brokerd, gatewayd, inferproxy, toolkit (tool container entrypoints), bxctl (owner CLI).
No source file over 500 lines. No crate depends on another role's crate, only on proto.
Dependencies are few and justified in docs/dependencies.md. No outbound call not listed in
docs/egress.md."
Every crate except proto is a library with a thin main.rs, so that doctests can run later.
Files
- Copy (never edit afterwards):
Makefile,deny.toml,scripts/test-gate-scripts.sh - Create:
Cargo.toml,Cargo.lock(generated),crates/<name>/Cargo.tomlfor all seven crates,crates/<name>/src/lib.rsfor all seven,crates/<name>/src/main.rsfor the six that are notproto - Create:
scripts/check-lines.sh,scripts/check-crate-deps.sh,scripts/check-dep-docs.sh - Create:
docs/dependencies.md,docs/egress.md - Modify:
docs/implementer-log.md
Steps
- 1. Branch and copy the given files.
git switch -c m1
mkdir -p scripts
cp docs/plans/M1/files/Makefile docs/plans/M1/files/deny.toml .
cp docs/plans/M1/files/scripts/test-gate-scripts.sh scripts/
Read Makefile and scripts/test-gate-scripts.sh. The second one is the test for the three
scripts you write in step 4: it shows exactly which inputs must pass and which must fail.
- 2. Write the root
Cargo.tomlwith exactly this content:
[workspace]
resolver = "3"
members = [
"crates/proto",
"crates/loopd",
"crates/brokerd",
"crates/gatewayd",
"crates/inferproxy",
"crates/toolkit",
"crates/bxctl",
]
[workspace.package]
edition = "2024"
rust-version = "1.95"
publish = false
[workspace.lints.rust]
unsafe_code = "forbid"
[workspace.dependencies]
proto = { path = "crates/proto" }
- 3. Write the seven crates.
crates/loopd/Cargo.tomlis:
[package]
name = "loopd"
version = "0.1.0"
edition.workspace = true
rust-version.workspace = true
publish.workspace = true
[lints]
workspace = true
[dependencies]
proto.workspace = true
The other five role crates are the same with their own name. crates/proto/Cargo.toml is the
same with name = "proto" and an empty [dependencies] section.
Each src/lib.rs is one doc comment line and nothing else:
| Crate | src/lib.rs |
|---|---|
proto |
//! Shared data types and the frame codec for Boxmaker. No policy and no I/O beyond frames. |
loopd |
//! The agent loop: sessions, prompt assembly and memory. It holds no authority. |
brokerd |
//! The broker: the only role that holds authority. |
gatewayd |
//! The Mattermost channel. Outbound connections only. |
inferproxy |
//! Forwards bytes between `infer.sock` and the llama-server router. It logs nothing. |
toolkit |
//! Entry points that run inside tool containers. |
bxctl |
//! The owner's command-line tool. |
Each src/main.rs (not for proto) follows this pattern, with its own name and milestone
(loopd M2, brokerd M3, gatewayd M4, inferproxy M2, toolkit M3, bxctl M2):
fn main() {
eprintln!("loopd: not implemented until M2");
std::process::exit(2);
}
Run cargo build. Expected: it finishes without warnings and creates Cargo.lock.
-
4. Write the three gate scripts. POSIX
shonly: no bash features, no Python, nojq. Each takes an optionalROOTargument that defaults to., prints one line per problem to stderr starting with the script's name, and exits 1 if there was any problem, 0 otherwise. -
scripts/check-lines.sh [ROOT]: fails if any*.rsfile underROOT/crateshas more than 500 lines. Files under anytarget/directory are ignored. Test files count. -
scripts/check-crate-deps.sh [ROOT]: the workspace crates are the directories inROOT/crates. Fails ifprotodepends on any workspace crate, or if any other crate depends on a workspace crate other thanproto. Look at every manifest section whose name containsdependencies(so[dev-dependencies]counts). A dependency is any key in such a section, however it is written:x.workspace = true,x = { path = "…" },x = "1". -
scripts/check-dep-docs.sh [ROOT]: fails if a key in[workspace.dependencies]ofROOT/Cargo.tomlthat is not a workspace crate has no table row starting| `name` |inROOT/docs/dependencies.md. It also fails if any dependency line in anyROOT/crates/*/Cargo.tomllacksworkspace = true.
Run sh scripts/test-gate-scripts.sh. Expected: test-gate-scripts: ok. If it reports failures,
fix your scripts, never the test.
- 5. Write the two documents.
docs/dependencies.md:
# Dependencies
Every external crate has a row here. `scripts/check-dep-docs.sh` enforces it.
| Crate | Version | Used by | Why |
|---|---|---|---|
docs/egress.md:
# Egress
Every outbound network call the project makes, at run time or in development. Nothing else is
allowed.
| When | From | To | What |
|---|---|---|---|
| Development | `cargo` | crates.io | Downloading the crates listed in `docs/dependencies.md` |
| Development | `make audit` | github.com/rustsec/advisory-db | The RustSec advisory database, fetched by `cargo deny check advisories` |
-
6. Run the gate.
make gate. Expected last line:gate: ok. At this stagecargo denyprintslicense-not-encounteredwarnings, because there are no dependencies yet. They are expected and they go away in task 02. Do not editdeny.toml. -
7. Log and commit. Add your row to
docs/implementer-log.md, then:
git add Cargo.toml Cargo.lock Makefile deny.toml crates scripts docs/dependencies.md docs/egress.md docs/implementer-log.md
git status --short
git commit
git status --short must show nothing untracked except ignored files. Use the commit subject at
the top of this file and the trailer from AGENTS.md.
Done when
make gateprintsgate: ok.cmp Makefile docs/plans/M1/files/Makefileand the same fordeny.tomlandscripts/test-gate-scripts.shprint nothing.- One new commit on
m1.
Stop and report if
cargo denyis not installed (cargo deny --versionfails).make gatefails in a step that is not one of your scripts and you cannot see why.