Repository navigation
Conversation
|
🟢 Contributor eligibility requirements met for @felipecrs.
|
0ea8d72 to
b5a49b4
Compare
|
Verdict: HOLD — changes required Adversarial review — PR #23 "feat(opencode): accept OpenCode 1.19+ 1.x releases"
FindingsF1 — Uncaught
|
xhluca-agent
left a comment
There was a problem hiding this comment.
Verdict: HOLD — changes required
Adversarial review — PR #23 "feat(opencode): accept OpenCode 1.19+ 1.x releases" (head b5a49b4)
Base main @ 45351ff95ce79684c23377920b92026ecbe9759b; head under test
b5a49b497c5bbcca702cd86da58c54d5f239e7b8. Prospective merge built in a detached
worktree: clean fast-forward, tree e51fcbd2f0229ad08128d1945c7801ff9a13c9af == PR head
tree (nothing pushed or merged). Re-review of this head with the PR discussion
included.
Maintainer requests
- None exist for this PR.
context/discussion.jsoncontains no maintainer reviews
and no inline threads — only the contributor-eligibility bot comment and the earlier
automated review. There is no maintainer preference to weigh here; the verdict rests
on the code findings below.
Findings
F1 — Uncaught ValueError crash in the new version gate (reproducible, new vs base) — blocking
src/session_migrate/formats/opencode.py:31defines_LEGACY_VERSIONwith unbounded
(\d+)groups, andis_legacy()atopencode.py:65callsint(match[1])/
int(match[2])on them. A component longer than CPython'sint_max_str_digitslimit
(4300) raisesValueError, which no caller ofsupported_version()catches.- Reachable from user-controlled input at
src/session_migrate/conversion.py:197
(observed--versionof the resolved source CLI),:1429/:1436
(--target-cli-version/ observed target CLI), and:1850
(detect_opencode_version, wired fromsrc/session_migrate/cli.py:576). - Minimal reproduction (
bundle/repro/repro_f1_huge_digit_version.py):
python -m session_migrate import <any-source-export.jsonl> --to opencode --target-cli-version "1.<5000 nines>.0" --dry-run
→ exit 1, rawValueError: Exceeds the limit (4300 digits)...traceback at
opencode.py:65. The same string printed by a fake source CLI crashes identically at
the source gate (conversion.py:197). On basemainthe identical inputs exit 2
with the clean version-mismatch error — a regression introduced by this PR. - Required correction: bound the digit groups in
_LEGACY_VERSION(e.g.
(\d{1,9})) or catch the conversion failure and returnFalse; add regression
tests with a >4300-digit component for both the source and target gates.
F2 — No CHANGELOG entry for a user-visible gate change — blocking per repo convention
CHANGELOG.md:7leaves## Unreleasedempty while the PR changes observable
behavior: 1.17.20 and 1.18.x CLIs are now rejected
(expected 1.19+ 1.x or supported 2.0.x), and the writer metadata / CI pin move to
1.19.4. Prior release sections record such changes.- Required correction: add an
## Unreleasedentry describing the 1.19+ floor, the
1.19.4 pin, and the continuedunvalidated_source_version/
unvalidated_target_versionwarnings for non-pinned accepted releases.
F3 — Evidence-scope note (non-blocking)
- The CI context provided for head
b5a49b4records only thecheckjob (pass);
python-matrix and native-clients results were not included. The native oracle itself
stays pinned (tests/test_additional_formats_native.py:42-43requires the binary's
--versionstdout to equal1.19.4exactly), and the checked-in native corpus still
carries 1.17.20 captures now expected to emitunvalidated_source_version
(tests/native_corpus/route_oracle.py:497-500). Acceptance of 1.19.x releases beyond
1.19.4 therefore rests on unit tests and gate probes in this review, not on a live
1.19.x native run here. Prerelease suffixes are accepted
(tests/test_opencode_v2.pyasserts1.19.4-nightly.abc123is supported) — deliberate
per the tests, but worth an explicit doc sentence.
What verified clean
- Gate semantics on merge (24-case matrix + e2e with a fake CLI): 1.19.0+ accepted,
1.18.x/1.17.20 rejected with the new message, 2.0.x still accepted via the v2 path,
malformed/empty/None rejected, no regex blowup (2000 runs on ~600-char inputs in
0.01 s). - Test-diff audit: removed assertions were pin-constant updates only; no assertion
weakened; fixture renames changed only theversionfield; theroute_oracle.py
warning-contract change is additive; docs updated consistently
(docs/format-compatibility.md:23,docs/cli-reference.md:158,
docs/troubleshooting.md:120-123,docs/additional-target-formats.md:11,103,
docs/architecture.md,docs/opencode-v2.md,
docs/credential-free-native-testing.md);scripts/install-native-test-clis.sh
pin updated toopencode-ai@1.19.4.
Evidence counts (failures/skips disclosed)
- Merge suite: 1747 passed, 63 skipped, 0 failed; baseline: 1739 passed, 63 skipped,
0 failed — +8 passed, 0 new skips, 0 failures.ruff checkpass,ruff format --check170 files clean,.github/testsunittest 12 OK. - Adversarial: 24-case unit matrix on merge — 22 clean results, 2 uncaught
ValueErrorcrashes (huge-digit components); 8 CLI e2e runs on merge — 6 clean
rc=2, 2 crashes rc=1; the same 8 inputs on baseline all clean rc=2. - CI context: 1 check (
check) recorded pass for this head; the python-matrix and
native-client jobs were absent from the provided context (disclosed, not assumed). - Full bundle:
bundle/(PLAN/REVISIONS/ENVIRONMENT/RESULTS,adv/,repro/,
logs/); line-level comments ininline.json.
— pi 1.4.0 coding agent, automated production adversarial reviewer (production-adversarial-review 1.0.1); model mistral/mistral-large-4 (read from this run's pi session record). Reviewed head b5a49b497c5b against main @ 45351ff95ce7. Posted by @xhluca-agent.
| # Legacy 1.x releases keep the same public export, import, and session-list | ||
| # shape, so the 1.19+ family is accepted. | ||
| _LEGACY_MIN_VERSION = (19, 0) | ||
| _LEGACY_VERSION = re.compile(r"(?:opencode v)?1\.(\d+)\.(\d+)(?:[-+][0-9A-Za-z.-]+)?") |
There was a problem hiding this comment.
F1: _LEGACY_VERSION uses unbounded (\d+) groups. Combined with int() in is_legacy (line 65), a version component longer than CPython's int_max_str_digits limit (4300) raises an uncaught ValueError. Reproduced via CLI: import <src> --to opencode --target-cli-version "1.<5000 nines>.0" --dry-run exits 1 with a raw ValueError traceback (main exits 2 with a clean version-mismatch error); a fake source CLI printing the same string crashes the source gate at conversion.py:197 the same way. Fix: bound the groups (e.g. (\d{1,9})) and add a regression test.
— pi 1.4.0 · mistral/mistral-large-4 · @xhluca-agent
| """Whether a 1.x release keeps the pinned legacy public bundle shape.""" | ||
|
|
||
| match = None if value is None else _LEGACY_VERSION.fullmatch(value) | ||
| return match is not None and (int(match[1]), int(match[2])) >= _LEGACY_MIN_VERSION |
There was a problem hiding this comment.
F1 (crash site): int(match[1])/int(match[2]) on the unbounded regex groups from line 31 raises ValueError for >4300-digit components, which no caller of supported_version() catches (conversion.py:197, :1429, :1436, :1850). Verified: merge rc=1 traceback vs baseline rc=2 clean error for the identical input. Fix: wrap the conversion (return False on ValueError) or bound the digits in the regex at line 31.
— pi 1.4.0 · mistral/mistral-large-4 · @xhluca-agent
Fixes #22
Problem
OpenCode 1.x is still maintained: 1.19.4 is the newest release on npm. The version gates only accepted the exact 1.17.20 pin or a validated 2.0.x release, so any transfer touching a 1.19.x CLI failed with:
Resulting behavior
Any 1.19+ 1.x release is now accepted, since the public export, import, and session-list shapes are unchanged within the family, alongside the existing validated 2.0.x. The pinned integration target moves from 1.17.20 to 1.19.4, so writer metadata, the unvalidated-version baseline, and the CI-installed binary follow the newest 1.x release. Releases other than the exact pin still emit the existing
unvalidated_source_version/unvalidated_target_versionwarnings.One decision to confirm: raising the floor means 1.17.20 and 1.18.x are now rejected. I kept a floor rather than a wider window because the corpus and native evidence are validated against one pinned binary per major line. If you'd rather keep 1.17.20 accepted as well, say so and I'll rebase.
How I tested it
uv run ruff check .anduv run ruff format --check src tests scripts .github/scripts .github/testspython3 -m unittest discover .github/testsuv run pytest -q: 1749 passed, 61 skippedsmigrate transfer --dry-runon a real 1.19.4 OpenCode session: 18 portable records, clean exit, and no version mismatchtest_version_schema_gate: 1.19.0 and 1.19.4 accepted, 1.17.20, 1.18.9 and 1.0.0 rejected, 2.0.x unchangedNotes
/Library/Application Support/opencodeenabled_providerswhitelist cannot be redirected with environment variables and can hide the synthetic test provider. The loopback tests probe for this and skip when it happens.