Found while correcting .changeset/console-82a94170c405.md (card #8893, PR #9398). Filing separately because the corrected table is one artifact, whereas this makes every console pin bump run in a shallow container ship the same fault.
The defect
scripts/bump-objectui.sh:139-142 decides whether the pin range can be walked:
RANGE_OK=0
if [[ "$OLD_SHA"!="(none sentinel)" ]] && git -C "$OBJECTUI_ROOT" cat-file -e "${OLD_SHA}^{commit}"2>/dev/null;then
RANGE_OK=1
fiIts own comment names the case it means to catch — "(A shallow clone or a first-ever pin may not have OLD reachable — degrade to the tip subject, and SAY SO in the artifact: a degraded list and a complete one must never look alike, #4731.)" — but the implemented test only asks whether OLD_SHAexists as an object. It never asks whether the walk between the endpoints is complete.
In the common container shape the objectui clone is shallow and its graft boundary sits inside the pin range. Then:
cat-file -e OLD_SHA passes (the object is there), so RANGE_OK=1 and the degraded path at bump-objectui.sh:163 never fires.collectAddedChangesets() runs git log --no-merges --diff-filter=A --name-only ... -- .changeset/, which walks only as far as the graft.- The graft boundary commit is parentless, so git diffs it against the empty tree and reports every
.changeset/*.md in its tree as Added by it. - The
seen dedup in collectAddedChangesets() hands it exactly the paths no newer commit claimed — a single "sink" commit absorbing a whole batch. objectui-changeset-digest.mjs exits 0. Nothing in the artifact says the history was incomplete.
Measured, not inferred
The landed .changeset/console-82a94170c405.md credits 36 of its 119 entries to 183d09b78, a commit that adds exactly one changeset file. Reproduced exactly by grafting a full clone at that commit:
$ git rev-parse 183d09b78 > .git/shallow # synthesize the boundary
$ git rev-list --count --no-merges 665661ab0932..82a94170c405
110 # the landed record's denominator
$ git cat-file -e 665661ab0932^{commit} && echo PASSES
PASSES # so RANGE_OK=1, no degradation
$ node scripts/objectui-changeset-digest.mjs \
--objectui-root GRAFTED_CLONE \
--from 665661ab0932 --to 82a94170c405 --max 100 --out repro.md
minor # exit 0
→ 121 releasing changeset(s), ..., 18 commit(s) without a changeset
$ diff (grep '^- ' repro.md) (git show origin/main:.changeset/console-82a94170c405.md | grep '^- ')
# byte-identical entry list
(the last line was a bash process substitution; the angle brackets are dropped here so the stored body survives GitHub's sanitizer)
The second data point falls out of the same mechanism: PR #9398's competing derivation reported 137 non-merge commits and pinned 12 entries to 75444e38a. 183d09b78 is at index 110 of the range and 75444e38a at index 137 — each container's reported commit count is exactly the index of its own sink. Two independent confirmations.
Ground truth on an unshallowed clone is 191 non-merge commits (all, --no-merges and --first-parent all agree; the range is linear).
Why this matters more than the one table
Suggested repair (not implemented here)
Make the guard test walk completeness rather than object presence, and keep the honest degradation that already exists:
- refuse-or-degrade when
git rev-parse --is-shallow-repository is trueand any graft boundary is an ancestor of the to endpoint / inside the range; - also verify the
to endpoint resolves (today only OLD_SHA is checked — in the container that produced the landed record, 82a94170c405 was initially absent entirely); - better still, have
bump-objectui.sh deepen first (git fetch --unshallow, or --shallow-since past the old pin) and only degrade if that fails, since the correct history is one fetch away; - consider a cheap sanity assertion in
objectui-changeset-digest.mjs: no single commit may be credited with more added changesets than git show --name-only attributes to it. That check alone would have caught all three bad runs.
Related: #4731 (why the digest exists), #6175 (the inverse false signal), #6494 (the ADR-0087 placeholder).
Repro material and the corrected table are in PR #9398.
Found while correcting
.changeset/console-82a94170c405.md(card #8893, PR #9398). Filing separately because the corrected table is one artifact, whereas this makes every console pin bump run in a shallow container ship the same fault.The defect
scripts/bump-objectui.sh:139-142decides whether the pin range can be walked:Its own comment names the case it means to catch — "(A shallow clone or a first-ever pin may not have OLD reachable — degrade to the tip subject, and SAY SO in the artifact: a degraded list and a complete one must never look alike, #4731.)" — but the implemented test only asks whether
OLD_SHAexists as an object. It never asks whether the walk between the endpoints is complete.In the common container shape the objectui clone is shallow and its graft boundary sits inside the pin range. Then:
cat-file -e OLD_SHApasses (the object is there), soRANGE_OK=1and the degraded path atbump-objectui.sh:163never fires.collectAddedChangesets()runsgit log --no-merges --diff-filter=A --name-only ... -- .changeset/, which walks only as far as the graft..changeset/*.mdin its tree asAdded by it.seendedup incollectAddedChangesets()hands it exactly the paths no newer commit claimed — a single "sink" commit absorbing a whole batch.objectui-changeset-digest.mjsexits 0. Nothing in the artifact says the history was incomplete.Measured, not inferred
The landed
.changeset/console-82a94170c405.mdcredits 36 of its 119 entries to183d09b78, a commit that adds exactly one changeset file. Reproduced exactly by grafting a full clone at that commit:(the last line was a bash process substitution; the angle brackets are dropped here so the stored body survives GitHub's sanitizer)
The second data point falls out of the same mechanism: PR #9398's competing derivation reported 137 non-merge commits and pinned 12 entries to
75444e38a.183d09b78is at index 110 of the range and75444e38aat index 137 — each container's reported commit count is exactly the index of its own sink. Two independent confirmations.Ground truth on an unshallowed clone is 191 non-merge commits (
all,--no-mergesand--first-parentall agree; the range is linear).Why this matters more than the one table
fatal:再报成功 —— 一个完整的结果长得像一次失败 #6175 fixed in the opposite direction (a complete result that looked like a failure). This is the mirror: an incomplete result that looks complete.chore: version packagesconsumes it.Suggested repair (not implemented here)
Make the guard test walk completeness rather than object presence, and keep the honest degradation that already exists:
git rev-parse --is-shallow-repositoryistrueand any graft boundary is an ancestor of thetoendpoint / inside the range;toendpoint resolves (today onlyOLD_SHAis checked — in the container that produced the landed record,82a94170c405was initially absent entirely);bump-objectui.shdeepen first (git fetch --unshallow, or--shallow-sincepast the old pin) and only degrade if that fails, since the correct history is one fetch away;objectui-changeset-digest.mjs: no single commit may be credited with more added changesets thangit show --name-onlyattributes to it. That check alone would have caught all three bad runs.Related: #4731 (why the digest exists), #6175 (the inverse false signal), #6494 (the ADR-0087 placeholder).
Repro material and the corrected table are in PR #9398.