Document GameCult daemonic swarm architecture
This commit is contained in:
parent
6e93513e8e
commit
d2d0eaada1
4 changed files with 316 additions and 0 deletions
88
docs/daemonic-swarm-prior-work.md
Normal file
88
docs/daemonic-swarm-prior-work.md
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
# Daemonic Swarm Prior Work
|
||||
|
||||
This note collects the local prior work behind the GameCult daemonic swarm
|
||||
architecture. It is a reference ledger for
|
||||
`docs/gamecult-daemonic-swarm.md`, not a second doctrine surface.
|
||||
|
||||
## AquaSynth
|
||||
|
||||
- `docs/verse-service-contract.md`: AquaSynth is already named as a synth
|
||||
daemon. It accepts `.aqua` patch/control documents, owns Faust compilation,
|
||||
native instrument lifetime, live control sessions, sampled outputs, and
|
||||
typed receipts. It now exposes `cultnet-host`, `cultnet-once`,
|
||||
`cultnet-stream`, and `cultnet-daemon` as local CultNet command surfaces.
|
||||
- `src/AquaSynth.Faust/AquaSynthDaemonService.cs`: the service owns
|
||||
`patch.compile`, `instrument.sample`, and bounded `instrument.stream`
|
||||
execution. It writes compile/session/render/stream/operator witnesses and
|
||||
emits CultMesh-compatible stream descriptors and packet receipts.
|
||||
- `src/AquaSynth.Faust/AquaSynthCultNetDaemon.cs`: local CultNet database host
|
||||
and command watcher. Typed command documents enter the database; typed
|
||||
receipts and provider state come back out.
|
||||
- `state/spine.yaml`: the current invariant says `AquaSynthDaemonService` owns
|
||||
execution while `AquaSynthCultNetDaemon` owns local CultNet command
|
||||
observation. JSON-lines modes are only operator/xeno edges.
|
||||
|
||||
## Eve
|
||||
|
||||
- `Eve:README.md`: Eve is the display/control/sensor edge for GameCult apps.
|
||||
Participants publish structured surfaces through CultMesh; clients render
|
||||
those surfaces locally, return operator intent, and publish local sensor
|
||||
observations. Durable service state belongs in CultCache `.cc`; local Verse
|
||||
visibility belongs in CultMesh; discovery belongs in Odin.
|
||||
- `Eve:docs/surface-contract-v1.md`: `gamecult.eve.surface.v1` is a retained
|
||||
CultMesh UI document. Providers own truth, accepted state, command effects,
|
||||
and style token values. Eve owns the surface contract, command envelope,
|
||||
renderer parity, and local input/sensor publication. Renderers own native
|
||||
projection only.
|
||||
- `gamecult-site:docs/gamecult_void_dossier.md`: the blunt public sentence:
|
||||
Eve should not share applications; Eve should share inspectable control
|
||||
surfaces. The same semantic surface gets different local bodies: web,
|
||||
desktop, mobile, Unity, overlays, rooms.
|
||||
|
||||
## CultLib And CultMesh
|
||||
|
||||
- `CultLib:src/GameCult.Mesh/docs/public-api.md`: `CultMeshNode` wraps the
|
||||
local runtime pieces: `CultCache`, `CultNet` server, distributed realtime
|
||||
database facade, and schema-v0 bridge. CultMesh is the package surface;
|
||||
CultNet remains lower-level transport plumbing where appropriate.
|
||||
- `CultLib-main-work:packages/cultmesh-kotlin/README.md`: Kotlin/Android
|
||||
clients carry typed MessagePack document codecs, a small CultNet lane, and
|
||||
Eve dashboard/sensor document contracts. Device streams are observation
|
||||
transport, not synchronization authority.
|
||||
- `CultLib-main-work:packages/cultcache-py/src/cultmesh_py/facade.py`: Python
|
||||
has the same conceptual entrypoint shape: create/start nodes, local servers,
|
||||
Verse discovery, peer exchange, game sessions, simulation fact commitment,
|
||||
and stream catalogs.
|
||||
|
||||
## Odin And Idunn
|
||||
|
||||
- `Odin:src/Idunn/README.md`: Idunn is the keepalive daemon for the Odin swarm.
|
||||
It knows which GameCult daemons should be alive, restarts or alarms when
|
||||
appropriate, records deployment/restart decisions as typed state, and does not
|
||||
steal work ownership from the daemons it supervises.
|
||||
- `Odin:crates/idunn-daemon/src/main.rs`: the Starfire/local swarm profile
|
||||
includes concrete daemon targets such as Odin, VoidBot, Weksa, Muninn, Vili,
|
||||
Yggdrasil services, Nightwing Gjallar, and other local machine helpers.
|
||||
- `gamecult-site:GameCult/Projects/index.md`: CultLib is described as the
|
||||
nervous system family: CultCache persists typed state, CultNet carries typed
|
||||
communication, and CultMesh networks daemons, service surfaces, schema
|
||||
catalogs, and interface projections. Odin is the all-seer for Verse
|
||||
discovery, schema awareness, translation routes, provider surfaces, and
|
||||
interface aggregation. Idunn keeps the swarm alive.
|
||||
|
||||
## Operating Pattern
|
||||
|
||||
The repeated shape across the prior work is:
|
||||
|
||||
```text
|
||||
script or supervisor starts daemons
|
||||
-> each daemon publishes typed state, command boundaries, health, and surfaces
|
||||
-> Odin discovers and aggregates provider state
|
||||
-> Eve lowers provider-owned surfaces into the local native runtime
|
||||
-> users issue command intent through the surface
|
||||
-> providers accept or reject commands
|
||||
-> providers publish updated typed state and receipts
|
||||
```
|
||||
|
||||
The window is usually not the application. The window is the local Eve body. The
|
||||
application is the swarm behind it.
|
||||
225
docs/gamecult-daemonic-swarm.md
Normal file
225
docs/gamecult-daemonic-swarm.md
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
# The GameCult Daemonic Swarm
|
||||
|
||||
Most GameCult apps are not one process wearing one window.
|
||||
|
||||
The window is usually a thin Eve terminal in whatever runtime is native to the
|
||||
machine in front of you: browser, UIKit, Android, Direct2D, Unity, overlay,
|
||||
framebuffer, TUI, or some future room-sized disgrace with good posture. The
|
||||
actual application intelligence lives in the swarm of daemons that the script,
|
||||
launcher, service manager, or Idunn profile brings alive behind it.
|
||||
|
||||
That is not ornament. It is the build pattern.
|
||||
|
||||
## The Shape
|
||||
|
||||
A GameCult app is a visible local body attached to a distributed service mind.
|
||||
|
||||
```text
|
||||
native Eve terminal
|
||||
-> CultMesh surface and command documents
|
||||
-> provider daemon command boundary
|
||||
-> provider-owned state transition
|
||||
-> CultCache/CultMesh receipts
|
||||
-> Eve projection update
|
||||
```
|
||||
|
||||
The user sees one app. The system is usually several organs:
|
||||
|
||||
- a provider daemon that owns domain truth and side effects;
|
||||
- a CultCache store that preserves typed state and receipts;
|
||||
- a CultNet/CultMesh node that publishes state and accepts command documents;
|
||||
- an Eve surface document that describes the controls, views, health, and
|
||||
command routes;
|
||||
- a local renderer that lowers that surface into native controls;
|
||||
- Odin, when present, discovering providers and assembling Verse sight;
|
||||
- Idunn, when present, keeping the expected daemons alive and witnessed.
|
||||
|
||||
The native window is important. It owns the user's local body: pixels, input,
|
||||
latency, accessibility, media decode, sensors, device permissions, platform
|
||||
integration. It does not own the truth just because it has glass.
|
||||
|
||||
## Why We Build This Way
|
||||
|
||||
Most software quietly fuses three things that should stay separate:
|
||||
|
||||
- the thing that knows the domain;
|
||||
- the thing that persists and publishes state;
|
||||
- the thing the user touches.
|
||||
|
||||
That works until it does not. Then every platform port becomes a second
|
||||
application, every dashboard becomes a private little kingdom, every renderer
|
||||
starts deciding state because it was nearby, and every service grows its own
|
||||
watchdog, schema story, and status panel. The machine fills with plausible
|
||||
duplicate authorities. It starts passing tests while forgetting what it is.
|
||||
|
||||
GameCult cuts the body differently.
|
||||
|
||||
Providers own consequences. Eve owns presentation and local input. CultMesh owns
|
||||
typed visibility, subscriptions, provenance, and command transport. CultCache
|
||||
owns durable typed state. Odin owns discovery and aggregation. Idunn owns
|
||||
continuity. Bifrost owns operator/public crossings when a command leaves the
|
||||
private machine and touches humans, governance, money, publishing, or social
|
||||
surface.
|
||||
|
||||
No organ gets the whole throne. This is how the machine stays legible after it
|
||||
starts doing real work.
|
||||
|
||||
## Eve Is The Terminal, Not The App
|
||||
|
||||
Eve is not remote desktop. Eve is not a browser shoved into every product until
|
||||
everything smells like a compromise. Eve is the portable control surface layer.
|
||||
|
||||
A provider publishes a retained semantic surface:
|
||||
|
||||
- stable component ids;
|
||||
- layout intent;
|
||||
- bindings to typed state;
|
||||
- available commands;
|
||||
- health and freshness;
|
||||
- style tokens;
|
||||
- provenance;
|
||||
- capability requirements.
|
||||
|
||||
Each runtime lowers that surface locally. Web uses web controls. iOS uses native
|
||||
views. Android uses Android views. Fensalir can lower the same surface into
|
||||
Direct2D/DirectWrite. Unity can mount the same surface into a game scene.
|
||||
Framebuffer and TUI clients can lower it into dense operator instruments.
|
||||
|
||||
Same semantic surface. Different flesh.
|
||||
|
||||
That is the point. Fensalir should not have to integrate AquaSynth as a private
|
||||
synth library just to make sound. It should talk to AquaSynth as a provider:
|
||||
discover the service, submit patch and control documents, receive instrument
|
||||
handles or stream descriptors, and render the operator surface locally.
|
||||
|
||||
## Daemons Own Capabilities
|
||||
|
||||
A daemon is not just a background process. In this architecture, a daemon is a
|
||||
capability owner with a typed public edge.
|
||||
|
||||
A good GameCult daemon publishes:
|
||||
|
||||
- service id and Verse id;
|
||||
- schema catalog or document bindings;
|
||||
- command documents it accepts;
|
||||
- receipt documents it emits;
|
||||
- health and freshness state;
|
||||
- durable `.cc` witness locations;
|
||||
- Eve/CultUI surfaces for operator inspection and control;
|
||||
- explicit boundaries naming what it does not own.
|
||||
|
||||
AquaSynth is the current synth example. AquaSynth owns patch parsing, Faust
|
||||
emission, native compilation, compiled instrument sessions, sample rendering,
|
||||
bounded stream receipts, and synth-control state. A client can send
|
||||
`instrument.sample` or `instrument.stream` as typed command state through the
|
||||
local CultNet database. AquaSynth compiles or opens the instrument, writes
|
||||
sample artifacts and receipts, and publishes the result. The client consumes
|
||||
the capability; it does not become the synth.
|
||||
|
||||
That lets one AquaSynth daemon sit on this machine or another machine in the
|
||||
Verse and serve multiple apps. The same engine can support Fensalir, Eve
|
||||
operator panels, music agents, render workers, game tools, and future live
|
||||
performance clients without each one embedding its own incompatible synth
|
||||
brain.
|
||||
|
||||
The same pattern applies elsewhere:
|
||||
|
||||
- Mimir owns observation and synchronization interpretation.
|
||||
- VoidBot owns its local swarm state and Persona/tool surfaces.
|
||||
- Weksa owns utterance intent and lowering.
|
||||
- StreamPixels owns creator/render pipeline state.
|
||||
- Odin owns discovery and provider aggregation.
|
||||
- Idunn owns daemon continuity and restart witnesses.
|
||||
|
||||
Each daemon is a small sovereign machine. The swarm is the application.
|
||||
|
||||
## The Script Starts The Swarm
|
||||
|
||||
When a GameCult script says "run the app," it often means "start the local
|
||||
swarm profile."
|
||||
|
||||
That may start one daemon. It may start ten. It may start a provider, a broker,
|
||||
a sensor receiver, a renderer, a bridge to a device, a keepalive process, and a
|
||||
browser reference client. The important part is that every process has a named
|
||||
authority.
|
||||
|
||||
The script should not become the owner of state. The script is an ignition
|
||||
ritual with logging. It starts the bodies, records enough handles to stop or
|
||||
inspect them, and gets out of the way. Long-running work belongs in durable
|
||||
processes with health signals, typed state, and restart policy.
|
||||
|
||||
If the app only works while one attached shell window stays open, the machine is
|
||||
still a prototype. Sometimes that is fine. It should not be confused with the
|
||||
architecture.
|
||||
|
||||
## Fast Local Does Not Mean In-Process
|
||||
|
||||
Same-machine providers should feel native. That does not require shoving every
|
||||
capability into the UI process.
|
||||
|
||||
The split is:
|
||||
|
||||
- typed state and commands over CultNet/CultMesh;
|
||||
- realtime data over the fastest honest local lane;
|
||||
- visible controls through Eve;
|
||||
- domain work inside the provider daemon.
|
||||
|
||||
For AquaSynth, that means patch requests, compile receipts, session state, and
|
||||
stream descriptors are typed documents. Audio blocks should eventually move
|
||||
through a low-latency local transport such as shared-memory rings, platform
|
||||
audio graph nodes, memory-mapped packet buffers, or another fixed-block lane
|
||||
that does not drag filesystem writes or chatty command protocols into the audio
|
||||
callback. The command surface still owns intent and receipts. The realtime lane
|
||||
just moves sound fast.
|
||||
|
||||
That distinction matters. Transport is not authority. A ring buffer should not
|
||||
decide what instrument exists. A renderer should not decide which command
|
||||
landed. A cache should not pretend to be the current audio clock. Every layer
|
||||
gets one job sharp enough to inspect.
|
||||
|
||||
## What This Buys Us
|
||||
|
||||
The daemonic swarm approach gives GameCult a few practical advantages:
|
||||
|
||||
- **Shared capability:** one local or network daemon can serve many apps.
|
||||
- **Native feeling:** each platform gets a real local renderer instead of the
|
||||
lowest common UI.
|
||||
- **Inspectable state:** commands, receipts, health, schemas, and surfaces are
|
||||
typed documents, not private process memory.
|
||||
- **Crash containment:** a renderer can die without erasing provider truth; a
|
||||
provider can fail with receipts instead of silent UI weirdness.
|
||||
- **Portability:** a service publishes one semantic surface; each runtime lowers
|
||||
it.
|
||||
- **Operator clarity:** Odin can discover what exists, and Idunn can keep
|
||||
expected daemons alive without guessing private truth.
|
||||
- **Coherent growth:** new apps compose existing capabilities instead of
|
||||
cloning them.
|
||||
|
||||
The tradeoff is discipline. This architecture punishes fuzzy ownership. If a
|
||||
daemon, renderer, script, cache, and bridge can all decide the same result, the
|
||||
swarm becomes mush with sockets. Fast mush, maybe. Still mush.
|
||||
|
||||
## The Rule
|
||||
|
||||
When building a GameCult app, ask first:
|
||||
|
||||
- What daemon owns the capability?
|
||||
- What typed state proves what happened?
|
||||
- What command documents does it accept?
|
||||
- What receipts does it emit?
|
||||
- What Eve surface makes it visible and controllable?
|
||||
- What local runtime lowers that surface for this user?
|
||||
- What fast lane is needed for realtime data?
|
||||
- What does this process explicitly not own?
|
||||
|
||||
If the answer is "the window owns everything," the design is probably still
|
||||
too small or too young.
|
||||
|
||||
If the answer is "the provider owns truth, Eve owns the local touch surface,
|
||||
CultMesh carries typed state, Odin sees it, and Idunn keeps it alive," then the
|
||||
machine is beginning to have the right anatomy.
|
||||
|
||||
That is how we build at GameCult: not one app with a private dashboard, but a
|
||||
swarm of provider daemons, typed memory, portable surfaces, and native bodies.
|
||||
The user touches a window. The window touches the swarm. The swarm does the
|
||||
work.
|
||||
|
|
@ -280,3 +280,4 @@
|
|||
{"timestamp":"2026-06-15T01:02:24+01:00","topic":"aquasynth-daemon-sample-duration-ownership","claim":"AquaSynth daemon instrument.sample requests must own render duration; direct CompileScript envelope estimates are not sufficient for sample-command frame counts. Use AquaSynthDaemonService duration-aware source compilation and verify requested frames at the receipt layer.","evidence":"JSON-lines smoke returned 2205 samples for 0.05s after duration ownership moved into daemon compile path."}
|
||||
{"timestamp":"2026-06-15T01:34:00+01:00","topic":"aquasynth-daemon-bounded-automation-stream","claim":"A bounded realtime-shaped automation stream now belongs to AquaSynthDaemonService, not the CLI or a future transport listener. The service compiles once, opens a native Faust streaming patch, applies per-block controls, emits CultMesh-compatible audio/control descriptors and frame handles, writes per-block float32 packet bodies, and persists one stream receipt.","evidence":"src/AquaSynth.Faust/AquaSynthDaemonService.cs; tests/AquaSynth.Dsl.Tests/AquaSynthDaemonServiceTests.cs; tools/AquaSynthDaemon/Program.cs; docs/verse-service-contract.md"}
|
||||
{"timestamp":"2026-06-15T01:42:00+01:00","topic":"aquasynth-local-cultnet-daemon","claim":"AquaSynth now has a local CultNet daemon boundary: typed patch/sample/stream command documents are written to the CultNet database, AquaSynthCultNetDaemon watches and serializes them through AquaSynthDaemonService, and typed compile/render/stream/provider receipts are published back to the database. The service remains the render/session owner; CultNet is transport and publication authority.","evidence":"src/AquaSynth.Faust/AquaSynthCultNetDaemon.cs; tools/AquaSynthDaemon/Program.cs; tests/AquaSynth.Dsl.Tests/AquaSynthDaemonServiceTests.cs; docs/verse-service-contract.md; CLI smokes: cultnet-once returned 2205 sample frames for 0.05s and cultnet-stream returned 2 packet receipts with control frame count 1 on block 1."}
|
||||
{"timestamp":"2026-06-15T02:05:00+01:00","topic":"gamecult-daemonic-swarm-doc","claim":"GameCult app architecture is now documented as a daemonic swarm pattern: the visible window is usually a thin native Eve terminal, while provider daemons own capabilities, typed state, commands, receipts, health, and surfaces. The prior-work ledger ties the article back to AquaSynth, Eve, CultMesh, Odin, Idunn, and public GameCult site references.","evidence":"docs/gamecult-daemonic-swarm.md; docs/daemonic-swarm-prior-work.md; state/map.yaml"}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ surfaces:
|
|||
cultnet_daemon: src/AquaSynth.Faust/AquaSynthCultNetDaemon.cs
|
||||
daemon_tool: tools/AquaSynthDaemon/AquaSynthDaemon.csproj
|
||||
verse_service_contract: docs/verse-service-contract.md
|
||||
daemonic_swarm_article: docs/gamecult-daemonic-swarm.md
|
||||
daemonic_swarm_prior_work: docs/daemonic-swarm-prior-work.md
|
||||
patch_library: patches
|
||||
tests: tests/AquaSynth.Dsl.Tests
|
||||
reference_roadmap: docs/reference-synth-roadmap.md
|
||||
|
|
|
|||
Loading…
Reference in a new issue