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
Commit b9dec72
Browse filesBrowse the repository at this point in the historyBrowse files
fix(devx): read a quoted blob as an argument, not as a program being run (#10889)
`invokesScript()` in check-shard-attestation added adjacency for #6589 but
tokenized with `command.split(/\s+/)` plus a per-token quote strip, so a quoted
string handed to `echo` was torn into words and the script name plus its flag
INSIDE that string read as a genuine invocation.
The reading is now the quote-aware one #10884 built for the sibling gate, moved
to the lexer whose output it consumes rather than mirrored: `commandWords` and
`invokes` live beside `shellCommands` in check-shard-attestation, and
check-required-contexts imports them over the one import edge that already
existed between the two files.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DdCnBGcHeufjrq7drTD3wt
assert(invokesScript('node scripts/check-shard-attestation.mjs --gate "a # b" --verify','--verify'),'a quoted `#` is an argument, not a comment — the command must not be truncated');
793
923
assert(invokesScript("node scripts/check-shard-attestation.mjs --gate 'a || b' --verify",'--verify'),'a quoted separator is an argument, not a command boundary');
794
924
assert(!invokesScript(undefined,'--verify')&&!invokesScript(null,'--verify'),'a step with no run: is not an invocation');
925
+
926
+
// ── …and the PROGRAM word must be unquoted (#10889) ───────────────────────
927
+
//
928
+
// Adjacency (above) closed co-occurrence but not PROSE. The tokenizer under
929
+
// it split on whitespace and stripped the quotes off each piece, so a quoted
930
+
// string handed to `echo` was torn into "tokens" and the script name plus its
931
+
// flag INSIDE that string read as a program being run with an argument.
932
+
//
933
+
// ⭐ Direction, because it decides which limb is the dangerous one to lose:
934
+
// these feed PRESENCE questions (does this job end with the `--emit` pair,
935
+
// does this gate run `--verify`), and a presence assertion fails toward a
936
+
// silent GREEN — the guard reporting that a leg attests when it does not.
937
+
// So every "prose" case below is paired with the same text made REAL, and
938
+
// #6589's cases above stay exactly as they were: a recognizer tightened until
939
+
// nothing satisfies it is a worse defect than the prose it excluded, because
940
+
// what a permanently red pin gets is loosened.
941
+
assert(
942
+
!invokesScript('echo "node scripts/check-shard-attestation.mjs --verify is how you would check"','--verify'),
943
+
'#10889: an `echo` QUOTING the invocation is prose — the quoted blob is ONE argument, not a program being run',
944
+
);
945
+
assert(
946
+
!invokesScript("echo 'node scripts/check-shard-attestation.mjs --verify is how you would check'",'--verify'),
947
+
'#10889: …and single quotes word-split no more than double quotes do',
948
+
);
949
+
assert(
950
+
!invokesScript('echo "run node scripts/check-shard-attestation.mjs --verify to reproduce"','--verify'),
951
+
'#10889: prose WRAPPED AROUND the invocation is still prose',
952
+
);
953
+
// ⚠️ The two `::error::` spellings are pinned together on purpose. The FUSED
954
+
// one was already false before this fix — but only incidentally, because
955
+
// `::error::` runs into the basename and the joined token matches neither
956
+
// `=== SCRIPT_BASENAME` nor `endsWith('/' + SCRIPT_BASENAME)`. The SPACED one
957
+
// is the same annotation, one space different, and it COUNTED. Keeping only
958
+
// the fused case would let the accident stand in for the fix.
0 commit comments