@tuvren/backend-postgres
v0.2.0
Published
Tuvren PostgreSQL backend leaf: durable session persistence on Postgres with a relational row-per-record schema (ADR-0067), constructed by the host and passed into createTuvren.
Readme
@tuvren/backend-postgres
Tuvren PostgreSQL backend leaf: durable session persistence on Postgres with a relational row-per-record schema (ADR-0067), constructed by the host and passed into createTuvren.
Install alongside @tuvren/core and @tuvren/sdk; this package peer-depends on a single shared @tuvren/core instance (ADR-0037).
Schema name
Always set a dedicated schemaName when constructing this backend — never rely on the default. The relational schema (ADR-0067) is thirteen generic, unprefixed family tables (objects, schemas, threads, branches, turns, runs, staged_results, …) plus twenty-one idx_* indexes, created with bare CREATE TABLE/CREATE INDEX and no package-specific prefix, so sharing a schema with anything else the host owns risks a name collision or silent cohabitation. When schemaName is omitted, the backend defaults to the backend-owned name "tuvren_kernel", not "public" — a default-constructed backend can no longer collide with or colonize an adopter's default schema. destroyPostgresBackend's { dropSchema: true } option drops the entire configured schema with CASCADE; because that schema is shared identity for every backend instance pointed at it, only pass dropSchema: true against a schema this backend exclusively owns (throwaway test/conformance schemas), never against a schema that also holds host tables.
Upgrading from a pre-#110 (blob) database
Opening a database that still has the legacy backend_postgres_snapshots blob table automatically explodes it into the relational family tables, once, inside the same locked schema-init transaction used for ordinary migrations. The explode is all-or-nothing: if it fails partway through, the enclosing transaction rolls back, the legacy table is left intact, and the migration is simply retried in full on the next open. The migration is one-way — downgrading a migrated database back to a package built against the blob-era schema is not supported. A phase observer attached to the backend attributes the cost of this one-time explode to a blob-migration phase, so an unusually slow first open against an older database is explainable rather than mysterious.
Pre-existing deployments built before this schema-name default changed relied on the old implicit "public" default; if such a deployment omitted schemaName, its legacy backend_postgres_snapshots table lives in public, not in the new default "tuvren_kernel". Those deployments must now set schemaName: "public" explicitly (or move the legacy table into their intended dedicated schema before upgrading) so the open-time migration described above can find it — otherwise the backend opens a fresh, empty "tuvren_kernel" schema and never sees the legacy data at all. As a backstop for a deployment that forgets to do this, opening a backend with a defaulted (never explicitly supplied) schemaName against a brand-new, not-yet-provisioned schema now checks whether a backend_postgres_snapshots table exists in some other schema in the same database and, if so, throws a typed postgres_backend_legacy_blob_schema_elsewhere error naming where it found the legacy table instead of silently standing up an empty "tuvren_kernel" — this guard only runs for a defaulted schema name and only the first time the configured schema is created, so it never fires against an already-provisioned schema or one an operator explicitly chose. Because opening the backend for the first time on a legacy database performs this one-time blob migration inline (and, on an upgraded-but-unmigrated deployment, the guard's catalog check), operators should open the backend once out-of-band before pointing short-timeout health probes at it, since a probe calling health() can itself be what triggers the first-open migration or guard check and take longer than a typical liveness-probe timeout.
See the Tuvren framework repository for documentation and adopter onboarding.
