Skip to content

feat: add verified OpenCode 2 support and prepare 0.11.0 - #78

Merged
william-ricchiuti merged 8 commits into
mainfrom
wr/release-0.11.0
Sep 30, 2026
Merged

william-ricchiuti merged 8 commits into
mainfrom
wr/release-0.11.0

Conversation

@william-ricchiuti

@william-ricchiuti william-ricchiuti commented Sep 30, 2026 •

Copy link
Copy Markdown
Owner

Adds OpenCode 2 support from #76 with corrections for live lease ownership, failed agent switching, verifier ownership and synchronous audit replies. Same-process location reloads now retire the old plugin instance explicitly instead of reclaiming a live lease by age. Every built-in V2 audit verifies the live verifier system and permissions before submission; a failed switch sends no prompt. Rejected config ownership revokes audit readiness, and child verdicts are read only after execution settles.

Directory normalization uses a linear scan to avoid backtracking on adversarial separator runs, with a bounded subprocess regression.

Includes current main's #75 and audit fixes through a normal merge. Prepares 0.11.0 with synchronized version pins and changelog; no publication. Preserves the original contributor commits. This corrected integration supersedes the reviewed #76 implementation.

Validation:

  • Complete release gate: 490 tests, 90/90 critical mutants, behavior 100/100, installed type/packed contracts, smoke, verify, zero dependency vulnerabilities and pack checks.
  • Exact tarball installed in isolation: real OpenCode 2.0.16 Plan add/sequence, Code Mode completion through read/glob/grep-only goal-verify, foreign-verifier rejection before a model request, and paused recovery after location reload.
  • Packed real OpenCode 1.18.25 acceptance: Plan add/sequence and timestamp-cap/ENOSYS persistence.
  • Every packed file compared byte-for-byte against the checkout; git diff --check passes.

OpenCode 2.0.16 exposes no session-removal method in the plugin context. Verifier children remain retained on that host; optional removal is mapped when supported. The checked-in live canary is isolated and uses a localhost deterministic provider with no paid calls. Hosted OS/Node checks should pass before merging.

datamoc and others added 7 commits September 25, 2026 01:10
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
npm run re-exports a user-level allow-scripts npmrc entry as environment
config, which npm 12 rejects with EALLOWSCRIPTS when the child install also
passes --ignore-scripts; the type, packed-host, and packed-tool contracts
now strip script-policy npm_config_* keys before invoking child npm.

npm 12 also keys pack --json output by package name instead of printing a
bare array. The packed-host and packed-tool contracts still assumed the
array shape and failed before their install step, and the type contract
crashed in its final success log (packResult[0] instead of the normalized
packed entry) even after both tsc passes. Normalize all three.
The 0.10.1 release notes left three surfaces marked unverified against a
live 2.x provider. All three now have live OpenCode 2.0.16 results recorded
in the verified-on-a-live-host table:

- a full goal run to completion through goal_complete (archive as achieved
  with the evidence claim and usage recorded);
- the auto-continue loop (two goal_continuation prompts admitted with
  correlation metadata and a live progress_budget countdown, then the
  talk-only stall gate pausing the goal);
- the session-title status indicator rendering the live status line.

Also recorded: cold-boot command ownership over a legacy config
command.goal entry (the plugin's framed control result is the admitted
turn; the config template text never reaches the model), agent
registration with system prompts and translated permission rules, and the
plugin-options precedence rule when the same package is listed in both
user-level and project config. completionAudit child sessions remain the
one unverified path, as documented.
A long-running host (opencode serve) can reload a location's plugin
instance without disposing the instance it replaces — a file-watcher
event under .opencode, including this plugin's own state writes, can
trigger that. The orphaned instance's session lease used to stay live
forever, since its owning pid is the host process itself and never
exits, permanently blocking its own successor with
session_owned_elsewhere.

Each plugin instance now touches its own lease's claim every time it
actually handles a hook or tool call for a session it owns (not a
free-running timer, which would keep an orphan's claim alive forever
too). persistence-lease.js reclaims a same-host claim once it stops
being refreshed for DEFAULT_STALE_CLAIM_MS; a different host's claim is
never reclaimed this way, since network partitions and clock skew make
"stopped heartbeating" indistinguishable from "still alive but slow to
reach us".

Adds a test-only leaseStaleAfterMs plugin option and touch()/touchClaim
lease API, plus tests covering reclaim-after-stale, touch() semantics,
and an end-to-end orphaned-instance recovery scenario.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Comment thread src/v2-bridge.js Fixed
@william-ricchiuti
william-ricchiuti merged commit 3ff0a18 into main Sep 30, 2026
10 checks passed
@william-ricchiuti
william-ricchiuti deleted the wr/release-0.11.0 branch October 30, 2026 20:59
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.

3 participants