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:
parent
d3b237a875
commit
cc5ff98245
4 changed files with 1331 additions and 5 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/target
|
||||||
1262
Cargo.lock
generated
Normal file
1262
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
11
Cargo.toml
11
Cargo.toml
|
|
@ -1,9 +1,10 @@
|
||||||
[package]
|
[package]
|
||||||
name = "idunn-daemon"
|
description = "GameCult deployment admission and daemon-survival authority"
|
||||||
|
name = "idunn"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition.workspace = true
|
edition = "2024"
|
||||||
license.workspace = true
|
license = "MIT"
|
||||||
publish.workspace = true
|
publish = false
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "idunn"
|
name = "idunn"
|
||||||
|
|
@ -19,7 +20,7 @@ path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1"
|
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" }
|
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" }
|
cultnet-rs = { git = "https://github.com/GameCult/CultLib.git", rev = "c13b6ba07e99f2535b455da74d07d88c308731f5", package = "cultnet-rs" }
|
||||||
rmp-serde = "1.3"
|
rmp-serde = "1.3"
|
||||||
|
|
|
||||||
62
README.md
Normal file
62
README.md
Normal 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.
|
||||||
Loading…
Reference in a new issue