Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
3d8015a
Centralize PR branch update flow
seonghobae Jun 22, 2026
cb64f3d
Align Strix self-test with generated OpenCode config
seonghobae Jun 22, 2026
382794d
Strengthen OpenCode review evidence contract
seonghobae Jun 22, 2026
7d9d8dc
Explain failed GitHub checks in OpenCode fallback
seonghobae Jun 22, 2026
553bcc8
Enable OpenCode execution and research tools
seonghobae Jun 22, 2026
2c90e70
Ensure OpenCode fallbacks run after model timeouts
seonghobae Jun 22, 2026
7405e85
Materialize PR OpenCode config for Strix self-test
seonghobae Jun 22, 2026
f7d971f
Avoid false reviews for trusted-base Strix lag
seonghobae Jun 22, 2026
1870d3a
Publish manual Strix evidence status
seonghobae Jun 22, 2026
2082df1
Block unmeasured OpenCode coverage approvals
seonghobae Jun 22, 2026
756d3d1
Detect self-modifying Strix lag from PR worktree
seonghobae Jun 22, 2026
5795959
Block approvals when coverage evidence fails
seonghobae Jun 22, 2026
a1a7cb6
Skip OpenCode models when coverage evidence fails
seonghobae Jun 22, 2026
fd9cc63
Document central PR governance audit
seonghobae Jun 22, 2026
a838bef
Block auto-merge on failed checks
seonghobae Jun 22, 2026
5ca81a0
Fetch PR head before Strix config materialization
seonghobae Jun 22, 2026
b02acc4
Refresh live PR governance inventory
seonghobae Jun 22, 2026
3d24b30
Avoid PR-target coverage execution
seonghobae Jun 22, 2026
e1fe53e
Enable OpenCode runtime review tools
seonghobae Jun 22, 2026
d68ece5
Align OpenCode dispatch inputs
seonghobae Jun 22, 2026
e870d8a
Fact-check OpenCode env apiKey Strix reports
seonghobae Jun 22, 2026
e81da31
Fix Strix dotdir changed-file fixture severity
seonghobae Jun 22, 2026
6649934
Prove OpenCode coverage evidence at 100 percent
seonghobae Jun 22, 2026
9d4b7aa
Stabilize scheduler coverage under GitHub env
seonghobae Jun 22, 2026
4e7814a
Bound OpenCode model fallback timeouts
seonghobae Jun 22, 2026
0014ba7
Classify generic Strix workflow false positives
seonghobae Jun 22, 2026
e375206
Validate OpenCode publish output on PR head
seonghobae Jun 23, 2026
35c0886
Wait for same-head manual Strix evidence
seonghobae Jun 23, 2026
8235aea
Require current-head approval before branch update
seonghobae Jun 23, 2026
395dc76
Refresh PR governance scheduler proof
seonghobae Jun 23, 2026
60c821e
Enable OpenCode CI review runtime tools
seonghobae Jun 23, 2026
906bc0d
Refresh PR governance audit state
seonghobae Jun 23, 2026
d8886a8
fix: inline bounded evidence in opencode prompts
seonghobae Jun 23, 2026
b5dea3f
fix: repair opencode approvals from bounded evidence
seonghobae Jun 23, 2026
811446d
test: cover opencode approval repair evidence edges
seonghobae Jun 23, 2026
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
1,441 changes: 1,000 additions & 441 deletions .github/workflows/opencode-review.yml

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions .github/workflows/pr-review-merge-scheduler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ on:
required: false
default: true
type: boolean
update_branches:
description: Update outdated PR branches after OpenCode approval
required: false
default: true
type: boolean

concurrency:
group: pr-review-merge-scheduler
Expand All @@ -46,6 +51,7 @@ jobs:
PROJECT_FLOW: ${{ vars.PROJECT_FLOW || 'git-flow' }}
TRIGGER_REVIEWS: ${{ github.event_name != 'workflow_dispatch' || inputs.trigger_reviews == true }}
ENABLE_AUTO_MERGE: ${{ github.event_name != 'workflow_dispatch' || inputs.enable_auto_merge == true }}
UPDATE_BRANCHES: ${{ github.event_name != 'workflow_dispatch' || inputs.update_branches == true }}
steps:
- name: Checkout trusted scheduler
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand Down Expand Up @@ -78,4 +84,9 @@ jobs:
else
args+=(--no-enable-auto-merge)
fi
if [ "$UPDATE_BRANCHES" = "true" ]; then
args+=(--update-branches)
else
args+=(--no-update-branches)
fi
python3 scripts/ci/pr_review_merge_scheduler.py "${args[@]}"
47 changes: 47 additions & 0 deletions .github/workflows/strix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ jobs:
# refs/pull/<n>/head has already advanced before this queued run starts.
if git -C "$TRUSTED_WORKSPACE" fetch --no-tags --depth=1 origin "$PR_HEAD_SHA"; then
git -C "$TRUSTED_WORKSPACE" cat-file -e "$PR_HEAD_SHA^{commit}"
if git -C "$TRUSTED_WORKSPACE" cat-file -e "$PR_HEAD_SHA:opencode.jsonc" 2>/dev/null; then
git -C "$TRUSTED_WORKSPACE" show "$PR_HEAD_SHA:opencode.jsonc" > "$TRUSTED_WORKSPACE/opencode.jsonc"
fi
git -C "$TRUSTED_WORKSPACE" update-ref "refs/remotes/pull/${PR_NUMBER}/head" "$PR_HEAD_SHA"
exit 0
fi
Expand All @@ -118,6 +121,9 @@ jobs:
fetched_head_sha="$(git -C "$TRUSTED_WORKSPACE" rev-parse "refs/remotes/pull/${PR_NUMBER}/head")"
if [ "$fetched_head_sha" = "$PR_HEAD_SHA" ]; then
git -C "$TRUSTED_WORKSPACE" cat-file -e "$PR_HEAD_SHA^{commit}"
if git -C "$TRUSTED_WORKSPACE" cat-file -e "$PR_HEAD_SHA:opencode.jsonc" 2>/dev/null; then
git -C "$TRUSTED_WORKSPACE" show "$PR_HEAD_SHA:opencode.jsonc" > "$TRUSTED_WORKSPACE/opencode.jsonc"
fi
exit 0
fi
if [ "$pr_head_fetch_attempt" -lt 6 ]; then
Expand Down Expand Up @@ -419,3 +425,44 @@ jobs:
path: strix_runs/
if-no-files-found: error
retention-days: 5

publish-manual-pr-evidence-status:
name: publish-manual-pr-evidence-status
needs: strix
if: ${{ always() && github.event_name == 'workflow_dispatch' && github.event.inputs.pr_head_sha != '' }}
runs-on: ubuntu-latest
permissions:
statuses: write
steps:
- name: Publish same-head manual Strix status
env:
GH_TOKEN: ${{ github.token }}
PR_HEAD_SHA: ${{ github.event.inputs.pr_head_sha }}
STRIX_RESULT: ${{ needs.strix.result }}
run: |
set -euo pipefail
if ! [[ "$PR_HEAD_SHA" =~ ^[0-9a-fA-F]{40}$ ]]; then
echo "::error::PR head SHA must be a 40-character git SHA."
exit 1
fi

case "$STRIX_RESULT" in
success)
state="success"
description="Manual workflow_dispatch Strix evidence passed"
;;
failure|cancelled|skipped)
state="failure"
description="Manual workflow_dispatch Strix evidence failed"
;;
*)
state="error"
description="Manual workflow_dispatch Strix evidence inconclusive"
;;
esac

gh api -X POST "repos/${GITHUB_REPOSITORY}/statuses/${PR_HEAD_SHA}" \
-f state="$state" \
-f context="strix" \
-f description="$description" \
-f target_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
115 changes: 115 additions & 0 deletions PR_GOVERNANCE_AUDIT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# PR Governance Audit

Live check: 2026-06-23 KST, GitHub API via `gh` as `seonghobae`.

## Canonical Policy

OpenCode decides; GitHub Actions mutates.

- OpenCode may return only a decision: `UPDATE_BRANCH`, `WAIT`, `REQUEST_CHANGES`, or `NO_ACTION`.
- GitHub Actions updates same-repository PR heads with `expected_head_sha`.
- Old approvals and old checks are not merge evidence after a head SHA changes.
- Merge uses one path: current-head OpenCode approval, no unresolved review threads, required checks green or native auto-merge waiting on them, mergeable head, and no policy blocker.
- Prefer `gh pr merge --auto --merge --match-head-commit <head>` when native auto-merge is enabled.
- Use direct `gh pr merge --merge --match-head-commit <head>` only when the repo policy already allows immediate merge.
- OpenCode app-token merges are deprecated; keep app tokens for review publication, not mechanical branch mutation.
- Tool failures are not source findings. Model failure, API transient, update-branch `422/403`, fork/write-permission failure, conflict, failed checks, and stale review state must be reported as distinct scheduler outcomes.

