Skip to content

bc-dgx7.37: B7e-head — Read a pull request's files at its head - #683

Open
mordam wants to merge 17 commits into
mainfrom
worktree-b7e-head-dgx737
Open

bc-dgx7.37: B7e-head — Read a pull request's files at its head#683
mordam wants to merge 17 commits into
mainfrom
worktree-b7e-head-dgx737

Conversation

@mordam

@mordam mordam commented Aug 24, 2026

Copy link
Copy Markdown
Owner

Adds b7e-head <pr-number>: reads a pull request's files at its head without ever
touching FETCH_HEAD or a branch, replacing the three different hand-built ways
bc-36xx.9, bc-zjab.12 and bc-36xx.22 each did this — two of which were silently wrong
(bc-36xx.9 fetched the branch, so a push mid-review moved the answer under it;
bc-zjab.12 fetched the branch into FETCH_HEAD too, and a concurrent session in the
same shared checkout overwrote it mid-build, so the sandbox it reviewed and ran a
suite against was main, not the pull request — found only by accident).

The fix underneath every mode (--file, --grep, --list, --tree): resolve the
head from gh pr view --json headRefOid — never a branch name — then, when the
tree is actually needed, git fetch --no-write-fetch-head origin <sha>, which pulls
the commit's objects in without writing FETCH_HEAD or any ref at all. --list never
even reaches git: GitHub's own files field on the same gh call is the whole
answer, so lib/pr.js gains a narrow headOf() alongside the existing card-facing
view(). --file/--grep/--tree reuse lib/gitref.js's readRefFile/git grep/
git archive, all already happy to take a bare sha instead of a ref.

