fix: detect edge index changes by ref object ID - #1
Open
mparrett wants to merge 1 commit into
Open
Conversation
ensure_edge_index_current decided which issues to re-parse by comparing each note ref's commit date against a wall-clock marker. That misses changes two ways. The comparison was lexical between incompatible formats. %(committerdate:iso-strict) renders the offset recorded in the commit, so 2026-08-02T22:26:21-07:00 sorts below 2026-08-03T05:26:20Z despite being a second newer. More fundamentally, a commit date does not say when a ref changed locally. A note arriving by fetch or import keeps the date it was written with, which can predate the marker, so its dependency headers are skipped permanently. The post-merge hook fetches issue notes on every pull, so this is the ordinary sync path rather than a corner case. Snapshot issue ref object IDs in a sibling blob of the edge index and re-parse the refs whose ID moved. Object IDs change whenever a ref does, however it moved and whatever date it carries. Refs that disappeared have their edges dropped. An index with no snapshot reads as "everything changed" and rebuilds in full, so an older index heals on first read with no migration step. Two regression tests cover it: an out-of-band header edit with TZ pinned west of UTC, and an edit backdated with GIT_COMMITTER_DATE. Both fail against the previous implementation in every timezone tested. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
mparrett
force-pushed
the
fix/edge-index-timestamp-comparison
branch
from
August 4, 2026 04:50
b353dba to
5e015cf
Compare
Author
|
@nnunley Thanks again for sharing your project. I have a few bug fixes if you're interested. This is the first. |
Owner
|
Awesome. Glad you're trying it out and finding gaps. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
ensure_edge_index_currentrefreshes the derived dependency graph atrefs/notes/dep-graphbeforedeps,ready, andtoporun. It decided which issues to re-parse by comparing each note ref's commit date against a wall-clock marker stored in the index, which misses changes two ways.The comparison was lexical between incompatible formats.
%(committerdate:iso-strict)renders the offset recorded in the commit, so a ref written at2026-08-02T22:26:21-07:00sorts below a marker of2026-08-03T05:26:20Zdespite being a second newer.More fundamentally, a commit date does not say when a ref changed locally. A note arriving by fetch or import keeps the date it was written with, which can predate the marker, so its dependency headers are skipped permanently.
hooks/post-mergefetches issue notes on every pull, so this is the ordinary sync path rather than a corner case.The symptom is the same either way. Dependency headers are the documented source of truth, and the graph silently disagrees with them. Anything editing a header outside
dep add/dep rm—git issue update --blocks=,git issue import, or a fetched note — becomes invisible to the graph:This is easy to miss, because the index self-heals while it has no cursor. The guard short-circuits on an empty marker, so the first graph query after
add_edgerebuilds from headers and installs one. Every query after that is affected.dep rebuildrepairs the index but reinstalls the cursor, so it is a one-shot.What
Snapshot issue ref object IDs in a
refsblob beside the existingedgesblob, and re-parse the refs whose ID moved. An object ID changes whenever a ref does, however it moved and whatever date it carries. Refs that have disappeared have their edges dropped.The snapshot lives in a sibling blob rather than in the edges text, so existing readers of the index are unaffected. An index with no snapshot reads as "everything changed" and rebuilds in full, so an existing index heals on first read and there is no migration step.
Verification
Two regression tests in
tests/test_deps.sh, both failing before this change and passing after:TZpinned west of UTC so the note records a negative offset and the lexical comparison fails on any hostGIT_COMMITTER_DATE, covering the fetched-note case, which fails on a date cursor in every timezoneBoth were run against the parent commit under
America/Los_Angeles,UTC,Europe/Berlin, andAsia/Tokyoto confirm they fail everywhere rather than only in one offset.tests/test_deps.shgoes from 55 to 59 assertions; the other suites are unchanged.tests/test_github_integration.shfails both before and after this change, unrelated to it.