Files
boxmaker/docs/plans/M4b/02-proto-gateway-wire.md
T
kyleandClaude Opus 5.5 2d415fc1be Plan M4b: approvals over Mattermost in 15 tasks
Skeletons for new files only; existing files change by exact edits, so no task overwrites an
earlier one's work. Each task's tests were run against a reference built in order from master,
with the gate at each step and mutations checked; each skeleton compiles and fails its tests, and
every todo!() comment was read beside its signature. The reference is kept off this machine.

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

3.7 KiB

M4b task 02: the gateway.sock messages in proto

Branch: m4b (run git switch m4b; git status --short must be empty, otherwise stop) Commit subject: proto: gateway, the four messages between brokerd and gatewayd

Goal

One gateway.sock connection carries one pending approval from brokerd to gatewayd, and its answer back (M4b spec, section 4). Every frame is a proto Envelope:

# From kind final Body
1 brokerd approval_request true ApprovalRequest { approval: PendingApproval }
2 gatewayd approval_posted false ApprovalPosted { posts: Vec<String> }
3 gatewayd approval_reply true ApprovalReply { approval, approved, by, post, reason }
4 brokerd approval_outcome true ApprovalOutcome { outcome: GatewayOutcome }

These are our format: unknown fields are errors everywhere.

Files

  • Copy: the skeleton crates/proto/src/gateway.rs, crates/proto/tests/gateway_wire.rs, and the eight fixtures crates/proto/tests/fixtures/wire/gateway_*.json
  • Modify: crates/proto/src/lib.rs, crates/proto/src/wire.rs, crates/brokerd/src/broker.rs, docs/implementer-log.md

The skeleton

Written: MAX_REASON (500), the four body types and GatewayOutcome with their serde attributes (they are the wire format: do not change them). To fill: is_mattermost_id and ApprovalReply::check, each with its steps above it.

The changes, exactly

crates/proto/src/lib.rs: pub mod gateway; after pub mod frame;, and this re-export, after the pub use frame::… line:

pub use gateway::{
    ApprovalOutcome, ApprovalPosted, ApprovalReply, ApprovalRequest, GatewayOutcome, MAX_REASON,
    is_mattermost_id,
};

crates/proto/src/wire.rs: four variants at the end of enum Message, after GrantsReport(GrantsReport),:

    ApprovalRequest(ApprovalRequest),
    ApprovalPosted(ApprovalPosted),
    ApprovalReply(ApprovalReply),
    ApprovalOutcome(ApprovalOutcome),

and at the top, use crate::gateway::{ApprovalOutcome, ApprovalPosted, ApprovalReply, ApprovalRequest};.

crates/brokerd/src/broker.rs: kind must name every message. Add these four arms after Message::GrantsReport(_) => "grants_report",, and change "all fourteen kinds" in its doc comment to "all eighteen kinds":

        Message::ApprovalRequest(_) => "approval_request",
        Message::ApprovalPosted(_) => "approval_posted",
        Message::ApprovalReply(_) => "approval_reply",
        Message::ApprovalOutcome(_) => "approval_outcome",

Steps

  • 1. Copy. git switch m4b, then cp docs/plans/M4b/files/crates/proto/src/gateway.rs crates/proto/src/ && cp docs/plans/M4b/files/crates/proto/tests/gateway_wire.rs crates/proto/tests/ && cp docs/plans/M4b/files/crates/proto/tests/fixtures/wire/gateway_*.json crates/proto/tests/fixtures/wire/.
  • 2. Make the three edits above. cargo build --workspace must succeed.
  • 3. See it fail. cargo test -p proto --test gateway_wire. Expected: 1 fails (an_answer_is_checked), 2 pass (the fixtures, since the types are given).
  • 4. Fill is_mattermost_id, then check. cargo check -p proto after each.
  • 5. See it pass. cargo test -p proto --test gateway_wire. Expected: 3 passed.
  • 6. Run the gate. cargo fmt --all, then make gate. Expected last line: gate: ok.
  • 7. Log and commit. git add crates/proto crates/brokerd docs/implementer-log.md Cargo.lock && git commit

Done when

  • cargo test -p proto --test gateway_wire passes; make gate prints gate: ok.

Stop and report if

  • A comment above a todo!() does not fit its function, or contradicts a test: quote it.