From f5390c17ad8ee362e468f5c65c8285111cb27046 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 18 May 2026 16:54:52 +0000 Subject: [PATCH 1/3] Initial plan From 506299b64b50ef5c012230f4b61c4307e83d2cc6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 18 May 2026 17:02:01 +0000 Subject: [PATCH 2/3] chore: initial plan for SPDD spec improvements Agent-Logs-Url: https://github.com/github/gh-aw/sessions/fdf8aa77-db27-4076-ad17-4466c19979ec Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- .github/workflows/aw-portfolio-yield.lock.yml | 18 +- .../workflows/pr-description-caveman.lock.yml | 237 ++++++++++++------ 2 files changed, 169 insertions(+), 86 deletions(-) diff --git a/.github/workflows/aw-portfolio-yield.lock.yml b/.github/workflows/aw-portfolio-yield.lock.yml index 56895632ec6..ec4d75d68ca 100644 --- a/.github/workflows/aw-portfolio-yield.lock.yml +++ b/.github/workflows/aw-portfolio-yield.lock.yml @@ -82,10 +82,10 @@ run-name: "Agentic Workflow Portfolio Yield" env: OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.GH_AW_OTEL_SENTRY_ENDPOINT }} - OTEL_SERVICE_NAME: gh-aw - OTEL_EXPORTER_OTLP_HEADERS: Authorization=${{ secrets.GH_AW_OTEL_SENTRY_AUTHORIZATION }} - GH_AW_OTLP_ALL_HEADERS: Authorization=${{ secrets.GH_AW_OTEL_SENTRY_AUTHORIZATION }},Authorization=${{ secrets.GH_AW_OTEL_GRAFANA_AUTHORIZATION }} - GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ secrets.GH_AW_OTEL_SENTRY_ENDPOINT }}","headers":"Authorization=${{ secrets.GH_AW_OTEL_SENTRY_AUTHORIZATION }}"},{"url":"${{ secrets.GH_AW_OTEL_GRAFANA_ENDPOINT }}","headers":"Authorization=${{ secrets.GH_AW_OTEL_GRAFANA_AUTHORIZATION }}"}]' + OTEL_SERVICE_NAME: gh-aw.aw-portfolio-yield + OTEL_EXPORTER_OTLP_HEADERS: x-sentry-auth=${{ secrets.GH_AW_OTEL_SENTRY_AUTHORIZATION }} + GH_AW_OTLP_ALL_HEADERS: x-sentry-auth=${{ secrets.GH_AW_OTEL_SENTRY_AUTHORIZATION }},Authorization=${{ secrets.GH_AW_OTEL_GRAFANA_AUTHORIZATION }} + GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ secrets.GH_AW_OTEL_SENTRY_ENDPOINT }}","headers":"x-sentry-auth=${{ secrets.GH_AW_OTEL_SENTRY_AUTHORIZATION }}"},{"url":"${{ secrets.GH_AW_OTEL_GRAFANA_ENDPOINT }}","headers":"Authorization=${{ secrets.GH_AW_OTEL_GRAFANA_AUTHORIZATION }}"}]' jobs: activation: @@ -122,6 +122,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Agentic Workflow Portfolio Yield" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/aw-portfolio-yield.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.48" + GH_AW_INFO_ENGINE_ID: "copilot" - name: Mask OTLP telemetry headers run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Generate agentic run info @@ -382,6 +383,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Agentic Workflow Portfolio Yield" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/aw-portfolio-yield.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.48" + GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths run: | @@ -793,7 +795,7 @@ jobs: GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) export GH_AW_NODE_BIN (umask 177 && touch /tmp/gh-aw/agent-stdio.log) - printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.46/awf-config.schema.json","network":{"allowDomains":["*.githubusercontent.com","*.grafana.net","*.sentry.io","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","codeload.github.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","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","host.docker.internal","json-schema.org","json.schemastore.org","keyserver.ubuntu.com","lfs.github.com","objects.githubusercontent.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"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000,"models":{"auto":["large"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"opus":["copilot/*opus*","anthropic/*opus*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"small":["mini"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"]}},"container":{"imageTag":"0.25.46"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" && cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.46/awf-config.schema.json","network":{"allowDomains":["*.githubusercontent.com","*.grafana.net","*.sentry.io","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","codeload.github.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","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","host.docker.internal","json-schema.org","json.schemastore.org","keyserver.ubuntu.com","lfs.github.com","objects.githubusercontent.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"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000,"models":{"auto":["large"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"opus":["copilot/*opus*","anthropic/*opus*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"small":["mini"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"vision":["copilot/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.25.46"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" && cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="" if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw" @@ -1003,6 +1005,7 @@ jobs: /tmp/gh-aw/agent/ /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/otel.jsonl + /tmp/gh-aw/otlp-export-errors.jsonl /tmp/gh-aw/safeoutputs.jsonl /tmp/gh-aw/agent_output.json /tmp/gh-aw/aw-*.patch @@ -1055,6 +1058,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Agentic Workflow Portfolio Yield" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/aw-portfolio-yield.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.48" + GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output continue-on-error: true @@ -1200,6 +1204,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Agentic Workflow Portfolio Yield" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/aw-portfolio-yield.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.48" + GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output continue-on-error: true @@ -1423,6 +1428,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Agentic Workflow Portfolio Yield" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/aw-portfolio-yield.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.48" + GH_AW_INFO_ENGINE_ID: "copilot" - name: Mask OTLP telemetry headers run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Download agent output artifact @@ -1456,7 +1462,7 @@ jobs: GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,*.grafana.net,*.sentry.io,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,codeload.github.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,docs.github.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.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_issue\":{\"close_older_issues\":true,\"expires\":720,\"labels\":[\"automation\",\"report\",\"observability\"],\"max\":1},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_issue\":{\"close_older_issues\":true,\"expires\":720,\"labels\":[\"automation\",\"report\",\"observability\"],\"max\":1},\"create_report_incomplete_issue\":{},\"mentions\":{\"enabled\":false},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}" with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | diff --git a/.github/workflows/pr-description-caveman.lock.yml b/.github/workflows/pr-description-caveman.lock.yml index 94a9a9550c3..93ba5fee311 100644 --- a/.github/workflows/pr-description-caveman.lock.yml +++ b/.github/workflows/pr-description-caveman.lock.yml @@ -1,5 +1,5 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"d323adc7f9e87e820faddb72dc94b0db9f74299868e4ca982ddcecc4a4edc777","compiler_version":"v0.72.1","strict":true,"agent_id":"copilot"} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_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":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"v0.72.1","version":"v0.72.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.41","digest":"sha256:cb2b565d070116d4b67e355775340528b5a2c3cb18b2c9049638bcc2df681770","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.25.41@sha256:cb2b565d070116d4b67e355775340528b5a2c3cb18b2c9049638bcc2df681770"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.41","digest":"sha256:fadd0de387209f69a9a7a1b8722bb5e7fdfb80ba9749a5c60f0e4cd7582a74d0","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.41@sha256:fadd0de387209f69a9a7a1b8722bb5e7fdfb80ba9749a5c60f0e4cd7582a74d0"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.41","digest":"sha256:62171f2fa508667b8b0a9e096f826983f312e3da0ce894f80c0f83a875af60fe","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.41@sha256:62171f2fa508667b8b0a9e096f826983f312e3da0ce894f80c0f83a875af60fe"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.41","digest":"sha256:1260445d25968dbf3ae70143964177a0e5914cf2ce07a6117f7d3caec6c3e3c4","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.25.41@sha256:1260445d25968dbf3ae70143964177a0e5914cf2ce07a6117f7d3caec6c3e3c4"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.6","digest":"sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c"},{"image":"ghcr.io/github/github-mcp-server:v1.0.3","digest":"sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"d323adc7f9e87e820faddb72dc94b0db9f74299868e4ca982ddcecc4a4edc777","strict":true,"agent_id":"copilot"} +# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_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":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","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.46"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.46"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.46"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.46"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.9","digest":"sha256:64828b42a4482f58fab16509d7f8f495a6d97c972a98a68aff20543531ac0388","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.9@sha256:64828b42a4482f58fab16509d7f8f495a6d97c972a98a68aff20543531ac0388"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]} # ___ _ _ # / _ \ | | (_) # | |_| | __ _ ___ _ __ | |_ _ ___ @@ -14,7 +14,7 @@ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ # -# This file was automatically generated by gh-aw (v0.72.1). DO NOT EDIT. +# 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 @@ -33,23 +33,22 @@ # Custom actions used: # - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 -# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 +# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) # - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup@v0.72.1 # # Container images used: -# - ghcr.io/github/gh-aw-firewall/agent:0.25.41@sha256:cb2b565d070116d4b67e355775340528b5a2c3cb18b2c9049638bcc2df681770 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.41@sha256:fadd0de387209f69a9a7a1b8722bb5e7fdfb80ba9749a5c60f0e4cd7582a74d0 -# - ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.41@sha256:62171f2fa508667b8b0a9e096f826983f312e3da0ce894f80c0f83a875af60fe -# - ghcr.io/github/gh-aw-firewall/squid:0.25.41@sha256:1260445d25968dbf3ae70143964177a0e5914cf2ce07a6117f7d3caec6c3e3c4 -# - ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c -# - ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959 +# - ghcr.io/github/gh-aw-firewall/agent:0.25.46 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.46 +# - ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.46 +# - ghcr.io/github/gh-aw-firewall/squid:0.25.46 +# - ghcr.io/github/gh-aw-mcpg:v0.3.9@sha256:64828b42a4482f58fab16509d7f8f495a6d97c972a98a68aff20543531ac0388 +# - ghcr.io/github/github-mcp-server:v1.0.4 # - node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f name: "PR Description Updater" -"on": +on: pull_request: types: - closed @@ -80,38 +79,48 @@ jobs: 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 }} + setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }} + setup-span-id: ${{ steps.setup.outputs.span-id }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} stale_lock_file_failed: ${{ steps.check-lock-file.outputs.stale_lock_file_failed == 'true' }} text: ${{ steps.sanitized.outputs.text }} title: ${{ steps.sanitized.outputs.title }} 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 id: setup - uses: github/gh-aw-actions/setup@v0.72.1 + uses: ./actions/setup with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} trace-id: ${{ needs.pre_activation.outputs.setup-trace-id }} + parent-span-id: ${{ needs.pre_activation.outputs.setup-parent-span-id || needs.pre_activation.outputs.setup-span-id }} env: GH_AW_SETUP_WORKFLOW_NAME: "PR Description Updater" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/pr-description-caveman.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.40" + GH_AW_INFO_VERSION: "1.0.48" + GH_AW_INFO_ENGINE_ID: "copilot" - 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 || 'claude-sonnet-4.6' }} - GH_AW_INFO_VERSION: "1.0.40" - GH_AW_INFO_AGENT_VERSION: "1.0.40" - GH_AW_INFO_CLI_VERSION: "v0.72.1" + GH_AW_INFO_VERSION: "1.0.48" + GH_AW_INFO_AGENT_VERSION: "1.0.48" GH_AW_INFO_WORKFLOW_NAME: "PR Description 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.25.41" + GH_AW_INFO_AWF_VERSION: "v0.25.46" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_COMPILED_STRICT: "true" @@ -134,6 +143,7 @@ jobs: sparse-checkout: | .github .agents + actions/setup .claude .codex .crush @@ -160,16 +170,6 @@ jobs: setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); await main(); - - name: Check compile-agentic version - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_AW_COMPILED_VERSION: "v0.72.1" - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); - await main(); - name: Compute current body text id: sanitized uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -185,10 +185,11 @@ jobs: env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl + GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} 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_EVENT_PULL_REQUEST_TITLE: ${{ github.event.pull_request.title }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} @@ -214,28 +215,28 @@ jobs: cat << 'GH_AW_PROMPT_5db6e1db2132fca6_EOF' The following GitHub context information is available for this workflow: - {{#if __GH_AW_GITHUB_ACTOR__ }} + {{#if github.actor}} - **actor**: __GH_AW_GITHUB_ACTOR__ {{/if}} - {{#if __GH_AW_GITHUB_REPOSITORY__ }} + {{#if github.repository}} - **repository**: __GH_AW_GITHUB_REPOSITORY__ {{/if}} - {{#if __GH_AW_GITHUB_WORKSPACE__ }} + {{#if github.workspace}} - **workspace**: __GH_AW_GITHUB_WORKSPACE__ {{/if}} - {{#if __GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ }} - - **issue-number**: #__GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ + {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}} + - **issue-number**: #__GH_AW_EXPR_802A9F6A__ {{/if}} - {{#if __GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ }} - - **discussion-number**: #__GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ + {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}} + - **discussion-number**: #__GH_AW_EXPR_1A3A194A__ {{/if}} - {{#if __GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ }} - - **pull-request-number**: #__GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ + {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}} + - **pull-request-number**: #__GH_AW_EXPR_463A214A__ {{/if}} - {{#if __GH_AW_GITHUB_EVENT_COMMENT_ID__ }} - - **comment-id**: __GH_AW_GITHUB_EVENT_COMMENT_ID__ + {{#if github.event.comment.id || github.aw.context.comment_id}} + - **comment-id**: __GH_AW_EXPR_FF1D34CE__ {{/if}} - {{#if __GH_AW_GITHUB_RUN_ID__ }} + {{#if github.run_id}} - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ {{/if}} @@ -266,10 +267,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} 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_EVENT_PULL_REQUEST_TITLE: ${{ github.event.pull_request.title }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} @@ -288,10 +290,11 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A, + GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A, + GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A, + GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE, 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_EVENT_PULL_REQUEST_TITLE: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_TITLE, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, @@ -346,6 +349,7 @@ jobs: agentic_engine_timeout: ${{ steps.detect-copilot-errors.outputs.agentic_engine_timeout || 'false' }} checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }} effective_tokens: ${{ steps.parse-mcp-gateway.outputs.effective_tokens }} + effective_tokens_rate_limit_error: ${{ steps.parse-mcp-gateway.outputs.effective_tokens_rate_limit_error || 'false' }} has_patch: ${{ steps.collect_output.outputs.has_patch }} inference_access_error: ${{ steps.detect-copilot-errors.outputs.inference_access_error || 'false' }} mcp_policy_error: ${{ steps.detect-copilot-errors.outputs.mcp_policy_error || 'false' }} @@ -353,19 +357,30 @@ jobs: model_not_supported_error: ${{ steps.detect-copilot-errors.outputs.model_not_supported_error || 'false' }} output: ${{ steps.collect_output.outputs.output }} output_types: ${{ steps.collect_output.outputs.output_types }} + setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }} + setup-span-id: ${{ steps.setup.outputs.span-id }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} 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 id: setup - uses: github/gh-aw-actions/setup@v0.72.1 + uses: ./actions/setup with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} trace-id: ${{ needs.activation.outputs.setup-trace-id }} + parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }} env: GH_AW_SETUP_WORKFLOW_NAME: "PR Description Updater" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/pr-description-caveman.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.40" + GH_AW_INFO_VERSION: "1.0.48" + GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths run: | @@ -419,14 +434,14 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); await main(); - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.40 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.48 env: GH_HOST: github.com - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.41 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.46 - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) env: GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} @@ -451,7 +466,7 @@ jobs: GH_AW_SUB_AGENT_EXT: ".agent.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh" - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.41@sha256:cb2b565d070116d4b67e355775340528b5a2c3cb18b2c9049638bcc2df681770 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.41@sha256:fadd0de387209f69a9a7a1b8722bb5e7fdfb80ba9749a5c60f0e4cd7582a74d0 ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.41@sha256:62171f2fa508667b8b0a9e096f826983f312e3da0ce894f80c0f83a875af60fe ghcr.io/github/gh-aw-firewall/squid:0.25.41@sha256:1260445d25968dbf3ae70143964177a0e5914cf2ce07a6117f7d3caec6c3e3c4 ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959 node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.46 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.46 ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.46 ghcr.io/github/gh-aw-firewall/squid:0.25.46 ghcr.io/github/gh-aw-mcpg:v0.3.9@sha256:64828b42a4482f58fab16509d7f8f495a6d97c972a98a68aff20543531ac0388 ghcr.io/github/github-mcp-server:v1.0.4 node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f - name: Generate Safe Outputs Config run: | mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" @@ -654,11 +669,16 @@ jobs: export GH_AW_ENGINE="copilot" export GH_AW_MCP_CLI_SERVERS='["safeoutputs"]' - echo 'GH_AW_MCP_CLI_SERVERS=["safeoutputs"]' >> "$GITHUB_ENV" + echo GH_AW_MCP_CLI_SERVERS='["safeoutputs"]' >> "$GITHUB_ENV" MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0') MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0') - DOCKER_SOCK_GID=$(stat -c '%g' /var/run/docker.sock 2>/dev/null || echo '0') - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -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.3.6' + case "${DOCKER_HOST:-}" in + unix://* ) DOCKER_SOCK_PATH="${DOCKER_HOST#unix://}" ;; + /* ) DOCKER_SOCK_PATH="$DOCKER_HOST" ;; + * ) DOCKER_SOCK_PATH=/var/run/docker.sock ;; + esac + DOCKER_SOCK_GID=$(stat -c '%g' "$DOCKER_SOCK_PATH" 2>/dev/null || echo '0') + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/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 DOCKER_HOST=unix:///var/run/docker.sock -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.3.9' mkdir -p /home/runner/.copilot GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) @@ -714,7 +734,7 @@ jobs: GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} GITHUB_SERVER_URL: ${{ github.server_url }} CLI_PROXY_POLICY: '{"allow-only":{"repos":"all","min-integrity":"none"}}' - CLI_PROXY_IMAGE: 'ghcr.io/github/gh-aw-mcpg:v0.3.6' + CLI_PROXY_IMAGE: 'ghcr.io/github/gh-aw-mcpg:v0.3.9' run: | bash "${RUNNER_TEMP}/gh-aw/actions/start_cli_proxy.sh" - name: Execute GitHub Copilot CLI @@ -726,6 +746,7 @@ jobs: # --allow-tool shell(cat*) # --allow-tool shell(date) # --allow-tool shell(echo) + # --allow-tool shell(gh:*) # --allow-tool shell(git diff*) # --allow-tool shell(git log*) # --allow-tool shell(grep) @@ -733,6 +754,7 @@ jobs: # --allow-tool shell(head*) # --allow-tool shell(ls) # --allow-tool shell(ls*) + # --allow-tool shell(printf) # --allow-tool shell(pwd) # --allow-tool shell(safeoutputs:*) # --allow-tool shell(sort) @@ -747,14 +769,19 @@ jobs: timeout-minutes: 15 run: | set -o pipefail + printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt touch /tmp/gh-aw/agent-step-summary.md GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) export GH_AW_NODE_BIN (umask 177 && touch /tmp/gh-aw/agent-stdio.log) - printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.41/awf-config.schema.json","network":{"allowDomains":["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"]},"apiProxy":{"enabled":true,"models":{"auto":["large"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*"],"gpt-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash"],"opus":["copilot/*opus*","anthropic/*opus*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"small":["mini"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"]}},"container":{"imageTag":"0.25.41,squid=sha256:1260445d25968dbf3ae70143964177a0e5914cf2ce07a6117f7d3caec6c3e3c4,agent=sha256:cb2b565d070116d4b67e355775340528b5a2c3cb18b2c9049638bcc2df681770,api-proxy=sha256:fadd0de387209f69a9a7a1b8722bb5e7fdfb80ba9749a5c60f0e4cd7582a74d0,cli-proxy=sha256:62171f2fa508667b8b0a9e096f826983f312e3da0ce894f80c0f83a875af60fe"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" && cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.46/awf-config.schema.json","network":{"allowDomains":["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"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000,"models":{"auto":["large"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"opus":["copilot/*opus*","anthropic/*opus*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"small":["mini"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"vision":["copilot/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.25.46"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" && cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json + GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="" + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw" + fi # shellcheck disable=SC1003 - sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --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 GH_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --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 --skip-pull --difc-proxy-host host.docker.internal:18443 --difc-proxy-ca-cert /tmp/gh-aw/difc-proxy-tls/ca.crt \ - -- /bin/bash -c 'export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 4 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && 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_harness.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(git diff*)'\'' --allow-tool '\''shell(git log*)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(head*)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(ls*)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(safeoutputs:*)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(split*)'\'' --allow-tool '\''shell(tail)'\'' --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 + sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --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" ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GH_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --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 --skip-pull --difc-proxy-host host.docker.internal:18443 --difc-proxy-ca-cert /tmp/gh-aw/difc-proxy-tls/ca.crt \ + -- /bin/bash -c 'export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && 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 || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.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(gh:*)'\'' --allow-tool '\''shell(git diff*)'\'' --allow-tool '\''shell(git log*)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(head*)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(ls*)'\'' --allow-tool '\''shell(printf)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(safeoutputs:*)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(split*)'\'' --allow-tool '\''shell(tail)'\'' --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 env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE @@ -765,7 +792,7 @@ jobs: GH_AW_PHASE: agent GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_VERSION: v0.72.1 + GH_AW_VERSION: dev GH_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN || github.token }} GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true @@ -960,23 +987,33 @@ jobs: concurrency: group: "gh-aw-conclusion-pr-description-caveman" cancel-in-progress: false + queue: max outputs: incomplete_count: ${{ steps.report_incomplete.outputs.incomplete_count }} 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 id: setup - uses: github/gh-aw-actions/setup@v0.72.1 + uses: ./actions/setup with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} trace-id: ${{ needs.activation.outputs.setup-trace-id }} + parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }} env: GH_AW_SETUP_WORKFLOW_NAME: "PR Description Updater" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/pr-description-caveman.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.40" + GH_AW_INFO_VERSION: "1.0.48" + GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output continue-on-error: true @@ -1066,6 +1103,8 @@ jobs: GH_AW_ENGINE_ID: "copilot" GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }} GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} + GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens || '' }} + GH_AW_EFFECTIVE_TOKENS_RATE_LIMIT_ERROR: ${{ needs.agent.outputs.effective_tokens_rate_limit_error || 'false' }} GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }} GH_AW_MCP_POLICY_ERROR: ${{ needs.agent.outputs.mcp_policy_error }} GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }} @@ -1078,6 +1117,7 @@ jobs: GH_AW_MISSING_TOOL_REPORT_AS_FAILURE: "true" GH_AW_MISSING_DATA_REPORT_AS_FAILURE: "true" GH_AW_TIMEOUT_MINUTES: "15" + GH_AW_MAX_EFFECTIVE_TOKENS: "25000000" with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1100,17 +1140,26 @@ jobs: detection_reason: ${{ steps.detection_conclusion.outputs.reason }} detection_success: ${{ steps.detection_conclusion.outputs.success }} 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 id: setup - uses: github/gh-aw-actions/setup@v0.72.1 + uses: ./actions/setup with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} trace-id: ${{ needs.activation.outputs.setup-trace-id }} + parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }} env: GH_AW_SETUP_WORKFLOW_NAME: "PR Description Updater" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/pr-description-caveman.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.40" + GH_AW_INFO_VERSION: "1.0.48" + GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output continue-on-error: true @@ -1136,7 +1185,7 @@ jobs: rm -rf /tmp/gh-aw/sandbox/firewall/logs rm -rf /tmp/gh-aw/sandbox/firewall/audit - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.41@sha256:cb2b565d070116d4b67e355775340528b5a2c3cb18b2c9049638bcc2df681770 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.41@sha256:fadd0de387209f69a9a7a1b8722bb5e7fdfb80ba9749a5c60f0e4cd7582a74d0 ghcr.io/github/gh-aw-firewall/squid:0.25.41@sha256:1260445d25968dbf3ae70143964177a0e5914cf2ce07a6117f7d3caec6c3e3c4 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.46 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.46 ghcr.io/github/gh-aw-firewall/squid:0.25.46 - name: Check if detection needed id: detection_guard if: always() @@ -1195,11 +1244,11 @@ jobs: node-version: '24' package-manager-cache: false - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.40 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.48 env: GH_HOST: github.com - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.41 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.46 - name: Execute GitHub Copilot CLI if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true @@ -1208,14 +1257,19 @@ jobs: timeout-minutes: 20 run: | set -o pipefail + printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt touch /tmp/gh-aw/agent-step-summary.md GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) export GH_AW_NODE_BIN (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) - printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.41/awf-config.schema.json","network":{"allowDomains":["api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","github.com","host.docker.internal","telemetry.enterprise.githubcopilot.com"]},"apiProxy":{"enabled":true},"container":{"imageTag":"0.25.41"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" && cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.46/awf-config.schema.json","network":{"allowDomains":["api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","github.com","host.docker.internal","telemetry.enterprise.githubcopilot.com"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000},"container":{"imageTag":"0.25.46"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" && cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json + GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="" + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw" + fi # shellcheck disable=SC1003 - sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --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 --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 --skip-pull \ - -- /bin/bash -c 'export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 4 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && 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_harness.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-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --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" ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --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 --skip-pull \ + -- /bin/bash -c 'export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && 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 || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.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-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE @@ -1224,7 +1278,7 @@ jobs: COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || 'claude-sonnet-4.6' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_VERSION: v0.72.1 + GH_AW_VERSION: dev GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1252,6 +1306,7 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} + DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }} GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" with: script: | @@ -1262,10 +1317,11 @@ jobs: await main(); } catch (loadErr) { const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false'; + const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure'; const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr)); core.error(msg); core.setOutput('reason', 'parse_error'); - if (continueOnError) { + if (continueOnError && !detectionExecutionFailed) { core.warning('\u26A0\uFE0F ' + msg); core.setOutput('conclusion', 'warning'); core.setOutput('success', 'false'); @@ -1280,21 +1336,33 @@ jobs: if: > (github.event.pull_request.merged == true) && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) runs-on: ubuntu-slim + permissions: + contents: read outputs: activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }} matched_command: '' + setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }} + setup-span-id: ${{ steps.setup.outputs.span-id }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} 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 id: setup - uses: github/gh-aw-actions/setup@v0.72.1 + uses: ./actions/setup with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} env: GH_AW_SETUP_WORKFLOW_NAME: "PR Description Updater" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/pr-description-caveman.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.40" + GH_AW_INFO_VERSION: "1.0.48" + GH_AW_INFO_ENGINE_ID: "copilot" - name: Check team membership for workflow id: check_membership uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -1326,7 +1394,7 @@ jobs: GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }} GH_AW_ENGINE_ID: "copilot" GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }} - GH_AW_ENGINE_VERSION: "1.0.40" + GH_AW_ENGINE_VERSION: "1.0.48" GH_AW_WORKFLOW_ID: "pr-description-caveman" GH_AW_WORKFLOW_NAME: "PR Description Updater" outputs: @@ -1337,17 +1405,26 @@ jobs: 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 id: setup - uses: github/gh-aw-actions/setup@v0.72.1 + uses: ./actions/setup with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} trace-id: ${{ needs.activation.outputs.setup-trace-id }} + parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }} env: GH_AW_SETUP_WORKFLOW_NAME: "PR Description Updater" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/pr-description-caveman.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.40" + GH_AW_INFO_VERSION: "1.0.48" + GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output continue-on-error: true From 12c7bd17ef875938fc65bd1dab906b2364312c24 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 18 May 2026 17:08:32 +0000 Subject: [PATCH 3/3] docs: SPDD 2026-05-18 spec improvements - safeguards, norms, compliance tests Agent-Logs-Url: https://github.com/github/gh-aw/sessions/fdf8aa77-db27-4076-ad17-4466c19979ec Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- .github/skills/error-messages/ssl.json | 24 +- .github/skills/jqschema/ssl.json | 26 +- .github/skills/reporting/ssl.json | 14 +- .github/skills/ssl/ssl.json | 62 +- actions/setup/js/pr_review_buffer.cjs | 5 +- .../setup/js/safe_output_handler_manager.cjs | 5 +- actions/setup/js/safe_outputs_handlers.cjs | 2 +- .../setup/js/safe_outputs_handlers.test.cjs | 24 +- docs/public/editor/autocomplete-data.json | 793 +---- .../effective-tokens-specification.md | 58 +- .../docs/reference/forecast-specification.md | 40 + .../reference/fuzzy-schedule-specification.md | 7 + .../reference/mcp-scripts-specification.md | 30 + pkg/parser/schemas/main_workflow_schema.json | 2873 +++-------------- pkg/workflow/safe_outputs_app_config.go | 4 +- specs/forecast-compliance-fixtures/README.md | 70 + .../run_summary_minimal.json | 55 + 17 files changed, 988 insertions(+), 3104 deletions(-) create mode 100644 specs/forecast-compliance-fixtures/README.md create mode 100644 specs/forecast-compliance-fixtures/run_summary_minimal.json diff --git a/.github/skills/error-messages/ssl.json b/.github/skills/error-messages/ssl.json index f57422600cc..adf70fb0a98 100644 --- a/.github/skills/error-messages/ssl.json +++ b/.github/skills/error-messages/ssl.json @@ -18,9 +18,7 @@ "goal": "Determine error category and required message components", "entry_condition": "$error_context and $validation_rule are available", "exit_condition": "$error_category and $message_components are selected", - "next_scene_rules": [ - {"condition": "category determined", "target": "scene_act"} - ], + "next_scene_rules": [{ "condition": "category determined", "target": "scene_act" }], "inputs": ["$error_context", "$invalid_input", "$validation_rule"], "outputs": ["$error_category", "$message_components"], "entry_logic_step": "step_reason_classify" @@ -31,9 +29,7 @@ "goal": "Compose error message string using the three-part template", "entry_condition": "$error_category and $message_components are ready", "exit_condition": "$error_message is composed", - "next_scene_rules": [ - {"condition": "success", "target": "scene_verify"} - ], + "next_scene_rules": [{ "condition": "success", "target": "scene_verify" }], "inputs": ["$error_category", "$message_components", "$invalid_input"], "outputs": ["$error_message"], "entry_logic_step": "step_act_compose" @@ -45,8 +41,8 @@ "entry_condition": "$error_message is composed", "exit_condition": "$error_message passes completeness check", "next_scene_rules": [ - {"condition": "message is complete and actionable", "target": "END_SUCCESS"}, - {"condition": "message is incomplete", "target": "END_FAIL"} + { "condition": "message is complete and actionable", "target": "END_SUCCESS" }, + { "condition": "message is incomplete", "target": "END_FAIL" } ], "inputs": ["$error_message"], "outputs": ["$error_message"], @@ -60,8 +56,8 @@ "action_type": "SELECT", "resource_scope": "MEMORY", "description": "Classify the error as format, type, enum, or configuration validation to determine required message components", - "inputs": {"context": "$error_context", "rule": "$validation_rule"}, - "outputs": {"category": "$error_category", "components": "$message_components"}, + "inputs": { "context": "$error_context", "rule": "$validation_rule" }, + "outputs": { "category": "$error_category", "components": "$message_components" }, "next": "YIELD_SUCCESS" }, { @@ -70,8 +66,8 @@ "action_type": "WRITE", "resource_scope": "MEMORY", "description": "Compose the error message string: [what is wrong]. [what is expected]. [example of correct usage]", - "inputs": {"category": "$error_category", "components": "$message_components", "input": "$invalid_input"}, - "outputs": {"message": "$error_message"}, + "inputs": { "category": "$error_category", "components": "$message_components", "input": "$invalid_input" }, + "outputs": { "message": "$error_message" }, "next": "YIELD_SUCCESS" }, { @@ -80,8 +76,8 @@ "action_type": "VALIDATE", "resource_scope": "MEMORY", "description": "Check that $error_message contains all three template components: problem statement, expected format or values, and a concrete usage example", - "inputs": {"message": "$error_message"}, - "outputs": {"validated": "$error_message"}, + "inputs": { "message": "$error_message" }, + "outputs": { "validated": "$error_message" }, "next": "YIELD_SUCCESS" } ] diff --git a/.github/skills/jqschema/ssl.json b/.github/skills/jqschema/ssl.json index 5c67cdcc5e0..34308c0f9c1 100644 --- a/.github/skills/jqschema/ssl.json +++ b/.github/skills/jqschema/ssl.json @@ -19,8 +19,8 @@ "entry_condition": "$GITHUB_WORKSPACE is set and jqschema.sh exists in the skill directory", "exit_condition": "/tmp/gh-aw/jqschema.sh is executable", "next_scene_rules": [ - {"condition": "setup successful", "target": "scene_acquire"}, - {"condition": "setup failed", "target": "END_FAIL"} + { "condition": "setup successful", "target": "scene_acquire" }, + { "condition": "setup failed", "target": "END_FAIL" } ], "inputs": ["$GITHUB_WORKSPACE"], "outputs": ["$jqschema_bin"], @@ -32,9 +32,7 @@ "goal": "Receive JSON input to analyze", "entry_condition": "$jqschema_bin is available", "exit_condition": "$json_input is available as a processable stream", - "next_scene_rules": [ - {"condition": "input available", "target": "scene_act"} - ], + "next_scene_rules": [{ "condition": "input available", "target": "scene_act" }], "inputs": ["$json_input"], "outputs": ["$json_input"], "entry_logic_step": "step_acquire_receive" @@ -46,8 +44,8 @@ "entry_condition": "$json_input and $jqschema_bin are ready", "exit_condition": "$schema_output is produced", "next_scene_rules": [ - {"condition": "execution successful", "target": "END_SUCCESS"}, - {"condition": "jq execution error", "target": "END_FAIL"} + { "condition": "execution successful", "target": "END_SUCCESS" }, + { "condition": "jq execution error", "target": "END_FAIL" } ], "inputs": ["$json_input", "$jqschema_bin"], "outputs": ["$schema_output"], @@ -61,7 +59,7 @@ "action_type": "CALL_TOOL", "resource_scope": "LOCAL_FS", "description": "Create /tmp/gh-aw directory if it does not exist", - "inputs": {"path": "/tmp/gh-aw"}, + "inputs": { "path": "/tmp/gh-aw" }, "outputs": {}, "next": "step_prepare_copy" }, @@ -71,8 +69,8 @@ "action_type": "CALL_TOOL", "resource_scope": "LOCAL_FS", "description": "Copy jqschema.sh from $GITHUB_WORKSPACE/.github/skills/jqschema/ to /tmp/gh-aw/ and set executable permissions", - "inputs": {"source": "$GITHUB_WORKSPACE/.github/skills/jqschema/jqschema.sh", "dest": "/tmp/gh-aw/jqschema.sh"}, - "outputs": {"bin": "$jqschema_bin"}, + "inputs": { "source": "$GITHUB_WORKSPACE/.github/skills/jqschema/jqschema.sh", "dest": "/tmp/gh-aw/jqschema.sh" }, + "outputs": { "bin": "$jqschema_bin" }, "next": "YIELD_SUCCESS" }, { @@ -81,8 +79,8 @@ "action_type": "READ", "resource_scope": "PROCESS", "description": "Receive JSON data as stdin or from a file path, binding the result to $json_input", - "inputs": {"data": "$json_input"}, - "outputs": {"data": "$json_input"}, + "inputs": { "data": "$json_input" }, + "outputs": { "data": "$json_input" }, "next": "YIELD_SUCCESS" }, { @@ -91,8 +89,8 @@ "action_type": "CALL_TOOL", "resource_scope": "PROCESS", "description": "Pipe $json_input through $jqschema_bin to produce a compact structural schema that replaces values with type names", - "inputs": {"json": "$json_input", "bin": "$jqschema_bin"}, - "outputs": {"schema": "$schema_output"}, + "inputs": { "json": "$json_input", "bin": "$jqschema_bin" }, + "outputs": { "schema": "$schema_output" }, "next": "YIELD_SUCCESS" } ] diff --git a/.github/skills/reporting/ssl.json b/.github/skills/reporting/ssl.json index d0e2895f3c2..46a07ce7b2c 100644 --- a/.github/skills/reporting/ssl.json +++ b/.github/skills/reporting/ssl.json @@ -18,9 +18,7 @@ "goal": "Wrap report content in HTML details/summary tags", "entry_condition": "$report_content and $report_title are available", "exit_condition": "$formatted_report is composed", - "next_scene_rules": [ - {"condition": "success", "target": "scene_finalize"} - ], + "next_scene_rules": [{ "condition": "success", "target": "scene_finalize" }], "inputs": ["$report_content", "$report_title"], "outputs": ["$formatted_report"], "entry_logic_step": "step_act_compose" @@ -31,9 +29,7 @@ "goal": "Emit the formatted report as final output", "entry_condition": "$formatted_report is ready", "exit_condition": "report emitted to caller", - "next_scene_rules": [ - {"condition": "success", "target": "END_SUCCESS"} - ], + "next_scene_rules": [{ "condition": "success", "target": "END_SUCCESS" }], "inputs": ["$formatted_report"], "outputs": ["$formatted_report"], "entry_logic_step": "step_finalize_emit" @@ -46,8 +42,8 @@ "action_type": "WRITE", "resource_scope": "MEMORY", "description": "Compose HTML
/ wrapper around $report_content using $report_title as the summary label", - "inputs": {"content": "$report_content", "title": "$report_title"}, - "outputs": {"formatted": "$formatted_report"}, + "inputs": { "content": "$report_content", "title": "$report_title" }, + "outputs": { "formatted": "$formatted_report" }, "next": "YIELD_SUCCESS" }, { @@ -56,7 +52,7 @@ "action_type": "TERMINATE", "resource_scope": "MEMORY", "description": "Emit $formatted_report as the final output to the caller", - "inputs": {"report": "$formatted_report"}, + "inputs": { "report": "$formatted_report" }, "outputs": {}, "next": "YIELD_SUCCESS" } diff --git a/.github/skills/ssl/ssl.json b/.github/skills/ssl/ssl.json index 382edd9d31a..d46c1825b9e 100644 --- a/.github/skills/ssl/ssl.json +++ b/.github/skills/ssl/ssl.json @@ -19,8 +19,8 @@ "entry_condition": "$skill_path is provided and the file exists", "exit_condition": "$raw_text and $frontmatter are available in memory", "next_scene_rules": [ - {"condition": "parse succeeded", "target": "scene_reason"}, - {"condition": "file not found or parse error", "target": "END_FAIL"} + { "condition": "parse succeeded", "target": "scene_reason" }, + { "condition": "file not found or parse error", "target": "END_FAIL" } ], "inputs": ["$skill_path"], "outputs": ["$raw_text", "$frontmatter"], @@ -32,9 +32,7 @@ "goal": "Run Passes 1–3: extract scheduling metadata, decompose scenes, and expand logic steps into a draft SSL JSON", "entry_condition": "$raw_text and $frontmatter are available", "exit_condition": "$draft_ssl is produced as an in-memory JSON object", - "next_scene_rules": [ - {"condition": "draft produced", "target": "scene_verify"} - ], + "next_scene_rules": [{ "condition": "draft produced", "target": "scene_verify" }], "inputs": ["$raw_text", "$frontmatter"], "outputs": ["$draft_ssl"], "entry_logic_step": "step_reason_pass1" @@ -46,9 +44,9 @@ "entry_condition": "$draft_ssl is available", "exit_condition": "$draft_ssl passes all Pass-4 validation rules, or retry budget is exhausted", "next_scene_rules": [ - {"condition": "all validation rules pass", "target": "scene_finalize"}, - {"condition": "validation failures detected and retry budget remains", "target": "scene_recover"}, - {"condition": "validation failures detected and retry budget exhausted", "target": "END_FAIL"} + { "condition": "all validation rules pass", "target": "scene_finalize" }, + { "condition": "validation failures detected and retry budget remains", "target": "scene_recover" }, + { "condition": "validation failures detected and retry budget exhausted", "target": "END_FAIL" } ], "inputs": ["$draft_ssl"], "outputs": ["$validation_failures"], @@ -61,8 +59,8 @@ "entry_condition": "$validation_failures is non-empty and $retry_count < retry_budget", "exit_condition": "$retry_count is incremented and $draft_ssl is cleared for regeneration", "next_scene_rules": [ - {"condition": "retry budget not exhausted", "target": "scene_reason"}, - {"condition": "retry budget exhausted", "target": "END_FAIL"} + { "condition": "retry budget not exhausted", "target": "scene_reason" }, + { "condition": "retry budget exhausted", "target": "END_FAIL" } ], "inputs": ["$validation_failures", "$retry_count"], "outputs": ["$retry_count", "$failure_log"], @@ -75,8 +73,8 @@ "entry_condition": "$draft_ssl passed all validation rules", "exit_condition": "ssl.json is written to disk and $validation_report is emitted", "next_scene_rules": [ - {"condition": "write succeeded", "target": "END_SUCCESS"}, - {"condition": "write failed", "target": "END_FAIL"} + { "condition": "write succeeded", "target": "END_SUCCESS" }, + { "condition": "write failed", "target": "END_FAIL" } ], "inputs": ["$draft_ssl", "$failure_log"], "outputs": ["$ssl_json", "$validation_report"], @@ -90,8 +88,8 @@ "action_type": "READ", "resource_scope": "LOCAL_FS", "description": "Read the SKILL.md file at $skill_path into $raw_text", - "inputs": {"path": "$skill_path"}, - "outputs": {"text": "$raw_text"}, + "inputs": { "path": "$skill_path" }, + "outputs": { "text": "$raw_text" }, "next": "step_prepare_parse" }, { @@ -100,8 +98,8 @@ "action_type": "INFER", "resource_scope": "MEMORY", "description": "Parse YAML frontmatter and markdown body from $raw_text into $frontmatter and $body", - "inputs": {"text": "$raw_text"}, - "outputs": {"frontmatter": "$frontmatter", "body": "$body"}, + "inputs": { "text": "$raw_text" }, + "outputs": { "frontmatter": "$frontmatter", "body": "$body" }, "next": "YIELD_SUCCESS" }, { @@ -110,8 +108,8 @@ "action_type": "INFER", "resource_scope": "MEMORY", "description": "Pass 1 – Extract scheduling layer: id, name, goal, intent_signature, inputs, outputs, dependencies, control_flow_features, entry_scene, subscene_refs from $frontmatter and $body", - "inputs": {"frontmatter": "$frontmatter", "body": "$body"}, - "outputs": {"scheduling": "$scheduling"}, + "inputs": { "frontmatter": "$frontmatter", "body": "$body" }, + "outputs": { "scheduling": "$scheduling" }, "next": "step_reason_pass2" }, { @@ -120,8 +118,8 @@ "action_type": "INFER", "resource_scope": "MEMORY", "description": "Pass 2 – Decompose skill execution flow into 2–5 macro-level scenes with allowed types, entry/exit conditions, transition rules, and input/output bindings", - "inputs": {"body": "$body", "scheduling": "$scheduling"}, - "outputs": {"scenes": "$scenes"}, + "inputs": { "body": "$body", "scheduling": "$scheduling" }, + "outputs": { "scenes": "$scenes" }, "next": "step_reason_pass3" }, { @@ -130,8 +128,8 @@ "action_type": "INFER", "resource_scope": "MEMORY", "description": "Pass 3 – Expand each scene into atomic logic steps with allowed action types, resource scopes, and $-prefixed variable bindings", - "inputs": {"body": "$body", "scenes": "$scenes"}, - "outputs": {"logic_steps": "$logic_steps"}, + "inputs": { "body": "$body", "scenes": "$scenes" }, + "outputs": { "logic_steps": "$logic_steps" }, "next": "step_reason_compose" }, { @@ -140,8 +138,8 @@ "action_type": "WRITE", "resource_scope": "MEMORY", "description": "Assemble $scheduling, $scenes, and $logic_steps into the $draft_ssl JSON object", - "inputs": {"scheduling": "$scheduling", "scenes": "$scenes", "logic_steps": "$logic_steps"}, - "outputs": {"draft": "$draft_ssl"}, + "inputs": { "scheduling": "$scheduling", "scenes": "$scenes", "logic_steps": "$logic_steps" }, + "outputs": { "draft": "$draft_ssl" }, "next": "YIELD_SUCCESS" }, { @@ -150,8 +148,8 @@ "action_type": "VALIDATE", "resource_scope": "MEMORY", "description": "Run all Pass-4 validation rules against $draft_ssl: JSON syntax, required fields, enum membership, unique IDs, entry pointers, transition targets, graph integrity", - "inputs": {"draft": "$draft_ssl"}, - "outputs": {"failures": "$validation_failures"}, + "inputs": { "draft": "$draft_ssl" }, + "outputs": { "failures": "$validation_failures" }, "next": "YIELD_SUCCESS" }, { @@ -160,8 +158,8 @@ "action_type": "UPDATE_STATE", "resource_scope": "MEMORY", "description": "Append $validation_failures to $failure_log and increment $retry_count", - "inputs": {"failures": "$validation_failures", "retry_count": "$retry_count"}, - "outputs": {"retry_count": "$retry_count", "failure_log": "$failure_log"}, + "inputs": { "failures": "$validation_failures", "retry_count": "$retry_count" }, + "outputs": { "retry_count": "$retry_count", "failure_log": "$failure_log" }, "next": "YIELD_SUCCESS" }, { @@ -170,8 +168,8 @@ "action_type": "WRITE", "resource_scope": "LOCAL_FS", "description": "Write $draft_ssl as ssl.json into the same directory as the source SKILL.md", - "inputs": {"draft": "$draft_ssl", "skill_path": "$skill_path"}, - "outputs": {"ssl_json": "$ssl_json"}, + "inputs": { "draft": "$draft_ssl", "skill_path": "$skill_path" }, + "outputs": { "ssl_json": "$ssl_json" }, "next": "step_finalize_report" }, { @@ -180,8 +178,8 @@ "action_type": "NOTIFY", "resource_scope": "MEMORY", "description": "Compose and emit the validation report containing processed count, valid/rejected counts, and per-artifact diagnostics from $failure_log", - "inputs": {"ssl_json": "$ssl_json", "failure_log": "$failure_log"}, - "outputs": {"report": "$validation_report"}, + "inputs": { "ssl_json": "$ssl_json", "failure_log": "$failure_log" }, + "outputs": { "report": "$validation_report" }, "next": "YIELD_SUCCESS" } ] diff --git a/actions/setup/js/pr_review_buffer.cjs b/actions/setup/js/pr_review_buffer.cjs index c61ac2f5c5d..4057d6b3eed 100644 --- a/actions/setup/js/pr_review_buffer.cjs +++ b/actions/setup/js/pr_review_buffer.cjs @@ -364,10 +364,7 @@ function createReviewBuffer() { // Sub-pattern A: Guard against empty review submission (no body and no inline comments). // GitHub returns 422 "Unprocessable Entity" when both are absent. if (comments.length === 0 && !body) { - const errorMsg = - "Empty review: review body is empty and no inline comments are present" + - (bufferedComments.length > 0 ? " (all comment paths were outside the PR diff)" : "") + - ". Skipping POST to avoid 422."; + const errorMsg = "Empty review: review body is empty and no inline comments are present" + (bufferedComments.length > 0 ? " (all comment paths were outside the PR diff)" : "") + ". Skipping POST to avoid 422."; core.warning(errorMsg); return { success: false, error: errorMsg }; } diff --git a/actions/setup/js/safe_output_handler_manager.cjs b/actions/setup/js/safe_output_handler_manager.cjs index db036542a79..5cfa38f38db 100644 --- a/actions/setup/js/safe_output_handler_manager.cjs +++ b/actions/setup/js/safe_output_handler_manager.cjs @@ -501,10 +501,7 @@ function formatManifestLogMessage(item) { */ function rollbackReviewResults(results, errorMessage) { for (const r of results) { - if ( - (r.type === "submit_pull_request_review" || r.type === "create_pull_request_review_comment") && - r.success === true - ) { + if ((r.type === "submit_pull_request_review" || r.type === "create_pull_request_review_comment") && r.success === true) { r.success = false; r.error = `Review finalization failed: ${errorMessage}`; } diff --git a/actions/setup/js/safe_outputs_handlers.cjs b/actions/setup/js/safe_outputs_handlers.cjs index fb27100ddac..5a20c4227fd 100644 --- a/actions/setup/js/safe_outputs_handlers.cjs +++ b/actions/setup/js/safe_outputs_handlers.cjs @@ -1178,7 +1178,7 @@ function createHandlers(server, appendSafeOutput, config = {}) { */ const submitPullRequestReviewHandler = args => { const body = (args && typeof args.body === "string" ? args.body : "").trim(); - const event = (args && args.event ? String(args.event).toUpperCase() : "COMMENT"); + const event = args && args.event ? String(args.event).toUpperCase() : "COMMENT"; const VALID_REVIEW_EVENTS = ["APPROVE", "REQUEST_CHANGES", "COMMENT"]; if (!VALID_REVIEW_EVENTS.includes(event)) { diff --git a/actions/setup/js/safe_outputs_handlers.test.cjs b/actions/setup/js/safe_outputs_handlers.test.cjs index 8a8a44869df..a7abbcf343a 100644 --- a/actions/setup/js/safe_outputs_handlers.test.cjs +++ b/actions/setup/js/safe_outputs_handlers.test.cjs @@ -1493,9 +1493,7 @@ describe("safe_outputs_handlers", () => { expect(result).toHaveProperty("content"); const data = JSON.parse(result.content[0].text); expect(data.result).toBe("success"); - expect(mockAppendSafeOutput).toHaveBeenCalledWith( - expect.objectContaining({ type: "submit_pull_request_review", body: "Looks good!" }) - ); + expect(mockAppendSafeOutput).toHaveBeenCalledWith(expect.objectContaining({ type: "submit_pull_request_review", body: "Looks good!" })); }); it("should write entry and return success when body is empty but inline comments were buffered", () => { @@ -1518,9 +1516,7 @@ describe("safe_outputs_handlers", () => { }); it("should throw MCP error when body is whitespace-only and no inline comments were buffered", () => { - expect(() => handlers.submitPullRequestReviewHandler({ body: " ", event: "COMMENT" })).toThrow( - expect.objectContaining({ code: -32602 }) - ); + expect(() => handlers.submitPullRequestReviewHandler({ body: " ", event: "COMMENT" })).toThrow(expect.objectContaining({ code: -32602 })); }); it("should throw MCP error when event is REQUEST_CHANGES and body is empty", () => { @@ -1559,9 +1555,7 @@ describe("safe_outputs_handlers", () => { const result = handlers.submitPullRequestReviewHandler({ body: "LGTM" }); const data = JSON.parse(result.content[0].text); expect(data.result).toBe("success"); - expect(mockAppendSafeOutput).toHaveBeenCalledWith( - expect.objectContaining({ type: "submit_pull_request_review" }) - ); + expect(mockAppendSafeOutput).toHaveBeenCalledWith(expect.objectContaining({ type: "submit_pull_request_review" })); }); it("should reset inline comment counter after a successful submit, allowing a second review to guard correctly", () => { // First review: submit with a body (succeeds, resets counter) @@ -1569,9 +1563,7 @@ describe("safe_outputs_handlers", () => { handlers.submitPullRequestReviewHandler({ event: "COMMENT", body: "First review" }); // Counter is now reset to 0. A second empty-body submit should be rejected. - expect(() => handlers.submitPullRequestReviewHandler({ event: "COMMENT" })).toThrow( - expect.objectContaining({ code: -32602 }) - ); + expect(() => handlers.submitPullRequestReviewHandler({ event: "COMMENT" })).toThrow(expect.objectContaining({ code: -32602 })); }); it("should throw MCP error when event is an invalid value", () => { @@ -1606,9 +1598,7 @@ describe("safe_outputs_handlers", () => { expect(result).toHaveProperty("content"); const data = JSON.parse(result.content[0].text); expect(data.result).toBe("success"); - expect(mockAppendSafeOutput).toHaveBeenCalledWith( - expect.objectContaining({ type: "create_pull_request_review_comment", path: "src/foo.js" }) - ); + expect(mockAppendSafeOutput).toHaveBeenCalledWith(expect.objectContaining({ type: "create_pull_request_review_comment", path: "src/foo.js" })); }); it("should allow empty-body submit after buffering a comment", () => { @@ -1625,9 +1615,7 @@ describe("safe_outputs_handlers", () => { }); expect(() => handlers.createPullRequestReviewCommentHandler({ path: "src/foo.js", line: 1, body: "nit" })).toThrow(); // Counter was NOT incremented, so empty-body submit should still be rejected - expect(() => handlers.submitPullRequestReviewHandler({ event: "COMMENT" })).toThrow( - expect.objectContaining({ code: -32602, message: expect.stringContaining("review body is empty") }) - ); + expect(() => handlers.submitPullRequestReviewHandler({ event: "COMMENT" })).toThrow(expect.objectContaining({ code: -32602, message: expect.stringContaining("review body is empty") })); }); }); }); diff --git a/docs/public/editor/autocomplete-data.json b/docs/public/editor/autocomplete-data.json index affc77b5105..cc280ed9761 100644 --- a/docs/public/editor/autocomplete-data.json +++ b/docs/public/editor/autocomplete-data.json @@ -59,10 +59,7 @@ "inlined-imports": { "type": "boolean", "desc": "If true, inline all imports (including those without inputs) at compilation time in the generated lock.yml instead of...", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "on": { @@ -243,9 +240,7 @@ "skip-if-check-failing": { "type": "null|boolean|object", "desc": "Skip workflow execution if any CI checks on the target branch are failing or pending.", - "enum": [ - true - ], + "enum": [true], "leaf": true }, "skip-roles": { @@ -267,15 +262,7 @@ "roles": { "type": "string|array", "desc": "Repository access roles required to trigger agentic workflows.", - "enum": [ - "admin", - "maintainer", - "maintain", - "write", - "triage", - "read", - "all" - ], + "enum": ["admin", "maintainer", "maintain", "write", "triage", "read", "all"], "leaf": true, "array": true }, @@ -293,10 +280,7 @@ "allow-bot-authored-trigger-comment": { "type": "boolean", "desc": "Allow the bot-posted-menu / user-checks-box pattern: when a workflow posts a checkbox-menu comment as a GitHub App bo...", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "manual-approval": { @@ -307,17 +291,7 @@ "reaction": { "type": "string|integer|object", "desc": "AI reaction to add/remove on triggering item.", - "enum": [ - "+1", - "-1", - "laugh", - "confused", - "heart", - "hooray", - "rocket", - "eyes", - "none" - ], + "enum": ["+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", "eyes", "none"], "leaf": true }, "status-comment": { @@ -351,10 +325,7 @@ "stale-check": { "type": "boolean", "desc": "When set to false, disables the frontmatter hash check step in the activation job.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true } } @@ -362,195 +333,120 @@ "permissions": { "type": "string|object", "desc": "GitHub token permissions for the workflow.", - "enum": [ - "read-all", - "write-all" - ], + "enum": ["read-all", "write-all"], "children": { "actions": { "type": "string", "desc": "Permission for GitHub Actions workflows and runs (read: view workflows, write: manage workflows, none: no access)", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "leaf": true }, "attestations": { "type": "string", "desc": "Permission for artifact attestations (read: view attestations, write: create attestations, none: no access)", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "leaf": true }, "checks": { "type": "string", "desc": "Permission for repository checks and status checks (read: view checks, write: create/update checks, none: no access)", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "leaf": true }, "contents": { "type": "string", "desc": "Permission for repository contents (read: view files, write: modify files/branches, none: no access)", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "leaf": true }, "deployments": { "type": "string", "desc": "Permission for repository deployments (read: view deployments, write: create/update deployments, none: no access)", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "leaf": true }, "discussions": { "type": "string", "desc": "Permission for repository discussions (read: view discussions, write: create/update discussions, none: no access)", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "leaf": true }, "id-token": { "type": "string", "desc": "Permission level for OIDC token requests (write/none only - read is not supported).", - "enum": [ - "write", - "none" - ], + "enum": ["write", "none"], "leaf": true }, "issues": { "type": "string", "desc": "Permission for repository issues (read: view issues, write: create/update/close issues, none: no access)", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "leaf": true }, "models": { "type": "string", "desc": "Permission for GitHub Copilot models (read: access AI models for agentic workflows, none: no access)", - "enum": [ - "read", - "none" - ], + "enum": ["read", "none"], "leaf": true }, "metadata": { "type": "string", "desc": "Permission for repository metadata (read: view repository information, write: update repository metadata, none: no ac...", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "leaf": true }, "packages": { "type": "string", "desc": "Permission level for GitHub Packages (read/write/none).", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "leaf": true }, "pages": { "type": "string", "desc": "Permission level for GitHub Pages (read/write/none).", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "leaf": true }, "pull-requests": { "type": "string", "desc": "Permission level for pull requests (read/write/none).", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "leaf": true }, "repository-projects": { "type": "string", "desc": "Permission level for repository projects (read/write/none).", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "leaf": true }, "organization-projects": { "type": "string", "desc": "Permission level for organization projects (read/write/none).", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "leaf": true }, "security-events": { "type": "string", "desc": "Permission level for security events (read/write/none).", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "leaf": true }, "statuses": { "type": "string", "desc": "Permission level for commit statuses (read/write/none).", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "leaf": true }, "vulnerability-alerts": { "type": "string", "desc": "Permission level for Dependabot vulnerability alerts (read/write/none).", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "leaf": true }, "all": { "type": "string", "desc": "Permission shorthand that applies read access to all permission scopes.", - "enum": [ - "read" - ], + "enum": ["read"], "leaf": true } } @@ -603,19 +499,13 @@ "cancel-in-progress": { "type": "boolean", "desc": "Whether to cancel in-progress workflows in the same concurrency group when a new one starts.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "queue": { "type": "string", "desc": "Pending run queue behavior for this concurrency group.", - "enum": [ - "single", - "max" - ], + "enum": ["single", "max"], "leaf": true }, "job-discriminator": { @@ -633,10 +523,7 @@ "inline-sub-agents": { "type": "boolean", "desc": "Deprecated switch for inline sub-agent support.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "features": { @@ -654,10 +541,7 @@ "storage": { "type": "string", "desc": "Storage backend for experiment state.", - "enum": [ - "cache", - "repo" - ], + "enum": ["cache", "repo"], "leaf": true } } @@ -665,19 +549,13 @@ "infer": { "type": "boolean", "desc": "DEPRECATED: Use 'disable-model-invocation' instead.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "disable-model-invocation": { "type": "boolean", "desc": "Controls whether the custom agent should disable model invocation.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "secrets": { @@ -753,9 +631,7 @@ "network": { "type": "string|object", "desc": "Network access control for AI engines using ecosystem identifiers and domain allowlists.", - "enum": [ - "defaults" - ], + "enum": ["defaults"], "children": { "allowed": { "type": "array", @@ -772,41 +648,29 @@ "sandbox": { "type": "string|object", "desc": "Sandbox configuration for AI engines.", - "enum": [ - "default", - "awf" - ], + "enum": ["default", "awf"], "children": { "type": { "type": "string", "desc": "Legacy sandbox type field (use agent instead).", - "enum": [ - "default", - "awf" - ], + "enum": ["default", "awf"], "leaf": true }, "agent": { "type": "boolean|string|object", "desc": "Agent sandbox type: 'awf' uses AWF (Agent Workflow Firewall), or false to disable agent sandbox.", - "enum": [ - "awf" - ], + "enum": ["awf"], "children": { "id": { "type": "string", "desc": "Agent identifier (replaces 'type' field in new format): 'awf' for Agent Workflow Firewall", - "enum": [ - "awf" - ], + "enum": ["awf"], "leaf": true }, "type": { "type": "string", "desc": "Legacy: Sandbox type to use (use 'id' instead)", - "enum": [ - "awf" - ], + "enum": ["awf"], "leaf": true }, "version": { @@ -853,10 +717,7 @@ "enableWeakerNestedSandbox": { "type": "boolean", "desc": "Enable weaker nested sandbox mode (recommended: true for Docker access)", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true } } @@ -895,10 +756,7 @@ "enableWeakerNestedSandbox": { "type": "boolean", "desc": "When true, allows nested sandbox processes to run with relaxed restrictions.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true } } @@ -954,10 +812,7 @@ "domain": { "type": "string", "desc": "Gateway domain for URL generation (default: 'host.docker.internal' when agent is enabled, 'localhost' when disabled)", - "enum": [ - "localhost", - "host.docker.internal" - ], + "enum": ["localhost", "host.docker.internal"], "leaf": true }, "keepalive-interval": { @@ -1035,19 +890,13 @@ "cancel-in-progress": { "type": "boolean", "desc": "Whether to cancel in-progress runs of the same concurrency group.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "queue": { "type": "string", "desc": "Pending run queue behavior for this concurrency group.", - "enum": [ - "single", - "max" - ], + "enum": ["single", "max"], "leaf": true } } @@ -1078,9 +927,7 @@ "type": { "type": "string", "desc": "Authentication type.", - "enum": [ - "github-oidc" - ], + "enum": ["github-oidc"], "leaf": true }, "audience": { @@ -1174,10 +1021,7 @@ "bare": { "type": "boolean", "desc": "When true, disables automatic loading of context and custom instructions by the AI engine.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "mcp": { @@ -1228,20 +1072,13 @@ "mode": { "type": "string", "desc": "GitHub access mode.", - "enum": [ - "gh-proxy", - "local", - "remote" - ], + "enum": ["gh-proxy", "local", "remote"], "leaf": true }, "type": { "type": "string", "desc": "GitHub MCP transport type: 'local' (Docker-based, default) or 'remote' (hosted at api.githubcopilot.com)", - "enum": [ - "local", - "remote" - ], + "enum": ["local", "remote"], "leaf": true }, "version": { @@ -1257,28 +1094,19 @@ "read-only": { "type": "boolean", "desc": "Enable read-only mode to restrict GitHub MCP server to read-only operations only", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "lockdown": { "type": "boolean", "desc": "Enable lockdown mode to limit content surfaced from public repositories (only items authored by users with push access).", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "integrity-proxy": { "type": "boolean", "desc": "Controls DIFC proxy injection for pre-agent gh CLI steps when guard policies (min-integrity) are configured.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "github-token": { @@ -1354,32 +1182,21 @@ "allowed-repos": { "type": "string|array", "desc": "Guard policy: repository access configuration.", - "enum": [ - "all", - "public" - ], + "enum": ["all", "public"], "leaf": true, "array": true }, "repos": { "type": "string|array", "desc": "Deprecated.", - "enum": [ - "all", - "public" - ], + "enum": ["all", "public"], "leaf": true, "array": true }, "min-integrity": { "type": "string", "desc": "Guard policy: minimum required integrity level for repository access.", - "enum": [ - "none", - "unapproved", - "approved", - "merged" - ], + "enum": ["none", "unapproved", "approved", "merged"], "leaf": true }, "blocked-users": { @@ -1413,22 +1230,13 @@ "disapproval-integrity": { "type": "string", "desc": "Guard policy: integrity level assigned when a disapproval reaction is present.", - "enum": [ - "none", - "unapproved", - "approved", - "merged" - ], + "enum": ["none", "unapproved", "approved", "merged"], "leaf": true }, "endorser-min-integrity": { "type": "string", "desc": "Guard policy: minimum integrity level required for an endorser (reactor) to promote content.", - "enum": [ - "unapproved", - "approved", - "merged" - ], + "enum": ["unapproved", "approved", "merged"], "leaf": true }, "github-app": { @@ -1511,10 +1319,7 @@ "mode": { "type": "string", "desc": "Integration mode: 'cli' (recommended) installs @playwright/cli via npm for token-efficient CLI invocations — use play...", - "enum": [ - "cli", - "mcp" - ], + "enum": ["cli", "mcp"], "leaf": true } } @@ -1546,19 +1351,13 @@ "restore-only": { "type": "boolean", "desc": "If true, only restore the cache without saving it back.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "scope": { "type": "string", "desc": "Cache restore key scope: 'workflow' (default, only restores from same workflow) or 'repo' (restores from any workflow...", - "enum": [ - "workflow", - "repo" - ], + "enum": ["workflow", "repo"], "leaf": true }, "allowed-extensions": { @@ -1601,10 +1400,7 @@ "footer": { "type": "boolean", "desc": "Controls whether AI-generated footer is added to the managed comment.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "github-token": { @@ -1615,10 +1411,7 @@ "staged": { "type": "boolean", "desc": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true } } @@ -1636,10 +1429,7 @@ "cli-proxy": { "type": "boolean", "desc": "When true, each user-facing MCP server is mounted as a standalone CLI tool on PATH.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "serena": { @@ -1693,19 +1483,13 @@ "create-orphan": { "type": "boolean", "desc": "Create orphaned branch if it doesn't exist (default: true)", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "wiki": { "type": "boolean", "desc": "Use the GitHub Wiki git repository instead of the regular repository.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "allowed-extensions": { @@ -1747,19 +1531,13 @@ "fail-on-cache-miss": { "type": "boolean", "desc": "Fail the workflow if cache entry is not found", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "lookup-only": { "type": "boolean", "desc": "If true, only checks if cache entry exists and skips download", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "name": { @@ -2006,10 +1784,7 @@ "staged": { "type": "boolean", "desc": "If true, emit step summary messages instead of making GitHub API calls (preview mode)", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "env": { @@ -2060,10 +1835,7 @@ "footer": { "type": "boolean", "desc": "Global footer control for all safe outputs.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "activation-comments": { @@ -2074,19 +1846,13 @@ "group-reports": { "type": "boolean", "desc": "When true, creates a parent '[aw] Failed runs' issue that tracks all workflow failures as sub-issues.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "report-failure-as-issue": { "type": "boolean", "desc": "When false, disables creating failure tracking issues when workflows fail.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "failure-issue-repo": { @@ -2102,10 +1868,7 @@ "id-token": { "type": "string", "desc": "Override the id-token permission for the safe-outputs job.", - "enum": [ - "write", - "none" - ], + "enum": ["write", "none"], "leaf": true }, "concurrency-group": { @@ -2187,11 +1950,7 @@ "if-missing": { "type": "string", "desc": "How to handle missing OTLP endpoint/header values at runtime (for example from unset secrets).", - "enum": [ - "error", - "warn", - "ignore" - ], + "enum": ["error", "warn", "ignore"], "leaf": true } } @@ -2258,37 +2017,25 @@ "strict": { "type": "boolean", "desc": "Enable strict mode validation for enhanced security and compliance.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "private": { "type": "boolean", "desc": "Mark the workflow as private, preventing it from being added to other repositories via 'gh aw add'.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "check-for-updates": { "type": "boolean", "desc": "Control whether the compile-agentic version update check runs in the activation job.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "run-install-scripts": { "type": "boolean", "desc": "Allow npm pre/post install scripts to execute during package installation.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "mcp-scripts": { @@ -2302,9 +2049,7 @@ "checkout": { "type": "object|array|boolean", "desc": "Checkout configuration for the agent job.", - "enum": [ - false - ], + "enum": [false], "children": { "repository": { "type": "string", @@ -2334,20 +2079,13 @@ "submodules": { "type": "string|boolean", "desc": "Controls submodule checkout.", - "enum": [ - "recursive", - "true", - "false" - ], + "enum": ["recursive", "true", "false"], "leaf": true }, "lfs": { "type": "boolean", "desc": "Whether to download Git LFS objects.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "token": { @@ -2396,300 +2134,181 @@ "administration": { "type": "string", "desc": "Permission level for repository administration (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "codespaces": { "type": "string", "desc": "Permission level for Codespaces (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "codespaces-lifecycle-admin": { "type": "string", "desc": "Permission level for Codespaces lifecycle administration (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "codespaces-metadata": { "type": "string", "desc": "Permission level for Codespaces metadata (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "email-addresses": { "type": "string", "desc": "Permission level for user email addresses (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "environments": { "type": "string", "desc": "Permission level for repository environments (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "git-signing": { "type": "string", "desc": "Permission level for git signing (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "members": { "type": "string", "desc": "Permission level for organization members (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-administration": { "type": "string", "desc": "Permission level for organization administration (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-announcement-banners": { "type": "string", "desc": "Permission level for organization announcement banners (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-codespaces": { "type": "string", "desc": "Permission level for organization Codespaces (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-copilot": { "type": "string", "desc": "Permission level for organization Copilot (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-custom-org-roles": { "type": "string", "desc": "Permission level for organization custom org roles (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-custom-properties": { "type": "string", "desc": "Permission level for organization custom properties (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-custom-repository-roles": { "type": "string", "desc": "Permission level for organization custom repository roles (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-events": { "type": "string", "desc": "Permission level for organization events (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-hooks": { "type": "string", "desc": "Permission level for organization webhooks (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-members": { "type": "string", "desc": "Permission level for organization members management (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-packages": { "type": "string", "desc": "Permission level for organization packages (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-personal-access-token-requests": { "type": "string", "desc": "Permission level for organization personal access token requests (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-personal-access-tokens": { "type": "string", "desc": "Permission level for organization personal access tokens (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-plan": { "type": "string", "desc": "Permission level for organization plan (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-self-hosted-runners": { "type": "string", "desc": "Permission level for organization self-hosted runners (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-user-blocking": { "type": "string", "desc": "Permission level for organization user blocking (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "repository-custom-properties": { "type": "string", "desc": "Permission level for repository custom properties (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "repository-hooks": { "type": "string", "desc": "Permission level for repository webhooks (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "single-file": { "type": "string", "desc": "Permission level for single file access (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "team-discussions": { "type": "string", "desc": "Permission level for team discussions (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "vulnerability-alerts": { "type": "string", "desc": "Permission level for Dependabot vulnerability alerts (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none" - ], + "enum": ["read", "none"], "leaf": true }, "workflows": { "type": "string", "desc": "Permission level for GitHub Actions workflow files (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true } } @@ -2699,10 +2318,7 @@ "current": { "type": "boolean", "desc": "Marks this checkout as the logical current repository for the workflow.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "fetch": { @@ -2714,19 +2330,13 @@ "wiki": { "type": "boolean", "desc": "When true, clones the repository's wiki git instead of the regular repository.", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true }, "force-clean-git-credentials": { "type": "boolean", "desc": "When true, persist credentials during checkout, then immediately run a post-checkout cleanup step that removes creden...", - "enum": [ - true, - false - ], + "enum": [true, false], "leaf": true } }, @@ -2768,300 +2378,181 @@ "administration": { "type": "string", "desc": "Permission level for repository administration (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "codespaces": { "type": "string", "desc": "Permission level for Codespaces (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "codespaces-lifecycle-admin": { "type": "string", "desc": "Permission level for Codespaces lifecycle administration (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "codespaces-metadata": { "type": "string", "desc": "Permission level for Codespaces metadata (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "email-addresses": { "type": "string", "desc": "Permission level for user email addresses (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "environments": { "type": "string", "desc": "Permission level for repository environments (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "git-signing": { "type": "string", "desc": "Permission level for git signing (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "members": { "type": "string", "desc": "Permission level for organization members (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-administration": { "type": "string", "desc": "Permission level for organization administration (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-announcement-banners": { "type": "string", "desc": "Permission level for organization announcement banners (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-codespaces": { "type": "string", "desc": "Permission level for organization Codespaces (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-copilot": { "type": "string", "desc": "Permission level for organization Copilot (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-custom-org-roles": { "type": "string", "desc": "Permission level for organization custom org roles (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-custom-properties": { "type": "string", "desc": "Permission level for organization custom properties (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-custom-repository-roles": { "type": "string", "desc": "Permission level for organization custom repository roles (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-events": { "type": "string", "desc": "Permission level for organization events (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-hooks": { "type": "string", "desc": "Permission level for organization webhooks (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-members": { "type": "string", "desc": "Permission level for organization members management (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-packages": { "type": "string", "desc": "Permission level for organization packages (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-personal-access-token-requests": { "type": "string", "desc": "Permission level for organization personal access token requests (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-personal-access-tokens": { "type": "string", "desc": "Permission level for organization personal access tokens (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-plan": { "type": "string", "desc": "Permission level for organization plan (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-self-hosted-runners": { "type": "string", "desc": "Permission level for organization self-hosted runners (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "organization-user-blocking": { "type": "string", "desc": "Permission level for organization user blocking (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "repository-custom-properties": { "type": "string", "desc": "Permission level for repository custom properties (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "repository-hooks": { "type": "string", "desc": "Permission level for repository webhooks (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "single-file": { "type": "string", "desc": "Permission level for single file access (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "team-discussions": { "type": "string", "desc": "Permission level for team discussions (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true }, "vulnerability-alerts": { "type": "string", "desc": "Permission level for Dependabot vulnerability alerts (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none" - ], + "enum": ["read", "none"], "leaf": true }, "workflows": { "type": "string", "desc": "Permission level for GitHub Actions workflow files (read/none; \"write\" is rejected by the compiler).", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "leaf": true } } @@ -3115,4 +2606,4 @@ "runtimes", "jobs" ] -} \ No newline at end of file +} diff --git a/docs/src/content/docs/reference/effective-tokens-specification.md b/docs/src/content/docs/reference/effective-tokens-specification.md index 12956ae2ef2..7655c3155fb 100644 --- a/docs/src/content/docs/reference/effective-tokens-specification.md +++ b/docs/src/content/docs/reference/effective-tokens-specification.md @@ -265,6 +265,42 @@ A conforming response MUST include a `summary` object alongside the `invocations } ``` +### 7.1 OpenTelemetry Attribute Requirements + +Implementations that emit OpenTelemetry spans or metrics for token accounting MUST use the following +normative attribute keys. These keys are not optional examples — they are required names for +cross-implementation interoperability. + +| OTel Attribute Key | Type | Description | +|---|---|---| +| `llm.token.effective_total` | integer | Total Effective Tokens for the invocation (ET as defined in §4.4) | +| `llm.token.input` | integer | Raw input token count for the invocation | +| `llm.token.output` | integer | Raw output token count for the invocation | +| `llm.token.cached_input` | integer | Number of input tokens served from cache | +| `llm.token.base_weighted` | integer | Base weighted token value before model multiplier is applied | +| `llm.model.multiplier` | float | The Copilot model multiplier (`m`) applied for this invocation | +| `llm.invocation.id` | string | Unique identifier for this invocation node (matches `id` field in execution graph) | + +**R-OTL-001**: Implementations that emit OTel attributes for effective token data MUST use +`llm.token.effective_total` as the attribute key for the ET value. Implementations MUST NOT use +alternative keys (e.g., `effective_tokens`, `et_total`) for this attribute. + +**R-OTL-002**: Implementations MUST emit `llm.token.input`, `llm.token.output`, and +`llm.token.cached_input` as separate span attributes when per-class token counts are available. +These three attributes MUST reflect raw (unweighted) token counts. + +**R-OTL-003**: Implementations MUST emit `llm.token.base_weighted` as a span attribute when the +base weighted token value is computed. This attribute allows consumers to audit the weighting step +independently of the model multiplier. + +**R-OTL-004**: When `llm.model.multiplier` is emitted, its value MUST match the multiplier used +to compute `llm.token.effective_total` for the same span. Implementations MUST NOT omit +`llm.model.multiplier` if `llm.token.effective_total` is present. + +**R-OTL-005**: All OTel attribute keys defined in this section are versioned under this +specification. Implementations MUST NOT rename or reuse these keys with different semantics +without a specification revision. + --- ## 8. Implementation Requirements @@ -351,13 +387,24 @@ Extensions MUST NOT alter the core ET definition or the default weight values wi - **T-ET-011**: `raw_total_tokens` equals the sum of all raw tokens across all invocations - **T-ET-012**: `total_invocations` count includes root, sub-agents, and tool-triggered calls -#### 10.1.3 Execution Graph Tests +#### 10.1.3 Aggregation with Zero-ET Leaf Nodes + +- **T-ET-006**: Multi-invocation aggregation where one or more leaf invocation nodes have all + token class values set to zero (simulating tool calls that produce no tokens, such as no-op + tool invocations or tool calls whose usage data is unavailable). The implementation MUST: + 1. Include the zero-ET invocation node in `total_invocations` count. + 2. Contribute `0` to `ET_total` from that node (rather than omitting it). + 3. Represent the node in the execution graph with all `usage.*` fields set to `0` and + `derived.effective_tokens = 0`. + 4. Not emit a warning or error solely because a leaf node has zero effective tokens. + +#### 10.1.4 Execution Graph Tests - **T-ET-020**: Root node has `parent_id = null` - **T-ET-021**: All sub-agent nodes reference a valid `parent_id` - **T-ET-022**: Node schema includes all required fields -#### 10.1.4 Reporting Tests +#### 10.1.5 Reporting Tests - **T-ET-030**: Summary object is present in all conforming responses - **T-ET-031**: Summary values are consistent with per-invocation data @@ -368,17 +415,18 @@ Extensions MUST NOT alter the core ET definition or the default weight values wi | Category | Count | |---|---| -| Total tests defined | 12 | -| Required tests | 12 | +| Total tests defined | 13 | +| Required tests | 13 | | Optional tests | 0 | -Count method: unique `T-ET-*` IDs in §10.1 (`001–004`, `010–012`, `020–022`, `030–031`). +Count method: unique `T-ET-*` IDs in §10.1 (`001–004`, `006`, `010–012`, `020–022`, `030–031`). | Requirement | Test ID | Level | Status | |---|---|---|---| | Per-invocation base weighted tokens | T-ET-001–004 | 1 | Implemented | | Per-invocation ET computation | T-ET-002 | 1 | Implemented | | Multi-invocation aggregation | T-ET-010–012 | 2 | Implemented | +| Zero-ET leaf node aggregation | T-ET-006 | 2 | Required | | Execution graph node schema | T-ET-020–022 | 2 | Implemented | | Summary reporting | T-ET-030–031 | 3 | Implemented | | Custom weight disclosure | T-ET-004 | 1 | Implemented | diff --git a/docs/src/content/docs/reference/forecast-specification.md b/docs/src/content/docs/reference/forecast-specification.md index 1769f36bc3e..eedcf155dcd 100644 --- a/docs/src/content/docs/reference/forecast-specification.md +++ b/docs/src/content/docs/reference/forecast-specification.md @@ -465,6 +465,14 @@ The `projected_effective_tokens` top-level field MUST equal `p50_projected_effec If no historical runs are available for a workflow, the implementation MUST return a nil (empty/zero) projection for that workflow. Nil projections MUST be represented in JSON output as zero values for all numeric Monte Carlo fields. The implementation MUST NOT run trials when the sample is empty. +### 7.6 Minimum Sample Size for Percentile Validity + +The P10 and P90 estimates produced by the Monte Carlo engine are only statistically reliable when the bootstrap sample contains a sufficient number of distinct ET observations. + +- **R-MC-030**: Implementations SHOULD require a minimum of **10** ET observations (i.e., runs with non-zero `effective_tokens`) before treating P10 and P90 as reliable estimates. When `n < 10`, implementations SHOULD emit a warning to stderr indicating that the confidence interval may be unreliable due to insufficient sample size. _Rationale: Bootstrap resampling with fewer than 10 observations produces percentile estimates that are highly sensitive to individual outliers. With n < 10, the P10 and P90 bounds collapse toward the single minimum and maximum observations, making the 80% confidence interval misleadingly precise. The threshold of 10 is consistent with standard statistical practice for non-parametric bootstrapping._ +- **R-MC-031**: Implementations MUST still run the Monte Carlo simulation and return P10/P50/P90 values even when `n < 10`. The simulation MUST NOT be suppressed solely on the basis of sample size; the warning in **R-MC-030** is advisory only. +- **R-MC-032**: When `n = 0` (no ET observations in the sample), the **Nil Projection Condition** in §7.5 applies and the simulation MUST NOT run. This is a separate condition from the low-sample warning. + --- ## 8. Episode Analysis @@ -762,6 +770,34 @@ When `--verbose` is specified, the implementation SHOULD emit the following addi - The computed `λ` (Poisson rate) for each workflow - Timing information for API calls and simulation execution +### 10.6 Safeguards for API Rate-Limit During Sampling + +When the GitHub API returns HTTP 429 or HTTP 403 (with a `X-RateLimit-Remaining: 0` header) +during `gh api` sampling calls (i.e., while fetching run lists or artifact data for individual +workflows): + +- **R-ERR-040**: The implementation MUST apply an exponential-backoff retry strategy: the first + retry MUST wait at least the number of seconds indicated by the `Retry-After` or + `X-RateLimit-Reset` header (whichever is present and non-zero). If neither header is present, + the implementation MUST wait at least 60 seconds before the first retry attempt. +- **R-ERR-041**: The implementation MUST retry the failed request at least once before treating + the workflow as a partial failure. Implementations SHOULD retry up to 3 times with increasing + backoff intervals. +- **R-ERR-042**: The implementation MUST emit a warning to stderr before each backoff wait + period, including the workflow identifier, the HTTP status code received, and the estimated + wait duration. +- **R-ERR-043**: If all retry attempts are exhausted and the request still fails, the + implementation SHOULD fall back to partial-result mode: the affected workflow MUST be included + in output with `sampled_runs: 0` and all projection fields set to zero, consistent with + **R-ERR-021**. The implementation MUST NOT abort the entire forecast run due to a single + workflow's rate-limit failure. +- **R-ERR-044**: When operating in partial-result mode due to rate-limit exhaustion, the + implementation SHOULD include a `rate_limit_skipped` boolean field set to `true` in the + workflow's JSON output entry so that callers can distinguish rate-limit-induced zero projections + from genuine zero-activity workflows. This field is an **additive optional extension** first + defined in Section 10.6; callers MUST treat its absence as equivalent to `false` (per + §11.5 / **R-IMPL-041**, unknown fields in JSON output MUST be treated as ignorable). + --- ## 11. Implementation Requirements @@ -800,6 +836,10 @@ Because the forecast command is marked **Experimental**: ### 12.1 Test Suite Requirements +Test fixtures for the compliance tests are located in `specs/forecast-compliance-fixtures/`. +See `specs/forecast-compliance-fixtures/README.md` for instructions on running the test suite +and adding new fixtures. + #### 12.1.1 Command Interface Tests - **T-FC-001**: Invocation with invalid `--days` value exits non-zero with descriptive error. diff --git a/docs/src/content/docs/reference/fuzzy-schedule-specification.md b/docs/src/content/docs/reference/fuzzy-schedule-specification.md index 44e8aafc6e4..83eea713969 100644 --- a/docs/src/content/docs/reference/fuzzy-schedule-specification.md +++ b/docs/src/content/docs/reference/fuzzy-schedule-specification.md @@ -1223,6 +1223,13 @@ This section maps the fuzzy schedule specification to implementation files. | Parser/scatter conformance tests | `pkg/parser/schedule_parser_test.go`, `pkg/parser/schedule_fuzzy_scatter_test.go` | | Calendar/cron visualization support for compile tooling (see §12) | `pkg/cli/compile_schedule_calendar.go` | +**Hash function**: The scattering algorithm (§6.2) uses the **FNV-1a 32-bit** hash function +(`FNV_offset_basis = 0x811c9dc5`, `FNV_prime = 0x01000193`) applied to the workflow identifier +string `{owner}/{repo}/{workflow_file_path}`. This hash is implemented in +`pkg/parser/schedule_fuzzy_scatter.go`. Alternative hash functions are permitted by §6.2.1 if +they satisfy the determinism, distribution, and stability requirements, but the FNV-1a reference +implementation is normative for cross-platform consistency tests. + After changing fuzzy schedule semantics: 1. Update this specification section and any affected normative clauses. 2. Update parser/scatter implementation in the mapped files. diff --git a/docs/src/content/docs/reference/mcp-scripts-specification.md b/docs/src/content/docs/reference/mcp-scripts-specification.md index fe38f7060be..7433b3e0ce4 100644 --- a/docs/src/content/docs/reference/mcp-scripts-specification.md +++ b/docs/src/content/docs/reference/mcp-scripts-specification.md @@ -744,6 +744,29 @@ Implementations MUST: 3. Apply size limits to output (see Section 8) 4. Remove or mask any accidental secret exposure in output +**SM-01**: Implementations MUST sanitize tool stdout before forwarding the result to the MCP +client. Any string value in the tool's output that matches a **registered secret pattern** MUST be +redacted and replaced with the string `"[REDACTED]"` prior to serialization. This requirement +applies to all output fields, including nested JSON objects and arrays. + +A *registered secret pattern* is any secret value that the GitHub Actions runner has registered +for masking (i.e., any value sourced from `${{ secrets.NAME }}` references declared in the +workflow's `env:` block, as described in §7.1). Implementations MUST obtain the list of active +secret values from the runner's masking registry (GitHub Actions `::add-mask::` mechanism) to +determine which patterns to redact. See §7.1 for the secret isolation model that governs which +secrets are in scope. + +**SM-02**: The secret pattern matching used for output sanitization MUST be consistent with the +masking logic applied to runner logs. Implementations MUST reuse or delegate to the sanitization +helper functions provided in `actions/setup/js/` (specifically the output-redaction utilities in +`actions/setup/js/mcp_scripts_mcp_server_http.cjs` and related helpers) rather than implementing +independent redaction logic. + +**SM-03**: Implementations MUST NOT forward raw tool stdout to the MCP client without first +passing it through the output sanitization pipeline. This applies regardless of whether the tool +declares secrets in its `env:` field; residual secret values that appear in stdout through indirect +means (e.g., subprocess output, error messages) MUST also be redacted. + ### 7.5 Timeout Enforcement Implementations MUST: @@ -936,6 +959,11 @@ A conforming implementation MUST pass the following test categories: - **T-INT-004**: JSON-RPC request handling - **T-INT-005**: Error response format +#### 10.1.8 Negative Tests + +- **T-MS-NEG-001**: Tool definition with missing `script` (or `run`, `py`, `go`) field — implementation MUST reject the configuration at compile time with an error identifying the missing implementation field. The error MUST reference the tool name and the required field names. +- **T-MS-NEG-002**: Tool input schema referencing an undefined type (e.g., `type: "uuid"`) — implementation MUST reject the schema at validation time with an error indicating the unsupported type. The error MUST include the tool name, parameter name, and the invalid type value. + ### 10.2 Compliance Checklist | Requirement | Test ID | Level | Status | @@ -952,6 +980,8 @@ A conforming implementation MUST pass the following test categories: | Dependencies support | T-DEP-* | 2 | Standard | | GitHub Actions globals | T-SEC-008 | 1 | Required | | MCP Gateway integration | T-INT-* | 1 | Required | +| Missing implementation field rejection | T-MS-NEG-001 | 1 | Required | +| Invalid input schema type rejection | T-MS-NEG-002 | 1 | Required | ### 10.3 Test Execution diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index 8702049650a..ae3debd5aaa 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -5,53 +5,35 @@ "description": "JSON Schema for validating agentic workflow frontmatter configuration", "version": "1.0.0", "type": "object", - "required": [ - "on" - ], + "required": ["on"], "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 256, "description": "Workflow name that appears in the GitHub Actions interface. If not specified, defaults to the filename without extension.", - "examples": [ - "Copilot Agent PR Analysis", - "Dev Hawk", - "Smoke Claude" - ] + "examples": ["Copilot Agent PR Analysis", "Dev Hawk", "Smoke Claude"] }, "description": { "type": "string", "maxLength": 10000, "description": "Optional workflow description that is rendered as a comment in the generated GitHub Actions YAML file (.lock.yml)", - "examples": [ - "Quickstart for using the GitHub Actions library" - ] + "examples": ["Quickstart for using the GitHub Actions library"] }, "emoji": { "type": "string", "description": "Optional emoji to represent the workflow visually in listings and UI surfaces.", - "examples": [ - "\ud83e\udd16", - "\ud83d\udd0d", - "\ud83d\ude80" - ] + "examples": ["\ud83e\udd16", "\ud83d\udd0d", "\ud83d\ude80"] }, "source": { "type": "string", "description": "Optional source reference indicating where this workflow was added from. Format: owner/repo/path@ref (e.g., githubnext/agentics/workflows/ci-doctor.md@v1.0.0). Rendered as a comment in the generated lock file.", - "examples": [ - "githubnext/agentics/workflows/ci-doctor.md", - "githubnext/agentics/workflows/daily-perf-improver.md@1f181b37d3fe5862ab590648f25a292e345b5de6" - ] + "examples": ["githubnext/agentics/workflows/ci-doctor.md", "githubnext/agentics/workflows/daily-perf-improver.md@1f181b37d3fe5862ab590648f25a292e345b5de6"] }, "redirect": { "type": "string", "description": "Optional workflow location redirect for updates. Format: workflow spec or GitHub URL (e.g., owner/repo/path@ref or https://github.com/owner/repo/blob/main/path.md). When present, update follows this location and rewrites source.", - "examples": [ - "githubnext/agentics/workflows/ci-doctor-v2.md@main", - "https://github.com/githubnext/agentics/blob/main/workflows/ci-doctor-v2.md" - ] + "examples": ["githubnext/agentics/workflows/ci-doctor-v2.md@main", "https://github.com/githubnext/agentics/blob/main/workflows/ci-doctor-v2.md"] }, "tracker-id": { "type": "string", @@ -59,11 +41,7 @@ "maxLength": 128, "pattern": "^[a-zA-Z0-9_-]+$", "description": "Optional tracker identifier to tag all created assets (issues, discussions, comments, pull requests). Must be at least 8 characters and contain only alphanumeric characters, hyphens, and underscores. This identifier will be inserted in the body/description of all created assets to enable searching and retrieving assets associated with this workflow.", - "examples": [ - "workflow-2024-q1", - "team-alpha-bot", - "security_audit_v2" - ] + "examples": ["workflow-2024-q1", "team-alpha-bot", "security_audit_v2"] }, "labels": { "type": "array", @@ -73,18 +51,9 @@ "minLength": 1 }, "examples": [ - [ - "automation", - "security" - ], - [ - "docs", - "maintenance" - ], - [ - "ci", - "testing" - ] + ["automation", "security"], + ["docs", "maintenance"], + ["ci", "testing"] ] }, "metadata": { @@ -121,9 +90,7 @@ { "type": "object", "description": "Import specification with path and optional inputs", - "required": [ - "path" - ], + "required": ["path"], "additionalProperties": false, "properties": { "path": { @@ -169,9 +136,7 @@ { "type": "object", "description": "Import specification with 'uses'/'with' syntax (mirrors GitHub Actions reusable workflow syntax). 'uses' references the workflow path and 'with' provides input values.", - "required": [ - "uses" - ], + "required": ["uses"], "additionalProperties": false, "properties": { "uses": { @@ -256,9 +221,7 @@ { "type": "object", "description": "Import specification with path and optional inputs", - "required": [ - "path" - ], + "required": ["path"], "additionalProperties": false, "properties": { "path": { @@ -304,9 +267,7 @@ { "type": "object", "description": "Import specification with 'uses'/'with' syntax.", - "required": [ - "uses" - ], + "required": ["uses"], "additionalProperties": false, "properties": { "uses": { @@ -378,21 +339,10 @@ } ], "examples": [ - [ - "shared/jqschema.md", - "shared/reporting.md" - ], - [ - "shared/mcp/gh-aw.md", - "shared/jqschema.md", - "shared/reporting.md" - ], - [ - "../instructions/documentation.instructions.md" - ], - [ - ".github/agents/my-agent.md" - ], + ["shared/jqschema.md", "shared/reporting.md"], + ["shared/mcp/gh-aw.md", "shared/jqschema.md", "shared/reporting.md"], + ["../instructions/documentation.instructions.md"], + [".github/agents/my-agent.md"], [ { "path": "shared/discussions-data-fetch.md", @@ -402,10 +352,7 @@ } ], { - "aw": [ - "shared/common-tools.md", - "shared/mcp/tavily.md" - ] + "aw": ["shared/common-tools.md", "shared/mcp/tavily.md"] } ] }, @@ -419,45 +366,25 @@ "pattern": "\\$\\{\\{" } }, - "examples": [ - [ - "triage-issue.md", - "label-issue.md" - ], - [ - "my-custom-action.yml" - ], - [ - "shared/helper-action.yml", - "close-stale.md" - ] - ] + "examples": [["triage-issue.md", "label-issue.md"], ["my-custom-action.yml"], ["shared/helper-action.yml", "close-stale.md"]] }, "inlined-imports": { "type": "boolean", "default": false, "description": "If true, inline all imports (including those without inputs) at compilation time in the generated lock.yml instead of using runtime-import macros. When enabled, the frontmatter hash covers the entire markdown body so any change to the content will invalidate the hash.", - "examples": [ - true, - false - ] + "examples": [true, false] }, "on": { "description": "Workflow triggers that define when the agentic workflow should run. Supports standard GitHub Actions trigger events plus special command triggers for /commands (required)", "examples": [ { "issues": { - "types": [ - "opened" - ] + "types": ["opened"] } }, { "pull_request": { - "types": [ - "opened", - "synchronize" - ] + "types": ["opened", "synchronize"] } }, "workflow_dispatch", @@ -471,13 +398,7 @@ "type": "string", "minLength": 1, "description": "Simple trigger event name (e.g., 'push', 'issues', 'pull_request', 'discussion', 'schedule', 'fork', 'create', 'delete', 'public', 'watch', 'workflow_call'), schedule shorthand (e.g., 'daily', 'weekly'), or slash command shorthand (e.g., '/my-bot' expands to slash_command + workflow_dispatch)", - "examples": [ - "push", - "issues", - "workflow_dispatch", - "daily", - "/my-bot" - ] + "examples": ["push", "issues", "workflow_dispatch", "daily", "/my-bot"] }, { "type": "object", @@ -529,16 +450,7 @@ { "type": "string", "description": "Single event name or '*' for all events. Use GitHub Actions event names: 'issues', 'issue_comment', 'pull_request_comment', 'pull_request', 'pull_request_review_comment', 'discussion', 'discussion_comment'.", - "enum": [ - "*", - "issues", - "issue_comment", - "pull_request_comment", - "pull_request", - "pull_request_review_comment", - "discussion", - "discussion_comment" - ] + "enum": ["*", "issues", "issue_comment", "pull_request_comment", "pull_request", "pull_request_review_comment", "discussion", "discussion_comment"] }, { "type": "array", @@ -547,16 +459,7 @@ "items": { "type": "string", "description": "GitHub Actions event name.", - "enum": [ - "*", - "issues", - "issue_comment", - "pull_request_comment", - "pull_request", - "pull_request_review_comment", - "discussion", - "discussion_comment" - ] + "enum": ["*", "issues", "issue_comment", "pull_request_comment", "pull_request", "pull_request_review_comment", "discussion", "discussion_comment"] }, "maxItems": 25 } @@ -565,10 +468,7 @@ "strategy": { "type": "string", "description": "Slash command trigger compilation strategy. 'inline' (default) compiles direct comment listeners in this workflow. 'centralized' compiles this workflow as workflow_dispatch-centric and routes slash events via the generated central trigger workflow.", - "enum": [ - "inline", - "centralized" - ] + "enum": ["inline", "centralized"] } }, "additionalProperties": false @@ -621,16 +521,7 @@ { "type": "string", "description": "Single event name or '*' for all events. Use GitHub Actions event names: 'issues', 'issue_comment', 'pull_request_comment', 'pull_request', 'pull_request_review_comment', 'discussion', 'discussion_comment'.", - "enum": [ - "*", - "issues", - "issue_comment", - "pull_request_comment", - "pull_request", - "pull_request_review_comment", - "discussion", - "discussion_comment" - ] + "enum": ["*", "issues", "issue_comment", "pull_request_comment", "pull_request", "pull_request_review_comment", "discussion", "discussion_comment"] }, { "type": "array", @@ -639,16 +530,7 @@ "items": { "type": "string", "description": "GitHub Actions event name.", - "enum": [ - "*", - "issues", - "issue_comment", - "pull_request_comment", - "pull_request", - "pull_request_review_comment", - "discussion", - "discussion_comment" - ] + "enum": ["*", "issues", "issue_comment", "pull_request_comment", "pull_request", "pull_request_review_comment", "discussion", "discussion_comment"] }, "maxItems": 25 } @@ -719,12 +601,7 @@ { "type": "string", "description": "Single item type or '*' for all types.", - "enum": [ - "*", - "issues", - "pull_request", - "discussion" - ] + "enum": ["*", "issues", "pull_request", "discussion"] }, { "type": "array", @@ -733,12 +610,7 @@ "items": { "type": "string", "description": "Item type.", - "enum": [ - "*", - "issues", - "pull_request", - "discussion" - ] + "enum": ["*", "issues", "pull_request", "discussion"] }, "maxItems": 3 } @@ -751,10 +623,7 @@ "strategy": { "type": "string", "description": "Label command trigger compilation strategy. 'inline' (default) compiles direct labeled listeners in this workflow. 'decentralized' compiles this workflow as workflow_dispatch-centric and routes labeled events via the generated agentic_commands.yml workflow.", - "enum": [ - "inline", - "decentralized" - ] + "enum": ["inline", "decentralized"] } }, "additionalProperties": false @@ -815,37 +684,25 @@ }, "oneOf": [ { - "required": [ - "branches" - ], + "required": ["branches"], "not": { - "required": [ - "branches-ignore" - ] + "required": ["branches-ignore"] } }, { - "required": [ - "branches-ignore" - ], + "required": ["branches-ignore"], "not": { - "required": [ - "branches" - ] + "required": ["branches"] } }, { "not": { "anyOf": [ { - "required": [ - "branches" - ] + "required": ["branches"] }, { - "required": [ - "branches-ignore" - ] + "required": ["branches-ignore"] } ] } @@ -855,37 +712,25 @@ { "oneOf": [ { - "required": [ - "paths" - ], + "required": ["paths"], "not": { - "required": [ - "paths-ignore" - ] + "required": ["paths-ignore"] } }, { - "required": [ - "paths-ignore" - ], + "required": ["paths-ignore"], "not": { - "required": [ - "paths" - ] + "required": ["paths"] } }, { "not": { "anyOf": [ { - "required": [ - "paths" - ] + "required": ["paths"] }, { - "required": [ - "paths-ignore" - ] + "required": ["paths-ignore"] } ] } @@ -1005,37 +850,25 @@ "additionalProperties": false, "oneOf": [ { - "required": [ - "branches" - ], + "required": ["branches"], "not": { - "required": [ - "branches-ignore" - ] + "required": ["branches-ignore"] } }, { - "required": [ - "branches-ignore" - ], + "required": ["branches-ignore"], "not": { - "required": [ - "branches" - ] + "required": ["branches"] } }, { "not": { "anyOf": [ { - "required": [ - "branches" - ] + "required": ["branches"] }, { - "required": [ - "branches-ignore" - ] + "required": ["branches-ignore"] } ] } @@ -1045,37 +878,25 @@ { "oneOf": [ { - "required": [ - "paths" - ], + "required": ["paths"], "not": { - "required": [ - "paths-ignore" - ] + "required": ["paths-ignore"] } }, { - "required": [ - "paths-ignore" - ], + "required": ["paths-ignore"], "not": { - "required": [ - "paths" - ] + "required": ["paths"] } }, { "not": { "anyOf": [ { - "required": [ - "paths" - ] + "required": ["paths"] }, { - "required": [ - "paths-ignore" - ] + "required": ["paths-ignore"] } ] } @@ -1094,26 +915,7 @@ "description": "Types of issue events", "items": { "type": "string", - "enum": [ - "opened", - "edited", - "deleted", - "transferred", - "pinned", - "unpinned", - "closed", - "reopened", - "assigned", - "unassigned", - "labeled", - "unlabeled", - "locked", - "unlocked", - "milestoned", - "demilestoned", - "typed", - "untyped" - ] + "enum": ["opened", "edited", "deleted", "transferred", "pinned", "unpinned", "closed", "reopened", "assigned", "unassigned", "labeled", "unlabeled", "locked", "unlocked", "milestoned", "demilestoned", "typed", "untyped"] } }, "names": { @@ -1151,11 +953,7 @@ "description": "Types of issue comment events", "items": { "type": "string", - "enum": [ - "created", - "edited", - "deleted" - ] + "enum": ["created", "edited", "deleted"] } }, "lock-for-agent": { @@ -1174,21 +972,7 @@ "description": "Types of discussion events", "items": { "type": "string", - "enum": [ - "created", - "edited", - "deleted", - "transferred", - "pinned", - "unpinned", - "labeled", - "unlabeled", - "locked", - "unlocked", - "category_changed", - "answered", - "unanswered" - ] + "enum": ["created", "edited", "deleted", "transferred", "pinned", "unpinned", "labeled", "unlabeled", "locked", "unlocked", "category_changed", "answered", "unanswered"] } } } @@ -1203,11 +987,7 @@ "description": "Types of discussion comment events", "items": { "type": "string", - "enum": [ - "created", - "edited", - "deleted" - ] + "enum": ["created", "edited", "deleted"] } } } @@ -1236,9 +1016,7 @@ "description": "Optional IANA timezone string for timezone-aware scheduling (e.g., 'America/New_York', 'Europe/London', 'Asia/Tokyo', 'UTC'). When set, the cron expression is interpreted in the specified timezone instead of UTC." } }, - "required": [ - "cron" - ], + "required": ["cron"], "additionalProperties": false }, "maxItems": 10 @@ -1288,13 +1066,7 @@ }, "type": { "type": "string", - "enum": [ - "string", - "choice", - "boolean", - "number", - "environment" - ], + "enum": ["string", "choice", "boolean", "number", "environment"], "description": "Input type. GitHub Actions supports: string (default), boolean, choice (string with predefined options), number, and environment (string referencing a GitHub environment)" }, "options": { @@ -1328,11 +1100,7 @@ "description": "Types of workflow run events", "items": { "type": "string", - "enum": [ - "completed", - "requested", - "in_progress" - ] + "enum": ["completed", "requested", "in_progress"] } }, "branches": { @@ -1354,37 +1122,25 @@ }, "oneOf": [ { - "required": [ - "branches" - ], + "required": ["branches"], "not": { - "required": [ - "branches-ignore" - ] + "required": ["branches-ignore"] } }, { - "required": [ - "branches-ignore" - ], + "required": ["branches-ignore"], "not": { - "required": [ - "branches" - ] + "required": ["branches"] } }, { "not": { "anyOf": [ { - "required": [ - "branches" - ] + "required": ["branches"] }, { - "required": [ - "branches-ignore" - ] + "required": ["branches-ignore"] } ] } @@ -1401,15 +1157,7 @@ "description": "Types of release events", "items": { "type": "string", - "enum": [ - "published", - "unpublished", - "created", - "edited", - "deleted", - "prereleased", - "released" - ] + "enum": ["published", "unpublished", "created", "edited", "deleted", "prereleased", "released"] } } } @@ -1424,11 +1172,7 @@ "description": "Types of pull request review comment events", "items": { "type": "string", - "enum": [ - "created", - "edited", - "deleted" - ] + "enum": ["created", "edited", "deleted"] } } } @@ -1443,11 +1187,7 @@ "description": "Types of branch protection rule events", "items": { "type": "string", - "enum": [ - "created", - "edited", - "deleted" - ] + "enum": ["created", "edited", "deleted"] } } } @@ -1462,12 +1202,7 @@ "description": "Types of check run events", "items": { "type": "string", - "enum": [ - "created", - "rerequested", - "completed", - "requested_action" - ] + "enum": ["created", "rerequested", "completed", "requested_action"] } } } @@ -1482,9 +1217,7 @@ "description": "Types of check suite events", "items": { "type": "string", - "enum": [ - "completed" - ] + "enum": ["completed"] } } } @@ -1544,31 +1277,13 @@ "oneOf": [ { "type": "string", - "enum": [ - "error", - "failure", - "pending", - "success", - "inactive", - "in_progress", - "queued", - "waiting" - ] + "enum": ["error", "failure", "pending", "success", "inactive", "in_progress", "queued", "waiting"] }, { "type": "array", "items": { "type": "string", - "enum": [ - "error", - "failure", - "pending", - "success", - "inactive", - "in_progress", - "queued", - "waiting" - ] + "enum": ["error", "failure", "pending", "success", "inactive", "in_progress", "queued", "waiting"] }, "minItems": 1 } @@ -1614,11 +1329,7 @@ "description": "Types of label events", "items": { "type": "string", - "enum": [ - "created", - "edited", - "deleted" - ] + "enum": ["created", "edited", "deleted"] } } } @@ -1633,9 +1344,7 @@ "description": "Types of merge group events", "items": { "type": "string", - "enum": [ - "checks_requested" - ] + "enum": ["checks_requested"] } } } @@ -1650,13 +1359,7 @@ "description": "Types of milestone events", "items": { "type": "string", - "enum": [ - "created", - "closed", - "opened", - "edited", - "deleted" - ] + "enum": ["created", "closed", "opened", "edited", "deleted"] } } } @@ -1774,37 +1477,25 @@ "additionalProperties": false, "oneOf": [ { - "required": [ - "branches" - ], + "required": ["branches"], "not": { - "required": [ - "branches-ignore" - ] + "required": ["branches-ignore"] } }, { - "required": [ - "branches-ignore" - ], + "required": ["branches-ignore"], "not": { - "required": [ - "branches" - ] + "required": ["branches"] } }, { "not": { "anyOf": [ { - "required": [ - "branches" - ] + "required": ["branches"] }, { - "required": [ - "branches-ignore" - ] + "required": ["branches-ignore"] } ] } @@ -1814,37 +1505,25 @@ { "oneOf": [ { - "required": [ - "paths" - ], + "required": ["paths"], "not": { - "required": [ - "paths-ignore" - ] + "required": ["paths-ignore"] } }, { - "required": [ - "paths-ignore" - ], + "required": ["paths-ignore"], "not": { - "required": [ - "paths" - ] + "required": ["paths"] } }, { "not": { "anyOf": [ { - "required": [ - "paths" - ] + "required": ["paths"] }, { - "required": [ - "paths-ignore" - ] + "required": ["paths-ignore"] } ] } @@ -1863,11 +1542,7 @@ "description": "Types of pull request review events", "items": { "type": "string", - "enum": [ - "submitted", - "edited", - "dismissed" - ] + "enum": ["submitted", "edited", "dismissed"] } } } @@ -1882,10 +1557,7 @@ "description": "Types of registry package events", "items": { "type": "string", - "enum": [ - "published", - "updated" - ] + "enum": ["published", "updated"] } } } @@ -1927,9 +1599,7 @@ "description": "Types of watch events", "items": { "type": "string", - "enum": [ - "started" - ] + "enum": ["started"] } } } @@ -1961,11 +1631,7 @@ }, "type": { "type": "string", - "enum": [ - "string", - "number", - "boolean" - ], + "enum": ["string", "number", "boolean"], "description": "Type of the input parameter" }, "default": { @@ -2007,9 +1673,7 @@ }, { "type": "object", - "required": [ - "query" - ], + "required": ["query"], "properties": { "query": { "type": "string", @@ -2031,9 +1695,7 @@ }, "scope": { "type": "string", - "enum": [ - "none" - ], + "enum": ["none"], "description": "Scope for the search query. Set to 'none' to disable the automatic 'repo:owner/repo' scoping, enabling org-wide or cross-repo queries." } }, @@ -2051,9 +1713,7 @@ }, { "type": "object", - "required": [ - "query" - ], + "required": ["query"], "properties": { "query": { "type": "string", @@ -2066,9 +1726,7 @@ }, "scope": { "type": "string", - "enum": [ - "none" - ], + "enum": ["none"], "description": "Scope for the search query. Set to 'none' to disable the automatic 'repo:owner/repo' scoping, enabling org-wide or cross-repo queries." } }, @@ -2086,9 +1744,7 @@ }, { "type": "boolean", - "enum": [ - true - ], + "enum": [true], "description": "Skip workflow execution if any CI checks on the target branch are currently failing. For pull_request events, checks the base branch. For other events, checks the current ref." }, { @@ -2184,15 +1840,7 @@ "oneOf": [ { "type": "string", - "enum": [ - "admin", - "maintainer", - "maintain", - "write", - "triage", - "read", - "all" - ], + "enum": ["admin", "maintainer", "maintain", "write", "triage", "read", "all"], "description": "Single repository permission level that can trigger the workflow. Use 'all' to allow any authenticated user (\u26a0\ufe0f disables permission checking entirely - use with caution)" }, { @@ -2200,14 +1848,7 @@ "description": "List of repository permission levels that can trigger the workflow. Permission checks are automatically applied to potentially unsafe triggers.", "items": { "type": "string", - "enum": [ - "admin", - "maintainer", - "maintain", - "write", - "triage", - "read" - ], + "enum": ["admin", "maintainer", "maintain", "write", "triage", "read"], "description": "Repository permission level: 'admin' (full access), 'maintainer'/'maintain' (repository management), 'write' (push access), 'triage' (issue management), 'read' (read-only access)" }, "minItems": 1, @@ -2254,24 +1895,11 @@ "oneOf": [ { "type": "string", - "enum": [ - "+1", - "-1", - "laugh", - "confused", - "heart", - "hooray", - "rocket", - "eyes", - "none" - ] + "enum": ["+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", "eyes", "none"] }, { "type": "integer", - "enum": [ - 1, - -1 - ], + "enum": [1, -1], "description": "YAML parses +1 and -1 without quotes as integers. These are converted to +1 and -1 strings respectively." }, { @@ -2282,24 +1910,11 @@ "oneOf": [ { "type": "string", - "enum": [ - "+1", - "-1", - "laugh", - "confused", - "heart", - "hooray", - "rocket", - "eyes", - "none" - ] + "enum": ["+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", "eyes", "none"] }, { "type": "integer", - "enum": [ - 1, - -1 - ], + "enum": [1, -1], "description": "YAML parses +1 and -1 without quotes as integers. These are converted to +1 and -1 strings respectively." } ], @@ -2386,9 +2001,7 @@ "github-token": { "type": "string", "description": "Custom GitHub token for pre-activation reactions, activation status comments, and skip-if search queries. When specified, overrides the default GITHUB_TOKEN for these operations.", - "examples": [ - "${{ secrets.MY_GITHUB_TOKEN }}" - ] + "examples": ["${{ secrets.MY_GITHUB_TOKEN }}"] }, "github-app": { "$ref": "#/$defs/github_app", @@ -2410,11 +2023,7 @@ "additionalItems": false, "uniqueItems": true, "default": [], - "examples": [ - [ - "secrets_fetcher" - ] - ] + "examples": [["secrets_fetcher"]] }, "steps": { "type": "array", @@ -2526,99 +2135,51 @@ "properties": { "actions": { "type": "string", - "enum": [ - "read", - "write", - "none" - ] + "enum": ["read", "write", "none"] }, "checks": { "type": "string", - "enum": [ - "read", - "write", - "none" - ] + "enum": ["read", "write", "none"] }, "contents": { "type": "string", - "enum": [ - "read", - "write", - "none" - ] + "enum": ["read", "write", "none"] }, "deployments": { "type": "string", - "enum": [ - "read", - "write", - "none" - ] + "enum": ["read", "write", "none"] }, "discussions": { "type": "string", - "enum": [ - "read", - "write", - "none" - ] + "enum": ["read", "write", "none"] }, "issues": { "type": "string", - "enum": [ - "read", - "write", - "none" - ] + "enum": ["read", "write", "none"] }, "packages": { "type": "string", - "enum": [ - "read", - "write", - "none" - ] + "enum": ["read", "write", "none"] }, "pages": { "type": "string", - "enum": [ - "read", - "write", - "none" - ] + "enum": ["read", "write", "none"] }, "pull-requests": { "type": "string", - "enum": [ - "read", - "write", - "none" - ] + "enum": ["read", "write", "none"] }, "repository-projects": { "type": "string", - "enum": [ - "read", - "write", - "none" - ] + "enum": ["read", "write", "none"] }, "security-events": { "type": "string", - "enum": [ - "read", - "write", - "none" - ] + "enum": ["read", "write", "none"] }, "statuses": { "type": "string", - "enum": [ - "read", - "write", - "none" - ] + "enum": ["read", "write", "none"] } }, "additionalProperties": false @@ -2661,37 +2222,25 @@ { "command": { "name": "mergefest", - "events": [ - "pull_request_comment" - ] + "events": ["pull_request_comment"] } }, { "workflow_run": { - "workflows": [ - "Dev" - ], - "types": [ - "completed" - ], - "branches": [ - "copilot/**" - ] + "workflows": ["Dev"], + "types": ["completed"], + "branches": ["copilot/**"] } }, { "pull_request": { - "types": [ - "ready_for_review" - ] + "types": ["ready_for_review"] }, "workflow_dispatch": null }, { "push": { - "branches": [ - "main" - ] + "branches": ["main"] } } ] @@ -2718,10 +2267,7 @@ "oneOf": [ { "type": "string", - "enum": [ - "read-all", - "write-all" - ], + "enum": ["read-all", "write-all"], "description": "Simple permissions string: 'read-all' (all read permissions) or 'write-all' (all write permissions)" }, { @@ -2732,10 +2278,7 @@ "run-name": { "type": "string", "description": "Custom name for workflow runs that appears in the GitHub Actions interface (supports GitHub expressions like ${{ github.event.issue.title }})", - "examples": [ - "Deploy to ${{ github.event.inputs.environment }}", - "Build #${{ github.run_number }}" - ] + "examples": ["Deploy to ${{ github.event.inputs.environment }}", "Build #${{ github.run_number }}"] }, "jobs": { "type": "object", @@ -2778,14 +2321,10 @@ "additionalProperties": false, "oneOf": [ { - "required": [ - "uses" - ] + "required": ["uses"] }, { - "required": [ - "run" - ] + "required": ["run"] } ], "properties": { @@ -3005,9 +2544,7 @@ "description": "The URL to set as the environment URL in the deployment." } }, - "required": [ - "name" - ] + "required": ["name"] } ], "description": "The GitHub Actions environment this job references. When set, any protection rules for the environment must pass before the job runs. Use this to gate jobs on manual approval workflows." @@ -3120,26 +2657,17 @@ ], "examples": [ "ubuntu-latest", - [ - "ubuntu-latest", - "self-hosted" - ], + ["ubuntu-latest", "self-hosted"], { "group": "larger-runners", - "labels": [ - "ubuntu-latest-8-cores" - ] + "labels": ["ubuntu-latest-8-cores"] } ] }, "runs-on-slim": { "type": "string", "description": "Runner for all framework/generated jobs (activation, pre-activation, safe-outputs, unlock, APM, etc.). Provides a compile-stable override for generated job runners without requiring a safe-outputs section. Overridden by safe-outputs.runs-on when both are set. Defaults to 'ubuntu-slim'. Use this when your infrastructure does not provide the default runner or when you need consistent runner selection across all jobs.", - "examples": [ - "self-hosted", - "ubuntu-latest", - "ubuntu-22.04" - ] + "examples": ["self-hosted", "ubuntu-latest", "ubuntu-22.04"] }, "timeout-minutes": { "description": "Workflow timeout in minutes (GitHub Actions standard field). Defaults to 20 minutes for agentic workflows. Has sensible defaults and can typically be omitted. Custom runners support longer timeouts beyond the GitHub-hosted runner limit. Supports GitHub Actions expressions (e.g. '${{ inputs.timeout }}') for reusable workflow_call workflows.", @@ -3147,11 +2675,7 @@ { "type": "integer", "minimum": 1, - "examples": [ - 5, - 10, - 30 - ] + "examples": [5, 10, 30] }, { "type": "string", @@ -3166,10 +2690,7 @@ { "type": "string", "description": "Simple concurrency group name to prevent multiple runs in the same group. Use expressions like '${{ github.workflow }}' for per-workflow isolation or '${{ github.ref }}' for per-branch isolation. Agentic workflows automatically generate enhanced concurrency policies using 'gh-aw-{engine-id}' as the default group to limit concurrent AI workloads across all workflows using the same engine.", - "examples": [ - "my-workflow-group", - "workflow-${{ github.ref }}" - ] + "examples": ["my-workflow-group", "workflow-${{ github.ref }}"] }, { "type": "object", @@ -3186,20 +2707,13 @@ }, "queue": { "type": "string", - "enum": [ - "single", - "max" - ], + "enum": ["single", "max"], "description": "Pending run queue behavior for this concurrency group. 'single' (default) allows one pending run and replaces older pending runs. 'max' allows up to 100 pending runs in FIFO order." }, "job-discriminator": { "type": "string", "description": "Additional discriminator expression appended to compiler-generated job-level concurrency groups (agent, output jobs). Use this when multiple workflow instances are dispatched concurrently with different inputs (fan-out pattern) to prevent job-level concurrency groups from colliding. For example, '${{ inputs.finding_id }}' ensures each dispatched run gets a unique job-level group. Supports GitHub Actions expressions. This field is stripped from the compiled lock file (it is a gh-aw extension, not a GitHub Actions field).", - "examples": [ - "${{ inputs.finding_id }}", - "${{ inputs.item_id }}", - "${{ github.run_id }}" - ] + "examples": ["${{ inputs.finding_id }}", "${{ inputs.item_id }}", "${{ github.run_id }}"] } }, "required": [], @@ -3251,9 +2765,7 @@ "inline-sub-agents": { "type": "boolean", "description": "Deprecated switch for inline sub-agent support. Inline sub-agents are enabled by default. Setting this to false is not supported and causes a compilation error.", - "examples": [ - true - ] + "examples": [true] }, "features": { "description": "Feature flags and configuration options for experimental or optional features in the workflow. Each feature can be a boolean flag or a string value. The 'action-tag' feature (string) specifies the tag or SHA to use when referencing actions/setup in compiled workflows (for testing purposes only).", @@ -3282,13 +2794,8 @@ }, "examples": [ { - "sonnet": [ - "mygateway/*sonnet-v3*" - ], - "": [ - "sonnet", - "gpt-5-codex" - ] + "sonnet": ["mygateway/*sonnet-v3*"], + "": ["sonnet", "gpt-5-codex"] } ] }, @@ -3319,9 +2826,7 @@ }, { "type": "object", - "required": [ - "variants" - ], + "required": ["variants"], "properties": { "variants": { "type": "array", @@ -3377,10 +2882,7 @@ "type": "array", "items": { "type": "object", - "required": [ - "name", - "threshold" - ], + "required": ["name", "threshold"], "properties": { "name": { "type": "string", @@ -3404,12 +2906,7 @@ }, "analysis_type": { "type": "string", - "enum": [ - "t_test", - "mann_whitney", - "proportion_test", - "bayesian_ab" - ], + "enum": ["t_test", "mann_whitney", "proportion_test", "bayesian_ab"], "description": "Statistical test to use for automated analysis by the reporting workflow. Valid values: t_test (Welch's two-sample t-test), mann_whitney (non-parametric rank test), proportion_test (two-proportion z-test), bayesian_ab (Bayesian A/B test)." }, "tags": { @@ -3444,24 +2941,15 @@ }, "examples": [ { - "feature1": [ - "A", - "B" - ] + "feature1": ["A", "B"] }, { "prompt_style": { - "variants": [ - "concise", - "verbose" - ], + "variants": ["concise", "verbose"], "description": "Test whether concise vs verbose prompts reduce token consumption", "hypothesis": "H0: no change in tokens. H1: concise reduces by >=15%", "metric": "effective_tokens", - "secondary_metrics": [ - "duration_ms", - "discussion_word_count" - ], + "secondary_metrics": ["duration_ms", "discussion_word_count"], "guardrail_metrics": [ { "name": "success_rate", @@ -3473,35 +2961,23 @@ } ], "min_samples": 25, - "weight": [ - 50, - 50 - ], + "weight": [50, 50], "issue": 1234, "start_date": "2026-05-01", "end_date": "2026-06-15", "analysis_type": "t_test", - "tags": [ - "cost", - "prompting" - ], + "tags": ["cost", "prompting"], "notify": { "issue": 1234 } }, - "model_temp": [ - "low", - "high" - ] + "model_temp": ["low", "high"] } ], "properties": { "storage": { "type": "string", - "enum": [ - "cache", - "repo" - ], + "enum": ["cache", "repo"], "default": "repo", "description": "Storage backend for experiment state. 'repo' (default) persists state to a git branch named 'experiments/{sanitizedWorkflowID}' (workflow ID lowercased with hyphens removed, e.g. 'my-workflow' -> 'experiments/myworkflow') for durability across cache evictions. 'cache' uses GitHub Actions cache (legacy behaviour). Repo storage is recommended because experiment data is valuable and more durable than cache." } @@ -3510,16 +2986,12 @@ "infer": { "type": "boolean", "description": "DEPRECATED: Use 'disable-model-invocation' instead. Controls whether the custom agent should infer additional context from the conversation. This field is maintained for backward compatibility with existing custom agent files.", - "examples": [ - false - ] + "examples": [false] }, "disable-model-invocation": { "type": "boolean", "description": "Controls whether the custom agent should disable model invocation. When set to true, the agent will not make additional model calls. This is the preferred field name for custom agent files (replaces the deprecated 'infer' field).", - "examples": [ - true - ] + "examples": [true] }, "secrets": { "description": "Secret values passed to workflow execution. Secrets can be defined as simple strings (GitHub Actions expressions) or objects with 'value' and 'description' properties. Typically used to provide secrets to MCP servers or custom engines. Note: For passing secrets to reusable workflows, use the jobs..secrets field instead.", @@ -3533,9 +3005,7 @@ { "type": "object", "description": "Secret with metadata", - "required": [ - "value" - ], + "required": ["value"], "properties": { "value": { "type": "string", @@ -3587,9 +3057,7 @@ "description": "A deployment URL" } }, - "required": [ - "name" - ], + "required": ["name"], "additionalProperties": false } ] @@ -3657,9 +3125,7 @@ "description": "Additional Docker container options" } }, - "required": [ - "image" - ], + "required": ["image"], "additionalProperties": false } ] @@ -3729,9 +3195,7 @@ "description": "Additional Docker container options" } }, - "required": [ - "image" - ], + "required": ["image"], "additionalProperties": false } ] @@ -3743,26 +3207,16 @@ "examples": [ "defaults", { - "allowed": [ - "defaults", - "github" - ] + "allowed": ["defaults", "github"] }, { - "allowed": [ - "defaults", - "python", - "node", - "*.example.com" - ] + "allowed": ["defaults", "python", "node", "*.example.com"] } ], "oneOf": [ { "type": "string", - "enum": [ - "defaults" - ], + "enum": ["defaults"], "description": "Use default network permissions (basic infrastructure: certificates, JSON schema, Ubuntu, etc.)" }, { @@ -3797,10 +3251,7 @@ "oneOf": [ { "type": "string", - "enum": [ - "default", - "awf" - ], + "enum": ["default", "awf"], "description": "String format for sandbox type: 'default' for no sandbox, 'awf' for Agent Workflow Firewall. Note: Legacy 'srt' and 'sandbox-runtime' values are automatically migrated to 'awf'" }, { @@ -3809,10 +3260,7 @@ "properties": { "type": { "type": "string", - "enum": [ - "default", - "awf" - ], + "enum": ["default", "awf"], "description": "Legacy sandbox type field (use agent instead). Note: Legacy 'srt' and 'sandbox-runtime' values are automatically migrated to 'awf'" }, "agent": { @@ -3826,9 +3274,7 @@ }, { "type": "string", - "enum": [ - "awf" - ], + "enum": ["awf"], "description": "Sandbox type: 'awf' for Agent Workflow Firewall" }, { @@ -3837,16 +3283,12 @@ "properties": { "id": { "type": "string", - "enum": [ - "awf" - ], + "enum": ["awf"], "description": "Agent identifier (replaces 'type' field in new format): 'awf' for Agent Workflow Firewall" }, "type": { "type": "string", - "enum": [ - "awf" - ], + "enum": ["awf"], "description": "Legacy: Sandbox type to use (use 'id' instead)" }, "version": { @@ -3882,22 +3324,13 @@ "pattern": "^[^:]+:[^:]+:(ro|rw)$", "description": "Mount specification in format 'source:destination:mode'" }, - "examples": [ - [ - "/host/data:/data:ro", - "/usr/local/bin/custom-tool:/usr/local/bin/custom-tool:ro" - ] - ] + "examples": [["/host/data:/data:ro", "/usr/local/bin/custom-tool:/usr/local/bin/custom-tool:ro"]] }, "memory": { "type": "string", "description": "Memory limit for the AWF container (e.g., '4g', '8g'). Passed as --memory-limit to AWF. If not specified, AWF's default memory limit is used.", "pattern": "^[0-9]+(b|k|m|g|kb|mb|gb|B|K|M|G|KB|MB|GB)$", - "examples": [ - "4g", - "8g", - "512m" - ] + "examples": ["4g", "8g", "512m"] }, "config": { "type": "object", @@ -4013,26 +3446,16 @@ "description": "Container image for the MCP gateway executable (required)" }, "version": { - "type": [ - "string", - "number" - ], + "type": ["string", "number"], "x-internal": true, "description": "Optional version/tag for the container image (e.g., 'latest', 'v1.0.0')", - "examples": [ - "latest", - "v1.0.0" - ] + "examples": ["latest", "v1.0.0"] }, "entrypoint": { "type": "string", "x-internal": true, "description": "Optional custom entrypoint for the MCP gateway container. Overrides the container's default entrypoint.", - "examples": [ - "/bin/bash", - "/custom/start.sh", - "/usr/bin/env" - ] + "examples": ["/bin/bash", "/custom/start.sh", "/usr/bin/env"] }, "args": { "type": "array", @@ -4058,12 +3481,7 @@ "pattern": "^[^:]+:[^:]+:(ro|rw)$", "description": "Mount specification in format 'source:destination:mode'" }, - "examples": [ - [ - "/host/data:/container/data:ro", - "/host/config:/container/config:rw" - ] - ] + "examples": [["/host/data:/container/data:ro", "/host/config:/container/config:rw"]] }, "env": { "type": "object", @@ -4088,22 +3506,14 @@ }, "domain": { "type": "string", - "enum": [ - "localhost", - "host.docker.internal" - ], + "enum": ["localhost", "host.docker.internal"], "description": "Gateway domain for URL generation (default: 'host.docker.internal' when agent is enabled, 'localhost' when disabled)" }, "keepalive-interval": { "type": "integer", "description": "Keepalive ping interval in seconds for HTTP MCP backends. Sends periodic pings to prevent session expiry during long-running agent tasks. Set to -1 to disable keepalive pings. Unset or 0 uses the gateway default (1500 seconds = 25 minutes).", "minimum": -1, - "examples": [ - -1, - 300, - 600, - 1500 - ] + "examples": [-1, 300, 600, 1500] } }, "additionalProperties": false @@ -4136,10 +3546,7 @@ "if": { "type": "string", "description": "Conditional execution expression", - "examples": [ - "${{ github.event.workflow_run.event == 'workflow_dispatch' }}", - "${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}" - ] + "examples": ["${{ github.event.workflow_run.event == 'workflow_dispatch' }}", "${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}"] }, "steps": { "description": "Custom workflow steps", @@ -4320,9 +3727,7 @@ { "type": "integer", "not": { - "enum": [ - 0 - ] + "enum": [0] }, "description": "Maximum effective-token (ET) budget for AWF API proxy enforcement. Use a negative value to disable budget enforcement and token steering." }, @@ -4373,10 +3778,7 @@ "filesystem": { "type": "stdio", "command": "npx", - "args": [ - "-y", - "@modelcontextprotocol/server-filesystem" - ] + "args": ["-y", "@modelcontextprotocol/server-filesystem"] } }, { @@ -4453,33 +3855,18 @@ }, "mode": { "type": "string", - "enum": [ - "gh-proxy", - "local", - "remote" - ], + "enum": ["gh-proxy", "local", "remote"], "description": "GitHub access mode. Prefer 'gh-proxy' for better performance (uses pre-authenticated gh CLI prompt guidance). Legacy MCP transport values 'local' and 'remote' are accepted for backward compatibility and use GitHub MCP server prompt guidance." }, "type": { "type": "string", - "enum": [ - "local", - "remote" - ], + "enum": ["local", "remote"], "description": "GitHub MCP transport type: 'local' (Docker-based, default) or 'remote' (hosted at api.githubcopilot.com)" }, "version": { - "type": [ - "string", - "number" - ], + "type": ["string", "number"], "description": "Optional version specification for the GitHub MCP server (used with 'local' type). Can be a string (e.g., 'v1.0.0', 'latest') or number (e.g., 20, 3.11). Numeric values are automatically converted to strings at runtime.", - "examples": [ - "v1.0.0", - "latest", - 20, - 3.11 - ] + "examples": ["v1.0.0", "latest", 20, 3.11] }, "args": { "type": "array", @@ -4552,15 +3939,7 @@ "pattern": "^[^:]+:[^:]+(:(ro|rw))?$", "description": "Mount specification in format 'host:container:mode'" }, - "examples": [ - [ - "/data:/data:ro", - "/tmp:/tmp:rw" - ], - [ - "/opt:/opt:ro" - ] - ] + "examples": [["/data:/data:ro", "/tmp:/tmp:rw"], ["/opt:/opt:ro"]] }, "allowed-repos": { "description": "Guard policy: repository access configuration. Restricts which repositories the agent can access. Use 'all' to allow all repos, 'public' for public repositories only, '${{ github.repository }}' for the current repository, or an array of repository patterns (e.g., 'owner/repo', 'owner/*', 'owner/prefix*').", @@ -4604,12 +3983,7 @@ "min-integrity": { "type": "string", "description": "Guard policy: minimum required integrity level for repository access. Restricts the agent to users with at least the specified permission level.", - "enum": [ - "none", - "unapproved", - "approved", - "merged" - ] + "enum": ["none", "unapproved", "approved", "merged"] }, "blocked-users": { "description": "Guard policy: GitHub usernames whose content is unconditionally blocked. Items from these users receive 'blocked' integrity (below 'none') and are always denied, even when 'min-integrity' is 'none'. Cannot be overridden by 'approval-labels'. Requires 'min-integrity' to be set. Accepts an array of usernames, a comma-separated string, a newline-separated string, or a GitHub Actions expression (e.g. '${{ vars.BLOCKED_USERS }}').", @@ -4671,27 +4045,10 @@ "items": { "type": "string", "description": "GitHub ReactionContent enum value", - "enum": [ - "THUMBS_UP", - "THUMBS_DOWN", - "HEART", - "HOORAY", - "CONFUSED", - "ROCKET", - "EYES", - "LAUGH" - ] + "enum": ["THUMBS_UP", "THUMBS_DOWN", "HEART", "HOORAY", "CONFUSED", "ROCKET", "EYES", "LAUGH"] }, - "default": [ - "THUMBS_UP", - "HEART" - ], - "examples": [ - [ - "THUMBS_UP", - "HEART" - ] - ] + "default": ["THUMBS_UP", "HEART"], + "examples": [["THUMBS_UP", "HEART"]] }, "disapproval-reactions": { "type": "array", @@ -4699,47 +4056,21 @@ "items": { "type": "string", "description": "GitHub ReactionContent enum value", - "enum": [ - "THUMBS_UP", - "THUMBS_DOWN", - "HEART", - "HOORAY", - "CONFUSED", - "ROCKET", - "EYES", - "LAUGH" - ] + "enum": ["THUMBS_UP", "THUMBS_DOWN", "HEART", "HOORAY", "CONFUSED", "ROCKET", "EYES", "LAUGH"] }, - "default": [ - "THUMBS_DOWN", - "CONFUSED" - ], - "examples": [ - [ - "THUMBS_DOWN", - "CONFUSED" - ] - ] + "default": ["THUMBS_DOWN", "CONFUSED"], + "examples": [["THUMBS_DOWN", "CONFUSED"]] }, "disapproval-integrity": { "type": "string", "description": "Guard policy: integrity level assigned when a disapproval reaction is present. Optional, defaults to 'none'. Requires the 'integrity-reactions' feature flag and MCPG >= v0.2.18.", - "enum": [ - "none", - "unapproved", - "approved", - "merged" - ], + "enum": ["none", "unapproved", "approved", "merged"], "default": "none" }, "endorser-min-integrity": { "type": "string", "description": "Guard policy: minimum integrity level required for an endorser (reactor) to promote content. Optional, defaults to 'approved'. Requires the 'integrity-reactions' feature flag and MCPG >= v0.2.18.", - "enum": [ - "unapproved", - "approved", - "merged" - ], + "enum": ["unapproved", "approved", "merged"], "default": "approved" }, "github-app": { @@ -4750,30 +4081,16 @@ "additionalProperties": false, "examples": [ { - "toolsets": [ - "pull_requests", - "actions", - "repos" - ] + "toolsets": ["pull_requests", "actions", "repos"] }, { - "allowed": [ - "search_pull_requests", - "pull_request_read", - "list_pull_requests", - "get_file_contents", - "list_commits", - "get_commit" - ] + "allowed": ["search_pull_requests", "pull_request_read", "list_pull_requests", "get_file_contents", "list_commits", "get_commit"] }, { "read-only": true }, { - "toolsets": [ - "pull_requests", - "repos" - ] + "toolsets": ["pull_requests", "repos"] } ] } @@ -4781,25 +4098,14 @@ "examples": [ null, { - "toolsets": [ - "pull_requests", - "actions", - "repos" - ] + "toolsets": ["pull_requests", "actions", "repos"] }, { - "allowed": [ - "search_pull_requests", - "pull_request_read", - "get_file_contents" - ] + "allowed": ["search_pull_requests", "pull_request_read", "get_file_contents"] }, { "read-only": true, - "toolsets": [ - "repos", - "issues" - ] + "toolsets": ["repos", "issues"] }, false ] @@ -4826,36 +4132,10 @@ ], "examples": [ true, - [ - "git fetch", - "git checkout", - "git status", - "git diff", - "git log", - "make recompile", - "make fmt", - "make lint", - "make test-unit", - "cat", - "echo", - "ls" - ], - [ - "echo", - "ls", - "cat" - ], - [ - "gh pr list *", - "gh search prs *", - "jq *" - ], - [ - "date *", - "echo *", - "cat", - "ls" - ] + ["git fetch", "git checkout", "git status", "git diff", "git log", "make recompile", "make fmt", "make lint", "make test-unit", "cat", "echo", "ls"], + ["echo", "ls", "cat"], + ["gh pr list *", "gh search prs *", "jq *"], + ["date *", "echo *", "cat", "ls"] ] }, "web-fetch": { @@ -4932,15 +4212,9 @@ "description": "Playwright tool configuration with custom version and arguments", "properties": { "version": { - "type": [ - "string", - "number" - ], + "type": ["string", "number"], "description": "Optional version pin. In CLI mode (recommended): the @playwright/cli npm package version (e.g., '0.1.11'). In MCP mode (deprecated): the Playwright browser Docker image version (e.g., 'v1.56.1'). Omit to use the default version.", - "examples": [ - "0.1.11", - "v1.56.1" - ] + "examples": ["0.1.11", "v1.56.1"] }, "args": { "type": "array", @@ -4952,10 +4226,7 @@ "mode": { "type": "string", "description": "Integration mode: 'cli' (recommended) installs @playwright/cli via npm for token-efficient CLI invocations \u2014 use playwright-cli commands in bash and localhost to reach local servers; 'mcp' (deprecated) runs a Docker-based MCP server.", - "enum": [ - "cli", - "mcp" - ] + "enum": ["cli", "mcp"] } }, "additionalProperties": false @@ -4974,10 +4245,7 @@ "description": "Enable agentic-workflows tool with default settings (same as true)" } ], - "examples": [ - true, - null - ] + "examples": [true, null] }, "cache-memory": { "description": "Cache memory MCP configuration for persistent memory storage", @@ -5014,10 +4282,7 @@ }, "scope": { "type": "string", - "enum": [ - "workflow", - "repo" - ], + "enum": ["workflow", "repo"], "default": "workflow", "description": "Cache restore key scope: 'workflow' (default, only restores from same workflow) or 'repo' (restores from any workflow in the repository). Use 'repo' with caution as it allows cross-workflow cache sharing." }, @@ -5070,10 +4335,7 @@ }, "scope": { "type": "string", - "enum": [ - "workflow", - "repo" - ], + "enum": ["workflow", "repo"], "default": "workflow", "description": "Cache restore key scope: 'workflow' (default, only restores from same workflow) or 'repo' (restores from any workflow in the repository). Use 'repo' with caution as it allows cross-workflow cache sharing." }, @@ -5085,10 +4347,7 @@ "description": "List of allowed file extensions (e.g., [\".json\", \".txt\"]). Default: [\".json\", \".jsonl\", \".txt\", \".md\", \".csv\"]" } }, - "required": [ - "id", - "key" - ], + "required": ["id", "key"], "additionalProperties": false }, "minItems": 1, @@ -5179,10 +4438,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -5203,11 +4459,7 @@ { "type": "integer", "minimum": 1, - "examples": [ - 60, - 120, - 300 - ] + "examples": [60, 120, 300] }, { "type": "string", @@ -5222,11 +4474,7 @@ { "type": "integer", "minimum": 1, - "examples": [ - 30, - 60, - 120 - ] + "examples": [30, 60, 120] }, { "type": "string", @@ -5238,9 +4486,7 @@ "cli-proxy": { "type": "boolean", "description": "When true, each user-facing MCP server is mounted as a standalone CLI tool on PATH. The agent can then call MCP servers via shell commands (e.g. 'github issue_read --method get ...'). CLI-mounted servers remain in the MCP gateway config so their containers can start, and are removed only from the agent's final config during convert_gateway_config_*.sh processing. Default: false.", - "examples": [ - true - ] + "examples": [true] }, "serena": { "description": "REMOVED: Built-in support for Serena has been removed. Use the shared/mcp/serena.md workflow instead.", @@ -5523,25 +4769,17 @@ "description": "Optional custom name for the cache step (overrides auto-generated name)" } }, - "required": [ - "key", - "path" - ], + "required": ["key", "path"], "additionalProperties": false, "examples": [ { "key": "node-modules-${{ hashFiles('package-lock.json') }}", "path": "node_modules", - "restore-keys": [ - "node-modules-" - ] + "restore-keys": ["node-modules-"] }, { "key": "build-cache-${{ github.sha }}", - "path": [ - "dist", - ".cache" - ], + "path": ["dist", ".cache"], "restore-keys": "build-cache-", "fail-on-cache-miss": false } @@ -5606,10 +4844,7 @@ "description": "Optional custom name for the cache step (overrides auto-generated name)" } }, - "required": [ - "key", - "path" - ], + "required": ["key", "path"], "additionalProperties": false } } @@ -5623,18 +4858,13 @@ { "create-issue": { "title-prefix": "[AI] ", - "labels": [ - "automation", - "ai-generated" - ] + "labels": ["automation", "ai-generated"] } }, { "create-pull-request": { "title-prefix": "[Bot] ", - "labels": [ - "bot" - ] + "labels": ["bot"] } }, { @@ -5656,23 +4886,7 @@ "items": { "type": "string" }, - "examples": [ - [ - "repo" - ], - [ - "repo", - "octocat/hello-world" - ], - [ - "microsoft/vscode", - "microsoft/typescript" - ], - [ - "repo", - "${{ github.repository }}" - ] - ] + "examples": [["repo"], ["repo", "octocat/hello-world"], ["microsoft/vscode", "microsoft/typescript"], ["repo", "${{ github.repository }}"]] }, "create-issue": { "oneOf": [ @@ -5774,9 +4988,7 @@ }, { "type": "boolean", - "enum": [ - false - ], + "enum": [false], "description": "Set to false to explicitly disable expiration" } ], @@ -5815,43 +5027,28 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false, "examples": [ { "title-prefix": "[ca] ", - "labels": [ - "automation", - "dependencies" - ], + "labels": ["automation", "dependencies"], "assignees": "copilot" }, { "title-prefix": "[duplicate-code] ", - "labels": [ - "code-quality", - "automated-analysis" - ], + "labels": ["code-quality", "automated-analysis"], "assignees": "copilot" }, { - "allowed-repos": [ - "org/other-repo", - "org/another-repo" - ], + "allowed-repos": ["org/other-repo", "org/another-repo"], "title-prefix": "[cross-repo] " }, { "title-prefix": "[weekly-report] ", - "labels": [ - "report", - "automation" - ], + "labels": ["report", "automation"], "close-older-issues": true } ] @@ -5907,10 +5104,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -5965,10 +5159,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -5985,9 +5176,7 @@ { "type": "object", "description": "Configuration for managing GitHub Projects boards. Enable agents to add issues and pull requests to projects, update custom field values (status, priority, effort, dates), create project fields and views. By default it is update-only: if the project does not exist, the job fails with instructions to create it. To allow workflows to create missing projects, explicitly opt in via agent output field create_if_missing=true. Requires a Personal Access Token (PAT) or GitHub App token with Projects permissions (default GITHUB_TOKEN cannot be used). Agent output includes: project (full URL or temporary project ID like aw_XXXXXXXXXXXX or #aw_XXXXXXXXXXXX from create_project), content_type (issue|pull_request|draft_issue), content_number, fields, create_if_missing. For specialized operations, agent can also provide: operation (create_fields|create_view), field_definitions (array of field configs when operation=create_fields), view (view config object when operation=create_view).", - "required": [ - "project" - ], + "required": ["project"], "properties": { "max": { "description": "Maximum number of project operations to perform (default: 10). Each operation may add a project item, or update its fields. Supports integer or GitHub Actions expression (e.g. '${{ inputs.max }}').", @@ -6012,10 +5201,7 @@ "type": "string", "description": "Target project URL for update-project operations. This is required in the configuration for documentation purposes. Agent messages MUST explicitly include the project field in their output - the configured value is not used as a fallback. Must be a valid GitHub Projects v2 URL.", "pattern": "^https://github\\.com/(users|orgs)/([^/]+|<[A-Z_]+>)/projects/(\\d+|<[A-Z_]+>)$", - "examples": [ - "https://github.com/orgs/myorg/projects/123", - "https://github.com/users/username/projects/456" - ] + "examples": ["https://github.com/orgs/myorg/projects/123", "https://github.com/users/username/projects/456"] }, "target-repo": { "description": "Default repository in format 'owner/repo' for cross-repository content resolution. When specified, the agent can use 'target_repo' in agent output to resolve issues or PRs from this repository. Wildcards ('*') are not allowed. Supports GitHub Actions expression syntax (e.g., '${{ vars.TARGET_REPO }}').", @@ -6054,10 +5240,7 @@ "items": { "type": "object", "description": "View configuration for creating project views", - "required": [ - "name", - "layout" - ], + "required": ["name", "layout"], "properties": { "name": { "type": "string", @@ -6065,11 +5248,7 @@ }, "layout": { "type": "string", - "enum": [ - "table", - "board", - "roadmap" - ], + "enum": ["table", "board", "roadmap"], "description": "The layout type of the view" }, "filter": { @@ -6096,10 +5275,7 @@ "description": "Optional array of project custom fields to create up-front.", "items": { "type": "object", - "required": [ - "name", - "data-type" - ], + "required": ["name", "data-type"], "properties": { "name": { "type": "string", @@ -6107,13 +5283,7 @@ }, "data-type": { "type": "string", - "enum": [ - "DATE", - "TEXT", - "NUMBER", - "SINGLE_SELECT", - "ITERATION" - ], + "enum": ["DATE", "TEXT", "NUMBER", "SINGLE_SELECT", "ITERATION"], "description": "The GitHub Projects v2 custom field type" }, "options": { @@ -6130,10 +5300,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false, @@ -6193,10 +5360,7 @@ "items": { "type": "object", "description": "View configuration for creating project views", - "required": [ - "name", - "layout" - ], + "required": ["name", "layout"], "properties": { "name": { "type": "string", @@ -6204,11 +5368,7 @@ }, "layout": { "type": "string", - "enum": [ - "table", - "board", - "roadmap" - ], + "enum": ["table", "board", "roadmap"], "description": "The layout type of the view" }, "filter": { @@ -6235,10 +5395,7 @@ "description": "Optional array of project custom fields to create automatically after project creation.", "items": { "type": "object", - "required": [ - "name", - "data-type" - ], + "required": ["name", "data-type"], "properties": { "name": { "type": "string", @@ -6246,13 +5403,7 @@ }, "data-type": { "type": "string", - "enum": [ - "DATE", - "TEXT", - "NUMBER", - "SINGLE_SELECT", - "ITERATION" - ], + "enum": ["DATE", "TEXT", "NUMBER", "SINGLE_SELECT", "ITERATION"], "description": "The GitHub Projects v2 custom field type" }, "options": { @@ -6269,10 +5420,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -6292,9 +5440,7 @@ { "type": "object", "description": "Configuration for posting status updates to GitHub Projects. Status updates provide stakeholder communication about project progress, health, and timeline. Each update appears in the project's Updates tab and creates a historical record. Requires a Personal Access Token (PAT) or GitHub App token with Projects read & write permission (default GITHUB_TOKEN cannot be used). Typically used by scheduled workflows or orchestrators to post regular progress summaries with status indicators (on-track, at-risk, off-track, complete, inactive), dates, and progress details.", - "required": [ - "project" - ], + "required": ["project"], "properties": { "max": { "description": "Maximum number of status updates to create (default: 1). Typically 1 per orchestrator run. Supports integer or GitHub Actions expression (e.g. '${{ inputs.max }}').", @@ -6319,18 +5465,12 @@ "type": "string", "description": "Target project URL for status update operations. This is required in the configuration for documentation purposes. Agent messages MUST explicitly include the project field in their output - the configured value is not used as a fallback. Must be a valid GitHub Projects v2 URL.", "pattern": "^https://github\\.com/(users|orgs)/([^/]+|<[A-Z_]+>)/projects/(\\d+|<[A-Z_]+>)$", - "examples": [ - "https://github.com/orgs/myorg/projects/123", - "https://github.com/users/username/projects/456" - ] + "examples": ["https://github.com/orgs/myorg/projects/123", "https://github.com/users/username/projects/456"] }, "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false, @@ -6362,16 +5502,9 @@ "description": "Optional prefix for the discussion title" }, "category": { - "type": [ - "string", - "number" - ], + "type": ["string", "number"], "description": "Optional discussion category. Can be a category ID (string or numeric value), category name, or category slug/route. If not specified, uses the first available category. Matched first against category IDs, then against category names, then against category slugs. Numeric values are automatically converted to strings at runtime.", - "examples": [ - "General", - "audits", - 123456789 - ] + "examples": ["General", "audits", 123456789] }, "min-body-length": { "type": "integer", @@ -6453,9 +5586,7 @@ }, { "type": "boolean", - "enum": [ - false - ], + "enum": [false], "description": "Set to false to explicitly disable expiration" } ], @@ -6469,10 +5600,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false, @@ -6494,17 +5622,12 @@ "close-older-discussions": true }, { - "labels": [ - "weekly-report", - "automation" - ], + "labels": ["weekly-report", "automation"], "category": "reports", "close-older-discussions": true }, { - "allowed-repos": [ - "org/other-repo" - ], + "allowed-repos": ["org/other-repo"], "category": "General" } ] @@ -6563,10 +5686,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false, @@ -6575,10 +5695,7 @@ "required-category": "Ideas" }, { - "required-labels": [ - "resolved", - "completed" - ], + "required-labels": ["resolved", "completed"], "max": 1 } ] @@ -6646,10 +5763,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] }, "github-token": { "$ref": "#/$defs/github_token", @@ -6715,18 +5829,11 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] }, "state-reason": { "type": "string", - "enum": [ - "completed", - "not_planned", - "duplicate" - ], + "enum": ["completed", "not_planned", "duplicate"], "default": "completed", "description": "Reason for closing the issue (default: completed)" } @@ -6737,10 +5844,7 @@ "required-title-prefix": "[refactor] " }, { - "required-labels": [ - "automated", - "stale" - ], + "required-labels": ["automated", "stale"], "max": 10 } ] @@ -6799,10 +5903,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false, @@ -6811,10 +5912,7 @@ "required-title-prefix": "[bot] " }, { - "required-labels": [ - "automated", - "outdated" - ], + "required-labels": ["automated", "outdated"], "max": 5 } ] @@ -6873,10 +5971,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false, @@ -6885,10 +5980,7 @@ "required-title-prefix": "[bot] " }, { - "required-labels": [ - "automated", - "ready" - ], + "required-labels": ["automated", "ready"], "max": 1 } ] @@ -6955,14 +6047,7 @@ "description": "List of allowed reasons for hiding older comments when hide-older-comments is enabled. Default: all reasons allowed (spam, abuse, off_topic, outdated, resolved, low_quality).", "items": { "type": "string", - "enum": [ - "spam", - "abuse", - "off_topic", - "outdated", - "resolved", - "low_quality" - ] + "enum": ["spam", "abuse", "off_topic", "outdated", "resolved", "low_quality"] } }, "discussions": { @@ -6989,10 +6074,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false, @@ -7133,11 +6215,7 @@ }, "if-no-changes": { "type": "string", - "enum": [ - "warn", - "error", - "ignore" - ], + "enum": ["warn", "error", "ignore"], "description": "Behavior when no changes to push: 'warn' (default - log warning but succeed), 'error' (fail the action), or 'ignore' (silent success)" }, "allow-empty": { @@ -7237,11 +6315,7 @@ "oneOf": [ { "type": "string", - "enum": [ - "blocked", - "allowed", - "fallback-to-issue" - ], + "enum": ["blocked", "allowed", "fallback-to-issue"], "description": "Controls protected-file protection. blocked (default): hard-block any patch that modifies package manifests (e.g. package.json, go.mod), engine instruction files (e.g. AGENTS.md, CLAUDE.md) or .github/ files. allowed: allow all changes. fallback-to-issue: push the branch but create a review issue instead of a PR, so a human can review the manifest changes before merging.", "default": "blocked" }, @@ -7257,11 +6331,7 @@ "oneOf": [ { "type": "string", - "enum": [ - "blocked", - "allowed", - "fallback-to-issue" - ], + "enum": ["blocked", "allowed", "fallback-to-issue"], "description": "Protection policy. blocked (default): hard-block any patch that modifies protected files. allowed: allow all changes. fallback-to-issue: push the branch but create a review issue instead of a PR.", "default": "blocked" }, @@ -7278,15 +6348,7 @@ "type": "string" }, "description": "List of filenames or path prefixes to remove from the default protected-file set. Items are matched by basename (e.g. \"AGENTS.md\") or path prefix (e.g. \".agents/\"). Use this to allow the agent to modify specific files that are otherwise blocked by default.", - "examples": [ - [ - "AGENTS.md" - ], - [ - "AGENTS.md", - ".agents/" - ] - ] + "examples": [["AGENTS.md"], ["AGENTS.md", ".agents/"]] } }, "additionalProperties": false, @@ -7323,10 +6385,7 @@ "oneOf": [ { "type": "string", - "enum": [ - "am", - "bundle" - ], + "enum": ["am", "bundle"], "default": "bundle", "description": "Transport format for packaging changes. \"bundle\" (default) uses git bundle, which preserves merge commit topology, per-commit authorship, and merge-resolution-only content. \"am\" uses git format-patch/git am." }, @@ -7346,38 +6405,26 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] }, "allow-workflows": { "type": "boolean", "description": "When true, adds workflows: write to the GitHub App token permissions. Required when allowed-files targets .github/workflows/ paths. Requires safe-outputs.github-app to be configured because the workflows permission is a GitHub App-only permission and cannot be granted via GITHUB_TOKEN.", "default": false, - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false, "examples": [ { "title-prefix": "[docs] ", - "labels": [ - "documentation", - "automation" - ], + "labels": ["documentation", "automation"], "reviewers": "copilot", "draft": false }, { "title-prefix": "[security-fix] ", - "labels": [ - "security", - "automated-fix" - ], + "labels": ["security", "automated-fix"], "reviewers": "copilot" } ] @@ -7413,10 +6460,7 @@ "side": { "type": "string", "description": "Side of the diff for comments: 'LEFT' or 'RIGHT' (default: 'RIGHT')", - "enum": [ - "LEFT", - "RIGHT" - ] + "enum": ["LEFT", "RIGHT"] }, "target": { "type": "string", @@ -7440,10 +6484,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -7484,11 +6525,7 @@ }, { "type": "string", - "enum": [ - "always", - "none", - "if-body" - ], + "enum": ["always", "none", "if-body"], "description": "Controls when AI-generated footer is added to the review body: 'always' (default), 'none' (never), or 'if-body' (only when review has body text)." } ], @@ -7513,11 +6550,7 @@ "type": "array", "items": { "type": "string", - "enum": [ - "APPROVE", - "COMMENT", - "REQUEST_CHANGES" - ] + "enum": ["APPROVE", "COMMENT", "REQUEST_CHANGES"] }, "description": "Optional list of allowed review event types. If omitted, all event types (APPROVE, COMMENT, REQUEST_CHANGES) are allowed. Use this to restrict the agent to specific event types, e.g. [COMMENT, REQUEST_CHANGES] to prevent approvals.", "minItems": 1 @@ -7533,10 +6566,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -7596,10 +6626,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -7639,10 +6666,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -7696,10 +6720,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -7738,10 +6759,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -7817,10 +6835,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -7892,10 +6907,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -7967,10 +6979,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -8022,10 +7031,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -8081,10 +7087,7 @@ ] }, "target": { - "type": [ - "string", - "number" - ], + "type": ["string", "number"], "description": "Target issue/PR to assign agents to. Use 'triggering' (default) for the triggering issue/PR, '*' to require explicit issue_number/pull_number, or a specific issue/PR number. With 'triggering', auto-resolves from github.event.issue.number or github.event.pull_request.number." }, "target-repo": { @@ -8118,10 +7121,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -8168,10 +7168,7 @@ ] }, "target": { - "type": [ - "string", - "number" - ], + "type": ["string", "number"], "description": "Target issue to assign users to. Use 'triggering' (default) for the triggering issue, '*' to allow any issue, or a specific issue number." }, "target-repo": { @@ -8197,10 +7194,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -8247,10 +7241,7 @@ ] }, "target": { - "type": [ - "string", - "number" - ], + "type": ["string", "number"], "description": "Target issue to unassign users from. Use 'triggering' (default) for the triggering issue, '*' to allow any issue, or a specific issue number." }, "target-repo": { @@ -8271,10 +7262,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -8344,10 +7332,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -8374,10 +7359,7 @@ "description": "Allow updating issue title - presence of key indicates field can be updated" }, "body": { - "type": [ - "boolean", - "null" - ], + "type": ["boolean", "null"], "description": "Allow updating issue body. Set to true to enable body updates, false to disable. For backward compatibility, null (body:) also enables body updates.", "default": true }, @@ -8423,10 +7405,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -8463,11 +7442,7 @@ "operation": { "type": "string", "description": "Default operation for body updates: 'append' (add to end), 'prepend' (add to start), or 'replace' (overwrite completely). Defaults to 'replace' if not specified.", - "enum": [ - "append", - "prepend", - "replace" - ] + "enum": ["append", "prepend", "replace"] }, "footer": { "type": "boolean", @@ -8500,10 +7475,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -8569,10 +7541,7 @@ "staged": { "type": "boolean", "description": "If true, evaluate merge gates and emit preview results without executing the merge API call.", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -8637,11 +7606,7 @@ }, "if-no-changes": { "type": "string", - "enum": [ - "warn", - "error", - "ignore" - ], + "enum": ["warn", "error", "ignore"], "description": "Behavior when no changes to push: 'warn' (default - log warning but succeed), 'error' (fail the action), or 'ignore' (silent success)" }, "ignore-missing-branch-failure": { @@ -8660,10 +7625,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] }, "github-token-for-extra-empty-commit": { "type": "string", @@ -8704,11 +7666,7 @@ "oneOf": [ { "type": "string", - "enum": [ - "blocked", - "allowed", - "fallback-to-issue" - ], + "enum": ["blocked", "allowed", "fallback-to-issue"], "description": "Controls protected-file protection. blocked (default): hard-block any patch that modifies package manifests (e.g. package.json, go.mod), engine instruction files (e.g. AGENTS.md, CLAUDE.md) or .github/ files. allowed: allow all changes. fallback-to-issue: create a review issue instead of pushing to the PR branch, so a human can review the changes before applying.", "default": "blocked" }, @@ -8724,11 +7682,7 @@ "oneOf": [ { "type": "string", - "enum": [ - "blocked", - "allowed", - "fallback-to-issue" - ], + "enum": ["blocked", "allowed", "fallback-to-issue"], "description": "Protection policy. blocked (default): hard-block any patch that modifies protected files. allowed: allow all changes. fallback-to-issue: create a review issue instead of pushing.", "default": "blocked" }, @@ -8745,15 +7699,7 @@ "type": "string" }, "description": "List of filenames or path prefixes to remove from the default protected-file set. Items are matched by basename (e.g. \"AGENTS.md\") or path prefix (e.g. \".agents/\"). Use this to allow the agent to modify specific files that are otherwise blocked by default.", - "examples": [ - [ - "AGENTS.md" - ], - [ - "AGENTS.md", - ".agents/" - ] - ] + "examples": [["AGENTS.md"], ["AGENTS.md", ".agents/"]] } }, "additionalProperties": false, @@ -8780,10 +7726,7 @@ "oneOf": [ { "type": "string", - "enum": [ - "am", - "bundle" - ], + "enum": ["am", "bundle"], "default": "bundle", "description": "Transport format for packaging changes. \"bundle\" (default) uses git bundle, which preserves merge commit topology, per-commit authorship, and merge-resolution-only content. \"am\" uses git format-patch/git am." }, @@ -8799,10 +7742,7 @@ "type": "boolean", "description": "When true, adds workflows: write to the GitHub App token permissions. Required when allowed-files targets .github/workflows/ paths. Requires safe-outputs.github-app to be configured because the workflows permission is a GitHub App-only permission and cannot be granted via GITHUB_TOKEN.", "default": false, - "examples": [ - true, - false - ] + "examples": [true, false] }, "check-branch-protection": { "type": "boolean", @@ -8849,14 +7789,7 @@ "description": "List of allowed reasons for hiding comments. Default: all reasons allowed (spam, abuse, off_topic, outdated, resolved, low_quality).", "items": { "type": "string", - "enum": [ - "spam", - "abuse", - "off_topic", - "outdated", - "resolved", - "low_quality" - ] + "enum": ["spam", "abuse", "off_topic", "outdated", "resolved", "low_quality"] } }, "discussions": { @@ -8866,10 +7799,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -8932,10 +7862,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -8996,10 +7923,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -9054,15 +7978,10 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, - "required": [ - "workflows" - ], + "required": ["workflows"], "additionalProperties": false }, { @@ -9121,13 +8040,7 @@ "properties": { "type": { "type": "string", - "enum": [ - "string", - "number", - "boolean", - "choice", - "environment" - ], + "enum": ["string", "number", "boolean", "choice", "environment"], "description": "Input type" }, "description": { @@ -9174,16 +8087,10 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, - "required": [ - "workflow", - "event_type" - ], + "required": ["workflow", "event_type"], "additionalProperties": false } }, @@ -9226,15 +8133,10 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, - "required": [ - "workflows" - ], + "required": ["workflows"], "additionalProperties": false }, { @@ -9295,10 +8197,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -9360,10 +8259,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -9413,10 +8309,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -9481,10 +8374,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -9576,10 +8466,7 @@ "if-no-files": { "type": "string", "description": "Behaviour when no files match: 'error' (default) or 'ignore'", - "enum": [ - "error", - "ignore" - ], + "enum": ["error", "ignore"], "default": "error" } }, @@ -9592,10 +8479,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub Actions artifact uploads (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -9642,10 +8526,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -9660,10 +8541,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] }, "env": { "type": "object", @@ -9679,11 +8557,7 @@ "github-token": { "$ref": "#/$defs/github_token", "description": "GitHub token to use for safe output jobs. Typically a secret reference like ${{ secrets.GITHUB_TOKEN }} or ${{ secrets.CUSTOM_PAT }}", - "examples": [ - "${{ secrets.GITHUB_TOKEN }}", - "${{ secrets.CUSTOM_PAT }}", - "${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}" - ] + "examples": ["${{ secrets.GITHUB_TOKEN }}", "${{ secrets.CUSTOM_PAT }}", "${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}"] }, "github-app": { "$ref": "#/$defs/github_app", @@ -9869,13 +8743,7 @@ }, "type": { "type": "string", - "enum": [ - "string", - "boolean", - "choice", - "number", - "environment" - ], + "enum": ["string", "boolean", "choice", "number", "environment"], "description": "Input parameter type. Supports: string (default), boolean, choice (string with predefined options), number, and environment (string referencing a GitHub environment)", "default": "string" }, @@ -9971,11 +8839,7 @@ }, "type": { "type": "string", - "enum": [ - "string", - "boolean", - "number" - ], + "enum": ["string", "boolean", "number"], "description": "Input parameter type", "default": "string" } @@ -9990,9 +8854,7 @@ "description": "JavaScript handler body. Write only the code that runs inside the handler for each item \u2014 the compiler generates the full outer wrapper including config input destructuring (`const { channel, message } = config;`) and the handler function (`return async function handleX(item, resolvedTemporaryIds) { ... }`). The body has access to `item` (runtime message with input values), `resolvedTemporaryIds` (map of temporary IDs), and config-destructured local variables for each declared input." } }, - "required": [ - "script" - ], + "required": ["script"], "additionalProperties": false } }, @@ -10005,129 +8867,82 @@ "footer": { "type": "string", "description": "Custom footer message template for AI-generated content. Available placeholders: {workflow_name}, {run_url}, {triggering_number}, {workflow_source}, {workflow_source_url}. Example: '> Generated by [{workflow_name}]({run_url})'", - "examples": [ - "> Generated by [{workflow_name}]({run_url})", - "> AI output from [{workflow_name}]({run_url}) for #{triggering_number}" - ] + "examples": ["> Generated by [{workflow_name}]({run_url})", "> AI output from [{workflow_name}]({run_url}) for #{triggering_number}"] }, "footer-install": { "type": "string", "description": "Custom installation instructions template appended to the footer. Available placeholders: {workflow_source}, {workflow_source_url}. Example: '> Install: `gh aw add {workflow_source}`'", - "examples": [ - "> Install: `gh aw add {workflow_source}`", - "> [Add this workflow]({workflow_source_url})" - ] + "examples": ["> Install: `gh aw add {workflow_source}`", "> [Add this workflow]({workflow_source_url})"] }, "footer-workflow-recompile": { "type": "string", "description": "Custom footer message template for workflow recompile issues. Available placeholders: {workflow_name}, {run_url}, {repository}. Example: '> Workflow sync report by [{workflow_name}]({run_url}) for {repository}'", - "examples": [ - "> Workflow sync report by [{workflow_name}]({run_url}) for {repository}", - "> Maintenance report by [{workflow_name}]({run_url})" - ] + "examples": ["> Workflow sync report by [{workflow_name}]({run_url}) for {repository}", "> Maintenance report by [{workflow_name}]({run_url})"] }, "footer-workflow-recompile-comment": { "type": "string", "description": "Custom footer message template for comments on workflow recompile issues. Available placeholders: {workflow_name}, {run_url}, {repository}. Example: '> Update from [{workflow_name}]({run_url}) for {repository}'", - "examples": [ - "> Update from [{workflow_name}]({run_url}) for {repository}", - "> Maintenance update by [{workflow_name}]({run_url})" - ] + "examples": ["> Update from [{workflow_name}]({run_url}) for {repository}", "> Maintenance update by [{workflow_name}]({run_url})"] }, "staged-title": { "type": "string", "description": "Custom title template for staged mode preview. Available placeholders: {operation}. Example: '\ud83c\udfad Preview: {operation}'", - "examples": [ - "\ud83c\udfad Preview: {operation}", - "## Staged Mode: {operation}" - ] + "examples": ["\ud83c\udfad Preview: {operation}", "## Staged Mode: {operation}"] }, "staged-description": { "type": "string", "description": "Custom description template for staged mode preview. Available placeholders: {operation}. Example: 'The following {operation} would occur if staged mode was disabled:'", - "examples": [ - "The following {operation} would occur if staged mode was disabled:" - ] + "examples": ["The following {operation} would occur if staged mode was disabled:"] }, "run-started": { "type": "string", "description": "Custom message template for workflow activation comment. Available placeholders: {workflow_name}, {run_url}, {event_type}. Default: 'Agentic [{workflow_name}]({run_url}) triggered by this {event_type}.'", - "examples": [ - "Agentic [{workflow_name}]({run_url}) triggered by this {event_type}.", - "[{workflow_name}]({run_url}) started processing this {event_type}." - ] + "examples": ["Agentic [{workflow_name}]({run_url}) triggered by this {event_type}.", "[{workflow_name}]({run_url}) started processing this {event_type}."] }, "run-success": { "type": "string", "description": "Custom message template for successful workflow completion. Available placeholders: {workflow_name}, {run_url}. Default: '\u2705 Agentic [{workflow_name}]({run_url}) completed successfully.'", - "examples": [ - "\u2705 Agentic [{workflow_name}]({run_url}) completed successfully.", - "\u2705 [{workflow_name}]({run_url}) finished." - ] + "examples": ["\u2705 Agentic [{workflow_name}]({run_url}) completed successfully.", "\u2705 [{workflow_name}]({run_url}) finished."] }, "run-failure": { "type": "string", "description": "Custom message template for failed workflow. Available placeholders: {workflow_name}, {run_url}, {status}. Default: '\u274c Agentic [{workflow_name}]({run_url}) {status} and wasn't able to produce a result.'", - "examples": [ - "\u274c Agentic [{workflow_name}]({run_url}) {status} and wasn't able to produce a result.", - "\u274c [{workflow_name}]({run_url}) {status}." - ] + "examples": ["\u274c Agentic [{workflow_name}]({run_url}) {status} and wasn't able to produce a result.", "\u274c [{workflow_name}]({run_url}) {status}."] }, "detection-failure": { "type": "string", "description": "Custom message template for detection job failure. Available placeholders: {workflow_name}, {run_url}. Default: '\u26a0\ufe0f Security scanning failed for [{workflow_name}]({run_url}). Review the logs for details.'", - "examples": [ - "\u26a0\ufe0f Security scanning failed for [{workflow_name}]({run_url}). Review the logs for details.", - "\u26a0\ufe0f Detection job failed in [{workflow_name}]({run_url})." - ] + "examples": ["\u26a0\ufe0f Security scanning failed for [{workflow_name}]({run_url}). Review the logs for details.", "\u26a0\ufe0f Detection job failed in [{workflow_name}]({run_url})."] }, "agent-failure-issue": { "type": "string", "description": "Custom footer template for agent failure tracking issues. Available placeholders: {workflow_name}, {run_url}. Default: '> Agent failure tracked by [{workflow_name}]({run_url})'", - "examples": [ - "> Agent failure tracked by [{workflow_name}]({run_url})", - "> Failure report from [{workflow_name}]({run_url})" - ] + "examples": ["> Agent failure tracked by [{workflow_name}]({run_url})", "> Failure report from [{workflow_name}]({run_url})"] }, "agent-failure-comment": { "type": "string", "description": "Custom footer template for comments on agent failure tracking issues. Available placeholders: {workflow_name}, {run_url}. Default: '> Agent failure update from [{workflow_name}]({run_url})'", - "examples": [ - "> Agent failure update from [{workflow_name}]({run_url})", - "> Update from [{workflow_name}]({run_url})" - ] + "examples": ["> Agent failure update from [{workflow_name}]({run_url})", "> Update from [{workflow_name}]({run_url})"] }, "pull-request-created": { "type": "string", "description": "Custom message template for pull request creation link appended to the activation comment. Available placeholders: {item_number}, {item_url}. Default: 'Pull request created: [#{item_number}]({item_url})'", - "examples": [ - "Pull request created: [#{item_number}]({item_url})", - "[#{item_number}]({item_url}) opened" - ] + "examples": ["Pull request created: [#{item_number}]({item_url})", "[#{item_number}]({item_url}) opened"] }, "issue-created": { "type": "string", "description": "Custom message template for issue creation link appended to the activation comment. Available placeholders: {item_number}, {item_url}. Default: 'Issue created: [#{item_number}]({item_url})'", - "examples": [ - "Issue created: [#{item_number}]({item_url})", - "[#{item_number}]({item_url}) filed" - ] + "examples": ["Issue created: [#{item_number}]({item_url})", "[#{item_number}]({item_url}) filed"] }, "commit-pushed": { "type": "string", "description": "Custom message template for commit push link appended to the activation comment. Available placeholders: {commit_sha}, {short_sha}, {commit_url}. Default: 'Commit pushed: [`{short_sha}`]({commit_url})'", - "examples": [ - "Commit pushed: [`{short_sha}`]({commit_url})", - "[`{short_sha}`]({commit_url}) pushed" - ] + "examples": ["Commit pushed: [`{short_sha}`]({commit_url})", "[`{short_sha}`]({commit_url}) pushed"] }, "body-header": { "type": "string", "description": "Custom header text prepended to every message body generated by safe outputs (issues, comments, pull requests, discussions). Applied after any threat-detection caution alert and before the agent-generated content. Available placeholders: {workflow_name}, {run_url}.", - "examples": [ - "> \u26a0\ufe0f This content was generated by [{workflow_name}]({run_url}).", - "> \ud83e\udd16 AI-generated output \u2014 please review before acting." - ] + "examples": ["> \u26a0\ufe0f This content was generated by [{workflow_name}]({run_url}).", "> \ud83e\udd16 AI-generated output \u2014 please review before acting."] }, "append-only-comments": { "type": "boolean", @@ -10190,50 +9005,31 @@ "type": "boolean", "description": "Global footer control for all safe outputs. When false, omits visible AI-generated footer content from all created/updated entities (issues, PRs, discussions, releases) while still including XML markers for searchability. Individual safe-output types (create-issue, update-issue, etc.) can override this by specifying their own footer field. Defaults to true.", "default": true, - "examples": [ - false, - true - ] + "examples": [false, true] }, "activation-comments": { - "type": [ - "boolean", - "string" - ], + "type": ["boolean", "string"], "description": "When set to false or \"false\", disables all activation and fallback comments entirely (run-started, run-success, run-failure, PR/issue creation links). Supports templatable boolean values including GitHub Actions expressions (e.g. ${{ inputs.activation-comments }}). Default: true", "default": true, - "examples": [ - false, - true, - "${{ inputs.activation-comments }}" - ] + "examples": [false, true, "${{ inputs.activation-comments }}"] }, "group-reports": { "type": "boolean", "description": "When true, creates a parent '[aw] Failed runs' issue that tracks all workflow failures as sub-issues. Helps organize failure tracking but may be unnecessary in smaller repositories. Defaults to false.", "default": false, - "examples": [ - false, - true - ] + "examples": [false, true] }, "report-failure-as-issue": { "type": "boolean", "description": "When false, disables creating failure tracking issues when workflows fail. Useful for workflows where failures are expected or handled elsewhere. Defaults to true.", "default": true, - "examples": [ - false, - true - ] + "examples": [false, true] }, "failure-issue-repo": { "type": "string", "description": "Repository to create failure tracking issues in, in the format 'owner/repo'. Useful when the current repository has issues disabled. Defaults to the current repository.", "pattern": "^[^/]+/[^/]+$", - "examples": [ - "github/docs-engineering", - "myorg/infra-alerts" - ] + "examples": ["github/docs-engineering", "myorg/infra-alerts"] }, "max-bot-mentions": { "description": "Maximum number of bot trigger references (e.g. 'fixes #123', 'closes #456') allowed in output before all of them are neutralized. Default: 10. Supports integer or GitHub Actions expression (e.g. '${{ inputs.max-bot-mentions }}').", @@ -10252,23 +9048,14 @@ }, "id-token": { "type": "string", - "enum": [ - "write", - "none" - ], + "enum": ["write", "none"], "description": "Override the id-token permission for the safe-outputs job. Use 'write' to force-enable the id-token: write permission (required for OIDC authentication with cloud providers). Use 'none' to suppress automatic detection and prevent adding id-token: write even when vault/OIDC actions are detected in steps. By default, the compiler auto-detects known OIDC/vault actions (aws-actions/configure-aws-credentials, azure/login, google-github-actions/auth, hashicorp/vault-action, cyberark/conjur-action) and adds id-token: write automatically.", - "examples": [ - "write", - "none" - ] + "examples": ["write", "none"] }, "concurrency-group": { "type": "string", "description": "Concurrency group for the safe-outputs job. When set, the safe-outputs job will use this concurrency group with cancel-in-progress: false. Supports GitHub Actions expressions.", - "examples": [ - "my-workflow-safe-outputs", - "safe-outputs-${{ github.repository }}" - ] + "examples": ["my-workflow-safe-outputs", "safe-outputs-${{ github.repository }}"] }, "needs": { "type": "array", @@ -10280,11 +9067,7 @@ "additionalItems": false, "uniqueItems": true, "default": [], - "examples": [ - [ - "secrets_fetcher" - ] - ] + "examples": [["secrets_fetcher"]] }, "environment": { "description": "Override the GitHub deployment environment for the safe-outputs job. When set, this environment is used instead of the top-level environment: field. When not set, the top-level environment: field is propagated automatically so that environment-scoped secrets are accessible in the safe-outputs job.", @@ -10306,9 +9089,7 @@ "description": "A deployment URL" } }, - "required": [ - "name" - ], + "required": ["name"], "additionalProperties": false } ] @@ -10343,11 +9124,7 @@ "uses": { "type": "string", "description": "The GitHub Action to use. Supports owner/repo@ref, owner/repo/subdir@ref, or ./local/path.", - "examples": [ - "actions-ecosystem/action-add-labels@v1", - "owner/repo@v1", - "owner/repo/subdir@v1" - ] + "examples": ["actions-ecosystem/action-add-labels@v1", "owner/repo@v1", "owner/repo/subdir@v1"] }, "description": { "type": "string", @@ -10392,9 +9169,7 @@ "additionalProperties": false } }, - "required": [ - "uses" - ], + "required": ["uses"], "additionalProperties": false } } @@ -10444,10 +9219,7 @@ "staged": { "type": "boolean", "description": "If true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [ - true, - false - ] + "examples": [true, false] } }, "additionalProperties": false @@ -10507,9 +9279,7 @@ { "type": "object", "description": "A single OTLP endpoint with a URL and optional per-endpoint headers.", - "required": [ - "url" - ], + "required": ["url"], "properties": { "url": { "type": "string", @@ -10539,9 +9309,7 @@ "items": { "type": "object", "description": "A single OTLP endpoint with a URL and optional per-endpoint headers.", - "required": [ - "url" - ], + "required": ["url"], "properties": { "url": { "type": "string", @@ -10586,11 +9354,7 @@ }, "if-missing": { "type": "string", - "enum": [ - "error", - "warn", - "ignore" - ], + "enum": ["error", "warn", "ignore"], "default": "error", "description": "How to handle missing OTLP endpoint/header values at runtime (for example from unset secrets). 'error' fails workflow startup (default), 'warn' logs a warning and skips MCP gateway OTLP configuration, and 'ignore' skips MCP gateway OTLP configuration without warning. This affects MCP gateway setup only; workflow-level OTEL_* environment variables are still injected." } @@ -10603,9 +9367,7 @@ "user-rate-limit": { "type": "object", "description": "Rate limiting configuration to restrict how frequently users can trigger the workflow. Helps prevent abuse and resource exhaustion from programmatically triggered events.", - "required": [ - "max-runs-per-window" - ], + "required": ["max-runs-per-window"], "properties": { "max-runs-per-window": { "description": "Maximum number of workflow runs allowed per user within the time window. Required field. Supports integer or GitHub Actions expression (e.g. '${{ inputs.max }}').", @@ -10634,16 +9396,7 @@ "description": "Optional list of event types to apply rate limiting to. If not specified, rate limiting applies to all programmatically triggered events (e.g., workflow_dispatch, issue_comment, pull_request_review).", "items": { "type": "string", - "enum": [ - "workflow_dispatch", - "issue_comment", - "pull_request_review", - "pull_request_review_comment", - "issues", - "pull_request", - "discussion_comment", - "discussion" - ] + "enum": ["workflow_dispatch", "issue_comment", "pull_request_review", "pull_request_review_comment", "issues", "pull_request", "discussion_comment", "discussion"] }, "minItems": 1 }, @@ -10652,13 +9405,7 @@ "description": "Optional list of roles that are exempt from rate limiting. Defaults to ['admin', 'maintain', 'write'] if not specified. Users with any of these roles will not be subject to rate limiting checks. To apply rate limiting to all users, set to an empty array: []", "items": { "type": "string", - "enum": [ - "admin", - "maintain", - "write", - "triage", - "read" - ] + "enum": ["admin", "maintain", "write", "triage", "read"] }, "minItems": 0 } @@ -10672,18 +9419,12 @@ { "max-runs-per-window": 10, "window": 30, - "events": [ - "workflow_dispatch", - "issue_comment" - ] + "events": ["workflow_dispatch", "issue_comment"] }, { "max-runs-per-window": 5, "window": 60, - "ignored-roles": [ - "admin", - "maintain" - ] + "ignored-roles": ["admin", "maintain"] } ] }, @@ -10733,16 +9474,7 @@ "description": "Optional list of event types to apply rate limiting to.", "items": { "type": "string", - "enum": [ - "workflow_dispatch", - "issue_comment", - "pull_request_review", - "pull_request_review_comment", - "issues", - "pull_request", - "discussion_comment", - "discussion" - ] + "enum": ["workflow_dispatch", "issue_comment", "pull_request_review", "pull_request_review_comment", "issues", "pull_request", "discussion_comment", "discussion"] }, "minItems": 1 }, @@ -10751,13 +9483,7 @@ "description": "Optional list of roles that are exempt from rate limiting.", "items": { "type": "string", - "enum": [ - "admin", - "maintain", - "write", - "triage", - "read" - ] + "enum": ["admin", "maintain", "write", "triage", "read"] }, "minItems": 0 } @@ -10769,37 +9495,25 @@ "default": true, "$comment": "Strict mode enforces several security constraints that are validated in Go code (pkg/workflow/strict_mode_validation.go) rather than JSON Schema: (1) Write Permissions + Safe Outputs: When strict=true AND permissions contains write values (contents:write, issues:write, pull-requests:write), safe-outputs must be configured. This relationship is too complex for JSON Schema as it requires checking if ANY permission property has a 'write' value. (2) Network Requirements: When strict=true, the 'network' field must be present and cannot contain standalone wildcard '*' (but patterns like '*.example.com' ARE allowed). (3) MCP Container Network: Custom MCP servers with containers require explicit network configuration. (4) Action Pinning: Actions must be pinned to commit SHAs. These are enforced during compilation via validateStrictMode().", "description": "Enable strict mode validation for enhanced security and compliance. Strict mode enforces: (1) Write Permissions - refuses contents:write, issues:write, pull-requests:write; requires safe-outputs instead, (2) Network Configuration - requires explicit network configuration with no standalone wildcard '*' in allowed domains (patterns like '*.example.com' are allowed), (3) Action Pinning - enforces actions pinned to commit SHAs instead of tags/branches, (4) MCP Network - requires network configuration for custom MCP servers with containers, (5) Deprecated Fields - refuses deprecated frontmatter fields. Can be enabled per-workflow via 'strict: true' in frontmatter, or disabled via 'strict: false'. CLI flag takes precedence over frontmatter (gh aw compile --strict enforces strict mode). Defaults to true. See: https://github.github.com/gh-aw/reference/frontmatter/#strict-mode-strict", - "examples": [ - true, - false - ] + "examples": [true, false] }, "private": { "type": "boolean", "default": false, "description": "Mark the workflow as private, preventing it from being added to other repositories via 'gh aw add'. A workflow with private: true is not meant to be shared outside its repository.", - "examples": [ - true, - false - ] + "examples": [true, false] }, "check-for-updates": { "type": "boolean", "default": true, "description": "Control whether the compile-agentic version update check runs in the activation job. When true (default), the activation job downloads config.json from the gh-aw repository and verifies the compiled version is not blocked and meets the minimum supported version. Set to false to disable the check (not allowed in strict mode). See: https://github.github.com/gh-aw/reference/frontmatter/#check-for-updates", - "examples": [ - true, - false - ] + "examples": [true, false] }, "run-install-scripts": { "type": "boolean", "default": false, "description": "Allow npm pre/post install scripts to execute during package installation. By default, --ignore-scripts is added to all generated npm install commands to prevent supply chain attacks via malicious install hooks. Setting run-install-scripts: true disables this protection globally (all runtimes). A supply chain security warning is emitted at compile time; in strict mode this is an error. Per-runtime control is also available via runtimes..run-install-scripts. See: https://github.github.com/gh-aw/reference/frontmatter/#run-install-scripts", - "examples": [ - false, - true - ] + "examples": [false, true] }, "mcp-scripts": { "type": "object", @@ -10808,9 +9522,7 @@ "^([a-ln-z][a-z0-9_-]*|m[a-np-z][a-z0-9_-]*|mo[a-ce-z][a-z0-9_-]*|mod[a-df-z][a-z0-9_-]*|mode[a-z0-9_-]+)$": { "type": "object", "description": "Custom tool definition. The key is the tool name (lowercase alphanumeric with dashes/underscores).", - "required": [ - "description" - ], + "required": ["description"], "properties": { "description": { "type": "string", @@ -10824,13 +9536,7 @@ "properties": { "type": { "type": "string", - "enum": [ - "string", - "number", - "boolean", - "array", - "object" - ], + "enum": ["string", "number", "boolean", "array", "object"], "default": "string", "description": "The JSON schema type of the input parameter." }, @@ -10884,108 +9590,71 @@ "description": "Timeout in seconds for tool execution. Default is 60 seconds. Applies to shell (run) and Python (py) tools.", "default": 60, "minimum": 1, - "examples": [ - 30, - 60, - 120, - 300 - ] + "examples": [30, 60, 120, 300] } }, "additionalProperties": false, "oneOf": [ { - "required": [ - "script" - ], + "required": ["script"], "not": { "anyOf": [ { - "required": [ - "run" - ] + "required": ["run"] }, { - "required": [ - "py" - ] + "required": ["py"] }, { - "required": [ - "go" - ] + "required": ["go"] } ] } }, { - "required": [ - "run" - ], + "required": ["run"], "not": { "anyOf": [ { - "required": [ - "script" - ] + "required": ["script"] }, { - "required": [ - "py" - ] + "required": ["py"] }, { - "required": [ - "go" - ] + "required": ["go"] } ] } }, { - "required": [ - "py" - ], + "required": ["py"], "not": { "anyOf": [ { - "required": [ - "script" - ] + "required": ["script"] }, { - "required": [ - "run" - ] + "required": ["run"] }, { - "required": [ - "go" - ] + "required": ["go"] } ] } }, { - "required": [ - "go" - ], + "required": ["go"], "not": { "anyOf": [ { - "required": [ - "script" - ] + "required": ["script"] }, { - "required": [ - "run" - ] + "required": ["run"] }, { - "required": [ - "py" - ] + "required": ["py"] } ] } @@ -11043,18 +9712,9 @@ "description": "Runtime configuration object identified by runtime ID (e.g., 'node', 'python', 'go')", "properties": { "version": { - "type": [ - "string", - "number" - ], + "type": ["string", "number"], "description": "Runtime version as a string (e.g., '22', '3.12', 'latest') or number (e.g., 22, 3.12). Numeric values are automatically converted to strings at runtime.", - "examples": [ - "22", - "3.12", - "latest", - 22, - 3.12 - ] + "examples": ["22", "3.12", "latest", 22, 3.12] }, "action-repo": { "type": "string", @@ -11067,22 +9727,13 @@ "if": { "type": "string", "description": "Optional GitHub Actions if condition to control when the runtime setup step runs. Supports standard GitHub Actions expression syntax. Useful for conditionally installing runtimes based on file presence (e.g., \"hashFiles('go.mod') != ''\" to install Go only when go.mod exists).", - "examples": [ - "hashFiles('go.mod') != ''", - "hashFiles('package.json') != ''", - "hashFiles('requirements.txt') != '' || hashFiles('pyproject.toml') != ''", - "hashFiles('uv.lock') != ''", - "github.event_name == 'workflow_dispatch'" - ] + "examples": ["hashFiles('go.mod') != ''", "hashFiles('package.json') != ''", "hashFiles('requirements.txt') != '' || hashFiles('pyproject.toml') != ''", "hashFiles('uv.lock') != ''", "github.event_name == 'workflow_dispatch'"] }, "run-install-scripts": { "type": "boolean", "default": false, "description": "Allow npm pre/post install scripts to execute for this runtime during package installation. Overrides the global run-install-scripts setting for this specific runtime. Only affects runtimes that generate npm install commands (node). A supply chain security warning is emitted at compile time; in strict mode this is an error.", - "examples": [ - false, - true - ] + "examples": [false, true] } }, "additionalProperties": false @@ -11106,9 +9757,7 @@ }, { "type": "boolean", - "enum": [ - false - ], + "enum": [false], "description": "Set to false to disable the default checkout step. The agent job will not check out any repository (dev-mode checkouts are unaffected)." } ] @@ -11140,13 +9789,7 @@ }, "type": { "type": "string", - "enum": [ - "string", - "number", - "boolean", - "choice", - "array" - ], + "enum": ["string", "number", "boolean", "choice", "array"], "description": "The type of the input value." }, "options": { @@ -11162,11 +9805,7 @@ "properties": { "type": { "type": "string", - "enum": [ - "string", - "number", - "boolean" - ], + "enum": ["string", "number", "boolean"], "description": "Type of each array item." } }, @@ -11178,9 +9817,7 @@ { "type": "object", "description": "Input parameter definition for object type (one level deep). Use 'properties' to declare the expected sub-fields.", - "required": [ - "type" - ], + "required": ["type"], "properties": { "description": { "type": "string", @@ -11193,9 +9830,7 @@ }, "type": { "type": "string", - "enum": [ - "object" - ], + "enum": ["object"], "description": "The type 'object' enables structured sub-fields accessible via 'github.aw.import-inputs..'." }, "properties": { @@ -11215,12 +9850,7 @@ "default": {}, "type": { "type": "string", - "enum": [ - "string", - "number", - "boolean", - "choice" - ], + "enum": ["string", "number", "boolean", "choice"], "description": "Type of the sub-property." }, "options": { @@ -11299,17 +9929,13 @@ "const": "centralized" } }, - "required": [ - "strategy" - ] + "required": ["strategy"] } } ] } }, - "required": [ - "slash_command" - ] + "required": ["slash_command"] }, { "properties": { @@ -11319,9 +9945,7 @@ } } }, - "required": [ - "command" - ] + "required": ["command"] } ] } @@ -11340,9 +9964,7 @@ } } }, - "required": [ - "issue_comment" - ] + "required": ["issue_comment"] }, { "properties": { @@ -11352,9 +9974,7 @@ } } }, - "required": [ - "pull_request_review_comment" - ] + "required": ["pull_request_review_comment"] }, { "properties": { @@ -11364,9 +9984,7 @@ } } }, - "required": [ - "label" - ] + "required": ["label"] } ] } @@ -11539,18 +10157,9 @@ "description": "AI engine identifier: built-in ('claude', 'codex', 'copilot', 'gemini', 'opencode', 'crush', 'pi') or a named catalog entry" }, "version": { - "type": [ - "string", - "number" - ], + "type": ["string", "number"], "description": "Optional version of the AI engine action (e.g., 'beta', 'stable', 20). Has sensible defaults and can typically be omitted. Numeric values are automatically converted to strings at runtime. GitHub Actions expressions (e.g., '${{ inputs.engine-version }}') are accepted and compiled with injection-safe env var handling.", - "examples": [ - "beta", - "stable", - 20, - 3.11, - "${{ inputs.engine-version }}" - ] + "examples": ["beta", "stable", 20, 3.11, "${{ inputs.engine-version }}"] }, "model": { "type": "string", @@ -11594,16 +10203,11 @@ }, "queue": { "type": "string", - "enum": [ - "single", - "max" - ], + "enum": ["single", "max"], "description": "Pending run queue behavior for this concurrency group. 'single' (default) allows one pending run and replaces older pending runs. 'max' allows up to 100 pending runs in FIFO order." } }, - "required": [ - "group" - ], + "required": ["group"], "additionalProperties": false } ], @@ -11635,9 +10239,7 @@ "properties": { "type": { "type": "string", - "enum": [ - "github-oidc" - ], + "enum": ["github-oidc"], "description": "Authentication type. Currently only 'github-oidc' is supported." }, "audience": { @@ -11662,9 +10264,7 @@ "description": "Optional Azure cloud name (for example, public, usgovernment, china)." } }, - "required": [ - "type" - ], + "required": ["type"], "additionalProperties": false }, "config": { @@ -11678,11 +10278,7 @@ "api-target": { "type": "string", "description": "Custom API endpoint hostname for the agentic engine. Used for GitHub Enterprise Cloud (GHEC), GitHub Enterprise Server (GHES), or custom AI endpoints. Example: 'api.acme.ghe.com' for GHEC, 'api.enterprise.githubcopilot.com' for GHES, or custom endpoint hostnames.", - "examples": [ - "api.acme.ghe.com", - "api.enterprise.githubcopilot.com", - "api.custom.endpoint.com" - ] + "examples": ["api.acme.ghe.com", "api.enterprise.githubcopilot.com", "api.custom.endpoint.com"] }, "token-weights": { "type": "object", @@ -11756,31 +10352,18 @@ "session-timeout": { "type": "string", "description": "Session timeout for MCP gateway sessions as a Go duration string (e.g. \"30m\", \"4h\", \"24h\"). Must be at least 5m (no upper bound). Omitted or empty uses the effective gateway default (precedence: this field > MCP_GATEWAY_SESSION_TIMEOUT env var > built-in default 6h). Longer timeouts benefit multi-hour workflows such as large-scale migrations; shorter values free gateway resources sooner.", - "examples": [ - "30m", - "1h", - "4h", - "6h", - "12h" - ] + "examples": ["30m", "1h", "4h", "6h", "12h"] }, "tool-timeout": { "type": "string", "description": "Timeout for individual MCP tool calls as a Go duration string (e.g. \"30s\", \"2m\", \"10m\"). Must be between 10s and 600s inclusive. Omitted or empty uses the gateway built-in default (60s). Use a higher value for slow MCP backends such as full-text search over large indexes.", - "examples": [ - "30s", - "2m", - "5m", - "10m" - ] + "examples": ["30s", "2m", "5m", "10m"] } }, "additionalProperties": false } }, - "required": [ - "id" - ], + "required": ["id"], "additionalProperties": false }, { @@ -11794,32 +10377,15 @@ "id": { "type": "string", "description": "Runtime adapter identifier (e.g. 'codex', 'claude', 'copilot', 'gemini', 'opencode', 'crush', 'pi')", - "examples": [ - "codex", - "claude", - "copilot", - "gemini", - "opencode", - "crush", - "pi" - ] + "examples": ["codex", "claude", "copilot", "gemini", "opencode", "crush", "pi"] }, "version": { - "type": [ - "string", - "number" - ], + "type": ["string", "number"], "description": "Optional version of the runtime adapter (e.g. '0.105.0', 'beta')", - "examples": [ - "0.105.0", - "beta", - "latest" - ] + "examples": ["0.105.0", "beta", "latest"] } }, - "required": [ - "id" - ], + "required": ["id"], "additionalProperties": false }, "provider": { @@ -11829,21 +10395,12 @@ "id": { "type": "string", "description": "Provider identifier (e.g. 'openai', 'anthropic', 'github', 'google')", - "examples": [ - "openai", - "anthropic", - "github", - "google" - ] + "examples": ["openai", "anthropic", "github", "google"] }, "model": { "type": "string", "description": "Optional specific LLM model to use (e.g. 'gpt-5', 'claude-3-5-sonnet-20241022')", - "examples": [ - "gpt-5", - "claude-3-5-sonnet-20241022", - "gpt-4o" - ] + "examples": ["gpt-5", "claude-3-5-sonnet-20241022", "gpt-4o"] }, "auth": { "type": "object", @@ -11852,58 +10409,37 @@ "secret": { "type": "string", "description": "Name of the GitHub Actions secret that contains the API key for this provider", - "examples": [ - "OPENAI_API_KEY", - "ANTHROPIC_API_KEY", - "CUSTOM_API_KEY" - ] + "examples": ["OPENAI_API_KEY", "ANTHROPIC_API_KEY", "CUSTOM_API_KEY"] }, "strategy": { "type": "string", - "enum": [ - "api-key", - "oauth-client-credentials", - "bearer" - ], + "enum": ["api-key", "oauth-client-credentials", "bearer"], "description": "Authentication strategy for the provider (default: api-key when secret is set)" }, "token-url": { "type": "string", "description": "OAuth 2.0 token endpoint URL. Required when strategy is 'oauth-client-credentials'.", - "examples": [ - "https://auth.example.com/oauth/token" - ] + "examples": ["https://auth.example.com/oauth/token"] }, "client-id": { "type": "string", "description": "GitHub Actions secret name that holds the OAuth client ID. Required when strategy is 'oauth-client-credentials'.", - "examples": [ - "OAUTH_CLIENT_ID" - ] + "examples": ["OAUTH_CLIENT_ID"] }, "client-secret": { "type": "string", "description": "GitHub Actions secret name that holds the OAuth client secret. Required when strategy is 'oauth-client-credentials'.", - "examples": [ - "OAUTH_CLIENT_SECRET" - ] + "examples": ["OAUTH_CLIENT_SECRET"] }, "token-field": { "type": "string", "description": "JSON field name in the token response that contains the access token. Defaults to 'access_token'.", - "examples": [ - "access_token", - "token" - ] + "examples": ["access_token", "token"] }, "header-name": { "type": "string", "description": "HTTP header name to inject the API key or token into (e.g. 'api-key', 'x-api-key'). Required when strategy is not 'bearer'.", - "examples": [ - "api-key", - "x-api-key", - "Authorization" - ] + "examples": ["api-key", "x-api-key", "Authorization"] } }, "additionalProperties": false @@ -11915,9 +10451,7 @@ "path-template": { "type": "string", "description": "URL path template with {model} and other variable placeholders (e.g. '/openai/deployments/{model}/chat/completions')", - "examples": [ - "/openai/deployments/{model}/chat/completions" - ] + "examples": ["/openai/deployments/{model}/chat/completions"] }, "query": { "type": "object", @@ -11955,9 +10489,7 @@ "default": false } }, - "required": [ - "runtime" - ], + "required": ["runtime"], "additionalProperties": false }, { @@ -11998,11 +10530,7 @@ }, "strategy": { "type": "string", - "enum": [ - "api-key", - "oauth-client-credentials", - "bearer" - ], + "enum": ["api-key", "oauth-client-credentials", "bearer"], "description": "Authentication strategy" }, "token-url": { @@ -12089,10 +10617,7 @@ "description": "Name of the GitHub Actions secret that provides credentials for this role" } }, - "required": [ - "role", - "secret" - ], + "required": ["role", "secret"], "additionalProperties": false } }, @@ -12102,10 +10627,7 @@ "additionalProperties": true } }, - "required": [ - "id", - "display-name" - ], + "required": ["id", "display-name"], "additionalProperties": false }, { @@ -12119,31 +10641,18 @@ "session-timeout": { "type": "string", "description": "Session timeout for MCP gateway sessions as a Go duration string (e.g. \"30m\", \"4h\", \"24h\"). Must be at least 5m (no upper bound). Omitted or empty uses the effective gateway default (precedence: this field > MCP_GATEWAY_SESSION_TIMEOUT env var > built-in default 6h).", - "examples": [ - "30m", - "1h", - "4h", - "6h", - "12h" - ] + "examples": ["30m", "1h", "4h", "6h", "12h"] }, "tool-timeout": { "type": "string", "description": "Timeout for individual MCP tool calls as a Go duration string (e.g. \"30s\", \"2m\", \"10m\"). Must be between 10s and 600s inclusive. Omitted or empty uses the gateway built-in default (60s). Use a higher value for slow MCP backends such as full-text search over large indexes.", - "examples": [ - "30s", - "2m", - "5m", - "10m" - ] + "examples": ["30s", "2m", "5m", "10m"] } }, "additionalProperties": false } }, - "required": [ - "mcp" - ], + "required": ["mcp"], "additionalProperties": false }, { @@ -12155,9 +10664,7 @@ "description": "Model preference or size category (e.g. 'small', 'large', 'gpt-4.1'). Applied to the default engine when engine.id is not specified." } }, - "required": [ - "model" - ], + "required": ["model"], "additionalProperties": false } ] @@ -12168,18 +10675,13 @@ "properties": { "type": { "type": "string", - "enum": [ - "stdio", - "local" - ], + "enum": ["stdio", "local"], "description": "MCP connection type for stdio (local is an alias for stdio)" }, "registry": { "type": "string", "description": "URI to the installation location when MCP is installed from a registry", - "examples": [ - "https://api.mcp.github.com/v0/servers/microsoft/markitdown" - ] + "examples": ["https://api.mcp.github.com/v0/servers/microsoft/markitdown"] }, "command": { "type": "string", @@ -12194,17 +10696,9 @@ "description": "Container image for stdio MCP connections" }, "version": { - "type": [ - "string", - "number" - ], + "type": ["string", "number"], "description": "Optional version/tag for the container image (e.g., 'latest', 'v1.0.0', 20, 3.11). Numeric values are automatically converted to strings at runtime.", - "examples": [ - "latest", - "v1.0.0", - 20, - 3.11 - ] + "examples": ["latest", "v1.0.0", 20, 3.11] }, "args": { "type": "array", @@ -12216,11 +10710,7 @@ "entrypoint": { "type": "string", "description": "Optional entrypoint override for container (equivalent to docker run --entrypoint)", - "examples": [ - "/bin/sh", - "/custom/entrypoint.sh", - "python" - ] + "examples": ["/bin/sh", "/custom/entrypoint.sh", "python"] }, "entrypointArgs": { "type": "array", @@ -12236,15 +10726,7 @@ "pattern": "^[^:]+:[^:]+:(ro|rw)$" }, "description": "Volume mounts for container in format 'source:dest:mode' where mode is 'ro' or 'rw'", - "examples": [ - [ - "/tmp/data:/data:ro" - ], - [ - "/workspace:/workspace:rw", - "/config:/config:ro" - ] - ] + "examples": [["/tmp/data:/data:ro"], ["/workspace:/workspace:rw", "/config:/config:ro"]] }, "env": { "type": "object", @@ -12290,18 +10772,7 @@ "items": { "type": "string" }, - "examples": [ - [ - "*" - ], - [ - "store_memory", - "retrieve_memory" - ], - [ - "brave_web_search" - ] - ] + "examples": [["*"], ["store_memory", "retrieve_memory"], ["brave_web_search"]] }, "proxy-args": { "type": "array", @@ -12315,32 +10786,22 @@ "$comment": "Validation constraints: (1) Mutual exclusion: 'command' and 'container' cannot both be specified. (2) Requirement: Either 'command' or 'container' must be provided (via 'anyOf'). (3) Type constraint: When 'type' is 'stdio' or 'local', either 'command' or 'container' is required. Note: Per-server 'network' field is deprecated and ignored.", "anyOf": [ { - "required": [ - "type" - ] + "required": ["type"] }, { - "required": [ - "command" - ] + "required": ["command"] }, { - "required": [ - "container" - ] + "required": ["container"] } ], "not": { "allOf": [ { - "required": [ - "command" - ] + "required": ["command"] }, { - "required": [ - "container" - ] + "required": ["container"] } ] }, @@ -12349,24 +10810,17 @@ "if": { "properties": { "type": { - "enum": [ - "stdio", - "local" - ] + "enum": ["stdio", "local"] } } }, "then": { "anyOf": [ { - "required": [ - "command" - ] + "required": ["command"] }, { - "required": [ - "container" - ] + "required": ["container"] } ] } @@ -12379,17 +10833,13 @@ "properties": { "type": { "type": "string", - "enum": [ - "http" - ], + "enum": ["http"], "description": "MCP connection type for HTTP" }, "registry": { "type": "string", "description": "URI to the installation location when MCP is installed from a registry", - "examples": [ - "https://api.mcp.github.com/v0/servers/microsoft/markitdown" - ] + "examples": ["https://api.mcp.github.com/v0/servers/microsoft/markitdown"] }, "url": { "type": "string", @@ -12412,26 +10862,13 @@ "items": { "type": "string" }, - "examples": [ - [ - "*" - ], - [ - "store_memory", - "retrieve_memory" - ], - [ - "brave_web_search" - ] - ] + "examples": [["*"], ["store_memory", "retrieve_memory"], ["brave_web_search"]] }, "auth": { "$ref": "#/$defs/http_mcp_auth" } }, - "required": [ - "url" - ], + "required": ["url"], "additionalProperties": false }, "http_mcp_auth": { @@ -12440,9 +10877,7 @@ "properties": { "type": { "type": "string", - "enum": [ - "github-oidc" - ], + "enum": ["github-oidc"], "description": "Authentication type. Currently only 'github-oidc' is supported, which acquires short-lived JWTs from the GitHub Actions OIDC endpoint." }, "audience": { @@ -12451,21 +10886,14 @@ "format": "uri" } }, - "required": [ - "type" - ], + "required": ["type"], "additionalProperties": false }, "github_token": { "type": "string", "pattern": "^\\$\\{\\{\\s*(secrets\\.[A-Za-z_][A-Za-z0-9_]*(\\s*\\|\\|\\s*secrets\\.[A-Za-z_][A-Za-z0-9_]*)*|needs\\.[A-Za-z_][A-Za-z0-9_]*\\.outputs\\.[A-Za-z_][A-Za-z0-9_]*)\\s*\\}\\}$", "description": "GitHub token expression. Accepts a secrets expression (e.g., `${{ secrets.NAME }}` or `${{ secrets.NAME1 || secrets.NAME2 }}`) or a job output expression (e.g., `${{ needs.auth.outputs.token }}`). Pattern details: secret names match `[A-Za-z_][A-Za-z0-9_]*`; job IDs and output names in dot notation match `[A-Za-z_][A-Za-z0-9_]*` (identifiers without hyphens).", - "examples": [ - "${{ secrets.GITHUB_TOKEN }}", - "${{ secrets.CUSTOM_PAT }}", - "${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}", - "${{ needs.auth.outputs.token }}" - ] + "examples": ["${{ secrets.GITHUB_TOKEN }}", "${{ secrets.CUSTOM_PAT }}", "${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}", "${{ needs.auth.outputs.token }}"] }, "github_app": { "type": "object", @@ -12474,23 +10902,17 @@ "app-id": { "type": "string", "description": "Deprecated alias for client-id. GitHub App ID/client ID (e.g., '${{ vars.APP_ID }}').", - "examples": [ - "${{ vars.APP_ID }}" - ] + "examples": ["${{ vars.APP_ID }}"] }, "client-id": { "type": "string", "description": "GitHub App client ID (e.g., '${{ vars.APP_ID }}'). Required to mint a GitHub App token.", - "examples": [ - "${{ vars.APP_ID }}" - ] + "examples": ["${{ vars.APP_ID }}"] }, "private-key": { "type": "string", "description": "GitHub App private key (e.g., '${{ secrets.APP_PRIVATE_KEY }}'). Required to mint a GitHub App token.", - "examples": [ - "${{ secrets.APP_PRIVATE_KEY }}" - ] + "examples": ["${{ secrets.APP_PRIVATE_KEY }}"] }, "ignore-if-missing": { "type": "boolean", @@ -12514,16 +10936,10 @@ }, "anyOf": [ { - "required": [ - "client-id", - "private-key" - ] + "required": ["client-id", "private-key"] }, { - "required": [ - "app-id", - "private-key" - ] + "required": ["app-id", "private-key"] } ], "additionalProperties": false, @@ -12638,14 +11054,10 @@ "additionalProperties": false, "anyOf": [ { - "required": [ - "uses" - ] + "required": ["uses"] }, { - "required": [ - "run" - ] + "required": ["run"] } ] }, @@ -12657,56 +11069,34 @@ "repository": { "type": "string", "description": "Repository to checkout in owner/repo format. Defaults to the current repository.", - "examples": [ - "owner/repo", - "github/gh-aw" - ] + "examples": ["owner/repo", "github/gh-aw"] }, "ref": { "type": "string", "description": "Branch, tag, or SHA to checkout. Defaults to the ref that triggered the workflow.", - "examples": [ - "main", - "v1.0.0", - "feature/my-branch" - ] + "examples": ["main", "v1.0.0", "feature/my-branch"] }, "path": { "type": "string", "description": "Relative path within GITHUB_WORKSPACE to place the checkout. Defaults to the workspace root.", - "examples": [ - ".", - "./libs/other-repo", - "./workspace" - ] + "examples": [".", "./libs/other-repo", "./workspace"] }, "fetch-depth": { "type": "integer", "minimum": 0, "description": "Number of commits to fetch. 0 fetches all history. 1 (default) is a shallow clone. When multiple configs target the same path, the deepest value is used.", - "examples": [ - 0, - 1, - 10 - ] + "examples": [0, 1, 10] }, "sparse-checkout": { "type": "string", "description": "Enable sparse-checkout with newline-separated patterns. When multiple configs target the same path, patterns are merged.", - "examples": [ - ".github/\nsrc/", - "docs/" - ] + "examples": [".github/\nsrc/", "docs/"] }, "submodules": { "oneOf": [ { "type": "string", - "enum": [ - "recursive", - "true", - "false" - ] + "enum": ["recursive", "true", "false"] }, { "type": "boolean" @@ -12721,18 +11111,12 @@ "token": { "type": "string", "description": "Deprecated: Use github-token instead. GitHub token for authentication. Credentials are always removed after checkout (persist-credentials: false is enforced).", - "examples": [ - "${{ secrets.MY_PAT }}", - "${{ secrets.GITHUB_TOKEN }}" - ] + "examples": ["${{ secrets.MY_PAT }}", "${{ secrets.GITHUB_TOKEN }}"] }, "github-token": { "type": "string", "description": "GitHub token for authentication. Use ${{ secrets.MY_TOKEN }} to reference a secret. Mutually exclusive with github-app (and deprecated app). Credentials are always removed after checkout (persist-credentials: false is enforced).", - "examples": [ - "${{ secrets.MY_PAT }}", - "${{ secrets.CROSS_REPO_PAT }}" - ] + "examples": ["${{ secrets.MY_PAT }}", "${{ secrets.CROSS_REPO_PAT }}"] }, "github-app": { "$ref": "#/$defs/github_app", @@ -12757,37 +11141,17 @@ } ], "description": "Additional Git refs to fetch after the checkout. Supported values: \"*\" (all branches), \"refs/pulls/open/*\" (all open pull-request refs), branch names (e.g. \"main\"), or glob patterns (e.g. \"feature/*\").", - "examples": [ - [ - "*" - ], - [ - "refs/pulls/open/*" - ], - [ - "main", - "feature/my-branch" - ], - [ - "feature/*" - ] - ] + "examples": [["*"], ["refs/pulls/open/*"], ["main", "feature/my-branch"], ["feature/*"]] }, "wiki": { "type": "boolean", "description": "When true, clones the repository's wiki git instead of the regular repository. The effective repository becomes \"{repository}.wiki\" (e.g. \"owner/repo.wiki\"). Defaults to false.", - "examples": [ - true, - false - ] + "examples": [true, false] }, "force-clean-git-credentials": { "type": "boolean", "description": "When true, persist credentials during checkout, then immediately run a post-checkout cleanup step that removes credentials from root and submodule git configs. Useful for submodule-safe cleanup behavior.", - "examples": [ - true, - false - ] + "examples": [true, false] } } }, @@ -12798,169 +11162,97 @@ "properties": { "actions": { "type": "string", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "description": "Permission for GitHub Actions workflows and runs (read: view workflows, write: manage workflows, none: no access)" }, "attestations": { "type": "string", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "description": "Permission for artifact attestations (read: view attestations, write: create attestations, none: no access)" }, "checks": { "type": "string", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "description": "Permission for repository checks and status checks (read: view checks, write: create/update checks, none: no access)" }, "contents": { "type": "string", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "description": "Permission for repository contents (read: view files, write: modify files/branches, none: no access)" }, "deployments": { "type": "string", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "description": "Permission for repository deployments (read: view deployments, write: create/update deployments, none: no access)" }, "discussions": { "type": "string", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "description": "Permission for repository discussions (read: view discussions, write: create/update discussions, none: no access)" }, "id-token": { "type": "string", - "enum": [ - "write", - "none" - ], + "enum": ["write", "none"], "description": "Permission level for OIDC token requests (write/none only - read is not supported). Allows workflows to request JWT tokens for cloud provider authentication." }, "issues": { "type": "string", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "description": "Permission for repository issues (read: view issues, write: create/update/close issues, none: no access)" }, "models": { "type": "string", - "enum": [ - "read", - "none" - ], + "enum": ["read", "none"], "description": "Permission for GitHub Copilot models (read: access AI models for agentic workflows, none: no access)" }, "metadata": { "type": "string", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "description": "Permission for repository metadata (read: view repository information, write: update repository metadata, none: no access)" }, "packages": { "type": "string", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "description": "Permission level for GitHub Packages (read/write/none). Controls access to publish, modify, or delete packages." }, "pages": { "type": "string", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "description": "Permission level for GitHub Pages (read/write/none). Controls access to deploy and manage GitHub Pages sites." }, "pull-requests": { "type": "string", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "description": "Permission level for pull requests (read/write/none). Controls access to create, edit, review, and manage pull requests." }, "repository-projects": { "type": "string", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "description": "Permission level for repository projects (read/write/none). Controls access to manage repository-level GitHub Projects boards." }, "organization-projects": { "type": "string", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "description": "Permission level for organization projects (read/write/none). Controls access to manage organization-level GitHub Projects boards." }, "security-events": { "type": "string", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "description": "Permission level for security events (read/write/none). Controls access to view and manage code scanning alerts and security findings." }, "statuses": { "type": "string", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "description": "Permission level for commit statuses (read/write/none). Controls access to create and update commit status checks." }, "vulnerability-alerts": { "type": "string", - "enum": [ - "read", - "write", - "none" - ], + "enum": ["read", "write", "none"], "description": "Permission level for Dependabot vulnerability alerts (read/write/none). Allows workflows to access the Dependabot alerts API via GITHUB_TOKEN instead of requiring a PAT or GitHub App." }, "all": { "type": "string", - "enum": [ - "read" - ], + "enum": ["read"], "description": "Permission shorthand that applies read access to all permission scopes. Can be combined with specific write permissions to override individual scopes. 'write' is not allowed for all." } } @@ -12972,271 +11264,152 @@ "properties": { "administration": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for repository administration (read/none; \"write\" is rejected by the compiler). GitHub App-only permission for repository administration." }, "codespaces": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for Codespaces (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "codespaces-lifecycle-admin": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for Codespaces lifecycle administration (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "codespaces-metadata": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for Codespaces metadata (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "email-addresses": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for user email addresses (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "environments": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for repository environments (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "git-signing": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for git signing (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "members": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for organization members (read/none; \"write\" is rejected by the compiler). Required for org team membership API calls." }, "organization-administration": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for organization administration (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "organization-announcement-banners": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for organization announcement banners (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "organization-codespaces": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for organization Codespaces (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "organization-copilot": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for organization Copilot (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "organization-custom-org-roles": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for organization custom org roles (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "organization-custom-properties": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for organization custom properties (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "organization-custom-repository-roles": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for organization custom repository roles (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "organization-events": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for organization events (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "organization-hooks": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for organization webhooks (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "organization-members": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for organization members management (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "organization-packages": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for organization packages (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "organization-personal-access-token-requests": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for organization personal access token requests (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "organization-personal-access-tokens": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for organization personal access tokens (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "organization-plan": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for organization plan (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "organization-self-hosted-runners": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for organization self-hosted runners (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "organization-user-blocking": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for organization user blocking (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "repository-custom-properties": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for repository custom properties (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "repository-hooks": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for repository webhooks (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "single-file": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for single file access (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "team-discussions": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for team discussions (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." }, "vulnerability-alerts": { "type": "string", - "enum": [ - "read", - "none" - ], + "enum": ["read", "none"], "description": "Permission level for Dependabot vulnerability alerts (read/none; \"write\" is rejected by the compiler). Also available as a GITHUB_TOKEN scope. When used with a GitHub App, forwarded as permission-vulnerability-alerts input." }, "workflows": { "type": "string", - "enum": [ - "read", - "none", - "write" - ], + "enum": ["read", "none", "write"], "description": "Permission level for GitHub Actions workflow files (read/none; \"write\" is rejected by the compiler). GitHub App-only permission." } }, diff --git a/pkg/workflow/safe_outputs_app_config.go b/pkg/workflow/safe_outputs_app_config.go index b035d2818f3..ff228c7e87b 100644 --- a/pkg/workflow/safe_outputs_app_config.go +++ b/pkg/workflow/safe_outputs_app_config.go @@ -127,8 +127,8 @@ func extractWrappedGitHubExpression(value string) (string, bool) { } // buildGitHubExpressionNonEmptyCheck renders a non-empty check node from wrapped -// expressions (`${{ secrets.KEY }}` -> `secrets.KEY != ''`) or literals -// (`plain-value` -> `'plain-value' != ''`). +// expressions (`${{ secrets.KEY }}` -> `secrets.KEY != ”`) or literals +// (`plain-value` -> `'plain-value' != ”`). func buildGitHubExpressionNonEmptyCheck(value string) ConditionNode { trimmed := strings.TrimSpace(value) if inner, ok := extractWrappedGitHubExpression(trimmed); ok { diff --git a/specs/forecast-compliance-fixtures/README.md b/specs/forecast-compliance-fixtures/README.md new file mode 100644 index 00000000000..a8539519f67 --- /dev/null +++ b/specs/forecast-compliance-fixtures/README.md @@ -0,0 +1,70 @@ +# Forecast Compliance Fixtures + +This directory contains fixture files for bootstrapping the Section 12 compliance tests of the +[Forecast Specification](../../docs/src/content/docs/reference/forecast-specification.md). + +## Fixture Files + +### `run_summary_minimal.json` + +A minimal `run_summary.json` fixture conforming to the `RunSummary` schema used by `pkg/cli/`. +This fixture represents a single successful workflow run (`daily-report`) with: + +- `conclusion: "success"` — the run is counted as successful in Bernoulli sampling +- `token_usage_summary.total_effective_tokens: 5400` — the ET observation used in bootstrap resampling +- `run.updated_at` and `run.run_started_at` — used to compute `duration_seconds` + +Use this fixture as the baseline for Monte Carlo engine compliance tests (**T-FC-031** through +**T-FC-040**) by loading it as a cached run summary. + +## How to Run Compliance Tests + +The forecast compliance tests are located in `pkg/cli/forecast_montecarlo_test.go` and +`pkg/cli/forecast_test.go`. + +To run the full forecast compliance test suite: + +```bash +go test -v -run "TestForecast" ./pkg/cli/ +``` + +To run only the Monte Carlo engine tests (covering T-FC-031–T-FC-040): + +```bash +go test -v -run "TestMonteCarlo" ./pkg/cli/ +``` + +To run with the race detector (recommended for CI): + +```bash +go test -race -run "TestForecast|TestMonteCarlo" ./pkg/cli/ +``` + +## Fixture Schema Reference + +The `run_summary_minimal.json` fixture follows the `RunSummary` struct defined in +`pkg/cli/logs_models.go`. Key fields used by the forecast command: + +| JSON Field | Go Field | Forecast Usage | +|---|---|---| +| `run.conclusion` | `Run.Conclusion` | Bernoulli success probability | +| `run.updated_at` | `Run.UpdatedAt` | Duration computation | +| `run.run_started_at` | `Run.RunStartedAt` | Duration computation | +| `token_usage_summary.total_effective_tokens` | `TokenUsage.TotalEffectiveTokens` | Bootstrap ET sample | +| `run_id` | `RunID` | Run identification | + +## Adding New Fixtures + +To add a fixture covering a specific compliance scenario: + +1. Copy `run_summary_minimal.json` and modify the relevant fields. +2. Name the fixture descriptively (e.g., `run_summary_zero_et.json` for T-FC-022). +3. Document the fixture purpose and the test IDs it covers in this README. + +### Recommended Additional Fixtures + +| Fixture Name | Purpose | Test IDs | +|---|---|---| +| `run_summary_zero_et.json` | Run with missing/zero ET (artifact not downloaded) | T-FC-022 | +| `run_summary_failed.json` | Run with `conclusion: "failure"` for Bernoulli sampling | T-FC-035 | +| `run_summary_high_et.json` | Run with very high ET (≥ 1,000,000) for overflow checks | T-ET-006 | diff --git a/specs/forecast-compliance-fixtures/run_summary_minimal.json b/specs/forecast-compliance-fixtures/run_summary_minimal.json new file mode 100644 index 00000000000..e235c590cf2 --- /dev/null +++ b/specs/forecast-compliance-fixtures/run_summary_minimal.json @@ -0,0 +1,55 @@ +{ + "cli_version": "0.0.0-test", + "run_id": 12345678, + "processed_at": "2026-05-01T12:00:00Z", + "run": { + "id": 12345678, + "name": "daily-report", + "workflow_id": 98765, + "head_branch": "main", + "head_sha": "abc123def456abc123def456abc123def456abc123", + "status": "completed", + "conclusion": "success", + "created_at": "2026-05-01T11:00:00Z", + "updated_at": "2026-05-01T11:05:30Z", + "run_started_at": "2026-05-01T11:00:05Z" + }, + "metrics": { + "total_steps": 5, + "failed_steps": 0, + "tool_calls": 12 + }, + "access_analysis": null, + "firewall_analysis": null, + "redacted_domains_analysis": null, + "missing_tools": [], + "missing_data": [], + "noops": [], + "mcp_failures": [], + "artifacts_list": [], + "job_details": [], + "token_usage_summary": { + "total_input_tokens": 4500, + "total_output_tokens": 1200, + "total_cache_read_tokens": 800, + "total_cache_write_tokens": 200, + "total_requests": 3, + "total_duration_ms": 18500, + "total_response_bytes": 24680, + "cache_efficiency": 0.1778, + "total_effective_tokens": 5400, + "by_model": { + "claude-3-7-sonnet": { + "provider": "anthropic", + "input_tokens": 4500, + "output_tokens": 1200, + "cache_read_tokens": 800, + "cache_write_tokens": 200, + "requests": 3, + "duration_ms": 18500, + "response_bytes": 24680, + "effective_tokens": 5400 + } + } + } +}