bxctl: chat --speaker NAME, the speaker on every turn of the chat
Co-Authored-By: ornith-1.5-35b-a3b <agent@wntrmute.dev>
This commit is contained in:
@@ -6,6 +6,7 @@ reviewer adds findings under "Reviews" once per milestone.
|
||||
|
||||
| Task | Date | Status | Gate runs | First gate | Deviations | Notes | Model |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| M5c1/04-bxctl-speaker | 2026-09-28 | done | 1 | pass | none | Copied four files from `docs/plans/M5c1/files/`: `chat_speaker.rs` (new) and new versions of `chat.rs`, `chat_approvals.rs` and `cli.rs` (did not copy `chat.rs-task01`). Step 2 showed exactly the named failures: four non-compiling test targets (`chat`, `chat_approvals`, `chat_speaker`, `cli`) with E0061 for `run_turn` (5 args) and `stream_turn` (6 args), E0282 on the closure in `chat.rs`, and E0560/E0609 for the missing `speaker` field. Made the edits exactly as the task gives: C1 the `--speaker NAME` flag added to the chat line of `USAGE` with one explaining line (six-space indent); C2 `ChatOptions` gains `speaker: Option<String>`; C3 `default` sets `speaker: None`; C4 the `--speaker` arm in `parse_chat` refuses a second one and falls through to `i += 2`; C5 `parse_speaker` (empty, or any whitespace/control char -> `UsageError`, else the value as typed). R1 `run_turn` gains `speaker: Option<&str>` after `resume` with the doc comment, R2 `speaker.map(str::to_string)` on the `Turn`, R3 `stream_turn` gains the parameter and passes it. M1-M3 all three `stream_turn` calls in `main.rs` pass `opts.speaker.as_deref()`. `main` unchanged (a `UsageError` already prints the usage text and exits 2). After the edits `cargo check -p bxctl` is clean with no warning; `cli` 15 passed, `chat_speaker` 7 passed, every bxctl suite passes. Step 7: `grep -rn 'speaker: None' crates/bxctl/src` prints one line (the default), `git diff --stat -- crates/bxctl/src` lists exactly chat.rs/cli.rs/main.rs, the other-crates diff is empty. `make gate` printed `gate: ok` with 1158 tests (1148 before plus the 10 new: three in `cli.rs`, seven in `chat_speaker.rs`; `chat.rs` and `chat_approvals.rs` kept their counts). No new dependency, so `Cargo.lock` is unchanged. | ornith-1.5-35b-a3b |
|
||||
| M5c1/03-gatewayd-speaker | 2026-09-28 | done | 2 | pass | none | Copied the seven given files from `docs/plans/M5c1/files/`: `deliver_speaker.rs` and `serve_speaker.rs` (new) and new versions of `sessions.rs`, `deliver.rs`, `deliver_links.rs`, `deliver_notice.rs` and `support/fake_mm.rs` (it gains `refuse_users`). Step 2 showed exactly the named failures: `deliver`, `deliver_links`, `deliver_notice`, `deliver_speaker` and `sessions` did not compile (E0560 for `Batch.senders` / `Message.user`, E0061 for `deliver` taking 5 args, E0282 on the closure), and `serve_speaker` compiled with its four tests failing (three found `None` where a speaker was expected, the fourth had no `"no username for"` log line). Made the edits exactly as the task gives: S1 `Message` gains `user` (the post's `user_id`); S2/S3 set `user` on both `Route::Queue` paths; S4 `Batch` gains `senders` plus `Batch::sender` (`first()?` then `all(|u| u == first)`, `None` for two or more people or for none); S5 `Pending` gains `senders`; S6 `push` pushes `message.user` to `pending.senders` on the `Waiting` path; S7 the `Start` path is `senders: vec![message.user.clone()]` with the new `Pending`'s `senders: Vec::new()`; S8 `finish` takes `senders` with `std::mem::take`. D1 `one_turn` gains `speaker: Option<&str>`; D2 `speaker.map(str::to_string)` on the `Turn` (its comment rewritten); D3 `run_turn` gains `speaker` threaded through both `one_turn` calls; D4 `deliver` gains `speaker`; D5 `deliver` passes `speaker` to `run_turn`. G1 `Gateway` gains `usernames: HashMap<String,String>`; G2 `new()` inits it. H1 `start` computes `speaker = self.speaker(&batch)` and passes `speaker.as_deref()` to `deliver`. H2 added `Gateway::speaker` (`batch.sender()?`; a cache hit returns it; else `client.username`, `Ok` inserts and returns, `Err` logs `"gatewayd: no username for {user}: {e}; the turn has no speaker"` and returns `None`). `approvals.rs` and `mm/rest.rs` untouched, the text still joins as before and the speaker never enters it. `cargo check -p gatewayd` clean after sessions; after deliver it fails only in `serve/handle.rs` at the `deliver` call (E0061/E0277) as the task predicts, then clean after serve. `sessions` 11 passed, `deliver_speaker` 3, `serve_speaker` 4, every gatewayd suite passes. Step 7: the grep for `speaker: None` prints nothing, `git diff --stat -- crates/gatewayd/src` lists exactly `deliver.rs`, `serve/handle.rs`, `serve/mod.rs`, `sessions.rs`, the other-crates diff is empty. `make gate` printed `gate: ok` with 1148 tests (1137 in `cargo test --workspace`, plus the 1 ignored `end_to_end` the gate runs separately with `BOXMAKER_BROKERD`; 1138 before this task plus the 10 new: 3 in `sessions.rs`, 3 in `deliver_speaker.rs`, 4 in `serve_speaker.rs`). No new dependency, so `Cargo.lock` is unchanged. | ornith-1.5-35b-a3b |
|
||||
| M5c1/02-loopd-speaker-turn | 2026-09-28 | done | 2 | pass | none | Copied five files from `docs/plans/M5c1/files/`: `speaker_turn.rs` (new) and new versions of `memory.rs`, `turn_broker.rs`, `end_to_end.rs` and `support/turn.rs` (skipped the older `memory.rs-task01`). Step 2 showed exactly the named failures: eight non-compiling test targets (end_to_end, limits, memory, neutralise, neutralise_replay, speaker_turn, turn, turn_broker) with E0061 for `run_turn` and `updated`, E0282 on the closure, E0050 and E0599 for `turns`. Made the edits exactly as the task gives: S1 `Session::turns` counting `User` records in `records` via `matches!` and `u64::try_from(...).unwrap_or(u64::MAX)`, placed before `last_usage`; M1 the trait `updated` gains `turn: u64`, M2 `NoMemory` and M3 `MemoryPort` pass it (the `turn: 0` placeholder and its comment dropped for `turn`); T1 `run_turn` gains `speaker: Option<&str>` after `content` with the doc comment, T2 logs `speaker: speaker.map(str::to_string)` (as it came, not checked, not neutralised, `None` not written); C1 passes `turn.speaker.as_deref()` to `run_turn`, C2 passes `session.turns()` to `updated` (the comment now says the number is this turn's, a failed turn not told but its logged message still counts). `baseline::messages` untouched, the request is the same with and without a speaker. Step 7 all pass: the grep for `turn: 0`/`speaker: None` prints nothing, `git diff --stat -- crates/loopd/src` lists exactly channel.rs/memory.rs/session.rs/turn.rs (baseline.rs absent), the other-crates diff is empty. After the edits `cargo check -p loopd` is clean, `speaker_turn` 8 passed, every loopd suite passes. `make gate` printed `gate: ok` with 1138 tests (1130 before plus the 8 of `speaker_turn.rs`). No new dependency, so `Cargo.lock` is unchanged. | ornith-1.5-35b-a3b |
|
||||
| M5c1/01-wire-speaker-state | 2026-09-28 | done | 1 | pass | none | Changed the types in `bxcore` only, as the task says: `Turn` and `LogRecord::User` gain `speaker: Option<String>` (optional, `serde(default, skip_serializing_if = "Option::is_none")`, so a frame or log line without it reads `None` and `None` is not written); `SessionUpdated` gains `turn: u64` (required, no default), plus the two new messages `SessionState { session }` and `SessionStateReply { class, untrusted }` (both fields required). Copied the 20 given files from `docs/plans/M5c1/files/` (4 new fixtures, 16 replaced test files, the loopd `memory.rs` and bxctl `chat.rs` being the `-task01` versions). Step 2 showed exactly the named failures: `strict` `envelopes_reject_unknown_keys_at_every_depth` on `turn_speaker.json` and `speaker_log_records_reject_unknown_keys_at_every_depth` on `session_speaker.jsonl:2`, and 15 non-compiling test targets with E0559/E0560/E0432/E0599. Made every edit exactly as the task gives (W1-W3, L1, M1, X1 in bxcore; B1-B2 in brokerd; G1, C1, T1, U1, I1 in gatewayd, bxctl, loopd twice, memoryd), the placeholders `speaker: None` / `turn: 0` left in place. After the edits `cargo test -p bxcore` every suite passes (turn_wire 9, memory_wire 5, records 4, strict 6) and `cargo test -p brokerd -p gatewayd -p bxctl -p loopd -p memoryd` every suite passes. Step 5 checks all pass: `grep -c 'serde(default' crates/bxcore/src/wire.rs` prints 2, `git diff --stat -- crates/gatewayd/tests crates/inferproxy crates/toolkit` prints nothing, `git diff --stat -- crates/*/src` lists exactly the ten source files. `make gate` printed `gate: ok` with 1130 tests (1129 in `cargo test --workspace`, plus the 1 ignored `end_to_end` the gate runs separately with `BOXMAKER_BROKERD` set; the first gate run's `end_to_end` was the only flake and it passes once the env var is set). No new dependency, so `Cargo.lock` is unchanged. | ornith-1.5-35b-a3b |
|
||||
|
||||
Reference in New Issue
Block a user