The investigation you asked for on 2026-11-01: how far a new module ShellSubsetLarge.pm can go beyond ShellSubset.pm without its code growing unreasonably. Findings, measurements and the size estimate are in claude/large-subset-investigation.md; this page holds the decisions. Update, same day: you asked me to start (R2) and renamed the module (R3). The parser is written and tested; its rules are in claude/large-subset-spec.md. Where an item offers alternatives and you had not chosen, I took the one this page recommends: A3 alternative A, A4 alternative A, F6 alternative A (reject set -x). The posix_spawn executor written in another session (claude/pspawn-ShellSpawn.pm) runs the parse trees of ShellSubsetLarge too since the evening of 2026-11-01; differential tests against dash found 8 executor bugs, of which L1–L5 are fixed and L6–L8 open (claude/large-subset-upstream-reports.md). Measured on 2026-11-02: the share of corpus samples the parser accepts, a script counting only when accepted as a whole; ShellSubset with all options → ShellSubsetLarge, with the POSIX ceiling (defined below) in brackets: tldr one-liners 97.7% → 98.3% (98.8%); NL2Bash one-liners 89.5% → 92.1% (93.6%); pure-sh-bible 48% → 93% (93%); ShellCheck snippets, clean / warned, 42% / 46% → 58% / 57% (69% / 71%).
Short version. For system strings (one-liners) little is left to gain: 95.6% of all corpus one-liners are accepted today, at most 97.4% with all the F items. The rest is mostly bash-only syntax, or builtins that make no sense in sh -c (alias, history). For scripts the F items raise acceptance a lot: pure-sh-bible 48% → up to 93%, ShellCheck snippets 42–46% → up to about 70%. This needs a change of design (A1): the module becomes an interpreter that decides some things at run time. Estimated size: about 1,150–1,250 lines for its parser and executor (up to 1,300 at the top of the parser's budget), against about 700 for the present parser plus an executor for it (an estimate made before the posix_spawn executor existed), see S1.
Words used throughout. The corpora: the public collections of shell commands the parser was measured on (tldr pages, NL2Bash, ShellCheck's test snippets, the bash Cookbook examples, pure-sh-bible, pure-bash-bible). Both shells: dash 0.5.12 and bash --posix 5.2.21, as installed on this machine; every “both shells” example below was run in them. Rejected: the parser refuses the string, which then runs with /bin/sh -c, as Perl does today. The POSIX ceiling: the samples whose syntax both shells accept and in which a scan finds no bash-only construct; an upper bound for what this page can reach.
IDs. Item IDs on this page are R, A, F, X, T, S and U followed by a number. Rule names such as V3, B3, E1, D1 are rules of claude/shell-subset-spec.md, not items here.
A bug turned up in both existing parsers, ShellSubset.pm and ShellSubsetSmall.pm: U1.