Skip to content

fix(review): reach paid Zen before hour-class free models - #698

Closed
seonghobae wants to merge 1 commit into
mainfrom
codex/prioritize-zen-before-free
Closed

fix(review): reach paid Zen before hour-class free models#698
seonghobae wants to merge 1 commit into
mainfrom
codex/prioritize-zen-before-free

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Production defect

The current public model order exhausts NVIDIA NIM candidates and then enters the hour-class opencode-free pool before it can reach paid Zen (opencode/gpt-5.6-terra).

Live evidence on exact heads:

The workflow allows up to 3,600 seconds for the free pool and has a bounded overall review budget, so placing paid Zen after that pool can make the explicitly configured paid fallback unreachable in practice.

Fix

  • keep the seven bounded public NVIDIA NIM candidates first;
  • move opencode/gpt-5.6-terra immediately after them and before all opencode-free candidates;
  • keep Terra first for private repositories;
  • preserve all remaining keyed fallbacks and their order;
  • lock both public and private ordering into contract and Strix static assertions.

Operational prerequisite

The paid Zen provider reads secrets.OPENCODE_ZEN_API_KEY. Current secret metadata and run 30687537798 show that this credential is not configured, so Terra presently fails with a provider error. This PR fixes ordering/reachability; it does not claim the paid provider is operational until an authorized operator provisions that secret.

Current-head validation

Head: 440b7b06feb8c12cfe6467d9dcb29fe55e83d064

  • python3 -m pytest -q tests/test_opencode_agent_contract.py — 40 passed
  • actionlint -shellcheck= — passed
  • bash -n scripts/ci/test_strix_quick_gate.sh — passed
  • git diff --check — passed
  • model-order parser PoC — public Terra index 7, first free index 8; private first model Terra
  • STRIX_TEST_PROCESS_TIMEOUT_SECONDS=2 STRIX_TEST_FAKE_SLEEP_SECONDS=3 bash scripts/ci/test_strix_quick_gate.sh — passed (test_strix_quick_gate: PASS)

This is intentionally limited to candidate ordering and the assertions that govern it.

@coderabbitai

coderabbitai Bot commented Aug 1, 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: 32 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

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: 2db693ec-272a-40de-bfdf-cd69c3da874a

📥 Commits

Reviewing files that changed from the base of the PR and between 2a83043 and 440b7b0.

📒 Files selected for processing (3)
  • .github/workflows/opencode-review-dispatch.yml
  • scripts/ci/test_strix_quick_gate.sh
  • tests/test_opencode_agent_contract.py

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

@seonghobae

Copy link
Copy Markdown
Contributor Author

Exact production model-pool evidence gathered after this PR was opened:

  • seedream_evasepic Fix R coverage package library path #166, exact head b35d243ff2a48103e5e2894120cc4238a7ea004a, run 30687537798:
    • model pool started at 06:22:25Z;
    • first free candidate started at 06:36:09Z;
    • seven opencode-free candidates ran before Terra;
    • opencode/gpt-5.6-terra did not start until 07:27:20Z, about 65 minutes after the pool began;
    • the run then exhausted 30 provider attempts and failed closed with MODEL_OUTPUT_UNAVAILABLE.
  • central fix(coverage-evidence): materialize uv.lock-only repos so their offline coverage can run #668, then-exact head eb856311322be4cbaadb92a1a1fbdf0a72d0e252, run 30688178673:
    • model pool started at 06:43:02Z;
    • first free candidate started at 06:55:43Z;
    • Terra did not start until 07:21:58Z, about 39 minutes after the pool began;
    • the pool exhausted 30 attempts without a valid control conclusion.

