ctx v4.0.0-rc1
v4.0.0-rc1 — Multi-tenant: scope is the tenant boundary
Release candidate for v4.0.0 (the multi-tenant major). Promoted to the final
v4.0.0 tag once CI and the release build are green on root. The notes below are
the v4.0.0 release notes.
The store goes multi-tenant on the Modell-C architecture — three nesting levels
(tenant ▸ scope ▸ block), with scope as the partition discriminator and NO
tenant_id on any data table. A single-tenant deployment stays byte-identical:
the default tenant owns the existing scopes, so every path behaves exactly as on
v3 until real tenants are provisioned. Built across seven axes / ~34 waves, each
TDD (red→green) + adversarially mutation-verified, on the feat/multi-tenant line
(migrations 058–068; the optional 066, tenant-owned OAuth, is deferred).
BREAKING:
- Migration 058 drops the legacy 3-value scope CHECK;
scopeis now
VARCHAR(50), unconstrained at the schema level — the data-table discriminator
for arbitrary tenant scopes. api-key-listnow defaults to ACTIVE keys only; soft-deleted keys need an
explicitactive_only=false(audit/forensics tooling must send it; design/05
§6.2).- Freshly minted foreign-tenant keys no longer inherit
sharedimplicitly
(R-LEAK5) — only the default tenant auto-inherits it.
What's new:
- Tenant register + lifecycle (059/060): context_tenants, per-request ctx_auth
with a status gate (suspended/offboarding ⇒ UNAUTHORIZED, fail-closed) and
positional read_scopes; a full FK-ordered tenant prune (no orphaned blocks). - Fail-closed read contract: RequireScopes — an empty resolved scope set is an
error, never a silent "all scopes" — wired into every scope-filtered store read
and the four MCP handlers (L7). - Admin tier (Achse 05): typed server-admin / tenant-admin / member roles, a
two-tier action gate, and tenant-gated key mint/list/delete (L1/L2/L3). - Cross-tenant read channel (061) + block-level grants (067/068, the third
level): scope grants and per-block grants, both opt-in and least-privilege,
behind a mandatory-parenthesised visibility OR that can't leak archived /
system-meta blocks, graph-bridge leaf protection, and a grant-fixed egress
sensitivity floor (config-independentpersonalbackstop). - Egress isolation: a tenant-filtered backend Chain (R-LEAK7) — a tenant can
never route a prompt to another tenant's external backend. - Per-tenant settings/secrets (two-write-worlds; strict-isolation secret
fallback gated on an opt-in), a per-tenant config overlay (lazy, gen-stamped,
single-flight) with scope-carried lazy cache invalidation (065). - Per-tenant cost/call quota (063) + management CLI; per-tenant telemetry
(llmlog/status) pull views; the background pipeline iterated per tenant with
its read window clamped to read_scopes ∩ entitlements.
Gate: the full integration suite (every package, the whole 058–068 migration
chain, the race detector) is green; a code-level pre-release isolation audit found
no cross-tenant leak across the read/write, settings/secrets, admin-tier, MCP, chat
and background paths. Three deliberately deferred seams (tenant-owned OAuth, the
dream round-robin's scope-blind PickBlock, the global quota default) are documented
and carry no leak. Rollout to a running deployment (migrating the production DB from
057 across the chain) is a separate operational step.
Installation
With Go:
go install github.com/GottZ/ctx/cmd/ctx@v4.0.0-rc1Binary download:
Download the binary for your platform, make it executable, move to PATH:
chmod +x ctx-*
sudo mv ctx-* /usr/local/bin/ctx