diff --git a/.github/workflows/opencode-review.yml b/.github/workflows/opencode-review.yml index 1e17bb067..37995a5d0 100644 --- a/.github/workflows/opencode-review.yml +++ b/.github/workflows/opencode-review.yml @@ -1810,7 +1810,10 @@ jobs: local strix_running # Exclude this OpenCode check run; otherwise the evidence step would - # wait on itself until the bounded retry budget is exhausted. + # wait on itself until the bounded retry budget is exhausted. The + # metadata-only gate also depends on this review and GitHub can + # attribute its check run to CodeQL rather than PR Governance, so + # identify that review-state helper by check name, not workflow. # shellcheck disable=SC2016 if ! rollup_running="$(timeout "${OPENCODE_EVIDENCE_GH_API_TIMEOUT_SECONDS:-30}s" gh api graphql \ -f owner="$owner" \ @@ -1855,6 +1858,7 @@ jobs: | select((.name // "") != "OpenCode Review") | select((.name // "") != "Required OpenCode Review") | select((.name // "") != "OpenCode PR Review") + | select((.name // "") != "metadata-only gate evaluation") | select((.checkSuite.workflowRun.workflow.name // "") != "OpenCode Review") | select((.checkSuite.workflowRun.workflow.name // "") != "Required OpenCode Review") | select((.checkSuite.workflowRun.workflow.name // "") != "OpenCode PR Review") @@ -3735,7 +3739,7 @@ jobs: self_check_filter=' def self_check: (.name // "") as $n - | ["opencode-review", "coverage-evidence", "coverage-source-tree", "required-workflow-bootstrap"] | index($n); + | ["opencode-review", "coverage-evidence", "coverage-source-tree", "required-workflow-bootstrap", "metadata-only gate evaluation"] | index($n); def latest_peer_checks: [ (.check_runs // [])[] diff --git a/scripts/ci/test_strix_quick_gate.sh b/scripts/ci/test_strix_quick_gate.sh index f59152074..8d97ee065 100755 --- a/scripts/ci/test_strix_quick_gate.sh +++ b/scripts/ci/test_strix_quick_gate.sh @@ -904,11 +904,12 @@ assert_opencode_review_uses_codegraph_and_gpt5_fallback() { assert_file_contains "$REPO_ROOT/scripts/ci/collect_failed_check_evidence.sh" '(.name // "") == "scan-pr-queue" and ((.checkSuite.workflowRun.workflow.name // "") == "PR Review Merge Scheduler" or (.checkSuite.workflowRun.workflow.name // "") == "Required PR Review Merge Scheduler")' "failed-check evidence ignores cancelled scheduler queue replacement checks" assert_file_contains "$REPO_ROOT/scripts/ci/collect_failed_check_evidence.sh" '((.name // "") | contains("${{"))' "failed-check evidence ignores cancelled matrix-template helper checks without logs" assert_file_contains "$REPO_ROOT/scripts/ci/collect_failed_check_evidence.sh" '(.name // "") == "noema-review"' "failed-check evidence ignores cancelled Noema queue replacement checks without source logs" - assert_file_contains "$workflow_file" 'select((.name // "") != "metadata-only gate evaluation")' "opencode failed-check collection ignores metadata-only review-state gates regardless of workflow attribution" + assert_file_contains "$workflow_file" 'select((.name // "") != "metadata-only gate evaluation")' "opencode ignores metadata-only review-state gates without trusting GitHub workflow attribution" metadata_gate_filter_count="$(grep -Fc 'select((.name // "") != "metadata-only gate evaluation")' "$workflow_file")" - if [ "$metadata_gate_filter_count" -lt 2 ]; then - fail "opencode failed- and pending-check collection both ignore metadata-only PR Governance review-state gates (found ${metadata_gate_filter_count}, expected at least 2)" + if [ "$metadata_gate_filter_count" -lt 3 ]; then + fail "opencode pre-model, failed-check, and pending-check collection all ignore metadata-only review-state gates (found ${metadata_gate_filter_count}, expected at least 3)" fi + assert_file_contains "$workflow_file" '["opencode-review", "coverage-evidence", "coverage-source-tree", "required-workflow-bootstrap", "metadata-only gate evaluation"]' "central fast approval ignores its dependent metadata-only review-state gate" assert_file_contains "$workflow_file" '["opencode-review","coverage-evidence","metadata-only gate evaluation"]' "opencode supplemental check-run collection ignores review-state helper gates" assert_file_contains "$workflow_file" '((.name // "") | contains("$" + "{{"))' "opencode failed-check collection ignores cancelled matrix-template helper checks without logs without exposing a raw Actions expression" assert_file_contains "$workflow_file" '(.name // "") == "noema-review"' "opencode failed-check collection ignores cancelled Noema queue replacement checks without source logs" diff --git a/tests/test_opencode_agent_contract.py b/tests/test_opencode_agent_contract.py index b259188b0..6b1bd0241 100644 --- a/tests/test_opencode_agent_contract.py +++ b/tests/test_opencode_agent_contract.py @@ -844,7 +844,7 @@ def test_workflow_provisions_sandbox_tool_and_reviewer_agent(): assert not re.search(r"--slurp\s*\\\n\s*--jq", workflow) assert workflow.count('["opencode-review","coverage-evidence","metadata-only gate evaluation"]') >= 2 metadata_gate_filter = 'select((.name // "") != "metadata-only gate evaluation")' - assert workflow.count(metadata_gate_filter) >= 2 + assert workflow.count(metadata_gate_filter) >= 3 failed_check_collector = Path( "scripts/ci/collect_failed_check_evidence.sh" ).read_text(encoding="utf-8") @@ -854,6 +854,11 @@ def test_workflow_provisions_sandbox_tool_and_reviewer_agent(): '(.checkSuite.workflowRun.workflow.name // "") == "PR Governance"' not in failed_check_collector ) + assert ( + '["opencode-review", "coverage-evidence", "coverage-source-tree", ' + '"required-workflow-bootstrap", "metadata-only gate evaluation"]' + in workflow + ) assert "falling back to current-head REST check-runs" in workflow strix_workflow = Path(".github/workflows/strix.yml").read_text(encoding="utf-8")