Files
boxmaker/docs/plans/M4b/10-gatewayd-approval-text.md
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

2.9 KiB

M4b task 10: the text of an approval's posts

Branch: m4b (run git switch m4b; git status --short must be empty, otherwise stop) Commit subject: gatewayd: approvals::text, the posts that show an approval

Goal

What an approval looks like in Mattermost (M4b spec, section 6). Pure: text in, text out.

**Approval 42** · tool `shell` · grant `ops-shell` · taint private · expires 2026-09-24 14:47 UTC

{"command":"ls -la /srv/backups"}

Reply in this thread with `!approve 42` or `!deny 42 <reason>`.
  • The arguments are escaped with proto::escape::escape_json_text (task 01) and fenced with a run of backticks longer than any inside them, so nothing in them renders or mentions anyone.
  • Nothing is shortened. Arguments over 15,000 characters come in parts (at most 4), and only the last carries the reply line, with the count and the SHA-256 of the whole. More than that, or a part whose post would be over 15,500 characters, is one post saying it is too long to show, answerable only in bxctl.
  • When an approval ends, a line is added to its last post (Ended, ended_line, with_ending).

Files

  • Copy: crates/gatewayd/src/approvals/mod.rs from mod.rs-task10 (three lines: the module comment and pub mod text;), the skeleton crates/gatewayd/src/approvals/text.rs, and crates/gatewayd/tests/approvals_text.rs
  • Modify: crates/gatewayd/src/lib.rs (pub mod approvals; first, before pub mod config;), docs/implementer-log.md

The skeleton

Written: the constants, Shown, Ended, and render, which builds the posts from the helpers below (read it first). To fill, each with its code in its comment: code, fence, longest_run, minute, name, reply_line, ended_line, with_ending.

Steps

  • 1. Copy. git switch m4b, then mkdir -p crates/gatewayd/src/approvals && cp docs/plans/M4b/files/crates/gatewayd/src/approvals/mod.rs-task10 crates/gatewayd/src/approvals/mod.rs && cp docs/plans/M4b/files/crates/gatewayd/src/approvals/text.rs crates/gatewayd/src/approvals/ && cp docs/plans/M4b/files/crates/gatewayd/tests/approvals_text.rs crates/gatewayd/tests/. Add pub mod approvals; to lib.rs.
  • 2. See it fail. cargo test -p gatewayd --test approvals_text. Expected: it compiles and 6 tests fail.
  • 3. Fill the eight functions, longest_run first, cargo check -p gatewayd after each.
  • 4. See it pass. cargo test -p gatewayd --test approvals_text. Expected: 6 passed.
  • 5. Run the gate. cargo fmt --all, then make gate. Expected last line: gate: ok.
  • 6. Log and commit. git add crates/gatewayd docs/implementer-log.md Cargo.lock && git commit

Done when

  • cargo test -p gatewayd --test approvals_text 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.