Skip to content

Orbiplex Node

Orbiplex Node is the primary runtime component of the system. It participates in protocol flows, enforces room and policy constraints, preserves provenance, and acts as the main bridge between network-facing protocol semantics and local execution.

Node-scoped roles such as archivist, memarium provider, or sensorium provider are not assumed to be in-process features of a single monolith. They may be implemented as separate programs or processes, written in different languages, as long as they attach to the Node through explicit protocol and API contracts.

The Node's middleware chain (PeerMessageChain) is a trait-based pipeline, not an HTTP pipeline. It supports two handler realization patterns:

  • In-process handlers: Rust trait implementations compiled into the daemon, with direct access to storage, capability registries, and zero serialization overhead. This pattern is preferred for protocol-core and constitutional concerns (e.g. capability passport verification, network ledger updates, memarium observation).
  • Out-of-process handlers: supervised sidecar modules reached through loopback HTTP, with language independence and fault isolation. This pattern is preferred for operator-replaceable extensions (e.g. marketplace workflow modules, content processing).

Both patterns implement the same trait interface and produce the same decision outcomes. The choice is a deployment concern per handler, not a property of the chain architecture. A constitutional organ like Memarium may participate as an in-process chain handler to guarantee co-lifecycle with the daemon while observing and enriching the full message flow.

Host-Service Boundaries

The Node daemon is the host/kernel: it owns config loading, lifecycle, composition, local HTTP routing, and capability-boundary enforcement. Domain mechanics should move into host-service crates only when there is a real contract that can be tested without importing the daemon.

The first split is seed-directory-client: it owns Seed Directory source eligibility, bounded capability/revocation fetch, multi-directory reconcile, and revocation suppression. The daemon maps layered config into that client and keeps operator surfaces and lifecycle. host-vocabulary is a leaf DTO crate for future host-service seams; it must stay free of Axum/Tokio/SQLite and daemon dependencies.

ad-host is the next extracted host-service seam. It is still in-process Rust, but it owns Artifact Delivery runtime composition, recovery worker ownership, Matrix mailbox transport/worker/chunk-store ownership, route/status snapshots, AD-owned transport cache status, the inac-direct, agora-publish, Matrix mailbox, and object-store-indirect transport adapters, the agora-record: and inac-peer-artifact: payload resolvers, the peer-artifact transport cache, the AD tracing observer, and inbound acceptor construction. The daemon remains the kernel for config, lifecycle, local HTTP, and capability boundaries; it calls AdHost rather than reaching into Artifact Delivery runtime internals, and supplies PeerSender, InacAdmissionBridge, middleware, Memarium, contact-request, object-store, and Matrix sealing shims for today's host-owned effects. Future peer-runtime and inac-host components may implement those consumer-side traits natively, while socket/session ownership stays outside Artifact Delivery.

The follow-up split is incremental, not a rewrite. host-capabilities now owns the daemon-free dispatch vocabulary and route-level host contract used by host capability routing. peer-runtime now owns peer endpoint evidence, session worker registries, pending responses, the WSS session worker loop, listener and dialer lifecycle, TLS pin/advisory enforcement, peer snapshots, and the native peer-message sender seam used by AD. middleware-supervisor now owns the daemon-free route contract, the HTTP-local process/runtime adapter, and the peer-message sidecar wrappers installed into that chain; peer transport asks for route/observer specs rather than rebuilding middleware semantics itself, and the daemon supplies storage/SSE effects through explicit handles rather than owning middleware process mechanics. memarium-host is now the Memarium host boundary and concrete implementation used by AD custody, local backup snapshots, and host-capability dispatch; the daemon maps configuration and supplies Memarium runtime, data-dir, and policy inputs as explicit dependencies rather than keeping Memarium host policy or backup mechanics in daemon route/context code. The daemon-local crypto_host handle wraps signer, sealer, service-CA trust, and dispatch-passport sources so route/context code no longer carries raw crypto fields.

The domain integration seams that used to be hidden in the daemon request context are now explicit daemon-local host handles as well. Identity, relationship, catalog, settlement, workflow, scheduler, control, and execution routes delegate through their respective host boundary instead of reaching into mutable runtime maps or storage helpers directly. Control is backed by a durable DaemonControlHost rather than an EndpointRuntimeContext trait implementation. This is an implementation boundary, not a new protocol surface: domain core crates remain the semantic owners, while the daemon hosts wiring, HTTP mapping, and lifecycle composition.

The daemon composes these in-process services once at startup and exposes them to route modules as durable host handles rather than borrowed wrappers over EndpointRuntimeContext. Daemon HTTP routing is cut into domain modules plus a shared common HTTP helper module so route code can depend on the kernel context only for auth, parsing, and the relevant host handle; the former endpoint_routes.rs monolith is now a module registrar/re-export surface rather than a body holder. A route module split is organizational; a host-service crate is accepted only when the crate itself has a daemon-free contract and tests.

Acceptance rule: a new host-service crate is not considered extracted if it imports daemon types such as EndpointRuntimeContext or DaemonConfig.

Purpose

The Node is responsible for the solution-level execution path of:

  • peer identity, handshake, and endpoint discovery,
  • question room lifecycle,
  • federated answer procurement,
  • supervised channel middleware services plus independently owned product HTTP APIs,
  • settlement policy coordination and disclosure trail exposure for paid procurement,
  • local learning and knowledge promotion,
  • archival handoff and retrieval,
  • optional transcript observation and later curation/training handoff.

Scope

This document defines solution-level responsibilities of the Node component.

It does not define:

  • concrete module layout in an implementation repository,
  • implementation details of Node-attached plugin or process roles,
  • rich end-user UI,
  • protocol-external payment execution,
  • default direct mutation of base models.

Local Storage Convention

Based on:

  • doc/project/40-proposals/062-temporal-storage-convention.md

Node-local SQLite stores should follow the accepted temporal storage convention when they persist queues, state machines, accepted public or federated facts, privacy-sensitive workflows, or other state that must be auditable and recoverable.

The convention is:

append-only transactions/events
  -> derived current projection
  -> short transactions around append and projection update

The event log is the durable information model. Current tables are query and UI projections derived from the event log; they are not second sources of truth. A projection row should carry as_of_tx_id, not an independent updated_at, when the component adopts the temporal convention.

Temporal stores distinguish:

  • tx_time — local transaction time controlled by this store;
  • valid_from / valid_until — optional validity interval for facts whose truth has a start and end;
  • domain timestamps such as authored_at, published_at, signed_at, or expires_at — payload attributes, not generic temporal axes;
  • operational timestamps such as started_at, finished_at, retry_after, or lease_until — execution metadata for workers, retries, and leases.

Background workers must not hold database locks while doing network, middleware, signing, sealing, replay, or other external work. When exclusive processing is needed, the worker claims a short lease in one transaction, performs work outside the database lock, and appends the result in a later transaction.

Adoption is selective:

  • use the convention for delivery/outbox attempts, notification state transitions, Seed Directory accepted facts, Artifact Delivery status, Whisper intake stages, and similar audit-sensitive state;
  • keep short-lived caches, idempotency lookups, cursors, and already append-only ledgers simple unless a concrete replay, audit, or forensics need appears;
  • store private workflow history as sealed references, digests, and metadata, not repeated plaintext payloads;
  • rely on correlation_id joins for cross-store sagas rather than introducing a shared transaction registry.

The first Notification state-transition pilot is implemented in the Node reference store. The canonical storage-design guidance lives in doc/project/60-solutions/028-temporal-storage-convention/028-temporal-storage-convention.md. That pilot covers the core event-log/projection shape; the per-store performance profile, compaction, emergency disk-pressure handling, and manifest layer from the solution remain follow-up work. The next recommended migration is Messaging outbox attempts. A shared helper crate for temporal stores should be extracted only after at least two migrations converge on the same shape.

Must Implement

Peer Identity, Discovery, and Session Baseline

Based on:

  • doc/project/40-proposals/002-comm-protocol.md
  • doc/project/40-proposals/014-node-transport-and-discovery-mvp.md
  • doc/project/50-requirements/requirements-006-node-networking-mvp.md

Related schemas:

  • node-identity.v1
  • node-advertisement.v1
  • peer-handshake.v1
  • capability-advertisement.v1
  • capability-schema.v1
  • capability-schema-present.v1
  • signal-marker-envelope.v1

