Dashboard › opencode › Distillation
bcc056d2-bf6f-47ef-aff8-da7090fcac0c["lore_tm_v1_v2TrcodTs9zk_hSB9uV7Az-qAOFi0eVH1r1LTugfeVg","lore_tm_v1_KiMY1YhQ2Md5a9wN-_I6yNRwgiDpiH0ScGFNFbzSQlE","lore_tm_v1_IsGQGDAhkRqv2VuZVqtS8X7PB_l3kZVdJ0brMasj0mA"]
Date: Sep 17, 2026
ses_f5342a3cdffezlzQRwyEts4Bkm completed with DO-NOT-MERGE because cancellation can strand a Session at the post-commit Step.Started boundary.startAssistant() commits Step.Started before storing the assistant ID in publisher memory (packages/core/src/session/runner/publish-llm-event.ts:88-107); cancellation between that commit and line 105 sees a durable incomplete assistant but publisher memory sees none; publisher.interruptAssistant(...) (packages/core/src/session/runner/llm.ts:417-465) calls startAssistant() again (packages/core/src/session/runner/publish-llm-event.ts:242-260); the second start cannot commit because ordinary claim updates reject monotonic phase cancelling (packages/core/src/session/execution/claim.ts:46-55, packages/core/src/session/runner/llm.ts:291-303).flush() may fail even earlier for a partially opened fragment because the publisher lacks a current assistant ID (packages/core/src/session/runner/publish-llm-event.ts:109-112,182-185); the execution remains cancelling because local finalization preserves it (packages/core/src/session/execution/local.ts:104-119), and after expiry recovery quarantines the cancellation rather than restoring availability (packages/core/src/session/recovery.ts:121-139), creating a durable per-Session denial of service that an authenticated caller can trigger by racing interrupt against the first assistant event, with slow listeners widening the window.Step.Started, symmetric with the existing Step.Failed regression at packages/core/test/session-runner.test.ts:3951-3997; cancellation must use the durable assistant ID, publish exactly one Step.Interrupted for that assistant without another Step.Started, remove the claim, and create no recovery state.Step.Failed blocker fix: cancellation reloads the owned execution and durable assistant projection after interruption (packages/core/src/session/runner/llm.ts:417-458, packages/core/src/session/message-updater.ts:225-230); if Step.Failed already completed the assistant, it settles cancellation directly without duplicate Step.Interrupted. The regression asserts one failure, zero interruptions, no execution claim, and no recovery row.packages/core/src/session/execution/local.ts:34-67); recovery alone takes expired claims through compare-and-swap (packages/core/src/session/recovery.ts:71-100).packages/core/src/session/execution/claim.ts:27-33,40-65,67-109); provider dispatch, publication, local-tool startup, context mutation, compaction, and settlement all pass through claim updates, preserving the accepted check-call residual risk.packages/core/src/session/recovery.ts:147-205, packages/core/src/session/projector.ts:399-467, packages/core/src/session/input.ts:354-429); recovery-owned inputs remain excluded from ordinary steer/queue selection (packages/core/src/session/input.ts:432-455,531-592); deterministic recovery IDs in packages/core/src/session/recovery-id.ts:1-6 make retries idempotent.packages/core/src/session.ts:427-431, packages/core/src/session/input.ts:164-189); recovery continuations are selected separately and promoted exactly (packages/core/src/session/execution/local.ts:70-87, packages/core/src/session/input.ts:594-648); claim, recovery-wake, and ordinary-wake scans are bounded, and fresh work retains capacity under retry saturation (packages/core/src/session/recovery.ts:25,65-78,270-388,390-488).packages/core/src/database/migration/20260914170650_session-recovery.ts, generated schema, and registry agree on phases, ownership fields, constraints, foreign keys, and indexes; new events appear in durable/current unions, sync events, generated clients, and OpenAPI as closed objects with correct optional fields; recovery adds no unauthenticated route; dependency direction remains Schema β Core/Protocol β Server.229 recovery tests, Core 1186/0, typecheck, migration, or smoke evidence because review rules prohibited tests and builds; the reviewer stated those tests did not cover the remaining Step.Started boundary.Step.Started commit-to-return window: the durable execution claim already stores the assistant ID atomically with Step.Started, so cancellation should use that ID directly rather than asking publisher memory to start or locate an assistant.Step.Started; completion or validation was not yet reported.ses_f53431949ffehdCfM2PmDBmJvD completed with MERGE, no MUST-FIX, and no concern beyond explicitly accepted check-call, process-local routing, and clock-skew residuals.packages/core/src/session/runner/llm.ts:415-466: cancellation reconciles tools first, reads the assistant attached to the exact claimed execution, checks durable time.completed, and settles cancelling β cancelled without duplicate Step.Interrupted.packages/core/src/event.ts:320-348,378-390), so the assistant-row check sees the committed Step.Failed projection even when post-commit notification is blocked.packages/core/test/session-runner.test.ts:3951-3997 reaches the exact Step.Failed boundary and proves one Failed event, zero Interrupted events, no execution claim, and no recovery row.packages/core/src/session/execution/claim.ts:27-33,84-108); cancellation ownership survives runner/finalizer completion, while cleanup removes only exact settled claims and preserves uncertain cancellation or recovery phases (packages/core/src/session/execution/local.ts:97-121,128-162).packages/core/src/session/recovery.ts:71-205, packages/core/src/session/input.ts:354-429); recovery and ordinary wake redrive are bounded, CAS-guarded, fair between fresh and retried work, and isolated from quarantined continuations (packages/core/src/session/recovery.ts:270-488).packages/core/src/session/sql.ts:148-253, packages/core/src/database/migration/20260914170650_session-recovery.ts:8-59); durable/public event manifests include new events and optional execution intent (packages/schema/src/session-event.ts:94-112,209-230,484-554); generated SDK/OpenAPI preserve literals, required fields, optional assistant identity, ID patterns, and closed objects (packages/sdk/js/src/v2/gen/types.gen.ts:3416-3449,3585-3618, packages/sdk/openapi.json:26226-26342).