Chio/Docs

Bilateral Federation

Two chio kernels in different organizations agree, by explicit handshake, to recognize each other's artifacts under stated boundaries. Trust is established per pair, not as a transitive property of any directory. The federation surface lives in chio-federation, with the kernel binding installed via builder methods on ChioKernel.

Bilateral, Not Multilateral

Every cross-kernel relationship is exactly one pair. Org A pins Org B's kernel key; Org B pins Org A's kernel key. Neither side gains authority over a third operator by transitivity. If Org B has a relationship with Org C, calls from A reaching tools at C require their own A-to-C handshake. There is no chio-operated root that vouches for either side.

  • No global identity provider: identity is the Ed25519 kernel keypair on each side, exchanged out of band and pinned locally.
  • No silent transitivity: a verifier checking a receipt from another org refuses unless the issuing kernel id matches a peer it has pinned.
  • Symmetric per-pair terms: rotation windows, handshake skew, and import controls live in each kernel's local configuration.

Federation widens visibility, not authority

Pinning a peer kernel lets you verify its signed artifacts. It does not let an agent in the peer org call your tools without an attenuated child capability that satisfies your local policy.

KernelTrustExchange Handshake

Two kernels bootstrap mutual trust by exchanging signed challenges and pinning each other's kernel signing public keys. The primitive is KernelTrustExchange, defined in chio-federation::trust_establishment. It is mTLS-style: both sides authenticate, both sides confirm key material, neither side accepts the other on weight of name alone.

The handshake body is HandshakeChallenge at chio-federation/src/trust_establishment.rs:76-85:

crates/chio-federation/src/trust_establishment.rs
pub const FEDERATION_HANDSHAKE_SCHEMA: &str =
    "chio.federation-kernel-handshake.v1";

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct HandshakeChallenge {
    pub schema: String,
    pub local_kernel_id: String,
    pub remote_kernel_id: String,
    pub nonce: String,
    pub timestamp: u64,
}

Each kernel signs the canonical-JSON encoding of its challenge and wraps the result in a PeerHandshakeEnvelope (trust_establishment.rs:108-114):

crates/chio-federation/src/trust_establishment.rs
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct PeerHandshakeEnvelope {
    pub challenge: HandshakeChallenge,
    pub declared_public_key: PublicKey,
    pub signature: Signature,
}

The remote side calls accept_envelope at trust_establishment.rs:367-424 with the envelope, the expected remote kernel id, and the local clock. The method enforces six steps in order:

  1. envelope.verify_signature() checks that the canonical-JSON challenge bytes verify under the declared public key (trust_establishment.rs:144-155).
  2. The envelope's challenge.remote_kernel_id MUST equal the local kernel id, otherwise AddressMismatch.
  3. The envelope's challenge.local_kernel_id MUST equal the expected peer id, otherwise KernelIdMismatch.
  4. envelope_ts.abs_diff(now) MUST be within max_handshake_skew_secs (default DEFAULT_HANDSHAKE_MAX_SKEW_SECS = 5 * 60 at trust_establishment.rs:50), otherwise ClockSkewExceeded.
  5. The declared key MUST match either an anchor installed via with_trusted_peer (trust_establishment.rs:325-332) or an already-pinned peer's key. Missing anchor returns MissingTrustAnchor; mismatched anchor returns UnexpectedPeerKey carrying both expected and actual hex.
  6. On success, the remote key is pinned as a fresh FederationPeer with rotation_due = now + rotation_window_secs (default DEFAULT_ROTATION_WINDOW_SECS = 12 * 60 * 60 at trust_establishment.rs:45).

Out-of-band key pinning is required

First contact has no authentication other than a pre-configured trust anchor. If neither side already knows the other's public key, the operator must install one through with_trusted_peer(kernel_id, public_key) before the handshake will be accepted. Without an anchor, accept_envelope fails with MissingTrustAnchor.
bootstrap.rs
use chio_federation::{
    KernelTrustExchange, KernelTrustExchangeConfig,
    PeerHandshakeEnvelope, DEFAULT_ROTATION_WINDOW_SECS,
};

