Skip to content

fix(opencode): bound free-model failover pool - #942

Open
seonghobae wants to merge 5 commits into
mainfrom
fix/opencode-pool-bounded-free-timeout
Open

fix(opencode): bound free-model failover pool#942
seonghobae wants to merge 5 commits into
mainfrom
fix/opencode-pool-bounded-free-timeout

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Problem and root cause

The central OpenCode review pool still advertised five stale free-provider aliases that fail with provider/auth errors, while one free candidate could consume up to 3,600 seconds. An observed ling-3.0-flash-free attempt occupied the full hour before the catalog exhausted without a verdict.

The root cause is twofold: a stale governed candidate catalog and a per-candidate timeout designed for paid/large models being reused for zero-cost failover. Merely retrying the stale aliases or turning timeout exhaustion into success would not change either cause.

Bounded repair

  • remove stale hy3-free, minimax-m3-free, glm-5-free, kimi-k2.5-free, and qwen3.6-plus-free definitions and candidates;
  • retain only the seven currently governed free candidates;
  • bound free-tier candidate attempts to 300 seconds while retaining the normal 5,400-second paid/large-review budget;
  • preserve fail-closed semantics: timeout advances only to another configured provider and can never approve a review;
  • preserve provider-scoped credential isolation, current-head review evidence, model-output validation, review authority, branch protection, and merge policy.

PR #830 owns the broader private-repository trusted-base opt-in, public-equivalent data classification, catalog provenance, and provider credential governance. This PR does not duplicate or weaken that boundary; after either branch integrates, reconcile the remaining unique timeout/catalog delta once against protected main.

Exact identity and scope

  • protected base and live tip: main@6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba;
  • exact current head: 44a302d283e2032f8b220d8f70a0acaae557bfa1;
  • state: Ready and mechanically mergeable;
  • bounded current diff: .github/workflows/opencode-review-dispatch.yml, scripts/ci/test_strix_quick_gate.sh, tests/test_opencode_agent_contract.py, focused doctoring, and CHANGELOG.md.

A cross-platform trusted-uv installer-test change had remained in the branch despite an earlier cleanup attempt. The current ordinary forward commit restores that file to protected-main content. No force-push, rebase, history rewrite, predecessor evidence transfer, or gate weakening was used.

Every check, review, benchmark, or comment bound to an earlier head is historical only.

Verification lineage

Earlier local evidence reported:

  • uv run pytest tests/test_opencode_agent_contract.py -q — 40 passed;
  • Bash syntax checks for the Strix/model-pool harness; and
  • clean diff validation.

Those results prove predecessor trees only. The current head must regenerate the complete exact-head quality, model-pool, security, SAST, dependency/SBOM, supply-chain, and semantic-review cycle. GNU timeout execution on the hosted Linux runner remains the authoritative behavioral gate.

Merge gate

Merge or auto-merge only after the unchanged current head has terminal-success required gates, zero valid unresolved findings, a qualifying current-head semantic verdict, the independent non-author approvals and last-push approval required by live protection, a compatible live base, and ordinary expected-head merge authority. Pending, queued, skipped, cancelled, stale, predecessor-head, self/author, status-only, synthetic, local-only, or model-only evidence is not acceptance. No administrative bypass or self-approval is requested.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@seonghobae, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 56 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 548ace06-0daa-4995-a507-ab19c6845ad2

📥 Commits

Reviewing files that changed from the base of the PR and between 6eb06cd and 44a302d.

📒 Files selected for processing (5)
  • .github/workflows/opencode-review-dispatch.yml
  • CHANGELOG.md
  • docs/doctoring/opencode-free-failover-budget.md
  • scripts/ci/test_strix_quick_gate.sh
  • tests/test_opencode_agent_contract.py

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@seonghobae
seonghobae enabled auto-merge (squash) August 12, 2026 03:07

Copy link
Copy Markdown
Contributor Author

@opencode-agent @cwl-noema-review review

Review only the exact current head 211d976e0bd5025ea14b454c029c1ac1c152fece against live main 6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba. This PR bounds the shared free-model failover pool and removes stale aliases. Check that the timeout/alias changes preserve fail-closed behavior, required workflow contracts, and the normal paid-model budget. Submit a current-head semantic verdict only; do not modify, merge, retarget, self-approve, or alter credentials. Keep automated review separate from the required independent protected-branch approval.

Copy link
Copy Markdown
Contributor Author

@opencode-agent review

Review only exact current head 211d976e0bd5025ea14b454c029c1ac1c152fece against live main 6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba. Verify stale free-alias removal, the 300-second free failover timeout, preserved 5400-second normal budget, and fail-closed approval behavior. Submit a semantic verdict only; do not modify, merge, retarget, self-approve, or alter credentials.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review
@opencode-agent review
@cwl-noema-review review

Review exact current head 211d976e0bd5025ea14b454c029c1ac1c152fece only. All nine exact-head security, supply-chain, and Strix quality workflows are terminal-success. Validate removal of stale aliases, the seven governed free candidates, 300-second free-tier failover versus unchanged 5400-second normal budget, credential/provider isolation, and fail-closed timeout semantics. Review only; do not mutate, merge, release, or alter protections.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

head_expected='211d976e0bd5025ea14b454c029c1ac1c152fece'
main_expected='6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba'

