fix(pipeline): preserve ADRs during incremental reindex - #992
Conversation
d0d5b24 to
3852990
Compare
|
Thanks for the ADR persistence fix. I have triaged this into 0.9.1-rc as a normal-priority UX/behavior bug fix. Review focus will be ADR state across incremental DB replacement and making sure we do not restore stale summary data by accident. |
|
Thanks. |
|
Reviewed and verified — this is correct and ready; it just needs a rebase onto current main (which moved since you opened it). I did the rebase locally to confirm the resolution and that the fix still works, so here's exactly what's needed: Verified: both The only conflict is in /* #992: restore the captured ADR before persisting hashes, mirroring the
* full-reindex path (#516) — the DB replacement above dropped it. */
if (saved_adr && cbm_store_adr_store(hash_store, project, saved_adr) != CBM_STORE_OK) {
cbm_log_error("incremental.err", "msg", "adr_restore", "project", project);
}
bool hash_records_complete = persist_hashes(hash_store, project, files, file_count,
mode_skipped, mode_skipped_count);(Your Rebase onto current main with that resolution and push; once it's green I'll merge immediately. Thanks — preventing ADR loss on the incremental path is a genuine data-safety fix, and mirroring #516's invariant is exactly right. |
3852990 to
207e9a5
Compare
|
Rebased onto current Resolved the Local verification:
I could not run Thank you. |
|
Reviewed, and I want to lead with this: your premise is correct and this is a real user data-loss bug. I verified it from the code rather than taking the description's word for it, because a data-loss claim deserves that.
The full-reindex path already protects them via the #516 work at Two more things I checked that you got right:
What I need before it can merge: a rebase, plus one thing to watch while you do it.
The hazard: a straightforward rebase that keeps capture-at-the-top and One optional hardening: nothing in the test asserts which route was actually taken, so a future change to the routing thresholds could quietly turn it vacuous. Asserting the Two last notes, both pre-existing and shared with the #516 path rather than introduced by you: the restore resets Rebase it and I will pick this straight back up — the fix itself is right and I would like it on main. |
Signed-off-by: Mustapha <m88e54ik@gmail.com>
207e9a5 to
5bb238e
Compare
|
Thanks for the thorough review. The exact failure analysis and the warning about the new early returns made the rebase straightforward. I’ve rebased #992 onto current I verified the signal on the rebased tree:
No unrelated changes were bundled. Thanks again for verifying the original data-loss path so carefully. |
|
A quick note so you are not left looking at two red checks wondering what you broke: neither is yours, and I have re-run them. Both failed inside the same minute, and both are network:
A re-run is the right fix here rather than a rebase: a re-run re-tests the same recorded merge commit, which is exactly what you want when the failure was a transient network blip rather than something stale in the base. Separately, thank you for the negative control. Removing only the ADR restoration and showing that the incremental-route assertion still passed before the ADR lookup returned The content review is in progress and I will come back with it shortly. |
|
Reviewed the rebased version in full. The two things I warned about last round are both genuinely fixed, and I verified them by enumeration rather than by reading the description. The single cleanup path holds. I walked every exit between the capture and the free:
There is no And the test binds for the right reason, which on this fix matters more than that it binds at all. Capturing One thing I would like changed before merge, and it is three characters. The ADR restore logs on failure but does not affect if (saved_adr && cbm_store_adr_store(hash_store, project, saved_adr) != CBM_STORE_OK) {
cbm_log_error("incremental.err", "msg", "adr_restore", "project", project);
}The coverage write forty lines below does the opposite: if (cbm_store_coverage_replace_ex(...) != CBM_STORE_OK) {
cbm_log_error("incremental.err", "msg", "persist_coverage", "project", project);
rc = CBM_STORE_ERR;
}So if the restore fails, the old database has already been unlinked, the ADR is not in the new one, and the reindex reports success. That is the same silent-data-loss shape this PR exists to remove, just in a much rarer branch — and it is inconsistent with the convention the surrounding code already follows. Adding I recognise there is a judgement call underneath it: failing the whole reindex because an ADR could not be restored costs the user their index refresh too. My view is that a loud failure is the right trade for a fix whose entire purpose is that user-authored content must not disappear quietly — but if you disagree, say so and I will take it to the maintainer rather than treat it as settled. On the two red checks: neither is yours, and I re-ran them — Worth stating plainly, since it has been open a while: this closes a real user-data-loss path. Incremental reindex was discarding user-authored ADRs, and a routine watcher-driven refresh was enough to trigger it. |
Signed-off-by: Mustapha <m88e54ik@gmail.com>
|
Thanks for catching this. I agree that an ADR restore failure needs to fail the incremental index instead of continuing successfully. I pushed the follow-up in The change now records the restore failure, completes the remaining staging maintenance, and returns the existing I also forced this failure path locally. The probe confirmed that the route was incremental, the replacement dump ran, the operation returned failure, and the original ADR remained byte-identical. After removing the injection, the normal sanitized pipeline suite passed at 239/239. Thanks for pointing out the silent-success gap. |
What does this PR do?
Preserves
manage_adrcontent whenindex_repositorytakes the incremental reindex path.This is a follow-up to #516. The full reindex path already captures ADR content from
project_summaries.summarybefore replacing the SQLite DB and restores it afterward. The incremental path also replaces the DB indump_and_persist(), but it only repersisted graph data, file hashes, coverage rows, and FTS state. Any ADR stored throughmanage_adrwas therefore silently dropped on the next incremental rebuild.The failure shape is:
manage_adrmodeupdate.get; content is present.index_repositoryroutes through incremental reindex.project_summarieswas recreated without the previoussummary.This PR mirrors the full-reindex preservation behavior in
src/pipeline/pipeline_incremental.c:cbm_gbuf_dump_to_sqlite()recreates the DB and it is reopened, write that ADR content back withcbm_store_adr_store();It also adds
pipeline_adr_survives_incremental_reindex, which indexes a tiny repo, stores an ADR, changes one existing file to force the incremental route, and asserts that the ADR content is still present afterward.This PR is intentionally scoped to ADR loss during incremental reindex. It does not attempt to address any separate stale-WAL/listed-but-unqueryable project lookup behavior.
Verification
git fetch origin mainand rebase onto currentorigin/main(6b57db2) succeeded without conflicts.make -j2 -f Makefile.cbm cbmsucceeded.manage_adr updatestored content;manage_adr getreturned the content;index_repositoryafter changing one file reported"adr_present":true;manage_adr getreturned the original content.make -j2 -f Makefile.cbm build/c/test-runnersucceeded.ASAN_OPTIONS=detect_leaks=0 build/c/test-runner pipelinereached and passed the newpipeline_adr_survives_incremental_reindextest, including thepipeline.route path=incrementalbranch.pipelinesuite still exits non-zero with an unrelated existing failure:pipeline_backpressure_futile_nap_disengagesattests/test_pipeline.c:6801(220 passed, 1 failed).Checklist
git commit -s) — required, CI rejectsunsigned commits (DCO, see CONTRIBUTING.md)
make -f Makefile.cbm test)make -f Makefile.cbm lint-ci)