From e4027ae4976c675a670433ffd2fa02cc307d059d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Jun 2026 23:51:20 +0000 Subject: [PATCH 1/2] Initial plan From 4296e83e2e911899a4fb6befe04bd61befd8d330 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 23 Jun 2026 00:07:29 +0000 Subject: [PATCH 2/2] Fix strict workflow read allowlists Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../daily-formal-spec-verifier.lock.yml | 6 +-- .../workflows/daily-formal-spec-verifier.md | 5 ++- .../daily-spdd-spec-planner.lock.yml | 6 +-- .github/workflows/daily-spdd-spec-planner.md | 5 ++- pkg/workflow/prompts_test.go | 42 +++++++++++++++++++ 5 files changed, 56 insertions(+), 8 deletions(-) diff --git a/.github/workflows/daily-formal-spec-verifier.lock.yml b/.github/workflows/daily-formal-spec-verifier.lock.yml index acd5242f7d0..4ecfd6d2148 100644 --- a/.github/workflows/daily-formal-spec-verifier.lock.yml +++ b/.github/workflows/daily-formal-spec-verifier.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"a9d5e624e8ab7bcc14d5e6119a6373d1a53916d69feb8130b1278e5e17ba7e28","body_hash":"dadb12963c3e9b6108924c8d3be1195905e12f2e42eb1ae6f9d889958351a2c4","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.63","copilot-sdk":"1.0.2"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"4fd573a06b8c125acb2c04ec7a98d360f7770a21f69391b017eb70a6422ad2b2","body_hash":"26c67b4a2782d26b7bfa22dc777fce782e98a859fbd2ef26454182f751eb8185","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.63","copilot-sdk":"1.0.2"}} # gh-aw-manifest: {"version":1,"secrets":["GH_AW_AGENT_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7","digest":"sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7","digest":"sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.7","digest":"sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.7@sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7","digest":"sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.27","digest":"sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.4.0","digest":"sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036","pinned_image":"ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036"}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -869,7 +869,7 @@ jobs: # --allow-tool shell(printf) # --allow-tool shell(pwd) # --allow-tool shell(safeoutputs:*) - # --allow-tool shell(sed -n) + # --allow-tool shell(sed) # --allow-tool shell(sort) # --allow-tool shell(tail) # --allow-tool shell(uniq) @@ -933,7 +933,7 @@ jobs: COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }} COPILOT_SDK_URI: http://127.0.0.1:3002 GH_AW_COPILOT_SDK_DRIVER: 1 - GH_AW_COPILOT_SDK_SERVER_ARGS: '["--headless","--no-auto-update","--port","3002","--add-dir","/tmp/gh-aw/","--log-level","all","--log-dir","/tmp/gh-aw/sandbox/agent/logs/","--disable-builtin-mcps","--no-ask-user","--allow-tool","github","--allow-tool","safeoutputs","--allow-tool","shell(cat pkg/cli/*.go)","--allow-tool","shell(cat pkg/workflow/*.go | head -200)","--allow-tool","shell(cat specs/*.md)","--allow-tool","shell(cat)","--allow-tool","shell(date)","--allow-tool","shell(echo)","--allow-tool","shell(find . -name \"*_test.go\" -path \"*/pkg/*\" | head -20)","--allow-tool","shell(find specs -type f -name \"*.md\" | sort)","--allow-tool","shell(gh:*)","--allow-tool","shell(grep)","--allow-tool","shell(head)","--allow-tool","shell(ls)","--allow-tool","shell(printf)","--allow-tool","shell(pwd)","--allow-tool","shell(safeoutputs:*)","--allow-tool","shell(sed -n)","--allow-tool","shell(sort)","--allow-tool","shell(tail)","--allow-tool","shell(uniq)","--allow-tool","shell(wc)","--allow-tool","shell(yq)","--allow-tool","write","--add-dir","/tmp/gh-aw/cache-memory/","--allow-all-paths"]' + GH_AW_COPILOT_SDK_SERVER_ARGS: '["--headless","--no-auto-update","--port","3002","--add-dir","/tmp/gh-aw/","--log-level","all","--log-dir","/tmp/gh-aw/sandbox/agent/logs/","--disable-builtin-mcps","--no-ask-user","--allow-tool","github","--allow-tool","safeoutputs","--allow-tool","shell(cat pkg/cli/*.go)","--allow-tool","shell(cat pkg/workflow/*.go | head -200)","--allow-tool","shell(cat specs/*.md)","--allow-tool","shell(cat)","--allow-tool","shell(date)","--allow-tool","shell(echo)","--allow-tool","shell(find . -name \"*_test.go\" -path \"*/pkg/*\" | head -20)","--allow-tool","shell(find specs -type f -name \"*.md\" | sort)","--allow-tool","shell(gh:*)","--allow-tool","shell(grep)","--allow-tool","shell(head)","--allow-tool","shell(ls)","--allow-tool","shell(printf)","--allow-tool","shell(pwd)","--allow-tool","shell(safeoutputs:*)","--allow-tool","shell(sed)","--allow-tool","shell(sort)","--allow-tool","shell(tail)","--allow-tool","shell(uniq)","--allow-tool","shell(wc)","--allow-tool","shell(yq)","--allow-tool","write","--add-dir","/tmp/gh-aw/cache-memory/","--allow-all-paths"]' GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }} GH_AW_MAX_TOOL_DENIALS: 5 GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }} diff --git a/.github/workflows/daily-formal-spec-verifier.md b/.github/workflows/daily-formal-spec-verifier.md index 8f33da199f9..a8acc1e5470 100644 --- a/.github/workflows/daily-formal-spec-verifier.md +++ b/.github/workflows/daily-formal-spec-verifier.md @@ -41,13 +41,14 @@ tools: branch-name: memory/formal-spec-verifier file-glob: ["*.md", "*.json"] max-file-size: 65536 + edit: null bash: - "find specs -type f -name \"*.md\" | sort" - "cat specs/*.md" - "find . -name \"*_test.go\" -path \"*/pkg/*\" | head -20" - "cat pkg/workflow/*.go | head -200" - "cat pkg/cli/*.go" - - "sed -n" + - "sed *" safe-outputs: mentions: false @@ -123,6 +124,8 @@ If a note file exists for the selected spec, read it and use the prior predicate Read the selected spec file in full with `bash`. +Use built-in file inspection tools only for read-only analysis when bash output is insufficient. Do not modify repository files. + Extract: - **Purpose**: the system or component being specified. diff --git a/.github/workflows/daily-spdd-spec-planner.lock.yml b/.github/workflows/daily-spdd-spec-planner.lock.yml index 794bbdaac73..0bb1ebc64e7 100644 --- a/.github/workflows/daily-spdd-spec-planner.lock.yml +++ b/.github/workflows/daily-spdd-spec-planner.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"222d90a04a2ee4067b71ea60eab8465d621572dbd40858432e9f20cc5502f614","body_hash":"b997cb1da9418130c52afd60a673901fdd779f3a95522b5bacb87e595dcf4c31","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.63","copilot-sdk":"1.0.2"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"2e9d3575f7de53da94a7b973bba78e746ec92876ed50c342a4a059dfb814e850","body_hash":"bc0986adbc4860e545ab0ca58c3185f809c95574c71fd5cd55e6b97c9abbd515","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.63","copilot-sdk":"1.0.2"}} # gh-aw-manifest: {"version":1,"secrets":["GH_AW_AGENT_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7","digest":"sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7","digest":"sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.7","digest":"sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.7@sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7","digest":"sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.27","digest":"sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.4.0","digest":"sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036","pinned_image":"ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036"}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -845,7 +845,7 @@ jobs: # --allow-tool shell(printf) # --allow-tool shell(pwd) # --allow-tool shell(safeoutputs:*) - # --allow-tool shell(sed -n) + # --allow-tool shell(sed) # --allow-tool shell(sort) # --allow-tool shell(tail) # --allow-tool shell(uniq) @@ -909,7 +909,7 @@ jobs: COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }} COPILOT_SDK_URI: http://127.0.0.1:3002 GH_AW_COPILOT_SDK_DRIVER: 1 - GH_AW_COPILOT_SDK_SERVER_ARGS: '["--headless","--no-auto-update","--port","3002","--add-dir","/tmp/gh-aw/","--log-level","all","--log-dir","/tmp/gh-aw/sandbox/agent/logs/","--disable-builtin-mcps","--no-ask-user","--allow-tool","github","--allow-tool","safeoutputs","--allow-tool","shell(cat docs/src/content/docs/reference/*specification*.md)","--allow-tool","shell(cat scratchpad/*specification*.md)","--allow-tool","shell(cat specs/*.md)","--allow-tool","shell(cat)","--allow-tool","shell(date)","--allow-tool","shell(echo)","--allow-tool","shell(find specs docs scratchpad -type f -name \"*.md\")","--allow-tool","shell(gh:*)","--allow-tool","shell(git log --oneline --since=\"14 days ago\" -- specs docs/src/content/docs/reference scratchpad)","--allow-tool","shell(grep)","--allow-tool","shell(head)","--allow-tool","shell(ls)","--allow-tool","shell(printf)","--allow-tool","shell(pwd)","--allow-tool","shell(safeoutputs:*)","--allow-tool","shell(sed -n)","--allow-tool","shell(sort)","--allow-tool","shell(tail)","--allow-tool","shell(uniq)","--allow-tool","shell(wc)","--allow-tool","shell(yq)","--allow-tool","write","--add-dir","/tmp/gh-aw/cache-memory/","--allow-all-paths"]' + GH_AW_COPILOT_SDK_SERVER_ARGS: '["--headless","--no-auto-update","--port","3002","--add-dir","/tmp/gh-aw/","--log-level","all","--log-dir","/tmp/gh-aw/sandbox/agent/logs/","--disable-builtin-mcps","--no-ask-user","--allow-tool","github","--allow-tool","safeoutputs","--allow-tool","shell(cat docs/src/content/docs/reference/*specification*.md)","--allow-tool","shell(cat scratchpad/*specification*.md)","--allow-tool","shell(cat specs/*.md)","--allow-tool","shell(cat)","--allow-tool","shell(date)","--allow-tool","shell(echo)","--allow-tool","shell(find specs docs scratchpad -type f -name \"*.md\")","--allow-tool","shell(gh:*)","--allow-tool","shell(git log --oneline --since=\"14 days ago\" -- specs docs/src/content/docs/reference scratchpad)","--allow-tool","shell(grep)","--allow-tool","shell(head)","--allow-tool","shell(ls)","--allow-tool","shell(printf)","--allow-tool","shell(pwd)","--allow-tool","shell(safeoutputs:*)","--allow-tool","shell(sed)","--allow-tool","shell(sort)","--allow-tool","shell(tail)","--allow-tool","shell(uniq)","--allow-tool","shell(wc)","--allow-tool","shell(yq)","--allow-tool","write","--add-dir","/tmp/gh-aw/cache-memory/","--allow-all-paths"]' GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }} GH_AW_MAX_TOOL_DENIALS: 5 GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }} diff --git a/.github/workflows/daily-spdd-spec-planner.md b/.github/workflows/daily-spdd-spec-planner.md index dc717883af5..2d5fbfaa853 100644 --- a/.github/workflows/daily-spdd-spec-planner.md +++ b/.github/workflows/daily-spdd-spec-planner.md @@ -34,13 +34,14 @@ tools: mode: gh-proxy toolsets: [default, repos, issues, pull_requests] cache-memory: true + edit: null bash: - "find specs docs scratchpad -type f -name \"*.md\"" - "cat specs/*.md" - "cat docs/src/content/docs/reference/*specification*.md" - "cat scratchpad/*specification*.md" - "git log --oneline --since=\"14 days ago\" -- specs docs/src/content/docs/reference scratchpad" - - "sed -n" + - "sed *" steps: - name: Copy OpenSPDD prompts @@ -89,6 +90,8 @@ Inspect specification files from: - `docs/src/content/docs/reference/*specification*.md` - `scratchpad/*specification*.md` +Use the allowed shell commands above or built-in file inspection tools only for read-only analysis. Do not modify repository files. + ### Daily Rotation Use cache-memory at `/tmp/gh-aw/cache-memory/spdd-daily/rotation.json` to rotate through spec files fairly: diff --git a/pkg/workflow/prompts_test.go b/pkg/workflow/prompts_test.go index bc74844a18f..5e5bbeb6ca5 100644 --- a/pkg/workflow/prompts_test.go +++ b/pkg/workflow/prompts_test.go @@ -348,6 +348,48 @@ func TestDailyFormalSpecVerifierDefinesDirectSafeOutputContract(t *testing.T) { } } +func TestDailyFormalSpecVerifierAllowsReadOnlyFileInspection(t *testing.T) { + repoRoot, err := findRepoRoot() + if err != nil { + t.Fatalf("Failed to find repo root: %v", err) + } + + workflowFile := filepath.Join(repoRoot, ".github", "workflows", "daily-formal-spec-verifier.md") + content, err := os.ReadFile(workflowFile) + if err != nil { + t.Fatalf("Failed to read workflow file: %v", err) + } + + workflow := string(content) + if !strings.Contains(workflow, "edit: null") { + t.Fatal("Expected daily-formal-spec-verifier workflow to enable built-in file inspection tools") + } + if !strings.Contains(workflow, `- "sed *"`) { + t.Fatal("Expected daily-formal-spec-verifier workflow to allow ranged sed reads") + } +} + +func TestDailySPDDSpecPlannerAllowsReadOnlyFileInspection(t *testing.T) { + repoRoot, err := findRepoRoot() + if err != nil { + t.Fatalf("Failed to find repo root: %v", err) + } + + workflowFile := filepath.Join(repoRoot, ".github", "workflows", "daily-spdd-spec-planner.md") + content, err := os.ReadFile(workflowFile) + if err != nil { + t.Fatalf("Failed to read workflow file: %v", err) + } + + workflow := string(content) + if !strings.Contains(workflow, "edit: null") { + t.Fatal("Expected daily-spdd-spec-planner workflow to enable built-in file inspection tools") + } + if !strings.Contains(workflow, `- "sed *"`) { + t.Fatal("Expected daily-spdd-spec-planner workflow to allow ranged sed reads") + } +} + func TestDailyCacheStrategyAnalyzerUsesCodexCompatibleModelsForExperiment(t *testing.T) { repoRoot, err := findRepoRoot() if err != nil {