Pheromone Substrate
A stigmergic substrate of signed deposits with exponential decay. It is the missing wire format that makes cross-trust-boundary coordination swarm-shaped instead of committee-shaped.
Forward-looking concept
Why this is gating
Without a substrate, cross-org coordination defaults to committee shape. Every other primitive (federation gossip surface, reputation weighting, ZK disclosure shape, action-class consistency model) ends up retrofitting around whatever wire eventually ships. The wire freeze comes first.
Required surface
- Signed deposits with exponential decay. Canonical-JSON-signed bodies on top of the existing Chio crypto stack.
- Subject hierarchy. Keyed on a domain-supplied class (threat class for cybersec, signal class for finance, compliance class for governance domains). Soft-pluggable.
- Source-diversity enforcement. Deposits signed by per-agent passport keys (not kernel keys), counted as
(kernel_id, agent_passport_key_hash)pairs. Per-pair token-bucket budget per epoch. Per-kernel cap ofceil(sqrt(active_peers_in_treaty))distinct passport keys per subject-class per window. - Evaporation garbage collection.
- Newcomer-discount. A passport’s effective weight is
min(1, age_in_anchored_epochs / N)with a default ofN = 8. Combine with org-level binding in revocation evidence so a fresh passport from a sanctioned org inherits the sanction. - Verifiable observation-cost commitment field. A hash-chain reference to telemetry receipts so peers that only co-sign without originating can be detected and weight-capped.
- Federation gossip. Reuse the bilateral push-queue pattern from
chio-federation::revocation_gossip, scoped per-treaty at subscribe boundary; FIFO with per-origin rate limit. Pheromones do not replace each other. - Receiver-side reputation weighting. Applied at concentration-query time via a closure injected by the runtime (the substrate stays unaware of reputation). Pinned to a
chio-anchorepoch so concentrations are reproducible. - Optional ZK selective disclosure. Proof of concentration without revealing raw indicators. See the Selective Disclosure page.
- Storage-agnostic substrate trait. Reference impls: in-memory and local-journal. Durable backends live in adapter crates so Chio’s “no host required” property survives.
Crate boundary
New top-level chio-pheromone beside chio-reputation and chio-federation, depending only on chio-core-types and chio-credentials. Reputation is not a dependency: pheromone outcomes feed reputation via outcome receipts, avoiding a cycle. Federation gossip lives in a thin sibling module under chio-federation.
Canonical signed deposit
The deposit is a chio.pheromone-deposit.v1 body in canonical JSON (RFC 8785). The signature is computed over the JCS encoding of the body with the signature field excluded, then reattached. The signing key is the agent passport key (Ed25519 by default, hybrid prefixed where the kernel admits it). Kernel keys are explicitly rejected by verifiers.
{
"schema": "chio.pheromone-deposit.v1",
"kernel_id": "did:chio:siegfried-soc",
"agent_passport_key_hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"agent_passport_jwk_thumbprint": "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs",
"subject_class": "ttp.lateral-movement.kerberoast",
"subject_class_namespace": "dev.chio.cybersec.mitre-attack",
"indicator": {
"asset_kind": "host",
"obs_kind": "auth-failure-burst",
"host_id": "h-2af1"
},
"severity": "high",
"confidence": 0.72,
"timestamp_unix_ms": 1746710400000,
"decay_half_life_secs": 1800,
"evaporation_floor": 0.01,
"nonce": "AQIDBAUGBwgJCgsMDQ4PEA",
"treaty_scope": ["treaty:cybersec.regional-soc.v1"],
"cost_commitment": {
"schema": "chio.pheromone-cost-commitment.v1",
"telemetry_chain_root": "5b41362bc82b7f3d56edc5a306db22105707d01ff4819e26faef9724a2d406c9",
"chain_position": 184223,
"chain_position_proof": "{\"path\":[\"...\"],\"root\":\"5b41362b...\"}",
"observed_at_unix_ms": 1746710395120
},
"signature": "ed25519:7e2b1f3a...c104"
}Notable fields: decay_half_life_secs is per-deposit (the substrate config supplies a default but the depositor owns the curve), treaty_scope lists every treaty under which this deposit may be gossiped (an empty list means local-only), and cost_commitment is REQUIRED by default for any subject class the participant’s ladder manifest declares destructive: true.
Bilateral gossip envelope
Federation gossip mirrors chio-federation::revocation_gossip: bilateral push queues, per-peer FIFO ring, deterministic flush. Pheromones differ in two ways. (1) No supersession: a newer deposit never replaces an older one, since concentration is a sum, not a current state. (2) Per-origin rate limit: every receiver enforces a token bucket keyed on the originating depositor tuple, not the gossiping peer.
{
"schema": "chio.pheromone-batch.v1",
"recipient_kernel_id": "did:chio:vega-soc",
"treaty_id": "treaty:cybersec.regional-soc.v1",
"frames": [
{
"schema": "chio.pheromone-deposit-gossip.v1",
"deposit": { "...": "chio.pheromone-deposit.v1 body with signature" },
"origin_kernel_id": "did:chio:siegfried-soc",
"gossiping_peer_kernel_id": "did:chio:siegfried-soc",
"treaty_id": "treaty:cybersec.regional-soc.v1",
"ts_unix_ms": 1746710400420
}
],
"flushed_at_unix_ms": 1746710401000
}Frames are FIFO within a batch; the substrate MUST NOT reorder by epoch or coalesce by deposit identity. Receivers run the structural envelope check (schema, origin agreement, treaty membership), then run validate_deposit (signature, replay nonce, diversity caps, observation-cost gate where required) before merging. Failures drop fail-closed; the per-origin rate-limit overflow surfaces as rate_limit_exhausted.
Concentration query
Concentration is computed receiver-side at query time. The substrate stays unaware of reputation: the runtime injects a peer-weight closure that returns a value in [0.0, 1.0] for each contributing kernel, pinned to a chio-anchor epoch. Per-deposit contribution is strength_at(t) * peer_weight(kernel_id, epoch) * newcomer_discount(passport, epoch).
Pinning the reputation_epoch makes results reproducible: a third party that reconstructs from the deposit corpus and the same anchored reputation snapshot recovers the same total_strength. The substrate refuses queries whose epoch is unknown to the local anchor view, with no silent fallback to the latest epoch.
The result body is a chio.pheromone-concentration.v1 carrying total_strength, unweighted_total_strength (the same sum without per-peer reputation, for diagnostics), distinct_origin_pairs, peak_confidence, and the pinned reputation_epoch so the answer is replayable.
Source-diversity caps
Origin diversity is counted as the number of distinct (kernel_id, agent_passport_key_hash) pairs contributing to a concentration. A single kernel running ten passports counts as ten origins only if all ten are bound to live, non-revoked agent passports under that kernel’s federation handshake. Two caps stack on this counting rule.
- Per-pair token bucket. A token bucket per
(kernel_id, agent_passport_key_hash, subject_class)per anchored epoch. Overruns reject withdiversity_cap_exceeded. - Per-kernel sqrt(N) cap. The receiving kernel caps, per subject-class per window, the number of distinct passport keys it accepts from any single origin kernel at
ceil(sqrt(active_peers_in_treaty)). Overruns reject withsqrt_n_passport_cap_exceeded. The window length SHOULD align with the reputation epoch cadence.
Worked example. A treaty has admitted 64 active peers in the current window. The cap is ceil(sqrt(64)) = 8: any single origin kernel may contribute deposits from at most 8 distinct passport keys per subject-class per window. Origin kernel A pushes 8 passports under subject_class = "ttp.lateral-movement" and the eighth deposit is accepted. The ninth (under a fresh ninth passport) is rejected with sqrt_n_passport_cap_exceeded; prior eight deposits remain stored. Halving the treaty population to 16 active peers tightens the cap to 4. Doubling to 256 raises it to 16.
What the cap actually does