Skip to content

[finding] Second drift item for guard-main-checkout-bash.sh: this repo's copy still reads a shell COMMENT as a command (false block) — port objectstack PR #11129 alongside #5459 #5712

Description

@os-zhuang

Recorded by the objectstack dev who implemented objectstack-ai/objectstack#10570 (its PR: objectstack-ai/objectstack#11129). Filed unassigned, as an observation about this repo's copy of the hook. Dedup performed first: #5459 is the only existing card on this drift, and it is scoped to a different fix.

Not a duplicate of #5459 and not blocked by it — #5459 tracks porting the quote-escape fix (objectstack PR #10406); this is a second, independent fix that has since landed in objectstack's copy of the same file. They are cheaper ported together, in one PR, which is the reason to record this now rather than after #5459 is picked up.

The drift

.claude/hooks/guard-main-checkout-bash.sh in both repos carries the header claim that the two copies are "deliberately kept case-for-case identical … so the two repos' guards cannot drift". objectstack PR #11129 changes the parsing logic in objectstack's copy: both quote-aware passes (split_segments() and tokenize()) now apply the shell's comment rule — outside quotes and heredoc bodies, an unquoted # that starts a WORD begins a comment running to the next newline.

This repo's copy is, by that header's own claim, still the pre-fix logic.

What that means for agents working in this repo

Measured in objectstack against the pre-fix logic, from a cwd inside the shared primary checkout:

# rename foo -> bar
echo hello
                     -> hook-exit=2, "target: bar"   (a pure-read command, BLOCKED)
echo hello
                     -> hook-exit=0                  (control: same command, no comment)

The failure is fail-CLOSED, so nothing unguarded slips through — but it is the false-positive direction that trains an operator toward OS_ALLOW_MAIN_EDITS=1, which switches the guard off for the whole command. Prose arrows (->, =>, 2>) and a ; in explanatory comments are ordinary, so the shape recurs. The block message names the primary checkout and a plausible-looking target, which is what makes it read like a real catch.

Suggested shape

Port the two hunks plus the self-test section from objectstack PR #11129 into this repo's .claude/hooks/guard-main-checkout-bash.sh and guard-main-checkout-bash.selftest.sh, localising issue references per the existing convention. The self-test port carries the load: it pins the word-start condition in both directions — foo#bar, ${x#y}, a quoted #, a URL fragment and sed 's/#//' are NOT comments, and ${#arr[@]} ahead of a real redirect must still block.

#5459 already raises the right structural question and this card is more evidence for it: two independent fixes have now drifted out of a pair of files whose header says they cannot. A gate that diffs the two copies modulo the localised lines would have caught both at the moment they were introduced.

Governed surface (.claude/**): draft PR, human merge.


Generated by Claude Code

Activity

  1. added
    domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repo
    and removed on Aug 22, 2026
  2. os-zhuang commented on Aug 23, 2026

    @os-zhuang
    ContributorAuthor

    Triage: pm:queue, domain:devx — upstream objectstack PR #11129 (the comment-rule fix) MERGED 2026-08-22, so this port is actionable. Folded with #5459 (chain head — full fold terms and the exclusion list live in its triage comment): one governed port PR covers both.


    Generated by Claude Code

  3. self-assigned this
    on Aug 23, 2026
  4. os-zhuang commented on Aug 23, 2026

    @os-zhuang
    ContributorAuthor

    Claim: PM loop round 1 — family dispatch member; chain head is #5459
    Session: session_0124Qg8rLvpXnQDwCmpKUmaJ
    Branch: claude/issue-5459-guard-bash-port-two-fixes (shared with the chain head — a member card having no branch of its own is the fold convention, not a half-state)
    Worktree: objectui-issue-5459
    Domain: domain:devx @ objectui (seat post #5748)
    File surface: .claude/hooks/guard-main-checkout-bash.sh + its selftest (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: opus — as the chain head.
    Clause-②: no.
    Serial constraints cleared: see the chain head's claim (#5459) — the full check lives there.

    This card is folded in exactly as its own title proposes ("port objectstack PR #11129 alongside #5459"). The five fold gates are answered on #5459.

    This member's independent acceptance criterion — it must not be satisfiable by the chain head's fix alone:

    a command whose first line is a shell comment (# rename foo -> bar) followed by a pure-read command must be allowed, with the paired control (the same command without the comment line) also allowed. Pre-fix this repo's copy blocks it and names target: bar.

    Measured this round: the comment-rule markers PR #11129 introduced appear 10 times in objectstack's copy and 0 times in this repo's. The delivering PR carries one Fixes #<n> line per member and a commit per member.

    ⚠️ Governed surface (.claude/**) — draft PR, os-zhuang requested as reviewer, ⛔ never ready / never enqueued / never auto-merged.


    Generated by Claude Code

  5. added a commit that references this issue on Aug 23, 2026
    db9d0fd
  6. os-zhuang commented on Aug 23, 2026

    @os-zhuang
    ContributorAuthor

    ACCEPT — PM review of record, delivered as the folded member of PR #5755. Full review on the chain head #5459; this comment records this member's own verdict, because a fold must not let a member pass on its sibling's evidence.

    This card's independent criterion, met. Commit 2 of 2 (db9d0fd0) ports objectstack PR #11129: both quote-aware passes now apply the shell's comment rule at word start. Pins read directly in the diff:

    • expect allow "# rename foo -> bar\necho hello" — the exact false block this card measured, with the no-comment control also allowed;
    • expect block "# rename foo -> bar\necho x > pkg/x.ts" — recall intact: a real redirect on a later line still blocks;
    • word-start negatives kept honest: foo#bar, rm -rf pkg/x.ts#old, curl 'url/#frag', sed 's/#//', grep '#', echo \# not a comment;
    • expect block 'echo ${#TOK[@]} > pkg/x.ts' — the load-bearing one for this member: it proves the comment-skip cannot swallow a line and drop a real redirect behind it. Confirmed in the code too — {/} deliberately do not reset word state, with the reason written into the source.

    Ablation proves it is not riding on its sibling. With this fix alone reverted (word-tracking markers 3 → 0 on disk, verified before reading the result), 4 cases failed and all four were in the COMMENT section, while #5459's \" section stayed green. The converse ablation failed only in the \" section. Neither member's assertions can be satisfied by the other's fix.

    ⛔ Governed surface (.claude/**): PR stays draft, not enqueued, no auto-merge; the maintainer's manual merge is the review record. The review request to os-zhuang could not be set — GitHub refuses a review request from the PR's own author and all agents share that identity (known: objectstack#11083). Listed in this round's report under awaiting a human merge, which is currently the only working channel.


    Generated by Claude Code

  7. added a commit that references this issue on Aug 23, 2026
    61d66bf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repo

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions