Basic services — Atlas, Almanac, Chronicle, Passport
audience: contributors
A basic service is a confluence (or, in the simplest shape, a single-committee organism) whose role is specified once in this blueprint so every instance means the same thing across govs. This chapter specifies the four basic services.
None of the four is mandatory. A gov may ship zero, one, two, three, or all four. If a gov ships a service named “Atlas”, it must have the shape on this page. A service named “Atlas” with a different shape is a bug, not a variant — the point of the catalog is that integrators and other confluences depend on the shape without reading per-gov operator prose.
Guiding discipline:
Fix the shapes, leave the catalogs open.
The four basic services, the GovConfig structure, and
the ConfluenceConfig structure are shapes. Which of
them any given gov ships, and what other confluences it
commissions, and what citizens it composes, are open.
Atlas — the directory
Problem. Integrators need a canonical list of the gov’s citizens with operator metadata: role name, fingerprint, endpoint hint, ticket-issuance root, MR_TD pins, subscription schema version. Every gov currently invents its own handshake table; standardising the shape lets a dashboard, analytics agent, or failover service read any gov’s directory without per-gov parsing.
Shape. Atlas is a confluence whose public surface is
a Map<CitizenId, CitizenCard>. Each card is co-signed
by the Atlas committee:
pub struct CitizenCard {
/// The citizen's fingerprint (LatticeConfig or
/// OrganismRef fingerprint).
pub citizen_id: UniqueId,
/// Role name ("lattice", "oracle", "attest", ...).
pub role: &'static str,
/// Endpoint hints for cold-start bootstrap.
pub endpoint_hints: &'static [EndpointHint],
/// Ticket-issuance root of the citizen's per-operator
/// ACL.
pub ticket_issuance_root: UniqueId,
/// MR_TD pins for TDX-gated organisms inside the
/// citizen (if any).
pub mrtd_pins: &'static [Mrtd],
/// Free-form metadata the operator surfaces.
pub metadata: &'static [(&'static str, &'static str)],
}
Config signature. An Atlas’s ConfluenceConfig
folds:
- the gov root;
- the ordered list of citizen fingerprints the Atlas catalogues (usually identical to the gov’s, but may be a subset);
- the Atlas committee’s ACL.
State machine. One command per card write, one command per card retirement. Applies produce card updates in deterministic order.
Trust shape. Usually majority-honest, non-TDX. A TDX- attested Atlas is a natural v1+ refinement if the gov requires signed provenance of the directory itself.
When to ship. Almost always. Atlas is the cheapest basic service to operate and the highest-leverage for integrators.
When to skip. A single-citizen gov does not need a directory.
Almanac — the shared clock
Problem. Confluences correlating facts across citizens need a shared time axis. Each citizen’s clock is local — a block-building lattice has slots, an oracle has ticks, an analytics pipeline has batches. Without a shared monotonic beacon, every correlator re-invents its own tolerance window.
Shape. Almanac is a confluence whose public surface
is a single append-only Stream<AlmanacTick>. Each tick
is co-signed by the Almanac committee and carries a
monotonic sequence number plus an observed wall-clock
timestamp:
pub struct AlmanacTick {
pub seq: u64,
/// Approximate wall-clock, observed by the quorum at
/// commit time. Not a precise clock; use `seq` for
/// ordering and `observed_at` for loose alignment
/// with external events.
pub observed_at: SystemTime,
}
Config signature. An Almanac’s ConfluenceConfig
folds:
- the gov root;
- the tick cadence (target inter-tick interval; state- affecting);
- the Almanac committee’s ACL.
State machine. A per-cadence-deadline Commit
command. Committee members propose ticks; the one that
wins the Raft round commits; others observe.
Trust shape. Majority-honest committee; optionally
TDX-attested if the gov requires observed_at to carry
an attested source.
When to ship. When more than one confluence needs cross-citizen timing, or when a standalone organism without a slot clock participates in cross-citizen correlation.
What it is not. Almanac is not a consensus clock for the universe; it is not synchronised across govs; it is not a substitute for each citizen’s own local clock. Ticks are ordering markers, not timestamps.
Chronicle — the audit log
Problem. A gov operator makes decisions that outlive
any one GovConfig — publications, rotations,
retirements, federation changes, basic-service upgrades.
Integrators, auditors, and future operators need a
tamper-evident record. Operator-published release notes
are insufficient; they can be edited in place.
Shape. Chronicle is a confluence whose public surface
is an append-only Stream<ChronicleEntry>. Each entry is
co-signed by the Chronicle committee:
pub struct ChronicleEntry {
pub seq: u64,
pub kind: ChronicleKind,
/// The gov fingerprint at the moment of entry.
pub gov_root: UniqueId,
/// Structured payload per kind.
pub payload: ChronicleBody,
pub observed_at: SystemTime,
}
pub enum ChronicleKind {
GovPublication, // new GovConfig fingerprint
CitizenAdded, // new lattice / organism reference
CitizenRemoved,
ConfluenceUpgraded, // ConfluenceConfig fingerprint bump
BasicServiceAdded,
BasicServiceRetired,
FederationChanged, // operator added / removed
Retirement, // gov retirement announcement
Other(&'static str),
}
Config signature. A Chronicle’s ConfluenceConfig
folds:
- the gov root;
- the Chronicle committee’s ACL;
- the schema version of
ChronicleEntry.
State machine. One command per entry. Applies
maintain a strictly monotonic seq. Retention is
operator-configured but must be substantial (years, not
days) — the point is longevity.
Trust shape. Majority-honest; TDX is common when the
Chronicle must attest observed_at accurately. A gov
that also ships a Passport often lets Chronicle entries
be countersigned by the actor that triggered them (a
federation operator, a basic-service operator).
When to ship. When the gov has more than one operator, a contested lineage (retirements, splits, forks), or a real need for externally verifiable provenance.
What it is not. Chronicle is descriptive, not prescriptive. It records decisions; it does not ratify them. A heavy-gov proposal could build ratification on top of Chronicle; that is not this blueprint.
Passport — optional citizenship
Problem. Some govs want a lightweight notion of “citizen of this gov” separate from the per-citizen ticket discipline — for discount rates, preferred routing, cross-operator recognition, or brand alignment. Ad hoc implementation per gov invites inconsistency and silent privilege leaks.
Shape. Passport is a confluence whose public surface is:
- a write-side
Stream<PassportRequest>(a citizen’s operator submits a request to be recognised); - a read-side
Map<OperatorId, PassportGrant>(the committee’s decision, with an expiry).
pub struct PassportRequest {
pub operator_id: UniqueId,
pub citizens: &'static [UniqueId],
pub attestation: Option<Mrtd>,
pub purpose: &'static str,
}
pub struct PassportGrant {
pub operator_id: UniqueId,
pub granted_at: SystemTime,
pub expires_at: SystemTime,
pub scopes: &'static [&'static str],
}
Config signature. A Passport’s ConfluenceConfig
folds:
- the gov root;
- the Passport committee’s ACL;
- the grant policy (state-affecting: issuable scopes, default expiry, attestation thresholds).
State machine. Request commands are validated against the policy; grant commands commit grants with expiries; revocation commands invalidate grants before expiry.
Trust shape. Variable. Passport for a single-operator gov is usually a thin layer over the operator’s own identity; Passport for a federated gov typically requires TDX attestation and a majority-honest committee to resist any one operator-member forging grants.
When to ship. When the gov has cross-operator federation and wants a durable cross-operator recognition primitive outside each citizen’s per-lattice ACL. Rarer than Atlas, Almanac, or Chronicle.
What it is not — strict. Passport is opt-in for citizens and integrators alike. Never required for a citizen to operate. A citizen’s operator may decline to request a Passport and the gov has no recourse. Integrators may present a Passport for preferred routing or ignore it. This is load-bearing: a Passport that required citizens to hold one would cross from light- gov to heavy-gov (authority over membership), which this blueprint refuses.
Deriving a basic service’s identity
Every basic service is a confluence; its derivation follows the confluence rule:
ATLAS_ROOT = GOV_ROOT.derive("service").derive("atlas")
ALMANAC_ROOT = GOV_ROOT.derive("service").derive("almanac")
CHRONICLE_ROOT = GOV_ROOT.derive("service").derive("chronicle")
PASSPORT_ROOT = GOV_ROOT.derive("service").derive("passport")
<service>_committee = blake3(
<service>_root
|| ordered citizen ids it spans (if any)
|| service_content_fingerprint
|| service_acl_fingerprint
).derive("committee")
The "service" prefix distinguishes basic services from
commissioned confluences (which use "confluence"). The
distinction is cosmetic but useful: an operator reading
peer-discovery gossip can tell which is which at a
glance.
GovConfig helpers
Because basic services have well-known names, the gov
meta-crate ships typed helpers returning their
ConfluenceConfigs from a GovConfig:
impl GovConfig {
pub const fn atlas(&self) -> Option<&ConfluenceConfig> { /* ... */ }
pub const fn almanac(&self) -> Option<&ConfluenceConfig> { /* ... */ }
pub const fn chronicle(&self) -> Option<&ConfluenceConfig> { /* ... */ }
pub const fn passport(&self) -> Option<&ConfluenceConfig> { /* ... */ }
}
Each helper looks up a ConfluenceConfig in the gov’s
confluences slice by name ("atlas", etc.) and returns
Some if found, None otherwise. A gov that ships the
service names its ConfluenceConfig accordingly; a gov
that does not ship it omits the entry.
Integrators use these helpers to stay forward-compatible:
a gov adding Almanac later does not break an integrator
that did not use it before, and the integrator can start
using it simply by re-reading gov.almanac().
Deliberately unspecified
- Chronicle retention policy and storage layout.
Operator-configured. The spec requires durability and a
monotonic
seq; it does not prescribe how operators achieve them. - Passport grant policies. Each gov picks its own issuance criteria; the spec pins only the request / grant surface.
- Almanac tick cadence. The spec allows any state- affecting cadence; different govs will pick substantially different rates.
- Atlas metadata schema. Free-form
(key, value)pairs beyond the required fields. Operators add what they need; standardisation emerges from patterns over time. - Whether a basic service is required for any
downstream confluence. Confluences may depend on a
basic service (e.g. a correlator aligning to Almanac
ticks), but the blueprint does not require it; a
confluence that needs a service declares the dependency
in its own
ConfluenceConfig. - Heavy-gov extensions. Law, taxation, enforcement, mandatory citizenship — all deferred, all requiring a fresh proposal that restates the non-authority line.
Cross-references
- topology-intro — rationale for the gov rung.
- architecture — basic services in an example gov.
- confluences — the generic shape every basic service inherits.
- composition — how a basic service’s subscriptions compose with the rest of the gov.
- threat model — trust composition when a confluence depends on a basic service.