Skip to content

codex-gate refuses an array assignment: args=(git commit -m x) invokes nothing #602

Description

@BaseInfinity

Found by cross-model review during #588 (PR #598), and measured against both origin/main and the PR head before filing — pre-existing on both, not introduced by #588.

The defect

args=(git commit -m x)
verdict
oracle inert — this builds an array, it does not run anything
origin/main BLOCK
PR #598 head BLOCK

An array assignment's elements are words, not a command. git here is element zero of args, exactly as -m is element two. Nothing is invoked.

Why the gate is fooled

The detector anchors git to positions bash can begin a command, and ( is one of them — legitimately, since (cd sub; git commit) is a real subshell invocation that must stay blocked. But name=( opens an array literal, not a subshell, and the text layer does not distinguish them.

Direction and cost

False POSITIVE. It fails closed: the cost is a rephrase, never an unreviewed commit. That is why it is filed rather than folded into #598, which is seven review rounds deep.

The constraint any fix inherits

Distinguishing args=( from a bare ( is narrow enough to look trivial, but it must not weaken the ( anchor itself — (cd sub; git commit -m x) and ( git commit -m x ) are pinned oracle rows in tests/test-codex-gate-command-position.sh and both must stay BLOCKED. The obvious shape of a fix is to require that ( not be preceded by an assignment-name-and-equals, using the existing GATE_ASSIGN name grammar rather than a new one.

Worth checking as part of the same fix: args+=(git commit) and declare -a args=(git commit) are the same class.

Acceptance criterion

args=(git commit -m x) is allowed; (cd sub; git commit -m x) and ( git commit -m x ) stay refused; every existing row in tests/test-codex-gate-command-position.sh still passes. Want values generated by that suite's bash oracle — a fake git on PATH that logs when an argument is exactly commit — rather than hand-asserted.

Superseded in scope by #603

#603 is the general form of this: the punctuation anchors ( ) { } ! all fire on prose because #588's "the anchor must itself be at a boundary" fix was applied to the keyword anchors and never to the punctuation ones. This issue is the specific ( case where the preceding text is an assignment name. A fix for #603 should subsume this one; close this as part of that work rather than fixing it separately.

Related

Same family as #600 (relocation flag matched in prose) and #601 (heredoc bodies): a guard that matches text without a notion of what the shell will actually execute. #533's ruling against positive command parsing bounds all three.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions