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>
This commit is contained in:
2026-09-24 03:34:21 -07:00
co-authored by Claude Opus 5.5
parent b1f732a42a
commit 2d415fc1be
64 changed files with 7701 additions and 2 deletions
@@ -0,0 +1,3 @@
//! The text-escape helpers, from `proto` (moved there in M4b so `gatewayd` shows the same thing).
pub use proto::escape::{escape_json_text, escape_model_text};
@@ -0,0 +1,42 @@
//! `bxctl deny` is another name for `bxctl refuse`: every argument list means the same under both
//! (M4b spec, section 2). Do not edit.
use bxctl::cli::{USAGE, parse};
use std::path::Path;
fn under(command: &str, rest: &[&str]) -> Vec<String> {
std::iter::once(command)
.chain(rest.iter().copied())
.map(str::to_string)
.collect()
}
#[test]
fn deny_parses_as_refuse() {
let cases: &[&[&str]] = &[
&["41"],
&["41", "--reason", "not on a Friday"],
&["--reason", "no", "41"],
&["41", "--admin-socket", "/tmp/a.sock"],
&["41", "--reason", "x", "--admin-socket", "/tmp/a.sock"],
&[],
&["x41"],
&["41", "--reason"],
&["41", "42"],
&["41", "--bogus"],
];
for rest in cases {
let home = Path::new("/srv/bx");
assert_eq!(
parse(&under("deny", rest), home),
parse(&under("refuse", rest), home),
"{rest:?}"
);
}
}
#[test]
fn usage_names_deny() {
assert!(USAGE.contains("bxctl deny <id>"), "{USAGE}");
assert!(USAGE.contains("bxctl refuse <id>"), "{USAGE}");
}