Add standalone recovery MCP runtime

This commit is contained in:
Meta Vens 2026-08-16 19:33:07 +02:00
commit b3191f4f2c
6 changed files with 42 additions and 10 deletions

View file

@ -0,0 +1,15 @@
import "dotenv/config";
import { createVoidbotMcpContext } from "./mcp-server-context";
import { startVoidbotMcpHttpServer } from "./mcp-http-server";
async function main(): Promise<void> {
await startVoidbotMcpHttpServer({
...createVoidbotMcpContext(),
});
}
void main().catch((error) => {
console.error("Resident MCP HTTP server failed:", error);
process.exit(1);
});

View file

@ -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.

View file

@ -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.

View file

@ -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",

View file

@ -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."}

View file

@ -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.