Designing coalitions on mosaik
audience: contributors
This chapter extends the design intros of zipnet and builder from one organism → one lattice → one coalition: a named composition of coexisting mosaik members — block-building lattices, standalone organisms (oracles, attestation fabrics, identity substrates, analytics pipelines, …), cross- member organisms (composite organisms), and up to five basic services (Atlas, Almanac, Chronicle, Compute, Randomness) plus an optional coalition-scoped ticket issuer.
The reader is assumed familiar with the mosaik book, the zipnet book, the builder book, and the two design intros cited above. This chapter does not re-derive content + intent addressing, the narrow-public-surface discipline, the shared-universe model, or within-lattice derivation; it uses them.
Stance
A coalition is an opt-in composition. The substrate has
no primitive for compulsion: every bond is opt-in at the
TicketValidator layer, member
identity is independent of coalition membership, and
basic services never gate member operation. Every design
choice in this chapter follows from this baseline.
The problem, at N members
Builder composes six organisms under one LatticeConfig
for one EVM chain, solving “one end-to-end pipeline for
one chain” cleanly. It does not solve:
-
Cross-member coordination at scale. An agent operating across ten block-building lattices holds ten
LatticeConfigs; one additionally correlating across an oracle and an attestation organism holds twelve handshakes. Driver code pairs facts across members, reconciles partial observations, and recovers outcome correlators. The same correlator is re-implemented per agent. The builder book’s Shape 1 is correct for two or three lattices and an unbounded implementation burden at ten-plus heterogeneous members. -
Shared attribution. MEV captured on a block of lattice A originating from a searcher bundle submitted on lattice B — or a trade attributed by an analytics organism also reported by an oracle organism — is invisible to each service without explicit wiring. Ad hoc repetition is the same burden, one level deeper, across more boundary kinds.
-
Consistent cross-member observability. Operators running five members want one dashboard; analytics integrators want one API. Both want a named composition with a fingerprint that moves in lockstep with what they subscribe to. The Atlas basic service addresses this.
-
Operator coordination. Teams coordinating a set of members — every chain in a superchain stack, every oracle feed in a region, every deployment’s bonded organisms — need a naming unit for that coordination that does not itself become a consensus unit.
-
Durable provenance. Decisions outlive any one
CoalitionConfig. An operator grouping needs a tamper-evident record of its own publications, rotations, and retirements — the Chronicle basic service addresses this.
Promoting “a set of members” to an in-consensus group collapses every member’s trust boundary into one committee. Builder rejected that shape at the organism level; promoting it one rung higher inherits the same objection at higher cost.
The correct rung is a fingerprint above the members that names them for discovery, basic services, and module derivation — without consensus, state, or admission authority. That fingerprint is a coalition.
Two axes of choice
Same two axes zipnet picked and builder reaffirmed. Each rung of the ladder inherits the zipnet conclusion; the coalition rung does too.
- Network topology. Does a coalition live on its own
NetworkId, or share a universe with every other mosaik service? - Composition. How do members and organisms reference each other without creating cross-Group atomicity mosaik does not support — and, now, without creating cross-coalition atomicity either?
The blueprint chooses shared universe + membership-by- reference + no cross-Group, cross-member, or cross- coalition atomicity. The three choices are independent; each has a narrow rationale.
Shared universe (unchanged)
builder::UNIVERSE = unique_id!("mosaik.universe") — the
same constant zipnet and builder use. Every coalition,
lattice, standalone organism, composite organism, and
module lives on it. Different coalitions coexist as overlays of
Groups, Streams, and Collections distinguished by
their content + intent addressed IDs. An integrator
caring about three coalitions holds one Network handle
and three CoalitionConfigs. Because coalitions
reference members rather than re-deriving them, an
integrator already bonded to some of the included members
observes no duplicate identity.
The alternative — one NetworkId per coalition, mirrored
all the way up — is rejected on the same grounds the
zipnet book rejects Shape A: operators already pay for one
mosaik endpoint, services compose, and one additional
endpoint per coalition would turn the coalition into a
routing device, which is not the rung’s function.
Membership-by-reference
A CoalitionConfig is a parent struct. Unlike a
LatticeConfig (which nests six organism Configs and
hashes them together), a CoalitionConfig references
existing member fingerprints without re-deriving the
members’ organism IDs. This is the key decision of the
coalition rung:
COALITION = blake3("coalition|" || SCHEMA_VERSION_U8
|| "|" || coalition_name)
COA_LATTICES = ordered stable ids of referenced lattices
COA_ORGANISMS = ordered stable ids of referenced organisms
(including any composite organisms)
COA_TICKETS = optional TicketIssuerConfig fingerprint (0 bytes if absent)
COALITION_ROOT = blake3(
COALITION
|| COA_LATTICES
|| COA_ORGANISMS
|| COA_TICKETS
)
Here COA_LATTICES[i] is the stable id of lattice i —
not a re-derivation. Likewise COA_ORGANISMS[j] is the
stable id the standalone organism (or composite organism)
j publishes in its own handshake. Composite organisms
are referenced by their own fingerprint just like any
other organism. Builder’s lattice identity is:
LATTICE(i) = blake3("builder|" || instance_name || "|chain=" || chain_id)
+ every organism's Config fingerprint inside that lattice
A coalition neither modifies LATTICE(i) nor the organism
roots under it, nor the Config of any standalone
organism or composite organism it references. A member
referenced by three coalitions is one member; its
operators issue tickets once, its integrators compile it
in once, and its GroupIds are stable across coalition
memberships.
Rationale for by-reference over by-containment:
-
Members predate coalitions. The first production organism and first production lattice ship before the first coalition. An integrator already bonded to a specific member must not have to re-bond when an operator composes that member into a new coalition.
-
Members outlive coalitions. Coalition membership is a composition choice and changes; member identity is an operator-level commitment. Coalitions must not force churn.
-
Members belong to multiple coalitions. The shared- universe choice implies a member may be referenced from several coalitions simultaneously — one per operator grouping, one per analytics vendor, one per umbrella grouping. Re-derivation would force a cartesian product of IDs.
Member reference shape
A member is referenced by two values: its stable id
— the (instance_name, network_id) blake3 hash — which
changes only on retirement; and its content hash,
which folds the member’s ACL, TDX Measurements, and policy
parameters and bumps with every operational rotation.
CoalitionConfig references members by stable id.
Composite organisms and modules choose per-component
whether they also pin the content hash. A read-only
correlator that does not bond into TDX-gated surfaces
pins only the stable id and survives TDX Measurements rotations in
its upstream members. A composite organism whose
committee bonds into a TDX-gated surface pins the content
hash and redeploys on rotation.
The split decouples TDX Measurements rotation churn from coalition-
level identity. A coalition referencing ten members
rotating TDX monthly sees its COALITION_ROOT change only
on member retirement or coalition membership change, not
on routine operational rotations.
Open for v0.3 decision. Whether content-hash- pinning is a per-component choice or a coalition-wide policy is unresolved. Leaving it per-component for v0.2;
CoalitionConfigmay gain a policy flag later.
Builder’s LatticeConfig derivation already distinguishes
the two in practice; this rung surfaces the distinction
in the coalition-layer spec. Both LatticeConfig and
OrganismRef expose a stable_id() accessor separate
from their full fingerprint accessor.
Composite organisms as a recurring pattern
Composite organisms are organisms in the zipnet sense:
one Config fingerprint, a narrow public surface, a
ticket-gated ACL. What distinguishes them is that their
content folds two or more member fingerprints. A
composite organism’s identity does not fold a
coalition root:
ORGANISM(cfg) = blake3(
"organism|"
|| SCHEMA_VERSION_U8
|| "|" || name
|| ordered spanned lattice references
|| ordered spanned organism references
|| content_fingerprint
|| acl_fingerprint
)
ORGANISM_committee = ORGANISM(cfg).derive("committee")
A composite organism is therefore referenced by zero,
one, or many coalitions exactly as a lattice or any other
standalone organism is. Its committee, state machine, and
log are shared across those references. A composite
organism misconfigured against the wrong spanned members
derives a disjoint GroupId and surfaces as
ConnectTimeout — the ladder’s standard debuggable
failure mode.
Modules (Atlas, Almanac, Chronicle) are the only
coalition-scoped components. Their identity derives under
COALITION_ROOT.derive("module").derive(name) where
name is "atlas", "almanac", or "chronicle". An
optional ticket issuer derives under
COALITION_ROOT.derive("tickets").
No cross-Group, cross-member, or cross-coalition atomicity
Every rung below refuses cross-Group atomicity. The coalition rung refuses cross-member and cross-coalition atomicity by the same argument:
- Cross-Group (one member, two organisms) — refused by builder and by every organism’s own design. Organisms subscribe to each other’s public surfaces; there is no atomic multi-organism commit.
- Cross-member (one coalition, two members) — refused by this blueprint. Composite organisms read public surfaces of the members they span; their state machine commits its own facts. A composite organism never forces two members to commit atomically.
- Cross-coalition (two coalitions) — refused by this blueprint. Coalitions do not coordinate in consensus. A use case for cross-coalition coordination resolves either to an integrator spanning coalitions or to a new composite organism whose content fingerprint folds the relevant members (which are already referenced by both coalitions anyway).
Fixed shapes, open catalogs
The blueprint’s central discipline; restated because every downstream choice flows from it.
Specified
- The
CoalitionConfigstruct and derivation rules. Every coalition has this shape; every coalition’s identity is computed this way. - The
OrganismConfigandOrganismRefstructs. Every organism (including composite organisms) and every standalone-organism reference has these shapes. - The five basic-service shapes (Atlas, Almanac,
Chronicle, Compute). Every instance of “Atlas” in any
coalition has the same
Configsignature, public surface, and derivation. Same for the other three. Specification in basic services. - The optional ticket-issuer shape. Specification in ticket issuance.
- Membership discipline — by-reference, multi- coalition-compatible, no re-derivation; stable-id and content-hash split.
Left open
- Whether any given coalition ships any basic services. A coalition with zero services is valid.
- Whether any given coalition ships a ticket issuer.
- The catalog of commissioned composite organisms. Each arrives when a cross-member problem forces it.
- The catalog of standalone-organism categories and lattice classes. New categories arrive with their own books. Block-building lattices are the first specified class; attestation fabrics, oracle grids, DA shards, and other categories follow their own proposals.
- Inter-coalition coordination. Coalitions coexist on the shared universe; a concrete need for coordination earns its way in through a fresh proposal.
- Governance of the coalition itself. Who approves
CoalitionConfigbumps, how operator groupings form and dissolve, what contracts multi-operator coalitions sign — all out of band.
Deliberately deferred (deferred-primitives space)
A family of primitives the blueprint refuses:
- Enforceable policies over members — a
CoalitionConfigdeclaring constraints members must satisfy (TDX Measurements requirements, bond minimums, code-audit attestations). - Taxation — a protocol-level mechanism for the coalition to collect fees from members’ commits.
- Judiciary — an organism whose commits have protocol-level precedence over individual members’, resolving disputes.
- Mandatory membership — any primitive whose absence renders a member’s commits invalid in the coalition’s view.
- Legislation — a state machine in the coalition that members must query and conform to before acting.
Each is a coherent design space, and adopting any one forces the blueprint to rewrite the trust composition and rebuild every passage that assumes opt-in participation. Any future deferred-primitives proposal lives on its own branch and earns the transition; the current blueprint neither anticipates nor precludes one.
Flag in-source and in-docs as “deferred-primitives space” when the topic arises so the current scope is unambiguous.
Coalition identity
A coalition is identified by a CoalitionConfig folding
every root input into one deterministic fingerprint.
Operators publish the CoalitionConfig as lattice
operators publish a LatticeConfig and organism operators
publish their own Config; integrators compile it in.
pub const SCHEMA_VERSION_U8: u8 = 1;
pub const COALITION_ROOT_SEED: UniqueId = /* fixed */;
#[non_exhaustive]
pub struct CoalitionConfig<'a> {
/// Schema version byte. Folded as the first element of
/// every top-level identity preimage.
pub schema_version: u8,
/// Coalition root domain-separation seed. Constant
/// across the blueprint; carried explicitly so the
/// fingerprint stays self-describing.
pub coalition_seed: UniqueId,
/// Short, stable, namespaced name chosen by the
/// coalition operator (e.g. "ethereum.superchain",
/// "signals.euro-fx", "searcher-α").
pub instance_name: &'a str,
/// Ordered set of lattice stable ids this coalition
/// references. Held by stable id so the coalition does
/// NOT re-derive any lattice's organism IDs; a lattice
/// retains a single canonical identity across every
/// coalition that references it.
pub lattices: &'a [UniqueId],
/// Ordered set of organism references this coalition
/// composes — any mosaik organism with a Config
/// fingerprint living directly on the universe,
/// including composite organisms whose `Config` folds
/// multiple member references. A composite organism's
/// identity is derived independently of any coalition;
/// the same composite organism may be referenced by
/// many coalitions.
pub organisms: &'a [OrganismRef<'a>],
/// Basic services the coalition ships. Each field
/// holds an `OrganismRef` when shipped, `None`
/// otherwise. See [basic services](./basic-services.md).
pub atlas: Option<OrganismRef<'a>>,
pub almanac: Option<OrganismRef<'a>>,
pub chronicle: Option<OrganismRef<'a>>,
pub compute: Option<OrganismRef<'a>>,
pub randomness: Option<OrganismRef<'a>>,
/// Optional coalition-scoped ticket issuer.
/// Non-authoritative: no component is required to
/// accept tickets from this issuer. Organisms opt in
/// via their own TicketValidator composition.
pub ticket_issuer: Option<TicketIssuerConfig<'a>>,
/// Per-coalition retirement policy. Default: explicit
/// republication on every content change.
pub retirement_policy: RetirementPolicy,
}
#[non_exhaustive]
pub struct OrganismRef<'a> {
pub role: &'a str,
/// blake3((instance_name, network_id)); changes only
/// on retirement.
pub stable_id: UniqueId,
/// Optional content hash (ACL, TDX Measurements, policy).
/// Components that pin this redeploy on operational
/// rotations.
pub content_hash: Option<UniqueId>,
}
impl CoalitionConfig<'_> {
/// blake3("coalition|" || schema_version || "|"
/// || coalition_seed || "|"
/// || instance_name || ...)
pub const fn stable_id(&self) -> UniqueId { /* ... */ }
}
CoalitionConfig is lifetime-parameterised so runtime
construction is a first-class path. All existing const
instances continue to compile under 'static inference.
An integrator binds to the coalition by passing the
CoalitionConfig into whichever member or organism
handles they need:
use std::sync::Arc;
use mosaik::Network;
use builder::{LatticeConfig, UNIVERSE};
use coalition::{
CoalitionConfig,
SCHEMA_VERSION_U8, COALITION_ROOT_SEED,
RetirementPolicy,
};
const ETH_SUPERCHAIN: CoalitionConfig<'static> =
CoalitionConfig {
schema_version: SCHEMA_VERSION_U8,
coalition_seed: COALITION_ROOT_SEED,
instance_name: "ethereum.superchain",
lattices: &[
ETH_MAINNET.stable_id(),
UNICHAIN_MAINNET.stable_id(),
BASE_MAINNET.stable_id(),
],
organisms: &[
EUR_PRICE_FEED,
INTENTS_ROUTER,
SHARED_LEDGER,
],
atlas: Some(SUPERCHAIN_ATLAS_ORG),
almanac: None,
chronicle: None,
compute: None,
randomness: None,
ticket_issuer: None,
retirement_policy: RetirementPolicy::default(),
};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let network = Arc::new(Network::new(UNIVERSE).await?);
let eth_bid = offer::Offer::<Bundle>::bid(&network, Ð_SUPERCHAIN.lattices[0].offer).await?;
let eur_feed = oracle::Feed::<Price>::read(&network, ETH_SUPERCHAIN.organisms[0].config()).await?;
let intents = intents::Router::<Intent>::publish(&network, Ð_SUPERCHAIN.organisms[1]).await?;
let atlas = atlas::Atlas::<MemberCard>::read(&network, ETH_SUPERCHAIN.atlas().unwrap()).await?;
// ...
Ok(())
}
Every organism (composite, module, or standalone) exposes
typed free-function constructors in the shape zipnet ships
and builder reproduces
(Organism::<D>::verb(&network, &Config)). Raw mosaik IDs
never cross a crate boundary.
The coalition crate’s convenience surface
The coalition crate re-exports a small convenience
surface so that book-level examples, composite organisms,
and integrator quickstarts can use the same vocabulary
without each reaching into mosaik’s module layout
directly. The surface is stable across the blueprint;
downstream crates depend on it rather than on mosaik’s
primitive modules where both are interchangeable.
| Symbol | Provenance / role |
|---|---|
coalition::Stream<T> | Alias for mosaik::streams::Producer<T> on the write side, mosaik::streams::Consumer<T> on the read side. |
coalition::Collection<K, V> | Alias for mosaik::collections::Map<K, V>. |
coalition::Network (re-export) | mosaik::Network verbatim. |
coalition::Network::subscribe_of::<T>(id) | Extension trait wrapping network.streams().consumer::<T>().with_stream_id(id).build() for ergonomic organism reads. |
coalition::TicketValidator (re-export) | mosaik::TicketValidator verbatim. |
coalition::Tdx (re-export) | mosaik::tee::Tdx; carries .require_mrtd(...) and .verify_peer(...). |
coalition::acl::ReputationFloor | Ticket composer binding admission to a reputation card floor. Consumes (UniqueId, f32). |
coalition::acl::MarketSettlement | Ticket composer binding admission to a market settlement pointer. |
coalition::when! | Declarative macro for reactive conditions over Streams; compiles to .when() method chains on mosaik::streams. |
coalition::unique_id! / const_blake3! | Compile-time blake3 of byte literals; convenience wrapper around mosaik::primitives::unique_id!. |
coalition::zipnet::SealClient | Thin wrapper over zipnet::Zipnet::<D>::submit(&network, &Config) that carries the committed digest back to the caller. |
coalition::RetirementPolicy | Per-coalition retirement policy; default is explicit republication on every content change. |
The convenience surface is the book’s one central
declaration of these symbols. Every chapter that uses
Stream, Collection, ReputationFloor, when!, or
SealClient imports them from coalition::*, not from
mosaik/zipnet directly. Downstream crates that want the
raw primitives are free to bypass the convenience surface,
but the book’s prose does not.
Fingerprint convention, not a registry
Same discipline as zipnet and builder:
- The coalition operator publishes the
CoalitionConfigstruct (or a serialised fingerprint) as the handshake. - Consumers compile it in.
- If TDX-gated, the operator publishes the committee TDX Measurements for every organism (composite, module, or standalone) whose admission is TDX-attested. Per-member TDX Measurements are published by the per-member operator; the coalition operator re-publishes them for convenience, not as authority.
- There is no on-network coalition registry. A directory collection of known coalitions may exist as a devops convenience; it is never part of the binding path.
Typos in the coalition instance name, in member
fingerprint ordering, or in any organism’s parameters
surface as Error::ConnectTimeout, not “coalition not
found”. The library cannot distinguish “nobody runs this”
from “operator is not up yet” without a registry, and
adding one would misrepresent the error.
What a coalition is not
-
A member’s owner. A coalition references a member; per-member operators control admission, rotate keys, retire instances. The coalition’s
CoalitionConfigupdates independently. -
A consensus unit. There is no coalition-level Raft group, no coalition state machine, no coalition log. The coalition layer adds naming, modules, and module derivation — no consensus.
-
A routing device. Coalitions do not carry traffic between members. Every member and organism discovers peers via mosaik’s usual gossip on the shared universe. The coalition fingerprint is a compile-time token, not a runtime hub.
-
An ACL root. A coalition does not issue tickets on behalf of referenced members. Each member’s
TicketValidatorcomposition is unchanged; each organism has its ownTicketValidator. The optional ticket issuer is opt-in per component: components that want to recognise its tickets include its issuance root in their validator composition; others ignore it. -
A closed catalog. Unlike builder’s six organisms, this blueprint does not enumerate a canonical set of lattice classes, organism categories, or composite organisms. Real members and composite organisms ship when a concrete problem forces them.
Four conventions (three inherited, one added)
Every organism the blueprint references — whether standalone, composite, or a module — reproduces the three zipnet conventions verbatim; the coalition adds one.
-
Identifier derivation from the organism’s Config fingerprint. Inherited from zipnet.
-
Typed free-function constructors.
Organism::<D>::verb(&network, &Config)returning typed handles; raw IDs never leak across crate boundaries. Inherited from zipnet; mirrored by every organism in every lattice, every composite organism, and every module. -
Fingerprint, not registry. Inherited from zipnet; reaffirmed by builder and here.
-
Membership-by-reference, module-by-derivation. New for the coalition rung. A
CoalitionConfigfolds member fingerprints as content without re-deriving their organism IDs; composite organisms are likewise referenced, not derived. Modules (Atlas, Almanac, Chronicle) and an optional ticket issuer are the components whose identity foldsCOALITION_ROOT.
What the pattern buys
-
Collapsed integrator model: one
Network, oneCoalitionConfigper coalition, typed handles on each referenced member, composite organism, and consumed module. -
Operator pacing. A coalition starts as one operator’s set of members, adds a second operator’s member without touching the first’s, and adds a composite organism or module without forcing either per-member operator to change anything.
-
Clean retirement. A commissioned composite organism retires by the coalition’s next
CoalitionConfigomitting it — or, if the organism itself is going away, by a retirement marker on its own stream. Integrators seeConnectTimeout, the ladder’s standard failure mode, or a clean upgrade pointer. -
Cross-member services as organisms, not protocols. A shared-ledger composite organism, cross-feed correlator, cross-chain intent router, Atlas, or Almanac is a mosaik organism following the zipnet pattern. Its author reuses every primitive, ticket validator, and replication guarantee.
-
Open catalog. New lattice classes, organism categories, and composite organisms arrive on their own schedules and fold into the existing handshake shape without forcing the coalition layer to change.
Where the pattern strains
Three limitations a contributor extending this must be explicit about.
Member upgrades churn coalition-scoped identity
A member-level change bumping its stable id — a retirement
— changes the corresponding entry in COA_LATTICES or
COA_ORGANISMS for every coalition that references the
member, which in turn changes COALITION_ROOT and every
module derived under it.
The stable-id / content-hash split keeps routine
operational rotations out of COALITION_ROOT: TDX Measurements
rotations do not change the stable id and therefore do not
cascade. A retirement does; retirement is rare and
announced.
Commissioned composite organisms do not derive under
COALITION_ROOT, so retirements ripple through modules
only. A composite organism re-derives only when the
members it itself spans retire or when its own content
changes.
Wide composite organisms are heavy
A composite organism reading public surfaces from ten members simultaneously runs ten subscriptions, holds peer entries for ten ticket-issuance roots, and is sensitive to the liveness of all ten. The coalition blueprint does not make this easier; it makes it legible.
Commissioning contributors should consider sharding: a per-pair composite organism over interesting member pairs, composed by an integrator, is often cheaper and more debuggable than one wide composite organism.
The coalition is not cryptographically authoritative
A CoalitionConfig fingerprint is a naming convenience.
It does not sign, commit on-chain, or expose a channel for
per-member operators to discover which coalitions
reference their member. A per-member operator objecting
to being referenced has no technical recourse — anyone
with a list of member stable ids can publish a
CoalitionConfig.
This is intentional. The only cryptographic check is
whether each referenced member admits the composite
organisms’ committee peers via its own TicketValidator.
Per-member and coalition operators negotiate references
out of band.
Checklist for commissioning a new composite organism
-
Identify the one or two public primitives. If the surface is not a small, named, finite set of streams or collections, the interface is not yet designed.
-
Identify the members it spans. Record as ordered sequences of member references in the composite organism’s
Config— lattices, organisms, or both. Order matters; changing it changes the fingerprint. -
Pick the composite organism’s name. Folded into the organism’s own derivation; no coalition root is involved.
-
Define the
Configfingerprint inputs. Content parameters affecting the state-machine signature, upstream public surfaces subscribed to, ACL composition. -
Write typed constructors.
Organism::<D>::verb(&network, &Config). Never export rawStreamId/StoreId/GroupIdacross the crate boundary. -
Specify
TicketValidatorcomposition on the public primitives. ACL lives there. If the composite organism wants to recognise any coalition’s ticket issuer, its validator composition includes that issuance root directly; the composite organism chooses, the coalition does not impose. -
Decide per-member-failure behaviour. If member A is down, does the composite organism keep processing remaining members’ inputs or stall? Document as part of the composition contract.
-
Document which members’ public surfaces are read. This is the composition contract; changes to it touch Composition.
-
Declare dependency on any modules. If the composite organism aligns to Almanac ticks or observes Chronicle entries, state so in the crate documentation.
-
Answer: does this composite organism meaningfully aggregate across members, or is it an integrator in disguise? If an ordinary integrator holding the same N member handshakes could do the same work, skip the composite organism. The pattern earns its keep when the aggregated fact is itself a commit with its own consumers.
-
State the versioning story. If the answer to “what happens when one of the referenced members bumps its fingerprint?” is not defined, the design is incomplete.
Cross-references
- Anatomy of a coalition — concrete instantiation of the pattern for one example coalition.
- Basic services — Atlas, Almanac, Chronicle specified.
- Ticket issuance — the optional coalition-scoped issuance root.
- Composite organisms — shape and discipline of cross-member organisms.
- Composition — how members and composite organisms wire together without cross-Group atomicity.
- Atomicity boundary — what the coalition layer inherits and adds.
- Threat model — compositional trust.
- Roadmap — versioning, the deferred-primitives space, first commissioned composite organisms.