diff --git a/.gitmodules b/.gitmodules index 5a9bf41..578af4b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "vendor/cultcache-py"] - path = vendor/cultcache-py - url = https://github.com/GameCult/cultcache-py.git [submodule "vendor/eve"] path = vendor/eve url = https://github.com/GameCult/Eve.git diff --git a/AGENTS.md b/AGENTS.md index 6f1c37d..d0ad6d4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -53,15 +53,22 @@ inside another project. - Architecture rationale: `F:\Projects\Ghostlight\notes\architecture-rationale.md` - State CLI: `F:\Projects\Ghostlight\tools\ghostlight_state.py` - CultCache state seam: `F:\Projects\Ghostlight\tools\ghostlight_state_store.py` -- CultCache-Py submodule: `F:\Projects\Ghostlight\vendor\cultcache-py` +- CultCache-Py dependency: pinned `cultcache-py==0.2.0` from PyPI, declared in + `F:\Projects\Ghostlight\tools\requirements.txt` - CultCache state store: `F:\Projects\Ghostlight\state\ghostlight-state.cultcache.jsonl` - Pre-compaction helper: `F:\Projects\Ghostlight\tools\ghostlight_prepare_compaction.py` ## Useful Commands -Use the bundled Python runtime if `python` is not on PATH: +Use the bundled Python runtime if `python` is not on PATH. `npm run state:status` +and `npm run state:prepare-compaction` install the pinned `cultcache-py` +dependency automatically (a `pre*` npm hook runs `state:bootstrap` first, an +idempotent `pip install -r tools/requirements.txt`). A direct +`ghostlight_state.py` invocation does not go through npm, so run +`state:bootstrap` once per session before the first direct call: ```powershell +npm run state:bootstrap npm run state:status npm run state:prepare-compaction & 'C:\Users\Meta\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe' '.\tools\ghostlight_state.py' add-evidence --type research --status ok --note '...' @@ -94,6 +101,8 @@ On fresh session load, do this before wandering off into implementation: - `notes/ghostlight-current-system-map.md` - `notes/ghostlight-implementation-plan.md` 2. run: + - `npm run state:bootstrap` (installs the pinned `cultcache-py` dependency; + idempotent, safe to rerun) - `npm run state:status` 3. restate the current next action from the persisted state before starting edits diff --git a/docs/architecture/persistence-spine.md b/docs/architecture/persistence-spine.md index a0bd5ab..c15e615 100644 --- a/docs/architecture/persistence-spine.md +++ b/docs/architecture/persistence-spine.md @@ -3,14 +3,19 @@ Ghostlight's machine-managed state is moving behind a small CultCache-style persistence layer instead of letting every tool paw raw files directly. -The Python port lives in `vendor/cultcache-py`, backed by the standalone -GameCult repository `cultcache-py`. +The Python port is `cultcache-py`, published by CultLib to PyPI and pinned in +`tools/requirements.txt`. It used to be vendored as the `vendor/cultcache-py` +git submodule against the now-retired standalone `GameCult/cultcache-py` +repository; PyPI distribution replaced that fork. ## Current Store - Cache store: `state/ghostlight-state.cultcache.jsonl` - Ghostlight seam: `tools/ghostlight_state_store.py` -- Library submodule: `vendor/cultcache-py` +- Library dependency: pinned `cultcache-py==0.2.0`, declared in + `tools/requirements.txt` and installed by `npm run state:bootstrap` + (an idempotent `pip install -r tools/requirements.txt`, wired as a `pre*` + hook ahead of `state:status` and `state:prepare-compaction`) - Readable exports: `state/branches.json`, `state/evidence.jsonl` The JSONL store is deliberate bootstrap plumbing. The package also exposes a diff --git a/package.json b/package.json index 29d2640..ace65ef 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,10 @@ "dungeon:run": "cargo run -p ghostlight-dungeon", "sdk:build": "npm --prefix sidecar/claude-sdk run build", "sdk:test": "npm --prefix sidecar/claude-sdk test", + "state:bootstrap": "\"C:\\Users\\Meta\\.cache\\codex-runtimes\\codex-primary-runtime\\dependencies\\python\\python.exe\" -m pip install -q -r tools\\requirements.txt", + "prestate:status": "npm run state:bootstrap", "state:status": "\"C:\\Users\\Meta\\.cache\\codex-runtimes\\codex-primary-runtime\\dependencies\\python\\python.exe\" .\\tools\\ghostlight_state.py status", + "prestate:prepare-compaction": "npm run state:bootstrap", "state:prepare-compaction": "\"C:\\Users\\Meta\\.cache\\codex-runtimes\\codex-primary-runtime\\dependencies\\python\\python.exe\" .\\tools\\ghostlight_prepare_compaction.py", "agent-state:validate": "\"C:\\Users\\Meta\\.cache\\codex-runtimes\\codex-primary-runtime\\dependencies\\python\\python.exe\" .\\tools\\validate_agent_state.py", "schema:validate": "npm run agent-state:validate && npm run projection:validate && npm run projected-context:validate && npm run lore-grounding:validate && npm run coordinator:validate && npm run responder-packets:validate && npm run responder-outputs:validate && npm run training-loop:validate && npm run initiative:validate && npm run ink:validate && npm run coverage:status", diff --git a/state/map.yaml b/state/map.yaml index 19aee29..59aa3c1 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -292,7 +292,7 @@ current_artifacts: live_examples: - state/ghostlight-state.cultcache.jsonl - tools/ghostlight_state_store.py - - vendor/cultcache-py + - tools/requirements.txt - state/corpus-coverage.json - examples/agent-state.call-of-the-void.json - examples/projections/call-of-the-void.scene-broken-taxi-oz.jsonl diff --git a/tools/ghostlight_state_store.py b/tools/ghostlight_state_store.py index 6d5839e..fc36f92 100644 --- a/tools/ghostlight_state_store.py +++ b/tools/ghostlight_state_store.py @@ -2,24 +2,28 @@ from __future__ import annotations import hashlib import json -import sys from pathlib import Path from typing import Any +try: + from cultcache_py import CultCache, JsonLinesBackingStore, define_document_type +except ModuleNotFoundError as error: + if error.name != "cultcache_py": + raise + raise SystemExit( + "Ghostlight state tooling needs cultcache-py. Install it with " + "`npm run state:bootstrap`, or with this interpreter directly: " + "`python -m pip install -r tools/requirements.txt`." + ) from error + ROOT = Path(__file__).resolve().parents[1] STATE_DIR = ROOT / "state" -VENDOR_SRC = ROOT / "vendor" / "cultcache-py" / "src" CACHE_PATH = STATE_DIR / "ghostlight-state.cultcache.jsonl" BRANCHES_PATH = STATE_DIR / "branches.json" EVIDENCE_PATH = STATE_DIR / "evidence.jsonl" ARCHIVE_PATH = STATE_DIR / "evidence.archive.jsonl" -if str(VENDOR_SRC) not in sys.path: - sys.path.insert(0, str(VENDOR_SRC)) - -from cultcache_py import CultCache, JsonLinesBackingStore, define_document_type - BRANCHES_DOC = define_document_type( "ghostlight.branches.v0", diff --git a/tools/requirements.txt b/tools/requirements.txt new file mode 100644 index 0000000..25fb93a --- /dev/null +++ b/tools/requirements.txt @@ -0,0 +1 @@ +cultcache-py==0.2.0 diff --git a/vendor/cultcache-py b/vendor/cultcache-py deleted file mode 160000 index 9b4bbb8..0000000 --- a/vendor/cultcache-py +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9b4bbb8a4d842dd02dc8b2eefda7e742aa47578c