Both logs explicitly show the configured 3,600-second runtime cap on each free candidate. This current head 440b7b06feb8c12cfe6467d9dcb29fe55e83d064 moves Terra ahead of those seven candidates while leaving the NIM and remaining keyed fallback order intact.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Additional bounded outcome audit: both cited production runs did eventually reach opencode/gpt-5.6-terra, but only after the free pool. seedream_evasepic#166 run 30687537798 reached Terra about 65 minutes after model-pool start; .github#668 run 30688178673 reached it after about 39 minutes. In both runs Terra then failed in approximately 5 seconds with sanitized class=provider-error metadata (json-bytes=218, no stderr), after which the remaining provider pool also exhausted. This exact-head change therefore fixes fallback reachability/latency, but it does not by itself prove Terra account/model readiness or restore formal approvals. Provider readiness remains a separate governance/capability defect and must not be represented as a clean review outcome.

@seonghobae
seonghobae enabled auto-merge (squash) August 1, 2026 07:48
@seonghobae

Copy link
Copy Markdown
Contributor Author

Operational credential check (names/metadata only; no secret values read):

  • run 30687537798 recorded OPENCODE_API_KEY: as empty in the exact model-pool step;
  • opencode/gpt-5.6-terra then failed after about five seconds with provider-error metadata;
  • neither the ContextualWisdomLab organization nor ContextualWisdomLab/.github currently lists OPENCODE_ZEN_API_KEY (or any secret name matching OPENCODE|ZEN);
  • the workflow maps only secrets.OPENCODE_ZEN_API_KEY into OPENCODE_API_KEY.

Therefore this PR fixes reachability/order, but paid Terra cannot produce a review until an authorized operator provisions OPENCODE_ZEN_API_KEY. I will not represent the paid model as operational without that external credential. The ordering change remains valid and makes Terra reachable immediately after the bounded NIM window once the secret is configured.

@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 440b7b06feb8c12cfe6467d9dcb29fe55e83d064.
  • 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["CI script: test_strix_quick_gate.sh"]
  S2 --> I2["review and security gate shell path"]
  I2 --> R2["Review risk: CI script: test_strix_quick_gate.sh"]
  R2 --> V2["bash -n plus Strix self-test"]
  Evidence --> S3["Test: test_opencode_agent_contract.py"]
  S3 --> I3["regression suite"]
  I3 --> R3["Review risk: Test: test_opencode_agent_contract.py"]
  R3 --> V3["targeted test run"]
Loading

@opencode-agent

opencode-agent Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

  • Head SHA: 440b7b06feb8c12cfe6467d9dcb29fe55e83d064
  • Workflow run: 30691621498
  • Workflow attempt: 2
  • 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 440b7b06feb8c12cfe6467d9dcb29fe55e83d064.
  • 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["CI script: test_strix_quick_gate.sh"]
  S2 --> I2["review and security gate shell path"]
  I2 --> R2["Review risk: CI script: test_strix_quick_gate.sh"]
  R2 --> V2["bash -n plus Strix self-test"]
  Evidence --> S3["Test: test_opencode_agent_contract.py"]
  S3 --> I3["regression suite"]
  I3 --> R3["Review risk: Test: test_opencode_agent_contract.py"]
  R3 --> V3["targeted test run"]
Loading

@opencode-agent
opencode-agent Bot disabled auto-merge August 1, 2026 09:55

Copy link
Copy Markdown
Contributor Author

@coderabbitai Please implement these fixes directly on the current PR branch and push a commit (do not open a stacked PR). Verify each item against the current head and keep the changes limited to the actionable Strix findings from job https://github.com/ContextualWisdomLab/.github/actions/runs/30689704416/job/91342129078:

  1. Harden the opencode-coverage-source.tar trust boundary in .github/workflows/opencode-review-dispatch.yml. Before creating/uploading the archive, reject non-regular source entries and enforce bounded member count, per-file size, aggregate uncompressed size, and final archive size. Before extraction, enforce the same archive/member/per-file/aggregate limits in addition to the existing traversal, duplicate-path, symlink/hardlink/device/FIFO, and destination containment checks. Use explicit conservative constants (100 MiB per file, 500 MiB aggregate uncompressed content, 1 GiB archive, and a bounded member count), fail closed with actionable errors, and retain filter="data".
  2. Make review-write identity internally consistent and App-only. review_head_guard_token must use the same OpenCode App review-write token as review/comment mutations, not the broader GH_TOKEN fallback. Align CONFIGURED_REVIEW_WRITE_TOKEN_SOURCE and the associated diagnostics so optional read/check/status credentials are never described as the review-writing principal. Preserve the existing fail-closed behavior when the App token is unavailable.
  3. Add or update focused regression/contract tests for both boundaries, including oversized archive, oversized member/aggregate/member-count rejection and the App-only head-guard/source contract. Preserve the existing model-order change in this PR.
  4. Run focused tests, the full Python suite with 100% scripts/ci coverage, docstring coverage, Ruff, actionlint, shell syntax/static Strix contract checks, and git diff --check. Address only failures caused by this change.

