# Changelog ## 0.0.1.alpha8 - 2026-07-20 ### Bumped - Runtime dependency `opencode-ruby` pinned to `= 0.0.1.alpha8`, carrying the hardened SSE framing parser while retaining the alpha7 subscribe-before- prompt and at-most-once reconnect contract. ### Fixed - Keep transform destination filenames out of the agent-authored identity attachment path and require transforms to verify trust explicitly. - Anchor uploads to an opened sandbox directory across path swaps, replace destination symlinks without following them, and validate bounded reads from the opened sandbox file. Upload copying now requires a traversable `/proc/self/fd` or `/dev/fd` descriptor filesystem and fails closed without it. - Load every runtime standard library explicitly and align the shipped permissions, observer, Turn, prompt, and instrumentation examples with the actual APIs. ### Changed - Test the supported runtime surface on Ruby 3.2, 3.3, 3.4, and 4.0. - Pin every third-party CI and release action to an exact reviewed commit and use Ruby 4.0 for release builds. - Fail the trusted-publishing job before release when the pushed tag does not match `Opencode::RAILS_VERSION`. ## 0.0.1.alpha7 - 2026-07-18 ### Fixed - Make `Opencode::Turn` submit `prompt_async` through the transport's at-most-once `on_subscribed` callback, after `server.connected` proves the SSE listener is ready. Reconnects reopen only SSE and never replay the user prompt. - Fail the turn directly when subscription setup or the prompt POST fails before a turn is confirmed started. The recovery path no longer risks finalizing stale exchange text after a pre-turn failure. - Add a gem-level behavioral regression for the cross-gem ordering contract, including reconnect and ambiguous prompt timeout cases. ### Bumped - Runtime dependency `opencode-ruby` pinned to `= 0.0.1.alpha7`. ## 0.0.1.alpha6 - 2026-07-18 ### Bumped - Runtime dependency `opencode-ruby` pinned to `= 0.0.1.alpha6`. This exposed subscribe-before-prompt through `Client#stream`, but the lower-level `Opencode::Turn` path still sent before `stream_events`; that orchestration gap is fixed in alpha7. ## 0.0.1.alpha5 - 2026-07-15 ### Bumped - Runtime dependency `opencode-ruby` pinned to `= 0.0.1.alpha5`, exposing native parent-linked and configured session creation to Rails hosts. ## 0.0.1.alpha4 - 2026-07-12 ### Bumped - Runtime dependency `opencode-ruby` pinned to `= 0.0.1.alpha4`, adding current `session.status` idle handling and correct multi-assistant tool-loop finalization for Rails turns. ## 0.0.1.alpha3 - 2026-07-10 ### Bumped - Runtime dependency `opencode-ruby` pinned to `= 0.0.1.alpha3`, exposing the session permission PATCH primitive to Rails host applications while leaving reconciliation policy in each host. ## 0.0.1.alpha2 — 2026-05-20 ### Changed - `Opencode::Exchange` now emits `opencode.apply_patch.artifacts_dropped` via the new `Opencode::Instrumentation.notify` fire-and-forget API (introduced in opencode-ruby v0.0.1.alpha2) instead of `.instrument(name, payload) { }` with an empty block. Cleaner read at the call site; identical semantics on the wire (same event name, same payload). ### Bumped - Runtime dependency `opencode-ruby` pinned to `= 0.0.1.alpha2` (was `= 0.0.1.alpha1`). Versions stay in lockstep during alpha. ## 0.0.1.alpha1 — 2026-05-20 Initial public alpha. Extracted from a production Rails app where these objects shipped as in-tree library code before being carved out into a standalone gem. **Includes:** - `Opencode::Session` — AR-coupled, row-level-locked session lifecycle (`ensure!`, `recreate!`, `abort!`) - `Opencode::Turn` — orchestrator covering send → stream → recover → finalize, with CAS-safe message terminal-state transitions - `Opencode::Exchange` — domain object over a turn's message array; emits `opencode.apply_patch.artifacts_dropped` when post-write file content is unavailable - `Opencode::Artifact` — value-object (filename + content + content_type + trust metadata), idempotent attach - `Opencode::MessageArtifacts` — ActiveStorage-aware artifact attachment pipeline with transform support - `Opencode::Sandbox` — disk-backed sandbox reader, returns `Artifact` list - `Opencode::SandboxFile` — single-file value object (pathname → bytes/content-type) - `Opencode::Transform` — base class for content-rewriting transforms - `Opencode::Impostor` — ActiveStorage download/upload round-trip helper - `Opencode::UploadedFilesPrompt` — user-prompt prefix builder listing uploaded files, sandbox-path inverted (injection-based, no `Opencode::Permissions` reference) - `Opencode::ToolDisplay` — view-model for tool-call hashes (Turbo Stream-friendly) - `Opencode::ErrorReporter` — pluggable adapter mirroring the `Opencode::Instrumentation` pattern **Runtime dependencies:** - `opencode-ruby ~> 0.0.1.alpha1` (wire client + Reply state machine) - `activerecord >= 7.1, < 9.0` - `activestorage >= 7.1, < 9.0` - `activesupport >= 7.1, < 9.0` **Known limitations (alpha):** - Apply-patch tool's post-write file content is not extracted (wire-format limitation in OpenCode v1.15+); affected files surface via the `opencode.apply_patch.artifacts_dropped` instrumentation event. Future work: optional sandbox-read fallback path. - Smoke tests only inside the gem. Behavioral coverage currently lives in the host app that produced this code. A standalone gem-side test suite using Combustion is open work. - No generator (`rails g opencode:install`) yet. - No Rails Engine integration — `require "opencode-rails"` is sufficient.