Skip to content

fix(server): command keys match what a shell command runs, not what it mentions - #243

Merged
lukemaj merged 9 commits into
mainfrom
fix/232-command-keys-run-not-mention
Oct 14, 2026
Merged

lukemaj merged 9 commits into
mainfrom
fix/232-command-keys-run-not-mention

Conversation

@lukemaj

@lukemaj lukemaj commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

What: Both matchers recognize shell -c scripts in every word position while excluding ordinary quoted prose and literal heredoc bodies.
Why: Executable-position tracking dropped real shell scripts after control syntax and command-running tools.
So what: The planner reviews and merges these final candidates; shared remaining limits are tracked in #284.

Closes #232. Twin PR: toolboxmd/contextmd#52.

Behavior

Unquoted words and quoted words whose dequoted value has no whitespace count in every position. Quoted prose with whitespace and literal heredoc bodies drop. Executed substitutions/backticks, expanding-heredoc substitutions and dequoted shell scripts stay visible. Path extraction still sees all raw words.

Any eligible word whose basename is sh/bash/zsh/dash/ksh starts shell option recognition, regardless of command position. Options containing c, including clusters and options before c, select one following word as a dequoted script. Consuming that script ends recognition for that invocation, so later positional -c/-ce words cannot reopen it. All command-position, assignment, wrapper-option and redirect-target tracking is removed.

All eight supplied cases now match: shells after then, !, braces, do, xargs, find -exec, timeout and ssh. Their quoted-prose negative companions do not. The prior post-script positional negatives remain excluded. A printed shell invocation such as echo bash -c 'gh pr create' now matches in the accepted safe direction; the former echo sh -c 'gh pr create' negative deliberately becomes a policy-positive fixture.

Prior substitution boundaries, backslash parity, exact/tab-stripped/empty heredocs, Unicode marker parity, here-strings, arithmetic/parameter expansions, script dequoting and ANSI-C scripts remain covered.

Bake fixtures

The bare chromeria-v2.sqlite command key matches bare filename, tilde/absolute arguments, readonly variants and quoted single filenames/paths. Both query-bearing SQLite URI forms miss the bare key because their basename includes ?mode=ro. The literal Python test-edit heredoc (1672), Issue-body heredoc (26379) and its quoted --body prose companion remain excluded. Raw path shapes are retained.

Proof

  • Chromeria ed1af37e72fd7dc970914dbd20dd4c9a2f933cda: from apps/server, pnpm exec vp test run src/contextmd/, 130 passed in four files.
  • ContextMD implementation 5d0e4e6b9230af71d8ea3784ab4a30e4bd0ab4d3: focused SegmentsTest 21 passed; CONTEXTMD_CHROMERIA=/home/luke/dev/toolboxmd/chromeria-worktrees/232-command-keys python3 -m unittest discover -s tests -t ., 156 passed, including 18 isolated real-server/hook contracts, no skips. Final 3d0051a44d18f375bf901b340681a55d94bedd3f only adds Track shared shell matcher limits and native shell proof #284 to the feature map, as repository instructions require; matcher and entire tests tree have identical Git objects.
  • Both new groups fail before the fix: Chromeria two failing tests, Python 15 failing assertions, at 600c9281a5/1cdf9ff268. Both old production extractors make 15 wrong decisions across these new fixtures; the same fixtures pass now.
  • 559 unique production commands, zero differences in command words, raw path shapes and key hits. Includes all 484 previous inputs, both current suites' collected fixtures/tool inputs/helper calls/path templates, the supplied eight cases and controls. Python raw path shapes use production shell_paths before repository normalization. Full output is in the round-6 reply.
  • 173 Bash controls, preserving all previous 154 and adding 19; 25 policy fixtures and all nine bake fixtures pass. The former echo-sh control keeps its Bash no-run result but now expects a key hit under the explicit printed-invocation rule. All experiments use PATH-local gh stubs, never real gh. SSH, sudo and SQLite use harmless stubs; absent native zsh/ksh use Bash stand-ins. No SSH connection or live database was opened.
  • Scoped server lint and typecheck pass: pnpm exec vp lint apps/server, pnpm exec vp run --filter t3 typecheck. Server Knip exports pass; full server Knip retains solely the existing unlisted cc binary in Server Knip reports the OS cc compiler as an unlisted binary #270. No new matcher diagnostic. Typecheck and full Knip briefly overlapped due to a sequencing mistake; subsequent launches waited until both finished. Test and contract runs were sequential.
  • ContextMD 0.6.3 retains its single transition from main's 0.6.2, freshly checked through GitHub. Release-check passes on final 3d0051a44d; CI-relative version doctor passes on the implementation. No version bump in Chromeria; older CHANGELOG content is unchanged.

Implementation commit trees equal the tested staged trees. Contracts used temporary state and captured process groups. Probes/logs remain outside both worktrees at /tmp/232-parity-r6. The original Sol 380-input file was lost in the earlier freeze; the recovered public corpus is retained and expanded, but inclusion of any unpublished extra members remains unverified.

Known limits

Follow-up #284 owns the shared limits, with 15 one-line Bash-verified examples and identical observations from both matchers. It explicitly requires ContextMD's keys.py to change in step with Matcher.ts.

These include escaped/partly quoted heredoc markers, separator punctuation in markers, ) from case/heredoc/comments inside substitutions, -- or a script filename before -c, native zsh/ksh proof gaps, and the accepted printed-shell invocation match. Unquoted argument/comment/escaped-syntax matches remain accepted approximations. This is the final fix round for #232; future disposition belongs to #284 and does not authorize changing the accepted rule.

Delivery

Chromeria final head ed1af37e72fd7dc970914dbd20dd4c9a2f933cda, implementation base 54fb0fc1886d7ee1ef030a6e5dae419d2b263a1f; main advanced to 14d2e7e67cae9416a58247059ca48cd5199aa31a. ContextMD final head 3d0051a44d18f375bf901b340681a55d94bedd3f, integrated main 42d312460cf3672ab7454ebfcb905d9db392b3e6. Both branches were pushed through new commits without rebase or history rewrite; clean worktrees are retained for the planner's reviews. No reviews requested, statuses posted or merges performed. Website/SEO impact is none. The original upstream search found no corresponding ContextMD matcher/fix in pingdotgg/t3code.

Elon record

  • Requirements and who asked: planner's final fix round requires position-free shell script recognition, one consumed script, identical twins, preserved controls/bake, proof and one follow-up limits Issue.
  • Deleted: command-position machinery, assignment/wrapper option parsing and redirect-target state; no growing executable-position list remains.
  • Bottleneck: recognizing a shell word anywhere while ending that invocation's option lifetime at its script.
  • Checked myself: the interrupted Sol review, failing-before groups, all eight cases and negatives, 559 production comparisons, Bash/policy/bake controls, 130 Chromeria and 156 Python tests with 18 contracts, scoped checks, source/tree identities, version/main state and live heads.

Work by Codex gpt-6.1-sol, max reasoning effort, T3 Code Codex harness.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:M labels Oct 13, 2026
@github-actions

github-actions Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 5.0 KiB 5.0 KiB 0 B (0.0%) 6.8 KiB ✅
Codex Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Codex Live turn WebSocket wire 1.2 KiB 1.2 KiB 0 B (0.0%) 2.0 KiB ✅
Codex Live turn WebSocket decoded 20.9 KiB 20.9 KiB 0 B (0.0%) 29.3 KiB ✅
Codex Live turn messages 2 2 0 (0.0%) 8 ✅
Claude Total thread wire 5.0 KiB 5.0 KiB −24 B (−0.5%) 6.8 KiB ✅
Claude Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Claude Live turn WebSocket wire 1.2 KiB 1.2 KiB −24 B (−2.0%) 2.0 KiB ✅
Claude Live turn WebSocket decoded 21.2 KiB 21.2 KiB −41 B (−0.2%) 29.3 KiB ✅
Claude Live turn messages 2 1 −1 (−50.0%) 8 ✅

Baseline: 54fb0fc · PR result: 4398db7 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@lukemaj

lukemaj commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

What: Independent review FAIL at ab97c49.
Why: Confirmed blockers remain in this candidate.
So what: The implementation owner must fix the findings and obtain a fresh exact-head review.

VERDICT: FAIL
Base: 95fb684.

Blocking findings:

  1. P1, apps/server/src/contextmd/Matcher.ts:57-73: all heredoc bodies are removed, including expanding heredocs. The command 'cat <<EOF' followed by a line containing '$(gh pr create)' and the closing EOF executes gh pr create, but the matcher extracts only ['cat'] and misses its rule. Preserve executable substitutions in expanding heredocs while excluding literal body text.

  2. P1, Matcher.ts:90-95: recursively processing a shell's -c string drops quoted executable words. bash -c "'gh' pr create" executes gh pr create, but extracts ['bash', '-c', 'pr', 'create'] and misses its rule. Preserve executable shell-word quoting/concatenation inside the -c script.

  3. P2, Matcher.ts:85-93: substitution extraction ignores escaping. echo "$(gh pr create)" prints the literal substitution and executes no gh, but matches gh pr create, recreating a false deny. Ignore escaped substitution operators.

  4. Blocking CI, Matcher.ts:45: exported visibleCommand is unused outside its module. Exact-head CI run 38411420256 fails Knip with 'Unused exports (1): visibleCommand apps/server/src/contextmd/Matcher.ts:45:14'. Keep the helper private unless it has an actual external consumer. Aggregate Check is red. Test also fails at apps/mobile/src/features/review/shikiReviewHighlighter.test.ts:88; that failure is outside this diff and is not attributed to this matcher.
    CI: https://github.com/toolboxmd/chromeria/actions/runs/38411420256

  5. Required parity gap, Matcher.ts:143 versus ContextMD Needs-a-look panel: skim suspicious agent work, dismiss or dig in #51 contextmd/serve/keys.py:93: echo "gh pr create" matches Python check but not Chromeria serving. The PR explicitly leaves Python unchanged, but this batch requires agreement. Bring the changed command semantics into parity or have the owner explicitly resolve that requirement before delivery.

Proof:

  • Original scoped serving suite: 71/71 pass; unchanged tests on base fix(server): path keys match files a shell command names #240 production sources: 2 assertion failures, 69 pass.
  • Four temporary tests: database-key control passes; expanding-heredoc, quoted-command and escaped-substitution assertions fail. Total 72 pass, 3 fail.
  • Verified execution oracles with /bin/bash and a harmless exported gh function printing EXECUTED: the heredoc and quoted command execute it; the escaped substitution only prints literal text.
  • Explicitly confirmed sqlite3 ~/.t3/userdata/chromeria-v2.sqlite still matches bare key chromeria-v2.sqlite.
  • ContextMD Needs-a-look panel: skim suspicious agent work, dismiss or dig in #51 real-server/hook contracts against this head: 18/18 pass. Direct TS/Python probes confirm the parity divergence.

These findings do not request command-position-only matching or removal of the accepted bare argument key.

Reviewed the complete diff, linked Issue and prior PR/Issue review comments, and affected selection, harness, state and transport consumers. All eight heads matched the brief. Tests used exact-head git archives in temporary directories and existing dependencies. Baseline runs held the head tests constant and restored changed production files from the stated merge base.

Chromeria command: vp test run --config review.config.ts, with include=['src/contextmd/*.test.ts'], node environment and serial files.
ContextMD command: PYTHONDONTWRITEBYTECODE=1 CONTEXTMD_CHROMERIA= python3 -m unittest discover -s tests -t .; baseline: python3 -m unittest tests.test_serve.

Passing state/route tests retain the cap of 3, failed/pending reads, session/epoch isolation, dropped/concurrent deliveries, fail-open guards and after-action suppression, including Grok carries. No checkout, reset, pull or source edits in any checkout. No private data or credentials found in the diff. Proof is synthetic hook/production-code execution, not a fresh live model session or deployment.

Reviewer: Codex gpt-6.1-sol, independent review, requested high effort.

@lukemaj

lukemaj commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

What: FAIL at ab97c49b0591e31d34bbc49ce90a4813e98d7248.
Why: A quoted mention can still match a command key, the new helper fails Knip, and this parse no longer matches contextmd's command matcher.
So what: Fix the three items below and get a new review of the new head. Do not treat the shiki failure as part of this change.

Head matches the brief. Base is fix/234-shell-path-keys (95fb684).

Confirmed separately: sqlite3 ~/.t3/userdata/chromeria-v2.sqlite still matches the bare command key chromeria-v2.sqlite. Importing this head's Matcher.ts returns words sqlite3 and ~/.t3/userdata/chromeria-v2.sqlite, and hasCommand hits on the basename. The same holds with -readonly and with an absolute /Users/u/.t3/... argument. A double-quoted path does not, which this PR intends; the path key from #240 still sees it.

Blocking:

  1. Matcher.ts visibleCommand, the double-quote arm, and SUBSTITUTION. echo "\$(gh pr create)" does not run the keyed command. The substitution regex still sees $(...) after the backslash, so firstMatch hits. The same arm treats an escaped backtick the same way. Issue contextmd serving: command keys fire on mentions such as echo strings and heredocs #232 requires that a quoted argument which only mentions a keyed command does not match. echo "gh pr create" is fixed; the escaped form is not.

  2. Matcher.ts:45, export const visibleCommand. Nothing outside the module imports it. CI run 38411420256, job Lint, fails Knip with Unused exports (1): visibleCommand. Drop the export. Aggregate Check is red because of this.

  3. Command keys no longer agree with contextmd. keys.py still does keys.words = words(command), so a quoted mention matches there and does not match here. Path extraction is unchanged and still agrees with contextmd#51. This batch requires the two matchers to agree, so the command parse has to land in keys.py as well, including the escape fix.

Not blocking:

  • An expanding heredoc body is dropped, so cat <<EOF plus $(gh pr create) does not match. Issue contextmd serving: command keys fire on mentions such as echo strings and heredocs #232's acceptance says heredoc bodies do not match. I am not asking for those substitutions to count.
  • bash -c "'gh' pr create" is missed (words are bash, -c, pr, create). Unquoted bash -c 'gh pr create', cd &&, env, and a pipeline still match, which is the acceptance list. Quoted argv0 inside -c is a limit, not this issue's case.
  • The file header still says command keys match inside quotes and heredocs. Update it when the behavior is fixed, so the next edit does not restore mention matching.
  • Root Test failed in apps/mobile/src/features/review/shikiReviewHighlighter.test.ts. This diff does not touch that file. Test Server 1-6 succeeded, so the serving tests on this head passed. The shiki failure is not a finding against this matcher.

DENY_CAP, fail-open, after-action suppression, and the full-read lift are not in this diff.

No credentials or database contents in the diff.

lukemaj added a commit that referenced this pull request Oct 13, 2026
…ords and escapes

