Skip to content

Truss v0.0.40

Choose a tag to compare

@easel easel released this 19 Oct 23:39
· 110 commits to main since this release

Truss v0.0.40

Publication requires installed-package qualification locally on macOS ARM64,
the three real schemas and all 11 unchanged stress workloads. The
operation cost ledger
records statement purposes, retained data and resource costs. Release artifacts
identify the exact source, package and qualification runs; earlier candidate
runs do not qualify a different package.

Scope and highlights

Qualification targets Python embedders using PostgreSQL18.6 on macOS ARM64;
the three real schemas and all 11 unchanged stress cases pass locally.
This update selects native 0.72-candidate, Weft 0.4.47, psycopg
3.3.6 and embedded V8 through mini-racer==0.14.1. Deployment needs no Bun,
Node or external JavaScript process.

Catalog preparation targets one source-only path for UMF 0.10.0. Older UMF
formats and upgrades from older Truss installations are unsupported. prepare_catalog,
prepare_acceptance retain original
documents and validation diagnostics without a mandatory inspector transcript.
The preparation interface is truss-registration-preparation/2.0; registration
reports use truss-catalog-registration-report/0.6. Reports retain effect counts
and applicable rebind/backfill profile identifiers. Consumers that inspect these
interfaces must accept the new versions rather than requiring the old transcript.

Loaded catalog views expose immutable application-memory schema indexes and
reuse them for an exact revision and source basis. Eligible rootless-create and
distinct stored-object update batches also use compiled application-memory
record schemas for value validation and canonical property-ID preparation. Warm
batches reuse schema across transaction/facade replacement, fetch no schema and
do not invoke the legacy per-record value validators.
Native admission still checks current authority and the exact revision, source
and registration identity. Mixed, owned and edge groups, unsupported preparation
subsets and historical prior images retain the existing native path. The retained
application cache holds at most two revisions within a 128MiB estimated-object budget. A reused
revision number with different source cannot reuse the old view. Prepared writes
also bind the registration UUID, so rollback followed by the same source at the
same revision cannot reuse obsolete native property IDs. Fresh native
context and permission checks still apply.

Changes and fixes

UMF string maxLength facets count Unicode scalar values; binary maxLength
facets count bytes. Catalog evolution checks existing stored values when a
current definition tightens either limit and refuses publication if any value
would violate the new facet. The catalog report distinguishes engine checks
from database constraints: business-key uniqueness is enforced by the engine
under the transaction writer gate; the database key-table primary key serializes
physical memberships. String and binary length checks are evaluated against
stored values by the engine.

Type and relationship qualification start with the indexed definition pin,
avoiding scans of unrelated source definitions for each object or edge.
Registration resolves property source pins together and compiles eligible key
codecs once for the revision, retaining original field definitions and facets.
Native cache initialization uses shared set-based stages rather than issuing
a sequence of catalog queries for every type. Conditions resolve their exact
object or relationship definition pin before inspecting the owning source.
Graph checks select the relationships for the affected type before resolving
their permissions and counts. Group admission compares each original schema
document once per call while retaining every operation's current owner and
permission checks. Bounded native value walks use an indexed array queue;
batch history and key metadata are collected once rather than repeatedly
copying growing JSON maps.
Batch creates and updates reuse compiled schema and key metadata. Independent
update transitions refer to canonical journal rows instead of storing another
copy of their event and origin payloads.
Import source attachment decodes its group once and stores one canonical source
row, preserving original input bytes without a second expected source image.
New object transitions also omit duplicate physical key-row images; canonical
memberships and retained reservations stay in their own tables.
Edge and cascade execution retain canonical history and expected-version/count
checks without full-image readback proofs or growing JSON payload concatenations.
Progress updates no longer compare unchanged whole request/document carriers.
Ownership-preserving groups capture only the existing independent edges being
changed. Unrelated owned definitions and growing unrelated independent-edge
populations do not force whole incident-edge snapshots. Stored owned endpoints
retain their required ownership component and root information; native final
cardinality and current authority checks remain. This applies to mixed value,
rootless-create and independent-edge operations as well as uniform batches.
Mixed and owned groups use indexed invocation-local working rows and adjacency
lookups, retaining one shared original snapshot and only changed members plus
root/endpoint header witnesses for each operation. Those headers are materialized
once in the working relation, so repeated children do not decompress an unchanged
root property map. Final forest validation visits each
node once; scope discovery and cascade walks use distinct membership rather than
repeated full-graph scans. Required historical frames remain recoverable from
the original snapshot and immutable transitions, including no-op updates followed
by catalog acceptance in the same transaction.
Historical public reads still materialize complete events. Batch writes check
affected-row counts and version-matched updates; finalization retains current
context, authority, and operation-completeness checks without replaying the trusted
producer's semantic work.

Independent update history is written in internal sets of at most 64 objects.
Each set writes ordered history and retains compact references to the actual
inserted journal rows. The full operation remains atomic: a later SQL failure
rolls back earlier sets. All sets share one protected native call and its
original SQL deadline. A
1,000-object update therefore uses 16 journal INSERT statements internally,
with no additional frontend guard submissions. Statement-level journal observers
see this changed batching cadence. Unrestricted multiplicity sides no longer
count edges; bounded checks, permissions and marker verification remain.
Within each set, history property order and pins are shared across both complete
images and all objects with the same revision/type. Entirely unbounded graph settlement needs no multiplicity counts or empty-marker
cleanup. Actual selected endpoint/root dependencies remain authorized; unrelated
relationship endpoint types do not create permission requirements. Bounded graphs
retain their count/marker checks. Current authority is checked at finish and commit.

