From 53717f98c5a1147856ae5a7fd9a962368c8459ee Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 19 Jul 2026 07:09:15 +0000 Subject: [PATCH 1/3] Initial plan From e0ceff8b2b8d7037b0e11861a82be19b30ffd8e0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 19 Jul 2026 07:31:54 +0000 Subject: [PATCH 2/3] fix: pin sub-agent model aliases to claude-haiku-4.5 to resolve model resolution mismatches The daily model resolution audit found that sub-agents declared with `model: small` were resolving to `claude-sonnet-4.6` at runtime instead of a small/haiku model. This is because the Copilot engine doesn't know how to resolve gh-aw model aliases like `small`. Fix: replace `model: small` with the concrete `model: claude-haiku-4.5` in the inline sub-agent frontmatter for: - pr-description-caveman.md: chunk-analyzer sub-agent - code-simplifier.md: scope-filter and simplification-scout sub-agents - contribution-check.md: prompt text instruction for subagent calls Add contract tests for pr-description-caveman.md and code-simplifier.md to enforce that sub-agents pin a concrete Haiku model, consistent with the existing pattern in pr-code-quality-reviewer.md. Update the existing contribution_check_workflow_contract_test.go to assert claude-haiku-4.5 instead of the unresolved `small` alias. Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/code-simplifier.lock.yml | 2 +- .github/workflows/code-simplifier.md | 8 ++--- .github/workflows/contribution-check.lock.yml | 2 +- .github/workflows/contribution-check.md | 2 +- .../workflows/pr-description-caveman.lock.yml | 2 +- .github/workflows/pr-description-caveman.md | 2 +- .../code_simplifier_workflow_contract_test.go | 31 +++++++++++++++++++ ...ntribution_check_workflow_contract_test.go | 2 +- ...cription_caveman_workflow_contract_test.go | 29 +++++++++++++++++ 9 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 pkg/cli/code_simplifier_workflow_contract_test.go create mode 100644 pkg/cli/pr_description_caveman_workflow_contract_test.go diff --git a/.github/workflows/code-simplifier.lock.yml b/.github/workflows/code-simplifier.lock.yml index 5b2ad0e1a85..ed73ba6e0f1 100644 --- a/.github/workflows/code-simplifier.lock.yml +++ b/.github/workflows/code-simplifier.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"517bf3a1285358a12edf4c99e618a8fcae9f4b0902186f04a2dca296cc60aff7","body_hash":"0ca4418dae477ef1d922845459efbab2121ee1bbe05003850c46e1d64f9f138f","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.71"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"517bf3a1285358a12edf4c99e618a8fcae9f4b0902186f04a2dca296cc60aff7","body_hash":"b9c6b23ba5219b24d164f0b8a59cfa474d22b9114e0687435fa01a94cbf052be","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.71"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_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":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"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-java","sha":"0f481fcb613427c0f801b606911222b5b6f3083a","version":"v5.5.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35","digest":"sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35@sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35","digest":"sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35@sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.35","digest":"sha256:fe83cd274636efa9de3f456e2b078fae137328b9bb6ee4986ae510acaef0cec5","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.35@sha256:fe83cd274636efa9de3f456e2b078fae137328b9bb6ee4986ae510acaef0cec5"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35","digest":"sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35@sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.1","digest":"sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.1@sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32"},{"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.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"}]} # 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 # diff --git a/.github/workflows/code-simplifier.md b/.github/workflows/code-simplifier.md index 81d31897965..897f8209692 100644 --- a/.github/workflows/code-simplifier.md +++ b/.github/workflows/code-simplifier.md @@ -188,9 +188,9 @@ Code simplifier has nothing to process today. For each file in `source-files.json`: -1. Use `scope-filter` (`model: small`) to confirm the file should be simplified and detect language. +1. Use `scope-filter` (`model: claude-haiku-4.5`) to confirm the file should be simplified and detect language. 2. Apply only the matching language skill guidance (do not load unrelated language guidance). -3. Use `simplification-scout` (`model: small`) for extractive opportunity scoring. +3. Use `simplification-scout` (`model: claude-haiku-4.5`) for extractive opportunity scoring. 4. Make targeted edits that preserve behavior. Priorities: @@ -260,7 +260,7 @@ Do not finish with plain text only. The safe-output tool call is required. ## agent: `scope-filter` --- description: Decides whether a candidate file should be simplified and labels its primary language -model: small +model: claude-haiku-4.5 --- Input is a single file path string. Return strict JSON only: `{"path":"...","include":true|false,"language":"go|typescript|javascript|python|csharp|other","reason":"..."}` @@ -270,7 +270,7 @@ Set `include` to false for tests, generated files, lockfiles, vendored code, or ## agent: `simplification-scout` --- description: Extractive scout that proposes low-risk simplification opportunities per file -model: small +model: claude-haiku-4.5 --- Given file content, return strict JSON only: `{"path":"...","opportunities":[{"kind":"clarity|duplication|complexity|naming","summary":"...","risk":"low|medium"}]}` diff --git a/.github/workflows/contribution-check.lock.yml b/.github/workflows/contribution-check.lock.yml index ea4713b6b24..40dc4005762 100644 --- a/.github/workflows/contribution-check.lock.yml +++ b/.github/workflows/contribution-check.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"17a99658dc8da34d7d71e204accb55393a6b6f03a8258330249d5e193d3bc9f3","body_hash":"352f47c4d2a6f0cd4ae8eaaf76aa067f6380b3fd3c6d3e0cfe237515f0d2de73","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.71"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"17a99658dc8da34d7d71e204accb55393a6b6f03a8258330249d5e193d3bc9f3","body_hash":"544b592c10b0d3f4f1791272d2660868b83dfc518eed66ee2beb04d2c612b097","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.71"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_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":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"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":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35","digest":"sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35@sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35","digest":"sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35@sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.35","digest":"sha256:fe83cd274636efa9de3f456e2b078fae137328b9bb6ee4986ae510acaef0cec5","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.35@sha256:fe83cd274636efa9de3f456e2b078fae137328b9bb6ee4986ae510acaef0cec5"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35","digest":"sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35@sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.1","digest":"sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.1@sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32"},{"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.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"}]} # 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 # diff --git a/.github/workflows/contribution-check.md b/.github/workflows/contribution-check.md index 647c59c6449..f1081b2724c 100644 --- a/.github/workflows/contribution-check.md +++ b/.github/workflows/contribution-check.md @@ -158,7 +158,7 @@ Read the contents of `contributing-guidelines-truncated.md` from the workspace r Call the contribution-checker subagent for each PR with this prompt: -Use `model: small` for every contribution-checker subagent call. +Use `model: claude-haiku-4.5` for every contribution-checker subagent call. ``` The CONTRIBUTING.md content for this repository is attached below (already truncated to 2000 chars by the pre-agent step). diff --git a/.github/workflows/pr-description-caveman.lock.yml b/.github/workflows/pr-description-caveman.lock.yml index a13a6c20887..8963bd4a12f 100644 --- a/.github/workflows/pr-description-caveman.lock.yml +++ b/.github/workflows/pr-description-caveman.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"6bae935057caa20309dd306db3e3d5211b89ee29e61ec580c37b7b099b3b32a8","body_hash":"485de652516c8dab3637169a8592eb1832716e0d0622387fdd8d719f9a472c25","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.71"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"6bae935057caa20309dd306db3e3d5211b89ee29e61ec580c37b7b099b3b32a8","body_hash":"9bac1d0ec1c8a732ca4069205f2a7b630492340afda7dd1a828c8aa49df56d0a","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.71"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"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":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35","digest":"sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35@sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35","digest":"sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35@sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.35","digest":"sha256:fe83cd274636efa9de3f456e2b078fae137328b9bb6ee4986ae510acaef0cec5","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.35@sha256:fe83cd274636efa9de3f456e2b078fae137328b9bb6ee4986ae510acaef0cec5"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35","digest":"sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35@sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.1","digest":"sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.1@sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32"},{"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.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"}],"has_pull_request":true} # 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 # diff --git a/.github/workflows/pr-description-caveman.md b/.github/workflows/pr-description-caveman.md index 3571a1b7a7c..e9c99378526 100644 --- a/.github/workflows/pr-description-caveman.md +++ b/.github/workflows/pr-description-caveman.md @@ -141,7 +141,7 @@ If there are no meaningful changes, call `noop` instead. ## agent: `chunk-analyzer` --- description: Analyses one 400-line slice of a unified diff and extracts structured per-file change facts. -model: small +model: claude-haiku-4.5 --- You receive a slice of a unified diff (`diff --git` format). Extract facts about every changed file found in this slice. diff --git a/pkg/cli/code_simplifier_workflow_contract_test.go b/pkg/cli/code_simplifier_workflow_contract_test.go new file mode 100644 index 00000000000..2136e5c656d --- /dev/null +++ b/pkg/cli/code_simplifier_workflow_contract_test.go @@ -0,0 +1,31 @@ +//go:build !integration + +package cli + +import ( + "os" + "path/filepath" + "testing" + + "github.com/github/gh-aw/pkg/gitutil" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestCodeSimplifierWorkflowSubAgentModelContract(t *testing.T) { + repoRoot, err := gitutil.FindGitRoot() + if err != nil { + t.Skipf("Skipping test: not in a git repository: %v", err) + } + + workflowPath := filepath.Join(repoRoot, ".github", "workflows", "code-simplifier.md") + content, err := os.ReadFile(workflowPath) + require.NoError(t, err, "Should read code-simplifier workflow") + + text := string(content) + assert.Contains(t, text, "## agent: `scope-filter`", "Workflow should define the scope-filter sub-agent") + assert.Contains(t, text, "## agent: `simplification-scout`", "Workflow should define the simplification-scout sub-agent") + assert.Contains(t, text, "model: claude-haiku-4.5", "Sub-agents should pin a supported Haiku model") + assert.NotContains(t, text, "model: small\n---\nInput is a single file path string", "scope-filter sub-agent should not use the unresolved 'small' alias") + assert.NotContains(t, text, "model: small\n---\nGiven file content", "simplification-scout sub-agent should not use the unresolved 'small' alias") +} diff --git a/pkg/cli/contribution_check_workflow_contract_test.go b/pkg/cli/contribution_check_workflow_contract_test.go index bd67892f8cb..47c0d097cdb 100644 --- a/pkg/cli/contribution_check_workflow_contract_test.go +++ b/pkg/cli/contribution_check_workflow_contract_test.go @@ -32,5 +32,5 @@ func TestContributionCheckWorkflowSafeOutputContract(t *testing.T) { assert.Contains(t, text, "#", "Workflow must describe item_number temporary_id reference format") assert.Contains(t, text, "Never emit `add_comment` without a numeric target field", "Workflow must forbid targetless add_comment items") assert.Contains(t, text, "\"issue_number\":35304", "Workflow should include a concrete add_comment issue_number example") - assert.Contains(t, text, "model: small", "Workflow should require small model for contribution-checker subagent calls") + assert.Contains(t, text, "model: claude-haiku-4.5", "Workflow should require small model for contribution-checker subagent calls") } diff --git a/pkg/cli/pr_description_caveman_workflow_contract_test.go b/pkg/cli/pr_description_caveman_workflow_contract_test.go new file mode 100644 index 00000000000..65b5b40e726 --- /dev/null +++ b/pkg/cli/pr_description_caveman_workflow_contract_test.go @@ -0,0 +1,29 @@ +//go:build !integration + +package cli + +import ( + "os" + "path/filepath" + "testing" + + "github.com/github/gh-aw/pkg/gitutil" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestPRDescriptionCavemanWorkflowSubAgentModelContract(t *testing.T) { + repoRoot, err := gitutil.FindGitRoot() + if err != nil { + t.Skipf("Skipping test: not in a git repository: %v", err) + } + + workflowPath := filepath.Join(repoRoot, ".github", "workflows", "pr-description-caveman.md") + content, err := os.ReadFile(workflowPath) + require.NoError(t, err, "Should read pr-description-caveman workflow") + + text := string(content) + assert.Contains(t, text, "## agent: `chunk-analyzer`", "Workflow should define the chunk-analyzer sub-agent") + assert.Contains(t, text, "model: claude-haiku-4.5", "chunk-analyzer sub-agent should pin a supported Haiku model") + assert.NotContains(t, text, "## agent: `chunk-analyzer`\n---\ndescription: Analyses one 400-line slice of a unified diff and extracts structured per-file change facts.\nmodel: small", "chunk-analyzer sub-agent should not use the unresolved 'small' alias") +} From a281155d6cbba87283a990662bade9d043a7e49f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 19 Jul 2026 07:33:00 +0000 Subject: [PATCH 3/3] refactor: simplify contract test assertions to avoid fragile multi-line matches Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/cli/code_simplifier_workflow_contract_test.go | 3 +-- pkg/cli/pr_description_caveman_workflow_contract_test.go | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pkg/cli/code_simplifier_workflow_contract_test.go b/pkg/cli/code_simplifier_workflow_contract_test.go index 2136e5c656d..5642fbe13ef 100644 --- a/pkg/cli/code_simplifier_workflow_contract_test.go +++ b/pkg/cli/code_simplifier_workflow_contract_test.go @@ -26,6 +26,5 @@ func TestCodeSimplifierWorkflowSubAgentModelContract(t *testing.T) { assert.Contains(t, text, "## agent: `scope-filter`", "Workflow should define the scope-filter sub-agent") assert.Contains(t, text, "## agent: `simplification-scout`", "Workflow should define the simplification-scout sub-agent") assert.Contains(t, text, "model: claude-haiku-4.5", "Sub-agents should pin a supported Haiku model") - assert.NotContains(t, text, "model: small\n---\nInput is a single file path string", "scope-filter sub-agent should not use the unresolved 'small' alias") - assert.NotContains(t, text, "model: small\n---\nGiven file content", "simplification-scout sub-agent should not use the unresolved 'small' alias") + assert.NotContains(t, text, "model: small", "Sub-agents should not use the unresolved 'small' alias") } diff --git a/pkg/cli/pr_description_caveman_workflow_contract_test.go b/pkg/cli/pr_description_caveman_workflow_contract_test.go index 65b5b40e726..62a8740cedd 100644 --- a/pkg/cli/pr_description_caveman_workflow_contract_test.go +++ b/pkg/cli/pr_description_caveman_workflow_contract_test.go @@ -25,5 +25,5 @@ func TestPRDescriptionCavemanWorkflowSubAgentModelContract(t *testing.T) { text := string(content) assert.Contains(t, text, "## agent: `chunk-analyzer`", "Workflow should define the chunk-analyzer sub-agent") assert.Contains(t, text, "model: claude-haiku-4.5", "chunk-analyzer sub-agent should pin a supported Haiku model") - assert.NotContains(t, text, "## agent: `chunk-analyzer`\n---\ndescription: Analyses one 400-line slice of a unified diff and extracts structured per-file change facts.\nmodel: small", "chunk-analyzer sub-agent should not use the unresolved 'small' alias") + assert.NotContains(t, text, "model: small", "chunk-analyzer sub-agent should not use the unresolved 'small' alias") }