// Org A side: install a trust anchor for Org B and accept their envelope.
let exchange = KernelTrustExchange::new("org-a-kernel", org_a_keypair)
    .with_trusted_peer("org-b-kernel", org_b_public_key.clone());

let envelope_from_b: PeerHandshakeEnvelope = receive_handshake_envelope();
let now = unix_seconds_now();
let peer = exchange.accept_envelope(&envelope_from_b, "org-b-kernel", now)?;

// 'peer' is now pinned. peer.is_fresh(now) returns true until rotation_due.
assert!(peer.is_fresh(now));

Handshake Over HTTP

Production deployments wrap the envelope exchange in two HTTP POST calls over an mTLS-attested transport. Org A POSTs its signed envelope to Org B's federation handshake endpoint; Org B replies with its own envelope. Each side runs accept_envelope on the envelope it received.

http
POST /v1/federation/handshake HTTP/1.1
Host: chio.org-b.example
Content-Type: application/json
Authorization: Bearer <op-token>

{
  "challenge": {
    "schema": "chio.federation-kernel-handshake.v1",
    "localKernelId": "org-a-kernel",
    "remoteKernelId": "org-b-kernel",
    "nonce": "8f3b9e0c-2a18-4f1a-9bd3-3a31c6e5d3f5",
    "timestamp": 1714291200
  },
  "declaredPublicKey": "ed25519:80f2b53c9a4f1c3b2e7d8a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d",
  "signature": "ed25519:7e1b...c4a2"
}
http
HTTP/1.1 200 OK
Content-Type: application/json

{
  "challenge": {
    "schema": "chio.federation-kernel-handshake.v1",
    "localKernelId": "org-b-kernel",
    "remoteKernelId": "org-a-kernel",
    "nonce": "5d27f0a1-3b4c-4d5e-9f8a-7b6c5d4e3f2a",
    "timestamp": 1714291203
  },
  "declaredPublicKey": "ed25519:9a4f1c3b2e7d8a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b",
  "signature": "ed25519:c2d8...4f3a"
}

After both responses verify, both sides hold a fresh FederationPeer with rotation_due = timestamp + 43_200 (12 hours). The transport is HTTP, but the trust comes from the Ed25519 signature on the canonical HandshakeChallenge bytes; mTLS adds confidentiality and channel auth, not handshake authenticity.


Federation Peer Set

Successful handshakes leave the local kernel with a set of pinned peers. ChioKernel exposes four methods around that set, defined in chio-kernel/src/kernel/mod.rs (Phase 20.3):

MethodPurposeSource
with_federation_peers(self, peers: Vec<FederationPeer>) -> SelfBuilder-style; install the trusted peer set during kernel construction. Replaces any prior set. Marked #[must_use].mod.rs:1533-1541
set_federation_cosigner(&mut self, cosigner)Install the bilateral cosigner that contacts a peer kernel for a co-signature. Tests use InProcessCoSigner; production uses an mTLS RPC client.mod.rs:1547-1552
set_federation_local_kernel_id(&self, id)Advertise this kernel's stable id (e.g. a DNS name) to remote peers. Defaults to the hex encoding of the signing public key.mod.rs:1558-1561
federation_peer(&self, remote_kernel_id, now) -> Option<FederationPeer>Resolve a peer; returns None when unknown OR when !peer.is_fresh(now). Stale pins fail closed at the lookup, not at the call site.mod.rs:1565-1577
federation_peers_snapshot(&self) -> Vec<FederationPeer>Cloned snapshot of all currently-pinned peers.mod.rs:1580-1582

Method names verified against source

The setter is with_federation_peers (builder, not set_federation_peers), the resolver is federation_peer(remote_kernel_id, now) (not resolve_federation_peer), and the local-id setter is set_federation_local_kernel_id (singular). Earlier docs drift was flagged in review; the names above were re-verified against mod.rs:1525-1582.

The pinned peer record is FederationPeer:

rust
pub struct FederationPeer {
    pub kernel_id: String,
    pub public_key: PublicKey,
    pub established_at: u64,
    pub rotation_due: u64,
}

impl FederationPeer {
    pub fn is_fresh(&self, now: u64) -> bool {
        now < self.rotation_due
    }
}

Stale peers fail closed

After rotation_due, the kernel returns None from federation_peer and any federation operation that depends on the peer must refuse. The two kernels MUST re-run the handshake before further bilateral traffic is accepted; rotation never silently renews.

Bilateral Federation Policy

The handshake establishes who you are talking to. A separate federation policy describes what each side will accept across the boundary. The policy lives on the trust control plane and is managed via chio trust federation-policy. Per-partner records carry these fields:

FieldPurpose
partner_idCanonical name of the counterparty operator. Audit and evidence tagging.
trusted_issuersEd25519 public keys the partner is allowed to sign passports and capabilities under.
max_scopeUpper bound on tools, parameters, and budgets a foreign capability may reach.
max_autonomy_tierHighest GovernedAutonomyTier accepted from the partner.
max_evidence_age_secsFreshness ceiling for imported reputation, receipts, and revocation feeds.
revocation_feedSigned transparency URL the partner uses to publish revocations.
sharing_postureWhether imported evidence may be re-exported or stays pair-scoped.

Federation activation artifacts in chio-federation attach the policy intent to a signed exchange. The struct definition at chio-federation/src/lib.rs:160-179:

crates/chio-federation/src/lib.rs
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct FederationActivationExchangeArtifact {
    pub schema: String,
    pub exchange_id: String,
    pub issued_at: u64,
    pub expires_at: u64,
    pub source_operator_id: String,
    pub target_operator_id: String,
    pub listing_id: String,
    pub activation_ref: FederationArtifactReference,
    pub listing_ref: FederationArtifactReference,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub governing_charter_ref: Option<FederationArtifactReference>,
    pub scope: FederationTrustScope,
    pub delegation_control: FederationDelegationControl,
    pub import_control: FederationImportControl,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub note: Option<String>,
}

Canonical-JSON form of one such artifact wrapped in a SignedFederationActivationExchange envelope:

json
{
  "body": {
    "schema": "chio.federation.activation-exchange.v1",
    "exchangeId": "fxa-org-a-org-b-2026-04-28-001",
    "issuedAt": 1714291200,
    "expiresAt": 1716883200,
    "sourceOperatorId": "org-a",
    "targetOperatorId": "org-b",
    "listingId": "lst-billing-readonly",
    "activationRef": {
      "artifactId": "act-org-b-2026-04-21-77",
      "operatorId": "org-b",
      "sha256": "ad81...c4"
    },
    "listingRef": {
      "artifactId": "lst-billing-readonly@v3",
      "operatorId": "org-b",
      "sha256": "92ef...fa"
    },
    "scope": {
      "namespaces": ["billing.org-b.internal"],
      "tools": [{ "tool": "billing.read" }]
    },
    "delegationControl": {
      "maxAutonomyTier": "TIER_2_DELEGATED",
      "maxRedelegationDepth": 1
    },
    "importControl": {
      "explicitLocalActivationRequired": true,
      "manualReviewRequired": true,
      "rejectStaleInputs": true,
      "allowVisibilityWithoutRuntimeTrust": true,
      "prohibitAmbientRuntimeAdmission": true
    }
  },
  "signerOperatorId": "org-a",
  "signerPublicKey": "ed25519:80f2b53c...",
  "signature": "ed25519:7e1b...c4a2"
}

The default FederationImportControl (lib.rs:148-157) is conservative across all five booleans, so even after the artifact lands in the local store no runtime traffic is admitted until the operator explicitly opts in.


Cross-Org Capability Issuance

With the peer set pinned and a partner policy stored, an authority in Org A can mint a capability that is honored at Org B. The endpoint is POST /v1/federation/capabilities/issue on the trust control plane.

Request fields, in addition to the standard issuance body:

FieldMeaning
presentationPassport presentation proving federated subject identity.
expectedChallengeChallenge value the presentation must satisfy.
capabilityRequested issued capability body.
delegationPolicyOptional signed ceiling for delegated issuance. Trust-control rejects untrusted signers.
upstreamCapabilityIdOptional imported parent capability anchor for multi-hop lineage.

Normative rules from the shipped service:

  • When upstreamCapabilityId is supplied, a delegation policy bound to that exact parent capability id MUST also be present.
  • When a delegation policy is supplied, the requested child capability MUST NOT exceed the policy ceiling.
  • The trust-control service MUST reject untrusted delegation-policy signers.

Success response:

json
{
  "capability": { "...": "..." },
  "delegationAnchorCapabilityId": "cap-anchor-org-a-2026-04-28-001",
  "subjectPublicKey": "ed25519:80f2b5..."
}

Delegation Anchor and Child Snapshot

When trust-control issues a delegated cross-org capability, it persists two records into capability lineage: the new local delegation anchor, and a child snapshot rooted at that anchor. The anchor is identified by the returned delegationAnchorCapabilityId and is the parent of the issued child. When upstreamCapabilityId is present, the anchor also bridges to the imported upstream capability so multi-hop lineage reconstructs truthfully through both organizations.

Lineage is the audit primitive

After issuance, querying the receipt and lineage stores at Org B for the child capability id walks the chain back through the delegation anchor and across the bridge to the upstream parent at Org A. Auditors verify the full chain without coordinating with either kernel at runtime.

Why Bilateral Instead of Global

A global identity network would require every operator to accept a shared root, accept changes to that root by majority or committee, and accept that revocation propagates through someone else's schedule. Bilateral federation avoids all three questions.

  • No shared root: every operator pins keys it has out-of-band reason to trust. There is no key whose compromise breaks the whole network.
  • Per-pair negotiation: rotation windows, autonomy ceilings, evidence freshness, and re-export posture are negotiated by the two operators who care and recorded in their own configurations.
  • Bounded blast radius: an Org A key compromise affects every counterparty pinned to that key, not the entire ecosystem. Each counterparty rotates on its own schedule.
  • Audit clarity: every cross-org artifact names the two kernels involved. An auditor checking a receipt knows exactly which two operators' policies applied.

Worked Example: Org A and Org B

Org A runs a research kernel; Org B runs a partner kernel hosting domain-specific tools. They want one of A's agents to call B's billing.read tool with a budget of USD 50.00.

1. Exchange Kernel Keys Out of Band

Each operator publishes its kernel signing public key through a channel both sides already trust (signed announcement, secure email, ticket attached to a procurement record). The other side installs the key as a trust anchor:

rust
// Org A configuring Org B as a trust anchor.
let exchange_a = KernelTrustExchange::new("org-a-kernel", org_a_keypair.clone())
    .with_trusted_peer("org-b-kernel", org_b_public_key.clone());

// Org B configuring Org A as a trust anchor.
let exchange_b = KernelTrustExchange::new("org-b-kernel", org_b_keypair.clone())
    .with_trusted_peer("org-a-kernel", org_a_public_key.clone());

2. Run the Handshake

Each side builds a signed envelope addressed to the other and sends it over an attested transport (mTLS RPC in production). Each side verifies and pins:

rust
let now = unix_seconds_now();
let envelope_a_to_b = exchange_a.local_envelope("org-b-kernel", "nonce-1", now)?;
let envelope_b_to_a = exchange_b.local_envelope("org-a-kernel", "nonce-2", now)?;

// Org B receives A's envelope and pins.
let peer_a_at_b = exchange_b.accept_envelope(&envelope_a_to_b, "org-a-kernel", now)?;

// Org A receives B's envelope and pins.
let peer_b_at_a = exchange_a.accept_envelope(&envelope_b_to_a, "org-b-kernel", now)?;

3. Install Pinned Peers on the Kernel

rust
let kernel_a = ChioKernel::new(config_a)
    .with_federation_peers(vec![peer_b_at_a]);
kernel_a.set_federation_local_kernel_id("org-a-kernel");

let kernel_b = ChioKernel::new(config_b)
    .with_federation_peers(vec![peer_a_at_b]);
kernel_b.set_federation_local_kernel_id("org-b-kernel");

4. Store the Federation Policy

Both sides record their bilateral policy on the local trust control plane.

