Skip to content

fix(coding-agent): preserve goals and dedupe stream notices - #733

Merged
code-yeongyu merged 18 commits into
mainfrom
fix/ttsr-goal-wait-widget-dedup
Aug 5, 2026
Merged

fix(coding-agent): preserve goals and dedupe stream notices#733
code-yeongyu merged 18 commits into
mainfrom
fix/ttsr-goal-wait-widget-dedup

Conversation

@code-yeongyu

@code-yeongyu code-yeongyu commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • classify extension aborts by owner so internal TTSR remediation never looks like a user interruption
  • keep active Goals resumable through system aborts, including no-monitor terminal errors
  • make Escape override in-flight system aborts before agent_settled, regardless of handler order
  • render TTSR activations and Goal cache-warm status through one durable TUI-owned record each

Root cause

ExtensionContext.abort() previously lost its initiator and always entered the user-abort path, so Goal persisted internal TTSR interruptions as blocked("user interrupted the turn").

The first provenance fix exposed adjacent lifecycle gaps:

  1. terminal system errors could leave an active Goal idle when no retry or monitor existed;
  2. Escape arriving after TTSR or extension agent_end handling could lose the race to a corrective follow-up;
  3. provider retry admission was computed before agent_end and was not revalidated after late user ownership;
  4. TTSR and Goal status appeared through both durable records and transient/private notices.

Changes

  • add optional "user" | "system" provenance to extension aborts and forward it through ExtensionRunner
  • mark all TTSR remediation aborts as system-owned
  • preserve system ownership across consecutive recovery generations
  • promote joined user aborts over system provenance without issuing a second underlying abort
  • keep the cancellation boundary open through extension and public agent_end delivery
  • emit one session_abort before agent_settled when a late user join must cancel work an earlier handler already admitted
  • retain the mutable abort boundary through agent_settled handler dispatch
  • defer settlement-triggered extension messages until every handler and public listener completes, dropping the whole batch on user cancellation
  • preserve user-owned steering/follow-up queues while suppressing TTSR corrective follow-ups, provider retry, recovery compaction, and automatic continuation after promotion
  • keep system-owned Goal aborts active instead of provider-blocked
  • schedule the monitor wait when a live monitor exists
  • stage a guarded Goal-owned systemRecovery continuation for a terminal system error with no retry or monitor, then launch it from the settled idle path
  • retain cap, repetition, pending-message, and single-flight guards on systemRecovery
  • release Goal's single-flight latch when a user abort cancels deferred settlement recovery, so /goal resume starts a fresh continuation
  • apply settlement guard outcomes to accounting and TUI state, preventing a persisted blocked Goal from still rendering Pursuing goal
  • persist one shared TTSR rule-activation entry and remove private/transient duplicates
  • keep Goal cache-warm scheduling/resume widget-owned and remove dead duplicate notices

Verification

  • npm run check — PASS
  • Goal/TTSR plus settlement/queue lifecycle matrix — 28 files / 310 tests PASS
  • third-review direct regressions — 54 tests PASS
  • npm run build — PASS
  • final root npm test — PASS

Third-review RED/GREEN coverage proves:

  • a handler blocked after TTSR no longer permits a corrective turn
  • a provider retry admitted before the late join is cancelled
  • Escape from the public post-extension agent_end boundary is delivered before settlement
  • re-entrant Escape still emits exactly one cancellation
  • a terminal system error without retry or monitor queues one hidden Goal continuation
  • both agent_settled handler orders cancel remediation
  • terminal system recovery launches after settlement instead of remaining stranded
  • a public-boundary user abort does not leak stale Goal recovery into the next user prompt
  • /goal resume works after canceled deferred recovery
  • settlement guard blocks immediately clear accounting and render Goal blocked

Real-surface QA

  • Goal-aware repetitive-turns mock loop: 8/8
    • final persisted Goal remains active
    • Goal exists before the TTSR system abort
    • recovery follows with monitor wait live
    • no hidden runtime or stale-context errors
  • TUI tmux smoke: 5/5, no leaked process, auth unchanged
  • RPC self-test: 4/4
  • CLI smoke: 8/8 including bad-input handling
  • prior xterm screenshot and dual visual review show one TTSR widget with no duplicate transient/plain notice

Evidence:

  • local-ignore/qa-evidence/20260805-abort-provenance/
  • local-ignore/qa-evidence/20260805-ttsr-widget-only/
  • local-ignore/qa-evidence/20260805-goal-widget-ownership/
  • local-ignore/qa-evidence/20260805-ttsr-goal-widget-regression/
  • local-ignore/qa-evidence/20260805-final-sweep/
  • local-ignore/qa-evidence/20260806-ttsr-goal-monitor/
  • local-ignore/qa-evidence/20260806-ttsr-goal-monitor-final/
  • local-ignore/qa-evidence/20260806-abort-provenance/
  • local-ignore/qa-evidence/20260806-ttsr-goal-settlement-final/
  • local-ignore/qa-evidence/20260806-ttsr-goal-latch-final/

Risk

The extension API addition is source-compatible because the provenance argument is optional and defaults to user semantics. Provider-originated terminal failures without system provenance still block Goal. Explicit user interruption remains a durable intentional block. Legacy TTSR private entries remain readable.

Let system-owned extensions abort without flowing through the user interrupt path. TTSR now preserves active goals and monitor-backed recovery while explicit user aborts still block.
Use the shared rule-activation entry as the only user-visible TTSR record, remove the transient warning, preserve the hidden model nudge, and retain read compatibility for legacy persisted entries.
Keep monitor-delayed Goal waits visible through their durable cache-warm entries and countdown status without repeating scheduled or resumed notices in the transcript area.
Use the stable activation custom type literal in the oversized race fixture so the behavior update adds no pure LOC to that file.
Assert durable cache-warm entries and the scheduling event across direct and RPC surfaces without expecting the removed transient notify request.
Delete the unused transient notice builders and their prose-only tests now that durable cache-warm entries own scheduled and resumed presentation.
@code-yeongyu
code-yeongyu merged commit 0cf61ee into main Aug 5, 2026
15 checks passed
@code-yeongyu
code-yeongyu deleted the fix/ttsr-goal-wait-widget-dedup branch August 5, 2026 17:51
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