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>
64 lines
3.8 KiB
Markdown
64 lines
3.8 KiB
Markdown
# M1 implementation plan: workspace, `proto`, gate
|
|
|
|
> **For the implementing model:** do not work from this file. The owner gives you one task file at
|
|
> a time (`01-…` to `07-…`). This file is the index for the owner and the reviewer.
|
|
|
|
**Goal:** A Cargo workspace whose gate passes, with the real shared types in `proto` and a
|
|
`Decision` type in `brokerd` that code outside its policy module cannot construct.
|
|
|
|
**Architecture:** Seven crates under `crates/`. `proto` holds data types and the frame codec and
|
|
depends on no workspace crate. Every role crate is a library with a thin `main.rs` and depends only
|
|
on `proto`. Behaviour is pinned by test files and byte-exact fixtures that the design model wrote
|
|
and verified against a private reference implementation; the implementer writes the code.
|
|
|
|
**Tech stack:** Rust stable (edition 2024, `rust-version = "1.95"`), `serde` 1.0.229,
|
|
`serde_json` 1.0.151, `humantime` 2.4.0, `toml` 1.1.6 (tests only), `cargo-deny` 0.20.2, POSIX `sh`.
|
|
|
|
**Spec:** `docs/specs/2026-09-17-pre-m1-design.md`, sections 4, 5 and 8. Brief: `docs/design.md`.
|
|
|
|
## Global constraints
|
|
|
|
- No `unsafe` (`unsafe_code = "forbid"` as a workspace lint). No async runtime.
|
|
- No source file over 500 lines. No role crate depends on another role crate.
|
|
- Every external dependency is in `[workspace.dependencies]` and has a row in
|
|
`docs/dependencies.md`. Crates are `publish = false`.
|
|
- Unknown fields are rejected everywhere. Field order is the wire format.
|
|
- `make gate` runs offline and must print `gate: ok` at the end of every task.
|
|
- Branch `m1`. One task, one fresh OpenCode session, one commit. Review happens once, after task 07.
|
|
|
|
## Tasks
|
|
|
|
| # | File | Delivers | Tests that define it |
|
|
|---|---|---|---|
|
|
| 01 | `01-workspace-and-gate.md` | Workspace, seven crates, `Makefile`, `deny.toml`, three gate scripts, `docs/dependencies.md`, `docs/egress.md` | `scripts/test-gate-scripts.sh` |
|
|
| 02 | `02-proto-values.md` | `SessionId`, `Epoch`, `CallId`, `Hash32`, `Timestamp`, `ValueError`, `DataClass` | `tests/ids.rs` |
|
|
| 03 | `03-proto-wire.md` | `Envelope`, `Message`, `ToolRequest`, `ToolResponse`, `WireError`, `ErrorCode`, `DenyReason` | `tests/wire.rs`, `fixtures/wire/` |
|
|
| 04 | `04-proto-frame.md` | `read_frame`, `write_frame`, `FrameError`, `MAX_FRAME` | `tests/frame.rs`, `fixtures/frame/` |
|
|
| 05 | `05-proto-grant.md` | `Grant`, `Mode`, `Constraints` | `tests/grant.rs`, `fixtures/grant/` |
|
|
| 06 | `06-proto-records.md` | `DecisionRecord`, `AuditRecord`, `ToolCall`, `LogRecord` | `tests/records.rs`, `fixtures/records/` |
|
|
| 07 | `07-brokerd-decision.md` | `brokerd::policy::Decision`, `decide`, `brokerd::runner::run` | doctests and unit tests in `policy.rs` |
|
|
|
|
`files/` holds everything the tasks copy into place. Tests for a later task do not compile until
|
|
that task's types exist, which is why they are copied task by task and not all at once.
|
|
|
|
## For the owner: running a task
|
|
|
|
In `~/src/boxmaker`, start a fresh OpenCode session with Laguna S 2.1 and send:
|
|
|
|
> Read `docs/plans/M1/01-workspace-and-gate.md` and do exactly that task.
|
|
|
|
Then the next file in a new session, and so on. If a session ends with a `stopped` row in
|
|
`docs/implementer-log.md`, do not start the next task.
|
|
|
|
## For the reviewer: after task 07
|
|
|
|
1. `git log --oneline master..m1` shows seven commits (plus any `stopped` rows), each with the
|
|
`Implemented-By` trailer.
|
|
2. Copied files are unchanged:
|
|
`for f in $(cd docs/plans/M1/files && find . -type f); do cmp "docs/plans/M1/files/$f" "$f"; done`
|
|
3. `git diff master..m1 --stat -- docs/design.md docs/specs docs/plans AGENTS.md CLAUDE.md` is empty.
|
|
4. `make gate` prints `gate: ok`. `make audit` passes.
|
|
5. Read every non-test source file against its task: field order, no panics in library code, no
|
|
`#[allow]`, no dependency the tasks did not name, error types as specified.
|
|
6. Write findings under "Reviews" in `docs/implementer-log.md`.
|