Skip to content

v1.1.0

Choose a tag to compare

@AlexJoaquimPereira AlexJoaquimPereira released this 14 Oct 12:57
· 147 commits to master since this release

OpenCode Cache Engine v1.1.0

This release completes Phase 1 of the post-1.0.0 plan: detect and explain system-prompt volatility without changing request behavior, add the corresponding telemetry, and ship a reusable offline harness for comparing serialized requests. It is diagnostics-only — no cache-policy or request-mutation changes.

Highlights

  • New read-only silent-invalidator linter for system text.
  • New first-difference primitive and a baseline-relative systemStablePrefixLength telemetry field.
  • A system_volatility boundary event, emitted once per high-severity state transition.
  • Full V1 + V2 integration with bounded, per-session dedup (V2 no longer allocates session state for neutral/unknown models).
  • A reusable offline/mock capture harness with a documented 0/1/2 exit contract, now runnable via npm run test:harness.

Core diagnostics (src/cache-engine-core.mjs)

  • firstSystemDifference(baseline, current) — byte offset of the first difference plus before/after lengths (empty-, equal-, prefix-, insertion-, deletion-, and reorder-safe).
  • lintSystemVolatility(parts, tools, options) — advisory, pure, never rewrites. Rules and severities:
    • high — VOL-TIMESTAMP, VOL-SESSION-ID, VOL-TOOL-SET
    • medium — VOL-TOOL-ORDER (implemented); VOL-CONDITIONAL, VOL-NONDET-JSON, VOL-DYNAMIC-BEFORE-STABLE are reserved and intentionally not emitted (a single snapshot cannot detect them reliably)
    • info (allow-listed) — VOL-DATE, VOL-CWD-PATH
  • effectiveSeverity() pins allow-listed rules to info regardless of their default, so an expected-volatility finding can never trigger a high-severity signal.
  • volatilitySignature() / volatilityTransition() — deterministic, content-free dedup (sorted, unique rule IDs).
  • Session-ID detection keeps ses_…/UUID forms high, and only treats a bare 32-hex token as a finding when session context is adjacent (avoids flagging stable hashes).
  • systemShapeHashes() now also returns stablePrefixLength.

V1 runtime (src/cache-engine.ts)

  • Lints the post-relocation system text (guarded; a diagnostic failure can never break a request).
  • Emits one boundary record with reason: "system_volatility" per transition into a high state (never every turn).
  • Persists systemStablePrefixLength on prefix-observation and prefix-change.

V2 runtime (src/cache-engine-v2.mjs)

  • Lints every family (including neutral/unknown), using a dedicated bounded lintSigs map so neutral models never allocate or refresh main session state.
  • system_volatility records carry provider/model when available (omitted, not empty-string placeholders, otherwise).
  • lintSigs is cleared on session deletion and cleanup.

New telemetry (consumer note)

Additive only — existing record kinds and fields are unchanged:

  • systemStablePrefixLength — byte length of the stable prefix, i.e. the first-differing byte offset relative to the session baseline system text (not the previous observation, not a raw wire offset).
  • boundary reason system_volatility — severity: "high" and rules: [...] (sorted high-severity rule IDs only; no prompt content). Emitted by both V1 and V2.

Consumers that enumerate boundary reasons or assume a fixed prefix-* field set may need to accommodate these additions.

Offline capture harness (test/harness/capture/)

Reusable, isolated two-request capture and structural diff:

  • run.sh (orchestrator) → inner.sh (sandboxed turns) → mock-provider.mjs (loopback-only mock) → decide.sh/diff-requests.mjs.
  • bwrap --unshare-net, private HOME/XDG, per-turn timeout, fail-closed temp root, retention via prune.sh; no unisolated fallback.
  • Documented exit contract: 0 identical/expected, 1 unexpected structural difference, 2 blocker/invalid input.
  • Run it: npm run test:harness (exit-contract + retention + port-parity). npm test is unchanged.

This harness proves structural equivalence of two equivalent mock requests; it is verification infrastructure and does not itself demonstrate any provider-side cache benefit.

Documentation

  • Phase 1 marked COMPLETE in docs/opencode-cache-engine-v1.x.x-implementation-plan.md and AGENTS.md (Phase 2 — date relocation — is not started and remains gated on provider-side rollover evidence).
  • docs/research-findings.md now notes that the competitor research report is gitignored/local-only and that the tracked plan holds its distilled conclusions.
  • baseline-report-*.md is gitignored (local-only), alongside audit-report-*.md.

Compatibility & testing

  • No breaking changes: exports (./server, ./tui, ./v2) and existing telemetry record kinds/fields are unchanged; all diagnostic additions are read-only.
  • 362 tests pass / 0 fail; npm run test:harness passes; git diff --check clean; package packs 9 files.

Limitations / evidence boundary

  • Diagnostics are structurally verified and offline/mock verified; no provider calls were made and no cache-read/write metrics or cache-stability improvement are measured or claimed.
  • Usage accounting remains best-effort (not exactly-once).
  • Reserved linter rules are deliberately not emitted.

Full Changelog: v1.0.1...v1.1.0


Thank you to everyone for using the plugin and helping make this project successful!


Provider-aware prompt-cache optimization and observability for OpenCode.

opencode-cache-engine is an OpenCode npm plugin that exposes three targets required by OpenCode's installed plugin model:

  • ./server — the V1 CacheEngine runtime, hooks, provider policies, and telemetry (verified on OpenCode 1.x).
  • ./tui — plugin-manager registration and enable/disable integration; it
    has no CacheEngine-specific UI.
  • ./v2 — the OpenCode V2 adapter (preview): implemented and offline-tested; isolated shim-based loading, setup, and hook registration/dispatch are verified in an isolated OpenCode 2.0.26 runtime, but managed-config discovery/registration remain unverified.

CacheEngine is an OpenCode plugin designed for long-running agent sessions where prompt-cache efficiency affects both latency and cost. It keeps the harness conservative for providers whose cache behavior is already automatic, while applying provider-specific optimizations where the provider exposes useful cache controls or where prompt structure can be safely improved.

The plugin currently has eleven cache-policy families: DeepSeek, GPT-5.6+, GLM-5.3+, MiMo V2.6+, Kimi, Claude, Gemini, Qwen, Grok, Muse, MiniMax

Initial models were personally chosen for their performance in max programming task completed per dollar. More models can be added based on newer releases or updates.

Future releases will be based on newer versions of models from the above providers, as well as any model that performs optimally over the Pareto distribution on OpenRouter as well as on personal discretion. Since cache stability policy doesn't change much for the providers, there's no need for a code rebase.

Installation

V1 (stable):

opencode plugin opencode-cache-engine          # TUI/CLI installer

or set config:

"plugin": ["opencode-cache-engine"]

V2 (preview):

opencode plugin add opencode-cache-engine      # TUI/CLI installer

or set config:

"plugins": ["opencode-cache-engine"]

Both install the package by name, and each runtime selects the interface it supports from the package's ./server export (V1 → server, V2 → setup). Do not pass opencode-cache-engine/v2 as the package specifier; use the bare name.

Best complemented with agents for the particular models configured at AlexJoaquimPereira/opencode-agent-config