Repository navigation
feat(core): make the portable shell scanner authoritative - #44016
Conversation
f30a44e to
bf8bedf
Compare
bf8bedf to
1a2b768
Compare
Nice work overall — the BASH_ENV/ — automated review (ox-alpha, round2) |
b969d77 to
c8efc57
Compare
Bound recursive scan work and prefix lookup, simplify directory bookkeeping and approval tests, and drop the unrelated OpenAPI snapshot refresh.
Why
The experimental Tree-sitter replacement needs to handle normal shell scripts without adding incidental permission prompts. Falling back to Tree-sitter hides missing syntax, while rejecting ordinary heredocs and loops makes the experiment impractical to use.
This keeps the experimental flag as a genuine native-only switch and fills in ordinary shell syntax, while testing permission decisions rather than just comparing parser objects.
What Changes
printf hello | cat > markercatapprovals and denials, as well as broadcat *approvals. Standalone redirect resources are not blanket-stripped.export VERSION=$(git describe --tags); npm run build& 'Write-Output' helloWith
experimental.portable_shell_scanner: true, only the portable scanner runs. There is no Tree-sitter retry or shadow comparison. With the flag disabled, the existing Tree-sitter implementation, prefix table, and shared helpers are unchanged.Both scanners retain lexical provenance for resource boundaries and saved prefixes. The native Bash scanner walks control structures and queued heredocs without interpreting shell values; the PowerShell scanner handles its expression and argument contexts. Existing input/work/depth bounds remain in place.
Scope
This is an opt-in parser replacement, not a permission-policy redesign. The permission service and production shell tool are unchanged. Tree-sitter is used as a test oracle, not a dependency of the enabled analysis path.
The native parser does not deliberately reproduce erroneous command nodes from literal heredoc bodies or arithmetic values. It also recognizes some commands legacy parsing missed, including tab-separated PowerShell commands; those can require approval, and their saved patterns now cover repeat execution. Numeric arguments and some legacy error-recovery cases retain explicitly tested differences. This is not a claim of complete shell-language or Tree-sitter parity.
Verification
The final Core suite passed 3,629 tests, with 19 skipped and zero failures. Core build, formatting, and diff checks passed, as did all repository typechecks through the normal pre-push hook. The skips include three explicitly marked Bash-only syntax cases in the Zsh runtime matrix; native scanning of those fixtures is still tested.
Coverage includes native-only generated oracle comparisons, real Bash/Zsh and PowerShell execution, real permission-service and shell-tool tests for existing approvals/denials and once/always/reject responses, and malformed-input tests proving native failures do not fall back or partially execute the script.
The simplify pass removed obsolete nesting metadata and parser arguments, reused one heredoc delimiter reader, and removed avoidable argument copies and escape-table allocations. It also caught and fixed grouped here-string and quoted-delimiter bugs. A final cleanup review found no further issues. The legacy parser, arity table, shared helpers, permission service, and production shell tool were verified unchanged.