Files
boxmaker/docs/plans/M5a/01-brokerd-split.md
T
kyleandClaude Opus 5.5 de1032157b Plan M5a: local memory in 15 tasks
memoryd (files, the check, edits, journal, index, recall, serving),
the memory tools and built-in grants in brokerd, the memory block in
loopd, bxctl reindex and memory, and the device checks with memoryd.

Each task was built as a reference and gated. Each was replayed on its
own at its end state (854 to 936 tests) and mutation-checked. Each
skeleton compiles and fails its tests. Every todo comment was read
beside its signature.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-24 15:32:54 -07:00

107 lines
4.4 KiB
Markdown

# M5a task 01: split `brokerd`'s policy and ledger into modules
**Branch:** `m5a` (run `git switch m5a`; `git status --short` must be empty, otherwise stop)
**Commit subject:** `brokerd: policy and ledger as modules, before the memory tools`
## Goal
`crates/brokerd/src/policy.rs` is 498 lines and `crates/brokerd/src/ledger.rs` 487; the limit is
500, and M5a adds to both crates' paths. Move each into a directory module, with part of it in a
child file. **Nothing else changes**: no line of code is edited, only moved, plus the visibility
and imports listed below. A child module can see its parent's private items, so `Decision` keeps
its private fields and its compile-fail doc tests still pass.
## Files
- Move: `crates/brokerd/src/policy.rs` to `crates/brokerd/src/policy/mod.rs`, and
`crates/brokerd/src/ledger.rs` to `crates/brokerd/src/ledger/mod.rs` (with `git mv`)
- New: `crates/brokerd/src/policy/matching.rs`, `crates/brokerd/src/ledger/answer.rs`
- Modify: `docs/implementer-log.md`
## The policy split, exactly
1. `mkdir crates/brokerd/src/policy && git mv crates/brokerd/src/policy.rs crates/brokerd/src/policy/mod.rs`
2. In `policy/mod.rs`, find the line `/// The grants left after matching, and the two flags that pick
the denial reason when none are` (the doc comment of `struct MatchResult`). Cut from that line
to the end of the file, and paste it into the new file `policy/matching.rs` below this header:
```rust
//! Matching a call against the grants: which grants cover it, and which one wins.
use super::{Label, Matched, SessionState};
use crate::args::{ToolArgs, host_matches, inside};
use crate::grants::GrantSet;
use proto::{DataClass, Grant, Hash32, Mode, Timestamp};
```
3. In `policy/matching.rs`, and nowhere else, add `pub(super)` to: `struct MatchResult` and its
three fields; `struct Candidate` and every one of its fields; `fn match_grants`, `fn winner`
and `fn build_matched`. Leave `covers`, `best_path`, `better` and `combined_label` private.
4. In `policy/mod.rs`, the three `use` lines
```rust
use crate::args::{self, ToolArgs, ToolName, host_matches, inside};
use crate::grants::GrantSet;
use proto::{DataClass, DenyReason, Grant, Hash32, Mode, Timestamp, ToolRequest};
```
become
```rust
mod matching;
use crate::args::{self, ToolArgs, ToolName};
use crate::grants::GrantSet;
use matching::{MatchResult, build_matched, match_grants, winner};
use proto::{DataClass, DenyReason, Hash32, Mode, Timestamp, ToolRequest};
```
## The ledger split, exactly
1. `mkdir crates/brokerd/src/ledger && git mv crates/brokerd/src/ledger.rs crates/brokerd/src/ledger/mod.rs`
2. In `ledger/mod.rs`, inside `impl Ledger`, find ` /// Re-decide an approval and record it.`
(the doc comment of `pub fn answer`). Cut from that line down to the end of `pub fn finish`,
which is everything up to, but not including, the `}` that closes `impl Ledger` (the last line
of the file). Paste it into the new file `ledger/answer.rs` inside an `impl Ledger { … }`, below
this header:
```rust
//! Answering an approval, and recording a call's result.
use std::sync::MutexGuard;
use proto::{ApprovalAnswer, AuditEvent, DataClass, DenyReason, Timestamp, ToolResponse};
use super::{Answer, Answered, Call, Grants, Inner, Ledger};
use crate::approvals::Verdict;
use crate::policy::{Ask, Denial, SessionState};
impl Ledger {
```
and close the file with `}` after `finish`.
3. In `ledger/mod.rs`: add `mod answer;` and a blank line just before
`use std::sync::{Mutex, MutexGuard};`, and remove `ApprovalAnswer, ` from the `use proto::{…}`
list (it is used only in `answer.rs` now).
## Steps
- [ ] **1. Move** the two files as above, one split at a time, with `cargo check -p brokerd`
after each. `cargo fmt --all`.
- [ ] **2. See nothing change.** `cargo test -p brokerd`: every suite passes, the doc tests
included (`policy`'s two `compile_fail` examples still fail to compile, which is a pass).
`wc -l crates/brokerd/src/policy/*.rs crates/brokerd/src/ledger/*.rs`: every file under 500.
- [ ] **3. Run the gate.** `make gate`. Expected last line: `gate: ok`, with the same number of
tests as before this task (about 854).
- [ ] **4. Log and commit.** `git add -A crates/brokerd docs/implementer-log.md Cargo.lock && git commit`
## Done when
- `make gate` prints `gate: ok` with no change in the number of tests.
## Stop and report if
- The compiler asks for a visibility change or an import not listed here.
- Any test changes result.