Operator: "None of these options involve repair and recovery, which is what
ultimately needs to happen." Q-R1..R6 open; R1 (CultLib typed read failures,
temp cleanup) does not depend on them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
README and architecture.md called Idunn "Odin's keepalive organ", listed
crates/idunn-daemon (not in this repo) and the deleted odin-core idunn.rs
as its body, described the Node coordinator's process lifecycle, refresh
loop and Docker/ADB probes as Odin's runtime body, and pointed at the
deleted start-odin.ps1. Rewritten to the live truth: Idunn builds, activates,
restarts and brakes every target, Odin included; odin-daemon reads Idunn's
projection, admits presences, publishes correlation records and answers RUDP
requests; process lifecycle is not Odin's.
The dated ledger (transport-shortcut-inventory.md), notes/ and the Hermodr
extraction plan are history and are left as written.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The three muninn crates, their seventeen actuator scripts, the two Raven
capture-mux wrappers that called one of them, and the two Muninn docs all
leave this workspace. GameCult/Muninn has carried them since 2026-09-09 and
has moved on (media stream advertisement, receivers dialling the producer);
this copy was a fork drifting behind under the same name, and gamecult-ops
now binds every Muninn target to the Muninn repository. Odin keeps the
Muninn records in odin-core until they are moved; that is the remaining
piece of the extraction.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Static lowering landed in GameCult/Hermodr: a library and CLI rendering a
surface graph to standalone HTML through the same renderer the browser uses,
with command controls inert because a static page has no back-channel.
All five phases of the Hermodr extraction are complete. This document stays as
the record of what left Odin and why.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Hermodr is a browser lowering, not an all-seer organ. It lived here as Node
inside a Rust repository, sharing a module directory with the coordinator, and
until this week it ran its own provider ingress and accepted publications into a
private store. The ingress went first on purpose: extracting it beforehand would
have relocated a second acceptance authority and called that progress.
Removed: the daemon, its provider subscription source and state stream, both
test files, four lifecycle scripts, the persona avatar, the hermodr:start
script, and src/odin/utils.cjs, whose only remaining consumer was Hermodr and
which it used for one of six functions.
src/odin/ falls from fourteen modules to eleven. The CommonJS surface falls from
sixteen files to twelve. What is left is the coordinator, the Rust organs, and
two adapters declaring contracts other repositories own.
The plan document stays as the record of what left and why. Phase 5, static
lowering, is Hermodr's business now.
5 tests pass, syntax check clean over twelve files.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The plan said move idunn-rudp.cjs to Idunn. Reading it first showed that would
relocate 311 lines of generic CultNet transport into a Rust repository and hand
Odin a fragile sibling-path dependency. The split was taken instead: transport
to CultLib beside the RUDP session it builds on, constants documented by Idunn,
a 65-line adapter left in Odin declaring that contract.
Phases 1 and 2 are both complete. documents.cjs is now the only genuinely shared
dependency standing between Odin and a future Hermodr repository, which makes it
Phase 3's single remaining question.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Phase 2 landed: Hermodr reads providers through Odin-advertised routes instead
of accepting publications into a private store.
Phase 1 did not, and the plan now says why instead of leaving a specification I
had already found to be wrong. Reading idunn-rudp.cjs before moving it changed
the answer: 13 of its 324 lines mention Idunn and most are error strings. The
Idunn-owned content is two constants. The other 311 lines are generic CultNet
transport, and moving them into a Rust repository with no Node packaging would
also hand Odin a cross-repo sibling-path dependency of exactly the kind that
broke Erycina's provider publisher when that repository moved. It buys nothing
until Hermodr leaves in Phase 4, because both consumers still live here.
Three ranked options recorded. The one I would take splits the transport into
CultLib beside cultnet-ts and leaves Idunn owning its connection ID and schema
name, which removes the sibling-path bug rather than relocating it. That is
larger than this phase assumed and touches CultLib, so it wants a decision
rather than being folded in quietly.
Also dropped idunn:build and idunn:start from package.json. They invoke
cargo -p idunn-daemon, and that crate left Odin with the extraction.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The previous revision assigned provider ingress and live-publication acceptance
to Odin, and described Hermodr as a second Odin holding a parallel instance of
the same store. Both claims were wrong, and the second was asserted without
checking.
Odin is a rendezvous organ. It publishes what state is available, what schema
speaks it, and where to reach it. It is not in the data path, and it never
carried this state: neither odin-coordinator.cjs nor any Odin test references
OdinLivePublicationSource or provider-session-ingress.cjs. Those modules are
Hermodr's own state machinery wearing Odin's name and filed under src/odin/,
which is what made it read as sanctioned.
So there is no second Odin. There was never a first one for this state. The cut
is not to hand acceptance back to Odin, which does not want it, but to delete it
and have Hermodr resolve providers through the catalog and subscribe to them
directly.
The command path already models this correctly. findProviderCommandRoute looks a
route up in the catalog and publishes to the provider's own endpoint, and
Erycina's surface names Odin as discoveryOwner while pointing canonicalSurfaceUri
at Erycina's own address. The retrofitted leg got the architecture right; the
original state leg did not.
Dependency picture corrected by actual reference counts. Only documents.cjs and
idunn-rudp.cjs are genuinely shared with the coordinator. utils.cjs,
live-publication-source.cjs, and provider-session-ingress.cjs are Hermodr-only
and leave with it or are deleted, which shrinks src/odin/ from fourteen modules
to ten and removes the documents.cjs decision from the critical path of
everything else.
Negative checks now include the one that matters for the corrected model: with
Odin stopped, existing provider subscriptions must keep delivering. If they do
not, Odin is in the data path and the plan failed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Hermodr is described as the Eve-to-browser lowering bridge. It is also a second
provider ingress and a second acceptance authority: main() constructs its own
OdinLivePublicationSource, binds its own provider session with its own token,
accepts publications into that private Map, and serves them to browsers. Odin's
coordinator holds a separate instance over the same providers with no
reconciliation. A surface reaches a browser only if its provider binds to
Hermodr, which makes a required ingress out of something named a bridge.
The intent path is not the problem and is kept as-is. POST /hermodr/commands/eve
is generic across providers, wraps intent as gamecult.eve.command.v1, stamps
itself as the relay rather than the author, publishes to the provider's
advertised route, and returns a receipt. Eve's client dispatches controls
through it and refuses anything that is not a correlated receipt in state
reconciled.
The defect is that the loop does not close. Intent leaves by CultMesh to the
owner of the consequence; the consequence returns only through Hermodr's private
ingress. A provider must publish twice for the Verse to be correct and for the
operator to see their own action land. Cutting the acceptance authority is what
closes it: with the state leg subscribed to Odin-accepted state, a command's
effect returns by the same route as every other change.
The plan orders the work so the authority cut happens in place, before any file
moves, because an extraction that carries the split brain into a new repository
has only changed its address. Static lowering lands last and as a library with a
CLI, since emitting bytes from a graph earns no daemon, and requiring one would
reintroduce the dependency static lowering exists to remove.
Records five open dependencies, three phases of subtraction, and negative checks
that prove the old path can no longer accept, no longer override, and no longer
paper over Odin being absent.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Completes the extraction. Unit files and documentation went to the Idunn
repository, where a service's own deployment surface belongs. Operator scripts
went to gamecult-ops, which is where fleet tooling lives.
To Idunn: scripts/linux/idunn-yggdrasil{,.service,.sudoers}, docs/idunn.md,
docs/idunn-deployment-authority.md,
docs/idunn-signed-daemon-health-authority.md, src/Idunn/README.md.
To gamecult-ops/scripts/idunn/: the eight PowerShell and cmd operator tools --
deployment targets, startup install, swarm coverage health, operator alarm
notification, local start.
Staying in Odin, deliberately: crates/odin-core/src/idunn.rs, Odin's own
projection of Idunn state for aggregation; src/odin/idunn-rudp.cjs, its client
for talking to Idunn; test/idunn-signed-health.test.cjs, its own integration
test; and deployment/idunn/recipe.toml, which despite the path builds
odin-daemon and is Odin's recipe expressed in Idunn's format.
docs/transport-shortcut-inventory.md is a dated evidence ledger citing several
of the moved script paths. Its entries are left as written and a path note
added at the top -- rewriting a ledger to match a later reorganisation would
destroy the record it exists to keep.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>