Repository navigation
finding(devx): the other 7 ported .claude/hooks/** files all carry EXECUTABLE drift from the pinned upstream ref, and 2 of them do not exist at it — the ledger cannot reach them under one global upstream.ref #7953
Description
Measured while landing the first .claude/hooks/** entry in scripts/upstream-port-pin.json. Part of #7263, which registered exactly one file and ruled the other hooks out of its own scope. Filed unassigned.
What was measured
Every file in .claude/hooks/ diffed against the upstream blob at the ref the pin already names, objectstack-ai/objectstack@bf10debd587f6ba891be9eadc2b76c91e15bd82b, and against upstream origin/main at a4816a79d. Differing lines are counted from a zero-context unified diff and split into executable and comment/blank by first non-space character. (The one row corrected after filing: this file vs upstream main, first written from a context-merged count.)
| hook | vs the pin's ref bf10debd5 |
vs upstream main a4816a79d |
|---|---|---|
guard-main-checkout.selftest.sh |
REGISTERED by #7263 — 14 declared divergences | 102 lines (40 exec / 62 comment) |
guard-main-checkout.sh |
67 lines (38 exec / 29 comment) | 39 lines (19 exec / 20 comment) |
guard-main-checkout-bash.sh |
78 lines (8 exec / 70 comment) | 111 lines (22 exec / 89 comment) |
guard-main-checkout-bash.selftest.sh |
17 lines (14 exec / 3 comment) | 93 lines (62 exec / 31 comment) |
guard-shared-stash.sh |
101 lines (23 exec / 78 comment) | 109 lines (22 exec / 87 comment) |
guard-shared-stash.selftest.sh |
61 lines (31 exec / 30 comment) | 108 lines (50 exec / 58 comment) |
guard-tree-enum.sh |
absent upstream at that ref | 17 lines (7 exec / 10 comment) |
guard-tree-enum.selftest.sh |
absent upstream at that ref | 55 lines (37 exec / 18 comment) |
Why this is the real work, and why it is not a bounded edit
-
Not one of them is a comment-only port. finding(devx):
upstream-port-pin.jsoncovers onlyscripts/, so the verbatim cross-repo ports under.claude/hooks/**have no drift gate — the same shape #6642 measured at ~212 KB #7263's body measured its one candidate at "exactly 4 declared divergences, all comment / echo-label text, no executable line differs". That was true of that file on the day it was measured and is true of no other hook here. Each remaining entry needs a divergence set whose text pairs cover executable code, with a one-sentencewhyper pair — which is the work finding(devx):upstream-port-pin.jsoncovers onlyscripts/, so the verbatim cross-repo ports under.claude/hooks/**have no drift gate — the same shape #6642 measured at ~212 KB #7263 called "real work and the actual value", because writing it down is what turns "this line differs because someone decided so" from memory into ledger. -
Two of them cannot be registered at all right now.
guard-tree-enum.shand its self-test do not exist in upstream's tree atbf10debd5; they arrived upstream later. The pin carries ONEupstream.reffor every entry (validatePinrequires it to be a single 40-character commit sha, and--resyncrewrites that one field), so registering them means either moving the pin's ref for all entries — which re-derives the three existing entries — or giving an entry its own ref. Both are schema-or-scope decisions, not implementation details, which is why this is filed rather than done. -
A green ledger row is a statement about the PINNED blob, not about upstream today. The row finding(devx):
upstream-port-pin.jsoncovers onlyscripts/, so the verbatim cross-repo ports under.claude/hooks/**have no drift gate — the same shape #6642 measured at ~212 KB #7263 landed readsbyte-identical to objectstack-ai/objectstack@bf10debd5 … modulo 14 declared divergence(s)and is exactly true. Against upstreammainthe same file differs by 98 further lines, two of which are live and already tracked: theslash-worktrees-slashsubstring hole (finding(hooks):guard-main-checkout.shreads any git-dir path containing/worktrees/as a linked worktree — a PRIMARY checkout under a dir namedworktreesis unguarded, and by DEPTH #7259, PR fix(hooks): a linked worktree is one whose git-dir differs from its git-common-dir #7749 in flight) that upstream has closed, and the escape-hatch remedy sentence (hooks: the four guards' refusal messages advertisere-run with OS_ALLOW_*=1, a command prefix that cannot reach the hook's environment — twin of objectstack#15971 #7775, twin of objectstack#15971). Whoever takes this card should decide whether bumping the pin's ref toward current upstream comes first — that decides how much of the divergence work above survives.
Not asserted here
Whether the answer is per-entry refs, a ref bump, or registering only the hooks that are stable. #7263 ruled the scope question (the ledger MAY register governed files; --resync refuses to write them without a named flag) and deliberately left the enumeration open.
Filed by an automated developer session (Claude Code, PM round R44) while working #7263; no assignee, no priority label set.
Generated by Claude Code
Activity
os-zhuang commentedon Sep 7, 2026
Triage: closing
not planned— outside the three admission classes (#16351, as refined by PR #16557).Against each class:
byte-identical to …@bf10debd5 … modulo 14 declared divergence(s)).check-upstream-port-parityreports per registered entry; an unregistered file is simply not mentioned, so nothing reads as "the hooks are in sync".p3today), which is admitted — there the gate prints a false provenance line for files it has registered. ⇒ Silence about unregistered files is not an over-claim; a wrong sentence about registered ones is.⇒ Coverage extension: register 7 more files in a ledger that correctly covers 1.
⭐ The measurement is excellent and survives the close as the ready-made worklist — every hook diffed against both the pinned ref and upstream
main, with differing lines split exec/comment by first non-space character, and ⭐ a correction recorded in the card itself (one row was first written from a context-merged count and re-measured). ⇒ The table is trustworthy and nobody re-derives it.承接者 for the parts that matter: ⛔ not this card, and that is the point. The two divergences from upstream that are live are already tracked on their own cards — the
slash-worktrees-slashsubstring hole (#7259, with PR #7749 in flight) which upstream has already closed, and the escape-hatch remedy sentence (#7775, twin of objectstack#15971, and the card objectui#8287 was closed into today). ⇒ Closing this loses no live defect; it closes an enumeration.⭐ The sequencing fact worth carrying, because it is load-bearing and cross-repo: this card's item 2 — that
guard-tree-enum.shand its self-test do not exist upstream atbf10debd5and so cannot be registered at all — is blocked on exactly the schema change objectui#8288 proposes (a per-fileref, sincevalidatePinrequires one 40-char sha and--resyncrewrites that single field). ⇒ Those two cards are the same problem seen from both ends: #8288 from the gate prints a false line side, this one from the two files cannot be registered side. #8288 is graded and queued; when it lands, this table is the worklist. ⛔ Do not attempt the ledger extension before it — under one global ref, registering these means either moving the ref for all entries (re-deriving the three existing ones) or inventing per-entry refs ad hoc, and both are the schema decision #8288 owns.What I am uncertain about: whether the pin's ref should be bumped toward current upstream first. The card raises it and is right that it decides how much of the divergence work survives — against
mainthe registered file alone differs by 98 further lines. ⛔ Not resolved here, and it is a live input to whoever eventually takes #8288.Reopen conditions (either, no approval needed):
guard-main-checkout.shreads any git-dir path containing/worktrees/as a linked worktree — a PRIMARY checkout under a dir namedworktreesis unguarded, and by DEPTH #7259 already is. That is class (a) with a repro, on its own card.Reversibility: fully reversible, nothing decays. The one registered entry keeps working; the seven unregistered hooks are no less covered than before; and ⛔ no window closes — the divergence sets are writable whenever the schema question is answered.
⛔ Correctly out of #7263's scope: that card registered exactly one file and ruled the rest out, and its own reasoning ("writing it down is what turns 'this line differs because someone decided so' from memory into ledger") is why the remaining seven are real work rather than a rider.
Generated by Claude Code