## Live Repository Inventory

Live generated: 2026-06-23 04:18 KST. PR #28 rechecked: 2026-06-23 11:43 KST.

| Repo | Flow | Default | Auto | Rulesets | Required checks | Stale dismissal | Merge queue | Workflows | Recent merged actor |
|---|---:|---:|---:|---|---|---:|---:|---|---|
| `ContextualWisdomLab/.github` | GitHub Flow | `main` | on | `Lock default branch` | none | true | no | OpenCode Review; PR Review Merge Scheduler; Strix Security Scan | #18 `seonghobae`; #17 `seonghobae`; #2 `seonghobae` |
| `ContextualWisdomLab/bandscope` | Git Flow | `develop` | on | `Lock default branch` | `ci / build-and-test`, `dependency-review`, `security-audit`, `CodeQL`, `sbom`, `release-preflight`, `gate / build / windows`, `gate / build / macos`, `trivy-fs-scan` | false | no | OpenCode Review; PR Review Merge Scheduler; Strix Security Scan | #427 `github-actions`; #408 `seonghobae`; #405 `seonghobae` |
| `ContextualWisdomLab/clearfolio` | GitHub Flow | `main` | off | `PR` | none | false | no | OpenCode Review; Strix Security Scan | #9 `seonghobae`; #8 `seonghobae`; #7 `seonghobae` |
| `ContextualWisdomLab/codec-carver` | GitHub Flow | `main` | on | `Lock default branch` | none | true | no | OpenCode Review; Scheduled PR Review Merge; Strix Security Scan | #94 `opencode-agent`; #93 `seonghobae`; #90 `seonghobae` |
| `ContextualWisdomLab/contextual-orchestrator` | GitHub Flow | `main` | off | none | none | unknown | unknown | none matched | none |
| `ContextualWisdomLab/ContextualWisdomLab.github.io` | GitHub Flow | `main` | on | `Lock default branch` | none | true | no | OpenCode Review; PR Review Merge Scheduler; Strix Security Scan | #15 `seonghobae`; #14 `seonghobae`; #13 `github-actions` auto by `github-actions` |
| `ContextualWisdomLab/naruon` | Git Flow | `develop` | on | `Lock default branch`, `PR` | `opencode-review`, `strix` | true | no | OpenCode Review; PR Governance; PR Review Merge Scheduler; Strix Gate Self-Test; Strix Security Scan | #747 `seonghobae`; #715 `seonghobae`; #692 `seonghobae` |
| `ContextualWisdomLab/newsdom-api` | Git Flow | `develop` | on | `Lock default branch`, `mirror-classic-protection-main-develop` | `codeql (python, actions)`, `dependency-review`, `pytest`, `quality-gate`, `scorecard` | true | no | OpenCode Review; PR Review Merge Scheduler; Strix Security Scan | #163 `seonghobae`; #105 `seonghobae`; #162 `seonghobae` |
| `ContextualWisdomLab/pg-erd-cloud` | GitHub Flow | `main` | on | `Lock default branch` | none | true | no | OpenCode Review; PR Review Autofix; PR Review Fix Scheduler; PR Review Merge Scheduler; Strix Security Scan | #239 `github-actions`; #238 `seonghobae`; #236 `github-actions` |
| `ContextualWisdomLab/scopeweave` | Git Flow | `develop` | on | `Lock default branch` | none | true | no | OpenCode Review; PR Review Merge Scheduler; Strix Gate Self-Test; Strix Security Scan | #106 `seonghobae`; #102 `seonghobae`; #101 `seonghobae` auto by `seonghobae` |
| `ContextualWisdomLab/VibeSec` | Git Flow | `develop` | on | `Lock default branch`, `PR` | none | false/true | no | OpenCode Review; PR Review Merge Scheduler; Strix Security Scan | #109 `seonghobae`; #67 `github-actions` auto by `github-actions`; #92 `seonghobae` auto by `seonghobae` |

## Current Gaps By Repo

