Artifact Delivery HOWTO¶
This HOWTO keeps the operational reference, configuration details, schema map, routing rules, and sequential examples. The shorter Artifact Delivery FAQ is the conceptual entry point.
What is Artifact Delivery?¶
Artifact Delivery is the host-owned delivery and inbound admission plane for
schema-bound artifacts. A component submits one artifact-delivery-envelope.v1
request to the host capability artifact.delivery.send; the host validates the
envelope, checks outbound permissions, expands the delivery plan, resolves
recipients, selects concrete transport adapters, executes the transport, records
the result, and exposes status to the operator.
The important boundary is that components express delivery intent, not transport mechanics. A middleware component does not need to know whether a public artifact should be published through Agora, whether a private artifact should travel through INAC over an authenticated WSS peer session, or whether a future mailbox adapter is available. The daemon owns that routing and records the resulting delivery in the Artifact Delivery ledger.
Artifact Delivery also owns inbound admission. Artifacts arriving from transport adapters enter one shared admission path, where the host checks byte identity, source-adapter policy, idempotency, and the single-owner acceptor registry. A given artifact schema/content-type class is accepted by at most one authoritative acceptor. If a domain needs fan-out, that domain acceptor must own the fan-out behind its own contract.
Data is transformed in a deliberately staged way. On egress, component-local JSON
is first normalized into a delivery envelope, then into an expanded dispatch plan,
then into adapter-specific transport requests. On ingress, transport frames such
as inac-control.v1 are converted into an inbound admission request, then into
one domain acceptor invocation. The artifact bytes are expected to remain
byte-identical across those transformations.
flowchart TD
Middleware["Middleware or node-attached component"]
HostCapability["artifact.delivery.send host capability"]
AD["Artifact Delivery runtime"]
Ledger["SQLite delivery ledger"]
Routes["Routes, defaults, groups, outbound allows"]
Resolver["Recipient resolver"]
Selector["Transport selector"]
Agora["Agora publish adapter"]
INAC["INAC direct adapter"]
Peer["Authenticated WSS peer session"]
Admission["Artifact Delivery inbound admission"]
Acceptors["Single-owner acceptor registry"]
Domain["Domain acceptor"]
Operator["Operator APIs and UI"]
Middleware --> HostCapability --> AD
AD --> Ledger
AD --> Routes
AD --> Resolver --> Selector
Selector --> Agora
Selector --> INAC --> Peer
Peer --> Admission
INAC --> Admission
Admission --> Acceptors --> Domain
AD --> Operator
Admission --> Operator
What is the rationale behind Artifact Delivery?¶
Artifact Delivery exists to avoid making every component a transport owner. INAC, Agora, peer sessions, retry loops, route tables, and inbound admission are host concerns; a component should not duplicate that machinery just to move one artifact.
The layer also keeps authority visible. A valid artifact schema is not enough to send an artifact. The sending component must have an explicit outbound allow for the artifact schema, route references, selector classes, target node ids, size limits, fan-out limits, and fallback limits that apply to the resolved plan.
The inbound side has a similar discipline. Inbound artifacts are admitted through a single shared path and dispatched to exactly one authoritative acceptor. This prevents middleware-chain ambiguity: the same artifact should not be silently accepted by several unrelated modules that each interpret it differently.
Artifact Delivery is also a stratification boundary. INAC remains the private/direct node-to-node transport adapter under AD, Agora remains the public/federated record substrate, and Memarium remains local custody. AD does not replace those components; it coordinates the host-owned movement and admission of artifacts between them.
What components use Artifact Delivery?¶
node/artifact-delivery-coreprovides the pure contract layer: envelope DTOs, plan validation, route expansion, recipient resolution, target deduplication, outbound authorization, deterministic delivery ids, and failure classes.node/artifact-deliveryprovides the runtime layer: adapter registry, referenced payload resolution, synchronous submit, deferred submit, delivery ledger, recovery, inbound admission registry, and admission ledger.- The daemon exposes
POST /v1/host/capabilities/artifact.delivery.send,GET /v1/artifact-delivery/routes,GET /v1/artifact-delivery/deliveries,GET /v1/artifact-delivery/deliveries/{delivery_id},POST /v1/artifact-delivery/recover?limit=...,POST /v1/artifact-delivery/admissions,GET /v1/artifact-delivery/admissions, andGET /v1/artifact-delivery/admissions/{admission_id}. - The daemon registers the
agora-defaultpublish adapter for signedagora-record.v1artifacts. - The daemon registers the
inac-directadapter for local INAC short-circuit delivery and remote INAC delivery over authenticated WSS peer-message sessions. - The daemon can register
matrix-mailboxandobject-store-indirectadapters for sealed mailbox control delivery and larger object-store-backed payloads when those adapters are enabled. - Remote WSS INAC
pushframes feed Artifact Delivery inbound admission on the receiver. - Supervised HTTP middleware,
ad-hostin-process acceptors, and explicitly configured pure JSON-e Flow acceptors can receive inbound artifacts through the acceptor registry. The daemon supplies effect shims, but does not own the AD acceptor implementations. - Node UI exposes
/admin/artifact-deliveryfor route, adapter, recovery, delivery, and admission visibility.
How can middleware use Artifact Delivery?¶
Middleware can use Artifact Delivery in two directions: outbound send and inbound
acceptance. Outbound send means the middleware calls the host capability
artifact.delivery.send with an artifact-delivery-envelope.v1. Inbound
acceptance means the host calls a registered acceptor after an artifact arrives
from a transport adapter and passes admission checks.
Outbound use always requires the caller to be an authenticated middleware module:
the daemon checks that component/id in the envelope matches the authenticated
module id. The runtime then checks the host-level outbound allow table. Inbound
use is configured by the operator through artifact_delivery_acceptors; the
current implementation does not infer Artifact Delivery acceptors directly from a
module report.
Built-in Rust middleware¶
Built-in Rust components can be wired directly by the host when the behavior is
host-owned and deserves to live in the trusted process. For outbound delivery,
host-composed Rust code can build a DeliveryEnvelope and call the runtime or
the same host-capability path used by middleware. For inbound delivery, ad-host
builds in-process acceptors from artifact_delivery_acceptors.in_process; the
daemon supplies only concrete effect shims such as local INAC admission,
Memarium custody, contact-request persistence/notification, and middleware
surface calls.
The currently supported in-process acceptor invoke target is inac.push. It is
used to feed admitted artifacts into the local INAC runtime without going through
loopback HTTP.
{
"artifact_delivery_acceptors": {
"in_process": [
{
"acceptor_id": "acceptor.inac.push",
"artifact_schema": "agora-record.v1",
"content_type": "application/json",
"invoke": "inac.push"
}
]
}
}
Supervised HTTP middleware¶
Supervised HTTP middleware can send artifacts by calling the daemon host
capability endpoint with its normal module capability authentication. It submits
one envelope and receives either artifact-delivery-result.v1 or, when using
?mode=deferred, deferred-operation.v1.
POST /v1/host/capabilities/artifact.delivery.send HTTP/1.1
Content-Type: application/json
{
"schema": "artifact-delivery-envelope.v1",
"component/id": "story005-whisper",
"artifact": {
"schema": "agora-record.v1",
"content/type": "application/json",
"digest": "sha256:EXAMPLE_DIGEST",
"size/bytes": 512,
"bytes/base64": "eyJzY2hlbWEiOiJhZ29yYS1yZWNvcmQudjEifQ=="
},
"delivery/plan": {
"route/ref": "public-agora"
},
"idempotency/key": "whisper:candidate:example"
}
Supervised HTTP middleware can also be an inbound acceptor. The operator registers
the acceptor in host config, and the daemon calls the component-local
invoke_path with an artifact-delivery-acceptor-invoke.v1 payload.
{
"artifact_delivery_acceptors": {
"supervised_http": [
{
"acceptor_id": "acceptor.whisper.private",
"component_id": "component/middleware/whisper",
"artifact_schema": "agora-record.v1",
"content_type": "application/json",
"invoke_path": "/v1/artifact-delivery/accept",
"request_timeout_ms": 5000,
"max_response_bytes": 65536
}
]
}
}
Sensorium OS Actions¶
Sensorium OS Actions are not Artifact Delivery acceptors by themselves. They are
actions behind the Sensorium OS connector, so the recommended current pattern is
to let a role flow or supervised middleware call Sensorium, receive the action
result, build an artifact envelope, and then call artifact.delivery.send.
This keeps the OS action focused on local sensing or execution while the host
keeps delivery, authorization, route selection, and retry semantics. In the
hard-MVP runtime, sensorium-os only executes script-backed C1/C2 entries from
the authorized catalog. Artifact-producing, filesystem-write, network-egress,
composed, or operator-gated action classes remain visible but unavailable and
fail closed until their enforcement envelopes exist. If an available action
returns deliverable content, return bounded JSON or bytes to its caller; the
caller should wrap that output in a schema-bound artifact and use AD.
JSON-e Flow or supervised role middleware
-> sensorium.directive.invoke
-> normalize action result
-> artifact.delivery.send
The Sensorium HOWTO covers the action catalog, directive, consent, Workbench operation, and artifact handoff boundaries in detail.
Sensorium Workbench Operations¶
Sensorium Workbench operations do not become Artifact Delivery senders or acceptors merely because they produce or consume artifacts. Workbench owns the local workspace, terminal, file, patch, and sandbox effect. Artifact Delivery owns transport, recipient admission, route selection, retry, and delivery evidence.
On the outbound path, terminal output remains ephemeral until an explicit
capture operation persists it. Terminal capture requires both the scoped
terminal-read grant and a separate artifact-write grant. The resulting local
artifact is not sent implicitly: an explicit handoff resolves it through the
host object boundary and submits a schema-bound envelope to
artifact.delivery.send.
On the inbound path, successful AD admission proves that the expected artifact
was delivered and accepted as an artifact. It does not authorize Workbench to
apply a patch or execute content. Patch application separately verifies the
artifact digest, size, and provenance, workspace containment, the
sensorium.workbench.patch grant, and any required operator approval or active
lease.
Workbench capture/export
-> local artifact ref
-> explicit artifact handoff
-> artifact.delivery.send
AD admission of patch artifact
-> verified artifact ref
-> separate Workbench patch admission
-> patch.apply
This preserves the central classification rule: possession or delivery of an artifact is not authority to cause its local effect. Detailed Workbench policy belongs to Solution 042.
JSON-e Flows¶
JSON-e Flow middleware can use Artifact Delivery outbound by listing
artifact.delivery.send in allowed_calls and using a host-capability call step
that renders an artifact-delivery-envelope.v1. This is useful for bounded
low-code adapters that need to publish or transfer an artifact after rendering a
small JSON value.
{
"id": "example.artifact.sender",
"module_id": "example-artifact-sender",
"component_id": "example-artifact-sender",
"profile_version": "orbiplex.json_e_flow.v1",
"allowed_calls": ["artifact.delivery.send"],
"steps": [
{
"id": "send",
"kind": "call",
"capability": "artifact.delivery.send",
"input": {
"schema": "artifact-delivery-envelope.v1",
"component/id": "example-artifact-sender",
"artifact": "${artifact}",
"delivery/plan": { "route/ref": "public-agora" }
}
}
]
}
JSON-e Flow can also serve as an inbound acceptor, but this acceptor mode is
intentionally pure. The configured flow must have a respond step that yields an
InboundAdmissionResult, and it must not declare host capability calls. The host
compiles this flow once at daemon startup and invokes it inside the admission
boundary.
{
"artifact_delivery_acceptors": {
"json_e_flow": [
{
"acceptor_id": "acceptor.json-e-flow.whisper",
"artifact_schema": "agora-record.v1",
"content_type": "application/json",
"flow_id": "whisper.private.acceptor"
}
]
}
}
How is Artifact Delivery configured?¶
Artifact Delivery configuration is host-owned. A package may ship suggested configuration fragments, but the effective authority comes from daemon config that the operator accepts.
Host-level configuration¶
artifact_delivery is the core delivery policy and route table.
defaultsdefine named recipient selectors that can be referenced from plans.groupsdefine named sets of recipient selectors.routesdefine named delivery plans withroute/id, optionalroute/version, and an inlineplan.outbound/allowsdefine which component may send which artifact schema and through which selector classes, route refs, target node ids, fan-out size, fallback count, and maximum bytes.
artifact_delivery_adapters configures concrete AD adapter behavior.
agora_publish.endpointoptionally overrides the local Agora service endpoint.agora_publish.auth_headeroptionally overrides the auth header name.agora_publish.auth_token_fileoptionally points to the token used by the Agora publish adapter.matrix_mailboxenables and configures Matrix mailbox transport: homeserver, access token, room alias prefix, event type, event payload limit, retention, peer artifact cache, and sealed-payload policy.object_storeenables the daemon-owned object store, root directory, maximum object size, and retention.object_store_indirectenables pointer-based indirect delivery for large payloads and selects its control adapter, fetch base URL, and threshold.
inac_peer_transport configures receiver-side remote WSS INAC transport policy.
inac_peer_transport.enabledcontrols whether remote WSS INAC transport can be used byinac-directtargets.inac_peer_transport.inbound_allowed_peersis the receiver-side allowlist for remote WSS INAC Artifact Delivery frames. Empty means deny-all.inac_peer_transport.contact_requestsis a schema-scoped publiccontact-request.v1admission policy. Fresh service/headless configs keep it disabled withunknown_peer_mode = "deny"; user-mode config materialization explicitly enables the narrowauto-admitcontact-request flow.inac_peer_transport.response_timeout_msbounds the wait for a peer response.
artifact_delivery_recovery configures deferred delivery recovery.
enableddefaults totrue.interval_msis the idle interval between background recovery passes.batch_limitcaps the number of recoverable deliveries processed in one pass.pass_deadline_mscaps one recovery pass.
artifact_delivery_acceptors configures inbound admission.
http_admission_allowed_source_adaptersallows selected source adapters to usePOST /v1/artifact-delivery/admissions; empty means deny-all for that HTTP control-plane path.supervised_httpregisters loopback HTTP middleware acceptors.json_e_flowregisters pure JSON-e Flow acceptors.in_processregistersad-hostbuilt acceptors such asinac.push,agora.record.ingest,memarium.inac.accept,contact.request,corpus.query,corpus.answer,capability-passport-present.accept,capability-proof-presentation-batch.accept, andfederation-service-endorsement.install; daemon-owned code supplies only the effect shims.memarium_blob_custodyselects the local target-space policy for acceptedmemarium-blob.v1custody facts. The sender does not choose this space in the MVP.
artifact_delivery_profiling controls lightweight operator/status counters for
payload materialization and transport profiling.
artifact_delivery_observers enables metadata-only read-only observers, such as
the tracing observer for delivery/admission completion events. Observer failures
do not affect delivery outcomes.
The runtime also creates host-owned storage under the node data directory:
storage/artifact-delivery.sqlite for the delivery ledger and
storage/artifact-store for the initial artifact-store: referenced payload
resolver.
Package-level configuration¶
There is no separate Artifact Delivery package-level authority contract in the current implementation. A middleware package can ship config fragments, templates, examples, or operator instructions, but outbound allows, routes, adapters, recovery policy, and acceptor registrations become effective only when they are present in the daemon's effective host configuration.
This is intentional: package installation should not silently grant artifact send authority or inbound acceptance authority.
Envelope-level configuration¶
The envelope controls only the delivery request, not the host's authority model.
component/idnames the caller and must match the authenticated middleware module id on the host-capability path.artifactdeclaresschema,content/type,digest,size/bytes, and exactly one payload location: inlinebytes/base64orartifact/ref.delivery/plancontains eitherroute/refor inlinestages, but not both.- A stage contains
stage/id, targets, optionalsuccess/policy, optionalquorum/min-success, and optionalon/failure. - Recipient selectors currently include
node,matrix-mailbox,configured-default,group,agora-default,capability-first,capability-many,participant,org,routing-subject,contact-lookup, andobject-store-indirect. policycan carryprivacy,delivery, andtimeout/ms. The runtime records and validates the shape, but full generic enforcement is still route-, adapter-, or acceptor-specific.idempotency/keylets the runtime treat repeated submissions as the same delivery intent.
Deferred mode is not an envelope field. It is selected by calling
POST /v1/host/capabilities/artifact.delivery.send?mode=deferred.
What data shapes are used by Artifact Delivery?¶
artifact-delivery-envelope.v1is the component-facing host capability request. It carries one artifact, one delivery plan, optional policy, and optional idempotency key.artifact-delivery-result.v1is the synchronous response returned after the runtime accepts and attempts a delivery.artifact-delivery-status.v1is the operator/export shape for one recorded delivery run.artifact-delivery-recovery.v1is the operator response after a manual recovery pass.deferred-operation.v1is returned when the caller uses?mode=deferred.deferred-operation-status.v1is exposed at the canonical per-delivery operation-status URL.artifact-object-pointer.v1is the object-store indirect control artifact for larger payloads. The pointer is not authority; receivers verify digest, size, expiry, and policy before admission.inac-control.v1is the transport control frame used by INAC foroffer,request,push, and response/refusal operations.contact-lookup-result.v1is consumed by the host Contact Catalog lookup provider when an envelope usesselector/kind = "contact-lookup".agora-record.v1is the signed record format accepted by the Agora publish adapter.memarium-blob.v1is a signed content-addressed artifact envelope that can be moved through AD and INAC paths.
The daemon also uses daemon-local admission shapes:
artifact-delivery-admission-request.v1,
artifact-delivery-admission-response.v1, and
artifact-delivery-acceptor-invoke.v1. They are implementation contracts of the
current daemon admission surface; they are not yet the primary public
component-facing schema family.
How does Artifact Delivery decide routing?¶
Routing starts from delivery/plan. If the plan contains route/ref, the host
loads the named route from artifact_delivery.routes. If the plan contains
inline stages, the host validates and expands those stages directly.
Each stage contains recipient selectors. The resolver turns those selectors into concrete targets:
agora-defaultresolves to the Agora publish adapter.noderesolves to aninac-directtarget for that node id.matrix-mailboxresolves to a Matrix mailbox target for a node id when the adapter is enabled.configured-defaultresolves throughartifact_delivery.defaults.groupexpands throughartifact_delivery.groups.capability-firstandcapability-manyresolve through the host capability lookup provider.participant,org, androuting-subjectresolve through host subject/org lookup providers.contact-lookupresolves through a host Contact Catalog provider and is currently constrained to lookup-safecontact/index-valuevalues, supported lookup modes,selector/purpose = "contact-request/messaging", andmax/nodes = 1.object-store-indirectresolves to an indirect object-store target for a node id when the object-store adapter and control adapter are enabled.
After resolution, the runtime deduplicates concrete targets and checks outbound authorization for the calling component. It verifies the artifact schema, optional route ref allowlist, selector class allowlist, target node id allowlist, maximum byte size, maximum target count, and maximum fallback stage count.
Transport selection is then exact: a resolved target carries an adapter scheme,
and the runtime invokes the registered adapter for that scheme. The current
adapter schemes are Agora publish, INAC direct, Matrix mailbox,
object-store indirect, and node-local loopback where configured. The stage
success policy (all, any, or quorum) decides whether a stage succeeded.
If it fails and on/failure points to another stage, the runtime follows that
fallback stage.
On the receiving side, incoming transport frames do not bypass AD. Remote WSS INAC frames must pass the receiver-side INAC peer allowlist first, then feed the shared Artifact Delivery admission path. Admission chooses exactly one acceptor by artifact schema and optional content type; exact content-type registrations win over wildcard registrations.
Sequential examples¶
Public Whisper publication through Agora¶
- A middleware component builds a signed
agora-record.v1artifact. Artifact Delivery does not sign it. - The component calls
artifact.delivery.sendwith anartifact-delivery-envelope.v1. - The envelope uses
delivery/plan.route/ref, for examplepublic-agora. - The daemon validates the envelope through schema-gate.
- The daemon checks that
component/idmatches the authenticated middleware module id. - Artifact Delivery expands the route and resolves it to the Agora publish adapter.
- Artifact Delivery checks the component's outbound allow for
agora-record.v1, the route ref, selector class, limits, and artifact size. - The Agora publish adapter verifies that the inline bytes are JSON with
schema = "agora-record.v1"and atopic/key. - The adapter posts the record to the configured local Agora service.
- Artifact Delivery records the delivery id, stage outcomes, status, and any diagnostic data in the delivery ledger.
Private direct delivery through INAC¶
- Node A middleware builds a signed byte-identical artifact, for example a
private
agora-record.v1. - The middleware calls
artifact.delivery.sendwith a plan that resolves to a target node. - Artifact Delivery resolves the target to the
inac-directadapter. - If the target is the local node, the adapter short-circuits into the local INAC runtime.
- If the target is remote, the adapter requires inline artifact bytes and an authenticated WSS peer session to that node.
- The adapter wraps the artifact in an
inac-control.v1pushframe and sends it as peer messagemsg = "inac.v1". - Node B receives the peer message and checks
inac_peer_transport.inbound_allowed_peers. - If the peer is allowed, Node B converts the frame into an Artifact Delivery inbound admission request.
- Admission checks byte identity, idempotency, and acceptor availability.
- The selected acceptor receives the artifact; AD records the admission result on the receiver.
Inbound supervised HTTP acceptor¶
- The operator configures a supervised HTTP acceptor for one artifact schema and optional content type.
- A transport adapter feeds an inbound artifact into Artifact Delivery admission.
- Admission finds the exact acceptor or a wildcard fallback for the schema.
- The daemon builds an
artifact-delivery-acceptor-invoke.v1payload containing source adapter, optional source peer, idempotency key, and artifact descriptor. - The daemon POSTs that payload to the component-local
invoke_path. - The acceptor returns an
InboundAdmissionResult. - Artifact Delivery records the receiver-local admission id and status.
Deferred delivery and recovery¶
- A middleware component calls
POST /v1/host/capabilities/artifact.delivery.send?mode=deferred. - The daemon validates and persists the delivery intent.
- The daemon returns
deferred-operation.v1with a stable operation id and status URL. - The background recovery worker periodically retries recoverable deliveries
according to
artifact_delivery_recovery. - An operator can also call
POST /v1/artifact-delivery/recover?limit={n}to run one manual recovery pass. - The delivery can be inspected through
/v1/artifact-delivery/deliveries/{delivery-id}and/v1/artifact-delivery/deliveries/{delivery-id}/operation-status.