fix(review): 중앙 스케줄러의 대상 PR 디스패치 지원#586
Conversation
There was a problem hiding this comment.
Pull request overview
OpenCode cannot approve yet because required coverage evidence did not pass.
Review outcome
1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence
-
Problem: The required coverage-evidence job result was
failure, so OpenCode cannot establish approval sufficiency for this head. -
Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.
-
Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports
successwith required evidence or explicit no-source not-applicable evidence. -
Regression test: Keep the approval branch checking
needs.coverage-evidence.result == successbefore posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present. -
Result: REQUEST_CHANGES
-
Reason: coverage-evidence result was
failure, so required test/docstring evidence was not proven for current headabd8f7d6a83a827c23157335e00c3ef70d66b414. -
Head SHA:
abd8f7d6a83a827c23157335e00c3ef70d66b414 -
Workflow run: 29580222601
-
Workflow attempt: 1
Coverage evidence
Coverage Decision
- Result: FAIL
- Test evidence: not proven passing
- Docstring evidence: not proven passing when configured
- Failure count: 1
Changed-File Evidence Map
flowchart LR
PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
Evidence --> S1["Workflow: pr-review-merge-scheduler.yml"]
S1 --> I1["GitHub Actions review job"]
I1 --> R1["Review risk: Workflow: pr-review-merge-scheduler.yml"]
R1 --> V1["actionlint plus required checks"]
Evidence --> S2["CI script: pr_review_merge_scheduler.py"]
S2 --> I2["review and security gate shell path"]
I2 --> R2["Review risk: CI script: pr_review_merge_scheduler.py"]
R2 --> V2["bash -n plus Strix self-test"]
Evidence --> S3["Test (3 files)"]
S3 --> I3["regression suite"]
I3 --> R3["Review risk: Test (3 files)"]
R3 --> V3["targeted test run"]
OpenCode Review Overview
Pull request overviewOpenCode could not approve from deterministic current-head evidence because GitHub Checks have failed. Findings1. HIGH Current-head GitHub Checks - Fix failed required checks before approval
Failed checks:
Changed-File Evidence Mapflowchart LR
PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
Evidence --> S1["Workflow: pr-review-merge-scheduler.yml"]
S1 --> I1["GitHub Actions review job"]
I1 --> R1["Review risk: Workflow: pr-review-merge-scheduler.yml"]
R1 --> V1["actionlint plus required checks"]
Evidence --> S2["CI script (2 files)"]
S2 --> I2["review and security gate shell path"]
I2 --> R2["Review risk: CI script (2 files)"]
R2 --> V2["bash -n plus Strix self-test"]
Evidence --> S3["Test (4 files)"]
S3 --> I3["regression suite"]
I3 --> R3["Review risk: Test (4 files)"]
R3 --> V3["targeted test run"]
|
|
현재 헤드 보강 검증 (
참고로 이 헤드의 Strix |
Superseded by current head 523bea3, which adds the missing branch regressions and proves 100% coverage (642 tests passed). A fresh current-head review is still required.
Current-HEAD 큐 backpressure 검증
현재 GitHub-hosted 체크는 기존 중앙 Actions 큐 포화로 대기 중이며, 위 변경은 새 OpenCode 디스패치가 큐를 계속 증폭시키는 저장소 로컬 원인을 차단합니다. |
Current-HEAD Noema identity hardening
|
Naruon stale Noema approval cleanupThe new identity guard was applied to the live open-PR inventory before merge.
|
Organization-wide active Noema identity audit
This is governance cleanup only; every dismissed review requires a fresh exact-current-HEAD independent Noema review before it can contribute to the two-reviewer rule. |
There was a problem hiding this comment.
Pull request overview
OpenCode cannot approve yet because required coverage evidence did not pass.
Review outcome
1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence
-
Problem: The required coverage-evidence job result was
failure, so OpenCode cannot establish approval sufficiency for this head. -
Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.
-
Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports
successwith required evidence or explicit no-source not-applicable evidence. -
Regression test: Keep the approval branch checking
needs.coverage-evidence.result == successbefore posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present. -
Result: REQUEST_CHANGES
-
Reason: coverage-evidence result was
failure, so required test/docstring evidence was not proven for current head1c7d00846428d36c3357d3683bba780e5313f694. -
Head SHA:
1c7d00846428d36c3357d3683bba780e5313f694 -
Workflow run: 29799150787
-
Workflow attempt: 1
Coverage evidence
Coverage Decision
- Result: FAIL
- Test evidence: not proven passing
- Docstring evidence: not proven passing when configured
- Failure count: 1
Changed-File Evidence Map
flowchart LR
PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
Evidence --> S1["Workflow: pr-review-merge-scheduler.yml"]
S1 --> I1["GitHub Actions review job"]
I1 --> R1["Review risk: Workflow: pr-review-merge-scheduler.yml"]
R1 --> V1["actionlint plus required checks"]
Evidence --> S2["CI script (2 files)"]
S2 --> I2["review and security gate shell path"]
I2 --> R2["Review risk: CI script (2 files)"]
R2 --> V2["bash -n plus Strix self-test"]
Evidence --> S3["Test (4 files)"]
S3 --> I3["regression suite"]
I3 --> R3["Review risk: Test (4 files)"]
R3 --> V3["targeted test run"]
There was a problem hiding this comment.
Pull request overview
This PR updates the central PR Review Merge Scheduler workflow and its supporting Python tooling to safely support targeted, cross-repository dispatch (binding to live PR metadata), add bounded retries for transient/truncated GitHub GraphQL responses, and introduce an aggregate central OpenCode active-run capacity limit to prevent organization-wide queue saturation.
Changes:
- Add a targeted
repository_dispatchpath that validatestarget_repository/pr_number, re-fetches live PR metadata (base repo/branch + base/head SHAs), and no-ops if the head has changed. - Harden scheduler reliability: retry transient/truncated GraphQL failures, scope Actions API calls to avoid guaranteed 403s, and sanitize Actions step-summary Markdown rendering.
- Strengthen Noema review reuse and transport safety: bind reuse to current HEAD via commit/body/marker, require verified actor, and enforce HTTPS + public-IP pinning for the LLM endpoint.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
.github/workflows/pr-review-merge-scheduler.yml |
Adds targeted central dispatch preflight + env wiring for scoped Actions access and aggregate OpenCode capacity limiting. |
scripts/ci/pr_review_merge_scheduler.py |
Implements Actions scope guard, GraphQL retry hardening, central OpenCode capacity checks, targeted expected-head no-op, and safe Markdown summary rendering. |
scripts/ci/noema_review_gate.py |
Tightens Noema reuse to current HEAD + verified actor; replaces URL fetching with validated/pinned HTTPS transport. |
tests/test_required_workflow_queue_contract.py |
Contract assertions for new targeted central dispatch binding behavior in the workflow. |
tests/test_pr_review_merge_scheduler.py |
Adds tests for GraphQL retry cases, Actions scoping, central capacity behavior, targeted expected-head behavior, and Markdown sanitization. |
tests/test_opencode_agent_contract.py |
Updates workflow contract expectations for expanded read-token selection and new env vars. |
tests/test_noema_review_gate.py |
Adds coverage for Noema head-binding checks, pinned HTTPS transport, and stricter URL validation behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| github.event_name == 'workflow_run' && github.event.workflow_run.pull_requests[0].number && format('pr-{0}', github.event.workflow_run.pull_requests[0].number) || | ||
| github.event_name == 'workflow_call' && inputs.pr_number != '' && format('pr-{0}', inputs.pr_number) || | ||
| github.event_name == 'workflow_call' && inputs.base_branch != '' && format('call-{0}', inputs.base_branch) || | ||
| github.event_name == 'repository_dispatch' && github.event.client_payload.target_repository != '' && format('target-{0}-pr-{1}', github.event.client_payload.target_repository, github.event.client_payload.pr_number) || | ||
| github.event_name == 'repository_dispatch' && github.event.client_payload.pr_number != '' && format('pr-{0}', github.event.client_payload.pr_number) || | ||
| github.event_name == 'repository_dispatch' && github.run_id || |
There was a problem hiding this comment.
Pull request overview
OpenCode could not approve from deterministic current-head evidence because GitHub Checks have failed.
Findings
1. HIGH Current-head GitHub Checks - Fix failed required checks before approval
- Problem: Failed same-head checks remain for
f490dfef0637b88fc5f281e84bb1118746812065. - Root cause: The model-unavailable evidence fallback is allowed only when peer GitHub Checks are complete and clean.
- Fix: Read and fix the failed check logs below, then rerun the current-head checks.
- Regression test: Keep the model-unavailable fallback gated on an empty failed-check rollup.
Failed checks:
- Bandit (Python SAST) check run: cancelled (https://github.com/ContextualWisdomLab/.github/actions/runs/29828972000/job/88628851520)
- CodeQL PR/CodeQL compatibility analysis (actions): CANCELLED (https://github.com/ContextualWisdomLab/.github/actions/runs/29828971796/job/88628851565)
- CodeQL PR/CodeQL compatibility analysis (python): CANCELLED (https://github.com/ContextualWisdomLab/.github/actions/runs/29828971796/job/88628851606)
- CodeQL PR/CodeQL merge preview (actions): CANCELLED (https://github.com/ContextualWisdomLab/.github/actions/runs/29828971796/job/88628851553)
- CodeQL PR/CodeQL merge preview (python): CANCELLED (https://github.com/ContextualWisdomLab/.github/actions/runs/29828971796/job/88628851533)
- CodeQL compatibility analysis (actions) check run: cancelled (https://github.com/ContextualWisdomLab/.github/actions/runs/29828971796/job/88628851565)
- CodeQL compatibility analysis (python) check run: cancelled (https://github.com/ContextualWisdomLab/.github/actions/runs/29828971796/job/88628851606)
- CodeQL merge preview (actions) check run: cancelled (https://github.com/ContextualWisdomLab/.github/actions/runs/29828971796/job/88628851553)
- CodeQL merge preview (python) check run: cancelled (https://github.com/ContextualWisdomLab/.github/actions/runs/29828971796/job/88628851533)
- OSV-Scanner PR/osv-scan / osv-scan: CANCELLED (https://github.com/ContextualWisdomLab/.github/actions/runs/29828972348/job/88628830791)
- Python Security/Bandit (Python SAST): CANCELLED (https://github.com/ContextualWisdomLab/.github/actions/runs/29828972000/job/88628851520)
- Python Security/pip-audit (Python dependency audit): CANCELLED (https://github.com/ContextualWisdomLab/.github/actions/runs/29828972000/job/88628851539)
- SAST Semgrep/Semgrep (multi-language SAST): CANCELLED (https://github.com/ContextualWisdomLab/.github/actions/runs/29828971774/job/88628828625)
- SBOM Generation/generate-sbom: CANCELLED (https://github.com/ContextualWisdomLab/.github/actions/runs/29828971999/job/88628829354)
- Scorecard PR/Scorecard: CANCELLED (https://github.com/ContextualWisdomLab/.github/actions/runs/29828971808/job/88628828731)
- Scorecard check run: cancelled (https://github.com/ContextualWisdomLab/.github/actions/runs/29828971808/job/88628828731)
- Secret Scan/gitleaks (secret scan): CANCELLED (https://github.com/ContextualWisdomLab/.github/actions/runs/29828971789/job/88628828559)
- Security Scan/dependency-review: CANCELLED (https://github.com/ContextualWisdomLab/.github/actions/runs/29828972046/job/88628829491)
- Security Scan/osv-scan: CANCELLED (https://github.com/ContextualWisdomLab/.github/actions/runs/29828972046/job/88628829348)
- Security Scan/scorecard: CANCELLED (https://github.com/ContextualWisdomLab/.github/actions/runs/29828972046/job/88628829394)
- Security Scan/trivy-fs: CANCELLED (https://github.com/ContextualWisdomLab/.github/actions/runs/29828972046/job/88628829393)
- Semgrep (multi-language SAST) check run: cancelled (https://github.com/ContextualWisdomLab/.github/actions/runs/29828971774/job/88628828625)
- Strix Security Scan/strix: CANCELLED (https://github.com/ContextualWisdomLab/.github/actions/runs/29828970847/job/88628826210)
- Strix Security Scan/strix: cancelled (https://github.com/ContextualWisdomLab/.github/actions/runs/29828970847/job/88628826210)
- dependency-review check run: cancelled (https://github.com/ContextualWisdomLab/.github/actions/runs/29828972046/job/88628829491)
- generate-sbom check run: cancelled (https://github.com/ContextualWisdomLab/.github/actions/runs/29828971999/job/88628829354)
- gitleaks (secret scan) check run: cancelled (https://github.com/ContextualWisdomLab/.github/actions/runs/29828971789/job/88628828559)
- osv-scan / osv-scan check run: cancelled (https://github.com/ContextualWisdomLab/.github/actions/runs/29828972348/job/88628830791)
- osv-scan check run: cancelled (https://github.com/ContextualWisdomLab/.github/actions/runs/29828972046/job/88628829348)
- pip-audit (Python dependency audit) check run: cancelled (https://github.com/ContextualWisdomLab/.github/actions/runs/29828972000/job/88628851539)
- scorecard check run: cancelled (https://github.com/ContextualWisdomLab/.github/actions/runs/29828972046/job/88628829394)
- trivy-fs check run: cancelled (https://github.com/ContextualWisdomLab/.github/actions/runs/29828972046/job/88628829393)
Changed-File Evidence Map
flowchart LR
PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
Evidence --> S1["Workflow: pr-review-merge-scheduler.yml"]
S1 --> I1["GitHub Actions review job"]
I1 --> R1["Review risk: Workflow: pr-review-merge-scheduler.yml"]
R1 --> V1["actionlint plus required checks"]
Evidence --> S2["CI script (2 files)"]
S2 --> I2["review and security gate shell path"]
I2 --> R2["Review risk: CI script (2 files)"]
R2 --> V2["bash -n plus Strix self-test"]
Evidence --> S3["Test (4 files)"]
S3 --> I3["regression suite"]
I3 --> R3["Review risk: Test (4 files)"]
R3 --> V3["targeted test run"]
개요
대상 저장소의 스케줄러가 중앙 Required OpenCode Review를 디스패치할 교차 저장소 자격증명이 없어 대기하는 문제를 해결합니다. 중앙
.github의merge-scheduler디스패치가target_repository와pr_number를 받아 한 PR만 안전하게 처리할 수 있도록 했습니다.조직 큐 실운영에서 GitHub GraphQL 응답이
unexpected end of JSON input으로 절단되어 naruon 큐 전체가 중단된 사례도 함께 복구합니다.운영 실패 증거: https://github.com/ContextualWisdomLab/.github/actions/runs/29730037605
변경 사항
ContextualWisdomLab/*대상과 양의 PR 번호만 허용합니다.GitHub API에서 열린 PR의 base 저장소·base/head SHA를 다시 읽어 라이브 메타데이터에 바인딩합니다.
검증 뒤 헤드가 바뀌면 오래된 디스패치는 성공적으로 무동작합니다.
중앙
github.token은 중앙 Actions 조회/디스패치에만 사용하고, 앱/PAT는 대상 PR 읽기·변경에 사용합니다.대상 저장소 Actions API에 중앙 전용 토큰으로 먼저 접근해 403이 발생하던 경로를 차단합니다.
대상 base branch에서 project flow를 파생합니다.
GitHub GraphQL의 절단된 stderr와 성공 종료 뒤 잘린 stdout을 일시 장애로 분류해 bounded retry합니다.
재시도 소진 뒤 기존 REST fallback으로 전환해 저장소 큐 전체가 중단되지 않게 합니다.
중앙
repository_dispatchOpenCode의 queued/in-progress 실행만 집계해 조직 전체 active 상한을 적용합니다.ACTIVE_OPENCODE_REVIEW_LIMIT저장소 변수로 상한을 조정하며 기본값은 16입니다.상한 도달 시 OpenCode만 다음 heartbeat로 미루고 Strix·일반 CI·병합 판단은 계속합니다.
잘못된 상한 값은 조용히 무제한으로 전환하지 않고 명시적 오류로 차단합니다.
Noema의 기존 리뷰 재사용 시 GitHub
commit_id, 본문의Head SHA,noema-review-gate head_sha를 모두 current HEAD에 바인딩합니다.본문/marker가 이전 HEAD를 가리키는 승인은 재사용하지 않아 독립 Noema 리뷰가 다시 실행될 수 있게 합니다.
검증
codegraph sync및 변경 call path 확인git diff --checkactionlint .github/workflows/pr-review-merge-scheduler.ymlpython3 -m ruff check scripts/ci/pr_review_merge_scheduler.py tests/test_pr_review_merge_scheduler.pypython3 -m py_compile scripts/ci/pr_review_merge_scheduler.pypython3 scripts/ci/pr_review_merge_scheduler.py --self-testactionlint -shellcheck= -pyflakes= .github/workflows/pr-review-merge-scheduler.ymlpython3 -m interrogate -c pyproject.toml scripts/ci— 100%python3 -m pytest -q— 650 passed