Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 36 additions & 2 deletions .github/workflows/opencode-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6259,8 +6259,42 @@ jobs:
return 0
fi

printf '::notice::MODEL_OUTPUT_UNAVAILABLE: current-head checks and alerts are clean, but no APPROVE review will be published without mandatory structured adversarial probes for head %s.\n' "$HEAD_SHA"
return 1
clean_evidence_fallback_body="$(printf '%s\n' \
"## Pull request overview" \
"" \
"OpenCode model providers were unavailable for this same-head run, but deterministic current-head evidence is clean: coverage evidence passed, peer GitHub Checks are complete, medium-or-higher code-scanning alerts are clear, mergeability is clean, and reviewer threads are resolved or outdated." \
"" \
"## Findings" \
"" \
"No blocking findings in deterministic current-head evidence." \
"" \
"## Evidence" \
"" \
"- Result: APPROVE" \
"- Reason: MODEL_UNAVAILABLE_CLEAN_EVIDENCE" \
"- Model-pool outcome: \`${OPENCODE_MODEL_POOL_OUTCOME:-unknown}\`" \
"- Head SHA: \`${HEAD_SHA}\`" \
"- Workflow run: ${RUN_ID}" \
"- Workflow attempt: ${RUN_ATTEMPT}" \
"- Review provenance: deterministic fallback after model-output unavailability; no adversarial_validation block was fabricated." \
"" \
"This fallback does not suppress failed checks, medium-or-higher code-scanning alerts, merge conflicts, unresolved reviewer threads, or failed coverage evidence; any of those conditions still publish REQUEST_CHANGES or leave the approval state unchanged."
)"
printf '::notice::MODEL_OUTPUT_UNAVAILABLE: current-head deterministic evidence is clean for head %s; publishing MODEL_UNAVAILABLE_CLEAN_EVIDENCE approval so provider outage is not treated as a source blocker.\n' "$HEAD_SHA"
create_pull_review "APPROVE" "$clean_evidence_fallback_body"
if [ -n "${GITHUB_STEP_SUMMARY:-}" ]; then
{
printf '## OpenCode required check satisfied by clean deterministic evidence\n\n'
printf -- '- Result: `MODEL_UNAVAILABLE_CLEAN_EVIDENCE`\n'
printf -- '- Head SHA: `%s`\n' "$HEAD_SHA"
printf -- '- Workflow run: %s\n' "$RUN_ID"
printf -- '- Workflow attempt: %s\n' "$RUN_ATTEMPT"
printf -- '- Model-pool outcome: `%s`\n' "${OPENCODE_MODEL_POOL_OUTCOME:-unknown}"
printf -- '- Reason: model providers were unavailable, while coverage, peer checks, code-scanning alerts, mergeability, and review threads were clean for this exact head.\n'
printf -- '- Review state: APPROVE posted from deterministic current-head evidence; no adversarial_validation block was fabricated.\n\n'
} >>"$GITHUB_STEP_SUMMARY"
fi
return 0
}

