From 66fd99d4ff48ba29a09c9f6ad5d1d1599b2a9575 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 5 Aug 2026 17:19:34 +0000 Subject: [PATCH 1/3] Initial plan From 31ae566547cff97efe40de6e8114539f354dc770 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 5 Aug 2026 17:30:37 +0000 Subject: [PATCH 2/3] Render trial logical repo in github-context prompt Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/unified_prompt_step.go | 31 ++++++++++++ pkg/workflow/unified_prompt_step_test.go | 60 ++++++++++++++++++++++++ 2 files changed, 91 insertions(+) diff --git a/pkg/workflow/unified_prompt_step.go b/pkg/workflow/unified_prompt_step.go index d33d128d10b..275c1a3a419 100644 --- a/pkg/workflow/unified_prompt_step.go +++ b/pkg/workflow/unified_prompt_step.go @@ -146,6 +146,14 @@ func (c *Compiler) collectPromptSections(data *WorkflowData) []PromptSection { // The checkout list may contain ${{ github.repository }} which must go through // the expression extractor so the placeholder substitution step can resolve it. combinedPromptText := githubContextPromptText + // In trial mode with a logical target repository, the workflow runs on the host + // repo (github.repository) but checkout and safe outputs are redirected to the + // logical target. Rewrite the reported repository so the agent's notion of "the + // repository" matches the logical target, and add a directive so GitHub MCP calls + // that omit owner/repo don't silently operate against the host repo. + if data.TrialMode && data.TrialLogicalRepo != "" { + combinedPromptText = applyTrialLogicalRepoToGitHubContext(combinedPromptText, data.TrialLogicalRepo) + } if checkoutsContent := buildCheckoutsPromptContent(data.CheckoutConfigs); checkoutsContent != "" { unifiedPromptLog.Printf("Injecting checkout list into GitHub context (%d checkouts)", len(data.CheckoutConfigs)) const closeTag = "" @@ -780,3 +788,26 @@ func buildSafeOutputsSections(safeOutputs *SafeOutputsConfig) []PromptSection { return sections } + +// applyTrialLogicalRepoToGitHubContext rewrites the github-context prompt so that +// the reported repository is the trial mode logical target rather than the host +// repository (github.repository). It replaces the unconditional repository line and +// appends a directive instructing the agent to target the logical repository for +// GitHub MCP calls that omit an explicit owner/repo. +func applyTrialLogicalRepoToGitHubContext(promptText, logicalRepo string) string { + const repoLine = "- **repository**: ${{ github.repository }}" + replacement := "- **repository**: " + logicalRepo + promptText = strings.Replace(promptText, repoLine, replacement, 1) + + directive := fmt.Sprintf( + "\nThis workflow is running in trial mode. The repository above (%s) is the logical target repository. When calling GitHub tools without an explicit owner/repo, use this repository.\n", + logicalRepo, + ) + const closeTag = "" + if idx := strings.LastIndex(promptText, closeTag); idx >= 0 { + promptText = promptText[:idx] + directive + promptText[idx:] + } else { + promptText += directive + } + return promptText +} diff --git a/pkg/workflow/unified_prompt_step_test.go b/pkg/workflow/unified_prompt_step_test.go index d950ba4b674..d7cc551851d 100644 --- a/pkg/workflow/unified_prompt_step_test.go +++ b/pkg/workflow/unified_prompt_step_test.go @@ -718,3 +718,63 @@ func TestGenerateUnifiedPromptCreationStep_BlankRunCapAdjacentToRuntimeImport(t // No run of four or more newlines (i.e., 3+ consecutive blank lines) anywhere. assert.NotContains(t, output, "\n\n\n\n", "blank run should be capped throughout the output") } + +func TestCollectPromptSections_TrialLogicalRepoGitHubContext(t *testing.T) { + compiler := &Compiler{} + + data := &WorkflowData{ + ParsedTools: NewTools(map[string]any{ + "github": true, + }), + Permissions: "contents: read", + On: "issue_comment", + TrialMode: true, + TrialLogicalRepo: "owner/target", + } + + sections := compiler.collectPromptSections(data) + + var githubContext string + for _, section := range sections { + if !section.IsFile && strings.Contains(section.Content, "github-context") { + githubContext = section.Content + break + } + } + require.NotEmpty(t, githubContext, "Should have a github-context section") + + assert.Contains(t, githubContext, "- **repository**: owner/target", + "github-context should report the logical target repository") + assert.NotContains(t, githubContext, "**repository**: ${{ github.repository }}", + "github-context should not report the host repository in trial mode") + assert.Contains(t, githubContext, "trial mode", + "github-context should include a trial mode directive") +} + +func TestCollectPromptSections_NoTrialLogicalRepoKeepsHostRepo(t *testing.T) { + compiler := &Compiler{} + + data := &WorkflowData{ + ParsedTools: NewTools(map[string]any{ + "github": true, + }), + Permissions: "contents: read", + On: "issue_comment", + } + + sections := compiler.collectPromptSections(data) + + var githubContext string + for _, section := range sections { + if !section.IsFile && strings.Contains(section.Content, "github-context") { + githubContext = section.Content + break + } + } + require.NotEmpty(t, githubContext, "Should have a github-context section") + + assert.Contains(t, githubContext, "**repository**:", + "github-context should report the repository via the github.repository expression") + assert.NotContains(t, githubContext, "owner/target", + "github-context should not include a logical target when trial mode is off") +} From 5f5f6e914a3818cc38985e44832b88bf1495a6e2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 5 Aug 2026 23:28:10 +0000 Subject: [PATCH 3/3] Apply remaining changes Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/discussion-task-miner.lock.yml | 2 +- pkg/actionpins/data/action_pins.json | 10 +++++----- pkg/workflow/data/action_pins.json | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/discussion-task-miner.lock.yml b/.github/workflows/discussion-task-miner.lock.yml index 4f74ed95383..4e32bca860d 100644 --- a/.github/workflows/discussion-task-miner.lock.yml +++ b/.github/workflows/discussion-task-miner.lock.yml @@ -1,5 +1,5 @@ # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"a33ed75d7a3b3250217e65bb04247452c200e0e1a6011929441296ebe2f8b331","body_hash":"30a2a145f9a81af5f4df91cb34aaee48c6671db9721c0f6bd19dd73c859f0663","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.77","copilot-sdk":"1.0.8"}} -# 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":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"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.43","digest":"sha256:04e2d1987a565000a8f114b89d806ae7a3864dd4f944be65275b28c93d8690e6","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.43@sha256:04e2d1987a565000a8f114b89d806ae7a3864dd4f944be65275b28c93d8690e6"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.43","digest":"sha256:d85f57975af5ea23af4996e41ed73fbc8f5b4a47402472bfe82e508f352cb0c1","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.43@sha256:d85f57975af5ea23af4996e41ed73fbc8f5b4a47402472bfe82e508f352cb0c1"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.43","digest":"sha256:65c45ea2967984d0024f3df61bc71335658a77ede96c8d9665da7a5f33a795ab","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.43@sha256:65c45ea2967984d0024f3df61bc71335658a77ede96c8d9665da7a5f33a795ab"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.43","digest":"sha256:26be5e0b8c8f4c41c8a59126b29bb5d80b07253597472ded2a16bdd75abcbf9d","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.43@sha256:26be5e0b8c8f4c41c8a59126b29bb5d80b07253597472ded2a16bdd75abcbf9d"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.7","digest":"sha256:7545220a9aca134b71e51193ee0eaf4c50756ebf8fbd25a63ae7556e62815c00","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.7@sha256:7545220a9aca134b71e51193ee0eaf4c50756ebf8fbd25a63ae7556e62815c00"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196","pinned_image":"ghcr.io/github/gh-aw-node@sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196"},{"image":"ghcr.io/github/github-mcp-server:v1.8.0","digest":"sha256:d5a18c04b92714c309eb46a2305087e91a4dbd80420f6e462656699f95093520","pinned_image":"ghcr.io/github/github-mcp-server:v1.8.0@sha256:d5a18c04b92714c309eb46a2305087e91a4dbd80420f6e462656699f95093520"}]} +# 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":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"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.44","digest":"sha256:0d727725c737b58c7bdf51f640cffb928385ec46517e0917c7f1a02f1bada8b4","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.44@sha256:0d727725c737b58c7bdf51f640cffb928385ec46517e0917c7f1a02f1bada8b4"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.44","digest":"sha256:b50fbadba138f6e9aba94aca09711335c489bb3b15861220cb66f6092e042dc7","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.44@sha256:b50fbadba138f6e9aba94aca09711335c489bb3b15861220cb66f6092e042dc7"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.44","digest":"sha256:c064d15974f7c933ec7d3f7b4038f4fd203547b3154bdc821afd379144887eff","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.44@sha256:c064d15974f7c933ec7d3f7b4038f4fd203547b3154bdc821afd379144887eff"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.44","digest":"sha256:83e48bbe12c634be8c228a576832fe45f66c529ac3659db92bddbcf2eeb6d627","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.44@sha256:83e48bbe12c634be8c228a576832fe45f66c529ac3659db92bddbcf2eeb6d627"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.8","digest":"sha256:38bbea36cdb46a3c9d04d1db05e672966f5239b431a2022eb35881688e5721d8","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.8@sha256:38bbea36cdb46a3c9d04d1db05e672966f5239b431a2022eb35881688e5721d8"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196","pinned_image":"ghcr.io/github/gh-aw-node@sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196"},{"image":"ghcr.io/github/github-mcp-server:v1.8.0","digest":"sha256:d5a18c04b92714c309eb46a2305087e91a4dbd80420f6e462656699f95093520","pinned_image":"ghcr.io/github/github-mcp-server:v1.8.0@sha256:d5a18c04b92714c309eb46a2305087e91a4dbd80420f6e462656699f95093520"}]} # 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/pkg/actionpins/data/action_pins.json b/pkg/actionpins/data/action_pins.json index b1b9be1fbba..1aeb18aac35 100644 --- a/pkg/actionpins/data/action_pins.json +++ b/pkg/actionpins/data/action_pins.json @@ -165,6 +165,11 @@ } }, "containers": { + "ghcr.io/fabio-rovai/open-ontologies:latest": { + "image": "ghcr.io/fabio-rovai/open-ontologies:latest", + "digest": "sha256:2932c10682eac29ccf840a6bd6c4c7c82c5ce770ad9e94697d44057187452530", + "pinned_image": "ghcr.io/fabio-rovai/open-ontologies:latest@sha256:2932c10682eac29ccf840a6bd6c4c7c82c5ce770ad9e94697d44057187452530" + }, "ghcr.io/github/gh-aw-firewall/agent:0.27.43": { "image": "ghcr.io/github/gh-aw-firewall/agent:0.27.43", "digest": "sha256:04e2d1987a565000a8f114b89d806ae7a3864dd4f944be65275b28c93d8690e6", @@ -264,11 +269,6 @@ "image": "python:alpine", "digest": "sha256:26730869004e2b9c4b9ad09cab8625e81d256d1ce97e72df5520e806b1709f92", "pinned_image": "python:alpine@sha256:26730869004e2b9c4b9ad09cab8625e81d256d1ce97e72df5520e806b1709f92" - }, - "ghcr.io/fabio-rovai/open-ontologies:latest": { - "image": "ghcr.io/fabio-rovai/open-ontologies:latest", - "digest": "sha256:2932c10682eac29ccf840a6bd6c4c7c82c5ce770ad9e94697d44057187452530", - "pinned_image": "ghcr.io/fabio-rovai/open-ontologies:latest@sha256:2932c10682eac29ccf840a6bd6c4c7c82c5ce770ad9e94697d44057187452530" } } } diff --git a/pkg/workflow/data/action_pins.json b/pkg/workflow/data/action_pins.json index b1b9be1fbba..1aeb18aac35 100644 --- a/pkg/workflow/data/action_pins.json +++ b/pkg/workflow/data/action_pins.json @@ -165,6 +165,11 @@ } }, "containers": { + "ghcr.io/fabio-rovai/open-ontologies:latest": { + "image": "ghcr.io/fabio-rovai/open-ontologies:latest", + "digest": "sha256:2932c10682eac29ccf840a6bd6c4c7c82c5ce770ad9e94697d44057187452530", + "pinned_image": "ghcr.io/fabio-rovai/open-ontologies:latest@sha256:2932c10682eac29ccf840a6bd6c4c7c82c5ce770ad9e94697d44057187452530" + }, "ghcr.io/github/gh-aw-firewall/agent:0.27.43": { "image": "ghcr.io/github/gh-aw-firewall/agent:0.27.43", "digest": "sha256:04e2d1987a565000a8f114b89d806ae7a3864dd4f944be65275b28c93d8690e6", @@ -264,11 +269,6 @@ "image": "python:alpine", "digest": "sha256:26730869004e2b9c4b9ad09cab8625e81d256d1ce97e72df5520e806b1709f92", "pinned_image": "python:alpine@sha256:26730869004e2b9c4b9ad09cab8625e81d256d1ce97e72df5520e806b1709f92" - }, - "ghcr.io/fabio-rovai/open-ontologies:latest": { - "image": "ghcr.io/fabio-rovai/open-ontologies:latest", - "digest": "sha256:2932c10682eac29ccf840a6bd6c4c7c82c5ce770ad9e94697d44057187452530", - "pinned_image": "ghcr.io/fabio-rovai/open-ontologies:latest@sha256:2932c10682eac29ccf840a6bd6c4c7c82c5ce770ad9e94697d44057187452530" } } }