Filed by the domain:skills seat (session session_019RfFHiRCSs3JXLK4cwcfox, os-steve) from the in-seat review of PR #15114 (#15083). Recorded as a latent shape, measured ABSENT on the tree at e98bfc87; not a defect in that PR's ruled scope and deliberately not a patch round on it.
What
DIRECT_CHECK_INVOCATION ends an argv tail at any of ;|&<>(). Since PR #15114 the tail is tokenised (argvTokens) and classified (WORKFLOW_VALUE_SOURCE): a token carrying ${{ … }}, ${VAR}, $VAR or a shell special is a VARIABLE and keeps the invocation out of --commands; anything else is a LITERAL and renders as a runnable command. Two shapes fall between the two rules:
- a command substitution in the value position —
--base "$(git merge-base origin/main HEAD)" — is cut at the (, leaving the tail --base "$; the unclosed quote becomes the token "$, the classifier finds no variable in it, and the key scripts/check-x.mjs --base "$ renders as a LITERAL invocation into --commands: a truncated argv that looks runnable, the one outcome the file's own docblock names as worst;
- the same for any tail whose quote is left open by a terminator character inside the quoted value (
'a;b', "x|y").
Measured at e98bfc87: zero live direct check invocations in .github/workflows/*.yml carry a paren or a terminator inside a quoted value (the only paren hits are comment lines), so no derived key is affected today. The self-test's truncation pin asserts no continuation backslash and no stray redirection fd — it does not assert balanced quotes, so the day a workflow writes a $(…) value the tool would render the truncation silently.
Ask (XS, scripts/pm/dispatch-gates.mjs only, serial behind PR #15114)
Treat an unbalanced quote in a tokenised tail, or a token ending in a bare $, as NOT RENDERABLE: classify it as a variable (name it as the unresolved remainder) or refuse the argv half and keep the bare key, whichever the file's "a missing lead, never a fabricated one" rule prefers — and extend the truncation pin to assert balanced quotes over every derived key, with a fixture quoting the $(…) shape.
Refs
#15083 / PR #15114 (the classifier) · #14880 / PR #15081 (the (script, args) key and the refusal it replaced).
Generated by Claude Code
Filed by the
domain:skillsseat (sessionsession_019RfFHiRCSs3JXLK4cwcfox, os-steve) from the in-seat review of PR #15114 (#15083). Recorded as a latent shape, measured ABSENT on the tree ate98bfc87; not a defect in that PR's ruled scope and deliberately not a patch round on it.What
DIRECT_CHECK_INVOCATIONends an argv tail at any of;|&<>(). Since PR #15114 the tail is tokenised (argvTokens) and classified (WORKFLOW_VALUE_SOURCE): a token carrying${{ … }},${VAR},$VARor a shell special is a VARIABLE and keeps the invocation out of--commands; anything else is a LITERAL and renders as a runnable command. Two shapes fall between the two rules:--base "$(git merge-base origin/main HEAD)"— is cut at the(, leaving the tail--base "$; the unclosed quote becomes the token"$, the classifier finds no variable in it, and the keyscripts/check-x.mjs --base "$renders as a LITERAL invocation into--commands: a truncated argv that looks runnable, the one outcome the file's own docblock names as worst;'a;b',"x|y").Measured at
e98bfc87: zero live direct check invocations in.github/workflows/*.ymlcarry a paren or a terminator inside a quoted value (the only paren hits are comment lines), so no derived key is affected today. The self-test's truncation pin asserts no continuation backslash and no stray redirection fd — it does not assert balanced quotes, so the day a workflow writes a$(…)value the tool would render the truncation silently.Ask (XS,
scripts/pm/dispatch-gates.mjsonly, serial behind PR #15114)Treat an unbalanced quote in a tokenised tail, or a token ending in a bare
$, as NOT RENDERABLE: classify it as a variable (name it as the unresolved remainder) or refuse the argv half and keep the bare key, whichever the file's "a missing lead, never a fabricated one" rule prefers — and extend the truncation pin to assert balanced quotes over every derived key, with a fixture quoting the$(…)shape.Refs
#15083 / PR #15114 (the classifier) · #14880 / PR #15081 (the
(script, args)key and the refusal it replaced).Generated by Claude Code