Transit native protocol v1
Transit v1 provides paged durable catalogs and state through bounded commands and queries. The node, shared client, Station and SDKs use this single definition. Growth.zig owns its types and transit-v1.schema.json is generated by the contract tasks. Their drift check compares the generated schema with the checked-in definition. The service contract owns HTTP framing and routes.
Representation and compatibility
Every request/query carries version 1, the current contract definition and its
realm. The generated schema's x-transit.definition owns that identifier.
Signatures bind it; query responses and persisted authority heads require it.
Missing or foreign persisted definitions reject before reading their catalogs.
The definition is the exact identifier string; enum ordinals, numeric strings,
all-zero fingerprints and JSON numbers are not alternate spellings.
Principal, process, resource,
view, receipt, output and effect identities use 64-bit fields, with the public
numeric address space capped at 2^53−1. They are values, never resident array
offsets. Commands cannot infer an identity from a catalog slot. Sequence zero is
invalid for mutations; read queries use a separate signed type/domain.
Mutation signing hashes transit.request.v1 followed by a NUL and canonical typed
JSON. Read signing uses transit.query.v1 followed by a NUL. Ed25519 signs that
SHA-256 digest. Include defaults/nulls, retain declaration order and use compact
UTF-8 JSON with decimal integers and single-key union objects. Opaque values use
the existing owned lowercase-hex encoding. Validators reject unknown versions,
oversized integers, malformed values, duplicate mutation keys and ambiguous key/
cursor queries before signing. Canonical logical requests are bounded at 16 KiB,
including the immutable block descriptors. Fixed byte arrays remain JSON arrays
regardless of whether their contents happen to be UTF-8. Large block bodies use
a separate transport budget and are excluded from authority journal records.
Incompatible signatures, histories, checkpoints, cursors and saved operations reject; no fallback decoder, alternate route or automatic migration exists. The versioning policy requires matching builds and preservation of original recovery material across a hard cutover.
Current identity observation
The declarative_authorization capability exposes the shared
role, credential and grant model. Its signed
authorization command/query variants provide revision-checked administration,
current decisions and scoped inspection. Credential and privilege records are
separate; native permission masks are derived from current graph grants.
The identity read returns the authenticated principal, current coarse
permission bits, optional PID scope and policy revision, at the enclosing
response's authority position. It requires current inspect permission and
uses the normal v1 signed-query domain. It exposes no signing key or resource
grant and does not authorize a later operation by itself.
Inspection clients can require exactly read-only permissions, then request bounded catalog pages at that same position. A grant change expires that cut; clients must not join the old identity observation to a newer page. Current resource grants continue to filter resource discovery independently. Grant expansion and revocation invalidate existing cuts; stale cuts fail explicitly. Board uses real signed HTTP for these observations; its scoped inspection profile does not acquire mutation authority.
Bounded operations over growing collections
A turn proposes up to four small metadata mutations and sixteen immutable block mutations in one writable associated resource, four view identities and four outputs, with optional captured effect intent. The block batch contains at most 128 KiB, with at most 64 KiB per block. The block contract defines checksums, ownership, source-qualified reads and publication semantics. Keys and association names are 1–32 bytes; individual values retain their 256-byte bound. These are per-operation bounds, not limits on resource rows, processes, principals, retained calls or receipts. Large logical results require explicit segments and complete-result evidence above these bounded records.
Capabilities must report the configured required-resource and lifetime-owner graph validation budgets. This profile requires quiescence of an owner and its borrowers before changing that owner's required dependency topology; it rejects changes that could invalidate an existing borrower's admitted work budget. These are explicit operation/admission constraints, not limits on total realm catalogs. The core guide describes the current defaults and restrictions.
Entry reads select exactly one basis: a caller-owned durable view ID, or a resource ID with an explicit current revision. The authority owns the root corresponding to a view; clients never supply roots. Each view read rechecks current grants, activation, dependencies and view lifetime. Current-resource reads recheck grants, scope and lifetime and reject a changed resource revision. They do not pin old state. Direct key lookup and an exclusive key continuation are mutually exclusive.
With retained_read_versions, a turn can atomically retain committed source
views for later inputs and replacement activations. The
turn_with_versions contract supplies bounded, currently
authorized historical reads.
Retaining a version does not extend owner/source expiry or grant access.
Pages contain at most eight records. A non-null cursor permits another read; only a null cursor establishes completion. Catalog continuations require the first response's authority position; any change expires that cut rather than mixing revisions. Association listing uses revision IDs as cursors so filtering cannot disclose hidden names in a continuation. Filtered pages may be empty with a non-null cursor. Resource and association metadata require resource inspection rights; reading values additionally requires read rights. A retained root/view is never a bearer capability. Each successful response validates that its authority tail still matches the policy/read basis before disclosure. The response may arrive after a later revocation; it grants no subsequent read authority.
With the association_lookup capability, a query can resolve one association by
PID and exact name without a catalog continuation. It enforces current PID scope
and target inspection rights, returning null for either absence or a hidden
target. It uses the same final authority-tail fence as paged discovery. The
client validates the returned PID, name, resource and association revision.
With resource_read_access, the read_access: resource_id query
returns current active resource metadata only after checking both inspect and
read resource rights, the caller's current native identity/PID association
scope, and resource/dependency lifetime. It uses the normal signed-query domain
and final authority-tail fence. It neither reads entries nor retains a version.
The signature may be retained and resubmitted as evidence of the caller's
current read authority; every submission rechecks current keys and grants.
Revoking read denies this query even when resource metadata remains readable.
It grants no authority to a later read or mutation. Clients must require the
capability and reject a peer that does not supply it.
With resource_read_batch, read_entries acquires one to eight distinct keys
from one resource in a single authorized observation. Its fixed eight-slot
keys array is a nonempty contiguous prefix followed by nulls. The response
contains active resource metadata and eight corresponding optional entries;
null at a requested slot means that key was absent at the returned revision.
Unrequested slots are null. Input order is preserved, without sorting or a
continuation. Optional revision requires that exact current revision; null
selects the current cut. This does not retain a version or permit stale reads.
An optional view selects an existing captured owner view while resource and
optional revision bind its exact resource. The response includes that view.
This path checks current process scope, executable ownership, generation,
resource authorization and view lifetime before reading and again before
returning. Keys are evaluated together at the captured catalog root; current
resource revisions do not replace the captured cut. A null view selects current
resource reads and returns a null view. Neither form grants or retains authority.
The query uses the existing signed-query domain, native PID association scope, current resource inspect/read permissions, dependency/lifetime checks and final authority-tail fence. Its memory and read work use the existing eight-entry page budget; mutation limits are unchanged. Clients validate slot/key identity, entry revisions and active resource metadata. They require the capability and reject a peer that does not supply it. Acquired bytes are one observation, not an authorization cache for later disclosure.
Process lists expose recorded metadata. An individual process read checks current execution eligibility before releasing its next mailbox input. Required dependency expiry may fence execution before background work materializes terminal metadata; these two observations must not be presented as equivalent readiness claims.
With leased_snapshots, open_snapshot, snapshot_entries and close_snapshot
provide bounded, volatile read snapshots independently of worker ownership and
durable retained versions. Current authorization still gates every read. The
interactive query contract
specifies tokens, leases, admission quotas, restart and cancellation semantics.
With scoped_retry, a current PID-scoped administrator can retry a blocked input
using retry: {pid, expected_generation, failure_input}. Process.failure
identifies the failed input in this profile; the generation distinguishes repeated
failed attempts at that same input. Retry clears the block, advances the generation
and removes ownership without consuming input or publishing application state.
It rechecks current work lifetime and required dependencies, cannot revive a
retired process, and does not authorize execution. Fresh ownership is a separate
operation. Permission, generation or failure-identity mismatches reject atomically.
Current inspection may disclose blocked process metadata with input: null;
that observation grants no permission to execute the retained head input.
A blocked handler does not close its mailbox: current send permission, work
lifetime and required state still govern admission behind the failed head.
Retry cannot move those later messages ahead of it.
Framework code should read individual keys or bounded batches through this interface, retaining private mutations for one final authority decision. It must not fetch the entire resource as a prerequisite to invoking a handler. Query computation remains in the caller. The kernel validates dependencies and effects; it does not execute application computations.
Integration obligations
Finite deployments may configure a journal admission ceiling and a separate
control-reserve band in genesis. These fields are exposed in signed capabilities;
they are independent of row cardinality, retention and resident pages. At the
ceiling new obligations fail with AdmissionClosed; at the end of the reserve
new control mutations also fail with ControlCapacity. Exact accepted retries
and currently authorized reads remain available. Neither trim nor restart resets
this accounting. The authority guide
defines allowed reserve operations, capacity limits and failure behavior.
Delivery resolves one retained output under current courier authority. Pending
route order is per source/destination pair; a later output cannot bypass an
unresolved predecessor. Admission or terminal disposition releases that route.
Process termination/known expiry immediately fences unattempted work; individual
outbox/effect metadata may await bounded disposition. cancel_effect is an
administrative operation restricted to an unattempted intent of a terminal caller.
It cannot cancel an authorized attempt or claim that external work stopped.
Authorized effects retain their executor, attempt, observation budget and optional
deadline independently of caller retirement. Finite callers require a finite
reconciliation deadline. The executor's current effect permission is required
for new observations; an administrator with effect permission can close an orphaned
attempt. A result after caller retirement remains evidence and cannot revive that
PID. The native effect record retains the authorization grant revision, the
last observation's input and grant revision, and terminal closure provenance.
Closure distinguishes observed, observation_budget, abandoned, deadline
and unattempted_cancel; it records the resolving principal and grant revision.
Deadline closure additionally retains the trusted sample's lower bound, which
must meet the original reconciliation deadline. These fields are committed with
the phase and closure position. Reads reject inconsistent phase/observation/closure
combinations. Current policy changes, exact retries and checkpoint recovery do
not replace the original evidence. Opaque result bytes remain connector-owned.
Closed attempts reject new results; exact historical retries still require
current permission. The growing engine currently enforces these rules internally;
the explicit HTTP profile exposes them. A separate node maintenance process
materializes terminal dispositions with bounded scans. Maintenance latency depends
on scan budgets and catalog size; there is no fixed lag bound. See
deployment for runtime requirements.
The immutable catalog is the storage basis. One conditional journal decision must publish state roots, mailbox progress, outputs, principal sequence and retry evidence together. Staging does not accept work. Recovery must consume published roots without dispatching effects or executing handlers. Unlimited retention requires growing durable receipt, wait and result history; cache eviction cannot authorize deletion.
The checkpoint command requires explicit realm/application
allow_history_trim genesis opt-in; unlimited journal history remains the default.
Capabilities distinguish support for root-history reclamation from the selected
retained-history policy. The checkpoint publication records a monotonic floor
that retains its own complete root-bearing journal entry. Trusted maintenance
verifies committed intent and root snapshot before advancing that floor. It does
not delete catalog pages, receipts, accepted inputs, values or captured roots.
Checkpointing does not expose a public history query. Physical segment collection
uses the separate storage fence and ownership traversal described below.
Conditional local worker replacement
create_principal and capability-gated rotate_worker both require
root authorization. create_principal takes the existing Grant fields but
refuses any previously allocated subject, including a revoked one. Exact retries
retain their original receipt; a fresh operation cannot overwrite another
installation's identity.
rotate_worker requires an executable PID, its exact prior generation and a
PID-scoped worker with the expected current public key and permission mask.
The worker must retain inspect/execute rights. One native decision replaces its
key, advances ownership and records its policy revision. Its signed sequence
and private role remain unchanged, while its credential epoch advances:
rotation cannot renew a removed
resource permission. It rejects an unchanged key, revoked worker, foreign scope,
stale generation, blocked process or permanent retirement. A revocation racing
prepared activation fences its conditional journal append.
This operation preserves PID, resources, mailbox, state, permit and outputs; it is eligible for the existing finite control reserve. It neither launches a worker nor declares application compatibility. The local manager attributes bootstrap evidence and checks artifact/configuration compatibility separately. Ordinary direct-native grant replacement retires the previous private role and binds a new one, invalidating its old resource rights. Named logical roles use the explicit credential-binding and rotation operations instead.
Capabilities report runtime bindings, resource and retained-read support,
configured dependency budgets and history-reclamation policy. Only genesis
opt-in allows a public checkpoint. A trusted --maintain process authenticates
current realm-wide control authority, verifies committed intent and performs
physical journal trimming. Its interval cannot authorize retention by itself.
The station capability identifies support for the native ownership, resource
and retained-read operations used by Station. Station runs above native authority;
the kernel does not execute or validate application handlers.
Runtime binding and readiness
runtime_intent, runtime_observe, runtime_upgrade and activate bind physical
placement to a recorded process operation, revision and provider incarnation.
Resource names remain permanently reserved after retirement. Activation fences
stale observations, replaces the scoped worker key while preserving its signed
sequence/resource-grant epoch, and records the current generation. A bound PID
cannot use direct own or rotate_worker. The
runtime contract owns provider attribution.
create declares up to four required association names and starts uninitialized.
initialize validates those resources and fences the generation before execution.
suspend records a finite resume deadline and revokes execution; resume requires
that generation, current dependencies and a stopped provider binding. Expired
suspensions retire permanently and account for unconsumed input as cancelled.
A failed turn fences the owner and activation while preserving its pending input.
An explicit retry validates the recorded failure and current dependencies.
Payloads and working-catalog collection
declare_payload records an immutable digest, byte length and publisher. Values
are limited to 64 KiB and finite process lifetimes reject standalone payloads.
Only that publisher can record payload_ready. Deletion requires creation-time
allow_delete, process retirement, retire_payload and confirmed
payload_deleted evidence. Physical I/O belongs to the backend payload store.
spawn.allow_collection or create.process.allow_collection opts into working
catalog collection before admission; the default is false. collect identifies
one process and an output, effect, payload, resource or process record. Pending
outputs, unresolved effects and payloads without confirmed deletion reject.
Delivered inputs own their values and origins, so collecting an output cannot
erase an accepted destination message.
Resources must be retired. Live views, retained read versions and associations from running consumers block removal. Cleanup detaches retired associations and removes at most eight entries or grants in one command. Process collection requires permanent retirement, a stopped provider operation, resolved related work and removed owned/written resources. It closes unusable views, releases retired caller versions and removes mailbox pages before leaving a permanent identity tombstone. Maintenance rotates bounded scans and rechecks every gate through a signed command. Restart resumes from committed catalog state.
Collection does not delete journal receipts or immutable storage pages, and cannot recycle a PID or provider reservation. History trimming remains an independent genesis opt-in. Neither capacity pressure nor storage failure grants retention permission.
HTTP boundary
POST /v1/command accepts SignedRequest and returns the shared positive-position
Receipt. POST /v1/query accepts the separately signed SignedQuery and returns
Response. Generated route/type metadata owns both. Requests remain bounded by
the service body/deadline limits, and no legacy-route fallback occurs. Typed
rejection responses distinguish conflict, denial, invalid proposals and uncertain
service/clock failures. Transport loss, malformed success and response allocation
failure after acceptance cannot authorize a new mutation sequence.
Both signed envelopes require the body's explicit current definition field.
Decoding rejects a missing or foreign definition before authentication or
execution; it never fills one from the current build. This also applies to
signed envelopes nested in saved caller artifacts. The construction defaults
on unsigned authoring types apply only before signing a new request.
The growing listener uses the bounded HTTP serving profile
with sequential connection reuse. A client can send X-Transit-Control: snapshot
for close_snapshot or snapshot_read with finish: true to use reserved control
admission. Other query kinds with that hint reject as InvalidRequest; unknown
values and duplicate hint headers reject. The hint is unsigned scheduling metadata,
never permission or evidence that release succeeded. Signed checks and uncertain
transport outcomes are unchanged.
Client response validation checks version/realm, query variant, requested IDs, resource/view revision basis, safe integer range, dense ordered pages and advancing continuations. Empty filtered catalog pages can legitimately advance. Output IDs have their own sequence and are not journal coordinates. These checks reject a malformed response; they do not replace an authenticated deployment boundary or prove that a compromised authority reports truthful application data.
The snapshot_read capability combines bounded captured data and
current metadata with snapshot acquisition or final validation/release. Its
range budget is independent of the ordinary eight-record page and mutation
budgets. See combined snapshot reads
for exact bounds, separate source/current bases and final authority validation.
Physical storage maintenance
storage_fence requires current realm-wide administrative authority and trusted
time. It advances the stored storage epoch in one normal signed acceptance.
Prepared candidates use the observed epoch and position; an intervening fence
makes their original publication fail. A later fence can record elapsed read
lease grace before physical deletion. Neither operation changes retention.
storage_compact requires current realm-wide administrative authority. One
acceptance relocates one block or one catalog/policy leaf and path, advancing the
head's durable compaction cursor. It preserves logical values, resource revisions
and retained read versions. It consumes ordinary physical allocation capacity.
Old accepted roots retain their original placement until independently released.
Stored heads require the current definition, storage epoch and compaction cursor. Page/block locations have one current 32-byte opaque definition. There is no preceding-format decoder or implied epoch for an old stored head. Configuration, provider placement and maintenance ledgers never authorize execution or expiry.