From 0220dfcc75c56f37a943ed58177e35391528bf16 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 28 Apr 2026 01:07:24 +0000 Subject: [PATCH 1/3] Initial plan From bfb97c372a03e48e3bf8d4a7da78543d0b87293e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 28 Apr 2026 01:22:47 +0000 Subject: [PATCH 2/3] feat: right-size schema-consistency-checker with max-turns cap and pre-computed schema diff step - Add max-turns: 60 to engine config (was unconstrained, causing 138-turn runs) - Add checkout: fetch-depth: 1, current: true for clean repo state - Add pre-agent-steps with deterministic bash script that pre-computes: - All schema top-level fields (jq) - All yaml-tagged struct fields from pkg/parser and pkg/workflow (grep) - All frontmatter keys used in .github/workflows/*.md - Schema field types - Field gap diffs (in_schema_not_parser, in_parser_not_schema, etc.) - Writes result to /tmp/gh-aw/agent/schema-diff.json - Update Implementation Steps to instruct agent to start from pre-computed data - Update Efficiency guidelines to reinforce use of pre-computed data Fixes: #28688 (deep-report right-size schema consistency checker)" Agent-Logs-Url: https://github.com/github/gh-aw/sessions/db6101c0-1700-4f5b-a09d-e116df370705 Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- .../schema-consistency-checker.lock.yml | 32 ++-- .../workflows/schema-consistency-checker.md | 166 +++++++++++++++--- .../docs/reference/frontmatter-full.md | 3 +- 3 files changed, 166 insertions(+), 35 deletions(-) diff --git a/.github/workflows/schema-consistency-checker.lock.yml b/.github/workflows/schema-consistency-checker.lock.yml index 803d4340c30..c771c6a5656 100644 --- a/.github/workflows/schema-consistency-checker.lock.yml +++ b/.github/workflows/schema-consistency-checker.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"6f90e7274ba80e81842cde62b899f683b295eed4a66b79d4e10b6c1a4797fb66","strict":true,"agent_id":"claude"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"e36a5d8caa19e2de4c3a9f4678451759685ce867732a7d7675a9897db296a384","strict":true,"agent_id":"claude"} # gh-aw-manifest: {"version":1,"secrets":["ANTHROPIC_API_KEY","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_ENDPOINT","GH_AW_OTEL_HEADERS","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/setup-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.28","digest":"sha256:a8834e285807654bf680154faa710d43fe4365a0868142f5c20e48c85e137a7a","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.25.28@sha256:a8834e285807654bf680154faa710d43fe4365a0868142f5c20e48c85e137a7a"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.28","digest":"sha256:93290f2393752252911bd7c39a047f776c0b53063575e7bde4e304962a9a61cb","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.28@sha256:93290f2393752252911bd7c39a047f776c0b53063575e7bde4e304962a9a61cb"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.28","digest":"sha256:844c18280f82cd1b06345eb2f4e91966b34185bfc51c9f237c3e022e848fb474","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.25.28@sha256:844c18280f82cd1b06345eb2f4e91966b34185bfc51c9f237c3e022e848fb474"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.0"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]} # ___ _ _ # / _ \ | | (_) @@ -192,15 +192,15 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_7a368a1c473b9485_EOF' + cat << 'GH_AW_PROMPT_d984ba9ebca19fc3_EOF' - GH_AW_PROMPT_7a368a1c473b9485_EOF + GH_AW_PROMPT_d984ba9ebca19fc3_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_7a368a1c473b9485_EOF' + cat << 'GH_AW_PROMPT_d984ba9ebca19fc3_EOF' Tools: create_discussion, missing_tool, missing_data, noop @@ -230,16 +230,19 @@ jobs: {{#if __GH_AW_GITHUB_RUN_ID__ }} - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ {{/if}} + - **checkouts**: The following repositories have been checked out and are available in the workspace: + - `$GITHUB_WORKSPACE` → `__GH_AW_GITHUB_REPOSITORY__` (cwd) (**current** - this is the repository you are working on; use this as the target for all GitHub operations unless otherwise specified) [shallow clone, fetch-depth=1] + - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it without proper authentication. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). - GH_AW_PROMPT_7a368a1c473b9485_EOF + GH_AW_PROMPT_d984ba9ebca19fc3_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_7a368a1c473b9485_EOF' + cat << 'GH_AW_PROMPT_d984ba9ebca19fc3_EOF' {{#runtime-import .github/workflows/shared/reporting.md}} {{#runtime-import .github/workflows/shared/observability-otlp.md}} {{#runtime-import .github/workflows/schema-consistency-checker.md}} - GH_AW_PROMPT_7a368a1c473b9485_EOF + GH_AW_PROMPT_d984ba9ebca19fc3_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 @@ -367,6 +370,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false + fetch-depth: 1 - name: Create gh-aw temp directory run: bash "${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh" - name: Configure gh CLI for GitHub Enterprise @@ -445,6 +449,9 @@ jobs: GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode" GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md opencode.jsonc" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" + - name: Pre-compute schema analysis data + run: "set -e\nmkdir -p /tmp/gh-aw/agent\n\necho \"=== Extracting schema fields ===\"\n\n# 1. All top-level fields in the main JSON schema\nSCHEMA_FIELDS=$(jq -r '.properties | keys[]' pkg/parser/schemas/main_workflow_schema.json 2>/dev/null | sort -u || echo \"\")\n\n# 2. yaml-tagged struct fields in pkg/parser/*.go\nPARSER_YAML_FIELDS=$(grep -rh 'yaml:\"' pkg/parser/*.go 2>/dev/null \\\n | grep -o 'yaml:\"[^\"]*\"' \\\n | sed 's/yaml:\"//;s/\"//' \\\n | sed 's/,omitempty//' \\\n | sed 's/,.*$//' \\\n | grep -v '^-$' \\\n | grep -v '^$' \\\n | sort -u || echo \"\")\n\n# 3. yaml-tagged struct fields in pkg/workflow/*.go\nWORKFLOW_YAML_FIELDS=$(grep -rh 'yaml:\"' pkg/workflow/*.go 2>/dev/null \\\n | grep -o 'yaml:\"[^\"]*\"' \\\n | sed 's/yaml:\"//;s/\"//' \\\n | sed 's/,omitempty//' \\\n | sed 's/,.*$//' \\\n | grep -v '^-$' \\\n | grep -v '^$' \\\n | sort -u || echo \"\")\n\n# 4. Top-level frontmatter keys actually used in workflow .md files\nUSED_FIELDS=$(grep -rh '^[a-z][a-z0-9_-]*:' .github/workflows/*.md 2>/dev/null \\\n | sed 's/:.*//' \\\n | grep -v '^#' \\\n | sort -u || echo \"\")\n\n# 5. Schema field types for all top-level fields\nFIELD_TYPES=$(jq -r '.properties | to_entries[] |\n \"\\(.key): \\(.value.type // (.value.anyOf // .value.oneOf // [] | map(.type // \"complex\") | unique | join(\"|\")) // \"complex\")\"' \\\n pkg/parser/schemas/main_workflow_schema.json 2>/dev/null | sort || echo \"\")\n\n# 6. Fields in schema but absent as yaml tags in parser structs\nIN_SCHEMA_NOT_PARSER=$(comm -23 \\\n <(echo \"$SCHEMA_FIELDS\") \\\n <(echo \"$PARSER_YAML_FIELDS\" | sort -u) 2>/dev/null || echo \"\")\n\n# 7. yaml tags in parser structs absent from schema\nIN_PARSER_NOT_SCHEMA=$(comm -23 \\\n <(echo \"$PARSER_YAML_FIELDS\" | sort -u) \\\n <(echo \"$SCHEMA_FIELDS\") 2>/dev/null || echo \"\")\n\n# 8. Fields in schema but absent from workflow compiler structs\nIN_SCHEMA_NOT_WORKFLOW=$(comm -23 \\\n <(echo \"$SCHEMA_FIELDS\") \\\n <(echo \"$WORKFLOW_YAML_FIELDS\" | sort -u) 2>/dev/null || echo \"\")\n\n# 9. Fields used in actual workflow .md files but not in schema\nIN_USED_NOT_SCHEMA=$(comm -23 \\\n <(echo \"$USED_FIELDS\" | sort -u) \\\n <(echo \"$SCHEMA_FIELDS\") 2>/dev/null || echo \"\")\n\n# Write JSON output\njq -n \\\n --arg generated_at \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\" \\\n --arg schema_fields \"$SCHEMA_FIELDS\" \\\n --arg parser_yaml_fields \"$PARSER_YAML_FIELDS\" \\\n --arg workflow_yaml_fields \"$WORKFLOW_YAML_FIELDS\" \\\n --arg used_in_workflows \"$USED_FIELDS\" \\\n --arg field_types \"$FIELD_TYPES\" \\\n --arg in_schema_not_parser \"$IN_SCHEMA_NOT_PARSER\" \\\n --arg in_parser_not_schema \"$IN_PARSER_NOT_SCHEMA\" \\\n --arg in_schema_not_workflow \"$IN_SCHEMA_NOT_WORKFLOW\" \\\n --arg in_used_not_schema \"$IN_USED_NOT_SCHEMA\" \\\n '{\n generated_at: $generated_at,\n schema_fields: ($schema_fields | split(\"\\n\") | map(select(. != \"\"))),\n parser_yaml_fields: ($parser_yaml_fields | split(\"\\n\") | map(select(. != \"\"))),\n workflow_yaml_fields: ($workflow_yaml_fields | split(\"\\n\") | map(select(. != \"\"))),\n used_in_workflows: ($used_in_workflows | split(\"\\n\") | map(select(. != \"\"))),\n field_types: ($field_types | split(\"\\n\") | map(select(. != \"\"))),\n field_gaps: {\n in_schema_not_parser: ($in_schema_not_parser | split(\"\\n\") | map(select(. != \"\"))),\n in_parser_not_schema: ($in_parser_not_schema | split(\"\\n\") | map(select(. != \"\"))),\n in_schema_not_workflow: ($in_schema_not_workflow | split(\"\\n\") | map(select(. != \"\"))),\n in_used_not_schema: ($in_used_not_schema | split(\"\\n\") | map(select(. != \"\")))\n }\n }' > /tmp/gh-aw/agent/schema-diff.json\n\necho \"✓ Schema diff written to /tmp/gh-aw/agent/schema-diff.json\"\necho \"Summary:\"\njq '{\n schema_field_count: (.schema_fields | length),\n parser_yaml_field_count: (.parser_yaml_fields | length),\n workflow_yaml_field_count: (.workflow_yaml_fields | length),\n gaps: {\n in_schema_not_parser: (.field_gaps.in_schema_not_parser | length),\n in_parser_not_schema: (.field_gaps.in_parser_not_schema | length),\n in_schema_not_workflow: (.field_gaps.in_schema_not_workflow | length),\n in_used_not_schema: (.field_gaps.in_used_not_schema | length)\n }\n}' /tmp/gh-aw/agent/schema-diff.json\n" + - name: Download container images run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.28@sha256:a8834e285807654bf680154faa710d43fe4365a0868142f5c20e48c85e137a7a ghcr.io/github/gh-aw-firewall/api-proxy:0.25.28@sha256:93290f2393752252911bd7c39a047f776c0b53063575e7bde4e304962a9a61cb ghcr.io/github/gh-aw-firewall/squid:0.25.28@sha256:844c18280f82cd1b06345eb2f4e91966b34185bfc51c9f237c3e022e848fb474 ghcr.io/github/gh-aw-mcpg:v0.3.0 node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f - name: Write Safe Outputs Config @@ -452,9 +459,9 @@ jobs: mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_c9048f3b1411df8b_EOF' + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_1747376f246ef114_EOF' {"create_discussion":{"category":"audits","close_older_discussions":true,"expires":24,"fallback_to_issue":true,"max":1,"title_prefix":"[Schema Consistency] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_c9048f3b1411df8b_EOF + GH_AW_SAFE_OUTPUTS_CONFIG_1747376f246ef114_EOF - name: Write Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -645,7 +652,7 @@ jobs: 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 -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -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.0' GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_2b1287f23f45d5c6_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_813566bd3a214c32_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "github": { @@ -691,7 +698,7 @@ jobs: } } } - GH_AW_MCP_CONFIG_2b1287f23f45d5c6_EOF + GH_AW_MCP_CONFIG_813566bd3a214c32_EOF - name: Clean git credentials continue-on-error: true run: bash "${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh" @@ -777,7 +784,7 @@ jobs: (umask 177 && touch /tmp/gh-aw/agent-stdio.log) # shellcheck disable=SC1003 sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --tty --env-all --exclude-env ANTHROPIC_API_KEY --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --allow-domains '*.githubusercontent.com,anthropic.com,api.anthropic.com,api.github.com,api.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,cdn.playwright.dev,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,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.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,playwright.download.prss.microsoft.com,ppa.launchpad.net,pypi.org,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,statsig.anthropic.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com' --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --image-tag 0.25.28,squid=sha256:844c18280f82cd1b06345eb2f4e91966b34185bfc51c9f237c3e022e848fb474,agent=sha256:a8834e285807654bf680154faa710d43fe4365a0868142f5c20e48c85e137a7a,api-proxy=sha256:93290f2393752252911bd7c39a047f776c0b53063575e7bde4e304962a9a61cb,cli-proxy=sha256:fdf310e4678ce58d248c466b89399e9680a3003038fd19322c388559016aaac7 --skip-pull --enable-api-proxy \ - -- /bin/bash -c 'export PATH="$(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 && claude --print --no-chrome --mcp-config "${{ runner.temp }}/gh-aw/mcp-config/mcp-servers.json" --allowed-tools '\''Bash,BashOutput,Edit,Edit(/tmp/gh-aw/cache-memory/*),ExitPlanMode,Glob,Grep,KillBash,LS,MultiEdit,MultiEdit(/tmp/gh-aw/cache-memory/*),NotebookEdit,NotebookRead,Read,Read(/tmp/gh-aw/cache-memory/*),Task,TodoWrite,Write,Write(/tmp/gh-aw/cache-memory/*),mcp__github__download_workflow_run_artifact,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_job_logs,mcp__github__get_label,mcp__github__get_latest_release,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_review_comments,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_release_by_tag,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__get_workflow_run,mcp__github__get_workflow_run_logs,mcp__github__get_workflow_run_usage,mcp__github__issue_read,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issue_types,mcp__github__list_issues,mcp__github__list_label,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_releases,mcp__github__list_secret_scanning_alerts,mcp__github__list_starred_repositories,mcp__github__list_tags,mcp__github__list_workflow_jobs,mcp__github__list_workflow_run_artifacts,mcp__github__list_workflow_runs,mcp__github__list_workflows,mcp__github__pull_request_read,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users,mcp__safeoutputs'\'' --debug-file /tmp/gh-aw/agent-stdio.log --verbose --permission-mode bypassPermissions --output-format stream-json "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_CLAUDE:+ --model "$GH_AW_MODEL_AGENT_CLAUDE"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + -- /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 && claude --print --no-chrome --max-turns 60 --mcp-config "${{ runner.temp }}/gh-aw/mcp-config/mcp-servers.json" --allowed-tools '\''Bash,BashOutput,Edit,Edit(/tmp/gh-aw/cache-memory/*),ExitPlanMode,Glob,Grep,KillBash,LS,MultiEdit,MultiEdit(/tmp/gh-aw/cache-memory/*),NotebookEdit,NotebookRead,Read,Read(/tmp/gh-aw/cache-memory/*),Task,TodoWrite,Write,Write(/tmp/gh-aw/cache-memory/*),mcp__github__download_workflow_run_artifact,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_job_logs,mcp__github__get_label,mcp__github__get_latest_release,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_review_comments,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_release_by_tag,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__get_workflow_run,mcp__github__get_workflow_run_logs,mcp__github__get_workflow_run_usage,mcp__github__issue_read,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issue_types,mcp__github__list_issues,mcp__github__list_label,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_releases,mcp__github__list_secret_scanning_alerts,mcp__github__list_starred_repositories,mcp__github__list_tags,mcp__github__list_workflow_jobs,mcp__github__list_workflow_run_artifacts,mcp__github__list_workflow_runs,mcp__github__list_workflows,mcp__github__pull_request_read,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users,mcp__safeoutputs'\'' --debug-file /tmp/gh-aw/agent-stdio.log --verbose --permission-mode bypassPermissions --output-format stream-json "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_CLAUDE:+ --model "$GH_AW_MODEL_AGENT_CLAUDE"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} BASH_DEFAULT_TIMEOUT_MS: 60000 @@ -785,6 +792,7 @@ jobs: DISABLE_BUG_COMMAND: 1 DISABLE_ERROR_REPORTING: 1 DISABLE_TELEMETRY: 1 + GH_AW_MAX_TURNS: 60 GH_AW_MCP_CONFIG: ${{ runner.temp }}/gh-aw/mcp-config/mcp-servers.json GH_AW_MODEL_AGENT_CLAUDE: ${{ vars.GH_AW_MODEL_AGENT_CLAUDE || '' }} GH_AW_PHASE: agent diff --git a/.github/workflows/schema-consistency-checker.md b/.github/workflows/schema-consistency-checker.md index aa133d5ea9a..43540df9f4d 100644 --- a/.github/workflows/schema-consistency-checker.md +++ b/.github/workflows/schema-consistency-checker.md @@ -8,7 +8,9 @@ permissions: discussions: read issues: read pull-requests: read -engine: claude +engine: + id: claude + max-turns: 60 tools: edit: bash: ["*"] @@ -18,11 +20,116 @@ tools: cache-memory: key: schema-consistency-cache-${{ github.workflow }} timeout-minutes: 30 +checkout: + - fetch-depth: 1 + current: true imports: - uses: shared/daily-audit-base.md with: title-prefix: "[Schema Consistency] " expires: 1d +pre-agent-steps: + - name: Pre-compute schema analysis data + run: | + set -e + mkdir -p /tmp/gh-aw/agent + + echo "=== Extracting schema fields ===" + + # 1. All top-level fields in the main JSON schema + SCHEMA_FIELDS=$(jq -r '.properties | keys[]' pkg/parser/schemas/main_workflow_schema.json 2>/dev/null | sort -u || echo "") + + # 2. yaml-tagged struct fields in pkg/parser/*.go + PARSER_YAML_FIELDS=$(grep -rh 'yaml:"' pkg/parser/*.go 2>/dev/null \ + | grep -o 'yaml:"[^"]*"' \ + | sed 's/yaml:"//;s/"//' \ + | sed 's/,omitempty//' \ + | sed 's/,.*$//' \ + | grep -v '^-$' \ + | grep -v '^$' \ + | sort -u || echo "") + + # 3. yaml-tagged struct fields in pkg/workflow/*.go + WORKFLOW_YAML_FIELDS=$(grep -rh 'yaml:"' pkg/workflow/*.go 2>/dev/null \ + | grep -o 'yaml:"[^"]*"' \ + | sed 's/yaml:"//;s/"//' \ + | sed 's/,omitempty//' \ + | sed 's/,.*$//' \ + | grep -v '^-$' \ + | grep -v '^$' \ + | sort -u || echo "") + + # 4. Top-level frontmatter keys actually used in workflow .md files + USED_FIELDS=$(grep -rh '^[a-z][a-z0-9_-]*:' .github/workflows/*.md 2>/dev/null \ + | sed 's/:.*//' \ + | grep -v '^#' \ + | sort -u || echo "") + + # 5. Schema field types for all top-level fields + FIELD_TYPES=$(jq -r '.properties | to_entries[] | + "\(.key): \(.value.type // (.value.anyOf // .value.oneOf // [] | map(.type // "complex") | unique | join("|")) // "complex")"' \ + pkg/parser/schemas/main_workflow_schema.json 2>/dev/null | sort || echo "") + + # 6. Fields in schema but absent as yaml tags in parser structs + IN_SCHEMA_NOT_PARSER=$(comm -23 \ + <(echo "$SCHEMA_FIELDS") \ + <(echo "$PARSER_YAML_FIELDS" | sort -u) 2>/dev/null || echo "") + + # 7. yaml tags in parser structs absent from schema + IN_PARSER_NOT_SCHEMA=$(comm -23 \ + <(echo "$PARSER_YAML_FIELDS" | sort -u) \ + <(echo "$SCHEMA_FIELDS") 2>/dev/null || echo "") + + # 8. Fields in schema but absent from workflow compiler structs + IN_SCHEMA_NOT_WORKFLOW=$(comm -23 \ + <(echo "$SCHEMA_FIELDS") \ + <(echo "$WORKFLOW_YAML_FIELDS" | sort -u) 2>/dev/null || echo "") + + # 9. Fields used in actual workflow .md files but not in schema + IN_USED_NOT_SCHEMA=$(comm -23 \ + <(echo "$USED_FIELDS" | sort -u) \ + <(echo "$SCHEMA_FIELDS") 2>/dev/null || echo "") + + # Write JSON output + jq -n \ + --arg generated_at "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ + --arg schema_fields "$SCHEMA_FIELDS" \ + --arg parser_yaml_fields "$PARSER_YAML_FIELDS" \ + --arg workflow_yaml_fields "$WORKFLOW_YAML_FIELDS" \ + --arg used_in_workflows "$USED_FIELDS" \ + --arg field_types "$FIELD_TYPES" \ + --arg in_schema_not_parser "$IN_SCHEMA_NOT_PARSER" \ + --arg in_parser_not_schema "$IN_PARSER_NOT_SCHEMA" \ + --arg in_schema_not_workflow "$IN_SCHEMA_NOT_WORKFLOW" \ + --arg in_used_not_schema "$IN_USED_NOT_SCHEMA" \ + '{ + generated_at: $generated_at, + schema_fields: ($schema_fields | split("\n") | map(select(. != ""))), + parser_yaml_fields: ($parser_yaml_fields | split("\n") | map(select(. != ""))), + workflow_yaml_fields: ($workflow_yaml_fields | split("\n") | map(select(. != ""))), + used_in_workflows: ($used_in_workflows | split("\n") | map(select(. != ""))), + field_types: ($field_types | split("\n") | map(select(. != ""))), + field_gaps: { + in_schema_not_parser: ($in_schema_not_parser | split("\n") | map(select(. != ""))), + in_parser_not_schema: ($in_parser_not_schema | split("\n") | map(select(. != ""))), + in_schema_not_workflow: ($in_schema_not_workflow | split("\n") | map(select(. != ""))), + in_used_not_schema: ($in_used_not_schema | split("\n") | map(select(. != ""))) + } + }' > /tmp/gh-aw/agent/schema-diff.json + + echo "✓ Schema diff written to /tmp/gh-aw/agent/schema-diff.json" + echo "Summary:" + jq '{ + schema_field_count: (.schema_fields | length), + parser_yaml_field_count: (.parser_yaml_fields | length), + workflow_yaml_field_count: (.workflow_yaml_fields | length), + gaps: { + in_schema_not_parser: (.field_gaps.in_schema_not_parser | length), + in_parser_not_schema: (.field_gaps.in_parser_not_schema | length), + in_schema_not_workflow: (.field_gaps.in_schema_not_workflow | length), + in_used_not_schema: (.field_gaps.in_used_not_schema | length) + } + }' /tmp/gh-aw/agent/schema-diff.json --- # Schema Consistency Checker @@ -178,6 +285,27 @@ Here are proven strategies you can use or build upon: ## Implementation Steps +### Step 0: Read Pre-Computed Data (Start Here) + +Before doing anything else, read the schema diff that was computed before your session began: + +```bash +cat /tmp/gh-aw/agent/schema-diff.json +``` + +This file contains: +- `schema_fields`: All top-level field names in the main JSON schema +- `parser_yaml_fields`: All yaml-tagged struct fields in `pkg/parser/*.go` +- `workflow_yaml_fields`: All yaml-tagged struct fields in `pkg/workflow/*.go` +- `used_in_workflows`: All top-level frontmatter keys used in `.github/workflows/*.md` +- `field_types`: Schema field types for all top-level fields +- `field_gaps.in_schema_not_parser`: Fields in schema absent from parser yaml tags +- `field_gaps.in_parser_not_schema`: Fields as parser yaml tags absent from schema +- `field_gaps.in_schema_not_workflow`: Fields in schema absent from workflow compiler yaml tags +- `field_gaps.in_used_not_schema`: Fields used in workflow files but not in schema + +**Use this pre-computed data as your primary starting point.** Do NOT re-run the field enumeration commands from scratch — instead, refine and supplement the pre-computed data with targeted follow-up queries (e.g., checking a specific file for a specific field). + ### Step 1: Load Previous Strategies ```bash # Check if strategies file exists @@ -186,30 +314,25 @@ if [ -f /tmp/gh-aw/cache-memory/strategies.json ]; then fi ``` -### Step 2: Choose Strategy -- If cache exists and has strategies, use proven strategy 70% of time -- Otherwise or 30% of time, try new/different approach +### Step 2: Choose Analysis Focus -### Step 3: Execute Analysis -Use chosen strategy to find inconsistencies. Examples: +Using the pre-computed `field_gaps` from Step 0 plus the strategy cache from Step 1: +- If `field_gaps` show promising leads, start there (they are likely high-signal) +- If cache has strategies, use a proven strategy 70% of the time; try a new approach 30% of the time +- Use the day of year modulo 10 (`date +%j` mod 10): values 0-6 → proven strategy, 7-9 → new approach -**Example: Field enumeration** -```bash -# Extract schema fields using jq for robust JSON parsing -jq -r '.properties | keys[]' pkg/parser/schemas/main_workflow_schema.json 2>/dev/null | sort -u +### Step 3: Execute Targeted Analysis -# Extract parser fields from pkg/parser (look for yaml tags) -grep -r "yaml:\"" pkg/parser/*.go | grep -o 'yaml:"[^"]*"' | sort -u +Use the pre-computed data as context and run **targeted** follow-up commands only when +deeper inspection is needed (e.g., checking how a specific field is actually processed in code). -# Extract workflow compiler fields from pkg/workflow (look for yaml tags and frontmatter access) -grep -r "yaml:\"" pkg/workflow/*.go | grep -o 'yaml:"[^"]*"' | sort -u -grep -r 'frontmatter\["[^"]*"\]' pkg/workflow/*.go | grep -o '\["[^"]*"\]' | sort -u - -# Extract documented fields -grep -r "^###\? " docs/src/content/docs/reference/frontmatter.md +**Example: Verify a gap from pre-computed data** +```bash +# Verify a specific field gap by searching implementation files +grep -r "fieldName" pkg/parser/ pkg/workflow/ 2>/dev/null | grep -v "_test.go" ``` -**Example: Type checking** +**Example: Type checking for a specific field** ```bash # Find schema field types (handles different JSON Schema patterns) jq -r ' @@ -330,10 +453,11 @@ Create a well-structured discussion report: - Suggest concrete fixes ### Efficiency -- Use bash tools efficiently (grep, jq, etc.) +- **Always start from `/tmp/gh-aw/agent/schema-diff.json`** — this pre-computed diff eliminates the need to re-read all source files +- Use targeted bash commands to verify specific leads from the pre-computed data - Cache results when re-analyzing same data - Don't re-check things found in previous runs (check cache first) -- Focus on high-impact areas +- Focus on high-impact areas (field gaps with parser mismatches are usually most critical) ### Strategy Evolution - Try genuinely different approaches when not using cached strategies diff --git a/docs/src/content/docs/reference/frontmatter-full.md b/docs/src/content/docs/reference/frontmatter-full.md index a308f718e79..7ba4d00e9c0 100644 --- a/docs/src/content/docs/reference/frontmatter-full.md +++ b/docs/src/content/docs/reference/frontmatter-full.md @@ -825,12 +825,11 @@ on: # Option 1: Single label name that must match the triggering label (e.g., # 'panel-review') - labels: "example-value" # Option 2: List of label names; the workflow fires when the triggering label # matches any entry. labels: [] - # Array items: Label name (e.g., 'panel-review', 'needs-triage') + # Array items: undefined # Environment name that requires manual approval before the workflow can run. Must # match a valid environment configured in the repository settings. From c2bf366fc1ececdf697d678ac411e3e6535b3928 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 28 Apr 2026 01:27:19 +0000 Subject: [PATCH 3/3] fix: restore frontmatter-full.md labels description and clarify strategy selection bash snippet Agent-Logs-Url: https://github.com/github/gh-aw/sessions/db6101c0-1700-4f5b-a09d-e116df370705 Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- .github/workflows/schema-consistency-checker.md | 11 ++++++++++- docs/src/content/docs/reference/frontmatter-full.md | 3 ++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/schema-consistency-checker.md b/.github/workflows/schema-consistency-checker.md index 43540df9f4d..03fc9101208 100644 --- a/.github/workflows/schema-consistency-checker.md +++ b/.github/workflows/schema-consistency-checker.md @@ -319,7 +319,16 @@ fi Using the pre-computed `field_gaps` from Step 0 plus the strategy cache from Step 1: - If `field_gaps` show promising leads, start there (they are likely high-signal) - If cache has strategies, use a proven strategy 70% of the time; try a new approach 30% of the time -- Use the day of year modulo 10 (`date +%j` mod 10): values 0-6 → proven strategy, 7-9 → new approach + +```bash +# Determine selection mode (0-6 = proven strategy, 7-9 = new approach) +day_mod=$(( $(date +%j) % 10 )) +if [ "$day_mod" -le 6 ]; then + echo "Use proven strategy from cache" +else + echo "Try new approach" +fi +``` ### Step 3: Execute Targeted Analysis diff --git a/docs/src/content/docs/reference/frontmatter-full.md b/docs/src/content/docs/reference/frontmatter-full.md index 7ba4d00e9c0..a308f718e79 100644 --- a/docs/src/content/docs/reference/frontmatter-full.md +++ b/docs/src/content/docs/reference/frontmatter-full.md @@ -825,11 +825,12 @@ on: # Option 1: Single label name that must match the triggering label (e.g., # 'panel-review') + labels: "example-value" # Option 2: List of label names; the workflow fires when the triggering label # matches any entry. labels: [] - # Array items: undefined + # Array items: Label name (e.g., 'panel-review', 'needs-triage') # Environment name that requires manual approval before the workflow can run. Must # match a valid environment configured in the repository settings.