git fetch --quiet origin main
printf '%s\n' '== Commit identity =='
printf 'HEAD: '; git rev-parse HEAD
printf 'origin/main: '; git rev-parse origin/main
printf 'Expected HEAD: %s\nExpected main: %s\n' "$head_expected" "$main_expected"

printf '%s\n' '== Merge-base and changed files =='
git merge-base origin/main HEAD
git diff --name-status origin/main...HEAD
git diff --check origin/main...HEAD

printf '%s\n' '== Changed diff =='
git diff --no-ext-diff --unified=80 origin/main...HEAD

printf '%s\n' '== Candidate workflow/script/test files =='
fd -t f . | rg '(^|/)(opencode-review-dispatch\.yml|run_opencode_review_model_pool\.sh|test_opencode_agent_contract\.py)$' || true

printf '%s\n' '== All relevant alias, timeout, approval, credential, and provider references =='
rg -n -i -C 4 \
  'hy3-free|minimax-m3-free|glm-5-free|kimi-k2\.5-free|qwen3\.6-plus-free|ling-3\.0-flash-free|free.*(candidate|model|timeout)|timeout.*(free|300|5400)|5400|300|APPROVE|approve|verdict|credential|token|api.?key|provider' \
  .github scripts tests 2>/dev/null || true

Length of output: 181861


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Exact revisions =='
printf 'HEAD='; git rev-parse HEAD
printf 'MAIN='; git rev-parse origin/main
printf 'MERGE_BASE='; git merge-base origin/main HEAD

printf '%s\n' '== Changed files =='
git diff --name-only origin/main...HEAD

printf '%s\n' '== Focused patch =='
git diff --no-ext-diff --unified=30 origin/main...HEAD -- \
  .github/workflows/opencode-review-dispatch.yml \
  scripts/ci/run_opencode_review_model_pool.sh \
  tests/test_opencode_agent_contract.py

printf '%s\n' '== Current pool script: candidate, timeout, result, and verdict control flow =='
nl -ba scripts/ci/run_opencode_review_model_pool.sh | \
  grep -E -C 18 \
  'FREE|free|CANDIDATE|candidate|TIMEOUT|timeout|5400|300|exit|verdict|approve|APPROVE|credential|token|api.?key|provider' || true

printf '%s\n' '== Current workflow: OpenCode dispatch and secret bindings =='
nl -ba .github/workflows/opencode-review-dispatch.yml | \
  grep -E -C 14 \
  'run_opencode_review_model_pool|FREE|free|CANDIDATE|candidate|TIMEOUT|timeout|5400|300|secret|token|api.?key|provider|approve|APPROVE|verdict' || true

printf '%s\n' '== Current contract assertions =='
nl -ba tests/test_opencode_agent_contract.py | \
  grep -E -C 10 \
  'hy3-free|minimax-m3-free|glm-5-free|kimi-k2\.5-free|qwen3\.6-plus-free|ling-3\.0-flash-free|300|5400|free.*candidate|candidate.*free|timeout|fail.closed|approve|verdict' || true

Length of output: 31524


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Locate runtime and outcome gates =='
grep -nE \
  'OPENCODE_FREE_RUN_TIMEOUT_SECONDS|OPENCODE_RUN_TIMEOUT_SECONDS|run_opencode_review_model_pool|MODEL_CANDIDATES|candidate|timeout|TIMEOUT|MODEL_UNAVAILABLE|verdict|VERDICT|APPROVE|approve|approval|OPENCODE_API_KEY|OPENAI_API_KEY|NVIDIA_API_KEY|OPENROUTER_API_KEY' \
  scripts/ci/run_opencode_review_model_pool.sh \
  .github/workflows/opencode-review-dispatch.yml \
  scripts/ci/test_strix_quick_gate.sh | head -n 450

printf '%s\n' '== Pool script first 520 lines =='
sed -n '1,520p' scripts/ci/run_opencode_review_model_pool.sh

printf '%s\n' '== Workflow pool invocation and immediate outcome handling =='
pool_line=$(grep -n 'run_opencode_review_model_pool' .github/workflows/opencode-review-dispatch.yml | head -n1 | cut -d: -f1 || true)
if [ -n "$pool_line" ]; then
  start=$((pool_line - 80)); [ "$start" -lt 1 ] && start=1
  end=$((pool_line + 160))
  sed -n "${start},${end}p" .github/workflows/opencode-review-dispatch.yml
fi

printf '%s\n' '== Workflow approval and publication gate locations =='
grep -nE 'Publish OpenCode review outcome|Run merge scheduler after approval|APPROVE|approval|verdict|model.unavailable|MODEL_UNAVAILABLE' \
  .github/workflows/opencode-review-dispatch.yml | head -n 220

Length of output: 70226


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Pool: approval-gate command and provider helper functions =='
sed -n '30,55p' scripts/ci/run_opencode_review_model_pool.sh
sed -n '350,450p' scripts/ci/run_opencode_review_model_pool.sh

printf '%s\n' '== Pool: model-attempt failure and timeout return path =='
sed -n '450,545p' scripts/ci/run_opencode_review_model_pool.sh

printf '%s\n' '== Pool: candidate loop and exhaustion return path =='
sed -n '545,805p' scripts/ci/run_opencode_review_model_pool.sh

