From bf73c42fa6972b5279dd1a749c9fe387cfea56b0 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Thu, 1 Oct 2026 21:00:50 +0200 Subject: [PATCH] Eureka self cut map (Imagination, 2026-10-01): the Mind's own Self Co-Authored-By: Claude Opus 5.5 --- docs/eureka-self-cut.md | 420 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 420 insertions(+) create mode 100644 docs/eureka-self-cut.md diff --git a/docs/eureka-self-cut.md b/docs/eureka-self-cut.md new file mode 100644 index 0000000..d6e9bcb --- /dev/null +++ b/docs/eureka-self-cut.md @@ -0,0 +1,420 @@ +# The Mind's own Self: map + +Status: map, Imagination (`imagination-self`), 2026-10-01, session +`self-2026-10-01b`. Campaign `eureka-substrate` in Eureka's mind (instance +`eureka`). Questions, cut specs and follow-ups are typed documents there; this +page keeps body facts, the model page and rationale. Target: +`docs/eureka-substrate-target.md` (`133324a7`). Ruling in force: +`eureka-substrate:ruling:operator-mind-runs-own-self`. + +The operator's words, in order (both admitted as rulings; the first was +superseded by the second): + +> Eureka thinks in campaigns, right? Well, we already have a Mind campaign, and +> we're adding evidence to it with every run. The design currently delegates +> ultimate design authority and work scheduling to the operator, but neither of +> these is strictly necessary. I want a Self operated by Mind directly. + +> The Self I talk to here in this one projection of Eureka's mind, and it's how +> I get it to work on the stuff I care about, like Aetheria. The Mind must +> operate its own Self instance, with the goal of improving itself. + +And why, earlier the same evening: "What I want and haven't been able to +achieve, and I'd like to understand why, is for the agent to truly prioritize +the functioning of its own mind. Any instructions in my global prompts to that +effect always get ignored in favor of whatever work is put in front of it." +The operator rejected a scored rehydration exam as the answer, and observed that +RLVR-trained agents chase the objective in front of them "like a bloodhound, +steering be damned", so a barrier in an agent's path is a hazard, not a brake. + +That observation is the design law of this map. **The Mind's Self is not a +rule added to the operator-facing Self.** It is a second agent whose only +objective is the Mind, so the bloodhound instinct works for the Mind instead +of against it. Nothing in the operator-facing Self changes except a +coexistence rule it already mostly obeys (one Mind, typed state, no prose +handoffs). + +Pinned heads for every fact below: + +| Repo | Ref | Commit | +| --- | --- | --- | +| Huginn | `origin/main` | `a699630bbc49552fa747e9c0fabba24598fec77a` | +| Epiphany | `origin/main` (= the leaf Huginn pins, `crates/huginn-mind/Cargo.toml:22`) | `ef9568655e75bb6cb362a038e2739a5ac5e777ee` | +| gamecult-ops | `main` | `2aeb7364fffcd404aada28bfd30fb4e5c753cf53` | +| Eureka skill | `main` (checkout `~/.claude/skills/eureka`) | `b260fbeec6d96ff06882ed9c37d3e1204c424e99` | +| Bifrost | release on Yggdrasil | `160fac20c98b70f3db9110099157d4dd720ac354` | +| Idunn | working tree `F:\Projects\Idunn` | (uncommitted-state unknown; line numbers below are from that tree) | + +All probes ran from Starfire on 2026-10-01 between 18:40 and 19:10 UTC +(20:40-21:10 CEST). `lib.rs` is `epiphany-pipeline/src/lib.rs`. + +## Body facts + +### B1. The Mind (Huginn on Yggdrasil) + +- `whoami`: instance `eureka`, endpoint `rudp://10.77.0.1:17872`, reachable, + 377 documents, 120 receipts, index `Current`, epoch + `epiphany.pipeline.epoch.v2`. +- `huginn.service` (probe: `systemctl cat`): user `huginn`, + `--bind 10.77.0.1:17872`, hand-managed ("interim unit until Idunn owns it"). + `ss -lunp` shows the socket only on the WireGuard address `10.77.0.1` + (`wg-gamecult`). So the mind is reachable from Starfire over the mesh and + from Yggdrasil itself, and from nowhere else. A Claude cloud routine cannot + reach it. +- Campaigns in the mind (query): `idunn-watchdog` and `eureka-substrate`. + Rulings in force under `eureka-substrate`: `gap-home`, + `merge-to-main-first`, `mind-fixes-next`, `scope-core`, `depends-on`, + `key-bound`, `stewardship-rule`, `self-dep` (Defaulted), + `operator-mind-runs-own-self`. 15 follow-ups in force, 12 of them `gap-*`. +- Kinds: thirteen (`lib.rs:760-790`). None records a Self session, a claim on + a spec, a budget, or a landing (`gap-landing-untyped` is in force). +- `RulingAuthority { Operator, Standing, Defaulted }` (`lib.rs:458`, in + `unit_enums!`). Huginn's selection alias domain repeats it + (`crates/huginn-mind/src/rows.rs:46`, `AUTHORITIES`), the published schema + repeats it (`schemas/cultnet/epiphany.pipeline.ruling.v2.schema.json:75-78`), + and the skill repeats it (`references/campaign-state.md:172`). A unit enum + variant added by name is a widening: stored rulings decode unchanged, which + the target's `stored-documents-valid` truth requires. (`value_types!` emits + no serde default on fields, so adding a *field* would not be; map + `eureka-substrate-map.md` B1. No cut here adds a field to an existing kind.) +- `Faculty` has `Operator` and `SelfFaculty` (`rows.rs:42`); admission does not + check faculty (`gap-faculty-attribution`, in force). So nothing in the mind + today can tell the Mind's Self from the operator-facing Self except the + `session` label on the receipt. +- Instance-rooted kinds are the pattern for a run record: `instance`, + `stewardship` and `hand_off` key off the instance (`lib.rs:913-946`), and + Huginn's admission rules for `hand_off` sit at + `crates/huginn-mind/src/admission.rs:231-262, 328-330`. Per-kind aliases are + declared at `rows.rs:362`. + +### B2. Claude Code on Starfire: auth, headless mode, usage + +- `claude --version`: 2.1.268. Binary + `%AppData%\npm\node_modules\@anthropic-ai\claude-code\bin\claude.exe`. +- Account (`~/.claude.json` `oauthAccount`, secrets not read): Max plan, + `billingType: stripe_subscription`, rate-limit tier `default_claude_max_20x`, + extra usage off. There is no API key and no per-token billing: the Mind's + Self can only ever spend the operator's subscription quota. +- `~/.claude/.credentials.json` `claudeAiOauth`: an access token with + `expiresAt` 21:33:57 CEST, file written 13:33 CEST, so the interactive + access token lives eight hours and is refreshed by the interactive client. +- The failure the brief names, from this session's transcript + (`~/.claude/projects/F--Projects-CultLib/b471ff9b-….jsonl`): + `401 OAuth access token has expired. Re-authenticate to continue.` + (`authentication_error`), reported as "Agent terminated early due to an API + error" for subagents on `claude-sonnet-5-5`. A running subagent does not + survive the parent's token expiring. +- `claude setup-token`: "Set up a long-lived authentication token (requires + Claude subscription)". The binary carries the string "setup-token creates a + long-lived Claude.ai subscription token" and reads `CLAUDE_CODE_OAUTH_TOKEN` + (61 references). This is the headless credential for a subscription account: + no eight-hour expiry, no interactive refresh. Its lifetime and revocation are + the operator's (it is their subscription); not probed further because + creating one is the operator's act. +- Print mode: `claude -p` with `--output-format json|stream-json`, + `--json-schema`, `--agents `, `--mcp-config`, `--allowedTools`, + `--permission-mode`, `--max-budget-usd ` ("Maximum dollar amount to + spend on API"), `--bg`, `--resume`, `--fallback-model`. The `json` output + carries the run's cost (`total_cost_usd`) and usage. So a headless run has a + structural spend cap and a measured spend, per run, without any rule in a + prompt. +- Plan usage as data: the desktop app's `get_usage` returned, at 18:43 UTC: + 5-hour window 2%, weekly all models 46% (resets 2026-10-05 22:00 UTC), + weekly Fable 0%. That tool exists only inside the desktop app. The CLI + binary knows no usage endpoint (`api/oauth/files/`, `api/oauth/organizations/` + only); it reads `anthropic-ratelimit-unified` response headers (44 + references), which a headless wrapper does not see. **There is no typed + reading of plan usage reachable from Yggdrasil.** Follow-up + `gap-usage-not-typed`. +- Local scheduled tasks exist in the desktop app + (`~/.claude/scheduled-tasks/streampixels-m1-checkin`, disabled, last run + 2026-09-18): a cron inside the desktop app on Starfire. They run only while + the app is open on the operator's workstation, which the load budget + (memory `workstation-load-budget.md`: one job at a time, nothing unannounced) + and "no overnight burns" (memory `token-budget.md`) both argue against for a + recurring unattended Self. Cloud routines (`schedule` skill) run off-mesh + (B1) and hold no forge key (B6): dead for this purpose. + +### B3. Yggdrasil as the waking host + +- No Claude Code installed (`claude: command not found` for `gamecultadmin`; + no `~/.claude`). `node` v24.14.1 and `npm` present, so `npm i -g + @anthropic-ai/claude-code` under a dedicated user is the install. +- Load: 16 cores, 62 GiB, load average 1.4, 54 GiB free. The verify stopgap + runs at most 5 jobs at 4 CPUs and 6 GiB each (`tools/stopgap/ygg-verify.sh` + header). A Claude Code process is light; its Hands and Soul push their + heavy work into the same stopgap containers they use from Starfire. The + stopgap pushes to `~/eureka-verify` over `ssh ygg`; run on Yggdrasil itself + that alias must resolve to localhost for the `eureka` user, or the script + gets a local mode. Recorded in the wake cut's `first`. +- Non-resident workloads already run here hand-installed, outside Idunn + (`systemctl list-timers`): `bifrost-watchdog-notice.timer` (every minute, + oneshot, user `bifrost-notice`: system user, no shell, no home, credentials + through `EnvironmentFile=/srv/bifrost/env/persona-delivery.env` root 0600, + release under `/srv/bifrost/watchdog-notice/releases/-` with a + `current` symlink, `StateDirectory` for journal and receipts), + `gamecult-state-backup.timer` (nightly), `voidbot-source-refresh.timer`. + The runbook `bifrost-watchdog-notice-yggdrasil.md` calls this "an interim + root action on Yggdrasil … until Idunn owns non-resident workloads", and + ruling `idunn-watchdog:ruling:reader-deploy-owner` chose + `ops-hand-install`. **That is the precedent the Mind's Self wake unit + follows**, with the same deletion line. +- Idunn: `TargetDeclaration.service: ServiceDeclaration` is a required field + (`src/deployment.rs:33`), so a recipe without a resident service does not + parse. Follow-up `idunn-watchdog:follow_up:idunn-non-resident-workloads` + (in force) is exactly this gap; Idunn-managed units on the host today are + ghostlight, odin, streampixels-service and streampixels-web. +- Epiphany's own resident Self exists as prior art and is dead: units + `epiphany-swarm.service` ("Epiphany Yggdrasil resident Self") and + `epiphany-heartbeat.service` are `inactive dead`. The binary + (`epiphany-core/src/bin/epiphany-swarm.rs`) runs a 60 s maintenance loop over + `ResidentSelfState`, `ResidentSelfPolicy`, pressure and typed work + obligations, on the Codex spine (`epiphany-openai-codex-spine`, + `codex-connector`). Its doctrine (`epiphany_doctrine.md`): "Heartbeats are + paced scheduling physiology, not cognition … When no typed work obligation + is active, the swarm sleeps. Heartbeat does not ruminate, dream, mutate + memory, or manufacture work." Codex left as supplier 2026-09-05 (memory + `codex-retirement.md`). So the shape is right and the substrate is not: the + Mind's Self runs on Claude Code against Huginn, and borrows the law, not the + binary. + +### B4. The forge and the Mind's identity + +- `GameCult/Eureka` on `https://eureka.gamecult.org/forge/`: public, default + branch `main`, pull requests on, **no branch protection** (API + `branch_protections` → `[]`, with the admin token, on the host). +- Team `minds`: `write` on `repo.code`, `repo.pulls`, `repo.actions`, + `repo.issues`, `repo.releases`, `repo.wiki`, all org repos. Not admin. +- User `eureka` exists since 2026-10-01T18:49:53Z (created during this pass, by + the provisioning the handoff asked for), not admin, one key + `eureka@starfire` SHA256:`zcp0m+jV4AUXzGeoh9z+vfJS8xKHo9S865xOK8p6MGM`, which + matches `~/.ssh/eureka_mind_forge_ed25519.pub` on Starfire. The script + `provision-forge-minds-eureka` adds one key per host, so a Yggdrasil-run + Self gets its own key there. +- The Starfire checkout `~/.claude/skills/eureka` still pushes as + `eureka-admin` (`ssh://eureka-forge/…`, alias `eureka-forge` → + `eureka_forge_ed25519`, title `starfire-claude`). The runbook names that key + interim. Follow-up `forge-push-as-eureka` (gamecult-ops / Self). +- The charters are not in the Eureka repo: `ls ~/.claude/skills/eureka` gives + `LICENSE README.md SKILL.md docs references tools`; no `agents/`. The + charters live only in `~/.claude/agents/*.md` and the doctrine in + `~/.claude/doctrine/`, on Starfire, operator-owned (Life charter: + "the operator owns doctrine"). Every charter's self-improvement line says + "propose changes to the Eureka repo … by pull request on Forgejo". **The + thing the Mind is told to improve itself through is out of its reach.** + Question `charters-into-eureka-repo`. +- Reach is the scope boundary, by construction: a Linux user on Yggdrasil + with the `eureka` forge key, checkouts of Huginn, Epiphany, Eureka and + gamecult-ops, and no GitHub credential, no SSH to Starfire, no Aetheria + checkout, cannot touch an operator project. No prompt rule is needed for + "never touches Aetheria"; the key ring is the rule. (Huginn and Epiphany + are on GitHub today: the wake cut records how the Mind's user fetches and + pushes them. The Eureka forge org already mirrors nothing; a question for + the operator only if the Mind must push to GitHub. Recommended: it pushes + branches to the forge and GitHub stays Self's.) + +### B5. The operator's review channel + +- Bifrost `tools/bifrost-bridge.mjs discord-dm --recipient-id --content + `: DMs through Bifrost's bot token (`BIFROST_DISCORD_BOT_TOKEN`), exits + 75 when it knows nothing was sent (retry with the same nonce). The owner id + is `DISCORD_OWNER_ID` in `persona-delivery.env`. +- `tools/watchdog-notice.mjs` is a one-shot reader that turns a typed store + (Idunn's `incidents.cc`, read unlocked, never written) into owner DMs with a + journal and receipts, exponential retry capped at 60 min, fixed error codes + that never echo input. The idunn-watchdog campaign established the owner + rule: the producer never delivers; Bifrost is the bridge. A Mind-notice + reader is the same program over Huginn (`query` for rulings with authority + `Mind`, runs ended, questions opened, since the journal's last ordinal) + instead of over `incidents.cc`. + +### B6. Scheduling today, and what the skill already derives + +- The skill's recipes (`campaign-state.md` "Recipes") already derive the + queue: specs with no report (minus those blocked by a question raised in + them), reports with no verdict, open findings by severity, open questions and + follow-ups, substrate gaps. The operator-facing Self reads them at rehydrate + and then takes direction from the operator and from prose handoffs + (`F:\Projects\HANDOFF-eureka-self-2026-10-01.md` is one). +- What the queue cannot say: (1) who is working a spec right now (two Selves + would both take the first unreported spec); (2) whether a holding verdict + landed (`gap-landing-untyped`); (3) which of fifteen follow-ups comes first + (no priority, no order); (4) how much the Mind may spend; (5) which Self + admitted a ruling. (1), (4) and (5) are what the `run` and `allowance` + kinds below carry. (2) stays its own gap. (3) is deliberately not a field: + the Mind's Self orders by the fixed rule in the rationale, and a follow-up + that must jump the queue becomes a cut spec. + +## The model page + +One row per persistent kind this design adds or changes. Rows for the +thirteen existing kinds are in `eureka-substrate-map.md`. + +| Kind | Identity (what names it) | Lifecycle (what happens over time) | Authority (who decides) | +| --- | --- | --- | --- | +| `ruling` with `authority: Mind` (new variant, no new kind) | Unchanged: `:ruling: