cultnet-ts removed a fragment buffer only on successful reassembly, so a
set that lost one fragment was stranded for the life of the session and
the map grew without bound.
That path is live here. Ghostlight sends this service sealed envelopes
over CultMesh RUDP with max_fragment_bytes = 2048
(Ghostlight/crates/ghostlight-dungeon/src/heimdall.rs:697), and the
private command plane reassembles them through exactly that map, so every
lost fragment on that link left a buffer nothing would collect on a
long-running auth service.
The pin also carries the media stream contracts, but those are cultnet-rs
additions this service does not build -- the recipe builds cultcache-ts,
cultnet-ts and cultmesh-ts only. The functional change for Heimdall is the
32-line eviction in cultnet-ts/src/rudp.ts.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Heimdall published `idunn.signed_daemon_health.v1`, the previous generation's
contract. Odin admits a document as runtime presence only when it carries
`gamecult.runtime_presence_health.v2` and its record key equals the signed
target; everything else it stores as an ordinary document. So Heimdall's
health arrived, was filed away, and no topology correlation for it was ever
produced -- which is what held every deployment at Warming.
The statement is dual-proved, so the process must also prove it is the
incarnation Idunn started, using the activation key passed as a descriptor
beside the presence identity. Every field describing the launch is read from
the runtime bundle rather than configuration.
Two things had to be fixed for that to be possible at all:
The descriptor lookup compared LISTEN_PID to our own pid. Under PrivatePIDs
systemd sets it to a pid in the outer namespace, so it never matched, and
because the lookup answers "undefined" rather than throwing, Heimdall quietly
self-enrolled a key nothing trusts -- exactly the failure its own comment
warns about. The name in LISTEN_FDNAMES identifies the descriptor.
The publisher sequence was an in-process counter starting at zero every boot.
Idunn treats a repeat or regression as a replay, so a restart would have made
every later statement refusable; it now lives beside the target's state.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Heimdall took CultLib as file:../CultLib/packages/*, a sibling checkout
outside this repository. Nothing pinned which CultLib a given Heimdall
commit was built against, and a sealed source could not reach it. The
deploy manifest worked around this by cloning CultLib separately to
/srv/build/CultLib with cultlib_commit=5cefa0db hardcoded in shell -- the
pin existed, it just lived in an untyped place where no build could see it.
vendor/CultLib is now a submodule pinned at exactly 5cefa0db, the commit
the manifest already used, so this change is purely structural: the
dependency does not move. Bumping to a current CultLib is a separate
change, and should be, or a failure could not be attributed.
This also uncovered that the build was never reproducible from a clean
checkout. The sibling directory had dist/ present because someone had
built it by hand at some point; a fresh CultLib clone has none, and the
packages' main/types point straight at dist/. Building Heimdall against a
fresh CultLib fails with thirteen TS2307s. The manifest knew -- it runs
npm ci then npm run build for cultcache-ts, cultnet-ts and cultmesh-ts
before touching Heimdall -- but that knowledge lived only in the shell
script. It belongs in the recipe's steps, which is where it goes next.
Verified end to end on a fresh submodule clone: the three CultLib packages
build, pnpm install resolves, tsc exits 0, dist/src/index.js is produced
(the exact path heimdall.service runs), and vitest passes 38 tests in 9
files.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>