Skip to content

fix: arm the startup rebuild watchdog on the background branch too (#158) - #341

Open
ProfSynapse wants to merge 2 commits into
mainfrom
fix/158-background-watchdog
Open

fix: arm the startup rebuild watchdog on the background branch too (#158)#341
ProfSynapse wants to merge 2 commits into
mainfrom
fix/158-background-watchdog

Conversation

@ProfSynapse

Copy link
Copy Markdown
Owner

Addresses gap 1 of #158.

The gap

startIdleWatchdog was gated on isBlockingHydration. But updateProgress() sets phase: 'running' on both branches, and running is not query-ready — so a stalled background rebuild left isQueryReady() false indefinitely with nothing to fail it.

This is the same shape as the bug fixed earlier today: phase completion was corrected for both branches, while stall protection still covered only the blocking one.

The fix

Both the watchdog and the Promise.race now arm on either branch.

armIdleWatchdog() stays inert until the phase is actually running, so a background rebuild that never reports progress at all — phase idle, which is query-ready — is unaffected. That distinction is the reason this can't just be a flag flip.

Tests

Three, and the third exists to stop the fix over-correcting:

  1. The rebuild promise rejects with made no progress on the non-blocking branch
  2. A mid-flight waitForQueryReady(10_000) settles false at the injected 50 ms watchdog timeout rather than burning its own budget
  3. The inert-while-idle case stays inert

Pre-fix, both stall tests hang to a Jest timeout — the promise never settles, which is the defect stated as a test.

Live verification

Exercised against the real shipped bundle in headless Obsidian 1.13.7 with a 1000 ms injected timeout: rejected at 1001 ms, phase error, and the gate resolved false against a 30 s budget. State restored and plugin reloaded afterwards; dev:errors clean.

Still open on #158

Gap 2 — ChatView.waitForStartupHydration writes the error into the overlay and returns early without hiding it, leaving no retry affordance. Not in this PR.

🤖 Generated with Claude Code

https://claude.ai/code/session_01C6aSoCAS5gNoew6n9qv6DJ


Generated by Claude Code

claude added 2 commits August 14, 2026 19:43
)

`runStartupFullRebuild` gated both the idle watchdog and the timeout race on
`isBlockingHydration`. But `onProgress` calls `updateProgress` on both
branches, and that moves the hydration phase to `running`, which is not
query-ready. A *background* rebuild that reported progress and then stalled
therefore left `isQueryReady()` false for the rest of the session with nothing
to fail it: every `waitForQueryReady()` caller burned its full idle timeout and
resolved false, and the rebuild promise never settled at all.

This is the same shape as the completion bug fixed in 7a5428c — the phase
transition was corrected for both branches, but stall protection still covered
only the blocking one.

Drop the gate. The watchdog is inert until the phase actually reaches
`running`, so a background rebuild that never reports progress (phase stays
`idle`, which is query-ready) is unaffected.

Tests inject a 50 ms idle timeout rather than waiting out the real 120 s: both
new stall tests hang to a Jest timeout against the pre-fix adapter, and a third
test pins the inert-while-idle behaviour so the fix cannot over-correct.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C6aSoCAS5gNoew6n9qv6DJ
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.

2 participants