Plan M4a: gatewayd in 15 tasks, with skeletons and given tests
Each task's tests were run against a reference at its end state; the end states were replayed from master in order with the gate at each step (650 to 762 tests); each skeleton compiles against its tests and fails them. The reference is kept off this machine. Lessons T27 (every wait in a test has a limit) and T28 (mutate the reference before hand-over) come from this work. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
# M4a task 13: a turn on `loop.sock`, and its answer in the thread
|
||||
|
||||
**Branch:** `m4a` (run `git switch m4a`; `git status --short` must be empty, otherwise stop)
|
||||
**Commit subject:** `gatewayd: deliver, turns on loop.sock and answers posted in their thread`
|
||||
|
||||
## Goal
|
||||
|
||||
A batch of messages (task 11) becomes one `turn` on `loopd`'s socket, exactly as `bxctl chat` sends
|
||||
one (read `crates/bxctl/src/chat.rs`, `run_turn`): one frame `{"kind": "turn", "body": {"session",
|
||||
"content", "resume"}}` with id 1, then events until a final `turn_done` or `error`. What comes back
|
||||
is posted in the thread (spec section 8):
|
||||
|
||||
- No thinking and no status reach Mattermost. The one event that is shown: `approval_pending`,
|
||||
posted once as `waiting for approval <id>: approve or deny it with `bxctl` (Mattermost approvals
|
||||
arrive in M4b)` (the skeleton's `approval_text`).
|
||||
- `turn_done` → its content, split into posts of at most 16,000 **characters** (a Mattermost post
|
||||
holds 16,383), at the last newline before the limit, or at the limit when there is none, in
|
||||
order. An empty answer is posted as `(the answer was empty)`: Mattermost refuses an empty post.
|
||||
- An `error` frame → `Error: <code>: <detail>`, where the code is the snake_case name
|
||||
(`no_such_session`), and the detail carries `loopd`'s runbook pointer when it has one.
|
||||
- `loop.sock` cannot be reached, or closes early, or sends a frame that does not belong →
|
||||
`LOOP_DOWN`, and the messages are not sent again: `loopd` may have run them.
|
||||
- A reply in a thread `loopd` does not know (`no_such_session` with `resume: true`) is sent once
|
||||
more with `resume: false`, creating the session, as `bxctl chat --session` does. Only then.
|
||||
|
||||
## Files
|
||||
|
||||
- Copy: `crates/gatewayd/tests/deliver.rs`, `crates/gatewayd/tests/support/fake_loop.rs`, and the
|
||||
skeleton `crates/gatewayd/src/deliver.rs`
|
||||
- Modify: `crates/gatewayd/src/lib.rs` (`pub mod deliver;`), `docs/implementer-log.md`
|
||||
|
||||
## The skeleton
|
||||
|
||||
Written: `MAX_POST` (16,000), `LOOP_DOWN`, `EMPTY_ANSWER`, the trait `Poster` (somewhere to post:
|
||||
Mattermost's `Client`, or a test's record) and its `impl` for `Client`, `Outcome` (`Answer`,
|
||||
`Refused`, `LoopDown(why)`), `approval_text`.
|
||||
|
||||
To fill: `error_text`, `split_answer`, `one_turn`, `run_turn`, `deliver`. `split_answer` counts
|
||||
**characters**, not bytes, and never cuts inside one: find the byte index of the 16,000th character
|
||||
with `char_indices().nth(MAX_POST)`.
|
||||
|
||||
## Steps
|
||||
|
||||
- [ ] **1. Copy.** `git switch m4a`, then
|
||||
`cp docs/plans/M4a/files/crates/gatewayd/tests/deliver.rs crates/gatewayd/tests/ && cp docs/plans/M4a/files/crates/gatewayd/tests/support/fake_loop.rs crates/gatewayd/tests/support/ && cp docs/plans/M4a/files/crates/gatewayd/src/deliver.rs crates/gatewayd/src/`.
|
||||
Add `pub mod deliver;` to `lib.rs`.
|
||||
- [ ] **2. See it fail.** `cargo test -p gatewayd --test deliver`. Expected: it compiles and 9
|
||||
tests fail.
|
||||
- [ ] **3. Fill `error_text`, `split_answer`, `one_turn`, `run_turn`, `deliver`**,
|
||||
`cargo check -p gatewayd` after each.
|
||||
- [ ] **4. See it pass.** `cargo test -p gatewayd --test deliver`. Expected: 9 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 deliver` passes; `make gate` prints `gate: ok`.
|
||||
|
||||
## Stop and report if
|
||||
|
||||
- A test seems to need a turn sent twice in any case other than the one above.
|
||||
Reference in New Issue
Block a user