printf '%s\n' '== Workflow: generated anonymous free-provider configuration =='
sed -n '3570,3795p' .github/workflows/opencode-review-dispatch.yml

printf '%s\n' '== Workflow: outer pool invocation and failure capture =='
sed -n '4285,4320p' .github/workflows/opencode-review-dispatch.yml

printf '%s\n' '== Workflow: model-output-unavailable and existing-approval gate =='
sed -n '7000,7285p' .github/workflows/opencode-review-dispatch.yml

printf '%s\n' '== Workflow: final control-result dispatch =='
sed -n '7435,7525p' .github/workflows/opencode-review-dispatch.yml

Length of output: 56601


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Stale alias references in the current head =='
grep -RInE \
  'hy3-free|minimax-m3-free|glm-5-free|kimi-k2\.5-free|qwen3\.6-plus-free' \
  --exclude-dir=.git . || true

printf '%s\n' '== Exact current free-candidate count from the workflow candidate string =='
python3 - <<'PY'
from pathlib import Path
import re
text = Path(".github/workflows/opencode-review-dispatch.yml").read_text(encoding="utf-8")
match = re.search(r'OPENCODE_MODEL_CANDIDATES: "([^"]+)"', text)
assert match, "candidate string not found"
free = re.findall(r'\bopencode-free/[^ \']+', match.group(1))
print("count=", len(free))
for candidate in free:
    print(candidate)
PY

printf '%s\n' '== Remaining changed-file patch =='
git diff --no-ext-diff --unified=50 origin/main...HEAD -- scripts/ci/test_strix_quick_gate.sh

printf '%s\n' '== Whitespace errors =='
git diff --check origin/main...HEAD

Length of output: 18619


@seonghobae Review complete for exact head 211d976e0bd5025ea14b454c029c1ac1c152fece against live main 6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba.