| Repo | Gap |
|---|---|
| `.github` | PR #28 head `60c821e` is blocked by current-head OpenCode `CHANGES_REQUESTED` and `strix` status failure. Same-head manual Strix run `27996904501` passed self-test but failed `Run Strix (quick)`, so it is not merge evidence. |
| `bandscope` | Required checks are repo-specific and broad; keep GitHub native auto-merge as the check interpreter. |
| `clearfolio` | Auto-merge is off and the PR Review Merge Scheduler is missing. |
| `codec-carver` | Latest merged sample #94 still used `opencode-agent`; replace the legacy scheduler with the central GitHub Actions path. |
| `contextual-orchestrator` | No matching rulesets or review workflows; either opt in deliberately or mark unmanaged. |
| `naruon` | Canonical strict check source, but open PRs still need the updated contract observed through one full outdated -> update -> new-head review trace. |
| `newsdom-api` | Ruleset-required checks must stay GitHub-interpreted; open queue is mostly review/check blocked. |
| `pg-erd-cloud` | Good GitHub Actions merge samples; keep autofix workflows repo-local. |
| `scopeweave` | Has central scheduler and Strix self-test, but no current representative update/merge trace captured. |
| `VibeSec` | Actor history is mixed; central scheduler should make GitHub Actions or native auto-merge the only mechanical path. |

## Representative Evidence

| Repo | Live evidence | Adopt | Reject |
|---|---|---|---|
| `naruon` | `develop`, strict required checks `opencode-review` and `strix`, stale review dismissal enabled. Open PRs show `BEHIND`, `DIRTY`, and `CHANGES_REQUESTED` cases. | Strict current-head evidence and stale-dismissal awareness. | Treating `BEHIND` as merge-ready. |
| `.github` | PR #28 is `MERGEABLE` but `BLOCKED`; required PR-target Strix failed on trusted-base self-test, and same-head manual Strix run `27996904501` also failed at `Run Strix (quick)` after publishing `strix` status failure. The latest OpenCode review still cited the stale PR-target Strix URL instead of the same-head manual Strix failure. | Same-head manual evidence for self-modifying trusted workflow changes, plus explicit handling for failed manual evidence. | Treating stale PR-target failure logs as the only current-head diagnosis after a same-head manual Strix rerun exists. |
| `pg-erd-cloud` | Recent PRs #236, #237, #239 were merged by `app/github-actions`. | GitHub Actions as mechanical merge actor with head guard. | Human-only queue draining. |
| `codec-carver` | Recent PR #94 was merged by `app/opencode-agent`, and the repo still has legacy `Scheduled PR Review Merge`. | Native auto-merge path for current-head approved PRs. | OpenCode app as merge actor. |
| `VibeSec` | PR #108 had native auto-merge enabled; #106 merged by `app/github-actions`; #109 merged by human. | Keep native auto-merge as preferred waiting path. | Repo-by-repo actor inconsistency. |

## Current Scheduler Contract

The checked-in scheduler already does the minimal central path:

- skips draft, wrong-base, and fork/external-head PRs;
- blocks `DIRTY` or `CONFLICTING`;
- blocks unresolved review threads;
- blocks current-head OpenCode `CHANGES_REQUESTED`;
- blocks current-head failed check runs or status contexts before enabling auto-merge;
- updates `BEHIND` only when OpenCode approved the exact current head, using `expected_head_sha`;
- enables native auto-merge only for current-head OpenCode approval;
- dispatches OpenCode when the current head has no OpenCode decision.

Small proof run:

```text
$ python3 scripts/ci/pr_review_merge_scheduler.py --self-test
self-test passed

$ python3 scripts/ci/pr_review_merge_scheduler.py --repo ContextualWisdomLab/.github --base-branch main --project-flow github-flow --dry-run --max-prs 40 --no-trigger-reviews
PR #19: block: current-head OpenCode review requested changes
PR #20: block: current-head OpenCode review requested changes
PR #21: block: current-head OpenCode review requested changes
PR #22: block: current-head OpenCode review requested changes
PR #23: block: merge conflict: DIRTY
PR #24: block: current-head OpenCode review requested changes
PR #25: block: current-head OpenCode review requested changes
PR #26: block: current-head OpenCode review requested changes
PR #27: block: current-head OpenCode review requested changes
PR #28: block: current-head OpenCode review requested changes
PR #29: block: current-head OpenCode review requested changes
PR #30: block: current-head OpenCode review requested changes
PR #31: block: current-head OpenCode review requested changes
PR #32: block: current-head OpenCode review requested changes
PR #33: block: current-head OpenCode review requested changes
PR #34: block: current-head OpenCode review requested changes
PR #35: block: current-head OpenCode review requested changes
PR #36: block: current-head OpenCode review requested changes
{"base_branch": "main", "counts": {"block": 18}, "dry_run": true, "inspected": 18, "project_flow": "github-flow"}
```

## Rollout List

