# Idunn Idunn is Odin's keepalive organ. Odin is the all-seer: it accepts Verse discovery, schema catalogs, translation routes, provider surfaces, and observation projections. Idunn keeps the daemon swarm alive from that accepted map. It is not a second Odin, not a dashboard, and not a heroic supervisor with secret service truth in its pockets. Idunn keeps the apples: desired daemon presence, deployment freshness, boot recovery, crash recovery, health freshness, deploy/restart intent, operator escalation, and continuity witness state. ## Authority Map - Owner: Idunn owns daemon lifecycle management after Odin has accepted where a daemon lives: bring-up after host reboot, deployment freshness, crash recovery, health watching, deploy/restart policy, and operator escalation. - Inputs: Odin's accepted service records, provider advertisements, `.cc` witnesses, advertised command boundaries, freshness windows, operator policy, local service manager state, and direct local service probes only when no provider advertisement exists. - Outputs: typed keepalive observations, deployment requests/results, restart requests/results, denied-action records, operator alarms, Bifrost operator-notification requests, and an Eve/CultUI keepalive surface. - Derived state: dashboard cells, Bifrost receipts, Discord or owner-DM lowerings, agent summaries, and Odin service projections are notification-only views of Idunn-owned keepalive records. - Forbidden writers: Idunn does not decide which Verses exist, invent provider schemas, mutate provider dashboards, own identity/session grants, or hide restarts behind Odin refresh logic. Individual daemons should not carry independent crash-recovery loops once Idunn owns their lifecycle path; they publish health, surfaces, state witnesses, and command boundaries instead. - Shared paths: manual operator deploy/restart, scheduled deploy/restart, degraded-health repair, boot rehydration, and future remote worker recovery must pass through the same Idunn command primitive. - Deletion line: any keepalive loop inside Odin, Gjallar, Eve lowerers, or renderer code must be cut or demoted to a probe that names Idunn as the restart owner. ## Body Idunn now shares Odin's Rust body: - `crates/odin-core/src/idunn.rs` owns the keepalive decision engine. - `crates/odin-core/src/documents.rs` publishes typed Idunn CultMesh records beside Odin and Gjallar records. - `crates/idunn-daemon` is the local keepalive actuator crate and now owns the resident Starfire-local swarm scheduler. - `src/Idunn/README.md` is the user-facing introduction for developers, operators, and daemon authors. - `scripts/start-idunn-local.ps1` is now a narrow bootstrap wrapper: it ensures one `idunn.exe` process is alive, checks the shared keepalive store for staleness, and lets Rust own the target catalog and per-target scheduling. - `scripts/deploy-yggdrasil-source-app.ps1` and `scripts/health-yggdrasil-source-app.ps1` are the generic Yggdrasil source artifact lane. They package committed local `HEAD` with `git archive`, run the existing ops-owned deploy/check scripts on Yggdrasil, and stamp a remote `gamecult.idunn.deployment_manifest.v1` only after the remote check passes. - `scripts/idunn-deployment-targets.ps1` is the current swarm deployment target catalog. Every known deployable target is either `enforced`, `blocked`, `external-owned`, or `not-runtime` with an explicit reason. - `scripts/health-idunn-swarm-deployment-coverage.ps1` is the coverage probe that fails when the target catalog becomes incoherent. The local Idunn launcher runs it as `idunn-swarm-deployment-coverage` so missing deploy ownership becomes a watched operational fault. - `scripts/notify-idunn-operator-alarm.ps1` is the local operator crossing: Idunn invokes it only after raising an operator alarm, and it asks Bifrost to publish a typed `gamecult.operator_dm_request.v1` CultMesh command document instead of learning Discord delivery itself. - `npm run idunn:build` builds the Rust daemon. - `npm run idunn:start -- ...` still supports the narrow one-daemon probe path for manual use. - `npm run idunn:start -- --swarm-profile starfire-local --repo-root E:\Projects\Odin --execute` runs the singular local swarm supervisor. The current typed records are: ```text idunn.desired_daemon.v1 idunn.daemon_health.v1 idunn.keepalive_decision.v1 idunn.deployment_request.v1 idunn.deployment_result.v1 idunn.restart_request.v1 idunn.restart_result.v1 idunn.operator_alarm.v1 ``` ## Invariants - Odin remains the accepted owner of Verse and service discovery. - Idunn owns continuity decisions after a daemon is known. - Individual daemons own their work and their health publication, not their surrounding lifecycle. They must be simple to kill and simple for Idunn to bring back. - Providers own their own command boundaries. Idunn requests deployment or restart through advertised authority or a named local service manager adapter. - Host reboot recovery, crash recovery, stale deployment recovery, stale-health recovery, and manual operator deploy/restart must share the same Idunn command primitive. - A repair loop is not an owner. If a daemon becomes healthy only after a later Odin refresh or manual click, Idunn's ownership path is still incomplete. - Restart attempts must be witnessed: requested by whom, against which service, through which command boundary, with what result and timestamp. - Idunn should fail closed when authority is unclear. Unknown ownership, repeated restart failure, missing command authority, or degraded health that needs a human becomes an operator alarm. - Operator alarms use CultMesh to request Bifrost-owned operator notification. Bifrost is the bridge for the crossing and records the receipt. VoidBot's `voidbot.operator-dm` command `owner.dm.send` with payload schema `gamecult.operator_dm_request.v1` is a demoted compatibility delivery actuator, not the owner. The owner-DM command lives in Bifrost's Verse; any still-VoidBot delivery path must be invoked by Bifrost or documented as migration debt. Idunn must not learn Discord token handling, DM delivery internals, or VoidBot-specific transport. - In the current local bridge, `--operator-alarm-command` invokes `notify-idunn-operator-alarm.cmd`, which forwards `IDUNN_ALARM_*` environment variables to `E:\Projects\Bifrost\tools\operator-notification.mjs publish-idunn-alarm`. Bifrost publishes the typed CultMesh command document; Idunn only decides that an alarm exists. - Muninn continuity on Raven is a remote keepalive path. Idunn probes the deployed Odin `muninn.exe --health` through the `raven` SSH alias and restarts Muninn's idle `serve` posture when needed. Raven is the host/body; Muninn is the local telemetry Verse assembler. Idunn must not activate screen/audio streams as part of keepalive. Raven A/V over SRT is an explicit activation path through `activate-muninn-raven-av-srt.ps1`, not daemon startup behavior. - Nightwing Gjallar deployment freshness is now part of Idunn's ops role. `health-nightwing-gjallar.ps1` verifies both `gjallar.service` liveness and the remote deployment manifest at `/opt/gamecult/gjallar/gamecult-gjallar-deploy-manifest.txt`. A missing or stale manifest makes health fail. Idunn then runs `deploy-nightwing-gjallar.ps1`, which publishes the committed local Gjallar revision, writes `gamecult.gjallar.deployment_manifest.v1`, restarts `gjallar.service`, and leaves deployment request/result records in its keepalive `.cc`. - Swarm-wide deployment ownership means Idunn owns the target catalog and the freshness contract for the repo swarm. It does not mean Idunn invents deploy authority for every repo immediately. A target without a safe noninteractive deploy command must remain `blocked` or `external-owned` with the missing authority named until a wrapper can produce a deployment manifest and route through Idunn's typed deployment request/result path. - Yggdrasil Heimdall, repixelizer, and StreamPixels are enforced through the generic source artifact lane and their existing `gamecult-ops` runbooks. Bifrost is explicitly blocked as of 2026-06-09: committed Bifrost `HEAD` expects `UserAccounts.HeimdallAccountId`, while Yggdrasil's production database lacks that column and EF reports no pending migration. Idunn must not claim Bifrost deployment freshness until Bifrost owns that schema migration path. ## Runtime Direction Idunn's current Rust runtime now has two postures: 1. One-daemon manual mode for focused probes and explicit local testing. 2. One-process swarm mode for the Starfire-local continuity graph. The local swarm mode owns: 1. the built-in Starfire-local target catalog; 2. one in-process schedule per target instead of one watchdog process per target; 3. shared typed keepalive records in one CultMesh store; 4. deploy/restart/alarm execution through the same Rust decision engine; 5. recovery of fast local targets like Odin without waiting behind slow remote Yggdrasil checks. Next: ingest Odin-owned service/provider advertisements directly, promote the target catalog out of hardcoded bootstrap data, add named adapters for Windows services, systemd, Docker, and provider-advertised CultMesh commands, then publish an Eve/CultUI keepalive surface. No ad hoc JSON manifest may become the live state owner. Debug projections are fine when they name the `.cc` record or CultMesh document behind them.