From b3191f4f2cd1bea5e45c4c988a8b82321b8d79a2 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 16 Aug 2026 19:33:07 +0200 Subject: [PATCH] Add standalone recovery MCP runtime --- apps/worker/src/mcp-http-main.ts | 15 +++++++++++++++ notes/fresh-workspace-handoff.md | 6 ++++-- notes/voidbot-current-system-map.md | 12 ++++++++++++ package.json | 1 + state/evidence.jsonl | 1 + state/map.yaml | 17 +++++++++-------- 6 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 apps/worker/src/mcp-http-main.ts diff --git a/apps/worker/src/mcp-http-main.ts b/apps/worker/src/mcp-http-main.ts new file mode 100644 index 0000000..d7bb5c6 --- /dev/null +++ b/apps/worker/src/mcp-http-main.ts @@ -0,0 +1,15 @@ +import "dotenv/config"; + +import { createVoidbotMcpContext } from "./mcp-server-context"; +import { startVoidbotMcpHttpServer } from "./mcp-http-server"; + +async function main(): Promise { + await startVoidbotMcpHttpServer({ + ...createVoidbotMcpContext(), + }); +} + +void main().catch((error) => { + console.error("Resident MCP HTTP server failed:", error); + process.exit(1); +}); diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index 6d75ea9..79ea492 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -16,8 +16,10 @@ Git history and smoke artifacts carry routine proof. `state/evidence.jsonl` shou ## Current Shape -- VoidBot's deployed runtime lives on Yggdrasil. Idunn owns deployment from upstream `main` and proves the served commit through `/srv/voidbot/deploy/deployment.env`. This workspace is for development and diagnostics; it is not a deployment target. Do not look for, create, or revive a local VoidBot deployment. To deploy a completed change, push the intended commit to upstream `main`, then verify Idunn converged `DEPLOYED_REVISION` and the Yggdrasil service set. -- Discord bot and worker are live. +- Disaster recovery is active on trusted old Yggdrasil (`94.130.75.184`). Big Yggdrasil (`94.130.223.131`) is retired and its recycled address is not a GameCult host. The old host retained Bifrost and PostgreSQL but lost VoidBot, Idunn, Odin, Epiphany, compose state, and service credentials. +- Raven's verified offsite archive `20260603-043304-offsite-auto.zip` is staged on old Yggdrasil. Its SHA-256 is `47572df766e63212012eb75762359113a11c8bbf149b497e120fc4fda7191dfc`; the newer June 4 archive is corrupt. The payload contains PostgreSQL state, six Qdrant snapshots, and exact RAG archives, but no secrets. +- Recover the standalone read-only resident MCP first. It owns only loopback `127.0.0.1:17875`, exact archives, VoidBot's history/source Qdrant collections, and the matching embedding model. Discord, worker jobs, Personas, moderation, Bifrost crossings, and delivery remain stopped until their missing authority and credentials are rebuilt. +- `apps/worker/src/mcp-http-main.ts` is the standalone HTTP entrypoint. It delegates to the existing MCP context and HTTP server; it is not a second retrieval implementation. - The unattended repo Face/native Persona CTB swarm runs on Yggdrasil. Resident `apps/persona-scheduler` inside `voidbot.service` owns the serialized Persona pulse and queues turns through Postgres for the worker. Void moderation, rumination, physiology, memory maintenance, and candidate delivery are now separate resident daemon organs; Persona initiative owns none of them. The Windows Local Orchestrator owns no Void decision loop. - The teardown authority remains `notes/agent-swarm-teardown-plan-2026-05-21.md`, but it is now a restart checklist and smell ledger rather than a stop sign. Keep using it when a Face/Bifrost/CTB boundary smells like prompt/parser/transport Jenga. - The repo-controlled pause flag is `state/agent-swarm-paused.json`. While it has `"paused": true` or is malformed, the resident Persona scheduler returns before registry, Discord, embedding, storage, or dispatch work. This is the brake. Do not route around it. diff --git a/notes/voidbot-current-system-map.md b/notes/voidbot-current-system-map.md index ceca631..0515504 100644 --- a/notes/voidbot-current-system-map.md +++ b/notes/voidbot-current-system-map.md @@ -340,3 +340,15 @@ Result-leg authority map: - Verification layer: hostile schema/binding tests plus a real temporary CultCache/CultMesh request-delivery-checkpoint replay smoke. Configured remote Persona feedback is an observation fork beside the existing mention scheduler. `discord-bot.ts` commits the local Persona mention obligation first and independently calls `exportPersonaFeedbackObservation` only when `remotePersonaFeedbackTarget` is present on the addressed Face. The exported immutable event carries exact Discord provenance, addressing mode, target binding, content hash, and stable `voidbot` producer identity. It writes only to `BIFROST_PERSONA_FEEDBACK_OBSERVATION_STORE_PATH`, never the outbound Discord command provider store or Bifrost-private binding/receipt state. It carries `feedback_only`; Bifrost—not VoidBot—classifies actor links, admits targets, and produces downstream cognition pressure. +# Disaster recovery boundary (2026-08-16) + +Trusted old Yggdrasil at `94.130.75.184` is the recovery host. Retired Big +Yggdrasil at `94.130.223.131` is no longer a GameCult machine. The verified +June 3 Raven backup restores exact archives and VoidBot-owned vector state, but +not secrets or the lost Idunn/Odin/Epiphany deployment substrate. + +The first restored organ is a loopback-only, read-only resident MCP. The +standalone `apps/worker/src/mcp-http-main.ts` entrypoint reuses the canonical +MCP context, factory, archive repositories, vector stores, and HTTP transport. +Its deployment allow-list contains retrieval tools only. It owns no Discord, +job, Persona, moderation, Bifrost, Idunn, or state-mutation authority. diff --git a/package.json b/package.json index 85d4972..8b71323 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "typecheck": "tsc -b --pretty false", "dev:bot": "tsx apps/bot/src/index.ts", "dev:mcp": "tsx apps/worker/src/mcp-server.ts", + "dev:mcp:http": "tsx apps/worker/src/mcp-http-main.ts", "dev:worker": "tsx apps/worker/src/index.ts", "stack:start": "powershell -ExecutionPolicy Bypass -File scripts/start-voidbot-stack.ps1", "state:status": "node tools/voidbot_state.ts status", diff --git a/state/evidence.jsonl b/state/evidence.jsonl index 53bc961..4596ad2 100644 --- a/state/evidence.jsonl +++ b/state/evidence.jsonl @@ -459,3 +459,4 @@ {"ts":"2026-07-19T14:58:00Z","type":"repair","status":"ok","note":"A raw SSH docker-exec MCP stream made every open agent task inherit the lifetime of Yggdrasil's replaceable worker container; an Idunn promotion therefore left tasks at Transport closed even after the new worker was healthy. Codex now attaches to a stable local stdio relay which opens one fresh remote MCP session per request. A real relay smoke advertised 20 tools, listed 52 indexed repositories, and returned a VoidBot source hit; direct history and source retrieval against Ygg also passed."} {"ts":"2026-07-19T14:25:00Z","type":"architecture","status":"ok","note":"The per-call SSH MCP relay was identified as a transport compensator and deleted. The resident Yggdrasil worker now owns a loopback streamable-HTTP MCP organ injected with its existing archive repositories, source ingester, and retrieval service. The canonical workstation tunnel owns the sole Starfire crossing at 127.0.0.1:17875; Codex uses the URL and tool calls start no processes or alternate retrieval authorities."} {"ts":"2026-07-19T20:10:00Z","type":"repair","status":"ok","note":"Direct Codex streamable-HTTP registration still closed permanently after a brief Idunn worker deployment or SSH-tunnel gap; stateless server sessions did not imply client transport recovery. Codex now attaches to a task-local stdio continuity bridge with no retrieval authority. Each tool call uses a lightweight HTTP client to the resident daemon, and the bridge lowers endpoint failure to a tool error. A single outer MCP client succeeded before a forced endpoint outage, received isError during the outage, and succeeded again after the same endpoint returned."} +{"ts":"2026-08-16T17:30:00Z","type":"recovery","status":"ok","note":"Big Yggdrasil was retired after an incomplete evacuation and its recycled 94.130.223.131 address is not trusted. Old Yggdrasil retained no VoidBot state, but Raven held a verified June 3 offsite archive (SHA-256 47572df766e63212012eb75762359113a11c8bbf149b497e120fc4fda7191dfc); the June 4 archive is corrupt. Recovery is intentionally bounded to a loopback read-only MCP over exact archives and VoidBot-owned vectors while lost Discord, Idunn, Odin, Epiphany, Persona, moderation, and delivery authority remains stopped."} diff --git a/state/map.yaml b/state/map.yaml index 7cd9565..79879b4 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -14,16 +14,16 @@ objective: Aetheria lore, while keeping the system understandable enough to modify safely. current: > - Keep the Persona swarm paused while the daemon organ migration continues. - The one-minute resident pulse is observation latency and must not authorize - inference by itself. Portable physiology now owns sleep and speaking - pressure, and portable memory maintenance consumes its typed nap intent with - one pre-receipted model attempt per nap and no automatic retry. Verify that - organ through Idunn's upstream deployment path, then split the legacy - moderation PowerShell body into shared evidence sources plus separate - daemon-owned moderation-heartbeat and person-shaped rumination coordinators. + Recover the read-only archive/source retrieval organ on surviving old + Yggdrasil from the verified 2026-06-03 offsite backup. Big Yggdrasil is + retired and its address is no longer trusted; its VoidBot, Idunn, Odin, + Epiphany, deployment, and secret state did not survive. Restore only the + resident loopback MCP, exact archives, and VoidBot-owned Qdrant collections + first. Keep Discord, worker jobs, Personas, moderation, and delivery stopped + until their missing authority and credentials are deliberately rebuilt. constraints: + - Disaster recovery currently targets trusted old Yggdrasil at 94.130.75.184; retired Big Yggdrasil at 94.130.223.131 is not a GameCult host and must not be trusted or targeted. - VoidBot's deployed runtime lives on Yggdrasil and deployment is owned by Idunn from upstream pushes; local workspaces are not deployment targets. - Public traffic still rides one remote Qwen box plus local embedding and ops infrastructure. - Owner flow and public flow share infrastructure but have different provider and safety boundaries. @@ -32,6 +32,7 @@ constraints: - Persistent project state must stay small enough to rehydrate from without becoming a second swamp. invariants: + - The recovery MCP organ is read-only and loopback-only. It may consume exact archives, VoidBot-owned vector collections, and the configured embedding provider; it cannot start Discord, worker-job, Persona, moderation, Bifrost, Idunn, or canon mutation paths. - The `/epiphany` Discord edge is an exact-owner request producer only. Its closed status/sleep/wake/direct command family writes short-lived immutable documents to a dedicated Bifrost inbox; ordinary conversation remains feedback-only, and VoidBot gains no Epiphany state, Mind, Hands, release, deployment, argv, or local-execution authority. - The `/epiphany` result edge consumes only Bifrost's frozen immutable terminal delivery schema, validates it against VoidBot's exact request and private Discord interaction checkpoint, and may only edit the original ephemeral response. It cannot inspect Epiphany state, synthesize execution truth, expose signatures/private state, mutate the Bifrost outbox, or retry consequences. - Deployment follows one path: push the intended upstream commit, then let Idunn deploy VoidBot on Yggdrasil. Do not create, restore, or search for a local VoidBot deployment path.