Related solution contracts:

  • doc/project/60-solutions/007-capability-advertisement/007-capability-advertisement.md

Responsibilities:

  • generate or load a stable local node identity,
  • derive and expose a stable node:did:key-shaped node-id,
  • derive and expose a stable participant:did:key-shaped participant-id,
  • resolve the signing key through key/storage-ref rather than inline secret material,
  • publish or consume signed endpoint advertisements,
  • establish signed peer handshakes and capability exchange over the baseline transport,
  • publish and validate the first participant-scoped signed application envelope above the session layer,
  • maintain keepalive and reconnect behavior for the first networked Node baseline.

Note:

  • The v1 node-id is Node-local and intentionally uses a did:key-compatible Ed25519/base58btc fingerprint shape rather than claiming full support for the generic did:key method, DID Document expansion, or generic DID resolution.
  • The persisted v1 identity contract should carry key/storage-ref only; the MVP resolver baseline is local-file:identity/node-signing-key.v1.json.
  • The MVP baseline assumes one operator-participant per Node by default. node-id names the infrastructure role, while participant-id names the participation role; the two identifiers may share the same underlying did:key fingerprint in v1 without collapsing their protocol semantics.
  • The networking slice should need only node-id, participant-id, and the signing or verification material for those roles. Higher identity layers such as anchor-identity, pod-user-id, nym, or federation continuity bindings belong above that slice rather than inside it.
  • The v1 handshake stays node-scoped and uses fresh ephemeral X25519 session keys in session/pub; the static key-agreement contribution is derived from the Ed25519 node:did:key identity for the MVP baseline rather than being re-advertised as separate long-lived X25519 state.
  • Participant authentication belongs to participant-scoped application artifacts carried over that encrypted node-to-node session, not to the handshake itself.
  • The minimal explicit advertised core capability in v1 is core/messaging; successful baseline participation and signed-handshake ability are treated as protocol-native facts rather than mandatory advertised capabilities.
  • WSS/TLS in v1 is only the carrier transport: TLS server authentication protects the endpoint and the channel, while peer identity still binds at the signed peer-handshake.v1 layer; public endpoints should follow normal WebPKI hostname validation, and private trust roots remain deployment-local rather than protocol-visible.
  • Key rotation is not a live continuity feature in the MVP baseline; a new Ed25519 key still means a new node-id, but the operational layer may already prepare a local signed overlap bundle and succession hint without assigning automatic discovery or trust continuity semantics.
  • node-advertisement.v1 may already carry a future-facing succession object, but the Node does not yet assign it active runtime continuity semantics in the MVP baseline.
  • In the MVP baseline, thin clients or remote UI sessions are delegated operator sessions of that same participant role, not independent hosted users with their own continuity layer.

Status:

  • done for hard-MVP — the Node reference implementation has stable node and participant identity, signed advertisements and handshakes, encrypted WSS sessions, advertisement cache, peer supervisor, replay guard, capability downgrade, participant restriction import, durable trace/network coverage, and the participant-scoped signal-marker-envelope.v1 first application slice. Remaining live succession, richer hosted-user policy/read-models above the minimal participant-bind/client-instance lifecycle, richer federation policy, and additional transport work is post-MVP extension work rather than a blocker for the P014 transport seed.
  • P034's local operator-binding lifecycle is implemented through dedicated operator control and Identity UI actions. Revoke and supersede retain signed subject withdrawal with the old binding, repair the local revocation view on restart/retry, and remove inactive bindings from readiness. Supersession uses an already accepted local replacement. This is local lifecycle evidence, not automatic remote propagation or a fresh release qualification; see the P034 checkpoint.

Host Signer and Key-Use Boundary

Based on:

  • doc/project/40-proposals/031-participant-key-passphrase-lock.md
  • doc/project/40-proposals/032-key-delegation-passports.md
  • doc/project/40-proposals/037-generic-signing-service.md
  • doc/project/40-proposals/038-key-roles-and-key-use-taxonomy.md

Related schemas:

  • capability-passport.v1
  • capability-passport-revocation.v1
  • key-delegation.v1

