fix(signal): pin idle-liveness turn-lifecycle parity (no wall-clock cap)#2624
Merged
Conversation
The Signal channel opens its agent session via `open_signal_agent_session`, which builds a `SessionBuilder` in `OperatingMode::Meeting`. Meeting mode is the seam that routes turns through `PersistentAgentProxy`, whose lifecycle reaps the agent child only on *idle-liveness* (no output for a generous window; every streamed chunk resets the clock) and never on a wall-clock elapsed-time cap. So on `main`, Signal already inherits the same no-wall-clock-timeout turn lifecycle the meeting REPL and dashboard chat use, and PR #2608's hours-scale idle default (`SIMARD_MEETING_IDLE_LIVENESS_SECS`, 3600s) governs it. Nothing locked that wiring, though: a future refactor of the signal agent session onto a non-Meeting mode would silently drop it back onto the per-turn adapter and reintroduce the wall-clock turn timeout that issue #2607 forbids, breaking the cross-transport parity issue #2604 requires — with no test to catch it. This extracts the mode decision into a documented `signal_agent_mode()` and adds a hermetic regression test (`signal_opens_agent_in_meeting_mode_for_idle_liveness_parity`) that pins it to `OperatingMode::Meeting`, closing the missing "Signal parity + tests" acceptance criterion of #2604/#2607. Tests: - `cargo test --release --lib signal_conversation::` — 89 passed (incl. new test) - `cargo clippy --release --no-deps -- -D warnings` — clean - `cargo fmt --all -- --check` — clean Refs #2607, #2604. Follow-up to #2608, #2581, #2612. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
📊 Coverage Summary
Coverage data from CI run. Test files matching |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Locks the Signal channel to the idle-liveness turn lifecycle (no wall-clock per-turn timeout), completing the cross-transport parity tracked by #2604 / #2607 and finishing the work PR #2608 started for the meeting surface.
Why
The idle-liveness / no-wall-clock-timeout turn-lifecycle fix had to span dashboard, meeting, AND signal (#2604). Meeting got the hours-scale idle default in #2608; dashboard and signal route through the same
MeetingBackend→PersistentAgentProxypath.On
main, Signal already inherits idle-liveness:open_signal_agent_session()builds itsSessionBuilderinOperatingMode::Meeting, and Meeting mode is the seam that routes turns throughPersistentAgentProxy— which reaps the agent child only on idle-liveness (no output for a generous window; every streamed chunk resets the clock) and never on a wall-clock elapsed-time cap.SIMARD_MEETING_IDLE_LIVENESS_SECS(default 3600s, per #2608) governs it,0= unbounded.The gap #2604/#2607 leaves open is that nothing locked that wiring. A future refactor of the signal agent session onto a non-Meeting mode would silently drop it back onto the per-turn adapter and reintroduce the wall-clock turn timeout #2607 forbids — with no test to catch the regression.
Scope
src/signal_conversation/channel.rs— extract the mode decision into a documentedsignal_agent_mode()returningOperatingMode::Meeting, with rationale citing Chat-management turn-lifecycle fix (idle-liveness + streaming) must span dashboard, meeting, AND signal — capture in proper worktrees/PRs #2604/No wall-clock timeouts on agent turns/subprocesses — reap on idle-liveness only (audit + signal parity) #2607; call it fromopen_signal_agent_session.src/signal_conversation/tests.rs— hermetic regression testsignal_opens_agent_in_meeting_mode_for_idle_liveness_paritypinning the mode. If someone flips signal off Meeting mode, this fails loudly and points back to the parity requirement.No behavioral change: signal turn handling already runs through the idle-liveness proxy today. This makes the guarantee explicit and regression-proof — the missing "Signal parity + test" acceptance criterion of #2604/#2607.
Tests
cargo test --release --lib signal_conversation::— 89 passed (incl. the new test)cargo clippy --release --no-deps -- -D warnings— cleancargo clippy --all-targets --all-features --locked -- -D warnings(pre-push) — cleancargo fmt --all -- --check— cleanRefs #2607, #2604. Follow-up to #2608, #2581, #2612.
Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com