1. Keep `naruon`, `.github`, `VibeSec`, `bandscope`, `newsdom-api`, `pg-erd-cloud`, and `scopeweave` on `PR Review Merge Scheduler`.
2. Replace `codec-carver` legacy `Scheduled PR Review Merge` with `PR Review Merge Scheduler`.
3. Add `PR Review Merge Scheduler` to `clearfolio` or explicitly mark it unmanaged; auto-merge is currently off.
4. Decide whether `contextual-orchestrator` should join the central PR governance surface; no matching workflows or rulesets were returned.
5. Keep `pg-erd-cloud` autofix workflows repo-local; do not make autofix part of the central merge contract.

## Remaining Proof Gaps

- No live outdated -> update-branch -> new-head review -> merge/auto-merge trace has been completed yet.
- `update-branch` `422/403` behavior still needs a safe fixture or a real blocked case before claiming standardized handling.
- Required-check interpretation should stay delegated to GitHub native auto-merge until a repo needs immediate merge.
- PR #28 itself cannot prove adoption until the same-head manual Strix failure is diagnosed and OpenCode stops reusing stale PR-target Strix self-test logs as the only failed-check evidence.
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,44 @@ Organization profile repository for **맥락지혜 연구실 / Contextual Wisdom
The public GitHub organization profile lives in [profile/README.md](profile/README.md).

Homepage: https://contextualwisdomlab.github.io/

PR governance live audit: [PR_GOVERNANCE_AUDIT.md](PR_GOVERNANCE_AUDIT.md).

## PR review and merge policy

OpenCode judges PRs; GitHub Actions performs mechanical updates and merges.
The scheduler updates a same-repository PR branch only when the latest OpenCode
review is approved and GitHub reports the PR as behind. After that update, the
new head must pass OpenCode, Strix, required checks, and review-thread gates
again before auto-merge or `--match-head-commit` merge can proceed.
Branch updates and merges run through the workflow `GITHUB_TOKEN`, so GitHub
records those mechanical mutations as `github-actions[bot]` rather than an
OpenCode app token or a personal token.

OpenCode approval is evidence-gated. Before approval, the review summary must
name changed files, CodeGraph or structural MCP evidence, a Change Flow DAG,
100% test coverage evidence, 100% docstring coverage evidence, and a concrete
PoC/execution result. The PoC can be a temporary scratch repro, focused test,
lint, security check, performance probe, or UI verification command, but it must
be actually run and cited. Scratch PoC files are not committed.

Failed GitHub Checks are not reviewed as URL lists. OpenCode must explain the
failed check name, failing step, source-backed file and line when available,
root cause, fix direction, and focused rerun command. Cancelled or superseded
checks must be described as queue or evidence blockers rather than invented
source-code findings.

Operational cases folded into the central policy:

- `naruon`: approved PRs can become `BEHIND`; the scheduler treats that as an
update request, not as a merge signal. GitHub Actions updates the branch with
`expected_head_sha`, then the new head is reviewed again.
- `pg-erd-cloud`: successful bot merges used current-head evidence and
`--match-head-commit`; the centralized path keeps that head-SHA guard.
- `.github`: PRs that edit trusted review workflows can fail because
`pull_request_target` runs the base branch's trusted scripts. A same-head
manual `workflow_dispatch` Strix run may supply evidence for review, but it
does not replace required PR checks until the trusted base branch catches up.
- `naruon#745`: new OpenCode review-flow work improves Mermaid output by
replacing generic risk sketches with changed-file flow DAGs. The central
workflow carries that review contract while keeping the self-test drift fix.
7 changes: 7 additions & 0 deletions ci-review-prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
You are a general-purpose, meticulous CI code-review agent.

OpenCode runtime tools are enabled: bash, task, webfetch, websearch, and lsp. Use bash for direct verification commands, task for focused subreviews when risk warrants it, webfetch and websearch for current external facts, and lsp for symbol-aware diagnostics when a language server is available.

Actively consult configured MCP evidence sources when reachable: CodeGraph for structural checks, DeepWiki for repository documentation, Context7 for current library and API documentation, and web_search for bounded external lookups such as industry standards, international standards, official platform specifications, and comparable issue or PR precedents.

Do not rely on model memory for user-claimed concepts, standards, runtime support, or domain terminology when a search source is available. Inspect changed files and focused hunks directly when external evidence is insufficient. Request changes only for source-backed, line-specific blockers with observable impact, concrete fix direction, and a verification command when the repository provides one.
Loading
Loading