The native query compiler admits a bounded 1,000-type catalog within its existing
4MiB model and binding byte limits. It indexes original module and element
coordinates once per prepared catalog. Its broader one-million-value parsing
budget applies only to the selected Truss runtime profile; other profiles retain
their previous limits.

A failed group condition takes precedence over a refused operation in that
group. Caller transaction ownership, operation-local rollback, original receipt
replay and current permission checks remain part of the qualified workflows.

prepare_group_in_transaction bundles the revision, group context and requested
type/relationship references. catalog_revision_in_transaction provides a small
revision probe for cached planning metadata. A write still checks its exact
current catalog basis and current authority. Group admission starts once rather
than issuing a separate replay-only group start.

Request-bearing AppliedPending results include the receipt token before commit.
The original token becomes included when the caller commits; another transaction
observes not_yet before that commit. A rolled-back token stays not_yet.
Possessing a pending token does not establish a confirmed commit or authorize
publication. Committed replay remains available for recovery.

Complete-entity SQL already supplies relationship columns through x.*.
Adding a second output with the same name remains an explicit WFT-OUTPUT-NAME
refusal. Stable UMF IDs continue to support unnamed records and fields.

Limits and qualification

Modern groups admit at most 1,024 operations; 10,000-operation groups remain
unsupported. Ordinary SQL and operation deadlines remain 10s and 30s. Catalog
preparation admits original documents up to 4MiB within a 16MiB request envelope;
the complete catalog-view wire budget is 16MiB with at most 65,536 definitions.
These are separate limits, not a promise that all maxima fit simultaneously.

Query callers can select the existing byte budget up to 16MiB for wider or larger
source sets. The default remains 1MiB. ABI 1.1 queries buffer complete source bags
before caller predicates and scan at most 10,000 rows per selected record or
relationship type. A small output limit does not bypass that source bound.
Complete-entity relationships contain at most 100 keys; excess is
refused. Use bounded RELATED_KEYS reads and their explicit truncation indicator
for higher-degree objects. No result is silently presented as complete.

The performance record records exact
functional workloads, timings and qualification limits. Release evidence
identifies the exact installed payload, distributed artifacts and local macOS qualification.

Local evidence covers the existing native-job unittest selection in
release.yml: 95 selectors across
88 modules, with 287 distinct selected method IDs. Every selected method's latest
local result passes, with no missing selector or selected-method failure. This
combines the broad discovery run with affected-test reruns; it is not a complete
rerun of that selection on the final wheel. Current-policy query and activation
tests are included; separately gated current-disclosure/Graph profiles remain
visibly skipped and unqualified.

The raw broad discovery receipt remains failed and incomplete: 1,927 reported
tests across 295 of 313 modules, with all workers shut down. The 197-test and
22-test targeted receipts also retain their original failures; subsequent
affected-test runs corrected those current test expectations, including the final
five source-preparation tests. These results do not establish that all ordinary
component modules pass. Historical uncomposed row-home/layout experiments and
profiles requiring missing original mapping/compiler prerequisites remain
outside the qualified release scope. No retired schema or earlier UMF format
is restored to make those fixtures run.

Pizza, Northwind and catalog each pass the installed public-API workflow with
1,000 created objects, 1,000 ID reads, 100 key reads, complete lists and 200
committed individual updates. All 11 unchanged stress cases complete once
locally with functional passes, preserving their eligible atomic boundary
controls and original 10s SQL/30s operation limits. The million-object large
case includes two million edges and its declared ID/key reads and writes. Its
SQL list remains outside ABI 1.1's 10,000-row source bound. dense-edges
retains the edge-source refusal and exact scalar-list control; skewed retains
the 100-related-key refusal and bounded RELATED_KEYS truncation control.
These passes do not qualify larger complete SQL lists or certify latency:
performance budgets remain provisional, and the wide bulk-100 speedup remains
below its triage threshold.

The release includes the qualification summary
and qualification evidence archive,
retaining report/package identities, selector review, raw failed receipts,
affected-test corrections, completed workload reports and public-example results.

Fresh installation and retained history

This candidate requires a fresh database without a truss schema. It does
not migrate, reset or rewrite an older installation. The retained
upgrade_in_transaction(tx) API returns an explicit unsupported_profile
error without issuing SQL, and the CLI no longer accepts --upgrade.
For a fresh local installation, use
truss-local-postgres --data-dir NEW_PATH --install --probe.

Use UMF 0.10.0 source documents; earlier-format preparation and key producers
are unsupported. Numeric precision and scale choices remain data facets within the
supported current format. This removal does not delete earlier accepted catalog
revisions, retained events, import provenance or receipts inside a current
installation. Compatible catalog evolution and historical access retain their
current authorization rules.

An existing deployment must retain its matching older package and database.
There is no supported in-place conversion or downgrade path. Captured query
bindings and separately activated protected-query registrations require their
exact compiler/runtime cohort.

Known scope and support

V8 remains embedded; a native UMF implementation is follow-up work. Existing
unsupported value/query domains and managed PostgreSQL qualification are not
expanded by this release. See the Python guide
for installation and API scope. Report issues through the
repository tracker with release
pins and the failing public operation.