Skip to content

fix(opencode): heal the transcript gap when the database path turns up late - #1229

Merged
Juliusolsson05 merged 4 commits into
mainfrom
fix/opencode-late-db-heal
Sep 25, 2026
Merged

Juliusolsson05 merged 4 commits into
mainfrom
fix/opencode-late-db-heal

Conversation

@Juliusolsson05

@Juliusolsson05 Juliusolsson05 commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

Fixes #1117

What was wrong

When opencode db path fails at launch, the package retries it (#1114). When it later succeeds, DurableReader.position() seeds from the database's current head, so every row the TUI committed while the pane was dark counts as already seen. Those rows are never emitted, and the pane shows an answer whose prompt never appeared, or nothing at all. The package reports db_path_recovered_late ("Reload the session to re-read it") because it cannot tell a dark-window row from last week's.

Fix

useIpcSubscriptions.ts answers db_path_recovered_late by running loadInitialHistoryForSession once. A history read admits only uuids the pane does not already hold, and placeHistoryEntries places them in order around the rows it does hold. On success the status becomes ready; if the load fails, the error stays, which is still true. The diagnostic never reaches the lifetime banner (unchanged).

Evidence

The OpenCode Terminal harness gains a lateDatabase option. It launches dark while the replay keeps committing to the real fixture database, and uses a mocked resolveOpencodeDbPath that starts answering on demand. The new test in opencodeTerminalDiagnostics.renderer.test.tsx runs through the real package, SessionManager and forwarder with the recorded plain.json:

  • Fail-first: without the fix, it failed with timed out waiting for the dark-window prompt, after the recovery had fired.
  • With the fix: the recorded prompt is in runtime.entries, the status is ready, and there is no lifetime banner.
  • Existing banner test: it asserted transcriptError for both codes. For recovered_late that value now belongs to the heal, so it asserts only the banner, with a comment explaining why.
  • Suites: renderer 3,034 of 3,034 pass (Node 24). tsc -b is clean.

Not verified

Live OpenCode (house rule). The package's own dark-window test (#6) is unchanged.

🤖 Generated with Claude Code

Review disposition (A Grok, B Pi; 2 rounds)

Finding Disposition
A MAJOR: the late open's first store open BUSY → retry via openDurable never emitted db_path_recovered_late, so no heal ran and the pane looked healthy Fixed in the package (opencode-terminal-headless#9, merged; submodule at its merge commit 6f343e7c): the report fires wherever the reader starts. New package system test
A/B: a failed heal's error was cleared by the next committed row Fixed (1f23a5d8): a failed heal sets the recovered-late message as the lifetime banner
B round 2: that banner then survived a later SUCCESSFUL read, so parents saw transcript_unavailable over a complete transcript Fixed (d52a779b): a successful history read clears that one banner (channelErrorAfterRead); other channel errors stand. The heal failure no longer resurrects a closed pane's runtime. Test extended; the mutant is killed
B1: the recovered-late write was unpinned Pinned: the heal ran exactly once; session:jsonl-error reached the pane
B3/B4, A suspicion: the history source and the pane resolve the DB path with separate memo keys Noted: for an absolute binary the keys coincide on the normal boot path; no change

Round 2: A and B both MERGE-READY. The round-2 banner fix followed, with a test and a mutation check.

Juliusolsson05 and others added 2 commits September 25, 2026 00:33
…p late

When OpenCode's database path is resolved late, the package opens the
durable channel at the database's current head, so every row the TUI
committed while the pane was dark counts as already seen and is never
emitted. It reports db_path_recovered_late and asks the user to reload.

The renderer now answers that diagnostic with the reload itself: a
history read admits only uuids the pane does not hold and places them
in order, so the dark-window prompt and answer come back. A load that
succeeds writes `ready`; a failed one leaves the error standing.

The OpenCode Terminal harness gains `lateDatabase`: launch dark while the
replay keeps committing, with a mocked resolver that starts answering on
demand. The new test drives the real package, SessionManager and
forwarder: it failed first ("timed out waiting for the dark-window
prompt") and passes with the fix.

Fixes #1117

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…anner

Review of #1229:
- A (major): a late path recovery whose first store open was BUSY never
  emitted db_path_recovered_late, so no heal ran. Fixed in the package
  (opencode-terminal-headless#9, pointer bumped here): the report now
  fires wherever the reader actually starts.
- A/B: a heal whose own history load failed was cleared by the next
  committed row, and the pane looked whole with rows still missing. The
  recovered-late message now becomes the lifetime banner in that case.
- B: the heal test now pins that the diagnostic reached the pane and
  healed exactly once; a new test covers the failed heal (removing the
  handler fails it).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Juliusolsson05 added a commit that referenced this pull request Sep 25, 2026
…question, #1228/#1229 round 2

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Juliusolsson05 and others added 2 commits September 25, 2026 01:58
Round-2 review of #1229: after a failed heal the recovered-late message
became a permanent lifetime banner, so a later read that succeeded (a
retry, a reload, a parent's hydrate) left Agent Status and every
parent's transcript_unavailable over a complete transcript. The history
load now drops that one banner on success; channel errors that describe
the live channel still stand. The failure handler also no longer
resurrects a runtime for a pane closed mid-heal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Juliusolsson05 added a commit that referenced this pull request Sep 25, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Juliusolsson05
Juliusolsson05 merged commit 49c925b into main Sep 25, 2026
2 checks passed
@Juliusolsson05
Juliusolsson05 deleted the fix/opencode-late-db-heal branch September 25, 2026 09:18
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.

bug(opencode): heal the transcript gap left when the durable channel opens late

1 participant