After committing, request a fresh full review on the resulting current head.

Copy link
Copy Markdown
Contributor Author

@jules Please apply the current-head Strix fixes directly to this PR branch and push a commit here. Keep the existing model-order change intact.

Required changes:

  1. Harden opencode-coverage-source.tar before creation/upload and before extraction: reject non-regular source entries and enforce a bounded member count, 100 MiB maximum per regular file, 500 MiB maximum aggregate uncompressed regular-file content, and 1 GiB maximum archive size. Keep the existing traversal, duplicate-path, special-member, containment, and filter="data" protections. Fail closed with actionable messages.
  2. Make review-write identity App-only: use the OpenCode App review-write token for review_head_guard_token, review/comment mutation, and the configured review-write principal diagnostics. Do not describe read/check/status token fallbacks as the review writer. Preserve fail-closed behavior when the App token is unavailable.
  3. Add focused contract/regression tests for archive/member/per-file/aggregate limits and the App-only head-guard/token-source invariant.
  4. Run focused and full tests, 100% scripts/ci coverage, interrogate, Ruff, actionlint, shell syntax/static Strix tests, and git diff --check. Resolve only change-related failures, then request fresh full reviews.

@coderabbitai

coderabbitai Bot commented Aug 3, 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

printf '%s\n' '== Current head =='
git rev-parse HEAD
git status --short

printf '%s\n' '== Candidate workflow and test files =='
fd -a -t f 'opencode-review-dispatch\.yml|test_.*opencode.*|.*strix.*|pyproject\.toml|ruff\.toml|actionlint' . \
  -E .git -E node_modules -E dist -E build | sort

printf '%s\n' '== Workflow outline and relevant matches =='
ast-grep outline .github/workflows/opencode-review-dispatch.yml --items all 2>/dev/null || true
rg -n -C 8 \
  'opencode-coverage-source\.tar|tarfile|filter="data"|review_head_guard_token|CONFIGURED_REVIEW_WRITE_TOKEN_SOURCE|OPENCODE_ZEN_API_KEY|opencode/gpt-5\.6-terra|opencode-free' \
  .github/workflows/opencode-review-dispatch.yml

printf '%s\n' '== Relevant test and CI references =='
rg -n -C 5 \
  'opencode-coverage-source|tarfile|review_head_guard_token|CONFIGURED_REVIEW_WRITE_TOKEN_SOURCE|gpt-5\.6-terra|opencode-free|test_strix_quick_gate|scripts/ci' \
  -g '*.py' -g '*.sh' -g '*.yml' -g '*.yaml' .

Length of output: 201299


🏁 Script executed:

#!/bin/bash
set -euo pipefail

workflow=.github/workflows/opencode-review-dispatch.yml
strix_test=scripts/ci/test_strix_quick_gate.sh

show_context() {
  local file="$1"
  local pattern="$2"
  local context="${3:-35}"
  rg -n -F "$pattern" "$file" | while IFS=: read -r line _; do
    local start=$(( line > context ? line - context : 1 ))
    local end=$(( line + context ))
    printf '\n== %s: lines %s-%s for %s ==\n' "$file" "$start" "$end" "$pattern"
    nl -ba "$file" | sed -n "${start},${end}p"
  done
}

