Skip to content

fix(bash-timeout): native Anthropic bash exception + mutation-proof the detach gate - #426

Merged
code-yeongyu merged 2 commits into
mainfrom
fix/detach-gate-mutation-coverage
Jul 28, 2026
Merged

fix(bash-timeout): native Anthropic bash exception + mutation-proof the detach gate#426
code-yeongyu merged 2 commits into
mainfrom
fix/detach-gate-mutation-coverage

Conversation

@code-yeongyu

@code-yeongyu code-yeongyu commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Summary

Follow-up to #422, fixing two real defects that post-merge review found. Both were confirmed against merged main before changing anything.

1. Native Anthropic bash advertised a ceiling it could not honor

When PI_ANTHROPIC_BASH is enabled for an anthropic-messages model, the provider replaces the PTY bash tool and the terminal extension steps aside (shouldStepAside). Nothing then implements the cache-deadline auto-detach — but bash-timeout still capped the recommended maximum and told the model a still-running command would be handed to a background session. That promised behavior that could not happen.

The budget is now suppressed on that path, restoring the byte-identical legacy policy. Failing test captured first, then fixed.

Also addressed from the same review:

  • the cache-aware prompt now steers cleanup through kill_bash (detached sessions stay live, so the model needs to be told to reap them)
  • docs/settings.md documents promptCache.cacheAwareTimeouts and promptCache.safetyBufferSeconds
  • builtin/bash-timeout/changes.md added, recording the fork surface and why the exception exists

2. The detach linearization gate had tautological coverage

#422's auto-detach suite had 9 green tests but could not fail for the property it protected: deleting both the queueMicrotask deferral and the settled-aware onExit gate from foreground-detach.ts left all 9 passing.

Root cause: those tests register the exit/abort timers during spawn — before the detach timer exists — so they only exercise "exit was already ordered ahead of D", never the real window between the deadline firing and the queued linearization microtask committing.

test/suite/terminal-detach-gate.test.ts drives createForegroundDetachGate directly with fake timers, so the deadline can fire without yielding the microtask queue:

  • exit inside the linearization window → no detach, abort listener untouched
  • exit already settled before the deadline → no detach
  • abort inside the linearization window → no detach
  • still running → detaches exactly once, abort listener removed exactly once
  • onExit dispatching synchronously at registration → exit stays authoritative (covers exitedAtGate)
  • cancel() → suppresses a pending detach

Mutation proof

Mutation Result
remove queueMicrotask(linearize) deferral 2 tests fail
remove the settled-aware onExit gate 1 test fails
unmodified 6/6 pass

The gate itself was correct — it was simply unprotected.

Verification

npm run check exit 0. Focused suites 65/65 (bash-timeout-extension, bash-timeout-handlers, terminal-detach-gate, terminal-bash-auto-detach, prompt-surface-stale-wait-idioms, prompt-cache-budget).

@code-yeongyu code-yeongyu changed the title test(terminal): mutation-proof the foreground detach linearization gate fix(bash-timeout): native Anthropic bash exception + mutation-proof the detach gate Jul 28, 2026
@code-yeongyu
code-yeongyu enabled auto-merge July 28, 2026 09:02
@code-yeongyu
code-yeongyu merged commit a2c36bb into main Jul 28, 2026
9 checks passed
@code-yeongyu
code-yeongyu deleted the fix/detach-gate-mutation-coverage branch July 28, 2026 09:14
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