CultLib's packages/cultcache-py is now published as cultcache-py==0.2.0 on
PyPI (MIT), so the standalone GameCult/cultcache-py fork that Ghostlight
vendored as a submodule is retired. Symbol-for-symbol and on-disk-format
verification against the pinned submodule commit 9b4bbb8 found no
incompatibility: every symbol tools/ghostlight_state_store.py imports
(CultCache, JsonLinesBackingStore, define_document_type) and every method it
calls kept its signature, and JsonLinesBackingStore's on-disk JSONL envelope
fields and sort order are unchanged, confirmed by a real round-trip against
Ghostlight's production state/ghostlight-state.cultcache.jsonl.
tools/ghostlight_state_store.py no longer pushes vendor/cultcache-py/src onto
sys.path; it imports cultcache_py directly. Since Ghostlight's session
bootstrap previously depended on the submodule needing no install step,
tools/requirements.txt now pins cultcache-py==0.2.0 and npm run
state:bootstrap (pip install -r tools/requirements.txt, idempotent) runs as a
pre-hook ahead of state:status and state:prepare-compaction; AGENTS.md's
Session Bootstrap protocol and Useful Commands section call it out explicitly
for the direct ghostlight_state.py CLI invocations that don't go through npm.
Verified for real: `python tools/ghostlight_state.py status` and `python
tools/ghostlight_prepare_compaction.py`, run from a venv with cultcache-py
installed from PyPI, against Ghostlight's actual production state file (22 ok
findings, 2 pre-existing unrelated warnings, exit 0 both times).
Idunn's deployment/idunn/recipe.toml never declared vendor/cultcache-py in
required_gitlinks (only vendor/eve) and its build/test/service steps never
touch Python state tooling, so no recipe change is needed for admission.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
vendor/README.md declared cultcache-rs, cultnet-rs and cultmesh-rs "a locally
owned compatible protocol generation". That charter is the defect. A consumer
holding its own generation of the wire stack sits outside the only harness that
checks cross-runtime agreement, and the fork behaved exactly as that predicts:
runtime_authority_contracts.rs drifted to e542225 while this repo's own
authority map named f4ab237, and the Rust CultMesh implementation existed
nowhere else in GameCult.
All three now come from CultLib pinned at 85f7024, and 19,604 lines of forked
substrate are deleted. Nothing was lost on the way out. The vendored cultnet
tree was compared file by file against CultLib: ten of twelve matched, lib.rs
differed only in module declarations, and transport.rs carried one guard that
existed nowhere else -- a framed length checked against the advertised maximum
before allocating. That guard is now CultLib 85f7024 with a test.
The migration this was expected to need does not exist. RuntimePresenceCorrelation
changing from enum to struct is Odin's side of the contract and no file here
touches it; with line endings normalised the two contract copies differ by 132
lines, and the only production change that reaches a provider is
IdunnExpectedRoute requiring rudp:// schemes for rudp transport, which this
service does not use. The code compiles unchanged.
89 tests pass across the workspace against the pinned rev.
vendor/ still holds the cultcache-py and eve submodules. cultcache-py is the
same pattern -- a runtime-specific repo CultLib also carries as
packages/cultcache-py -- but it backs the state tooling rather than the
daemon, so it is left for its own change.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>