Skip to content

fix: compiler detects and sanitizes single-quoted bash tool commands that crash Copilot CLI#30040

Merged
pelikhan merged 4 commits intomainfrom
copilot/fix-daily-model-inventory-checker
May 4, 2026
Merged

fix: compiler detects and sanitizes single-quoted bash tool commands that crash Copilot CLI#30040
pelikhan merged 4 commits intomainfrom
copilot/fix-daily-model-inventory-checker

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 4, 2026

Copilot CLI 1.0.40 exits immediately (code 1, no output) when passed --allow-tool arguments containing single-quoted jq filter expressions. The workflow broke when 8 specific jq tools were added with filters like:

bash:
  - "jq '.data[] | {id, billing}' /tmp/gh-aw/model-inventory/artifacts/copilot-models/raw.json"
  - "jq '[.data[] | keys] | add | unique' /tmp/gh-aw/model-inventory/artifacts/copilot-models/raw.json"
  # ...6 more

These compile to --allow-tool 'shell(jq '\''.data[] | {id, billing}'\'' /path)' — the embedded single-quote escaping trips the CLI parser and causes a silent startup crash.

Changes

  • pkg/workflow/copilot_engine_tools.go: Added sanitizeCopilotShellCommand() that detects single quotes in bash tool commands using strings.Cut, truncates to a safe prefix (e.g. jq '.filter' /pathjq), emits a compiler warning pointing users to the simpler form, and deduplicates identical sanitized values so multiple filter tools produce exactly one --allow-tool entry. Copilot CLI uses prefix matching for shell() so shell(jq) still allows all jq invocations.
  • pkg/workflow/copilot_engine_test.go: Added TestSanitizeCopilotShellCommand unit tests and new cases in TestCopilotEngineComputeToolArguments covering truncation, deduplication, and passthrough.
  • daily-model-inventory.md: Restored to its original form with specific jq filter tools — the compiler now handles them safely at compile time.
  • daily-model-inventory.lock.yml: Recompiled — now emits a single deduplicated --allow-tool shell(jq) with no embedded single quotes.

[!WARNING]

Copilot AI linked an issue May 4, 2026 that may be closed by this pull request
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 4, 2026

Hey @copilot 👋 — thanks for picking up the Daily Model Inventory Checker failure! Debugging engine crashes is exactly the kind of infrastructure health work this project needs.

A few things to address before this is ready for review:

  • No changes yet — the PR currently has 0 files changed and 0 lines of diff. The fix hasn't been implemented yet. The WIP label in the title confirms this is still in-progress.
  • Add tests — once the fix lands, make sure the relevant test files are updated or new tests are added to cover the corrected behaviour.
  • Remove [WIP] from the title and update the PR description with a clear summary of what was changed and why once the implementation is complete.

If you'd like a hand finishing up, you can use this prompt with your coding agent:

Debug the Daily Model Inventory Checker engine failure from https://github.com/github/gh-aw/actions/runs/25291737132

The copilot engine exits with code 1 immediately (1s duration, no stdout/stderr), which typically indicates a binary-not-found, permission, or silent startup crash.

Investigate:
1. Load .github/agents/agentic-workflows.agent.md for context.
2. Identify what changed between the last successful run and this failing run.
3. Determine the root cause of the exit-code-1 crash (missing binary, bad flag, auth failure, etc.).
4. Implement the fix in the relevant workflow or configuration file.
5. Add or update tests to cover the fix.
6. Run `make agent-finish` to validate all checks pass before marking the PR ready.

Generated by Contribution Check · ● 1.1M ·

