Files
boxmaker/docs/plans/M5d2/01-loopd-session-slot.md
T
kyleandGrok 4.6 df987c3058 docs: M5d-2 checklist: given-test lifetimes and cron AND
session_slot and the scheduler tests held a temporary JSON Value across
statements (E0716). Cron now pins DOM and DOW as AND, which the given tests
had not. Gate counts from task 04 on move up by one.

Co-Authored-By: Grok 4.6 <noreply@x.ai>
2026-10-03 01:31:07 -07:00

126 lines
5.4 KiB
Markdown

# M5d-2 task 01: `run_turn` sends `session.slot()`
**Branch:** `m5d2`. Check it: `git branch --show-current` prints `m5d2` and `git status --short`
is empty; otherwise stop. Never switch branch.
**Commit subject:** `loopd: live turns use the session's slot`
**Log row:** the Task cell is `M5d2/01-loopd-session-slot`.
## Goal
Heartbeat and cron run on the background slot (spec 4). Live Mattermost and `bxctl chat`
sessions keep `cfg.slots.main`. Today `run_turn` always sends `slots.main`. This task makes it
send `session.slot()`: the slot stored on that session's `SessionStart` (M5d-1 task 02).
Nothing else changes. Compaction's summary call already uses `slots.background`. The scheduler
does not exist yet.
## Every place that changes
| Place | What happens there |
|---|---|
| `crates/loopd/src/turn.rs` | `ChatRequest.slot` is `session.slot()` (edit T1) |
| `crates/loopd/tests/session_slot.rs` | new, given |
| everything else | **no change**: not `session.rs`, not `compact.rs`, not channel |
## Files
- Copy, from `docs/plans/M5d2/files/` (the same path under it): the new test
`crates/loopd/tests/session_slot.rs`.
- Modify: `crates/loopd/src/turn.rs`, `docs/implementer-log.md`.
- Do not touch: any other file.
## Facts you need
- **`Session::slot()`** returns the `u32` stored on create / on the current epoch's
`SessionStart`. It is already `pub` (M5d-1 task 02).
- **`messages_with_carry`** stays as it is. Only the `slot:` line changes.
- **Existing turn tests** create sessions with `cfg.slots.main` (0). They still send 0.
- The items the edits use. This table is complete.
| Item | What it does |
|---|---|
| `Session::slot` | the live slot for this session |
| `ChatRequest.slot` | becomes `id_slot` on the wire |
## The edits, exactly
Each quoted "before" block occurs exactly once after M5d-1 task 08.
### `crates/loopd/src/turn.rs`
**T1.** The lines
```rust
let request = ChatRequest {
slot: rt.cfg.slots.main,
messages: messages_with_carry(baseline, session.records(), session.carry()),
tools: baseline.tools.clone(),
thinking: true,
};
```
become
```rust
let request = ChatRequest {
slot: session.slot(),
messages: messages_with_carry(baseline, session.records(), session.carry()),
tools: baseline.tools.clone(),
thinking: true,
};
```
## Steps
- [ ] **1. Copy the given test.** From the repository root, one command:
```sh
cp docs/plans/M5d2/files/crates/loopd/tests/session_slot.rs crates/loopd/tests/
```
Then `git status --short` lists one new file, `crates/loopd/tests/session_slot.rs`.
- [ ] **2. See it fail.** `cargo test -p loopd --test session_slot`, with a shell timeout of
600000 ms: the four tests compile (they call `session.slot()`, which exists) and three fail.
`a_session_created_on_the_background_slot_sends_that_slot` fails: `id_slot` is `0`, not `1`.
`a_main_slot_session_still_sends_main` passes. `the_request_slot_follows_session_start_not_the_config_main`
fails: `id_slot` is `0`, not `7`. `a_heartbeat_turn_between_two_main_turns_does_not_change_the_main_prefix`
fails: the heartbeat request's `id_slot` is `0`, not `1`.
- [ ] **3. The edit.** Make edit T1. `cargo check -p loopd` prints no error and no warning.
- [ ] **4. The tests.** `cargo test -p loopd --test session_slot --test turn --test channel
--test compact_turn`: every test passes, 4 in `session_slot` and the others as before.
- [ ] **5. Check.** `git diff --stat` lists exactly `crates/loopd/src/turn.rs`.
- [ ] **6. Run the gate.** `cargo fmt --all`, then `make gate`, with a shell timeout of 600000 ms.
Expected last line: `gate: ok`. The test count is **1512** after this task, 1508 before it,
and the 4 new ones are the tests of `session_slot.rs`. To count, add up the `N passed` of
every `test result:` line the gate's `cargo test --workspace` printed, and add 1. Never run
the gate again only to count.
- [ ] **7. Log and commit.** Add your row to `docs/implementer-log.md`; its Task cell is
`M5d2/01-loopd-session-slot`. Stage with
`git add crates/loopd docs/implementer-log.md Cargo.lock`, then commit as `AGENTS.md` says.
`Cargo.lock` does not change in this task; the `git add` is harmless.
## Done when
- `make gate` prints `gate: ok` with 1512 tests.
- `git diff HEAD~1 --stat` lists only `crates/loopd/src/turn.rs`,
`crates/loopd/tests/session_slot.rs` and `docs/implementer-log.md`.
## Stop and report if
- The branch check at the top fails.
- A "before" block is not in its file exactly as shown, or is there more than once.
- Step 2 shows a different result: the tests do not compile, or a different assertion fails.
- `cargo check` in step 3 prints an error or a warning. Quote it, and stop.
- A test fails in step 4. Do not change the test: stop, and give the failing tests' names and
their messages.
- The fix seems to need a change anywhere else. It does not; stop and say why you think so.
- A test outside `session_slot.rs` fails in the gate: check once whether it fails without your
change (`git stash -u`, run it, `git stash pop`), then stop and report both results.
- The gate passes with a count other than 1512.
## What the given tests pin
A session created with `cfg.slots.background` sends that slot; one created with `cfg.slots.main`
still sends main; a session created with slot `7` sends `7` even when `cfg.slots.main` is `0`; a
heartbeat turn between two main turns does not change the main session's message prefix.