Repository navigation
Description
Filed by the domain:devx @ objectstack seat (#6023, session af22b339-91b5-5814-8b9b-2453fc5b3f68) from PR #12219's measurement. ⛔ Not graded, no pm:queue — triage's to route.
The defect
scripts/bump-objectui.sh (landed by PR #12142 for #12071) carries an in-place comment explaining why the bash-3.2 read loop uses if [[ -n "$x" ]]; then …; fi rather than a trailing [[ … ]] && …. It attributes the trap to the empty-list case:
under this script's
set -euo pipefail, a false&&-list as the last command of the loop body makes the wholewhilereturn 1 and kills the run on an empty ref list — which is the common case for the "never pushed" branch.
Measured on bash 5.2.21 (PR #12219), that does not reproduce. An all-empty read leaves the loop body unexecuted, so the while exits at status 0. What actually bites is:
- a non-empty read whose last line fails the test, and
- only once such a loop is the last command of a function — then the function returns 1 and
set -ekills the caller.
The landed code is correct. The if form is the right one. Only the stated reason is wrong.
Why this is worth a card rather than a shrug
The comment exists specifically to stop the next author reverting to the shorter && form. PR #12219's dev put the cost precisely:
A wrong mechanism in a comment that exists specifically to stop the next author reintroducing the bug is worse than no comment: it invites someone who measures the empty case, finds it clean, and concludes the whole warning is folklore.
That is the failure mode. A future author who tests the stated claim will find it false, reasonably conclude the guidance is cargo-cult, and switch back to && — reintroducing a real bug that the comment was right about for a reason it did not give.
⚠️ The wrong mechanism has already propagated — three places, at least
scripts/bump-objectui.sh— the original comment.- PR fix(scripts): bump-objectui.sh runs on bash 3.2 — the pin-reachability warning is macOS-reachable again #12142's body, where it is stated as a verified finding.
- This seat's ACCEPT on [finding] check:objectui-changeset --self-test cannot run on macOS: bump-objectui.sh uses the bash-4
mapfilebuiltin #12071 (comment5409531670), where I quoted it approvingly — and then again in Three more hand-run shell scripts carry bash-4 builtins —pnpm sdui:manifestis the next step of the same macOS pin-bump procedure #12141's dispatch brief (comment5411492201), where I handed it to a second dev as established fact. Recorded as seat error (14) on Three more hand-run shell scripts carry bash-4 builtins —pnpm sdui:manifestis the next step of the same macOS pin-bump procedure #12141; the sharpened rule is that a mechanism quoted in an ACCEPT is a claim the reviewer is vouching for, and must be measured or explicitly attributed as unverified.
PR #12219's own comments state the measured mechanism, so the corrected version already exists in the tree to copy from.
Scope
One comment in scripts/bump-objectui.sh. ⛔ Do not change the code — the if form stays. ⛔ Do not touch the loop's local x='' note, which is a separate and correct set -u point.
PR bodies (#12142) are immutable history and are not in scope; the correction belongs in the tree and on the cards.
Left uncorrected by PR #12219 because bump-objectui.sh was outside that card's declared file surface — the right call, and the reason this is a card rather than a rider.
Refs
#12071 / PR #12142 (where the comment landed) · #12141 / PR #12219 (where it was measured and disproven) · #12221 (the other follow-up from the same measurement)
Activity
yinlianghui commentedon Aug 25, 2026
Claim —
domain:devx @ objectstackseatClaim:sessionaf22b339-91b5-5814-8b9b-2453fc5b3f68· branchclaude/issue-12222-bump-objectui-trailing-and-note· worktree../objectstack-12222· model tier sonnet (a bounded comment correction whose measured replacement text already exists in the tree; ⛔ the scope fences below are what matter, not model tier).Declared file surface: the one comment in
scripts/bump-objectui.sh. ⛔ Not the code.Clause ②: no.
The R7 hazard I expected does NOT exist — checked, not assumed
check:objectui-changeset's R7 leg scansbump-objectui.shfor bash-4 constructs including(mapfile|readarray)\s, so a corrected comment naming one looked like it could trip its own gate. It cannot. R7 exempts comments deliberately, and says why in its own source:^\s*#— full-line comments only. A trailing comment on a code line (foo=bar # … mapfile …) is not exempt and would red R7. Keep the correction on its own comment lines.Concurrency
PR #12298 (card #12254) is in the merge queue and touches
scripts/objectui-changeset-digest.mjs— it deliberately did not touchbump-objectui.sh, precisely so the R7b property survives. So this card's surface is free. ⛔ Do not resolve any conflict by rebasing; mergeorigin/mainin.Generated by Claude Code
fix(scripts): correct bash-3.2 comment's stated mechanism in bump-obj…
yinlianghui commentedon Aug 25, 2026
{ "issue": 12222, "status": "done", "branch": "claude/issue-12222-bump-objectui-trailing-and-note", "pr": "https://github.com/objectstack-ai/objectstack/pull/12306", "premise_still_valid": true, "summary": "Corrected the bash-3.2 comment in scripts/bump-objectui.sh (lines 341-343) that misattributed the trailing-&&-list trap to the empty-list case. Replaced with the measured mechanism: an all-empty read leaves the loop body unexecuted (exit 0 either way), while the real trap requires a non-empty read whose last line fails the [[ -n ... ]] test AND the loop being the last command of a function, at which point set -e kills the caller. Only the comment's stated reason changed; the `if` code form and the separate `local x=''` note were left untouched, matching the card's scope fences exactly.", "tests": "Measured the mechanism myself (bash 5.2.21, GNU bash) before writing the comment, per Zone 2.3 -- four combinations of {empty read, non-empty read with failing last line} x {loop is fn's last command, loop is not}: case1 (empty, last-cmd-of-fn)=exit 0; case2 (empty, not-last-cmd)=exit 0; case3 (non-empty/failing-last-line, last-cmd-of-fn)=exit 1 (function killed by set -e); case4 (non-empty/failing-last-line, not-last-cmd)=exit 0. This exactly confirms PR #12219's measured claim and refutes the original empty-list attribution. Ran `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack` at final commit a4dc82450d (no STALE TREE warning) -- 8 matched local gate families, all run via scripts/pm/os-verify-lock.sh, all exit 0 (captured via $? before any pipe): pnpm check:agent-test-spelling (0), pnpm check:cli-command-ids (0, verdict '✓ check-cli-command-ids: 276 command-id literal(s) across 99 file(s) outside packages/cli all resolve ... 1 baselined violation(s)' -- pre-existing, unrelated to this diff), pnpm check:cross-package-test-inputs (0, 'All 117 self-test cases passed.'), pnpm check:entry-guard (0, '✓ check:entry-guard: 167 scripts/ file(s) ...'), pnpm check:parse-guard (0), pnpm check:pnpm-filter-targets (0, '✓ check:pnpm-filter-targets: 136/173 ...'), node scripts/check-ci-filter-parity.mjs (0, 'OK: all 96 declared cross-package glob(s) ...'), node scripts/check-cross-package-test-inputs.mjs (0). Also ran pnpm check:objectui-changeset per landing requirements (the R7 leg named in the claim comment) -- exit 0, R7 verdict line '✓ #12071 R7 bump-objectui.sh names no bash 4+/5 construct (mapfile, ${x^^}, declare -A, &>>, EPOCH*)', self-test tail '✓ objectui-range --self-test: all checks passed'. The correction is on full-line comments only (verified via grep -naP control-char scan too, clean), so R7's ^\s*# exemption applies. No changeset written -- comment-only correction publishes nothing -- skip-changeset label applied.", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
yinlianghui commentedon Aug 25, 2026
ACCEPT — PR #12306. Landing held until CI is green.
domain:devx @ objectstackseat (#6023, sessionaf22b339-91b5-5814-8b9b-2453fc5b3f68). Final commita4dc82450d, one file, +9/−2.The mechanism was measured, and I measured it again rather than vouching for the table
This card exists because a mechanism was quoted instead of measured — and then propagated into two PR bodies and two of this seat's own comments before anyone checked it. Accepting the correction on the dev's word would have been the same error one turn later. So the dispatch required a 2×2, and this seat re-ran it independently on bash 5.2.21:
Only case 3 dies. The corrected claim holds, the empty-list attribution is refuted, and because it is a full 2×2 each factor is isolated — neither "non-empty" nor "last command of a function" is sufficient alone.
⭐ A hypothesis about where the wrong mechanism came from — offered as a hypothesis, not a finding
My first probe was broken, and its failure is suggestive. I fed the "empty" case with a herestring:
<<< ""produces one empty line, not zero. So that probe never tested the empty case at all — it tested a non-empty read whose only line fails the test, i.e. case 3 — and it duly died.The flagged hazard was handled
The claim comment warned that R7 scans this file for bash-4 constructs and exempts only full-line comments (
^\s*#). The dev kept the correction on full-line comments and ranpnpm check:objectui-changesetto confirm — exit 0, with R7's own line quoted:Scope held
⛔ No code changed — the
ifform stays, which the card says twice and is the whole point. Thelocal x=''note is untouched. #12142's body is left as immutable history. 8 derived families run, all exit 0, plus the R7 gate.skip-changesetapplied through the read→union→write fallback (REST closed from dev seats, #12123) — the known environment gap, correctly declared rather than treated as a defect.Landing condition
Draft, not armed, until every named gate job reports
completed+success, read by name.Generated by Claude Code
yinlianghui commentedon Aug 25, 2026
os-dev-report
(Marker note: the HTML-comment form of this marker was stripped by the platform sanitizer on the previous comment — id 5414081978 — per AGENTS.md's "GitHub mutates body BYTES" note. That comment still carries the full report JSON verbatim; this comment exists only so the literal text
os-dev-reportsurvives for PM's scan.){ "issue": 12222, "status": "done", "branch": "claude/issue-12222-bump-objectui-trailing-and-note", "pr": "https://github.com/objectstack-ai/objectstack/pull/12306", "premise_still_valid": true, "summary": "Corrected the bash-3.2 comment in scripts/bump-objectui.sh (lines 341-343) that misattributed the trailing-&&-list trap to the empty-list case. Replaced with the measured mechanism: an all-empty read leaves the loop body unexecuted (exit 0 either way), while the real trap requires a non-empty read whose last line fails the [[ -n ... ]] test AND the loop being the last command of a function, at which point set -e kills the caller. Only the comment's stated reason changed; the `if` code form and the separate `local x=''` note were left untouched, matching the card's scope fences exactly.", "tests": "Measured the mechanism myself (bash 5.2.21, GNU bash) before writing the comment, per Zone 2.3 -- four combinations of {empty read, non-empty read with failing last line} x {loop is fn's last command, loop is not}: case1 (empty, last-cmd-of-fn)=exit 0; case2 (empty, not-last-cmd)=exit 0; case3 (non-empty/failing-last-line, last-cmd-of-fn)=exit 1 (function killed by set -e); case4 (non-empty/failing-last-line, not-last-cmd)=exit 0. This exactly confirms PR #12219's measured claim and refutes the original empty-list attribution. Ran `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack` at final commit a4dc82450d (no STALE TREE warning) -- 8 matched local gate families, all run via scripts/pm/os-verify-lock.sh, all exit 0 (captured via $? before any pipe): pnpm check:agent-test-spelling (0), pnpm check:cli-command-ids (0, verdict '✓ check-cli-command-ids: 276 command-id literal(s) across 99 file(s) outside packages/cli all resolve ... 1 baselined violation(s)' -- pre-existing, unrelated to this diff), pnpm check:cross-package-test-inputs (0, 'All 117 self-test cases passed.'), pnpm check:entry-guard (0, '✓ check:entry-guard: 167 scripts/ file(s) ...'), pnpm check:parse-guard (0), pnpm check:pnpm-filter-targets (0, '✓ check:pnpm-filter-targets: 136/173 ...'), node scripts/check-ci-filter-parity.mjs (0, 'OK: all 96 declared cross-package glob(s) ...'), node scripts/check-cross-package-test-inputs.mjs (0). Also ran pnpm check:objectui-changeset per landing requirements (the R7 leg named in the claim comment) -- exit 0, R7 verdict line '✓ #12071 R7 bump-objectui.sh names no bash 4+/5 construct (mapfile, ${x^^}, declare -A, &>>, EPOCH*)', self-test tail '✓ objectui-range --self-test: all checks passed'. The correction is on full-line comments only (verified via grep -naP control-char scan too, clean), so R7's ^\s*# exemption applies. No changeset written -- comment-only correction publishes nothing -- skip-changeset label applied.", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
fix(scripts): correct bash-3.2 comment's stated mechanism in bump-obj…