From e9cc2662d4576f7be592df52224d045518be64aa Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 21 Mar 2026 15:21:05 +0000
Subject: [PATCH 1/7] Initial plan


From b345160d53fb1038fba057936f2b1b57575e6fbe Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 21 Mar 2026 15:42:38 +0000
Subject: [PATCH 2/7] Harden release community attribution with multi-tier
 approach and GitHub-native linkage

- Add GitHub MCP tools to release.md frontmatter for cross-reference queries
- Add closingIssuesReferences to PR fetch for GitHub-native close links
- Pre-build closing_refs_by_issue.json and community_issues_closed_in_window.json
- Replace single PR-body-only attribution with 4-tier approach:
  Tier 1: GitHub-native closing refs (primary)
  Tier 2: PR body keyword parsing with bare+qualified refs (fallback)
  Tier 3: GitHub MCP issue_read for follow-up/split chains
  Tier 4: Surface ambiguous cases for review (fail soft)
- Create shared/community-attribution.md for reusable attribution logic
- Recompile all lock files

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/75485530-a319-41ef-8e3e-bba99414cede
---
 .github/workflows/release.lock.yml            |  29 ++--
 .github/workflows/release.md                  | 136 ++++++++++++++++--
 .../workflows/shared/community-attribution.md | 104 ++++++++++++++
 3 files changed, 249 insertions(+), 20 deletions(-)
 create mode 100644 .github/workflows/shared/community-attribution.md

diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml
index bb963979cdb..c6543fba1af 100644
--- a/.github/workflows/release.lock.yml
+++ b/.github/workflows/release.lock.yml
@@ -22,7 +22,11 @@
 #
 # Build, test, and release gh-aw extension, then generate and prepend release highlights
 #
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"5219f3be0d79b84fde78c4e4699d10bc376e7ba113c8403197534753d66ef0c8","strict":true,"agent_id":"copilot"}
+# Resolved workflow manifest:
+#   Imports:
+#     - shared/community-attribution.md
+#
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"c3af35d56c9f78113b5d5b284f067cd9c951934d63aaf69520f04ed156733607","strict":true,"agent_id":"copilot"}
 
 name: "Release"
 "on":
@@ -182,6 +186,9 @@ jobs:
           </system>
           GH_AW_PROMPT_EOF
           cat << 'GH_AW_PROMPT_EOF'
