Skip to content

refactor(core): opencode-session shared decode into core — opencode, kilo-code (phase 8, shared batch S2) - #837

Merged
iamtoruk merged 1 commit into
feat/core-extractionfrom
phase8/shared-modules
Jul 27, 2026
Merged

refactor(core): opencode-session shared decode into core — opencode, kilo-code (phase 8, shared batch S2)#837
iamtoruk merged 1 commit into
feat/core-extractionfrom
phase8/shared-modules

Conversation

@iamtoruk

Copy link
Copy Markdown
Member

Phase 8 shared-module batch S2 (tracking #809), completing the Category C tier: unifies the three-file opencode decode family (session-message + sqlite-session-parser + opencode-file-parser) into a single @codeburn/core module (providers/opencode-session) and fully converts opencode and kilo-code — deleting the S1 thin cline adapter, so kilo-code's both arms (cline task dirs + sqlite) now run through core decodes. Driver, SQL, subtree recursion, and blob handling stay CLI-side; the session-level fallback is pre-fetched into the envelope with its decision logic in core, exactly matching the original condition.

Guidance spec → Kimi two-phase (34 goldens verified green against unmodified code first, including a from-scratch fixture for kilo-code's previously untested sqlite arm and byte-exact CODEBURN_VERBOSE stderr pins via spies) → Opus validation. The validator found:

  • 1 real defect: opencode's file arm emitted a spurious sqlite verbose line naming the previous sqlite session (stale provider-instance closure state across mixed-arm sources). Reproduced against the original as oracle; fixed with a handoff reset + regression test.
  • 4 non-discriminating dedup goldens: proven by mutation (hoisting seenKeys.add above the build failed zero tests before, fails 4 after the fixture fixes). The tier's opposed dedup semantics — add-after-build here vs burn-before-skip in vscode-cline — are both preserved and now genuinely pinned.

The session-fallback call's distinct key shape (no skills/subagentTypes keys) is guarded by the key-presence gate; archived-child exclusion is exercised by a fixture that would emit an extra call if the SQL filter broke. Golden provenance independently confirmed: all goldens pass against the restored pre-migration originals.

Gates: core 400/400; CLI suite and root npm test both 2404 passed, 5 skipped; tsc --noEmit clean both packages; discovery byte-identical; no parse-version changes.

Pre-existing, flagged not fixed: normalizeToolName bare-Record prototype leak (blocked from the sync envelope by the canonical-name filter, reaches local reports), duplicated display map in opencode.ts, dead role guard, file-arm silent drops. These join the prototype-exposure sweep follow-up.

…kilo-code (phase 8, shared batch S2)

Unifies the three-file OpenCode decode family — session-message.ts,
sqlite-session-parser.ts, and opencode-file-parser.ts — into a single core
module, packages/core/src/providers/opencode-session, exposing a two-arm
tagged envelope (kind: 'sqlite' | 'file') over one shared assistant-turn
builder. The SQLite driver, both WITH RECURSIVE session_tree queries,
blobToText, discovery, and extractBashCommands all stay CLI-side.

session-message.ts shrinks to the discovery-side sanitize helper;
sqlite-session-parser.ts and opencode-file-parser.ts keep their SQL and
directory walks and expose readRecords adapters. No decode logic remains
CLI-side in any of the three.

kilo-code is now fully converted: both arms — cline task dirs via the batch-S1
core vscode-cline module and SQLite via the new module — run through core
decodes from one bridged provider, and the thin createClineParser adapter S1
retained is deleted.

The CODEBURN_VERBOSE zero-yield notice is reconstructed host-side by
zed-style decode wrappers, byte-identical for both the OpenCode and KiloCode
labels, with parseFailCount/roleSkipCount derived from the decode's
malformed-json / unknown-shape diagnostics. The session-level SQLite fallback
is pre-fetched onto the envelope instead of queried lazily — output-neutral,
changing only I/O volume — and keeps its distinct key shape, emitting no
skills/subagentTypes keys.

Validator fixes on top of the migration:

- opencode's file arm emitted a spurious SQLite verbose stderr line, reporting
  a previous SQLite source's session id and message count, because the
  readRecords -> decode count handoff was never cleared when switching arms.
  The handoff is now reset on the file path. Pinned by a new regression test.
- The S8 and F9 dedup goldens did not actually pin add-after-build: the SQLite
  fixture used two different message ids, and both file fixtures were degenerate
  (the CLI one wrote the same filename twice and silently overwrote; the core
  one shared a text part across both messages, so the "skipped" message built
  successfully). All four now fail if seenKeys.add is hoisted above the build.
- Added key-presence gates to the goldens, since toEqual accepts a
  present-but-undefined key: the session-level fallback must omit
  skills/subagentTypes, a message-arm call per arm must carry them, and
  fallbackCostUSD must be present for cost 0 and absent for an absent cost.

Goldens were captured pre-migration and re-verified against the original tree
by restoring 3817289's sources in place; all 36 pass on both sides.

Pre-existing issues moved verbatim and left alone: the bare-Record tool map
with a truthy hit check in normalizeToolName (prototype leak on names like
'constructor'), opencode.ts's duplicated display-only tool map, and the dead
inner role guard in the SQLite arm. Every new lookup introduced by the
unification is a Map.
@iamtoruk
iamtoruk merged commit f4f4dcc into feat/core-extraction Jul 27, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant