From 928932ea60e4e7f723d13ede9d33bc2a637a5c42 Mon Sep 17 00:00:00 2001 From: Landon Cox Date: Mon, 13 Apr 2026 21:11:41 -0700 Subject: [PATCH 1/2] fix: correct integrity level descriptions and auto-enable cli-proxy for reactions Three changes: 1. Fix incorrect min-integrity: unapproved descriptions in the maintaining-repos guide. The guide incorrectly described unapproved as allowing 'all community content' including 'everyone', which is the behavior of min-integrity: none. Fixed to accurately describe unapproved as including CONTRIBUTOR and FIRST_TIME_CONTRIBUTOR while filtering out FIRST_TIMER and NONE association. 2. Compiler: implicitly enable cli-proxy when integrity-reactions feature flag is set. Reaction-based integrity decisions require the proxy to identify reaction authors, so cli-proxy must be active. This avoids requiring users to set both features.integrity-reactions: true and features.cli-proxy: true manually. 3. Docs: rewrite integrity-reactions section to describe compiler defaults rather than showing explicit frontmatter for endorsement-reactions, disapproval-reactions, endorser-min-integrity, and disapproval-integrity. Note availability in v0.68.2 and clarify that reactions only work in proxy mode (not gateway mode). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../content/docs/guides/maintaining-repos.md | 32 +++--- pkg/workflow/compiler_difc_proxy.go | 13 ++- pkg/workflow/compiler_difc_proxy_test.go | 100 ++++++++++++++++++ pkg/workflow/docker.go | 7 +- 4 files changed, 132 insertions(+), 20 deletions(-) diff --git a/docs/src/content/docs/guides/maintaining-repos.md b/docs/src/content/docs/guides/maintaining-repos.md index 38e4716d821..f16fea6a11a 100644 --- a/docs/src/content/docs/guides/maintaining-repos.md +++ b/docs/src/content/docs/guides/maintaining-repos.md @@ -50,7 +50,7 @@ Review the newly opened issue. Based on the issue content: 5. Otherwise, post a comment thanking the contributor and explaining what information is still needed. ``` -`min-integrity: unapproved` allows repo-assist to see all community content — first-time contributors, external users, everyone. The `safe-outputs` block limits what repo-assist can do in response: it can only apply labels and post comments. Any other GitHub mutation (opening PRs, merging, closing issues) is blocked by the runtime, regardless of what the agent attempts. +`min-integrity: unapproved` allows repo-assist to see content from contributors who have previously interacted with the repository — including first-time contributors and users who have had PRs merged before — while still filtering out content from brand-new GitHub users (`FIRST_TIMER`) and users with no repository association (`NONE`). For most active repositories, this captures the vast majority of community input. The `safe-outputs` block limits what repo-assist can do in response: it can only apply labels and post comments. Any other GitHub mutation (opening PRs, merging, closing issues) is blocked by the runtime, regardless of what the agent attempts. ### Routing to Downstream Agents @@ -134,7 +134,7 @@ When a safe-output validation failure appears in your audit logs, it means the a ## Controlling Workflow Inputs with Integrity Filtering -Integrity filtering is the primary mechanism for controlling what content the agent sees. It evaluates the author of each issue, PR, or comment and removes items that don't meet the configured trust threshold — before the agent's context is assembled. Every public repository automatically applies `min-integrity: approved` as a baseline — repo-assist overrides this to `unapproved` so it can see all incoming issues. +Integrity filtering is the primary mechanism for controlling what content the agent sees. It evaluates the author of each issue, PR, or comment and removes items that don't meet the configured trust threshold — before the agent's context is assembled. Every public repository automatically applies `min-integrity: approved` as a baseline — repo-assist overrides this to `unapproved` so it can see issues from contributors and first-time contributors, not just trusted members. The four configurable levels, from most to least restrictive: @@ -147,7 +147,7 @@ The four configurable levels, from most to least restrictive: Choose based on what the workflow does: -- **Repo-assist / triage workflows**: `unapproved` — classify all community content without acting on it. +- **Repo-assist / triage workflows**: `unapproved` — classify content from contributors and first-time contributors without acting on it. - **Code-modifying workflows** (open PRs, apply patches, close issues): `approved` or `merged` — only act on trusted input. - **Spam detection or analytics**: `none` — see everything, but produce no direct GitHub mutations. @@ -202,30 +202,30 @@ The runtime automatically merges per-workflow values with the variable. Set thes ### Reactions as Trust Signals -Starting from MCPG v0.2.18, maintainers can use GitHub reactions (👍, ❤️) to promote content past the integrity filter without modifying labels. This is useful in repo-assist workflows where a maintainer wants to fast-track an external contribution: +Starting from gh-aw v0.68.2, maintainers can use GitHub reactions (👍, ❤️) to promote content past the integrity filter without modifying labels. This is useful in repo-assist workflows where a maintainer wants to fast-track an external contribution. + +To enable reactions, add the `integrity-reactions` feature flag: ```aw wrap features: integrity-reactions: true -mcp-gateway: - version: "v0.2.18" tools: github: min-integrity: approved - endorsement-reactions: - - "THUMBS_UP" - - "HEART" - disapproval-reactions: - - "THUMBS_DOWN" - - "CONFUSED" - endorser-min-integrity: approved - disapproval-integrity: none ``` -When a trusted member (at or above `endorser-min-integrity`) adds an endorsement reaction to an issue or comment, the item's integrity is promoted to `approved`. A disapproval reaction demotes it to the level set by `disapproval-integrity`. +The compiler handles the rest — when `integrity-reactions: true` is set, it automatically: + +- Enables the CLI proxy (`cli-proxy: true`), which is required for reaction-based integrity decisions +- Injects default endorsement reactions: `THUMBS_UP`, `HEART` +- Injects default disapproval reactions: `THUMBS_DOWN`, `CONFUSED` +- Uses `endorser-min-integrity: approved` (only reactions from owners, members, and collaborators count) +- Uses `disapproval-integrity: none` (a disapproval reaction demotes content to `none`) + +These defaults mean that when a trusted member (owner, member, or collaborator) adds a 👍 or ❤️ reaction to an issue or comment, the item's integrity is promoted to `approved` — making it visible to agents using `min-integrity: approved`. Conversely, a 👎 or 😕 reaction from a trusted member demotes the item to `none`. > [!IMPORTANT] -> Reactions only work when running through the MCPG proxy mode. They are not available in gateway mode. +> Reactions only work when running through the MCPG proxy mode. If `integrity-reactions` is enabled when MCPG is configured in gateway mode, a warning is logged and reactions are ignored for integrity decisions because the GitHub MCP server protocol does not expose reaction author information. See the [Integrity Filtering Reference](/gh-aw/reference/integrity/) for complete configuration details. diff --git a/pkg/workflow/compiler_difc_proxy.go b/pkg/workflow/compiler_difc_proxy.go index a8707d29cae..1a1ad408d6f 100644 --- a/pkg/workflow/compiler_difc_proxy.go +++ b/pkg/workflow/compiler_difc_proxy.go @@ -334,13 +334,22 @@ func (c *Compiler) generateStopDIFCProxyStep(yaml *strings.Builder, data *Workfl // isCliProxyNeeded returns true if the CLI proxy should be started on the host. // // The CLI proxy is needed when: -// 1. The cli-proxy feature flag is enabled, and +// 1. The cli-proxy feature flag is enabled (explicitly or implicitly), and // 2. The AWF sandbox (firewall) is enabled, and // 3. The AWF version supports CLI proxy flags +// +// The cli-proxy feature is implicitly enabled when integrity-reactions is enabled, +// because reaction-based integrity decisions require the proxy to identify reaction authors. func isCliProxyNeeded(data *WorkflowData) bool { - if !isFeatureEnabled(constants.CliProxyFeatureFlag, data) { + cliProxyEnabled := isFeatureEnabled(constants.CliProxyFeatureFlag, data) + integrityReactionsEnabled := isFeatureEnabled(constants.IntegrityReactionsFeatureFlag, data) + + if !cliProxyEnabled && !integrityReactionsEnabled { return false } + if integrityReactionsEnabled && !cliProxyEnabled { + difcProxyLog.Print("integrity-reactions enabled: implicitly enabling CLI proxy") + } if !isFirewallEnabled(data) { return false } diff --git a/pkg/workflow/compiler_difc_proxy_test.go b/pkg/workflow/compiler_difc_proxy_test.go index 006c8e022e7..3e4f289c1ff 100644 --- a/pkg/workflow/compiler_difc_proxy_test.go +++ b/pkg/workflow/compiler_difc_proxy_test.go @@ -810,3 +810,103 @@ func TestResolveProxyContainerImage(t *testing.T) { }) } } + +// TestIsCliProxyNeeded_IntegrityReactionsImplicitEnable verifies that the CLI proxy +// is implicitly enabled when the integrity-reactions feature flag is set, even without +// an explicit cli-proxy feature flag. +func TestIsCliProxyNeeded_IntegrityReactionsImplicitEnable(t *testing.T) { + awfVersion := "0.25.20" + + tests := []struct { + name string + data *WorkflowData + expected bool + desc string + }{ + { + name: "integrity-reactions enables cli proxy implicitly", + data: &WorkflowData{ + NetworkPermissions: &NetworkPermissions{ + Firewall: &FirewallConfig{ + Enabled: true, + Version: awfVersion, + }, + }, + Features: map[string]any{"integrity-reactions": true}, + }, + expected: true, + desc: "integrity-reactions should implicitly enable the CLI proxy", + }, + { + name: "explicit cli-proxy still works", + data: &WorkflowData{ + NetworkPermissions: &NetworkPermissions{ + Firewall: &FirewallConfig{ + Enabled: true, + Version: awfVersion, + }, + }, + Features: map[string]any{"cli-proxy": true}, + }, + expected: true, + desc: "explicit cli-proxy feature flag should still enable the CLI proxy", + }, + { + name: "both flags enabled", + data: &WorkflowData{ + NetworkPermissions: &NetworkPermissions{ + Firewall: &FirewallConfig{ + Enabled: true, + Version: awfVersion, + }, + }, + Features: map[string]any{"cli-proxy": true, "integrity-reactions": true}, + }, + expected: true, + desc: "both flags together should enable the CLI proxy", + }, + { + name: "neither flag set", + data: &WorkflowData{ + NetworkPermissions: &NetworkPermissions{ + Firewall: &FirewallConfig{ + Enabled: true, + Version: awfVersion, + }, + }, + Features: map[string]any{}, + }, + expected: false, + desc: "no feature flags should not enable the CLI proxy", + }, + { + name: "integrity-reactions without firewall", + data: &WorkflowData{ + Features: map[string]any{"integrity-reactions": true}, + }, + expected: false, + desc: "integrity-reactions without firewall should not enable the CLI proxy", + }, + { + name: "integrity-reactions with old AWF version", + data: &WorkflowData{ + NetworkPermissions: &NetworkPermissions{ + Firewall: &FirewallConfig{ + Enabled: true, + Version: "v0.25.16", + }, + }, + Features: map[string]any{"integrity-reactions": true}, + }, + expected: false, + desc: "integrity-reactions with old AWF version should not enable the CLI proxy", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := isCliProxyNeeded(tt.data) + assert.Equal(t, tt.expected, got, tt.desc) + }) + } +} diff --git a/pkg/workflow/docker.go b/pkg/workflow/docker.go index 6dbe2b8efb1..25588370afb 100644 --- a/pkg/workflow/docker.go +++ b/pkg/workflow/docker.go @@ -103,10 +103,13 @@ func collectDockerImages(tools map[string]any, workflowData *WorkflowData, actio } } - // Add cli-proxy sidecar container when the cli-proxy feature flag is enabled + // Add cli-proxy sidecar container when the cli-proxy is needed (explicitly via + // cli-proxy feature flag, or implicitly via integrity-reactions feature flag) // and the AWF version supports it. Without this, --skip-pull causes AWF to fail // because the cli-proxy image was never pulled. - if isFeatureEnabled(constants.CliProxyFeatureFlag, workflowData) && awfSupportsCliProxy(firewallConfig) { + cliProxyNeeded := isFeatureEnabled(constants.CliProxyFeatureFlag, workflowData) || + isFeatureEnabled(constants.IntegrityReactionsFeatureFlag, workflowData) + if cliProxyNeeded && awfSupportsCliProxy(firewallConfig) { cliProxyImage := constants.DefaultFirewallRegistry + "/cli-proxy:" + awfImageTag if !imageSet[cliProxyImage] { images = append(images, cliProxyImage) From bbd1375b0a34a04d0508e21b44e2c16a307bbc33 Mon Sep 17 00:00:00 2001 From: Landon Cox Date: Mon, 13 Apr 2026 21:13:32 -0700 Subject: [PATCH 2/2] docs: remove proxy mode warning from reactions section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the compiler now implicitly enables cli-proxy when integrity-reactions: true is set, the warning about proxy mode is unnecessary — reactions are guaranteed to run through the proxy. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/src/content/docs/guides/maintaining-repos.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/src/content/docs/guides/maintaining-repos.md b/docs/src/content/docs/guides/maintaining-repos.md index f16fea6a11a..4f68f899dc1 100644 --- a/docs/src/content/docs/guides/maintaining-repos.md +++ b/docs/src/content/docs/guides/maintaining-repos.md @@ -224,9 +224,6 @@ The compiler handles the rest — when `integrity-reactions: true` is set, it au These defaults mean that when a trusted member (owner, member, or collaborator) adds a 👍 or ❤️ reaction to an issue or comment, the item's integrity is promoted to `approved` — making it visible to agents using `min-integrity: approved`. Conversely, a 👎 or 😕 reaction from a trusted member demotes the item to `none`. -> [!IMPORTANT] -> Reactions only work when running through the MCPG proxy mode. If `integrity-reactions` is enabled when MCPG is configured in gateway mode, a warning is logged and reactions are ignored for integrity decisions because the GitHub MCP server protocol does not expose reaction author information. - See the [Integrity Filtering Reference](/gh-aw/reference/integrity/) for complete configuration details. ## Scaling Strategies