Wire Message Families
Status & scope
- Status: DRAFT — cross-engine consolidation
- Scope: Cross-engine. Consolidates message-shape vocabulary across parallax, axonis-lens (Prism), cortex (DES), and Xanadu.
- Depends on: parallax correlation-persistence, fusion-governance-lifecycle, signal-payload, three-phase-protocol, attestation-rationale, continuous-fusion, multi-contributor-combination, quorum, dissent, consensus-session; axonis-lens SPEC-12, SPEC-19; xanadu README; cortex tools/evidence.py + edition.py + governance.py + signal.py
- Sister specs: None — this is the first cross-engine wire-protocol consolidation
- Milestone: M5 (Operational System)
- Date: 2026-04-27
1. Problem
The Axonis platform has a real, working wire-protocol contract — what flows between Edge Nodes, between contributors in a fusion run, between the fusion engine and the decision substrate, between operators and the audit replayer. What it does not have is a single canonical document that names what those messages are.
The contract exists across at least eight specs and three repos:
parallax/specs/SPEC-11— Correlation Records, lineage eventsparallax/specs/SPEC-13— Fusion governance lifecycle (CREATE → ATTEST), 8 governance objectsparallax/specs/SPEC-14— Signal payload + signal schemaparallax/specs/SPEC-16— Three-phase federation protocol (DH-PSI rounds, scoring, clustering)parallax/specs/SPEC-24— Attestation rationale, ATTESTATION_CORRECTED actionparallax/specs/SPEC-27— Continuous fusion pipeline, signal emissionparallax/specs/SPEC-28— Multi-contributor combiner messagesparallax/specs/SPEC-30— Dissent records (DissentRecord / MachineDissent)axonis-lens/specs/SPEC-12— Lens composition,lens://referencesaxonis-lens/specs/SPEC-19— Incremental updates: LayerChangeEvent, RecompositionEvent, ThresholdCrossingEventcortex/cortex/tools/evidence.py + edition.py + governance.py + signal.py— 39 MCP tools across the DES surfacexanadu/README.md— Coordinator + Federate peer-to-peer messaging, heartbeat semantics
When a fusion expert (DEVCOM evaluator, coalition partner technical lead, regulator) asks "what messages flow between your nodes," the honest answer today is "it's spread across these eight specs and one README." That answer is correct but unhelpful. This spec is the consolidation.
Three audiences benefit from this spec existing as a single artifact:
- External technical evaluators — fusion experts, classification authorities, coalition technical leads — who need to verify the wire-protocol shape before approving deployment.
- Engineering — when adding a new event type or new MCP tool, the engineer should be able to read one document to find the right family and the right pattern, rather than choosing among inconsistent precedents.
- Spec maintenance — when a sister spec is updated, this spec is the cross-reference that catches drift between SPEC-19's
ThresholdCrossingEventand SPEC-27'ssignal_class="computed"(for example).
This spec is documentation hygiene, not new engineering. No new behavior is specified. Every message named here exists today, in code or in spec.
2. Decision
Define five message families as the canonical taxonomy for everything that flows on the Axonis wire. Every existing message in any spec maps to exactly one family. New messages added in future specs MUST declare their family.
The five families:
| # | Family | What it carries | When it flows |
|---|---|---|---|
| 1 | Capability | Registration, discovery, lens-contract negotiation, capability declarations | Federation join, contract change, capability update |
| 2 | Cue | Lens-output events, lens-to-lens subscriptions, explicit cueing requests | At the lens execution boundary; whenever a lens emits a declared output |
| 3 | Fusion | DH-PSI blocking exchanges, per-pair scoring, UnionFind cluster updates, Correlation Record lifecycle events | Multi-source entity emergence; per-fusion-run |
| 4 | Evidence | Block creation, Edition freeze, attestation signature, replay request, lineage export | Decision governance lifecycle |
| 5 | Operational | Heartbeats, peer status, signals, machine-dissent records, threshold crossings | Liveness, alerts, disagreement, streaming |
All five families share three cross-cutting properties (§4):
- Every message is replayable — append-only event chain; same input → same output.
- Every contract is signed — lens contracts, attestations, dissent records carry cryptographic signatures.
- Every dissent is recorded — disagreement is never silently averaged; it's a first-class message.
3. The five families
3.1 Capability messages
Purpose. Establish, negotiate, and update what a federation member can do, what crosses, and under what contract.
When they flow. - Federate joins or leaves the federation (Xanadu register / deregister) - Lens contract is created, reviewed, approved, published (SPEC-13 governance lifecycle stages CREATE → PUBLISH) - Each federate consents to participate in a specific lens run (SPEC-13 stage CONSENT, SPEC-16 §6 consent model) - Lens version bumps (capability re-declaration) - ABAC capability scope changes (UDS authority)
Message types.
| Message | Source spec | Notes |
|---|---|---|
NODE_REGISTER / NODE_DEREGISTER |
xanadu/README | Federate joins / leaves the federation via coordinator |
PEER_LIST |
xanadu/README | Coordinator returns active peers to a registering federate |
Lens lifecycle event (draft → submitted → approved → active → retired) |
parallax SPEC-13 §"Object 1: Lens" | Append-only governance state transitions |
| Lens binding (per-federate field projection) | parallax SPEC-13 §"Object 4: Binding"; SPEC-10 | Each federate's mapping of lens fields to local schema |
| Consent declaration | parallax SPEC-13 §"Object 5: Consent"; SPEC-16 §6 | "I consent to share soundex(name) + year(dob) for blocking under lens vrs_v1" |
Schema reference. Per-message types are defined as frozen dataclasses across the listed specs. There is no single message-class registry today — see §6 (Future Work).
3.2 Cue messages
Purpose. Carry the output of one lens to another lens that subscribes to it. The wire shape of cross-INT cueing.
When they flow.
- A lens emits a declared output (per its lens.yaml output block)
- A downstream lens has subscribed via lens://type/name (axonis-lens SPEC-12)
- An adapter explicitly requests a cue from another lens (e.g., SIGINT lens cues GEOINT collection)
- A composition cascade fires (axonis-lens SPEC-19 — composition-cascade trigger)
Message types.
| Message | Source spec | Notes |
|---|---|---|
| Lens-output event | axonis-lens SPEC-12 §"Composition Pattern"; lens.yaml output: block |
Emitted whenever a lens completes a composition |
LayerChangeEvent |
axonis-lens SPEC-19 §6.1 | A layer's underlying data changed; downstream lenses may need to recompose |
| Cueing request | DEVCOM positioning §4.2 (RF→GEOINT, MTI→SIGINT examples) | One INT explicitly requests another INT's collection or computation |
| Subscription declaration | axonis-lens SPEC-12 (lens:// references in lens.yaml) |
Static at lens-author time; resolved at composer time |
Schema reference. LayerChangeEvent defined in axonis-lens SPEC-19 §7 (frozen dataclass). Cueing-request schema is per-lens (declared in lens.yaml output:); no platform-wide envelope exists yet — see §8 Open Question 1.
3.3 Fusion messages
Purpose. Carry the per-pair, per-cluster, per-run state of multi-source entity resolution. The wire shape of the three-phase protocol.
When they flow. - A fusion run starts (batch or incremental) - A blocking-derived feature is exchanged (DH-PSI Phase 1) - A candidate pair is scored (Phase 2) - A cluster is updated (Phase 3 — UnionFind merges) - A Correlation Record changes lifecycle state
Message types.
| Message | Source spec | Notes |
|---|---|---|
psi_round1_request / psi_round1_response |
parallax SPEC-16 §"Phase 1"; node_a/routers/phases.py |
DH-PSI blocking key exchange |
psi_round2_request / psi_round2_response |
parallax SPEC-16 §"Phase 1" | DH-PSI second round; produces blocked candidate set |
score_pair_request / score_pair_response |
parallax SPEC-16 §"Phase 2"; SPEC-04 | Per-pair metric evaluation |
cluster_update |
parallax SPEC-16 §"Phase 3" | UnionFind merge / split events |
Correlation Record lineage events: CREATED, RECORD_ADDED, RECORD_REMOVED, SCORE_UPDATED, ATTESTED, INVALIDATED, DECAYED, RECONFIRMED, ATTESTATION_CORRECTED |
parallax SPEC-11 §"Lineage Actions"; SPEC-24 | Append-only CR state transitions |
split_correlation event chain (originating CR → 2 new CRs + RECORD_REMOVED + negative-correlation auto-link) |
parallax SPEC-11 + parallax issue #21 | Surgical unmerge — gap (ticket filed, not yet implemented) |
Schema reference. CorrelationRecord, LineageEntry, LineageAction, CorrelationStatus defined in parallax/ops/fusion/models/correlation.py. PSI round payloads in node_a/schemas.py.
3.4 Evidence messages
Purpose. Carry the lifecycle of decision evidence — Block creation, Edition freeze, human attestation, replay. The wire shape of decision governance.
When they flow. - An Investigation is opened on a promoted signal or correlation - A Block is created carrying upstream evidence by reference - An Edition is drafted, frozen for attestation, attested - A decision is replayed, lineage is exported, integrity is verified
Message types.
| Message | Source / file | Notes |
|---|---|---|
create_block, freeze_block, pin_block_to_insight, unpin_block, get_block_content, list_blocks_for_insight, explain_block_limits, add_note, add_external_reference |
cortex/cortex/tools/evidence.py (9 tools) |
Block lifecycle |
create_edition, freeze_edition_for_attestation, attest_edition, tag_decision, list_decision_tags, remove_decision_tag, request_edition_review, get_edition |
cortex/cortex/tools/edition.py (8 tools) |
Edition lifecycle |
get_decision_lineage, list_events_for_insight, export_insight_with_attestation, replay_decision, query_agent_provenance, verify_integrity, verify_edition_integrity |
cortex/cortex/tools/governance.py (7 tools) |
Audit / replay surface |
| InsightRoot + InsightEvent lifecycle | cortex/cortex/tools/insight.py (11 tools) |
Append-only event spine for an Investigation |
Total: 24 named DES tools across Block / Edition / Governance, plus 11 Insight tools at the entry boundary. All capability-tagged for ABAC (17 distinct capability scopes — see SPEC-CPO-CL series for the full set).
Schema reference. Object schemas at fedai-rest/server/api/schema/objects.yml. JSON Schema files in adi-demo-harness/data/schemas/*.schema.json.
3.5 Operational messages
Purpose. Liveness, alerts, threshold-crossings, and disagreement. The wire shape of the system observing itself and surfacing what an operator or downstream system needs to react to.
When they flow. - Continuously (heartbeats) - When a federate's status changes - When a lens output crosses a configured threshold - When a new signal is emitted into the promotion boundary - When contributors disagree on a multi-INT entity or decision
Message types.
| Message | Source spec | Notes |
|---|---|---|
| Heartbeat | xanadu/README §"Lifecycle" | Periodic liveness signal between federates |
PEER_STATUS_CHANGED |
xanadu/README | Coordinator broadcast on missed heartbeat or restart |
PEER_LEFT |
xanadu/README | Explicit deregister broadcast |
Signal (typed; signal_class, producing_engine, producing_lens_id) |
parallax SPEC-14 + SPEC-27 §"Signal Triage + Filter" | Promoted into DES if filter passes |
ThresholdCrossingEvent |
axonis-lens SPEC-19 §6.3 | Lens output crossed a configured threshold; emits typed signal |
RecompositionEvent |
axonis-lens SPEC-19 §6.2 | Layer change triggered re-recomposition over the affected footprint |
DissentRecord |
parallax SPEC-30 | Contributor disagrees with consensus; append-only |
| Multi-contributor combiner output | parallax SPEC-28 | Joint output that may contain dissent annotations |
Schema reference. Per-message dataclasses across listed specs. Signal schema in parallax SPEC-14. DissentRecord in SPEC-30. SPEC-19 events in axonis-lens/lens/models/incremental.py.
4. Cross-cutting properties — the three principles
All five families share three properties. These are the invariants that distinguish a wire-protocol contract from a logging system.
4.1 Every message is replayable
Every message on the wire is captured in an append-only event chain. Given the same upstream state, replay reproduces the same downstream messages byte-for-byte.
Maps to Invariant 2 (Events are append-only — no UPDATE, no DELETE) and Invariant 4 (Frozen means frozen — SHA-256 digest locked forever).
The replay-determinism property is gated by FED-SPEC-02 (themis benchmark). Streaming-case replay is the V1 work (axonis-lens SPEC-19 §6.4).
4.2 Every contract is signed
Every cross-organization message references a signed lens contract. Every Edition carries a human attestation signature. Every dissent record carries the contributor's signature.
A message without a contract reference is not on the wire. Messages internal to a single Edge Node may omit the contract reference; messages crossing a Federation Gateway MUST carry it.
Maps to Invariant 6 (AI assists, humans attest — only humans sign off).
4.3 Every dissent is recorded
When contributors disagree on a multi-INT entity or a multi-source assessment, the system does not silently average. Disagreement becomes a first-class DissentRecord (SPEC-30) with full lineage.
This is the property that lets a commander see not just "the system said X" but "contributors A and B agreed on X; contributor C dissented on grounds Y." That distinction is the difference between an opaque consensus and an auditable joint output.
Maps to Invariant 7 ("No action" is a decision — explicit closure required) generalized to "Disagreement is a result — explicit recording required."
5. Promotion across engine boundaries
The five families are not fully independent. Three explicit promotion boundaries exist where a message in one family becomes (or triggers) a message in another:
5.1 Cue → Fusion (continuous fusion trigger)
A LayerChangeEvent (Cue family) on an upstream source can trigger an incremental Correlation Record update (Fusion family). The add_record_to_correlation path in parallax/ops/fusion/correlation.py is the implementation.
The trigger is currently scheduled / on-demand; the event-driven trigger is the gap framed in parallax SPEC-27 + axonis-lens SPEC-19.
5.2 Fusion → Evidence (the DES promotion boundary)
When a fusion event is promoted into an Investigation (signal, threshold, manual flag), a Block is created carrying the fusion evidence by reference (hash). DES does not duplicate the fusion event stream.
This boundary is explicit in capabilities/evidence-bound-decisions.md §1 and is the discipline feedback_des_provenance_separation.md (memory) was created to protect.
5.3 Operational → Evidence (signal promotion)
A Signal (Operational family) that survives the promotion filter (SPEC-27 §"Signal Triage + Filter") creates an InsightRoot, which begins an Evidence-family lifecycle. The filter discriminates noise from signal.
6. Schema registry — future work
Today: message schemas live as frozen dataclasses (Python) and JSON Schema files, scattered across the source specs. There is no single registry.
Proposed: a single message-schema registry generated from the source specs:
- Python:
axonis_messages/__init__.pywith imports from each engine's models module - TypeScript:
@axonis/messagesnpm package generated from JSON Schema for Beacon and atlasfl-web consumers - JSON Schema:
schemas/wire/directory with one schema file per message type, named after the family
This is engineering hygiene work, not new behavior. Recommended as a follow-on after this spec lands. Estimated effort: small (~1 week to consolidate, generate, and verify).
7. Acceptance criteria
- [ ] All five families documented with source-spec references and per-message-type lists.
- [ ] Cross-cutting properties (replayable, signed, recorded) verified for each family with explicit invariant mapping.
- [ ] Promotion boundaries between families enumerated.
- [ ] Schema registry as future work named with a discrete next-step ticket.
- [ ] Open questions enumerated (§8).
- [ ] No new message types defined in this spec — every type listed already exists in source specs or in code.
- [ ] Cross-references resolve (each cited spec exists and the cited section is present).
8. Open questions
-
Cue vs Fusion message boundary for incremental fusion. When a
LayerChangeEvent(Cue) triggersadd_record_to_correlation(Fusion), is the trigger event itself a Cue family message or an Operational family message? Current lean: Cue, because it carries a lens-declared output. Worth a precision-pass. -
DissentRecordfamily placement. Currently in Operational (§3.5). Argument for Fusion: it's emitted by the multi-contributor combiner during fusion. Argument for Operational: it's surfaced to operators / downstream consumers and is independent of any specific fusion run. Lean: Operational, because the consumer (commander, audit, downstream lens) treats it as an alert-shaped object. -
Capability messages for streaming-mesh peer discovery (Profile 3). Xanadu register/deregister are Capability family. Are the per-message-broker peer-routing messages also Capability, or do they belong in Operational as plumbing? Lean: Operational — they're transport plumbing, not federation membership.
-
Should Cortex MCP tool calls be considered messages? A
create_editioninvocation from Beacon to Cortex via the MCP transport is conceptually a message. Currently we treat them as RPC calls. Lean: yes, count them as Evidence-family messages — the wire-protocol shape includes the operator-to-substrate path. -
Per-spec vocabulary drift. SPEC-19 uses
ThresholdCrossingEvent; SPEC-27 usesSignalwithsignal_class="computed". These describe overlapping concepts. Reconciliation: the ThresholdCrossingEvent emits a Signal; Signal is the promotable form. Worth pinning in a small SPEC-27 amendment so the two specs use one vocabulary. -
Naming for new messages. When a new spec adds a message type (e.g., the future
split_correlationevent chain from parallax issue #21), this spec should be updated as part of the same merge. Recommend adding a CI check or a pre-merge checklist item: "if you added a wire message, did you update SPEC-32?"
9. Cross-references
| Spec / file | Family contribution |
|---|---|
| parallax SPEC-11 | Fusion (CR lineage events), promotion boundary |
| parallax SPEC-13 | Capability (lens lifecycle, governance objects) |
| parallax SPEC-14 | Operational (Signal payload schema) |
| parallax SPEC-16 | Fusion (three-phase protocol, DH-PSI rounds) |
| parallax SPEC-24 | Fusion (ATTESTATION_CORRECTED action) |
| parallax SPEC-27 | Operational (signal emission, triage filter) |
| parallax SPEC-28 | Operational (multi-contributor combiner) |
| parallax SPEC-30 | Operational (DissentRecord) |
| axonis-lens SPEC-12 | Cue (lens:// references, composition) |
| axonis-lens SPEC-19 | Cue (LayerChangeEvent), Operational (RecompositionEvent, ThresholdCrossingEvent) |
xanadu/README.md |
Capability (NODE_REGISTER, PEER_LIST, deregister), Operational (heartbeat, PEER_STATUS_CHANGED) |
cortex/cortex/tools/evidence.py + edition.py + governance.py + insight.py + signal.py |
Evidence (24 named tools), Operational (signal entry tools) |
capabilities/entity-provenance.md |
Documents Fusion-family event stream as a customer-facing capability |
capabilities/evidence-bound-decisions.md |
Documents Evidence family as a customer-facing capability |
feedback_des_provenance_separation.md (memory) |
Discipline for the Fusion→Evidence promotion boundary |
10. Status / next steps
DRAFT. Recommended sequencing:
- Land this spec as the canonical reference. No code changes required; this is documentation of existing behavior.
- Resolve the six open questions in §8. Either by amendment to this spec or by small amendments to the source specs (e.g., the SPEC-27 vocabulary reconciliation in OQ 5).
- Schema registry follow-on (§6). File as a discrete ticket once this spec lands. Generate Python + TypeScript + JSON Schema bundles from the source specs. Estimated ~1 week.
- CI check for new messages. Pre-merge check that asks "if you added a wire message, did you update SPEC-32?" — implement as a simple pattern-grep against the spec source files (~half-day).
- External-reader companion. A short customer-facing version of this spec for fusion-expert audiences (DEVCOM, coalition technical leads) — pulls the §3 family tables and §4 principles into a 4-page brief without internal implementation detail. The
multiint-fusion-intro.pptx"Five Message Families" slide is the deck-shaped version of that brief.
Owner: CPO. Cross-engine consolidation; aligned with parallax SPEC-NN, axonis-lens SPEC-NN, themis FED-SPEC-NN. Next review when the schema registry follow-on lands or when a sister spec adds a new message type.
Depends on: component.parallax.attestation-rationale, component.parallax.consensus-session, component.parallax.continuous-fusion, component.parallax.correlation-persistence, component.parallax.dissent, component.parallax.fusion-governance-lifecycle, component.parallax.multi-contributor-combination, component.parallax.quorum, component.parallax.signal-payload, component.parallax.three-phase-protocol
Realizes: product.fusion
Required by: component.parallax.coordination-ledger, component.parallax.fusion-adi-integration