8000 fix: derive FactRefs from on-disk layout when rebuilding indexes on open (#370) by adityamukho · Pull Request #372 · project-minigraf/minigraf · GitHub
[go: up one dir, main page]

Skip to content

fix: derive FactRefs from on-disk layout when rebuilding indexes on open (#370) - #372

Merged
adityamukho merged 1 commit into
mainfrom
fix/370-rebuild-fact-refs
Sep 21, 2026
Merged

adityamukho merged 1 commit into
mainfrom
fix/370-rebuild-fact-refs

Conversation

@adityamukho
Copy link
Copy Markdown
Collaborator

Summary

Fixes the root cause behind the silent entity-lookup loss reported in #370.

When the index checksum doesn't match on open (e.g. after a kill mid-save(), which overwrites old index pages before committing the header), load() rebuilds all four indexes from the fact pages. It derived each fact's FactRef by re-packing every fact contiguously with pack_facts(&all_facts, 1). But each save() starts a fresh page, so a file written by several checkpoints has partially filled pages that a contiguous re-pack does not reproduce. From the second checkpoint onward, every rebuilt index entry pointed at the wrong page/slot, so entity-bound lookups returned nothing (or errored) while the file opened cleanly, and checkpoint() copied the bad refs forward.

Changes

  • packed_pages::read_all_with_refs: reads facts together with their real (page_id, slot_index); read_all_from_pages now delegates to it.
  • The rebuild path in persistent_facts.rs builds the indexes from those refs instead of re-packing.
  • Regression test test_rebuild_after_multiple_checkpoints_keeps_entity_lookups: five checkpoints, corrupt the index checksum, reopen, look up every entity. Fails before the fix with Slot 1 out of bounds (page has 1 records); passes after.

Caveats

Test plan

  • cargo test (757 lib tests + integration + doc)
  • cargo clippy --lib, cargo fmt
  • pre-push hook

Refs #370

🤖 Generated with Claude Code

https://claude.ai/code/session_01PuKbXn6NaHBMDVkScdBNQZ

…pen (#370)

The rebuild-on-load path (index checksum mismatch, e.g. after a crash mid-save)
re-packed all facts contiguously with pack_facts() to derive FactRefs. Every
save() starts a fresh page, so a file written by multiple checkpoints has
partially filled pages that a contiguous re-pack does not reproduce. From the
second checkpoint onward, all four rebuilt indexes pointed at the wrong
page/slot, so entity-bound lookups returned nothing (or errored) while the
file opened cleanly.

Read facts together with their real (page, slot) via the new
packed_pages::read_all_with_refs and build the indexes from those.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PuKbXn6NaHBMDVkScdBNQZ
@adityamukho adityamukho added bug Something isn't working corruption Data corruption risk data-integrity Data integrity issue labels Sep 21, 2026
@codecov
codecov Bot commented Sep 21, 2026
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@adityamukho
adityamukho merged commit 84bf375 into main Sep 21, 2026
17 checks passed
@adityamukho
adityamukho deleted the fix/370-rebuild-fact-refs branch September 21, 2026 04:46
adityamukho added a commit that referenced this pull request Sep 25, 2026
Patch release on the v2.x line; file format unchanged (v7), no API
changes. Ships #372: the index rebuild on open now uses each fact's
real on-disk location, so entity-bound lookups no longer come back
empty after a crash-triggered rebuild of a multi-checkpoint file.

Doc sync: CHANGELOG (v2.0.1 entry + known issues #371/#287, #373/#374),
CLAUDE.md, README.md, ROADMAP.md (v2.x on main, v3.0.0 on the `v3`
branch), docs/TEST_COVERAGE.md (1154 tests).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BedF9ZmqVZLkvDwn91fuKy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working corruption Data corruption risk data-integrity Data integrity issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

0