same_head_opencode_approval_exists() {
Expand Down
8 changes: 5 additions & 3 deletions scripts/ci/test_strix_quick_gate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -670,16 +670,18 @@ assert_opencode_review_uses_codegraph_and_gpt5_fallback() {
assert_file_not_contains "$workflow_file" "approve_current_head_after_model_unavailable" "opencode cannot approve without model-backed adversarial evidence"
assert_file_contains "$workflow_file" "publish_blockers_after_model_unavailable" "opencode still publishes source-backed blockers after model-output failures"
assert_file_contains "$workflow_file" "Current-head model-unavailable evidence fallback candidate" "opencode model-unavailable fallback logs repository, head, and scope evidence"
assert_file_contains "$workflow_file" "no APPROVE review will be published without mandatory structured adversarial probes" "opencode model-unavailable path fails closed without adversarial evidence"
assert_file_contains "$workflow_file" "same_head_opencode_approval_exists" "model-unavailable path may satisfy the required check only from an existing same-head OpenCode approval"
assert_file_contains "$workflow_file" "MODEL_UNAVAILABLE_CLEAN_EVIDENCE" "model-unavailable path can satisfy the required check only after clean deterministic current-head evidence"
assert_file_contains "$workflow_file" "same_head_opencode_approval_exists" "model-unavailable path reuses an existing same-head OpenCode approval before publishing fallback approval"
assert_file_contains "$workflow_file" "EXISTING_CURRENT_HEAD_APPROVAL" "existing same-head approval fallback logs an explicit required-check result"
assert_file_contains "$workflow_file" "no duplicate APPROVE review was posted" "existing same-head approval fallback does not publish a duplicate approval review"
assert_file_contains "$workflow_file" "no adversarial_validation block was fabricated" "deterministic model-unavailable approval must not fabricate model adversarial evidence"
assert_file_contains "$workflow_file" 'create_pull_review "APPROVE" "$clean_evidence_fallback_body"' "deterministic model-unavailable approval is explicit and source-evidence gated"
assert_file_contains "$workflow_file" "CENTRAL_FAST_APPROVAL_ADVERSARIAL_INVALID" "central fast approval revalidates structured adversarial evidence"
assert_file_contains "$workflow_file" "stop_without_review_after_model_unavailable" "general model-unavailable path leaves PR review state unchanged"
assert_file_not_contains "$workflow_file" "approve_central_review_process_after_model_unavailable" "opencode fallback name reflects current-head deterministic evidence, not central-only scope"
assert_file_contains "$workflow_file" "collect_open_code_scanning_alerts" "model-unavailable fallback checks open code-scanning alerts before approval"
assert_file_not_contains "$workflow_file" 'if [ "${GH_REPOSITORY:-}" != "ContextualWisdomLab/.github" ]' "model-unavailable fallback is not limited to central governance repository once current-head evidence is clean"
assert_file_contains "$workflow_file" "MODEL_OUTPUT_UNAVAILABLE" "model-unavailable path fails the check without publishing review feedback"
assert_file_contains "$workflow_file" "MODEL_OUTPUT_UNAVAILABLE" "model-unavailable path logs provider outage before deterministic evidence gating"
assert_file_contains "$workflow_file" "No pull request review was posted because provider delay or model-output unavailability is not review feedback." "model-unavailable path explains delay without changing review state"
assert_file_contains "$workflow_file" "Cross-repository workflow_dispatch review-tool failure" "cross-repository dispatch tool failures log the reason without poisoning the central source-branch check"
assert_file_contains "$workflow_file" '[ "${GH_REPOSITORY:-}" != "${GITHUB_REPOSITORY:-}" ]' "opencode approval distinguishes central cross-repository dispatch from same-repository required checks"
Expand Down
14 changes: 8 additions & 6 deletions tests/test_opencode_agent_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ def test_workflow_provisions_sandbox_tool_and_reviewer_agent():
assert "publish_blockers_after_model_unavailable" in workflow
assert 'OPENCODE_REQUIRE_ADVERSARIAL_VALIDATION: "true"' in workflow
assert "CENTRAL_FAST_APPROVAL_ADVERSARIAL_INVALID" in workflow
assert "no APPROVE review will be published without mandatory structured adversarial probes" in workflow
assert "MODEL_UNAVAILABLE_CLEAN_EVIDENCE" in workflow
assert '"adversarial_validation"' in model_pool_runner
assert "ContextualWisdomLab/.github:ci-review-prompt.md | \\" in workflow
assert "ContextualWisdomLab/.github:code-reviewer-prompt.md | \\" in workflow
Expand Down Expand Up @@ -634,7 +634,7 @@ def test_workflow_provisions_sandbox_tool_and_reviewer_agent():
assert "Central review-process evidence fallback eligible" in model_pool_runner
assert "provider delay is logged before the publish fallback evaluates current-head peer evidence" in model_pool_runner
assert "model pool was intentionally skipped" not in workflow
assert "current-head model-unavailable evidence fallback" not in workflow
assert "current-head deterministic evidence is clean" in workflow
assert 'collect_github_checks_with_retry collect_pending_github_checks "$pending_checks_file"' in workflow
current_head_fallback = workflow.split("publish_blockers_after_model_unavailable()", 1)[1].split(
"request_changes_for_merge_conflict_if_present()", 1
Expand Down Expand Up @@ -1164,8 +1164,8 @@ def test_opencode_jq_filters_do_not_embed_literal_expression_openers():
assert 'contains("$" + "{{")' in workflow


def test_opencode_model_pool_failure_stops_without_review_state_change():
"""A continue-on-error model-pool failure must not approve by accident."""
def test_opencode_model_pool_failure_uses_gated_clean_evidence_fallback():
"""A model-pool failure may approve only after all deterministic gates are clean."""
workflow = Path(".github/workflows/opencode-review.yml").read_text(
encoding="utf-8"
)
Expand All @@ -1185,15 +1185,17 @@ def test_opencode_model_pool_failure_stops_without_review_state_change():
assert 'stop_approval_without_review "MODEL_OUTPUT_UNAVAILABLE" "$body"' in workflow
assert "same_head_opencode_approval_exists" in workflow
assert "EXISTING_CURRENT_HEAD_APPROVAL" in workflow
assert "MODEL_UNAVAILABLE_CLEAN_EVIDENCE" in workflow
assert "no adversarial_validation block was fabricated" in workflow
assert "no duplicate APPROVE review was posted" in workflow
assert 'create_pull_review "APPROVE"' in workflow
assert 'create_pull_review "APPROVE" "$clean_evidence_fallback_body"' in workflow
model_unavailable_block = re.search(
r"if \[ \"\$opencode_review_outcome\" != \"success\" \]; then"
r"(?P<body>[\s\S]{0,900})stop_without_review_after_model_unavailable",
workflow,
)
assert model_unavailable_block is not None
assert 'create_pull_review "APPROVE"' not in model_unavailable_block.group("body")
assert "publish_blockers_after_model_unavailable" in model_unavailable_block.group("body")


def test_opencode_review_thread_jq_filters_preserve_bash_single_quotes():
Expand Down
Loading