Stand Idunn up as its own repository

Extracted from Odin with full history via subtree split -- 136 commits, not a
flat copy. Idunn had lived as crates/idunn-daemon inside the repository of a
service it manages, which inverted the authority it exists to hold: doctrine
says Idunn must start, recover, observe and report while any managed target is
absent, and it was a directory inside one.

Manifest made standalone: workspace inheritance replaced with concrete edition,
license and publish; package renamed idunn; and cultmesh-rs moved off the
vendored path onto CultLib at c13b6ba, where the reconciled crate now lives.
All three substrate deps now resolve from CultLib and nothing resolves from
Odin.

The severing was small because most of it had already happened. idunn-daemon
already sourced its contracts from cultnet_rs -- brakes, service identity,
runtime activation, expected incarnation. One residual odin_core import
remained, and four of its six symbols were not odin-core's to begin with; it
merely re-exported them from cultnet_rs. drivers.rs was already importing two
of those directly, so the crate disagreed with itself about where they came
from.

Behaviour preserved exactly: 63 passed / 18 failed here, identical to the
results in the Odin tree. The 18 are Windows path semantics -- Linux
deployment paths against Path::is_absolute -- not regressions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-09-05 17:51:56 +02:00
commit cc5ff98245
4 changed files with 1331 additions and 5 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

1262
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,10 @@
[package]
name = "idunn-daemon"
description = "GameCult deployment admission and daemon-survival authority"
name = "idunn"
version = "0.1.0"
edition.workspace = true
license.workspace = true
publish.workspace = true
edition = "2024"
license = "MIT"
publish = false
[[bin]]
name = "idunn"
@ -19,7 +20,7 @@ path = "src/lib.rs"
[dependencies]
anyhow = "1"
cultmesh-rs = { path = "../../vendor/cultmesh-rs" }
cultmesh-rs = { git = "https://github.com/GameCult/CultLib.git", rev = "c13b6ba07e99f2535b455da74d07d88c308731f5", package = "cultmesh-rs" }
cultcache-rs = { git = "https://github.com/GameCult/CultLib.git", rev = "c13b6ba07e99f2535b455da74d07d88c308731f5", package = "cultcache-rs" }
cultnet-rs = { git = "https://github.com/GameCult/CultLib.git", rev = "c13b6ba07e99f2535b455da74d07d88c308731f5", package = "cultnet-rs" }
rmp-serde = "1.3"

62
README.md Normal file
View file

@ -0,0 +1,62 @@
# Idunn
GameCult's deployment admission and daemon-survival authority.
Extracted from [Odin](https://github.com/GameCult/Odin) on 2026-09-05 with its
full history (136 commits). Idunn had lived as `crates/idunn-daemon` inside the
repository of a service it manages, which inverted the authority it exists to
hold.
## Authority
**Owner.** Idunn owns deployment admission and the continuity of installed
bodies. It decides whether an artifact may be installed and whether an
already-admitted body may be restarted.
**Inputs.** Its own typed state stores, its own credentials, and an
operator-provided trust anchor. Nothing else.
**Invariant.** *Idunn must be able to start, recover, observe and report while
any managed target is absent, broken, or deliberately braked.* A target's brake
gates mutation of that target only; it can neither authorize nor block Idunn's
own startup, nor another target's lifecycle.
**Two brakes, not one.** Deployment and continuity are separate authorities
with separate stores, and the daemon refuses to start if they resolve to the
same store. Restarting an already-admitted installed release is continuity
physiology. Changing an artifact, revision, configuration, schema, unit or
authority binding is deployment. A deployment brake does not own the former.
**Forbidden.** Idunn does not depend on any managed target. It does not repair
a target merely to satisfy a deploy; if recovery would require that, the target
dependency is the thing to cut.
## Contracts
Idunn's typed contracts are published by
[CultLib](https://github.com/GameCult/CultLib) in `cultnet-rs` — the deployment
and lifecycle brakes, service identity, runtime activation, expected
incarnation, and the provider-health family. Idunn consumes them; it does not
define its own copies.
Odin holds its own separate projection of Idunn state for aggregation, in
`odin-core`. That is Odin's view as the all-seer, not Idunn's contract, and the
two sets do not overlap.
## Binaries
- `idunn` — the daemon.
- `idunn-provision` — operator provisioning and brake inspection.
## Building
```
cargo build
cargo test
```
**Idunn is a Linux daemon.** On Windows, 18 of 81 tests fail because they
assert against absolute deployment paths (`/srv/...`, `/var/lib/gamecult/...`)
and Rust's `Path::is_absolute()` requires a drive prefix there. That is
platform semantics, not breakage; the same 18 fail identically in the Odin tree
this was extracted from. Build and test on Linux for a true result.