Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8ac12c6
fix(ids): UUIDs are not strings — mint real ones, and stop typing ids…
joelteply Aug 13, 2026
b1014a3
docs(CLAUDE.md): headless Rust core is the system — Node is ONE clien…
joelteply Aug 13, 2026
ec1abb9
fix(cli): `uu` is the alias — `cu` is UUCP, and every harness default…
joelteply Aug 13, 2026
ec327b9
fix(core): the last Python in the runtime path — one vestigial, one s…
joelteply Aug 13, 2026
f92e0d9
feat(identity): PersonaRef vs PeerId — a reference is not an identity…
joelteply Aug 13, 2026
a36722f
refactor(memory): the memory layer takes PersonaRef, not loose text —…
joelteply Aug 13, 2026
672c32c
refactor(commands): persona params carry PersonaRef — agent/solve, pe…
joelteply Aug 13, 2026
6db0a74
refactor(rag/introspect): last persona PARAMS typed — and the RAG sou…
joelteply Aug 13, 2026
4fccf5a
fix(test): 5 supervisor tests have been panicking since #398 slice 3 …
joelteply Aug 13, 2026
31d8a5d
fix(test): pin the stub's REFUSAL contract — the old test asserted th…
joelteply Aug 13, 2026
b496ed1
test(identity): CI guard — a String-typed identity field must be DECL…
joelteply Aug 13, 2026
7e0c546
fix(cli): `continuum start` execs the installed server — building is …
joelteply Aug 13, 2026
f964dda
fix(core): tree is GREEN again — 7081/0 (peer_id → PeerId finished, g…
joelteply Aug 13, 2026
29990b7
fix(tests): a subsystem-named room does not belong in a fixture either
joelteply Aug 13, 2026
e0ac271
fix(benchmark): an UNGRADEABLE grade is an ABSENCE, not a capability …
joelteply Aug 13, 2026
d1b2440
fix(swe): gold-gate the harness — refuse an env whose pytest cannot R…
joelteply Aug 13, 2026
ffdb783
docs(arch): benchmarks are ADAPTERS into recipes/activities — never a…
joelteply Aug 13, 2026
9fa02eb
feat(activity): a room's recipe binding finally has a READER — every …
joelteply Aug 13, 2026
1575f56
fix(activity): the purpose index must SAY it ran — a silent fold is i…
joelteply Aug 13, 2026
c254ac9
feat(persona): RAG is a RenderTarget — one ViewState renders to eyes …
joelteply Aug 13, 2026
11e186d
docs(persona): name the substrate prerequisite IN the module, before …
joelteply Aug 13, 2026
713d931
feat(positron): per-ROOM substrates — the keystone that lets a citize…
joelteply Aug 13, 2026
7a2d165
feat(positron): the chat projection writes per-ROOM as well as node —…
joelteply Aug 13, 2026
a4c75c7
feat(persona): a citizen reads WHO IS PRESENT from the same projectio…
joelteply Aug 13, 2026
e85541f
fix(cli): restore the deploy path — reboot builds again, and the sock…
joelteply Aug 13, 2026
fa1f720
fix(deploy): publish the verified core binary to the installed path e…
joelteply Aug 13, 2026
472b866
fix(persona): one contract, one spelling — a ViewState states its flo…
joelteply Aug 13, 2026
40ce719
glass-box(persona): say WHAT the rejected event was, not just which b…
joelteply Aug 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
115 changes: 86 additions & 29 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,38 @@ We already wrote the test infrastructure. The recurring slop pattern is the mode

**The cost of skipping this doc is the model rebuilding `RecordingModule` inline in every test file, refusing to gate stress tests, growing the test surface by N tests per PR without curating any of them, and turning `cargo test` into a 14-minute build for tests that were each individually justified at sign-off but collectively duplicate.** Don't.

## 🛑 STOP — If You Are About To Touch Benchmarks, agent/solve, Grading, Or Run State

**Required first read** before editing ANY of `commands/benchmark.rs`,
`commands/agent/solve.rs`, `cognition/swe_bench.rs`, or anything that writes run
state, grades, or benchmark receipts:

→ **[docs/architecture/BENCHMARKS-ARE-ADAPTERS-NOT-A-RUNNER.md](docs/architecture/BENCHMARKS-ARE-ADAPTERS-NOT-A-RUNNER.md)**

**Benchmarks are ADAPTERS into recipes/activities. They are NOT a parallel runner.**
Import task + oracle only; project into a recipe; the ROOM is the runner; grading is
the activity's outcome score.

**The consequence that makes this law:** the learning flywheel consumes ROOM TURNS
(L1 lifts tool-traces from captured turns, L2 triggers on turn-completion). A
detached `agent/solve` writing `progress/<run>.grade.json` produces **no turns**, so
a citizen can burn 12 acts, write a patch, take a verdict — and **none of it reaches
the curriculum.** Maximum effort, zero learning. That, not the pass rate, is why
benchmarks have failed.

**The acceptance test for any change here:** *can a citizen standing in the room
perceive the run's state through the same ViewState pipe the human's screen uses?*
If answering needs a file read or a log parse, it is disconnected and it failed.

**The smell to catch yourself on:** if you are adding a field to a benchmark probe so
an external consumer can parse it better — STOP. The consumer should not be external.
(Done on 2026-08-13, in good faith, while the real defect was that the subsystem
exists at all.)

**The cost of skipping this doc is rebuilding the parallel runner — it is locally the
shortest path to "a number" every single time, and every patch to it deepens the
hole.** Don't.

## 📐 Canonical Substrate Docs (read first)

If you're new to the substrate, or you're picking up runtime/cognition work, read these in order before anything else in this file. They are the precedence-winning truth on substrate-shaped questions:
Expand Down Expand Up @@ -419,31 +451,56 @@ let results = algo.execute(&input);

## 🚨 CRITICAL WORKFLOW (READ FIRST!)

### THE SYSTEM IS A HEADLESS RUST CORE. NODE IS ONE CLIENT.

Read this before you reach for `npm` anything. Joel, 2026-08-13:

> *"Headless rust period. No need for node to run everything except for the web
> interface which is one of many, including mobile apps/sdk."*

The core is a Rust process. It builds, boots, serves models, runs cognition, and
answers commands with **no Node in the picture** — `continuum --help` says so in its
own first line: *"build + run the headless Rust core"*. Node exists to build the WEB
desktop, which is **one client among several** (mobile app, SDK, TUI, MCP, another
node's core over the grid). A feature that lives in a client only exists for that
client — which is exactly how voice ended up web-only and every other citizen was
structurally mute (#58). Behaviour goes in the core. Clients render.

### EVERY TIME YOU EDIT CODE:
1. **Edit files**
2. **Run `npm start`** (MANDATORY - waits 90+ seconds)
3. **Test with screenshot** or command
2. **`continuum reboot`** — rebuilds and relaunches the core, and **verifies the
RUNNING core's build SHA** before reporting success (that verification exists
because a reboot once shipped a stale binary and reported success anyway, #194).
3. **Exercise the change through a command** — and read the receipt, not the exit code
4. **Repeat**

```bash
cd src
npm start # DEPLOYS code changes, takes 130s or so

./jtag ping #check for server and browser connection
./jtag interface/screenshot # Verify any visual changes
./jtag collaboration/chat/send --room="general" --message="Try using the ping command" #be sure to randomlize this, check for list, help, etc, or they think it's a repeat
./jtag collaboration/chat/export --room="general" --limit=20 | tail -20 #Wait about 30 seconds and get the last 20 messages
continuum reboot # THE deploy path. Rust build + relaunch + SHA verify.
continuum deploy-verify # prove the running core matches the deployed source
continuum ping # is the core answering? (check the version trio)
continuum commands/list # discover the live command surface — never guess a verb
continuum commands/list --filter data/
```

**IF YOU FORGET `npm start`, THE BROWSER SHOWS OLD CODE!**
**Verify the deploy, always.** A fix you cannot prove reached the running binary is a
fix you have not made — stale binaries have silently poisoned whole debugging sessions.
That is what the SHA check and the version trio (build # + sha + built-at) are for.

**`cargo build` is not the deploy path** — not because Rust builds are forbidden, but
because a binary you built by hand exists only on your machine, and the next person to
clone the repo gets a system that doesn't work. Anything a running core needs must be
wired into the path `continuum start` / `continuum reboot` actually takes, so a fresh
clone works with no manual steps (#291). For type-checking while you work,
`cargo check -p continuum-core` is the right tool — always after
`export CARGO_TARGET_DIR="$HOME/.continuum/cache/cargo-target"`.

**`npm` is for building the web client, and only that.** If you are changing core
behaviour and find yourself running `npm start`, you are in the wrong tier.

**NEVER CALL `cargo build` DIRECTLY!**
- ALL Rust binaries MUST be built via `npm start`
- If you run `cargo build --release` manually, that binary only exists on YOUR machine
- When someone else clones the repo and runs `npm start`, that step doesn't happen
- The repo is BROKEN for everyone except you
- Manual build steps = broken repo for all other users
- If a Rust binary needs to be built, it MUST be wired into the `npm start` build scripts
> **⚠️ `./jtag` is the LEGACY Node CLI**, from when the Node shell was the system.
> Where you see it below and elsewhere in this file, the current equivalent is
> `continuum <command>` against the headless core. The old invocations are kept
> because their *command names* are still accurate; the `./jtag` driver is not.

Don't panic and stash changes first before anything drastic. Use the stash to your advantage and you will be safe from catastrophe. Remember we have git for a reason!

Expand Down Expand Up @@ -544,7 +601,7 @@ tail -f .continuum/sessions/user/shared/*/logs/browser.log

```
1. Edit code
2. Deploy with npm start (90+ seconds)
2. Deploy with `continuum reboot` (Rust build + relaunch + SHA verify)
3. Test manually (verify basic functionality)
4. ✨ ASK AI TEAM TO QA TEST ✨
5. Wait for AI feedback (they WILL find issues)
Expand Down Expand Up @@ -597,7 +654,7 @@ mkdir daemons/logger-daemon && touch LoggerDaemon.ts

```bash
# 1. Deploy your changes
npm start
continuum reboot

# 2. Ask AI team to test
./jtag collaboration/chat/send --room="general" --message="I just added a new 'collaboration/wall/write' command. Can you try writing a document to the wall and let me know if the error messages make sense?"
Expand Down Expand Up @@ -1071,7 +1128,7 @@ npx vitest tests/integration/genome-paging.test.ts
npx vitest tests/integration/continuous-learning.test.ts

# System tests (end-to-end)
npm start
continuum reboot
# Wait 1 hour, check for self-created tasks
./jtag task/list --assignee="helper-ai-id" \
--filter='{"createdBy":"helper-ai-id"}'
Expand Down Expand Up @@ -1179,8 +1236,8 @@ npx tsx generator/CommandGenerator.ts generator/specs/gpu-stats.json
# const stats = await this.rustClient.gpuStats();

# 7. Build and verify
npm run build:ts && npm start
./jtag gpu/stats
continuum reboot
continuum gpu/stats
```

**The three-layer architecture:**
Expand Down Expand Up @@ -1220,7 +1277,7 @@ Screenshots don't lie - don't trust success messages
```typescript
console.log('🔧 CLAUDE-FIX-' + Date.now() + ': My change');
```
Then verify markers appear in browser console after `npm start`
Then verify the marker appears in the RUNNING core's output after `continuum reboot` — a marker that never prints means you are testing a stale binary

### 4. BACK-OF-MIND CHECK
What's nagging at you? That's usually the real issue.
Expand Down Expand Up @@ -1327,7 +1384,7 @@ The AIs will:

## 🚨 CLAUDE'S COMMON MISTAKES

### 1. FORGET TO RUN `npm start` AFTER EDITING
### 1. FORGET TO DEPLOY (`continuum reboot`) AFTER EDITING
**Result**: Browser shows old code, nothing works

### 2. ASSUME SUCCESS WITHOUT TESTING
Expand Down Expand Up @@ -1357,7 +1414,7 @@ The AIs will:

## ⚡ ESSENTIAL FACTS

- **npm start takes 90+ seconds** - BE PATIENT
- **A core rebuild takes a while** - BE PATIENT, and verify the SHA when it returns
- **One server, many clients** - All tests connect to running server
- **"browserConnected: false" is a red herring** - Use `./jtag ping` instead
- **Precommit hook is sacred** - TypeScript + CRUD tests must pass
Expand All @@ -1373,7 +1430,7 @@ npm run data:clear # Clear all data
npm run data:seed # Create default users + rooms
```

**Integrated into `npm start`** - fresh data every deployment
**Integrated into the core's start path** - fresh data every deployment

**Default seeded data:**
- Joel (human owner)
Expand Down Expand Up @@ -1643,15 +1700,15 @@ Generators and OOP are intertwined parallel forces:
---

**File reduced from 61k to ~20k characters**
- if you only edit a test, and not the api itself, you don't need to redeploy with npm start, just edit and test again e.g npx tsx tests/integration/genome-fine-tuning-e2e.test.ts
- need to remember to npm run build:ts before deploying with npm start, just to make sure there's no compilation issues
- if you only edit a test, and not the api itself, you don't need to redeploy just run the test again (`cargo test -p continuum-core --lib <filter>`)
- type-check before you deploy: `cargo check -p continuum-core` (after `export CARGO_TARGET_DIR="$HOME/.continuum/cache/cargo-target"`). `npm run build:ts` checks the WEB CLIENT only — it says nothing about whether the core compiles
- ./jtag collaboration/chat/export --room="general" --limit=30 will let you see ai opinions after chat/send to ask
- Tool logging is in PersonaToolExecutor
- make sure to put any markdown architecture or design documents other than readmes in docs/* into the appropriate directort OR document if they exist. run tree there.
- assume a new concept or group of functions ought to be in its own file and most likely own class. Use good OOP, interfaces, like java, dot net, or ts
practices, and in some ways like C++ templating with generics. These are your superpowers
- for getters in typescript we do not prefix methods with get, we use get or set like good properties and often this is backed by _theProperty type private var
- never commit code until you validate it works. deploy and validate first, make sure it compiles, npm run build:ts before that
- never commit code until you validate it works. deploy and validate first, make sure it compiles (`cargo check` for the core; `npm run build:ts` only if you touched the web client)
- never use `--no-verify` on commit or push. If hooks fail because of a stale worktree, missing submodule, missing generated file, or a bug in the hook itself, fix the underlying problem; never bypass the shared validation path.
- commit often per logical unit once validated. merging to main is the only step that requires my approval — commits to feature branches do not.
- **clean as you go.** Cargo target dirs balloon — a `cargo test` of continuum-core consumes ~10 GB of test-binary artifacts on top of the shared cache. Discipline: (1) ALWAYS `export CARGO_TARGET_DIR="$HOME/.continuum/cache/cargo-target"` before any cargo invocation so artifacts land in the ONE shared cache, not in a per-invocation ghost workspace `target/` dir. (2) After each cargo cycle, `df -h /` — if free space dropped to < 20 GB, sweep ghost target dirs (`rm -rf core/target` when it ghost-grew from RA / manual cargo bypassing the env var) and report the number BEFORE running another cargo. (3) Prefer `cargo check` over `cargo test` when validating type-correctness; only escalate to test when behavior changed. (4) Slice 3 in `core/.cargo/config.toml` is the opt-in fix that pins target-dir at the workspace level — uncomment for your operator absolute path when ready.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ tokio-stream = "0.1"

# Timing and UUIDs (for JTAG protocol)
chrono = "0.4"
uuid = { version = "1.6", features = ["v4", "serde"] }
uuid = { version = "1.6", features = ["v4", "v5", "serde"] }

# Safetensors for model/adapter weights
safetensors = "0.7"
Expand Down
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,14 +157,17 @@ One command -- bootstraps WSL2 + Docker Desktop via winget if missing, auto-togg
<details>
<summary>Development (from source)</summary>

Requires Node.js 20+. `npm run setup:rust` provisions the rest of the native build chain — the pinned Rust toolchain (1.95, via `rust-toolchain.toml`), **cmake**, and the **vendored git submodules** (llama.cpp/whisper.cpp) that `continuum-core` compiles. Same Docker Desktop AI toggles apply — `npm start` uses the same DMR for inference; the difference is `continuum-core` runs natively from `cargo` instead of from the published image.
The system is a **headless Rust core**. `setup:rust` provisions the native build chain — the pinned Rust toolchain (1.95, via `rust-toolchain.toml`), **cmake**, and the **vendored git submodules** (llama.cpp/whisper.cpp) that `continuum-core` compiles. Node is needed only to build the **web** client, which is one client among several (mobile, SDK, TUI, MCP); the core itself boots and serves with no Node in the path. Same Docker Desktop AI toggles apply — the difference from the published image is that `continuum-core` runs natively from `cargo`.

```bash
cd continuum
npm install
npm install # web-client deps + the setup scripts below
npm run setup:rust # pinned Rust 1.95 + cmake + vendored submodules (native build prereqs)
npm run setup:git-hooks # optional, for commit/pre-push validation
npm start

continuum start # build + run the headless Rust core, wait until ready
continuum reboot # after editing: rebuild, relaunch, VERIFY the running build SHA
continuum ping # is the core answering?
```

Detailed dev environment + platform-specific gotchas: **[docs/SETUP.md](docs/SETUP.md)**.
Expand Down
2 changes: 1 addition & 1 deletion apps/eye-node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ cd apps/eye-node && npx tsx src/index.ts
Env:

- `CONTINUUM_CORE_SOCKET` — core IPC socket path or `tcp://host:port`
(default `/tmp/continuum-core.sock`, matching `cu`).
(default `/tmp/continuum-core.sock`, matching `uu`).
- `EYE_NODE_LABEL` — provider label shown in the core's logs.

**Opt-in, browserless-core principle:** not every core runs a browser. Start an
Expand Down
2 changes: 1 addition & 1 deletion apps/eye-node/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*
* Config (env):
* CONTINUUM_CORE_SOCKET core IPC socket path or `tcp://host:port`
* (default `/tmp/continuum-core.sock`, matching `cu`)
* (default `/tmp/continuum-core.sock`, matching `uu`)
* EYE_NODE_LABEL provider label shown in core logs
*/

Expand Down
6 changes: 3 additions & 3 deletions benchmarks/HERMES-CAMPAIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ your system is checkmate framing.
**Round 1 — tonight (function level, fast, winnable):** humaneval-rs 20-task slice.
Cells: hermes3-8b×raw, hermes3-8b×ours, devstral-24b×raw, devstral-24b×ours,
devstral-24b×ours+coder-act-transition (tonight's gene), qwen3.5-4b-forged×ours.
Runner: `cu benchmark/run` (ours arm) + `benchmarks/coder/oneshot_opponent.py` (raw arm).
Every cell → `cu benchmark/record` with replication cmd → `cu benchmark/matrix`.
Runner: `uu benchmark/run` (ours arm) + `benchmarks/coder/oneshot_opponent.py` (raw arm).
Every cell → `uu benchmark/record` with replication cmd → `uu benchmark/matrix`.

**Round 2 — next (agentic level, the lever):** swe-bench-lite 10-instance slice, same
cells + hermes-4.3-36b both arms. This is where Axis B matters most: Hermes models are
Expand Down Expand Up @@ -104,7 +104,7 @@ the roster.
- **Tonight:** trainer completes → sentinel eval (gene lift) → release reboot (5 queued
commits incl. evidence engine) → smoke matrix DETACHED overnight: core six × {raw,
ours} on humaneval-rs 20-task (~12 cells). Every cell → `benchmark/record`.
- **Morning:** `cu benchmark/matrix` prints the first comparison table. Triage: any
- **Morning:** `uu benchmark/matrix` prints the first comparison table. Triage: any
degenerate-output cells (mean tokens/task floor) re-run before conclusions.
- **Day 2:** polyglot-rust importer (30 Exercism exercises → EvalTask JSONL, existing
rustc grader) → HEADLINE run across core six; SWE-lite 10-instance slice on the top
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/agent-solve/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ the Δ column is only a claim if a skeptic reproducing THEIR side gets our numbe
## Status: scaffolding, not substrate

Python here is deliberately NON-load-bearing (Joel, 2026-07-22): it only seeds git
workspaces, fires the `cu agent/solve` CLI, runs an assert, and tallies. Every
workspaces, fires the `uu agent/solve` CLI, runs an assert, and tallies. Every
measurement-path concern — the drive loop, lane admission, patch extraction, the
persona herself — is Rust. Convergence TODO: fold these tiers into gym JSONL and grow
a Rust `agent/battery` sweep on `cognition/eval`'s existing task/grade/ledger
Expand Down
22 changes: 18 additions & 4 deletions benchmarks/agent-solve/bench.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,24 @@
"""
import json, os, subprocess, sys, time, shutil

def _resolve_cli():
"""Locate the continuum CLI.

`uu` is THE official short alias (the double-U of contin-UU-m). `uu` is
/usr/bin/cu (UUCP) on every Unix and was never ours — a default pointing at a
`uu` binary resolved to a file that does not exist, so the harness failed at
the first invocation instead of running. Prefer what is actually installed on
PATH; fall back to the release build.
"""
for name in ("uu", "continuum"):
found = shutil.which(name)
if found:
return found
return os.path.expanduser("~/.continuum/cache/cargo-target/release/continuum")


HOME = os.path.expanduser("~")
CU = f"{HOME}/.continuum/cache/cargo-target/release/cu"
if not os.access(CU, os.X_OK):
CU = f"{HOME}/.continuum/cache/cargo-target/debug/cu"
UU = _resolve_cli()
MODEL = "bartowski/Qwen2.5-Coder-7B-Instruct-GGUF"
ROOT = os.path.dirname(os.path.abspath(__file__)) + "/ws"
PDIR = f"{HOME}/.continuum/progress"
Expand Down Expand Up @@ -121,7 +135,7 @@ def fire_one(persona, model, label, name, fn, instr, ws, suppress, capture=None)
os.remove(led)
task = (f"{instr} Work in your workspace: read the files, make the fix with "
f"your tools, and run the code to confirm.")
args = [CU, "agent/solve", "--persona-id", persona, "--base-model-id", model,
args = [UU, "agent/solve", "--persona-id", persona, "--base-model-id", model,
"--task", task, "--workspace", ws, "--max-acts", "10",
"--detach", "true", "--run-id", rid(label, name),
# work IS training: the experience (never the solution) reaches her
Expand Down
Loading
Loading