diff --git a/README.md b/README.md index 4b6c526..966bdc9 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,7 @@ To add distilled evidence: ## Best Starting Points - `docs/architecture/canonical-agent-state-schema.md` +- `docs/architecture/cultnet-shared-agent-state-contract.md` - `docs/architecture/agent-state-variable-glossary.md` - `docs/architecture/prompt-projection-contract.md` - `docs/architecture/projection-distillation-plan.md` diff --git a/docs/architecture/cultnet-shared-agent-state-contract.md b/docs/architecture/cultnet-shared-agent-state-contract.md new file mode 100644 index 0000000..bb59a7b --- /dev/null +++ b/docs/architecture/cultnet-shared-agent-state-contract.md @@ -0,0 +1,98 @@ +# CultNet Shared Agent-State Contract + +Ghostlight owns the first cross-runtime agent-state payload contract. + +That contract is not a new ontology. It is the existing Ghostlight state shape +moving over a wire without turning into bespoke JSON fog in every other repo. + +## Canonical Payload + +The first shared payload contract is: + +- schema id: + `https://github.com/GameCult/Ghostlight/schemas/agent-state.schema.json` +- schema version: + `ghostlight.agent_state.v0` +- canonical file: + `schemas/agent-state.schema.json` + +This is the same state shape already used for Ghostlight fixtures and the same +top-level shape Epiphany role dossiers adopted. The contract is: + +- `world` +- `agents` +- `relationships` +- `events` +- `scenes` + +If another runtime wants to carry socially persistent agent state without +inventing its own private folk religion, this is the first house shape. + +## Wire Envelope + +CultNet should carry the Ghostlight payload as a typed document replication +message, not as a one-off ad hoc blob. + +Current expected document envelope: + +- `documentType`: `ghostlight.agent-state` +- `documentKey`: runtime-defined stable key +- `payloadSchemaVersion`: `ghostlight.agent_state.v0` +- `payload`: exact Ghostlight state document + +The current TypeScript client library is: + +- repo: `GameCult/cultnet-ts` + +Its job is not merely to make pipes pretty. It owns: + +- direct-pipe MessagePack framing +- typed message contracts +- authentication/session semantics compatible with CultLib's `GameCult.Networking` +- typed replication into CultCache-compatible stores + +## Authentication Story + +CultNet inherits the useful security shape from CultLib: + +- a shared connection key known to client and server/runtime peers +- AES-GCM encrypted auth/session payloads derived from that key +- a server-side session-signing secret +- signed session tokens used for verify/reconnect flows + +This matters because "shared agent state" is not only a serialization problem. +It is also a trust boundary problem. We want one family resemblance across C#, +TypeScript, Rust, and Python instead of four mutually unintelligible little +shrines to local convenience. + +## Contract Discipline + +Ghostlight remains the source of truth for the payload shape. + +That means: + +- if `schemas/agent-state.schema.json` changes, CultNet mirrors must update in + lockstep +- consumers may add local document metadata around the payload, but should not + silently mutate the payload contract itself +- if a runtime needs a narrower projection or local working view, that is a + derivative contract, not a revision of `ghostlight.agent_state.v0` + +The rule is simple: + +- prompt projection may differ +- storage engines may differ +- language bindings may differ +- the shared payload contract does not drift just because another repo got + lonely + +## Immediate Consumers + +The first intended consumers are: + +- Ghostlight fixture/state tooling +- EpiphanyAgent role dossiers and heartbeat-adjacent agent state +- VoidBot companion-state and social memory machinery where the full Ghostlight + payload is useful + +More bindings can come later. They do not get to invent a prettier truth. diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index d58f509..70bd718 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -65,6 +65,7 @@ The active path is a source-grounded branching-scene data loop: - Implementation plan: `notes/ghostlight-implementation-plan.md` - Documentation inventory: `notes/documentation-inventory.md` - Agent-state schema: `schemas/agent-state.schema.json` +- Shared CultNet state-contract note: `docs/architecture/cultnet-shared-agent-state-contract.md` - Projected local context schema: `schemas/projected-local-context.schema.json` - Coordinator artifact schema: `schemas/coordinator-artifact.schema.json` - Responder packet schema: `schemas/responder-packet.schema.json` @@ -332,6 +333,7 @@ corpus fixtures. ## Warnings - Keep persistent state small. Git history and artifacts own chronology. +- Treat `ghostlight.agent_state.v0` as the first shared cross-runtime payload contract. If another runtime needs to move agent state over a wire, it should carry the Ghostlight payload unchanged inside a typed CultNet document envelope instead of quietly forking the ontology. - Do not let notes, map, handoff, and evidence become four versions of the same brain. - Do not train on coordinator-repaired responder prose unless the repair is labeled. - Do not accept branch fixtures without branch compiler notes and IF artifact review. diff --git a/state/evidence.jsonl b/state/evidence.jsonl index 0d96512..e18cf4b 100644 --- a/state/evidence.jsonl +++ b/state/evidence.jsonl @@ -64,4 +64,5 @@ {"note": "Published Corvid Collective First Exodus to AetheriaLore as a cinematic illustrated Ink page. Site player now supports data-ink-mode=cinematic with section click-through, background image crossfades, animated text transitions, hidden state chips by default, and cohesive branch-card choices.", "status": "ok", "ts": "2026-05-05T01:04:51+00:00", "type": "implementation"} {"note": "VoidBot's new routine should become Ghostlight's cast swarm timing and memory substrate: characters take scene turns through heartbeat initiative, offstage agents use slower rumination/sleep turns for consolidation, canonical state moves toward CultCache-style MessagePack with JSON projections, and memory resonance/incubation/dream state should be backed by Qdrant vectors. Captured the plan in docs/architecture/voidbot-routine-adoption-plan.md.", "status": "ok", "ts": "2026-05-06T00:25:00+00:00", "type": "architecture"} {"note": "Ghostlight began migrating machine-managed persistent state behind cultcache-py: branch and evidence records now route through a registered CultCache seam with readable JSON exports kept for diffability and compatibility.", "status": "accepted", "ts": "2026-05-06T03:46:41+00:00", "type": "architecture"} -{"ts": "2026-05-06T03:57:10+00:00", "type": "architecture", "status": "accepted", "note": "CultCache wire contract clarified: DatabaseEntry payloads must be MessagePack arrays indexed by explicit field keys with nil gaps for reserved/deleted slots; cultcache-py now exposes define_database_entry_type for that contract and CultLib generator was patched to preserve sparse key slots."} +{"note": "CultCache wire contract clarified: DatabaseEntry payloads must be MessagePack arrays indexed by explicit field keys with nil gaps for reserved/deleted slots; cultcache-py now exposes define_database_entry_type for that contract and CultLib generator was patched to preserve sparse key slots.", "status": "accepted", "ts": "2026-05-06T03:57:10+00:00", "type": "architecture"} +{"ts": "2026-05-06T04:49:20+00:00", "type": "architecture", "status": "accepted", "note": "Ghostlight agent-state schema is now the first shared cross-runtime payload contract. CultNet clients should carry ghostlight.agent_state.v0 unchanged inside typed document envelopes, with CultLib-style auth/session semantics handled by the transport layer rather than bespoke per-repo glue."} diff --git a/state/ghostlight-state.cultcache.jsonl b/state/ghostlight-state.cultcache.jsonl index 3f1958a..1644bf6 100644 --- a/state/ghostlight-state.cultcache.jsonl +++ b/state/ghostlight-state.cultcache.jsonl @@ -66,3 +66,4 @@ {"key": "2026-05-06T002500Z0000-0064-2d3f733215cf", "payload": "eyJub3RlIjogIlZvaWRCb3QncyBuZXcgcm91dGluZSBzaG91bGQgYmVjb21lIEdob3N0bGlnaHQncyBjYXN0IHN3YXJtIHRpbWluZyBhbmQgbWVtb3J5IHN1YnN0cmF0ZTogY2hhcmFjdGVycyB0YWtlIHNjZW5lIHR1cm5zIHRocm91Z2ggaGVhcnRiZWF0IGluaXRpYXRpdmUsIG9mZnN0YWdlIGFnZW50cyB1c2Ugc2xvd2VyIHJ1bWluYXRpb24vc2xlZXAgdHVybnMgZm9yIGNvbnNvbGlkYXRpb24sIGNhbm9uaWNhbCBzdGF0ZSBtb3ZlcyB0b3dhcmQgQ3VsdENhY2hlLXN0eWxlIE1lc3NhZ2VQYWNrIHdpdGggSlNPTiBwcm9qZWN0aW9ucywgYW5kIG1lbW9yeSByZXNvbmFuY2UvaW5jdWJhdGlvbi9kcmVhbSBzdGF0ZSBzaG91bGQgYmUgYmFja2VkIGJ5IFFkcmFudCB2ZWN0b3JzLiBDYXB0dXJlZCB0aGUgcGxhbiBpbiBkb2NzL2FyY2hpdGVjdHVyZS92b2lkYm90LXJvdXRpbmUtYWRvcHRpb24tcGxhbi5tZC4iLCAic3RhdHVzIjogIm9rIiwgInRzIjogIjIwMjYtMDUtMDZUMDA6MjU6MDArMDA6MDAiLCAidHlwZSI6ICJhcmNoaXRlY3R1cmUifQ==", "stored_at": "2026-05-06T03:45:26.023960+00:00", "type": "ghostlight.evidence_record.v0"} {"key": "2026-05-06T034641Z0000-0065-ea57d8ad2b40", "payload": "eyJub3RlIjogIkdob3N0bGlnaHQgYmVnYW4gbWlncmF0aW5nIG1hY2hpbmUtbWFuYWdlZCBwZXJzaXN0ZW50IHN0YXRlIGJlaGluZCBjdWx0Y2FjaGUtcHk6IGJyYW5jaCBhbmQgZXZpZGVuY2UgcmVjb3JkcyBub3cgcm91dGUgdGhyb3VnaCBhIHJlZ2lzdGVyZWQgQ3VsdENhY2hlIHNlYW0gd2l0aCByZWFkYWJsZSBKU09OIGV4cG9ydHMga2VwdCBmb3IgZGlmZmFiaWxpdHkgYW5kIGNvbXBhdGliaWxpdHkuIiwgInN0YXR1cyI6ICJhY2NlcHRlZCIsICJ0cyI6ICIyMDI2LTA1LTA2VDAzOjQ2OjQxKzAwOjAwIiwgInR5cGUiOiAiYXJjaGl0ZWN0dXJlIn0=", "stored_at": "2026-05-06T03:46:41.487861+00:00", "type": "ghostlight.evidence_record.v0"} {"key": "2026-05-06T035710Z0000-0066-272010506962", "payload": "eyJub3RlIjogIkN1bHRDYWNoZSB3aXJlIGNvbnRyYWN0IGNsYXJpZmllZDogRGF0YWJhc2VFbnRyeSBwYXlsb2FkcyBtdXN0IGJlIE1lc3NhZ2VQYWNrIGFycmF5cyBpbmRleGVkIGJ5IGV4cGxpY2l0IGZpZWxkIGtleXMgd2l0aCBuaWwgZ2FwcyBmb3IgcmVzZXJ2ZWQvZGVsZXRlZCBzbG90czsgY3VsdGNhY2hlLXB5IG5vdyBleHBvc2VzIGRlZmluZV9kYXRhYmFzZV9lbnRyeV90eXBlIGZvciB0aGF0IGNvbnRyYWN0IGFuZCBDdWx0TGliIGdlbmVyYXRvciB3YXMgcGF0Y2hlZCB0byBwcmVzZXJ2ZSBzcGFyc2Uga2V5IHNsb3RzLiIsICJzdGF0dXMiOiAiYWNjZXB0ZWQiLCAidHMiOiAiMjAyNi0wNS0wNlQwMzo1NzoxMCswMDowMCIsICJ0eXBlIjogImFyY2hpdGVjdHVyZSJ9", "stored_at": "2026-05-06T03:57:10.429056+00:00", "type": "ghostlight.evidence_record.v0"} +{"key": "2026-05-06T044920Z0000-0067-d18749ed9b85", "payload": "eyJub3RlIjogIkdob3N0bGlnaHQgYWdlbnQtc3RhdGUgc2NoZW1hIGlzIG5vdyB0aGUgZmlyc3Qgc2hhcmVkIGNyb3NzLXJ1bnRpbWUgcGF5bG9hZCBjb250cmFjdC4gQ3VsdE5ldCBjbGllbnRzIHNob3VsZCBjYXJyeSBnaG9zdGxpZ2h0LmFnZW50X3N0YXRlLnYwIHVuY2hhbmdlZCBpbnNpZGUgdHlwZWQgZG9jdW1lbnQgZW52ZWxvcGVzLCB3aXRoIEN1bHRMaWItc3R5bGUgYXV0aC9zZXNzaW9uIHNlbWFudGljcyBoYW5kbGVkIGJ5IHRoZSB0cmFuc3BvcnQgbGF5ZXIgcmF0aGVyIHRoYW4gYmVzcG9rZSBwZXItcmVwbyBnbHVlLiIsICJzdGF0dXMiOiAiYWNjZXB0ZWQiLCAidHMiOiAiMjAyNi0wNS0wNlQwNDo0OToyMCswMDowMCIsICJ0eXBlIjogImFyY2hpdGVjdHVyZSJ9", "stored_at": "2026-05-06T04:49:20.304695+00:00", "type": "ghostlight.evidence_record.v0"} diff --git a/state/map.yaml b/state/map.yaml index b79e5fa..f1fc91c 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -62,6 +62,7 @@ live_architecture: - `state/ghostlight-state.cultcache.jsonl` is the current CultCache-backed store for migrated branch and evidence records. - `state/branches.json` and `state/evidence.jsonl` remain readable export surfaces during migration so humans, diffs, and older validators do not lose the plot. - New persistent state seams should use `tools/ghostlight_state_store.py` instead of direct file writes. + - `schemas/agent-state.schema.json` is also the first shared cross-runtime payload contract. CultNet clients should move `ghostlight.agent_state.v0` documents unchanged inside typed document envelopes instead of inventing forked state ontologies per repo. state_model: - Layer personality through organization, disposition, behavior, presentation, situational activation, relationships, goals, and values. - Canonical authored state has no certainty; perceived overlays carry observed activation, attributed disposition, and confidence.