ABI policy¶
ABI version 15 is pre-release and may change during the 0.x series, with every
change recorded in the changelog and ABI tests. pp_abi_version() reports the
implemented version. Exported symbol names are unversioned until the first stable
release, but removals or signature changes require an explicit ABI-version bump.
Types and ownership¶
Productions, transactions, asset sets, media-root sets, representation sets,
resolution sets, activity sets, external-identifier sets, object-reference sets,
metadata inputs, and errors are opaque handles. A
successful creation/open call transfers one production ownership reference to the
caller, which releases it exactly once with pp_production_release. Failed calls
optionally transfer an error object, released exactly once with
pp_error_release. Release functions accept null as a no-op; releasing the same
non-null pointer twice is invalid.
A production permits one open transaction at a time. Import and media-root mutations
are prepared and staged in memory, then persisted together by
pp_transaction_commit. Rollback or release of an open transaction discards all
staged work. A transaction retains the underlying production state, so its handle
remains valid if the originating production handle is released. Closed transaction
handles may only be released.
pp_uuid_t contains exactly 16 network-order UUID bytes. pp_object_ref_t
combines that ID with a fixed-width object-kind tag; open-world concepts such as
identifier schemes remain UTF-8 strings rather than C enums. Numeric errors and
object kinds are fixed-width values defined in the C header.
Strings and errors¶
Input strings are borrowed, NUL-terminated UTF-8 and may not contain embedded NUL. Optional strings use null. Error messages are borrowed NUL-terminated UTF-8 owned by their error object and remain valid until that object is released. Stable error codes are the contract; message wording is diagnostic and may evolve.
Panics and threading¶
Every exported operation contains Rust unwinding with catch_unwind. Panics are
translated to PP_ERROR_INTERNAL; no panic may cross the C boundary. Production
handles may move between threads and support concurrent calls. Calls on one handle
serialize internally and block rather than reporting a contention conflict. A
panic while the handle is locked does not poison later calls.
Transaction, result-set, and error handles require caller-side serialization. No handle may be released while another thread uses it. Transactions stage mutations without holding the production lock; commit serializes with operations using the same production state. Opening the production again provides a separate handle for reads during that interval, subject to SQLite’s own file-locking behavior.
Header compatibility¶
The hand-reviewed C header is authoritative. Rust implementation types, SQLite types, allocation APIs, and standard-library layouts never cross the ABI.
C++ wrapper¶
postproject.hpp is a header-only C++17 wrapper over the authoritative C API.
It owns production and transaction handles with RAII, makes both wrappers move-only,
and converts failed status codes to postproject::Error. Destruction of an open
transaction invokes the C release behavior and therefore discards staged work.
The exception retains the stable ErrorCode and copies diagnostic text before
releasing the C error object. No exception crosses the C ABI. Inputs containing
embedded NUL bytes are rejected before calling C.
Resolution results¶
pp_production_resolve_asset returns an immutable opaque set containing one result
per representation. Each representation reports aggregate availability,
ordered resource results, and availability issues such as offline required
resources or missing sequence frames. Fixed-width states, issue kinds, frames,
candidates, and evidence are read through index-checked accessors. Candidate URI
and optional evidence-detail strings are borrowed from the result set and remain
valid until pp_resolution_set_release. The C++ wrapper copies these into
RepresentationResolution, ResourceResolution, AvailabilityIssue,
ResolutionCandidate, and Evidence values, so their lifetime is independent
of the C handle.
Resolution never mutates a production. A caller explicitly stages a selected
candidate using pp_transaction_confirm_locator, and only transaction commit
makes that location durable. The caller is responsible for passing a URI from
the result it reviewed; the API validates the URI and resource identity at
persistence time but does not silently choose a candidate.
Resolution snapshots the database state it needs while holding the production lock, then releases that lock before filesystem discovery and fingerprinting.
Logical media-root names are production knowledge. pp_media_root_mapping_t
values borrow a root name and a machine-local directory only for one resolution
call; the library copies and validates them before scanning. A null mapping
pointer is valid only with a zero count. Root summaries expose an optional
legacy absolute URI solely for lossless migration from schema versions before 6.
Representation inspection¶
pp_production_representations returns immutable snapshots of an asset’s
representations. Index-checked accessors expose structure kind, ordered members,
requiredness and roles, compact image-sequence descriptors, concrete resources,
locators, and their last observed availability. Resource fingerprints and
structure-aware representation fingerprints have separate accessors and counts;
callers must not treat one as the other. Returned strings and fingerprint byte
spans borrow the result set and remain valid until
pp_representation_set_release.
The C++ wrapper copies the complete snapshot into Representation, Resource,
Locator, and Fingerprint values. Compact image sequences remain one resource
with a pattern and frame domain rather than one synthetic resource per frame.
External identifiers¶
External identifiers are staged with a typed object reference, scheme, opaque value, and optional qualifier. Add/remove operations are atomic with every other transaction mutation. Enumeration returns an owned result-set handle whose strings remain borrowed until release. Exact scheme/value lookup returns a separate owned object-reference set and does not normalize inputs or contact a registry.
The wrapper adds no domain behavior and exposes no C++ standard-library type through exported library symbols. Its source compatibility follows the 0.x pre-release policy independently of the C ABI version.