Skip to content

fix: a failed index reload keeps what recall has, says so, and retries (GIT-118) - #53

Merged
2 commits merged into
mainfrom
bugfix/GIT-118-failed-reload-keeps-index
Sep 23, 2026
Merged

2 commits merged into
mainfrom
bugfix/GIT-118-failed-reload-keeps-index

Conversation

@nTEG-dev

Copy link
Copy Markdown
Member

What

A failed index reload keeps what recall has, says so, and retries (GIT-118).

  • Failure is no longer "empty": loadScarsFromSupabase reports ok / error. On failure it offers the last disk vector cache (possibly stale) instead of []. A genuinely empty store is still ok: true with 0 rows.
  • A failed reload keeps the index and hook-scars.json, and returns success: false with 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.
  • Retry with backoff after any failed load: 30 s, doubling, capped at 10 min. A later success clears it.
  • ensureInitialized no 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_learning awaits 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 carries index_refreshed: false.

Decision to review

create_learning now refreshes with the per-row delta (GIT-98, new refreshIndexAfterWrite), not flushCache, 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, loadScarsFromSupabase returned [] with no flag. flushCache then reinitialised the index and the hooks' scar cache with it, logged "N → 0", and reported success. It runs after every create_learning and 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.0 setup.sql; production not touched). A new flow probe puts a forwarding proxy in front of the venue that fails GET /rest/v1/gitmem_learnings… on demand while writes pass. So create_learning really saves while its refresh really fails; then, after background work settles, recall runs.

origin/main 1.11.0 This branch
Server log Flushed and reloaded: 5 → 0 scars Reload failed (… 503 …); kept 5 scars, hook cache unchanged · retry 1 in 30 s
create_learning display "Created win" only adds "Recall index NOT refreshed (… 503 …)"
Recall right after no scar seeded scar found
Exit 1 0, no expected failures seen

Unit 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; ensureInitialized retries. 6 of the 7 fail on main; the empty-store control passes on both. There are also +2 create_learning display tests.

Existing tests changed

create-learning-errors, create-learning-field-persistence and variants-dev-only mocked startup.js with only flushCache. The new awaited refreshIndexAfterWrite was therefore missing. It threw inside create_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

  • Fails on main, passes on the branch (unit + venue v1.8.0 with fault injection)
  • No schema change

🤖 Generated with Claude Code

Claude and others added 2 commits September 22, 2026 20:36
…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>
@nTEG-dev nTEG-dev closed this pull request by merging all changes into main in 60a990e Sep 23, 2026
@nTEG-dev
nTEG-dev deleted the bugfix/GIT-118-failed-reload-keeps-index branch September 23, 2026 05:34
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