From 74270c2c37cc0be7d6d690f4295b732305e951d1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 23 Apr 2026 17:58:32 +0000 Subject: [PATCH 1/2] Initial plan From 466bfa229bdb6c223104a805478a012e168c5f25 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 23 Apr 2026 18:18:20 +0000 Subject: [PATCH 2/2] feat: optimize architecture-guardian with bash pre-step consolidation - Add bash pre-step that collects all file metrics upfront into /tmp/gh-aw/agent/arch-metrics.json, replacing ~20-30 per-file agent turns with a single deterministic bash step - Remove github: toolsets: [repos] (unused in local static analysis) - Remove edit: tool (workflow is read-only, tool was never called) - Simplify violation reporting to 2-line templated format per violation instead of verbose 3-part narrative suggestions - Improve Go receiver method detection in awk pattern - Expand JS function detection to cover arrow functions and exports - Add comment explaining go list error handling - Add instruction for agent to replace template placeholders Estimated savings: ~800K-1.1M tokens per run (~40-55% reduction) Reduces expected turns from 47 to ~15-20 Agent-Logs-Url: https://github.com/github/gh-aw/sessions/8b9b7035-c5bd-4617-9684-7537d0c6b157 Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --- .../workflows/architecture-guardian.lock.yml | 53 ++-- .github/workflows/architecture-guardian.md | 298 ++++++++---------- .../src/content/docs/agent-factory-status.mdx | 3 + .../docs/reference/frontmatter-full.md | 22 +- 4 files changed, 174 insertions(+), 202 deletions(-) diff --git a/.github/workflows/architecture-guardian.lock.yml b/.github/workflows/architecture-guardian.lock.yml index db4c8ef18ee..c40fdaffbdc 100644 --- a/.github/workflows/architecture-guardian.lock.yml +++ b/.github/workflows/architecture-guardian.lock.yml @@ -1,5 +1,5 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"6e058dfe39de24cbb46e8cf0c81f6070575ac7392250c7e4b5e61d68efe6ac44","strict":true,"agent_id":"copilot"} -# gh-aw-manifest: {"version":1,"secrets":["GH_AW_AGENT_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.28","digest":"sha256:a8834e285807654bf680154faa710d43fe4365a0868142f5c20e48c85e137a7a","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.25.28@sha256:a8834e285807654bf680154faa710d43fe4365a0868142f5c20e48c85e137a7a"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.28","digest":"sha256:93290f2393752252911bd7c39a047f776c0b53063575e7bde4e304962a9a61cb","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.28@sha256:93290f2393752252911bd7c39a047f776c0b53063575e7bde4e304962a9a61cb"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.28","digest":"sha256:844c18280f82cd1b06345eb2f4e91966b34185bfc51c9f237c3e022e848fb474","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.25.28@sha256:844c18280f82cd1b06345eb2f4e91966b34185bfc51c9f237c3e022e848fb474"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.2.30","digest":"sha256:e950e6d39f003862d33bfb8d4eb93e242d919cf6ca874b90728e5e0ea7434c6f","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.2.30@sha256:e950e6d39f003862d33bfb8d4eb93e242d919cf6ca874b90728e5e0ea7434c6f"},{"image":"ghcr.io/github/github-mcp-server:v1.0.0","digest":"sha256:d2550953f8050bc5a1c8f80d1678766f66f60bbfbcd953fdeaf661fe4269bd95","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.0@sha256:d2550953f8050bc5a1c8f80d1678766f66f60bbfbcd953fdeaf661fe4269bd95"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"1021a0c5d12ef4d0b6f13853aa04edcaa454412f67d8bcba8af9df4231221afd","strict":true,"agent_id":"copilot"} +# gh-aw-manifest: {"version":1,"secrets":["GH_AW_AGENT_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/setup-go","sha":"4a3601121dd01d1626a1e23e37211e3254c1c06c","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.28","digest":"sha256:a8834e285807654bf680154faa710d43fe4365a0868142f5c20e48c85e137a7a","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.25.28@sha256:a8834e285807654bf680154faa710d43fe4365a0868142f5c20e48c85e137a7a"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.28","digest":"sha256:93290f2393752252911bd7c39a047f776c0b53063575e7bde4e304962a9a61cb","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.28@sha256:93290f2393752252911bd7c39a047f776c0b53063575e7bde4e304962a9a61cb"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.28","digest":"sha256:844c18280f82cd1b06345eb2f4e91966b34185bfc51c9f237c3e022e848fb474","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.25.28@sha256:844c18280f82cd1b06345eb2f4e91966b34185bfc51c9f237c3e022e848fb474"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.2.30","digest":"sha256:e950e6d39f003862d33bfb8d4eb93e242d919cf6ca874b90728e5e0ea7434c6f","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.2.30@sha256:e950e6d39f003862d33bfb8d4eb93e242d919cf6ca874b90728e5e0ea7434c6f"},{"image":"ghcr.io/github/github-mcp-server:v1.0.0","digest":"sha256:d2550953f8050bc5a1c8f80d1678766f66f60bbfbcd953fdeaf661fe4269bd95","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.0@sha256:d2550953f8050bc5a1c8f80d1678766f66f60bbfbcd953fdeaf661fe4269bd95"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]} # ___ _ _ # / _ \ | | (_) # | |_| | __ _ ___ _ __ | |_ _ ___ @@ -38,6 +38,7 @@ # - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 +# - actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 # # Container images used: @@ -173,20 +174,20 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_596272447b0a6f31_EOF' + cat << 'GH_AW_PROMPT_32704be96c42d3fd_EOF' - GH_AW_PROMPT_596272447b0a6f31_EOF + GH_AW_PROMPT_32704be96c42d3fd_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_596272447b0a6f31_EOF' + cat << 'GH_AW_PROMPT_32704be96c42d3fd_EOF' Tools: create_issue, missing_tool, missing_data, noop - GH_AW_PROMPT_596272447b0a6f31_EOF + GH_AW_PROMPT_32704be96c42d3fd_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_596272447b0a6f31_EOF' + cat << 'GH_AW_PROMPT_32704be96c42d3fd_EOF' The following GitHub context information is available for this workflow: {{#if __GH_AW_GITHUB_ACTOR__ }} @@ -215,12 +216,12 @@ jobs: {{/if}} - GH_AW_PROMPT_596272447b0a6f31_EOF + GH_AW_PROMPT_32704be96c42d3fd_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_596272447b0a6f31_EOF' + cat << 'GH_AW_PROMPT_32704be96c42d3fd_EOF' {{#runtime-import .github/workflows/architecture-guardian.md}} - GH_AW_PROMPT_596272447b0a6f31_EOF + GH_AW_PROMPT_32704be96c42d3fd_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 @@ -349,12 +350,22 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false + - name: Setup Go + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version: '1.25' + cache: false + - name: Capture GOROOT for AWF chroot mode + run: echo "GOROOT=$(go env GOROOT)" >> "$GITHUB_ENV" - 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 }} + - name: Collect architecture metrics + run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\n\n# Read thresholds from .architecture.yml or use defaults\nFILE_LINES_BLOCKER=1000\nFILE_LINES_WARNING=500\nFUNCTION_LINES=80\nMAX_EXPORTS=10\n\nif [ -f .architecture.yml ]; then\n b=$(grep -E '^\\s*file_lines_blocker:' .architecture.yml 2>/dev/null | awk '{print $2}' | tr -d '\"' | head -1 || true)\n w=$(grep -E '^\\s*file_lines_warning:' .architecture.yml 2>/dev/null | awk '{print $2}' | tr -d '\"' | head -1 || true)\n f=$(grep -E '^\\s*function_lines:' .architecture.yml 2>/dev/null | awk '{print $2}' | tr -d '\"' | head -1 || true)\n e=$(grep -E '^\\s*max_exports:' .architecture.yml 2>/dev/null | awk '{print $2}' | tr -d '\"' | head -1 || true)\n [[ -n \"${b:-}\" && \"$b\" =~ ^[0-9]+$ ]] && FILE_LINES_BLOCKER=$b\n [[ -n \"${w:-}\" && \"$w\" =~ ^[0-9]+$ ]] && FILE_LINES_WARNING=$w\n [[ -n \"${f:-}\" && \"$f\" =~ ^[0-9]+$ ]] && FUNCTION_LINES=$f\n [[ -n \"${e:-}\" && \"$e\" =~ ^[0-9]+$ ]] && MAX_EXPORTS=$e\nfi\n\n# Get changed Go/JS files in last 24 hours, excluding tests and vendor paths\nCHANGED_FILES=$(git log --since=\"24 hours ago\" --name-only --pretty=format: \\\n | sort -u \\\n | grep -E '\\.(go|js|cjs|mjs)$' \\\n | grep -vE '(node_modules/|vendor/|\\.git/|_test\\.go$)' \\\n | while IFS= read -r f; do [ -f \"$f\" ] && echo \"$f\"; done \\\n || true)\n\nif [ -z \"$CHANGED_FILES\" ]; then\n jq -n \\\n --argjson blocker \"$FILE_LINES_BLOCKER\" \\\n --argjson warning \"$FILE_LINES_WARNING\" \\\n --argjson func_lines \"$FUNCTION_LINES\" \\\n --argjson max_exports \"$MAX_EXPORTS\" \\\n '{noop: true, thresholds: {file_lines_blocker: $blocker, file_lines_warning: $warning, function_lines: $func_lines, max_exports: $max_exports}, files: [], import_cycles: \"\"}' \\\n > /tmp/gh-aw/agent/arch-metrics.json\n echo \"No changed Go/JS files found in the last 24 hours.\"\n exit 0\nfi\n\n# Build file metrics array\nFILES_JSON=\"[]\"\nwhile IFS= read -r FILE; do\n [ -z \"$FILE\" ] && continue\n LINES=$(wc -l < \"$FILE\" 2>/dev/null | tr -d ' ' || echo 0)\n EXT=\"${FILE##*.}\"\n\n if [[ \"$EXT\" == \"go\" ]]; then\n # Function sizes: \"func declaration\\tline_count\" per function\n # Pattern matches both regular functions (^func Name) and receiver methods (^func (r *T) Name)\n FUNC_DATA=$(awk '/^func /{if(start>0 && name!=\"\") printf \"%s\\t%d\\n\", name, NR-start; name=$0; start=NR} END{if(start>0 && name!=\"\") printf \"%s\\t%d\\n\", name, NR-start+1}' \"$FILE\" 2>/dev/null | head -50 || true)\n # Export count and names (top-level exported identifiers start with uppercase)\n EXPORT_COUNT=$(grep -cE \"^func [A-Z]|^type [A-Z]|^var [A-Z]|^const [A-Z]\" \"$FILE\" 2>/dev/null || echo 0)\n EXPORT_NAMES=$(grep -nE \"^func [A-Z]|^type [A-Z]|^var [A-Z]|^const [A-Z]\" \"$FILE\" 2>/dev/null | head -20 || true)\n else\n # JS/CJS/MJS: capture named functions, arrow functions, and class methods\n FUNC_DATA=$(grep -nE \"^function |^const [a-zA-Z_$][a-zA-Z0-9_$]* = (function|\\(|async \\(|async function)|^(export (default )?function|export const [a-zA-Z_$][a-zA-Z0-9_$]* =)|^[a-zA-Z_$][a-zA-Z0-9_$]*\\s*\\([^)]*\\)\\s*\\{\" \"$FILE\" 2>/dev/null | head -50 || true)\n CJS_COUNT=$(grep -cE \"^module\\.exports|^exports\\.\" \"$FILE\" 2>/dev/null || echo 0)\n ESM_COUNT=$(grep -cE \"^export \" \"$FILE\" 2>/dev/null || echo 0)\n EXPORT_COUNT=$((CJS_COUNT + ESM_COUNT))\n EXPORT_NAMES=$(grep -nE \"^export |^module\\.exports|^exports\\.\" \"$FILE\" 2>/dev/null | head -20 || true)\n fi\n\n FILES_JSON=$(jq \\\n --arg file \"$FILE\" \\\n --argjson lines \"$LINES\" \\\n --argjson exports \"$EXPORT_COUNT\" \\\n --arg func_data \"${FUNC_DATA:-}\" \\\n --arg export_names \"${EXPORT_NAMES:-}\" \\\n '. + [{file: $file, lines: $lines, export_count: $exports, func_data: $func_data, export_names: $export_names}]' \\\n <<< \"$FILES_JSON\")\ndone <<< \"$CHANGED_FILES\"\n\n# Check Go import cycles once across all packages\n# Note: go list may also emit errors for syntax issues; grep filters to only cycle errors\nIMPORT_CYCLES=$(go list ./... 2>&1 | grep -iE \"import cycle|cycle not allowed\" || true)\n\njq -n \\\n --argjson blocker \"$FILE_LINES_BLOCKER\" \\\n --argjson warning \"$FILE_LINES_WARNING\" \\\n --argjson func_lines \"$FUNCTION_LINES\" \\\n --argjson max_exports \"$MAX_EXPORTS\" \\\n --argjson files \"$FILES_JSON\" \\\n --arg import_cycles \"$IMPORT_CYCLES\" \\\n '{noop: false, thresholds: {file_lines_blocker: $blocker, file_lines_warning: $warning, function_lines: $func_lines, max_exports: $max_exports}, files: $files, import_cycles: $import_cycles}' \\\n > /tmp/gh-aw/agent/arch-metrics.json\n\nFILE_COUNT=$(echo \"$CHANGED_FILES\" | wc -l | tr -d ' ')\necho \"✅ Pre-computed metrics for $FILE_COUNT file(s) → /tmp/gh-aw/agent/arch-metrics.json\"\n" + - name: Configure Git credentials env: REPO_NAME: ${{ github.repository }} @@ -405,9 +416,9 @@ jobs: 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_96d69fc13f9c7deb_EOF' + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_a0a098aec577897c_EOF' {"create_issue":{"assignees":["copilot"],"max":1},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_96d69fc13f9c7deb_EOF + GH_AW_SAFE_OUTPUTS_CONFIG_a0a098aec577897c_EOF - name: Write Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -606,7 +617,7 @@ jobs: mkdir -p /home/runner/.copilot GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_192fa1e2d2baec6f_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_9f6cb6bd242c59db_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "github": { @@ -616,7 +627,7 @@ jobs: "GITHUB_HOST": "\${GITHUB_SERVER_URL}", "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}", "GITHUB_READ_ONLY": "1", - "GITHUB_TOOLSETS": "repos" + "GITHUB_TOOLSETS": "context,repos,issues,pull_requests" }, "guard-policies": { "allow-only": { @@ -647,7 +658,7 @@ jobs: "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" } } - GH_AW_MCP_CONFIG_192fa1e2d2baec6f_EOF + GH_AW_MCP_CONFIG_9f6cb6bd242c59db_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -681,29 +692,19 @@ jobs: # Copilot CLI tool arguments (sorted): # --allow-tool github # --allow-tool safeoutputs - # --allow-tool shell(awk:*) # --allow-tool shell(cat) # --allow-tool shell(cat:*) # --allow-tool shell(date) # --allow-tool shell(echo) - # --allow-tool shell(find:*) - # --allow-tool shell(git diff:*) - # --allow-tool shell(git log:*) - # --allow-tool shell(git show:*) # --allow-tool shell(grep) - # --allow-tool shell(grep:*) # --allow-tool shell(head) - # --allow-tool shell(head:*) # --allow-tool shell(ls) # --allow-tool shell(pwd) # --allow-tool shell(safeoutputs:*) - # --allow-tool shell(sed:*) # --allow-tool shell(sort) - # --allow-tool shell(sort:*) # --allow-tool shell(tail) # --allow-tool shell(uniq) # --allow-tool shell(wc) - # --allow-tool shell(wc:*) # --allow-tool shell(yq) # --allow-tool write timeout-minutes: 20 @@ -715,7 +716,7 @@ jobs: (umask 177 && touch /tmp/gh-aw/agent-stdio.log) # shellcheck disable=SC1003 sudo -E awf --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" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --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 --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --image-tag 0.25.28,squid=sha256:844c18280f82cd1b06345eb2f4e91966b34185bfc51c9f237c3e022e848fb474,agent=sha256:a8834e285807654bf680154faa710d43fe4365a0868142f5c20e48c85e137a7a,api-proxy=sha256:93290f2393752252911bd7c39a047f776c0b53063575e7bde4e304962a9a61cb,cli-proxy=sha256:fdf310e4678ce58d248c466b89399e9680a3003038fd19322c388559016aaac7 --skip-pull --enable-api-proxy \ - -- /bin/bash -c 'export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || echo node)"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_driver.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-tool github --allow-tool safeoutputs --allow-tool '\''shell(awk:*)'\'' --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(cat:*)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(find:*)'\'' --allow-tool '\''shell(git diff:*)'\'' --allow-tool '\''shell(git log:*)'\'' --allow-tool '\''shell(git show:*)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(grep:*)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(head:*)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(safeoutputs:*)'\'' --allow-tool '\''shell(sed:*)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(sort:*)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(uniq)'\'' --allow-tool '\''shell(wc)'\'' --allow-tool '\''shell(wc:*)'\'' --allow-tool '\''shell(yq)'\'' --allow-tool write --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + -- /bin/bash -c 'export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || echo node)"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_driver.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-tool github --allow-tool safeoutputs --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(cat:*)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(safeoutputs:*)'\'' --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 --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log env: COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_API_KEY: dummy-byok-key-for-offline-mode diff --git a/.github/workflows/architecture-guardian.md b/.github/workflows/architecture-guardian.md index a7e0d8aa043..8ffe29daa29 100644 --- a/.github/workflows/architecture-guardian.md +++ b/.github/workflows/architecture-guardian.md @@ -12,21 +12,8 @@ engine: copilot tracker-id: architecture-guardian tools: mount-as-clis: true - github: - toolsets: [repos] bash: - - "git log:*" - - "git diff:*" - - "git show:*" - - "find:*" - - "wc:*" - - "grep:*" - "cat:*" - - "head:*" - - "awk:*" - - "sed:*" - - "sort:*" - edit: safe-outputs: create-issue: expires: 2d @@ -45,6 +32,98 @@ timeout-minutes: 20 features: mcp-cli: true copilot-requests: true +steps: + - name: Collect architecture metrics + run: | + set -euo pipefail + mkdir -p /tmp/gh-aw/agent + + # Read thresholds from .architecture.yml or use defaults + FILE_LINES_BLOCKER=1000 + FILE_LINES_WARNING=500 + FUNCTION_LINES=80 + MAX_EXPORTS=10 + + if [ -f .architecture.yml ]; then + b=$(grep -E '^\s*file_lines_blocker:' .architecture.yml 2>/dev/null | awk '{print $2}' | tr -d '"' | head -1 || true) + w=$(grep -E '^\s*file_lines_warning:' .architecture.yml 2>/dev/null | awk '{print $2}' | tr -d '"' | head -1 || true) + f=$(grep -E '^\s*function_lines:' .architecture.yml 2>/dev/null | awk '{print $2}' | tr -d '"' | head -1 || true) + e=$(grep -E '^\s*max_exports:' .architecture.yml 2>/dev/null | awk '{print $2}' | tr -d '"' | head -1 || true) + [[ -n "${b:-}" && "$b" =~ ^[0-9]+$ ]] && FILE_LINES_BLOCKER=$b + [[ -n "${w:-}" && "$w" =~ ^[0-9]+$ ]] && FILE_LINES_WARNING=$w + [[ -n "${f:-}" && "$f" =~ ^[0-9]+$ ]] && FUNCTION_LINES=$f + [[ -n "${e:-}" && "$e" =~ ^[0-9]+$ ]] && MAX_EXPORTS=$e + fi + + # Get changed Go/JS files in last 24 hours, excluding tests and vendor paths + CHANGED_FILES=$(git log --since="24 hours ago" --name-only --pretty=format: \ + | sort -u \ + | grep -E '\.(go|js|cjs|mjs)$' \ + | grep -vE '(node_modules/|vendor/|\.git/|_test\.go$)' \ + | while IFS= read -r f; do [ -f "$f" ] && echo "$f"; done \ + || true) + + if [ -z "$CHANGED_FILES" ]; then + jq -n \ + --argjson blocker "$FILE_LINES_BLOCKER" \ + --argjson warning "$FILE_LINES_WARNING" \ + --argjson func_lines "$FUNCTION_LINES" \ + --argjson max_exports "$MAX_EXPORTS" \ + '{noop: true, thresholds: {file_lines_blocker: $blocker, file_lines_warning: $warning, function_lines: $func_lines, max_exports: $max_exports}, files: [], import_cycles: ""}' \ + > /tmp/gh-aw/agent/arch-metrics.json + echo "No changed Go/JS files found in the last 24 hours." + exit 0 + fi + + # Build file metrics array + FILES_JSON="[]" + while IFS= read -r FILE; do + [ -z "$FILE" ] && continue + LINES=$(wc -l < "$FILE" 2>/dev/null | tr -d ' ' || echo 0) + EXT="${FILE##*.}" + + if [[ "$EXT" == "go" ]]; then + # Function sizes: "func declaration\tline_count" per function + # Pattern matches both regular functions (^func Name) and receiver methods (^func (r *T) Name) + FUNC_DATA=$(awk '/^func /{if(start>0 && name!="") printf "%s\t%d\n", name, NR-start; name=$0; start=NR} END{if(start>0 && name!="") printf "%s\t%d\n", name, NR-start+1}' "$FILE" 2>/dev/null | head -50 || true) + # Export count and names (top-level exported identifiers start with uppercase) + EXPORT_COUNT=$(grep -cE "^func [A-Z]|^type [A-Z]|^var [A-Z]|^const [A-Z]" "$FILE" 2>/dev/null || echo 0) + EXPORT_NAMES=$(grep -nE "^func [A-Z]|^type [A-Z]|^var [A-Z]|^const [A-Z]" "$FILE" 2>/dev/null | head -20 || true) + else + # JS/CJS/MJS: capture named functions, arrow functions, and class methods + FUNC_DATA=$(grep -nE "^function |^const [a-zA-Z_$][a-zA-Z0-9_$]* = (function|\(|async \(|async function)|^(export (default )?function|export const [a-zA-Z_$][a-zA-Z0-9_$]* =)|^[a-zA-Z_$][a-zA-Z0-9_$]*\s*\([^)]*\)\s*\{" "$FILE" 2>/dev/null | head -50 || true) + CJS_COUNT=$(grep -cE "^module\.exports|^exports\." "$FILE" 2>/dev/null || echo 0) + ESM_COUNT=$(grep -cE "^export " "$FILE" 2>/dev/null || echo 0) + EXPORT_COUNT=$((CJS_COUNT + ESM_COUNT)) + EXPORT_NAMES=$(grep -nE "^export |^module\.exports|^exports\." "$FILE" 2>/dev/null | head -20 || true) + fi + + FILES_JSON=$(jq \ + --arg file "$FILE" \ + --argjson lines "$LINES" \ + --argjson exports "$EXPORT_COUNT" \ + --arg func_data "${FUNC_DATA:-}" \ + --arg export_names "${EXPORT_NAMES:-}" \ + '. + [{file: $file, lines: $lines, export_count: $exports, func_data: $func_data, export_names: $export_names}]' \ + <<< "$FILES_JSON") + done <<< "$CHANGED_FILES" + + # Check Go import cycles once across all packages + # Note: go list may also emit errors for syntax issues; grep filters to only cycle errors + IMPORT_CYCLES=$(go list ./... 2>&1 | grep -iE "import cycle|cycle not allowed" || true) + + jq -n \ + --argjson blocker "$FILE_LINES_BLOCKER" \ + --argjson warning "$FILE_LINES_WARNING" \ + --argjson func_lines "$FUNCTION_LINES" \ + --argjson max_exports "$MAX_EXPORTS" \ + --argjson files "$FILES_JSON" \ + --arg import_cycles "$IMPORT_CYCLES" \ + '{noop: false, thresholds: {file_lines_blocker: $blocker, file_lines_warning: $warning, function_lines: $func_lines, max_exports: $max_exports}, files: $files, import_cycles: $import_cycles}' \ + > /tmp/gh-aw/agent/arch-metrics.json + + FILE_COUNT=$(echo "$CHANGED_FILES" | wc -l | tr -d ' ') + echo "✅ Pre-computed metrics for $FILE_COUNT file(s) → /tmp/gh-aw/agent/arch-metrics.json" --- # Architecture Guardian @@ -56,168 +135,56 @@ You are the Architecture Guardian, a code quality agent that enforces structural - **Analysis Period**: Last 24 hours - **Run ID**: ${{ github.run_id }} -## Step 1: Load Configuration +## Step 1: Read Pre-Computed Metrics -Read the `.architecture.yml` configuration file if it exists. This file contains configurable thresholds for the analysis. +All file metrics have been collected by the pre-step. Read the JSON summary: ```bash -cat .architecture.yml 2>/dev/null || echo "No .architecture.yml found, using defaults" +cat /tmp/gh-aw/agent/arch-metrics.json ``` -**Default thresholds** (used when `.architecture.yml` is absent or a value is missing): +The JSON has this structure: +- `noop` (bool) — `true` when no Go/JS files changed in the last 24 hours +- `thresholds` — effective thresholds (from `.architecture.yml` or defaults) +- `files[]` — one entry per changed file with: + - `file` — file path + - `lines` — total line count + - `export_count` — number of exported identifiers + - `func_data` — function declarations with sizes (`name\tline_count` per line for Go; line numbers for JS) + - `export_names` — list of exported identifier declarations +- `import_cycles` — output of `go list ./...` filtered for cycle errors (empty if none) -| Threshold | Default | Config Key | -|-----------|---------|------------| -| File size BLOCKER | 1000 lines | `thresholds.file_lines_blocker` | -| File size WARNING | 500 lines | `thresholds.file_lines_warning` | -| Function size | 80 lines | `thresholds.function_lines` | -| Max public exports | 10 | `thresholds.max_exports` | - -Parse the YAML values if the file exists. Fall back to defaults for any missing key. - -## Step 2: Identify Files Changed in the Last 24 Hours - -Use git to find commits from the last 24 hours and the files they touched: - -```bash -git log --since="24 hours ago" --oneline --name-only -``` - -Collect the unique set of changed source files: - -```bash -git log --since="24 hours ago" --name-only --pretty=format: | sort -u | grep -E '\.(go|js|cjs|mjs)$' -``` - -If no Go or JavaScript files were changed in the last 24 hours, call the `noop` tool and stop: +If `noop` is `true`, call the `noop` safe-output tool and stop: ```json {"noop": {"message": "No Go or JavaScript source files changed in the last 24 hours. Architecture scan skipped."}} ``` -Exclude generated files, test fixtures, and vendor directories (e.g., `node_modules/`, `vendor/`, `.git/`, `*_test.go`). - -## Step 3: Run Structural Analysis - -For each relevant source file, perform the following checks. Collect all violations in a structured list. - -### Check 1: File Size - -Count lines in each file: - -```bash -wc -l 2>/dev/null -``` - -Classify: -- Lines > `thresholds.file_lines_blocker` (default 1000) → **BLOCKER** -- Lines > `thresholds.file_lines_warning` (default 500) → **WARNING** - -### Check 2: Function Size (Go) - -Find Go function declarations and estimate sizes by counting lines between consecutive `func` markers: - -```bash -# List all func declaration line numbers in a Go file -grep -n "^func " -``` - -Use the line numbers to estimate each function's length. For a more precise count, use `awk`: - -```bash -awk '/^func /{if(start>0) print name, NR-start; name=$0; start=NR} END{if(start>0) print name, NR-start+1}' -``` - -Functions exceeding `thresholds.function_lines` (default 80) → **WARNING** - -### Check 3: Function Size (JavaScript / CommonJS) - -Approximate function sizes in `.js` / `.cjs` / `.mjs` files using grep: - -```bash -# List function declaration line numbers -grep -n "^function \|^const .* = function\|^const .* = (" -``` - -Count lines between consecutive function declarations to estimate length. Functions exceeding `thresholds.function_lines` (default 80) → **WARNING** +## Step 2: Classify Violations by Severity -### Check 4: High Public Export Count (Go) +Using the pre-computed data, classify all findings into three severity tiers. -In Go, exported identifiers start with an uppercase letter. Count exported top-level functions, types, variables, and constants: +**Default thresholds** (used when `.architecture.yml` is absent): -```bash -# Count exported top-level declarations in a Go file -grep -c "^func [A-Z]\|^type [A-Z]\|^var [A-Z]\|^const [A-Z]" - -# List them for reporting -grep -n "^func [A-Z]\|^type [A-Z]\|^var [A-Z]\|^const [A-Z]" -``` - -For JavaScript files, count module-level exports: - -```bash -# CommonJS -grep -c "^module\.exports\|^exports\." - -# ES modules -grep -c "^export " -``` - -Files with more than `thresholds.max_exports` (default 10) public names → **INFO** - -### Check 5: Import Cycles (Go) - -Go's toolchain detects import cycles at build time. Use `go list` to surface any cycles across all packages: - -```bash -go list ./... 2>&1 | grep -i "import cycle\|cycle not allowed" -``` - -Alternatively, use `go build` which also reports cycles: - -```bash -go build ./... 2>&1 | grep -i "import cycle\|cycle not allowed" -``` - -Any output from these commands indicates a circular import dependency → **BLOCKER** - -For JavaScript files, detect circular `require()` chains by grepping for cross-file imports and checking for mutual dependencies: - -```bash -# Find all require() calls pointing to local modules -grep -rn "require('\.\./\|\./" --include="*.js" --include="*.cjs" -``` - -Circular dependency cycles → **BLOCKER** - -## Step 4: Classify Violations by Severity - -Group all findings into three severity tiers: +| Threshold | Default | Config Key | +|-----------|---------|------------| +| File size BLOCKER | 1000 lines | `thresholds.file_lines_blocker` | +| File size WARNING | 500 lines | `thresholds.file_lines_warning` | +| Function size | 80 lines | `thresholds.function_lines` | +| Max public exports | 10 | `thresholds.max_exports` | ### BLOCKER (critical — must be addressed promptly) -- Circular import / dependency cycles between Go packages -- Files exceeding 1000 lines (configurable) +- Non-empty `import_cycles` field → import cycle detected +- `files[].lines` > `thresholds.file_lines_blocker` (default 1000) ### WARNING (should be addressed soon) -- Files exceeding 500 lines (configurable) -- Functions/methods exceeding 80 lines (configurable) +- `files[].lines` > `thresholds.file_lines_warning` (default 500) +- Any function in `files[].func_data` with line count > `thresholds.function_lines` (default 80) ### INFO (informational only) -- Files with more than 10 public exports (configurable) - -## Step 5: Generate AI Refactoring Suggestions - -For each **BLOCKER** and **WARNING** violation, generate a concise refactoring suggestion that explains: - -1. **What the violation is** — e.g., "`pkg/workflow/compiler.go` has 1,247 lines" -2. **Why it's a problem** — e.g., "Large files are harder to navigate, review, and maintain" -3. **A concrete plan to fix it** — e.g., "Extract the expression-extraction logic into `pkg/workflow/expression_extraction.go` and move YAML helpers into `pkg/workflow/compiler_yaml.go`" +- `files[].export_count` > `thresholds.max_exports` (default 10) -Use your knowledge of software architecture best practices. Be specific and actionable. - -For **INFO** violations, provide a brief note about the high export count and suggest whether the module might benefit from splitting. - -## Step 6: Post Report +## Step 3: Post Report ### If NO violations are found @@ -231,6 +198,8 @@ Call the `noop` safe-output tool: Create an issue with a structured report. Only create ONE issue (the `max: 1` limit applies and an existing open issue skips the run via `skip-if-match`). +Replace all `[PLACEHOLDER]` values with actual data from the pre-computed metrics JSON, and replace `N` with actual counts. + **Issue title**: Architecture Violations Detected — [DATE] **Issue body format**: @@ -255,13 +224,8 @@ Create an issue with a structured report. Only create ONE issue (the `max: 1` li > These violations indicate serious structural problems that require prompt attention. -#### [Violation Title] - -**File**: `path/to/file.go` -**Commit**: [sha] — [commit message] -**Issue**: [Description of the problem] -**Why it matters**: [Explanation] -**Suggested fix**: [Concrete refactoring plan] +- `path/to/file.go` — N lines (limit: 1000) · **Fix**: split into focused sub-files, one responsibility per file +- Import cycle detected: [cycle description] · **Fix**: introduce an interface or move shared types to a lower-level package --- @@ -269,12 +233,8 @@ Create an issue with a structured report. Only create ONE issue (the `max: 1` li > These violations should be addressed soon to prevent further structural debt. -#### [Violation Title] - -**File**: `path/to/file.go` | **Function**: `FunctionName` | **Lines**: N -**Commit**: [sha] — [commit message] -**Issue**: [Description] -**Suggested fix**: [Concrete refactoring plan] +- `path/to/file.go` — N lines (limit: 500) · **Fix**: extract related functions into a new file +- `path/to/file.go::FunctionName` — N lines (limit: 80) · **Fix**: decompose into smaller helper functions --- @@ -282,13 +242,13 @@ Create an issue with a structured report. Only create ONE issue (the `max: 1` li > Informational findings. Consider addressing in future refactoring. -- `path/to/file.go`: N exported identifiers — consider splitting into focused packages or sub-packages +- `path/to/file.go`: N exported identifiers (limit: 10) — consider splitting into focused packages --- ### Configuration -Thresholds from `.architecture.yml` (or defaults): +Thresholds (from `.architecture.yml` or defaults): - File size BLOCKER: N lines - File size WARNING: N lines - Function size: N lines diff --git a/docs/src/content/docs/agent-factory-status.mdx b/docs/src/content/docs/agent-factory-status.mdx index 16086b0063c..91162f03b61 100644 --- a/docs/src/content/docs/agent-factory-status.mdx +++ b/docs/src/content/docs/agent-factory-status.mdx @@ -16,6 +16,7 @@ These are experimental agentic workflows used by the GitHub Next team to learn, | [Agent Performance Analyzer - Meta-Orchestrator](https://github.com/github/gh-aw/blob/main/.github/workflows/agent-performance-analyzer.md) | copilot | [![Agent Performance Analyzer - Meta-Orchestrator](https://github.com/github/gh-aw/actions/workflows/agent-performance-analyzer.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/agent-performance-analyzer.lock.yml) | - | - | | [Agent Persona Explorer](https://github.com/github/gh-aw/blob/main/.github/workflows/agent-persona-explorer.md) | copilot | [![Agent Persona Explorer](https://github.com/github/gh-aw/actions/workflows/agent-persona-explorer.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/agent-persona-explorer.lock.yml) | - | - | | [Agentic Observability Kit](https://github.com/github/gh-aw/blob/main/.github/workflows/agentic-observability-kit.md) | copilot | [![Agentic Observability Kit](https://github.com/github/gh-aw/actions/workflows/agentic-observability-kit.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/agentic-observability-kit.lock.yml) | - | - | +| [Agentic Optimization Kit](https://github.com/github/gh-aw/blob/main/.github/workflows/agentic-optimization-kit.md) | copilot | [![Agentic Optimization Kit](https://github.com/github/gh-aw/actions/workflows/agentic-optimization-kit.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/agentic-optimization-kit.lock.yml) | - | - | | [Agentic Workflow Audit Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/audit-workflows.md) | claude | [![Agentic Workflow Audit Agent](https://github.com/github/gh-aw/actions/workflows/audit-workflows.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/audit-workflows.lock.yml) | - | - | | [AI Moderator](https://github.com/github/gh-aw/blob/main/.github/workflows/ai-moderator.md) | codex | [![AI Moderator](https://github.com/github/gh-aw/actions/workflows/ai-moderator.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/ai-moderator.lock.yml) | - | - | | [Approach Validator](https://github.com/github/gh-aw/blob/main/.github/workflows/approach-validator.md) | claude | [![Approach Validator](https://github.com/github/gh-aw/actions/workflows/approach-validator.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/approach-validator.lock.yml) | - | - | @@ -85,10 +86,12 @@ These are experimental agentic workflows used by the GitHub Next team to learn, | [Daily Secrets Analysis Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-secrets-analysis.md) | copilot | [![Daily Secrets Analysis Agent](https://github.com/github/gh-aw/actions/workflows/daily-secrets-analysis.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/daily-secrets-analysis.lock.yml) | - | - | | [Daily Security Red Team Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-security-red-team.md) | claude | [![Daily Security Red Team Agent](https://github.com/github/gh-aw/actions/workflows/daily-security-red-team.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/daily-security-red-team.lock.yml) | - | - | | [Daily Semgrep Scan](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-semgrep-scan.md) | copilot | [![Daily Semgrep Scan](https://github.com/github/gh-aw/actions/workflows/daily-semgrep-scan.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/daily-semgrep-scan.lock.yml) | - | - | +| [Daily Skill Optimizer Improvements](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-skill-optimizer.md) | copilot | [![Daily Skill Optimizer Improvements](https://github.com/github/gh-aw/actions/workflows/daily-skill-optimizer.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/daily-skill-optimizer.lock.yml) | - | - | | [Daily Syntax Error Quality Check](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-syntax-error-quality.md) | copilot | [![Daily Syntax Error Quality Check](https://github.com/github/gh-aw/actions/workflows/daily-syntax-error-quality.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/daily-syntax-error-quality.lock.yml) | - | - | | [Daily Team Evolution Insights](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-team-evolution-insights.md) | claude | [![Daily Team Evolution Insights](https://github.com/github/gh-aw/actions/workflows/daily-team-evolution-insights.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/daily-team-evolution-insights.lock.yml) | - | - | | [Daily Team Status](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-team-status.md) | copilot | [![Daily Team Status](https://github.com/github/gh-aw/actions/workflows/daily-team-status.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/daily-team-status.lock.yml) | `daily around 9:00 on weekdays` | - | | [Daily Testify Uber Super Expert](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-testify-uber-super-expert.md) | copilot | [![Daily Testify Uber Super Expert](https://github.com/github/gh-aw/actions/workflows/daily-testify-uber-super-expert.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/daily-testify-uber-super-expert.lock.yml) | - | - | +| [Daily Token Consumption Report (Sentry OTel)](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-token-consumption-report.md) | claude | [![Daily Token Consumption Report (Sentry OTel)](https://github.com/github/gh-aw/actions/workflows/daily-token-consumption-report.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/daily-token-consumption-report.lock.yml) | - | - | | [Daily Workflow Updater](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-workflow-updater.md) | copilot | [![Daily Workflow Updater](https://github.com/github/gh-aw/actions/workflows/daily-workflow-updater.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/daily-workflow-updater.lock.yml) | - | - | | [Dead Code Removal Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/dead-code-remover.md) | copilot | [![Dead Code Removal Agent](https://github.com/github/gh-aw/actions/workflows/dead-code-remover.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/dead-code-remover.lock.yml) | - | - | | [DeepReport - Intelligence Gathering Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/deep-report.md) | claude | [![DeepReport - Intelligence Gathering Agent](https://github.com/github/gh-aw/actions/workflows/deep-report.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/deep-report.lock.yml) | `daily around 15:00 on weekdays` | - | diff --git a/docs/src/content/docs/reference/frontmatter-full.md b/docs/src/content/docs/reference/frontmatter-full.md index c11bd3d2578..e3405f2e3f2 100644 --- a/docs/src/content/docs/reference/frontmatter-full.md +++ b/docs/src/content/docs/reference/frontmatter-full.md @@ -899,6 +899,12 @@ on: # Option 2: undefined + # Explicit additional custom workflow jobs that pre_activation and activation + # should depend on. + # (optional) + needs: [] + # Array of strings + # Steps to inject into the pre-activation job. These steps run after all built-in # checks (membership, stop-time, skip-if, etc.) and their results are exposed as # pre-activation outputs. Use 'id' on steps to reference their results via @@ -983,11 +989,6 @@ on: # (optional) statuses: "read" - # Explicit additional custom workflow jobs that pre_activation and activation - # should depend on. - # (optional) - needs: ["secrets_fetcher"] - # When set to false, disables the frontmatter hash check step in the activation # job. Default is true (check is enabled). Useful when the workflow source files # are managed outside the default GitHub repo context (e.g. cross-repo org @@ -1469,8 +1470,8 @@ pre-steps: pre-steps: [] # Array items: undefined -# Custom workflow steps to run before MCP gateway startup in the agent job, -# so prerequisite MCP installation/configuration can happen first. +# Custom workflow steps to run immediately before AI execution, after all +# initialization and setup steps in the agent job. # (optional) # This field supports multiple formats (oneOf): @@ -3488,6 +3489,13 @@ safe-outputs: assignees: [] # Array items: string + # Optional labels to apply to fallback issues created when pull request creation + # cannot proceed. When omitted, fallback issues reuse pull request labels. A + # managed label is always added for triage. + # (optional) + fallback-labels: [] + # Array of strings + # Whether to create pull request as draft (defaults to true). Accepts a boolean or # a GitHub Actions expression. # (optional)