Responsibilities:

  • expose a narrow host signer surface for domain-tagged Ed25519 signing, passphrase-scoped unlock, explicit lock/status inspection, and node-self X25519 Diffie-Hellman derivation,
  • keep artifact canonicalization outside the signer; artifact adapters own the bytes to be signed and the signer owns only key access, policy, audit, and cryptographic execution,
  • enforce caller x domain authorization before key material is touched,
  • keep unlock rate limiting as daemon/operator policy rather than as a signer-service contract,
  • support envelope-backed primary and proxy keys without teaching the generic signer daemon-local storage formats,
  • preserve derived node-self and recovery-org key availability for unattended daemon operation under an explicit MVP deployment assumption,
  • surface locked, unauthorized, bad-passphrase, and rate-limited states through stable local host-capability responses.

TODO:

  • migrate the deployed verifier set to domain-wrapped signatures and then enable domain wrapping by default for signer-routed artifacts,
  • define the post-MVP unattended-secret profile for node-self and recovery-org material, e.g. OS keychain, hardware-backed key store, secrets manager, or explicit operator session unlock,
  • replace label-only local caller identity for less trusted modules with a passport or presentation-backed caller model,
  • expose an operator-facing diagnostic surface for recent denied signer decisions, including caller, domain, key reference, and denial reason,
  • publish concise JSON wire examples for signer.sign, signer.unlock, signer.lock, signer.status, and signer.derive-shared-secret,
  • keep settlement and marketplace passport fixtures separate from the signer backlog; missing role passports such as role/escrow are authorization data issues above the signer, not signer engine defects.

Status:

  • partial

Question Room Lifecycle

Based on:

  • doc/project/30-stories/story-001-swarm-node-onboarding.md
  • doc/project/30-stories/story-004-pod-client-onboarding.md
  • doc/project/50-requirements/requirements-001-node-onboarding.md

Related schemas:

  • question-envelope.v1
  • answer-room-metadata.v1
  • response-envelope.v1

Responsibilities:

  • open or bind a room to question/id,
  • enforce exposure mode and room policy profile,
  • preserve provenance across room outputs.

Status:

  • partial — the selected-responder MVP path opens and tracks question executions, persists transition facts, and closes response delivery with receipt/settlement joins. Open collaborative room semantics remain deferred.

Federated Answer Procurement

Based on:

  • doc/project/30-stories/story-001-swarm-node-onboarding.md
  • doc/project/40-proposals/011-federated-answer-procurement-lifecycle.md
  • doc/project/50-requirements/requirements-001-node-onboarding.md

Related schemas:

  • service-offer.v1
  • service-order.v1
  • procurement-offer.v1
  • procurement-contract.v1
  • procurement-receipt.v1
  • gateway-policy.v1
  • escrow-policy.v1
  • settlement-policy-disclosure.v1

Responsibilities:

  • expose standing service-offer discovery and buyer-side service-order ingress for marketplace-style exchange,
  • own the bridge from service-order.v1 into the currently executable selected-responder procurement substrate,
  • collect and evaluate offers,
  • select responders under policy,
  • record contracts and receipts without coupling protocol semantics to crypto rails,
  • expose the effective gateway-policy and escrow-policy context for paid procurement,
  • suppress or degrade paid procurement paths when settlement disclosures mark a blocking or degraded state.

Status:

  • partial — selected-responder procurement, offer ranking, contract/receipt persistence, timeout cascade, dispute filing, and service-order bridge paths are live. Broader federated marketplace/catalog distribution remains open.

Settlement Policy Coordination and Disclosure Trail

Based on:

  • doc/project/30-stories/story-007-settlement-capable-node.md
  • doc/project/40-proposals/016-supervised-prepaid-gateway-and-escrow-mvp.md
  • doc/project/40-proposals/017-organization-subjects-and-org-did-key.md
  • doc/project/50-requirements/requirements-007-gateway-escrow-mvp.md
  • doc/project/50-requirements/requirements-008-org-subject-rollout.md

Related schemas:

  • gateway-policy.v1
  • escrow-policy.v1
  • settlement-policy-disclosure.v1
  • gateway-receipt.v1
  • ledger-hold.v1

