Repository navigation
Description
Summary
Branch.head_sha in the graph does not update when re-indexing an already-existing project. It stays frozen at whatever commit was HEAD when the project was first created, even though the graph content itself (nodes/edges) updates correctly on re-index.
Environment
- cbm v0.9.0, linux-amd64 release, SHA-256 verified against
checksums.txt - Invoked directly via
cli(no MCP server auto-install), isolatedCBM_CACHE_DIR/CBM_ALLOWED_ROOTagainst a throwaway git repo
Repro (~5 commands)
-
Fresh index at commit A:
cli index_repository --repo-path <repo> --name smoketest
→MATCH (b:Branch) RETURN b.head_sha=A. Correct. -
Advance HEAD to commit B (real commit, e.g. adding a function). Re-index the same project (default mode):
cli index_repository --repo-path <repo> --name smoketest
→ graph content updates correctly (node/edge counts increase, new function present in the graph).
→Branch.head_shastill readsA— unchanged. -
Advance HEAD to commit C. Re-index explicitly with
--mode full:
→ graph content updates again correctly.
→Branch.head_shanow readsB— one commit behind the re-index that caused it, notC. -
Control:
delete_projectthen freshindex_repository(no prior project) at current HEAD:
→Branch.head_shacorrectly matches current HEAD immediately.
So the bug is specific to re-indexing an existing project — both default and --mode full — not to indexing itself.
Why this matters
Branch.head_sha (and index_status, which we separately confirmed reads live git HEAD rather than indexed-state — always "fresh," not useful either) are the two natural surfaces for a caller to answer "is the index actually caught up with the repo?" Neither gives a trustworthy answer in the normal long-lived-project + incremental-watcher-reindex scenario. A caller trusting Branch.head_sha as a freshness signal would see staleness silently understated forever after the first index, even while the watcher is correctly doing its job content-wise.
Suggested area to look
Whatever code path updates the Branch node's head_sha property likely only runs on project creation, not on the re-index/update path that touches node/edge content.
Activity
TheDarkniteFalls commentedon Jul 23, 2026
I traced this on current main (
5e7d3eb): the full structure pass upserts theBranchnode from the captured Git context, but both successful incremental paths bypass that update. The changed-file path refreshes affected graph content only, while the no-change path returns without touching the database.I can take a focused, test-first fix, subject to one contract check:
Branchmetadata on every successful incremental indexing invocation, including runs whose indexed file hashes do not change;Branchnode identity and edges, with no MCP schema orindex_statuschanges.Should
Branch.head_shamean “HEAD captured at the start of the successful indexing invocation,” matching the current full-index model, or should indexing detect a mid-run HEAD change and refuse/retry so the value is bound to one immutable repository state?I would validate the change with the focused pipeline tests, full sanitizer test suite, lint/security gates, and a DCO-signed commit. I use AI-assisted tooling under human review and would disclose that in the PR.
DeusData commentedon Jul 24, 2026
Thanks for tracing this to the incremental paths. The contract should remain consistent with a full index:
Branch.head_shameans the HEAD captured at the start of the successful indexing invocation. Both changed-file and no-change incremental success must update the existing Branch node. Detecting or retrying when HEAD moves during an active run is a stronger snapshot-consistency feature and should be handled separately, not folded into this fix. This is now a high-priority0.9.1-rccorrectness bug under #391.TheDarkniteFalls commentedon Jul 24, 2026
Thanks—that resolves the contract. I’ll keep the fix narrowly scoped to refreshing the existing Branch metadata on changed-file and no-change incremental success, with the temporary-Git regression test and no schema,
index_status, or mid-run snapshot changes.I noticed #1245 also substantially changes incremental indexing and touches the same pipeline. Would this still be useful as a separate focused 0.9.1-rc PR, or would you prefer it coordinated with or held pending that review?
TheDarkniteFalls commentedon Aug 21, 2026
Quick follow-up on the coordination question: #1245 remains a draft and currently conflicts with
main. Would a separate focused PR for the changed-file and no-changeBranch.head_sharefresh still be useful, or should #1213 remain held for #1245? I’ll keep implementation on hold until you confirm.DeusData commentedon Sep 25, 2026
@TheDarkniteFalls, thank you for tracing this to the incremental paths, and I owe you an apology: you asked twice whether to go ahead, and we never answered. @HorusScale, thank you for the tight A→B→C repro!
The good news is that this is fixed. On v0.11.0 I ran your exact sequence: index at A, commit a real change, re-index; then an empty commit, re-index.
Branch.head_shamatched HEAD after every run, including the no-change case. The incremental pipeline was reworked after this was filed and now refreshes the git context on every successful run.One thing would still be valuable if you're up for it, @TheDarkniteFalls: the temporary-git regression test you designed (A→B with a changed file, B→C with an empty commit, asserting
head_sha) doesn't exist yet. As a small test-only PR it would pin this contract so it can't quietly regress, and we'd be happy to review it quickly. @HorusScale, could you confirm on v0.11.0? Then we'll close this.TheDarkniteFalls commentedon Sep 26, 2026
Thanks for confirming the fix and inviting regression coverage. I’ve opened #2359 with the focused test-only extension.
Current main already includes the empty-commit/run-start refresh test, so this adds the initial-A and tracked-source-change-B assertions before its empty-commit-C step rather than duplicating the fixture. The existing route assertions remain, and there are no production or mid-run snapshot-consistency changes.
The full local test run passed (8,190 tests, zero failures, ten platform skips), along with the prescribed local lint gates and security checks. Written with OpenAI Codex assistance; details and platform limits are in the PR.
github-actions commentedon Sep 26, 2026
Thanks for the report! To move this forward we need a bit more so we can reproduce it ourselves:
codebase-memory-mcp --versionyou're onOnce that's here we'll pick it straight back up. Heads-up: issues left
awaiting-reporterare automatically closed after a few weeks of silence, but a comment reopens the door anytime.DeusData commentedon Sep 27, 2026
The requested A→B→C regression coverage is on
mainin 4f7fa84 (PR #2359, thanks to @TheDarkniteFalls). Thank you for the report!docs(fork): roadmap + community alignment sweep — phase-2 index econo…
feat(watcher): two-round confirmation + cooldown + index_status fresh…