Ghostlight/deployment/idunn/recipe.toml
Meta Vens 751b5c4150 Take runtime identity, bind, and state root from Idunn
The daemon declared its own GHOSTLIGHT_RUNTIME_ID, GHOSTLIGHT_DUNGEON_BIND,
and GHOSTLIGHT_DUNGEON_ROOT. Under the managed contract Idunn owns all three:
the runtime id arrives inside the activation bundle, the bind is a candidate
socket Idunn hands down, and the state root is an admitted workload path.
A service that also names them from its own environment is a second opinion
about facts it does not own.

runtime.rs already resolved the runtime id from the admission and kept
GHOSTLIGHT_RUNTIME_ID only as the unmanaged fallback. This is the caller side
catching up: main.rs accepts --state-root and passes it through, and the recipe
declares the state_root argument binding plus the three GAMECULT_IDUNN_*
variables while dropping the three the daemon no longer reads.

The binding is required, not cosmetic. Idunn refuses a stateful workload with
no state_root argument binding and refuses one whose binding disagrees with
the admitted root, so the recipe could not have deployed without it.

The acceptance harness kept its own GHOSTLIGHT_RUNTIME_ID; it is renamed to
GHOSTLIGHT_ACCEPTANCE_RUNTIME_ID so a test-supplied identity cannot be mistaken
for the managed one.

The mesh surface test compared the published record against a freshly built
surface, including updatedAtUtc, which is a live timestamp. It now asserts the
structural fields, parses the timestamp, and compares surface and commands.

cargo test --workspace: 89 passed, 0 failed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 01:24:08 +02:00

187 lines
4.7 KiB
TOML

schema = "gamecult.idunn.target_declaration.v1"
target = "ghostlight"
source_stamp_environment = "GHOSTLIGHT_BUILD_COMMIT"
required_gitlinks = ["vendor/eve"]
[[steps]]
id = "test-persona-boundary"
phase = "test"
runner = "rust-build"
argv = ["cargo", "test", "--locked", "-p", "ghostlight-persona-projection"]
[[steps]]
id = "test-world-owner"
phase = "test"
runner = "rust-build"
argv = ["cargo", "test", "--locked", "-p", "ghostlight-dungeon", "--bin", "ghostlight-dungeon"]
[[steps]]
id = "build-daemon"
phase = "build"
runner = "rust-build"
argv = ["cargo", "build", "--locked", "--release", "-p", "ghostlight-dungeon", "--bin", "ghostlight-dungeon"]
[[steps]]
id = "install-web-dependencies"
phase = "prepare"
runner = "web-build"
argv = ["npm", "--prefix", "web", "ci"]
[[steps]]
id = "test-web"
phase = "test"
runner = "web-build"
argv = ["npm", "--prefix", "web", "test"]
[[steps]]
id = "build-web"
phase = "build"
runner = "web-build"
argv = ["npm", "--prefix", "web", "run", "build"]
[[steps]]
id = "accept-real-persona-membrane"
phase = "acceptance"
runner = "rust-acceptance"
argv = [
"cargo",
"test",
"--locked",
"-p",
"ghostlight-dungeon",
"--bin",
"ghostlight-dungeon",
"world::controllers::tests::real_codex_connector_cognition_modes_commit_speech",
"--",
"--ignored",
"--exact",
]
required_environment = [
"GHOSTLIGHT_ACCEPTANCE_PERSONA_PROSE_LOG",
"GHOSTLIGHT_ACCEPTANCE_RUNTIME_ID",
"GHOSTLIGHT_CONTROLLER_CONNECTOR",
"GHOSTLIGHT_CONTROLLER_CREDENTIAL",
"GHOSTLIGHT_CONTROLLER_INTERPRETER_MODEL",
"GHOSTLIGHT_CONTROLLER_OPERATIONAL_MODEL",
"GHOSTLIGHT_CONTROLLER_PERSONA_MODEL",
"GHOSTLIGHT_CONTROLLER_PROJECTOR_MODEL",
]
[[artifacts]]
id = "ghostlight-dungeon"
source_kind = "runner-output"
runner = "rust-build"
source = "target/release/ghostlight-dungeon"
destination = "ghostlight-dungeon"
executable = true
[[artifacts]]
id = "web"
source_kind = "runner-output"
runner = "web-build"
source = "web/dist"
destination = "web"
[service]
executable_artifact = "ghostlight-dungeon"
required_adjacent_artifacts = ["web"]
arguments = [
{ kind = "literal", value = "--state-root" },
{ kind = "binding", name = "state_root" },
]
transport = "http"
route_required = true
required_environment = [
"GAMECULT_IDUNN_CANDIDATE_BIND",
"GAMECULT_IDUNN_PROCESS_WRITE_LEASE",
"GAMECULT_IDUNN_RUNTIME_BUNDLE",
"GHOSTLIGHT_CONTROLLER_CONNECTOR",
"GHOSTLIGHT_CONTROLLER_CREDENTIAL",
"GHOSTLIGHT_CONTROLLER_INTERPRETER_MODEL",
"GHOSTLIGHT_CONTROLLER_OPERATIONAL_MODEL",
"GHOSTLIGHT_CONTROLLER_PERSONA_MODEL",
"GHOSTLIGHT_CONTROLLER_PROJECTOR_MODEL",
"GHOSTLIGHT_DISCORD_GUILD_ID",
"GHOSTLIGHT_DISCORD_ROLE_ID",
"GHOSTLIGHT_HEIMDALL_APP_SECRET_FILE",
"GHOSTLIGHT_HEIMDALL_BASE_URL",
"GHOSTLIGHT_LOCATED_SERVICE",
"GHOSTLIGHT_ODIN_RUDP",
"GHOSTLIGHT_PUBLIC_APP_URL",
"GHOSTLIGHT_SERVICE_ID",
"GHOSTLIGHT_SESSION_WRAPPING_KEY_FILE",
]
optional_environment = ["RUST_LOG"]
[service.health]
contract = "ghostlight.cultnet-rudp-service-health"
[state]
schema_generation = "world-v2"
[[state.slots]]
id = "world"
relative_path = "world.cc"
kind = "cultcache-file"
schema = "ghostlight.world_state.foundation.v0"
writer = "process-bound-single-writer"
recovery = "preserve"
startup = "create-or-open-after-write-lease"
[[state.slots]]
id = "app-sessions"
relative_path = "service/app-sessions-v2.cc"
kind = "cultcache-file"
schema = "ghostlight.app_session_store.v2"
writer = "process-bound-single-writer"
recovery = "preserve"
startup = "create-or-open-after-write-lease"
[[state.slots]]
id = "controller-work"
relative_path = "service/controller-work.cc"
kind = "cultcache-file"
schema = "ghostlight.controller_work.v3"
writer = "process-bound-single-writer"
recovery = "preserve"
startup = "create-or-open-after-write-lease"
[[state.slots]]
id = "mesh-projection"
relative_path = "service/mesh-v2.cc"
kind = "cultcache-file"
schema = "gamecult.eve.surface.v1"
writer = "process-bound-single-writer"
recovery = "rebuildable"
startup = "create-or-open-after-write-lease"
[[provides]]
capability = "ghostlight.world-service"
schema = "ghostlight.world_state.foundation.v0"
compatibility = "foundation-v0"
[[provides]]
capability = "gamecult.eve.surface-provider"
schema = "gamecult.eve.surface.v1"
compatibility = "v1"
[[dependencies]]
kind = "shared-infrastructure"
capability = "odin.verse-rendezvous"
schema = "odin.verse-topology.v1"
compatibility = "v1"
startup = "before-promotion"
[[dependencies]]
kind = "private"
capability = "gamecult.codex.subscription-inference"
schema = "gamecult.codex.transport_envelope.v2"
compatibility = "v2"
startup = "before-promotion"
[[dependencies]]
kind = "required"
capability = "heimdall.command-boundary"
schema = "heimdall.command_boundary.v1"
compatibility = "v1"
startup = "before-promotion"