Skip to content

fix(chat): validate continuation events before delivering after compact - #1051

Merged
TheGreatAxios merged 2 commits into
cl-7917-chat-director-replace-requestcontinuation-with-a-reactorfrom
cl-7976-validate-continuation-events-before-delivering-billable
Sep 15, 2026
Merged

TheGreatAxios merged 2 commits into
cl-7917-chat-director-replace-requestcontinuation-with-a-reactorfrom
cl-7976-validate-continuation-events-before-delivering-billable

Conversation

@TheGreatAxios

Copy link
Copy Markdown
Collaborator

Summary

Stream sinks answered any custom.compaction.continue event with an unconditional deliver, so a forged or duplicated continuation cost one billable model turn per event on a fresh director (and reset loop-protection budgets). Hosts now answer each continuation emission at most once via a seq-keyed consume-once gate, and the director answers an unsolicited empty continuation with wait instead of infer.

Verification

  • New director tests: fresh-director-empty-continuation holds without infer; duplicate continuation infers at most once (both fail without the guard, pass with it).
  • New gate unit tests: replayed seq ignored, distinct seq delivered, gates are per-host.
  • Targeted suites: 63 pass, 0 fail across tests/unit/director.test.ts, src/session/runtime-assembly.test.ts, src/agent/compaction.test.ts.
  • Full gate: bun run check exit 0 (lint, typecheck, build, guard; suite 7393 pass, 0 fail).

Fixes CL-7976

Hosts answer each compaction continuation emit at most once via a seq-keyed consume-once gate, and the director holds unsolicited empty continuations with wait instead of inferring, so forged or replayed events cannot burn billable model turns.
@linear-code

linear-code Bot commented Sep 14, 2026

Copy link
Copy Markdown

CL-7976

…1060)

Summary: update the architecture doc to the emit-and-deliver continuation mechanism; collapse idle-turn arming into a single-delivery contract (closure fires and the flag stays false, or no closure and the flag reports the arming) with a guard test; extract the session deliver generation re-check into runGenerationGuardedDeliver with race-pinning tests. Emit shape, guards, and gates unchanged.

Verification: bun test src/tui/deliver-agent-message.test.ts src/agent/compaction.test.ts (38 pass); bun run check (7396 pass, 0 fail).
@TheGreatAxios
TheGreatAxios merged commit 30c886f into cl-7917-chat-director-replace-requestcontinuation-with-a-reactor Sep 15, 2026
13 checks passed
TheGreatAxios added a commit that referenced this pull request Sep 15, 2026
)

* feat(chat): express compaction continuation as a reactor emit action

Removes requestContinuation from ChatDirectorOptions. The compaction governor now appends a custom.compaction.continue emit action wherever it previously invoked the closure, and the TUI and exec hosts answer that event by delivering the compaction continuation message.

* fix(chat): validate continuation events before delivering after compact (#1051)

* fix(chat): validate continuation events before delivering after compact

Hosts answer each compaction continuation emit at most once via a seq-keyed consume-once gate, and the director holds unsolicited empty continuations with wait instead of inferring, so forged or replayed events cannot burn billable model turns.

* fix(chat): pin continuation polish leftovers from emit-and-deliver (#1060)

Summary: update the architecture doc to the emit-and-deliver continuation mechanism; collapse idle-turn arming into a single-delivery contract (closure fires and the flag stays false, or no closure and the flag reports the arming) with a guard test; extract the session deliver generation re-check into runGenerationGuardedDeliver with race-pinning tests. Emit shape, guards, and gates unchanged.

Verification: bun test src/tui/deliver-agent-message.test.ts src/agent/compaction.test.ts (38 pass); bun run check (7396 pass, 0 fail).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant