Repository navigation
Add model-based fuzzing for the Copilot SDK shell parser - #70528
Conversation
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
✅ Ponytail Reviewer completed successfully! Ponytail ReviewerOutcome: The agent completed and reported no action. A no-op output alone does not verify that all required work was completed or that publication was possible. Agent messages are omitted from this comment. The category uses structured run status, not interpretation of agent prose.
|
|
🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅
|
|
✅ PR Code Quality Reviewer completed the code quality review.
|
|
✅ Design Decision Gate 🏗️ completed the design decision gate check. See the comment below for the result and any generated ADR draft. Design Decision Gate 🏗️Outcome: The agent completed and reported no action. A no-op output alone does not verify that all required work was completed or that publication was possible. Agent messages are omitted from this comment. The category uses structured run status, not interpretation of agent prose.
|
|
✅ Test Quality Sentinel completed test quality analysis. Test Quality SentinelOutcome: The agent completed and reported no action. A no-op output alone does not verify that all required work was completed or that publication was possible. Agent messages are omitted from this comment. The category uses structured run status, not interpretation of agent prose.
|
Comment MemoryPeek at saved memory (pr-code-quality-reviewer)Note This comment is managed by comment memory.Expand the saved memory block to view or edit the persistent context for this thread.
|
There was a problem hiding this comment.
Verdict
One performance issue needs attention before relying on this fuzz target: every fuzz case launches a new Node process, so the configured 30-second run will spend most of its time on startup and achieve very low parser coverage.
Details
pkg/workflow/bash_command_parser_fuzz_test.go:57creates a freshexec.CommandContextfor every input.- Reuse a persistent Node worker or move the model in-process, with per-request timeouts.
🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt50 · 3.02 AIC · ⌖ 0.545 AIC · ⊞ 1.6K
Comment /review to run again
| } | ||
| ctx, cancel := context.WithTimeout(t.Context(), 5*time.Second) | ||
| defer cancel() | ||
| cmd := exec.CommandContext(ctx, node, harness) |
There was a problem hiding this comment.
This fuzz target starts a fresh Node process for every generated input, so the 30-second fuzz job spends most of its budget on process startup/module loading rather than exploring parser behavior and can provide almost no meaningful coverage.
💡 Why this matters
Each iteration invokes exec.CommandContext, starts Node, loads the harness and all required modules, and pays the fixed setup cost before one request is handled; the five-second timeout also makes a slow startup indistinguishable from a failing case. Reuse a persistent Node worker (or run the model in-process) and apply a per-request timeout so fuzzing can actually execute a useful number of cases.
There was a problem hiding this comment.
Skills-Based Review 🧠
Applied /tdd (test-only PR: model-based fuzzing infrastructure). No actionable issues found — approving.
📋 Verification performed
- Ran
FuzzBashCommandParserModellive (go test -fuzz=... -fuzztime=10s): passes, finds new coverage, no crashes. - Fuzzed the JS generator directly across 5000+ deterministic LCG seeds via
checkShellProgramModel: all pass, including the line-continuation blank (backslash+newline) and zero-command edge cases. - Confirmed
extractCommandName/splitOnPipelineOperators/permission-handler code paths referenced by the model (fail-closed quoting, env-assignment skipping, shell keyword handling) match the model's independent oracle. - Confirmed the Go test's
CombinedOutput()+ JSON-stdout pattern is consistent with sibling fuzz tests inpkg/workflow/.
Positive highlights
- ✅ Byte-driven (not hashed) choice consumption — enables real Go corpus shrinking.
- ✅ Independent oracle: expected segments/names are computed by the generator itself, not by re-parsing the module under test, so bugs in
bash_command_parser.cjscan't silently pass. - ✅ Explicit negative-space coverage: unsupported suffixes must invalidate the whole parse (not just a trailing segment) — a good regression guard against partial-trust bugs.
- ✅ Bounded, reproducible generator (≤8 commands, <5000 chars) keeps fuzzing fast and shrinkable.
- ✅ Proper CI/Makefile/
.github/workflows/cgo.ymlwiring so the new fuzz target actually runs in the matrix.
Minor, non-blocking observation
Makefile's new line uses-run='^$$'while the two existing fuzz lines above it (FuzzParseFrontmatter,FuzzExpressionParser) don't. Harmless either way (fuzz seed corpus still runs as subtests without it) and a pre-existing inconsistency, not a risk introduced here — no change requested.
🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet50 · 91.9 AIC · ⌖ 14.8 AIC · ⊞ 10.2K
Comment /matt to run again
There was a problem hiding this comment.
🟢 Approval recommended
The test-only additions have no identified blocking issues; the remaining maintenance suggestion is optional.
No open issues 🎉
What changed in this PR
Adds model-based fuzzing for the Copilot SDK shell parser and permission handler through the existing Node harness.
Changes:
- Generates bounded, deterministic programs with independent extraction and permission expectations.
- Adds malformed-input checks and deterministic regressions without executing generated shell programs.
- Registers the Go fuzz target in local and CI workflows.
| File | Description |
|---|---|
pkg/workflow/bash_command_parser_fuzz_test.go |
Adds the native Go fuzz target. |
Makefile |
Includes the target in make fuzz. |
actions/setup/js/fuzz_bash_command_parser_harness.cjs |
Adds model-checking harness mode. |
actions/setup/js/fuzz_bash_command_model.test.cjs |
Adds deterministic generator regressions. |
actions/setup/js/fuzz_bash_command_model.cjs |
Implements generation and oracle assertions. |
.github/workflows/cgo.yml |
Registers the target in the CI fuzz matrix. |
Review effort: Max
|
@copilot address the following outstanding work in one pass:
Push the necessary fixes, reply to each listed review thread and resolve it when addressed. Ignore feedback already answered or resolved. Use the pr-finisher skill and stop when only human review or CI remains; do not trigger CI. Sous-chef head: ebe5228
|
Extend shell-parser coverage with generated programs and independent extraction and permission oracles.
make fuzzand the CI fuzz matrix.