+          {{#runtime-import .github/workflows/shared/community-attribution.md}}
+          GH_AW_PROMPT_EOF
+          cat << 'GH_AW_PROMPT_EOF'
           {{#runtime-import .github/workflows/release.md}}
           GH_AW_PROMPT_EOF
           } > "$GH_AW_PROMPT"
@@ -308,7 +315,7 @@ jobs:
           RELEASE_ID: ${{ needs.release.outputs.release_id }}
           RELEASE_TAG: ${{ needs.config.outputs.release_tag }}
         name: Setup release environment
-        run: "set -e\nmkdir -p /tmp/gh-aw/release-data\n\n# Use the release ID and tag from the release job\necho \"Release ID from release job: $RELEASE_ID\"\necho \"Release tag from release job: $RELEASE_TAG\"\n\necho \"Processing release: $RELEASE_TAG\"\necho \"RELEASE_TAG=$RELEASE_TAG\" >> \"$GITHUB_ENV\"\n\n# Get the current release information\n# Use release ID to fetch release data\ngh api \"/repos/${{ github.repository }}/releases/$RELEASE_ID\" > /tmp/gh-aw/release-data/current_release.json\necho \"✓ Fetched current release information\"\n\n# Get the previous release to determine the range\nPREV_RELEASE_TAG=$(gh release list --limit 2 --json tagName --jq '.[1].tagName // empty')\n\nif [ -z \"$PREV_RELEASE_TAG\" ]; then\n  echo \"No previous release found. This appears to be the first release.\"\n  echo \"PREV_RELEASE_TAG=\" >> \"$GITHUB_ENV\"\n  touch /tmp/gh-aw/release-data/pull_requests.json\n  echo \"[]\" > /tmp/gh-aw/release-data/pull_requests.json\nelse\n  echo \"Previous release: $PREV_RELEASE_TAG\"\n  echo \"PREV_RELEASE_TAG=$PREV_RELEASE_TAG\" >> \"$GITHUB_ENV\"\n  \n  # Get commits between releases\n  echo \"Fetching commits between $PREV_RELEASE_TAG and $RELEASE_TAG...\"\n  git fetch --unshallow 2>/dev/null || git fetch --depth=1000\n  \n  # Get all merged PRs between the two releases\n  echo \"Fetching pull requests merged between releases...\"\n  PREV_PUBLISHED_AT=$(gh release view \"$PREV_RELEASE_TAG\" --json publishedAt --jq .publishedAt)\n  CURR_PUBLISHED_AT=$(gh release view \"$RELEASE_TAG\" --json publishedAt --jq .publishedAt)\n  gh pr list \\\n    --state merged \\\n    --limit 1000 \\\n    --json number,title,author,labels,mergedAt,url,body \\\n    --jq \"[.[] | select(.mergedAt >= \\\"$PREV_PUBLISHED_AT\\\" and .mergedAt <= \\\"$CURR_PUBLISHED_AT\\\")]\" \\\n    > /tmp/gh-aw/release-data/pull_requests.json\n  \n  PR_COUNT=$(jq length \"/tmp/gh-aw/release-data/pull_requests.json\")\n  echo \"✓ Fetched $PR_COUNT pull requests\"\nfi\n\n# Fetch community-labeled issues\necho \"Fetching issues with 'community' label...\"\nif ! gh issue list \\\n  --label \"community\" \\\n  --state all \\\n  --limit 500 \\\n  --json number,title,author,labels,closedAt,url \\\n  > /tmp/gh-aw/release-data/community_issues.json; then\n  echo \"[]\" > /tmp/gh-aw/release-data/community_issues.json\nfi\n\nCOMMUNITY_COUNT=$(jq length \"/tmp/gh-aw/release-data/community_issues.json\")\necho \"✓ Fetched $COMMUNITY_COUNT community-labeled issues\"\n\n# Get the CHANGELOG.md content around this version\nif [ -f \"CHANGELOG.md\" ]; then\n  cp CHANGELOG.md /tmp/gh-aw/release-data/CHANGELOG.md\n  echo \"✓ Copied CHANGELOG.md for reference\"\nfi\n\n# List documentation files for linking\nfind docs -type f -name \"*.md\" 2>/dev/null > /tmp/gh-aw/release-data/docs_files.txt || echo \"No docs directory found\"\n\necho \"✓ Setup complete. Data available in /tmp/gh-aw/release-data/\""
+        run: "set -e\nmkdir -p /tmp/gh-aw/release-data\n\n# Use the release ID and tag from the release job\necho \"Release ID from release job: $RELEASE_ID\"\necho \"Release tag from release job: $RELEASE_TAG\"\n\necho \"Processing release: $RELEASE_TAG\"\necho \"RELEASE_TAG=$RELEASE_TAG\" >> \"$GITHUB_ENV\"\n\n# Get the current release information\n# Use release ID to fetch release data\ngh api \"/repos/${{ github.repository }}/releases/$RELEASE_ID\" > /tmp/gh-aw/release-data/current_release.json\necho \"✓ Fetched current release information\"\n\n# Get the previous release to determine the range\nPREV_RELEASE_TAG=$(gh release list --limit 2 --json tagName --jq '.[1].tagName // empty')\n\nif [ -z \"$PREV_RELEASE_TAG\" ]; then\n  echo \"No previous release found. This appears to be the first release.\"\n  echo \"PREV_RELEASE_TAG=\" >> \"$GITHUB_ENV\"\n  touch /tmp/gh-aw/release-data/pull_requests.json\n  echo \"[]\" > /tmp/gh-aw/release-data/pull_requests.json\nelse\n  echo \"Previous release: $PREV_RELEASE_TAG\"\n  echo \"PREV_RELEASE_TAG=$PREV_RELEASE_TAG\" >> \"$GITHUB_ENV\"\n  \n  # Get commits between releases\n  echo \"Fetching commits between $PREV_RELEASE_TAG and $RELEASE_TAG...\"\n  git fetch --unshallow 2>/dev/null || git fetch --depth=1000\n  \n  # Get all merged PRs between the two releases (include closingIssuesReferences for attribution)\n  echo \"Fetching pull requests merged between releases...\"\n  PREV_PUBLISHED_AT=$(gh release view \"$PREV_RELEASE_TAG\" --json publishedAt --jq .publishedAt)\n  CURR_PUBLISHED_AT=$(gh release view \"$RELEASE_TAG\" --json publishedAt --jq .publishedAt)\n  gh pr list \\\n    --state merged \\\n    --limit 1000 \\\n    --json number,title,author,labels,mergedAt,url,body,closingIssuesReferences \\\n    --jq \"[.[] | select(.mergedAt >= \\\"$PREV_PUBLISHED_AT\\\" and .mergedAt <= \\\"$CURR_PUBLISHED_AT\\\")]\" \\\n    > /tmp/gh-aw/release-data/pull_requests.json\n  \n  PR_COUNT=$(jq length \"/tmp/gh-aw/release-data/pull_requests.json\")\n  echo \"✓ Fetched $PR_COUNT pull requests\"\nfi\n\n# Fetch community-labeled issues (include createdAt for timeline correlation)\necho \"Fetching issues with 'community' label...\"\nif ! gh issue list \\\n  --label \"community\" \\\n  --state all \\\n  --limit 500 \\\n  --json number,title,author,labels,closedAt,createdAt,url \\\n  > /tmp/gh-aw/release-data/community_issues.json; then\n  echo \"[]\" > /tmp/gh-aw/release-data/community_issues.json\nfi\n\nCOMMUNITY_COUNT=$(jq length \"/tmp/gh-aw/release-data/community_issues.json\")\necho \"✓ Fetched $COMMUNITY_COUNT community-labeled issues\"\n\n# Build closing references index from GitHub-native closingIssuesReferences\n# Maps each closed issue number -> list of PR numbers that directly close it\necho \"Building closing references index from GitHub-native PR links...\"\njq '\n  reduce .[] as $pr (\n    {};\n    $pr.closingIssuesReferences[]? as $issue |\n    ($issue.number | tostring) as $key |\n    .[$key] = (.[$key] // []) + [$pr.number]\n  )\n' /tmp/gh-aw/release-data/pull_requests.json \\\n  > /tmp/gh-aw/release-data/closing_refs_by_issue.json 2>/dev/null \\\n  || echo \"{}\" > /tmp/gh-aw/release-data/closing_refs_by_issue.json\n\nDIRECT_CLOSE_COUNT=$(jq 'keys | length' /tmp/gh-aw/release-data/closing_refs_by_issue.json)\necho \"✓ Found $DIRECT_CLOSE_COUNT issues with GitHub-native closing PR references\"\n\n# Find community issues closed during this release window (candidates for attribution review)\nif [ -n \"$PREV_PUBLISHED_AT\" ]; then\n  jq --arg prev \"$PREV_PUBLISHED_AT\" --arg curr \"$CURR_PUBLISHED_AT\" \\\n    '[.[] | select(.closedAt != null and .closedAt >= $prev and .closedAt <= $curr)]' \\\n    /tmp/gh-aw/release-data/community_issues.json \\\n    > /tmp/gh-aw/release-data/community_issues_closed_in_window.json 2>/dev/null \\\n    || echo \"[]\" > /tmp/gh-aw/release-data/community_issues_closed_in_window.json\n  \n  CLOSED_IN_WINDOW=$(jq length /tmp/gh-aw/release-data/community_issues_closed_in_window.json)\n  echo \"✓ Found $CLOSED_IN_WINDOW community issues closed in this release window\"\nelse\n  echo \"[]\" > /tmp/gh-aw/release-data/community_issues_closed_in_window.json\nfi\n\n# Get the CHANGELOG.md content around this version\nif [ -f \"CHANGELOG.md\" ]; then\n  cp CHANGELOG.md /tmp/gh-aw/release-data/CHANGELOG.md\n  echo \"✓ Copied CHANGELOG.md for reference\"\nfi\n\n# List documentation files for linking\nfind docs -type f -name \"*.md\" 2>/dev/null > /tmp/gh-aw/release-data/docs_files.txt || echo \"No docs directory found\"\n\necho \"✓ Setup complete. Data available in /tmp/gh-aw/release-data/\"\necho \"  Files: current_release.json, pull_requests.json, community_issues.json,\"\necho \"         closing_refs_by_issue.json, community_issues_closed_in_window.json,\"\necho \"         CHANGELOG.md (if exists), docs_files.txt\""
 
       - name: Configure Git credentials
         env:
@@ -353,7 +360,7 @@ jobs:
             const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs');
             await determineAutomaticLockdown(github, context, core);
       - name: Download container images
-        run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.24.5 ghcr.io/github/gh-aw-firewall/api-proxy:0.24.5 ghcr.io/github/gh-aw-firewall/squid:0.24.5 ghcr.io/github/gh-aw-mcpg:v0.1.20 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.24.5 ghcr.io/github/gh-aw-firewall/api-proxy:0.24.5 ghcr.io/github/gh-aw-firewall/squid:0.24.5 ghcr.io/github/gh-aw-mcpg:v0.1.20 node:lts-alpine
       - name: Write Safe Outputs Config
         run: |
           mkdir -p ${RUNNER_TEMP}/gh-aw/safeoutputs
@@ -523,20 +530,24 @@ jobs:
           export DEBUG="*"
           
           export GH_AW_ENGINE="copilot"
-          export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.1.20'
+          export GITHUB_PERSONAL_ACCESS_TOKEN="$GITHUB_MCP_SERVER_TOKEN"
+          export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_PERSONAL_ACCESS_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.1.20'
           
           mkdir -p /home/runner/.copilot
           cat << GH_AW_MCP_CONFIG_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh
           {
             "mcpServers": {
               "github": {
-                "type": "stdio",
-                "container": "ghcr.io/github/github-mcp-server:v0.32.0",
+                "type": "http",
+                "url": "https://api.githubcopilot.com/mcp/",
+                "headers": {
+                  "Authorization": "Bearer \${GITHUB_PERSONAL_ACCESS_TOKEN}",
+                  "X-MCP-Readonly": "true",
+                  "X-MCP-Toolsets": "issues,pull_requests"
+                },
                 "env": {
-                  "GITHUB_HOST": "\${GITHUB_SERVER_URL}",
                   "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
-                  "GITHUB_READ_ONLY": "1",
-                  "GITHUB_TOOLSETS": "context,repos,issues,pull_requests"
+                  "GITHUB_HOST": "\${GITHUB_SERVER_URL}"
                 },
                 "guard-policies": {
                   "allow-only": {
diff --git a/.github/workflows/release.md b/.github/workflows/release.md
index fe2f88797da..91270886ba0 100644
--- a/.github/workflows/release.md
+++ b/.github/workflows/release.md
@@ -28,8 +28,14 @@ network:
     - defaults
     - node
     - "github.github.com"
+tools:
+  github:
+    mode: "remote"
+    toolsets: [issues, pull_requests]
 safe-outputs:
   update-release:
+imports:
+  - shared/community-attribution.md
 jobs:
   config:
     needs: ["pre_activation", "activation"]
@@ -398,14 +404,14 @@ steps:
         echo "Fetching commits between $PREV_RELEASE_TAG and $RELEASE_TAG..."
         git fetch --unshallow 2>/dev/null || git fetch --depth=1000
         
-        # Get all merged PRs between the two releases
+        # Get all merged PRs between the two releases (include closingIssuesReferences for attribution)
         echo "Fetching pull requests merged between releases..."
         PREV_PUBLISHED_AT=$(gh release view "$PREV_RELEASE_TAG" --json publishedAt --jq .publishedAt)
         CURR_PUBLISHED_AT=$(gh release view "$RELEASE_TAG" --json publishedAt --jq .publishedAt)
         gh pr list \
           --state merged \
           --limit 1000 \
-          --json number,title,author,labels,mergedAt,url,body \
+          --json number,title,author,labels,mergedAt,url,body,closingIssuesReferences \
           --jq "[.[] | select(.mergedAt >= \"$PREV_PUBLISHED_AT\" and .mergedAt <= \"$CURR_PUBLISHED_AT\")]" \
           > /tmp/gh-aw/release-data/pull_requests.json
         
@@ -413,13 +419,13 @@ steps:
         echo "✓ Fetched $PR_COUNT pull requests"
       fi
       
-      # Fetch community-labeled issues
+      # Fetch community-labeled issues (include createdAt for timeline correlation)
       echo "Fetching issues with 'community' label..."
       if ! gh issue list \
         --label "community" \
         --state all \
         --limit 500 \
-        --json number,title,author,labels,closedAt,url \
+        --json number,title,author,labels,closedAt,createdAt,url \
         > /tmp/gh-aw/release-data/community_issues.json; then
         echo "[]" > /tmp/gh-aw/release-data/community_issues.json
       fi
@@ -427,6 +433,37 @@ steps:
       COMMUNITY_COUNT=$(jq length "/tmp/gh-aw/release-data/community_issues.json")
       echo "✓ Fetched $COMMUNITY_COUNT community-labeled issues"
       
+      # Build closing references index from GitHub-native closingIssuesReferences
+      # Maps each closed issue number -> list of PR numbers that directly close it
+      echo "Building closing references index from GitHub-native PR links..."
+      jq '
+        reduce .[] as $pr (
+          {};
+          $pr.closingIssuesReferences[]? as $issue |
+          ($issue.number | tostring) as $key |
+          .[$key] = (.[$key] // []) + [$pr.number]
+        )
+      ' /tmp/gh-aw/release-data/pull_requests.json \
+        > /tmp/gh-aw/release-data/closing_refs_by_issue.json 2>/dev/null \
+        || echo "{}" > /tmp/gh-aw/release-data/closing_refs_by_issue.json
+      
+      DIRECT_CLOSE_COUNT=$(jq 'keys | length' /tmp/gh-aw/release-data/closing_refs_by_issue.json)
+      echo "✓ Found $DIRECT_CLOSE_COUNT issues with GitHub-native closing PR references"
+      
+      # Find community issues closed during this release window (candidates for attribution review)
+      if [ -n "$PREV_PUBLISHED_AT" ]; then
+        jq --arg prev "$PREV_PUBLISHED_AT" --arg curr "$CURR_PUBLISHED_AT" \
+          '[.[] | select(.closedAt != null and .closedAt >= $prev and .closedAt <= $curr)]' \
+          /tmp/gh-aw/release-data/community_issues.json \
+          > /tmp/gh-aw/release-data/community_issues_closed_in_window.json 2>/dev/null \
+          || echo "[]" > /tmp/gh-aw/release-data/community_issues_closed_in_window.json
+        
+        CLOSED_IN_WINDOW=$(jq length /tmp/gh-aw/release-data/community_issues_closed_in_window.json)
+        echo "✓ Found $CLOSED_IN_WINDOW community issues closed in this release window"
+      else
+        echo "[]" > /tmp/gh-aw/release-data/community_issues_closed_in_window.json
+      fi
+      
       # Get the CHANGELOG.md content around this version
       if [ -f "CHANGELOG.md" ]; then
         cp CHANGELOG.md /tmp/gh-aw/release-data/CHANGELOG.md
@@ -437,6 +474,9 @@ steps:
       find docs -type f -name "*.md" 2>/dev/null > /tmp/gh-aw/release-data/docs_files.txt || echo "No docs directory found"
       
       echo "✓ Setup complete. Data available in /tmp/gh-aw/release-data/"
+      echo "  Files: current_release.json, pull_requests.json, community_issues.json,"
+      echo "         closing_refs_by_issue.json, community_issues_closed_in_window.json,"
+      echo "         CHANGELOG.md (if exists), docs_files.txt"
 ---
 
 # Release Highlights Generator
@@ -449,8 +489,10 @@ Generate an engaging release highlights summary for **${{ github.repository }}**
 
 All data is pre-fetched in `/tmp/gh-aw/release-data/`:
 - `current_release.json` - Release metadata (tag, name, dates, existing body)
-- `pull_requests.json` - PRs merged between `${PREV_RELEASE_TAG}` and `${RELEASE_TAG}` (empty array if first release)
-- `community_issues.json` - All issues labeled `community` (issue number, title, author, closedAt, url)
+- `pull_requests.json` - PRs merged between `${PREV_RELEASE_TAG}` and `${RELEASE_TAG}` (includes `closingIssuesReferences` for each PR; empty array if first release)
+- `community_issues.json` - All issues labeled `community` (issue number, title, author, closedAt, createdAt, url)
+- `closing_refs_by_issue.json` - Map of `{issue_number: [pr_numbers]}` built from GitHub-native closing references in merged PRs
+- `community_issues_closed_in_window.json` - Community issues whose `closedAt` falls within this release window (attribution candidates)
 - `CHANGELOG.md` - Full changelog for context (if exists)
 - `docs_files.txt` - Available documentation files for linking
 
@@ -484,24 +526,89 @@ head -100 /tmp/gh-aw/release-data/CHANGELOG.md 2>/dev/null || echo "No CHANGELOG
 cat /tmp/gh-aw/release-data/docs_files.txt
 ```
 
+### 1. Load Data
+
+```bash
+# View release metadata
+cat /tmp/gh-aw/release-data/current_release.json | jq
+
+# List PRs (empty if first release)
+cat /tmp/gh-aw/release-data/pull_requests.json | jq -r '.[] | "- #\(.number): \(.title) by @\(.author.login)"'
+
+# List community issues
+cat /tmp/gh-aw/release-data/community_issues.json | jq -r '.[] | "- #\(.number): \(.title) by @\(.author.login)"'
+
+# View GitHub-native closing references (issue -> [PRs])
+cat /tmp/gh-aw/release-data/closing_refs_by_issue.json | jq
+
+# List community issues closed in this release window (attribution candidates)
+cat /tmp/gh-aw/release-data/community_issues_closed_in_window.json | jq -r '.[] | "- #\(.number): \(.title) by @\(.author.login) (closed: \(.closedAt))"'
+
+# Check CHANGELOG context
+head -100 /tmp/gh-aw/release-data/CHANGELOG.md 2>/dev/null || echo "No CHANGELOG"
+
+# View available docs
+cat /tmp/gh-aw/release-data/docs_files.txt
+```
+
 ### 2. Identify Community Contributions
 
-Cross-reference `community_issues.json` with `pull_requests.json` to find which community issues are resolved in this release.
+Cross-reference `community_issues.json` with `pull_requests.json` to find which community issues are resolved in this release. Use a **tiered approach** — work through all tiers before concluding attribution, and do **not** silently omit ambiguous cases.
+
+#### Tier 1 — GitHub-native closing references (primary)
+
+`closing_refs_by_issue.json` contains GitHub's own link metadata: the set of issues that each merged PR is marked as "closing" via the native GitHub close-with-keyword feature. This is the most reliable signal.
+
+```bash
+# Get all community issue numbers
+COMMUNITY_NUMBERS=$(jq '[.[].number]' /tmp/gh-aw/release-data/community_issues.json)
+
+# Find community issues that have a GitHub-native closing PR in this release
+jq --argjson community "$COMMUNITY_NUMBERS" \
+  'to_entries | map(select((.key | tonumber) as $n | $community | any(. == $n))) | from_entries' \
+  /tmp/gh-aw/release-data/closing_refs_by_issue.json
+```
 
-A community issue is considered resolved in this release if any PR in `pull_requests.json` references its number in the PR body (e.g., `Fixes #123`, `Closes #123`, `Resolves #123`).
+For each matched issue, record it as **confirmed** attribution.
+
+#### Tier 2 — PR body keyword parsing (secondary fallback)
+
+For community issues **not yet matched** in Tier 1, search PR bodies for closing keywords. This covers cases where authors used keywords but GitHub's native link was not established (e.g., fully-qualified repo references).
 
 ```bash
-# Extract PR bodies and cross-reference with community issue numbers
+# Supports both bare (#123) and fully-qualified (org/repo#123) references
 cat /tmp/gh-aw/release-data/pull_requests.json | jq -r '.[].body // ""' | \
-  grep -oP '(?i)(close[sd]?|fix(e[sd])?|resolve[sd]?)\s*#\K[0-9]+' | sort -u
+  grep -oP '(?i)(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s*(?:github/gh-aw#|#)\K[0-9]+' | sort -u
 ```
 
+Add any newly matched community issues to the **confirmed** list.
+
+#### Tier 3 — GitHub MCP cross-reference lookup (deep investigation for follow-up chains)
+
+For community issues **still unmatched** after Tiers 1 and 2, use the GitHub MCP `issue_read` tool to check whether the issue is linked to a follow-up or split issue whose fix shipped in this release. This handles the case where a community report was routed through a separate tracking issue.
+
+For each unmatched community issue that was closed during this release window (from `community_issues_closed_in_window.json`):
+
+1. Use `issue_read` with `method: "get_comments"` to scan the issue body and comments for references to other issues or PRs.
+2. Check whether any referenced issue number appears as a closing target in `closing_refs_by_issue.json` or in the PR bodies already scanned.
+3. If a transitive chain is found (community issue → follow-up issue → merged PR), record it as **confirmed (via follow-up)** attribution and note the chain (e.g., "via follow-up #N").
+
+#### Tier 4 — Surface ambiguous attribution candidates for review
+
+After all three active tiers, check `community_issues_closed_in_window.json` for any community issues that were closed during this release window but **could not be linked** to a specific merged PR through any tier. These should **not be silently dropped** — instead surface them in a dedicated review section.
+
+```bash
+# Check for community issues closed in window but not yet attributed
+cat /tmp/gh-aw/release-data/community_issues_closed_in_window.json | jq 'length'
+```
+
+If any unlinked candidates exist, add them to the **"⚠️ Attribution Candidates Need Review"** subsection (see output format below).
+
 For each community issue resolved in this release, note the **issue author** from `community_issues.json`. These are the community contributors to celebrate.
 
 ### 3. Categorize & Prioritize
 
 Group PRs by category (omit categories with no items):
-- **✨ New Features** - User-facing capabilities
 - **🐛 Bug Fixes** - Issue resolutions
 - **⚡ Performance** - Speed/efficiency improvements
 - **📚 Documentation** - Guide/reference updates
@@ -532,8 +639,15 @@ Structure:
 [Only if any community-labeled issues are resolved in this release]
 A huge thank you to the community members who reported issues that were resolved in this release:
 - **@[author]** for [issue title] ([#number](url))
+  - _(via follow-up #N)_ — include only when attribution was confirmed through a follow-up issue chain
 [One entry per community issue author. Omit this section entirely if no community issues are resolved.]
 
+### ⚠️ Attribution Candidates Need Review
+[Only if Tier 4 found community issues closed in this release window with no confirmed linkage]
+The following community issues were closed during this release window but could not be automatically linked to a specific merged PR. Please verify whether they should be credited:
+- **@[author]** for [issue title] ([#number](url)) — closed [date], no confirmed PR linkage found
+[Omit this section entirely if all closed community issues have confirmed attribution.]
+
 ---
 For complete details, see [CHANGELOG](https://github.com/github/gh-aw/blob/main/CHANGELOG.md).
 ```
diff --git a/.github/workflows/shared/community-attribution.md b/.github/workflows/shared/community-attribution.md
new file mode 100644
index 00000000000..80576619e89
--- /dev/null
+++ b/.github/workflows/shared/community-attribution.md
@@ -0,0 +1,104 @@
+<!--
+This shared component documents the tiered strategy for reliably attributing
+community contributions in release notes.
+
+The following pre-fetched files must exist before applying this strategy.
+They are typically produced by the release setup step:
+
+- merged pull requests with closing issue references
+- community-labeled issues with closed timestamps
+- a closing references index mapping issue numbers to PR numbers
+- community issues closed within the release window
+-->
+
+## Community Attribution Strategy
+
+Use the following **four-tier** approach to identify which community-labeled
+issues were resolved in a release.  Work through all tiers before concluding,
+and never silently drop a community issue that was closed during the release window.
+
+### Tier 1 — GitHub-native closing references (primary)
+
+`closing_refs_by_issue.json` records the issues that GitHub itself marks as
+"closed by" each merged PR (the native close-with-keyword feature).  This is
+the strongest signal because it does not depend on free-text conventions.
+
+```bash
+COMMUNITY_NUMBERS=$(jq '[.[].number]' /tmp/gh-aw/release-data/community_issues.json)
+
+jq --argjson community "$COMMUNITY_NUMBERS" \
+  'to_entries
+   | map(select((.key | tonumber) as $n | $community | any(. == $n)))
+   | from_entries' \
+  /tmp/gh-aw/release-data/closing_refs_by_issue.json
+```
+
+Record every matched issue as **confirmed** attribution.
+
+### Tier 2 — PR body keyword parsing (secondary fallback)
+
+For issues **not yet matched** in Tier 1, scan PR bodies for the standard
+closing keywords.  Both bare (`#123`) and fully-qualified (`org/repo#123`)
+forms are supported.
+
+```bash
+jq -r '.[].body // ""' /tmp/gh-aw/release-data/pull_requests.json \
+  | grep -oP '(?i)(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s*(?:github/gh-aw#|#)\K[0-9]+' \
+  | sort -u
+```
+
+Add any newly matched community issues to the **confirmed** list.
+
+### Tier 3 — GitHub MCP cross-reference lookup (follow-up / split issue chains)
+
+For community issues **still unmatched** after Tiers 1 and 2 that appear in
+`community_issues_closed_in_window.json`, use the GitHub MCP `issue_read`
+tool to look for indirect linkage through follow-up or split issues:
+
+1. Call `issue_read` with `method: "get_comments"` on the community issue.
+2. Collect any referenced issue or PR numbers found in the body or comments.
+3. Check whether any of those numbers appear as a closed target in
+   `closing_refs_by_issue.json` or in the PR bodies already scanned.
+4. If a transitive chain is found (community issue → follow-up issue → merged
+   PR), record the community issue as **confirmed (via follow-up)** and note
+   the chain in the release notes entry, for example: `_(via follow-up #N)_`.
+
+### Tier 4 — Surface ambiguous candidates (fail soft, not silent)
+
+After all three active tiers, any community issue that was closed during the
+release window but cannot be linked to a specific merged PR must **not** be
+silently dropped.  Add it to the **"⚠️ Attribution Candidates Need Review"**
+section so a maintainer can make the final call.
+
+```bash
+cat /tmp/gh-aw/release-data/community_issues_closed_in_window.json | jq 'length'
+```
+
+### Output sections
+
+**Confirmed attributions → Community Contributions**
+
+```markdown
+### 🌍 Community Contributions
+
+A huge thank you to the community members who reported issues that were
+resolved in this release:
+
+- **@author** for Issue title ([#N](url))
+- **@author** for Issue title ([#N](url)) _(via follow-up #M)_
+```
+
+**Unlinked candidates → Attribution Candidates Need Review**
+
+```markdown
+### ⚠️ Attribution Candidates Need Review
+
+The following community issues were closed during this release window but
+could not be automatically linked to a specific merged PR.  Please verify
+whether they should be credited:
+
+- **@author** for Issue title ([#N](url)) — closed DATE, no confirmed PR linkage found
+```
+
+Omit the "Attribution Candidates Need Review" section entirely if every closed
+community issue has confirmed attribution.

From f0a64402c82f8fc76e9e05a813a14d451807ac09 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 21 Mar 2026 15:50:38 +0000
Subject: [PATCH 3/7] Switch GitHub MCP tools mode from remote to local in
 release.md

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/ed2f6a3c-29bb-4a64-8883-ec52b909f560
---
 .github/workflows/release.lock.yml | 20 ++++++++------------
 .github/workflows/release.md       |  2 +-
 2 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml
index c6543fba1af..45526b90175 100644
--- a/.github/workflows/release.lock.yml
+++ b/.github/workflows/release.lock.yml
@@ -26,7 +26,7 @@
 #   Imports:
 #     - shared/community-attribution.md
 #
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"c3af35d56c9f78113b5d5b284f067cd9c951934d63aaf69520f04ed156733607","strict":true,"agent_id":"copilot"}
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"f306ddda3cb96b1fb79f8d9a2d8b667a4cecf9c9f46bb1ffab476119cd9b3ebc","strict":true,"agent_id":"copilot"}
 
 name: "Release"
 "on":
@@ -360,7 +360,7 @@ jobs:
             const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs');
             await determineAutomaticLockdown(github, context, core);
       - name: Download container images
-        run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.24.5 ghcr.io/github/gh-aw-firewall/api-proxy:0.24.5 ghcr.io/github/gh-aw-firewall/squid:0.24.5 ghcr.io/github/gh-aw-mcpg:v0.1.20 node:lts-alpine
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.24.5 ghcr.io/github/gh-aw-firewall/api-proxy:0.24.5 ghcr.io/github/gh-aw-firewall/squid:0.24.5 ghcr.io/github/gh-aw-mcpg:v0.1.20 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine
       - name: Write Safe Outputs Config
         run: |
           mkdir -p ${RUNNER_TEMP}/gh-aw/safeoutputs
@@ -530,24 +530,20 @@ jobs:
           export DEBUG="*"
           
           export GH_AW_ENGINE="copilot"
-          export GITHUB_PERSONAL_ACCESS_TOKEN="$GITHUB_MCP_SERVER_TOKEN"
-          export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_PERSONAL_ACCESS_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.1.20'
+          export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.1.20'
           
           mkdir -p /home/runner/.copilot
           cat << GH_AW_MCP_CONFIG_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh
           {
             "mcpServers": {
               "github": {
-                "type": "http",
-                "url": "https://api.githubcopilot.com/mcp/",
-                "headers": {
-                  "Authorization": "Bearer \${GITHUB_PERSONAL_ACCESS_TOKEN}",
-                  "X-MCP-Readonly": "true",
-                  "X-MCP-Toolsets": "issues,pull_requests"
-                },
+                "type": "stdio",
+                "container": "ghcr.io/github/github-mcp-server:v0.32.0",
                 "env": {
+                  "GITHUB_HOST": "\${GITHUB_SERVER_URL}",
                   "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
-                  "GITHUB_HOST": "\${GITHUB_SERVER_URL}"
+                  "GITHUB_READ_ONLY": "1",
+                  "GITHUB_TOOLSETS": "issues,pull_requests"
                 },
                 "guard-policies": {
                   "allow-only": {
diff --git a/.github/workflows/release.md b/.github/workflows/release.md
index 91270886ba0..2870b0fad81 100644
--- a/.github/workflows/release.md
+++ b/.github/workflows/release.md
@@ -30,7 +30,7 @@ network:
     - "github.github.com"
 tools:
   github:
-    mode: "remote"
+    mode: "local"
     toolsets: [issues, pull_requests]
 safe-outputs:
   update-release:

From d3b0fe17a45d85e3ad34a1cb8b24fc63c6273412 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 21 Mar 2026 16:06:38 +0000
Subject: [PATCH 4/7] Move community attribution computation to shared
 workflow; add daily-community-attribution workflow

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/39552e43-66a6-4659-965e-1c2fe83b851e
---
 .../daily-community-attribution.lock.yml      | 1147 +++++++++++++++++
 .../workflows/daily-community-attribution.md  |  219 ++++
 .github/workflows/release.lock.yml            |   30 +-
 .github/workflows/release.md                  |  118 +-
 .../workflows/shared/community-attribution.md |   87 +-
 5 files changed, 1479 insertions(+), 122 deletions(-)
 create mode 100644 .github/workflows/daily-community-attribution.lock.yml
 create mode 100644 .github/workflows/daily-community-attribution.md

diff --git a/.github/workflows/daily-community-attribution.lock.yml b/.github/workflows/daily-community-attribution.lock.yml
new file mode 100644
index 00000000000..30a0dede129
--- /dev/null
+++ b/.github/workflows/daily-community-attribution.lock.yml
@@ -0,0 +1,1147 @@
+#    ___                   _   _      
+#   / _ \                 | | (_)     
+#  | |_| | __ _  ___ _ __ | |_ _  ___ 
+#  |  _  |/ _` |/ _ \ '_ \| __| |/ __|
+#  | | | | (_| |  __/ | | | |_| | (__ 
+#  \_| |_/\__, |\___|_| |_|\__|_|\___|
+#          __/ |
+#  _    _ |___/ 
+# | |  | |                / _| |
+# | |  | | ___ _ __ _  __| |_| | _____      ____
+# | |/\| |/ _ \ '__| |/ /|  _| |/ _ \ \ /\ / / ___|
+# \  /\  / (_) | | | | ( | | | | (_) \ V  V /\__ \
+#  \/  \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
+#
+# This file was automatically generated by gh-aw. DO NOT EDIT.
+#
+# To update this file, edit the corresponding .md file and run:
+#   gh aw compile
+# Not all edits will cause changes to this file.
+#
+# For more information: https://github.github.com/gh-aw/introduction/overview/
+#
+# Maintains a live community contributions section in README.md by attributing all community-labeled issues to merged PRs using the four-tier attribution strategy
+#
+# Resolved workflow manifest:
+#   Imports:
+#     - shared/community-attribution.md
+#
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"c36009e53493e2e1a341c008594333bd52392f065213d299e4883f7ee2e1da56","strict":true,"agent_id":"copilot"}
+
+name: "Daily Community Attribution Updater"
+"on":
+  schedule:
+  - cron: "32 13 * * *"
+    # Friendly format: daily (scattered)
+  workflow_dispatch:
+
+permissions: {}
+
+concurrency:
+  group: "gh-aw-${{ github.workflow }}"
+
+run-name: "Daily Community Attribution Updater"
+
+jobs:
+  activation:
+    runs-on: ubuntu-slim
+    permissions:
+      contents: read
+    outputs:
+      comment_id: ""
+      comment_repo: ""
+      lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
+      model: ${{ steps.generate_aw_info.outputs.model }}
+      secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
+    steps:
+      - name: Checkout actions folder
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          repository: github/gh-aw
+          sparse-checkout: |
+            actions
+          persist-credentials: false
+      - name: Setup Scripts
+        uses: ./actions/setup
+        with:
+          destination: ${{ runner.temp }}/gh-aw/actions
+      - name: Generate agentic run info
+        id: generate_aw_info
+        env:
+          GH_AW_INFO_ENGINE_ID: "copilot"
+          GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
+          GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
+          GH_AW_INFO_VERSION: ""
+          GH_AW_INFO_AGENT_VERSION: "latest"
+          GH_AW_INFO_WORKFLOW_NAME: "Daily Community Attribution Updater"
+          GH_AW_INFO_EXPERIMENTAL: "false"
+          GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
+          GH_AW_INFO_STAGED: "false"
+          GH_AW_INFO_ALLOWED_DOMAINS: '["defaults"]'
+          GH_AW_INFO_FIREWALL_ENABLED: "true"
+          GH_AW_INFO_AWF_VERSION: "v0.24.5"
+          GH_AW_INFO_AWMG_VERSION: ""
+          GH_AW_INFO_FIREWALL_TYPE: "squid"
+          GH_AW_COMPILED_STRICT: "true"
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
+            await main(core, context);
+      - name: Validate COPILOT_GITHUB_TOKEN secret
+        id: validate-secret
+        run: ${RUNNER_TEMP}/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
+        env:
+          COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+      - name: Checkout .github and .agents folders
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          persist-credentials: false
+          sparse-checkout: |
+            .github
+            .agents
+          sparse-checkout-cone-mode: true
+          fetch-depth: 1
+      - name: Check workflow file timestamps
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_WORKFLOW_FILE: "daily-community-attribution.lock.yml"
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs');
+            await main();
+      - name: Create prompt with built-in context
+        env:
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+          GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
+          GH_AW_GITHUB_ACTOR: ${{ github.actor }}
+          GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }}
+          GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }}
+          GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
+          GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
+          GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
+          GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
+          GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
+        run: |
+          bash ${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh
+          {
+          cat << 'GH_AW_PROMPT_EOF'
+          <system>
+          GH_AW_PROMPT_EOF
+          cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
+          cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
+          cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
+          cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
+          cat << 'GH_AW_PROMPT_EOF'
+          <safe-output-tools>
+          Tools: create_pull_request, missing_tool, missing_data, noop
+          GH_AW_PROMPT_EOF
+          cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md"
+          cat << 'GH_AW_PROMPT_EOF'
+          </safe-output-tools>
+          <github-context>
+          The following GitHub context information is available for this workflow:
+          {{#if __GH_AW_GITHUB_ACTOR__ }}
+          - **actor**: __GH_AW_GITHUB_ACTOR__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_REPOSITORY__ }}
+          - **repository**: __GH_AW_GITHUB_REPOSITORY__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_WORKSPACE__ }}
+          - **workspace**: __GH_AW_GITHUB_WORKSPACE__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ }}
+          - **issue-number**: #__GH_AW_GITHUB_EVENT_ISSUE_NUMBER__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ }}
+          - **discussion-number**: #__GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ }}
+          - **pull-request-number**: #__GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_EVENT_COMMENT_ID__ }}
+          - **comment-id**: __GH_AW_GITHUB_EVENT_COMMENT_ID__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_RUN_ID__ }}
+          - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__
+          {{/if}}
+          </github-context>
+          
+          GH_AW_PROMPT_EOF
+          cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
+          cat << 'GH_AW_PROMPT_EOF'
+          </system>
+          GH_AW_PROMPT_EOF
+          cat << 'GH_AW_PROMPT_EOF'
+          {{#runtime-import .github/workflows/shared/community-attribution.md}}
+          GH_AW_PROMPT_EOF
+          cat << 'GH_AW_PROMPT_EOF'
+          {{#runtime-import .github/workflows/daily-community-attribution.md}}
+          GH_AW_PROMPT_EOF
+          } > "$GH_AW_PROMPT"
+      - name: Interpolate variables and render templates
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs');
+            await main();
+      - name: Substitute placeholders
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+          GH_AW_GITHUB_ACTOR: ${{ github.actor }}
+          GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }}
+          GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }}
+          GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
+          GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
+          GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
+          GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
+          GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            
+            const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs');
+            
+            // Call the substitution function
+            return await substitutePlaceholders({
+              file: process.env.GH_AW_PROMPT,
+              substitutions: {
+                GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
+                GH_AW_GITHUB_EVENT_COMMENT_ID: process.env.GH_AW_GITHUB_EVENT_COMMENT_ID,
+                GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: process.env.GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER,
+                GH_AW_GITHUB_EVENT_ISSUE_NUMBER: process.env.GH_AW_GITHUB_EVENT_ISSUE_NUMBER,
+                GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER,
+                GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY,
+                GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
+                GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE
+              }
+            });
+      - name: Validate prompt placeholders
+        env:
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh
+      - name: Print prompt
+        env:
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh
+      - name: Upload activation artifact
+        if: success()
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+        with:
+          name: activation
+          path: |
+            /tmp/gh-aw/aw_info.json
+            /tmp/gh-aw/aw-prompts/prompt.txt
+          retention-days: 1
+
+  agent:
+    needs: activation
+    runs-on: ubuntu-latest
+    permissions:
+      contents: read
+      issues: read
+      pull-requests: read
+    concurrency:
+      group: "gh-aw-copilot-${{ github.workflow }}"
+    env:
+      DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
+      GH_AW_ASSETS_ALLOWED_EXTS: ""
+      GH_AW_ASSETS_BRANCH: ""
+      GH_AW_ASSETS_MAX_SIZE_KB: 0
+      GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
+      GH_AW_WORKFLOW_ID_SANITIZED: dailycommunityattribution
+    outputs:
+      checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
+      detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }}
+      detection_success: ${{ steps.detection_conclusion.outputs.success }}
+      has_patch: ${{ steps.collect_output.outputs.has_patch }}
+      inference_access_error: ${{ steps.detect-inference-error.outputs.inference_access_error || 'false' }}
+      model: ${{ needs.activation.outputs.model }}
+      output: ${{ steps.collect_output.outputs.output }}
+      output_types: ${{ steps.collect_output.outputs.output_types }}
+    steps:
+      - name: Checkout actions folder
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          repository: github/gh-aw
+          sparse-checkout: |
+            actions
+          persist-credentials: false
+      - name: Setup Scripts
+        uses: ./actions/setup
+        with:
+          destination: ${{ runner.temp }}/gh-aw/actions
+      - name: Set runtime paths
+        run: |
+          echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" >> "$GITHUB_ENV"
+          echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" >> "$GITHUB_ENV"
+          echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" >> "$GITHUB_ENV"
+      - name: Checkout repository
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          persist-credentials: false
+      - name: Create gh-aw temp directory
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh
+      - name: Configure gh CLI for GitHub Enterprise
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh
+        env:
+          GH_TOKEN: ${{ github.token }}
+      - env:
+          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        name: Fetch community-labeled issues
+        run: "mkdir -p /tmp/gh-aw/community-data\n\n# The \"community\" label is the **primary attribution signal**: a maintainer\n# explicitly tagged the issue as community-authored, making it a strong and\n# intentional marker that does not rely on free-text heuristics.\necho \"Fetching issues with 'community' label (primary attribution signal)...\"\nif ! gh issue list \\\n  --label \"community\" \\\n  --state all \\\n  --limit 500 \\\n  --json number,title,author,labels,closedAt,createdAt,url \\\n  > /tmp/gh-aw/community-data/community_issues.json; then\n  echo \"[]\" > /tmp/gh-aw/community-data/community_issues.json\nfi\n\nCOMMUNITY_COUNT=$(jq length \"/tmp/gh-aw/community-data/community_issues.json\")\necho \"✓ Fetched $COMMUNITY_COUNT community-labeled issues\"\necho \"  Data: /tmp/gh-aw/community-data/community_issues.json\""
+      - env:
+          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        name: Fetch PR data for attribution index
+        run: "mkdir -p /tmp/gh-aw/community-data\n\n# Fetch merged PRs from the last 90 days (wide enough to catch any recently attributed issue)\nSINCE=$(date -d '90 days ago' '+%Y-%m-%dT%H:%M:%SZ' 2>/dev/null \\\n        || date -v-90d '+%Y-%m-%dT%H:%M:%SZ')\n\necho \"Fetching PRs merged since $SINCE...\"\ngh pr list \\\n  --state merged \\\n  --limit 500 \\\n  --json number,title,author,mergedAt,url,body,closingIssuesReferences \\\n  --jq \"[.[] | select(.mergedAt >= \\\"$SINCE\\\")]\" \\\n  > /tmp/gh-aw/community-data/pull_requests.json \\\n  || echo \"[]\" > /tmp/gh-aw/community-data/pull_requests.json\n\nPR_COUNT=$(jq length /tmp/gh-aw/community-data/pull_requests.json)\necho \"✓ Fetched $PR_COUNT merged PRs\"\n\n# Build closing references index: {issue_number: [pr_numbers]}\njq '\n  reduce .[] as $pr (\n    {};\n    $pr.closingIssuesReferences[]? as $issue |\n    ($issue.number | tostring) as $key |\n    .[$key] = (.[$key] // []) + [$pr.number]\n  )\n' /tmp/gh-aw/community-data/pull_requests.json \\\n  > /tmp/gh-aw/community-data/closing_refs_by_issue.json 2>/dev/null \\\n  || echo \"{}\" > /tmp/gh-aw/community-data/closing_refs_by_issue.json\n\nLINK_COUNT=$(jq 'keys | length' /tmp/gh-aw/community-data/closing_refs_by_issue.json)\necho \"✓ Built closing refs index: $LINK_COUNT issues with native GitHub close links\"\n\n# Find community issues closed within the PR lookback window (attribution candidates)\njq --arg since \"$SINCE\" \\\n  '[.[] | select(.closedAt != null and .closedAt >= $since)]' \\\n  /tmp/gh-aw/community-data/community_issues.json \\\n  > /tmp/gh-aw/community-data/community_issues_closed_in_window.json 2>/dev/null \\\n  || echo \"[]\" > /tmp/gh-aw/community-data/community_issues_closed_in_window.json\n\nCLOSED_COUNT=$(jq length /tmp/gh-aw/community-data/community_issues_closed_in_window.json)\necho \"✓ Found $CLOSED_COUNT community issues closed in the lookback window\"\n\necho \"\"\necho \"Data available in /tmp/gh-aw/community-data/:\"\necho \"  community_issues.json                  — all community-labeled issues\"\necho \"  pull_requests.json                     — merged PRs (last 90 days)\"\necho \"  closing_refs_by_issue.json             — native GitHub close links\"\necho \"  community_issues_closed_in_window.json — closed during lookback\""
+
+      - name: Configure Git credentials
+        env:
+          REPO_NAME: ${{ github.repository }}
+          SERVER_URL: ${{ github.server_url }}
+        run: |
+          git config --global user.email "github-actions[bot]@users.noreply.github.com"
+          git config --global user.name "github-actions[bot]"
+          git config --global am.keepcr true
+          # Re-authenticate git with GitHub token
+          SERVER_URL_STRIPPED="${SERVER_URL#https://}"
+          git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
+          echo "Git configured with standard GitHub Actions identity"
+      - name: Checkout PR branch
+        id: checkout-pr
+        if: |
+          github.event.pull_request || github.event.issue.pull_request
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
+            await main();
+      - name: Install GitHub Copilot CLI
+        run: ${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh latest
+        env:
+          GH_HOST: github.com
+      - name: Install AWF binary
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.24.5
+      - name: Determine automatic lockdown mode for GitHub MCP Server
+        id: determine-automatic-lockdown
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
+          GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
+        with:
+          script: |
+            const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs');
+            await determineAutomaticLockdown(github, context, core);
+      - name: Download container images
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.24.5 ghcr.io/github/gh-aw-firewall/api-proxy:0.24.5 ghcr.io/github/gh-aw-firewall/squid:0.24.5 ghcr.io/github/gh-aw-mcpg:v0.1.20 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine
+      - name: Write Safe Outputs Config
+        run: |
+          mkdir -p ${RUNNER_TEMP}/gh-aw/safeoutputs
+          mkdir -p /tmp/gh-aw/safeoutputs
+          mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
+          cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
+          {"create_pull_request":{"expires":24,"max":1,"title_prefix":"[community] "},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+          GH_AW_SAFE_OUTPUTS_CONFIG_EOF
+      - name: Write Safe Outputs Tools
+        run: |
+          cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_EOF'
+          {
+            "description_suffixes": {
+              "create_pull_request": " CONSTRAINTS: Maximum 1 pull request(s) can be created. Title will be prefixed with \"[community] \". Labels [\"community\" \"automation\"] will be automatically added."
+            },
+            "repo_params": {},
+            "dynamic_tools": []
+          }
+          GH_AW_SAFE_OUTPUTS_TOOLS_META_EOF
+          cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
+          {
+            "create_pull_request": {
+              "defaultMax": 1,
+              "fields": {
+                "body": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 65000
+                },
+                "branch": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 256
+                },
+                "draft": {
+                  "type": "boolean"
+                },
+                "labels": {
+                  "type": "array",
+                  "itemType": "string",
+                  "itemSanitize": true,
+                  "itemMaxLength": 128
+                },
+                "repo": {
+                  "type": "string",
+                  "maxLength": 256
+                },
+                "title": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 128
+                }
+              }
+            },
+            "missing_data": {
+              "defaultMax": 20,
+              "fields": {
+                "alternatives": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 256
+                },
+                "context": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 256
+                },
+                "data_type": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 128
+                },
+                "reason": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 256
+                }
+              }
+            },
+            "missing_tool": {
+              "defaultMax": 20,
+              "fields": {
+                "alternatives": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 512
+                },
+                "reason": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 256
+                },
+                "tool": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 128
+                }
+              }
+            },
+            "noop": {
+              "defaultMax": 1,
+              "fields": {
+                "message": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 65000
+                }
+              }
+            }
+          }
+          GH_AW_SAFE_OUTPUTS_VALIDATION_EOF
+          node ${RUNNER_TEMP}/gh-aw/actions/generate_safe_outputs_tools.cjs
+      - name: Generate Safe Outputs MCP Server Config
+        id: safe-outputs-config
+        run: |
+          # Generate a secure random API key (360 bits of entropy, 40+ chars)
+          # Mask immediately to prevent timing vulnerabilities
+          API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
+          echo "::add-mask::${API_KEY}"
+          
+          PORT=3001
+          
+          # Set outputs for next steps
+          {
+            echo "safe_outputs_api_key=${API_KEY}"
+            echo "safe_outputs_port=${PORT}"
+          } >> "$GITHUB_OUTPUT"
+          
+          echo "Safe Outputs MCP server will run on port ${PORT}"
+          
+      - name: Start Safe Outputs MCP HTTP Server
+        id: safe-outputs-start
+        env:
+          DEBUG: '*'
+          GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
+          GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
+          GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
+          GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json
+          GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
+        run: |
+          # Environment variables are set above to prevent template injection
+          export DEBUG
+          export GH_AW_SAFE_OUTPUTS_PORT
+          export GH_AW_SAFE_OUTPUTS_API_KEY
+          export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
+          export GH_AW_SAFE_OUTPUTS_CONFIG_PATH
+          export GH_AW_MCP_LOG_DIR
+          
+          bash ${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh
+          
+      - name: Start MCP Gateway
+        id: start-mcp-gateway
+        env:
+          GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
+          GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }}
+          GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }}
+          GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }}
+          GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }}
+          GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+        run: |
+          set -eo pipefail
+          mkdir -p /tmp/gh-aw/mcp-config
+          
+          # Export gateway environment variables for MCP config and gateway script
+          export MCP_GATEWAY_PORT="80"
+          export MCP_GATEWAY_DOMAIN="host.docker.internal"
+          MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
+          echo "::add-mask::${MCP_GATEWAY_API_KEY}"
+          export MCP_GATEWAY_API_KEY
+          export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads"
+          mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}"
+          export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288"
+          export DEBUG="*"
+          
+          export GH_AW_ENGINE="copilot"
+          export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.1.20'
+          
+          mkdir -p /home/runner/.copilot
+          cat << GH_AW_MCP_CONFIG_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh
+          {
+            "mcpServers": {
+              "github": {
+                "type": "stdio",
+                "container": "ghcr.io/github/github-mcp-server:v0.32.0",
+                "env": {
+                  "GITHUB_HOST": "\${GITHUB_SERVER_URL}",
+                  "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
+                  "GITHUB_READ_ONLY": "1",
+                  "GITHUB_TOOLSETS": "issues,pull_requests"
+                },
+                "guard-policies": {
+                  "allow-only": {
+                    "min-integrity": "$GITHUB_MCP_GUARD_MIN_INTEGRITY",
+                    "repos": "$GITHUB_MCP_GUARD_REPOS"
+                  }
+                }
+              },
+              "safeoutputs": {
+                "type": "http",
+                "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
+                "headers": {
+                  "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}"
+                },
+                "guard-policies": {
+                  "write-sink": {
+                    "accept": [
+                      "*"
+                    ]
+                  }
+                }
+              }
+            },
+            "gateway": {
+              "port": $MCP_GATEWAY_PORT,
+              "domain": "${MCP_GATEWAY_DOMAIN}",
+              "apiKey": "${MCP_GATEWAY_API_KEY}",
+              "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
+            }
+          }
+          GH_AW_MCP_CONFIG_EOF
+      - name: Download activation artifact
+        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+        with:
+          name: activation
+          path: /tmp/gh-aw
+      - name: Clean git credentials
+        continue-on-error: true
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh
+      - name: Execute GitHub Copilot CLI
+        id: agentic_execution
+        # Copilot CLI tool arguments (sorted):
+        # --allow-tool github
+        # --allow-tool safeoutputs
+        # --allow-tool shell(cat *)
+        # --allow-tool shell(cat)
+        # --allow-tool shell(cp *)
+        # --allow-tool shell(date *)
+        # --allow-tool shell(date)
+        # --allow-tool shell(echo *)
+        # --allow-tool shell(echo)
+        # --allow-tool shell(gh issue list *)
+        # --allow-tool shell(gh pr list *)
+        # --allow-tool shell(git add:*)
+        # --allow-tool shell(git branch:*)
+        # --allow-tool shell(git checkout:*)
+        # --allow-tool shell(git commit:*)
+        # --allow-tool shell(git merge:*)
+        # --allow-tool shell(git rm:*)
+        # --allow-tool shell(git status)
+        # --allow-tool shell(git switch:*)
+        # --allow-tool shell(grep)
+        # --allow-tool shell(head)
+        # --allow-tool shell(jq *)
+        # --allow-tool shell(ls)
+        # --allow-tool shell(mkdir *)
+        # --allow-tool shell(pwd)
+        # --allow-tool shell(sort)
+        # --allow-tool shell(tail)
+        # --allow-tool shell(uniq)
+        # --allow-tool shell(wc)
+        # --allow-tool shell(yq)
+        # --allow-tool write
+        timeout-minutes: 30
+        run: |
+          set -o pipefail
+          touch /tmp/gh-aw/agent-step-summary.md
+          # shellcheck disable=SC1003
+          sudo -E awf --env-all --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" --allow-domains "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.24.5 --skip-pull --enable-api-proxy \
+            -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-tool github --allow-tool safeoutputs --allow-tool '\''shell(cat *)'\'' --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(cp *)'\'' --allow-tool '\''shell(date *)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(echo *)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(gh issue list *)'\'' --allow-tool '\''shell(gh pr list *)'\'' --allow-tool '\''shell(git add:*)'\'' --allow-tool '\''shell(git branch:*)'\'' --allow-tool '\''shell(git checkout:*)'\'' --allow-tool '\''shell(git commit:*)'\'' --allow-tool '\''shell(git merge:*)'\'' --allow-tool '\''shell(git rm:*)'\'' --allow-tool '\''shell(git status)'\'' --allow-tool '\''shell(git switch:*)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq *)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(mkdir *)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(uniq)'\'' --allow-tool '\''shell(wc)'\'' --allow-tool '\''shell(yq)'\'' --allow-tool write --allow-all-paths --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+        env:
+          COPILOT_AGENT_RUNNER_TYPE: STANDALONE
+          COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+          COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
+          GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json
+          GH_AW_PHASE: agent
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+          GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
+          GH_AW_VERSION: dev
+          GITHUB_API_URL: ${{ github.api_url }}
+          GITHUB_AW: true
+          GITHUB_HEAD_REF: ${{ github.head_ref }}
+          GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          GITHUB_REF_NAME: ${{ github.ref_name }}
+          GITHUB_SERVER_URL: ${{ github.server_url }}
+          GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
+          GITHUB_WORKSPACE: ${{ github.workspace }}
+          GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
+          GIT_AUTHOR_NAME: github-actions[bot]
+          GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
+          GIT_COMMITTER_NAME: github-actions[bot]
+          XDG_CONFIG_HOME: /home/runner
+      - name: Detect inference access error
+        id: detect-inference-error
+        if: always()
+        continue-on-error: true
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/detect_inference_access_error.sh
+      - name: Configure Git credentials
+        env:
+          REPO_NAME: ${{ github.repository }}
+          SERVER_URL: ${{ github.server_url }}
+        run: |
+          git config --global user.email "github-actions[bot]@users.noreply.github.com"
+          git config --global user.name "github-actions[bot]"
+          git config --global am.keepcr true
+          # Re-authenticate git with GitHub token
+          SERVER_URL_STRIPPED="${SERVER_URL#https://}"
+          git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
+          echo "Git configured with standard GitHub Actions identity"
+      - name: Copy Copilot session state files to logs
+        if: always()
+        continue-on-error: true
+        run: |
+          # Copy Copilot session state files to logs folder for artifact collection
+          # This ensures they are in /tmp/gh-aw/ where secret redaction can scan them
+          SESSION_STATE_DIR="$HOME/.copilot/session-state"
+          LOGS_DIR="/tmp/gh-aw/sandbox/agent/logs"
+          
+          if [ -d "$SESSION_STATE_DIR" ]; then
+            echo "Copying Copilot session state files from $SESSION_STATE_DIR to $LOGS_DIR"
+            mkdir -p "$LOGS_DIR"
+            cp -v "$SESSION_STATE_DIR"/*.jsonl "$LOGS_DIR/" 2>/dev/null || true
+            echo "Session state files copied successfully"
+          else
+            echo "No session-state directory found at $SESSION_STATE_DIR"
+          fi
+      - name: Stop MCP Gateway
+        if: always()
+        continue-on-error: true
+        env:
+          MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
+          MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
+          GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }}
+        run: |
+          bash ${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh "$GATEWAY_PID"
+      - name: Redact secrets in logs
+        if: always()
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
+            await main();
+        env:
+          GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
+          SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+          SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
+          SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
+          SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+      - name: Append agent step summary
+        if: always()
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh
+      - name: Copy Safe Outputs
+        if: always()
+        run: |
+          mkdir -p /tmp/gh-aw
+          cp "$GH_AW_SAFE_OUTPUTS" /tmp/gh-aw/safeoutputs.jsonl 2>/dev/null || true
+      - name: Ingest agent output
+        id: collect_output
+        if: always()
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
+          GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
+          GITHUB_SERVER_URL: ${{ github.server_url }}
+          GITHUB_API_URL: ${{ github.api_url }}
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs');
+            await main();
+      - name: Parse agent logs for step summary
+        if: always()
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs');
+            await main();
+      - name: Parse MCP Gateway logs for step summary
+        if: always()
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs');
+            await main();
+      - name: Print firewall logs
+        if: always()
+        continue-on-error: true
+        env:
+          AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
+        run: |
+          # Fix permissions on firewall logs so they can be uploaded as artifacts
+          # AWF runs with sudo, creating files owned by root
+          sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true
+          # Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
+          if command -v awf &> /dev/null; then
+            awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
+          else
+            echo 'AWF binary not installed, skipping firewall log summary'
+          fi
+      - name: Upload agent artifacts
+        if: always()
+        continue-on-error: true
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+        with:
+          name: agent
+          path: |
+            /tmp/gh-aw/aw-prompts/prompt.txt
+            /tmp/gh-aw/sandbox/agent/logs/
+            /tmp/gh-aw/redacted-urls.log
+            /tmp/gh-aw/mcp-logs/
+            /tmp/gh-aw/sandbox/firewall/logs/
+            /tmp/gh-aw/agent-stdio.log
+            /tmp/gh-aw/agent/
+            /tmp/gh-aw/safeoutputs.jsonl
+            /tmp/gh-aw/agent_output.json
+            /tmp/gh-aw/aw-*.patch
+          if-no-files-found: ignore
+      # --- Threat Detection (inline) ---
+      - name: Check if detection needed
+        id: detection_guard
+        if: always()
+        env:
+          OUTPUT_TYPES: ${{ steps.collect_output.outputs.output_types }}
+          HAS_PATCH: ${{ steps.collect_output.outputs.has_patch }}
+        run: |
+          if [[ -n "$OUTPUT_TYPES" || "$HAS_PATCH" == "true" ]]; then
+            echo "run_detection=true" >> "$GITHUB_OUTPUT"
+            echo "Detection will run: output_types=$OUTPUT_TYPES, has_patch=$HAS_PATCH"
+          else
+            echo "run_detection=false" >> "$GITHUB_OUTPUT"
+            echo "Detection skipped: no agent outputs or patches to analyze"
+          fi
+      - name: Clear MCP configuration for detection
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        run: |
+          rm -f /tmp/gh-aw/mcp-config/mcp-servers.json
+          rm -f /home/runner/.copilot/mcp-config.json
+          rm -f "$GITHUB_WORKSPACE/.gemini/settings.json"
+      - name: Prepare threat detection files
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        run: |
+          mkdir -p /tmp/gh-aw/threat-detection/aw-prompts
+          cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true
+          cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true
+          for f in /tmp/gh-aw/aw-*.patch; do
+            [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
+          done
+          echo "Prepared threat detection files:"
+          ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true
+      - name: Setup threat detection
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          WORKFLOW_NAME: "Daily Community Attribution Updater"
+          WORKFLOW_DESCRIPTION: "Maintains a live community contributions section in README.md by attributing all community-labeled issues to merged PRs using the four-tier attribution strategy"
+          HAS_PATCH: ${{ steps.collect_output.outputs.has_patch }}
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs');
+            await main();
+      - name: Ensure threat-detection directory and log
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        run: |
+          mkdir -p /tmp/gh-aw/threat-detection
+          touch /tmp/gh-aw/threat-detection/detection.log
+      - name: Execute GitHub Copilot CLI
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        id: detection_agentic_execution
+        # Copilot CLI tool arguments (sorted):
+        # --allow-tool shell(cat)
+        # --allow-tool shell(grep)
+        # --allow-tool shell(head)
+        # --allow-tool shell(jq)
+        # --allow-tool shell(ls)
+        # --allow-tool shell(tail)
+        # --allow-tool shell(wc)
+        timeout-minutes: 20
+        run: |
+          set -o pipefail
+          touch /tmp/gh-aw/agent-step-summary.md
+          # shellcheck disable=SC1003
+          sudo -E awf --env-all --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" --allow-domains "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,raw.githubusercontent.com,registry.npmjs.org,telemetry.enterprise.githubcopilot.com" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.24.5 --skip-pull --enable-api-proxy \
+            -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(wc)'\'' --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
+        env:
+          COPILOT_AGENT_RUNNER_TYPE: STANDALONE
+          COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+          COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }}
+          GH_AW_PHASE: detection
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+          GH_AW_VERSION: dev
+          GITHUB_API_URL: ${{ github.api_url }}
+          GITHUB_AW: true
+          GITHUB_HEAD_REF: ${{ github.head_ref }}
+          GITHUB_REF_NAME: ${{ github.ref_name }}
+          GITHUB_SERVER_URL: ${{ github.server_url }}
+          GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
+          GITHUB_WORKSPACE: ${{ github.workspace }}
+          GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
+          GIT_AUTHOR_NAME: github-actions[bot]
+          GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
+          GIT_COMMITTER_NAME: github-actions[bot]
+          XDG_CONFIG_HOME: /home/runner
+      - name: Parse threat detection results
+        id: parse_detection_results
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs');
+            await main();
+      - name: Upload threat detection log
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+        with:
+          name: detection
+          path: /tmp/gh-aw/threat-detection/detection.log
+          if-no-files-found: ignore
+      - name: Set detection conclusion
+        id: detection_conclusion
+        if: always()
+        env:
+          RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
+          DETECTION_SUCCESS: ${{ steps.parse_detection_results.outputs.success }}
+        run: |
+          if [[ "$RUN_DETECTION" != "true" ]]; then
+            echo "conclusion=skipped" >> "$GITHUB_OUTPUT"
+            echo "success=true" >> "$GITHUB_OUTPUT"
+            echo "Detection was not needed, marking as skipped"
+          elif [[ "$DETECTION_SUCCESS" == "true" ]]; then
+            echo "conclusion=success" >> "$GITHUB_OUTPUT"
+            echo "success=true" >> "$GITHUB_OUTPUT"
+            echo "Detection passed successfully"
+          else
+            echo "conclusion=failure" >> "$GITHUB_OUTPUT"
+            echo "success=false" >> "$GITHUB_OUTPUT"
+            echo "Detection found issues"
+          fi
+
+  conclusion:
+    needs:
+      - activation
+      - agent
+      - safe_outputs
+    if: always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true')
+    runs-on: ubuntu-slim
+    permissions:
+      contents: write
+      issues: write
+      pull-requests: write
+    concurrency:
+      group: "gh-aw-conclusion-daily-community-attribution"
+      cancel-in-progress: false
+    outputs:
+      noop_message: ${{ steps.noop.outputs.noop_message }}
+      tools_reported: ${{ steps.missing_tool.outputs.tools_reported }}
+      total_count: ${{ steps.missing_tool.outputs.total_count }}
+    steps:
+      - name: Checkout actions folder
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          repository: github/gh-aw
+          sparse-checkout: |
+            actions
+          persist-credentials: false
+      - name: Setup Scripts
+        uses: ./actions/setup
+        with:
+          destination: ${{ runner.temp }}/gh-aw/actions
+      - name: Download agent output artifact
+        id: download-agent-output
+        continue-on-error: true
+        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+        with:
+          name: agent
+          path: /tmp/gh-aw/
+      - name: Setup agent output environment variable
+        if: steps.download-agent-output.outcome == 'success'
+        run: |
+          mkdir -p /tmp/gh-aw/
+          find "/tmp/gh-aw/" -type f -print
+          echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_ENV"
+      - name: Process No-Op Messages
+        id: noop
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
+          GH_AW_NOOP_MAX: "1"
+          GH_AW_WORKFLOW_NAME: "Daily Community Attribution Updater"
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/noop.cjs');
+            await main();
+      - name: Record Missing Tool
+        id: missing_tool
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
+          GH_AW_WORKFLOW_NAME: "Daily Community Attribution Updater"
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs');
+            await main();
+      - name: Handle Agent Failure
+        id: handle_agent_failure
+        if: always()
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
+          GH_AW_WORKFLOW_NAME: "Daily Community Attribution Updater"
+          GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+          GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
+          GH_AW_WORKFLOW_ID: "daily-community-attribution"
+          GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }}
+          GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
+          GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }}
+          GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }}
+          GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }}
+          GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
+          GH_AW_GROUP_REPORTS: "false"
+          GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
+          GH_AW_TIMEOUT_MINUTES: "30"
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs');
+            await main();
+      - name: Handle No-Op Message
+        id: handle_noop_message
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
+          GH_AW_WORKFLOW_NAME: "Daily Community Attribution Updater"
+          GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+          GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
+          GH_AW_NOOP_MESSAGE: ${{ steps.noop.outputs.noop_message }}
+          GH_AW_NOOP_REPORT_AS_ISSUE: "true"
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs');
+            await main();
+      - name: Handle Create Pull Request Error
+        id: handle_create_pr_error
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
+          GH_AW_WORKFLOW_NAME: "Daily Community Attribution Updater"
+          GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_create_pr_error.cjs');
+            await main();
+
+  safe_outputs:
+    needs:
+      - activation
+      - agent
+    if: (!cancelled()) && needs.agent.result != 'skipped' && needs.agent.outputs.detection_success == 'true'
+    runs-on: ubuntu-slim
+    permissions:
+      contents: write
+      issues: write
+      pull-requests: write
+    timeout-minutes: 15
+    env:
+      GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/daily-community-attribution"
+      GH_AW_ENGINE_ID: "copilot"
+      GH_AW_WORKFLOW_ID: "daily-community-attribution"
+      GH_AW_WORKFLOW_NAME: "Daily Community Attribution Updater"
+    outputs:
+      code_push_failure_count: ${{ steps.process_safe_outputs.outputs.code_push_failure_count }}
+      code_push_failure_errors: ${{ steps.process_safe_outputs.outputs.code_push_failure_errors }}
+      create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }}
+      create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }}
+      created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }}
+      created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }}
+      process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }}
+      process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }}
+    steps:
+      - name: Checkout actions folder
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          repository: github/gh-aw
+          sparse-checkout: |
+            actions
+          persist-credentials: false
+      - name: Setup Scripts
+        uses: ./actions/setup
+        with:
+          destination: ${{ runner.temp }}/gh-aw/actions
+      - name: Download agent output artifact
+        id: download-agent-output
+        continue-on-error: true
+        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+        with:
+          name: agent
+          path: /tmp/gh-aw/
+      - name: Setup agent output environment variable
+        if: steps.download-agent-output.outcome == 'success'
+        run: |
+          mkdir -p /tmp/gh-aw/
+          find "/tmp/gh-aw/" -type f -print
+          echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_ENV"
+      - name: Download patch artifact
+        continue-on-error: true
+        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+        with:
+          name: agent
+          path: /tmp/gh-aw/
+      - name: Checkout repository
+        if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request')
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          ref: ${{ github.base_ref || github.event.pull_request.base.ref || github.ref_name || github.event.repository.default_branch }}
+          token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          persist-credentials: false
+          fetch-depth: 1
+      - name: Configure Git credentials
+        if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request')
+        env:
+          REPO_NAME: ${{ github.repository }}
+          SERVER_URL: ${{ github.server_url }}
+          GIT_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+        run: |
+          git config --global user.email "github-actions[bot]@users.noreply.github.com"
+          git config --global user.name "github-actions[bot]"
+          git config --global am.keepcr true
+          # Re-authenticate git with GitHub token
+          SERVER_URL_STRIPPED="${SERVER_URL#https://}"
+          git remote set-url origin "https://x-access-token:${GIT_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
+          echo "Git configured with standard GitHub Actions identity"
+      - name: Configure GH_HOST for enterprise compatibility
+        shell: bash
+        run: |
+          # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
+          # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
+          GH_HOST="${GITHUB_SERVER_URL#https://}"
+          GH_HOST="${GH_HOST#http://}"
+          echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
+      - name: Process Safe Outputs
+        id: process_safe_outputs
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
+          GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
+          GITHUB_SERVER_URL: ${{ github.server_url }}
+          GITHUB_API_URL: ${{ github.api_url }}
+          GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_pull_request\":{\"draft\":false,\"expires\":24,\"labels\":[\"community\",\"automation\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"title_prefix\":\"[community] \"},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"}}"
+          GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }}
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs');
+            await main();
+      - name: Upload safe output items
+        if: always()
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+        with:
+          name: safe-output-items
+          path: /tmp/gh-aw/safe-output-items.jsonl
+          if-no-files-found: ignore
+
diff --git a/.github/workflows/daily-community-attribution.md b/.github/workflows/daily-community-attribution.md
new file mode 100644
index 00000000000..b7a3cd6bbf3
--- /dev/null
+++ b/.github/workflows/daily-community-attribution.md
@@ -0,0 +1,219 @@
+---
+name: Daily Community Attribution Updater
+description: Maintains a live community contributions section in README.md by attributing all community-labeled issues to merged PRs using the four-tier attribution strategy
+on:
+  schedule:
+    - cron: daily
+  workflow_dispatch:
+
+permissions:
+  contents: read
+  pull-requests: read
+  issues: read
+
+engine: copilot
+timeout-minutes: 30
+
+network:
+  allowed:
+    - defaults
+
+tools:
+  github:
+    mode: "local"
+    toolsets: [issues, pull_requests]
+  bash:
+    - "gh pr list *"
+    - "gh issue list *"
+    - "jq *"
+    - "mkdir *"
+    - "echo *"
+    - "cp *"
+    - "cat *"
+    - "date *"
+  edit:
+
+safe-outputs:
+  create-pull-request:
+    expires: 1d
+    title-prefix: "[community] "
+    labels: [community, automation]
+    reviewers: []
+    draft: false
+
+imports:
+  - shared/community-attribution.md
+
+steps:
+  - name: Fetch PR data for attribution index
+    env:
+      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+    run: |
+      mkdir -p /tmp/gh-aw/community-data
+
+      # Fetch merged PRs from the last 90 days (wide enough to catch any recently attributed issue)
+      SINCE=$(date -d '90 days ago' '+%Y-%m-%dT%H:%M:%SZ' 2>/dev/null \
+              || date -v-90d '+%Y-%m-%dT%H:%M:%SZ')
+
+      echo "Fetching PRs merged since $SINCE..."
+      gh pr list \
+        --state merged \
+        --limit 500 \
+        --json number,title,author,mergedAt,url,body,closingIssuesReferences \
+        --jq "[.[] | select(.mergedAt >= \"$SINCE\")]" \
+        > /tmp/gh-aw/community-data/pull_requests.json \
+        || echo "[]" > /tmp/gh-aw/community-data/pull_requests.json
+
+      PR_COUNT=$(jq length /tmp/gh-aw/community-data/pull_requests.json)
+      echo "✓ Fetched $PR_COUNT merged PRs"
+
+      # Build closing references index: {issue_number: [pr_numbers]}
+      jq '
+        reduce .[] as $pr (
+          {};
+          $pr.closingIssuesReferences[]? as $issue |
+          ($issue.number | tostring) as $key |
+          .[$key] = (.[$key] // []) + [$pr.number]
+        )
+      ' /tmp/gh-aw/community-data/pull_requests.json \
+        > /tmp/gh-aw/community-data/closing_refs_by_issue.json 2>/dev/null \
+        || echo "{}" > /tmp/gh-aw/community-data/closing_refs_by_issue.json
+
+      LINK_COUNT=$(jq 'keys | length' /tmp/gh-aw/community-data/closing_refs_by_issue.json)
+      echo "✓ Built closing refs index: $LINK_COUNT issues with native GitHub close links"
+
+      # Find community issues closed within the PR lookback window (attribution candidates)
+      jq --arg since "$SINCE" \
+        '[.[] | select(.closedAt != null and .closedAt >= $since)]' \
+        /tmp/gh-aw/community-data/community_issues.json \
+        > /tmp/gh-aw/community-data/community_issues_closed_in_window.json 2>/dev/null \
+        || echo "[]" > /tmp/gh-aw/community-data/community_issues_closed_in_window.json
+
+      CLOSED_COUNT=$(jq length /tmp/gh-aw/community-data/community_issues_closed_in_window.json)
+      echo "✓ Found $CLOSED_COUNT community issues closed in the lookback window"
+
+      echo ""
+      echo "Data available in /tmp/gh-aw/community-data/:"
+      echo "  community_issues.json                  — all community-labeled issues"
+      echo "  pull_requests.json                     — merged PRs (last 90 days)"
+      echo "  closing_refs_by_issue.json             — native GitHub close links"
+      echo "  community_issues_closed_in_window.json — closed during lookback"
+---
+
+# Daily Community Attribution Updater
+
+Maintain an up-to-date **🌍 Community Contributions** section in `README.md`
+by attributing all resolved community-labeled issues to merged PRs.
+
+## Mission
+
+The `community` label is the **primary attribution signal**: every issue
+tagged with it was explicitly identified by a maintainer as community-authored.
+This workflow attributes those issues to PRs, updates `README.md`, and opens
+a PR for review.
+
+## Pre-fetched Data
+
+All data is in `/tmp/gh-aw/community-data/`:
+
+```bash
+# View all community-labeled issues
+cat /tmp/gh-aw/community-data/community_issues.json | \
+  jq -r '.[] | "- #\(.number) [\(.state // "?")] \(.title) by @\(.author.login)"'
+
+# View recently closed community issues (attribution candidates)
+cat /tmp/gh-aw/community-data/community_issues_closed_in_window.json | \
+  jq -r '.[] | "- #\(.number): \(.title) by @\(.author.login) (closed: \(.closedAt))"'
+
+# View closing reference index
+cat /tmp/gh-aw/community-data/closing_refs_by_issue.json | jq
+
+# View current README
+head -80 /tmp/gh-aw/community-data/README_current.md
+```
+
+## Workflow
+
+### 1. Attribute All Resolved Community Issues
+
+Apply the **Community Attribution Strategy** from the imported shared component
+to every closed community-labeled issue.
+
+Focus on issues in `community_issues_closed_in_window.json` first (recently
+closed, most likely to be new). Then check older closed issues in
+`community_issues.json` that are not already reflected in `README.md`.
+
+For each community issue, work through all four attribution tiers (see shared
+component) and mark it as **confirmed**, **confirmed (via follow-up)**, or
+**needs review**.
+
+### 2. Build the Community Contributions Table
+
+Produce a concise, sorted table of attributed community contributors:
+
+```markdown
+## 🌍 Community Contributions
+
+Thank you to the community members whose issue reports were resolved in this project!
+This list is updated automatically and reflects all attributed contributions.
+
+| Issue | Title | Author | Resolved By | Attribution |
+|-------|-------|--------|-------------|-------------|
+| [#N](url) | Issue title | @author | [#PR](url) | direct |
+| [#N](url) | Issue title | @author | [#PR](url) via [#M](url) | follow-up |
+```
+
+- Sort by issue number descending (newest first)
+- `Attribution` column: `direct` for Tier 1/2, `via follow-up #M` for Tier 3
+- Omit issues that cannot be attributed (see Attribution Candidates section below)
+
+If there are unattributed candidates (Tier 4), append:
+
+```markdown
+### ⚠️ Attribution Candidates Need Review
+
+The following community issues were closed but could not be automatically
+linked to a specific merged PR. Please verify whether they should be credited:
+
+- **@author** for [Issue title](#N) — closed DATE
+```
+
+### 3. Update README.md
+
+Replace the existing `## 🌍 Community Contributions` section in `README.md`
+with the newly generated content, or append it after the `## Contributing`
+section if it does not yet exist.
+
+Use the edit tool to make the change in-place.
+
+If no changes are needed (all attributions already present and current),
+call the `noop` safe-output tool and stop.
+
+### 4. Open a Pull Request
+
+If `README.md` was updated, call the `create_pull_request` safe-output tool
+to open a PR with the changes.
+
+**PR title**: `[community] Update community contributions in README`
+
+**PR body template**:
+```markdown
+### Community Contributions Update
+
+Automated update to the 🌍 Community Contributions section in `README.md`.
+
+#### Changes
+- N community issues newly attributed
+- N attribution candidates flagged for review (if any)
+
+#### Attribution Summary
+[brief summary of what changed and how each was attributed]
+```
+
+**Important**: If no action is needed after completing your analysis, you
+**MUST** call the `noop` safe-output tool with a brief explanation.
+
+```json
+{"noop": {"message": "No action needed: [brief explanation]"}}
+```
diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml
index 45526b90175..316b26306aa 100644
--- a/.github/workflows/release.lock.yml
+++ b/.github/workflows/release.lock.yml
@@ -26,7 +26,7 @@
 #   Imports:
 #     - shared/community-attribution.md
 #
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"f306ddda3cb96b1fb79f8d9a2d8b667a4cecf9c9f46bb1ffab476119cd9b3ebc","strict":true,"agent_id":"copilot"}
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"c44a6a762f1295539c44e0e18976497d6ae9d82fa1e86d280ea40b71087c0511","strict":true,"agent_id":"copilot"}
 
 name: "Release"
 "on":
@@ -310,12 +310,17 @@ jobs:
         run: bash ${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh
         env:
           GH_TOKEN: ${{ github.token }}
+      - env:
+          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        name: Fetch community-labeled issues
+        run: "mkdir -p /tmp/gh-aw/community-data\n\n# The \"community\" label is the **primary attribution signal**: a maintainer\n# explicitly tagged the issue as community-authored, making it a strong and\n# intentional marker that does not rely on free-text heuristics.\necho \"Fetching issues with 'community' label (primary attribution signal)...\"\nif ! gh issue list \\\n  --label \"community\" \\\n  --state all \\\n  --limit 500 \\\n  --json number,title,author,labels,closedAt,createdAt,url \\\n  > /tmp/gh-aw/community-data/community_issues.json; then\n  echo \"[]\" > /tmp/gh-aw/community-data/community_issues.json\nfi\n\nCOMMUNITY_COUNT=$(jq length \"/tmp/gh-aw/community-data/community_issues.json\")\necho \"✓ Fetched $COMMUNITY_COUNT community-labeled issues\"\necho \"  Data: /tmp/gh-aw/community-data/community_issues.json\""
       - env:
           GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
           RELEASE_ID: ${{ needs.release.outputs.release_id }}
           RELEASE_TAG: ${{ needs.config.outputs.release_tag }}
         name: Setup release environment
-        run: "set -e\nmkdir -p /tmp/gh-aw/release-data\n\n# Use the release ID and tag from the release job\necho \"Release ID from release job: $RELEASE_ID\"\necho \"Release tag from release job: $RELEASE_TAG\"\n\necho \"Processing release: $RELEASE_TAG\"\necho \"RELEASE_TAG=$RELEASE_TAG\" >> \"$GITHUB_ENV\"\n\n# Get the current release information\n# Use release ID to fetch release data\ngh api \"/repos/${{ github.repository }}/releases/$RELEASE_ID\" > /tmp/gh-aw/release-data/current_release.json\necho \"✓ Fetched current release information\"\n\n# Get the previous release to determine the range\nPREV_RELEASE_TAG=$(gh release list --limit 2 --json tagName --jq '.[1].tagName // empty')\n\nif [ -z \"$PREV_RELEASE_TAG\" ]; then\n  echo \"No previous release found. This appears to be the first release.\"\n  echo \"PREV_RELEASE_TAG=\" >> \"$GITHUB_ENV\"\n  touch /tmp/gh-aw/release-data/pull_requests.json\n  echo \"[]\" > /tmp/gh-aw/release-data/pull_requests.json\nelse\n  echo \"Previous release: $PREV_RELEASE_TAG\"\n  echo \"PREV_RELEASE_TAG=$PREV_RELEASE_TAG\" >> \"$GITHUB_ENV\"\n  \n  # Get commits between releases\n  echo \"Fetching commits between $PREV_RELEASE_TAG and $RELEASE_TAG...\"\n  git fetch --unshallow 2>/dev/null || git fetch --depth=1000\n  \n  # Get all merged PRs between the two releases (include closingIssuesReferences for attribution)\n  echo \"Fetching pull requests merged between releases...\"\n  PREV_PUBLISHED_AT=$(gh release view \"$PREV_RELEASE_TAG\" --json publishedAt --jq .publishedAt)\n  CURR_PUBLISHED_AT=$(gh release view \"$RELEASE_TAG\" --json publishedAt --jq .publishedAt)\n  gh pr list \\\n    --state merged \\\n    --limit 1000 \\\n    --json number,title,author,labels,mergedAt,url,body,closingIssuesReferences \\\n    --jq \"[.[] | select(.mergedAt >= \\\"$PREV_PUBLISHED_AT\\\" and .mergedAt <= \\\"$CURR_PUBLISHED_AT\\\")]\" \\\n    > /tmp/gh-aw/release-data/pull_requests.json\n  \n  PR_COUNT=$(jq length \"/tmp/gh-aw/release-data/pull_requests.json\")\n  echo \"✓ Fetched $PR_COUNT pull requests\"\nfi\n\n# Fetch community-labeled issues (include createdAt for timeline correlation)\necho \"Fetching issues with 'community' label...\"\nif ! gh issue list \\\n  --label \"community\" \\\n  --state all \\\n  --limit 500 \\\n  --json number,title,author,labels,closedAt,createdAt,url \\\n  > /tmp/gh-aw/release-data/community_issues.json; then\n  echo \"[]\" > /tmp/gh-aw/release-data/community_issues.json\nfi\n\nCOMMUNITY_COUNT=$(jq length \"/tmp/gh-aw/release-data/community_issues.json\")\necho \"✓ Fetched $COMMUNITY_COUNT community-labeled issues\"\n\n# Build closing references index from GitHub-native closingIssuesReferences\n# Maps each closed issue number -> list of PR numbers that directly close it\necho \"Building closing references index from GitHub-native PR links...\"\njq '\n  reduce .[] as $pr (\n    {};\n    $pr.closingIssuesReferences[]? as $issue |\n    ($issue.number | tostring) as $key |\n    .[$key] = (.[$key] // []) + [$pr.number]\n  )\n' /tmp/gh-aw/release-data/pull_requests.json \\\n  > /tmp/gh-aw/release-data/closing_refs_by_issue.json 2>/dev/null \\\n  || echo \"{}\" > /tmp/gh-aw/release-data/closing_refs_by_issue.json\n\nDIRECT_CLOSE_COUNT=$(jq 'keys | length' /tmp/gh-aw/release-data/closing_refs_by_issue.json)\necho \"✓ Found $DIRECT_CLOSE_COUNT issues with GitHub-native closing PR references\"\n\n# Find community issues closed during this release window (candidates for attribution review)\nif [ -n \"$PREV_PUBLISHED_AT\" ]; then\n  jq --arg prev \"$PREV_PUBLISHED_AT\" --arg curr \"$CURR_PUBLISHED_AT\" \\\n    '[.[] | select(.closedAt != null and .closedAt >= $prev and .closedAt <= $curr)]' \\\n    /tmp/gh-aw/release-data/community_issues.json \\\n    > /tmp/gh-aw/release-data/community_issues_closed_in_window.json 2>/dev/null \\\n    || echo \"[]\" > /tmp/gh-aw/release-data/community_issues_closed_in_window.json\n  \n  CLOSED_IN_WINDOW=$(jq length /tmp/gh-aw/release-data/community_issues_closed_in_window.json)\n  echo \"✓ Found $CLOSED_IN_WINDOW community issues closed in this release window\"\nelse\n  echo \"[]\" > /tmp/gh-aw/release-data/community_issues_closed_in_window.json\nfi\n\n# Get the CHANGELOG.md content around this version\nif [ -f \"CHANGELOG.md\" ]; then\n  cp CHANGELOG.md /tmp/gh-aw/release-data/CHANGELOG.md\n  echo \"✓ Copied CHANGELOG.md for reference\"\nfi\n\n# List documentation files for linking\nfind docs -type f -name \"*.md\" 2>/dev/null > /tmp/gh-aw/release-data/docs_files.txt || echo \"No docs directory found\"\n\necho \"✓ Setup complete. Data available in /tmp/gh-aw/release-data/\"\necho \"  Files: current_release.json, pull_requests.json, community_issues.json,\"\necho \"         closing_refs_by_issue.json, community_issues_closed_in_window.json,\"\necho \"         CHANGELOG.md (if exists), docs_files.txt\""
+        run: "set -e\nmkdir -p /tmp/gh-aw/release-data\n\n# Use the release ID and tag from the release job\necho \"Release ID from release job: $RELEASE_ID\"\necho \"Release tag from release job: $RELEASE_TAG\"\n\necho \"Processing release: $RELEASE_TAG\"\necho \"RELEASE_TAG=$RELEASE_TAG\" >> \"$GITHUB_ENV\"\n\n# Get the current release information\n# Use release ID to fetch release data\ngh api \"/repos/${{ github.repository }}/releases/$RELEASE_ID\" > /tmp/gh-aw/release-data/current_release.json\necho \"✓ Fetched current release information\"\n\n# Get the previous release to determine the range\nPREV_RELEASE_TAG=$(gh release list --limit 2 --json tagName --jq '.[1].tagName // empty')\n\nif [ -z \"$PREV_RELEASE_TAG\" ]; then\n  echo \"No previous release found. This appears to be the first release.\"\n  echo \"PREV_RELEASE_TAG=\" >> \"$GITHUB_ENV\"\n  touch /tmp/gh-aw/release-data/pull_requests.json\n  echo \"[]\" > /tmp/gh-aw/release-data/pull_requests.json\nelse\n  echo \"Previous release: $PREV_RELEASE_TAG\"\n  echo \"PREV_RELEASE_TAG=$PREV_RELEASE_TAG\" >> \"$GITHUB_ENV\"\n  \n  # Get commits between releases\n  echo \"Fetching commits between $PREV_RELEASE_TAG and $RELEASE_TAG...\"\n  git fetch --unshallow 2>/dev/null || git fetch --depth=1000\n  \n  # Get all merged PRs between the two releases (include closingIssuesReferences for attribution)\n  echo \"Fetching pull requests merged between releases...\"\n  PREV_PUBLISHED_AT=$(gh release view \"$PREV_RELEASE_TAG\" --json publishedAt --jq .publishedAt)\n  CURR_PUBLISHED_AT=$(gh release view \"$RELEASE_TAG\" --json publishedAt --jq .publishedAt)\n  gh pr list \\\n    --state merged \\\n    --limit 1000 \\\n    --json number,title,author,labels,mergedAt,url,body,closingIssuesReferences \\\n    --jq \"[.[] | select(.mergedAt >= \\\"$PREV_PUBLISHED_AT\\\" and .mergedAt <= \\\"$CURR_PUBLISHED_AT\\\")]\" \\\n    > /tmp/gh-aw/release-data/pull_requests.json\n  \n  PR_COUNT=$(jq length \"/tmp/gh-aw/release-data/pull_requests.json\")\n  echo \"✓ Fetched $PR_COUNT pull requests\"\nfi\n\n# Build closing references index from GitHub-native closingIssuesReferences\n# Maps each closed issue number -> list of PR numbers that directly close it\necho \"Building closing references index from GitHub-native PR links...\"\njq '\n  reduce .[] as $pr (\n    {};\n    $pr.closingIssuesReferences[]? as $issue |\n    ($issue.number | tostring) as $key |\n    .[$key] = (.[$key] // []) + [$pr.number]\n  )\n' /tmp/gh-aw/release-data/pull_requests.json \\\n  > /tmp/gh-aw/release-data/closing_refs_by_issue.json 2>/dev/null \\\n  || echo \"{}\" > /tmp/gh-aw/release-data/closing_refs_by_issue.json\n# Also expose to community-data dir so shared attribution strategy can reference it\ncp /tmp/gh-aw/release-data/closing_refs_by_issue.json /tmp/gh-aw/community-data/closing_refs_by_issue.json\ncp /tmp/gh-aw/release-data/pull_requests.json /tmp/gh-aw/community-data/pull_requests.json\n\nDIRECT_CLOSE_COUNT=$(jq 'keys | length' /tmp/gh-aw/release-data/closing_refs_by_issue.json)\necho \"✓ Found $DIRECT_CLOSE_COUNT issues with GitHub-native closing PR references\"\n\n# Find community issues closed during this release window (candidates for attribution review)\nif [ -n \"$PREV_PUBLISHED_AT\" ]; then\n  jq --arg prev \"$PREV_PUBLISHED_AT\" --arg curr \"$CURR_PUBLISHED_AT\" \\\n    '[.[] | select(.closedAt != null and .closedAt >= $prev and .closedAt <= $curr)]' \\\n    /tmp/gh-aw/community-data/community_issues.json \\\n    > /tmp/gh-aw/release-data/community_issues_closed_in_window.json 2>/dev/null \\\n    || echo \"[]\" > /tmp/gh-aw/release-data/community_issues_closed_in_window.json\n  \n  CLOSED_IN_WINDOW=$(jq length /tmp/gh-aw/release-data/community_issues_closed_in_window.json)\n  echo \"✓ Found $CLOSED_IN_WINDOW community issues closed in this release window\"\nelse\n  echo \"[]\" > /tmp/gh-aw/release-data/community_issues_closed_in_window.json\nfi\n\n# Get the CHANGELOG.md content around this version\nif [ -f \"CHANGELOG.md\" ]; then\n  cp CHANGELOG.md /tmp/gh-aw/release-data/CHANGELOG.md\n  echo \"✓ Copied CHANGELOG.md for reference\"\nfi\n\n# List documentation files for linking\nfind docs -type f -name \"*.md\" 2>/dev/null > /tmp/gh-aw/release-data/docs_files.txt || echo \"No docs directory found\"\n\necho \"✓ Setup complete.\"\necho \"  Release data: /tmp/gh-aw/release-data/ (current_release.json, pull_requests.json,\"\necho \"    closing_refs_by_issue.json, community_issues_closed_in_window.json,\"\necho \"    CHANGELOG.md (if exists), docs_files.txt)\"\necho \"  Community data: /tmp/gh-aw/community-data/ (community_issues.json,\"\necho \"    closing_refs_by_issue.json, pull_requests.json)\""
 
       - name: Configure Git credentials
         env:
@@ -586,13 +591,32 @@ jobs:
       - name: Execute GitHub Copilot CLI
         id: agentic_execution
         # Copilot CLI tool arguments (sorted):
+        # --allow-tool github
+        # --allow-tool safeoutputs
+        # --allow-tool shell(cat)
+        # --allow-tool shell(date)
+        # --allow-tool shell(echo *)
+        # --allow-tool shell(echo)
+        # --allow-tool shell(gh issue list *)
+        # --allow-tool shell(grep)
+        # --allow-tool shell(head)
+        # --allow-tool shell(jq *)
+        # --allow-tool shell(ls)
+        # --allow-tool shell(mkdir *)
+        # --allow-tool shell(pwd)
+        # --allow-tool shell(sort)
+        # --allow-tool shell(tail)
+        # --allow-tool shell(uniq)
+        # --allow-tool shell(wc)
+        # --allow-tool shell(yq)
+        # --allow-tool write
         timeout-minutes: 20
         run: |
           set -o pipefail
           touch /tmp/gh-aw/agent-step-summary.md
           # shellcheck disable=SC1003
           sudo -E awf --env-all --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" --allow-domains "*.jsr.io,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,bun.sh,cdn.jsdelivr.net,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,deb.nodesource.com,deno.land,esm.sh,get.pnpm.io,github.com,github.github.com,googleapis.deno.dev,googlechromelabs.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,s.symcb.com,s.symcd.com,security.ubuntu.com,skimdb.npmjs.com,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com,www.npmjs.com,www.npmjs.org,yarnpkg.com" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.24.5 --skip-pull --enable-api-proxy \
-            -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-all-tools --allow-all-paths --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+            -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-tool github --allow-tool safeoutputs --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(echo *)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(gh issue list *)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq *)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(mkdir *)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(uniq)'\'' --allow-tool '\''shell(wc)'\'' --allow-tool '\''shell(yq)'\'' --allow-tool write --allow-all-paths --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
         env:
           COPILOT_AGENT_RUNNER_TYPE: STANDALONE
           COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
diff --git a/.github/workflows/release.md b/.github/workflows/release.md
index 2870b0fad81..e2458547aad 100644
--- a/.github/workflows/release.md
+++ b/.github/workflows/release.md
@@ -419,20 +419,6 @@ steps:
         echo "✓ Fetched $PR_COUNT pull requests"
       fi
       
-      # Fetch community-labeled issues (include createdAt for timeline correlation)
-      echo "Fetching issues with 'community' label..."
-      if ! gh issue list \
-        --label "community" \
-        --state all \
-        --limit 500 \
-        --json number,title,author,labels,closedAt,createdAt,url \
-        > /tmp/gh-aw/release-data/community_issues.json; then
-        echo "[]" > /tmp/gh-aw/release-data/community_issues.json
-      fi
-      
-      COMMUNITY_COUNT=$(jq length "/tmp/gh-aw/release-data/community_issues.json")
-      echo "✓ Fetched $COMMUNITY_COUNT community-labeled issues"
-      
       # Build closing references index from GitHub-native closingIssuesReferences
       # Maps each closed issue number -> list of PR numbers that directly close it
       echo "Building closing references index from GitHub-native PR links..."
@@ -446,6 +432,9 @@ steps:
       ' /tmp/gh-aw/release-data/pull_requests.json \
         > /tmp/gh-aw/release-data/closing_refs_by_issue.json 2>/dev/null \
         || echo "{}" > /tmp/gh-aw/release-data/closing_refs_by_issue.json
+      # Also expose to community-data dir so shared attribution strategy can reference it
+      cp /tmp/gh-aw/release-data/closing_refs_by_issue.json /tmp/gh-aw/community-data/closing_refs_by_issue.json
+      cp /tmp/gh-aw/release-data/pull_requests.json /tmp/gh-aw/community-data/pull_requests.json
       
       DIRECT_CLOSE_COUNT=$(jq 'keys | length' /tmp/gh-aw/release-data/closing_refs_by_issue.json)
       echo "✓ Found $DIRECT_CLOSE_COUNT issues with GitHub-native closing PR references"
@@ -454,7 +443,7 @@ steps:
       if [ -n "$PREV_PUBLISHED_AT" ]; then
         jq --arg prev "$PREV_PUBLISHED_AT" --arg curr "$CURR_PUBLISHED_AT" \
           '[.[] | select(.closedAt != null and .closedAt >= $prev and .closedAt <= $curr)]' \
-          /tmp/gh-aw/release-data/community_issues.json \
+          /tmp/gh-aw/community-data/community_issues.json \
           > /tmp/gh-aw/release-data/community_issues_closed_in_window.json 2>/dev/null \
           || echo "[]" > /tmp/gh-aw/release-data/community_issues_closed_in_window.json
         
@@ -473,10 +462,12 @@ steps:
       # List documentation files for linking
       find docs -type f -name "*.md" 2>/dev/null > /tmp/gh-aw/release-data/docs_files.txt || echo "No docs directory found"
       
-      echo "✓ Setup complete. Data available in /tmp/gh-aw/release-data/"
-      echo "  Files: current_release.json, pull_requests.json, community_issues.json,"
-      echo "         closing_refs_by_issue.json, community_issues_closed_in_window.json,"
-      echo "         CHANGELOG.md (if exists), docs_files.txt"
+      echo "✓ Setup complete."
+      echo "  Release data: /tmp/gh-aw/release-data/ (current_release.json, pull_requests.json,"
+      echo "    closing_refs_by_issue.json, community_issues_closed_in_window.json,"
+      echo "    CHANGELOG.md (if exists), docs_files.txt)"
+      echo "  Community data: /tmp/gh-aw/community-data/ (community_issues.json,"
+      echo "    closing_refs_by_issue.json, pull_requests.json)"
 ---
 
 # Release Highlights Generator
@@ -487,15 +478,19 @@ Generate an engaging release highlights summary for **${{ github.repository }}**
 
 ## Data Available
 
-All data is pre-fetched in `/tmp/gh-aw/release-data/`:
+Release-specific data is pre-fetched in `/tmp/gh-aw/release-data/`:
 - `current_release.json` - Release metadata (tag, name, dates, existing body)
 - `pull_requests.json` - PRs merged between `${PREV_RELEASE_TAG}` and `${RELEASE_TAG}` (includes `closingIssuesReferences` for each PR; empty array if first release)
-- `community_issues.json` - All issues labeled `community` (issue number, title, author, closedAt, createdAt, url)
 - `closing_refs_by_issue.json` - Map of `{issue_number: [pr_numbers]}` built from GitHub-native closing references in merged PRs
 - `community_issues_closed_in_window.json` - Community issues whose `closedAt` falls within this release window (attribution candidates)
 - `CHANGELOG.md` - Full changelog for context (if exists)
 - `docs_files.txt` - Available documentation files for linking
 
+Community data is pre-fetched in `/tmp/gh-aw/community-data/` (by the shared community-attribution step):
+- `community_issues.json` - All issues labeled `community` (issue number, title, author, closedAt, createdAt, url)
+- `closing_refs_by_issue.json` - Same closing references index, mirrored for the shared attribution strategy
+- `pull_requests.json` - Same PR list, mirrored for the shared attribution strategy
+
 ## Output Requirements
 
 Create a **"🌟 Release Highlights"** section that:
@@ -516,27 +511,8 @@ cat /tmp/gh-aw/release-data/current_release.json | jq
 # List PRs (empty if first release)
 cat /tmp/gh-aw/release-data/pull_requests.json | jq -r '.[] | "- #\(.number): \(.title) by @\(.author.login)"'
 
-# List community issues
-cat /tmp/gh-aw/release-data/community_issues.json | jq -r '.[] | "- #\(.number): \(.title) by @\(.author.login)"'
-
-# Check CHANGELOG context
-head -100 /tmp/gh-aw/release-data/CHANGELOG.md 2>/dev/null || echo "No CHANGELOG"
-
-# View available docs
-cat /tmp/gh-aw/release-data/docs_files.txt
-```
-
-### 1. Load Data
-
-```bash
-# View release metadata
-cat /tmp/gh-aw/release-data/current_release.json | jq
-
-# List PRs (empty if first release)
-cat /tmp/gh-aw/release-data/pull_requests.json | jq -r '.[] | "- #\(.number): \(.title) by @\(.author.login)"'
-
-# List community issues
-cat /tmp/gh-aw/release-data/community_issues.json | jq -r '.[] | "- #\(.number): \(.title) by @\(.author.login)"'
+# List community issues (fetched by shared community-attribution step)
+cat /tmp/gh-aw/community-data/community_issues.json | jq -r '.[] | "- #\(.number): \(.title) by @\(.author.login)"'
 
 # View GitHub-native closing references (issue -> [PRs])
 cat /tmp/gh-aw/release-data/closing_refs_by_issue.json | jq
@@ -553,58 +529,12 @@ cat /tmp/gh-aw/release-data/docs_files.txt
 
 ### 2. Identify Community Contributions
 
-Cross-reference `community_issues.json` with `pull_requests.json` to find which community issues are resolved in this release. Use a **tiered approach** — work through all tiers before concluding attribution, and do **not** silently omit ambiguous cases.
-
-#### Tier 1 — GitHub-native closing references (primary)
-
-`closing_refs_by_issue.json` contains GitHub's own link metadata: the set of issues that each merged PR is marked as "closing" via the native GitHub close-with-keyword feature. This is the most reliable signal.
-
-```bash
-# Get all community issue numbers
-COMMUNITY_NUMBERS=$(jq '[.[].number]' /tmp/gh-aw/release-data/community_issues.json)
-
-# Find community issues that have a GitHub-native closing PR in this release
-jq --argjson community "$COMMUNITY_NUMBERS" \
-  'to_entries | map(select((.key | tonumber) as $n | $community | any(. == $n))) | from_entries' \
-  /tmp/gh-aw/release-data/closing_refs_by_issue.json
-```
-
-For each matched issue, record it as **confirmed** attribution.
-
-#### Tier 2 — PR body keyword parsing (secondary fallback)
-
-For community issues **not yet matched** in Tier 1, search PR bodies for closing keywords. This covers cases where authors used keywords but GitHub's native link was not established (e.g., fully-qualified repo references).
-
-```bash
-# Supports both bare (#123) and fully-qualified (org/repo#123) references
-cat /tmp/gh-aw/release-data/pull_requests.json | jq -r '.[].body // ""' | \
-  grep -oP '(?i)(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s*(?:github/gh-aw#|#)\K[0-9]+' | sort -u
-```
-
-Add any newly matched community issues to the **confirmed** list.
-
-#### Tier 3 — GitHub MCP cross-reference lookup (deep investigation for follow-up chains)
-
-For community issues **still unmatched** after Tiers 1 and 2, use the GitHub MCP `issue_read` tool to check whether the issue is linked to a follow-up or split issue whose fix shipped in this release. This handles the case where a community report was routed through a separate tracking issue.
-
-For each unmatched community issue that was closed during this release window (from `community_issues_closed_in_window.json`):
-
-1. Use `issue_read` with `method: "get_comments"` to scan the issue body and comments for references to other issues or PRs.
-2. Check whether any referenced issue number appears as a closing target in `closing_refs_by_issue.json` or in the PR bodies already scanned.
-3. If a transitive chain is found (community issue → follow-up issue → merged PR), record it as **confirmed (via follow-up)** attribution and note the chain (e.g., "via follow-up #N").
-
-#### Tier 4 — Surface ambiguous attribution candidates for review
-
-After all three active tiers, check `community_issues_closed_in_window.json` for any community issues that were closed during this release window but **could not be linked** to a specific merged PR through any tier. These should **not be silently dropped** — instead surface them in a dedicated review section.
-
-```bash
-# Check for community issues closed in window but not yet attributed
-cat /tmp/gh-aw/release-data/community_issues_closed_in_window.json | jq 'length'
-```
-
-If any unlinked candidates exist, add them to the **"⚠️ Attribution Candidates Need Review"** subsection (see output format below).
-
-For each community issue resolved in this release, note the **issue author** from `community_issues.json`. These are the community contributors to celebrate.
+The `community` label is the **primary attribution signal** — apply the
+four-tier Community Attribution Strategy from the imported shared component
+(`shared/community-attribution.md`) to attribute all community-labeled issues
+that were closed in this release window.  Use `/tmp/gh-aw/release-data/community_issues_closed_in_window.json`
+as the set of candidates and `/tmp/gh-aw/release-data/closing_refs_by_issue.json`
+as the attribution index.
 
 ### 3. Categorize & Prioritize
 
diff --git a/.github/workflows/shared/community-attribution.md b/.github/workflows/shared/community-attribution.md
index 80576619e89..cc643b876d3 100644
--- a/.github/workflows/shared/community-attribution.md
+++ b/.github/workflows/shared/community-attribution.md
@@ -1,21 +1,58 @@
-<!--
-This shared component documents the tiered strategy for reliably attributing
-community contributions in release notes.
+---
+# Fetches all issues carrying the "community" label. This label is the
+# primary signal that a report was authored by a community member; every
+# issue bearing it should be considered for attribution.
+tools:
+  bash:
+    - "gh issue list *"
+    - "jq *"
+    - "mkdir *"
+    - "echo *"
+
+steps:
+  - name: Fetch community-labeled issues
+    env:
+      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+    run: |
+      mkdir -p /tmp/gh-aw/community-data
+
+      # The "community" label is the **primary attribution signal**: a maintainer
+      # explicitly tagged the issue as community-authored, making it a strong and
+      # intentional marker that does not rely on free-text heuristics.
+      echo "Fetching issues with 'community' label (primary attribution signal)..."
+      if ! gh issue list \
+        --label "community" \
+        --state all \
+        --limit 500 \
+        --json number,title,author,labels,closedAt,createdAt,url \
+        > /tmp/gh-aw/community-data/community_issues.json; then
+        echo "[]" > /tmp/gh-aw/community-data/community_issues.json
+      fi
+
+      COMMUNITY_COUNT=$(jq length "/tmp/gh-aw/community-data/community_issues.json")
+      echo "✓ Fetched $COMMUNITY_COUNT community-labeled issues"
+      echo "  Data: /tmp/gh-aw/community-data/community_issues.json"
+---
 
-The following pre-fetched files must exist before applying this strategy.
-They are typically produced by the release setup step:
+## Community Attribution Strategy
 
-- merged pull requests with closing issue references
-- community-labeled issues with closed timestamps
-- a closing references index mapping issue numbers to PR numbers
-- community issues closed within the release window
--->
+The **`community` label** is the primary attribution signal.  It is applied by
+maintainers to explicitly mark issues as community-authored — a strong,
+intentional indicator that does not rely on free-text heuristics.
 
-## Community Attribution Strategy
+Pre-fetched data is available at `/tmp/gh-aw/community-data/`:
+
+```bash
+# List all community-labeled issues
+cat /tmp/gh-aw/community-data/community_issues.json \
+  | jq -r '.[] | "- #\(.number): \(.title) by @\(.author.login) (closed: \(.closedAt // "open"))"'
+```
 
 Use the following **four-tier** approach to identify which community-labeled
-issues were resolved in a release.  Work through all tiers before concluding,
-and never silently drop a community issue that was closed during the release window.
+issues were resolved in a given period.  Work through all tiers before
+concluding, and never silently drop a community issue that was closed during
+the period under review.
 
 ### Tier 1 — GitHub-native closing references (primary)
 
@@ -24,13 +61,13 @@ and never silently drop a community issue that was closed during the release win
 the strongest signal because it does not depend on free-text conventions.
 
 ```bash
-COMMUNITY_NUMBERS=$(jq '[.[].number]' /tmp/gh-aw/release-data/community_issues.json)
+COMMUNITY_NUMBERS=$(jq '[.[].number]' /tmp/gh-aw/community-data/community_issues.json)
 
 jq --argjson community "$COMMUNITY_NUMBERS" \
   'to_entries
    | map(select((.key | tonumber) as $n | $community | any(. == $n)))
    | from_entries' \
-  /tmp/gh-aw/release-data/closing_refs_by_issue.json
+  /tmp/gh-aw/community-data/closing_refs_by_issue.json
 ```
 
 Record every matched issue as **confirmed** attribution.
@@ -42,7 +79,7 @@ closing keywords.  Both bare (`#123`) and fully-qualified (`org/repo#123`)
 forms are supported.
 
 ```bash
-jq -r '.[].body // ""' /tmp/gh-aw/release-data/pull_requests.json \
+jq -r '.[].body // ""' /tmp/gh-aw/community-data/pull_requests.json \
   | grep -oP '(?i)(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s*(?:github/gh-aw#|#)\K[0-9]+' \
   | sort -u
 ```
@@ -51,9 +88,9 @@ Add any newly matched community issues to the **confirmed** list.
 
 ### Tier 3 — GitHub MCP cross-reference lookup (follow-up / split issue chains)
 
-For community issues **still unmatched** after Tiers 1 and 2 that appear in
-`community_issues_closed_in_window.json`, use the GitHub MCP `issue_read`
-tool to look for indirect linkage through follow-up or split issues:
+For community issues **still unmatched** after Tiers 1 and 2, use the GitHub
+MCP `issue_read` tool to look for indirect linkage through follow-up or split
+issues:
 
 1. Call `issue_read` with `method: "get_comments"` on the community issue.
 2. Collect any referenced issue or PR numbers found in the body or comments.
@@ -61,17 +98,17 @@ tool to look for indirect linkage through follow-up or split issues:
    `closing_refs_by_issue.json` or in the PR bodies already scanned.
 4. If a transitive chain is found (community issue → follow-up issue → merged
    PR), record the community issue as **confirmed (via follow-up)** and note
-   the chain in the release notes entry, for example: `_(via follow-up #N)_`.
+   the chain in the output, for example: `_(via follow-up #N)_`.
 
 ### Tier 4 — Surface ambiguous candidates (fail soft, not silent)
 
 After all three active tiers, any community issue that was closed during the
-release window but cannot be linked to a specific merged PR must **not** be
+review period but cannot be linked to a specific merged PR must **not** be
 silently dropped.  Add it to the **"⚠️ Attribution Candidates Need Review"**
 section so a maintainer can make the final call.
 
 ```bash
-cat /tmp/gh-aw/release-data/community_issues_closed_in_window.json | jq 'length'
+cat /tmp/gh-aw/community-data/community_issues_closed_in_window.json | jq 'length'
 ```
 
 ### Output sections
@@ -93,9 +130,9 @@ resolved in this release:
 ```markdown
 ### ⚠️ Attribution Candidates Need Review
 
-The following community issues were closed during this release window but
-could not be automatically linked to a specific merged PR.  Please verify
-whether they should be credited:
+The following community issues were closed during this period but could not
+be automatically linked to a specific merged PR.  Please verify whether they
+should be credited:
 
 - **@author** for Issue title ([#N](url)) — closed DATE, no confirmed PR linkage found
 ```

From 5dc266e5c0f7414185adda1fdd15cb272fa84c3e Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 21 Mar 2026 16:15:03 +0000
Subject: [PATCH 5/7] Set draft: true on daily-community-attribution
 create-pull-request safe-output

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/19bb8494-62a2-4049-b4e0-9ddeada1ba1b
---
 .github/workflows/daily-community-attribution.lock.yml | 8 ++++----
 .github/workflows/daily-community-attribution.md       | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/.github/workflows/daily-community-attribution.lock.yml b/.github/workflows/daily-community-attribution.lock.yml
index 30a0dede129..c4acbd9f903 100644
--- a/.github/workflows/daily-community-attribution.lock.yml
+++ b/.github/workflows/daily-community-attribution.lock.yml
@@ -26,7 +26,7 @@
 #   Imports:
 #     - shared/community-attribution.md
 #
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"c36009e53493e2e1a341c008594333bd52392f065213d299e4883f7ee2e1da56","strict":true,"agent_id":"copilot"}
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"53af59b5c774f5d29c12f82bf589b92b3fa7647df4de1d65c074b870ad31d6ce","strict":true,"agent_id":"copilot"}
 
 name: "Daily Community Attribution Updater"
 "on":
@@ -357,14 +357,14 @@ jobs:
           mkdir -p /tmp/gh-aw/safeoutputs
           mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
           cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
-          {"create_pull_request":{"expires":24,"max":1,"title_prefix":"[community] "},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+          {"create_pull_request":{"draft":true,"expires":24,"max":1,"title_prefix":"[community] "},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
           GH_AW_SAFE_OUTPUTS_CONFIG_EOF
       - name: Write Safe Outputs Tools
         run: |
           cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_EOF'
           {
             "description_suffixes": {
-              "create_pull_request": " CONSTRAINTS: Maximum 1 pull request(s) can be created. Title will be prefixed with \"[community] \". Labels [\"community\" \"automation\"] will be automatically added."
+              "create_pull_request": " CONSTRAINTS: Maximum 1 pull request(s) can be created. Title will be prefixed with \"[community] \". Labels [\"community\" \"automation\"] will be automatically added. PRs will be created as drafts."
             },
             "repo_params": {},
             "dynamic_tools": []
@@ -1128,7 +1128,7 @@ jobs:
           GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
           GITHUB_SERVER_URL: ${{ github.server_url }}
           GITHUB_API_URL: ${{ github.api_url }}
-          GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_pull_request\":{\"draft\":false,\"expires\":24,\"labels\":[\"community\",\"automation\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"title_prefix\":\"[community] \"},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"}}"
+          GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_pull_request\":{\"draft\":true,\"expires\":24,\"labels\":[\"community\",\"automation\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"title_prefix\":\"[community] \"},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"}}"
           GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }}
         with:
           github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/daily-community-attribution.md b/.github/workflows/daily-community-attribution.md
index b7a3cd6bbf3..70201dba72b 100644
--- a/.github/workflows/daily-community-attribution.md
+++ b/.github/workflows/daily-community-attribution.md
@@ -39,7 +39,7 @@ safe-outputs:
     title-prefix: "[community] "
     labels: [community, automation]
     reviewers: []
-    draft: false
+    draft: true
 
 imports:
   - shared/community-attribution.md

From 43dd611e809dba7eb94163da9ffcd95f462ceed4 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 21 Mar 2026 16:28:56 +0000
Subject: [PATCH 6/7] =?UTF-8?q?Remove=20tools.github=20from=20release.md?=
 =?UTF-8?q?=20=E2=80=94=20data=20is=20precomputed=20in=20files?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/52ee973b-7cdc-4221-937b-2ec43fbabd9a
---
 .github/workflows/release.lock.yml | 4 ++--
 .github/workflows/release.md       | 4 ----
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml
index 316b26306aa..3078f29c94f 100644
--- a/.github/workflows/release.lock.yml
+++ b/.github/workflows/release.lock.yml
@@ -26,7 +26,7 @@
 #   Imports:
 #     - shared/community-attribution.md
 #
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"c44a6a762f1295539c44e0e18976497d6ae9d82fa1e86d280ea40b71087c0511","strict":true,"agent_id":"copilot"}
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"53ad451269810399fa9802e325cf7e29e33bd559463f521e6b78b8f814bf0369","strict":true,"agent_id":"copilot"}
 
 name: "Release"
 "on":
@@ -548,7 +548,7 @@ jobs:
                   "GITHUB_HOST": "\${GITHUB_SERVER_URL}",
                   "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
                   "GITHUB_READ_ONLY": "1",
-                  "GITHUB_TOOLSETS": "issues,pull_requests"
+                  "GITHUB_TOOLSETS": "context,repos,issues,pull_requests"
                 },
                 "guard-policies": {
                   "allow-only": {
diff --git a/.github/workflows/release.md b/.github/workflows/release.md
index e2458547aad..ec0f69593a9 100644
--- a/.github/workflows/release.md
+++ b/.github/workflows/release.md
@@ -28,10 +28,6 @@ network:
     - defaults
     - node
     - "github.github.com"
-tools:
-  github:
-    mode: "local"
-    toolsets: [issues, pull_requests]
 safe-outputs:
   update-release:
 imports:

From 00aaf945574c27c78b710f161674016067d687d6 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 21 Mar 2026 16:45:19 +0000
Subject: [PATCH 7/7] Merge main and recompile lock files

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/66f2887f-5b99-46d8-a00c-9c772a294e3b
---
 .../daily-community-attribution.lock.yml      |  8 ++--
 .github/workflows/release.lock.yml            | 37 +++++++++++++++++--
 2 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/.github/workflows/daily-community-attribution.lock.yml b/.github/workflows/daily-community-attribution.lock.yml
index c4acbd9f903..a963681925a 100644
--- a/.github/workflows/daily-community-attribution.lock.yml
+++ b/.github/workflows/daily-community-attribution.lock.yml
@@ -236,7 +236,7 @@ jobs:
         run: bash ${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh
       - name: Upload activation artifact
         if: success()
-        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
         with:
           name: activation
           path: |
@@ -766,7 +766,7 @@ jobs:
       - name: Upload agent artifacts
         if: always()
         continue-on-error: true
-        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
         with:
           name: agent
           path: |
@@ -880,7 +880,7 @@ jobs:
             await main();
       - name: Upload threat detection log
         if: always() && steps.detection_guard.outputs.run_detection == 'true'
-        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
         with:
           name: detection
           path: /tmp/gh-aw/threat-detection/detection.log
@@ -1139,7 +1139,7 @@ jobs:
             await main();
       - name: Upload safe output items
         if: always()
-        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
         with:
           name: safe-output-items
           path: /tmp/gh-aw/safe-output-items.jsonl
diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml
index 40c8c8b5a49..08959a6e681 100644
--- a/.github/workflows/release.lock.yml
+++ b/.github/workflows/release.lock.yml
@@ -22,7 +22,11 @@
 #
 # Build, test, and release gh-aw extension, then generate and prepend release highlights
 #
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"1762a952e24f3391b6c12f03293ea3819ee4c2435eddea8c42e477cb3684b3db","strict":true,"agent_id":"copilot"}
+# Resolved workflow manifest:
+#   Imports:
+#     - shared/community-attribution.md
+#
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"77776679e0e3d2842bfd82b1429abeb6ba6d1005274257fe7a5753d84431c8aa","strict":true,"agent_id":"copilot"}
 
 name: "Release"
 "on":
@@ -182,6 +186,9 @@ jobs:
           </system>
           GH_AW_PROMPT_EOF
           cat << 'GH_AW_PROMPT_EOF'
+          {{#runtime-import .github/workflows/shared/community-attribution.md}}
+          GH_AW_PROMPT_EOF
+          cat << 'GH_AW_PROMPT_EOF'
           {{#runtime-import .github/workflows/release.md}}
           GH_AW_PROMPT_EOF
           } > "$GH_AW_PROMPT"
@@ -303,12 +310,17 @@ jobs:
         run: bash ${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh
         env:
           GH_TOKEN: ${{ github.token }}
+      - env:
+          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        name: Fetch community-labeled issues
+        run: "mkdir -p /tmp/gh-aw/community-data\n\n# The \"community\" label is the **primary attribution signal**: a maintainer\n# explicitly tagged the issue as community-authored, making it a strong and\n# intentional marker that does not rely on free-text heuristics.\necho \"Fetching issues with 'community' label (primary attribution signal)...\"\nif ! gh issue list \\\n  --label \"community\" \\\n  --state all \\\n  --limit 500 \\\n  --json number,title,author,labels,closedAt,createdAt,url \\\n  > /tmp/gh-aw/community-data/community_issues.json; then\n  echo \"[]\" > /tmp/gh-aw/community-data/community_issues.json\nfi\n\nCOMMUNITY_COUNT=$(jq length \"/tmp/gh-aw/community-data/community_issues.json\")\necho \"✓ Fetched $COMMUNITY_COUNT community-labeled issues\"\necho \"  Data: /tmp/gh-aw/community-data/community_issues.json\""
       - env:
           GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
           RELEASE_ID: ${{ needs.release.outputs.release_id }}
           RELEASE_TAG: ${{ needs.config.outputs.release_tag }}
         name: Setup release environment
-        run: "set -e\nmkdir -p /tmp/gh-aw/release-data\n\n# Use the release ID and tag from the release job\necho \"Release ID from release job: $RELEASE_ID\"\necho \"Release tag from release job: $RELEASE_TAG\"\n\necho \"Processing release: $RELEASE_TAG\"\necho \"RELEASE_TAG=$RELEASE_TAG\" >> \"$GITHUB_ENV\"\n\n# Get the current release information\n# Use release ID to fetch release data\ngh api \"/repos/${{ github.repository }}/releases/$RELEASE_ID\" > /tmp/gh-aw/release-data/current_release.json\necho \"✓ Fetched current release information\"\n\n# Get the previous release to determine the range\nPREV_RELEASE_TAG=$(gh release list --limit 2 --json tagName --jq '.[1].tagName // empty')\n\nif [ -z \"$PREV_RELEASE_TAG\" ]; then\n  echo \"No previous release found. This appears to be the first release.\"\n  echo \"PREV_RELEASE_TAG=\" >> \"$GITHUB_ENV\"\n  touch /tmp/gh-aw/release-data/pull_requests.json\n  echo \"[]\" > /tmp/gh-aw/release-data/pull_requests.json\nelse\n  echo \"Previous release: $PREV_RELEASE_TAG\"\n  echo \"PREV_RELEASE_TAG=$PREV_RELEASE_TAG\" >> \"$GITHUB_ENV\"\n  \n  # Get commits between releases\n  echo \"Fetching commits between $PREV_RELEASE_TAG and $RELEASE_TAG...\"\n  git fetch --unshallow 2>/dev/null || git fetch --depth=1000\n  \n  # Get all merged PRs between the two releases\n  echo \"Fetching pull requests merged between releases...\"\n  PREV_PUBLISHED_AT=$(gh release view \"$PREV_RELEASE_TAG\" --json publishedAt --jq .publishedAt)\n  CURR_PUBLISHED_AT=$(gh release view \"$RELEASE_TAG\" --json publishedAt --jq .publishedAt)\n  gh pr list \\\n    --state merged \\\n    --limit 1000 \\\n    --json number,title,author,labels,mergedAt,url,body \\\n    --jq \"[.[] | select(.mergedAt >= \\\"$PREV_PUBLISHED_AT\\\" and .mergedAt <= \\\"$CURR_PUBLISHED_AT\\\")]\" \\\n    > /tmp/gh-aw/release-data/pull_requests.json\n  \n  PR_COUNT=$(jq length \"/tmp/gh-aw/release-data/pull_requests.json\")\n  echo \"✓ Fetched $PR_COUNT pull requests\"\nfi\n\n# Fetch community-labeled issues\necho \"Fetching issues with 'community' label...\"\nif ! gh issue list \\\n  --label \"community\" \\\n  --state all \\\n  --limit 500 \\\n  --json number,title,author,labels,closedAt,url \\\n  > /tmp/gh-aw/release-data/community_issues.json; then\n  echo \"[]\" > /tmp/gh-aw/release-data/community_issues.json\nfi\n\nCOMMUNITY_COUNT=$(jq length \"/tmp/gh-aw/release-data/community_issues.json\")\necho \"✓ Fetched $COMMUNITY_COUNT community-labeled issues\"\n\n# Get the CHANGELOG.md content around this version\nif [ -f \"CHANGELOG.md\" ]; then\n  cp CHANGELOG.md /tmp/gh-aw/release-data/CHANGELOG.md\n  echo \"✓ Copied CHANGELOG.md for reference\"\nfi\n\n# List documentation files for linking\nfind docs -type f -name \"*.md\" 2>/dev/null > /tmp/gh-aw/release-data/docs_files.txt || echo \"No docs directory found\"\n\necho \"✓ Setup complete. Data available in /tmp/gh-aw/release-data/\""
+        run: "set -e\nmkdir -p /tmp/gh-aw/release-data\n\n# Use the release ID and tag from the release job\necho \"Release ID from release job: $RELEASE_ID\"\necho \"Release tag from release job: $RELEASE_TAG\"\n\necho \"Processing release: $RELEASE_TAG\"\necho \"RELEASE_TAG=$RELEASE_TAG\" >> \"$GITHUB_ENV\"\n\n# Get the current release information\n# Use release ID to fetch release data\ngh api \"/repos/${{ github.repository }}/releases/$RELEASE_ID\" > /tmp/gh-aw/release-data/current_release.json\necho \"✓ Fetched current release information\"\n\n# Get the previous release to determine the range\nPREV_RELEASE_TAG=$(gh release list --limit 2 --json tagName --jq '.[1].tagName // empty')\n\nif [ -z \"$PREV_RELEASE_TAG\" ]; then\n  echo \"No previous release found. This appears to be the first release.\"\n  echo \"PREV_RELEASE_TAG=\" >> \"$GITHUB_ENV\"\n  touch /tmp/gh-aw/release-data/pull_requests.json\n  echo \"[]\" > /tmp/gh-aw/release-data/pull_requests.json\nelse\n  echo \"Previous release: $PREV_RELEASE_TAG\"\n  echo \"PREV_RELEASE_TAG=$PREV_RELEASE_TAG\" >> \"$GITHUB_ENV\"\n  \n  # Get commits between releases\n  echo \"Fetching commits between $PREV_RELEASE_TAG and $RELEASE_TAG...\"\n  git fetch --unshallow 2>/dev/null || git fetch --depth=1000\n  \n  # Get all merged PRs between the two releases (include closingIssuesReferences for attribution)\n  echo \"Fetching pull requests merged between releases...\"\n  PREV_PUBLISHED_AT=$(gh release view \"$PREV_RELEASE_TAG\" --json publishedAt --jq .publishedAt)\n  CURR_PUBLISHED_AT=$(gh release view \"$RELEASE_TAG\" --json publishedAt --jq .publishedAt)\n  gh pr list \\\n    --state merged \\\n    --limit 1000 \\\n    --json number,title,author,labels,mergedAt,url,body,closingIssuesReferences \\\n    --jq \"[.[] | select(.mergedAt >= \\\"$PREV_PUBLISHED_AT\\\" and .mergedAt <= \\\"$CURR_PUBLISHED_AT\\\")]\" \\\n    > /tmp/gh-aw/release-data/pull_requests.json\n  \n  PR_COUNT=$(jq length \"/tmp/gh-aw/release-data/pull_requests.json\")\n  echo \"✓ Fetched $PR_COUNT pull requests\"\nfi\n\n# Build closing references index from GitHub-native closingIssuesReferences\n# Maps each closed issue number -> list of PR numbers that directly close it\necho \"Building closing references index from GitHub-native PR links...\"\njq '\n  reduce .[] as $pr (\n    {};\n    $pr.closingIssuesReferences[]? as $issue |\n    ($issue.number | tostring) as $key |\n    .[$key] = (.[$key] // []) + [$pr.number]\n  )\n' /tmp/gh-aw/release-data/pull_requests.json \\\n  > /tmp/gh-aw/release-data/closing_refs_by_issue.json 2>/dev/null \\\n  || echo \"{}\" > /tmp/gh-aw/release-data/closing_refs_by_issue.json\n# Also expose to community-data dir so shared attribution strategy can reference it\ncp /tmp/gh-aw/release-data/closing_refs_by_issue.json /tmp/gh-aw/community-data/closing_refs_by_issue.json\ncp /tmp/gh-aw/release-data/pull_requests.json /tmp/gh-aw/community-data/pull_requests.json\n\nDIRECT_CLOSE_COUNT=$(jq 'keys | length' /tmp/gh-aw/release-data/closing_refs_by_issue.json)\necho \"✓ Found $DIRECT_CLOSE_COUNT issues with GitHub-native closing PR references\"\n\n# Find community issues closed during this release window (candidates for attribution review)\nif [ -n \"$PREV_PUBLISHED_AT\" ]; then\n  jq --arg prev \"$PREV_PUBLISHED_AT\" --arg curr \"$CURR_PUBLISHED_AT\" \\\n    '[.[] | select(.closedAt != null and .closedAt >= $prev and .closedAt <= $curr)]' \\\n    /tmp/gh-aw/community-data/community_issues.json \\\n    > /tmp/gh-aw/release-data/community_issues_closed_in_window.json 2>/dev/null \\\n    || echo \"[]\" > /tmp/gh-aw/release-data/community_issues_closed_in_window.json\n  \n  CLOSED_IN_WINDOW=$(jq length /tmp/gh-aw/release-data/community_issues_closed_in_window.json)\n  echo \"✓ Found $CLOSED_IN_WINDOW community issues closed in this release window\"\nelse\n  echo \"[]\" > /tmp/gh-aw/release-data/community_issues_closed_in_window.json\nfi\n\n# Get the CHANGELOG.md content around this version\nif [ -f \"CHANGELOG.md\" ]; then\n  cp CHANGELOG.md /tmp/gh-aw/release-data/CHANGELOG.md\n  echo \"✓ Copied CHANGELOG.md for reference\"\nfi\n\n# List documentation files for linking\nfind docs -type f -name \"*.md\" 2>/dev/null > /tmp/gh-aw/release-data/docs_files.txt || echo \"No docs directory found\"\n\necho \"✓ Setup complete.\"\necho \"  Release data: /tmp/gh-aw/release-data/ (current_release.json, pull_requests.json,\"\necho \"    closing_refs_by_issue.json, community_issues_closed_in_window.json,\"\necho \"    CHANGELOG.md (if exists), docs_files.txt)\"\necho \"  Community data: /tmp/gh-aw/community-data/ (community_issues.json,\"\necho \"    closing_refs_by_issue.json, pull_requests.json)\""
 
       - name: Configure Git credentials
         env:
@@ -579,13 +591,32 @@ jobs:
       - name: Execute GitHub Copilot CLI
         id: agentic_execution
         # Copilot CLI tool arguments (sorted):
+        # --allow-tool github
+        # --allow-tool safeoutputs
+        # --allow-tool shell(cat)
+        # --allow-tool shell(date)
+        # --allow-tool shell(echo *)
+        # --allow-tool shell(echo)
+        # --allow-tool shell(gh issue list *)
+        # --allow-tool shell(grep)
+        # --allow-tool shell(head)
+        # --allow-tool shell(jq *)
+        # --allow-tool shell(ls)
+        # --allow-tool shell(mkdir *)
+        # --allow-tool shell(pwd)
+        # --allow-tool shell(sort)
+        # --allow-tool shell(tail)
+        # --allow-tool shell(uniq)
+        # --allow-tool shell(wc)
+        # --allow-tool shell(yq)
+        # --allow-tool write
         timeout-minutes: 20
         run: |
           set -o pipefail
           touch /tmp/gh-aw/agent-step-summary.md
           # shellcheck disable=SC1003
           sudo -E awf --env-all --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" --allow-domains "*.jsr.io,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,bun.sh,cdn.jsdelivr.net,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,deb.nodesource.com,deno.land,esm.sh,get.pnpm.io,github.com,github.github.com,googleapis.deno.dev,googlechromelabs.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,s.symcb.com,s.symcd.com,security.ubuntu.com,skimdb.npmjs.com,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com,www.npmjs.com,www.npmjs.org,yarnpkg.com" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.24.5 --skip-pull --enable-api-proxy \
-            -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-all-tools --allow-all-paths --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+            -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-tool github --allow-tool safeoutputs --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(echo *)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(gh issue list *)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq *)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(mkdir *)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(uniq)'\'' --allow-tool '\''shell(wc)'\'' --allow-tool '\''shell(yq)'\'' --allow-tool write --allow-all-paths --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
         env:
           COPILOT_AGENT_RUNNER_TYPE: STANDALONE
           COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
