Dashboard › opencode › Distillation
caca258e-5a30-4743-ae31-06de077d92f3["lore_tm_v1_KTFUe8QKykKMooQy4QtdMMo_man9M-Qzm1o2rQ8jLug","lore_tm_v1_OfnTV32oNoE9MnimhakC4aXFkLDMRlktaF_F509YIYs","lore_tm_v1_PeZUb5HOzaZVOF_bGr0kw7Wms-Pn9g9vQ3Uqx5LQFyg","lore_tm_v1_NezGKNMdmWE10UEGtRz54pnzmg5GAmL8s03dzp5FrW8","lore_tm_v1_pn4rFQF2szWpWqgjR7xFQw6ItDMojNI8p7M6_2UIrgc","lore_tm_v1_Th3--y-A8631KHCfx41y-ilwuDUQMcSNsrolI0-EojE","lore_tm_v1_FH2qzo4Ij9lByiBlvVhxbPgjFq4C7t0aYuhx_PnuCIg","lore_tm_v1_Kvr25uzq43XS0U6dhh9yWQWE7ELt7QSomx6mJJquA-c","lore_tm_v1_x5DfD3jwPg0FKgXoyzzIYWExL78TTHAhCbgT4Zz1CJo","lore_tm_v1_2ZjoHxTBirh0MdWHJo0Jo0kK5lvhqWECZAxeR1T1S6I"]
Date: Sep 16, 2026
packages/core/test/session-runner-recorded.test.ts configures the recorded OpenAI transport with cassette "session-runner/openai-chat-streams-text" under fixtures/recordings; RECORD === "true" selects HttpRecorderInternal.cassetteLayer(..., { mode: "record" }), otherwise HttpRecorder.http(...). The model is OpenAI Chat gpt-4o-mini at https://api.openai.com/v1, bearer auth from OPENAI_API_KEY ?? "fixture", with maxTokens: 20 and temperature: 0.ses_runner_recorded with "Say hello in one short sentence." using resume: false, then calls session.resume(sessionID). It expects exactly 2 context messages: the original user prompt and an assistant message with agent: "build", finish: "stop", and text "Hello!"."session.next.prompt.admitted.1", 2. "session.next.prompted.1", 3. "session.next.step.started.1", 4. "session.next.text.started.1", 5. "session.next.text.ended.1", 6. "session.next.step.ended.2".packages/core/test/session-runner-tool-events.test.ts verifies local tool success stores media base64 exactly once: "session.next.tool.success.1" omits the compatibility result field and retains structured content containing "Image read successfully" plus a data:image/png;base64,... file with MIME "image/png".result; 2. a binary error "Cannot read binary file" emits "session.next.tool.failed.1" and no success event; 3. old SessionEvent.Tool.Success.data containing result still decodes; 4. LLMEvent.stepFinish({ index: 0, reason: "stop" }) records publisher.stepSettlement().finish === "stop" without publishing "session.next.step.ended.2".packages/core/test/session-projector.test.ts contains recovery/reconciliation coverage in source order: 1. atomically reconciles one abandoned execution into one continuation; 2. records a recovery continuation without forging an assistant identity; 3. recovers each abandoned execution once across repeated startup scans; 4. never recovers a live execution lease; 5. never recovers an execution superseded by a newer assistant; 6. redrives a durable recovery wake after admission; 7. quarantines a malformed recovery row without blocking a valid wake; 8. quarantines a full batch of poison recovery rows before redriving valid work; 9. fairly redrives recovery and ordinary work beyond a full bounded batch; 10. quarantines a continuation belonging to another Session; 11. redrives durable ordinary-input execution intent after a lost advisory wake.packages/core/test/session-projector.test.ts recovery cases, continuing source order: 12. redrives ordinary input without recovering a claim that crashed before promotion; 13. redrives one existing recovery after its replacement claim crashes before promotion; 14. never recovers a pre-promotion claim when input commits at the recovery boundary; 15. rejects a recovered assistant from another Session; 16. quarantines a recovery wake behind a newer assistant; 17. never promotes a recovery superseded before scanner validation; 18. never promotes a quarantined recovery continuation as an ordinary steer; 19. quarantines a malformed claim without blocking a valid claim; 20. bounds each deterministic recovery scan.packages/core/test/session-projector.test.ts fencing/projection cases, continuing source order: 21. rolls back promotion and Context Epoch mutation after ownership loss; 22. never advances the Context Epoch after ownership changes; 23. rolls back claim renewal when Context Epoch advance fails; 24. fences a paused owner after expiry, reconciliation, and takeover; 25. projects moved sessions without the transitional context epoch table; 26. projects staged, cleared, and committed reverts; 27. orders projected messages and context by durable aggregate sequence; 28. marks an inbox row promoted with the Prompted event sequence; 29. projects durable context messages supported by the updater; 30. rejects distinct creator events that reuse one projected message ID; 31. does not revive a stale incomplete in-memory assistant projection; 32. updates only the newest incomplete assistant projection; 33. has another later case ensuring a stale incomplete assistant projection is not revived."never recovers a live execution lease"."never recovers an execution superseded by a newer assistant"."never recovers a pre-promotion claim when input commits at the recovery boundary"."never promotes a recovery superseded before scanner validation"."never promotes a quarantined recovery continuation as an ordinary steer".packages/core/test/session-runner.test.ts:700-728 verifies startup recovery redrives lost ordinary-input execution intent: prompt "run after restart" is admitted with delivery "steer" and requestExecution: true; after SessionRecovery.recover(), the provider receives that text and the input ends with wake_pending: false and numeric promoted_seq.packages/core/test/session-runner.test.ts:731-755 verifies no provider dispatch after ownership changes: while model resolution is gated, session_execution is replaced by { id: "provider-successor", owner_id: "successor", expires_at: 60_000 }; afterward requests remains empty and the event count does not change.packages/core/test/session-runner.test.ts:757-782 verifies streamed output is fenced after ownership changes: response text "stale output" is paused, execution ownership changes to { id: "publication-successor", owner_id: "successor", expires_at: 60_000 }, and resuming the stream publishes no additional event and projects no assistant message.packages/core/test/session-runner.test.ts:784-822 verifies a local tool is never started after ownership changes. On SessionEvent.Tool.Called for call-fenced, execution is replaced by { id: "tool-successor", owner_id: "successor", expires_at: 60_000 }; no local executions occur and neither SessionEvent.Tool.Success nor SessionEvent.Tool.Failed is published.packages/core/test/session-runner.test.ts:824-879 verifies interrupted tools are not failed by a stale owner. After projecting running tool call-interrupted-fence, ownership is changed to { id: "interrupted-tool-successor", owner_id: "successor" }; runner.run({ sessionID, force: true, executionID, ownerID: "test" }) fails, while context still shows the tool in { status: "running" }.packages/core/schema.json includes table session_context_epoch with baseline_seq; session_execution columns id, session_id, owner_id, optional assistant_message_id, phase, time_created, expires_at, and optional recovery_error.packages/core/schema.json defines session_input columns id, session_id, prompt, delivery, admitted_seq, optional promoted_seq, wake_pending defaulting to "false", wake_attempts defaulting to "0", and time_created.packages/core/schema.json defines session_message columns id, session_id, type, seq, time_created, time_updated, and data.packages/core/schema.json defines session_recovery columns session_id, execution_id, optional assistant_message_id, continuation_message_id, phase, wake_pending defaulting to "true", wake_attempts defaulting to "0", optional recovery_error, and time_created./tmp/opencode/session-recovery-final-v4.patch contains the packages/core/test/session-runner.test.ts diff beginning at line 5897./tmp/opencode/session-recovery-final-v4.patch contains the packages/opencode/src/server/routes/instance/httpapi/server.ts diff beginning at line 6624.