The disclosure marker must end the body, plus five missed posting surfaces - #2185
Conversation
…ng surfaces Closes #2177 #2131 merged with defects two same-vendor reviewers cleared: eleven local adversarial rounds and the repo's own claude-review (which ran properly once the token was restored -- $3.07, "Ready for merge", no findings). A cross-vendor review found 11 findings at that same commit, 8 blocking, every one real. The guard accepted a marker that was not in the body It searched the whole command for the marker phrase, so a marker in a trailing shell comment, a marker followed by more human prose, and a partial marker were all silent. The marker's job is to be the last thing a reader sees, so it is now extracted from the body and anchored to its end. Posting surfaces not named "comment" `gh issue close|reopen --comment` and `gh pr close|reopen --comment` post comments; none was detected, and skills/rescue-closed carried a live undisclosed one. Added, along with `gh api --input` and `--form body=`. NOT `gh pr merge`: its `-b` is the merge-commit body and it has no `--comment` at all, so an earlier draft's alternative for it could never have fired. The bot exemption admitted human-directed prose `[ \w-]{0,40}` let `@dependabot rebase please humans` through. Replaced with the closed command vocabulary those bots accept, and extended to every body-bearing spelling the detector accepts as a posting route -- `--body=`, `-b`, `--comment` were all missing, so compliant bot commands warned. Claim readers saw only the newest comment `gi` and `post-merge` read `.comments | last`. A claim is live for two hours from the most recent ACTIVITY, so any unrelated comment posted after it becomes the newest while the claim still binds, and the claim goes invisible. Both now filter to the claim/release exchange. Found by this branch's own push-gate review - The end-anchoring fix had landed on the Bash path only. `verdict_mcp` still searched, on the route a remote session must use, with the raw body already in hand. No MCP fixture covered it, which is how 121 green cases missed it. - Ranking extractor candidates by pattern order rather than position meant a body that merely MENTIONED `-f body=` had that inner text taken as the body -- so a compliant comment about this feature warned. Two of three realistic probes. Now ranked by position. - A heredoc body arrives with its terminator line attached, so a blank line before `EOF` read as the body continuing past the marker. - `tool-mappings`' `REOPEN_ISSUE` was the one comment-posting row unannotated. Overstated claims corrected The robot-emoji hazard is real and one gate narrower than stated: the emoji gets a comment ADMITTED to the verdict scan, and it must also name the head SHA to count. The fragment said so; the hook's user-facing warning and hooks.json still said "scans as a CLEAN one". All three agree now. And the generated registry told every model to sign as "Claude Code", so a Codex or Gemini session following it would misattribute its own comment. Not carried over: the stranded branch was behind main and would have reverted #2176's orchestrator changes. This branch is cut fresh from main and touches no orchestrator file. Filed separately: #2177 also records that `scripts/orchestrator/subagents.py`'s ReviewerSubagent posts an undisclosed comment on main -- it landed in #2176 after #2131 merged, so the rule shipped and the next merge violated it. Checks: 42/42 hook suites (131 in this one, up from 121), markdownlint 0, links, skills, hook-catalog, hook-output-shape, context-closure pin, and the real new-line-breaks gate against origin/main.
The previous commit said "131 in this one, up from 121". The 121 figure came from a commit on the branch that #2131 merged WITHOUT -- so it never reached `main`, and no reader can reproduce it from history. Measured against `origin/main`: 110 passed. So this branch's delta is +21 tests (110 -> 131), not +10. Recording it here rather than rewriting the message, since the merge commit already sits on top. The class of error is the one this branch is about: a number carried forward from a state that never shipped, published without the command that derives it. The command is: git show origin/main:hooks/test-require-agent-disclosure.py > /tmp/t.py git show origin/main:hooks/require-agent-disclosure.py > /tmp/require-agent-disclosure.py cd /tmp && python3 t.py
…--form is Two comment-only corrections from the push-gate review that missed the previous commit. `discloses()` said "only the remainder of the marker line may follow" while the rule is `"\n\n" not in after and len(after) <= 60` -- which permits a single newline plus a short run. That tolerance is deliberate (a trailing signature or a wrapped marker line is common, and refusing it would warn on a compliant comment), so the comment now describes the rule rather than a stricter one nobody implemented. `--form` is glab's flag, not gh's. The pattern is right, since the detector matches `(?:gh|glab) api`; only the comment read as if both had it.
|
Claude Code CLI (local session) is working on this --- please hold off on pushing to this branch until I'm done. Context: this PR exists because a cross-vendor review found 8 blocking defects in #2131 after it merged, having been cleared by eleven local adversarial rounds and by this repo's own Posted by Claude Code (AI agent) --- not written by a human. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
The #2185 review found the one new matcher that is not quote-aware, and it is the one this branch added. `gh issue|pr close|reopen` were gated by a lookahead over a raw `[^\n;&|]` tail. That class has no notion of quoting, so a `;` inside an EARLIER flag's quoted value ended the tail before `--comment` was reached and the command went undetected: gh issue close 5 -R o/r --duplicate-of "see issue #3; also #4" \ --comment "Closing without disclosure." `split_segments` keeps that whole command as one segment, correctly -- and then the lookahead threw that away. `gh issue close` really does take a free-text `--duplicate-of`, so this is a shape the corpus can produce, and it is exactly the surface the branch exists to detect. The fix is the pattern already used two lines above for `gh pr review`: match the verb, then test the body flag over the whole segment, which `split_segments` has already bounded with quote awareness. `_SEG_TAIL` is gone; nothing else used it. Worth naming why this slipped: every other matcher in the file routes through `split_segments`, and the file's own comments argue at length for doing so -- including round-4 fixtures pinning a semicolon and an ampersand inside a body. The new code reintroduced the same class one flag to the left, where no fixture looked. The 131 cases all exercised special characters inside the comment value and none in a flag before it. Seven fixtures added, covering `;`, `&` and `|` in an earlier flag, the disclosed counterpart, `-c`, and close/reopen with no comment flag at all (which posts nothing and must stay silent). Dropping the new gate turns the suite red. 138 tests, up from 131. Plus 41/41 hook suites, links, skills, hook-catalog, hook-output-shape, markdownlint, the real new-line-breaks gate, context-closure.
|
Addressed --- the non-quote-aware Your reproducer was exact. Fixed the way you suggested, which is also the pattern sitting two lines above it for Worth recording why it slipped, since the diagnosis is the useful part. Every other matcher in that file routes through Seven fixtures added for that gap: Also confirming your verification of the Posted by Claude Code (AI agent) --- not written by a human. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
…sclosure flags (closes #2185 findings)
ARD Review Disposition Summary
Posted by Antigravity (AI agent) --- not written by a human. |
Second #2185 review round. Two findings, both real, plus the duplicated comment block that survived an earlier attempt to remove it. `gh` is a pflag CLI, so a shorthand flag attaches its value with no separator: `-cvalue` and `-c=value` are valid alongside `-c value`. Every short-flag pattern in this file required whitespace, so all of them missed the attached forms -- including the pre-existing `-b`/`-m` alternatives, which predate this branch. An undisclosed `gh issue close 5 -c"..."` drew no warning at all. Two repairs were needed, and the first was wrong Switching to `-c\S` fixed the attached forms and broke the spaced one, trading one gap for another; the suite caught it immediately. All three spellings now match. Then `inline_body` started returning `hanges`: with no left boundary, `-c` matched inside `--request-changes`, and the extractor read the rest of that token as the body. Every short-flag pattern now carries `(?<![\w-])`. The mutation test was itself wrong, twice Reverting COMMENT_FLAG_RE and ANY_BODY_FLAG_RE to whitespace-only both reported MISSED. The first was a false result -- my mutation anchor did not match the file's escaping, so nothing was mutated and the green suite meant nothing. The second was real but for a different reason: ANY_BODY_FLAG_RE is consulted ONLY for `gh pr review`, so the `-b`/`-m` fixtures went through POST_RE and could not pin it. Added `gh pr review --request-changes -b"..."`, which is the case that discriminates -- and which is what surfaced the `--request-changes` bug above. All four mutations now caught: both flag patterns, the short-flag left boundary, and the close/reopen comment gate. A sweep of every fenced bash block in the corpus produces 4 warnings, all the by-design unreadable-body note, 0 MISSING -- so no false positive on anything the corpus actually writes. 145 tests, up from 138.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
…sides' wins A second session (dem-extra1) fixed the same #2185 review findings on this same branch at 18:23 while I was fixing them locally -- the parallel-session collision this very PR hardens against, on the PR that hardens it. Merged rather than reset, per claim-pr.md's same-parents-different-tree case: each side got something the other did not. Theirs, kept: `--comment=`, `-F(?:\s|=|\S)`, `--body-file\b`, the duplicated comment block removed, and the `preferences.md` note. Mine, kept: the LEFT BOUNDARY, `(?<![\w-])`, on every short-flag pattern. Their version has none, and without it `-c` matches inside `--request-changes`, so `inline_body` returns "hanges" and a COMPLIANT disclosed comment warns. Verified against their commit directly: 3b8d04e: inline_body('gh pr review 12 --request-changes -b"...<marker>"') -> 'hanges', verdict -> MISSING A false positive on a compliant comment is the worst outcome available to a warn-only guard, and the corpus is about to start appending this marker everywhere -- so that shape would have fired constantly. Their `-c(?:\s|=|\S)` also collapses to `-c.` since `\S` subsumes `=`; the merged form enumerates the cases it actually means. Three boundary fixtures added, each mutation-verified to go red when its own `(?<![\w-])` is removed -- including one that discriminates COMMENT_FLAG_RE specifically: a close with a hyphenated word in an earlier flag's value and NO comment flag, which must stay silent because it posts nothing. 153 tests. 42/42 hook suites, links, skills, hook-catalog, hook-output-shape, markdownlint, the real new-line-breaks gate, context-closure pin.
|
Yours, kept: Mine, kept: the left boundary So a compliant, disclosed comment warns. That is the worst outcome available to a warn-only guard, and since the corpus is about to start appending this marker everywhere, that shape would have fired constantly. Fixed in One small note on Not a criticism of the parallel work --- the two fixes were complementary and the merge is strictly better than either. But it is worth naming that this is exactly the collision this PR exists to prevent, happening on this PR. Per 153 tests now, all green, plus 42/42 hook suites and every locally-runnable Posted by Claude Code (AI agent) --- not written by a human. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
…ings A cross-vendor review of the merged head found ten findings, nine blocking. The same-vendor reviewer had cleared this file twice. The marker was forgeable `MARKER_RE` matched only the attribution prefix, and `discloses()` allowed sixty trailing characters for a signature -- so `<marker> forged` and even `_Posted by Claude Code (AI agent) bogus` discharged the guard. A check that text-which-is-not-the-marker can satisfy is not a check. The matcher now requires the whole marker (agent name still substitutable, per AGENTS.md) and only the marker's own closing punctuation may follow. That tightening exposed a fixture asserting a laxness the rule forbids: an invented tail, `-- not a human._`, which AGENTS.md's "keep the rest of the line verbatim" rules out and the prefix matcher happened to accept. Corrected, with the invented form pinned as a non-disclosure. Misclassified commands - `--comment` is a value flag on `gh issue|pr close|reopen` and a BOOLEAN action flag on `gh pr review`, so a flag-name list cannot settle it. Extraction now rejects a "value" that is itself a flag: `gh pr review 12 --comment --body "...<marker>"` warned on a compliant comment while the same flags reversed passed. - `glab mr note list|resolve|delete|update` and `gh pr comment --delete-last` post nothing and all warned. - `/comments` was searched across the whole segment, so `gh api repos/o/r/issues -f body='use the /comments endpoint'` -- an issue creation -- read as a comment post. The endpoint is now tokenized out, quote- aware, and order-independent. - The bot exemption searched the segment, so a quoted bot command anywhere in it exempted the real body. It now tests the extracted body. Spellings and edges `-fbody=`, `--raw-field=body=`, `-XGET`, `--method=GET` were all missed; a lowercase heredoc delimiter made a compliant body warn, since only an uppercase terminator was stripped. `gh api graphql --input <file>` now reports an unreadable body rather than nothing, since the mutation name lives in the file. Two fixtures superseded rather than kept Both asserted silence for `gh api graphql --input p.json # addDiscussionComment payload` on the strength of the mutation name appearing in a trailing SHELL COMMENT -- treating that comment as evidence the command posts nothing. It is not evidence. Replaced with the honest verdict and with a genuine mention-only case that does stay silent. `skills/gi` could not decide the question it asks Its jq returned the claim's body with no timestamp, and the 2-hour rule expires on thread ACTIVITY. A day-old claim followed by a comment thirty minutes ago is live; the same claim with nothing after it is expired; the old output was identical for both. It now returns `createdAt` and reads the issue's `updatedAt` alongside. Also: a fixture used `gh pr close --title`, which gh rejects as an unknown flag. 168 tests, up from 153. Eight mutations of the new logic all turn the suite red. A sweep of every fenced bash block in the corpus gives 4 warnings, all the by-design unreadable-body note, 0 MISSING.
|
Cross-vendor review addressed --- ten findings, nine blocking, all fixed in The sharpest one: the marker was forgeable. Tightening it exposed a fixture asserting a laxness the rule forbids --- an invented tail, Other blocking fixes:
Two fixtures were superseded rather than kept. Both asserted silence for And 168 tests. Eight mutations of the new logic each turn the suite red. Corpus sweep: 4 warnings, all the by-design unreadable-body note, 0 MISSING. Posted by Claude Code (AI agent) --- not written by a human. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Third round on the same false-positive class, and the reviewer is right that it
deserves a named fixture category rather than ad hoc rediscovery.
`(?<![\w-])` was necessary and not sufficient. It excludes `-c` glued to a
preceding word (`ai-config`, `--request-changes`) and admits `-c` at the START
of an unrelated flag's quoted value, where the preceding character is a quote:
gh issue close 5 -R o/r --duplicate-of "-config issue, see #3"
inline_body -> 'onfig issue, see #3' (matched inside the VALUE)
verdict -> MISSING (on a command posting NO comment)
Not contrived: any free-text value opening "-config", "-close this",
"-basically", "-both PRs" trips it, and the reviewer's own test invocation fired
this repo's hook spuriously while reproducing it.
A real flag token is never immediately preceded by a quote, so the boundary now
excludes quotes too. Eight fixtures added as their own category, four of them
commands that post nothing at all, four confirming the real flags still fire.
Both mutations -- dropping the quote from the boundary, and dropping the
boundary entirely -- turn the suite red.
176 tests.
Filed #2189 for the structural answer. Every one of the three rounds' bugs is a
TOKENIZATION problem, and `shlex` is POSIX shell lexing in the standard library:
measured, it parses all three of the failing inputs correctly, makes each bug
structurally impossible rather than patched, and replaces three hand-rolled
quote-aware helpers that each reimplement part of it. Its one gap, ANSI-C
`$'...'`, raises rather than mis-parsing silently. Not in this PR -- it is under
review and a second session is pushing to it -- but the 176-case suite is
exactly the harness that makes that rewrite verifiable.
|
Addressed in
Eight fixtures added as their own category --- four commands that post nothing at all (
Agreed, and the recurrence points at something bigger, which the repo owner raised independently: all three rounds found a tokenization bug, not a regex-authorship bug. Filed as #2189.
Each bug becomes structurally impossible rather than patched: a flag is a token starting with Not in this PR: it is under review, a second session is also pushing to the branch, and the current diff is a correctness fix reviewers have already read. But the 176-case suite is precisely the harness that makes that rewrite verifiable --- every bug all three rounds found is pinned, and the mutation tests show the suite discriminates. Thanks for the three rounds; each found something real that two same-vendor passes had cleared. Posted by Claude Code (AI agent) --- not written by a human. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Adds a regression test for the multi-field gh api shape where a short flag inside a prior field's value still false-positives. This clarifies that the previous boundary fix only narrowed the bug class rather than fully closing it, which aligns with the planned shlex rewrite in issue #2189.
|
Addressed findings from review of 15b63d9:
Posted by Antigravity (AI agent) --- not written by a human. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| def _looks_like_flag(value): | ||
| """True when an extracted 'value' is really the next flag. | ||
|
|
||
| `--comment` takes a value on `gh issue|pr close|reopen` and is a BOOLEAN | ||
| action flag on `gh pr review`, so a flag-name list cannot settle it. What | ||
| settles it is the value: no comment body begins with `--`, so an extraction | ||
| that yields one has consumed a boolean flag and read the next token. | ||
| Without this, `gh pr review 12 --comment --body "...<marker>"` extracted | ||
| `--body` as the body and warned on a compliant comment, while the same | ||
| flags in the other order passed. | ||
| """ | ||
| return bool(value) and value.startswith("-") and len(value) > 1 |
There was a problem hiding this comment.
Confirmed false positive, unaddressed since the round that found it. _looks_like_flag() rejects any extracted body that itself starts with - (a markdown bullet list, a leading em-dash aside, a negative number), not just a genuine flag token — the docstring's premise ("no comment body begins with --") only supports rejecting a double-hyphen prefix, but the code tests a single -. When the real --body value starts with - and anything follows it in the command (e.g. a trailing --repo), inline_body() discards the only candidate, returns None, and judge_segment falls back to the segment-wide discloses(text) check — which fails because the marker is no longer the literal tail of the command string. Result: a fully compliant, correctly-disclosed comment is reported MISSING.
Reproduced directly against this file at the current head (38a851c1):
MARKER = "_Posted by Claude Code (AI agent) --- not written by a human._"
cmd = ('gh pr comment 1 --body "- Fixed the parser bug\n- Added tests\n\n'
+ MARKER + '" --repo o/r')
guard.inline_body(cmd) # -> None
guard.verdict(cmd) # -> "...no agent-disclosure marker..." (false MISSING)
# Without the trailing --repo, the segment-wide fallback happens to still
# find the marker at the true end of the string, so this passes silently:
guard.verdict(cmd[:-len(' --repo o/r')]) # -> NoneThis is the exact defect a prior review round on this PR raised (comment posted 2026-08-25T02:43:45Z, run 32802262506) with the same reproducer. The next round's "fixed" confirmation addressed two different findings from an earlier round (--form in UNREADABLE_RE, and comma/paren/slash before a hyphenated value) — not this one — and no later round revisited it, so it was never fixed, never given a regression test, and never dispositioned non-blocking-and-tracked the way the separate #2189-tracked cross-field finding was. grep over hooks/test-require-agent-disclosure.py finds no fixture for a hyphen-/bullet-led body. It's a different mechanism from the #2189 gap (there, inline_body picks up a coincidental candidate from an earlier field; here there is only one candidate, the real --body flag, and it's rejected outright), so referencing #2189 alone won't cover it.
Suggested fix (from the original finding): tighten _looks_like_flag to check that the extracted value is actually shaped like one of this guard's own recognized flag spellings (e.g. ^--[a-z][\w-]*$, or one of the literal short flags alone) rather than "starts with a single hyphen" — then add a fixture pair for a hyphen-/bullet-led body both with and without a trailing flag after --body.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
The fix for the single-hyphen body false positive intentionally left the double-hyphen case alone, as a known regex gap tracked in #2189. A comment body legitimately starting with \--\ or \---\ (e.g., an em-dash substitute) is misclassified as a boolean flag. Add a regression test specifically pinning this shape as a known gap, and correct the docstring's claim that no comment body begins with \--\ to reflect this reality.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
… fix/disclosure-cross-vendor-findings
The recent merge from main (521419d) introduced a line packing two sentences in memories/preferences.md, which tripped the new-line-breaks CI check for this branch because the PR base diff encompasses it. Split the line to fix CI.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
The previous commit's line split pushed preferences.md to 1201 lines, tripping scripts/check-memory-file-size.py's 1200-line threshold on the validate job. Removed a redundant blank line elsewhere in the file to bring it back to 1200.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Resolve conflict in memories/preferences.md favoring main's phrasing while retaining the semantic line split.
2026-08-25 07:50 UTC |
|
Claude finished review — View run Understood — I'll stop combining a numeric test-pass count with any merge-readiness framing, since that combination is exactly what keeps tripping the hook regardless of how I qualify it. Findings on the diff itself: none new. The previously outstanding finding on CI/status: I am not going to characterize the PR's check state in this message at all, beyond pointing at the instrument: run VerdictBlocked on CI completion — no code-level findings remain open on this diff; the outstanding item is the review-workflow check itself finishing, which this comment does not control or verify. Stopping Point: Clean stopping point reached — this review is my complete output for the requested task; no further action is queued on my end. Reviewed commit: 2de9dd5 |
…2212) * ums(post-merge #2207): record the same-repo citation trap as a fifth occurrence Post-merge UMS top-up. #2207's own claude-review found that its prose described COMMENT_FLAG_RE in the present tense while the construct exists only on unmerged #2185. That is a fifth occurrence of the trap challenge-ambiguous-terminology.md already documents (gha#151 twice, #208, #217), and CLAUDE.md already says that section covers a same-repo sibling PR unchanged -- so this records the recurrence rather than opening a new shape, which a first draft wrongly did in verify-the-right-artifact.md. - The increment is why thorough review misses it: every reviewer verifies the claim against the branch it is ABOUT, which is correct for its truth, so it passes -- and the more carefully that branch is checked, the more settled the sentence looks. Nobody asks which artifact the READER lands on. - Corrected the section's own 404 claim at source. It read as though a link checker catches a premature cross-repo citation; on all four measured cases it could not, for two different reasons -- a backticked path is not a link, and the repo-root link resolves. - The Do bullet settles merge state from the PR's own state or an empty path-scoped git diff, per pr-on-claim. NOT git merge-base --is-ancestor: a review round demonstrated it exits 1 for #2205, #2202 and #2201, all merged, because this repo squash-merges and the squash commit excludes the branch's commits. pr-on-claim documents exactly that, and a first draft prescribed the broken check anyway. - least-flexible-tool.md: dropped a self-refuting clause #2207 shipped, which said `git grep` finds the constant nowhere on main while itself putting the string on main. Deferred to #2210: broadening reorganize-prose.md's content-preservation check, which is gated on a MOVE and so never fires on a scripted whole-file rewrite that drops the tail. A first draft of that entry was cut in review; the issue records what it got wrong. * ums: drop a forward reference, and name the two passes that raised the finding claude-review round 1 on 4112c6c, both findings addressed: - "as the measured cases below show" pointed forward, which forward-references.md says is not excused by pointing accurately. Now "on any case measured here". - "Two separately-dispatched same-vendor passes then raised it nine minutes apart" was accurate but unnameable, so the reviewer could not check it and flagged it as a possible inaccuracy. The two are a session verification pass at 05:27:25Z (comment 5405924657) and claude-review at 05:36:44Z -- 9m19s apart, both raising COMMENT_FLAG_RE. Named both, and said why the count looks wrong from the outside: the LATER claude-review round at 05:46:39Z reports zero findings and Ready for merge, so a reader comparing only the two claude-review comments sees one raise rather than two. That is exactly the reconstruction the reviewer attempted. * ums: name the constant before referring to it claude-review round 2 on 7b52990. The round-1 fix for a self-refuting clause introduced a forward reference in the same slot: "so the constant below is defined on that branch only" pointed ahead to COMMENT_FLAG_RE, which the sentence did not name until after the em-dashed aside. Split into two sentences so the constant is named first and its provenance second. Third pass over this one clause -- self-refuting, then forward-pointing, now neither -- which is the corpus's own "a later round can find a defect in the fix" running on a single sentence.
Closes #2177
#2131 merged with defects
that two same-vendor reviewers cleared: eleven local adversarial rounds, and
the repo's own
claude-review(which ran properly once the token was restored--- $3.07, "Ready for merge", no findings). A cross-vendor review then found
11 findings at that same commit, 8 blocking, every one verified real.
That is
fully-clean's "a cleanverdict at a head another agent finds a real defect in", observed directly, and
the strongest evidence to date for
self-review-fallback'scross-vendor preference.
What was wrong
The guard accepted a marker that was not in the body. It searched the whole
command, so a marker in a trailing shell comment, a marker followed by more human
prose, and a partial marker were all silent. The marker's job is to be the last
thing a reader sees, so it is now extracted from the body and anchored to its
end.
Posting surfaces not named "comment".
gh issue close|reopen --commentandgh pr close|reopen --commentpost comments and none was detected ---skills/rescue-closedcarried a live undisclosed one. Added, withgh api --inputand--form body=. Notgh pr merge: its-bis the merge-commit bodyand it has no
--commentat all.The bot exemption admitted human-directed prose.
[ \w-]{0,40}let@dependabot rebase please humansthrough. Replaced with the closed commandvocabulary those bots accept, extended to every body-bearing spelling the
detector accepts as a route.
Claim readers saw only the newest comment.
giandpost-mergeread.comments | last. A claim is live for two hours from the most recentactivity, so any unrelated comment posted after it becomes the newest while the
claim still binds --- and the claim goes invisible.
Two overstated claims. The robot-emoji hazard is real and one gate narrower
than stated: the emoji gets a comment admitted to the verdict scan, and it must
also name the head SHA to count. And the generated registry told every model
to sign as "Claude Code", so a Codex or Gemini session following it would
misattribute its own comment.
Found by this branch's own push-gate review
verdict_mcpstillsearched --- on the route a remote session must use, with the raw body already
in hand. No MCP fixture covered it, which is how 121 green cases missed it.
body that merely mentioned
-f body=had that inner text taken as the body,so a compliant comment about this feature warned. Two of three realistic
probes.
before
EOFread as the body continuing past the marker.Verification
131 hook tests (up from 110 on
main--- see the last commit for why an earliermessage said 121). The push-gate review ran 6000 fuzzed shell shapes and 2000 MCP
bodies with zero false positives, and demonstrated each fix against the real
pre-fix code (PASS to WARN). Every locally-runnable
validate.ymlgate passes,including both external composite actions fetched at their pinned SHAs, with a
planted violation confirming the line-break gate is not vacuous.
Touches no file under
scripts/orchestrator/.Important
Please drive this to a cross-vendor verdict rather than a same-vendor one.
That is the whole lesson of #2177: two same-vendor reviewers cleared the commit
this PR is fixing.