From 71929ed37cdc560b6b8aa62b5f7182e417c8a850 Mon Sep 17 00:00:00 2001
From: morluto <76467478+morluto@users.noreply.github.com>
Date: Sat, 17 Oct 2026 09:24:43 +0800
Subject: [PATCH] fix(cutter): normalize command checkpoint cancellation
Produce typed cancellation at each command checkpoint while retaining the exact opaque reason as cause. Preserve independent typed physical failures without downstream equality guesses.
Validated 72 focused tests across nine files, static checks, docs and five conformance controls, including real client/service admission races and matching physical-error controls. No native Cutter engine or new public-transport reproduction claimed.
Refs: #4635
---
docs/reverse-engineering-tools.md | 3 +
src/cutter/CutterBridgeClient.ts | 13 ++-
.../providers/CutterBridgeClient.test.ts | 6 +-
.../CutterCommandCancellation.test.ts | 79 +++++++++++++++++++
4 files changed, 97 insertions(+), 4 deletions(-)
create mode 100644 tests/boundary/providers/CutterCommandCancellation.test.ts
diff --git a/docs/reverse-engineering-tools.md b/docs/reverse-engineering-tools.md
index bb5df5ef30..e224100a79 100644
--- a/docs/reverse-engineering-tools.md
+++ b/docs/reverse-engineering-tools.md
@@ -76,6 +76,9 @@ probe retries the original command. Failed acknowledgements remain pending and
block new commands until they can be retried successfully. Status proof failures
identify `cutter_command` and retain `status` in
`details.diagnostics.auxiliary_operation`; malformed proof still blocks dispatch.
+Descriptor failures likewise retain the requesting operation through cleanup.
+Command admission reports typed cancellation and treats the caller's abort reason
+as opaque metadata, without inferring cleanup ownership from it.
## Configuration and coverage
diff --git a/src/cutter/CutterBridgeClient.ts b/src/cutter/CutterBridgeClient.ts
index 3de1be6db1..9e76f3c509 100644
--- a/src/cutter/CutterBridgeClient.ts
+++ b/src/cutter/CutterBridgeClient.ts
@@ -176,6 +176,13 @@ class CutterBridgeResponseFrames {
}
}
+const assertCommandActive = (signal: AbortSignal | undefined): void => {
+ if (signal?.aborted)
+ throw new AnalysisCancelledError("cutter_command", {
+ cause: signal.reason,
+ });
+};
+
const mapDiscovery = async (
inputs: readonly Input[],
operation: (input: Input) => Promise