Repository navigation
feat(store): index-format rebuild boundary for the File-QN change - #1104
Conversation
4cb3014 to
b79f397
Compare
|
Thanks for the focused diagnosis and for linking the public #769 repro. I have triaged this as a high-priority 0.9.1-rc parsing/search correctness fix. The current diff has no dependency, workflow, network, credential, prompt-injection, or supply-chain concern. The present unit coverage is not sufficient for this change:
CI is still running. The identity compatibility decision remains a blocker even if it turns green. |
|
Maintainer decision: the File-QN direction is accepted, and we will use an automatic one-time full-reindex compatibility boundary rather than an in-place migration. Please update this PR with the following scope:
This resolves the maintainer-owned compatibility decision. Merge review will resume against the new exact head after these correctness and upgrade-path tests are present and CI is green. |
9408889 to
074edcc
Compare
|
Rebased onto main. #1108 landed the same file guard while this was in review, so I’ve dropped my fqn.c change — this PR no longer touches that file. |
|
Thanks for rebasing this on top of #1108 and narrowing the PR to the compatibility boundary. That remaining boundary is useful, but this head is not ready to merge yet:
Once those are in place, we can re-review the exact updated head. |
09f7936 to
9925970
Compare
|
Reviewed in depth. This closes a real gap that still exists on main today, the mechanism is the right one, and it needs a focused rebase rather than a rewrite. The gap is live. #1108 (File QNs keep the extension) merged on 16 July without any format boundary, and main has no format-version mechanism of any kind — I checked, there are zero The design choices are right, and two in particular are worth calling out.
And you caught the trap that would have made this useless: stamping both dump paths. If only the full path stamped, every incremental run would reset the marker and force a perpetual rebuild loop. Getting that right is the difference between a boundary and a footgun. On correctness in both directions, which is what I most wanted to check:
Your tests are binding. Run 1 fabricates a genuinely legacy graph — a collided QN node with Four things before it lands:
On the rebase: Your tests should port unchanged. Ping me when it is rebased and I will pick it straight back up — I would like this on main. |
|
Checking back in, and I want to be clear that this is still wanted rather than quietly dying. The gap is still live on main. I re-checked today: there is still no format-version mechanism anywhere in One correction I owe you first. In my last review I flagged The other three points from that review still stand: bind the incremental-path stamp with a test that actually fails if On the rebase — you have three options and I am happy with any of them.
My preference is 1 or 2, in that order, because the design is yours and the reasoning behind it is yours. If I do not hear back I will fall back to option 2 rather than let a live data-corruption gap sit unfixed — but I would much rather you told me which you want. For the record, the two design calls I most wanted to credit still hold up: |
|
I’ll take the rebase should have it up in a few days |
…ary Refs DeusData#769 Signed-off-by: LA-10 <[email protected]>
9925970 to
4d9da40
Compare
|
Rebased onto current main The main structural change: On your three points: Stamp binding. The stamp is now in Reopen failure as stamp failure. Migration visibility. Surfaced as Upgrade note for the release: the first index after upgrading rebuilds each project's graph once, since a pre-#1108 index holds collided File identities. Subsequent unchanged runs stay incremental. Tests: |
|
Merged in feb7208. Thank you, @LA-10 — this closes a real data-corruption window, and it closed it the careful way. Two things in here deserve explicit credit: The Collapsing to a single stamp site. My 07-31 review worried about a second, unbound stamp location drifting out of step. You made that concern structurally impossible instead of merely fixing it — every published generation now inherits one stamp at the publication choke point, so full, incremental and delta cannot disagree. That is a better answer than the one I asked for. I verified the important parts rather than taking them on trust:
Carried forward, not forgotten: every existing project rebuilds once on first index after upgrade. That was the accepted trade-off when we chose a boundary over an in-place migration, and your Sorry this took as long as it did to get over the line after your 08-25 rebase — the delay was mine, not yours. |
…efault The lean-output branch starts the raw logger at WARN so allocator setup cannot pollute protocol or CLI output before argv is classified. The index-format boundary's route record, `pipeline.route path=format_change_reindex`, was an INFO record, so a process that never applies the role policy (the test runner, an embedder) and every thin frontend at its default lost the only log-side evidence that an index was rebuilt once because its format changed (#1104) — the response's `format_migration:true` was unaffected. Log the migration route at WARN, like the sibling `invalid_existing_db` deviation: a once-per-upgrade full rebuild is exactly what explains a long index and a cursor reset. Signed-off-by: Martin Vogel <[email protected]>
…efault The lean-output branch starts the raw logger at WARN so allocator setup cannot pollute protocol or CLI output before argv is classified. The index-format boundary's route record, `pipeline.route path=format_change_reindex`, was an INFO record, so a process that never applies the role policy (the test runner, an embedder) and every thin frontend at its default lost the only log-side evidence that an index was rebuilt once because its format changed (DeusData#1104) — the response's `format_migration:true` was unaffected. Log the migration route at WARN, like the sibling `invalid_existing_db` deviation: a once-per-upgrade full rebuild is exactly what explains a long index and a cursor reset. Signed-off-by: Martin Vogel <[email protected]>
What this does
#1108 made File-node QNs keep the extension, but shipped without a compatibility boundary. So on
main, an index built before #1108 keeps its old collided QNs, and the next incremental run only updates changed files, mixing old and new identities (duplicate nodes, stale edges).This adds a persisted format marker (
PRAGMA user_version). A stale-format index goes through the existing full-reindex path once (keeping ADR/metadata, per #516) and is stamped so the next unchanged run stays incremental. No in-place migration an old collided DB can't reconstruct the missing siblings safely.Notes
cbm_writer_openrebuilds the DB file on every dump, so the stamp is written on both dump paths; otherwise every incremental run resets the marker and forces a rebuild.test_incremental.ccatches that.fqn.cis unchanged fix(fqn): preserve full filename in File-node QNs so sibling files don't collide #1108 owns that fix. This is only the boundary.Tests (
tests/test_index_format.c, in the gatingtestsuite)search_codecoverage