Package and deployment operations
The latent CLI packages local bytes, transfers immutable packages and detached
evidence through OCI, checks an explicit local verification policy, and manages
releases, deployments and rollouts through authenticated RPCs. A local client
path is never interpreted as a node catalog path. The node independently checks
its current policy, release lifecycle and runtime requirements.
Local packages and evidence
latent package build --source package-source.json --input-root build-inputs --output-dir package --sbom-inputs sbom-inputs.json
latent package inspect package --output json
latent package verify package --evidence-index evidence/index.json --evidence-root evidence --policy policy.json --tenant example --output json
Build consumes explicitly selected existing bytes; it does not compile source, run package scripts, sign a package or manufacture provenance. The optional SBOM input uses the existing bounded inventory contract. Inspect checks exact package content and supported semantics. Neither command grants publisher trust or permission to execute.
Verify shares the node's publisher, independent builder, tenant allowlist,
capsule identity and SBOM checks. The v1 policy requires exactly one publisher
signature and one provenance entry. It samples the local wall clock once and
creates a diagnostic report with exact policy/evidence identities. Its output
explicitly marks target runtime compatibility as not-evaluated and durable
policy/clock floors as absent. It opens no admission ledger and cannot create a
catalog grant. A successful local check does not predict admission under a
different node policy or lifecycle state.
Package directories retain their exact manifest.json, config.json and
declared layers/ inventory. Detached evidence lives in a separate directory;
its closed index schema names
the expected package digest and explicit manifest/configuration/payload files
for signatures, provenance and SBOMs. Empty arrays mean explicit absence.
Selection rejects duplicate JSON keys, unknown fields, null arrays, duplicate
paths, duplicate referrer identities and nonportable paths. Descendants are
opened from one approved capability root without following symlinks; regular
file size and consistency are checked before and after reading.
The CLI limits a package to 64 MiB of layer bytes and each layer to 32 MiB,
including the qualified Angular renderer.
Detached evidence has a separate 16 MiB aggregate ceiling, at most eight entries
per kind, a 16 KiB index, 4 KiB referrer manifests and exact {} configuration.
Signature payloads are at most 4 KiB, provenance payloads 48 KiB, and SBOM
payloads 1 MiB. The existing evidence codecs impose their additional semantic
and cryptographic limits. These are byte/owner limits, not a process RSS claim.
OCI transfer
latent package push package --registry-profile registry.json --reference candidate --evidence-index evidence/index.json --evidence-root evidence
latent package pull --registry-profile registry.json --reference candidate --output-dir received-package --evidence-output received-evidence
The closed registry profile contains an origin, repository, bounded numeric socket addresses, optional credential-file reference and optional DER CA-file references. This CLI shape selects the static transport. Challenge-based Bearer, DNS and redirect configuration is available through the Rust network API; those fields are not accepted in this CLI profile. Those relative files are read below the profile's parent using the same regular-file, no-follow boundary. Credentials are separate from node management tokens and use the closed credential file schema. HTTPS is required except for explicitly enabled numeric loopback HTTP fixtures. The existing OCI adapter enforces origin/repository scope, TLS identity, credential handling, exact byte hashes, finite transfer ownership and bounded referrer discovery.
Pull resolves a mutable tag once, then uses its immutable digest. Returned
registry package leases remain held while the client inspects and exports the
bytes. Output directories must be new; no existing output is overwritten.
Evidence exports publish index.json last, and an incomplete export is not
reported as a complete package/evidence result.
Push publishes package and referrers as separate registry operations. A partial
transfer preserves known completed digests and an uncertain remaining outcome;
there is no registry transaction across those publications. No command retries
a mutation automatically. The command uses one absolute transfer deadline
(--rpc-timeout-ms, default 60 seconds) and observes interruption. Actual
registry cleanup has a separate bounded shutdown interval; canceling a wait
does not prove that a remote upload was undone.
Managed deployment receipts
Managed Apply/Delete requires a caller-retained operation ID, explicit object
generation and explicit catalog state version. Actor and tenant come from the
authenticated principal. Use deployment get --operation-snapshot to read the
object and global state version from one publication, including when the
object is absent. An ordinary Get preserves the existing read path and does
not fabricate a snapshot precondition for unsupported adapters.
The operation ID, action, actor, tenant, normalized request and both preconditions bind a compact receipt. Routes, desired deployment state and the receipt are published in one atomic catalog replacement. Exact retained replay returns that original receipt before checking current state or execution eligibility; it publishes nothing. Changing any bound request field conflicts. Delete receipts remain available after the object disappears or is recreated.
The ring is finite. Unknown covers never seen and evicted operations; it does
not mean that a request never ran. Requiring the original monotonic state
version prevents an evicted create request from running again after a later
Delete makes the object generation zero. Unrelated catalog writes can therefore
cause an explicit state-version conflict. The client must not silently fetch a
newer precondition or generate a replacement operation ID.
Managed requests are at most 64 KiB of retained typed input and receipts at most 4 KiB. The default ring retains 256 receipts (hard maximum 1,024) within one 8 MiB shared metadata allowance for live/next tables, preparation scratch and retained replies. Read owners are finite. Preparation uses the existing single control-publication slot; no deployment worker, listener or timer is added. Every catalog writer and rollout action preserves the operation ring. The catalog writes publication-aware format 5, format 6 with capability bindings, or format 7 with HTTP route state. Obsolete formats 1 through 4 are rejected before recovery cleanup; there is no reader or migration fallback. See the current persistence contract.
Audit and uncertain results
Managed deployment mutations require configured audit and never fall back to
an unmanaged mutation when that support is unavailable. The server checks the full
response and audit envelope sizes before durable acceptance. After acceptance,
marking mutation started and committing the prepared catalog are synchronous,
with no intervening await. Caller loss after commit can leave an audit outcome
Unknown; the retained catalog operation receipt remains independently
inspectable. Startup reconciles exact managed deployment receipts before the
generic release-audit fallback, including when rollout management is disabled.
Keep three separate facts: which catalog publication was selected, whether its directory synchronization was confirmed, and whether its audit conclusion was durably acknowledged. A timeout or lost response is not evidence of rollback. Use the original operation ID for explicit lookup before deciding what to do. Delete keeps its existing Empty protobuf response and carries bounded operation and audit metadata; a separate lookup returns the full compact receipt.
Contracts and SDK scope
The deployment service, release service, rollout service and audit service are authoritative. All six external SDK clients implement the bounded shared client profile, with native authenticated loopback transports and invocation, policy/provider inspection, preconditioned management and operation recovery. Their common semantic fixtures and real-node transport checks cover identity, cancellation and explicit shutdown. Guest capability bindings are a separate component SDK.
Validation uses compact file, policy, catalog, RPC and separate client/node registry workflows. Heavy catalog/benchmark runs remain opt-in.
A rollout candidate manifest must have generation zero and a route weight equal
to the first value in --weights. The CLI preserves the supplied manifest. For
example, --weights 1000,10000 starts with a candidate weight of 1,000 basis
points; a later explicit advance or healthy promotion selects the next stage.
The maintained workflow runner uses two small compatible capsule revisions and a disposable authenticated TLS registry. It checks exact rebuild and evidence transfer, current-policy verification, publication, deployment and rollout recovery, explicit canary decisions, audit pagination and restart. Client output and node storage occupy different temporary directories; child processes and registry cleanup have finite owners and deadlines. CI runs this after the existing Rust tests and reuses their build outputs.
Its explicit ignored export_operator_workflow_fixture policy test creates
fresh publisher and independent builder keys in memory, emits only signed test
evidence and public trust configuration, and requires a new directory selected
by LSF_OPERATOR_FIXTURE_ROOT. The signed observation is synthetic test data;
the separate observed-build/OCI integration remains the evidence for actual
source capture and tool execution. No private key, registry content, node
catalog or full process log is retained by the workflow runner.