bash
$ chio trust federation-policy create \
    --config ./org-a-to-org-b.yaml \
    --control-url https://ctl.org-a.example:8940 \
    --control-token-file ./secrets/chio_admin.txt
org-a-to-org-b.yaml
apiVersion: chio.dev/v1
kind: FederationPolicy
metadata:
  name: org-a-to-org-b
spec:
  partner_id: org-b
  trusted_issuers:
    - ed25519:9a4f1c3b2e7d8a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b
  max_scope:
    tool_servers: [billing.org-b.internal]
    tools:
      - tool: billing.read
  max_autonomy_tier: TIER_2_DELEGATED
  max_evidence_age_secs: 3600
  revocation_feed: https://trust.org-b.example/v1/revocations/feed
  sharing_posture: pair_scoped

5. Issue the Cross-Org Capability

An authority at Org A calls POST /v1/federation/capabilities/issue with a delegation policy that caps scope to billing.read on billing.org-b.internal with a USD 50.00 ceiling. Trust-control mints the child capability, persists the delegation anchor and child snapshot, and returns both ids.

6. Dispatch the Tool Call

The agent at Org A presents the child capability to Org B's tool surface. Org B's kernel verifies the issuer key against its bilateral trusted_issuers set, applies its max_scope and max_autonomy_tier, invokes the tool, and produces a receipt. The receipt is co-signed by both kernels (see Bilateral Receipts).

rendering…
Two kernels exchange handshake envelopes and pin each other. A federation policy is then stored at each trust control plane. Cross-org capabilities are issued through the federated issuance endpoint and persist a delegation anchor in capability lineage.

Error Cases

The handshake variants are enumerated by PeerHandshakeError at chio-federation/src/trust_establishment.rs:160-208. Every variant is fail-closed; callers MUST refuse to pin a peer when any step fails.

VariantWhen it firesOperator action
UnsupportedSchemaEnvelope's challenge.schema does not equal FEDERATION_HANDSHAKE_SCHEMA.Update the producer to emit chio.federation-kernel-handshake.v1.
InvalidSignatureSignature does not verify against declared_public_key.Investigate. Likely tampering, key mismatch, or canonical-JSON drift on the producer.
AddressMismatchEnvelope addressed to a different remote_kernel_id than the local kernel.Confirm the remote producer is using the right peer id.
KernelIdMismatchEnvelope's declared local_kernel_id disagrees with the expected peer id.Confirm the receiving operator is calling accept_envelope with the right peer name.
ClockSkewExceededenvelope_ts.abs_diff(now) > max_handshake_skew_secs (default 300s).Check NTP on both kernels. Re-issue the envelope with a current timestamp.
MissingTrustAnchorFirst-contact handshake without a prior with_trusted_peer install.Install the anchor out-of-band, then retry.
UnexpectedPeerKeyDeclared key differs from the anchor or the already-pinned key. The error carries both expected and actual hex.Manual investigation. Re-pinning requires explicit operator action.
PeerStaleresolve(kernel_id, now) on a peer past rotation_due.Re-run the handshake.

Example error response for a missing-anchor first contact:

http
HTTP/1.1 412 Precondition Failed
Content-Type: application/problem+json

{
  "type": "https://chio.dev/errors/federation/missing-trust-anchor",
  "title": "Missing trust anchor",
  "status": 412,
  "detail": "peer org-b-kernel is not trusted for first contact; configure a trust anchor before accepting handshakes",
  "kernelId": "org-b-kernel"
}

Example response for an out-of-skew envelope (the variant carries all three integers; the { envelope, local, skew } struct from trust_establishment.rs:183-188 is mirrored verbatim into the error body):

http
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/problem+json

{
  "type": "https://chio.dev/errors/federation/clock-skew-exceeded",
  "title": "Clock skew exceeded",
  "status": 422,
  "detail": "remote envelope timestamp 1714290000 drifts from local clock 1714291205 beyond 300s",
  "envelope": 1714290000,
  "local": 1714291205,
  "skew": 300
}

Trust-control issuance has its own failure case beyond the handshake:

  • Untrusted delegation-policy signer: a federated issuance carrying a delegation policy whose signer is not in the local trusted issuer set is rejected at POST /v1/federation/capabilities/issue (see spec/WIRE_PROTOCOL.md §4.2).

