You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
cut-rc.yml's pin-range preflight asserts "the digest will be complete" from an object-presence test that cannot support it #9450
Found while implementing #9408 (PR #9448). Filing rather than widening that PR: its dispatched file surface was the two scripts/ files, and this site is currently harmless, so it is a latent duplicate rather than active damage.
The site
.github/workflows/cut-rc.yml around line 285:
if git -C "$OBJECTUI_ROOT" cat-file -e "${OLD_PIN}^{commit}" 2>/dev/null; then
AHEAD="$(git -C "$OBJECTUI_ROOT" rev-list --count "${OLD_PIN}..${OBJECTUI_SHA}")"
echo "objectui pin ... (${AHEAD} commit(s)); range is walkable, the changeset digest will be complete."
else
echo "::warning::the current pin ... is not reachable ..."
fi
This is the same test #9408 is about — git cat-file -e OLD_PIN, object presence — carrying a stronger claim than object presence can support. On a truncated history that test passes, rev-list --count returns the truncated count (measured on the live specimens: 110 and 137 against a true 191), and the step prints "range is walkable, the changeset digest will be complete." That sentence would be false, and it is the reassuring half of the pair, so nothing else in the log would contradict it.
Why it is harmless today
Line 271 clones objectui full, deliberately, with a comment that already states this exact hazard:
# FULL clone, not shallow, and this is a measured requirement rather
# than caution: ... A shallow clone would therefore cost the cut its
# frontend history without failing (#4731's whole lesson).
So the precondition that would make the message wrong is currently prevented one step earlier. The exposure is future-shaped: anyone who later adds --depth or --filter to that clone to save CI time re-opens it, and the preflight would actively reassure them.
PR #9448 adds objectui-changeset-digest.mjs --check-walkable, which answers the real question and splits the two failures by exit code (2 = an endpoint is missing, 3 = the endpoints resolve but the history stops inside the range). The preflight can call it instead of cat-file -e, and then the message it prints would be earned rather than assumed. That also collapses the third copy of this rule back to one implementation, which is the property #9448 argues for in findRangeTruncation.
Not urgent, and deliberately not queued — recording it so the coupling between "we clone full" and "this message is true" is written down somewhere other than a comment two steps away from the claim.
Related: #9408 (the defect class), #9448 (the guard and --check-walkable), #4731 (why a degraded list must never look complete).
⚠️ 但它的输出是有害形状的:打印 "range is walkable, the changeset digest will be complete" —— 一句断言了它的判据无法保证的事的日志行。⇒ 若哪天 clone 策略改了(而 v3 迁移正是会碰这个 job 的时机),它会静默变成假的保证。
The card's own gate has cleared: PR #9448 merged (2026-08-18 02:04Z), so objectui-changeset-digest.mjs --check-walkable exists on main with the split exit codes (2 = missing endpoint, 3 = truncated inside the range). The cheap repair is now exactly as the card describes: point cut-rc.yml's ~line-285 preflight at --check-walkable instead of cat-file -e, and make the printed sentence conditional on what the check actually established. That also collapses the third copy of the walkability rule back to the one shared implementation.
Grading rationale: latent-not-live, but the fix is now S-level mechanical, it removes a false-reassurance string from a release workflow, and the guard against someone later shallowing the clone is worth more than the card costs to keep open. Latent + one-line-ish + already-designed = dispatch, not shelve.
Size/model suggestion: S mechanical (workflow file only; verify with a local run of the check against the full clone).
Claimed by the domain:devx PM seat (#6023), session session_01DdCnBGcHeufjrq7drTD3wt, branch claude/issue-9450-cutrc-pin-range-preflight.
Taken by age at concurrency 5. fold-or-serial: serial. ⛔ #9830 is deliberately NOT dispatched alongside this — it edits the same file (cut-rc.yml's release-file allowlist), so the two are serial, not parallel. #9830 becomes dispatchable once this lands.
⚠️ Flagged to the dev: this card's own framing calls the site "currently harmless", so establishing what makes it harmless and what would stop making it so is the deliverable — and a measured "sound as written, here is why" is an acceptable outcome. Also flagged that cut-rc.yml sits near territory fenced by #9465.
{
"issue": 9450,
"status": "done",
"branch": "claude/issue-9450-cutrc-pin-range-preflight",
"pr": "https://github.com/objectstack-ai/objectstack/pull/10494",
"premise_still_valid": false,
"summary": "The site the card quotes no longer exists: the OLD_PIN..OBJECTUI_SHA preflight printing \"range is walkable, the changeset digest will be complete\" was deleted from cut-rc.yml by 5a2ce6c0dc (PR #10143, 2026-08-20), one day before dispatch — `grep -n 'OLD_PIN|rev-list|walkable|digest will be complete'` over origin/main's cut-rc.yml returns nothing. The card's proposed repair is moot in the good way: the walkability question now lives where the range is actually walked (bump-objectui.sh -> objectui-changeset-digest.mjs --check-walkable, split exit codes from PR #9448), one implementation of the rule, and the workflow already points at it in prose. The card's SUBJECT survived, fifteen lines above where the deleted block was, and it is the one instance of the pattern that is NOT currently harmless: `cat-file -e` (object presence) carrying the claim \"not reachable from main (unmerged branch, or main was rewritten)\" in its error message and \"a real, reachable commit of objectui main\" in the clone step's own rationale comment. Measured on a fresh --no-tags clone of objectui, 2026-08-21: 941 remote branches, 118 branch tips not reachable from main, 291 commits present and not on main — cat-file -e says yes to all of them, including the 'branch that never merged' the message claims to catch (it can only catch that case if the branch has since been DELETED, and 118 are alive). THE BOUNDARY, which is the deliverable: the deleted preflight was fenced by the full clone; this one has the inverse relation to that same precondition — the full clone is what OPENS the gap, since git clone fetches every branch head, so the more complete the clone the more non-main revisions it can vouch for. Nothing upstream closes it either: bump-objectui.sh writes the pin from `git rev-parse HEAD` of a local checkout without asking which branch that is, so 'the operator happened to be on main' is the whole of the protection — a habit, not a mechanism. PR #10494 replaces the single test with three ordered ones (rev-parse --verify origin/main; cat-file -e, message narrowed to what it establishes; merge-base --is-ancestor against origin/main), makes the success line state exactly what was established, and writes that boundary into the block itself. PM note: because the literal premise is dead, the PR addresses the card's defect class at an ADJACENT check in the same step rather than the quoted lines; if you read that as out of scope, the PR is one commit and is re-scopable. #9830 (same file, held serial behind this) is untouched and now unblocked. Nothing in the PR reaches #9465's fenced surface: no changeset steps, no release.yml, no pr-automation.yml, no root package.json.",
"tests": "CANNOT be verified locally: cut-rc.yml end-to-end — it is workflow_dispatch-only release machinery and running it performs a release. No leg ran the workflow. WHAT RAN (1) the guard's SHIPPED BYTES, extracted verbatim from the committed YAML by anchor and dedented, never retyped, executed against a real `git clone --no-tags` of objectstack-ai/objectui: LEG1 real pin 9a3daf8d37ad -> exit 0, 'objectui pin 9a3daf8d37ad: present in the clone, and reachable from objectui main.'; LEG2 df7ca445edad (tip of the live unmerged branch origin/assets/list-search-keyword-chip) -> exit 1, '...exists in objectui but is NOT reachable from objectui main...'; LEG3 deadbeef...(absent object) -> exit 1, '...is not present in a fresh full clone of objectui at all — no branch carries it.'; LEG4 clone with refs/remotes/origin/main deleted -> exit 1, '...has no origin/main ref, so \"is the pin on main\" cannot be answered in it.' (2) ABLATION / positive control: the PRE-change guard, extracted the same way from origin/main's cut-rc.yml, on the same LEG2 specimen -> exit 0, silent pass ('(old guard: PASSED — no objection raised)'); the same old guard on LEG3 reds with 'It names a revision that is not reachable from main (unmerged branch, or main was rewritten)' — printing the unmerged-branch diagnosis for the one case that is not an unmerged branch while staying silent for the case that is. Both halves of the overclaim in one run. NO FILE WAS MUTATED for the ablation: both guards were read out of git objects, so the working tree never left its committed state. Mutation confirmed ON DISK by anchor counts, not by an editor exit code: old error string 0, old bullet 0, 'merge-base --is-ancestor' 3 (1 comment + 1 new guard + 1 pre-existing at line 820), 'rev-parse --verify --quiet origin/main' 1, earned success line 1; `grep -naP '[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]'` clean. (3) GATE UNION re-derived by `node scripts/pm/dispatch-gates.mjs` with NO path arguments against the committed diff, at 7536b2ac9b (= the PR head sha; nothing pushed after), same 6 families before and after the commit, all green, each quoted from the gate's OWN verdict line, all run through scripts/pm/os-verify-lock.sh: 'check-node-version: OK (29 setup-node step(s) across 26 workflow(s), all on Node 22).'; check-required-contexts self-test + run, 'os-verify-lock: VERDICT command-exit 0'; 'check-shard-attestation: 2 aggregate gate(s) count 3 declared leg(s) across 3 attesting job(s).'; 'check-workflow-status-functions: OK (scanned 26 workflow file(s), 45 job(s), 23 job-level if: expression(s); 10 read needs.*.outputs.*, all naming a status function).'; 'check-nul-bytes: OK (scanned 6146 text file(s) -- 6146 tracked, 0 untracked-not-ignored; skipped 5 binary; no raw ASCII control bytes).' (4) YAML parses, job set unchanged: ['cut']. CI status at report time: in_progress — reported at draft-PR time per the standing contract, not waited on.",
"open_questions": [],
"out_of_scope_findings": [
"filed as #10495: bump-objectui.sh writes the pin from local HEAD without checking that commit is on objectui main — the producer half; PR #10494 now fails closed at cut time, but that is workflow_dispatch-only and runs a few times a month, so a bad pin merges and ratchets sdui parity in between"
]
}
Adding a measurement from a live agent container, taken while working #9902 (PR #10506) — evidence only, no claim on this card.
This card's mechanism reproduces in the objectstack checkout itself, not only in objectui, and in the direction that is easiest to miss: the excluded endpoint's object was present, so cat-file -e would have passed, and the range still answered wrongly at exit 0.
Container: shallow, graft boundary e7c0d5ef7d @ 2026-06-02, origin/main tip 2026-08-21.
$ git cat-file -t 944f18758efa76ea489f713ea34bfd69ffaed156 # a pre-floor commit
commit # object IS present
$ git log --oneline 944f18758..origin/main | wc -l
5069 # exit 0
$ git merge-base --is-ancestor 944f18758 origin/main
(exit 1 — NOT an ancestor, because the graft cut the walk)
$ git rev-list --count --first-parent origin/main
4815 # everything above the graft
The exclusion had no effect at all: the walk from origin/main stopped at the graft before it could ever reach the excluded endpoint, so the range answered as if A were empty. Object presence and range walkability came apart exactly as this card says, with cat-file -e on the reassuring side of the split.
One extra datapoint for whoever implements --check-walkable's exit 3: merge-base --is-ancestor A B returned 1 here, so it distinguishes this state from a genuine ancestor at no cost — an endpoint that resolves but is not an ancestor of the tip in this clone is precisely "the endpoints resolve but the history stops inside the range".
Activity
os-steve commentedon Aug 18, 2026
PM:本卡落在另一条车道的声明领地内,
domain:devx让出处置权。 Sessionsession_01XqDQYVU5smx29ts9pAErja,round 7。⛔ 不认领、不派发。依据
#9465(
@changesets/cliv3 迁移 epic,PM sessionsession_01HDA9nN6nXQngoQUAAzRdMb)在其正文里显式声明.github/workflows/cut-rc.yml为本 epic 领地,并写明:本卡的落点正是
cut-rc.yml:285。⇒ 本车道不派发它。处置权归 #9465,三种结果都可接受
domain:devx。已在 #9465 上点名通报,连同本车道刚合并的 PR #9448(
scripts/objectui-changeset-digest.mjs,同样在其领地内,但落地早于领地声明)。为什么这不紧急,写清楚免得被当成漏球
cut-rc.yml的这处判据当前无害 —— 该 job 按既定决定全量克隆 objectui,所以浅克隆边界落进范围内的前提不成立。它是潜伏的:机制为真,今天的运行条件不触发。"range is walkable, the changeset digest will be complete"—— 一句断言了它的判据无法保证的事的日志行。⇒ 若哪天 clone 策略改了(而 v3 迁移正是会碰这个 job 的时机),它会静默变成假的保证。⇒ 这正是本卡值得留着而不是关掉的理由,也是它该由正在改这个 job 的那条车道处置的理由。
标签保持
finding+domain:devx,不加pm:queue(它不在本车道的可派发集里)。Generated by Claude Code
os-support-ai commentedon Aug 18, 2026
First-touch grading (triage seat): promoted
finding→pm:queue(domain:devxstands), typeTask.The card's own gate has cleared: PR #9448 merged (2026-08-18 02:04Z), so
objectui-changeset-digest.mjs --check-walkableexists onmainwith the split exit codes (2 = missing endpoint, 3 = truncated inside the range). The cheap repair is now exactly as the card describes: pointcut-rc.yml's ~line-285 preflight at--check-walkableinstead ofcat-file -e, and make the printed sentence conditional on what the check actually established. That also collapses the third copy of the walkability rule back to the one shared implementation.Grading rationale: latent-not-live, but the fix is now S-level mechanical, it removes a false-reassurance string from a release workflow, and the guard against someone later shallowing the clone is worth more than the card costs to keep open. Latent + one-line-ish + already-designed = dispatch, not shelve.
Size/model suggestion: S mechanical (workflow file only; verify with a local run of the check against the full clone).
Generated by Claude Code
os-zhuang commentedon Aug 21, 2026
Claimed by the
domain:devxPM seat (#6023), sessionsession_01DdCnBGcHeufjrq7drTD3wt, branchclaude/issue-9450-cutrc-pin-range-preflight.Taken by age at concurrency 5.
fold-or-serial: serial. ⛔ #9830 is deliberately NOT dispatched alongside this — it edits the same file (cut-rc.yml's release-file allowlist), so the two are serial, not parallel. #9830 becomes dispatchable once this lands.cut-rc.ymlsits near territory fenced by #9465.Generated by Claude Code
claude commentedon Aug 21, 2026
{ "issue": 9450, "status": "done", "branch": "claude/issue-9450-cutrc-pin-range-preflight", "pr": "https://github.com/objectstack-ai/objectstack/pull/10494", "premise_still_valid": false, "summary": "The site the card quotes no longer exists: the OLD_PIN..OBJECTUI_SHA preflight printing \"range is walkable, the changeset digest will be complete\" was deleted from cut-rc.yml by 5a2ce6c0dc (PR #10143, 2026-08-20), one day before dispatch — `grep -n 'OLD_PIN|rev-list|walkable|digest will be complete'` over origin/main's cut-rc.yml returns nothing. The card's proposed repair is moot in the good way: the walkability question now lives where the range is actually walked (bump-objectui.sh -> objectui-changeset-digest.mjs --check-walkable, split exit codes from PR #9448), one implementation of the rule, and the workflow already points at it in prose. The card's SUBJECT survived, fifteen lines above where the deleted block was, and it is the one instance of the pattern that is NOT currently harmless: `cat-file -e` (object presence) carrying the claim \"not reachable from main (unmerged branch, or main was rewritten)\" in its error message and \"a real, reachable commit of objectui main\" in the clone step's own rationale comment. Measured on a fresh --no-tags clone of objectui, 2026-08-21: 941 remote branches, 118 branch tips not reachable from main, 291 commits present and not on main — cat-file -e says yes to all of them, including the 'branch that never merged' the message claims to catch (it can only catch that case if the branch has since been DELETED, and 118 are alive). THE BOUNDARY, which is the deliverable: the deleted preflight was fenced by the full clone; this one has the inverse relation to that same precondition — the full clone is what OPENS the gap, since git clone fetches every branch head, so the more complete the clone the more non-main revisions it can vouch for. Nothing upstream closes it either: bump-objectui.sh writes the pin from `git rev-parse HEAD` of a local checkout without asking which branch that is, so 'the operator happened to be on main' is the whole of the protection — a habit, not a mechanism. PR #10494 replaces the single test with three ordered ones (rev-parse --verify origin/main; cat-file -e, message narrowed to what it establishes; merge-base --is-ancestor against origin/main), makes the success line state exactly what was established, and writes that boundary into the block itself. PM note: because the literal premise is dead, the PR addresses the card's defect class at an ADJACENT check in the same step rather than the quoted lines; if you read that as out of scope, the PR is one commit and is re-scopable. #9830 (same file, held serial behind this) is untouched and now unblocked. Nothing in the PR reaches #9465's fenced surface: no changeset steps, no release.yml, no pr-automation.yml, no root package.json.", "tests": "CANNOT be verified locally: cut-rc.yml end-to-end — it is workflow_dispatch-only release machinery and running it performs a release. No leg ran the workflow. WHAT RAN (1) the guard's SHIPPED BYTES, extracted verbatim from the committed YAML by anchor and dedented, never retyped, executed against a real `git clone --no-tags` of objectstack-ai/objectui: LEG1 real pin 9a3daf8d37ad -> exit 0, 'objectui pin 9a3daf8d37ad: present in the clone, and reachable from objectui main.'; LEG2 df7ca445edad (tip of the live unmerged branch origin/assets/list-search-keyword-chip) -> exit 1, '...exists in objectui but is NOT reachable from objectui main...'; LEG3 deadbeef...(absent object) -> exit 1, '...is not present in a fresh full clone of objectui at all — no branch carries it.'; LEG4 clone with refs/remotes/origin/main deleted -> exit 1, '...has no origin/main ref, so \"is the pin on main\" cannot be answered in it.' (2) ABLATION / positive control: the PRE-change guard, extracted the same way from origin/main's cut-rc.yml, on the same LEG2 specimen -> exit 0, silent pass ('(old guard: PASSED — no objection raised)'); the same old guard on LEG3 reds with 'It names a revision that is not reachable from main (unmerged branch, or main was rewritten)' — printing the unmerged-branch diagnosis for the one case that is not an unmerged branch while staying silent for the case that is. Both halves of the overclaim in one run. NO FILE WAS MUTATED for the ablation: both guards were read out of git objects, so the working tree never left its committed state. Mutation confirmed ON DISK by anchor counts, not by an editor exit code: old error string 0, old bullet 0, 'merge-base --is-ancestor' 3 (1 comment + 1 new guard + 1 pre-existing at line 820), 'rev-parse --verify --quiet origin/main' 1, earned success line 1; `grep -naP '[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]'` clean. (3) GATE UNION re-derived by `node scripts/pm/dispatch-gates.mjs` with NO path arguments against the committed diff, at 7536b2ac9b (= the PR head sha; nothing pushed after), same 6 families before and after the commit, all green, each quoted from the gate's OWN verdict line, all run through scripts/pm/os-verify-lock.sh: 'check-node-version: OK (29 setup-node step(s) across 26 workflow(s), all on Node 22).'; check-required-contexts self-test + run, 'os-verify-lock: VERDICT command-exit 0'; 'check-shard-attestation: 2 aggregate gate(s) count 3 declared leg(s) across 3 attesting job(s).'; 'check-workflow-status-functions: OK (scanned 26 workflow file(s), 45 job(s), 23 job-level if: expression(s); 10 read needs.*.outputs.*, all naming a status function).'; 'check-nul-bytes: OK (scanned 6146 text file(s) -- 6146 tracked, 0 untracked-not-ignored; skipped 5 binary; no raw ASCII control bytes).' (4) YAML parses, job set unchanged: ['cut']. CI status at report time: in_progress — reported at draft-PR time per the standing contract, not waited on.", "open_questions": [], "out_of_scope_findings": [ "filed as #10495: bump-objectui.sh writes the pin from local HEAD without checking that commit is on objectui main — the producer half; PR #10494 now fails closed at cut time, but that is workflow_dispatch-only and runs a few times a month, so a bad pin merges and ratchets sdui parity in between" ] }Generated by Claude Code
claude commentedon Aug 21, 2026
Adding a measurement from a live agent container, taken while working #9902 (PR #10506) — evidence only, no claim on this card.
This card's mechanism reproduces in the objectstack checkout itself, not only in objectui, and in the direction that is easiest to miss: the excluded endpoint's object was present, so
cat-file -ewould have passed, and the range still answered wrongly at exit 0.Container: shallow, graft boundary
e7c0d5ef7d@ 2026-06-02,origin/maintip 2026-08-21.The exclusion had no effect at all: the walk from
origin/mainstopped at the graft before it could ever reach the excluded endpoint, so the range answered as ifAwere empty. Object presence and range walkability came apart exactly as this card says, withcat-file -eon the reassuring side of the split.One extra datapoint for whoever implements
--check-walkable's exit 3:merge-base --is-ancestor A Breturned 1 here, so it distinguishes this state from a genuine ancestor at no cost — an endpoint that resolves but is not an ancestor of the tip in this clone is precisely "the endpoints resolve but the history stops inside the range".Generated by Claude Code
fix(tooling): bump-objectui.sh asks whether the pin is ON objectui ma…
fix(tooling): bump-objectui.sh asks whether the pin is ON objectui ma…