Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions IMPLEMENTATION_PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,19 @@ priorities.
unknown fields and always requires unparseable projections to be empty.
The PowerShell manifest now owns all 310 entries and round-trips exactly;
explicit false/null assertions remain opt-in and generator-preserved.
- [ ] Deliver paired Bash and PowerShell `$()` substitution slices for all
locked executable value positions, including ordering, ancestry,
shell-specific cwd propagation, literal/escaped boundaries, dynamic
identities, fail-closed negatives, executable corpus, and Netclaw cases.
- [x] Deliver the first Bash `$()` substitution slice for supported
simple-command arguments and redirect targets. Direct tests and corpus
entries pin multiple and nested ordering, exact ancestry/spans, isolated
cwd, decoded wrappers, literal boundaries, dynamic compatibility values,
depth limits, comment-safe delimiter scanning, and fail-closed command
identities, background lists, assignment prefixes, backticks, heredocs,
and malformed interiors.
- [ ] Extend Bash substitution discovery to iterables and expanding heredoc
bodies, then add the corresponding Netclaw approval-matrix cases.
- [ ] Deliver the PowerShell `$()` substitution slice for every locked value
and expression position, including current-scope state propagation,
literal boundaries, incomplete dynamic identities, executable corpus,
and Netclaw cases.
- [ ] Deliver Bash `for ... in` and PowerShell `foreach` as the first two
language-specific vertical slices, then extract only the shared analysis
proven by both implementations.
Expand Down
26 changes: 14 additions & 12 deletions SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,11 @@ command can consume it.
- Variable expansion. We mark dynamic tokens, never resolve them.
- Function definitions, here-docs body extraction, complex parameter
expansion (`${var//pattern/replacement}`), arithmetic expansion.
- Command-substitution evaluation. `$(cmd)` and backtick `` `cmd` `` are
recognized at the lex level and collapsed into a single
`Kind=DynamicSkip, IsPath=false` arg per locked interpretation #2 (see
`openspec/changes/archive/.../v0.1-locked-interpretations`). The
surrounding clause stays parseable so hard-deny rules still fire on
visible parts.
- Command-substitution evaluation. The library never executes a substitution
or claims its produced value is known. Stable v0.3 recursively discovers
commands inside supported Bash `$()` positions while retaining the authored
`Kind=DynamicSkip, IsPath=false` compatibility value. Legacy backticks and
incomplete executable interiors fail closed.
- Performance tuning beyond "fast enough to invoke per shell call without
noticeable latency" (~1ms per typical input).

Expand Down Expand Up @@ -966,7 +965,9 @@ quoted_string := single-quoted | double-quoted
immediately following a compound operator all collapse: they never
yield an empty clause. The newline after a heredoc terminator likewise
separates the heredoc's clause from what follows.
- `\` followed by a newline is a line continuation (treat as whitespace).
- `\` followed by a newline is removed before word-boundary analysis. It joins
adjacent fragments (`r\` + newline + `m` is the command name `rm`); actual
surrounding spaces still separate words.
- Bash line comments (`#` at a word boundary through end-of-line) are
whitespace-equivalent at the lexer level — they emit a Comment token
for source fidelity but are filtered alongside Whitespace by the
Expand All @@ -982,10 +983,10 @@ quoted_string := single-quoted | double-quoted
NOT path-resolved. The parser carries the raw token (e.g. `&1`) on
`Redirect.Target` and sets `Redirect.IsDynamicSkip = true`. This
prevents `2>&1` from being incorrectly resolved to `<cwd>/&1`.
- Function definitions, `case`/`esac`, C-style or implicit loops, arithmetic
execution, process substitution, and single-`&` background lists remain
unparseable in stable v0.3 because they can hide executable regions outside
the bounded grammar below.
- Function definitions, assignment-prefix commands, `case`/`esac`, C-style or
implicit loops, arithmetic execution, process substitution, and single-`&`
background lists remain unparseable in stable v0.3 because they can hide
executable regions outside the bounded grammar below.

### v0.3 structured Bash grammar

Expand Down Expand Up @@ -1072,7 +1073,8 @@ The lexer produces tokens consumed by the parser. Token kinds:
is flagged as a **statement separator**; the parser retains those
tokens past `FilterSignificant` and splits clauses on them per §4. A
pure space/tab run carries no flag and is discarded after splitting.
- **CONTINUATION** — `\` + `\n`. Treated as whitespace.
- **CONTINUATION** — `\` + `\n` (or `\r\n`). Removed before word-boundary
analysis; adjacent lexical fragments remain one authored word.
- **OPAQUE_SUBSTITUTION** — `$(cmd)` or backtick `` `cmd` ``. The full
substitution slice (including delimiters) becomes a single token.
Boundary tracking handles nested same-kind regions, nested quotes,
Expand Down
3 changes: 3 additions & 0 deletions openspec/changes/v0-3-structured-shell-analysis/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@
- [x] 3.8 Add tests proving existing parser inputs retain their v0.2 leaf and compatibility results, except for explicitly promoted v0.3 fail-closed cases.
- [x] 3.9 Add corpus expectations for syntax shape, occurrences, roles, and completeness for existing constructs.
- [ ] 3.10 Implement Bash `$()` discovery in supported argument words, redirect values, iterables, and expanding heredoc bodies; retain literal/escaped spellings and fail closed on command-name substitutions, legacy backticks, or incomplete interiors.
- [x] 3.10a Implement the simple-command argument and redirect-target slice, including comment-safe boundaries and fail-closed unsupported interiors.
- [ ] 3.11 Implement PowerShell `$()` discovery in supported words, redirect values, foreach expressions, call-operator dynamic identities, standalone expression statements, double-quoted strings, and expandable here-strings; never invent invocation from standalone output, retain literal/escaped spellings, and fail closed on trailing command-style arguments, call-operator script blocks, or unsupported execution-bearing `@()` / `@{}` forms.
- [ ] 3.12 Pin substitution parentage, authored sibling indices, innermost-first ordering, Bash-isolated versus PowerShell-current-scope state, unknown-state propagation, nesting/depth limits, and incomplete dynamic identities in direct tests.
- [x] 3.12a Pin the Bash argument/redirect slice, isolated cwd behavior, wrapper provenance, and the shared structural-depth budget.
- [ ] 3.13 Promote ordinary, multiple, nested, iterator, redirect, quoted, escaped, stateful, malformed, and hidden-execution substitution cases into both executable corpora and the Netclaw approval matrix.
- [x] 3.13a Promote the Bash ordinary, multiple, nested, redirect, quoted, escaped, stateful, malformed, and hidden-execution cases into its executable corpus.

## 4. Explicit Redirect Semantics

Expand Down
Loading