Deliberately not on DEFAULT_TOOL_LIST, unlike its closest siblings b7e-prior/
b7e-siblings: every mode but --list shells out to git fetch, which lib/grants.js
already classifies write/repo, held by merge-advocate alone ("classified honestly
rather than waved through") — see the comment beside the toolbelt.js entry for the
full argument, and the README section for the rest.

Also fixes a real, separate bug hit while wiring --tree's git archive | tar -x
through this repo's supplier-egress sweep: egressProblems's command loop never
actually consulted a command-kind NOT_EGRESS entry (only the reverse "stale
exemption" check did), even though its own refusal sentence promises that path. Fixed
alongside registering tar.

What I'm unsure of: whether --tree is worth keeping at all now that bc-dgx7.38
(b7e-prtree) does a richer version of the same materialisation — see --risk above and
bc-dgx7.50, filed for that question rather than decided here. Also genuinely a guess:
the bead's own text for --grep ("this repo's roots and exclusions already decided,
same as b7e-grep would") names a command that does not exist in this tree, so I built
it as a plain git grep over the whole head tree with an optional -- <paths>
narrowing, documented as a deliberate choice in lib/head.js's own header.

Tests: node test/b7ehead.mjs (19/19) plus the full gate via bin/b7e-gate --jobs 6: 419/421, both reds pre-existing concurrency flakes unrelated to this diff (test/atomic.mjs — a kill -9 mid-write timing test that also fails standalone/alone; test/advswitch.mjs — passes standalone, 23/23). Also individually re-ran test/pr.mjs, test/lockfile.mjs, test/grants.mjs, test/anchors.mjs, test/suppliers.mjs, test/evidence.mjs, test/allowlist.mjs — all green.

Worth knowing: bc-dgx7.38 (b7e-prtree, PR #681, already on the merge queue as bc-z4fty) independently converged on the same core mechanism — resolve headRefOid, fetch one sha with --no-write-fetch-head, git archive|tar into a scratch dir — and fixed the identical dormant lib/suppliers.js bug (a command-kind NOT_EGRESS entry was never actually consulted) while registering the same tar exemption. If #681 lands first, this branch's downmerge may hit a real but trivial conflict on those few lines in lib/suppliers.js (same net effect, different wording) — the resolution is to keep either version, they say the same thing. Filed bc-dgx7.50 to consider consolidating b7e-head --tree into lib/prtree.js later; not blocking this delivery, since b7e-head's --file/--grep/--list modes read one file or search without materialising anything, which lib/prtree.js/b7e-prtree does not offer.

Files changed — 9 files · +927 −0 · against `main`
test/b7ehead.mjs   +374 −0
lib/head.js        +219 −0
bin/b7e-head       +182 −0
README.md          +75 −0
lib/pr.js          +41 −0
lib/toolbelt.js    +18 −0
lib/suppliers.js   +16 −0
package-lock.json  +1 −0
package.json       +1 −0

Opened by a beadcause worker session on bc-dgx7.37 — b7e-head — Read a pull request's files at its head, without a ref a sibling session can clobber. It merges itself once the checks report; merging is what closes the bead. If this is still open, something stopped that, and the reason is on bc-dgx7.37 and in Adam's inbox.

bead: bc-dgx7.37

…ut a ref a sibling session can clobber

Resolves the head from gh pr view --json headRefOid, fetches only that commit
with git fetch --no-write-fetch-head (no ref ever written), and reads it with
plumbing that already takes a sha: readRefFile for --file, git grep for
--grep, git archive|tar for --tree (keyed by head oid under os.tmpdir(),
node_modules symlinked in). --list is free off the same gh call: GitHub's own
files field, no git diff needed.

lib/pr.js gains headOf(dir, ref) for the narrow field set (headRefOid,
baseRefOid, files) kept off the card-facing PR_FIELDS on purpose.

Also fixes a dormant bug in lib/suppliers.js found while registering tar:
egressProblems' command loop never consulted a command-kind NOT_EGRESS entry
— only the reverse (stale-exemption) check did — so no such exemption could
ever have worked. Needed for lib/head.js's own tar spawn to pass test/suppliers.mjs.

Deliberately NOT on DEFAULT_TOOL_LIST: every read mode but --list shells out
to git fetch, which lib/grants.js already classifies write/repo, held by
merge-advocate alone. See the comment beside the entry in lib/toolbelt.js.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@mordam

mordam commented Aug 24, 2026

Copy link
Copy Markdown
Owner Author

A beadcause worker opened this and does not merge its own work. It is on the merge queue as bc-l7d07.

@mordam

mordam commented Aug 24, 2026

Copy link
Copy Markdown
Owner Author

The beadcause merge queue tried to merge this and could not: it has been tried 3 times and stopped at the same place each time. the branch still conflicts with main and no resolver is on it any more — the window that was opened on it ended without making it mergeable, so this one is yours to settle. Tried 3 times — that was the last. It is Adam's call now — see bc-l7d07.

# Conflicts:
#	README.md
#	lib/toolbelt.js
#	package-lock.json
#	package.json
# Conflicts:
#	lib/suppliers.js
#	lib/toolbelt.js
@NeanderthalMan

Copy link
Copy Markdown
Contributor

beadcause-resolver: stood down — worktree-b7e-head-dgx737 is locked by a live resolver (pid 45604, reason "resolver pid 45604 #683"); another window is already resolving this one, so I did not touch the tree.

@NeanderthalMan

Copy link
Copy Markdown
Contributor

beadcause-resolver: stood down — worktree-b7e-head-dgx737 is locked by a live resolver (reason "resolver pid 37482 #683"; ps knows that pid as a running claude, started 2026-08-24 22:42). Its tree is 31 commits ahead of origin and not mid-merge, so that window is still working. I did not touch or unlock it.

NeanderthalMan and others added 10 commits August 25, 2026 08:04
# Conflicts:
#	package-lock.json
#	package.json
The merge of origin/main brought in the b7e-dup section, which landed in
the same slot this branch adds b7e-head to. Both stay, but the order is
not free: the b7e-head section says "unlike b7e-prior just above", so it
has to sit directly after b7e-prior. b7e-dup makes no positional claim
and follows it.

Co-Authored-By: Claude Opus 5 (1M context) <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.

2 participants