Federated Receipt Tables

Imported evidence and cross-org lineage land in three SQLite tables created by chio-store-sqlite/src/receipt_store/bootstrap.rs. The schemas (lines 847-884):

crates/chio-store-sqlite/src/receipt_store/bootstrap.rs
CREATE TABLE IF NOT EXISTS federated_lineage_bridges (
    local_capability_id TEXT PRIMARY KEY
        REFERENCES capability_lineage(capability_id) ON DELETE CASCADE,
    parent_capability_id TEXT NOT NULL,
    share_id TEXT REFERENCES federated_evidence_shares(share_id)
);
CREATE INDEX IF NOT EXISTS idx_federated_lineage_bridges_parent
    ON federated_lineage_bridges(parent_capability_id);

CREATE TABLE IF NOT EXISTS federated_evidence_shares (
    share_id TEXT PRIMARY KEY,
    manifest_hash TEXT NOT NULL,
    imported_at INTEGER NOT NULL,
    exported_at INTEGER NOT NULL,
    issuer TEXT NOT NULL,
    partner TEXT NOT NULL,
    signer_public_key TEXT NOT NULL,
    require_proofs INTEGER NOT NULL DEFAULT 0,
    query_json TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_federated_evidence_shares_imported_at
    ON federated_evidence_shares(imported_at);

CREATE TABLE IF NOT EXISTS federated_share_tool_receipts (
    share_id TEXT NOT NULL
        REFERENCES federated_evidence_shares(share_id) ON DELETE CASCADE,
    seq INTEGER NOT NULL,
    receipt_id TEXT NOT NULL,
    timestamp INTEGER NOT NULL,
    capability_id TEXT NOT NULL,
    subject_key TEXT,
    issuer_key TEXT,
    raw_json TEXT NOT NULL,
    PRIMARY KEY (share_id, seq),
    UNIQUE (share_id, receipt_id)
);
CREATE INDEX IF NOT EXISTS idx_federated_share_receipts_capability
    ON federated_share_tool_receipts(capability_id);
CREATE INDEX IF NOT EXISTS idx_federated_share_receipts_subject
    ON federated_share_tool_receipts(subject_key);
  • federated_evidence_shares records each accepted import with issuer, partner, signer key, and the canonical query that produced it.
  • federated_share_tool_receipts stores raw imported receipt JSON keyed by (share_id, seq); (share_id, receipt_id) is uniquely indexed so duplicate imports are idempotent.
  • federated_lineage_bridges links a locally-minted delegation anchor (in capability_lineage) to its imported parent and the share that brought the parent across. ON DELETE CASCADE on the local capability id means deleting the local anchor drops the bridge row, never the imported share.

In the Procurement Tour

This is station 4 of the Procurement Tour: the buyer kernel resolves Vanguard as a pinned federation peer before sending the call. The handshake itself completed earlier; this station is the runtime check.

Picks up from previous station. The buyer holds a GovernedTransactionIntent targeting vanguard-security with a quoted, hold-capture settlement.

Lattice and Vanguard ran a bilateral handshake at onboarding; each kernel pinned the other's key as a FederationPeer with a 12-hour rotation window. At dispatch time the buyer kernel calls KernelTrustExchange::resolve(remote_kernel_id, now); the call returns the pinned record and asserts freshness via FederationPeer::is_fresh(now):

lattice-resolves-vanguard.federation-peer.json
{
  "kernelId": "did:chio:c87a...",
  "publicKey": "ed25519:c87a3f9b...",
  "establishedAt": 1745784000,
  "rotationDue": 1745827200
}

The pin is fresh (now < rotationDue), so the buyer kernel proceeds. The resolved public key is the verification anchor that station 5 will use to check Vanguard's detached signature on the dual-signed receipt; if the pin had been stale, the kernel would return PeerStale and refuse the call until a re-handshake. Per-pair policy (autonomy tier ceiling, evidence-reshare flags, tenant scope) is carried by the bilateral policy contract pinned alongside the peer.

Continue at next station, where the tool runs and both kernels co-sign the same receipt body.