Repository navigation
fix: a failed index reload keeps what recall has, says so, and retries (GIT-118) - #53
Merged
2 commits merged intoSep 23, 2026
Merged
2 commits merged into
2 commits merged into
Conversation
…s (GIT-118) loadScarsFromSupabase returned [] on any error with no flag. flushCache (fired after every create_learning, and every 15 min) reinitialised the index and overwrote hook-scars.json with it, logged "N -> 0", and reported success. A failed init was cached as ensureInitialized's promise, so it was never retried. - loadScarsFromSupabase reports ok/error; on failure it offers the last disk vector cache (stale) instead of [], and never as "the store is empty". - A failed reload keeps the index and the hook cache (an empty index takes the stale disk copy) and returns success: false with the cause. - A failed load retries with backoff (30 s, doubling, 10 min cap); ensureInitialized forgets a failed init; an init after a stale start replaces the stale rows (initialize() is a no-op once initialized). - create_learning awaits a refresh and its display says when the recall index could not be refreshed (index_refreshed: false). The post-write refresh uses the per-row delta (GIT-98), not the disk-bypassing flush. +7 startup tests (6 fail on main), +2 create_learning display tests. Three test files mocked startup.js without refreshIndexAfterWrite; the missing export threw inside create_learning's try and every call reported "NOT refreshed" unseen. Their mocks now provide it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…all survives (GIT-118) A forwarding proxy in front of the venue fails GET gitmem_learnings* on demand while writes pass. On 1.11.0: "Flushed and reloaded: 5 -> 0", create_learning silent, recall empty; exit 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A failed index reload keeps what recall has, says so, and retries (GIT-118).
loadScarsFromSupabasereportsok/error. On failure it offers the last disk vector cache (possibly stale) instead of[]. A genuinely empty store is stillok: truewith 0 rows.hook-scars.json, and returnssuccess: falsewith the cause. The one exception is an index that is already empty, which takes the stale disk copy because it has nothing better to lose.ensureInitializedno longer caches a failed init forever. An init that follows a stale start replaces the stale rows (initialize()is a no-op once initialized, so this needed a reinitialize).create_learningawaits the refresh. If it fails, the display says: "Recall index NOT refreshed (…). The learning is saved; recall will find it after the next successful reload (retrying in the background)." The result carriesindex_refreshed: false.Decision to review
create_learningnow refreshes with the per-row delta (GIT-98, newrefreshIndexAfterWrite), notflushCache, which bypasses the disk cache and re-downloads the whole index (≈0.9 MB for 250 learnings) after every write. That makes awaiting it affordable.flushCache(the tool) keeps bypassing, as documented.Not changed, flagged: the 15-minute periodic refresh also calls
flushCache, i.e. a full download every 15 minutes per process. It now fails safely, but the cost is untouched. A one-line follow-up would switch it to the delta.Why
On any error,
loadScarsFromSupabasereturned[]with no flag.flushCachethen reinitialised the index and the hooks' scar cache with it, logged "N → 0", and reported success. It runs after everycreate_learningand every 15 minutes, so one failed request emptied recall until the next good load, and a failed init was never retried.How to test
Venue (
vujndhcumgroztfkkdus, v1.8.0setup.sql; production not touched). A newflowprobe puts a forwarding proxy in front of the venue that failsGET /rest/v1/gitmem_learnings…on demand while writes pass. Socreate_learningreally saves while its refresh really fails; then, after background work settles,recallruns.origin/main1.11.0Flushed and reloaded: 5 → 0 scarsReload failed (… 503 …); kept 5 scars, hook cache unchanged·retry 1 in 30 screate_learningdisplayUnit tests: 1366/1366.
startup-reload-failure.test.ts(+7, real disk cache, local index and hook cache; store mocked at the client) covers: flush with the store down; post-write refresh is a delta, not a full download; cold start serves the disk cache and reports failure; empty store is success; retry recovers; backoff doubles;ensureInitializedretries. 6 of the 7 fail onmain; the empty-store control passes on both. There are also +2create_learningdisplay tests.Existing tests changed
create-learning-errors,create-learning-field-persistenceandvariants-dev-onlymockedstartup.jswith onlyflushCache. The new awaitedrefreshIndexAfterWritewas therefore missing. It threw insidecreate_learning's try, and every Pro create in those suites silently reported "NOT refreshed"; they passed only because none checks the display. That is the audit's mock-blindness shape. Their mocks now provide it. No assertions changed.Checklist
🤖 Generated with Claude Code