Skip to content

fix(coord): count a FETCH_HEAD as origin/main's clock only when it names that ref (BACKLOG #1374) - #871

Open
wshallwshall wants to merge 2 commits into
mainfrom
claude/fleet-clock-1374
Open

fix(coord): count a FETCH_HEAD as origin/main's clock only when it names that ref (BACKLOG #1374)#871
wshallwshall wants to merge 2 commits into
mainfrom
claude/fleet-clock-1374

Conversation

@wshallwshall

Copy link
Copy Markdown
Collaborator

Closes the stated remainder of BACKLOG #1374.

Most of #1374 was ALREADY ON MAIN before this branch

Verified with git merge-base --is-ancestor 3279141e2 origin/main, not inferred from the PR being
closed. PR 774 at 3279141e2 already shipped:

  • the clock reading a FETCH_HEAD mtime instead of the refs/remotes/origin/main ref file;
  • the sweep across <common> and every <common>/worktrees/* git dir;
  • the unmeasurable case as an explicit STOP, and the (null) sentinel in the text receipt;
  • tests/test_coord_fleet_fetch_clock.py, nine Windows-gated arms.

None of that was rebuilt. The item's banner said "NOT merged" and its scoring note said "Not
started" while the code was on main; both were false and both are corrected here.

What this branch adds: a fetch clock is not a main clock

FETCH_HEAD means "a fetch happened", not "origin/main was refreshed". git fetch origin refs/pull/N/head, or a fetch of another remote, bumps the mtime and leaves the ref alone, so the
field could read FRESH against a stale ref -- the dangerous direction. The item said the file names
what it fetched and that closing this was possible; it was stated as a limit and not attempted.

A FETCH_HEAD now counts only if it NAMES origin's main: branch 'main' of <origin url>.

Measured in a sandbox 2026-09-04, one fetch form per run:

form description git writes counts?
git fetch origin branch 'main' of <url> yes
git fetch origin main branch 'main' of <url> yes
git fetch origin refs/heads/main branch 'main' of <url> yes
git fetch origin refs/pull/7/head 'refs/pull/7/head' of <url> no

Two traps, both measured and both pinned by their own arm:

  1. git STRIPS the .git suffix from the url it writes. git remote get-url origin returned
    .../up.git where FETCH_HEAD in the same clone said .../up. A literal compare never matches,
    and the failure is silent -- everything goes UNMEASURABLE.
  2. The file is REWRITTEN, not appended. git fetch origin main then git fetch origin refs/pull/7/head left a one-line FETCH_HEAD naming only the pull ref, six seconds newer, main
    line gone.

When nothing qualifies the field goes null rather than falling back to the newest clock. That
fallback is the tempting line and it would restore the exact defect. The two roads to null get
DIFFERENT stops, because "no FETCH_HEAD exists anywhere" is a false sentence in a clone that just
fetched a pull ref, and an instrument caught in an obvious lie stops being read at all.

git ls-remote origin main stays DECLINED, for the reason the item already records: this is a pure
reader a stranded session runs, so a network round-trip per render adds the failure mode the
instrument exists to survive.

Renamed a second time, and why

lastFetchAgeMinutes -> originMainFetchAgeMinutes, lastFetchClock -> originMainFetchClock.

lastFetchAgeMinutes timed a real fetch but ANY fetch. With a pull-ref fetch one minute old beside
a main fetch three hours old the honest value of this field is 180, which the name contradicts -- a
name fighting its own value is how this item started. Nothing outside docs/BACKLOG.md and this
script's own test read either retired key, rechecked over this repo and the vault's origin/main
with originMainSha as the positive control that the search could see the files. Both retired keys
are pinned absent.

Tests

Five new arms in TestOnlyAFetchOfOriginMainCountsAsTheClock, positive control first. Every one
was shown to redden under a mutation of the seam it covers
, with each mutation asserted to have
actually applied so a no-op patch could not read as a passing test:

mutation arms that went red
newest clock wins, regardless of what it fetched 3 of 3 targeted
literal url compare (stop stripping .git) the positive control
drop the url compare entirely the different-remote arm
one sentence for both blind states the two-sentence arm

Checks run

check result
ruff check . pass
ruff format --check . pass
mypy messagefoundry (strict) pass, 267 files
pytest tests/test_coord_fleet_fetch_clock.py 14 passed
affected coord + tooling-gate suites (6 files) 88 passed
scripts/docs/backlog_status_check.py pass, 664 items
pre-commit (both commits) pass

tests/test_coord_fleet_fetch_clock.py was already in tests/tooling_manifest.txt, so rule 5 needs
no new line. Legs that only run on a hosted runner were not seen from here and need reading after
merge.

Not done, deliberately

The banner stays open. A closure banner asserts a verified landing with a sha, and this half has
none yet, so the flip stays the Lander's. The summary row moves to partly shipped, the file's
existing vocabulary for this state.

🤖 Generated with Claude Code

wshallwshall and others added 2 commits September 4, 2026 18:14
…mes that ref (BACKLOG #1374)

The stated remainder of #1374. FETCH_HEAD means "a fetch happened", not "origin/main was
refreshed": `git fetch origin refs/pull/N/head`, or a fetch of another remote, bumps the mtime
and leaves the ref alone, so the field could read FRESH against a stale ref -- the dangerous
direction.

git records WHAT it fetched, one line per ref, so `branch 'main' of <origin url>` is the evidence
and nothing else qualifies. Measured in a sandbox 2026-09-04: `git fetch origin`, `git fetch
origin main` and `git fetch origin refs/heads/main` all write that line, while `git fetch origin
refs/pull/7/head` writes `'refs/pull/7/head' of <url>` -- no `branch` prefix, no mention of main.

Two traps, both measured and both pinned. git STRIPS the `.git` suffix from the url it writes
(`remote get-url` returned `.../up.git` where FETCH_HEAD said `.../up`), so a literal compare
never matches. And it REWRITES the file rather than appending, so a pull-ref fetch destroyed the
earlier main line six seconds later.

When nothing qualifies the field goes null rather than falling back to the newest clock. The
fallback is the tempting line and it would restore the exact defect. The two roads to null get
DIFFERENT stops, because "no FETCH_HEAD exists anywhere" is a false sentence in a clone that just
fetched a pull ref, and an instrument caught in an obvious lie stops being read at all.

Renamed a second time, to originMainFetchAgeMinutes/originMainFetchClock. `lastFetchAgeMinutes`
timed a real fetch but ANY fetch: with a pull-ref fetch one minute old beside a main fetch three
hours old the honest value is 180, which the name contradicts. Nothing outside docs/BACKLOG.md
and this script's test read either retired key -- rechecked over this repo and the vault's
origin/main, with originMainSha as the positive control -- and both are now pinned absent.

Five new arms, each shown to redden under a mutation of its own seam: newest-clock-wins, a
literal url compare, dropping the url compare, and one sentence for both blind states.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…de was on main

Both were false. PR 774 merged the first two halves at 3279141 on 2026-09-04, verified with
`git merge-base --is-ancestor` against origin/main rather than inferred from the PR being closed.
The scoring note still said "Not started" and the banner still said "NOT merged", so a Builder
briefed off either would have rebuilt shipped work.

The stated remainder is recorded as built on claude/fleet-clock-1374 and unmerged. The banner
stays open on that strength; a closure banner asserts a verified landing and this half has none
yet, so the flip stays the Lander's.

The status cell moves to "partly shipped", the file's existing vocabulary for exactly this state.
The full statement lives in the item's banner and the two summary lines point at it rather than
restating it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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