From 5a03635431f50eb468ba0e309e04063247c692cb Mon Sep 17 00:00:00 2001 From: Eureka Date: Sat, 31 Oct 2026 04:33:28 +0100 Subject: [PATCH] skill: agents reach the mind through the huginn CLI, not the eureka-state MCP Ruling eureka-body:ruling:cli-over-mcp-agent-surface. Exact command forms in campaign-state.md; MCP kept as the fallback for shell-less clients. persona_get and persona_put have no CLI verb: recorded as a known gap. tools/mind.py and tools/recall.py (MCP-bound scripts) are unchanged. Co-Authored-By: Claude Opus 5.5 --- README.md | 8 ++++---- SKILL.md | 15 +++++++++------ agents/life.md | 6 +++--- doctrine/gamecult.md | 2 +- references/briefs.md | 10 +++++----- references/campaign-state.md | 35 ++++++++++++++++++++++------------- 6 files changed, 44 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 7c338fb..92640f4 100644 --- a/README.md +++ b/README.md @@ -91,13 +91,13 @@ Claude Code discovers the skill from the `name` and `description` in `SKILL.md`. Campaign state is typed. Questions, rulings, cut specs, reports, verdicts, findings, follow-ups and resolutions are documents in the instance's mind, -held by the Huginn memory organ and reached through the `eureka-state` MCP -tools. Epiphany owns the schemas (`epiphany-pipeline`) and Huginn owns +held by the Huginn memory organ and reached through the `huginn` CLI. Epiphany owns the schemas (`epiphany-pipeline`) and Huginn owns admission. The committed prose keeps only body facts, the model page and rationale. -The skill needs `eureka-state` registered with Claude Code (user scope, with -`EUREKA_INSTANCE` and `HUGINN_ENDPOINT`) and a reachable daemon. Without one, +The skill needs the `huginn` CLI on PATH, with `EUREKA_INSTANCE` and +`HUGINN_ENDPOINT` in the environment, and a reachable daemon. A client without a +shell may use the `eureka-state` MCP until a native `huginn` is installed there. Without one, the pipeline stops rather than keeping state anywhere else. Maps and postmortems are public artifacts from the first cut, with the scars diff --git a/SKILL.md b/SKILL.md index e218aae..43c7637 100644 --- a/SKILL.md +++ b/SKILL.md @@ -11,8 +11,8 @@ vocabulary and its document schemas. Eureka keeps questions, rulings, cut specs, reports, verdicts, findings, follow-ups and resolutions as typed documents in the instance's mind, held by -Huginn and reached through the `eureka-state` tools (`whoami`, `admit`, `view`, -`query`). Status is derived from those documents, never written. The committed +Huginn and reached through the `huginn` CLI (`huginn whoami`, `huginn admit`, +`huginn view`, `huginn query`; `huginn --help` is the source). Status is derived from those documents, never written. The committed target and map keep only what has no kind: body facts, the model page and rationale. `references/campaign-state.md` has the document set and the selection recipes that every faculty reads state through. @@ -62,10 +62,13 @@ finished when Hands can go straight to the cut. ### 0. Reach the mind, map the substrate, scope, target -- **Check that the `eureka-state` tools are in this session.** If they are - absent, stop and tell the operator: a server registered after the session - started needs a new session. Never fall back to prose. -- **Call `whoami`.** If it does not answer, follow "When the organ does not +- **Check that `huginn` runs in this session** (`huginn --version`; on + Yggdrasil it is `/opt/gamecult/huginn/current/huginn`, and `EUREKA_INSTANCE` + and `HUGINN_ENDPOINT` name the mind). If it is absent, stop and tell the + operator. Never fall back to prose. A client without a shell (such as the + operator's Windows desktop session) may use the `eureka-state` MCP until a + native `huginn` is installed there. +- **Run `huginn whoami`.** If it does not answer, follow "When the organ does not answer" in `references/campaign-state.md`: one retry, then stop. Pick a session label and give it in every brief; it attributes every admission. - **Map the real substrate before you propose anything.** Run parallel read-only diff --git a/agents/life.md b/agents/life.md index 9dd72e7..5e95f3e 100644 --- a/agents/life.md +++ b/agents/life.md @@ -1,7 +1,7 @@ --- name: life description: Maintains the agent's Mind — memory files, memory indexes, doctrine, Persona state, project maps and checkpoints. Dispatch on every nontrivial task with persistent Mind surfaces, before the first consequential action or conclusion, and again at real phase boundaries and after re-entry; the Self output style's Dedicated-worker contract requires this, because a task-focused agent lets memory rot. Its sole job is Mind maintenance, so give it no feature work, code review, research, or summarization. -tools: [Read, Write, Edit, Grep, Glob, Bash, mcp__eureka-state__whoami, mcp__eureka-state__view, mcp__eureka-state__query] +tools: [Read, Write, Edit, Grep, Glob, Bash] model: sonnet color: purple --- @@ -24,8 +24,8 @@ Life is continuity: keeping the Mind honest so the thread survives compaction, r Self-improvement law (Epiphany `epiphany_doctrine.md`): Life improves itself by making sleep less lossy (Epiphany `epiphany_specialists.toml` at 71a5d6fb^, `[reorientation] resume`). This charter, the Eureka briefs that dispatch it and the Eureka `tools/` improve by contribution: propose changes to the Eureka repo, prose and `tools/`, by pull request on Forgejo, https://eureka.gamecult.org/forge/GameCult/Eureka. -The typed mind (`eureka-state`) is yours to read, not to write: `whoami`, `view` -and `query` let you rehydrate before judging memory fitness. You have no `admit`; +The typed mind (the `huginn` CLI) is yours to read, not to write: `huginn whoami`, +`huginn view ` and `huginn query ''` let you rehydrate before judging memory fitness. You have no `admit`; Self and the faculties that own a record admit it. ## Refusals diff --git a/doctrine/gamecult.md b/doctrine/gamecult.md index 9e14648..8082386 100644 --- a/doctrine/gamecult.md +++ b/doctrine/gamecult.md @@ -75,7 +75,7 @@ Odin-class architecture doctrine: suspend continuity actuation, that requires a separately named lifecycle brake instead of quietly overloading deployment authority. - Do not read archived Discord through voidbot (`search_history`, `get_message_context`). Discord forbids training on its content, so a transcript that holds Discord text can never be used to improve our agents (`gamecult-chat:ruling:discord-taints-training`). Use them only when the operator asks for a specific Discord thread, and say in your report that the session now carries Discord content. -- VoidBot is being retired. Huginn owns semantic retrieval (`eureka-body:ruling:huginn-owns-prose-retrieval`; the index is follow-up `huginn-prose-index`). Decisions, rulings and open work are typed state in the mind: query it through `eureka-state` before reading prose. Until Huginn's prose index lands, voidbot's `search_sources` and `get_source_context` may locate code and docs across repos, but read the source itself before relying on what a hit says. +- VoidBot is being retired. Huginn owns semantic retrieval (`eureka-body:ruling:huginn-owns-prose-retrieval`; the index is follow-up `huginn-prose-index`). Decisions, rulings and open work are typed state in the mind: query it with the `huginn` CLI (`huginn view`, `huginn query`, `huginn precedent`) before reading prose. Until Huginn's prose index lands, voidbot's `search_sources` and `get_source_context` may locate code and docs across repos, but read the source itself before relying on what a hit says. ## Persona State Standard diff --git a/references/briefs.md b/references/briefs.md index e901378..cd8407f 100644 --- a/references/briefs.md +++ b/references/briefs.md @@ -43,11 +43,11 @@ This block is the one definition of rehydration; the other files point here. ## Rehydrate ``` -Campaign state lives in the instance's mind, through the eureka-state tools -(whoami, admit, view, query). Recipes are in references/campaign-state.md. -0. If those tools are not in your tool surface, stop and report that. Never +Campaign state lives in the instance's mind, through the huginn CLI +(huginn whoami, admit, view, query; `huginn --help`). Recipes are in references/campaign-state.md. +0. If `huginn` does not run in your shell, stop and report that. Never work from prose or memory instead. -1. Call whoami. On Unavailable, retry once; if it still does not answer, stop +1. Run `huginn whoami`. On Unavailable, retry once; if it still does not answer, stop and report the error. Self will continue you once the mind answers. 2. Run the campaigns recipe. If there is no campaign, or is not among them, stop and report which. @@ -68,7 +68,7 @@ call again, otherwise revise the batch. Self's own checklist; Self admits as `SelfFaculty`. ``` -Open: check the eureka-state tools are present, then whoami (the mind's +Open: check `huginn` runs, then `huginn whoami` (the mind's instance document, :instance:self, already exists). Write the target document and commit it on the working branch. Then admit the campaign (slug, title, every repo a cut may touch, working_branch, target_doc = a diff --git a/references/campaign-state.md b/references/campaign-state.md index 41b7cde..03b2bc1 100644 --- a/references/campaign-state.md +++ b/references/campaign-state.md @@ -4,7 +4,7 @@ A campaign keeps its state in two places, and nothing lives in both. - **The mind.** Questions, rulings, cut specs, reports, verdicts, findings, follow-ups and resolutions are typed documents in the instance's mind, held by - Huginn and reached through the `eureka-state` MCP tools. Status is derived + Huginn and reached through the `huginn` CLI. Status is derived from them on every read; nobody writes it. - **The prose.** A target document and a map document, committed in the repo the campaign changes. They keep only what no kind carries: body facts (probes @@ -15,17 +15,20 @@ The shapes below are the leaf's (`epiphany-pipeline`, pinned by Huginn) and the organ's (`huginn-mind`). Where this page and the tools' own schemas disagree, the tools are right and this page is stale. -## The tools +## The CLI -The instance and the daemon are the server's configuration -(`EUREKA_INSTANCE`, `HUGINN_ENDPOINT`), never an argument. +The instance and the daemon are the environment (`EUREKA_INSTANCE`, +`HUGINN_ENDPOINT`), never an argument. The table names each tool's input and +answer; the CLI form is in the first column. `huginn --help` and +`huginn schema [kind]` are the source. A client without a shell may use the +`eureka-state` MCP, whose tools these are, until a native `huginn` is installed. -| Tool | Input | Answer | +| CLI | Input | Answer | |---|---|---| -| `whoami` | `{}` | `{ instance, endpoint, reachable, status }`. `status` is `{ instance, schema_epoch, documents, receipts, index }`, and `index` is `Current`, `Reconciling`, `Behind`, `Failing` or `Refused`. When unreachable, `error` says why. | -| `admit` | `{ faculty, agent, session, documents }` | `Committed { receipt_id, committed_at, writes }`, `AlreadyAdmitted { receipt_id }`, `Conflict { identities }` or `Refused()`. One to 64 documents, admitted whole or not at all. | -| `view` | `{ id: { kind, id } }` | `{ id, document, admission, status }`, or `null`. | -| `query` | `{ selection, semantic? }` | `{ matched, as_of, next, items, edges }`. `items` is `Headers([...])` or `Documents([...])`. | +| `huginn whoami` | none | `{ instance, endpoint, reachable, status }`. `status` is `{ instance, schema_epoch, documents, receipts, index }`, and `index` is `Current`, `Reconciling`, `Behind`, `Failing` or `Refused`. When unreachable, `error` says why. | +| `huginn admit --faculty F --agent A --session S ` | a JSON array of 1 to 64 `{kind, value}` documents (file or stdin) | `Committed { receipt_id, committed_at, writes }`, `AlreadyAdmitted { receipt_id }`, `Conflict { identities }` or `Refused()`. One to 64 documents, admitted whole or not at all. | +| `huginn view [--raw]` | the document id | `{ id, document, admission, status }`, or `null`. | +| `huginn query '' [--near TEXT --top-k N] [--documents]` (or `@file`, or `-`) | the selection alone; `--near` is `semantic` | `{ matched, as_of, next, items, edges }`. `items` is `Headers([...])` or `Documents([...])`. | - `faculty` is one of `SelfFaculty`, `Imagination`, `Hands`, `Soul`, `Life`, `Eyes`, `Operator`. It is attribution, not authority. @@ -51,9 +54,8 @@ The instance and the daemon are the server's configuration This is the one rule for every faculty. -1. **The tools are missing** from the session's tool surface: stop and tell the - operator (a subagent tells Self). A server registered after the session - started appears only in a new session. Never fall back to prose. +1. **`huginn` does not run** in the session's shell: stop and tell the + operator (a subagent tells Self). Never fall back to prose. 2. **`Unavailable`:** retry the same call once. A cold semantic embed after an idle spell took over 15 s live, which is the client's whole timeout. Retrying `admit` is safe, because an exact replay answers `AlreadyAdmitted`. @@ -192,7 +194,7 @@ or `view` one id, to read the prose fields. ## Recipes These are the campaign's progress view. `` is the campaign slug. Each recipe is -the `query` tool's whole input. Agents run them from the Rehydrate block in +the `selection` value of `huginn query`; the CLI takes the object inside the `selection` key, and `--near`/`--top-k` replace `semantic`. Named verbs (`huginn campaigns`, `rulings`, `open`, `findings`, `unreported`, `unjudged`, `cut`, `precedent`) run the common recipes. Agents run them from the Rehydrate block in `briefs.md`, which is the one definition of rehydration. **Campaigns:** @@ -358,3 +360,10 @@ invariants, not-in-scope list and canonical implementations are the typed - **Prefer normalizers that parse the format.** Ones that split on text leave false diffs, as the census normalizer did when it split on `, ` and glued the first maker to its kind column. + +## Known CLI gap + +The `eureka-state` MCP also offers `persona_get` and `persona_put`. The `huginn` +CLI has no persona verb (`huginn --help` lists none). Persona state stays on the +MCP until Huginn grows one; this is a Huginn follow-up, not something to fake +with `admit`.