diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index ebab1909..bdae5871 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -116,6 +116,7 @@ remembers doctrine; the branch remembers the blade. - `bifrost-ledger` is the compact Bifrost/Imagination readback rite; use it after collaboration or publication writes to see the latest body-change, GitHub, feedback, and consensus receipts without opening the full local Verse. - `tool-directory` is the non-mutating daemon tool sight rite; it shows which globally available daemon-hosted tools any agent can invoke through typed intents and receipts, while still exposing host readiness. - `gjallar` is the non-mutating whole-Verse herald to run first when reorienting; `swarm-overview` remains its compatibility name. It locates agents, cluster/private-Verse topology, daemon liveness, Eve surfaces, and daemon tools in one compact report without opening private Verse state or full-context debug serialization. +- Idunn, not Codex/Self/Gjallar, owns daemon survival and service lifecycle physiology. `tools/epiphany_local_run.ps1 -Mode swarm-online-runbook` now generates an Idunn-owned service lifecycle runbook for the Epiphany hosted body: the artifact launches each sealed elevated child runbook with `Start-Process ... -PassThru`, records child exit codes, continues after child failure, runs aftercare audits, and exits nonzero if any child or aftercare step fails. It still requires explicit elevated operator authority before service mutation. - `swarm-triage` is the compact responsibility rite after sight: it no-ops when liveness is ready, carries blocked tool-host/service lifecycle attention plus an ordered action queue as sealed sight, and emits topology-aware typed daemon poke receipts only for current daemon liveness attention rows. - `epiphany-openai-runtime` worker result ingress now parses assistant output directly into typed role/reorient ingress structs selected from the durable launch document, stores nested `statePatch` and `selfPatch` as typed MessagePack in `EpiphanyRuntimeRoleWorkerResult`, and no longer passes worker result data through generic `serde_json::Value`. JSON survives there only as the OpenAI text-output edge before typed deserialization. - Agent self-memory review/application now has typed `AgentSelfPatch` core APIs. JSON-value selfPatch functions are compatibility wrappers for CLI/artifact ingress; native callers should parse once at the edge and then call `review_agent_self_patch_document` / `apply_agent_self_patch_document`. Role-result self-persistence no longer exports a JSON-value reviewer; the live API is `review_role_self_patch_document`. diff --git a/state/ledgers.msgpack b/state/ledgers.msgpack index 96ee5c5c..98f28093 100644 Binary files a/state/ledgers.msgpack and b/state/ledgers.msgpack differ diff --git a/state/map.yaml b/state/map.yaml index dcf203b2..7652a435 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -71,6 +71,7 @@ data_flow: active_subgoals: - Gjallar is Odin's herald for whole-Verse sight: Odin coordinates and discovers advertised Verse metadata, while Gjallar publishes compact operator-safe rows for topology, liveness, Eve surfaces, daemon tools, receipts, and action queues without opening private state. The first native Gjallar surface is a read-only alias over the compact swarm overview: `epiphany-verse-query gjallar` and `tools/epiphany_local_run.ps1 -Mode gjallar`. + - Idunn owns daemon survival and service lifecycle physiology. Codex/operator sessions may inspect, generate runbooks, and route explicit operator authority, but keeping daemons alive belongs to Idunn-owned service lifecycle receipts, scheduler policy, audits, and aftercare. Do not let Self, Gjallar, or ad hoc wrapper summaries become a second daemon-keeper. - Use `notes/epiphany-cultmesh-dreaming-roadmap.md` as the design authority for distributed Epiphany dreaming. Public dreams are separately authored typed documents distributed through CultMesh/CultNet; private state remains local and cannot be shared by flipping a visibility flag. Foreign dreams are external thought weather until a reviewed local adoption receipt digests them into memory, planning, doctrine, or governance. - CultMesh is now the preferred ergonomic Rust abstraction over CultCache and CultNet for Epiphany-owned local database surfaces. The Rust substrate is repo-contained under `vendor/cultcache-rs`, `vendor/cultnet-rs`, and `vendor/cultmesh-rs`; the old `E:\Projects\CultLib\crates\*` path is dead in this checkout and must not be reintroduced as a compile-time dependency. Future local Verse/dream/status work should start at CultMesh unless it is explicitly polishing CultMesh internals. `CultMeshNode::get_all_with_keys()` now exposes typed document enumeration through the mesh organ, and `CultMeshNode::soa()` exposes CultCache's typed SoA table projection without bypassing the mesh organ. Compact audits can scan local Verse receipt families, and agent-state summary documents now prove SoA readback through CultMesh columns. `epiphany-verse-query agent-state-report` and wrapper `-Mode agent-state-soa` refresh/mirror the persisted seven-row agent-state SoA into local Verse, then emit a compact TUI/JSON report from CultMesh SoA columns without full local Verse serialization. Compact SoA rows now include each standing faculty's role id, agent id, profile kind, portable contract, memory/goal/value counts, and `private=false`; wrapper proof `local-20260618-175913-074-b22ff01c` printed all seven faculties in one sealed line. Preserve the three-Verse boundary: `epiphany-internal` for private sub-agent typed state, `gamecult-local` for trusted LAN/Yggdrasil-tunnel GameCult project sharing, and `epiphany-global` for untrusted public dreams plus topic-specific threaded public rooms for Persona posts. - Use `notes/epiphany-verse-architecture.md` as the source note for local Verse/Odin/Yggdrasil prompt-context architecture. Odin is the all-seer discovery/coordinator surface for advertised Verse metadata, not a trust-boundary bypass. Yggdrasil is the hosting spine for important trusted GameCult Verses such as Bifrost. The first native local Verse query surface is `epiphany-verse-query`, which seeds/queries compact CultMesh policy/status/contract context for dynamic prompt assembly and operator inspection; `epiphany-prompt-context-smoke` proves that compact local Verse context plus a semantic memory graph context cut can render a bounded dynamic prompt packet, omit unrelated private-looking text, and preserve the packet inside a role worker launch document. Live bridge role/reorient launch paths now feed `dynamicPromptContext` from sibling `local-verse.ccmp` and `memory-graph.msgpack` stores beside runtime-spine, refreshing the memory graph from current typed thread-state repo graphs when absent; the bridge launch-context test proves that packet survives into a persisted runtime-spine worker launch request. `tools/epiphany_local_run.ps1 -Mode status` now uses `.epiphany-run/cultmesh/local-verse.ccmp` as the shared local operator Verse store for run intent, operator snapshot, run receipt, and final `local-verse-context.json`, so the read path sees the latest operator witnesses instead of a policy-only seed packet. Local runs also refresh persisted `epiphany.agent_state_soa.v0` from `state/agents.msgpack` and mirror it into local Verse as sealed `epiphany.cultmesh.agent_state_soa_summary.v0`, preserving seven-faculty row/column shape and contract/count metadata without exposing memory text. `epiphany-verse-query poke-daemon --daemon-id ` now records an operator-safe `epiphany.cultmesh.daemon_poke_intent.v0` plus `epiphany.cultmesh.daemon_poke_receipt.v0` in local Verse, so a down daemon has a typed lifecycle intervention path without private Verse rummaging; follow-up daemon status remains the liveness authority. `epiphany-verse-query connect-eve` now selects an Odin advertisement by id or target cluster through the narrow Eve surface directory, records Eve connection intent/receipt documents, and verifies latest receipts through narrow CultMesh loaders; `tools/epiphany_local_run.ps1 -Mode eve-connect` wraps the same receipt path, defaulting to the Persona public discussion surface without full local Verse serialization. `epiphany-verse-query bifrost-publication` now records the Bifrost body-change publication intent, Bifrost publication receipt, and GitHub publication receipt from explicit changed path, verification, review, authorship, credit, ledger, Hands PR, and publication URL inputs, verifies the latest chain through narrow CultMesh loaders, and is wrapped by `tools/epiphany_local_run.ps1 -Mode bifrost-publication` for non-mutating operator proof defaults. `epiphany-verse-query collaboration-feedback` now records public Persona/peer collaboration feedback plus an Imagination consensus-discovery receipt from explicit public refs, Eve receipt, topic, summary, and candidate action refs, verifies latest feedback/consensus through narrow CultMesh loaders, and is wrapped by `tools/epiphany_local_run.ps1 -Mode collaboration-feedback`, which first records the prerequisite Eve receipt; adoption still requires Mind/Bifrost gates. `-Mode mvp` now seeds the same local Verse, routes Persona front-door `bubble` speech audits into that store, and writes final `local-verse-context.json` so the Persona mouth-edge witness is visible beside operator run witnesses. `epiphany-operator-snapshot from-status` now also distills the latest native status `tools.invocations[]` row into local Verse daemon-tool invocation intent/receipt mirrors, so operator-safe runtime tool calls become discoverable as `epiphany.cultmesh.daemon_tool_invocation_*` while runtime-spine remains lifecycle owner and raw MCP JSON stays quarantined behind typed tool documents. Plan/run/MVP coordinator summaries can now mirror their runtime-spine `epiphany.coordinator_run_receipt.v0` into local Verse as `epiphany.cultmesh.coordinator_run_receipt.v0`, referencing sealed artifacts by path only while keeping runtime-spine as lifecycle owner. When that summary contains a `finalAction.handsActionGate`, the same distillation pass writes `epiphany.cultmesh.hands_action_gate.v0` into local Verse with the Hands intent/review ids, Substrate Gate grant id, requested paths, required receipt types, and record-pass command template; runtime-spine Hands/Substrate Gate receipts remain the only action owners. When coordinator steps contain `roleAccept` or `roleFailureReview`, the same pass writes the latest operator-safe `epiphany.cultmesh.role_review_event.v0` mirror with surface, role id, status, source coordinator receipt id, and any exposed acceptance receipt/result/job ids; thread-state acceptance receipts remain the review owner. diff --git a/tools/epiphany_local_run.ps1 b/tools/epiphany_local_run.ps1 index 55981b40..db9f59d0 100644 --- a/tools/epiphany_local_run.ps1 +++ b/tools/epiphany_local_run.ps1 @@ -886,27 +886,56 @@ if ($Mode -eq "swarm-online-runbook") { $quotedRoot = ConvertTo-PowerShellLiteral $Root $runbookLines = @( "# Epiphany swarm online runbook.", + "# Lifecycle owner: Idunn. This artifact routes operator authority to Idunn-owned service lifecycle receipts.", "# Generated from compact CultMesh swarm action rows.", "# Run only with explicit operator authority. The individual sealed runbooks write lifecycle receipts.", "# After execution, this runbook executes the advertised aftercare audit command(s).", "Set-StrictMode -Version Latest", '$ErrorActionPreference = "Stop"', "Set-Location -LiteralPath $quotedRoot", + '$failureCount = 0', "" ) foreach ($row in $authorityRows) { + $serviceLiteral = ConvertTo-PowerShellLiteral $row.serviceId + $routeLiteral = ConvertTo-PowerShellLiteral $row.serviceRoute + $artifactLiteral = ConvertTo-PowerShellLiteral $row.operatorArtifactRef + $shaLiteral = ConvertTo-PowerShellLiteral $row.operatorArtifactSha256 + $aftercareLiteral = ConvertTo-PowerShellLiteral $row.operatorAftercareCommand $runbookLines += "# Service: $($row.serviceId)" $runbookLines += "# Route: $($row.serviceRoute)" $runbookLines += "# Artifact: $($row.operatorArtifactRef)" $runbookLines += "# SHA-256: $($row.operatorArtifactSha256)" $runbookLines += "# Aftercare: $($row.operatorAftercareCommand)" - $runbookLines += $row.operatorArtifactExecutionCommand + $runbookLines += "Write-Host `"Running Idunn service lifecycle runbook for Epiphany: service=$serviceLiteral route=$routeLiteral artifact=$artifactLiteral sha256=$shaLiteral aftercare=$aftercareLiteral`"" + $runbookLines += "try {" + $runbookLines += " `$process = Start-Process PowerShell -Verb RunAs -Wait -PassThru -ArgumentList @('-NoProfile','-ExecutionPolicy','Bypass','-File',$artifactLiteral)" + $runbookLines += " `$exitCode = `$process.ExitCode" + $runbookLines += " if (`$null -eq `$exitCode) { `$exitCode = -1 }" + $runbookLines += " Write-Host `"Idunn service lifecycle runbook exit: service=$serviceLiteral route=$routeLiteral exitCode=`$exitCode`"" + $runbookLines += " if (`$exitCode -ne 0) { `$failureCount += 1 }" + $runbookLines += "} catch {" + $runbookLines += " `$failureCount += 1" + $runbookLines += " Write-Host `"Idunn service lifecycle runbook launch failed: service=$serviceLiteral route=$routeLiteral error=`$(`$_.Exception.Message)`"" + $runbookLines += "}" $runbookLines += "" } $runbookLines += "# Aftercare audit command(s):" foreach ($aftercare in $aftercareCommands) { - $runbookLines += $aftercare + $aftercareLiteral = ConvertTo-PowerShellLiteral $aftercare + $runbookLines += "Write-Host `"Running Idunn aftercare audit for Epiphany service lifecycle: command=$aftercareLiteral`"" + $runbookLines += "try {" + $runbookLines += " Invoke-Expression $aftercareLiteral" + $runbookLines += "} catch {" + $runbookLines += " `$failureCount += 1" + $runbookLines += " Write-Host `"Idunn aftercare audit failed: command=$aftercareLiteral error=`$(`$_.Exception.Message)`"" + $runbookLines += "}" } + $runbookLines += 'if ($failureCount -gt 0) {' + $runbookLines += ' Write-Host "Idunn service lifecycle runbook for Epiphany failed: failures=$failureCount"' + $runbookLines += ' exit 1' + $runbookLines += '}' + $runbookLines += 'Write-Host "Idunn service lifecycle runbook for Epiphany completed: failures=0"' Set-Content -LiteralPath $runbookPath -Value ($runbookLines -join [Environment]::NewLine) -Encoding UTF8 $runbookSha256 = Get-LocalArtifactSha256 $runbookPath [pscustomobject]@{ @@ -916,8 +945,13 @@ if ($Mode -eq "swarm-online-runbook") { runbookPath = $runbookPath artifactSha256 = $runbookSha256 commandCount = $authorityRows.Count + lifecycleOwner = "Idunn" + hostedBody = "Epiphany" commands = @($authorityRows | ForEach-Object { $_.operatorArtifactExecutionCommand }) aftercareCommands = $aftercareCommands + detectsChildExitCodes = $true + continuesAfterChildFailure = $true + exitsNonzeroAfterChildOrAftercareFailure = $true sourceOverviewPath = $overviewPath privateStateExposed = $false } | ConvertTo-Json -Depth 6 | Set-Content -LiteralPath $resultPath -Encoding UTF8 @@ -2030,7 +2064,7 @@ if ($resultPath -ne "" -and (Test-Path -LiteralPath $resultPath)) { if ($null -ne $result.aftercareCommands -and $result.aftercareCommands.Count -gt 0) { $aftercare = ($result.aftercareCommands -join "; ") } - Write-Host "Swarm online runbook: status=$($result.status), commands=$($result.commandCount), artifactSha256=$($result.artifactSha256), aftercare=$aftercare, path=$($result.runbookPath), privateStateExposed=$($result.privateStateExposed)" + Write-Host "Swarm online runbook: status=$($result.status), owner=$($result.lifecycleOwner), hostedBody=$($result.hostedBody), commands=$($result.commandCount), artifactSha256=$($result.artifactSha256), aftercare=$aftercare, path=$($result.runbookPath), privateStateExposed=$($result.privateStateExposed)" } elseif ($Mode -eq "service-policy-directory") { $policyRows = "none" if ($null -ne $result.tuiRows -and $result.tuiRows.Count -gt 0) {