fix(#60): pre-aborted signal short-circuits before run; guard onProgress relay

Review findings (Medium+Low): a signal already aborted before runEditTurn is
called could not be honored by agent.abort() (the SDK AbortController isn't
created until run()), so the turn ran to completion — now it throws before
run() (INV-47). And a throwing onProgress relay is swallowed so observability
can never fail the turn (INV-44). Strengthened the unit + E2E to prove both.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BenStullsBets
2026-06-26 04:49:02 -07:00
parent 21bbf6b114
commit a3ea6c65ca
3 changed files with 30 additions and 17 deletions
+4 -3
View File
@@ -60,11 +60,12 @@ suite("#60 live turn progress (additive + cancel)", () => {
await vscode.commands.executeCommand("cowriting.showTrackChangesPreview");
await settle();
// Simulate the SDK honoring the abort signal: throw as runEditTurn does on a
// non-"completed" (aborted) status.
// The stub throws ONLY when the aborted signal reached it — so if opts.signal
// failed to thread through runEditAndPropose, the stub would instead return a
// rewrite and create a proposal, failing this test. That proves propagation.
ctl.setEditTurnForTest(async (_i, _text, opts) => {
if (opts?.signal?.aborted) throw new Error("claude-code turn aborted");
throw new Error("claude-code turn aborted");
return { replacement: "# Title\n\nSHOULD NOT BE PROPOSED.\n", model: "sonnet", sessionId: "e2e-live60-nope" };
});
const ac = new AbortController();