printf '%s\n' '== Exact workflow archive and identity locations =='
rg -n -F \
  -e 'opencode-coverage-source.tar' \
  -e 'tarfile.open' \
  -e 'filter="data"' \
  -e 'review_head_guard_token' \
  -e 'CONFIGURED_REVIEW_WRITE_TOKEN_SOURCE' \
  -e 'review_write_token=' \
  -e 'review_write_token_source=' \
  "$workflow"

show_context "$workflow" 'opencode-coverage-source.tar' 55
show_context "$workflow" 'tarfile.open' 55
show_context "$workflow" 'review_head_guard_token' 45
show_context "$workflow" 'CONFIGURED_REVIEW_WRITE_TOKEN_SOURCE' 35
show_context "$workflow" 'review_write_token=' 30

printf '%s\n' '== Existing static assertions for the requested boundaries =='
rg -n -C 12 \
  -e 'opencode-coverage-source.tar' \
  -e 'review_head_guard_token' \
  -e 'CONFIGURED_REVIEW_WRITE_TOKEN_SOURCE' \
  -e 'review_write_token="${OPENCODE_APP_TOKEN:-}"' \
  "$strix_test"

printf '%s\n' '== Focused Python test modules and configuration =='
fd -a -t f 'test_opencode_agent_contract\.py|conftest\.py|pyproject\.toml|pytest\.ini|tox\.ini|setup\.cfg' . \
  -E .git -E node_modules -E dist -E build | sort
ast-grep outline tests/test_opencode_agent_contract.py --items all 2>/dev/null || true
sed -n '1,260p' tests/test_opencode_agent_contract.py 2>/dev/null || true
for file in pyproject.toml pytest.ini tox.ini setup.cfg; do
  if [ -f "$file" ]; then
    printf '\n== %s ==\n' "$file"
    sed -n '1,240p' "$file"
  fi
done

Length of output: 3621


🏁 Script executed:

#!/bin/bash
set -euo pipefail

workflow=.github/workflows/opencode-review-dispatch.yml
strix_test=scripts/ci/test_strix_quick_gate.sh

show_range() {
  local file="$1"
  local start="$2"
  local end="$3"
  printf '\n== %s: Lines %s-%s ==\n' "$file" "$start" "$end"
  awk -v start="$start" -v end="$end" 'NR >= start && NR <= end { printf "%6d\t%s\n", NR, $0 }' "$file"
}

printf '%s\n' '== Archive producer and artifact upload =='
show_range "$workflow" 270 375

printf '%s\n' '== Archive download and extractor =='
show_range "$workflow" 410 520

printf '%s\n' '== Review-write identity and head guard =='
show_range "$workflow" 4825 5025

printf '%s\n' '== Existing static contract assertions =='
rg -n -C 10 \
  -e 'opencode-coverage-source.tar' \
  -e 'review_head_guard_token' \
  -e 'CONFIGURED_REVIEW_WRITE_TOKEN_SOURCE' \
  -e 'review_write_token="${OPENCODE_APP_TOKEN:-}"' \
  "$strix_test"

printf '%s\n' '== Focused Python test module =='
if [ -f tests/test_opencode_agent_contract.py ]; then
  awk 'NR <= 360 { printf "%6d\t%s\n", NR, $0 }' tests/test_opencode_agent_contract.py
else
  printf '%s\n' 'tests/test_opencode_agent_contract.py is absent'
fi

printf '%s\n' '== Python test and lint configuration =='
for file in pyproject.toml pytest.ini tox.ini setup.cfg; do
  if [ -f "$file" ]; then
    printf '\n== %s ==\n' "$file"
    awk 'NR <= 260 { printf "%6d\t%s\n", NR, $0 }' "$file"
  fi
done

printf '%s\n' '== Candidate Python test files =='
fd -a -t f -g 'test_*.py' tests . 2>/dev/null | sort | head -n 160

Length of output: 29145


🏁 Script executed:

#!/bin/bash
set -euo pipefail

workflow=.github/workflows/opencode-review-dispatch.yml
strix_test=scripts/ci/test_strix_quick_gate.sh

