Skip to content

feat(providers): accept OpenCode 1.18.31-1.19.3 through an explicit verified set - #713

Open
Yoseph-Zuskin wants to merge 5 commits into
NVIDIA:mainfrom
Yoseph-Zuskin:feat/opencode-version-range
Open

Yoseph-Zuskin wants to merge 5 commits into
NVIDIA:mainfrom
Yoseph-Zuskin:feat/opencode-version-range

Conversation

@Yoseph-Zuskin

@Yoseph-Zuskin Yoseph-Zuskin commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Fixes: #712

The opencode_cli gate currently admits a single exact pin, so every upstream patch release locks out provider users until a new pin lands. This PR replaces the pin with an explicit verified set: nine releases (1.18.31-1.18.35, 1.19.0-1.19.3), each individually reviewed with its own live matrix. Never a range: the set only grows by adding a triple with evidence, so a raised boundary can never silently admit an unverified patch.

What changed:

  • _OPENCODE_SUPPORTED_VERSIONS is a frozenset of verified triples; both gates share one membership predicate. Error messages list the verified members.
  • Per-member evidence lives beside the set, including the plugin-source check requested in review: plugin packages are pinned identically across 1.19.0-1.19.3 in bun.lock (opencode-gitlab-auth 2.1.0, opencode-poe-auth 0.0.1, @gitlab/opencode-gitlab-auth 1.3.3, same integrity hashes) and no in-tree plugin source changed.
  • Prereleases and unparsable --version output are rejected; the debug config resolved-subset check is untouched.
  • Boundary tests: accept all nine members; reject 1.18.30/1.18.36/1.19.4/prerelease/garbage/empty at parse, probe and preflight levels; the set itself is pinned by a membership test.

Verification matrix (all through the production path under the isolated deny-all env; live runs on openrouter/nvidia/nemotron-3-ultra-550b-a55b:free; auth output is byte-identical across the sweep):

Version auth preflight live run run --help
1.18.31 PASS PASS MATRIX-OK identical
1.18.32 PASS PASS MATRIX-OK identical
1.18.33 PASS PASS MATRIX-OK identical
1.18.34 PASS PASS MATRIX-OK identical
1.18.35 PASS PASS MATRIX-35 identical (d62299eb...)
1.19.0 PASS PASS MATRIX-19 identical (d62299eb...)
1.19.1 PASS PASS MATRIX-111 identical in-group (177277fa...)
1.19.2 PASS PASS MATRIX-112 identical in-group (177277fa...)
1.19.3 PASS PASS MATRIX-113 identical in-group (177277fa...)

The 1.19.1 run --help delta versus 1.19.0 is the hidden --share flag (session sharing was discontinued); no other run surface changed. Per-release static pass: 1.19.1 share removal, 1.19.2 installer/upgrade internals, 1.19.3 additive reasoning-variant support.

Unit: tests/provider + tests/unit/test_agent_cli.py: 155 passed, 10 skipped (pre-existing POSIX-only skips). ruff check + format + git diff --check clean.

OpenCode 2.x (preview) is out of scope here and tracked separately.

- Replace the exact pin with inclusive _OPENCODE_MIN_VERSION /
  _OPENCODE_MAX_VERSION triplets; _parse_opencode_version returns
  a triple and both gates (preflight + auth check) share one
  range predicate; prereleases and unparsable output still fail
  closed; the debug-config subset check is untouched
- 14 new boundary cases: parse accept (.31-.34) / reject (.30,
  .35, prerelease, garbage, empty); probe accept / reject; RED
  witnessed on the exact pin before the cutover
- Verified: tests/provider 55 passed, 3 skipped (pre-existing
  POSIX-only skips); ruff + format + diff-check clean; live
  matrix .31/.32/.33/.34 all green (auth + preflight +
  isolated live run + run --help diff)
- Ponytail review: lean, no findings

Signed-off-by: Yoseph Zuskin <zuskinyoseph@gmail.com>
Co-Authored-By: OpenCode Muse Spark 1.3 Free (1M context) <noreply@opencode.ai>

@rng1995 rng1995 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[SkillSpector Review]

Hi @Yoseph-Zuskin, thank you for turning the one-release-at-a-time OpenCode pin into a verified version window, and for testing each version live!

Value and readiness: The code change is correct and still fails closed. _is_supported_opencode_version admits exactly 1.18.31, 1.18.32, 1.18.33 and 1.18.34. Both gates reject every other version before auth list or inference runs, including prereleases, unparsable or empty output, and a non-zero --version exit. The debug config subset check is unchanged. Every admitted version has evidence. Versions .31, .32 and .33 were verified in #575, #613 and #665. Since #562, the isolation and preflight code they were checked against has changed only in version strings. The upstream v1.18.33...v1.18.34 delta touches nothing the policy depends on. It is not ready yet: README and docs/DEVELOPMENT.md still tell users the provider needs exactly 1.18.33.

