fix(opencode): allow governed free models for private repositories - #830
fix(opencode): allow governed free models for private repositories#830seonghobae wants to merge 2 commits into
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughPrivate 저장소의 익명 OpenCode 무료 모델 사용을 base 커밋 정책으로 제한했습니다. 모델 풀을 별도 구현으로 위임하고, 공급자별 자격 증명 격리, 실행 제어, fail-closed 테스트를 추가했습니다. ChangesOpenCode 거버넌스 및 실행 제어
Estimated code review effort: 4 (Complex) | ~75 minutes Possibly related issues
Possibly related PRs
Sequence Diagram(s)sequenceDiagram
participant Wrapper as run_opencode_review_model_pool.sh
participant Policy as opencode_private_free_model_policy.py
participant Guard as opencode_provider_guard.sh
participant Pool as run_opencode_review_model_pool_impl.sh
participant OpenCode as OpenCode
Wrapper->>Policy: base/head 커밋으로 정책 평가
Policy-->>Wrapper: 무료 모델 사용 허용 또는 거부
Wrapper->>Guard: OpenCode 실행 wrapper 설치
Wrapper->>Pool: 후보 목록과 실행 환경 전달
Pool->>Guard: 선택된 모델 실행 요청
Guard->>OpenCode: 정리된 자격 증명 환경으로 실행
OpenCode-->>Pool: 모델 출력과 세션 결과 반환
Pool-->>Wrapper: 성공, 재시도 또는 exhausted 상태 기록
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (6)
tests/test_opencode_private_free_model_runner_contract.py (1)
206-221: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win이 테스트는 두 개의 독립된 차단 이유를 동시에 만족합니다.
base_has_policy=False이므로 정책 평가가 이미 거부됩니다. 동시에 후보 목록에opencode-free/glm-5-free가 있어candidate_list_contains_anonymous_free_model이 조기 반환합니다. 따라서 "기존 free 풀은 재정렬하지 않는다"는 계약이 단독으로 검증되지 않습니다.base_has_policy=True로 바꾸면 조기 반환 경로만 검증합니다.💚 테스트 강화 제안
source, base_sha, head_sha = create_source_repository( tmp_path, - base_has_policy=False, + base_has_policy=True, head_changes_policy=False, )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/test_opencode_private_free_model_runner_contract.py` around lines 206 - 221, Update test_existing_public_free_pool_is_not_reordered_or_duplicated to set base_has_policy=True while keeping head_changes_policy=False, so the policy gate passes and the test isolates the existing public free-pool ordering behavior without triggering the anonymous free-model early return.scripts/ci/run_opencode_review_model_pool.sh (2)
169-170: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win
trap을install_provider_guard앞에 등록하십시오.현재
trap cleanup_provider_guard EXIT INT TERM은install_provider_guard다음 줄에 있습니다.mktemp -d성공 후cp또는chmod가 실패하면set -e가 스크립트를 종료합니다. 그 시점에는 trap이 아직 없으므로 임시 디렉터리가 남습니다. trap을 먼저 등록하면 모든 실패 경로에서 정리가 실행됩니다.♻️ 순서 변경 제안
-install_provider_guard trap cleanup_provider_guard EXIT INT TERM +install_provider_guard🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/ci/run_opencode_review_model_pool.sh` around lines 169 - 170, Register the cleanup trap before calling install_provider_guard so cleanup_provider_guard handles failures during temporary-directory setup, including cp or chmod errors under set -e.
77-103: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value후보 목록 확장 시 glob 확장을 차단하십시오.
for candidate in ${OPENCODE_MODEL_CANDIDATES:-}는 인용을 생략하여 단어 분리를 의도합니다. 그러나 파일명 확장도 함께 활성화됩니다. 워크플로가*,?,[를 포함한 후보 문자열을 전달하면 후보 이름이 현재 디렉터리 파일명으로 치환될 수 있습니다. 두 함수를set -f/set +f로 감싸거나,read -r -a로 배열을 만들면 확장이 차단됩니다.🛡️ 제안
candidate_list_contains_anonymous_free_model() { - local candidate - for candidate in ${OPENCODE_MODEL_CANDIDATES:-}; do + local candidate + local -a candidates + read -r -a candidates <<<"${OPENCODE_MODEL_CANDIDATES:-}" + for candidate in "${candidates[@]}"; do case "$candidate" in opencode-free/*) return 0 ;; esac done return 1 } prepend_unique_anonymous_free_candidates() { local combined="" local candidate - for candidate in $anonymous_free_candidates ${OPENCODE_MODEL_CANDIDATES:-}; do + local -a candidates + read -r -a candidates <<<"$anonymous_free_candidates ${OPENCODE_MODEL_CANDIDATES:-}" + for candidate in "${candidates[@]}"; do case " $combined " in🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/ci/run_opencode_review_model_pool.sh` around lines 77 - 103, Disable pathname expansion while iterating over OPENCODE_MODEL_CANDIDATES in candidate_list_contains_anonymous_free_model and prepend_unique_anonymous_free_candidates, preserving intentional whitespace-based word splitting. Restore the caller’s globbing state after each function completes, including early returns, or use a read-based array approach that prevents glob expansion without changing candidate parsing.scripts/ci/opencode_private_free_model_policy.py (1)
176-177: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueblob SHA 검증에 커밋 SHA 패턴을 재사용합니다.
COMMIT_SHA_PATTERN은 40자 16진수만 허용합니다. SHA-256 오브젝트 포맷 저장소에서git ls-tree는 64자 SHA를 반환합니다. 그 경우 정책 평가는 상태 2로 실패합니다. 현재 GitHub 호스팅 저장소는 SHA-1이므로 즉시 영향은 없습니다. 별도의 오브젝트 ID 패턴(40 또는 64자)을 사용하면 향후 마이그레이션에서 안전합니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/ci/opencode_private_free_model_policy.py` around lines 176 - 177, Update the validation around entry.object_sha in the policy evaluation flow to use a dedicated object ID pattern that accepts valid 40- or 64-character hexadecimal SHAs, rather than COMMIT_SHA_PATTERN. Keep the existing PolicyEvaluationError and invalid-SHA handling unchanged.scripts/ci/run_opencode_review_model_pool_impl.sh (1)
42-51: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value
normalize_opencode_output은 호출 컨텍스트의 errexit 비활성화에 의존합니다.
set -euo pipefail이 활성 상태입니다. Line 44의opencode_review_approve_gate.sh가 0이 아닌 상태로 끝나면, 조건 컨텍스트 밖에서는 errexit이 발동하여 Line 46의rc=$?와 Line 50의rm -f "$probe"가 실행되지 않습니다. 현재 유일한 호출 지점인 Line 536은if !조건이므로 동작합니다. 향후 다른 위치에서 호출하면 임시 파일이 남고 폴백이 중단됩니다. 명시적으로 상태를 잡으면 호출 위치와 무관하게 안전합니다.♻️ 제안
if python3 "$GITHUB_WORKSPACE/scripts/ci/opencode_review_normalize_output.py" \ "$HEAD_SHA" "$RUN_ID" "$RUN_ATTEMPT" "$probe"; then - bash "$GITHUB_WORKSPACE/scripts/ci/opencode_review_approve_gate.sh" \ - "$HEAD_SHA" "$RUN_ID" "$RUN_ATTEMPT" "$probe" >/dev/null - rc=$? + rc=0 + bash "$GITHUB_WORKSPACE/scripts/ci/opencode_review_approve_gate.sh" \ + "$HEAD_SHA" "$RUN_ID" "$RUN_ATTEMPT" "$probe" >/dev/null || rc=$? else rc=1 fi🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/ci/run_opencode_review_model_pool_impl.sh` around lines 42 - 51, Update the normalize_opencode_output flow around opencode_review_approve_gate.sh so its nonzero status is captured explicitly without relying on an outer if or ! condition to suppress errexit. Ensure rc is assigned before cleanup, rm -f "$probe" always runs, and the function returns the captured status for callers regardless of invocation context.tests/test_opencode_private_free_model_policy_1.py (1)
17-113: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win세 테스트 파일이 동일한 97줄 헤더를 복제합니다. 공유 헬퍼 모듈이 없어 모듈 로더,
run,git,commit_all,write_policy,repositoryfixture,evaluate가 세 번 정의되었습니다. 정책 검사기 인터페이스가 바뀌면 세 곳을 모두 수정해야 합니다.tests/conftest.py또는 전용 헬퍼 모듈로 추출하십시오.
tests/test_opencode_private_free_model_policy_1.py#L17-L113: 헬퍼와 fixture를 공유 모듈로 옮기고 import로 대체하십시오.tests/test_opencode_private_free_model_policy_2.py#L17-L113: 동일한 공유 모듈을 import하도록 바꾸십시오.tests/test_opencode_private_free_model_policy_3.py#L17-L113: 동일한 공유 모듈을 import하도록 바꾸십시오.참고: 세 파일 모두
sys.modules["opencode_private_free_model_policy"]에 서로 다른 모듈 객체를 등록합니다. 공유 모듈로 통합하면 이 중복 등록도 사라집니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/test_opencode_private_free_model_policy_1.py` around lines 17 - 113, Extract the duplicated module loader, run, git, commit_all, write_policy, repository fixture, and evaluate helpers into one shared test helper module. Update tests/test_opencode_private_free_model_policy_1.py#L17-L113, tests/test_opencode_private_free_model_policy_2.py#L17-L113, and tests/test_opencode_private_free_model_policy_3.py#L17-L113 to import the shared helpers and remove their local definitions, including separate sys.modules registrations for opencode_private_free_model_policy.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/doctoring/opencode-private-free-model-policy.md`:
- Around line 63-74: 문서의 모델 목록에서 1번, 3번, 12번 항목의 잘린 `-fre` 접미사를 `-free`로 수정해
`anonymous_free_candidates` 및 `EXPECTED_FREE_CANDIDATES`와 이름을 일치시키세요.
In `@scripts/ci/opencode_private_free_model_policy.py`:
- Around line 218-219: Update the validation around EXPECTED_POLICY to compare
JSON values with strict type sensitivity, so boolean true is not accepted as
numeric 1 and vice versa. Preserve the exact canonical declaration requirement
for every field, including schema_version and allow_private_free_models, while
retaining the existing PolicyDenied behavior for mismatches.
In `@scripts/ci/opencode_provider_guard.sh`:
- Around line 16-24: Update the argument scan around previous_argument and
model_candidate to recognize both “--model candidate” and “--model=candidate”
forms. Track occurrences explicitly and reject duplicate --model values before
provider credential removal, while preserving the existing candidate validation
and single-model behavior.
In `@scripts/ci/run_opencode_review_model_pool_impl.sh`:
- Line 463: Validate OPENCODE_FATAL_ERROR_POLL_SECONDS through the existing
env_integer_or_default helper when assigning fatal_poll_seconds, preserving the
default of 5 for unset or non-integer values. Ensure the validated value is used
by the sleep call in the kill -0 polling loop.
---
Nitpick comments:
In `@scripts/ci/opencode_private_free_model_policy.py`:
- Around line 176-177: Update the validation around entry.object_sha in the
policy evaluation flow to use a dedicated object ID pattern that accepts valid
40- or 64-character hexadecimal SHAs, rather than COMMIT_SHA_PATTERN. Keep the
existing PolicyEvaluationError and invalid-SHA handling unchanged.
In `@scripts/ci/run_opencode_review_model_pool_impl.sh`:
- Around line 42-51: Update the normalize_opencode_output flow around
opencode_review_approve_gate.sh so its nonzero status is captured explicitly
without relying on an outer if or ! condition to suppress errexit. Ensure rc is
assigned before cleanup, rm -f "$probe" always runs, and the function returns
the captured status for callers regardless of invocation context.
In `@scripts/ci/run_opencode_review_model_pool.sh`:
- Around line 169-170: Register the cleanup trap before calling
install_provider_guard so cleanup_provider_guard handles failures during
temporary-directory setup, including cp or chmod errors under set -e.
- Around line 77-103: Disable pathname expansion while iterating over
OPENCODE_MODEL_CANDIDATES in candidate_list_contains_anonymous_free_model and
prepend_unique_anonymous_free_candidates, preserving intentional
whitespace-based word splitting. Restore the caller’s globbing state after each
function completes, including early returns, or use a read-based array approach
that prevents glob expansion without changing candidate parsing.
In `@tests/test_opencode_private_free_model_policy_1.py`:
- Around line 17-113: Extract the duplicated module loader, run, git,
commit_all, write_policy, repository fixture, and evaluate helpers into one
shared test helper module. Update
tests/test_opencode_private_free_model_policy_1.py#L17-L113,
tests/test_opencode_private_free_model_policy_2.py#L17-L113, and
tests/test_opencode_private_free_model_policy_3.py#L17-L113 to import the shared
helpers and remove their local definitions, including separate sys.modules
registrations for opencode_private_free_model_policy.
In `@tests/test_opencode_private_free_model_runner_contract.py`:
- Around line 206-221: Update
test_existing_public_free_pool_is_not_reordered_or_duplicated to set
base_has_policy=True while keeping head_changes_policy=False, so the policy gate
passes and the test isolates the existing public free-pool ordering behavior
without triggering the anonymous free-model early return.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 4ef09089-44f5-44d9-997c-fbf050bce76d
📒 Files selected for processing (13)
CHANGELOG.mddocs/doctoring/opencode-private-free-model-policy.mddocs/examples/opencode-private-free-models.jsonscripts/ci/opencode_private_free_model_policy.pyscripts/ci/opencode_provider_guard.shscripts/ci/run_opencode_review_model_pool.shscripts/ci/run_opencode_review_model_pool_impl.shtests/test_opencode_delegated_runner_contract.pytests/test_opencode_private_free_model_policy_1.pytests/test_opencode_private_free_model_policy_2.pytests/test_opencode_private_free_model_policy_3.pytests/test_opencode_private_free_model_runner_contract.pytests/test_opencode_provider_guard.py
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/test_opencode_private_free_model_runner_contract.py`:
- Around line 275-280: In test_wrapper_preserves_every_quick_gate_runner_marker,
correct the undefined wrapper_tex reference in the marker assertion loop to use
the existing wrapper_text variable read from WRAPPER.
- Line 116: Update the test fixture’s candidate-selection logic to use
OPENCODE_MODEL_CANDIDATES exclusively, remove the unused
OPENCODE_MODD_CANDIDATES fallback, and capture/assert that the first candidate
is selected because the fake opencode does not validate --model. Also correct
the undefined wrapper_tex reference to wrapper_text.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 42094baf-07a5-4706-8dcb-044a8071e605
📒 Files selected for processing (2)
scripts/ci/run_opencode_review_model_pool.shtests/test_opencode_private_free_model_runner_contract.py
🚧 Files skipped from review as they are similar to previous changes (1)
- scripts/ci/run_opencode_review_model_pool.sh
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/test_opencode_private_free_model_runner_contract.py`:
- Line 237: 손상된 테스트 코드를 복구해 `for script in (...)` 구문이 `WRAPPER`와
`PROVIDER_GUARD`를 순회하도록 수정하고, 각 스크립트에 대해 Bash `-n` 구문 검증을 수행하게 하십시오. 변경 후 전체 테스트
스위트를 실행해 검증하십시오.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 0581ad70-cdc7-4c1b-90cf-b3c384e52202
📒 Files selected for processing (1)
tests/test_opencode_private_free_model_runner_contract.py
|
@opencode-agent address Exact-head bounded GREEN repair for The current branch already contains RED contracts in
Do not alter model selection, credentials, review semantics, timeout policy beyond this validation, or any unrelated file. Run the focused runner contract and the repository-authoritative exact-head suite before committing. Do not merge or synthesize approval. |
|
@opencode-agent address Exact-head bounded GREEN repair for Current-head Strix Changed Path Quality CI run Two production defects are directly evidenced in the delegated stable implementation:
Make only these minimal production repairs plus any strictly necessary test/doc wording alignment. Do not weaken the fail-first assertions, do not change provider eligibility, credentials, wrapper policy, model order, secrets, workflows, or branch protection, and do not create temporary/self-modifying workflows. Run the focused runner contract first, then the complete repository tests, |
|
@opencode-agent address Same unchanged exact head
Do not alter candidate ordering or any other model identifier. Validate the documentation against |
|
@opencode-agent address Repair only the exact current head Exact-head Strix run
Do not change the trusted-base private/free-model policy, provider credential isolation, model list/order, reviewer identities or credentials, NVIDIA NIM behavior, branch protection, tests, or unrelated model-pool semantics. Do not add a temporary/write-capable repair workflow. Run the focused private-free-model runner contract first, then the complete central suite and Strix exact-head gate. Keep the branch unmerged; any new head requires fresh exact-head security/review evidence. |
|
@opencode-agent address Repair only the exact current-head deterministic/review blockers on PR #830. Live head is Exact-head Strix Changed Path Quality CI run Make the smallest repair, limited to the delegated implementation, its focused regression only if needed to cover zero, and the doctoring list:
Do not modify wrapper governance, provider credential isolation, candidate ordering, workflows, permissions, CHANGELOG, unrelated tests, or any other file. Run the focused runner contract, relevant delegated-runner tests, Bash syntax, and doc/model-name consistency before committing, then let normal exact-head CI/security/Strix and review gates rerun. Do not mark Ready/merge/release, resolve unrelated threads, or synthesize approval. |
|
Perform a read-only formal review of exact current head RCA focus: the former blanket private-repository exclusion conflated repository visibility with data classification. Verify that the replacement is operationally realistic and fail-closed: anonymous All exact-head GitHub Actions checks currently report success and all inline review threads are resolved/outdated. Review the current source and bounded evidence independently. Submit a formal |
|
Operational closure is tracked in #833. Code-level merge is not considered sufficient: after protected integration, the scheduled central loop must execute one opted-in private |
|
@cwl-noema-review Please perform independent review-only evaluation of exact current head |
|
@coderabbitai review Please perform a fresh full review of unchanged exact head |
|
|
|
@coderabbitai review The prior exact-head request was rate-limited and its stated cooldown has elapsed. Please now perform one fresh full review of unchanged head |
|
|
|
@coderabbitai review Exact-current-head full review request for |
|
|
|
@coderabbitai review The reported organization review cooldown has now elapsed. Re-requesting one full review for unchanged exact head |
|
|
|
@coderabbitai review Please perform one fresh full review of exact head |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '== Live PR identity =='
gh api repos/ContextualWisdomLab/.github/pulls/830 \
--jq '{number, state, base: .base.sha, head: .head.sha, updated_at}'
printf '%s\n' '== Local commit identities =='
git rev-parse HEAD
git rev-parse 6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba^{commit}
git rev-parse 9a9b3e061599c28905aed793fc803123a2615205^{commit}
printf '%s\n' '== Changed files =='
git diff --name-status 6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba 9a9b3e061599c28905aed793fc803123a2615205
printf '%s\n' '== Relevant file outlines =='
ast-grep outline scripts/ci/opencode_private_free_model_policy.py --items all
ast-grep outline tests/test_opencode_provider_guard.py --items all
ast-grep outline tests/test_opencode_private_free_model_runner_contract.py --items all
printf '%s\n' '== Relevant symbols and credential references =='
rg -n -C 3 --glob 'scripts/ci/*.sh' --glob 'scripts/ci/*.py' \
'anonymous_free_candidates|evaluate_policy|require_policy_unchanged|policy_blob_entry|normalize_opencode_output|run_one_model_attempt|OPENCODE_FATAL_ERROR_POLL_SECONDS|OPENCODE_REAL_BIN|GITHUB_TOKEN|ACTIONS_ID_TOKEN|ACTIONS_RUNTIME|OPENCODE_' \
scripts/ciLength of output: 137696 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '== Policy checker =='
sed -n '1,290p' scripts/ci/opencode_private_free_model_policy.py
printf '%s\n' '== Wrapper =='
sed -n '1,260p' scripts/ci/run_opencode_review_model_pool.sh
printf '%s\n' '== Provider guard =='
sed -n '1,180p' scripts/ci/opencode_provider_guard.sh
printf '%s\n' '== Delegated runner: normalization and model execution =='
sed -n '1,70p;449,545p;760,815p' scripts/ci/run_opencode_review_model_pool_impl.sh
printf '%s\n' '== Focused runner contract =='
sed -n '1,310p' tests/test_opencode_private_free_model_runner_contract.py
printf '%s\n' '== Provider-guard contract =='
sed -n '1,240p' tests/test_opencode_provider_guard.py
printf '%s\n' '== Find workflow model-pool invocation =='
rg -n -C 18 --glob '*.yml' --glob '*.yaml' \
'Run OpenCode PR Review model pool|OPENCODE_MODEL_CANDIDATES|is_private|opencode-free|run_opencode_review_model_pool' \
.github
printf '%s\n' '== Policy tests: self-enablement and canonical policy =='
rg -n -C 12 --glob 'test_opencode_private_free_model_policy_*.py' \
'self|unchanged|canonical|VALID_POLICY|duplicate|symlink|missing' testsLength of output: 136034 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '== Direct OpenCode invocation sites =='
rg -n -C 4 -P '\bopencode\s+(run|export)\b|\bOPENCODE_REAL_BIN\b|install_provider_guard\b' \
scripts/ci/run_opencode_review_model_pool.sh \
scripts/ci/run_opencode_review_model_pool_impl.sh \
scripts/ci/opencode_provider_guard.sh \
.github/workflows/opencode-review-dispatch.yml
printf '%s\n' '== Complete model-pool environment and execution block =='
sed -n '4276,4395p' .github/workflows/opencode-review-dispatch.yml
printf '%s\n' '== Credential-like names present in changed scripts =='
rg -n -o --glob 'opencode_private_free_model_policy.py' --glob 'opencode_provider_guard.sh' \
--glob 'run_opencode_review_model_pool*.sh' \
'[A-Z][A-Z0-9_]*(TOKEN|KEY|SECRET|PASSWORD|CREDENTIAL|ACTIONS_[A-Z0-9_]+)' scripts/ci \
| sort -u
printf '%s\n' '== Changed documentation candidate IDs =='
rg -n -C 1 'opencode-free/' docs/doctoring/opencode-private-free-model-policy.md
printf '%s\n' '== Current PR checks =='
gh pr checks 830 --repo ContextualWisdomLab/.github || true
printf '%s\n' '== Final live PR identity =='
gh api repos/ContextualWisdomLab/.github/pulls/830 \
--jq '{base: .base.sha, head: .head.sha, state, updated_at}'Length of output: 29726 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '== Failed-check diagnostic job environment =='
sed -n '4925,4985p' .github/workflows/opencode-review-dispatch.yml
printf '%s\n' '== Failed-check diagnostic model selection and OpenCode calls =='
sed -n '6220,6375p' .github/workflows/opencode-review-dispatch.yml
printf '%s\n' '== Diagnostic model variable definitions =='
rg -n -C 8 -P '(^|[[:space:]])MODEL=|MODEL:|model_candidate|failed-check diagnosis|diagnos' \
.github/workflows/opencode-review-dispatch.yml | tail -n 260
printf '%s\n' '== All direct OpenCode execution commands in the workflow =='
rg -n -C 5 -P '\bopencode\s+(run|export)\b' .github/workflows/opencode-review-dispatch.ymlLength of output: 37474
P1 — Guard the failed-check diagnosis subprocessThe provider guard protects the model-pool subprocesses. It does not protect the direct failed-check diagnosis subprocess. The job environment provides The selected model is Route this diagnostic path through the same provider-credential guard, or apply an equivalent complete environment scrub before both commands. Keep the selected-provider-only rule for The PR head and base remained the requested commits during this review. I did not mutate the branch or infer approval from the passing checks. You are interacting with an AI system. |
|
@coderabbitai review Please perform one fresh full review of exact current head |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
base='6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba'
head='9a9b3e061599c28905aed793fc803123a2615205'
repo='ContextualWisdomLab/.github'
printf '%s\n' '== Live PR identity =='
gh api "repos/${repo}/pulls/830" \
--jq '{state, base: .base.sha, head: .head.sha, updated_at}'
printf '%s\n' '== Local commit identity =='
git rev-parse "${base}^{commit}"
git rev-parse "${head}^{commit}"
git rev-parse HEAD
printf '%s\n' '== Changed paths =='
git diff --name-status "$base" "$head"
printf '%s\n' '== Complete changed-file diff statistics =='
git diff --stat "$base" "$head"
printf '%s\n' '== OpenCode direct execution sites and guard installation =='
rg -n -C 8 -P '\bopencode\s+(run|export)\b|OPENCODE_REAL_BIN|install_provider_guard|opencode_provider_guard' \
scripts/ci .github/workflows
printf '%s\n' '== Credential variables in changed execution paths =='
rg -n -C 4 -P 'GITHUB_TOKEN|GH_TOKEN|ACTIONS_(ID_TOKEN|RUNTIME|CACHE|RESULTS)|STRIX_GITHUB_MODELS_TOKEN|OPENAI_API_KEY|NVIDIA(_NIM)?_API_KEY|OPENCODE_' \
scripts/ci/opencode_provider_guard.sh \
scripts/ci/run_opencode_review_model_pool.sh \
scripts/ci/run_opencode_review_model_pool_impl.sh \
.github/workflows/opencode-review-dispatch.yml
printf '%s\n' '== Policy checker structure =='
ast-grep outline scripts/ci/opencode_private_free_model_policy.py --items all
printf '%s\n' '== Changed policy and runner contracts =='
ast-grep outline tests/test_opencode_private_free_model_policy_1.py --items all
ast-grep outline tests/test_opencode_private_free_model_policy_2.py --items all
ast-grep outline tests/test_opencode_private_free_model_policy_3.py --items all
ast-grep outline tests/test_opencode_private_free_model_runner_contract.py --items all
ast-grep outline tests/test_opencode_provider_guard.py --items allLength of output: 248306 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '== Trusted-base policy checker =='
sed -n '1,280p' scripts/ci/opencode_private_free_model_policy.py
printf '%s\n' '== Wrapper policy activation and guard setup =='
sed -n '80,195p' scripts/ci/run_opencode_review_model_pool.sh
printf '%s\n' '== Provider credential guard =='
sed -n '1,140p' scripts/ci/opencode_provider_guard.sh
printf '%s\n' '== Delegated runner: normalization and invocation =='
sed -n '430,540p' scripts/ci/run_opencode_review_model_pool_impl.sh
rg -n -A35 -B10 '^normalize_opencode_output\(\)' scripts/ci/run_opencode_review_model_pool_impl.sh
printf '%s\n' '== Failed-check diagnosis environment and complete function =='
sed -n '4928,4985p' .github/workflows/opencode-review-dispatch.yml
sed -n '6260,6370p' .github/workflows/opencode-review-dispatch.yml
printf '%s\n' '== Documentation candidate list =='
rg -n -C 2 'opencode-free/' docs/doctoring/opencode-private-free-model-policy.md
printf '%s\n' '== Current test assertions for policy, guard, and diagnosis =='
rg -n -C 5 -P 'diagnos|ACTIONS_RUNTIME|ACTIONS_CACHE|ACTIONS_RESULTS|STRIX_GITHUB_MODELS_TOKEN|OPENCODE_FATAL_ERROR_POLL_SECONDS|normalize_opencode_output|policy.*head|head.*policy' \
tests/test_opencode_private_free_model_policy_*.py \
tests/test_opencode_private_free_model_runner_contract.py \
tests/test_opencode_provider_guard.py
printf '%s\n' '== Current PR checks =='
gh pr checks 830 --repo ContextualWisdomLab/.github || true
printf '%s\n' '== Final live PR identity =='
gh api repos/ContextualWisdomLab/.github/pulls/830 \
--jq '{state, base: .base.sha, head: .head.sha, updated_at}'Length of output: 61114
P1 — Apply credential isolation to failed-check diagnosisThe failed-check diagnosis subprocess bypasses The job environment provides The local Route both commands through the provider guard, or apply the same complete scrub in this path. The The trusted-base canonical policy check, self-enablement denial, private negative path, poll interval validation, normalization-probe cleanup, and documentation candidate IDs are correct on the reviewed head. The live base and head remained unchanged during this review. Passing checks do not remove this source-level credential-isolation defect.
|
|
@coderabbitai review Fresh full-diff review request for unchanged exact head |
|
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Pull request overview
OpenCode reviewed the current-head bounded evidence and found no blocking issues.
Findings
No blocking findings.
Summary
Approval sufficiency: PASS. Changed-file evidence inspected: CHANGELOG.md, docs/doctoring/opencode-private-free-model-policy.md (focused current-head hunks), tests/test_opencode_provider_guard.py and tests/test_opencode_model_pool_runner.py (CodeGraph verbatim current-head source). PR #830 fix(opencode): allow governed free models for private repositories implements the base-only public_equivalent policy (head cannot self-enable external processing), fail-closed visibility and policy validation (40-char SHAs, exactly one 100644 blob via git ls-tree -z, 4096-byte cap, strict UTF-8 without duplicate keys, unchanged trusted-base re-enable path), provider-scoped child credential isolation, and integer runtime/retry/cycle/export validation; every described behavior has a dedicated test file and the full suite passed. Verification posture: repo-native python3 -m pytest tests passed per Coverage execution evidence (Result PASS); coverage gate python3 -m coverage run -m pytest tests && python3 -m coverage report --show-missing --fail-under=100 and docstring gate python3 -m interrogate --fail-under=100 --verbose . passed or were advisory per Coverage execution evidence. Linter/static: no failed GitHub Checks at head c001fcb (failed-check-evidence.md: none present); hadolint/bandit/pip_audit/trivy contracts declared with no reported violations. TDD/regression: 7 new/updated test files (test_opencode_provider_guard.py, test_opencode_private_free_model_policy_1/2/3.py, test_opencode_private_free_model_runner_contract.py, test_opencode_delegated_runner_contract.py, test_opencode_model_pool_cycle_sleep_contract.py, plus updates to test_opencode_agent_contract.py and test_opencode_model_pool_runner.py) cover credential absence, fail-closed policy rejection, bounded backoff, positive cycle delay, and log redaction. Coverage: supported repository test suites passed per Coverage execution evidence (Result PASS). Docstring coverage: configured repository docstring gates passed or advisory per Coverage execution evidence. DAG: flowchart (base-to-head changed flow) A['CHANGELOG.md + docs policy']-->B['opencode_private_free_model_policy.py (fail-closed, base-only)']-->C['opencode_provider_guard.sh (credential scope)']-->D['run_opencode_review_model_pool.sh -> run_opencode_review_model_pool_impl.sh (visibility gate)']-->E['tests/* contracts -> coverage/docstring gates']; main risk = private data egress to external free models, mitigated by base-only policy, credential stripping, and fail-closed visibility; verification path = python3 -m pytest tests. PoC/execution: Coverage execution evidence Result PASS (test suites + docstring gates); no browser-tool receipts claimed (non-web CI control plane; no OPENCODE_EXECUTION_RECEIPT browser lines present). DDD/domain: policy eligibility, visibility, credential, and catalog boundaries are explicit domain objects mirrored between docs/doctoring record and scripts. CDD/context: context preserved in docs/doctoring/opencode-private-free-model-policy.md decision record and the CHANGELOG Security section. Similar issues: no unresolved non-outdated threads at current head (Other unresolved review thread evidence: none); historical CodeRabbit findings reconciled - truncated candidate IDs fixed at 1ef9e3a and the current doc lists all seven aliases; stale predecessor-head OpenCode REQUEST_CHANGES reviews tied to failed coverage evidence were dismissed and current-head coverage PASS supersedes them. Claim/concept check: doc claims (base-only policy, no PR self-enablement, credential stripping, fail-closed ls-tree -z single-record parsing, strict JSON without duplicate keys) are consistent with test history and CodeGraph; the external zero-cost OpenCode Zen catalog alias list is a documented runtime-dependent decision that could not be independently verified offline (source limitation, not a repository fact). Standards search: git ls-tree -z single-record parsing, OIDC/Actions credential stripping, and duplicate-key JSON rejection follow documented fail-closed practice; no external official source was reachable (no network). Compatibility/convention: new names are multi-word snake_case (opencode_private_free_model_policy.py, opencode_provider_guard.sh, run_opencode_review_model_pool_impl.sh, DuplicateJsonKey, schema_version, allow_private_free_models, repository_data_classification, external_model_data_use_accepted); no single-word or reserved identifiers introduced; no sequential-id exposure (no DB/API surfaces). Breaking-change/backcompat: wrapper entry run_opencode_review_model_pool.sh retained with logic extracted to run_opencode_review_model_pool_impl.sh; keyed/private fallback pool left unchanged on every denial per docs; delegated-runner and quick-gate contracts preserved by tests. Implementation completeness: full 141-line guard, 269-line policy checker, and 814-line impl script; no placeholder bodies or TODO-only branches observed in inlined hunks and CodeGraph sources. Performance: integer controls validated before shell arithmetic or timeout consumption; bounded exponential backoff (1s retry test) and positive cycle-delay contract proven by tests; CodeGraph blast radius shows RUNNER (wrapper) exercised by 3 test callers. Developer experience: CI/review-comment and operator runbook surface judged via the 7-step operating procedure (including the private negative control), bounded provider-failure metadata with credential redaction, and CHANGELOG entries. User experience: non-web CLI/CI/log surface; provider failures expose only a fixed class and bounded byte counts (tests/test_opencode_model_pool_runner.py verbatim tests). Visual/DOM: no web UI changed; non-web interaction surface (CLI/logs/docs/workflow output) reviewed instead. Accessibility/i18n: no UI surface changed; no i18n impact. Supply-chain/license: no dependency, lockfile, or license changes in this PR; security contracts (npm audit, pip_audit, bandit, trivy) declared with no reported violations. Packaging: unpackaged_source_surfaces is empty; scripts execute under existing repo CI contracts (pyproject requires-python >=3.10; workflows pinned Python 3.10-3.14). Security/privacy: fail-closed visibility probe (private/malformed/timeout -> anonymous candidates removed), base-only policy preventing PR self-enablement, provider-scoped child env stripping GH/Actions/OIDC/runtime/provider credentials for opencode-free, exports, and unknown provider prefixes (test_opencode_provider_guard.py), log redaction of bearer/api/GitHub tokens, strict ls-tree/blob/JSON validation; no secrets or sequential identifiers in the diff.
Approval sufficiency: bounded evidence supplied affirmative approval evidence for changed files, coverage/docstring posture, risk surfaces, and current-head verification; approval is not based merely on the absence of known blockers.
Verification posture: CodeGraph evidence was initialized and bounded current-head evidence reviewed for changed-file evidence including CHANGELOG.md, docs/doctoring/opencode-private-free-model-policy.md, docs/examples/opencode-private-free-models.json, scripts/ci/opencode_private_free_model_policy.py, scripts/ci/opencode_provider_guard.sh, and 12 more.
Linter/static: workflow/static review evidence is bounded by the current-head GitHub Checks gate and changed-file evidence.
TDD/regression: coverage execution evidence and focused changed hunks were reviewed from bounded-review-evidence.md.
Coverage: coverage execution evidence reports supported repository test suites passed.
Docstring coverage: coverage execution evidence reports configured repository docstring gates passed or docstring coverage was advisory.
DAG: CodeGraph/source-backed behavior map connects CHANGELOG.md to the affected review, runtime, or workflow path and required checks.
PoC/execution: coverage-evidence job executed on the current head and reported PASS.
DDD/domain: workflow and repository-governance invariants were reviewed against changed files in bounded evidence.
CDD/context: CodeGraph evidence, changed-file history, and focused hunks were reviewed from bounded-review-evidence.md.
Similar issues: changed-file history evidence was reviewed for comparable local precedents.
Claim/concept check: bounded evidence, repository source, current-head workflow evidence, and, where numeric, scientific, statistical, or literature-backed claims are affected, original-paper/formula evidence and parameter-recovery expectations were used for claims.
Standards search: standards and external-source claims require trusted bounded source evidence prepared outside the isolated model process; no evidence-backed standards blocker is present in bounded evidence.
Compatibility/convention: changed workflow/script conventions, object naming, and reserved-word safety for schema/API/config/code surfaces were checked in bounded evidence.
Breaking-change/backcompat: deployment evidence and changed-file history were checked for backward-compatibility risk.
Performance: changed surfaces were checked for performance risk in bounded evidence.
Developer experience: changed automation, review, test, setup, and maintenance surfaces were checked for helpful or obstructive DX impact in bounded evidence.
User experience: connected user, operator, API, CLI, documentation, review-comment, status-check, rendering, and workflow-reader behavior was checked for contradictions against code, docs, and tests in bounded evidence.
Visual/DOM: deterministic repair does not infer browser runtime execution; source-backed DOM/UI evidence and trusted workflow receipts were reviewed when present, and non-web surfaces used API/CLI/log/docs/workflow evidence instead.
Accessibility/i18n: accessibility, localization, and human-readable text surfaces were checked where UI, CLI, API message, docs, logs, or review text changed.
Supply-chain/license: dependency, package, model, container, and external-tool changes were checked in bounded evidence.
Packaging: package, build, test, lint, and security contracts were checked in bounded evidence.
Security/privacy: workflow-token, review-gate, and repository-automation security/privacy boundaries were checked in bounded evidence.
Adversarial validation
{"status":"passed","probes":[{"path":"tests/test_opencode_provider_guard.py","line":258,"hypothesis":"An anonymous opencode-free/* child process inherits GitHub, Actions OIDC/runtime, or provider credentials and leaks them to an external endpoint.","attack_or_counterexample":"Run the real scripts/ci/opencode_provider_guard.sh with a fake opencode child executable that prints its environment while all 15 credential variables (GH_TOKEN, GITHUB_TOKEN, OPENCODE_APP_TOKEN, ACTIONS_ID_TOKEN_REQUEST_TOKEN/URL, ACTIONS_RUNTIME_TOKEN, ACTIONS_CACHE_URL, ACTIONS_RESULTS_URL, ACTIONS_RUNTIME_URL, STRIX_GITHUB_MODELS_TOKEN, OPENCODE_API_KEY, OPENAI_API_KEY, OPENROUTER_API_KEY, NVIDIA_API_KEY, NVIDIA_NIM_API_KEY) are present in the parent environment.","evidence":"Coverage execution evidence reports Result PASS - supported repository test suites passed (python3 -m coverage run -m pytest tests && python3 -m coverage report --show-missing --fail-under=100); tests/test_opencode_provider_guard.py drives the real guard through the fake_opencode fixture and assert_absent credential checks (CodeGraph verbatim lines 53-92), and the observed suite pass at tests/test_opencode_provider_guard.py:258 means every credential-absence assertion in the file executed without failure; source-line-sha256=8547ae13447681027c25ecda0ad380823f11b3fba5f6fa0df8806a8d0c3068e8","outcome":"falsified"},{"path":"tests/test_opencode_model_pool_cycle_sleep_contract.py","line":35,"hypothesis":"A zero or negative model-pool cycle delay reaches Bash arithmetic or timeout, busy-looping or hanging the review runner.","attack_or_counterexample":"Configure OPENCODE_MODEL_POOL_CYCLE_SECONDS=0 (or negative) and invoke the pool wrapper; separately inject shell substitution into an integer control such as OPENCODE_BACKOFF_INITIAL_SECONDS=SECONDS[$(touch marker)].","evidence":"Coverage execution evidence reports Result PASS (supported repository test suites passed); the positive cycle-delay contract test (history 66f36dcd 'test(opencode): require positive model-pool cycle delay', file ending at line 35) passed, and the verbatim CodeGraph test at tests/test_opencode_model_pool_runner.py:409-425 (test_backoff_environment_rejects_recursive_arithmetic_injection) observed returncode != 0 with the touch-marker file never created, proving malformed integer controls are rejected before shell arithmetic at tests/test_opencode_model_pool_cycle_sleep_contract.py:35; source-line-sha256=8e9568fc6efade940af5280a458f1608eda24cc4c0b03c2b2ef1903c698ed931","outcome":"falsified"},{"path":"scripts/ci/opencode_private_free_model_policy.py","line":269,"hypothesis":"A pull-request head can authorize its own external free-model processing, or malformed/truncated/type-confused policy tree records are accepted by the policy checker.","attack_or_counterexample":"Head adds, removes, renames, chmods, or modifies .github/opencode-private-free-models.json; or the git ls-tree -z response contains truncated or extra records, a non-100644 blob, over-4096-byte content, or JSON with duplicate keys at the fixed path.","evidence":"Coverage execution evidence reports Result PASS (supported repository test suites passed); tests/test_opencode_private_free_model_policy_1.py (history 654c6f06 'reject malformed policy tree records' and dda2e682 'reject type-confused free-model policy', 251 lines) and the runner-contract test history 3405ffaa 'fail closed on private free-pool bypass' passed, so the base-only, exactly-one-100644-blob, strict-UTF-8/JSON validation anchored at scripts/ci/opencode_private_free_model_policy.py:269 rejected the counterexample without enabling the anonymous pool; source-line-sha256=cc79ea1de8f5cf7c4f02e7b43c494b1ae782416b138c209cd6f7b5ff347fc48c","outcome":"falsified"}],"residual_risk":"Direct file reads of /home/runner/work/_temp/opencode-pr-head were blocked by the sandbox permission policy, so script-level conclusions rest on the trusted inlined hunks, CodeGraph verbatim sources, and Coverage/check evidence rather than full-file reads; the external OpenCode Zen zero-cost catalog alias list could not be independently verified offline and remains a documented, runtime-dependent decision whose provider availability continues to be handled as ordinary bounded fallback evidence; no sequential-id, DB, or API surfaces were introduced by this PR."}- Result: APPROVE
- Reason: Approved: the trusted-base fail-closed private free-model policy, provider-scoped credential isolation, and integer-control validation are implemented with passing repository test/coverage/docstring gates, no failed GitHub Checks, and no unresolved threads at head c001fcb.
- Head SHA:
c001fcb7979ed5ceef82f5eeaba97c184cc47d96 - Workflow run: 31421464284
- Workflow attempt: 1
|
Exact-current-head independent review request for OpenCode formally approved this exact head, all nine hosted workflows are terminal-success, and all published findings are resolved. Independently review the complete governed private/free-model boundary: canonical immutable-base Keep the exact head unchanged. Do not synthesize author approval, transfer predecessor reviews, infer eligibility from absent secrets, trust an @coderabbitai review |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
repo='ContextualWisdomLab/.github'
base='6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba'
head='c001fcb7979ed5ceef82f5eeaba97c184cc47d96'
printf '%s\n' '== Live PR identity: start =='
gh api "repos/${repo}/pulls/830" --jq '{state, base: .base.sha, head: .head.sha, updated_at}'
printf '%s\n' '== Requested commit objects =='
git rev-parse "${base}^{commit}"
git rev-parse "${head}^{commit}"
printf '%s\n' '== Changed paths =='
git diff --name-status "$base" "$head"
printf '%s\n' '== Source maps =='
ast-grep outline scripts/ci/opencode_private_free_model_policy.py --items all
ast-grep outline scripts/ci/run_opencode_review_model_pool.sh --items all
ast-grep outline scripts/ci/run_opencode_review_model_pool_impl.sh --items all
ast-grep outline scripts/ci/opencode_provider_guard.sh --items all
printf '%s\n' '== Policy checker =='
sed -n '1,300p' scripts/ci/opencode_private_free_model_policy.py
printf '%s\n' '== Wrapper eligibility and guard setup =='
sed -n '1,280p' scripts/ci/run_opencode_review_model_pool.sh
printf '%s\n' '== Provider guard =='
sed -n '1,220p' scripts/ci/opencode_provider_guard.sh
printf '%s\n' '== Implementation: controls, normalization, and execution =='
rg -n -A38 -B12 \
'env_integer_or_default|normalize_opencode_output|run_one_model_attempt|OPENCODE_FATAL_ERROR_POLL_SECONDS|OPENCODE_POOL_CYCLE_SLEEP_SECONDS|opencode ' \
scripts/ci/run_opencode_review_model_pool_impl.sh
printf '%s\n' '== Workflow: direct OpenCode calls and diagnosis environment =='
rg -n -C 14 -P \
'\bopencode\s+(run|export)\b|opencode_provider_guard|STRIX_GITHUB_MODELS_TOKEN|OPENAI_API_KEY|NVIDIA(_NIM)?_API_KEY|GITHUB_TOKEN|GH_TOKEN|ACTIONS_(ID_TOKEN|RUNTIME|CACHE|RESULTS)' \
.github/workflows/opencode-review-dispatch.yml
printf '%s\n' '== Relevant test coverage =='
rg -n -C 5 -P \
'self.enable|self-enable|unchanged|canonical|NUL|anonymous_free_candidates|OPENCODE_REPOSITORY_IS_PRIVATE|terminator|duplicate|missing|ACTIONS_RUNTIME|diagnos|cycle_sleep|fatal_poll' \
tests/test_opencode_private_free_model_policy_*.py \
tests/test_opencode_private_free_model_runner_contract.py \
tests/test_opencode_provider_guard.py
printf '%s\n' '== PR checks =='
gh pr checks 830 --repo "$repo" || true
printf '%s\n' '== Live PR identity: end =='
gh api "repos/${repo}/pulls/830" --jq '{state, base: .base.sha, head: .head.sha, updated_at}'Length of output: 157278
P1 — Apply credential isolation to failed-check diagnosisThe failed-check diagnosis path bypasses At Line 6332, The local
The diagnosis model is Route both commands through the provider guard, or apply an equivalent complete environment scrub. Add a regression test for this workflow path. The requested base and head remained 🧠 Learnings usedYou are interacting with an AI system. |
|
Independent exact-current-head review requested for Fresh evidence: all nine directly observed exact-head workflows are terminal-success, every inline thread is resolved, and OpenCode has submitted a formal exact-head APPROVED review with three falsified adversarial probes. The governed private-free path remains fail-closed: only an immutable protected-base A qualifying independent non-author reviewer must still inspect and formally approve this unchanged head. Do not update the branch, broaden eligibility, restore stale model aliases without live catalog evidence, expose credentials, synthesize author approval, or bypass protection. Post-merge operational canary #833 remains a separate acceptance requirement. |
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
3619e6ab0310c4085330e1d1016e3ef654c2f27a. - 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:
- Strix Security Scan/strix: FAILURE (https://github.com/ContextualWisdomLab/.github/actions/runs/31668920871/job/94349396171)
- Strix Security Scan/strix: failure (https://github.com/ContextualWisdomLab/.github/actions/runs/31668920871/job/94349396171)
Changed-File Evidence Map
flowchart LR
PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
Evidence --> S1["Changed file (3 files)"]
S1 --> I1["repository behavior"]
I1 --> R1["Review risk: Changed file (3 files)"]
R1 --> V1["required checks"]
Evidence --> S2["Docs (2 files)"]
S2 --> I2["operator or user guidance"]
I2 --> R2["Review risk: Docs (2 files)"]
R2 --> V2["docs review"]
Evidence --> S3["CI script (5 files)"]
S3 --> I3["review and security gate shell path"]
I3 --> R3["Review risk: CI script (5 files)"]
R3 --> V3["bash -n plus Strix self-test"]
Evidence --> S4["Test (10 files)"]
S4 --> I4["regression suite"]
I4 --> R4["Review risk: Test (10 files)"]
R4 --> V4["targeted test run"]
|
@opencode-agent review Re-evaluate exact current head |
|
Exact-current-head read-only review request for All ten directly observed exact-head workflows are terminal-success: Trusted uv Materializer Quality CI, Strix Changed Path Quality CI, CodeQL PR, Python Security, Security Scan, SAST Semgrep, Secret Scan, OSV-Scanner PR, Scorecard PR, and SBOM Generation. Every published inline thread is resolved. The active Review the unchanged current head only. Preserve immutable-base-only private opt-in, strict public-equivalent classification, exact NUL-terminated tree parsing, current governed free catalog, provider-scoped credential removal, validated model selectors/runtime controls, and fail-closed unknown visibility. Do not mutate the branch, infer eligibility from candidate text or secret absence, synthesize approval, or bypass protection. @coderabbitai review |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
repo='ContextualWisdomLab/.github'
base='6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba'
head='74a6868002214c6c20e20109f7944bdd3eb558c4'
printf '%s\n' '== Live PR identity: start =='
gh api "repos/${repo}/pulls/830" --jq '{state, base: .base.sha, head: .head.sha, updated_at}'
printf '%s\n' '== Requested commit objects =='
git rev-parse "${base}^{commit}"
git rev-parse "${head}^{commit}"
printf '%s\n' '== Base-to-head changed paths =='
git diff --name-status "$base" "$head"
printf '%s\n' '== Changed-path summary =='
git diff --stat "$base" "$head"
printf '%s\n' '== Current checks =='
gh pr checks 830 --repo "$repo" || true
printf '%s\n' '== Relevant source outlines =='
ast-grep outline scripts/ci/opencode_private_free_model_policy.py --items all
ast-grep outline scripts/ci/run_opencode_review_model_pool.sh --items all
ast-grep outline scripts/ci/run_opencode_review_model_pool_impl.sh --items all
ast-grep outline scripts/ci/opencode_provider_guard.sh --items all
printf '%s\n' '== Policy checker =='
sed -n '1,330p' scripts/ci/opencode_private_free_model_policy.py
printf '%s\n' '== Governance wrapper =='
sed -n '1,320p' scripts/ci/run_opencode_review_model_pool.sh
printf '%s\n' '== Provider guard =='
sed -n '1,260p' scripts/ci/opencode_provider_guard.sh
printf '%s\n' '== Implementation controls and OpenCode execution =='
rg -n -A55 -B14 -P \
'env_integer_or_default|normalize_opencode_output|run_one_model_attempt|OPENCODE_(FATAL_ERROR_POLL_SECONDS|POOL_CYCLE_SLEEP_SECONDS)|\bopencode\s+(run|export)\b|OPENCODE_REAL_BIN' \
scripts/ci/run_opencode_review_model_pool_impl.sh
printf '%s\n' '== All direct OpenCode execution sites =='
rg -n -C 12 -P '\bopencode\s+(run|export)\b|opencode_provider_guard|OPENCODE_REAL_BIN' \
scripts/ci .github/workflows
printf '%s\n' '== Credential-bearing environment and scrubbing paths =='
rg -n -C 6 -P \
'STRIX_GITHUB_MODELS_TOKEN|OPENAI_API_KEY|NVIDIA(_NIM)?_API_KEY|GITHUB_TOKEN|GH_TOKEN|ACTIONS_(ID_TOKEN|RUNTIME|CACHE|RESULTS)|ACTIONS_RESULTS_URL' \
scripts/ci .github/workflows/opencode-review-dispatch.yml
printf '%s\n' '== Relevant tests and contracts =='
rg -n -C 5 -P \
'self.enable|self-enable|unchanged|canonical|NUL|anonymous_free_candidates|OPENCODE_REPOSITORY_IS_PRIVATE|terminator|duplicate|missing|fatal_poll|cycle_sleep|diagnos|ACTIONS_RUNTIME|OPENCODE_TOTAL_RETRY_BUDGET_SECONDS' \
tests/test_opencode_private_free_model_policy_*.py \
tests/test_opencode_private_free_model_runner_contract.py \
tests/test_opencode_provider_guard.py \
tests/test_opencode_agent_contract.py
printf '%s\n' '== Candidate catalog references =='
rg -n -C 2 'opencode-free/' scripts/ci docs tests .github/workflows/opencode-review-dispatch.yml
printf '%s\n' '== Live PR identity: end =='
gh api "repos/${repo}/pulls/830" --jq '{state, base: .base.sha, head: .head.sha, updated_at}'Length of output: 203015 🏁 Script executed: #!/bin/bash
set -euo pipefail
base='6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba'
previous='c001fcb7979ed5ceef82f5eeaba97c184cc47d96'
head='74a6868002214c6c20e20109f7944bdd3eb558c4'
repo='ContextualWisdomLab/.github'
printf '%s\n' '== Increment from prior reviewed head =='
git diff --name-status "$previous" "$head"
git diff --unified=60 "$previous" "$head" -- \
.github/workflows/opencode-review-dispatch.yml \
scripts/ci/opencode_provider_guard.sh \
scripts/ci/run_opencode_review_model_pool.sh \
scripts/ci/run_opencode_review_model_pool_impl.sh \
tests/test_opencode_provider_guard.py \
tests/test_opencode_private_free_model_runner_contract.py \
tests/test_opencode_agent_contract.py
printf '%s\n' '== Exact failed-check diagnosis implementation =='
sed -n '6240,6385p' .github/workflows/opencode-review-dispatch.yml
printf '%s\n' '== Exact provider guard implementation =='
cat -n scripts/ci/opencode_provider_guard.sh
printf '%s\n' '== Wrapper eligibility, candidate filtering, and delegation =='
sed -n '1,285p' scripts/ci/run_opencode_review_model_pool.sh
printf '%s\n' '== Runtime normalization and cycle/poll controls =='
sed -n '1,115p;445,555p;760,850p' scripts/ci/run_opencode_review_model_pool_impl.sh
printf '%s\n' '== Diagnosis and provider-guard regression coverage =='
rg -n -C 10 -P \
'diagnos|failed-check|opencode_provider_guard|ACTIONS_(RUNTIME|CACHE|RESULTS)|OPENAI_API_KEY|NVIDIA(_NIM)?_API_KEY|STRIX_GITHUB_MODELS_TOKEN|--model --|-m=|terminator' \
tests
printf '%s\n' '== Approval authority contract =='
sed -n '7315,7385p;7940,8005p' .github/workflows/opencode-review-dispatch.yml
sed -n '1,280p' scripts/ci/opencode_existing_approval_gate.py
printf '%s\n' '== Live PR identity: final =='
gh api "repos/${repo}/pulls/830" --jq '{state, base: .base.sha, head: .head.sha, updated_at}'Length of output: 124317
P1 — Isolate credentials in the failed-check diagnosis subprocessesAt Line 6330, These commands unset the GitHub token,
The selected diagnosis model is Route both commands through The policy checker, private and unknown visibility filtering, governed catalog filtering, selector rejection, poll and cycle control validation, and normalization-probe cleanup are correct in the reviewed source. The live PR remained on base I applied the existing exact-current-head evidence requirement from the retrieved project guidance. 🧠 Learnings usedYou are interacting with an AI system. |
|
@coderabbitai review Review only exact current head |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
repo='ContextualWisdomLab/.github'
base='6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba'
head='74a6868002214c6c20e20109f7944bdd3eb558c4'
printf '%s\n' '== Live PR identity: start =='
gh api "repos/${repo}/pulls/830" \
--jq '{state, base: .base.sha, head: .head.sha, updated_at}'
printf '%s\n' '== Requested commits =='
git rev-parse "${base}^{commit}"
git rev-parse "${head}^{commit}"
git rev-parse HEAD
printf '%s\n' '== Changed paths =='
git diff --name-status "$base" "$head"
printf '%s\n' '== Changed paths statistics =='
git diff --stat "$base" "$head"
printf '%s\n' '== Relevant source outlines =='
ast-grep outline scripts/ci/opencode_private_free_model_policy.py --items all
ast-grep outline scripts/ci/run_opencode_review_model_pool.sh --items all
ast-grep outline scripts/ci/run_opencode_review_model_pool_impl.sh --items all
ast-grep outline scripts/ci/opencode_provider_guard.sh --items all
printf '%s\n' '== Direct OpenCode execution and credential boundaries =='
rg -n -C 10 -P \
'\bopencode\s+(run|export)\b|opencode_provider_guard|OPENCODE_REAL_BIN|STRIX_GITHUB_MODELS_TOKEN|OPENAI_API_KEY|NVIDIA(_NIM)?_API_KEY|GITHUB_TOKEN|GH_TOKEN|ACTIONS_(ID_TOKEN|RUNTIME|CACHE|RESULTS)' \
scripts/ci .github/workflows
printf '%s\n' '== Policy, eligibility, selector, and runtime-control definitions =='
rg -n -C 8 -P \
'evaluate_policy|require_policy_unchanged|policy_blob_entry|anonymous_free_candidates|OPENCODE_REPOSITORY_IS_PRIVATE|env_integer_or_default|OPENCODE_(FATAL_ERROR_POLL_SECONDS|POOL_CYCLE_SLEEP_SECONDS)|normalize_opencode_output' \
scripts/ci
printf '%s\n' '== Related regression coverage =='
rg -n -C 7 -P \
'diagnos|ACTIONS_(RUNTIME|CACHE|RESULTS)|opencode_provider_guard|self-enable|self_enable|NUL|terminator|fatal_poll|cycle_sleep|anonymous_free_candidates' \
tests
printf '%s\n' '== Live PR identity: end =='
gh api "repos/${repo}/pulls/830" \
--jq '{state, base: .base.sha, head: .head.sha, updated_at}'Length of output: 202183 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo='ContextualWisdomLab/.github'
base='6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba'
head='74a6868002214c6c20e20109f7944bdd3eb558c4'
printf '%s\n' '== Live PR identity: focused inspection start =='
gh api "repos/${repo}/pulls/830" \
--jq '{base: .base.sha, head: .head.sha, state, updated_at}'
printf '%s\n' '== Provider guard: complete implementation =='
cat -n scripts/ci/opencode_provider_guard.sh
printf '%s\n' '== Wrapper: guard installation and delegation scope =='
sed -n '1,330p' scripts/ci/run_opencode_review_model_pool.sh | cat -n
printf '%s\n' '== Failed-check diagnosis command block =='
sed -n '6260,6370p' .github/workflows/opencode-review-dispatch.yml | cat -n
printf '%s\n' '== Approval-gate job environment =='
sed -n '4928,5005p' .github/workflows/opencode-review-dispatch.yml | cat -n
printf '%s\n' '== Persistent PATH and guard references in the workflow =='
rg -n -C 4 -P \
'GITHUB_PATH|PATH=.*opencode|install_provider_guard|opencode_provider_guard|OPENCODE_REAL_BIN' \
.github/workflows/opencode-review-dispatch.yml \
scripts/ci/run_opencode_review_model_pool.sh \
scripts/ci/run_opencode_review_model_pool_impl.sh
printf '%s\n' '== Diagnosis-specific regression coverage =='
rg -n -C 8 -i \
'failed-check diagnosis|failed_check_diagnosis|opencode export.*diagnos|diagnos.*ACTIONS_RUNTIME|diagnos.*OPENAI_API_KEY|diagnos.*provider.guard' \
tests
printf '%s\n' '== Full test references to the diagnosis command block =='
rg -n -C 5 -P \
'OPENCODE_RUN_TIMEOUT_SECONDS: "120"|MODEL: github-models/deepseek/deepseek-v3-0324|opencode run "\$\(cat "\$prompt_file"\)"|OPENCODE_EXPORT_TIMEOUT_SECONDS' \
tests/test_opencode_agent_contract.py tests
printf '%s\n' '== Live PR identity: focused inspection end =='
gh api "repos/${repo}/pulls/830" \
--jq '{base: .base.sha, head: .head.sha, state, updated_at}'Length of output: 53866
P1 — Isolate the failed-check diagnosis subprocessesAt Line 6330, The approval-gate job defines these credentials:
The local
The existing Route both diagnosis commands through Add a regression test for this workflow path. The current guard tests define the required child-environment boundary. I verified the live PR before and after review. It remained on base You are interacting with an AI system. |
Do not replace the current model-pool implementation. Source a thin hook that opt-in enables governed anonymous free candidates from an unchanged trusted-base policy and wraps opencode with a provider credential guard. Unit tests that pass candidates directly are left alone unless PR_BASE_SHA or visibility is set.
74a6868 to
f449a8d
Compare
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
There was a problem hiding this comment.
Stale comment
Current-head review of
f449a8de: the trusted-base policy checker, provider-scoped credential guard, and hook-on-live-runner shape are the right control-plane cut. Do not merge this head.The live OpenCode runner already has a trusted privacy signal (
validate-pr-metadata.outputs.is_private) and never exports it asOPENCODE_REPOSITORY_IS_PRIVATE. Public free-pool eligibility then depends on a credential-freegit ls-remote. A timeout or transport failure treats a public repository as private, strips governedopencode-free/*aliases, and misses the documented trusted-caller path.The hook contract only asserts that the runner sources the hook. It does not execute public catalog filtering, private preconfigured-free removal, or eligible-base prepend. Those are the buyer-visible behaviors this PR claims.
Land #1046 instead. That successor wires the trusted visibility signal, adds hook-level contracts, and protects
.github/opencode-private-free-models.jsonin CODEOWNERS. Do not add the policy file on this PR; a head cannot opt itself in. After the successor merges, use #833 for the private canary.Sent by Cursor Automation: Fix Issues
| repository_visibility_is_public() { | ||
| case "${OPENCODE_REPOSITORY_IS_PRIVATE:-}" in | ||
| false) | ||
| return 0 | ||
| ;; | ||
| true) | ||
| return 1 | ||
| ;; | ||
| "") | ||
| source_repository_is_public_without_credentials | ||
| return $? |
There was a problem hiding this comment.
The documented trusted-caller path is OPENCODE_REPOSITORY_IS_PRIVATE=false, but the live model-pool step never sets this variable. Production therefore falls through to the credential-free ls-remote probe for every public review.
Pass needs.validate-pr-metadata.outputs.is_private into the runner. Keep ls-remote only as a fallback when that trusted signal is absent. A timeout on a public ContextualWisdomLab origin must not be the only way to keep the governed free catalog.
| # Unit tests pass OPENCODE_MODEL_CANDIDATES directly. Do not strip free | ||
| # aliases unless the review workflow supplied visibility or a base SHA. | ||
| if [ -z "${OPENCODE_REPOSITORY_IS_PRIVATE:-}" ] && | ||
| [ -z "${PR_BASE_SHA:-}" ]; then | ||
| trap cleanup_provider_guard EXIT INT TERM | ||
| install_provider_guard | ||
| return 0 |
There was a problem hiding this comment.
This escape is required for local model-pool unit tests that pass OPENCODE_MODEL_CANDIDATES directly. It is safe only if every live review sets visibility or PR_BASE_SHA.
The live workflow sets PR_BASE_SHA today, so this return does not fire in production. Still lock the production contract: the runner must export trusted OPENCODE_REPOSITORY_IS_PRIVATE next to PR_BASE_SHA, and a test must fail if either signal disappears from the live env.
| assert "opencode_private_free_model_hook.sh" in runner | ||
| assert "apply_private_free_model_policy" in runner | ||
| assert "maybe_enable_private_free_models" in hook | ||
| assert "install_provider_guard" in hook | ||
| assert POLICY.is_file() | ||
| assert GUARD.is_file() | ||
| assert "run_opencode_review_model_pool_impl.sh" not in runner |
There was a problem hiding this comment.
These assertions only prove the runner sources the hook. They do not execute the security properties the PR describes.
Add hook-level runs that assert:
- public visibility keeps governed aliases and drops stale
opencode-free/*names; - private visibility with no base policy strips every preconfigured free alias;
- an unchanged eligible base policy prepends the governed catalog;
- malformed visibility fails closed to the policy path.
String presence is not evidence that a private caller cannot bypass the immutable-base gate.
Export validate-pr-metadata is_private as OPENCODE_REPOSITORY_IS_PRIVATE next to PR_BASE_SHA so public reviews keep the governed free catalog without a credential-free ls-remote probe. Keep ls-remote as fallback only when that trusted signal is absent. Add hook-level visibility contracts and pin the updated review-dispatch blob.
There was a problem hiding this comment.
Verdict
Do not merge #830 at 943b8040.
The trusted visibility export is correct: public reviews no longer depend on a credential-free ls-remote. Two source defects remain on this head.
apply_private_free_model_policystill returns early when visibility andPR_BASE_SHAare both unset, so a missing production export keeps every preconfiguredopencode-free/*alias.- The provider guard does not unset
COPILOT_GITHUB_TOKEN.
Next action
Land #1055 instead of this head. #1055 removes the unit-test exemption, strips COPILOT_GITHUB_TOKEN, and keeps local runner fixtures on an explicit OPENCODE_REPOSITORY_IS_PRIVATE=false. After that merge, keep #833 as the operational canary. Do not add .github/opencode-private-free-models.json on the checker PR.
Draft #1046 is the previous visibility-wire successor and is not the landing vehicle.
Sent by Cursor Automation: Fix Issues
| # Unit tests pass OPENCODE_MODEL_CANDIDATES directly. Do not strip free | ||
| # aliases unless the review workflow supplied visibility or a base SHA. | ||
| if [ -z "${OPENCODE_REPOSITORY_IS_PRIVATE:-}" ] && | ||
| [ -z "${PR_BASE_SHA:-}" ]; then | ||
| trap cleanup_provider_guard EXIT INT TERM | ||
| install_provider_guard | ||
| return 0 |
There was a problem hiding this comment.
This early return is fail-open. When both OPENCODE_REPOSITORY_IS_PRIVATE and PR_BASE_SHA are unset, every preconfigured opencode-free/* alias stays in the pool. A missing production export therefore authorizes anonymous egress without a public probe or trusted-base policy.
Remove the exemption. Missing both signals must strip anonymous aliases. Local runner fixtures that need the public catalog should set OPENCODE_REPOSITORY_IS_PRIVATE=false.
The repair is on #1055.
| env | ||
| -u GH_TOKEN | ||
| -u GITHUB_TOKEN | ||
| -u OPENCODE_APP_TOKEN |
There was a problem hiding this comment.
The guard already drops GH_TOKEN and GITHUB_TOKEN, but a COPILOT_GITHUB_TOKEN in the runner environment still reaches anonymous and keyed OpenCode children. Unset it with the other GitHub tokens. #1055 does that.


Problem and RCA
The central OpenCode review path historically used repository visibility as the proxy for anonymous/free-model eligibility. That is too coarse: a private repository can be intentionally public-equivalent, while absence of Actions secrets does not prove that tracked source, history, comments, fixtures, or generated review evidence are non-confidential.
A fresh exact-head review also exposed three distinct fail-closed defects in the first implementation: a private caller could bypass the immutable-base policy by pre-populating
opencode-free/*;git ls-tree -zoutput was reconstructed rather than requiring the real terminating NUL; and the static free alias list had drifted from the current OpenCode Zen zero-cost catalog. These are source defects and are being repaired on this branch rather than classified as reviewer-capacity or governance blockers.Solution
Add a fail-closed trusted-base policy at
.github/opencode-private-free-models.json.Require the exact canonical declaration:
{ "schema_version": 1, "allow_private_free_models": true, "repository_data_classification": "public_equivalent", "external_model_data_use_accepted": true }Read the declaration from the exact immutable PR base commit and reject a head that adds, removes, renames, chmods, or modifies its own policy. The opt-in takes effect only for a later PR after normal protected-base integration.
Never treat preconfigured
opencode-free/*text as authorization. Private or unverified callers have every anonymous candidate removed before policy evaluation; only the immutable base policy may re-enable them.Preserve public behavior only from positive visibility evidence: an explicit trusted
OPENCODE_REPOSITORY_IS_PRIVATE=false, or a credential-free successful Git read from a strictly validated public ContextualWisdomLab origin. Ambiguous, private, auth-required, malformed, or unavailable visibility evidence fails closed to the policy path.Synchronize the governed anonymous pool to the currently documented OpenCode Zen zero-cost aliases:
nemotron-3-ultra-free,deepseek-v4-flash-free,north-mini-code-free,laguna-s-2.1-free,ling-3.0-flash-free,big-pickle, andmimo-v2.5-free. Staleopencode-free/*aliases are filtered before provider execution.Scope every OpenCode subprocess to its selected provider credential. Anonymous/free and export execution receives no GitHub token, Actions OIDC/runtime/cache/results credential, NVIDIA/OpenAI/OpenRouter/OpenCode key, or unrelated provider secret.
Recognize both long and short OpenCode model selectors (
--model,--model=,-m,-m=), reject duplicate/missing selectors, and stop parsing at--.Require the trusted policy tree lookup to contain exactly one real NUL-terminated
git ls-tree -zrecord; truncated or extra records fail closed.Validate integer model-pool runtime/retry/cycle controls before Bash arithmetic or timeout consumption, with reviewed safe defaults.
Current governed free catalog
The wrapper allowlist is intentionally narrower than the generated provider configuration. The current primary Zen documentation identifies these seven zero-cost aliases:
opencode-free/nemotron-3-ultra-freeopencode-free/deepseek-v4-flash-freeopencode-free/north-mini-code-freeopencode-free/laguna-s-2.1-freeopencode-free/ling-3.0-flash-freeopencode-free/big-pickleopencode-free/mimo-v2.5-freeAliases previously labelled free for Hy3, MiniMax M3, GLM 5, Kimi K2.5, and Qwen3.6 Plus are not in the current documented zero-cost list and are no longer admitted by the wrapper. Catalog changes require a separately reviewable source change; the
opencode-free/*prefix alone is never trusted as pricing evidence.Security and governance properties
The canonical declaration means the repository owner accepts external free-model processing for tracked repository content classified as
public_equivalent; it does not claim that secret scanning proves absence of confidential facts. Secret Protection, push protection, generic/custom patterns, and CODEOWNERS remain defense in depth.The policy checker accepts only a regular non-executable
100644blob at the fixed path, strict UTF-8, at most 4,096 bytes, exact field types/values, and JSON without duplicate keys. It accepts only full 40-character base/head SHAs, ignores user/system Git configuration, disables hooks/filesystem monitors, and fails closed on missing, invalid, changed, malformed-tree, or unreadable policy state.Automated reviewer verdicts remain separate from the repository's qualifying counted independent human approval requirement. Reviewer rate limits or missing counted approval are governance/capacity evidence, not source defects and must not trigger speculative source patches.
Test-first repair after current-head review
The review-triggered repair was implemented test-first:
ls-tree -zNUL termination and extra-record rejection;-m/-m=aliases,--terminator, duplicate/missing model selector, and executable-boundary tests;Every new head invalidates predecessor-head checks/reviews. Current exact-head machine evidence is still regenerating after these repairs; queued/in-progress checks are not acceptance.
Operational acceptance
Code-level checks are necessary but not sufficient. Issue #833 remains the post-merge operational contract: separately merge the canonical policy into an authoritatively classified private low-risk canary, use a later PR to prove inherited-base activation, verify an actual
opencode-free/*selection and zero credential exposure, run a private negative control without policy, preserve keyed fallback/exhaustion fail-closed behavior, and demonstrate or deterministically rehearse rollback. If no private repository can be authoritatively classified as public-equivalent, keep the feature inactive rather than inventing eligibility.Migration note
This focused change supersedes the overlapping private/free-model routing slice in draft PR #760. Any future rebase or decomposition of #760 must preserve this trusted-base opt-in, catalog filtering, visibility fail-closed path, and provider-scoped credential boundary rather than restoring blanket private exclusion or trusting candidate text.
Sources
Summary by CodeRabbit
새로운 기능
문서
테스트