No blocking findings.

  • All five stale aliases are absent from the current head.
  • The public free pool contains exactly seven governed candidates.
  • opencode-free/* candidates have a 300-second timeout cap.
  • The normal and dynamic paid-model timeout remains 5400 seconds.
  • A timeout only advances failover. It cannot produce a successful model result.
  • The pool accepts output only after normalization and opencode_review_approve_gate.sh succeed.
  • Provider exhaustion and unavailable output cannot publish a new approval. Only a previously validated real-model approval on the exact head can satisfy that fallback path.
  • The anonymous free provider has no API-key configuration. The runtime removes GitHub, app, and OIDC credentials before invoking OpenCode.
  • git diff --check passed.

I applied the existing current-head-only evidence guidance during this review. I did not run repository tests in the sandbox.


🧠 Learnings used
Learnt from: seonghobae
Repo: ContextualWisdomLab/.github PR: 0
File: :0-0
Timestamp: 2026-08-05T13:44:10.007Z
Learning: For PR `#782`, only successful checks associated with the exact current head are valid merge evidence. Do not treat queued, in-progress, cancelled, predecessor-head, temporary-workflow, or administrative-bypass results as passing evidence. Before a formal approval, verify that the direct security and supply-chain workflows, the permanent hourly NVIDIA NIM contract, current-head reviews, unresolved-thread checks, and an independent approval have completed successfully.

Learnt from: seonghobae
Repo: ContextualWisdomLab/.github PR: 649
File: tests/test_opencode_agent_contract.py:0-0
Timestamp: 2026-07-29T15:24:47.267Z
Learning: In `.github/workflows/opencode-review-dispatch.yml`, the anonymous `opencode-free/deepseek-v4-flash-free` reviewer must retain `tool_call: true` without a forced `options.response_format`. An isolated OpenCode invocation showed that forcing `response_format` serialized an intended Read tool call as text, while omitting it allowed the Read call to execute and returned exact JSON. The North fallback likewise uses `tool_call: true` with no forced `response_format`.
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor Author

@opencode-agent review
@cwl-noema-review review
@coderabbitai review

Review exact current head 211d976e0bd5025ea14b454c029c1ac1c152fece only. Validate that the five removed aliases are absent from both configuration and the ordered candidate pool, the seven retained free candidates still have governed model definitions, the 300-second free-tier timeout advances only to the next candidate without changing verdict or merge authority, paid/large-review budgets remain unchanged, and the Linux runner exercises the GNU timeout path that was unavailable locally. Treat predecessor evidence as stale. Review only: do not mutate the branch, approve from the author identity, merge, release, or alter protections/credentials.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

head_expected='211d976e0bd5025ea14b454c029c1ac1c152fece'
main_expected='6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba'
repo='ContextualWisdomLab/.github'
pr='942'

git fetch --quiet origin main
printf '%s\n' '== Revision identity =='
printf 'HEAD='; git rev-parse HEAD
printf 'origin/main='; git rev-parse origin/main
printf 'merge-base='; git merge-base origin/main HEAD
printf 'expected-head=%s\nexpected-main=%s\n' "$head_expected" "$main_expected"

printf '%s\n' '== Changed files and whitespace =='
git diff --name-status origin/main...HEAD
git diff --check origin/main...HEAD

printf '%s\n' '== Focused patch =='
git diff --no-ext-diff --unified=45 origin/main...HEAD -- \
  .github/workflows/opencode-review-dispatch.yml \
  scripts/ci/run_opencode_review_model_pool.sh \
  scripts/ci/test_strix_quick_gate.sh \
  tests/test_opencode_agent_contract.py

printf '%s\n' '== Target file structure =='
ast-grep outline scripts/ci/run_opencode_review_model_pool.sh --items all || true
ast-grep outline tests/test_opencode_agent_contract.py --items all || true

printf '%s\n' '== Alias and candidate definitions =='
rg -n -C 5 \
  'hy3-free|minimax-m3-free|glm-5-free|kimi-k2\.5-free|qwen3\.6-plus-free|OPENCODE_MODEL_CANDIDATES|opencode-free/' \
  .github/workflows/opencode-review-dispatch.yml scripts/ci/run_opencode_review_model_pool.sh tests/test_opencode_agent_contract.py

printf '%s\n' '== Timeout, failover, verdict, and approval control flow =='
rg -n -C 8 \
  'OPENCODE_FREE_RUN_TIMEOUT_SECONDS|OPENCODE_RUN_TIMEOUT_SECONDS|timeout |timeout\(|TIMEOUT|300|5400|candidate|MODEL_UNAVAILABLE|approve|APPROVE|verdict|exit [0-9]+' \
  scripts/ci/run_opencode_review_model_pool.sh \
  .github/workflows/opencode-review-dispatch.yml \
  tests/test_opencode_agent_contract.py \
  scripts/ci/test_strix_quick_gate.sh

printf '%s\n' '== Current-head workflow runs =='
gh api "repos/${repo}/actions/runs?head_sha=${head_expected}&per_page=100" \
  --jq '.workflow_runs[] | [.id,.name,.status,.conclusion,.event,.head_sha,.run_started_at,.updated_at,.html_url] | `@tsv`'

printf '%s\n' '== Current-head check runs =='
gh api "repos/${repo}/commits/${head_expected}/check-runs?per_page=100" \
  --jq '.check_runs[] | [.name,.status,.conclusion,.started_at,.completed_at,.details_url] | `@tsv`'

printf '%s\n' '== Current-head Linux timeout evidence in OpenCode-related run logs =='
run_ids=$(gh api "repos/${repo}/actions/runs?head_sha=${head_expected}&per_page=100" \
  --jq '.workflow_runs[] | select(.name | test("OpenCode|Strix"; "i")) | .id')
for run_id in $run_ids; do
  echo "-- run ${run_id} --"
  gh api "repos/${repo}/actions/runs/${run_id}/jobs?per_page=100" \
    --jq '.jobs[] | [.id,.name,.status,.conclusion,.runner_name,.labels[]?] | `@tsv`'
  gh run view "$run_id" --repo "$repo" --log 2>/dev/null | \
    rg -n -i -C 3 'GNU timeout|timeout --version|coreutils|OPENCODE_FREE_RUN_TIMEOUT_SECONDS|timeout 300|timeout.*300|run_opencode_review_model_pool' || true
done

Length of output: 197563


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/.github'
head='211d976e0bd5025ea14b454c029c1ac1c152fece'
log='/tmp/coderabbit-shell-logs/shell-output-RYMahs'
job='93996585280'
run='31558764608'

printf '%s\n' '== First inspection: revision, changed files, and diff result =='
rg -n -A20 -B2 '^== Revision identity ==|^== Changed files and whitespace ==|^== Focused patch ==' "$log" | head -n 220

printf '%s\n' '== Current candidate string and governed free definitions =='
sed -n '3550,3810p' .github/workflows/opencode-review-dispatch.yml
python3 - <<'PY'
from pathlib import Path
import re
p = Path(".github/workflows/opencode-review-dispatch.yml")
s = p.read_text()
m = re.search(r'OPENCODE_MODEL_CANDIDATES: "([^"]+)"', s)
if not m:
    raise SystemExit("candidate string not found")
candidates = re.findall(r'opencode-free/[^\s"]+', m.group(1))
print("candidate-count:", len(candidates))
for x in candidates:
    alias = x.removeprefix("opencode-free/")
    defined = bool(re.search(rf'(?m)^\s*{re.escape(alias)}:\s*$', s))
    print(f"{x}\tgoverned-definition={defined}")
for stale in ("hy3-free","minimax-m3-free","glm-5-free","kimi-k2.5-free","qwen3.6-plus-free"):
    print(f"{stale}\tpresent={stale in s}")
PY

printf '%s\n' '== Pool timeout selection, command execution, and result loop =='
rg -n -C 18 \
  'OPENCODE_FREE_RUN_TIMEOUT_SECONDS|OPENCODE_RUN_TIMEOUT_SECONDS|timeout --|timeout |run_timeout|candidate.*timeout|timeout.*candidate|MODEL_UNAVAILABLE|opencode_review_approve_gate|for candidate|while .*candidate|return [0-9]+' \
  scripts/ci/run_opencode_review_model_pool.sh

printf '%s\n' '== Workflow invocation, runtime platform, and approval/publication gates =='
rg -n -C 14 \
  'runs-on:|run_opencode_review_model_pool|OPENCODE_FREE_RUN_TIMEOUT_SECONDS|OPENCODE_RUN_TIMEOUT_SECONDS|MODEL_UNAVAILABLE|existing.*approval|approve|APPROVE|verdict|merge' \
  .github/workflows/opencode-review-dispatch.yml

printf '%s\n' '== Contract assertions for aliases, free count, timeout, and fail-closed behavior =='
rg -n -C 12 \
  'hy3-free|minimax-m3-free|glm-5-free|kimi-k2\.5-free|qwen3\.6-plus-free|seven|7|300|5400|timeout|MODEL_UNAVAILABLE|approve|verdict' \
  tests/test_opencode_agent_contract.py

printf '%s\n' '== Exact current-head OpenCode job metadata and steps =='
gh api "repos/${repo}/actions/jobs/${job}" \
  --jq '{id,name,status,conclusion,started_at,completed_at,runner_name,labels,steps:[.steps[]|{number,name,status,conclusion,started_at,completed_at}]}'

printf '%s\n' '== Exact current-head OpenCode job log: invocation, timeout, and skip evidence =='
gh run view "$run" --repo "$repo" --log --job "$job" 2>&1 | \
  rg -n -i -C 8 \
  'run_opencode_review_model_pool|OPENCODE_FREE_RUN_TIMEOUT_SECONDS|OPENCODE_RUN_TIMEOUT_SECONDS|timeout|GNU|coreutils|candidate|skipp|condition|MODEL_UNAVAILABLE|opencode-review' || true

printf '%s\n' '== Exact current-head workflow YAML timeout precondition =='
rg -n -C 8 'timeout --version|command -v timeout|GNU timeout|coreutils|ubuntu-latest|ubuntu-24.04' \
  .github/workflows/opencode-review-dispatch.yml scripts/ci/run_opencode_review_model_pool.sh tests/test_opencode_agent_contract.py

Length of output: 155705


@seonghobae Review result: inconclusive for the requested Linux runtime validation.

Static review found no blocking defect:

  • The five stale aliases are absent from the retained candidate contract.
  • The ordered free pool contains seven candidates.
  • Each retained free candidate has a governed model definition.
  • OPENCODE_FREE_RUN_TIMEOUT_SECONDS is 300.
  • The normal and dynamic paid-model timeout remains 5400.
  • The pool treats timeout as candidate failover. It does not create an approval.
  • MODEL_OUTPUT_UNAVAILABLE does not publish a new approval. The only success fallback requires an existing validated OpenCode App approval for this exact head.

The exact-head OpenCode check ran on Ubuntu 24.04.4. However, it was a stub job. Its only executable step was:

echo "Review approval remains a separate current-head PR review requirement produced by the authenticated dispatch workflow."

It did not execute scripts/ci/run_opencode_review_model_pool.sh. Therefore, the current-head evidence does not prove that the Linux runner exercised the GNU timeout path with the new 300-second free-tier limit.

The static contract checks cover the configured timeout values and control flow. They do not replace execution evidence for GNU timeout. A completed exact-head repository_dispatch run that executes the model-pool step is required for that validation.

I used the existing current-head-only evidence guidance. I did not modify, approve, merge, release, or change credentials or protections.


🧠 Learnings used
Learnt from: seonghobae
Repo: ContextualWisdomLab/.github PR: 0
File: :0-0
Timestamp: 2026-08-05T13:44:10.007Z
Learning: For PR `#782`, only successful checks associated with the exact current head are valid merge evidence. Do not treat queued, in-progress, cancelled, predecessor-head, temporary-workflow, or administrative-bypass results as passing evidence. Before a formal approval, verify that the direct security and supply-chain workflows, the permanent hourly NVIDIA NIM contract, current-head reviews, unresolved-thread checks, and an independent approval have completed successfully.

You are interacting with an AI system.

Copy link
Copy Markdown
Contributor Author

Exact-current-head review request for 211d976e0bd5025ea14b454c029c1ac1c152fece over protected main@6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba.

Review the bounded three-file pool repair: remove five stale free-provider aliases, retain the seven governed free candidates, cap free-candidate failover at 300 seconds, and preserve the 5,400-second paid/large-review budget and fail-closed verdict semantics. Strix Changed Path Quality CI, CodeQL PR, Python Security, Security Scan, SAST Semgrep, Secret Scan, OSV-Scanner PR, Scorecard PR, and SBOM Generation are terminal-success on this exact head; no review thread exists.

Keep the head unchanged. Do not update the branch, synthesize author approval, merge, release, treat a timeout as approval, or weaken provider/security gates.

@coderabbitai review
@opencode-agent review
@cwl-noema-review review
@strix review

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Rate Limit Exceeded

@seonghobae have exceeded the limit for the number of chat messages per hour. Please wait 20 minutes and 58 seconds before sending another message.

@seonghobae seonghobae left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exact-current-head source review for 211d976e0bd5025ea14b454c029c1ac1c152fece against protected main@6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba.

The three-file diff removes five ungoverned free aliases from both provider configuration and candidate order, while retaining the seven configured free candidates and every paid/NVIDIA/GitHub Models fallback. The launcher already applies provider-specific caps through cap_model_run_timeout; this head changes only the opencode-free/* environment cap from 3600s to 300s. Normal paid/large-review OPENCODE_RUN_TIMEOUT_SECONDS=5400, NVIDIA's 180s per-candidate/900s combined budget, GitHub GPT-5's 45s cap, attempt ceiling, control-schema validation, and fail-closed exhausted-pool result remain unchanged. Timeout advances to another configured provider but cannot create an approval.

The exact-head Strix quality run checked out this literal SHA, ran 977 tests plus 16 subtests and the bounded shell regression suite successfully; all nine directly observed hosted workflows are terminal-success and no inline thread exists. The remaining uncertainty is operational rather than a source blocker: the next live review runs should confirm provider throughput and may justify a later data-driven cap adjustment without restoring hour-long free-candidate stalls.

A qualifying independent reviewer must still submit formal approval on this unchanged head. Do not update the branch, restore stale aliases without live catalog evidence, synthesize author approval, or bypass protection.

Document the 300s free-candidate cap so hung aliases cannot consume the
paid/NIM review budget. Cite NIST SP 800-53 Rev. 5. Isolate Darwin
installer tests on the linux x86_64 path.
@seonghobae

Copy link
Copy Markdown
Contributor Author

Reviewed current head. No unresolved review threads. Added CHANGELOG + APA 7th doctoring for the 300s free-tier failover cap. Local suite 977 passed x2, coverage 100%. Auto-merge armed; not waiting.

@seonghobae
seonghobae enabled auto-merge (squash) August 13, 2026 03:04
Materialize a base Python lock only when every package line is an exact
SHA-256 pin or a two-token relative -r/--requirement include of a
candidate lock path. A lone --require-hashes directive, ./dotted paths,
and -r other-hashes.txt no longer enter the trusted build context.

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 fb24aecffa887975d4b34a8c914337c2d95fc378.
  • 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:

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Workflow: opencode-review-dispatch.yml"]
  S1 --> I1["GitHub Actions review job"]
  I1 --> R1["Review risk: Workflow: opencode-review-dispatch.yml"]
  R1 --> V1["actionlint plus required checks"]
  Evidence --> S2["Changed file (2 files)"]
  S2 --> I2["repository behavior"]
  I2 --> R2["Review risk: Changed file (2 files)"]
  R2 --> V2["required checks"]
  Evidence --> S3["Docs: opencode-free-failover-budget.md"]
  S3 --> I3["operator or user guidance"]
  I3 --> R3["Review risk: Docs: opencode-free-failover-budget.md"]
  R3 --> V3["docs review"]
  Evidence --> S4["CI script (2 files)"]
  S4 --> I4["review and security gate shell path"]
  I4 --> R4["Review risk: CI script (2 files)"]
  R4 --> V4["bash -n plus Strix self-test"]
  Evidence --> S5["Test (2 files)"]
  S5 --> I5["regression suite"]
  I5 --> R5["Review risk: Test (2 files)"]
  R5 --> V5["targeted test run"]
Loading

@opencode-agent

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

  • Head SHA: fb24aecffa887975d4b34a8c914337c2d95fc378
  • Workflow run: 31754402552
  • Workflow attempt: 1
  • Gate result: REQUEST_CHANGES (approval step)

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 fb24aecffa887975d4b34a8c914337c2d95fc378.
  • 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:

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Workflow: opencode-review-dispatch.yml"]
  S1 --> I1["GitHub Actions review job"]
  I1 --> R1["Review risk: Workflow: opencode-review-dispatch.yml"]
  R1 --> V1["actionlint plus required checks"]
  Evidence --> S2["Changed file (2 files)"]
  S2 --> I2["repository behavior"]
  I2 --> R2["Review risk: Changed file (2 files)"]
  R2 --> V2["required checks"]
  Evidence --> S3["Docs: opencode-free-failover-budget.md"]
  S3 --> I3["operator or user guidance"]
  I3 --> R3["Review risk: Docs: opencode-free-failover-budget.md"]
  R3 --> V3["docs review"]
  Evidence --> S4["CI script (2 files)"]
  S4 --> I4["review and security gate shell path"]
  I4 --> R4["Review risk: CI script (2 files)"]
  R4 --> V4["bash -n plus Strix self-test"]
  Evidence --> S5["Test (2 files)"]
  S5 --> I5["regression suite"]
  I5 --> R5["Review risk: Test (2 files)"]
  R5 --> V5["targeted test run"]
Loading

@opencode-agent
opencode-agent Bot disabled auto-merge August 14, 2026 01:54
@seonghobae
seonghobae marked this pull request as draft August 14, 2026 09:05

Copy link
Copy Markdown
Contributor Author

Returned to Draft because the exact current tree mixes the bounded free-model failover repair with an unrelated trusted-uv materializer branch.

The useful slice is clear: remove demonstrably stale aliases, keep the governed catalog, apply a 300-second free-candidate budget while preserving the normal 5,400-second budget, and fail closed when the pool exhausts. Head fb24aecffa887975d4b34a8c914337c2d95fc378 additionally changes materialize_base_python_requirements.py and its tests.

Rebuild from protected main retaining only the OpenCode dispatch/pool surfaces, focused executable workflow tests, doctoring, directly attributable AGENTS/changelog evidence, and no materializer changes. Validate the catalog against current provider evidence immediately before Ready, then reacquire exact-head workflow/security/supply-chain and independent-review evidence.

@seonghobae
seonghobae marked this pull request as ready for review August 14, 2026 13:58

Copy link
Copy Markdown
Contributor Author

@coderabbitai review
@opencode-agent review
@cwl-noema-review review
@strix review

Review only exact current head 56e1e7a6804037c9752728b712e4bb1f54f94430 against live protected main@6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba. I removed the unrelated trusted-uv production delta by restoring the exact bounded-free-failover tree as a new descendant. The current diff removes only stale free aliases, retains the governed seven-candidate free pool, caps each free candidate at 300s while preserving the normal paid/large-review budget, and remains fail-closed because timeout can only advance to another provider and cannot synthesize approval. No review thread exists. Exact-head checks are regenerating; nonterminal evidence is not acceptance. Review read-only; do not mutate source, restore stale aliases without catalog evidence, synthesize approval, weaken provider-budget controls, or merge.

@seonghobae
seonghobae enabled auto-merge (squash) August 14, 2026 13:58
@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/.github'
head_expected='56e1e7a6804037c9752728b712e4bb1f54f94430'
main_expected='6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba'

git fetch --quiet origin main
printf '%s\n' '== Revision identity =='
printf 'HEAD='; git rev-parse HEAD
printf 'origin/main='; git rev-parse origin/main
printf 'merge-base='; git merge-base origin/main HEAD
printf 'expected-head=%s\nexpected-main=%s\n' "$head_expected" "$main_expected"

printf '%s\n' '== Changed files and whitespace =='
git diff --name-status "origin/main...${head_expected}"
git diff --check "origin/main...${head_expected}"

printf '%s\n' '== Exact patch =='
git diff --no-ext-diff --unified=50 "origin/main...${head_expected}" -- \
  .github/workflows/opencode-review-dispatch.yml \
  scripts/ci/run_opencode_review_model_pool.sh \
  scripts/ci/test_strix_quick_gate.sh \
  tests/test_opencode_agent_contract.py \
  CHANGELOG.md AGENTS.md

printf '%s\n' '== Candidate definitions and stale aliases =='
python3 - <<'PY'
from pathlib import Path
import re
path = Path(".github/workflows/opencode-review-dispatch.yml")
text = path.read_text(encoding="utf-8")
match = re.search(r'OPENCODE_MODEL_CANDIDATES: "([^"]+)"', text)
if not match:
    raise SystemExit("OPENCODE_MODEL_CANDIDATES not found")
candidates = re.findall(r'opencode-free/[^\s"]+', match.group(1))
print(f"free-candidate-count={len(candidates)}")
for candidate in candidates:
    alias = candidate.split("/", 1)[1]
    defined = bool(re.search(rf'(?m)^\s*{re.escape(alias)}:\s*$', text))
    print(f"{candidate}\tgoverned-definition={defined}")
for alias in ("hy3-free", "minimax-m3-free", "glm-5-free", "kimi-k2.5-free", "qwen3.6-plus-free"):
    print(f"{alias}\tpresent-in-workflow={alias in text}")
PY

printf '%s\n' '== Pool timeout, candidate, approval, and exhaustion control flow =='
rg -n -C 14 \
  'OPENCODE_FREE_RUN_TIMEOUT_SECONDS|OPENCODE_RUN_TIMEOUT_SECONDS|timeout |timeout\(|FREE|opencode-free/|MODEL_OUTPUT_UNAVAILABLE|MODEL_UNAVAILABLE|opencode_review_approve_gate|APPROVE|approve|verdict|return [0-9]+|exit [0-9]+' \
  scripts/ci/run_opencode_review_model_pool.sh \
  .github/workflows/opencode-review-dispatch.yml \
  tests/test_opencode_agent_contract.py \
  scripts/ci/test_strix_quick_gate.sh

printf '%s\n' '== Exact-head check and workflow status =='
gh api "repos/${repo}/commits/${head_expected}/check-runs?per_page=100" \
  --jq '.check_runs[] | [.name,.status,.conclusion,.started_at,.completed_at,.details_url] | `@tsv`'
gh api "repos/${repo}/actions/runs?head_sha=${head_expected}&per_page=100" \
  --jq '.workflow_runs[] | [.name,.status,.conclusion,.event,.run_started_at,.updated_at,.html_url] | `@tsv`'

Length of output: 203137


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/.github'
head='56e1e7a6804037c9752728b712e4bb1f54f94430'
main='6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba'
log='/tmp/coderabbit-shell-logs/shell-output-ssriHn'

printf '%s\n' '== First-script compact evidence =='
rg -n -A30 -B2 \
  '^== Revision identity ==|^== Changed files and whitespace ==|^== Exact patch ==|^== Candidate definitions and stale aliases ==|^free-candidate-count=|^== Exact-head check and workflow status ==' \
  "$log" | head -n 260

printf '%s\n' '== Exact revision and changed paths =='
printf 'HEAD='; git rev-parse HEAD
printf 'origin/main='; git rev-parse origin/main
printf 'merge-base='; git merge-base "origin/main" HEAD
git diff --name-status "origin/main...${head}"
git diff --check "origin/main...${head}"

printf '%s\n' '== Pool structure and focused source ranges =='
ast-grep outline scripts/ci/run_opencode_review_model_pool.sh --items all || true
rg -n \
  'OPENCODE_FREE_RUN_TIMEOUT_SECONDS|OPENCODE_RUN_TIMEOUT_SECONDS|opencode-free/|run_timeout|timeout --kill-after|for candidate|MODEL_OUTPUT_UNAVAILABLE|opencode_review_approve_gate' \
  scripts/ci/run_opencode_review_model_pool.sh

for range in 360,520 520,720 720,850; do
  start=${range%,*}; end=${range#*,}
  printf '\n== scripts/ci/run_opencode_review_model_pool.sh:%s-%s ==\n' "$start" "$end"
  sed -n "${start},${end}p" scripts/ci/run_opencode_review_model_pool.sh
done

printf '%s\n' '== Workflow candidate configuration and invocation =='
rg -n -C 8 \
  'OPENCODE_MODEL_CANDIDATES:|OPENCODE_FREE_RUN_TIMEOUT_SECONDS:|OPENCODE_RUN_TIMEOUT_SECONDS:|run_opencode_review_model_pool\.sh' \
  .github/workflows/opencode-review-dispatch.yml

printf '%s\n' '== Current PR review-thread state =='
gh api graphql \
  -F owner='ContextualWisdomLab' \
  -F name='.github' \
  -F number=942 \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes { isResolved isOutdated comments(first: 1) { nodes { path line } } }
      }
    }
  }
}' \
  --jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select((.isResolved | not) and (.isOutdated | not))] | length'

Length of output: 46685


🏁 Script executed:

#!/bin/bash
set -euo pipefail

head='56e1e7a6804037c9752728b712e4bb1f54f94430'

printf '%s\n' '== Unrelated materializer test patch with line numbers =='
git diff --no-ext-diff --unified=30 "origin/main...${head}" -- \
  tests/test_materialize_base_python_requirements.py
nl -ba tests/test_materialize_base_python_requirements.py | sed -n '1,260p'

printf '%s\n' '== Seven candidate definitions in generated OpenCode configuration =='
python3 - <<'PY'
from pathlib import Path
import json
import re

text = Path(".github/workflows/opencode-review-dispatch.yml").read_text(encoding="utf-8")
candidates_match = re.search(r'OPENCODE_MODEL_CANDIDATES: "([^"]+)"', text)
if not candidates_match:
    raise SystemExit("candidate string not found")
candidates = re.findall(r'opencode-free/[^\s"]+', candidates_match.group(1))

for candidate in candidates:
    alias = candidate.split("/", 1)[1]
    pattern = rf'"{re.escape(alias)}"\s*:\s*\{{'
    print(f"{candidate}\tdefined={bool(re.search(pattern, text))}")

for alias in ("hy3-free", "minimax-m3-free", "glm-5-free", "kimi-k2.5-free", "qwen3.6-plus-free"):
    print(f"{alias}\tpresent-anywhere={alias in text}")
PY

printf '%s\n' '== Contract test patch =='
git diff --no-ext-diff --unified=25 "origin/main...${head}" -- \
  tests/test_opencode_agent_contract.py \
  scripts/ci/test_strix_quick_gate.sh \
  CHANGELOG.md \
  docs/doctoring/opencode-free-failover-budget.md

Length of output: 9641


@seonghobae Review result: request changes.

HIGH — Remove the unrelated trusted-uv test delta

tests/test_materialize_base_python_requirements.py is still changed in this head.

The change adds _force_linux_x86_64_installer() and calls it from three trusted-uv installer tests. This is unrelated to the bounded free-model failover repair. It conflicts with the stated requirement to rebuild from main without materializer changes.

Restore tests/test_materialize_base_python_requirements.py to its main version. Keep only the OpenCode pool, workflow contract, focused workflow-test, doctoring, and directly attributable changelog changes.

Static review otherwise confirms the five stale aliases are absent, the pool lists seven free candidates, the free-candidate cap is 300 seconds, and the normal budget remains 5400 seconds. The pool records success only after control-output validation. Pool exhaustion remains non-approval behavior.

Exact-head checks are queued, in progress, or cancelled. They are not acceptance evidence. I could not complete the final structured model-definition parse because the sandbox lacks nl, but this does not affect the scope finding.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor Author

Exact-current-head read-only review request for 44a302d283e2032f8b220d8f70a0acaae557bfa1 over protected base 6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba.

The bounded five-file repair removes five stale free-provider aliases, retains the seven governed candidates, applies a 300-second free-tier candidate budget without changing the 5,400-second paid/large-review budget, keeps timeout as failover-only rather than success, and removes unrelated installer-test drift. Recheck provider-scoped credentials, current-head evidence, model-output validation, #830 compatibility, and unchanged review/merge authority.

Submit a verdict for this unchanged head only. Treat predecessor checks/reviews as historical. Do not mutate or merge the branch, synthesize author approval, or weaken protection.

@opencode-agent review
@cwl-noema-review review
@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown

Rate Limit Exceeded

@seonghobae have exceeded the limit for the number of chat messages per hour. Please wait 16 minutes and 59 seconds before sending another message.

@opencode-agent
opencode-agent Bot disabled auto-merge August 16, 2026 10:21
@seonghobae
seonghobae enabled auto-merge (squash) August 16, 2026 10:56
@opencode-agent
opencode-agent Bot disabled auto-merge August 16, 2026 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant