Added
- feat(update): Enterprise Update Management - fleet self-update served by
your own org server. A node never contacts GitHub, npm or a CDN for an
update; it fetches only from the org server it is enrolled with. That
server's mirror is filled by
observer-org update import(air-gapped sites) orobserver-org update sync(connected ones), which is what makes air-gap the default path rather than a special case. Three channels (stable/lts/edge) are a property of the MANIFEST, never of the binary, and the node side isobserver update status|check|apply|history. Operator reference:docs/enterprise-updates.md. - feat(update): two-signature update manifests and a compiled-in vendor key. Every manifest carries the org's Ed25519 TOFU-pinned distribution signature AND a per-artifact vendor signature over the archive bytes, verified against a key compiled into the agent, so a compromised org server alone cannot substitute a binary we did not build. An artifact with no vendor signature is refused - fail closed. The release pipeline now signs every artifact and publishes a signed release manifest plus an air-gap bundle; cosign-bundle and minisign were deleted from the signature vocabulary because neither ever had a verifier.
- feat(update): drain-gated apply with a fork-exec-and-watch handshake.
Applying an update is never an execve replace. The old daemon drains
in-flight proxied requests (
503plusRetry-Afterthrough the newinternal/quiesce, never a connection refusal), swaps the binary atomically, spawns the new one as a child, and - if the child fails its self-check, exits non-zero, or hangs - the still-alive parent kills it and restores the previous binary, along with a pre-applyVACUUM INTOsnapshot when the target advanced the schema. Supervisor templates for systemd, launchd and Windows ship underdeploy/supervisor/for the residual window after the old parent exits. - feat(org,update): staged rollout rings, a fleet version board and a skew
gate. Manifests roll out through a pure ring engine (
rolloutcore, extracted from the policy-rollout cohort code) keyed on each node's own subject.[server].min_agent_versionandmin_agent_version_action(warn by default, a typed426 agent_too_oldwhen set to refuse) plusmax_skew_minorsfeedGET /api/org/fleet/versionswith a version histogram, a skew banner and a stranding-by-install-method panel. The newobserver-org upgrade preflightturns the server's own pre-upgrade checklist (backup, migration dry run, disk headroom, skew report, config validation) into one gate-able exit code, and the VS Code extension will never launch its bundled binary over a strictly newer installed one. - feat(org,pricing): enterprise per-model pricing.
org_model_prices(server migration 132, effective-dated, USD only) becomes the ONE authored price table, and the two places that already priced a turn become projections of it: the AI gateway's rate card, projected through one seam (the old rate-card PUT answers409 moved_to_pricing), and a signed fleet-wideGET /api/agent/pricingrail that each node persists locally (agent migration 106) and feeds into a single process-wide cost engine, so captured turns are stamped at the org's negotiated rate. Reads needread:budgets; writes use the new 18th RBAC keywrite:pricing. Since migration 135 every rate column is nullable: NULL means not quoted and falls through, a set 0 means the org negotiated that rate free. Operator reference:docs/pricing.md. - feat(org,assistant): an org admin assistant that can author the
organization's administration under approval. A closed table of 57 tools
generates the tool specs, the labels, the system contract and the gate, and
three enforcement points make a proposal safe: the chatting member is
authorized before dispatch (a miss writes no proposal row at all), the
parked proposal is inert with a server-computed preview, and approval
re-checks the APPROVER against the same table, re-previews (a changed plan
goes stale, an uncomputable one invalid) and executes the resolved plan
under the approver. Bulk operations are ordinary table rows capped at 200
items, with invites itemized because mail cannot be un-sent. Ships with an
Approvals inbox, a sidebar badge, nine status pills and an opt-in
[dashboard].approval_emailnotification. Operator reference:docs/assistant.md. - feat(org,budgets): team and developer spend budgets with real
enforcement. One authored
budgetstable (server migration 125) carriescap_tokensbesidemonthly_usd_cap, anenforcementcolumn (report / soft / hard) and calendar periods with a timezone. Two real chokepoints act on it: the existing alert evaluator, and the AI gateway's reservation ledger, which now PROJECTS its cap frombudgetsinstead of being separately authored. A third, opt-in node-side chokepoint composes the org's cap onto the node's existing guard engine through a signed per-callerGET /api/agent/budgetpull - lowering-only on an individual node, org-authoritative on a managed node holding theenforce.budgetauthority. Dashboard team CRUD makes a "team budget" addressable without an IdP. An org that would rather not show dollars can render every figure on the org dashboard as tokens, or as a percentage of the relevant cap, through one formatter seam - never per-surface division - and token counts now ride beside cost on every payload that carried cost alone. Operator reference:docs/budgets.md. - feat(org,budgets): an honest per-developer coverage column. A budget
nothing can enforce must never render as "under budget". Nodes now
self-report an enum-only budget posture that ingest lands in
org_node_budget_posture(server migration 130) and the rollup turns into table-driven coverage reasons on the Budgets page, so an unenforceable scope or a developer who does not route through the gateway is visibly uncovered rather than silently green. The gateway also buckets each cap's window in the cap's own timezone (migration 131), retiring the gateway-buckets-in-UTC warning. - feat(org): three sign-in rails behind one seam - local, SAML and OIDC.
The new OIDC rail does authorization-code plus PKCE with JWKS rotation and
presets for Entra, Okta, Google and a generic provider; SAML now boots
non-fatally against an unreachable IdP instead of aborting startup; and the
local email-and-password rail (argon2id) is unconditionally mounted as the
break-glass path when an IdP is down. Identity is configured from the
dashboard (Settings, Identity) and the setup wizard, seeded once from TOML
and dashboard-owned thereafter, with
observer-org auth show/auth reset-bootstrapas the CLI escape. - feat(org): IdP group to role mapping, gated JIT provisioning and member
approval. Group-to-role mapping is an admin-editable ordered rule set
applied at every sign-in, with a last-admin guard and an explicit
dashboard-versus-IdP precedence. More importantly, an unknown email on an
SSO rail no longer becomes an active member by default: it auto-activates
only via an email-domain allow-list (empty by default) or a matching group
rule, and otherwise lands
pendingawaiting an explicit approval. Sessions are generation- and epoch-aware for every rail, so a single member or the whole org can be signed out (POST /api/org/members/{id}/revoke-sessionsandPOST /api/org/auth/revoke-all-sessions); every sign-in, failure, lockout, revocation and settings change is audited BEFORE the session issues; andadmin:identityis the 16th RBAC permission key, held only by the builtin admin role. - feat(org,loc): lines-of-code tracking. Per-session and per-developer
AI-versus-human-versus-system CODE line counts, with comments, blanks and
whitespace split out, produced by a pure classifier over already-scrubbed
tool input (agent migration 103, node-local). Human capture is VS Code-only
in v1 and
human_capture="none"means unmeasured, never zero - no surface renders an AI share on it.observer backfill --locre-counts history; the org wire ships aggregate counts by default and gates only the per-language mix behind the raw-content posture. Operator reference:docs/loc-tracking.md. - feat(org): Project Identity Resolver v2. N differently-named local
folders across N developers now fold onto one project with zero developer
action: the node resolves a set of identity hashes at capture (agent
migration 102), they ride on the session wire (server migration 121), and a
pure table-driven rule engine (server migration 122) materializes projects
through a single writer at ingest. Ships with
observer-org resolve-projects, admin surfaces on Projects and Project Detail, and a Settings, Identity panel for the rule table. - feat(telemetrylog): a shared durable log in front of both org ingest
paths. Node push and OTLP gateway requests each publish one record to a
durable log and are acked only after the log's PubAck - a log fault answers
503plusRetry-After, never a lying200. The log contract is pure (internal/telemetrylog) with a NATS/JetStream adapter that can run embedded in-process or against an external cluster, a[log]config block with redaction, anobserver-org doctorprobe, and a conformance suite. Three durable consumers drain it, and records that cannot be applied land in a quarantine table with one writer and its own alerting. - feat(orgserver): typed Parquet on object storage as the durable system of
record, with offline replay. Accepted telemetry is written as typed
Parquet to local, S3-compatible or Azure Blob storage, which is also the
update mirror; legacy JSONL replay remains supported. Recovery inventories
and validates the whole archive first, then applies one generation's
sequence order in bounded pages, and transactional receipts (SQLite
migration 137 / PostgreSQL 0003) stop a stale occurrence committing its
derived rows twice. Object-store credentials resolve by identity (S3
default chain, Azure SAS) rather than long-lived keys. Alongside this,
observer-org serve --role all|collector|worker|api|aigateway(or[server].roles) splits the server into independently scalable tiers behind a load balancer, with advisory-lock singletons for the jobs that must run once and/healthzreporting the roles and the log probe. - feat(aigateway): AI Gateway v1. An optional org-side gateway with virtual keys, atomic budget reservation and settlement, streaming support and metadata-only audit, plus Bedrock and Vertex providers, a standalone gateway binary, a capacity envelope and a live disallow gate.
- feat(node): direct-vendor budget enforcement on managed nodes. A managed node whose developer talks straight to a vendor - no gateway, no proxy - is now inside the budget too: the node watches its own captured spend against the org's cap and, past the cap, stops the offending agent processes and refuses new launches, with a policy-bound process cutoff and a three-class accounting readiness model so an unpriced model is FLAGGED, never silently denied.
- feat(cloud): Cloud Intelligence - a signed-in personal plane (BETA).
An entirely opt-in, manual-first lane in which a developer can send one
session's evidence to a hosted service and get an AI-written summary back.
Signed-in Free allows up to 20 session enrichments per day and 100 per
month on GPT-5.6 Luna (xhigh reasoning). Plus is beta and experimental,
USD 15 per month with a 7-day trial: enrichments run on the substantially
stronger GPT-5.6 Sol (xhigh reasoning), capped at 120 per month (25 per
day), and add weekly project digests. Results now read as narrative
sections - what was done, plans implemented, issues found, failures, and
what to do next - and never expose internal evidence ids. The node half is
zero-egress by construction: the
observer cloudCLI is the only outbound trigger, preview bytes are the upload bytes, and nothing leaves a machine that a consent screen did not already name. Operator reference:docs/cloud-intelligence.md. - feat(cloud): consent, results and background enrichment where developers already look. One plain consent card in Settings replaces the purpose vocabulary (which moves to an Advanced fold), a "What we sent" ledger shows every upload content-free, and session cards gained Enrich now, Sync now and a preview-first flow. With the policy on, a daemon-side sweep enriches finished sessions in the background on a 15-minute default. AI-written session titles and descriptions surface on the Sessions list, the session header and the VS Code tree, with inline editing and a user-over-AI precedence.
- feat(orgserver): org-served Cloud Intelligence. An enrolled node can get the same AI session enrichment from its OWN org server instead of the hosted personal plane, over a disjoint authority plane with its own org settings, job and result tables, a signed result-pull rail, per-org retention and an admission bound. Surfaces land on the node dashboard, the org session drawer and a Settings card.
- feat(adapter): four new tool adapters.
poolside(Poolside's agentic coding model, reached as a JetBrains ACP agent; event-sourced NDJSON trajectories, per-call tokens),zed(Zed's own native agent; per-OSthreads.dbwhose rows are rewritten whole per turn as zstd-compressed JSON),kiro-crew(AWS Kiro Crew, the multi-agent desktop app that drives kiro-cli - it emits rows ONLY for a Crew chat with no kiro-cli twin, so nothing is double-counted) andgrokbot(the Grok Bot desktop app, whose inference runs in a remote sandbox, so tokens, model, cost and cwd are honestly absent rather than guessed). Freebuff also gained its desktop store, and Qoder, Open Interpreter, Factory and OpenClaw gained additional grounded surfaces. Supported-tool copy is reconciled to 40 across every surface. - feat(surfaceenrich): a hosted-surface enricher for JetBrains AI Assistant. An orchestration host that owns no conversation but points at the agent session it drove now stamps that session's capture surface: a daemon-lifetime loop maps JetBrains agent-session pointers onto the owning adapter's session id, and the host record wins over the agent's own self-report (an empty host never clears it). Agents that do not round-trip by exact id stay honestly unmapped, and no JetBrains capture adapter was added, because one would double-count every agent's conversation.
- feat(org): node session-detail trickles up to the org dashboard. The org session drawer now carries what the node has always shown, additively: the capture surface, sub-agent token and cost attribution, real message columns with per-message role, effort, tools and stop reason, per-model cost buckets, a per-event cache timeline, the process tree with metrics, a Tasks tab and per-message tool-account attribution - the last two behind two new opt-in share tiers, with the rest as default metadata.
- feat(design-system): one shared design system for every application
surface.
shared/is now an npm-workspace package owning the tokens, the Tailwind preset, the primitives and the charts that the node dashboard, the org dashboard and the cloud portal all consume, ending web2's hand-copied tokens and webcloud's look-alike tiles. Components promoted into it stay pure, with a one-line re-export shim left at the old path so existing importers are untouched. - feat(config,dashboard): config management from the dashboard. A
generated config schema (with a CI drift gate) backs
GET /api/config/schemaandPUT /api/config/keys, a surgical file patcher that preserves comments and formatting, credential redaction, and a schema-driven Settings renderer that is honest about which keys need a restart. - feat(pricing): a signed public pricing feed. List prices can now be refreshed without a package release: a signed feed published from the Tokenomics database and shaped like the node rate vocabulary, an in-process poller that re-prices the live cost engine, explicit precedence (enrolment first), an air-gap bundle, park and auto modes, and an org-side importer with a dashboard panel.
- feat(ssh,terminal): SSH remote-profile terminals and an instance
switcher. Dashboard terminals can open on another machine through an
allow-listed SSH profile (the request carries a profile NAME only),
observer sshreaches CLI parity with a "Test connection" verb and an opt-in reverse proxy forward, and the dashboard can switch to a remote install's dashboard over a local port forward. - feat(archive): corpus archival and reclaim. An opt-in cold store
(
archive.db, its own lineage and its own owner) moves aged corpus rows out of the hot database copy-verify-delete, never delete-first, verifying by reading back from the cold file;observer archive status|rehydrate|reclaimdrives it, and reclaim is operator-invoked only and never deletes. Disabled by default, so an untouched install is byte-identical to before. - feat(orgpush): a uniform envelope budget across all 41 wire families. Every family is now bounded end to end with a loud push breaker, closing the class behind the 2026-08-26 host-crash amplifier, and cursor wires leave explicit slack so a push cannot pause 693 bytes over the limit.
- feat(govern): enterprise share algebra and node governance. A managed node's reporting tiers are composed through one share algebra with grant replacement and posture-conditional invariants, enterprise authority tokens reach the node through the enrolment-delivered grant, and every authority string on the dashboard says honestly what it does and does not allow.
- docs: a private-datacenter deployment playbook and a sizing
calculator.
docs/private-datacenter-deployment.mdis the full operator playbook for standingobserver-orgup inside a private or air-gapped data center - hardware sizing, a non-cloud object store, HA PostgreSQL and NATS, a Kubernetes path, the air-gapped update mirror and the private-DC pricing feed - with a companion per-component sizing calculator rebuilt for the PostgreSQL, Parquet and NATS architecture.
Changed
- feat(orgserver): SQLite is no longer the org server's runtime engine.
The deployed org server runs its control plane and its Plane-B hot and
query data on PostgreSQL (
OBSERVER_CONTROL_STORE_DSN/OBSERVER_DATA_STORE_DSN;--role allmay point both at one database), with typed Parquet as the durable system of record and a NATS/JetStream durable log. SQLite remains the org server's test engine and is completely unchanged as the node's local store. Migration is documented indocs/stateless-collectors-postgres-migration-runbook.md; note that the reference deployment's NATS sidecar uses ephemeral storage at R=1 and so does not by itself support an HA or container-group-loss claim. - feat(org,pricing): the gateway rate card and the gateway budget cap are
projections, not authored objects.
POST /api/org/ai-gateway/budgetsandPUT /api/org/ai-gateway/rate-cardare retired to409; caps come frombudgetsand rates fromorg_model_prices. The projection is lossy by design (the card carries 4 of 13 price fields), and the one shape that cannot project is surfaced asgateway_skippedon the Pricing page rather than being dropped silently. - fix(orgserver):
scrub-contentnow erases the durable system of record too. Targeted erasure previously scrubbed only the hot data store, leaving the Parquet/object SoR readable and able to resurrect scrubbed content on a rebuild; it now runs through the same governance and retention seam with verify-read-back before tombstoning, fails loud, and refuses legacy JSONL. Replay defaults to a dry run with a target assertion and a sequence-gap policy. - feat(orgserver): retention covers the raw-detail tiers and the gateway
lane. The server-side retention allow-list was widened so the
content-bearing tables added by recent arcs age out with everything else,
and the ingest quarantine follows
data_retention_dayswith requeued rows pruned after 7 days. - feat(web2): primary content shows directly. The click-to-disclose gates on the org dashboard are gone; audited message bodies reveal on click instead of collapsing to a spacer row, and a content cell says honestly whether it holds a preview, an audited chip, or nothing because the node did not share it. The dashboard itself was reorganised into three areas with Observe and Configure split, Trajectories became a master-detail drill-down, every entity mention is a link through one shared primitive, and the brand mark and favicons now match the node dashboard.
- fix(web,web2): em-dashes replaced with hyphens in user-facing copy. A sweep across the node dashboard, the org dashboard, the shared components and the cloud portal, leaving code comments untouched.
- fix(handoff): Full+cache is disabled where the source cannot provide it. Thirty adapters have no full-body reader, so the Full+cache carry mode was inherently identical to Full for them; the option is now disabled with honest copy rather than offering a distinction that does not exist.
- perf(orgpush): the org push tick no longer recomputes every snapshot wire on every tick (steady-state CPU remediation, Track R2). Before this, all ~23 snapshot/aggregate wire families — the teams-tier aggregates plus the enterprise per-session and per-developer wires — re-ran their full 7-day window or whole-table read on every push regardless of whether anything had changed, which was the systemic cause behind the three query-shape findings fixed in 1.32.0. Each family is now guarded by an O(1) change probe over its own source tables (a single index-endpoint seek in most cases), so an idle node's whole snapshot family costs a handful of seeks instead of a full recompute. The cursor wires (sessions, actions, api_turns, token_usage, guard_events, otel_content) are untouched and still ship every tick. Fail-open by construction: a probe error, an unknown family, a failed push, or a budget-truncated wire all recompute, and every family is force-refreshed at least hourly so its server-side freshness never ages out of a dashboard window. No wire shape, server behaviour, or migration changed.
- feat(config): new
[org_client] snapshot_interval_secondsbounds how often the snapshot wire families recompute even when their source data DID change, for nodes busy enough that the change probe never gets to skip. Unset means 4× the effectivepush_interval_seconds(8 minutes at the shipped defaults, and it tracks a retuned push interval rather than freezing an absolute); a negative value restores the previous every-tick cadence. The staleness it buys is explicit — seedocs/teams-operations.md.
Fixed
- fix(budget): a fallback-priced model is no longer reported as an unpriced one (BUDGET-COV-3). Org budget coverage lumped "this model was priced from the built-in table because the org has no negotiated rate for it" together with "this model has no price anywhere", so an estate with a perfectly enforceable budget read as partially blind. The two are now distinct posture classes (server migration 152) with their own coverage notes.
- fix(node): a transient capture state never stops a running process. The managed-node budget intervention treated a momentarily unresolvable per-tool capture state as an enforcement signal and could kill a healthy agent process. Transient states are now inert: only a settled, measured crossing acts.
- fix(node): managed budget accounting uses the full pricing ladder. A prior correction narrowed managed accounting to exact and org-quoted prices only, so every model without an org rate read "unpriced" and got blocked at effectively zero spend. Accounting now walks the whole engine ladder, and an unpriced model is FLAGGED, never denied; org spend is additionally sourced by capability rather than by tool name.
- fix(org,budgets): the Budgets page sources spend by capability. Spend attributed on the Budgets page could disagree with the enforcing chokepoint; both now read through the same capability-scoped source, and coverage ignores the individual-tenancy predecessor of a node that has since become managed.
- fix(org): one org distribution identity (SIGN-1). Several signed rails minted or pinned their own key material, so a node could hold more than one trusted org identity. Every signed rail now uses the single enrolment-delivered key, and pre-existing TOFU pins heal on a hash match instead of failing the node.
- fix(org,budgets): budgets fail CLOSED on a managed node (BUDGET-FC-1). A managed node that could not resolve its cap previously behaved as if no cap existed. It now fails closed, an explicitly-no-budget answer is signed rather than inferred from silence, and per-window hardness is shared so the node and the gateway cannot disagree about whether a window is hard.
- fix(org): team-management routes worked only on fresh installs
(TEAM-KEY-1).
write:teamswas granted by the migration that created it, so an already-bootstrapped admin never received it and every team route answered403. Server migration 129 back-grants it, and a matching control-store retrofit coversadmin:identity. - fix(harness-gateway): cancellation and timeouts are plumbed end to end. Closing the org bridge now cancels the in-flight provider inference and disposes uncached failed sessions instead of leaking them, the provider request is bounded independently and below the org deadline, the saved provider timeout is forwarded rather than defaulted, and a silent exit or an empty completion produces an actionable diagnostic.
- fix(orgserver): the org hot window evicts correctly. A hot-window eviction defect that could leave stale rows resident was fixed and shipped with the v54 estate roll.
- fix(org,policy): a committed mutation whose audit row fails is not a
client error. Under a split PostgreSQL control plane, policy-rollout and
policy-resource mutations wrote their audit row inside the control
transaction against a table that is not mirrored there, failing the whole
mutation. The audit now rides inside the transaction only when the pools
are the same, and a post-commit audit failure maps to a typed
500 audit_failed_after_committhat says the change took effect and must not be retried. - fix(orgclient): the push cursor advances by compare-and-swap. A blind save could rewind or skip the cursor under concurrency; the cycle now advances it with a CAS, and the task, tool-account and cache-event wires are mapped into the envelope with a reflective sentinel so a new wire cannot be silently forgotten.
- fix(orgpush): zero-cost token rows are priced at push time. Rows that reached the org with no cost are now priced with the node's own cost engine before shipping, and the org prices previously-unpriced model ids, falls back honestly for an unknown session model, and shows an explicit Unattributed spend bucket instead of quietly dropping it.
- fix(terminal): dashboard terminals link to their captured sessions. Late-starting sessions are now correlated (the first scan no longer gives up before first activity), simultaneous terminals of the same tool no longer share one candidate set, default-cwd launches auto-link, and the behaviour extends across every adapter with a launcher rather than a handful.
- fix(launcher,predict,hook): three node-daemon defects. Hooks under
observer claudecrashed on an inheritedOBSERVER_OOB_FD=3that was adopted without first checking it was still a pipe or socket (it is now verified, andOBSERVER_OOB_*is scrubbed from tool-child environments); predictor facts were coupled to pricing availability, so proxy-only sessions got no cost band; and hook events collapsed several distinct events into one row. - fix(scripts):
restart-daemon.shrefuses to run inside a daemon-launched session. Restarting the daemon kills that session outright, because the daemon owns the pty, and it never resumes; the script now refuses by default and tells you to restart from an outside shell. - fix(scrub): Anthropic API keys with hyphens now redact. The API-key
body regexes did not admit hyphens, so
sk-ant-api03keys survived scrubbing. - fix(codeintel,watcher,orgserver): three smaller regressions. Project
roots discovered under temporary directories were re-indexed on every
daemon start, burning minutes per boot; a legitimate large watermark
SQLite store was rejected by the oversize DoS gate; and
/ai-gatewaycrashed on an empty estate because its list endpoints returnednullrather than[]. - fix(cloud): two hosted-lane defects. The results-pull cursor is now keyed by cloud host, so a node that had synced against staging no longer replays staging's cursor against production and never pulls a production result; and a zero-total trial-start transaction no longer flips a trialing subscription to active (found against a live sandbox checkout, with the Paddle goldens replaced by real sandbox deliveries).
- fix(org,pricing): a colliding price row answers
409, and an undated price takes effect when it is approved. A duplicate model plus effective-date pair produced a raw constraint500, and an undated row approved from the assistant landed behind an earlier dated import instead of superseding it.
Security
- Nine dated reviews since 1.32.0, all recorded in
docs/security.md. Every arc in this release went through at least one fresh-context adversarial pass before shipping: the Plane-B gateway and RBAC arc (2026-08-30), Cloud Intelligence across seven separate rounds (2026-09-02 through 2026-09-16), the sign-in arc and its hardening wave (2026-09-07), lines-of-code tracking and the identity resolver (2026-09-07), enterprise pricing and the admin assistant (2026-09-08), the stateless-collectors architecture (2026-09-08 and a whole-arc review on 2026-09-10), and org budgets (2026-09-07). The ledger indocs/security.mdremains the canonical record. - SOR-2: targeted erasure reached the durable store.
observer-org scrub-contentscrubbed only the hot data store, so a rebuild from the Parquet system of record could resurrect scrubbed content. Closed - see the Changed entry above. - XFF-1: dashboard audit rows record the real transport peer. Audit rows recorded a forwarded address even when no trusted-proxy resolver was injected; the transport peer is now recorded unless one explicitly is.
- Sign-in hardening.
__Host-cookie prefix behind a dual-read rename transition (so no admin is force-logged-out across the upgrade),Secureas an enforced policy with one explicit override, a double-submit CSRF token on the one server-rendered form POST, logout as a CSRF-bearing POST, MFA signal passthrough, IdP-initiated logout, an SSRF-hardened identity probe, and a held identity that can no longer admit itself simply by signing in again. - Cloud Intelligence privacy invariants are pinned, not promised. Zero egress from the daemon (the CLI is the only outbound trigger, pinned by an invariant test), preview bytes equal upload bytes, an authority gate that refuses org-owned or unknown-authority evidence, credential absence checked before any provider call, a content-free local ledger of everything sent, and a per-table deletion matrix. The provider's data-retention posture is now stated as an explicit, operator-attested disclosure rather than an unqualified claim, and the marketing copy was flipped from absolute to conditional truth with a CI gate holding it there.
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.33.0-linux-x64.tar.gz |
| Linux arm64 | observer-v1.33.0-linux-arm64.tar.gz |
| macOS x86_64 (Intel) | observer-v1.33.0-darwin-x64.tar.gz |
| macOS arm64 (Apple Silicon) | observer-v1.33.0-darwin-arm64.tar.gz |
| Windows x86_64 | observer-v1.33.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.33.0
Org server (Docker)
The self-hosted org server ships as a Docker image and as per-platform observer-org-v1.33.0-* archives (attached below).
:::bash
docker pull ghcr.io/superbasedapp/observer-org:v1.33.0
The image is keyless-signed with cosign. Verify it:
:::bash
cosign verify ghcr.io/superbasedapp/observer-org:v1.33.0 \
--certificate-identity-regexp 'https://github.com/marmutapp/superbased-observer-private/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
Enterprise updates
This release publishes on the stable channel.
Each agent archive carries a detached vendor signature (<archive>.sig, raw Ed25519 over the archive bytes) and the release ships a signed update-manifest-stable.json. Self-hosted org servers consume them with:
:::bash
observer-org update sync --version v1.33.0
observer-org update publish --channel stable --version v1.33.0
For a disconnected server, download observer-v1.33.0-airgap-bundle.tar (archives + signatures + SHA256SUMS + the signed manifest + provenance), carry it across the gap, and run observer-org update import --version v1.33.0 --bundle <dir>.
Supply 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):
:::bash
slsa-verifier verify-artifact ./observer \
--provenance-path *.intoto.jsonl \
--source-uri github.com/marmutapp/superbased-observer-private