Load grant files, failing closed on any invalid file
crates/brokerd/src/grants.rs reads grants/*.toml into a GrantSet: load reports every problem in every file and returns either a complete valid set or the full problem list, never a partial one; from_grants sorts by id and collects every rule-2..9 problem; render prints each problem then the runbook pointer. All 17 grants tests pass; make gate prints gate: ok. Implemented-By: OpenCode session (model recorded in docs/implementer-log.md)
This commit is contained in:
@@ -46,6 +46,7 @@ reviewer adds findings under "Reviews" once per milestone.
|
||||
| M3a/01-proto-audit-types | 2026-09-22 | done | 1 | pass | none | Finished the blocked task. `audit.rs` now holds the chained shapes: `DecisionRecord` (`Allowed {}`, `Ask {}`, `Denied { reason }`), `ApprovalAnswer`, `ResultStatus`, `AuditEvent` (Decision/Approval/Result/Recovery/AcceptedBreak), and `AuditRecord { seq, time, prev, event }`; `lib.rs` re-exports the five names. All `Option`s emit as `null` (no `skip_serializing_if`); `deny_unknown_fields` on all three object enums/struct. Tests copied from `docs/plans/M3a/files/`: `records` 3 passed, `strict` 5 passed. Proved the brace rule has teeth: with `Allowed`/`Ask` as unit variants, `audit_records_reject_unknown_keys_at_every_depth` accepted `{"outcome":"allowed","zz_unknown":true}` and failed; braces restored, it passes again. NOTE: `docs/plans/M3a/files/crates/proto/tests/strict.rs` was already locally modified in the working tree (the committed version walks 16 wire fixtures that do not exist on m3a and are created by task 02) — I copied it as-is from the path, which is why `strict` is 5 passed; I did not touch any other protected file. `git status` was not empty at start because of that pre-existing modification, which I left uncommitted and unstaged. | OpenCode |
|
||||
| M3a/03-proto-chain-verifier | 2026-09-19 | done | 1 | pass | implementation matches the reference tree's chain.rs verbatim |
|
||||
| M3a/04-brokerd-config | 2026-09-18 | done | 1 | pass | none | Wrote crates/brokerd/src/config.rs: Paths (Default: home is $BOXMAKER_HOME via var_os else /var/lib/boxmaker, grants /etc/boxmaker/grants), Sockets (derived Default), Approvals (Default ttl_ms 900_000) and Config (derived Default), all with serde(deny_unknown_fields, default) and Config at top level; hand-written ConfigError Read/Parse with Display and std::error::Error; parse/load/broker_socket/admin_socket/audit_dir/state_dir. Added serde, serde_json, toml to Cargo.toml, `pub mod config;` to lib.rs, and `brokerd` to the serde and serde_json "Used by" cells in dependencies.md. 7 config tests pass; `make gate` prints `gate: ok`. | OpenCode |
|
||||
| M3a/06-brokerd-grants | 2026-09-23 | done | 2 | fail | none | Wrote crates/brokerd/src/grants.rs: `RUNBOOK`, `LoadedGrant`, `GrantSet` (private `grants` field, `from_grants` sorts by id and collects every problem, `grants()`), `valid_id`, `load` (read_dir -> one directory problem, a missing dir is not empty, sorted names, skip non-.toml, read/utf8/toml/sha256 each record a problem and continue, then `from_grants`, stable sort by file), `render`, and `span_line` (count newlines in `text.get(..offset)` + 1). Rules 2-9 live in `check_grant`/`check_tool_constraints`; an unknown tool skips rule 6 only. First gate failed on clippy `needless_borrows_for_generic_args` (pass `format!()` not `&format!()` to the `impl Into<String>` `push`); all 17 grants tests pass; `make gate` prints `gate: ok`. | OpenCode |
|
||||
| M3a/05-brokerd-args | 2026-09-23 | done | 4 | fail | none | Wrote crates/brokerd/src/args.rs (MAX_PATH, MAX_URL, ToolName with ALL/parse/as_str, ToolArgs with tool/canonical_json, ArgsError with hand-written Display+Error, parse, valid_path, inside, valid_host, valid_host_pattern, host_matches, url_host) and added `pub mod args;` to lib.rs. 13 args tests pass; `make gate` prints `gate: ok`. Three clippy fixes before a clean gate: collapsed the shell `cwd` if-let into an edition-2024 let-chain, `('a'..='z').contains` -> `is_ascii_lowercase`, and the trailing `/` match -> `?`. `source()` returns None because `String` does not implement `std::error::Error`. The URL rules read the host as written (no `to_lowercase`); uppercase fails `valid_host`, matching the test that lists `https://Example.com/` as invalid. | OpenCode | Wrote crates/proto/src/chain.rs: `ChainVerifier`, a pure line-holding state machine (each line is judged only once the next one has arrived, so a `Recovery` record can mark the line before it not-a-record), plus `ChainFailure`, `TornTail`, `ChainReport`, `Location`. Holds each line, checks recovery against the next, then rule 1 (parse, expected seq, prev with the file-before text for line 1 of a resumed/continued verifier), the failed-region counting of rule 5, the resumed-earlier-file break exception of rule 6, run/ask tracking for `abandoned`/`unfinished`, and clock warnings; `finish` reports the torn tail and the break's required seq/prev. Added `pub mod chain` and the five re-exports to lib.rs and the same line to audit.rs. The single worker subagent for this task entered an unrecoverable reasoning loop on the state machine and was not completing, so the orchestrator implemented it directly from the spec and fixtures. 13 chain tests pass; `make gate` prints `gate: ok`. | OpenCode |
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user