Repository navigation
fix(auto_ensure,inspect): serve pre-index edits when the head_sha sidecar is lost; read the L1 overlay in inspect - #863
Conversation
…lost admin index wrote graph.bin.head_sha on a detached thread nothing joined. A fast exit left it missing or empty, git_fingerprint_shortcut returned None, and the mtime walk reported Ready because it cannot see files older than graph.bin. No overlay was written, so an untracked file left out of the commit-keyed graph stayed unfindable (CI flake in an_untracked_file_stays_out_of_the_commit_keyed_graph on macOS/Windows). - The shortcut also accepts a graph whose commit-dir name is HEAD; with neither a sidecar nor a parseable dir it still returns before any git call. - write_head_sha_sidecar_with_sha writes synchronously, like write_builder_fingerprint_sidecar. - Tests: sidecar missing/empty at HEAD, other-SHA sidecar at HEAD, graph behind HEAD with sidecar lost, and the l1 integration case.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
ecp impact cache (0 symbols) — internal, used by
|
Pull request was converted to draft
…mpact inspect still read the legacy load_overlay + merge_archived layer and always answered with the base node: a symbol in a dirty file showed its committed span, a new symbol was "not found", and a deleted one stayed inspectable. Search and every block section now run over MergedGraph built from engine.overlay_view(). A same-uid redefinition of a non-overload symbol is listed once, as the index keeps it. - Delete the legacy layer with no production caller left: Overlay, merge_archived, MergeIter, load_overlay, load_overlay_hits, OverlayHit, for_each_fragment and the tests that exercised only them. - MergedNode::file_path uses files.get instead of indexing. - tests/inspect_overlay_view.rs: 14 languages, dirty-tree inspect must equal inspect after commit + reindex. Resolves FU-2026-06-10-a8af472d45f7.
Why
Outcome. A file created or edited before
ecp admin indexis now served by the L1 overlay even when thegraph.bin.head_shasidecar is missing or empty:ecp find untracked_fnanswers"found":trueinstead of"found":false. This fixes the macOS (#862) and Windows (#861 run on 121cc51) failures ofan_untracked_file_stays_out_of_the_commit_keyed_graph. Door: two-way. No stored format changes; a revert restores the old reader and the detached write. Blast radius:git_fingerprint_shortcut→ensure_index(every query's freshness check; upstreamensure_fresh_with_rebuild,check_inin doctor,maybe_reindex_noticein the post-tool-use hook,fetch_freshnessin summary; 77 transitive).write_head_sha_sidecar_with_shahas 3 callers (build publish, fingerprint attach, overlay refresh).admin indexwrote the HEAD-SHA sidecar on astd::thread::spawnthat nothing joined. When the process exited first, the sidecar was missing or 0 bytes.git_fingerprint_shortcutthen returnedNone, andensure_indexfell back to the mtime walk, which cannot see files older thangraph.bin. The result wasReady, so no overlay fragment was written, and every later query kept answeringfound:false. Reproduced 100% on 0.16.2 and on main by deleting or truncating the sidecar afteradmin index. The race predates #861.Second fix in this PR (FU-2026-06-10-a8af472d45f7):
ecp inspectignored the L1 overlay thatfind,impactandcypheruse. It read the legacyload_overlay+merge_archivedlayer and always answered with the base node. On a dirty Rust file, a function shifted 6 lines reported its committed span (6-8 instead of 12-14), a new function answeredSymbol 'shortcut' not found, and a deleted one stayed inspectable. Door: two-way (no stored format changes; overlay fragments are read through the sameaccepted_fragmentspath as before). Blast radius:inspect::run/search_nodes/build_inspect_block(theecp inspectcommand and the MCP inspect tool);MergedNode::file_path(shared by impact and cypher, nowfiles.getinstead of an index panic on a malformed graph).What changed
git_fingerprint_shortcutalso accepts a graph whose commit-dir name (commit_dir_sha) is HEAD. The dir is published by the same atomic rename asgraph.bin, andgraph_behind_headalready treats the name as the authority. With neither a sidecar nor a parseable dir, it still returnsNonebefore any git call, so a legacy layout pays nothing new.write_head_sha_sidecar_with_shawrites synchronously, aswrite_builder_fingerprint_sidecaralready does for the same reason. The compatible-version sidecar stays detached: its loss only costs a header validation.wait_for_sidecaris deleted; the write it waited for is synchronous now.MergedGraphbuilt fromengine.overlay_view(): a surviving dirty symbol reports its worktree span and overlay edges (clean callers included), an overlay-only symbol gets a full block, a deleted one is not found. A same-uid redefinition of a non-overload symbol is listed once, as the index does. Sections that need base-only data degrade to honest empty values for an overlay-only symbol:blind_spotsempty, decorators from the base twin, contained members miss members the edit added (overlay builds no containment edges).Overlay,merge_archived,MergeIter(ecp-core),load_overlay,load_overlay_hits,OverlayHit,for_each_fragment(ecp-cli),overlay_merge_zero_copy.rsand the two tests that exercised onlyload_overlay_hits.tests/inspect_overlay_view.rs, 14 languages. Oracle:inspecton the dirty tree equalsinspectaftergit commit+admin index(file, span, Calls names both ways) forcallerandfresh;doomedis not found. Plus namesakes in clean and dirty files, owner filter on a dirty method, toon output, clean tree with a session.How to verify
Red before, green after (source files swapped to
HEAD, tests kept):auto_ensure::test_ensure_index_head_sha_sidecar_lost_graph_at_head_reports_prior_edits_stale(missing and empty sidecar, untracked + tracked edits older than graph.bin)got Readyauto_ensure::test_ensure_index_head_sha_sidecar_other_sha_graph_at_head_reports_untracked_stalel1_overlay_integration::test_find_head_sha_sidecar_lost_after_index_untracked_file_found{"found":false,...,"total_candidates":0}inspect_overlay_view(5 tests, 14 languages)Symbol 'fresh' not found,(2, 4)base spaninspect::tests::test_search_nodes_same_uid_redefinition_lists_first_onlyleft: [7, 8]auto_ensure::test_ensure_index_head_sha_sidecar_lost_graph_behind_head_reports_stale(guard: a dir naming an older commit must not take the shortcut)dir_sha.is_none()cargo test -j 4 -p egent-code-plexus --tests: 2185 passed, 0 failed;cargo test -j 4 -p ecp-core: 587 passed (6merge_archivedtests deleted with it);cargo test -j 4 -p ecp-mcp: 51 passed.cargo clippy -j 4 -p egent-code-plexus --testsand-p ecp-core --tests: 0 warnings.deep-review(Correctness, Quality, Efficiency) and codex. Every finding at 50+ is fixed: the stale perf-hint doc, two untested states, the synchronous write. The l1 test now derives sidecar paths fromgraph.binand asserts that a graph was published.deep-review(Correctness, Efficiency) and codex. Clean-tree output is identical to HEAD field by field; the no-overlay path adds no allocation and drops HEAD's secondbase_constructorscall and its all-node uid map. Fixed: same-uid duplicate listing (65), dead legacy reader and its stale docs (55). Filed: FU-2026-10-24-0d2a9372c6a7 (find and cypher keep the same-uid duplicate; pre-existing).