# fix\(server\): let Claude steer interrupt a running Bash command · PR \#23892 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/pull/23892)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: closed

Source repository: pingdotgg/t3code

Source branch: fix/issue-15720

Target branch: main

Head commit: 9223781a8782ad19f504a78dadb03772196dbc7a

[Discussion and reviews](https://git.cafe/pingdotgg/t3code/pull/23892)

[Commits](https://git.cafe/pingdotgg/t3code/pull/23892/commits?format=markdown)

[Files changed](https://git.cafe/pingdotgg/t3code/pull/23892/diffs?format=markdown)

## Description

---

## Problem

Claude Steer waited behind a running foreground Bash command. In the web app, starting a gated curl command and sending a change of plan left the command running without a reply.

## Change

Interrupt the live Claude query before offering an explicit steer when a root Bash command is running and no question or approval is pending. Keep the query and tracked turn open, recheck ownership after the interrupt, and still offer the steer if the interrupt request fails or is unanswered for five seconds. Automatic deliveries retain their existing behavior.

## Scope and approval

Fixes https://github.com/pingdotgg/t3code/issues/15720

Triaged bug via the automated issue flow. This changes only the Claude server adapter and its regression fixtures; no client, contract, setting, or approval policy changes.

## Verification

- Base regression fails because no interrupt occurs; the fixed regression passes.
- Focused adapter, automatic-delivery, and steering-completion suites: 229 tests passed. Server typecheck passed. Scoped lint reports only the existing unused `layer` warning.
- Both isolated reviewers returned MERGE after the final review round; proof audit returned SUFFICIENT.
- Current main merged at [133b3edd4f](https://github.com/pingdotgg/t3code/commit/133b3edd4f116fd6fc57b6758ea8d5e8fe4001ff); the original three reviewed files were byte-identical to the runtime-tested head. The subsequent [9223781a87](https://github.com/pingdotgg/t3code/commit/9223781a8782ad19f504a78dadb03772196dbc7a) adds only the interrupt deadline and its TestClock regression; both fresh reviewers returned MERGE, and all 229 focused tests, scoped lint and server typecheck passed. The live transcript predates this deadline addition.

### Evidence

[Sanitized red/green and runtime transcript](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/e5aba791fea0d195/issue-15720-proof.md) · [Empty visual fixture matrix](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/a38574aa8fc4a264/issue-15720-pass1-proof-matrix.md)

| Before | After |
| --- | --- |
| Base [11adcb0e25](https://github.com/pingdotgg/t3code/commit/11adcb0e25a04785f70d01c3f2a858889683007e): foreground curl remained active and no steer reply arrived for over 70 seconds; a dev watcher restart ended the observation. | Head [1e0934a32d](https://github.com/pingdotgg/t3code/commit/1e0934a32d0fcc7eaee86855a0816926fd74b4fb): interrupt → aborted-tools result → reply 1.460 seconds after CLI receipt, one query, no close/reopen, one tracked completion. |

Linux web dev server with Claude Sonnet 5.5, SDK 0.3.276 and CLI 2.1.303. This is a server-only change with no changed render paths. Runtime commit attribution was recorded by the lead; native logs do not embed the app SHA. Base/final curl timeouts differed, while both commands remained gated at steering.

Pending-input preservation and completion-race fallback have deterministic supporting coverage. Combined post-steer question/approval answer resolution, native interrupt-error continuation, exact native completion-race composition, and parallel subagent coexistence were not exercised end to end.

Models: Claude Opus 5.5 (implementation), GPT-6.1 Sol and Claude Opus 5.5 (review); T3 Code with Codex and Claude harnesses.