Responsibilities:

  • ingest and expose the active settlement policy references relevant to paid procurement,
  • retain auditable joins from procurement artifacts to settlement policies and later disclosure events,
  • expose degraded, blocked, or manual-review-only settlement states as first-class operational facts,
  • keep this visibility separate from protocol-external payment execution and fiat rail mechanics.

Status:

  • partial — settlement disclosures, gateway/escrow policy imports, paid-path gating, hold-time policy freezing, and operator inspection are implemented. Buyer-host service-order closeout is also implemented: the host creates a hold before local or AD dispatch, persists remote request/correlation state, admits exact terminal AD results, performs release/refund/freeze transitions, writes receipts idempotently, and reconstructs those projections after restart. Result admission consumes a one-shot acceptor/schema/digest token and derives source-peer identity from host-owned Artifact Delivery provenance. Typed reason codes and a retryable datum replace error-message matching. Richer policy-violation exploration remains open.

The buyer host is the settlement authority for this slice. Arca may transport the exact AD result invocation and Dator may report provider execution facts, but neither component may use provider-supplied settlement references to mutate the ledger or author the terminal procurement receipt.

The paid three-node Story-009 acceptance covers buyer node A and provider nodes B/C. For manual-review-only, execution release and workflow resume remain two explicit transitions: the former settles hold/receipt state, while the latter advances Arca.

Settlement-Capable Node Profile

The baseline Node does not automatically become a payment processor or escrow authority just because it supports paid procurement.

Two deployment profiles are expected:

  • policy-consuming Node:
  • consumes gateway-policy.v1, escrow-policy.v1, and settlement-policy-disclosure.v1,
  • gates paid procurement according to those artifacts,
  • preserves audit joins from procurement contracts and receipts,
  • does not itself execute fiat rail operations or supervise holds.
  • settlement-capable Node:
  • does everything above,
  • additionally hosts or attaches trusted gateway and/or escrow services,
  • emits or serves settlement-facing artifacts such as gateway-policy.v1, escrow-policy.v1, settlement-policy-disclosure.v1, gateway-receipt.v1, and ledger-hold.v1 through explicit contracts,
  • does not yet freeze a concrete MVP HA profile beyond one logical settlement authority and no split-brain behavior,
  • may later swap the storage backend to MariaDB or a similar replicated engine as long as one logical settlement authority and protocol-visible contract compatibility are preserved,
  • remains accountable through policy-bound roles rather than by collapsing the whole Node into one opaque settlement monolith.

In other words, settlement capability is a deployment profile layered onto the Node, not the default meaning of Orbiplex Node.

Story-006 Marketplace Deployment Roles

For the marketplace baseline from story-006-voluntary-swarm-exchange.md, the minimal logical deployment shape around Node should be made explicit:

  • buyer-orchestrator node Roman-side Node hosting Arca, buyer-local workflow state, and local packaging.
  • provider nodes service-providing Nodes hosting Dator and publishing standing offers.
  • gateway node trusted ORC ingress/egress boundary emitting gateway-receipt.v1.
  • escrow supervisor node trusted settlement authority creating and releasing ledger-hold.v1.
  • service-catalog role bounded catalog ownership for remote observed offers and fetch/push exchange; owned by Dator (supply) and Arca (demand) in the standard deployment.
  • arbiter node optional or policy-dependent role for arbiter-confirmed and dispute paths.

Hard MVP may co-locate gateway, escrow, catalog, and even arbiter into one deployment, but their responsibilities should remain distinct at the protocol and audit level.

The daemon's operator-facing local/observed service-offer projection is bounded at 4,096 entries. Before refusing a new entry it reaps expired or withdrawn observed offers; updates to an existing offer remain admissible. For observed offers the host verifies the signed provider identity and derives trust from its own trusted-provider state. Middleware-provided trust_level and source_node_id values do not become authority; the snapshot's source node is the signed provider node, while relay-hop provenance remains in Artifact Delivery or peer metadata.

Supervised Middleware Services

Based on:

  • doc/project/40-proposals/019-supervised-local-http-json-middleware-executor.md
  • doc/project/40-proposals/020-bundled-python-middleware-modules.md
  • doc/project/40-proposals/044-host-owned-generic-module-store.md
  • doc/project/50-requirements/requirements-010-middleware-executor.md
  • doc/project/50-requirements/requirements-011-dator-arca-contracts.md
  • doc/project/30-stories/story-006-voluntary-swarm-exchange.md