Copilot AI and others added 2 commits May 4, 2026 01:37
…orkflow (#30065)

The Copilot CLI 1.0.40 crashes immediately (exit code 1, no output) when
passed --allow-tool arguments containing single-quoted jq filter expressions
like shell(jq '.data[] | {id, billing}' /path).

Comparing the successful run (25289424690) vs failing runs (25291737132+),
the failing runs had 8 new jq tools with single-quoted filter expressions:
  - jq '.data[] | {id, billing}' ...
  - jq '[.data[] | keys] | add | unique' ...
  etc.

Fix: Replace all 8 specific jq bash tools with a single 'jq' entry, which
allows the Copilot agent to run any jq command without single-quote quoting
issues.

Recompile lock file with --allow-tool shell(jq) instead of per-filter entries.

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/8019f8cc-b685-4b57-a559-453d8ffd34c6

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix daily model inventory checker engine failure fix: replace single-quoted jq filter tools in daily-model-inventory to prevent Copilot CLI crash May 4, 2026
Copilot AI requested a review from pelikhan May 4, 2026 01:47
@pelikhan
Copy link
Copy Markdown
Collaborator

pelikhan commented May 4, 2026

@copilot the compiler should detect and properly handle single quotes

…that crash Copilot CLI

Add sanitizeCopilotShellCommand() in copilot_engine_tools.go that:
- Detects single quotes in bash tool commands using strings.Cut
- Truncates the command to a safe prefix (e.g. jq '.filter' → jq)
- Emits a compiler warning pointing users to the simpler form
- Deduplicates sanitized allow-tool values after sort

Copilot CLI 1.0.40 crashes at startup (exit 1, no output) when
--allow-tool arguments contain single-quoted filter expressions due
to multi-level shell escaping conflicts in the AWF entrypoint.

Restore daily-model-inventory.md to its original form with specific
jq filter tools - the compiler now handles them safely at compile time.

Also deduplicates sorted --allow-tool values to avoid 7 identical
shell(jq) entries when multiple filter tools truncate to the same prefix.

Tests added:
- TestSanitizeCopilotShellCommand: unit tests for the new helper
- New cases in TestCopilotEngineComputeToolArguments: truncation,
  deduplication, and passthrough of commands without single quotes

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/fd996d8a-30e1-43fe-bb00-346c34d9668d

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 4, 2026

@copilot the compiler should detect and properly handle single quotes

Done in 94d6702. Added sanitizeCopilotShellCommand() to copilot_engine_tools.go that:

  1. Detects single quotes in bash tool commands using strings.Cut
  2. Handles them by truncating to the safe prefix before the first ' (e.g. jq '.data[] | {id, billing}' /pathjq) — Copilot CLI uses prefix matching for shell() so shell(jq) still allows all jq invocations
  3. Emits a compiler warning naming the original command, the truncated prefix, and how to silence the warning
  4. Deduplicates the sorted allow-tool values so multiple filtered jq tools produce exactly one shell(jq) in the compiled output

The daily-model-inventory.md is restored to its original form with specific jq filter tools — the compiler now handles them safely at compile time rather than needing the workaround.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh gh repo view --json owner,name --jq .owner.login &#43; &#34;/&#34; &#43; .name /home/REDACTED/.local/bin/bash (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw -d 168.63.129.16 bash t-ha�� vaScript29760460INVALID,NEW conntrack 1/x64/bin/node INVALID,NEW -j DROP bash (http block)
  • https://api.github.com/orgs/test-owner/actions/secrets
    • Triggering command: /usr/bin/gh gh api /orgs/test-owner/actions/secrets --jq .secrets[].name h ../../../.prettierignore (http block)
  • https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq [.object.sha, .object.type] | @tsv /ref/tags/v9 sh sv &#34;prettier&#34; --wrigit (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq [.object.sha, .object.type] | @tsv (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv ithub-script/git/ref/tags/v9 infocmp bject.type] | @tsv xterm-color (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv --show-toplevel git /usr/bin/git /tmp/gh-aw-test-git rev-parse /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv -v -run 1/x64/bin/node ./../.prettieriggit (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv ithub-script/git/ref/tags/v9 infocmp bject.type] | @tsv xterm-color -tests ache/node/24.14.--show-toplevel git rev-�� ithub-script/git/ref/tags/v9 ache/node/24.14.1/x64/bin/node bject.type] | @tsv &#39;value&#39; || secregit (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv --show-toplevel git /usr/bin/infocmp --show-toplevel bash /usr/bin/git infocmp -1 xterm-color git /usr/bin/git --show-toplevel bash /usr/bin/git git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv /tmp/go-build3248549413/b392/_pkg_.a -trimpath /usr/bin/infocmp -p main -lang=go1.25 infocmp estl�� xterm-color -goversion /usr/bin/git -c=4 -nolocalimports -importcfg git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv /repos/test-owner/test-repo/actions/secrets l /usr/bin/git with-tools.md (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv /ref/tags/v9 remote.origin.url sv (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v8
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq [.object.sha, .object.type] | @tsv /ref/tags/v9 git sv /ref/tags/v9 remote.origin.urrev-parse sv git rev-�� --show-toplevel git /usr/bin/gh (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v9
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv validation\|validateBash\|ValidateBash\|validateTool ot_engine_tools.go e_validation.go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv go1.25.8 -c=4 -nolocalimports -importcfg /tmp/go-build3248549413/b070/importcfg -pack /tmp/go-build3248549413/b070/_testmain.go /pre�� (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v9.0.0
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9.0.0 --jq [.object.sha, .object.type] | @tsv (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9.0.0 --jq [.object.sha, .object.type] | @tsv -c=4 -nolocalimports -importcfg /tmp/go-build3248549413/b125/importcfg -pack /home/REDACTED/work/gh-aw/gh-aw/cmd/gh-aw/main.go /home/REDACTED/work/gh-aw/gh-aw/cmd/gh-aw/capitalization_test.go /pre�� (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9.0.0 --jq [.object.sha, .object.type] | @tsv js/**/*.json&#39; ---errorsas (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv /repos/actions/github-script/git/ref/tags/v9 --jq /usr/bin/git OnlyCompiledOutpinfocmp on 1/x64/bin/node git rev-�� --show-toplevel sh /usr/bin/git ithub/workflows/git (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv user.name Test User /usr/bin/git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv xterm-color /tmp/go-build161414718/b001/workremote1 /usr/bin/gh OnlyCompiledOutpgh on rkflow/js/**/*.j/repos/actions/github-script/git/ref/tags/v9 gh api /repos/actions/github-script/git/ref/tags/v9 --jq /usr/bin/git npx prettier --wgit (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv ithub-script/git/ref/tags/v9 /usr/bin/git bject.type] | @tsv v1.0.0 (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv /tmp/go-build3248549413/b070/_pkg_.a -trimpath /usr/bin/gh -p main -lang=go1.25 gh api /repos/actions/github-script/git/ref/tags/v9 --jq /usr/bin/git go1.25.8 -c=4 -nolocalimports git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv xterm-color (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv /home/REDACTED/work/gh-aw/gh-aw/.github/workflows/agent-performance-analyzer.md (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv list --json /opt/hostedtoolcache/node/24.14.1/x64/bin/node --workflow nonexistent-workrev-parse --limit /opt/hostedtoolcache/node/24.14.1/x64/bin/node /tmp�� github.event.inputs.enforce_all == &#39;true&#39; &amp;&amp; &#39;full-sweep (enforce_all)&#39; || &#39;round-robin&#39; git (http block)
  • https://api.github.com/repos/aws-actions/configure-aws-credentials/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/aws-actions/configure-aws-credentials/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv --show-toplevel ache/node/24.14.1/x64/bin/node /usr/bin/git uts.enforce_all git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/aws-actions/configure-aws-credentials/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv --show-toplevel git /usr/bin/git ons-test22788825git (http block)
  • https://api.github.com/repos/azure/login/git/ref/tags/v2
    • Triggering command: /usr/bin/gh gh api /repos/azure/login/git/ref/tags/v2 --jq [.object.sha, .object.type] | @tsv --show-toplevel git /usr/bin/git --show-toplevel jFisbkl/NnnTXH9Vrev-parse /usr/bin/git git rev-�� --show-toplevel git /usr/bin/gh (http block)
  • https://api.github.com/repos/docker/login-action/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/docker/login-action/git/ref/tags/v3 --jq [.object.sha, .object.type] | @tsv ithub-script/git/ref/tags/v9 ache/node/24.14.1/x64/bin/node bject.type] | @tsv &#39;value&#39; || secregit (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v0.1.2
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq [.object.sha, .object.type] | @tsv /repos/actions/github-script/git/ref/tags/v9 --jq /usr/bin/git te &#39;../../../**/gh (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq [.object.sha, .object.type] | @tsv steps.test.outputs.result (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq [.object.sha, .object.type] | @tsv /v1.0.0 --jq sv func.*validateTogit g/workflow/toolsrev-parse g/workflow/compi--show-toplevel /opt/hostedtoolcache/node/24.14.1/x64/bin/node /tmp�� Actor: ${{ github.actor }}, Repo: ${{ github.repository }} git e/git-remote-https Gitcustom_branchgit Gitcustom_branchrev-parse cal/bin/bash e/git-remote-https (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --limit 100 --created &gt;=2026-04-27 (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --limit 100 --created &gt;=2026-04-04 (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --limit 100 --created &gt;=2026-02-03 (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/1/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/1/artifacts --jq .artifacts[].name (http block)
    • Triggering command: /usr/bin/gh gh run download 1 --dir test-logs/run-1 (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12345/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12345/artifacts --jq .artifacts[].name copilot/fix-daily-model-inventory-checker 64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh run download 12345 --dir test-logs/run-12345 (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/1234567890
    • Triggering command: /usr/bin/gh gh api repos/{owner}/{repo}/actions/runs/1234567890 --jq {databaseId: .id, number: .run_number, url: .html_url, status: .status, conclusion: .conclusion, workflowName: .name, workflowPath: .path, createdAt: .created_at, startedAt: .run_started_at, updatedAt: .updated_at, event: .event, headBranch: .head_branch, 90846458/001&#39; 90846458/001&#39; eloper-action-main/dist/gh-gpgsign/gh-gpgsign-linux-x86_64 (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12346/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12346/artifacts --jq .artifacts[].name copilot/fix-daily-model-inventory-checker 64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh run download 12346 --dir test-logs/run-12346 (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/2/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/2/artifacts --jq .artifacts[].name (http block)
    • Triggering command: /usr/bin/gh gh run download 2 --dir test-logs/run-2 (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/3/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/3/artifacts --jq .artifacts[].name (http block)
    • Triggering command: /usr/bin/gh gh run download 3 --dir test-logs/run-3 (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/4/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/4/artifacts --jq .artifacts[].name (http block)
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/5/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/5/artifacts --jq .artifacts[].name (http block)
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 (http block)
  • https://api.github.com/repos/github/gh-aw/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path h ../../../.prettierignore (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 100 (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 6 (http block)
  • https://api.github.com/repos/github/gh-aw/contents/.github/workflows/shared/reporting.md
    • Triggering command: /tmp/go-build3248549413/b404/cli.test /tmp/go-build3248549413/b404/cli.test -test.testlogfile=/tmp/go-build3248549413/b404/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v0.47.4
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v0.47.4 --jq [.object.sha, .object.type] | @tsv --show-toplevel git /usr/bin/git /tmp/TestGuardPobasename remote /usr/bin/infocmp git rev-�� --show-toplevel infocmp /usr/bin/gh xterm-color x_amd64/vet /usr/bin/git gh (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq [.object.sha, .object.type] | @tsv validateBashTool\|validateBash\|func.*validateTo--exclude-hidden=receive /home/REDACTED/work/gh-aw/gh-aw/pkg/workflow/tools--all /home/REDACTED/.dotnet/tools/bash (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.2.3 --jq [.object.sha, .object.type] | @tsv (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v2.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq [.object.sha, .object.type] | @tsv func.*validateTo--exclude-hidden=receive g/workflow/tools--all g/workflow/compi--quiet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq [.object.sha, .object.type] | @tsv ant-2684886929/.github/workflows (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq [.object.sha, .object.type] | @tsv nt &gt;/dev/null 2&gt;&amp;1 (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v3.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq [.object.sha, .object.type] | @tsv (http block)
  • https://api.github.com/repos/google-github-actions/auth/git/ref/tags/v2
    • Triggering command: /usr/bin/gh gh api /repos/google-github-actions/auth/git/ref/tags/v2 --jq [.object.sha, .object.type] | @tsv --show-toplevel ache/node/24.14.1/x64/bin/node /usr/bin/git secrets.TOKEN (http block)
  • https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq [.object.sha, .object.type] | @tsv --noprofile (http block)
  • https://api.github.com/repos/nonexistent/repo/actions/runs/12345
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion (http block)
  • https://api.github.com/repos/owner/repo/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo a19fc335185c8f5aeee512be8f5044b5-d hub.com/.extrahenode (http block)
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo eloper-action-main/dist/gh-gpgsign/gh-gpgsign-linux-x86_64 hub.com/.extrahenode (http block)
    • Triggering command: /usr/bin/gh gh workflow list --repo owner/repo --json name,path,state e_modules/.bin/sh nore (http block)
  • https://api.github.com/repos/test-owner/test-repo/actions/secrets
    • Triggering command: /usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name with-tools.md (http block)
  • https://api.github.com/repos/test/repo
    • Triggering command: /usr/bin/gh gh api /repos/test/repo --jq .default_branch rite &#39;**/*.cjs&#39; &#39;**/*.ts&#39; &#39;**/*.json&#39; --ignore-p--detach (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title fix: replace single-quoted jq filter tools in daily-model-inventory to prevent Copilot CLI crash fix: compiler detects and sanitizes single-quoted bash tool commands that crash Copilot CLI May 4, 2026
@pelikhan pelikhan marked this pull request as ready for review May 4, 2026 02:14
Copilot AI review requested due to automatic review settings May 4, 2026 02:14
@pelikhan pelikhan merged commit d8c623a into main May 4, 2026
30 of 31 checks passed
@pelikhan pelikhan deleted the copilot/fix-daily-model-inventory-checker branch May 4, 2026 02:15
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a Copilot CLI startup crash when --allow-tool shell(...) arguments include embedded single quotes (e.g., jq filters), by sanitizing bash tool commands into safe prefix-matching forms and deduplicating resulting allow-tool entries.

Changes:

  • Add single-quote detection/sanitization for bash tool commands when generating Copilot CLI --allow-tool shell(...) args, plus value deduplication after sorting.
  • Add unit tests covering sanitization behavior and deduplication in computed tool arguments.
  • Recompile workflow lock files (notably daily-model-inventory.lock.yml) to remove single-quoted jq filters and emit a single --allow-tool shell(jq) entry.
Show a summary per file
File Description
pkg/workflow/copilot_engine_tools.go Adds sanitizeCopilotShellCommand() and deduplicates sorted --allow-tool values to avoid single-quote crashes and repeated entries.
pkg/workflow/copilot_engine_test.go Adds focused tests for sanitization and new cases validating truncation + deduplication in computed tool args.
.github/workflows/smoke-codex.lock.yml Lockfile update; also changes Codex invocation plumbing (now via codex_harness.cjs and --prompt-file).
.github/workflows/smoke-call-workflow.lock.yml Lockfile update reflecting regenerated runner command/harness usage.
.github/workflows/daily-observability-report.lock.yml Lockfile update reflecting regenerated runner command/harness usage.
.github/workflows/daily-model-inventory.lock.yml Removes single-quoted jq allow-tool entries and replaces with a deduplicated shell(jq) allow-tool entry.
.github/workflows/daily-fact.lock.yml Lockfile update reflecting regenerated runner command/harness usage.
.github/workflows/daily-cache-strategy-analyzer.lock.yml Lockfile update reflecting regenerated runner command/harness usage.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 8/8 changed files
  • Comments generated: 2

Comment on lines +99 to +103
sanitized, wasSanitized := sanitizeCopilotShellCommand(cmdStr)
if wasSanitized {
fmt.Fprintln(os.Stderr, console.FormatWarningMessage(
fmt.Sprintf("bash tool %q contains single quotes that crash Copilot CLI; "+
"truncated to safe prefix %q for shell() prefix-matching. "+
# shellcheck disable=SC1003
sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env CODEX_API_KEY --exclude-env GH_AW_GH_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --exclude-env OPENAI_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
-- /bin/bash -c 'export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 4 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && INSTRUCTION="$(cat /tmp/gh-aw/aw-prompts/prompt.txt)" && codex ${GH_AW_MODEL_AGENT_CODEX:+-c model="$GH_AW_MODEL_AGENT_CODEX" }exec -c web_search="disabled" --dangerously-bypass-approvals-and-sandbox --skip-git-repo-check "$INSTRUCTION"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
-- /bin/bash -c 'export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 4 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || echo node)"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/codex_harness.cjs codex ${GH_AW_MODEL_AGENT_CODEX:+-c model="$GH_AW_MODEL_AGENT_CODEX" }exec -c web_search="disabled" --dangerously-bypass-approvals-and-sandbox --skip-git-repo-check --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 4, 2026

🧪 Test Quality Sentinel Report

Test Quality Score: 90/100

Excellent test quality

Metric Value
New/modified tests analyzed 5
✅ Design tests (behavioral contracts) 5 (100%)
⚠️ Implementation tests (low value) 0 (0%)
Tests with error/edge cases 5 (100%)
Duplicate test clusters 0
Test inflation detected Yes (115 test lines / 40 production lines ≈ 2.9:1)
🚨 Coding-guideline violations None

Test Classification Details

The PR adds the sanitizeCopilotShellCommand function in copilot_engine_tools.go and covers it with 5 new table-driven rows inside TestCopilotEngineComputeToolArguments.

View all 5 test cases
Test File Classification Notes
bash tool with single-quoted jq filter is truncated to prefix pkg/workflow/copilot_engine_test.go ✅ Design Verifies core behavioral contract: single-quoted command → safe prefix
bash tool with single-quoted filter and leading space trimmed pkg/workflow/copilot_engine_test.go ✅ Design Edge case: trailing space after truncation is stripped
bash tool without single quotes passes through unchanged pkg/workflow/copilot_engine_test.go ✅ Design Non-regression path: clean commands are not mangled
multiple bash tools: single-quoted ones truncated, others unchanged pkg/workflow/copilot_engine_test.go ✅ Design Mixed-input edge case; verifies selective sanitization
multiple single-quoted tools with same prefix are deduplicated pkg/workflow/copilot_engine_test.go ✅ Design Deduplication invariant: N synonymous filters → one shell(jq)

Flagged Tests — Requires Review

No individual tests require remediation. The only flag is test inflation (115 additions in test file vs. 40 additions in production file ≈ 2.9:1). This is a minor concern: much of the additional test-file volume covers regression-proofing of pre-existing behaviour in the same TestCopilotEngineComputeToolArguments table, which is a positive pattern. No action required, but worth noting.


Language Support

Tests analyzed:

  • 🐹 Go (*_test.go): 5 new test cases (unit — //go:build !integration ✅ present on line 1)
  • 🟨 JavaScript (*.test.cjs, *.test.js): 0 new tests

Verdict

Check passed. 0% of new tests are implementation tests (threshold: 30%). Build tag present. No mock libraries detected. All 5 new tests exercise observable output contracts of sanitizeCopilotShellCommand and its integration into computeCopilotToolArguments.


📖 Understanding Test Classifications

Design Tests (High Value) verify what the system does:

  • Assert on observable outputs, return values, or state changes
  • Cover error paths and boundary conditions
  • Would catch a behavioral regression if deleted
  • Remain valid even after internal refactoring

Implementation Tests (Low Value) verify how the system does it:

  • Assert on internal function calls (mocking internals)
  • Only test the happy path with typical inputs
  • Break during legitimate refactoring even when behavior is correct
  • Give false assurance: they pass even when the system is wrong

Goal: Shift toward tests that describe the system's behavioral contract — the promises it makes to its users and collaborators.

References: §25297769960

🧪 Test quality analysis by Test Quality Sentinel · ● 1.2M ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Test Quality Sentinel: 90/100. Test quality is excellent — 0% of new tests are implementation tests (threshold: 30%). All 5 new tests verify behavioral contracts of the single-quote sanitization fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[aw] Daily Model Inventory Checker failed

3 participants