Skip to content

An unfinished scan answered with silence, which reads as "no records here" - #778

Merged
MongLong0214 merged 1 commit into
mainfrom
inject-partial-silence
Aug 18, 2026
Merged

An unfinished scan answered with silence, which reads as "no records here"#778
MongLong0214 merged 1 commit into
mainfrom
inject-partial-silence

Conversation

@MongLong0214

Copy link
Copy Markdown
Owner

Closes the third recommendation on #776.

buildInjection returned an empty payload whenever a path had no active records — including when the scan stopped at its budget before reaching the commits that hold them. The caveat existed, on stderr, which a model reading additionalContext never sees.

So two different answers arrived identically:

a repository with nothing recorded for this path
a repository this tool had not finished reading

That distinction is the one CommitLore keeps everywhere else — coverage: partial, history: unavailable and notes: unfetched are separate states precisely so absence is never read as evidence. The surface a model actually consumes was collapsing them.

Where it bit

A freshly materialized worktree: 588 commits unread, zero bytes out, and a benchmark ON arm that recorded it as a hook which had never fired. The arm looked configured and was untreated, and nothing in the row said otherwise.

Two early returns, not one

:856   if (active.length === 0) return empty;                       ← the one that fires in a fresh clone
:899   if (entries.length === 0 && withheld.length === 0) …          ← the one I fixed first

A fix at the second alone passes review and changes nothing. Found by driving it rather than reading it: with scanBudgetMs: 0 the payload stayed at zero bytes after the first attempt.

Both now go through one helper. Silence is kept where it is right — a complete scan with nothing to say still costs nothing, and this hook fires on every Read.

What the payload says now

incomplete: the scan stopped at its time budget with 40 commit(s) unread. treat the
list above as some of what applies here, not all of it: records in those commits are
missing, and because supersession and expiry are recorded in commits like any other
record, one shown as active may since have been withdrawn.

Verified

Driven by scanBudgetMs so the partial state is constructed rather than raced for — reproducing it by clone-and-hope is the very non-determinism the defect is about, and one attempt at that returned 3281 bytes because the budget happened to reach the right commits that time.

budget 0, before   0 bytes
budget 0, after    830 bytes, included 0, notice present
no budget          unchanged — records returned, no notice
reverting either return   fails the notice test, other two still pass

98 tests pass across the three inject suites. artifact:verify passes against the regenerated manifest.

Limit (on the commit): this says the scan was cut short, not which records were missed — the payload cannot name what it never read.

…here"

`buildInjection` returned an empty payload whenever a path had no active
records -- including when the scan stopped at its budget before reaching the
commits that hold them. The caveat existed, on stderr, which a model reading
`additionalContext` never sees.

So the two answers arrived identically:

  a repository with nothing recorded for this path
  a repository this tool had not finished reading

That distinction is the one CommitLore keeps everywhere else. `coverage:
partial`, `history: unavailable` and `notes: unfetched` are separate states
precisely so absence is never read as evidence, and the surface a model
actually consumes was collapsing them.

Found in a freshly materialized worktree: 588 commits unread, zero bytes out,
and a benchmark ON arm that recorded it as a hook which had never fired -- the
arm looked configured and was untreated. Filed as #776.

There were two early returns, not one. The first, on `active.length === 0`, is
the path that actually fires in a fresh clone, and a fix at the second alone
would have passed review and changed nothing. Both now go through one helper.

Silence is kept where it is right: a complete scan with nothing to say still
costs nothing, and this hook fires on every Read.

Limit: this says the scan was cut short, not which records were missed -- the payload cannot name what it never read
Blast: module
Undo: easy
Certainty: firm
Record-Id: r-partialsilence
Provenance: authored
Verified: driven by scanBudgetMs so the partial state is constructed rather than raced for -- reproducing it by clone-and-hope is the non-determinism the defect is about; reverting either return fails the notice test and leaves the other two passing
CommitLore-Version: 2.0.0
@github-actions

Copy link
Copy Markdown

CommitLore — record lint

Trailers: clean — 1 commit in origin/main..9553e2c25ac71c3f361e20b330c848f0bcec6c5c
Active constraints: not read — commitlore: git log --follow accepts exactly one pathspec, so renames are not followed for 6 paths; query one path at a time to follow its rename chain (6 changed paths)

Trailer violations fail this check. Active constraints are informational — they are what the repository already decided, not a verdict on this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant