Skip to main content
The generic versioned-document store contract. A kind-discriminated, body-opaque persistence primitive: append-only version rows over an opaque JSONB body, an active-version pointer, and rollback. The store knows NOTHING about presets/policies/agents — those are typed VIEWS layered on top. Identity is (kind, name) throughout; every write is one transaction. This package holds the VersionedStore Protocol plus its record models (DocumentRecord, DocumentVersion) and typed errors. It is reached from the assembled facade as app.versioning.store (see AppVersioning).

DocumentExistsError

tai42_contract.versioning.errors.DocumentExistsError
A live document already exists for (kind, name) (create would collide).

DocumentNotFoundError

tai42_contract.versioning.errors.DocumentNotFoundError
No active document for (kind, name).

DocumentRecord

tai42_contract.versioning.models.DocumentRecord
A versioned document’s live record: its identity plus the active pointer. active_version names the version currently served for (kind, name); rollback re-points it without copying data. is_active is the soft-delete flag — a soft-deleted document keeps its version history (audit) but drops out of list/get. created_at is an ISO-8601 timestamp string. Attributes

DocumentStoreError

tai42_contract.versioning.errors.DocumentStoreError
Base for versioned-document store failures, carrying (kind, name). Attributes

DocumentVersion

tai42_contract.versioning.models.DocumentVersion
One immutable version row: the opaque body plus its version number. A version is append-only — once written, its version, body, tags, and created_at never change. tags is a generic per-version label for grouping versions (release/grouping labels); it is kind-agnostic and carries no product meaning (distinct from any categorization a kind’s body may hold). is_current is a read-time projection of the owning record’s active_version — the store sets it True on the active version when it lists/returns versions; it is not stored on the row. created_at is an ISO-8601 timestamp string. Attributes

DocumentVersionNotFoundError

tai42_contract.versioning.errors.DocumentVersionNotFoundError
No version version exists for the (kind, name) document. version is carried when known (the version-specific ops always know it); the (kind, name) identity is always present, as for the other store errors. Attributes

VersionedStore

tai42_contract.versioning.VersionedStore
Kind-discriminated, body-opaque version store. Identity is (kind, name). The body is opaque dict/JSONB — the store never inspects it; the caller (a typed view) owns its shape. Every method raises loudly on a missing, duplicate, or invalid target — never a silent default. tags is the generic per-version grouping label (see DocumentVersion), distinct from any categorization a kind’s body may carry. A write method (create, save_version, delete, rollback) accepts an optional tx — the handle from an open transaction. Passed, the write runs WITHIN that unit of work and commits or rolls back with it; omitted, the write is self-contained and atomic on its own.

Members

transaction

tai42_contract.versioning.VersionedStore.transaction
Open a single-backend unit of work: async with store.transaction() as tx. Every store write performed with the yielded tx (passed as tx= to the write methods) commits or rolls back TOGETHER — a clean exit commits, an exception rolls the whole scope back. A pure durability primitive over the one backend: it carries no audit or domain awareness, and yields an opaque handle the caller only threads back into the write methods.

create

tai42_contract.versioning.VersionedStore.create
Insert a new document at active_version = 1 plus its version 1, one transaction. Raise DocumentExistsError if (kind, name) is already a live document. Runs within tx when one is supplied. Parameters

save_version

tai42_contract.versioning.VersionedStore.save_version
Append a new version (new_version = max(version) + 1, NOT active_version + 1) and bump the active pointer to it, one transaction (a partial failure rolls the whole save back — no orphan version, no half-bumped pointer). Raise DocumentNotFoundError if absent. Runs within tx when one is supplied. Parameters

list

tai42_contract.versioning.VersionedStore.list
List the active (non-soft-deleted) documents of kind. Parameters

get

tai42_contract.versioning.VersionedStore.get
Fetch the active record for (kind, name). Raise DocumentNotFoundError if absent. Parameters

get_active_body

tai42_contract.versioning.VersionedStore.get_active_body
Return the body of the active version for (kind, name). Raise DocumentNotFoundError if absent. Passed a tx, the read rides that transaction’s connection so a read-modify-write can lock and mutate the row on one connection (no second pooled connection while the transaction is open). With for_update=True it takes a SELECT ... FOR UPDATE row lock on the active document so concurrent writers serialize — the lock is meaningful only inside a transaction, so for_update REQUIRES a tx and raises loudly without one. Omitting both preserves the stand-alone read. Parameters

list_versions

tai42_contract.versioning.VersionedStore.list_versions
List every version of (kind, name), each carrying the DocumentVersion.is_current signal derived from active_version. Raise DocumentNotFoundError if the document is absent. Parameters

get_version

tai42_contract.versioning.VersionedStore.get_version
Fetch one version. Raise DocumentVersionNotFoundError if that version does not exist. Passed a tx, the read rides that transaction’s connection rather than opening a second pooled one. Parameters

rollback

tai42_contract.versioning.VersionedStore.rollback
Re-point active_version to version (NO data copy). Raise DocumentVersionNotFoundError if that version does not exist. Runs within tx when one is supplied. Parameters

soft_delete

tai42_contract.versioning.VersionedStore.soft_delete
Set is_active = False, keeping the version history (audit). The document drops out of list/get but its rows survive. Parameters

delete

tai42_contract.versioning.VersionedStore.delete
HARD delete, DISTINCT from soft_delete: remove ONLY the ACTIVE document row for (kind, name) AND its version rows, so nothing of the active document survives; a soft-deleted ghost of the same name is left untouched. Raise DocumentNotFoundError if there is no active row. Used to roll a never-succeeded create fully back and to remove a conflicted record without leaving the ghost + spurious history a soft delete would. Runs within tx when one is supplied. Parameters

rename

tai42_contract.versioning.VersionedStore.rename
Re-key the ACTIVE document (kind, name) to (kind, new_name) in one atomic write. The whole version history, every per-version tags label, and the active_version pointer move untouched — versions key on the document, not the name, so nothing is copied. The body is never inspected (the store stays body-opaque). A soft-deleted ghost named new_name does NOT block (the same partial-unique identity rule create follows), and a soft-deleted ghost of name is left untouched as audit history. Raise DocumentNotFoundError if (kind, name) has no active row; raise DocumentExistsError (carrying new_name) if (kind, new_name) is already a live document. Parameters

VersionedStoreTransaction

tai42_contract.versioning.VersionedStoreTransaction
Opaque unit-of-work handle yielded by VersionedStore.transaction. A pure durability token exposing NO operations of its own: a caller only passes it back to a write method’s tx= parameter so that write joins the open transaction. The concrete store owns the handle’s real shape (its pooled connection); the token carries no audit or domain awareness.