Releases: marmutapp/superbased-observer
v1.8.4
Changed
- Package homepage now points to https://superbased.app/. The npm
and PyPI package metadata (and their READMEs) link to the product
homepage instead of the GitHub repository. Source, issue-tracker, and
changelog links continue to point at GitHub.
No functional or binary changes from 1.8.3 — the bundled observer
binary is byte-for-byte identical. This release exists to refresh the
published package metadata.
Downloads
Pre-built binaries for each supported platform are attached below. Linux variants bundle antigravity-bridge.exe next to the observer binary for WSL2 users of the Antigravity adapter.
| Platform | Asset |
|---|---|
| Linux x86_64 | observer-v1.8.4-linux-x64.tar.gz |
| Linux arm64 | observer-v1.8.4-linux-arm64.tar.gz |
| macOS x86_64 (Intel) | observer-v1.8.4-darwin-x64.tar.gz |
| macOS arm64 (Apple Silicon) | observer-v1.8.4-darwin-arm64.tar.gz |
| Windows x86_64 | observer-v1.8.4-win32-x64.zip |
Verify with sha256sum -c SHA256SUMS (or shasum -a 256 -c SHA256SUMS on macOS) from the directory containing the downloads.
Also available via npm: npm install -g @superbased/observer@1.8.4
Org server (Docker)
The self-hosted org server ships as a Docker image and as per-platform observer-org-v1.8.4-* archives (attached below).
docker pull ghcr.io/marmutapp/observer-org:v1.8.4The image is keyless-signed with cosign. Verify it:
cosign verify ghcr.io/marmutapp/observer-org:v1.8.4 \
--certificate-identity-regexp 'https://github.com/marmutapp/superbased-observer-private/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comSupply chain
CycloneDX SBOMs are attached: observer.cdx.json and observer-org.cdx.json.
SLSA Level 3 build provenance for the binaries is attached below as a *.intoto.jsonl attestation. The build runs on the private origin repo, so pass that as the source when verifying an extracted binary with slsa-verifier v2.7.0 or newer (older versions fail with unexpected tlog entry type: expected intoto:0.0.2, got dsse:0.0.1):
slsa-verifier verify-artifact ./observer \
--provenance-path *.intoto.jsonl \
--source-uri github.com/marmutapp/superbased-observer-privatev1.8.2
Release headline. Quality-of-life follow-up to the v1.8.0 Teams
shipment + release-pipeline hardening on top of v1.8.1's G8 fix, plus
three new AI-tool adapters (Hermes / Cline-CLI / Kilo Code two-product
pair) and the full Observer Quest website-arcade arc: a v1
6-world / 24-level NES platformer expansion, a 12-phase
addictive-modernization layer (skill tree + INSIGHT + mastery +
engine primitives + bestiary + daily challenge + ghost replays +
achievements + cosmetics + FTUE + a11y), a Phase 13 visual + content
expansion (character redesign + 3 new pickups + shoot mechanic +
7-biome remap + +50% level extensions), and a mobile-playable
redesign with dedicated touch band on the arcade and a polished
editorial column on the main page. 166 commits past v1.8.1.
Added — Kilo Code adapters (legacy IDE extension + CLI)
Captures session data from both Kilo Code products:
kilo-code— the legacykilocode.kilo-codeIDE extension
(Cline + Roo Code fork). Persistence is byte-identical to Cline:
<vsCodeGlobalStorage>/kilocode.kilo-code/tasks/<taskId>/api_conversation_history.json.
The newkilocode.LegacyAdapterwraps the existing
internal/adapter/cline.Adapterand re-tags every emitted event
withTool = "kilo-code"so dashboard rollups don't blur Kilo
activity into Cline.kilo-code-cli— the current@kilocode/cli(npm package,
binarykilo), a fork of sst/opencode. The all-new IDE extension
is rebuilt on this CLI runtime. SQLite store at
~/.local/share/kilo/kilo.db— same path on Linux, macOS, AND
Windows (Kilo intentionally mirrors XDG everywhere; Windows does
NOT use%APPDATA%/%LOCALAPPDATA%here). Schema is OpenCode-shaped
(message/part/todo) plus Kilo-specific tables (project,
workspace,event,session_message,account,permission,
session_share). The newkilocode.CLIAdapteris a structural
transposition ofinternal/adapter/opencode/, including the
stageMirrorIfForeigncross-mount pattern (SQLite returns
SQLITE_IOERR_SHORT_READon a /mnt/c-mounted kilo.db while
Windows is actively writing, so the trio copies into a per-source
cache dir before SQLite opens).
Token capture. Per-assistant-message bundle on message.data.tokens = {total, input, output, reasoning, cache: {read, write}} — mirrors
the OpenCode invariant. Step-finish parts carry per-step token slices
summing to the message-level bundle; the adapter surfaces them as
ToolEvents but NEVER as TokenEvents (would double-count). Step-start
parts are skipped entirely (informational marker; would 12× the
per-turn row count without adding signal).
Pricing. Three new entries cover the Kilo Gateway routing:
kilo-auto/free (zero — Gateway free tier confirmed live),
kilo-auto/small (Haiku 4.5 / GPT-4o-mini class alias for the
title-generation slot), and a kilo-auto family prefix (Sonnet 4
family rates for future paid tiers). Direct provider models
(anthropic/claude-…, openai/…) inherit family-prefix fallback
from existing pricing entries.
Live capture confirmed 2026-06-06 on both WSL Ubuntu 24.04 and
Windows 11 — Kilo CLI @kilocode/plugin@7.3.40, 18 SQLite migrations
applied. Tools exercised: read, write, bash, websearch. See
docs/plans/kilocode-adapter-plan-2026-06-06.md (Phase-0 reality
check) and testdata/kilocode/ (reference dumps of both captures).
enabled_adapters default list grows from 15 to 17 with
"kilo-code" and "kilo-code-cli". Existing users with an explicit
enabled_adapters list in ~/.observer/config.toml must add both
strings to capture Kilo activity.
Added — Hermes Agent adapter (Nous Research)
Captures session data from Nous Research's Hermes
Agent — the open-source
multi-platform autonomous AI agent with 70+ built-in tools, MCP
client + server, and 18+ LLM providers. Distinct from the Hermes LLM
family (Hermes 3, 4) — this is the agent runtime.
Capture strategy is hooks-primary + SQLite backfill (same hybrid
model the cursor adapter uses):
- The Python plugin bridge at
~/.hermes/plugins/superbased-observer/
registers callbacks viactx.register_hook("post_tool_call", …)/
"post_api_request"/"on_session_start"/"on_session_end"/
"subagent_stop"and firesobserver hook hermes <event>as a
fire-and-forget subprocess (0.5s timeout, exceptions swallowed). - The watcher walks
~/.hermes/state.db(or
%LOCALAPPDATA%\hermes\state.dbon Windows native, plus
cross-mount candidates on WSL2) and emits ToolEvents + TokenEvents
viamodernc.org/sqliteread-only access. Filters
messages.active = 1to skip rewound / compressed-out rows
(schema-v14 reality-check finding the original plan missed). - The two paths produce comparable rows; dedup happens via
(source_file, source_event_id)UNIQUE — hook rows carry
"hermes:hook", backfill rows carry the absolute state.db path.
Install: observer init --hermes writes the Python plugin +
merges an mcp_servers.superbased-observer entry into
~/.hermes/config.yaml. Hermes auto-discovers plugins at startup —
no separate enable step. --uninstall removes both surgically.
--dry-run shows the would-be writes. --skip-mcp / --skip-hooks
gate each half independently.
Backfill: observer backfill --hermes-rescan walks every
state.db from messages.id=0 for sessions that pre-date plugin
install (or were captured during an observer outage). Included in
--all.
Tool taxonomy (70+ tools): every Hermes tool folds into the
normalized action set — read_file / write_file / patch /
terminal / search_files / web_search / web_extract /
browser_* / delegate_task / todo / clarify / memory / etc.
The unknown-tool fall-through is mcp_call (Hermes is itself an MCP
host so most user-added tools are MCP-shaped); the raw name is
preserved in actions.raw_tool_name.
Token capture: Tier 2 approximate on both paths. Hook path lifts
post_api_request.usage{input/output/cache/reasoning_tokens} (the
plan originally targeted post_llm_call but the §17.1.F reality
check showed it carries no usage payload at all). SQLite path lifts
session-level aggregates. Provider prefix (anthropic/, nvidia/,
openrouter/anthropic/) is stripped before pricing lookup;
OpenRouter :suffix tails (:free, :beta, :fast) are preserved
so the dashboard distinguishes paid vs free tiers in the same model
family.
Reality-check documentation: the schema-v14 dump captured from a
live install (testdata/hermes/sessions.sql / messages.sql,
9 sessions / 62 messages) backs the SQLite integration tests
(coverage 80.9% on the new package). The §17.1 reality-check section
of docs/hermes-adapter-plan.md documents every delta between the
originally-researched v11 spec and observed v14 reality.
Docs: docs/hermes-adapter.md (operator reference),
docs/hermes-adapter-plan.md (research + reality check),
docs/plans/hermes-adapter-implementation-plan-2026-06-05.md
(per-file build order). 12 conventional commits;
feat(adapter): add ToolHermes constant and EnabledAdapters entry
through feat(observer): backfill --hermes-rescan +
test(adapter): hermes SQLite integration tests +
docs(adapter): hermes adapter user docs + README + CHANGELOG.
Added — Cline-CLI adapter (npm-distributed Cline 3.0.20+)
Captures session data from Cline CLI — the
npm-distributed standalone Cline runtime, distinct from the existing
cline VS Code extension adapter (which now lives at
internal/adapter/cline/; the new CLI adapter at
internal/adapter/clinecli/). Persistence at
~/.cline/data/db/sessions.db (SQLite schema v1, 28 columns read)
plus per-session ~/.cline/data/db/<id>.messages.json content-block
files emitting user_prompt / assistant_text / tool_use /
paired tool_result / per-API-call token rows.
Tool taxonomy. 28 tools — 10 core (read, write, bash, etc.) +
18 team_* coordination primitives (team_create, team_join,
team_message, team_handoff, …). Per-message modelInfo
override handles mid-session provider switching cleanly.
Subagent + team linkage. 5 new ActionMetadata fields —
ParentSessionID, ParentAgentID, AgentID, IsSubagent,
TeamName. Extends Invariant #50's IsZero coverage; no rename of
existing fields.
Token capture. Tier 2 per-API-call from a Phase 0 reality-check
upgrade (the originally researched Tier 1 session-level path was
upgraded after testdata showed per-call rows). Message-level
metrics roll up cleanly to session totals.
V2 cross-mount fix. WSL2 observers reading the Windows-side
/mnt/c/Users/<u>/.cline/data/db/sessions.db over the DrvFs bridge
need the same stageMirror pattern as opencode / kilocode —
copies the db into a per-source cache dir before SQLite opens so
mid-write Windows access doesn't surface SQLITE_IOERR_SHORT_READ.
Fixture tests caught zero of this; live operator end-to-end
surfaced it.
SessionHookChecker dedup gate ships by default so cline-cli
avoids the H1 hermes-audit trap (no WARN entries on the live
4-session install: 1 WSL + 3 Windows-native, 44 actions + 25 token
rows captured zero-loss). Opt-in hooks.jsonl tailer (byte-offset
cursor, partial-line tolerant) covers all 9 hook event types from
plan §6.
Install: ToolClineCLI = "cline-cli" constant + EnabledAdapters
default (15 → 16 prior to kilocode bumping it to 17);
observer backfill --clinecli-rescan (also picked up by --all).
49 sub-tests pass on Windows + WSL2.
Docs: docs/clinecli-adapter.md (operator reference),
docs/plans/cline-cli-adapter-plan-2026-06-06.md (build order +
reality check, including the Phase 0 schema-v1 upgrade),
testdata/clinecli/ (live-install fixtures).
Added — Observer Quest (website arcade expansion)
The public superbased.app/arcade rebrands to Observer Quest —
a 6-world (24-level) NES ...
v1.8.1
Release headline. Hotfix for the v1.8.0 release run: lint cleanup +
fixes the VS Code Marketplace publish that failed with "v1.7.28
already exists" because the VSIX manifest version wasn't being
stamped in lockstep with the release tag. No Go behaviour changes —
the agent + org-server interop story from v1.8.0 stands.
Fixed
- VS Code Marketplace + Open VSX publish now build VSIXes with the
correct release-tag version.scripts/sync-npm-version.shstamps
vscode/package.jsonalongside the six npm packages, and the
vscode-packageCI job invokes it beforevsce package(the
npm-publish stamp runs in parallel, too late for the VSIX build). internal/store/orgpush.go::SelectUnpushedSincecarried a
//nolint:gocycloannotation explaining why the four sequential
per-table loops keep the function long-but-regular.- Four call sites in
internal/db/db.go,internal/orgserver/server.go,
andcmd/observer-org/scrub.gocarry//nolint:gosecannotations
onfmt.SprintfSQL fragments whose table/column args come from
in-package allowlists (gosec G201 is a false positive for those). cmd/observer/org.goenrol-followup if/else chain rewritten as a
switch (gocritic).- Stale
scrubConfigDefaultPathpackage var removed from
cmd/observer-org/scrub.go.
Downloads
Pre-built binaries for each supported platform are attached below. Linux variants bundle antigravity-bridge.exe next to the observer binary for WSL2 users of the Antigravity adapter.
| Platform | Asset |
|---|---|
| Linux x86_64 | observer-v1.8.1-linux-x64.tar.gz |
| Linux arm64 | observer-v1.8.1-linux-arm64.tar.gz |
| macOS x86_64 (Intel) | observer-v1.8.1-darwin-x64.tar.gz |
| macOS arm64 (Apple Silicon) | observer-v1.8.1-darwin-arm64.tar.gz |
| Windows x86_64 | observer-v1.8.1-win32-x64.zip |
Verify with sha256sum -c SHA256SUMS (or shasum -a 256 -c SHA256SUMS on macOS) from the directory containing the downloads.
Also available via npm: npm install -g @superbased/observer@1.8.1
Org server (Docker)
The self-hosted org server ships as a Docker image and as per-platform observer-org-v1.8.1-* archives (attached below).
docker pull ghcr.io/marmutapp/observer-org:v1.8.1The image is keyless-signed with cosign. Verify it:
cosign verify ghcr.io/marmutapp/observer-org:v1.8.1 \
--certificate-identity-regexp 'https://github.com/marmutapp/superbased-observer-private/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comSupply chain
CycloneDX SBOMs are attached: observer.cdx.json and observer-org.cdx.json.
SLSA Level 3 build provenance for the binaries is attached below as a *.intoto.jsonl attestation. The build runs on the private origin repo, so pass that as the source when verifying an extracted binary with slsa-verifier v2.7.0 or newer (older versions fail with unexpected tlog entry type: expected intoto:0.0.2, got dsse:0.0.1):
slsa-verifier verify-artifact ./observer \
--provenance-path *.intoto.jsonl \
--source-uri github.com/marmutapp/superbased-observer-privatev1.8.0
Release headline. Closes the Issues 1+2 privacy leak the
2026-06-02 teams test caught, and ships the operator-experience
surround the same test asked for: a per-node opt-in for full content,
quickstart admin bring-up, dev-auth bypass, observer doctor
org-awareness, and a golden-path CI smoke. The wire shape changes —
all v1.7.x and v1.8.x agents and servers interoperate gracefully (see
"Compat" below).
Privacy posture (Issues 1+2 + the privacy invariant test blind spot)
- The Teams push seam at
internal/store/orgpush.goshipped raw
actions.target(run_command bodies + task_complete prose),
actions.source_file,projects.root_path,projects.git_remote,
andtoken_usage.source_file/project_rootto the org server.
The privacy invariant test had a blind spot — it asserted
target=main.gowas present as proof of populated payload. - v1.8.0 ships sha256-hex hashes (
target_hash,source_file_hash,
project_root_hash,git_remote_hash) on the wire by default; raw
content / path columns are stripped at the seam unless the node
operator opts in via[org_client.share].full_content = truein
their local config. A per-action allowlist
(target_action_allowlist = ["read_file", "edit_file", ...]) ships
raws for safe action types without enabling full content. The org
admin cannot flip these remotely — they live solely in the node's
TOML. - Migration 034 (agent) + migration 003 (server) add the denormalized
hash columns; on-disk rows are backfilled at first boot. observer-org scrub-content --all --confirmpurges already-landed
content from pre-v1.8.0 server DBs, preserving the hash counterparts
so dedup + rollups still function. A startup WARN flags any
remaining leaked content.- The privacy invariant test now sentinels every string column the
seam reads and asserts none leak in metadata-only mode.
Compat
- v1.7.x agent → v1.8.x server: ingest computes hashes from raws
on the fly; rows land with both shapes populated. - v1.8.x agent → v1.7.x server: new hash keys are ignored by the
older schema (additive); the metadata-only payload's empty raw
fields are accepted with no migration drama. SelectUnpushedSincegains two trailing parameters
(ShareOptions,ScopeOptions); call sites updated. Zero values
preserve the safer metadata-only posture.
Push scope (Issue 4)
- The push cursor seeds at the current high-water id at
observer enrolltime (already true since v1.7.x; M2.1 of the remediation
added a regression test). observer org statusnow reports the share mode, the
per-action / project-root allow/denylists in effect, and per-table
historical-vs-eligible row counts.observer org backfill --all --confirmrewinds the cursor to 0 so
the entire local corpus becomes eligible (explicit opt-in;
dry-run by default).observer org previewexposes the existing
/api/enrolment/last-payloadvia the CLI for "exactly what is my
agent shipping" inspection.[org_client.scope]addsproject_root_allowlist/
project_root_denylistso a node can push only specific projects.
Admin setup (Issue 5 + the eleven setup-friction points)
observer-org quickstartorchestrates the whole dev bring-up:
compose up → /healthz wait → SCIM provision admin → dev-auth login
→ mint enrolment token → print Dashboard URL + dev-auth curl + a
ready-to-shareobserver enrolllink.[server].dev_auth = trueexposesPOST /auth/dev/login(a
password-free session-issuing endpoint) for local stack inspection.
Logs a startup WARN and reportsdev_auth:trueon/healthzso
monitoring catches a misconfigured production server.deploy/observer-org/idp-config-override.phppins the dev IdP to
http://localhost:8088/simplesaml/, fixing the entityID-dynamism
trap that produced unreachable redirects + 403 at the ACS
(Issue 5a) and the SSO loop (Issue 5b) on a WSL2 host browser.- New
GET /healthzandGET /readyzprobes.
Node setup (the node-side friction items)
observer enroll --link http(s)://host/enrol/<code>accepts the
magic-link form admins share from quickstart, no manual URL split.- A successful enrol auto-writes a default
[org_client]block
(enabled, push_interval, max_push_bytes, share, scope) into
~/.observer/config.tomlif absent. Idempotent; never re-encodes
the file.--write-block=falseskips for managed-config installs. observer doctornow reports enrolment state, share mode (warns
loudly whenfull_content=true), allow/denylists, and the last
push status.- The OS-keychain-unavailable WARN now fires once per host downgrade
(sentinel-driven), and antigravity decrypt-failure warnings are
collapsed across files so the initial-scan burst onobserver startis bounded.
Robustness
- Root
.gitattributesenforces LF tree-wide (covers Issue 6 — a
Windows checkout no longer breaks the dev-stackkeygen.sh). observer org push-nowreports the cursor + max ids + last push
when there's nothing to push, so the operator can tell why.- New CI workflow
.github/workflows/teams-golden-path.ymlruns an
end-to-end smoke against PRs touching the org code paths or
compose stack: brings up the stack, enrols a synthetic agent,
seeds an action with a raw command body, pushes via metadata-only
mode, and asserts the wire shape (raw withheld, hash shipped, no
grep-detectable leak).
Documentation
docs/teams-getting-started.mdgains a "Local in 5 minutes"
section using quickstart + dev-auth + enroll --link.docs/teams-test-findings-remediation-plan-2026-06-03.mdis the
point-of-record for the remediation arc.
Downloads
Pre-built binaries for each supported platform are attached below. Linux variants bundle antigravity-bridge.exe next to the observer binary for WSL2 users of the Antigravity adapter.
| Platform | Asset |
|---|---|
| Linux x86_64 | observer-v1.8.0-linux-x64.tar.gz |
| Linux arm64 | observer-v1.8.0-linux-arm64.tar.gz |
| macOS x86_64 (Intel) | observer-v1.8.0-darwin-x64.tar.gz |
| macOS arm64 (Apple Silicon) | observer-v1.8.0-darwin-arm64.tar.gz |
| Windows x86_64 | observer-v1.8.0-win32-x64.zip |
Verify with sha256sum -c SHA256SUMS (or shasum -a 256 -c SHA256SUMS on macOS) from the directory containing the downloads.
Also available via npm: npm install -g @superbased/observer@1.8.0
Org server (Docker)
The self-hosted org server ships as a Docker image and as per-platform observer-org-v1.8.0-* archives (attached below).
docker pull ghcr.io/marmutapp/observer-org:v1.8.0The image is keyless-signed with cosign. Verify it:
cosign verify ghcr.io/marmutapp/observer-org:v1.8.0 \
--certificate-identity-regexp 'https://github.com/marmutapp/superbased-observer-private/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comSupply chain
CycloneDX SBOMs are attached: observer.cdx.json and observer-org.cdx.json.
SLSA Level 3 build provenance for the binaries is attached below as a *.intoto.jsonl attestation. The build runs on the private origin repo, so pass that as the source when verifying an extracted binary with slsa-verifier v2.7.0 or newer (older versions fail with unexpected tlog entry type: expected intoto:0.0.2, got dsse:0.0.1):
slsa-verifier verify-artifact ./observer \
--provenance-path *.intoto.jsonl \
--source-uri github.com/marmutapp/superbased-observer-privatev1.7.28
Release headline. VS Code extension Marketplace listing polish.
The v1.7.27 listing rendered with broken wordmark images (relative
paths don't get rewritten for subfolder READMEs on Marketplace) and
led with descriptive copy rather than an actionable quick start.
v1.7.28 fixes both — no Go changes, no breaking changes, just a
better first impression for users hitting the Marketplace page.
Fixed (v1.7.28)
- VS Code extension Marketplace listing showed broken logo images.
Relative<picture>URLs invscode/README.mddon't get
path-rewritten by Marketplace's markdown renderer when the README
lives in a subfolder (vscode/, not the repo root). Fixed by
switching to absoluteraw.githubusercontent.comURLs pointing at
the public repo's main branch.
Changed (v1.7.28)
-
VS Code extension README rewritten as an onboarding-first
Marketplace landing page. Leads with a 5-minute quick start
(numbered steps from install through "your AI session shows up
with accurate token counts"), followed by a surface-by-surface
table that names the exact command or click to reach each surface.
Earlier ordering led with descriptive "what this extension does"
copy that buried the actionable parts. -
scripts/release.shpublic-repo carve-out now includes
docs/vscode-extension.md+docs/vscode-extension-user-guide.md.
These were referenced from the rewritten README's "Going deeper"
section but were previously private-only (the
defaultdocs/*exclusion stripped them from the public repo).
Added to all three sites the script enforces: the
git add --forcere-staging list, the.gitignoreallowlist, and
the docs-leak sanity-check regex.
Compatibility (v1.7.28)
- No code changes. Same observer binary as v1.7.27 (same SHA256,
same behaviour). Pure docs + manifest release. - VS Code extension auto-updates on next launch for users on v1.7.27.
Downloads
Pre-built binaries for each supported platform are attached below. Linux variants bundle antigravity-bridge.exe next to the observer binary for WSL2 users of the Antigravity adapter.
| Platform | Asset |
|---|---|
| Linux x86_64 | observer-v1.7.28-linux-x64.tar.gz |
| Linux arm64 | observer-v1.7.28-linux-arm64.tar.gz |
| macOS x86_64 (Intel) | observer-v1.7.28-darwin-x64.tar.gz |
| macOS arm64 (Apple Silicon) | observer-v1.7.28-darwin-arm64.tar.gz |
| Windows x86_64 | observer-v1.7.28-win32-x64.zip |
Verify with sha256sum -c SHA256SUMS (or shasum -a 256 -c SHA256SUMS on macOS) from the directory containing the downloads.
Also available via npm: npm install -g @superbased/observer@1.7.28
Org server (Docker)
The self-hosted org server ships as a Docker image and as per-platform observer-org-v1.7.28-* archives (attached below).
docker pull ghcr.io/marmutapp/observer-org:v1.7.28The image is keyless-signed with cosign. Verify it:
cosign verify ghcr.io/marmutapp/observer-org:v1.7.28 \
--certificate-identity-regexp 'https://github.com/marmutapp/superbased-observer-private/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comSupply chain
CycloneDX SBOMs are attached: observer.cdx.json and observer-org.cdx.json.
SLSA Level 3 build provenance for the binaries is attached below as a *.intoto.jsonl attestation. The build runs on the private origin repo, so pass that as the source when verifying an extracted binary with slsa-verifier v2.7.0 or newer (older versions fail with unexpected tlog entry type: expected intoto:0.0.2, got dsse:0.0.1):
slsa-verifier verify-artifact ./observer \
--provenance-path *.intoto.jsonl \
--source-uri github.com/marmutapp/superbased-observer-privatev1.7.27
Release headline. SuperBased Observer is now a VS Code extension.
The same observer binary that ships via npm + PyPI now also ships as
superbased.superbased-observer on the VS Code Marketplace and Open VSX,
with 5 platform-tagged VSIXes (linux-x64, linux-arm64, darwin-x64,
darwin-arm64, win32-x64) per release. The extension wraps the existing
CLI + dashboard + proxy + MCP server with a UX shell — status bar with
today's spend, sidebar with Today / Sessions / Discovery / Costs trees,
embedded dashboard webview, file-freshness decorations, budget +
watcher-lag notifications, daemon crash recovery, contributed terminal
profile that pre-exports the proxy env vars, CodeLens on
CLAUDE.md / AGENTS.md / .cursorrules, and a native Get Started
walkthrough. Zero telemetry. All seven plan milestones (M0 → M6) +
the user-walkthrough follow-up (M6.1) shipped in one session.
Added (v1.7.27)
VS Code extension
vscode/— full TypeScript extension undersuperbased.superbased-observer
publisher, version 1.7.27. Bundles the observer binary per platform
via the newvscode-packagematrix CI job +vscode-publishjob in
.github/workflows/npm-release.yml. 118 unit tests (~5.7 s green).- Binary manager with 4-step precedence:
observer.binary.path
setting →$PATH→ bundled in VSIX → download from GitHub Releases
with SHA256 verification. - Three-mode daemon lifecycle (
observer.daemon.mode = detect | managed | auto) with lockfile safety so the extension never
spawns a second daemon over the same database. Crash recovery via
exponential backoff[1 s, 2 s, 5 s]; 4th failure surfaces an
"Open Output Channel" / "Retry" toast. - Today-spend status bar polling
/api/analysis/headline?days=1
every 60 s. Click → open dashboard. - Native sidebar with four
TreeViews: Today (60 s), Sessions
(60 s + onSave), Discovery (5 min), Costs 7d (5 min). - Embedded dashboard webview hosting the React SPA via iframe,
withportMappingso Codespaces / Remote-SSH work without
operator intervention. - File-freshness decorations via the new
/api/file/state
endpoint — small dot in the explorer + Markdown hover with last-
read-by, edits in 24 h, stale re-reads flagged, tools touched.
5-min TTL cache with in-flight dedup. - Budget + watcher-lag notifications with sensible dedup
(budget once/day, watcher-lag once/5 min/file). - Contributed terminal profile "AI Coding Tool (Observer-proxied)"
pre-exportingANTHROPIC_BASE_URL,OPENAI_BASE_URL, and
ENABLE_TOOL_SEARCH=true. - CodeLens on
CLAUDE.md/AGENTS.md/.cursorrules
surfacingRefresh from Observer learningsandPreview suggestions. - Native walkthrough via
contributes.walkthroughs— 7 steps
with completion-event tracking, rendered in VS Code's Get Started
view on first install. - Zero telemetry, zero outbound network calls except first-install
binary download from GitHub Releases. All/api/*traffic to
127.0.0.1.
- Binary manager with 4-step precedence:
Go side
/api/file/state?path=<abs>— new dashboard endpoint
(internal/intelligence/dashboard/file_state.go) returning
{last_read_at, last_read_by, edit_count_24h, stale_rereads_24h, tools_touched[]}for one file. Four single-row queries against the
existingactions+sessionstables; no new schema. Drives the
VS Code extension'sFileDecorationProvider+HoverProvider.
Field name pinned asstale_rereads_24h(not_avoided_24h) —
observer flags stale re-reads viaactions.freshness='stale',
doesn't prevent them.
Release pipeline
vscode-packagematrix CI job (5 targets) +vscode-publish
job added to.github/workflows/npm-release.yml. Both gated on
VSCE_PATpresence with an inlineid: gatestep — no-op
gracefully when secrets are absent so previously-passing releases
stay green. OVSX has an additionalOVSX_PATgate with
continue-on-error: true.
Docs (v1.7.27)
docs/vscode-extension.md— user-facing reference (commands,
settings, surface tour).docs/vscode-extension-user-guide.md— long-form prose user
guide (quick start, daily workflow, per-AI-tool integration for
Claude Code / Cursor / Codex / Cline / Copilot, customisation,
troubleshooting).docs/vscode-extension-tracker.md— implementation tracker for
the M0 → M6 + M6.1 build-out.docs/vscode-marketplace-publish-process.md— canonical
publish runbook with 7 named gotchas (G1 AzDO PAT scope, G2 indexing
lag, G3 OVSX namespace auto-create, G4 Eclipse Publisher Agreement,
G5 no-republish-same-version, G6 VSIX secret leakage, G7
multi-target). Pairs withdocs/pypi-release-process.md.docs/release-runbook.mdupdated: pipeline diagram includes
vscode-package + vscode-publish jobs; output enumeration lists the
5 Marketplace + 5 OVSX VSIXes alongside npm + PyPI; new
Marketplace + OVSX section withVSCE_PAT+OVSX_PATsetup..env.exampleat repo root +vscode/.vscodeignorebelt-and-
braces.envexclusion so secrets never ride into a VSIX.
Compatibility (v1.7.27)
- No breaking changes. CLI surface unchanged; existing npm + PyPI
installs continue working identically. The new
/api/file/stateendpoint is additive — pre-1.7.27 dashboard
consumers don't notice it. The VS Code extension is a new
distribution channel, not a replacement. - Marketplace listing for v1.7.27 ships with the real SuperBased
brand icon (replacing the placeholder used for the v1.7.26
linux-x64 smoke publish), all 5 platforms instead of just linux-x64,
and the new walkthrough.
Downloads
Pre-built binaries for each supported platform are attached below. Linux variants bundle antigravity-bridge.exe next to the observer binary for WSL2 users of the Antigravity adapter.
| Platform | Asset |
|---|---|
| Linux x86_64 | observer-v1.7.27-linux-x64.tar.gz |
| Linux arm64 | observer-v1.7.27-linux-arm64.tar.gz |
| macOS x86_64 (Intel) | observer-v1.7.27-darwin-x64.tar.gz |
| macOS arm64 (Apple Silicon) | observer-v1.7.27-darwin-arm64.tar.gz |
| Windows x86_64 | observer-v1.7.27-win32-x64.zip |
Verify with sha256sum -c SHA256SUMS (or shasum -a 256 -c SHA256SUMS on macOS) from the directory containing the downloads.
Also available via npm: npm install -g @superbased/observer@1.7.27
Org server (Docker)
The self-hosted org server ships as a Docker image and as per-platform observer-org-v1.7.27-* archives (attached below).
docker pull ghcr.io/marmutapp/observer-org:v1.7.27The image is keyless-signed with cosign. Verify it:
cosign verify ghcr.io/marmutapp/observer-org:v1.7.27 \
--certificate-identity-regexp 'https://github.com/marmutapp/superbased-observer-private/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comSupply chain
CycloneDX SBOMs are attached: observer.cdx.json and observer-org.cdx.json.
SLSA Level 3 build provenance for the binaries is attached below as a *.intoto.jsonl attestation. The build runs on the private origin repo, so pass that as the source when verifying an extracted binary with slsa-verifier v2.7.0 or newer (older versions fail with unexpected tlog entry type: expected intoto:0.0.2, got dsse:0.0.1):
slsa-verifier verify-artifact ./observer \
--provenance-path *.intoto.jsonl \
--source-uri github.com/marmutapp/superbased-observer-privatev1.7.26
Release headline. Hotfix for v1.7.25: the PyPI wheels
uploaded in v1.7.25 were 24 KB and did NOT contain the observer
binary. Root cause: hatchling's default file-collection respects
.gitignore, and pypi/observer/.gitignore listed
src/observer/_bin/observer (intentionally — to keep staged
binaries out of git). The interaction silently dropped the
binary from the wheel. v1.7.25 has been yanked from PyPI.
Fixed (v1.7.26)
pypi/observer/pyproject.toml— explicitly excludes
src/observer/_binfrom the[tool.hatch.build.targets.wheel] packagesglob and pulls the binary back in via
[tool.hatch.build.targets.wheel.force-include], which
bypasses gitignore filtering. Wheels now contain the binary
again (~21 MB compressed, was 24 KB).- CI guard in
publish-to-pypi: after retagging each wheel,
unzip-inspect to verify_bin/observer{,.exe}is present and1 MB. Fails the workflow loudly instead of shipping empty
wheels.
Compatibility (v1.7.26)
- No behavior changes for npm users (npm v1.7.25 was fully
functional; the bug was PyPI-only). - PyPI users on v1.7.25 should upgrade to v1.7.26:
pip install --upgrade superbased-observer.
Downloads
Pre-built binaries for each supported platform are attached below. Linux variants bundle antigravity-bridge.exe next to the observer binary for WSL2 users of the Antigravity adapter.
| Platform | Asset |
|---|---|
| Linux x86_64 | observer-v1.7.26-linux-x64.tar.gz |
| Linux arm64 | observer-v1.7.26-linux-arm64.tar.gz |
| macOS x86_64 (Intel) | observer-v1.7.26-darwin-x64.tar.gz |
| macOS arm64 (Apple Silicon) | observer-v1.7.26-darwin-arm64.tar.gz |
| Windows x86_64 | observer-v1.7.26-win32-x64.zip |
Verify with sha256sum -c SHA256SUMS (or shasum -a 256 -c SHA256SUMS on macOS) from the directory containing the downloads.
Also available via npm: npm install -g @superbased/observer@1.7.26
Org server (Docker)
The self-hosted org server ships as a Docker image and as per-platform observer-org-v1.7.26-* archives (attached below).
docker pull ghcr.io/marmutapp/observer-org:v1.7.26The image is keyless-signed with cosign. Verify it:
cosign verify ghcr.io/marmutapp/observer-org:v1.7.26 \
--certificate-identity-regexp 'https://github.com/marmutapp/superbased-observer-private/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comSupply chain
CycloneDX SBOMs are attached: observer.cdx.json and observer-org.cdx.json.
SLSA Level 3 build provenance for the binaries is attached below as a *.intoto.jsonl attestation. The build runs on the private origin repo, so pass that as the source when verifying an extracted binary with slsa-verifier v2.7.0 or newer (older versions fail with unexpected tlog entry type: expected intoto:0.0.2, got dsse:0.0.1):
slsa-verifier verify-artifact ./observer \
--provenance-path *.intoto.jsonl \
--source-uri github.com/marmutapp/superbased-observer-privatev1.7.25
Release headline. PyPI distribution alongside npm:
pip install superbased-observer (or uv tool install /
pipx install) now installs the same prebuilt observer binary
shipped on npm. Five platform-tagged wheels per release —
manylinux2014_{x86_64,aarch64}, macosx_*_{x86_64,arm64},
win_amd64 — published from the same v* tag-push that drives
the npm release. Versions are kept in lock-step.
Added (v1.7.25)
pypi/observer/package source layout with hatchling-based
build (pyproject.toml), thin Python launcher
(observer/__main__.py) thatos.execvs the bundled binary,
and a per-platform wheel build flow mirroring the npm matrix.publish-to-pypijob in.github/workflows/npm-release.yml:
builds the 5 wheels and uploads viaPYPI_TOKEN_OBSERVER+
pypa/gh-action-pypi-publish. Runs in parallel with the npm
publishjob; gated to the private repo same as the rest.pypi/observer/README.mdlong-description rendered on PyPI
(mirrors npm README with pip-flavored install + troubleshooting
sections).- Root
README.mdinstall section gains a pip / uv / pipx
sub-section alongside the existing npm sub-section. - npm
README.mdadds a one-line cross-reference to the PyPI
package so users see both options. docs/pypi-package-plan-2026-06-02.mdcaptures the full design
doc (per-platform wheels vs sdist tradeoff, wheel-build
mechanics, workflow integration, risks).
Compatibility (v1.7.25)
- No schema migrations, no API changes, no behavior changes for
existing users. pip installandnpm install -gproduce byte-identical
observerbinaries — the wheel + tarball pull from the same
CI artifact.
Downloads
Pre-built binaries for each supported platform are attached below. Linux variants bundle antigravity-bridge.exe next to the observer binary for WSL2 users of the Antigravity adapter.
| Platform | Asset |
|---|---|
| Linux x86_64 | observer-v1.7.25-linux-x64.tar.gz |
| Linux arm64 | observer-v1.7.25-linux-arm64.tar.gz |
| macOS x86_64 (Intel) | observer-v1.7.25-darwin-x64.tar.gz |
| macOS arm64 (Apple Silicon) | observer-v1.7.25-darwin-arm64.tar.gz |
| Windows x86_64 | observer-v1.7.25-win32-x64.zip |
Verify with sha256sum -c SHA256SUMS (or shasum -a 256 -c SHA256SUMS on macOS) from the directory containing the downloads.
Also available via npm: npm install -g @superbased/observer@1.7.25
Org server (Docker)
The self-hosted org server ships as a Docker image and as per-platform observer-org-v1.7.25-* archives (attached below).
docker pull ghcr.io/marmutapp/observer-org:v1.7.25The image is keyless-signed with cosign. Verify it:
cosign verify ghcr.io/marmutapp/observer-org:v1.7.25 \
--certificate-identity-regexp 'https://github.com/marmutapp/superbased-observer-private/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comSupply chain
CycloneDX SBOMs are attached: observer.cdx.json and observer-org.cdx.json.
SLSA Level 3 build provenance for the binaries is attached below as a *.intoto.jsonl attestation. The build runs on the private origin repo, so pass that as the source when verifying an extracted binary with slsa-verifier v2.7.0 or newer (older versions fail with unexpected tlog entry type: expected intoto:0.0.2, got dsse:0.0.1):
slsa-verifier verify-artifact ./observer \
--provenance-path *.intoto.jsonl \
--source-uri github.com/marmutapp/superbased-observer-privatev1.7.24
Release headline. Codex per-event token rows: each
token_count event in a codex rollout now lands as its own
token_usage row, with a new turn_id column grouping them
back to the user-turn. The dashboard's Session Detail panel
adds a Turn / Inference toggle on codex sessions so operators
can drill from the per-turn rollup (default, preserves existing
UX) into per-inference billing detail. Plus: canonical
PRIVACY.md, recipe-naming clarity sweep (codex-variant =
OpenAI's -codex reasoning fork; codex-safe = plain GPT
under codex CLI; both are recipes for the codex CLI), and a
one-shot backfill migration (033) for legacy codex rows whose
ON CONFLICT preserved the pre-v1.7.24 message_id = TurnID
shape.
Schema (v1.7.24)
- Migration 032 —
token_usageaddsturn_id TEXTcolumnidx_token_usage_session_turnindex. NULL on existing
rows; dashboard'sCOALESCE(turn_id, message_id, source_event_id)
fallback keeps them rendering correctly without a backfill.
- Migration 033 — one-shot backfill of legacy codex rows:
moves the oldmessage_id(which IS the TurnID) into
turn_id, replacesmessage_idwithsource_event_id.
Idempotent. Non-codex rows untouched.
Added (v1.7.24)
?detail=inferencequery parameter on
/api/session/<id>/messages; default behavior unchanged.- Frontend Turn / Inference SegmentedControl in the Session
Detail panel's Messages section (visible only on codex
sessions — Anthropic adapters already emit one row per
upstreammsg_xxx, the toggle would be a no-op there). PRIVACY.mdcanonical privacy doc at repo root.
Changed (v1.7.24)
- Codex adapter MessageID semantic shifts from per-turn
to per-model-inference:MessageID = "tk:<file>:L<n>"
(the per-event identifier) instead of the oldTurnID.
TurnID = turnIDis now stored separately on the
TokenEventstruct and persisted to the new column.
This aligns codex with claudecode's "MessageID = upstream
API-call identifier" contract. - Recipe TOML headers rewritten to lead with model-family
decisions: explicit USE-WHEN / DO-NOT-USE blocks with
example model IDs + a Naming clarification paragraph for
the codex-* recipes. Same clarity in README and npm
README compression tables. - README + npm README updated with stronger privacy
paragraph + PRIVACY.md link. npm README adds a "Measured
savings" sub-section under Compression with v1.7.23
empirical numbers and honest caveats.
Fixed (v1.7.24)
- Stale "
codecompressor is opt-in only" comment in npm
README (claude-code recipe has hadcodein defaults
since v1.7.23 / V7-24). - Legacy codex rows whose
message_idwas preserved as
pre-v1.7.24 TurnID-UUID after the v1.7.24 adapter
re-emitted under ON CONFLICT (migration 033).
Downloads
Pre-built binaries for each supported platform are attached below. Linux variants bundle antigravity-bridge.exe next to the observer binary for WSL2 users of the Antigravity adapter.
| Platform | Asset |
|---|---|
| Linux x86_64 | observer-v1.7.24-linux-x64.tar.gz |
| Linux arm64 | observer-v1.7.24-linux-arm64.tar.gz |
| macOS x86_64 (Intel) | observer-v1.7.24-darwin-x64.tar.gz |
| macOS arm64 (Apple Silicon) | observer-v1.7.24-darwin-arm64.tar.gz |
| Windows x86_64 | observer-v1.7.24-win32-x64.zip |
Verify with sha256sum -c SHA256SUMS (or shasum -a 256 -c SHA256SUMS on macOS) from the directory containing the downloads.
Also available via npm: npm install -g @superbased/observer@1.7.24
Org server (Docker)
The self-hosted org server ships as a Docker image and as per-platform observer-org-v1.7.24-* archives (attached below).
docker pull ghcr.io/marmutapp/observer-org:v1.7.24The image is keyless-signed with cosign. Verify it:
cosign verify ghcr.io/marmutapp/observer-org:v1.7.24 \
--certificate-identity-regexp 'https://github.com/marmutapp/superbased-observer-private/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comSupply chain
CycloneDX SBOMs are attached: observer.cdx.json and observer-org.cdx.json.
SLSA Level 3 build provenance for the binaries is attached below as a *.intoto.jsonl attestation. The build runs on the private origin repo, so pass that as the source when verifying an extracted binary with slsa-verifier v2.7.0 or newer (older versions fail with unexpected tlog entry type: expected intoto:0.0.2, got dsse:0.0.1):
slsa-verifier verify-artifact ./observer \
--provenance-path *.intoto.jsonl \
--source-uri github.com/marmutapp/superbased-observer-privatev1.7.23
Release-arc summary (v1.7.6 → v1.7.23). 18 versions consolidated
into a single release covering the V7-1 through V7-26 work-stream:
new MCP knowledge tools (get_file/get_symbols/get_relations/
retrieve_stashed batch + codegraph BFS), Windows Job Object for
observer codex, the V7-19 critical buildAllow([]) nil-trap fix
(inverted the codex-variant recipe in v1.7.6-v1.7.18), the V7-21
tools-defs gate, the V7-22 → V7-24 compression measurement arc that
ended with restoring compress_types=["json","logs","code"] as the
claude-code default after n=8 A/B (−6.9% mean cost vs OFF), the
V7-25 stash-vs-Anthropic-cache finding (stash stays disabled by
default), and the V7-26 codex baseline (inconclusive on gpt-5.4;
codex-safe recipe unchanged). Operators MUST set
ENABLE_TOOL_SEARCH=true in the launching shell when using Claude
Code with observer's proxy — without it, Claude Code's SDK eager-
inlines MCP schemas under ANTHROPIC_BASE_URL and the proxy becomes
a net loss. Full empirical writeup in
docs/v1.7.23-compression-savings-empirical-2026-06-01.md.
Headline (v1.7.23): Re-measured the v1.7.22 catastrophic regression
on the V7-22 binary and found it gone. V7-22's preceding fixes
(V7-19 nil-trap + V7-21 tools-defs gate) closed enough of the
re-marshal pathway that per-type compression no longer cascades on
the V7-22+ binary. n=8 Claude Code B-arm with per-arm prompt salts on
V7-22 binary 0a2b7900...: −6.9% mean cost vs n=4 OFF baseline
($1.069 vs $1.148), CV 7.6% (tighter than OFF's 7.5%), zero tail
outliers (max cost $1.168, max turns 18). The claude-code recipe
default compress_types is restored to ["json","logs","code"] —
the empirical winner. Operators MUST set ENABLE_TOOL_SEARCH=true
in the launching shell when using this recipe; without it Claude
Code's SDK eager-inlines MCP schemas under ANTHROPIC_BASE_URL
(~+21K tokens/turn), turning the proxy into a net loss. Plus: stash
is documented as cache-breaking on Anthropic traffic (V7-24: n=1
showed +25% cost / +97% cache_creation) and stays disabled by
default. Full empirical writeup:
docs/v1.7.23-compression-savings-empirical-2026-06-01.md.
Fixed (v1.7.23)
- Default
CompressTypesrestored to["json","logs","code"]
(internal/config/config.go:703). V7-22's defensive[]flip was
based on n=4 on V7-21 binary; V7-24 n=8 on V7-22 binary shows the
cascade is gone. The compressor implementations were already kept
in place; this just re-enables them in the default allow-set. claude-code.tomlrecipe →compress_types = ["json","logs","code"]
in bothdocs/recipes/andinternal/config/recipes/(mirrored
to satisfyTestRecipes_InternalAndDocsAreIdentical). Inline
comments capture V7-23's empirical baseline and theENABLE_TOOL_SEARCH
operator requirement.claude-code.tomlrecipe — stash documented as DO NOT ENABLE
on Anthropic traffic (V7-24). Stash's content-replacement breaks
Anthropic's prefix cache, costing more than the bytes-on-wire
savings. Disabled by default; operators can opt in for measured
workloads but shouldn't expect savings.
Updated tests (v1.7.23)
internal/config/config_test.go::TestDefaultCompressTypesIsEmpty
renamed toTestDefaultCompressTypesIsJSONLogsCode; assertion
flips fromlen(got) == 0back to{"json","logs","code"}.
Comment captures the V7-24 n=8 measurement and the historical
default lineage.internal/config/recipes_test.go::TestLoadRecipe_ClaudeCode
assertion flips fromlen == 0to["json","logs","code"]plus
a new check thatStash.Enabledis false. Comment captures the
V7-24 rationale.
Backwards compatibility (v1.7.23)
- Anyone using no explicit
[compression.conversation]block sees
the default flip from[](v1.7.22) back to["json","logs","code"].
This is the same default value as pre-v1.7.22 — operators who
were on v1.4.40-v1.7.21 see no semantic change relative to that
era; operators who were on v1.7.22 see compression re-enabled.
Per the V7-24 measurement, this is empirically a net win on
Claude Code traffic; codex and other OpenAI traffic see the same
default but the fast-path early-return makes it a no-op when no
event fires. - The
claude-coderecipe behavior reverts to the v1.4.40+
semantic — per-type compression on. Other knobs unchanged. - The
codex-variantrecipe is unchanged — still[]. The V7-21
$0.270 measurement holds; codex operators see no behavior change. - The
codex-saferecipe is unchanged — still["logs"]. - Operators who want v1.7.22 passthrough behavior opt out by
settingcompress_types = []in their config or recipe override.
Operator note (v1.7.23)
Set ENABLE_TOOL_SEARCH=true in your shell when using Claude Code
with observer's proxy. Claude Code's SDK disables its
ToolSearch:optimistic deferred-MCP-loading feature under
ANTHROPIC_BASE_URL. Without the override, all MCP tool schemas
(observer's 17 + any Google Auth/Drive/Calendar/Gmail) are eager-
inlined into every request — ~+21K tokens per turn on the reference
rig. Observer's proxy forwards tool_reference blocks byte-identically,
which satisfies the SDK's documented safety condition for the override
(strings ~/.local/share/claude/versions/*/claude | grep ENABLE_TOOL_SEARCH).
For operators wanting to verify: the cost-check.sh script in
docs/skills/observer-cost-tuning/scripts/ reads observer's
/api/cost endpoint and shows real per-tool $/turn from your
actual sessions.
v1.7.22 (superseded by v1.7.23)
Headline (v1.7.22): The first real Claude Code A/B against the
proxy (n=4 OFF + n=4 B-arm via observer on :8831 running the V7-21
binary with the claude-code recipe compress_types = ["json","logs","code"], mode = cache_aware) measured a +60% cost
regression and +88% turn-count regression vs no-proxy Claude Code.
The model was doing nearly 2× the work to complete the same refactor
task. Root cause is the same shape as V7-19: every per-type
compression event bypasses the fast-path early-return in
runAnthropic and triggers serializeAnthropic re-marshal. The
marshalEnvelope helper sorts top-level keys alphabetically + escapes
HTML off, producing a byte-different shape than Claude Code's native
ordering. Anthropic's prefix cache (which keys on the first ~N bytes)
misses; cache_creation doubles; the model loses visibility into
prior content and re-derives → V7-11 cascade. v1.7.22 flips the
default compress_types from ["json","logs","code"] to [] and
mirrors the change in the claude-code recipe. Per-type compression
becomes opt-in everywhere — operators who want it (e.g. cache-cold
short sessions where logs/code byte savings outweigh the re-marshal
tax) opt in explicitly. The codex-variant recipe (which V7-21 made a
small net win vs OFF at $0.270 codex / $0.30 OFF) and the codex-safe
recipe (still ["logs"] — explicit operator opt-in) are untouched.
Plan + BC analysis:
docs/v1.7.22-claude-code-passthrough-plan-2026-06-01.md.
Fixed (v1.7.22)
- Default
CompressTypesflips to[]
(internal/config/config.go:703). The 2026-06-01 Claude Code A/B
showed["json","logs","code"]triggered the V7-11 re-derivation
cascade because every per-type compression event re-marshals the
envelope throughmarshalEnvelope(alphabetical key order),
producing a byte-shape Anthropic's prefix cache won't hit. Empty
default → fast-path early-return on every turn → byte-identical
forwarding → cache hits hold. The compressor implementations
(compressToolResults,LogsCompressor,CodeCompressor,
JSONCompressor, etc.) are kept; they just don't fire by default. claude-code.tomlrecipe →compress_types = []in both
docs/recipes/andinternal/config/recipes/(mirrored to satisfy
TestRecipes_InternalAndDocsAreIdentical). Inline comments capture
the V7-22 measurement + opt-in path.
Updated tests (v1.7.22)
internal/config/config_test.go::TestDefaultCompressTypesIncludesCode
renamed toTestDefaultCompressTypesIsEmpty; assertion flips from
{json,logs,code}tolen(got) == 0. Comment captures the V7-22
finding (+60% cost / +88% turns under prior default) and the
historical default lineage (["json","logs"]→["json","logs","code"]
in v1.4.40 →[]in v1.7.22).internal/config/recipes_test.go::TestLoadRecipe_ClaudeCode
assertion flips from["json","logs","code"]tolen == 0. Comment
captures the V7-22 rationale + opt-in path.
Backwards compatibility (v1.7.22)
- Anyone using no explicit
[compression.conversation]block sees
the default flip from["json","logs","code"]to[]. For Anthropic
traffic this is unambiguously a win (the A/B measurement was −60%
cost). For OpenAI traffic the codex-variant + codex-safe operators
already had explicit configs so no change; operators with no config
hitting OpenAI would also see the change but their behavior was
governed by the same fast-path/slow-path split as Anthropic, so the
outcome there is also expected to be neutral-to-positive. - The
claude-coderecipe behavior changes from per-type-on to
per-type-off. The recipe's other knobs (mode = cache_aware,
target_ratio = 0.85,preserve_last_n = 5) are unchanged. - The
codex-variantrecipe is unchanged — still[]. Codex
operators see no behavior change from V7-21's $0.270 cost mean. - The
codex-saferecipe is unchanged — still["logs"]. That's
an explicit opt-in to logs compression and respects operator intent.
If real-world codex-safe usage hits the same re-marshal regression
it can be addressed in a future release. - Operators who want pre-v1.7.22 per-type behavior opt in by
settingcompress_types = ["json","logs","code"](or any subset)
in their config or recipe override.
Documentation (v1.7.22)
- New:
docs/skills/observer-cost-tuning/— a Clau...