Responsibilities:

  • host the supervised channel_json executor as a first-class daemon-owned middleware runtime,
  • distribute Orbiplex Dator and Orbiplex Arca with the hard-MVP Node release,
  • run both bundled modules as supervised Python middleware services rather than as unmanaged sidecars,
  • attach those modules through the host-owned channel_json connector/executor,
  • expose middleware.dator and middleware.arca as operator-visible components with lifecycle, readiness, and restart state,
  • preserve middleware operator UI as a layered contract: packages may ship host-rendered HTML(X) in ui/, operator-surface metadata belongs in ui-op/, live modules report operator_surfaces during middleware-init, and Python middleware may expose server-html pages through the shared stdlib helper under a host-owned /middleware/{surface_id}/... mount,
  • delegate local standing offer lifecycle and participant-facing publication to Dator, while keeping outbound relay transport and peer-session routing in the daemon,
  • expose host capabilities such as offers.local.query and peer.session.establish so middleware may compose daemon-local offers with middleware-owned observed offers without taking ownership of peer transport,
  • expose a host-owned generic module store for small module-local JSON records (workflow-template, cursors, local projections) while keeping record payload semantics owned by the module,
  • keep bundled middleware under the same host-owned envelope and policy contracts as any future replaceable external module,
  • remain the future host-granted capability surface for local modules such as Orbiplex Monus, including bounded memory/read-model access, local signal summaries, Inquirium/model-assisted draft shaping, and bounded publication requests without yielding direct transport or publication authority to the middleware.

Status:

  • done

Local Learning and Knowledge Promotion

Based on:

  • doc/project/30-stories/story-002-federated-peer-learning.md
  • doc/project/50-requirements/requirements-002-peer-learning.md

Related schemas:

  • learning-outcome.v1
  • knowledge-artifact.v1

Responsibilities:

  • classify outcomes as confirmed, corrected, or unresolved,
  • promote only policy-accepted outcomes,
  • keep unresolved material out of trusted retrieval by default.

Status:

  • done in the Node reference implementation. Reviews, learning outcomes, and projected knowledge artifacts are persisted and exposed through daemon, launcher, and Node UI inspection surfaces.

Archivist and Vault Handoff

Based on:

  • doc/project/30-stories/story-003-remote-memory-preservation.md
  • doc/project/40-proposals/012-learning-outcomes-and-archival-contracts.md
  • doc/project/50-requirements/requirements-003-memory-archivists.md

Related schemas:

  • archival-package.v1
  • archivist-advertisement.v1
  • retrieval-request.v1
  • retrieval-response.v1

Responsibilities:

  • prepare archival packages,
  • select archivists under policy,
  • preserve publication scope, integrity, and retrieval provenance.

Status:

  • todo

May Implement

Transcript Monitoring

Based on:

  • doc/project/40-proposals/008-transcription-monitors-and-public-vaults.md
  • doc/project/50-requirements/requirements-004-transcript-curation.md
  • doc/project/50-requirements/requirements-005-transcript-segments.md

Related schemas:

  • transcript-segment.v1
  • transcript-bundle.v1

Responsibilities:

  • observe only policy-allowed traffic,
  • preserve consent and human-origin semantics,
  • emit transcript artifacts suitable for curation.

Status:

  • optional

Consumes

  • question-envelope.v1
  • retrieval-response.v1
  • archivist-advertisement.v1
  • gateway-policy.v1
  • escrow-policy.v1
  • settlement-policy-disclosure.v1

Produces

  • answer-room-metadata.v1
  • response-envelope.v1
  • learning-outcome.v1
  • knowledge-artifact.v1
  • archival-package.v1
  • node-caps.edn

Notes

Implementation-specific decomposition, file ownership, and delivery status belong in the concrete Node repository.

Role components attached to the Node may live in separate repositories, runtimes, or processes. This document defines what the Node must coordinate and expose, not that every role must be compiled into one binary.

Settlement-capable deployments may attach gateway or escrow roles as separate services. The Node still remains the operator-facing coordination point for policy context, disclosure trail visibility, and procurement gating.