The RUDP connection id 0x1d0d0001 appeared nowhere in this repository. It lived only in Odin's publisher implementation, which meant the constant defining how to reach Idunn was owned by a consumer. The three constants are now stated here: connection id, signed statement schema, and the unsigned diagnostic schema. The publishing transport moves to CultLib as a generic module that takes them as a contract, so consumers declare them against this document rather than each carrying their own copy of the transport. Recorded a discrepancy while writing it down: the wire value for the unsigned schema is idunn.daemon_health, with no version suffix, while prose in guide.md and earlier in this file says idunn.daemon_health.v1. The table gives the wire value. Reconciling the prose is a separate question about whether the wire should carry the suffix. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
13 KiB
Idunn signed daemon-health authority
Objective
Idunn must know which daemon authored a health statement before that statement
can affect lifecycle judgment or operator status. A typed packet is a shape,
not an identity. The current generic idunn.daemon_health.v1 RUDP path checks
shape, daemon id, contract, self-declared publication source, and freshness but
does not authenticate the publisher. It is diagnostic input until replaced.
Owner
- Each daemon owns its health statement and signs it with its pinned service or host identity.
- Idunn owns admission, freshness, monotonic lineage, and the outward projection of current authenticated provider health. Lifecycle judgment remains private Idunn policy and is not smuggled into that provider-health statement.
- Root deployment configuration owns the trust binding between daemon id, health contract, source runtime, and signer identity.
No renderer, transport peer, systemd unit, PID probe, caller boolean, or typed but unsigned packet owns health.
Authenticated daemon health is selected before release-source inspection. Release state may request a rollout of an otherwise healthy body, but a missing checkout or upstream cannot replace the daemon's liveness statement or block restart of an unhealthy admitted body. Continuity restart and deployment are separate authorities: only the latter is gated by the deployment brake.
Wire contract
Idunn owns these constants. A publisher supplies them to a generic transport; they are not the transport's to choose, and this document is where they are defined.
| Constant | Value |
|---|---|
| RUDP connection id | 0x1d0d0001 |
| Signed statement schema | idunn.signed_daemon_health.v1 |
| Unsigned diagnostic schema | idunn.daemon_health |
The signing purpose is the signed statement schema id, so a statement signed for
Idunn cannot verify as another service's health. The signature and identity
domains — gamecult.provider-health.signature.v1 and
gamecult.provider-health.identity.v1 — are shared GameCult domains rather than
Idunn's, and a publisher may not vary them.
The publishing transport lives in CultLib as
cultnet-ts's signed-daemon-health module. It is generic: it binds, shakes
hands, signs, puts the document, and waits for the ack, taking the three
constants above as a contract. Consumers declare that contract against this
document; they do not each reimplement the transport.
Note that the unsigned schema is idunn.daemon_health, without a version
suffix, while prose elsewhere in this repository says idunn.daemon_health.v1.
The wire value is the one in the table.
Inputs
The daemon-authored statement binds:
- exact daemon id and health contract;
- source runtime id and signer identity;
- observation time, publisher incarnation, and monotonic sequence;
- bounded health state and detail;
- release id, release witness, source revision, and deployment request when the managed target is release-bound;
private_state_exposed=false;- an Ed25519 signature over the complete unsigned statement under a domain-separated signing purpose.
The Idunn trust binding names the only public key allowed to speak for that daemon/contract/runtime tuple and whether release identity is required.
Yggdrasil Odin uses the generic signed contract with daemon
yggdrasil-odin, source runtime odin-yggdrasil, and a root-provisioned
Ed25519 key readable only by the Odin runtime group. Its health signature owns
liveness. Exact Odin and CultLib revisions remain deployment authority in the
immutable release and /srv/odin/deploy/deployment.env; neither Docker health
nor the signed liveness statement may rewrite that witness.
Outputs
Idunn persists two separate current facts per daemon:
- one admitted daemon-authored statement, keyed by daemon id, plus its exact digest in the admission;
- an Idunn-authored
idunn.authenticated_provider_health_projection.v1record binding the trust record, admission, exact provider lineage, and freshness interval.
Signed heartbeats are current liveness state, not an append-only event ledger. Advancing a daemon's publisher sequence atomically replaces that daemon's prior statement, admission, and compatibility health row. Startup atomically compacts legacy digest-keyed statement history to the one exact statement named by each current admission. A missing or digest-mismatched witness fails closed; it is never reconstructed from process probes or a later heartbeat.
The surrounding keepalive store follows a separate bounded-retention policy. It keeps exact current authority plus small per-daemon diagnostic windows; historical pulse decisions, repeated alarms, and superseded actuation receipts cannot make authentication fsync cost grow with host age. The current deployment head and every record required to rejoin active signed health remain pinned through compaction.
The outward record exists only while a generic provider-authored admission is
current and still matches its root trust and optional release binding. Missing
publication, release drift, dependency failure, target absence, and recovery
policy are absence of this projection. They are not synthetic provider states.
The projected state is exactly the authenticated provider state. Its only
explanation is a closed Idunn-generated reason code paired to that state:
authenticated_provider_active, _warming, _degraded, or _failed.
There is no free-text detail field.
Consumers such as Epiphany Discord Status receive only the outward projection through CultNet/CultMesh and verify Idunn's pinned identity. Reading Idunn's private store is not a consumer protocol.
The query transport is an explicit, read-only CultNet/RUDP listener enabled by
--public-health-query-bind <addr>. It has no default and is valid only with
--swarm-profile, --service-identity-store, and --public-health-store.
The listener opens only the dedicated public store and derives its allowlist
from the configured target catalog's daemon/health-contract pairs. It returns
the exact stored projection payload bytes with fixed source runtime
idunn-daemon and role authenticated-provider-health-projector. It has no
handle to Idunn's private stores and accepts no mutation message.
Derived state
- Process and systemd observations are diagnostic evidence only.
- RUDP source endpoints and connection ids are transport routing only.
publication_source,transport,ready, andhealthystrings are display data unless contained inside a valid signed statement.- An unsigned legacy health packet may be retained temporarily for diagnostics but cannot satisfy managed health, prevent recovery, or produce a healthy outward projection.
Forbidden writers
- The inbound packet cannot choose its own trust anchor.
- A daemon cannot change its configured daemon id, contract, or source runtime by signing different values.
- Idunn cannot manufacture daemon-authored health from PID, executable, container, HTTP, systemd, or command exit observations.
- Epiphany, Bifrost, VoidBot, Eve, and Discord cannot infer Idunn acceptance from a sent packet.
- A generic typed
idunn.daemon_health.v1packet cannot fall back into lifecycle authority when signature verification fails or trust is absent.
Shared paths
Every managed daemon uses the same verification primitive:
signed statement -> root trust binding -> signature and tuple verification -> monotonic admission -> target/deployment join -> Idunn outward projection
Epiphany's deployed epiphany.idunn_signed_runtime_health.v0 path is migration
evidence and the first working implementation of the signature half. It is not
the permanent excuse for a service-specific verifier. The generic contract
must absorb its invariants before the special path is deleted.
Cut line
- Add generic signed-health and trust-binding contracts.
- Make generic Idunn admission verify the pinned tuple, signature, sequence, incarnation, freshness, and release requirements.
- Migrate Epiphany and Bifrost publishers and install their root-owned trust bindings.
- Publish and verify Idunn's outward signed authenticated-provider-health
projection using the fixed CultNet signature profile
idunn.authenticated-provider-health-projection.v1. - Point Discord Status at the outward projections.
- Delete generic unsigned health from managed-health authority and delete the Epiphany-only verifier after its last publisher migrates.
The rebuild is incomplete while an unsigned packet can keep a managed daemon healthy or while a status consumer must inspect Idunn's private store.
Implemented cut (2026-07-19)
The deployed-lineage source now has the first executable generic admission
path. idunn.signed_daemon_health.v1 is verified against an exact root-store
daemon/contract/runtime binding, the signer identity is derived from the bound
public key, the Ed25519 signature covers the positional empty-signature
statement under the domain-separated document purpose, and Idunn atomically
persists the signed statement, its generic admission, and the compatibility
health row. Managed-health selection rejoins all three with the current root
binding on every read; trust rotation invalidates old health. Sequence,
incarnation, observation, freshness, and optional deployment lineage advance
under CAS.
Unsigned idunn.daemon_health.v1 packets now persist only as
idunn.unsigned_daemon_health_diagnostic.v1 under diagnostic:<daemon>.
They cannot overwrite the daemon health key, create an admission, reset the
missing-publication clock, suppress recovery, or produce authenticated health.
The evaluation clock is passed through the whole target cycle instead of being
resampled inside the health selector.
Idunn now also has the local outward projection writer. One publisher opens an
already-enrolled Idunn service identity before workers start, captures an
incarnation-stable root trust snapshot, and writes only
idunn.authenticated_provider_health_projection.v1 envelopes to a distinct
public store. Each write rejoins the exact health, admission, signed statement,
root binding, and optional current deployment lineage. The signed positional
record has a fixed hash-derived key, a store-monotonic sequence, a process UUID,
and an expiry capped by the provider observation's managed-health silence
window. Missing, legacy, unsigned, drifted, or mutated input cannot write,
refresh, or delete a projection; an old row simply expires for consumers.
The public projection has a dedicated multi-peer CultNet/RUDP snapshot
listener. Startup synchronously binds the explicit address and validates the
public store before target workers start. Bind failure or public-store
contamination is fatal startup evidence. Each request rereads only that store
and passes exact records through CultNet's read-only snapshot server with the
target-derived (schema,key) allowlist. Unknown schema/key requests return no
record. Malformed datagrams or messages are refused per peer without killing
the daemon. No request can write, delete, import, or inspect private Idunn
state.
This source is deliberately not deployable yet: Bifrost and the remaining generic publishers still emit the unsigned diagnostic contract, production root trust and Idunn identity stores have not been installed, and Epiphany still uses its signed v0 migration path. The query transport and Epiphany consumer verifier now exist in source, but neither makes an unmigrated publisher authoritative. Deploying this intermediate source would correctly classify unmigrated daemons as missing health and could therefore actuate recovery. Publisher migration and trust enrollment must land before promotion.
Verification layer
Hostile tests must prove:
- valid shape with no signature is not admitted;
- wrong key, daemon, contract, runtime, release, deployment, or trust record is not admitted;
- replay, sequence rollback, time rollback, incarnation substitution, and future/stale observations are not admitted;
- a live PID, existing executable, green HTTP response, or generic
readystring cannot repair failed authentication; - one daemon's trust record cannot authenticate another daemon;
- unsigned legacy health cannot suppress recovery or yield outward healthy;
- outward provider health is signed by Idunn under the fixed, typed purpose and binds the exact admitted statement;
- missing health, release drift, and dependency failure cannot write or refresh the projection; any prior row expires instead of being rewritten as an Idunn-authored provider state;
- caller-selected signing purposes, signer ids, reason strings, and synthetic states fail closed;
- private detail and filesystem/process internals never enter the operator projection.
- repeated signed heartbeats keep exactly one signed statement per admitted daemon rather than growing the monolithic keepalive store;
- startup compaction keeps only the exact statement named by each admission, is idempotent, and loses cleanly to a concurrent whole-store mutation rather than overwriting it.