Material findings

  1. [Blocker] README.md:245, README.md:653 (lines 300 and 712 on current main), docs/DEVELOPMENT.md:348: these lines still say opencode_cli "fails closed unless the installed OpenCode version is exactly 1.18.33". DEVELOPMENT adds that it "fails closed on every other runtime version because the deny-all policy is verified against that exact release". After this PR, those statements describe a security gate the code no longer has. A user on 1.18.31 would upgrade for no reason. Each earlier bump (#575, #613, #665) updated these lines. Please list the accepted versions (1.18.31 through 1.18.34) and say that every other version, including prereleases, still fails closed.
  2. [Non-blocking] src/skillspector/providers/_agent_cli.py:463-464: the only record of which versions were verified, and how, is the table in the PR description. Comments at :457, :597-601, :620, :695 and :749 still describe a single 1.18.33 pin; :600 says "The same pinned version uses this override". Please add a comment beside the bounds that lists each admitted version with its evidence (#575, #613, #665, this PR). Please also reword the OPENCODE_TEST_HOME / OPENCODE_TEST_MANAGED_CONFIG_DIR comment to say these internal overrides were confirmed for every version in the window. This matters because the description understates the version gate. The debug config check sees 11 resolved keys and the selected agent's permission. It cannot tell whether OpenCode still honours those two test hooks, which keep home AGENTS.md, .opencode, .claude and platform managed config out of the child. Any patch release may rename them. The version gate therefore stays load-bearing, not "belt-and-suspenders", and each future widening needs the same upstream review #575, #613 and #665 received.
  3. [Non-blocking] tests/provider/test_opencode_cli.py:298-308: test_parse_supported_versions_compare_in_range and test_parse_unsupported_versions_rejected repeat the range comparison inline instead of calling _is_supported_opencode_version. They would pass even if that predicate broke. The auth-check cases at :312-324 do exercise the real predicate at .30, .31, .34 and .35. The preflight gate itself is tested only with 1.18.99 (:457-468). A fake-binary run_agent_cli case at 1.18.30 and 1.18.35 would pin that gate directly.

PIC tradeoffs:

  • Window or explicit set. The review on #613 suggested exact matching against an explicit set of individually verified versions, never a range. Today the two are equivalent, because .31 to .34 all have evidence. They diverge later. If the maximum moves from .34 to .36 after only .36 is checked, .35 is admitted silently, and a window cannot exclude one bad patch. A frozenset of verified triples makes per-version verification structural at almost no cost. Issue #712 asks for a range, so this is the PIC's call.
  • Re-admitting 1.18.31 and 1.18.32. This helps users who did not upgrade. Those builds print debug config without the credential redaction added in 1.18.33. The preflight only parses that output in memory and never logs or reports it, so admitting them adds no exposure.
  • Release notes. The next release notes should state the accepted window. The 2.12.0 notes still say exactly 1.18.31.

Verification and gaps:

  • Traced both gates at this head. _preflight_opencode_policy (_agent_cli.py:649-658) and _opencode_auth_check (:860-869) share the predicate. Tuple ordering admits exactly four triples. 1.19.0, 1.18.3, 1.18.34-1, garbage and empty output are rejected.
  • Ran git diff c3bb8132 main -- src/skillspector/providers/_agent_cli.py. Only version strings differ, so .31, .32 and .33 were verified against the same isolation and preflight code.
  • Upstream anomalyco/opencode v1.18.33...v1.18.34 (30 commits, 135 files). The CLI source changes are two added request headers (x-opencode-session-id, x-opencode-parent-session-id), a TUI path fix and macOS signing. bun.lock only bumps workspace versions. Nothing touches config loading, permission merging, OPENCODE_* handling, debug config or run flags. v1.18.34 is the latest upstream release today.
  • I could not reproduce the live matrix in the description. Per policy, I did not run the tests or the OpenCode binary.
  • CI: all six checks pass on this head, and it merges cleanly with current main.
  • Overlaps: this PR conflicts with #716 in the constants block after _OPENCODE_DENY_ALL (#716 inserts _ZEN_FREE_TIER_MARKERS right after the line this PR replaces). It also conflicts with #738 at the fake binary's --version line (tests/provider/test_opencode_cli.py:370). Both fixes are mechanical. I suggest landing #716 first, then rebasing this PR along with the doc fix. #747 changes the TypeScript extension, not this provider, so it does not overlap.

Decision: Changes Requested (reviewed head 684922305d15b3ead51a0dd45483e80b85fabafa)

…on-range

Signed-off-by: Yoseph Zuskin <zuskinyoseph@gmail.com>
Co-Authored-By: OpenCode Muse Spark 1.3 Free (1M context) <noreply@opencode.ai>

@rng1995 rng1995 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[SkillSpector Review]

@Yoseph-Zuskin thank you for the verified version window and the per-version matrix. Sorry it now needs a rebase after #716 and #738 landed.

Value and readiness

The change is still needed: main still pins exactly 1.18.33, and upstream has since shipped 1.18.34, 1.18.35 (Oct 6) and 1.19.0 (Oct 11). Every OpenCode user not on 1.18.33 is still locked out. The PR is not ready: the docs blocker is unchanged, and the branch now conflicts in _agent_cli.py and tests/provider/test_opencode_cli.py. These are the #716 and #738 overlaps flagged last time; both have now merged.

Material findings

Prior findings:

  1. Blocker: the docs still say "exactly 1.18.33". Still open. On main this is README.md:301, README.md:774 and docs/DEVELOPMENT.md:352.

  2. Optional: evidence comment beside the bounds. Still open, and #810 makes it more useful. Main now keeps OpenCode's internal plugins enabled, and _prepare_opencode_env says they "register no tools", a claim verified only at 1.18.33. I checked upstream, and the claim holds across your window:

    • From v1.18.31 to v1.18.33, the in-tree plugin changes are cosmetic: open became openUrl, and two model IDs joined codex's allow-list.
    • v1.18.33 to v1.18.34 changes no plugin source.
    • opencode-gitlab-auth 2.1.0 and opencode-poe-auth 0.0.1 are the same in every release.

    Please record this next to _OPENCODE_MIN_VERSION / _OPENCODE_MAX_VERSION, so the next widening repeats the check.

  3. Optional: tests that inline the range comparison instead of calling the predicate. Still open.

There are no new code issues. Your hunks do not touch #810's removal of OPENCODE_DISABLE_DEFAULT_PLUGINS, so a normal three-way merge keeps it. Please don't resolve _agent_cli.py by taking the branch side wholesale.

PIC tradeoffs

  • Window versus an explicit set of verified versions: unchanged from the last review.
  • Upstream is now at 1.19.0. Admitting 1.18.35 or later needs the same per-release review, and is outside the scope of #712.

Verification and gaps

  • git merge-tree against main at 8b993d32 reports 2 conflicting files. Main's _agent_cli.py still uses _OPENCODE_SUPPORTED_VERSION = "1.18.33" in both gates.
  • Ran the GitHub compare API on anomalyco/opencode for v1.18.31...v1.18.33, v1.18.32...v1.18.33 and v1.18.33...v1.18.34, filtered to plugin sources, packages/opencode/package.json and bun.lock.
  • CI was green on Oct 3. Static review only; I did not run OpenCode.

Yoseph-Zuskin and others added 3 commits October 17, 2026 14:15
- Replace the MIN/MAX window with _OPENCODE_SUPPORTED_VERSIONS,
  a frozenset of the 4 verified triples; the predicate is
  membership, so a raised MAX can never silently admit an
  unverified patch; error text keeps the 1.18.31-through-1.18.34
  wording
- README + DEVELOPMENT list the verified releases; prereleases
  fail closed
- Comments carry per-version evidence; TEST_HOME/MANAGED
  overrides confirmed per window; gate documented load-bearing,
  not belt-and-suspenders
- tests: predicate-call rewrites, frozenset membership pin,
  fake-binary preflight at .30/.35 (RED: missing name)
- Verified: file 58/5, provider+unit 140/5, ruff clean

Signed-off-by: Yoseph Zuskin <zuskinyoseph@gmail.com>
Co-Authored-By: OpenCode Muse Spark 1.3 Free (1M context) <noreply@opencode.ai>
…on-range

Signed-off-by: Yoseph Zuskin <zuskinyoseph@gmail.com>
Co-Authored-By: OpenCode Zen DeepSeek V4.1 Flash Free (200K context) <noreply@opencode.ai>
- Add (1, 19, 1), (1, 19, 2), (1, 19, 3) to
  _OPENCODE_SUPPORTED_VERSIONS; nine explicit triples, never a
  range
- Evidence beside the set: per-release live matrix with exact
  nonce replies, auth-list shape byte-identical, preflight PASS;
  run --help byte-identical across 1.19.1-1.19.3 (sole delta vs
  1.19.0: hidden --share flag, session sharing discontinued);
  plugin packages pinned identically across 1.19.0-1.19.3 in
  bun.lock and no in-tree plugin source changed (the check review
  asked to keep next to the set)
- Boundary tests move with the edge: accept 1.19.1-1.19.3; reject
  1.19.4 at parse, probe and preflight levels; set pin covers
  nine
- Docs: README table + fail-closed note and DEVELOPMENT list nine
- Verified: provider + agent_cli suites 155 passed, 10 skipped;
  ruff check + format and git diff --check clean

Signed-off-by: Yoseph Zuskin <zuskinyoseph@gmail.com>
Co-Authored-By: OpenCode Zen DeepSeek V4.1 Flash Free (200K context) <noreply@opencode.ai>
@Yoseph-Zuskin Yoseph-Zuskin changed the title feat(providers): accept OpenCode 1.18.31-1.18.34 version range feat(providers): accept OpenCode 1.18.31-1.19.3 through an explicit verified set Oct 17, 2026
@Yoseph-Zuskin

Copy link
Copy Markdown
Contributor Author

Hi @rng1995, thank you for the two thorough reviews. There are no inline threads to reply to, so here is the full response in one place, plus what changed on the branch since your last pass (head a9337de1).

Material findings, point by point

  1. Docs blocker: fixed. README.md (provider table and the fail-closed note) and docs/DEVELOPMENT.md now list every verified release, 1.18.31 through 1.18.35 and 1.19.0 through 1.19.3, nine in total, and state that every other version, including prereleases, still fails closed. No user upgrades for no reason.
  2. Evidence beside the set: done, and extended per your second review. The set carries per-member evidence for all nine releases (feat(providers): verify OpenCode 1.18.31 for the deny-all policy #575, feat(providers): verify OpenCode 1.18.32 for the deny-all policy #613, feat(providers): verify OpenCode 1.18.33 for the deny-all policy #665, and this PR's matrices for the rest), and the comment next to _OPENCODE_SUPPORTED_VERSIONS records the plugin-source check you asked to keep there: opencode-gitlab-auth 2.1.0, opencode-poe-auth 0.0.1 and @gitlab/opencode-gitlab-auth 1.3.3 are pinned with identical bun.lock integrity hashes across 1.19.0-1.19.3, and no in-tree plugin source appears in any of those diffs. Your rationale is kept beside the gate: the debug config check cannot tell whether the OPENCODE_TEST_HOME / OPENCODE_TEST_MANAGED_CONFIG_DIR hooks still apply, so the gate stays load-bearing, not "belt-and-suspenders", and each widening repeats the same review.
  3. Predicate tests: done. Both parse tests call _is_supported_opencode_version directly, the set itself is pinned by a membership test, and the preflight gate has fake-binary cases at 1.18.30, 1.18.36 and 1.19.4 with empty markers.

PIC tradeoffs

  • Window versus an explicit set of verified versions: went with the frozenset as suggested. A raised maximum could silently admit an unverified patch; 1.18.35 and 1.19.0 are the proof of the alternative working, each arrived as one triple with its own evidence, and 1.19.1 through 1.19.3 followed the same pattern.
  • Scope: you flagged 1.18.35+ as needing the same per-release review and outside opencode_cli version range 1.18.31-1.18.34, 1.19.0-1.19.3 #712; the call here was to fold that review into this PR instead of a follow-up, same gate and same evidence pattern. OpenCode 2.x (preview only) could be tracked as a separate issue.

Since the last review

  • Merge: cleared the conflict by merging current main rather than taking branch sides, exactly as you predicted. The three-way merge keeps fix(providers): keep OpenCode's internal plugins so OAuth logins work #810's removal of OPENCODE_DISABLE_DEFAULT_PLUGINS; internal plugins stay enabled (they register no tools, and the plugin-source check above now covers the new versions) and external plugins stay off via --pure.
  • New rows: 1.18.35 and 1.19.0, then 1.19.1, 1.19.2 and 1.19.3. Same matrix for each: --version exits 0, auth list byte-identical across the whole sweep, preflight PASS under the isolated env, exact nonce replies through the production path.
  • 1.19.x static pass: 1.19.1 removes session sharing (its only run --help delta is the now hidden --share flag), 1.19.2 is installer and upgrade internals, 1.19.3 is additive reasoning-variant support. Nothing touches config loading, permission merging or the run surface; run --help is byte-identical within .34/.35/1.19.0 (d62299eb) and within 1.19.1-1.19.3 (177277fa).

Verification

  • The description carries the full nine-row matrix; every row went through the production provider path.
  • Boundary tests move with the edge: accept all nine members; reject 1.18.30, 1.18.36 and 1.19.4 at parse, probe and preflight levels, plus prerelease, garbage and empty output.
  • Local: tests/provider + tests/unit/test_agent_cli.py: 155 passed, 10 skipped (pre-existing POSIX-only skips); ruff check, ruff format --check and git diff --check clean.

On release notes: agreed, the next release notes should state the accepted set, noted here so it does not get lost.

Thanks again for the close reads.

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.

opencode_cli version range 1.18.31-1.18.34, 1.19.0-1.19.3

2 participants