An unquoted-marker heredoc expands $(...) and backticks, so they run; a quoted
word in command position ('gh' pr create) is the command; an escaped \$( or
backtick is literal. visibleCommand is private again (Knip). From Sol's review
of #243, each checked against /bin/bash.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@lukemaj

lukemaj commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

Author response to Sol's review of ab97c49b05: all five accepted. Head 7463b9dd28: (1) an unquoted-marker heredoc expands $(...)/backticks, which now match; a quoted marker stays literal. (2) A quoted word in command position ('gh' pr create, bash -c "'gh' pr create") is the command. (3) Escaped \$( and backticks are literal. Each checked against /bin/bash. (4) visibleCommand is private; local Knip on apps/server reports no unused exports. The mobile shikiReviewHighlighter Test failure is outside this diff (main and #240 pass Test). (5) Parity: toolboxmd/contextmd#52 ports the rule to keys.py; a 24-command probe gives identical results in both. New tests failed before; vp test run src/contextmd/ 72 passed.

@lukemaj
lukemaj changed the base branch from fix/234-shell-path-keys to main October 13, 2026 14:45
lukemaj added a commit that referenced this pull request Oct 13, 2026
…ords and escapes

An unquoted-marker heredoc expands $(...) and backticks, so they run; a quoted
word in command position ('gh' pr create) is the command; an escaped \$( or
backtick is literal. visibleCommand is private again (Knip). From Sol's review
of #243, each checked against /bin/bash.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@lukemaj
lukemaj force-pushed the fix/232-command-keys-run-not-mention branch from 7463b9d to 561b0d8 Compare October 13, 2026 14:50
lukemaj added a commit to toolboxmd/contextmd that referenced this pull request Oct 13, 2026
Python parity with toolboxmd/chromeria#243: quoted strings and heredoc bodies
no longer match command keys; sh -c strings, unescaped substitutions in double
quotes or expanding heredocs, and quoted command words still do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@lukemaj

lukemaj commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto main (8288172) as 561b0d8258; no code change beyond the rebase. Includes the fixes for Sol's and Grok's findings (7463b9dd before the rebase): expanding heredocs, quoted command words, escaped substitutions, the private helper (Knip clean on apps/server). Parity with contextmd's matcher is contextmd#52 (now 2bb0c178), identical on a 24-command probe. vp test run src/contextmd/ 78 passed; typecheck and lint clean; contextmd suite with #52 OK against this head.

lukemaj added a commit that referenced this pull request Oct 13, 2026
…ords and escapes

An unquoted-marker heredoc expands $(...) and backticks, so they run; a quoted
word in command position ('gh' pr create) is the command; an escaped \$( or
backtick is literal. visibleCommand is private again (Knip). From Sol's review
of #243, each checked against /bin/bash.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@lukemaj
lukemaj force-pushed the fix/232-command-keys-run-not-mention branch from 561b0d8 to cd7768b Compare October 13, 2026 15:39
lukemaj added a commit to toolboxmd/contextmd that referenced this pull request Oct 13, 2026
Python parity with toolboxmd/chromeria#243: quoted strings and heredoc bodies
no longer match command keys; sh -c strings, unescaped substitutions in double
quotes or expanding heredocs, and quoted command words still do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@lukemaj

lukemaj commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto main with Cue #227 (a6fc446) as cd7768b85c; no code change. 101 passed; typecheck, lint and Knip clean; contextmd suite with #52 OK.

@github-actions github-actions Bot added size:L and removed size:M labels Oct 13, 2026
@lukemaj

lukemaj commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

Re-checked every review comment against cd7768b85c: all blocking findings from Sol (ab97c49b05) and Grok (ab97c49b05) were fixed in 7463b9dd before the rebases, and a probe of this head confirms each case (escaped \$( and backticks no match, echo "gh pr create" no match, expanding heredoc and quoted command word match, bare chromeria-v2.sqlite key matches sqlite3 ~/.t3/userdata/chromeria-v2.sqlite, visibleCommand not exported, Python parity via contextmd#52). New head 1639031b47 adds Grok's non-blocking item: the Matcher.ts header now describes the current matching rule. 101 tests pass; lint clean.

lukemaj added a commit to toolboxmd/contextmd that referenced this pull request Oct 13, 2026
Python parity with toolboxmd/chromeria#243: quoted strings and heredoc bodies
no longer match command keys; sh -c strings, unescaped substitutions in double
quotes or expanding heredocs, and quoted command words still do. A command
after an empty heredoc still matches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@lukemaj

lukemaj commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

What: Independent review FAIL at 1639031b472a81b0da804bab21d9d727236d06fa.
Why: Prior reported cases are fixed, but the shared scanner still misses real substitutions and matches literal heredoc data.
So what: Fix the three scanner boundaries in both matchers and obtain fresh exact-head reviews.

Blocking findings

  1. P2, apps/server/src/contextmd/Matcher.ts:97-99 and apps/server/src/contextmd/Matcher.ts:38: executable substitutions are lost at inner quotes or nested parentheses. Bash executes gh pr create in both:

    echo "$(gh pr create --title "hello")"
    echo "$(gh pr create $(printf x))"

    The first extracts only ['echo', 'hello']; the second extracts ['echo', 'printf', 'x']. The quote scanner mistakes the quote inside $(...) for the end of the enclosing string, while the flat substitution regex cannot retain a body containing another substitution. Both lose an actual matching command and its deny/serve rule. Keep substitution boundaries and their internal quoting intact, with regression cases for both shapes.

  2. P2, apps/server/src/contextmd/Matcher.ts:38: (?<!\\) treats every immediately preceding backslash as escaping the operator. An even pair of backslashes quotes the backslash, so Bash still executes the substitution:

    echo "\\$(gh pr create)"
    cat <<EOF
    \\$(gh pr create)
    EOF

    Both extract only the surrounding command and miss gh pr create. These examples contain two literal backslashes before the dollar sign. The one-backslash control echo "\$(gh pr create)" correctly does not execute or match. Determine escape parity, rather than rejecting every operator preceded by a backslash.

  3. P2, apps/server/src/contextmd/Matcher.ts:75: the terminator regex permits leading spaces and trailing whitespace for all heredocs. In this valid literal heredoc, the first indented line is data, not a terminator:

    cat <<'EOF'
     EOF
    gh pr create
    EOF

    Bash prints the command name without executing it; the matcher instead ends the body early, extracts ['cat', 'gh', 'pr', 'create', 'EOF'], and matches the command key. This recreates the false deny/serve on heredoc mentions that contextmd serving: command keys fire on mentions such as echo strings and heredocs #232 requires removing. Match the actual delimiter line exactly, allowing leading tab stripping only for <<-, not leading spaces or trailing whitespace.

These are verified execution differences, not a request to restore command-position-only matching or remove the accepted bare argument key. The same defects exist in both pinned matchers: parity alone does not establish shell correctness. I checked every example with /bin/bash and a temporary PATH-local gh stub that only prints EXECUTED to stderr, then compared both production extractors. No real GitHub command ran.

Proof and limits

  • Full review of the complete diff against main a6fc446646070701577a7b6db4b873bbf32ed55f, PR body, linked contextmd serving: command keys fire on mentions such as echo strings and heredocs #232 and all prior comments, and affected selection/state consumers. Compared the pinned Python companion PR panel shows "All fibers interrupted without error" when a PR link opens #52 at 5d2dc1e09c60dc66e8ed7ff3b7d15f71f43ed66d.
  • ./node_modules/.bin/vp test run --config review.config.ts, include src/contextmd/*.test.ts, node environment, serial files: 101/101 original tests pass. Holding the candidate tests constant on main gives 3 expected failures, establishing that the supplied regressions detect the change.
  • With five independent boundary tests: 101 original tests pass, all 5 added tests fail for the documented match assertions.
  • ContextMD PR panel shows "All fibers interrupted without error" when a PR link opens #52's full suite against this temporary exact-head server: 120 passed, including all 18 real-server/hook contracts.
  • The prior expanding-heredoc, quoted command word, escaped-single-backslash mention, private-helper and Python parity findings are cleared on their supplied cases. visibleCommand is private and exact-head GitHub CI Lint and Check are green. Bare database argument keys and raw-word path matching are preserved.
  • Python and TypeScript word extraction agrees on 45 unique commands from candidate tests and independent probes, including these new failures. Pointer full-read, partial/failed-read, cap-of-3, inline shown-lift, dropped/concurrent delivery and fail-open tests pass.

No private data or credentials found in the complete diff. Supplied positive/negative regression tests are meaningful, but do not cover these boundaries. The change otherwise uses the surrounding module's style. All writes and test processes stayed under /tmp, with dependency links to existing installed packages; no source writes in main checkouts, live ports, live database access or live Chromeria restart. This is synthetic runtime and contract proof, not live model-session evidence or deployment.

Reviewer: independent Sol, medium effort.

@lukemaj

lukemaj commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

What: PASS at 1639031b472a81b0da804bab21d9d727236d06fa. No blocking findings.
Why: Command keys match the command that runs, including the cases the earlier review of ab97c49b05 required, and they match contextmd#52.
So what: Land this with contextmd#52. The header now describes this rule.

Base a6fc446646. Quoted mentions and quoted heredoc bodies do not match. An unquoted-marker heredoc keeps unescaped $(...) and backticks. sh -c / bash -c / zsh -lc strings are unwrapped, a quoted command word is kept ('gh' pr create, g'h' pr create), and an escaped \$( or backtick is literal. Unquoted arguments still match, so sqlite3 ~/.t3/userdata/chromeria-v2.sqlite still hits chromeria-v2.sqlite. A quoted path does not hit that command key. Path keys still see every raw word. visibleCommand is not exported. DENY_CAP, the full-read lift, and inline lift are not in this diff.

This is the revised rule on #232 (quoted text and heredoc bodies), not the earlier command-position-only proposal. Unquoted rg or printf arguments still match on purpose.

Proof, temp worktree:

  • vp test run src/contextmd/: 101 passed.
  • Those two new tests against base Matcher.ts failed: echo "live check: gh pr create" still matched, and g'h' pr create did not.
  • Against contextmd#52 5d2dc1e09c60dc66e8ed7ff3b7d15f71f43ed66d: 59 commands, command words and path shapes identical, including empty heredocs. contextmd's contract file against this head: 18 passed.

Non-blocking limit, same in contextmd: bash runs echo "\\$(gh pr create)", and both matchers miss it. The single-backslash form stays literal.

No private data in the diff. Not a live model session. No checkout in ~/dev/toolboxmd.

@lukemaj

lukemaj commented Oct 14, 2026

Copy link
Copy Markdown
Contributor Author

What: Sol's round-4 findings are repaired on both pushed round-5 heads under the refined quoted-token rule.
Why: Retention depended on command position, and shell option detection stayed active after its script argument.
So what: The planner owns fresh review and merge of these candidates.

Chromeria head: 600c9281a5adc8475eedee70781610d7d6fe50e7.
ContextMD head: 1cdf9ff2681a210ad938c3dda273dffcde7c7b0d.

  1. Numbered redirections: quoted words without whitespace count everywhere. Redirects consume their descriptor and operator together, preserving script recognition for 2>/dev/null bash -c 'gh pr create' and 2>&1 bash -ce 'gh pr create'. All three Sol reproductions match, with negative quoted-prose companions in both suites.
  2. Control words: retention no longer checks executable position. if true; then 'gh' pr create; fi, ! 'gh' pr create and { 'gh' pr create; } match. Both suites also cover else, do and time -p. The stub logs execution of the negated case despite its expected exit of 1. No control-word list was added for quoted tokens.
  3. Later positional -c: consuming the one script enters argument state permanently for that invocation; the stale shell flag is deleted. All three Sol negatives stay unmatched, including bash -c 'echo "$@"' _ -c 'gh pr create'. The positive first-script companion matches. Clustered/ANSI-C flags and an executed outer substitution have controls too.

Five new groups fail on both reviewed starting heads, along with the changed quoted-path assertion: six TypeScript tests and 28 Python assertions. Both old production extractors make 27 wrong decisions across the new fixture lists. Every new fixture passes after the fix. The accepted single-token rule deliberately restores the quoted SQLite path match, and the 1672/26379 prose bodies remain excluded.

Requirements and who asked: planner's refined rule, Sol's three findings and twin proof/delivery brief.
Deleted: quoted-word retention by command position and the stale shell flag.
Bottleneck: keeping single tokens, dropping prose and ending option parsing after the one script.
Checked myself: failing-before cases, 154 Bash controls, 17 policy fixtures, nine bake fixtures, 484 production comparisons, scoped checks, required suites and live heads.

Behavior

Command keys keep unquoted words and any quoted word whose dequoted value contains no whitespace, in every position. Single, double, ANSI-C and partly quoted tokens count, including file arguments. Quoted text containing whitespace and literal heredoc bodies are excluded. Executed $(...)/backticks and substitutions in expanding heredocs remain visible; shell -c scripts are dequoted once and scanned as commands. Path keys continue to see every raw word.

The shell-word scanner records whether a word contains quoting. Retention no longer depends on executable position, so quoted words survive assignments, wrappers, numbered redirects and control syntax. The remaining position state only identifies a shell script: redirects including 2>&1 are consumed together, and consuming the first script ends option parsing. Later positional -c/-ce words cannot reopen it. The stale shell flag and quoted-command-position branch are removed.

Prior repairs remain covered: nested substitution boundaries, even/odd escape parity, exact heredoc terminators, tab stripping only for <<-, empty/multiple heredocs, <<<, arithmetic/parameter expansions, Unicode markers, outer script dequoting, clustered c options, options before -c and ANSI-C decoding/NUL boundaries. Both heredoc recognizers still use identical explicit ASCII separator boundaries, including support for Unicode and simple dash/dot literal markers.

Bake fixtures (ContextMD #39)

Fixture for command: chromeria-v2.sqlite Matches?
sqlite3 chromeria-v2.sqlite .tables Yes
sqlite3 ~/.t3/userdata/chromeria-v2.sqlite Yes
sqlite3 /Users/u/.t3/userdata/chromeria-v2.sqlite Yes
sqlite3 "/Users/u/.t3/userdata/chromeria-v2.sqlite" .tables Yes
sqlite3 'file:/Users/u/.t3/userdata/chromeria-v2.sqlite?mode=ro' No
sqlite3 file:/Users/u/.t3/userdata/chromeria-v2.sqlite?mode=ro No
Candidate 1672: literal Python test-edit heredoc naming the file No
Candidate 26379: literal Issue-body heredoc naming the file No
Candidate 26379's quoted --body prose companion No

The old quoted-path exclusion assertion is deliberately changed: a single quoted path is a real file argument. Both query-bearing URI forms still miss the bare command key because the basename includes ?mode=ro; raw path extraction retains their file path. Quoted bare names and partly/ANSI-C quoted filenames also match. Mention fixtures use synthetic bodies with the reported live shapes.

Proof

  • Chromeria 600c9281a5adc8475eedee70781610d7d6fe50e7, from apps/server: pnpm exec vp test run src/contextmd/, 128 passed in four files.
  • ContextMD implementation d6f91003afbc11b0a4e56e0644bd2d6ad28ce277: python3 -m unittest tests.test_serve.SegmentsTest, 19 passed; CONTEXTMD_CHROMERIA=/home/luke/dev/toolboxmd/chromeria-worktrees/232-command-keys python3 -m unittest discover -s tests -t ., 154 passed, including all 18 isolated real-server/hook contracts, no skips. The final ContextMD head 1cdf9ff2681a210ad938c3dda273dffcde7c7b0d adds only README wording; keys.py and the entire tests tree have identical Git objects to the tested implementation.
  • pnpm exec vp lint apps/server and pnpm exec vp run --filter t3 typecheck: exit 0, with existing warnings/suggestions outside the changed matcher.
  • pnpm exec knip --workspace apps/server --exports --preprocessor ./scripts/knip-schemas.ts --no-config-hints: exit 0. Full server Knip without --exports exits 1 solely on the pre-existing unlisted cc binary in AcpSessionRuntime.processTree.test.ts, tracked in #270; that file is unchanged from the implementation base.
  • 484 unique production extraction inputs, zero differences in command words, raw path shapes and command-key hits. The corpus recovers all 366 rows of the previous public proof (which included the earlier 187 and Sol's 251), then adds current fixtures, tool inputs/helper calls and instantiated path templates from both suites, and all published Sol/Grok reproductions. Python path shapes use production shell_paths(words(raw)) before its repository normalization.
  • Sol's original /tmp/232-sol-r4/commands.json is unavailable after the freeze cleared /tmp. This run covers the recovered public corpus and published round-4 examples; exact coverage of any unpublished extra members of that 380-input file is unverified.
  • 154 Bash positive/negative controls pass: all 123 prior controls plus 31 new controls. Another 17 quoted-token policy fixtures and nine bake fixtures pass. A PATH-local gh stub logs execution, never real gh; the negated command correctly exits 1 while its execution is logged. Database arguments use a logging sqlite3 stub. sudo is a harmless wrapper stub; absent zsh uses Bash for the simple script controls, so native Zsh semantics are unverified.
  • Five new regression groups fail on both reviewed starting heads, 23c4834c0b/782b42c758, along with the updated quoted-path assertion. Before the fixes Chromeria has six failing tests; Python has 28 failing assertions. Direct production extraction makes 27 wrong decisions across the new fixture lists in each old matcher. The same fixtures pass after the fixes.
  • versionctl release-check --json and versionctl doctor --ci --base origin/main --json pass at ContextMD 1cdf9ff2681a210ad938c3dda273dffcde7c7b0d. ContextMD retains its single 0.6.2 to 0.6.3 transition; the 0.6.2 CHANGELOG entry and all older content are byte-for-byte unchanged. Chromeria has no version bump.

Heavy checks ran sequentially. Contract servers used temporary bases and their captured process groups; no server used live userdata. Tested staged and committed implementation trees are identical. Scripts/logs remain outside the worktrees at /tmp/232-parity-r5; the full 484-row result accompanies the round-5 response in this PR thread.

Current heads and delivery

Chromeria: 600c9281a5adc8475eedee70781610d7d6fe50e7, implementation base 54fb0fc1886d7ee1ef030a6e5dae419d2b263a1f. Main advanced to d2914354e17977f044ed5a1a89803a231ea91e6d; the PR remains mergeable and was not rebased.

ContextMD: 1cdf9ff2681a210ad938c3dda273dffcde7c7b0d, integrated main 42d312460cf3672ab7454ebfcb905d9db392b3e6. Version remains 0.6.3. The README now describes the refined quoted-token rule.

Both task branches were pushed through new commits, with no history rewrite. Both exclusive worktrees are clean and retained for the planner's review. Current state is recorded in the #232 handoff. No review was requested, no commit status was set, and neither PR was merged.

Remaining limits

This is a bounded scanner. Escaped/partly quoted heredoc delimiters (<<\EOF, <<E'OF', <<EO'F'), separator punctuation inside markers (<<'E;OF'), and ) in a substitution's case pattern, heredoc body or comment remain non-blocking grammar limits. Bash-stub probes verify that the delimiter forms can expose literal data and the substitution forms can hide later execution. The inherited bash -- -c 'gh pr create' option-boundary limit also remains: Bash treats -c as a filename, while the scanner treats its argument as a script. Grok's echo sh -c 'gh pr create' mention remains excluded and has a passing negative control. Unquoted mentions count under the accepted unquoted-word rule.

The 380-file recovery gap and native Zsh gap above are proof limits. Full server Knip retains #270. Proof covers the matcher and isolated contracts; fresh independent review and merge remain with the planner. Website/SEO impact is none; the original upstream-first search found no ContextMD matcher or related fix in pingdotgg/t3code.

Elon record

  • Requirements and who asked: the planner's refined contextmd serving: command keys fire on mentions such as echo strings and heredocs #232 rule and round-5 brief require quoted single tokens in every position, one consumed shell script, identical twin behavior, failing-before tests, bake fixtures, Bash verification and scoped proof.
  • Deleted: quoted-word retention by command position and the stale shell flag; no growing list of control words or wrappers was added for retaining quoted tokens.
  • Bottleneck: rejecting quoted prose without losing real command words or treating positional shell data as another script.
  • Checked myself: Sol's full review, five failing-before groups, 154 Bash controls, 17 token-policy fixtures, nine bake fixtures, 484 production comparisons, 128 Chromeria tests, 154 Python tests with 18 contracts, scoped checks, source/tree identities, version checks and live remote heads.

Work by Codex gpt-6.1-sol with max reasoning effort in T3 Code's Codex harness.

Full 484-command production parity output

Columns: command, command words, raw path shapes, gh-key hit, database-key hit. Both matchers agree on every row.

["! 'gh' pr create",["!","gh","pr","create"],[],true,false]
["! printf '%s' 'gh pr create'",["!","printf","%s"],[],false,false]
["\"gh\" pr create --fill",["gh","pr","create","--fill"],[],true,false]
["'gh' pr create",["gh","pr","create"],[],true,false]
["/bin/bash -c \"cd x && gh pr create\"",["/bin/bash","-c","cd","x","gh","pr","create"],["/bin/bash"],true,false]
["/bin/cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md 2>/dev/null",["/bin/cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","2","/dev/null"],["/bin/cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","/dev/null"],false,false]
["/bin/cat /tmp/232-parity-r5/repo/RULE.md 2>/dev/null",["/bin/cat","/tmp/232-parity-r5/repo/RULE.md","2","/dev/null"],["/bin/cat","/tmp/232-parity-r5/repo/RULE.md","/dev/null"],false,false]
["/bin/cat /tmp/232-parity.lMKzlv/repo/RULE.md 2>/dev/null",["/bin/cat","/tmp/232-parity.lMKzlv/repo/RULE.md","2","/dev/null"],["/bin/cat","/tmp/232-parity.lMKzlv/repo/RULE.md","/dev/null"],false,false]
["/bin/sh /old/bin/contextmd-hook codex /tmp/232-parity-r5/base",["/bin/sh","/old/bin/contextmd-hook","codex","/tmp/232-parity-r5/base"],["/bin/sh","/old/bin/contextmd-hook","/tmp/232-parity-r5/base"],false,false]
["/opt/bin/git push",["/opt/bin/git","push"],["/opt/bin/git"],false,false]
["/usr/local/bin/audit-hook --label contextmd-hook",["/usr/local/bin/audit-hook","--label","contextmd-hook"],["/usr/local/bin/audit-hook"],false,false]
["/usr/local/bin/foreign",["/usr/local/bin/foreign"],["/usr/local/bin/foreign"],false,false]
["/usr/local/bin/foreign-/tmp/232-parity-r3.Jt3dHh/repo/n.md",["/usr/local/bin/foreign-/tmp/232-parity-r3.Jt3dHh/repo/n.md"],["/usr/local/bin/foreign-/tmp/232-parity-r3.Jt3dHh/repo/n.md"],false,false]
["/usr/local/bin/foreign-/tmp/232-parity.lMKzlv/repo/n.md",["/usr/local/bin/foreign-/tmp/232-parity.lMKzlv/repo/n.md"],["/usr/local/bin/foreign-/tmp/232-parity.lMKzlv/repo/n.md"],false,false]
["/usr/local/bin/foreign-1",["/usr/local/bin/foreign-1"],["/usr/local/bin/foreign-1"],false,false]
["/usr/local/bin/other-hook",["/usr/local/bin/other-hook"],["/usr/local/bin/other-hook"],false,false]
["2>&1 bash -ce 'gh pr create'",["2","1","bash","-ce","gh","pr","create"],[],true,false]
["2>&1 env 'gh' pr create",["2","1","env","gh","pr","create"],[],true,false]
["2>&1 env printf '%s' 'gh pr create'",["2","1","env","printf","%s"],[],false,false]
["2>/dev/null 'gh' pr create",["2","/dev/null","gh","pr","create"],["/dev/null"],true,false]
["2>/dev/null bash -c 'echo \"gh pr create\"'",["2","/dev/null","bash","-c","echo"],["/dev/null"],false,false]
["2>/dev/null bash -c 'gh pr create'",["2","/dev/null","bash","-c","gh","pr","create"],["/dev/null"],true,false]
["2>/dev/null printf '%s' 'gh pr create'",["2","/dev/null","printf","%s"],["/dev/null"],false,false]
["2>>/dev/null g'h' pr create",["2","/dev/null","gh","pr","create"],["/dev/null"],true,false]
["3<<'EOF' bash -c 'gh pr create'\nliteral gh pr create\nEOF",["bash","-c","gh","pr","create"],[],true,false]
["3<<'EOF' cat\nliteral gh pr create\nEOF",["cat"],[],false,false]
[">/dev/null 'gh' pr create",["/dev/null","gh","pr","create"],["/dev/null"],true,false]
["DB=/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite; sqlite3 -readonly \"$DB\" .tables",["DB=/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite","sqlite3","-readonly","DB",".tables"],["/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite"],false,true]
["DB=/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite; sqlite3 -readonly \"$DB\" .tables",["DB=/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite","sqlite3","-readonly","DB",".tables"],["/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite"],false,true]
["DB=/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite; sqlite3 -readonly \"$DB\" .tables",["DB=/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite","sqlite3","-readonly","DB",".tables"],["/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite"],false,true]
["DB=~/.t3/userdata/chromeria-v2.sqlite; sqlite3 \"$DB\"",["DB=~/.t3/userdata/chromeria-v2.sqlite","sqlite3","DB"],["~/.t3/userdata/chromeria-v2.sqlite"],false,true]
["FLAG='one two' OTHER=2 \"gh\" pr create",["OTHER=2","gh","pr","create"],[],true,false]
["FLAG=1 'gh' pr create",["FLAG=1","gh","pr","create"],[],true,false]
["FLAG=1 g'h' pr create",["FLAG=1","gh","pr","create"],[],true,false]
["FLAG=1 printf '%s' 'gh pr create'",["FLAG=1","printf","%s"],[],false,false]
["awk 'NR<10' /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["awk","NR","10","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["awk 'NR<10' /tmp/232-parity-r5/repo/RULE.md",["awk","NR","10","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["awk 'NR<10' /tmp/232-parity.lMKzlv/repo/RULE.md",["awk","NR","10","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["bash",["bash"],[],false,false]
["bash -- -c 'gh pr create'",["bash","--","-c","gh","pr","create"],[],true,false]
["bash --noprofile -o pipefail -ce '\"g\"h pr create'",["bash","--noprofile","-o","pipefail","-ce","gh","pr","create"],[],true,false]
["bash --posix -c 'gh pr create'",["bash","--posix","-c","gh","pr","create"],[],true,false]
["bash -c \"'gh' pr create\"",["bash","-c","gh","pr","create"],[],true,false]
["bash -c \"\\\"g\\\"h pr create\"",["bash","-c","gh","pr","create"],[],true,false]
["bash -c \"\\\"g\\\"h\"' pr create'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c \"echo \\\"$(gh pr create)\\\"\"",["bash","-c","echo","gh","pr","create","gh","pr","create"],[],true,false]
["bash -c \"echo \\\"gh pr create\\\"\"",["bash","-c","echo"],[],false,false]
["bash -c \"echo \\\"gh pr create\\\"\"suffix",["bash","-c","echo"],[],false,false]
["bash -c \"echo \\$(gh pr create)\"",["bash","-c","echo","gh","pr","create"],[],true,false]
["bash -c \"echo \\`gh pr create\\`\"",["bash","-c","echo","gh","pr","create"],[],true,false]
["bash -c \"g\"'h pr create'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c \"gh pr create --title \\\"hello\\\"\"",["bash","-c","gh","pr","create","--title","hello"],[],true,false]
["bash -c \"gh pr create\"",["bash","-c","gh","pr","create"],[],true,false]
["bash -c $'\\147h pr create'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c $'\\u0067h pr create'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c $'\\x27gh\\x27 pr create'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c $'\\x67h pr create'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c $'echo \"$(printf \\'%s\\' \\'gh pr create\\')\"'",["bash","-c","echo","printf","%s"],[],false,false]
["bash -c $'echo \\\"gh pr create\\\"'",["bash","-c","echo"],[],false,false]
["bash -c $'echo \\047gh pr create\\047'",["bash","-c","echo"],[],false,false]
["bash -c $'echo \\0; gh pr create'",["bash","-c","echo"],[],false,false]
["bash -c $'echo \\x22gh pr create\\x22'",["bash","-c","echo"],[],false,false]
["bash -c $'echo done' _ -c $'gh pr create'",["bash","-c","echo","done","_","-c"],[],false,false]
["bash -c $'g'\"h pr create\"",["bash","-c","gh","pr","create"],[],true,false]
["bash -c $'gh pr create'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c $'gh pr create\\0; echo mention'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c $'gh\\x20pr\\tcreate'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c $'printf \\'%s\\' \\'gh pr create\\''",["bash","-c","printf","%s"],[],false,false]
["bash -c 'echo \"$@\"' _ -c 'gh pr create'",["bash","-c","echo","@","_","-c"],[],false,false]
["bash -c 'echo \"gh pr create\"'",["bash","-c","echo"],[],false,false]
["bash -c 'echo '\"\\\"gh pr create\\\"\"",["bash","-c","echo"],[],false,false]
["bash -c 'echo \\$(gh pr create)'",["bash","-c","echo","gh","pr","create"],[],true,false]
["bash -c 'echo done' -- -c 'gh pr create'",["bash","-c","echo","done","--","-c"],[],false,false]
["bash -c 'echo done' -c 'gh pr create'",["bash","-c","echo","done","-c"],[],false,false]
["bash -c 'echo done' _ -c \"$(gh pr create)\"",["bash","-c","echo","done","_","-c","gh","pr","create"],[],true,false]
["bash -c 'gh pr create'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c 'gh pr create' _ -c 'echo \"gh pr create\"'",["bash","-c","gh","pr","create","_","-c"],[],true,false]
["bash -c'gh pr create'",["bash"],[],false,false]
["bash -cE 'gh pr create'",["bash","-cE","gh","pr","create"],[],true,false]
["bash -ce 'echo \"gh pr create\"'",["bash","-ce","echo"],[],false,false]
["bash -ce 'echo done' _ -ce 'gh pr create'",["bash","-ce","echo","done","_","-ce"],[],false,false]
["bash -ce 'gh pr create'",["bash","-ce","gh","pr","create"],[],true,false]
["bash -cl 'gh pr create'",["bash","-cl","gh","pr","create"],[],true,false]
["bash -ec 'gh pr create'",["bash","-ec","gh","pr","create"],[],true,false]
["bash -lc 'gh pr create'",["bash","-lc","gh","pr","create"],[],true,false]
["bash -o pipefail -c 'echo \"gh pr create\"'",["bash","-o","pipefail","-c","echo"],[],false,false]
["bash -o pipefail -c 'gh pr create'",["bash","-o","pipefail","-c","gh","pr","create"],[],true,false]
["bash -o pipefail -ce 'echo \"gh pr create\"'",["bash","-o","pipefail","-ce","echo"],[],false,false]
["bat --plain /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["bat","--plain","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["bat --plain /tmp/232-parity-r5/repo/RULE.md",["bat","--plain","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["bat --plain /tmp/232-parity.lMKzlv/repo/RULE.md",["bat","--plain","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["bat -r 1:5 /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["bat","-r","1:5","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["bat -r 1:5 /tmp/232-parity-r5/repo/RULE.md",["bat","-r","1:5","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["bat -r 1:5 /tmp/232-parity.lMKzlv/repo/RULE.md",["bat","-r","1:5","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["bat -r1:5 /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["bat","-r1:5","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["bat -r1:5 /tmp/232-parity-r5/repo/RULE.md",["bat","-r1:5","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["bat -r1:5 /tmp/232-parity.lMKzlv/repo/RULE.md",["bat","-r1:5","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["bat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["bat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["bat /tmp/232-parity-r5/repo/RULE.md",["bat","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["bat /tmp/232-parity.lMKzlv/repo/RULE.md",["bat","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["batcat --line-range 1:5 /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["batcat","--line-range","1:5","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["batcat --line-range 1:5 /tmp/232-parity-r5/repo/RULE.md",["batcat","--line-range","1:5","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["batcat --line-range 1:5 /tmp/232-parity.lMKzlv/repo/RULE.md",["batcat","--line-range","1:5","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["batcat -pr1:5 /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["batcat","-pr1:5","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["batcat -pr1:5 /tmp/232-parity-r5/repo/RULE.md",["batcat","-pr1:5","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["batcat -pr1:5 /tmp/232-parity.lMKzlv/repo/RULE.md",["batcat","-pr1:5","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat \"/tmp/232-parity-r3.Jt3dHh/repo/RULE.md\"-n",["cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md-n"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat \"/tmp/232-parity-r5/repo/RULE.md\"-n",["cat","/tmp/232-parity-r5/repo/RULE.md-n"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat \"/tmp/232-parity.lMKzlv/repo/RULE.md\"-n",["cat","/tmp/232-parity.lMKzlv/repo/RULE.md-n"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat '/tmp/232-parity-r3.Jt3dHh/repo/RULE.md'",["cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat '/tmp/232-parity-r5/repo/RULE.md'",["cat","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat '/tmp/232-parity.lMKzlv/repo/RULE.md'",["cat","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat -n /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["cat","-n","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat -n /tmp/232-parity-r5/repo/RULE.md",["cat","-n","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat -n /tmp/232-parity.lMKzlv/repo/RULE.md",["cat","-n","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat /dev/null 2< /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["cat","/dev/null","2","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/dev/null","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat /dev/null 2< /tmp/232-parity-r5/repo/RULE.md",["cat","/dev/null","2","/tmp/232-parity-r5/repo/RULE.md"],["/dev/null","/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat /dev/null 2< /tmp/232-parity.lMKzlv/repo/RULE.md",["cat","/dev/null","2","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/dev/null","/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat /dev/null 2> /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["cat","/dev/null","2","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/dev/null","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat /dev/null 2> /tmp/232-parity-r5/repo/RULE.md",["cat","/dev/null","2","/tmp/232-parity-r5/repo/RULE.md"],["/dev/null","/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat /dev/null 2> /tmp/232-parity.lMKzlv/repo/RULE.md",["cat","/dev/null","2","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/dev/null","/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md &",["cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md > /dev/null",["cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","/dev/null"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","/dev/null"],false,false]
["cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md >&2",["cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","2"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md missing.md",["cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","missing.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","missing.md"],false,false]
["cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md | head -n 5",["cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","head","-n","5"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r3.Jt3dHh/repo/a[.]md",["cat","/tmp/232-parity-r3.Jt3dHh/repo/a[.]md"],["/tmp/232-parity-r3.Jt3dHh/repo/a[.]md"],false,false]
["cat /tmp/232-parity-r3.Jt3dHh/repo/x/../a.md",["cat","/tmp/232-parity-r3.Jt3dHh/repo/x/../a.md"],["/tmp/232-parity-r3.Jt3dHh/repo/x/../a.md"],false,false]
["cat /tmp/232-parity-r5/repo/PUSH.md",["cat","/tmp/232-parity-r5/repo/PUSH.md"],["/tmp/232-parity-r5/repo/PUSH.md"],false,false]
["cat /tmp/232-parity-r5/repo/RULE.md",["cat","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r5/repo/RULE.md &",["cat","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r5/repo/RULE.md > /dev/null",["cat","/tmp/232-parity-r5/repo/RULE.md","/dev/null"],["/tmp/232-parity-r5/repo/RULE.md","/dev/null"],false,false]
["cat /tmp/232-parity-r5/repo/RULE.md >&2",["cat","/tmp/232-parity-r5/repo/RULE.md","2"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r5/repo/RULE.md missing.md",["cat","/tmp/232-parity-r5/repo/RULE.md","missing.md"],["/tmp/232-parity-r5/repo/RULE.md","missing.md"],false,false]
["cat /tmp/232-parity-r5/repo/RULE.md | head -n 5",["cat","/tmp/232-parity-r5/repo/RULE.md","head","-n","5"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r5/repo/a[.]md",["cat","/tmp/232-parity-r5/repo/a[.]md"],["/tmp/232-parity-r5/repo/a[.]md"],false,false]
["cat /tmp/232-parity-r5/repo/x/../a.md",["cat","/tmp/232-parity-r5/repo/x/../a.md"],["/tmp/232-parity-r5/repo/x/../a.md"],false,false]
["cat /tmp/232-parity.lMKzlv/repo/RULE.md",["cat","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat /tmp/232-parity.lMKzlv/repo/RULE.md &",["cat","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat /tmp/232-parity.lMKzlv/repo/RULE.md > /dev/null",["cat","/tmp/232-parity.lMKzlv/repo/RULE.md","/dev/null"],["/tmp/232-parity.lMKzlv/repo/RULE.md","/dev/null"],false,false]
["cat /tmp/232-parity.lMKzlv/repo/RULE.md >&2",["cat","/tmp/232-parity.lMKzlv/repo/RULE.md","2"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat /tmp/232-parity.lMKzlv/repo/RULE.md missing.md",["cat","/tmp/232-parity.lMKzlv/repo/RULE.md","missing.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md","missing.md"],false,false]
["cat /tmp/232-parity.lMKzlv/repo/RULE.md | head -n 5",["cat","/tmp/232-parity.lMKzlv/repo/RULE.md","head","-n","5"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat /tmp/232-parity.lMKzlv/repo/a[.]md",["cat","/tmp/232-parity.lMKzlv/repo/a[.]md"],["/tmp/232-parity.lMKzlv/repo/a[.]md"],false,false]
["cat /tmp/232-parity.lMKzlv/repo/x/../a.md",["cat","/tmp/232-parity.lMKzlv/repo/x/../a.md"],["/tmp/232-parity.lMKzlv/repo/x/../a.md"],false,false]
["cat <<\"EOF\"\n$(gh pr create)\nEOF",["cat"],[],false,false]
["cat <<\"EÖF\"\n$(gh pr create)\nEÖF",["cat"],[],false,false]
["cat <<'A'\nA\ncat <<'B'\nB\ngh pr create",["cat","cat","gh","pr","create"],[],true,false]
["cat <<'A'\nA\ncat <<'B'\ngh pr create\nB",["cat","cat"],[],false,false]
["cat <<'E\"OF\"'\ngh pr create\nE\"OF\"",["cat","E","OF","gh","pr","create","EOF"],[],true,false]
["cat <<'E;OF'\ngh pr create\nE;OF",["cat","E","OF","gh","pr","create","E","OF"],[],true,false]
["cat <<'END-MARK'\nEND-MARK\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<'END-MARK'\ngh pr create\nEND-MARK",["cat"],[],false,false]
["cat <<'END.MARK'\nENDXMARK\ngh pr create\nEND.MARK",["cat"],["END.MARK"],false,false]
["cat <<'EOF'\n\tEOF\ngh pr create\nEOF",["cat"],[],false,false]
["cat <<'EOF'\n EOF\ngh pr create\nEOF",["cat"],[],false,false]
["cat <<'EOF'\n$(gh pr create --title \"hello\" $(printf x))\nEOF",["cat"],[],false,false]
["cat <<'EOF'\n$(gh pr create)\nEOF",["cat"],[],false,false]
["cat <<'EOF'\nEOF\t\ngh pr create\nEOF",["cat"],[],false,false]
["cat <<'EOF'\nEOF\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<'EOF'\nEOF \ngh pr create\nEOF",["cat"],[],false,false]
["cat <<'EOF'\nEOFX\ngh pr create\nEOF",["cat"],[],false,false]
["cat <<'EOF'\ngh pr create\nEOF",["cat"],[],false,false]
["cat <<'EOF'\nthen run gh pr create\nEOF",["cat"],[],false,false]
["cat <<'EÖF'\nEÖF\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<'EÖF'\ngh pr create\nEÖF",["cat"],[],false,false]
["cat <<'\\EOF'\ngh pr create\n\\EOF",["cat","EOF","gh","pr","create","EOF"],[],true,false]
["cat <<'ÉOF'\ngh pr create\nÉOF",["cat"],[],false,false]
["cat <<'ÉOF'\nÉOF\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<'𝔈OF'\ngh pr create\n𝔈OF",["cat"],[],false,false]
["cat <<'𝔈OF'\n𝔈OF\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<-'EOF'\n\tEOF\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<-'EOF'\n\tEOF \ngh pr create\nEOF",["cat"],[],false,false]
["cat <<-'EOF'\n EOF\ngh pr create\nEOF",["cat"],[],false,false]
["cat <<-EOF\n\tEOF\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<< /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat <<< /tmp/232-parity-r5/repo/RULE.md",["cat","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat <<< /tmp/232-parity.lMKzlv/repo/RULE.md",["cat","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat <<<\"gh pr create\"",["cat"],[],false,false]
["cat <<<EOF\ngh pr create",["cat","EOF","gh","pr","create"],[],true,false]
["cat <<A <<'B'\nA\nB\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<A <<'B'\nx\nA\nB\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<A <<B\nA\nB\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<E'OF'\n$(gh pr create)\nEOF",["cat","EOF","gh","pr","create","EOF"],[],true,false]
["cat <<E'OF'\ngh pr create\nEOF",["cat","EOF","gh","pr","create","EOF"],[],true,false]
["cat <<EO'F'\ngh pr create\nEOF",["cat","EOF","gh","pr","create","EOF"],[],true,false]
["cat <<EOF\n$((1 + $(gh pr create)0))\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\n$(gh pr create $(printf %s x))\nEOF",["cat","gh","pr","create","printf","%s","x"],[],true,false]
["cat <<EOF\n$(gh pr create ${v:-\")\"})\nEOF",["cat","gh","pr","create","v:-"],[],true,false]
["cat <<EOF\n$(gh pr create --title \"a (b)\")\nEOF",["cat","gh","pr","create","--title"],[],true,false]
["cat <<EOF\n$(gh pr create --title \"hello\" $(printf x))\nEOF",["cat","gh","pr","create","--title","hello","printf","x"],[],true,false]
["cat <<EOF\n$(gh pr create)\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\n$(printf %s \"$(gh pr create)\")\nEOF",["cat","printf","%s","gh","pr","create"],[],true,false]
["cat <<EOF\n$(printf %s \"gh pr create\")\nEOF",["cat","printf","%s"],[],false,false]
["cat <<EOF\n${v:-$(gh pr create)}\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\nEOF\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\n\\$(gh pr create)\nEOF",["cat"],[],false,false]
["cat <<EOF\n\\\\$(gh pr create)\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\n\\\\\\$(gh pr create)\nEOF",["cat"],[],false,false]
["cat <<EOF\n\\\\\\\\$(gh pr create)\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\n\\\\\\\\\\$(gh pr create)\nEOF",["cat"],[],false,false]
["cat <<EOF\n\\\\\\\\\\\\$(gh pr create)\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\n\\\\\\\\\\\\`gh pr create`\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\n\\\\\\\\\\`gh pr create`\nEOF",["cat"],[],false,false]
["cat <<EOF\n\\\\\\\\`gh pr create`\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\n\\\\\\`gh pr create`\nEOF",["cat"],[],false,false]
["cat <<EOF\n\\\\`gh pr create`\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\n\\`gh pr create\\`\nEOF",["cat"],[],false,false]
["cat <<EOF\n\\`gh pr create`\nEOF",["cat"],[],false,false]
["cat <<EOF\n`gh pr create`\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\nrun gh pr create later\nEOF",["cat"],[],false,false]
["cat <<EÖF\n$(gh pr create)\nEÖF",["cat","gh","pr","create"],[],true,false]
["cat <<EÖF\ngh pr create\nEÖF",["cat"],[],false,false]
["cat <<\\EOF\ngh pr create\nEOF",["cat","EOF","gh","pr","create","EOF"],[],true,false]
["cat <<ÉOF\n$(gh pr create)\nÉOF",["cat","gh","pr","create"],[],true,false]
["cat <<ÉOF\ngh pr create\nÉOF",["cat"],[],false,false]
["cat <<𝔈OF\n$(gh pr create)\n𝔈OF",["cat","gh","pr","create"],[],true,false]
["cat <<𝔈OF\ngh pr create\n𝔈OF",["cat"],[],false,false]
["cat > notes.md <<'EOF'\nhello\nEOF\ngh pr create",["cat","notes.md","gh","pr","create"],["notes.md"],true,false]
["cat RULE.md",["cat","RULE.md"],["RULE.md"],false,false]
["cat missing.md",["cat","missing.md"],["missing.md"],false,false]
["cat: Permission denied",["cat:","Permission","denied"],[],false,false]
["cd - && cat a.md",["cd","-","cat","a.md"],["a.md"],false,false]
["cd /tmp/232-parity-r3.Jt3dHh/repo && cat a.md",["cd","/tmp/232-parity-r3.Jt3dHh/repo","cat","a.md"],["/tmp/232-parity-r3.Jt3dHh/repo","a.md"],false,false]
["cd /tmp/232-parity-r3.Jt3dHh/repo/sub && cat a.md",["cd","/tmp/232-parity-r3.Jt3dHh/repo/sub","cat","a.md"],["/tmp/232-parity-r3.Jt3dHh/repo/sub","a.md"],false,false]
["cd /tmp/232-parity-r5/repo && cat a.md",["cd","/tmp/232-parity-r5/repo","cat","a.md"],["/tmp/232-parity-r5/repo","a.md"],false,false]
["cd /tmp/232-parity-r5/repo/sub && cat a.md",["cd","/tmp/232-parity-r5/repo/sub","cat","a.md"],["/tmp/232-parity-r5/repo/sub","a.md"],false,false]
["cd /tmp/232-parity.lMKzlv/repo && cat a.md",["cd","/tmp/232-parity.lMKzlv/repo","cat","a.md"],["/tmp/232-parity.lMKzlv/repo","a.md"],false,false]
["cd /tmp/232-parity.lMKzlv/repo/sub && cat a.md",["cd","/tmp/232-parity.lMKzlv/repo/sub","cat","a.md"],["/tmp/232-parity.lMKzlv/repo/sub","a.md"],false,false]
["cd x && env A=1 /usr/local/bin/gh pr create --fill",["cd","x","env","A=1","/usr/local/bin/gh","pr","create","--fill"],["/usr/local/bin/gh"],true,false]
["cd x && gh pr create --fill",["cd","x","gh","pr","create","--fill"],[],true,false]
["chromeria-v2.sqlite",["chromeria-v2.sqlite"],["chromeria-v2.sqlite"],false,true]
["command -- 'gh' pr create",["command","--","gh","pr","create"],[],true,false]
["command printf '%s' 'gh pr create'",["command","printf","%s"],[],false,false]
["curl -s https://example.com/chromeria-v2.sqlite.gz",["curl","-s","https://example.com/chromeria-v2.sqlite.gz"],[],false,false]
["curl https://example.com/chromeria-v2.sqlite.gz",["curl","https://example.com/chromeria-v2.sqlite.gz"],[],false,false]
["dash -c 'gh pr create'",["dash","-c","gh","pr","create"],[],true,false]
["echo \"$( # )\ngh pr create\n)\"",["echo","#"],[],false,false]
["echo \"$((1 + $(gh pr create)0))\"",["echo","gh","pr","create"],[],true,false]
["echo \"$((1 + (2))) gh pr create\"",["echo"],[],false,false]
["echo \"$(case x in x) gh pr create ;; esac)\"",["echo","case","x","in","x"],[],false,false]
["echo \"$(case x in x) gh pr create;; esac)\"",["echo","case","x","in","x"],[],false,false]
["echo \"$(cat <<'EOF'\n)\nEOF\ngh pr create\n)\"",["echo","cat"],[],false,false]
["echo \"$(cat <<'EOF'\n)\nEOF\ngh pr create)\"",["echo","cat"],[],false,false]
["echo \"$(gh pr create \"$(printf x)\")\"",["echo","gh","pr","create","printf","x"],[],true,false]
["echo \"$(gh pr create $((1 + (2))))\"",["echo","gh","pr","create","1","+","2"],[],true,false]
["echo \"$(gh pr create $(printf %s x))\"",["echo","gh","pr","create","printf","%s","x"],[],true,false]
["echo \"$(gh pr create $(printf x))\"",["echo","gh","pr","create","printf","x"],[],true,false]
["echo \"$(gh pr create ${v:-\")\"})\"",["echo","gh","pr","create","v:-"],[],true,false]
["echo \"$(gh pr create --title \"a (b)\")\"",["echo","gh","pr","create","--title"],[],true,false]
["echo \"$(gh pr create --title \"hello\")\"",["echo","gh","pr","create","--title","hello"],[],true,false]
["echo \"$(gh pr create)\"",["echo","gh","pr","create"],[],true,false]
["echo \"$(printf \"%s\" \"$(printf \"%s\" \"gh pr create\")\")\"",["echo","printf","%s","printf","%s"],[],false,false]
["echo \"$(printf \"%s\" \"${v:-gh pr create}\")\"",["echo","printf","%s"],[],false,false]
["echo \"$(printf \"%s\" \"gh pr create\")\"",["echo","printf","%s"],[],false,false]
["echo \"$(printf %s \"$(gh pr create)\")\"",["echo","printf","%s","gh","pr","create"],[],true,false]
["echo \"$(printf %s \"gh pr create\")\"",["echo","printf","%s"],[],false,false]
["echo \"$(printf x # )\ngh pr create)\"",["echo","printf","x","#"],[],false,false]
["echo \"$(true; cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md ; true)\" > /dev/null",["echo","true","cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","true","/dev/null"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","/dev/null"],false,false]
["echo \"$(true; cat /tmp/232-parity-r5/repo/RULE.md ; true)\" > /dev/null",["echo","true","cat","/tmp/232-parity-r5/repo/RULE.md","true","/dev/null"],["/tmp/232-parity-r5/repo/RULE.md","/dev/null"],false,false]
["echo \"$(true; cat /tmp/232-parity.lMKzlv/repo/RULE.md ; true)\" > /dev/null",["echo","true","cat","/tmp/232-parity.lMKzlv/repo/RULE.md","true","/dev/null"],["/tmp/232-parity.lMKzlv/repo/RULE.md","/dev/null"],false,false]
["echo \"${v:-$(gh pr create --title \"hello\")}\"",["echo","gh","pr","create","--title","hello"],[],true,false]
["echo \"${v:-$(gh pr create)}\"",["echo","gh","pr","create"],[],true,false]
["echo \"${v:-gh pr create}\"",["echo"],[],false,false]
["echo \"\\$(gh pr create)\"",["echo"],[],false,false]
["echo \"\\\\$(gh pr create)\"",["echo","gh","pr","create"],[],true,false]
["echo \"\\\\\\$(gh pr create)\"",["echo"],[],false,false]
["echo \"\\\\\\\\$(gh pr create)\"",["echo","gh","pr","create"],[],true,false]
["echo \"\\\\\\\\\\$(gh pr create)\"",["echo"],[],false,false]
["echo \"\\\\\\\\\\\\$(gh pr create)\"",["echo","gh","pr","create"],[],true,false]
["echo \"\\\\\\\\\\\\`gh pr create`\"",["echo","gh","pr","create"],[],true,false]
["echo \"\\\\\\\\\\`gh pr create`\"",["echo"],[],false,false]
["echo \"\\\\\\\\`gh pr create`\"",["echo","gh","pr","create"],[],true,false]
["echo \"\\\\\\`gh pr create`\"",["echo"],[],false,false]
["echo \"\\\\`gh pr create`\"",["echo","gh","pr","create"],[],true,false]
["echo \"\\`gh pr create\\`\"",["echo"],[],false,false]
["echo \"\\`gh pr create`\"",["echo"],[],false,false]
["echo \"`gh pr create --title \"hello\"`\"",["echo","gh","pr","create","--title","hello"],[],true,false]
["echo \"`gh pr create`\"",["echo","gh","pr","create"],[],true,false]
["echo \"`printf \"%s\" \"gh pr create\"`\"",["echo","printf","%s"],[],false,false]
["echo \"`printf \"%s\" \\`gh pr create\\``\"",["echo","printf","%s","gh","pr","create"],[],true,false]
["echo \"gh\" pr create",["echo","gh","pr","create"],[],true,false]
["echo \"live check: gh pr create\"",["echo"],[],false,false]
["echo \"open /Users/u/.t3/userdata/chromeria-v2.sqlite later\"",["echo"],["/Users/u/.t3/userdata/chromeria-v2.sqlite"],false,false]
["echo $'\\x67h' pr create",["echo","gh","pr","create"],[],true,false]
["echo $'gh pr create'",["echo"],[],false,false]
["echo $'the file chromeria-v2.sqlite'",["echo"],["chromeria-v2.sqlite"],false,false]
["echo $((1 + $(gh pr create)0))",["echo","1","+","gh","pr","create","0","gh","pr","create"],[],true,false]
["echo $(gh pr create $(printf %s x))",["echo","gh","pr","create","printf","%s","x"],[],true,false]
["echo $(gh pr create ${v:-\")\"})",["echo","gh","pr","create","v:-"],[],true,false]
["echo $(gh pr create --title \"a (b)\")",["echo","gh","pr","create","--title"],[],true,false]
["echo $(gh pr create --title \"hello\")",["echo","gh","pr","create","--title","hello"],[],true,false]
["echo $(printf %s \"$(gh pr create)\")",["echo","printf","%s","gh","pr","create"],[],true,false]
["echo $(printf %s \"gh pr create\")",["echo","printf","%s"],[],false,false]
["echo ${v:-$(gh pr create)}",["echo","v:-","gh","pr","create","gh","pr","create"],[],true,false]
["echo '$(gh pr create)'",["echo"],[],false,false]
["echo 'gh pr create'",["echo"],[],false,false]
["echo 'ignore; cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md ; ignore'",["echo"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["echo 'ignore; cat /tmp/232-parity-r5/repo/RULE.md ; ignore'",["echo"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["echo 'ignore; cat /tmp/232-parity.lMKzlv/repo/RULE.md ; ignore'",["echo"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["echo 'the file chromeria-v2.sqlite'",["echo"],["chromeria-v2.sqlite"],false,false]
["echo /tmp/232-parity-r3.Jt3dHh/repo/RULE.md && cat missing.md",["echo","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","cat","missing.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","missing.md"],false,false]
["echo /tmp/232-parity-r5/repo/RULE.md && cat missing.md",["echo","/tmp/232-parity-r5/repo/RULE.md","cat","missing.md"],["/tmp/232-parity-r5/repo/RULE.md","missing.md"],false,false]
["echo /tmp/232-parity.lMKzlv/repo/RULE.md && cat missing.md",["echo","/tmp/232-parity.lMKzlv/repo/RULE.md","cat","missing.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md","missing.md"],false,false]
["echo a",["echo","a"],[],false,false]
["echo after",["echo","after"],[],false,false]
["echo g\"h\" pr create",["echo","gh","pr","create"],[],true,false]
["echo g'h pr create'",["echo"],[],false,false]
["echo g'h' pr create",["echo","gh","pr","create"],[],true,false]
["echo gh pr",["echo","gh","pr"],[],false,false]
["echo hello",["echo","hello"],[],false,false]
["echo ok &&\ngh pr create",["echo","ok","gh","pr","create"],[],true,false]
["echo prefix' the file chromeria-v2.sqlite'",["echo"],["chromeria-v2.sqlite"],false,false]
["echo sh -c 'gh pr create'",["echo","sh","-c"],[],false,false]
["env 'gh' pr create",["env","gh","pr","create"],[],true,false]
["env -u UNUSED 'gh' pr create",["env","-u","UNUSED","gh","pr","create"],[],true,false]
["env -u UNUSED printf '%s' 'gh pr create'",["env","-u","UNUSED","printf","%s"],[],false,false]
["env FLAG=1 'gh' pr create",["env","FLAG=1","gh","pr","create"],[],true,false]
["env FLAG=1 bash -c \"\\\"g\\\"h pr create\"",["env","FLAG=1","bash","-c","gh","pr","create"],[],true,false]
["env FLAG=1 bash -o pipefail -ce 'gh pr create'",["env","FLAG=1","bash","-o","pipefail","-ce","gh","pr","create"],[],true,false]
["env FOO=1 gh pr create",["env","FOO=1","gh","pr","create"],[],true,false]
["env bash -c 'gh pr create'",["env","bash","-c","gh","pr","create"],[],true,false]
["env g'h' pr create",["env","gh","pr","create"],[],true,false]
["env printf '%s' 'gh pr create'",["env","printf","%s"],[],false,false]
["exec -a gh-alias 'gh' pr create",["exec","-a","gh-alias","gh","pr","create"],[],true,false]
["exec g'h' pr create",["exec","gh","pr","create"],[],true,false]
["exec printf '%s' 'gh pr create'",["exec","printf","%s"],[],false,false]
["false",["false"],[],false,false]
["false && cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md; true",["false","cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","true"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["false && cat /tmp/232-parity-r5/repo/RULE.md; true",["false","cat","/tmp/232-parity-r5/repo/RULE.md","true"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["false && cat /tmp/232-parity.lMKzlv/repo/RULE.md; true",["false","cat","/tmp/232-parity.lMKzlv/repo/RULE.md","true"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["for n in 1; do \"gh\" pr create; done",["for","n","in","1","do","gh","pr","create","done"],[],true,false]
["for n in 1; do printf '%s' 'gh pr create'; done",["for","n","in","1","do","printf","%s","done"],[],false,false]
["g'h' pr create",["gh","pr","create"],[],true,false]
["g\\h pr create",["gh","pr","create"],[],true,false]
["gh",["gh"],[],false,false]
["gh issue create",["gh","issue","create"],[],false,false]
["gh issue create --title \"Record the bake\" --body \"The entry names chromeria-v2.sqlite in a test fixture.\"",["gh","issue","create","--title","--body"],["chromeria-v2.sqlite"],false,false]
["gh issue create --title \"Record the bake\" --body-file - <<'EOF'\nThe entry names chromeria-v2.sqlite in a test fixture.\nEOF",["gh","issue","create","--title","--body-file","-"],["chromeria-v2.sqlite"],false,false]
["gh issue create --title t --body \"open it with gh pr create\"",["gh","issue","create","--title","t","--body"],[],false,false]
["gh issue create --title x --body-file -",["gh","issue","create","--title","x","--body-file","-"],[],false,false]
["gh issue view 5 --json body -q .body; gh pr create",["gh","issue","view","5","--json","body","-q",".body","gh","pr","create"],[],true,false]
["gh pr",["gh","pr"],[],false,false]
["gh pr create",["gh","pr","create"],[],true,false]
["gh pr create --body SECRET-BODY",["gh","pr","create","--body","SECRET-BODY"],[],true,false]
["gh pr create --fill",["gh","pr","create","--fill"],[],true,false]
["gh pr create --title \"x\" --body-file - <<'EOF'\nbody\nEOF",["gh","pr","create","--title","x","--body-file","-"],[],true,false]
["gh pr create | cat",["gh","pr","create","cat"],[],true,false]
["gh pr createx",["gh","pr","createx"],[],false,false]
["gh pr list",["gh","pr","list"],[],false,false]
["gh-calls.jsonl",["gh-calls.jsonl"],["gh-calls.jsonl"],false,false]
["gh.json",["gh.json"],["gh.json"],false,false]
["ghx pr create",["ghx","pr","create"],[],false,false]
["git",["git"],[],false,false]
["git commit",["git","commit"],[],false,false]
["git commit -m x",["git","commit","-m","x"],[],false,false]
["git push",["git","push"],[],false,false]
["git push; echo \"exit=$?\"",["git","push","echo","exit=","?"],[],false,false]
["git status",["git","status"],[],false,false]
["git status push",["git","status","push"],[],false,false]
["git@github.com: Permission denied (publickey).",["git@github.com:","Permission","denied","publickey","."],[],false,false]
["grep -n x /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["grep","-n","x","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["grep -n x /tmp/232-parity-r3.Jt3dHh/repo/RULE.md; cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["grep","-n","x","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["grep -n x /tmp/232-parity-r5/repo/RULE.md",["grep","-n","x","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["grep -n x /tmp/232-parity-r5/repo/RULE.md; cat /tmp/232-parity-r5/repo/RULE.md",["grep","-n","x","/tmp/232-parity-r5/repo/RULE.md","cat","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["grep -n x /tmp/232-parity.lMKzlv/repo/RULE.md",["grep","-n","x","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["grep -n x /tmp/232-parity.lMKzlv/repo/RULE.md; cat /tmp/232-parity.lMKzlv/repo/RULE.md",["grep","-n","x","/tmp/232-parity.lMKzlv/repo/RULE.md","cat","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["head -n 40 /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["head","-n","40","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["head -n 40 /tmp/232-parity-r5/repo/RULE.md",["head","-n","40","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["head -n 40 /tmp/232-parity.lMKzlv/repo/RULE.md",["head","-n","40","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["if false; then :; else g'h' pr create; fi",["if","false","then",":","else","gh","pr","create","fi"],[],true,false]
["if true; then 'gh' pr create; fi",["if","true","then","gh","pr","create","fi"],[],true,false]
["if true; then printf '%s' 'gh pr create'; fi",["if","true","then","printf","%s","fi"],[],false,false]
["less +40 /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["less","+40","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["less +40 /tmp/232-parity-r5/repo/RULE.md",["less","+40","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["less +40 /tmp/232-parity.lMKzlv/repo/RULE.md",["less","+40","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["less /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["less","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["less /tmp/232-parity-r5/repo/RULE.md",["less","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["less /tmp/232-parity.lMKzlv/repo/RULE.md",["less","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["ls",["ls"],[],false,false]
["ls /nope",["ls","/nope"],["/nope"],false,false]
["ls /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["ls","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["ls /tmp/232-parity-r5/repo/RULE.md",["ls","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["ls /tmp/232-parity.lMKzlv/repo/RULE.md",["ls","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["make",["make"],[],false,false]
["nl -ba /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["nl","-ba","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["nl -ba /tmp/232-parity-r5/repo/PUSH.md",["nl","-ba","/tmp/232-parity-r5/repo/PUSH.md"],["/tmp/232-parity-r5/repo/PUSH.md"],false,false]
["nl -ba /tmp/232-parity-r5/repo/RULE.md",["nl","-ba","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["nl -ba /tmp/232-parity.lMKzlv/repo/RULE.md",["nl","-ba","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["nohup 'gh' pr create",["nohup","gh","pr","create"],[],true,false]
["printf '%s ' 'gh pr create'",["printf"],[],false,false]
["printf '%s ' 'gh' 'pr' 'create'",["printf","gh","pr","create"],[],true,false]
["printf '%s' ';' gh pr create",["printf","%s","gh","pr","create"],[],true,false]
["printf '%s' '>'&gh pr create",["printf","%s","gh","pr","create"],[],true,false]
["printf '%s' \\>&gh pr create",["printf","%s","gh","pr","create"],[],true,false]
["printf '%s\\n' '<<EOF'\ngh pr create\nEOF",["printf","%s","n","EOF","gh","pr","create","EOF"],[],true,false]
["printf gh pr create",["printf","gh","pr","create"],[],true,false]
["printf x | gh pr create --fill",["printf","x","gh","pr","create","--fill"],[],true,false]
["python3 - <<'EOF'\nfrom pathlib import Path\np = Path('tests/test_serve.py')\np.write_text(p.read_text().replace('state.sqlite', 'chromeria-v2.sqlite'))\nEOF",["python3","-"],["tests/test_serve.py","state.sqlite","chromeria-v2.sqlite"],false,false]
["python3 - <<'PY'\nkeys = ['gh pr create']\nPY",["python3","-"],[],false,false]
["python3 -c \"import sqlite3; sqlite3.connect('file:///tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite?mode=ro', uri=True)\"",["python3","-c"],["sqlite3.connect","/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite"],false,false]
["python3 -c \"import sqlite3; sqlite3.connect('file:///tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite?mode=ro', uri=True)\"",["python3","-c"],["sqlite3.connect","/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite"],false,false]
["python3 -c \"import sqlite3; sqlite3.connect('file:///tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite?mode=ro', uri=True)\"",["python3","-c"],["sqlite3.connect","/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite"],false,false]
["python3 -c \"print('gh pr create')\"",["python3","-c"],[],false,false]
["rg gh pr create tests/",["rg","gh","pr","create","tests/"],["tests/"],true,false]
["rg x /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["rg","x","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["rg x /tmp/232-parity-r5/repo/RULE.md",["rg","x","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["rg x /tmp/232-parity.lMKzlv/repo/RULE.md",["rg","x","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["sed -n '1,200p' /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["sed","-n","1,200p","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["sed -n '1,200p' /tmp/232-parity-r5/repo/RULE.md",["sed","-n","1,200p","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["sed -n '1,200p' /tmp/232-parity.lMKzlv/repo/RULE.md",["sed","-n","1,200p","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["sh -c \"\\\"g\\\"h pr create\"",["sh","-c","gh","pr","create"],[],true,false]
["sh -c \"printf '%s' \\\"gh pr create\\\"\"",["sh","-c","printf","%s"],[],false,false]
["sh -c $'\\x67h pr create'",["sh","-c","gh","pr","create"],[],true,false]
["sh -c 'echo done' _ -c 'gh pr create'",["sh","-c","echo","done","_","-c"],[],false,false]
["sh -c 'gh pr create'",["sh","-c","gh","pr","create"],[],true,false]
["sh -c 'gh pr create' -c 'echo \"gh pr create\"'",["sh","-c","gh","pr","create","-c"],[],true,false]
["sqlite3 ",["sqlite3"],[],false,false]
["sqlite3 \"/Users/u/.t3/userdata/chromeria-v2.sqlite\" .tables",["sqlite3","/Users/u/.t3/userdata/chromeria-v2.sqlite",".tables"],["/Users/u/.t3/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 $'chromeria-v2.sqlite' .tables",["sqlite3","chromeria-v2.sqlite",".tables"],["chromeria-v2.sqlite"],false,true]
["sqlite3 'chromeria-v2.sqlite' .tables",["sqlite3","chromeria-v2.sqlite",".tables"],["chromeria-v2.sqlite"],false,true]
["sqlite3 'file:",["sqlite3","file:"],[],false,false]
["sqlite3 'file:/Users/u/.t3/userdata/chromeria-v2.sqlite?mode=ro'",["sqlite3","file:/Users/u/.t3/userdata/chromeria-v2.sqlite?mode=ro"],["/Users/u/.t3/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 'file:/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite?mode=ro' 'select 1'",["sqlite3","file:/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite?mode=ro"],["/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 'file:/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite?mode=ro' .tables",["sqlite3","file:/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite?mode=ro",".tables"],["/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 'file:/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite?mode=ro' 'select 1'",["sqlite3","file:/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite?mode=ro"],["/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 'file:/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite?mode=ro' .tables",["sqlite3","file:/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite?mode=ro",".tables"],["/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 'file:/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite?mode=ro' 'select 1'",["sqlite3","file:/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite?mode=ro"],["/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 'file:/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite?mode=ro' .tables",["sqlite3","file:/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite?mode=ro",".tables"],["/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 'file:/x/userdata/chromeria-v2.sqlite?mode=ro' .tables",["sqlite3","file:/x/userdata/chromeria-v2.sqlite?mode=ro",".tables"],["/x/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 -readonly /Users/u/.t3/userdata/chromeria-v2.sqlite .tables",["sqlite3","-readonly","/Users/u/.t3/userdata/chromeria-v2.sqlite",".tables"],["/Users/u/.t3/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 -readonly ~/.t3/userdata/chromeria-v2.sqlite .tables",["sqlite3","-readonly","~/.t3/userdata/chromeria-v2.sqlite",".tables"],["~/.t3/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /Users/u/.t3/userdata/chromeria-v2.sqlite",["sqlite3","/Users/u/.t3/userdata/chromeria-v2.sqlite"],["/Users/u/.t3/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /Users/u/.t3/userdata/chromeria-v2.sqlite 'select 1'",["sqlite3","/Users/u/.t3/userdata/chromeria-v2.sqlite"],["/Users/u/.t3/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite 'select 1'",["sqlite3","/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite"],["/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite .tables",["sqlite3","/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite",".tables"],["/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite 'select 1'",["sqlite3","/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite"],["/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite .tables",["sqlite3","/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite",".tables"],["/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite 'select 1'",["sqlite3","/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite"],["/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite .tables",["sqlite3","/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite",".tables"],["/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /x/userdata/chromeria-v2.sqlite .tables",["sqlite3","/x/userdata/chromeria-v2.sqlite",".tables"],["/x/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 chromeria-v2'.sqlite' .tables",["sqlite3","chromeria-v2.sqlite",".tables"],[],false,true]
["sqlite3 chromeria-v2.sqlite",["sqlite3","chromeria-v2.sqlite"],["chromeria-v2.sqlite"],false,true]
["sqlite3 chromeria-v2.sqlite .tables",["sqlite3","chromeria-v2.sqlite",".tables"],["chromeria-v2.sqlite"],false,true]
["sqlite3 file:/Users/u/.t3/userdata/chromeria-v2.sqlite?mode=ro",["sqlite3","file:/Users/u/.t3/userdata/chromeria-v2.sqlite?mode=ro"],["/Users/u/.t3/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 ~/.t3/userdata/chromeria-v2.sqlite",["sqlite3","~/.t3/userdata/chromeria-v2.sqlite"],["~/.t3/userdata/chromeria-v2.sqlite"],false,true]
["ssh host",["ssh","host"],[],false,false]
["step /tmp/232-parity-r3.Jt3dHh/repo/i.md",["step","/tmp/232-parity-r3.Jt3dHh/repo/i.md"],["/tmp/232-parity-r3.Jt3dHh/repo/i.md"],false,false]
["step /tmp/232-parity.lMKzlv/repo/i.md",["step","/tmp/232-parity.lMKzlv/repo/i.md"],["/tmp/232-parity.lMKzlv/repo/i.md"],false,false]
["step 0",["step","0"],[],false,false]
["step 1",["step","1"],[],false,false]
["step 2",["step","2"],[],false,false]
["step 3",["step","3"],[],false,false]
["step 4",["step","4"],[],false,false]
["step 5",["step","5"],[],false,false]
["step 6",["step","6"],[],false,false]
["step 7",["step","7"],[],false,false]
["sudo -n 'gh' pr create",["sudo","-n","gh","pr","create"],[],true,false]
["sudo -n printf '%s' 'gh pr create'",["sudo","-n","printf","%s"],[],false,false]
["sudo -u nobody g'h' pr create",["sudo","-u","nobody","gh","pr","create"],[],true,false]
["tail -n 20 /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["tail","-n","20","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["tail -n 20 /tmp/232-parity-r5/repo/RULE.md",["tail","-n","20","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["tail -n 20 /tmp/232-parity.lMKzlv/repo/RULE.md",["tail","-n","20","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["time 'gh' pr create",["time","gh","pr","create"],[],true,false]
["time -p 'gh' pr create",["time","-p","gh","pr","create"],[],true,false]
["tool/tmp/232-parity-r3.Jt3dHh/repo/i.md",["tool/tmp/232-parity-r3.Jt3dHh/repo/i.md"],["tool/tmp/232-parity-r3.Jt3dHh/repo/i.md"],false,false]
["tool/tmp/232-parity.lMKzlv/repo/i.md",["tool/tmp/232-parity.lMKzlv/repo/i.md"],["tool/tmp/232-parity.lMKzlv/repo/i.md"],false,false]
["tool0",["tool0"],[],false,false]
["tool1",["tool1"],[],false,false]
["tool2",["tool2"],[],false,false]
["tool3",["tool3"],[],false,false]
["tool4",["tool4"],[],false,false]
["tool5",["tool5"],[],false,false]
["tool6",["tool6"],[],false,false]
["tool7",["tool7"],[],false,false]
["x=`gh pr create`",["x=","gh","pr","create"],[],true,false]
["zsh -lc \"\\\"g\\\"h pr create\"",["zsh","-lc","gh","pr","create"],[],true,false]
["zsh -lc \"echo \\\"gh pr create\\\"\"",["zsh","-lc","echo"],[],false,false]
["zsh -lc 'echo done' _ -c 'gh pr create'",["zsh","-lc","echo","done","_","-c"],[],false,false]
["zsh -lc 'gh pr create --fill'",["zsh","-lc","gh","pr","create","--fill"],[],true,false]
["{ 'gh' pr create; }",["gh","pr","create"],[],true,false]
["{ gh pr create; }",["gh","pr","create"],[],true,false]
["{ printf '%s' 'gh pr create'; }",["printf","%s"],[],false,false]

@lukemaj

lukemaj commented Oct 14, 2026

Copy link
Copy Markdown
Contributor Author

What: Round 5 review stopped without a verdict on this head; a blocking regression was confirmed before it stopped.
Why: Shell -c scripts are still recognized only at command position, so a script after a control word or a command-running tool is dropped.
So what: The implementation worker fixes this in both matchers; round 6 reviews the new heads.

The Sol round-5 reviewer (gpt-6.1-sol) was cut mid-review after confirming with /bin/bash and a stub gh that then, !, { and do before bash -c 'gh pr create' hide an executed command that the main-base matcher detected. The planner reproduced it in keys.py at this head and found the same miss after xargs, find . -exec, timeout 5 and ssh host. Each of these appears in both twins. The Grok round-5 review was cancelled as superseded. Both review/independent-* statuses on this head are set to error.

@lukemaj

lukemaj commented Oct 14, 2026

Copy link
Copy Markdown
Contributor Author

What: The final fix recognizes shell scripts in every word position in both matchers.
Why: Command-position tracking dropped scripts after control words and command-running tools.
So what: The planner owns fresh review/merge; remaining limits belong to #284.

Chromeria: ed1af37e72fd7dc970914dbd20dd4c9a2f933cda.
ContextMD: 3d0051a44d18f375bf901b340681a55d94bedd3f.

Any eligible sh/bash/zsh/dash/ksh word starts shell option recognition; a c flag selects one dequoted script, then recognition ends. All eight reported cases match, including then/!/braces/do and xargs/find/timeout/ssh. Their prose negatives and all prior positional -c negatives pass. Command-position, assignments, wrappers and redirect-target state are deleted.

Printed invocations now match by the accepted rule, including the former echo-sh negative. Header, docstring and README say so. All nine bake fixtures retain their expected results, including the quoted single-path match and excluded 1672/26379 prose.

Before: two TS tests and 15 Python assertions fail; both old extractors make 15 wrong decisions. After: 130 TS tests; 21 focused Python and 156 full-suite tests, including 18 isolated contracts, pass. The full suite ran at implementation 5d0e4e6; final 3d0051a only links #284 in the feature map, with identical matcher/tests. 173 Bash controls, 25 policy fixtures and 559 parity inputs pass, zero word/path-shape/key-hit differences. Stubs prevent real gh/SSH; native zsh/ksh remain unverified.

Lint/typecheck and Knip exports pass; full Knip retains #270. ContextMD stays 0.6.3 with release-check passing. No rebase/history rewrite, reviews requested, statuses posted or merges. All 15 verified shared limit examples are in #284, linked from both PRs' Known limits sections. Logs/scripts: /tmp/232-parity-r6.

Requirements and who asked: planner's final fix/proof and follow-up Issue brief.
Deleted: command-position machinery and wrapper lists.
Bottleneck: position-free recognition with one consumed script.
Checked myself: failing-before/after, Bash, parity, suites, scoped checks, identities, versions and live heads.

Codex gpt-6.1-sol, max effort, T3 Code Codex harness.

Full 559-command parity result

Columns: command, words, raw path shapes, gh hit, database hit. Both production matchers agree on every row.

["! 'gh' pr create",["!","gh","pr","create"],[],true,false]
["! bash -c 'echo \"gh pr create\"'",["!","bash","-c","echo"],[],false,false]
["! bash -c 'gh pr create'",["!","bash","-c","gh","pr","create"],[],true,false]
["! printf '%s' 'gh pr create'",["!","printf","%s"],[],false,false]
["\"gh\" pr create --fill",["gh","pr","create","--fill"],[],true,false]
["'gh' pr create",["gh","pr","create"],[],true,false]
["/bin/bash -c \"cd x && gh pr create\"",["/bin/bash","-c","cd","x","gh","pr","create"],["/bin/bash"],true,false]
["/bin/cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md 2>/dev/null",["/bin/cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","2","/dev/null"],["/bin/cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","/dev/null"],false,false]
["/bin/cat /tmp/232-parity-r5/repo/RULE.md 2>/dev/null",["/bin/cat","/tmp/232-parity-r5/repo/RULE.md","2","/dev/null"],["/bin/cat","/tmp/232-parity-r5/repo/RULE.md","/dev/null"],false,false]
["/bin/cat /tmp/232-parity-r6/repo/RULE.md 2>/dev/null",["/bin/cat","/tmp/232-parity-r6/repo/RULE.md","2","/dev/null"],["/bin/cat","/tmp/232-parity-r6/repo/RULE.md","/dev/null"],false,false]
["/bin/cat /tmp/232-parity.lMKzlv/repo/RULE.md 2>/dev/null",["/bin/cat","/tmp/232-parity.lMKzlv/repo/RULE.md","2","/dev/null"],["/bin/cat","/tmp/232-parity.lMKzlv/repo/RULE.md","/dev/null"],false,false]
["/bin/sh /old/bin/contextmd-hook codex /tmp/232-parity-r5/base",["/bin/sh","/old/bin/contextmd-hook","codex","/tmp/232-parity-r5/base"],["/bin/sh","/old/bin/contextmd-hook","/tmp/232-parity-r5/base"],false,false]
["/bin/sh /old/bin/contextmd-hook codex /tmp/232-parity-r6/base",["/bin/sh","/old/bin/contextmd-hook","codex","/tmp/232-parity-r6/base"],["/bin/sh","/old/bin/contextmd-hook","/tmp/232-parity-r6/base"],false,false]
["/opt/bin/git push",["/opt/bin/git","push"],["/opt/bin/git"],false,false]
["/usr/local/bin/audit-hook --label contextmd-hook",["/usr/local/bin/audit-hook","--label","contextmd-hook"],["/usr/local/bin/audit-hook"],false,false]
["/usr/local/bin/foreign",["/usr/local/bin/foreign"],["/usr/local/bin/foreign"],false,false]
["/usr/local/bin/foreign-/tmp/232-parity-r3.Jt3dHh/repo/n.md",["/usr/local/bin/foreign-/tmp/232-parity-r3.Jt3dHh/repo/n.md"],["/usr/local/bin/foreign-/tmp/232-parity-r3.Jt3dHh/repo/n.md"],false,false]
["/usr/local/bin/foreign-/tmp/232-parity.lMKzlv/repo/n.md",["/usr/local/bin/foreign-/tmp/232-parity.lMKzlv/repo/n.md"],["/usr/local/bin/foreign-/tmp/232-parity.lMKzlv/repo/n.md"],false,false]
["/usr/local/bin/foreign-1",["/usr/local/bin/foreign-1"],["/usr/local/bin/foreign-1"],false,false]
["/usr/local/bin/other-hook",["/usr/local/bin/other-hook"],["/usr/local/bin/other-hook"],false,false]
["2>&1 bash -ce 'gh pr create'",["2","1","bash","-ce","gh","pr","create"],[],true,false]
["2>&1 env 'gh' pr create",["2","1","env","gh","pr","create"],[],true,false]
["2>&1 env printf '%s' 'gh pr create'",["2","1","env","printf","%s"],[],false,false]
["2>/dev/null 'gh' pr create",["2","/dev/null","gh","pr","create"],["/dev/null"],true,false]
["2>/dev/null bash -c 'echo \"gh pr create\"'",["2","/dev/null","bash","-c","echo"],["/dev/null"],false,false]
["2>/dev/null bash -c 'gh pr create'",["2","/dev/null","bash","-c","gh","pr","create"],["/dev/null"],true,false]
["2>/dev/null printf '%s' 'gh pr create'",["2","/dev/null","printf","%s"],["/dev/null"],false,false]
["2>>/dev/null g'h' pr create",["2","/dev/null","gh","pr","create"],["/dev/null"],true,false]
["3<<'EOF' bash -c 'gh pr create'\nliteral gh pr create\nEOF",["bash","-c","gh","pr","create"],[],true,false]
["3<<'EOF' cat\nliteral gh pr create\nEOF",["cat"],[],false,false]
[">/dev/null 'gh' pr create",["/dev/null","gh","pr","create"],["/dev/null"],true,false]
["DB=/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite; sqlite3 -readonly \"$DB\" .tables",["DB=/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite","sqlite3","-readonly","DB",".tables"],["/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite"],false,true]
["DB=/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite; sqlite3 -readonly \"$DB\" .tables",["DB=/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite","sqlite3","-readonly","DB",".tables"],["/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite"],false,true]
["DB=/tmp/232-parity-r6/repo/userdata/chromeria-v2.sqlite; sqlite3 -readonly \"$DB\" .tables",["DB=/tmp/232-parity-r6/repo/userdata/chromeria-v2.sqlite","sqlite3","-readonly","DB",".tables"],["/tmp/232-parity-r6/repo/userdata/chromeria-v2.sqlite"],false,true]
["DB=/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite; sqlite3 -readonly \"$DB\" .tables",["DB=/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite","sqlite3","-readonly","DB",".tables"],["/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite"],false,true]
["DB=~/.t3/userdata/chromeria-v2.sqlite; sqlite3 \"$DB\"",["DB=~/.t3/userdata/chromeria-v2.sqlite","sqlite3","DB"],["~/.t3/userdata/chromeria-v2.sqlite"],false,true]
["FLAG='one two' OTHER=2 \"gh\" pr create",["OTHER=2","gh","pr","create"],[],true,false]
["FLAG=1 'gh' pr create",["FLAG=1","gh","pr","create"],[],true,false]
["FLAG=1 g'h' pr create",["FLAG=1","gh","pr","create"],[],true,false]
["FLAG=1 printf '%s' 'gh pr create'",["FLAG=1","printf","%s"],[],false,false]
["awk 'NR<10' /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["awk","NR","10","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["awk 'NR<10' /tmp/232-parity-r5/repo/RULE.md",["awk","NR","10","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["awk 'NR<10' /tmp/232-parity-r6/repo/RULE.md",["awk","NR","10","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["awk 'NR<10' /tmp/232-parity.lMKzlv/repo/RULE.md",["awk","NR","10","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["bash",["bash"],[],false,false]
["bash -- -c 'gh pr create'",["bash","--","-c","gh","pr","create"],[],true,false]
["bash --noprofile -o pipefail -ce '\"g\"h pr create'",["bash","--noprofile","-o","pipefail","-ce","gh","pr","create"],[],true,false]
["bash --posix -c 'gh pr create'",["bash","--posix","-c","gh","pr","create"],[],true,false]
["bash -c \"'gh' pr create\"",["bash","-c","gh","pr","create"],[],true,false]
["bash -c \"\\\"g\\\"h pr create\"",["bash","-c","gh","pr","create"],[],true,false]
["bash -c \"\\\"g\\\"h\"' pr create'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c \"echo \\\"$(gh pr create)\\\"\"",["bash","-c","echo","gh","pr","create","gh","pr","create"],[],true,false]
["bash -c \"echo \\\"gh pr create\\\"\"",["bash","-c","echo"],[],false,false]
["bash -c \"echo \\\"gh pr create\\\"\"suffix",["bash","-c","echo"],[],false,false]
["bash -c \"echo \\$(gh pr create)\"",["bash","-c","echo","gh","pr","create"],[],true,false]
["bash -c \"echo \\`gh pr create\\`\"",["bash","-c","echo","gh","pr","create"],[],true,false]
["bash -c \"g\"'h pr create'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c \"gh pr create --title \\\"hello\\\"\"",["bash","-c","gh","pr","create","--title","hello"],[],true,false]
["bash -c \"gh pr create\"",["bash","-c","gh","pr","create"],[],true,false]
["bash -c $'\\147h pr create'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c $'\\u0067h pr create'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c $'\\x27gh\\x27 pr create'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c $'\\x67h pr create'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c $'echo \"$(printf \\'%s\\' \\'gh pr create\\')\"'",["bash","-c","echo","printf","%s"],[],false,false]
["bash -c $'echo \\\"gh pr create\\\"'",["bash","-c","echo"],[],false,false]
["bash -c $'echo \\047gh pr create\\047'",["bash","-c","echo"],[],false,false]
["bash -c $'echo \\0; gh pr create'",["bash","-c","echo"],[],false,false]
["bash -c $'echo \\x22gh pr create\\x22'",["bash","-c","echo"],[],false,false]
["bash -c $'echo done' _ -c $'gh pr create'",["bash","-c","echo","done","_","-c"],[],false,false]
["bash -c $'g'\"h pr create\"",["bash","-c","gh","pr","create"],[],true,false]
["bash -c $'gh pr create'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c $'gh pr create\\0; echo mention'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c $'gh\\x20pr\\tcreate'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c $'printf \\'%s\\' \\'gh pr create\\''",["bash","-c","printf","%s"],[],false,false]
["bash -c 'echo \"$@\"' _ -c 'gh pr create'",["bash","-c","echo","@","_","-c"],[],false,false]
["bash -c 'echo \"gh pr create\"'",["bash","-c","echo"],[],false,false]
["bash -c 'echo '\"\\\"gh pr create\\\"\"",["bash","-c","echo"],[],false,false]
["bash -c 'echo \\$(gh pr create)'",["bash","-c","echo","gh","pr","create"],[],true,false]
["bash -c 'echo done' -- -c 'gh pr create'",["bash","-c","echo","done","--","-c"],[],false,false]
["bash -c 'echo done' -c 'gh pr create'",["bash","-c","echo","done","-c"],[],false,false]
["bash -c 'echo done' _ -c \"$(gh pr create)\"",["bash","-c","echo","done","_","-c","gh","pr","create"],[],true,false]
["bash -c 'gh pr create'",["bash","-c","gh","pr","create"],[],true,false]
["bash -c 'gh pr create' _ -c 'echo \"gh pr create\"'",["bash","-c","gh","pr","create","_","-c"],[],true,false]
["bash -c'gh pr create'",["bash"],[],false,false]
["bash -cE 'gh pr create'",["bash","-cE","gh","pr","create"],[],true,false]
["bash -ce 'echo \"gh pr create\"'",["bash","-ce","echo"],[],false,false]
["bash -ce 'echo done' _ -ce 'gh pr create'",["bash","-ce","echo","done","_","-ce"],[],false,false]
["bash -ce 'gh pr create'",["bash","-ce","gh","pr","create"],[],true,false]
["bash -cl 'gh pr create'",["bash","-cl","gh","pr","create"],[],true,false]
["bash -ec 'gh pr create'",["bash","-ec","gh","pr","create"],[],true,false]
["bash -lc 'gh pr create'",["bash","-lc","gh","pr","create"],[],true,false]
["bash -o pipefail -c 'echo \"gh pr create\"'",["bash","-o","pipefail","-c","echo"],[],false,false]
["bash -o pipefail -c 'gh pr create'",["bash","-o","pipefail","-c","gh","pr","create"],[],true,false]
["bash -o pipefail -ce 'echo \"gh pr create\"'",["bash","-o","pipefail","-ce","echo"],[],false,false]
["bash missing-script -c 'gh pr create'",["bash","missing-script","-c","gh","pr","create"],[],true,false]
["bat --plain /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["bat","--plain","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["bat --plain /tmp/232-parity-r5/repo/RULE.md",["bat","--plain","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["bat --plain /tmp/232-parity-r6/repo/RULE.md",["bat","--plain","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["bat --plain /tmp/232-parity.lMKzlv/repo/RULE.md",["bat","--plain","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["bat -r 1:5 /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["bat","-r","1:5","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["bat -r 1:5 /tmp/232-parity-r5/repo/RULE.md",["bat","-r","1:5","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["bat -r 1:5 /tmp/232-parity-r6/repo/RULE.md",["bat","-r","1:5","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["bat -r 1:5 /tmp/232-parity.lMKzlv/repo/RULE.md",["bat","-r","1:5","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["bat -r1:5 /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["bat","-r1:5","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["bat -r1:5 /tmp/232-parity-r5/repo/RULE.md",["bat","-r1:5","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["bat -r1:5 /tmp/232-parity-r6/repo/RULE.md",["bat","-r1:5","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["bat -r1:5 /tmp/232-parity.lMKzlv/repo/RULE.md",["bat","-r1:5","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["bat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["bat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["bat /tmp/232-parity-r5/repo/RULE.md",["bat","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["bat /tmp/232-parity-r6/repo/RULE.md",["bat","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["bat /tmp/232-parity.lMKzlv/repo/RULE.md",["bat","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["batcat --line-range 1:5 /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["batcat","--line-range","1:5","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["batcat --line-range 1:5 /tmp/232-parity-r5/repo/RULE.md",["batcat","--line-range","1:5","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["batcat --line-range 1:5 /tmp/232-parity-r6/repo/RULE.md",["batcat","--line-range","1:5","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["batcat --line-range 1:5 /tmp/232-parity.lMKzlv/repo/RULE.md",["batcat","--line-range","1:5","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["batcat -pr1:5 /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["batcat","-pr1:5","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["batcat -pr1:5 /tmp/232-parity-r5/repo/RULE.md",["batcat","-pr1:5","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["batcat -pr1:5 /tmp/232-parity-r6/repo/RULE.md",["batcat","-pr1:5","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["batcat -pr1:5 /tmp/232-parity.lMKzlv/repo/RULE.md",["batcat","-pr1:5","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat \"/tmp/232-parity-r3.Jt3dHh/repo/RULE.md\"-n",["cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md-n"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat \"/tmp/232-parity-r5/repo/RULE.md\"-n",["cat","/tmp/232-parity-r5/repo/RULE.md-n"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat \"/tmp/232-parity-r6/repo/RULE.md\"-n",["cat","/tmp/232-parity-r6/repo/RULE.md-n"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["cat \"/tmp/232-parity.lMKzlv/repo/RULE.md\"-n",["cat","/tmp/232-parity.lMKzlv/repo/RULE.md-n"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat '/tmp/232-parity-r3.Jt3dHh/repo/RULE.md'",["cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat '/tmp/232-parity-r5/repo/RULE.md'",["cat","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat '/tmp/232-parity-r6/repo/RULE.md'",["cat","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["cat '/tmp/232-parity.lMKzlv/repo/RULE.md'",["cat","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat -n /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["cat","-n","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat -n /tmp/232-parity-r5/repo/RULE.md",["cat","-n","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat -n /tmp/232-parity-r6/repo/RULE.md",["cat","-n","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["cat -n /tmp/232-parity.lMKzlv/repo/RULE.md",["cat","-n","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat /dev/null 2< /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["cat","/dev/null","2","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/dev/null","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat /dev/null 2< /tmp/232-parity-r5/repo/RULE.md",["cat","/dev/null","2","/tmp/232-parity-r5/repo/RULE.md"],["/dev/null","/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat /dev/null 2< /tmp/232-parity-r6/repo/RULE.md",["cat","/dev/null","2","/tmp/232-parity-r6/repo/RULE.md"],["/dev/null","/tmp/232-parity-r6/repo/RULE.md"],false,false]
["cat /dev/null 2< /tmp/232-parity.lMKzlv/repo/RULE.md",["cat","/dev/null","2","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/dev/null","/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat /dev/null 2> /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["cat","/dev/null","2","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/dev/null","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat /dev/null 2> /tmp/232-parity-r5/repo/RULE.md",["cat","/dev/null","2","/tmp/232-parity-r5/repo/RULE.md"],["/dev/null","/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat /dev/null 2> /tmp/232-parity-r6/repo/RULE.md",["cat","/dev/null","2","/tmp/232-parity-r6/repo/RULE.md"],["/dev/null","/tmp/232-parity-r6/repo/RULE.md"],false,false]
["cat /dev/null 2> /tmp/232-parity.lMKzlv/repo/RULE.md",["cat","/dev/null","2","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/dev/null","/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md &",["cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md > /dev/null",["cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","/dev/null"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","/dev/null"],false,false]
["cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md >&2",["cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","2"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md missing.md",["cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","missing.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","missing.md"],false,false]
["cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md | head -n 5",["cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","head","-n","5"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r3.Jt3dHh/repo/a[.]md",["cat","/tmp/232-parity-r3.Jt3dHh/repo/a[.]md"],["/tmp/232-parity-r3.Jt3dHh/repo/a[.]md"],false,false]
["cat /tmp/232-parity-r3.Jt3dHh/repo/x/../a.md",["cat","/tmp/232-parity-r3.Jt3dHh/repo/x/../a.md"],["/tmp/232-parity-r3.Jt3dHh/repo/x/../a.md"],false,false]
["cat /tmp/232-parity-r5/repo/PUSH.md",["cat","/tmp/232-parity-r5/repo/PUSH.md"],["/tmp/232-parity-r5/repo/PUSH.md"],false,false]
["cat /tmp/232-parity-r5/repo/RULE.md",["cat","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r5/repo/RULE.md &",["cat","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r5/repo/RULE.md > /dev/null",["cat","/tmp/232-parity-r5/repo/RULE.md","/dev/null"],["/tmp/232-parity-r5/repo/RULE.md","/dev/null"],false,false]
["cat /tmp/232-parity-r5/repo/RULE.md >&2",["cat","/tmp/232-parity-r5/repo/RULE.md","2"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r5/repo/RULE.md missing.md",["cat","/tmp/232-parity-r5/repo/RULE.md","missing.md"],["/tmp/232-parity-r5/repo/RULE.md","missing.md"],false,false]
["cat /tmp/232-parity-r5/repo/RULE.md | head -n 5",["cat","/tmp/232-parity-r5/repo/RULE.md","head","-n","5"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r5/repo/a[.]md",["cat","/tmp/232-parity-r5/repo/a[.]md"],["/tmp/232-parity-r5/repo/a[.]md"],false,false]
["cat /tmp/232-parity-r5/repo/x/../a.md",["cat","/tmp/232-parity-r5/repo/x/../a.md"],["/tmp/232-parity-r5/repo/x/../a.md"],false,false]
["cat /tmp/232-parity-r6/repo/PUSH.md",["cat","/tmp/232-parity-r6/repo/PUSH.md"],["/tmp/232-parity-r6/repo/PUSH.md"],false,false]
["cat /tmp/232-parity-r6/repo/RULE.md",["cat","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r6/repo/RULE.md &",["cat","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r6/repo/RULE.md > /dev/null",["cat","/tmp/232-parity-r6/repo/RULE.md","/dev/null"],["/tmp/232-parity-r6/repo/RULE.md","/dev/null"],false,false]
["cat /tmp/232-parity-r6/repo/RULE.md >&2",["cat","/tmp/232-parity-r6/repo/RULE.md","2"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r6/repo/RULE.md missing.md",["cat","/tmp/232-parity-r6/repo/RULE.md","missing.md"],["/tmp/232-parity-r6/repo/RULE.md","missing.md"],false,false]
["cat /tmp/232-parity-r6/repo/RULE.md | head -n 5",["cat","/tmp/232-parity-r6/repo/RULE.md","head","-n","5"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["cat /tmp/232-parity-r6/repo/a[.]md",["cat","/tmp/232-parity-r6/repo/a[.]md"],["/tmp/232-parity-r6/repo/a[.]md"],false,false]
["cat /tmp/232-parity-r6/repo/x/../a.md",["cat","/tmp/232-parity-r6/repo/x/../a.md"],["/tmp/232-parity-r6/repo/x/../a.md"],false,false]
["cat /tmp/232-parity.lMKzlv/repo/RULE.md",["cat","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat /tmp/232-parity.lMKzlv/repo/RULE.md &",["cat","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat /tmp/232-parity.lMKzlv/repo/RULE.md > /dev/null",["cat","/tmp/232-parity.lMKzlv/repo/RULE.md","/dev/null"],["/tmp/232-parity.lMKzlv/repo/RULE.md","/dev/null"],false,false]
["cat /tmp/232-parity.lMKzlv/repo/RULE.md >&2",["cat","/tmp/232-parity.lMKzlv/repo/RULE.md","2"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat /tmp/232-parity.lMKzlv/repo/RULE.md missing.md",["cat","/tmp/232-parity.lMKzlv/repo/RULE.md","missing.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md","missing.md"],false,false]
["cat /tmp/232-parity.lMKzlv/repo/RULE.md | head -n 5",["cat","/tmp/232-parity.lMKzlv/repo/RULE.md","head","-n","5"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat /tmp/232-parity.lMKzlv/repo/a[.]md",["cat","/tmp/232-parity.lMKzlv/repo/a[.]md"],["/tmp/232-parity.lMKzlv/repo/a[.]md"],false,false]
["cat /tmp/232-parity.lMKzlv/repo/x/../a.md",["cat","/tmp/232-parity.lMKzlv/repo/x/../a.md"],["/tmp/232-parity.lMKzlv/repo/x/../a.md"],false,false]
["cat <<\"EOF\"\n$(gh pr create)\nEOF",["cat"],[],false,false]
["cat <<\"EÖF\"\n$(gh pr create)\nEÖF",["cat"],[],false,false]
["cat <<'A'\nA\ncat <<'B'\nB\ngh pr create",["cat","cat","gh","pr","create"],[],true,false]
["cat <<'A'\nA\ncat <<'B'\ngh pr create\nB",["cat","cat"],[],false,false]
["cat <<'E\"OF\"'\ngh pr create\nE\"OF\"",["cat","E","OF","gh","pr","create","EOF"],[],true,false]
["cat <<'E;OF'\ngh pr create\nE;OF",["cat","E","OF","gh","pr","create","E","OF"],[],true,false]
["cat <<'END-MARK'\nEND-MARK\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<'END-MARK'\ngh pr create\nEND-MARK",["cat"],[],false,false]
["cat <<'END.MARK'\nENDXMARK\ngh pr create\nEND.MARK",["cat"],["END.MARK"],false,false]
["cat <<'EOF'\n\tEOF\ngh pr create\nEOF",["cat"],[],false,false]
["cat <<'EOF'\n EOF\ngh pr create\nEOF",["cat"],[],false,false]
["cat <<'EOF'\n$(gh pr create --title \"hello\" $(printf x))\nEOF",["cat"],[],false,false]
["cat <<'EOF'\n$(gh pr create)\nEOF",["cat"],[],false,false]
["cat <<'EOF'\nEOF\t\ngh pr create\nEOF",["cat"],[],false,false]
["cat <<'EOF'\nEOF\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<'EOF'\nEOF \ngh pr create\nEOF",["cat"],[],false,false]
["cat <<'EOF'\nEOFX\ngh pr create\nEOF",["cat"],[],false,false]
["cat <<'EOF'\ngh pr create\nEOF",["cat"],[],false,false]
["cat <<'EOF'\nthen run gh pr create\nEOF",["cat"],[],false,false]
["cat <<'EÖF'\nEÖF\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<'EÖF'\ngh pr create\nEÖF",["cat"],[],false,false]
["cat <<'\\EOF'\ngh pr create\n\\EOF",["cat","EOF","gh","pr","create","EOF"],[],true,false]
["cat <<'ÉOF'\ngh pr create\nÉOF",["cat"],[],false,false]
["cat <<'ÉOF'\nÉOF\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<'𝔈OF'\ngh pr create\n𝔈OF",["cat"],[],false,false]
["cat <<'𝔈OF'\n𝔈OF\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<-'EOF'\n\tEOF\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<-'EOF'\n\tEOF \ngh pr create\nEOF",["cat"],[],false,false]
["cat <<-'EOF'\n EOF\ngh pr create\nEOF",["cat"],[],false,false]
["cat <<-EOF\n\tEOF\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<< /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["cat <<< /tmp/232-parity-r5/repo/RULE.md",["cat","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["cat <<< /tmp/232-parity-r6/repo/RULE.md",["cat","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["cat <<< /tmp/232-parity.lMKzlv/repo/RULE.md",["cat","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["cat <<<\"gh pr create\"",["cat"],[],false,false]
["cat <<<EOF\ngh pr create",["cat","EOF","gh","pr","create"],[],true,false]
["cat <<A <<'B'\nA\nB\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<A <<'B'\nx\nA\nB\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<A <<B\nA\nB\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<E'OF'\n$(gh pr create)\nEOF",["cat","EOF","gh","pr","create","EOF"],[],true,false]
["cat <<E'OF'\ngh pr create\nEOF",["cat","EOF","gh","pr","create","EOF"],[],true,false]
["cat <<EO'F'\ngh pr create\nEOF",["cat","EOF","gh","pr","create","EOF"],[],true,false]
["cat <<EOF\n$((1 + $(gh pr create)0))\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\n$(gh pr create $(printf %s x))\nEOF",["cat","gh","pr","create","printf","%s","x"],[],true,false]
["cat <<EOF\n$(gh pr create ${v:-\")\"})\nEOF",["cat","gh","pr","create","v:-"],[],true,false]
["cat <<EOF\n$(gh pr create --title \"a (b)\")\nEOF",["cat","gh","pr","create","--title"],[],true,false]
["cat <<EOF\n$(gh pr create --title \"hello\" $(printf x))\nEOF",["cat","gh","pr","create","--title","hello","printf","x"],[],true,false]
["cat <<EOF\n$(gh pr create)\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\n$(printf %s \"$(gh pr create)\")\nEOF",["cat","printf","%s","gh","pr","create"],[],true,false]
["cat <<EOF\n$(printf %s \"gh pr create\")\nEOF",["cat","printf","%s"],[],false,false]
["cat <<EOF\n${v:-$(gh pr create)}\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\nEOF\ngh pr create",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\n\\$(gh pr create)\nEOF",["cat"],[],false,false]
["cat <<EOF\n\\\\$(gh pr create)\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\n\\\\\\$(gh pr create)\nEOF",["cat"],[],false,false]
["cat <<EOF\n\\\\\\\\$(gh pr create)\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\n\\\\\\\\\\$(gh pr create)\nEOF",["cat"],[],false,false]
["cat <<EOF\n\\\\\\\\\\\\$(gh pr create)\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\n\\\\\\\\\\\\`gh pr create`\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\n\\\\\\\\\\`gh pr create`\nEOF",["cat"],[],false,false]
["cat <<EOF\n\\\\\\\\`gh pr create`\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\n\\\\\\`gh pr create`\nEOF",["cat"],[],false,false]
["cat <<EOF\n\\\\`gh pr create`\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\n\\`gh pr create\\`\nEOF",["cat"],[],false,false]
["cat <<EOF\n\\`gh pr create`\nEOF",["cat"],[],false,false]
["cat <<EOF\n`gh pr create`\nEOF",["cat","gh","pr","create"],[],true,false]
["cat <<EOF\nrun gh pr create later\nEOF",["cat"],[],false,false]
["cat <<EÖF\n$(gh pr create)\nEÖF",["cat","gh","pr","create"],[],true,false]
["cat <<EÖF\ngh pr create\nEÖF",["cat"],[],false,false]
["cat <<\\EOF\ngh pr create\nEOF",["cat","EOF","gh","pr","create","EOF"],[],true,false]
["cat <<ÉOF\n$(gh pr create)\nÉOF",["cat","gh","pr","create"],[],true,false]
["cat <<ÉOF\ngh pr create\nÉOF",["cat"],[],false,false]
["cat <<𝔈OF\n$(gh pr create)\n𝔈OF",["cat","gh","pr","create"],[],true,false]
["cat <<𝔈OF\ngh pr create\n𝔈OF",["cat"],[],false,false]
["cat > notes.md <<'EOF'\nhello\nEOF\ngh pr create",["cat","notes.md","gh","pr","create"],["notes.md"],true,false]
["cat RULE.md",["cat","RULE.md"],["RULE.md"],false,false]
["cat missing.md",["cat","missing.md"],["missing.md"],false,false]
["cat: Permission denied",["cat:","Permission","denied"],[],false,false]
["cd - && cat a.md",["cd","-","cat","a.md"],["a.md"],false,false]
["cd /tmp/232-parity-r3.Jt3dHh/repo && cat a.md",["cd","/tmp/232-parity-r3.Jt3dHh/repo","cat","a.md"],["/tmp/232-parity-r3.Jt3dHh/repo","a.md"],false,false]
["cd /tmp/232-parity-r3.Jt3dHh/repo/sub && cat a.md",["cd","/tmp/232-parity-r3.Jt3dHh/repo/sub","cat","a.md"],["/tmp/232-parity-r3.Jt3dHh/repo/sub","a.md"],false,false]
["cd /tmp/232-parity-r5/repo && cat a.md",["cd","/tmp/232-parity-r5/repo","cat","a.md"],["/tmp/232-parity-r5/repo","a.md"],false,false]
["cd /tmp/232-parity-r5/repo/sub && cat a.md",["cd","/tmp/232-parity-r5/repo/sub","cat","a.md"],["/tmp/232-parity-r5/repo/sub","a.md"],false,false]
["cd /tmp/232-parity-r6/repo && cat a.md",["cd","/tmp/232-parity-r6/repo","cat","a.md"],["/tmp/232-parity-r6/repo","a.md"],false,false]
["cd /tmp/232-parity-r6/repo/sub && cat a.md",["cd","/tmp/232-parity-r6/repo/sub","cat","a.md"],["/tmp/232-parity-r6/repo/sub","a.md"],false,false]
["cd /tmp/232-parity.lMKzlv/repo && cat a.md",["cd","/tmp/232-parity.lMKzlv/repo","cat","a.md"],["/tmp/232-parity.lMKzlv/repo","a.md"],false,false]
["cd /tmp/232-parity.lMKzlv/repo/sub && cat a.md",["cd","/tmp/232-parity.lMKzlv/repo/sub","cat","a.md"],["/tmp/232-parity.lMKzlv/repo/sub","a.md"],false,false]
["cd x && env A=1 /usr/local/bin/gh pr create --fill",["cd","x","env","A=1","/usr/local/bin/gh","pr","create","--fill"],["/usr/local/bin/gh"],true,false]
["cd x && gh pr create --fill",["cd","x","gh","pr","create","--fill"],[],true,false]
["chromeria-v2.sqlite",["chromeria-v2.sqlite"],["chromeria-v2.sqlite"],false,true]
["command -- 'gh' pr create",["command","--","gh","pr","create"],[],true,false]
["command printf '%s' 'gh pr create'",["command","printf","%s"],[],false,false]
["curl -s https://example.com/chromeria-v2.sqlite.gz",["curl","-s","https://example.com/chromeria-v2.sqlite.gz"],[],false,false]
["curl https://example.com/chromeria-v2.sqlite.gz",["curl","https://example.com/chromeria-v2.sqlite.gz"],[],false,false]
["dash -c 'gh pr create'",["dash","-c","gh","pr","create"],[],true,false]
["echo \"$( # )\ngh pr create\n)\"",["echo","#"],[],false,false]
["echo \"$((1 + $(gh pr create)0))\"",["echo","gh","pr","create"],[],true,false]
["echo \"$((1 + (2))) gh pr create\"",["echo"],[],false,false]
["echo \"$(case x in x) gh pr create ;; esac)\"",["echo","case","x","in","x"],[],false,false]
["echo \"$(case x in x) gh pr create;; esac)\"",["echo","case","x","in","x"],[],false,false]
["echo \"$(cat <<'EOF'\n)\nEOF\ngh pr create\n)\"",["echo","cat"],[],false,false]
["echo \"$(cat <<'EOF'\n)\nEOF\ngh pr create)\"",["echo","cat"],[],false,false]
["echo \"$(gh pr create \"$(printf x)\")\"",["echo","gh","pr","create","printf","x"],[],true,false]
["echo \"$(gh pr create $((1 + (2))))\"",["echo","gh","pr","create","1","+","2"],[],true,false]
["echo \"$(gh pr create $(printf %s x))\"",["echo","gh","pr","create","printf","%s","x"],[],true,false]
["echo \"$(gh pr create $(printf x))\"",["echo","gh","pr","create","printf","x"],[],true,false]
["echo \"$(gh pr create ${v:-\")\"})\"",["echo","gh","pr","create","v:-"],[],true,false]
["echo \"$(gh pr create --title \"a (b)\")\"",["echo","gh","pr","create","--title"],[],true,false]
["echo \"$(gh pr create --title \"hello\")\"",["echo","gh","pr","create","--title","hello"],[],true,false]
["echo \"$(gh pr create)\"",["echo","gh","pr","create"],[],true,false]
["echo \"$(printf \"%s\" \"$(printf \"%s\" \"gh pr create\")\")\"",["echo","printf","%s","printf","%s"],[],false,false]
["echo \"$(printf \"%s\" \"${v:-gh pr create}\")\"",["echo","printf","%s"],[],false,false]
["echo \"$(printf \"%s\" \"gh pr create\")\"",["echo","printf","%s"],[],false,false]
["echo \"$(printf %s \"$(gh pr create)\")\"",["echo","printf","%s","gh","pr","create"],[],true,false]
["echo \"$(printf %s \"gh pr create\")\"",["echo","printf","%s"],[],false,false]
["echo \"$(printf x # )\ngh pr create)\"",["echo","printf","x","#"],[],false,false]
["echo \"$(true; cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md ; true)\" > /dev/null",["echo","true","cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","true","/dev/null"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","/dev/null"],false,false]
["echo \"$(true; cat /tmp/232-parity-r5/repo/RULE.md ; true)\" > /dev/null",["echo","true","cat","/tmp/232-parity-r5/repo/RULE.md","true","/dev/null"],["/tmp/232-parity-r5/repo/RULE.md","/dev/null"],false,false]
["echo \"$(true; cat /tmp/232-parity-r6/repo/RULE.md ; true)\" > /dev/null",["echo","true","cat","/tmp/232-parity-r6/repo/RULE.md","true","/dev/null"],["/tmp/232-parity-r6/repo/RULE.md","/dev/null"],false,false]
["echo \"$(true; cat /tmp/232-parity.lMKzlv/repo/RULE.md ; true)\" > /dev/null",["echo","true","cat","/tmp/232-parity.lMKzlv/repo/RULE.md","true","/dev/null"],["/tmp/232-parity.lMKzlv/repo/RULE.md","/dev/null"],false,false]
["echo \"${v:-$(gh pr create --title \"hello\")}\"",["echo","gh","pr","create","--title","hello"],[],true,false]
["echo \"${v:-$(gh pr create)}\"",["echo","gh","pr","create"],[],true,false]
["echo \"${v:-gh pr create}\"",["echo"],[],false,false]
["echo \"\\$(gh pr create)\"",["echo"],[],false,false]
["echo \"\\\\$(gh pr create)\"",["echo","gh","pr","create"],[],true,false]
["echo \"\\\\\\$(gh pr create)\"",["echo"],[],false,false]
["echo \"\\\\\\\\$(gh pr create)\"",["echo","gh","pr","create"],[],true,false]
["echo \"\\\\\\\\\\$(gh pr create)\"",["echo"],[],false,false]
["echo \"\\\\\\\\\\\\$(gh pr create)\"",["echo","gh","pr","create"],[],true,false]
["echo \"\\\\\\\\\\\\`gh pr create`\"",["echo","gh","pr","create"],[],true,false]
["echo \"\\\\\\\\\\`gh pr create`\"",["echo"],[],false,false]
["echo \"\\\\\\\\`gh pr create`\"",["echo","gh","pr","create"],[],true,false]
["echo \"\\\\\\`gh pr create`\"",["echo"],[],false,false]
["echo \"\\\\`gh pr create`\"",["echo","gh","pr","create"],[],true,false]
["echo \"\\`gh pr create\\`\"",["echo"],[],false,false]
["echo \"\\`gh pr create`\"",["echo"],[],false,false]
["echo \"`gh pr create --title \"hello\"`\"",["echo","gh","pr","create","--title","hello"],[],true,false]
["echo \"`gh pr create`\"",["echo","gh","pr","create"],[],true,false]
["echo \"`printf \"%s\" \"gh pr create\"`\"",["echo","printf","%s"],[],false,false]
["echo \"`printf \"%s\" \\`gh pr create\\``\"",["echo","printf","%s","gh","pr","create"],[],true,false]
["echo \"bash\" -ce 'gh pr create'",["echo","bash","-ce","gh","pr","create"],[],true,false]
["echo \"gh\" pr create",["echo","gh","pr","create"],[],true,false]
["echo \"live check: gh pr create\"",["echo"],[],false,false]
["echo \"open /Users/u/.t3/userdata/chromeria-v2.sqlite later\"",["echo"],["/Users/u/.t3/userdata/chromeria-v2.sqlite"],false,false]
["echo $'\\x67h' pr create",["echo","gh","pr","create"],[],true,false]
["echo $'gh pr create'",["echo"],[],false,false]
["echo $'the file chromeria-v2.sqlite'",["echo"],["chromeria-v2.sqlite"],false,false]
["echo $((1 + $(gh pr create)0))",["echo","1","+","gh","pr","create","0","gh","pr","create"],[],true,false]
["echo $(gh pr create $(printf %s x))",["echo","gh","pr","create","printf","%s","x"],[],true,false]
["echo $(gh pr create ${v:-\")\"})",["echo","gh","pr","create","v:-"],[],true,false]
["echo $(gh pr create --title \"a (b)\")",["echo","gh","pr","create","--title"],[],true,false]
["echo $(gh pr create --title \"hello\")",["echo","gh","pr","create","--title","hello"],[],true,false]
["echo $(printf %s \"$(gh pr create)\")",["echo","printf","%s","gh","pr","create"],[],true,false]
["echo $(printf %s \"gh pr create\")",["echo","printf","%s"],[],false,false]
["echo ${v:-$(gh pr create)}",["echo","v:-","gh","pr","create","gh","pr","create"],[],true,false]
["echo '$(gh pr create)'",["echo"],[],false,false]
["echo 'bash -c gh pr create'",["echo"],[],false,false]
["echo 'gh pr create'",["echo"],[],false,false]
["echo 'ignore; cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md ; ignore'",["echo"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["echo 'ignore; cat /tmp/232-parity-r5/repo/RULE.md ; ignore'",["echo"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["echo 'ignore; cat /tmp/232-parity-r6/repo/RULE.md ; ignore'",["echo"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["echo 'ignore; cat /tmp/232-parity.lMKzlv/repo/RULE.md ; ignore'",["echo"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["echo 'the file chromeria-v2.sqlite'",["echo"],["chromeria-v2.sqlite"],false,false]
["echo /tmp/232-parity-r3.Jt3dHh/repo/RULE.md && cat missing.md",["echo","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","cat","missing.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","missing.md"],false,false]
["echo /tmp/232-parity-r5/repo/RULE.md && cat missing.md",["echo","/tmp/232-parity-r5/repo/RULE.md","cat","missing.md"],["/tmp/232-parity-r5/repo/RULE.md","missing.md"],false,false]
["echo /tmp/232-parity-r6/repo/RULE.md && cat missing.md",["echo","/tmp/232-parity-r6/repo/RULE.md","cat","missing.md"],["/tmp/232-parity-r6/repo/RULE.md","missing.md"],false,false]
["echo /tmp/232-parity.lMKzlv/repo/RULE.md && cat missing.md",["echo","/tmp/232-parity.lMKzlv/repo/RULE.md","cat","missing.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md","missing.md"],false,false]
["echo a",["echo","a"],[],false,false]
["echo after",["echo","after"],[],false,false]
["echo b'a'sh -o pipefail -c 'gh pr create'",["echo","bash","-o","pipefail","-c","gh","pr","create"],[],true,false]
["echo bash -c 'echo \"gh pr create\"'",["echo","bash","-c","echo"],[],false,false]
["echo bash -c 'echo done' _ -c 'gh pr create'",["echo","bash","-c","echo","done","_","-c"],[],false,false]
["echo bash -c 'gh pr create'",["echo","bash","-c","gh","pr","create"],[],true,false]
["echo g\"h\" pr create",["echo","gh","pr","create"],[],true,false]
["echo g'h pr create'",["echo"],[],false,false]
["echo g'h' pr create",["echo","gh","pr","create"],[],true,false]
["echo gh pr",["echo","gh","pr"],[],false,false]
["echo gh pr create",["echo","gh","pr","create"],[],true,false]
["echo hello",["echo","hello"],[],false,false]
["echo ksh -c 'gh pr create'",["echo","ksh","-c","gh","pr","create"],[],true,false]
["echo ok &&\ngh pr create",["echo","ok","gh","pr","create"],[],true,false]
["echo prefix' the file chromeria-v2.sqlite'",["echo"],["chromeria-v2.sqlite"],false,false]
["echo sh -c 'gh pr create'",["echo","sh","-c","gh","pr","create"],[],true,false]
["env 'gh' pr create",["env","gh","pr","create"],[],true,false]
["env -u UNUSED 'gh' pr create",["env","-u","UNUSED","gh","pr","create"],[],true,false]
["env -u UNUSED printf '%s' 'gh pr create'",["env","-u","UNUSED","printf","%s"],[],false,false]
["env FLAG=1 'gh' pr create",["env","FLAG=1","gh","pr","create"],[],true,false]
["env FLAG=1 bash -c \"\\\"g\\\"h pr create\"",["env","FLAG=1","bash","-c","gh","pr","create"],[],true,false]
["env FLAG=1 bash -o pipefail -ce 'gh pr create'",["env","FLAG=1","bash","-o","pipefail","-ce","gh","pr","create"],[],true,false]
["env FOO=1 gh pr create",["env","FOO=1","gh","pr","create"],[],true,false]
["env bash -c 'gh pr create'",["env","bash","-c","gh","pr","create"],[],true,false]
["env g'h' pr create",["env","gh","pr","create"],[],true,false]
["env ksh -c 'echo \"gh pr create\"'",["env","ksh","-c","echo"],[],false,false]
["env ksh -c 'gh pr create'",["env","ksh","-c","gh","pr","create"],[],true,false]
["env printf '%s' 'gh pr create'",["env","printf","%s"],[],false,false]
["exec -a gh-alias 'gh' pr create",["exec","-a","gh-alias","gh","pr","create"],[],true,false]
["exec g'h' pr create",["exec","gh","pr","create"],[],true,false]
["exec printf '%s' 'gh pr create'",["exec","printf","%s"],[],false,false]
["false",["false"],[],false,false]
["false && cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md; true",["false","cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","true"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["false && cat /tmp/232-parity-r5/repo/RULE.md; true",["false","cat","/tmp/232-parity-r5/repo/RULE.md","true"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["false && cat /tmp/232-parity-r6/repo/RULE.md; true",["false","cat","/tmp/232-parity-r6/repo/RULE.md","true"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["false && cat /tmp/232-parity.lMKzlv/repo/RULE.md; true",["false","cat","/tmp/232-parity.lMKzlv/repo/RULE.md","true"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["find . -exec bash -c 'echo \"gh pr create\"' \\;",["find",".","-exec","bash","-c","echo"],[],false,false]
["find . -exec bash -c 'gh pr create' \\;",["find",".","-exec","bash","-c","gh","pr","create"],[],true,false]
["for i in 1; do bash -c 'echo \"gh pr create\"'; done",["for","i","in","1","do","bash","-c","echo","done"],[],false,false]
["for i in 1; do bash -c 'gh pr create'; done",["for","i","in","1","do","bash","-c","gh","pr","create","done"],[],true,false]
["for n in 1; do \"gh\" pr create; done",["for","n","in","1","do","gh","pr","create","done"],[],true,false]
["for n in 1; do printf '%s' 'gh pr create'; done",["for","n","in","1","do","printf","%s","done"],[],false,false]
["g'h' pr create",["gh","pr","create"],[],true,false]
["g\\h pr create",["gh","pr","create"],[],true,false]
["gh",["gh"],[],false,false]
["gh issue create",["gh","issue","create"],[],false,false]
["gh issue create --title \"Record the bake\" --body \"The entry names chromeria-v2.sqlite in a test fixture.\"",["gh","issue","create","--title","--body"],["chromeria-v2.sqlite"],false,false]
["gh issue create --title \"Record the bake\" --body-file - <<'EOF'\nThe entry names chromeria-v2.sqlite in a test fixture.\nEOF",["gh","issue","create","--title","--body-file","-"],["chromeria-v2.sqlite"],false,false]
["gh issue create --title t --body \"open it with gh pr create\"",["gh","issue","create","--title","t","--body"],[],false,false]
["gh issue create --title x --body-file -",["gh","issue","create","--title","x","--body-file","-"],[],false,false]
["gh issue view 5 --json body -q .body; gh pr create",["gh","issue","view","5","--json","body","-q",".body","gh","pr","create"],[],true,false]
["gh pr",["gh","pr"],[],false,false]
["gh pr create",["gh","pr","create"],[],true,false]
["gh pr create --body SECRET-BODY",["gh","pr","create","--body","SECRET-BODY"],[],true,false]
["gh pr create --fill",["gh","pr","create","--fill"],[],true,false]
["gh pr create --title \"x\" --body-file - <<'EOF'\nbody\nEOF",["gh","pr","create","--title","x","--body-file","-"],[],true,false]
["gh pr create | cat",["gh","pr","create","cat"],[],true,false]
["gh pr createx",["gh","pr","createx"],[],false,false]
["gh pr list",["gh","pr","list"],[],false,false]
["gh-calls.jsonl",["gh-calls.jsonl"],["gh-calls.jsonl"],false,false]
["gh.json",["gh.json"],["gh.json"],false,false]
["ghx pr create",["ghx","pr","create"],[],false,false]
["git",["git"],[],false,false]
["git commit",["git","commit"],[],false,false]
["git commit -m x",["git","commit","-m","x"],[],false,false]
["git push",["git","push"],[],false,false]
["git push; echo \"exit=$?\"",["git","push","echo","exit=","?"],[],false,false]
["git status",["git","status"],[],false,false]
["git status push",["git","status","push"],[],false,false]
["git@github.com: Permission denied (publickey).",["git@github.com:","Permission","denied","publickey","."],[],false,false]
["grep -n x /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["grep","-n","x","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["grep -n x /tmp/232-parity-r3.Jt3dHh/repo/RULE.md; cat /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["grep","-n","x","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md","cat","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["grep -n x /tmp/232-parity-r5/repo/RULE.md",["grep","-n","x","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["grep -n x /tmp/232-parity-r5/repo/RULE.md; cat /tmp/232-parity-r5/repo/RULE.md",["grep","-n","x","/tmp/232-parity-r5/repo/RULE.md","cat","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["grep -n x /tmp/232-parity-r6/repo/RULE.md",["grep","-n","x","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["grep -n x /tmp/232-parity-r6/repo/RULE.md; cat /tmp/232-parity-r6/repo/RULE.md",["grep","-n","x","/tmp/232-parity-r6/repo/RULE.md","cat","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["grep -n x /tmp/232-parity.lMKzlv/repo/RULE.md",["grep","-n","x","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["grep -n x /tmp/232-parity.lMKzlv/repo/RULE.md; cat /tmp/232-parity.lMKzlv/repo/RULE.md",["grep","-n","x","/tmp/232-parity.lMKzlv/repo/RULE.md","cat","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["head -n 40 /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["head","-n","40","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["head -n 40 /tmp/232-parity-r5/repo/RULE.md",["head","-n","40","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["head -n 40 /tmp/232-parity-r6/repo/RULE.md",["head","-n","40","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["head -n 40 /tmp/232-parity.lMKzlv/repo/RULE.md",["head","-n","40","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["if false; then :; else g'h' pr create; fi",["if","false","then",":","else","gh","pr","create","fi"],[],true,false]
["if true; then 'gh' pr create; fi",["if","true","then","gh","pr","create","fi"],[],true,false]
["if true; then bash -c 'echo \"gh pr create\"'; fi",["if","true","then","bash","-c","echo","fi"],[],false,false]
["if true; then bash -c 'gh pr create'; fi",["if","true","then","bash","-c","gh","pr","create","fi"],[],true,false]
["if true; then printf '%s' 'gh pr create'; fi",["if","true","then","printf","%s","fi"],[],false,false]
["less +40 /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["less","+40","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["less +40 /tmp/232-parity-r5/repo/RULE.md",["less","+40","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["less +40 /tmp/232-parity-r6/repo/RULE.md",["less","+40","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["less +40 /tmp/232-parity.lMKzlv/repo/RULE.md",["less","+40","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["less /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["less","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["less /tmp/232-parity-r5/repo/RULE.md",["less","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["less /tmp/232-parity-r6/repo/RULE.md",["less","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["less /tmp/232-parity.lMKzlv/repo/RULE.md",["less","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["ls",["ls"],[],false,false]
["ls /nope",["ls","/nope"],["/nope"],false,false]
["ls /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["ls","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["ls /tmp/232-parity-r5/repo/RULE.md",["ls","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["ls /tmp/232-parity-r6/repo/RULE.md",["ls","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["ls /tmp/232-parity.lMKzlv/repo/RULE.md",["ls","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["make",["make"],[],false,false]
["nl -ba /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["nl","-ba","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["nl -ba /tmp/232-parity-r5/repo/PUSH.md",["nl","-ba","/tmp/232-parity-r5/repo/PUSH.md"],["/tmp/232-parity-r5/repo/PUSH.md"],false,false]
["nl -ba /tmp/232-parity-r5/repo/RULE.md",["nl","-ba","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["nl -ba /tmp/232-parity-r6/repo/PUSH.md",["nl","-ba","/tmp/232-parity-r6/repo/PUSH.md"],["/tmp/232-parity-r6/repo/PUSH.md"],false,false]
["nl -ba /tmp/232-parity-r6/repo/RULE.md",["nl","-ba","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["nl -ba /tmp/232-parity.lMKzlv/repo/RULE.md",["nl","-ba","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["nohup 'gh' pr create",["nohup","gh","pr","create"],[],true,false]
["printf '%s ' 'gh pr create'",["printf"],[],false,false]
["printf '%s ' 'gh' 'pr' 'create'",["printf","gh","pr","create"],[],true,false]
["printf '%s' ';' gh pr create",["printf","%s","gh","pr","create"],[],true,false]
["printf '%s' '>'&gh pr create",["printf","%s","gh","pr","create"],[],true,false]
["printf '%s' \\>&gh pr create",["printf","%s","gh","pr","create"],[],true,false]
["printf '%s\\n' '<<EOF'\ngh pr create\nEOF",["printf","%s","n","EOF","gh","pr","create","EOF"],[],true,false]
["printf gh pr create",["printf","gh","pr","create"],[],true,false]
["printf x | gh pr create --fill",["printf","x","gh","pr","create","--fill"],[],true,false]
["python3 - <<'EOF'\nfrom pathlib import Path\np = Path('tests/test_serve.py')\np.write_text(p.read_text().replace('state.sqlite', 'chromeria-v2.sqlite'))\nEOF",["python3","-"],["tests/test_serve.py","state.sqlite","chromeria-v2.sqlite"],false,false]
["python3 - <<'PY'\nkeys = ['gh pr create']\nPY",["python3","-"],[],false,false]
["python3 -c \"import sqlite3; sqlite3.connect('file:///tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite?mode=ro', uri=True)\"",["python3","-c"],["sqlite3.connect","/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite"],false,false]
["python3 -c \"import sqlite3; sqlite3.connect('file:///tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite?mode=ro', uri=True)\"",["python3","-c"],["sqlite3.connect","/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite"],false,false]
["python3 -c \"import sqlite3; sqlite3.connect('file:///tmp/232-parity-r6/repo/userdata/chromeria-v2.sqlite?mode=ro', uri=True)\"",["python3","-c"],["sqlite3.connect","/tmp/232-parity-r6/repo/userdata/chromeria-v2.sqlite"],false,false]
["python3 -c \"import sqlite3; sqlite3.connect('file:///tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite?mode=ro', uri=True)\"",["python3","-c"],["sqlite3.connect","/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite"],false,false]
["python3 -c \"print('gh pr create')\"",["python3","-c"],[],false,false]
["rg gh pr create tests/",["rg","gh","pr","create","tests/"],["tests/"],true,false]
["rg x /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["rg","x","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["rg x /tmp/232-parity-r5/repo/RULE.md",["rg","x","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["rg x /tmp/232-parity-r6/repo/RULE.md",["rg","x","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["rg x /tmp/232-parity.lMKzlv/repo/RULE.md",["rg","x","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["sed -n '1,200p' /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["sed","-n","1,200p","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["sed -n '1,200p' /tmp/232-parity-r5/repo/RULE.md",["sed","-n","1,200p","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["sed -n '1,200p' /tmp/232-parity-r6/repo/RULE.md",["sed","-n","1,200p","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["sed -n '1,200p' /tmp/232-parity.lMKzlv/repo/RULE.md",["sed","-n","1,200p","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["sh -c \"\\\"g\\\"h pr create\"",["sh","-c","gh","pr","create"],[],true,false]
["sh -c \"printf '%s' \\\"gh pr create\\\"\"",["sh","-c","printf","%s"],[],false,false]
["sh -c $'\\x67h pr create'",["sh","-c","gh","pr","create"],[],true,false]
["sh -c 'echo done' _ -c 'gh pr create'",["sh","-c","echo","done","_","-c"],[],false,false]
["sh -c 'gh pr create'",["sh","-c","gh","pr","create"],[],true,false]
["sh -c 'gh pr create' -c 'echo \"gh pr create\"'",["sh","-c","gh","pr","create","-c"],[],true,false]
["sqlite3 ",["sqlite3"],[],false,false]
["sqlite3 \"/Users/u/.t3/userdata/chromeria-v2.sqlite\" .tables",["sqlite3","/Users/u/.t3/userdata/chromeria-v2.sqlite",".tables"],["/Users/u/.t3/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 $'chromeria-v2.sqlite' .tables",["sqlite3","chromeria-v2.sqlite",".tables"],["chromeria-v2.sqlite"],false,true]
["sqlite3 'chromeria-v2.sqlite' .tables",["sqlite3","chromeria-v2.sqlite",".tables"],["chromeria-v2.sqlite"],false,true]
["sqlite3 'file:",["sqlite3","file:"],[],false,false]
["sqlite3 'file:/Users/u/.t3/userdata/chromeria-v2.sqlite?mode=ro'",["sqlite3","file:/Users/u/.t3/userdata/chromeria-v2.sqlite?mode=ro"],["/Users/u/.t3/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 'file:/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite?mode=ro' 'select 1'",["sqlite3","file:/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite?mode=ro"],["/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 'file:/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite?mode=ro' .tables",["sqlite3","file:/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite?mode=ro",".tables"],["/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 'file:/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite?mode=ro' 'select 1'",["sqlite3","file:/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite?mode=ro"],["/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 'file:/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite?mode=ro' .tables",["sqlite3","file:/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite?mode=ro",".tables"],["/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 'file:/tmp/232-parity-r6/repo/userdata/chromeria-v2.sqlite?mode=ro' 'select 1'",["sqlite3","file:/tmp/232-parity-r6/repo/userdata/chromeria-v2.sqlite?mode=ro"],["/tmp/232-parity-r6/repo/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 'file:/tmp/232-parity-r6/repo/userdata/chromeria-v2.sqlite?mode=ro' .tables",["sqlite3","file:/tmp/232-parity-r6/repo/userdata/chromeria-v2.sqlite?mode=ro",".tables"],["/tmp/232-parity-r6/repo/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 'file:/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite?mode=ro' 'select 1'",["sqlite3","file:/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite?mode=ro"],["/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 'file:/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite?mode=ro' .tables",["sqlite3","file:/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite?mode=ro",".tables"],["/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 'file:/x/userdata/chromeria-v2.sqlite?mode=ro' .tables",["sqlite3","file:/x/userdata/chromeria-v2.sqlite?mode=ro",".tables"],["/x/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 -readonly /Users/u/.t3/userdata/chromeria-v2.sqlite .tables",["sqlite3","-readonly","/Users/u/.t3/userdata/chromeria-v2.sqlite",".tables"],["/Users/u/.t3/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 -readonly ~/.t3/userdata/chromeria-v2.sqlite .tables",["sqlite3","-readonly","~/.t3/userdata/chromeria-v2.sqlite",".tables"],["~/.t3/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /Users/u/.t3/userdata/chromeria-v2.sqlite",["sqlite3","/Users/u/.t3/userdata/chromeria-v2.sqlite"],["/Users/u/.t3/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /Users/u/.t3/userdata/chromeria-v2.sqlite 'select 1'",["sqlite3","/Users/u/.t3/userdata/chromeria-v2.sqlite"],["/Users/u/.t3/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite 'select 1'",["sqlite3","/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite"],["/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite .tables",["sqlite3","/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite",".tables"],["/tmp/232-parity-r3.Jt3dHh/repo/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite 'select 1'",["sqlite3","/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite"],["/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite .tables",["sqlite3","/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite",".tables"],["/tmp/232-parity-r5/repo/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /tmp/232-parity-r6/repo/userdata/chromeria-v2.sqlite 'select 1'",["sqlite3","/tmp/232-parity-r6/repo/userdata/chromeria-v2.sqlite"],["/tmp/232-parity-r6/repo/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /tmp/232-parity-r6/repo/userdata/chromeria-v2.sqlite .tables",["sqlite3","/tmp/232-parity-r6/repo/userdata/chromeria-v2.sqlite",".tables"],["/tmp/232-parity-r6/repo/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite 'select 1'",["sqlite3","/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite"],["/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite .tables",["sqlite3","/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite",".tables"],["/tmp/232-parity.lMKzlv/repo/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 /x/userdata/chromeria-v2.sqlite .tables",["sqlite3","/x/userdata/chromeria-v2.sqlite",".tables"],["/x/userdata/chromeria-v2.sqlite"],false,true]
["sqlite3 chromeria-v2'.sqlite' .tables",["sqlite3","chromeria-v2.sqlite",".tables"],[],false,true]
["sqlite3 chromeria-v2.sqlite",["sqlite3","chromeria-v2.sqlite"],["chromeria-v2.sqlite"],false,true]
["sqlite3 chromeria-v2.sqlite .tables",["sqlite3","chromeria-v2.sqlite",".tables"],["chromeria-v2.sqlite"],false,true]
["sqlite3 file:/Users/u/.t3/userdata/chromeria-v2.sqlite?mode=ro",["sqlite3","file:/Users/u/.t3/userdata/chromeria-v2.sqlite?mode=ro"],["/Users/u/.t3/userdata/chromeria-v2.sqlite"],false,false]
["sqlite3 ~/.t3/userdata/chromeria-v2.sqlite",["sqlite3","~/.t3/userdata/chromeria-v2.sqlite"],["~/.t3/userdata/chromeria-v2.sqlite"],false,true]
["ssh host",["ssh","host"],[],false,false]
["ssh host bash -c 'echo \"gh pr create\"'",["ssh","host","bash","-c","echo"],[],false,false]
["ssh host bash -c 'gh pr create'",["ssh","host","bash","-c","gh","pr","create"],[],true,false]
["step /tmp/232-parity-r3.Jt3dHh/repo/i.md",["step","/tmp/232-parity-r3.Jt3dHh/repo/i.md"],["/tmp/232-parity-r3.Jt3dHh/repo/i.md"],false,false]
["step /tmp/232-parity.lMKzlv/repo/i.md",["step","/tmp/232-parity.lMKzlv/repo/i.md"],["/tmp/232-parity.lMKzlv/repo/i.md"],false,false]
["step 0",["step","0"],[],false,false]
["step 1",["step","1"],[],false,false]
["step 2",["step","2"],[],false,false]
["step 3",["step","3"],[],false,false]
["step 4",["step","4"],[],false,false]
["step 5",["step","5"],[],false,false]
["step 6",["step","6"],[],false,false]
["step 7",["step","7"],[],false,false]
["sudo -n 'gh' pr create",["sudo","-n","gh","pr","create"],[],true,false]
["sudo -n printf '%s' 'gh pr create'",["sudo","-n","printf","%s"],[],false,false]
["sudo -u nobody g'h' pr create",["sudo","-u","nobody","gh","pr","create"],[],true,false]
["tail -n 20 /tmp/232-parity-r3.Jt3dHh/repo/RULE.md",["tail","-n","20","/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],["/tmp/232-parity-r3.Jt3dHh/repo/RULE.md"],false,false]
["tail -n 20 /tmp/232-parity-r5/repo/RULE.md",["tail","-n","20","/tmp/232-parity-r5/repo/RULE.md"],["/tmp/232-parity-r5/repo/RULE.md"],false,false]
["tail -n 20 /tmp/232-parity-r6/repo/RULE.md",["tail","-n","20","/tmp/232-parity-r6/repo/RULE.md"],["/tmp/232-parity-r6/repo/RULE.md"],false,false]
["tail -n 20 /tmp/232-parity.lMKzlv/repo/RULE.md",["tail","-n","20","/tmp/232-parity.lMKzlv/repo/RULE.md"],["/tmp/232-parity.lMKzlv/repo/RULE.md"],false,false]
["time 'gh' pr create",["time","gh","pr","create"],[],true,false]
["time -p 'gh' pr create",["time","-p","gh","pr","create"],[],true,false]
["timeout 5 bash -c 'echo \"gh pr create\"'",["timeout","5","bash","-c","echo"],[],false,false]
["timeout 5 bash -c 'gh pr create'",["timeout","5","bash","-c","gh","pr","create"],[],true,false]
["tool/tmp/232-parity-r3.Jt3dHh/repo/i.md",["tool/tmp/232-parity-r3.Jt3dHh/repo/i.md"],["tool/tmp/232-parity-r3.Jt3dHh/repo/i.md"],false,false]
["tool/tmp/232-parity.lMKzlv/repo/i.md",["tool/tmp/232-parity.lMKzlv/repo/i.md"],["tool/tmp/232-parity.lMKzlv/repo/i.md"],false,false]
["tool0",["tool0"],[],false,false]
["tool1",["tool1"],[],false,false]
["tool2",["tool2"],[],false,false]
["tool3",["tool3"],[],false,false]
["tool4",["tool4"],[],false,false]
["tool5",["tool5"],[],false,false]
["tool6",["tool6"],[],false,false]
["tool7",["tool7"],[],false,false]
["x=`gh pr create`",["x=","gh","pr","create"],[],true,false]
["xargs bash -c 'echo \"gh pr create\"'",["xargs","bash","-c","echo"],[],false,false]
["xargs bash -c 'gh pr create'",["xargs","bash","-c","gh","pr","create"],[],true,false]
["xargs bash -o pipefail -ce 'gh pr create'",["xargs","bash","-o","pipefail","-ce","gh","pr","create"],[],true,false]
["zsh -lc \"\\\"g\\\"h pr create\"",["zsh","-lc","gh","pr","create"],[],true,false]
["zsh -lc \"echo \\\"gh pr create\\\"\"",["zsh","-lc","echo"],[],false,false]
["zsh -lc 'echo done' _ -c 'gh pr create'",["zsh","-lc","echo","done","_","-c"],[],false,false]
["zsh -lc 'gh pr create --fill'",["zsh","-lc","gh","pr","create","--fill"],[],true,false]
["{ 'gh' pr create; }",["gh","pr","create"],[],true,false]
["{ bash -c 'echo \"gh pr create\"'; }",["bash","-c","echo"],[],false,false]
["{ bash -c 'gh pr create'; }",["bash","-c","gh","pr","create"],[],true,false]
["{ gh pr create; }",["gh","pr","create"],[],true,false]
["{ printf '%s' 'gh pr create'; }",["printf","%s"],[],false,false]

@lukemaj

lukemaj commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor Author

What: Independent round-6 review FAIL on both exact heads, with one blocking parity finding.
Why: JavaScript and Python use different whitespace alphabets for quoted-token retention and word splitting, so identical commands produce different words and key hits.
So what: The implementation owner must align the twins' whitespace handling and obtain fresh exact-head review; the other shared grammar limits remain non-blocking under the planner's bar.

Blocking finding

P2: whitespace semantics differ between the twin matchers. apps/server/src/contextmd/Matcher.ts:276,281 and its WORD_BREAK at line 11; contextmd/serve/keys.py:247,251 and its WORD_BREAK at line 18.

JavaScript \s excludes U+0085 and U+001C through U+001F, which Python re includes. JavaScript includes U+FEFF, which Python excludes. The new quoted-token filter inherits those language-specific meanings, and the final raw/visible word split also uses them.

Minimal input, constructed without invisible characters in this comment:

sep = chr(0x85)
command = f"echo gh{sep}pr{sep}create"

Feed that same string through the production shell extract in each language. Chromeria returns two words: echo and one word consisting of gh, U+0085, pr, U+0085, create; it does not match command:gh pr create. ContextMD returns ["echo", "gh", "pr", "create"] and does match. Changing sep to chr(0xFEFF) reverses the key mismatch: only Chromeria matches.

An ASCII-only parser input reproduces the U+0085 key divergence through the new ANSI-C script decoding. Construct it as follows and feed the resulting string to both extractors:

sep_escape = chr(92) + "u0085"
command = f"bash -c $'echo gh{sep_escape}pr{sep_escape}create'"

Chromeria returns bash, -c, echo, and the single U+0085-containing word, with no gh-key hit. Python returns ["bash", "-c", "echo", "gh", "pr", "create"] with a hit. /bin/bash --noprofile --norc, with a PATH-local logging gh stub, only prints the string and never invokes gh.

The new retention predicate itself also diverges. For command = f"echo 'gh{sep}pr{sep}create'", U+0085 retains the quoted token in Chromeria and drops it in Python; U+FEFF does the reverse. Six code points across quoted, unquoted, printf, ANSI-C script and database-token probes give 30 word divergences, including 12 gh-key divergences and 6 raw path-shape divergences.

The unquoted splitting difference already exists on both main bases. This finding blocks specifically under the planner's (c), divergence on any input, and does not claim those inherited differences are new real-run regressions. The quoted-token retention difference is on the newly added path. Use the same explicit whitespace definition for retention and splitting in both twins, with matching fixtures. A retention-only change leaves the unquoted/key/path divergence in place.

Reachability: Chromeria Select.ts:310 extracts a shell call and passes its keys to firstMatch; Python store.Entry.matches calls Keys.has_command. The difference therefore changes whether the same stored rule is selected by the two products.

Cleared required cases

All prior supplied findings pass on both candidates: substitution boundaries and inner quotes, even/odd escaping, exact/tab-stripped/empty/multiple heredocs, quoted words after assignments/env/redirections/control syntax, outer script dequoting, Unicode markers, clustered c flags/options before c, ANSI-C scripts and NUL boundaries, and the later positional -c negatives.

The round-5 scripts after then/!/braces/do/xargs/find/timeout/ssh and their quoted-prose controls pass. Printed shell invocations match under the explicit final rule, including echo sh -c 'gh pr create'. Quoted single words count in every position, with no command-position requirement added.

All nine bake fixtures pass: bare name, tilde/absolute and quoted single-path arguments match the database key; query-bearing quoted/unquoted SQLite URIs do not. Candidate 1672's literal Python test-edit heredoc, candidate 26379's Issue-body heredoc and its quoted --body companion do not match. SQLite execution probes use a logging stub, never a database.

Known limits, non-blocking

Reconfirmed the shared limits tracked by #284: escaped/partly quoted heredoc markers and separator punctuation can expose literal bodies; a case-pattern, heredoc-body or comment ) inside a substitution can hide execution; shell -- or a script filename before -c can produce a false script match. Printed invocations and unquoted mentions/comments/escaped syntax retain the accepted approximations.

A shell-name token in positional data can also start another recognized invocation: bash -c 'echo done' bash -c 'gh pr create' prints only done, while both matchers hit. This is non-blocking under the accepted any-position shell-name approximation. The supplied positional negatives without another shell-name token remain fixed.

Native zsh/ksh are unavailable here. Their simple controls use Bash stand-ins; SSH/sudo/SQLite use harmless local stubs. No native-shell, remote-SSH, live database, browser, deployment or live-model-session proof is claimed. Both PR bodies have Known limits sections and link #284.

Independent proof

All test runs and scratch writes stayed under ~/scratch/232-review/sol-r6; candidate trees came from exact-SHA Git archives. Existing third-party dependencies were linked, and workspace package links resolve within the archives. Heavy suites ran one at a time.

  • Chromeria, from the head archive's apps/server: ./node_modules/.bin/vp test run --config review.config.ts src/contextmd/, with the temporary config restricting includes to src/contextmd/*.test.ts, node environment and serial files: 130 passed, four files.
  • Same candidate tests with only Matcher.ts replaced by main base 54fb0fc1886d7ee1ef030a6e5dae419d2b263a1f: 19 failed, 111 passed, for behavioral assertions. The exact-head matcher was restored and its Git object verified afterward.
  • ContextMD, at its final head: TMPDIR=<review root> PYTHONDONTWRITEBYTECODE=1 CONTEXTMD_CHROMERIA=<exact Chromeria archive> python3 -m unittest discover -s tests -t .: 156 passed, including all 18 isolated real-server/hook contracts, no skips. Contract servers used temporary bases and their captured process groups. The log contains incidental ResourceWarnings/BrokenPipe output; the suite exits 0.
  • Candidate python3 -m unittest tests.test_serve.SegmentsTest with only keys.py replaced by main base 42d312460cf3672ab7454ebfcb905d9db392b3e6: 21 tests, 109 failing assertions. The exact-head module was restored and its Git object verified afterward.
  • node parity.mjs, PYTHONDONTWRITEBYTECODE=1 python3 verify.py and python3 extra.py in the review root: 646 unique production comparisons, including all 559 published inputs, both current suites' collected inputs/path templates, prior reproductions, bake and independent probes. The entire published 559-input corpus agrees; the 30 added divergences above account for every observed difference. Python raw paths use production shell_paths(words(command)) before repository normalization.
  • 173 Bash controls, 25 token/printed-invocation policy fixtures and nine bake fixtures pass in both matchers. Another 51 independent Bash probes verify the divergence examples and shared limits. Every execution probe used /bin/bash --noprofile --norc with a PATH-local gh stub, never real gh.
  • gh pr checks on both exact heads: Chromeria's workflow checks pass, including Lint, Check, Typecheck, Test and Test Server 1-6. ContextMD has no workflow check-runs; independent review statuses are separate. The historical Test Server 6: continuation offers are 2 where the MCP toolkit test expects 1 #259 main failure was inspected in main run 38534351845: OrchestratorMcpToolkit.integration.test.ts:1944, expected ... to have a length of 1 but got 2. Test Server 6: continuation offers are 2 where the MCP toolkit test expects 1 #259 is now closed and current candidate Test Server 6/Check pass.
  • Full scoped server Knip, ./node_modules/.bin/knip --workspace apps/server --preprocessor ./scripts/knip-schemas.ts --no-config-hints: candidate, main-base and current main bcc4db86b85a841d21f6772c5c91129bcd1d29cc archives all exit 1 with byte-identical sole Unlisted binaries (1): cc apps/server/src/provider/acp/AcpSessionRuntime.processTree.test.ts output, confirming pre-existing Server Knip reports the OS cc compiler as an unlisted binary #270. Temporary test configs were removed before the retained Knip runs.
  • Complete diffs inspected, git diff --check passes for both. No secrets or unrelated code changes found. Headers/docstrings/README describe the refined rule; the ContextMD feature-map link is scoped to Track shared shell matcher limits and native shell proof #284. ContextMD has one 0.6.2 to 0.6.3 transition with its own CHANGELOG entry and unchanged older entries. Chromeria has no version bump.

Reviewed exact identities, checked live before review and again before publication:

Requirements and who asked: planner's round-6 brief requires exact-head twin review with the regression/required-case/parity blocking bar.
Deleted: no general-shell-parser requirement, command-position rule or implementation scope added; shared grammar limits stay non-blocking.
Bottleneck: identical whitespace semantics at token retention and splitting.
Checked myself: full diffs/tracker and review records, production consumers, exact-head suites/contracts, main-base failing-before tests, 646 comparisons, Bash controls/probes, version/diff hygiene, CI and Knip evidence.

Reviewer: independent Codex gpt-6.1-sol, medium reasoning effort, T3 Code Codex harness, context review/independent-sol.

@lukemaj

lukemaj commented Oct 14, 2026

Copy link
Copy Markdown
Contributor Author

What: FAIL on both exact heads. A redirection or here-string between -c and its script hides a command bash runs, and the twins split six whitespace code points differently.
Why: The script slot consumes the redirect target, and JavaScript \s and Python re \s are not the same set, so the same command yields different words and key hits.
So what: Fix both in the two matchers together; this review does not merge.

Blocking findings

1. A redirection or here-string between -c and the script hides a command bash runs. apps/server/src/contextmd/Matcher.ts:269-279 and contextmd/serve/keys.py:241-250.

After a shell -c option, bash removes redirections before it chooses the script argument. The matcher skips only the operator and then takes the next word as the script. The real script is never scanned.

Reproduction, in a private temp directory, with a PATH-local gh that appends its arguments to a log and never calls real gh:

/bin/bash --noprofile --norc -c "bash -c 2>/dev/null 'gh pr create'"

The stub logs pr create and bash exits 0. Both candidates return words bash, -c, 2, /dev/null and miss command:gh pr create. Main base 54fb0fc188 / 42d312460 still matches, because it splits the raw text. The same miss, with bash executing gh, holds for >, 2>&1, <, a quoted target 2>'/dev/null', a here-string <<<'x', bash -ce, sh -c, bash -o pipefail -c, and the same forms after env or FOO=1. That is 72 bash-confirmed commands, one mechanism. zsh -lc 2>/dev/null 'gh pr create' takes the same wrong script word in both matchers; native zsh is not installed here, so that one was not executed.

A redirect before the shell name still matches (2>/dev/null bash -c 'gh pr create'). The passing suites do not place a redirect between -c and the script.

2. The twins do not agree on whitespace. Matcher.ts:10 and the \s checks at Matcher.ts:276 and Matcher.ts:281; keys.py:17 and the \s checks at keys.py:247 and keys.py:251.

JavaScript \s does not treat U+0085 or U+001C through U+001F as whitespace, and it does treat U+FEFF as whitespace. Python re \s does the reverse. Feeding the production extractors:

  • "echo gh\u0085pr\u0085create": Chromeria words echo, gh\u0085pr\u0085create and no gh-key hit. ContextMD words echo, gh, pr, create and a hit.
  • "echo gh\ufeffpr\ufeffcreate": the hits swap.
  • "echo 'gh\u0085pr\u0085create'": Chromeria keeps the quoted token; ContextMD drops it.
  • "echo /tmp/gh\u0085pr": Chromeria's raw path is /tmp/gh\u0085pr; ContextMD's is /tmp/gh.

/bin/bash --noprofile --norc prints gh\u0085pr\u0085create and does not invoke the gh stub, so this is not a real-run regression. It is a twin divergence on the candidates. The unquoted split and the path split already differ on both main bases. The quoted-token check is new in this round and diverges on the same code points. U+00A0, U+2028, and U+2029 agreed in this probe.

Known limits

These are not the failure. #284 already tracks them, and both PR bodies link it:

  • Escaped or partly quoted heredoc markers, and separator punctuation in a marker, can expose a literal body.
  • A ) from a case pattern, heredoc, or comment inside a substitution can hide a command that runs.
  • bash -- -c '...' and bash missing-script -c '...' can be read as a script.
  • Printed invocations (echo bash -c 'gh pr create', echo sh -c 'gh pr create') match by the accepted rule. Bash does not run gh.
  • Unquoted arguments, comments, and escaped syntax count as words.
  • A later shell name starts another script scan: bash -c 'echo done' bash -c 'gh pr create' prints done, the gh stub is not called, and both matchers hit.
  • Native zsh and ksh are not installed here.

Proof

Reviewed trees were git archive of the exact SHAs under ~/scratch/232-review/grok-r6. No writes in the dev checkouts. Heavy suites ran one at a time. Bash probes used /bin/bash --noprofile --norc and a PATH-local gh stub.

  • Chromeria ./node_modules/.bin/vp test run src/contextmd/ from the head archive: 130 passed, 4 files.
  • The same Select.test.ts with only Matcher.ts replaced by main base 54fb0fc188: 19 failed, 22 passed (41). The head file was restored; its SHA-256 matched the archive copy.
  • ContextMD CONTEXTMD_CHROMERIA=<exact Chromeria archive> python3 -m unittest discover -s tests -t .: 156 passed in 57s, no skips, including the contract server on a temporary base. ResourceWarnings and one BrokenPipe traceback were printed; the process exited 0.
  • SegmentsTest with only keys.py replaced by main base 42d312460: 21 tests, 109 failing assertions. The head module was restored and its SHA-256 matched.
  • 375 commands (suite literals, bake and mention fixtures, the redirect grid, heredoc probes) through both production extractors: 0 differences in words, raw path shapes, and the gh / chromeria-v2.sqlite key hits. The whitespace set above is outside that ASCII corpus and is the divergence.
  • Required cases in the suites and in direct extractor calls: bare filename, tilde path, absolute path, and quoted single paths match the database key; both ?mode=ro URI forms do not; candidate 1672's heredoc and candidate 26379's heredoc and quoted --body do not; echo / printf quoted mentions do not; echo bash -c / echo sh -c match; bash -c, sh -c, zsh -lc, bash -ce, bash -o pipefail -c, and bash -c $'...' match, including after then, !, braces, do, xargs, find -exec, timeout, and ssh.
  • gh pr checks on Chromeria ed1af37: Lint, Check, Typecheck, Test, and Test Server 1-6 pass. ContextMD 3d0051a has no workflow checks. Full Knip was not re-run here.

Diffs are Matcher.ts and Select.test.ts in Chromeria, and keys.py, tests/test_serve.py, VERSION, CHANGELOG.md, README.md, and docs/map.md in ContextMD. No secrets. Headers and docstrings state the position-free rule. ContextMD is one transition, 0.6.2 to 0.6.3, with its own changelog entry. Chromeria does not bump a version. Both bodies have a Known limits section and link #284.

SHAs, checked live before the review and again before this comment:

Reviewer: independent Grok, grok-4.7, context review/independent-grok.

@lukemaj

lukemaj commented Oct 14, 2026

Copy link
Copy Markdown
Contributor Author

What: Independent round-7 review PASS on both exact heads, with no blocking findings in the planner's narrow scope.
Why: Both matchers now use the same explicit ASCII whitespace alphabet, the required round-6 behavior is preserved, and the required suites pass.
So what: The planner can use this exact-head review for #232; grammar limits remain owned by #284 and merging still requires human approval.

Scope and exact candidates

This verdict applies only to whitespace parity, no regression on the required round-6 cases, incremental diff hygiene, passing specified suites, and no new CI failure. Both live PR heads were checked before review and again before publication.

Findings

No blocking findings. I read both incremental diffs in full and both production matchers. The diffs contain only the named ASCII whitespace constants, their uses in splitting/quoted-token retention/scanning/error normalization, and equivalent six-code-point tests. Every general whitespace predicate/split derives from the common " \t\n\r\v\f" alphabet; newline and horizontal-prefix checks retain their specific grammar purpose. No unrelated change, secret, or version bump was introduced in this round. Both incremental git diff --check commands pass. Chromeria has no version bump; ContextMD retains the task's 0.6.3 version against main's 0.6.2.

The expanded corpus has 750 distinct inputs with zero twin differences, comparing production visible words, raw path shapes, gh-pr-create hits, and database-name hits. It includes all 559 published prior inputs, command fixtures/path templates collected from both current suites, and independent probes. All six disputed code points, U+0085, U+001C through U+001F and U+FEFF, were exercised through quoted/unquoted words, printf, ANSI-C shell scripts, and database-path shapes. The round-6 twins disagree on 78 of these expanded inputs; the current twins agree on all of them. All observed output changes versus round 6 contain the affected whitespace characters or their ANSI-C encodings. Other corpus inputs remain unchanged.

Required cases pass in both twins and were checked with /bin/bash --noprofile --norc and a harmless PATH-local gh stub: database bare filename, tilde/absolute/quoted path matches; quoted/unquoted file:...?mode=ro non-matches; 1672's Python test-edit heredoc and both 26379 Issue-body forms remain non-matches; quoted echo/printf mentions remain non-matches; bash/sh/zsh -c/-lc unwrapping matches. The retained oracle harness passes 173 execution controls, 25 accepted-token/printed-invocation policy fixtures, and nine database bake fixtures. Another 51 independent Bash probes cover the six code points and known limits. SQLite is also a logging stub, never a database connection. The zsh/ksh names use Bash stand-ins because native binaries are unavailable; this does not establish native shell semantics.

Suites and CI

All scratch writes and test execution stayed under ~/scratch/232-review/sol-r7. Candidate trees came from exact-SHA Git archives. Dependency links reuse installed third-party packages; workspace package links resolve into the candidate archive. Heavy suites ran sequentially. Reviewed source/test blobs were verified against their exact Git objects after testing.

  • Chromeria archive, apps/server: ./node_modules/.bin/vp test run --config review.config.ts src/contextmd/: 131 passed, four files. The temporary config selects src/contextmd/*.test.ts, node environment, and serial files; it was removed after the run.
  • ContextMD archive: TMPDIR=<review root> PYTHONDONTWRITEBYTECODE=1 CONTEXTMD_CHROMERIA=<exact Chromeria head archive> python3 -m unittest discover -s tests -t .: 157 passed, including 18 real-server/hook contract tests, no skips. Servers use temporary base directories and captured process groups; no live userdata server was started. Incidental ResourceWarnings do not change the successful exit.
  • Review-root probes: python3 collect.py, node parity.mjs, PYTHONDONTWRITEBYTECODE=1 python3 verify.py, PYTHONDONTWRITEBYTECODE=1 python3 extra.py, node compare.mjs, and PYTHONDONTWRITEBYTECODE=1 python3 compare.py. These directly exercise both production implementations and the prior reviewed implementations.
  • Fresh gh pr checks: Chromeria workflow checks pass, including Check, Lint, Typecheck, Test and Test Server 1 through 6. ContextMD has no workflow check-runs; independent review statuses are separate.
  • Test Server 6: continuation offers are 2 where the MCP toolkit test expects 1 #259 is now closed, and the candidate's corresponding checks pass. I inspected the historical failed main run 38534351845, SHA 918e78f67c4e13701e44db44fb3fdb6a1be8c30a: OrchestratorMcpToolkit.integration.test.ts:1944, expected ... to have a length of 1 but got 2. This is historical main evidence, not a claim that current main still fails.
  • Full server Knip, ./node_modules/.bin/knip --workspace apps/server --preprocessor ./scripts/knip-schemas.ts --no-config-hints, exits 1 on both the exact candidate and independently archived current main bcc4db86b85a841d21f6772c5c91129bcd1d29cc, with byte-identical sole output: Unlisted binaries (1): cc apps/server/src/provider/acp/AcpSessionRuntime.processTree.test.ts. This confirms existing Server Knip reports the OS cc compiler as an unlisted binary #270 rather than a new failure.

Known limits for #284

The deferred redirection/here-string defect is explicitly recorded in #284's round-7 comment, including bash -c 2>/dev/null 'gh pr create' and 15 related forms. It is not a blocker under the planner's ruling. Shared escaped/partly quoted heredoc markers, substitution closer handling, shell positional-data approximations, and accepted printed/unquoted mentions remain known limits rather than additional repair scope. No native zsh/ksh, remote SSH, browser, deployment, or live-model-session proof is claimed.

Requirements and who asked: The planner's round-7 brief requires only whitespace parity, required-case regression checks, clean incremental diffs, passing specified suites, and no new CI failure.
Deleted: Redirection repair, general shell-parser requirements, unrelated fixes, and another expansion of the blocking bar.
Bottleneck: Proving one whitespace alphabet across the twin production extractors while preserving the required round-6 behavior.
Checked myself: Both exact incremental diffs and source blobs, 750 twin comparisons against round 6, Bash-stub controls and bake fixtures, both suites including contracts, CI, historical main failure, current-main Knip, and #284's deferred-defect record.

Reviewer: independent Codex gpt-6.1-sol, medium reasoning effort, T3 Code Codex harness; status context review/independent-sol.

@lukemaj

lukemaj commented Oct 14, 2026

Copy link
Copy Markdown
Contributor Author

What: Round 7 passes at 4398db720f21c9e7b8444c45d471da7e153dc2f7. The matcher now uses one explicit ASCII whitespace set, and the required round-6 cases still match /bin/bash.
Why: The incremental diff only replaces language \s with that shared set. The twin at contextmd 4056f2b02dcbb47cc4fe3766e43370cd9c1c876d agrees on words, raw path shapes, and key hits.
So what: No blocking finding. The redirection between -c and its script stays on #284.

Blocking findings

None.

Known limits for #284

  • A redirection or here-string between -c and its script is recorded on #284, including bash -c 2>/dev/null 'gh pr create' and 15 more forms. This round does not fix it. Both current matchers still miss it, and they still agree with each other.
  • Native zsh and ksh are not installed. zsh -lc 'gh pr create --fill' matches in the matcher. The bash oracle ran it through a bash stand-in named zsh. Native shell behavior remains the gap already on Track shared shell matcher limits and native shell proof #284. /bin/sh on this host is bash, and that real sh -c ran the stub.
  • Error signatures still differ outside this diff. Python \d folds 360 Unicode digits (first example U+0660) that JavaScript \d leaves unchanged, and U+A7CE, U+A7D2, and U+A7D4 lowercase differently. The previous heads already did this. It does not change command words, raw paths, or key hits.

Proof

Reviewed by grok-4.7. Chromeria head 4398db720f21c9e7b8444c45d471da7e153dc2f7, previous ed1af37e72fd7dc970914dbd20dd4c9a2f933cda. ContextMD head 4056f2b02dcbb47cc4fe3766e43370cd9c1c876d, previous 3d0051a44d18f375bf901b340681a55d94bedd3f. Live heads matched these SHAs before the review and again before this comment. Archives were git archive into ~/scratch/232-review/grok-r7. Extracted blobs match the commits (Matcher.ts 674e149b13, Select.test.ts 21168521dc).

Incremental diff is apps/server/src/contextmd/Matcher.ts and Select.test.ts only. No secrets, no unrelated files, no Chromeria version bump. WHITESPACE is space, tab, LF, CR, VT, FF (Matcher.ts lines 11-15), and the word split, heredoc boundaries, shell breaks, quoted-word test, and normalizeError all use it.

Character-class hits for that set, the word break, and the shell break are identical on every BMP code point except surrogates. The whitespace hits are exactly U+0009, U+000A, U+000B, U+000C, U+000D, and U+0020. Word splits are identical for all 63488 of those code points. Sol's six code points (U+0085, U+001C through U+001F, U+FEFF) stay inside the token for unquoted, quoted, printf, ANSI-C $'...', and the database-path probe. 331 corpus commands (both test suites, the six probes, the #284 examples, and the required cases) and 40 extra VT/FF/NEL/BOM probes: 0 disagreements in words, raw paths, or key hits. Inputs that do not contain those six code points are unchanged versus the previous heads.

Required cases against /bin/bash --noprofile --norc with a PATH-local gh stub and a sqlite3 stub, HOME in a scratch temp directory, never the real gh: 19/19. Bare filename, tilde path, and absolute path hit chromeria-v2.sqlite and invoke sqlite3. Both file:...?mode=ro forms invoke sqlite3 and do not hit that bare key. Candidate 1672 and both 26379 forms do not hit. echo and printf strings that only mention gh pr create do not run gh and do not hit. bash -c, /bin/bash -c, and sh -c unwrap, hit, and run the stub.

vp test run --config review.config.ts --no-file-parallelism --maxWorkers 1 --no-cache src/contextmd/ from the archive's apps/server: 131 passed, 4 files. ContextMD python3 -m unittest discover -s tests -t . with CONTEXTMD_CHROMERIA pointing at this exact archive: 157 tests, OK, no skips. The log includes the usual BrokenPipe traceback from a closed hook socket. Suites ran one at a time. Vite cache mtimes in the dev checkout did not change.

gh pr checks on this head: CI jobs pass, including Test Server 6. #259 is closed. #270 is still open and is not a failing check on this head. The only pending status before this verdict was review/independent-grok.

lukemaj added a commit to toolboxmd/contextmd that referenced this pull request Oct 14, 2026
#52)

* fix(serve): command keys follow what bash runs, as Chromeria's matcher

Python parity with toolboxmd/chromeria#243: quoted strings and heredoc bodies
no longer match command keys; sh -c strings, unescaped substitutions in double
quotes or expanding heredocs, and quoted command words still do. A command
after an empty heredoc still matches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(serve): preserve shell substitution boundaries for command keys

* fix(serve): recognize shell options and ANSI-C scripts

* chore(release): prepare 0.6.3 for command key fixes

* fix(serve): keep quoted tokens in every command position

* docs(serve): explain quoted command tokens

* fix(serve): recognize shell scripts in every word position

* docs(map): link the shared command matcher limits

* fix(serve): use explicit ASCII whitespace in command keys

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@lukemaj
lukemaj merged commit 8f939c2 into main Oct 14, 2026
28 checks passed
@lukemaj
lukemaj deleted the fix/232-command-keys-run-not-mention branch October 14, 2026 12:01
lukemaj added a commit that referenced this pull request Oct 14, 2026
…t mentions (#243)

* fix(server): command keys match what a shell command runs, not what it mentions

Words in quoted strings and heredoc bodies no longer match command keys;
strings run by 'sh -c' (bash, zsh -lc) and $(...) or backticks inside double
quotes still do, and unquoted arguments still match a bare key. On rocky's log
this drops 39 of 45 mention matches and keeps every confirmed run.

Closes #232

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(server): command keys follow what bash runs in heredocs, quoted words and escapes

An unquoted-marker heredoc expands $(...) and backticks, so they run; a quoted
word in command position ('gh' pr create) is the command; an escaped \$( or
backtick is literal. visibleCommand is private again (Knip). From Sol's review
of #243, each checked against /bin/bash.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(server): the matcher header describes what command keys match now

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(server): preserve shell substitution boundaries for command keys

* fix(server): dequote shell words before matching command keys

* fix(server): recognize shell options and ANSI-C scripts

* fix(contextmd): keep quoted tokens in every command position

* fix(contextmd): recognize shell scripts in every word position

* fix(contextmd): use explicit ASCII whitespace in command keys

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 8f939c2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

contextmd serving: command keys fire on mentions such as echo strings and heredocs

1 participant