@@ -1015,13 +1015,13 @@ is named in spec for closure):
10151015- ** Config.** ` BITCODE_DEPOSIT_SYNTHESIS_PIPELINE ` removed (full SDIVF pipeline only;
10161016 Validation — measurement + quality — never skipped).
10171017
1018- ### Gate-3 #25 — SandboxHost in-box deposit dispatch (Garrett, 2026-06-27)
1018+ ### Gate-3 #25 — SandboxHost in-box deposit dispatch (Garrett, 2026-06-27; cancel+auth hardened 2026-07-08 )
10191019
10201020SandboxHost deposit runs the synthesis pipeline INSIDE the box (the asset-pack
10211021harness already runs ` assetPackPipeline ` in-box for read-fit via a runner that imports
10221022the live packages and executes the full SDIVF). Deposit reuses that mechanism:
10231023
1024- - ** Harness deposit mode.** ` buildAssetPackSandboxHarness ` accepts ` synthesisMode `
1024+ - ** Harness deposit mode.** ` buildAssetPackSandboxHarness ` accepts ` synthesizeMode `
10251025 (` 'deposit' | 'read' ` ) + the deposit STEERING (obfuscations, protected-IP exclusions,
10261026 demand context); these flow into ` PipelineHarnessManifest ` and the in-box runner
10271027 INPUT (` synthesizeMode ` , steering). The in-box pipeline resolves deposit mode
@@ -1031,19 +1031,66 @@ the live packages and executes the full SDIVF). Deposit reuses that mechanism:
10311031 surfaces the synthesized ` implementation:options ` in ` evidence.json ` as
10321032 ` depositOptions ` (source-safe option metadata; the measure-agent's absolutes are
10331033 already attached by the Validation phase IN the box).
1034- - ** Route dispatch.** When the configured HostKind is ` sandbox ` , the deposit route
1035- dispatches the deposit harness (a git ` source ` for the revision) via
1036- ` VercelSandboxPipelineHost.runHarness ` (provider Vercel) instead of the in-process
1037- InlineHost path; it reads ` evidence.depositOptions ` , runs the SAME pure projection
1038- (` validateDepositSynthesisOptions ` + ` buildRealDepositAssetPackOptionSynthesis ` ) and
1039- persists the deposit option synthesis to the execution row — identical to the inline
1040- path. Source-safe telemetry streams from the harness telemetry artifact to
1041- ` execution_events ` .
1042- - ** Parity of result.** InlineHost (in current box) and SandboxHost (in the provisioned
1043- box) produce the SAME deposit option synthesis; only WHERE the pipeline runs differs.
1044- Real-sandbox execution is verified against deployed sandbox infra (` @vercel/sandbox ` ,
1045- ` VERCEL_* ` , git in the box image); the harness plan-building + the route dispatch +
1046- the option projection are unit-tested with a mocked host.
1034+ - ** Ephemeral boxes.** Deposit one-shots create sandboxes with ` persistent: false `
1035+ (no snapshot storage on stop). Auth: prefer ` VERCEL_OIDC_TOKEN ` (local: `vercel env
1036+ pull` ; automatic on Vercel); fallback ` VERCEL_TOKEN` + ` VERCEL_TEAM_ID` +
1037+ ` VERCEL_PROJECT_ID ` . ` assertVercelSandboxAuthAvailable ` fails closed before create.
1038+ - ** Route dispatch.** When ` BITCODE_PIPELINE_HOST=sandbox ` , the deposit route
1039+ dispatches via ` runDepositInBoxHarness ` → ` VercelSandboxPipelineHost.runHarness `
1040+ instead of InlineHost provision + in-process SDIVF; it reads ` evidence.depositOptions ` ,
1041+ runs the SAME pure projection (` validateDepositSynthesisOptions ` +
1042+ ` buildRealDepositAssetPackOptionSynthesis ` ) and persists the deposit option
1043+ synthesis. ` resolveDepositPipelineHost ` is ** inline-only** (throws if hostKind is
1044+ sandbox — callers must use the harness path). On ` sandbox-created ` , the route
1045+ persists ` context.sandboxId ` on the running execution row for cancel.
1046+ - ** Cooperative cancel.** See Gate-3 #26 .
1047+ - ** Parity of result.** InlineHost and SandboxHost produce the SAME deposit option
1048+ synthesis; only WHERE the pipeline runs differs. Real-sandbox execution is verified
1049+ against deployed sandbox infra; harness plan-building + route dispatch + projection
1050+ are unit-tested with a mocked host.
1051+
1052+ ### Gate-3 #26 — Cooperative run cancel (Garrett, 2026-07-08)
1053+
1054+ Deposit (and any agentic) runs are cancelable without killing mid-token LLM streams.
1055+
1056+ ** Law**
1057+
1058+ 1 . ** User authority.** A depositor who owns the ` executions ` row may cancel while
1059+ ` status === 'running' ` . Terminal rows (` completed ` | ` failed ` | ` interrupted ` |
1060+ ` cancelled ` ) are not re-cancelled (already-cancelled is idempotent 200).
1061+ 2 . ** Row is authority.** Cancel writes ` executions.status = 'cancelled' ` ,
1062+ ` completed_at ` , source-safe ` error.message ` , and ` context.cancelledAt ` /
1063+ ` context.cancelReason ` . Background workers MUST NOT overwrite a cancelled row
1064+ with ` failed ` or ` completed ` .
1065+ 3 . ** Event.** A source-safe ` execution_events ` status row (` message ` , ` cancelled: true ` )
1066+ is inserted so the deposit telemetry accordion shows the cancel.
1067+ 4 . ** Cooperative abort.** Background deposit ` runSynthesis ` polls
1068+ ` assertExecutionNotCancelled ` between major stages (auth, provision, pipeline,
1069+ validate). Sandbox detached command polls call ` shouldAbort ` each interval and
1070+ return exit code 130 / outcome ` 'cancelled' ` , then ` sandbox.stop() ` .
1071+ 5 . ** Sandbox stop.** If ` context.sandboxId ` is present, cancel best-effort stops the
1072+ box via ` Sandbox.get ` + ` stop ` (in addition to harness ` finally ` stop).
1073+ 6 . ** UI.** While a synthesis is running, Telemetry shows ** Cancel run** ; on success
1074+ the detail shows a Cancelled badge and analytics fires
1075+ ` deposit_synthesis_cancelled ` (duration only — no identifiers).
1076+ 7 . ** Not cancel.** Orphan sweep still maps silent stuck rows → ` interrupted ` (not
1077+ cancelled). Deleting activity anchors is unrelated.
1078+
1079+ ** API**
1080+
1081+ - ` POST /api/executions/[runId]/cancel ` body optional ` { reason?: string } ` (≤280 chars)
1082+ - Auth: session user must own the row
1083+ - Responses: 200 cancelled (or already cancelled), 401 unauthenticated, 404 not
1084+ found/not owned, 409 not running
1085+
1086+ ** Implementation symbols**
1087+
1088+ - ` uapi/lib/execution-cancel.ts ` — ` cancelUserExecution ` , ` assertExecutionNotCancelled ` ,
1089+ ` ExecutionCancelledError ` , ` isExecutionCancelled `
1090+ - ` uapi/app/api/executions/[runId]/cancel/route.ts `
1091+ - Deposit route cooperative checks + sandbox ` shouldAbort `
1092+ - ` VercelSandboxPipelineHost ` ` shouldAbort ` + ` sandbox-cancelled ` events
1093+ - ` DepositPageClient ` Cancel run control
10471094
10481095### Gate-3 depositing PARITY MATRIX (gate-closure audit; Garrett, 2026-06-27)
10491096
@@ -1077,17 +1124,26 @@ Parity: ✅ specified + implemented + tested · 🟦 specified + implemented as
10771124| 22 | HostKind selection (configured, not env) | ` selectDepositHostKind ` / ` resolveDepositPipelineHost ` | depositSourceProvisioning.test | ✅ |
10781125| 23 | full inventory (sources+samples) + fail-closed exclusions | ` provisionDepositSourceInventory ` / ` applyExclusionsToInventory ` | depositSourceProvisioning.test, asset-packs-synthesis.test | ✅ |
10791126| 24 | deposit provisions full checkout via Host | deposit route + ` InlineHost ` path | depositSynthesizeOptionsRoute.test | ✅ |
1080- | 25 | SandboxHost IN-BOX deposit dispatch (run the pipeline in the box) | harness deposit mode (` synthesizeMode ` + steering → in-box runner; ` depositOptions ` in evidence) + ` runDepositInBoxHarness ` + route hostKind branch | asset-pack-harness.test, depositSourceProvisioning.test, depositSynthesizeOptionsRoute.test | ✅* |
1127+ | 25 | SandboxHost IN-BOX deposit dispatch (run the pipeline in the box) | harness deposit mode (` synthesizeMode ` + steering → in-box runner; ` depositOptions ` in evidence) + ` runDepositInBoxHarness ` + route hostKind branch; ephemeral ` persistent:false ` ; OIDC/token auth fail-closed | asset-pack-harness.test, depositSourceProvisioning.test, depositSynthesizeOptionsRoute.test, vercel-sandbox-host.test | ✅* |
1128+ | 26 | Cooperative run cancel | ` POST /api/executions/[runId]/cancel ` + ` execution-cancel.ts ` + deposit route polls + sandbox ` shouldAbort ` + UI Cancel run + ` deposit_synthesis_cancelled ` analytics | executionCancelRoute.test, vercel-sandbox-host.test (abort), depositPageClient (cancel control) | ✅ |
1129+ | 27 | Run configuration locked above telemetry in run detail | ` DepositPageClient ` config above telemetry; ` disabled ` when ` synthesisRunId ` set | depositPageClient.test | ✅ |
1130+ | 28 | Formal absolutes fail-closed (no placeholder catalog fallback) | ` validateDepositSynthesisOptions ` requires ` absolutes[] ` | agent-measure-absolutes.test, asset-packs-synthesis.test | ✅ |
1131+ | 29 | Map-tree LLM token rollup | ` sumLlmTokensFromExecutionTree ` | asset-packs-synthesis-pipeline.test | ✅ |
1132+ | 30 | Full deposit SDIVF integration under test (boundary LLM mock) | ` BITCODE_ENABLE_ASSET_PACK_SDIVF_RUNTIME_IN_TEST ` + deposit-sdivf-pipeline-integration.test | deposit-sdivf-pipeline-integration.test | ✅ |
1133+ | 31 | Deposit implementation agent key (telemetry clarity) | ` implementation:deposit-asset-pack-synthesis ` | synthesize-asset-packs-phase-rosters.test | ✅ |
10811134
10821135✅* = wired + unit-tested with a mocked host (harness plan-building, the dispatch, the
10831136option projection); real in-sandbox execution is verified against deployed sandbox infra.
10841137
10851138** Open items for full gate-3 depositing closure (deployment + verification, not code):**
10861139- ** Deployment config** : the Vercel sandbox provider's runtime deps (` @vercel/sandbox ` ,
1087- ` VERCEL_* ` , git in the box image); the AWS provider (#20 ) beyond the stub.
1140+ OIDC or ` VERCEL_TOKEN ` +team+project, git in the box image); set
1141+ ` BITCODE_PIPELINE_HOST=sandbox ` on prod for durable in-box runs; the AWS provider
1142+ (#20 ) beyond the stub.
10881143- ** Live verification** : a real deposit run — on the InlineHost (in-process) and on the
1089- SandboxHost (in-box) — confirming measured sizes + the decision panel end-to-end and
1090- that both hosts produce the same deposit option synthesis.
1144+ SandboxHost (in-box) — confirming measured sizes + the decision panel end-to-end,
1145+ that both hosts produce the same deposit option synthesis, and that Cancel run stops
1146+ a live sandbox (Observability → Sandboxes).
10911147
10921148## Non-goals during V48 opening
10931149
0 commit comments