acpmux: a lane reports the end of each turn to the session that started it
A lane now tells the session that started it when each of its turns ends, the way a Claude subagent's parent hears when the subagent stops. The lane doesn't have to remember to acpmux send. The parent receives one short prompt per turn:
[NAME] lane report: turn N ended, STATE.
Session: ID
Last message: the first 400 characters of its last reply
Pull requests: URLs it opened or named, not reported before
Commits named: full SHAs in the reply
STATE is idle, working on its next prompt, waiting on a permission / waiting on a question: ..., or blocked: ... (a failed turn and the queue it paused, a stopped agent).
How it works (hub/lane_reports.rs, on the link from #25327):
- A report is built when the lane's turn ends, from that turn's own transcript records (paged back to its
turn_started) and the lane's state at that moment, and then queued. Delivery and retries send that queued report and never read the lane again, so a later turn can't leak into it. A turn that failed before its agent started reports no reply. - One delivery per lane is in flight at a time. If the parent refuses a report, it stays queued and goes at the next turn end. A newer turn's report replaces a queued one and keeps the pull requests only the older one named.
- A report identical to the last one (state, reply, pull requests) isn't sent again. Each lane sends at most 20 reports per 10 minutes; past that, the newest is held until a later turn ends with the lane back under the cap.
- A report goes in as a hub-set prompt with provenance
{kind: "lane_report", from, fromName, to, turn, state}, as another agent's message (digest.rs;prompt_line.rsshows the lane's name). It counts toward the runaway pair guard (agent_pairs.rs), and a report into a paused pair is held for the person. A report never steers: it waits for the parent's turn to end.
This is part 2 of 3 split from #24365 (Leo: keep PRs under ~800 lines). It comes after #25327, which added the link. Part 3 adds the rule that a parent's turn spent only on reports doesn't report upward. Until it lands, a coordinator that is itself a lane also reports its turns on its lanes' reports. Tree depth, the 20-per-10-minutes cap and the pair guard bound that.
Observed / Not run
Observed at 240a9b5ad7600fbba48f9d8ed8ae2932fed70171 on huge-blue:
cargo fmt -p acpmux --check: clean.cargo clippy -p acpmux --all-targets -- -D warnings: clean.cargo test -p acpmux --test lane_reports: 11 passed (each turn reported once, the same report not sent twice, a PR named once, pair-guard hold and resume, the tag doesn't steer the link, a turn whose agent can't start reports blocked with no reply, back-to-back turns and the 20-in-10-minutes cap, a closed parent gets nothing, plus #25327's link tests).cargo test -p acpmux --lib -- lane_reports: 5 passed (a held report's pull request still goes out, replacing a queued report, reading a 1,000-chunk reply from its turn's start, state wording, the closed-parent and mid-link-close cases).
Not run: the full acpmux lib and integration suites, and a live daemon with real harnesses.
Changelog
- acpmux: a lane reports the end of each of its turns (state, the start of its last reply, the pull requests and commits it names) to the session that started it.
š¤ Generated with Claude Code
Agent session: agent session
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.