show_matches() {
  local file="$1"
  local literal="$2"
  local context="$3"
  local lines
  lines="$(rg -n -F "$literal" "$file" || true)"
  if [ -z "$lines" ]; then
    printf '\n== No matches in %s for %s ==\n' "$file" "$literal"
    return
  fi
  while IFS=: read -r line _; do
    start=$(( line > context ? line - context : 1 ))
    end=$(( line + context ))
    printf '\n== %s: Lines %s-%s for %s ==\n' "$file" "$start" "$end" "$literal"
    awk -v start="$start" -v end="$end" 'NR >= start && NR <= end { printf "%6d\t%s\n", NR, $0 }' "$file"
  done <<<"$lines"
}

show_matches "$strix_test" 'opencode-coverage-source.tar' 12
show_matches "$strix_test" 'review_head_guard_token' 12
show_matches "$strix_test" 'CONFIGURED_REVIEW_WRITE_TOKEN_SOURCE' 12
show_matches "$strix_test" 'review_write_token="${OPENCODE_APP_TOKEN:-}"' 12

printf '%s\n' '== Focused Python contract test outline =='
if [ -f tests/test_opencode_agent_contract.py ]; then
  ast-grep outline tests/test_opencode_agent_contract.py --items all
  awk 'NR <= 520 { printf "%6d\t%s\n", NR, $0 }' tests/test_opencode_agent_contract.py
fi

printf '%s\n' '== Test configuration files =='
for file in pyproject.toml pytest.ini tox.ini setup.cfg; do
  if [ -f "$file" ]; then
    printf '\n== %s ==\n' "$file"
    awk 'NR <= 300 { printf "%6d\t%s\n", NR, $0 }' "$file"
  fi
done

printf '%s\n' '== Existing validation command references =='
rg -n -C 3 -F 'pytest' README.md .github scripts/ci 2>/dev/null | head -n 300

Length of output: 72791


@seonghobae I confirmed the two actionable defects on the current head.

  • The archive producer has no type or resource limits.

  • The extractor has traversal and special-member checks, but no resource limits.

  • review_head_guard_token uses GH_TOKEN after that token can change to a read credential.

  • CONFIGURED_REVIEW_WRITE_TOKEN_SOURCE can describe non-App credentials as review-write credentials.

  • Add one trusted archive-validation helper for both archive creation and extraction.

  • Apply explicit limits: 10,000 members, 100 MiB per file, 500 MiB aggregate uncompressed content, and 1 GiB archive size.

  • Bind all review-write operations, including the live-head guard, to the OpenCode App token only.

  • Add behavioral Python tests and Strix static assertions.

  • Preserve the existing Terra-before-opencode-free ordering and its current assertions.


Failed to handle agent chat message. Please try again.

You are interacting with an AI system.

@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 440b7b06feb8c12cfe6467d9dcb29fe55e83d064.
  • 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["CI script: test_strix_quick_gate.sh"]
  S2 --> I2["review and security gate shell path"]
  I2 --> R2["Review risk: CI script: test_strix_quick_gate.sh"]
  R2 --> V2["bash -n plus Strix self-test"]
  Evidence --> S3["Test: test_opencode_agent_contract.py"]
  S3 --> I3["regression suite"]
  I3 --> R3["Review risk: Test: test_opencode_agent_contract.py"]
  R3 --> V3["targeted test run"]
Loading

@seonghobae
seonghobae enabled auto-merge (squash) August 3, 2026 03:00

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

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

Closing as operationally incomplete, tracked by #707. The branch only moves opencode/gpt-5.6-terra ahead of the free pool, while its own exact-head evidence says the required OPENCODE_ZEN_API_KEY is absent. That ordering does not produce a working paid fallback or a predictable review SLA, and merging it would advertise a capability that is not operational. Reopen or recreate the focused ordering change after #707 proves the credential, quota, cost owner, timeout, and valid control-artifact path—or remove the unavailable provider from the active pool.

@seonghobae seonghobae closed this Aug 3, 2026
auto-merge was automatically disabled August 3, 2026 03:55

Pull request was closed

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