Live e2e test caught a paste-inserted whitespace in URL token param —
copy-paste from terminal had inserted %20%20%20 into middle of the
64-char hex token, which passed URL parsing but failed byte-level
auth::tokens_match on the daemon → 403.
Two fixes:
1. `sanitize_token()` strips ALL whitespace (spaces, tabs, newlines,
zero-width) from token before use, applied on both URL-param and
localStorage read paths. Defensive even against future Setup-form
paste mishaps — Setup input itself could also be whitespace-dirty.
2. `credentials: 'include'` → `credentials: 'omit'`. Bearer auth rides
on an explicit header; we don't need cookies. `include` triggers
browser quirks (Safari especially) around credentialed cross-origin
fetches that can strip or mismangle Authorization on redirects.
3. Error message now includes response body preview — `"403 Forbidden
— {\"error\":{\"code\":\"forbidden\",\"message\":\"bearer token
rejected\"}}"` — so the next failing setup surfaces root-cause.
Tests unchanged (10 passing). Rebuild hash: index-7ZqAoBoM.js.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|---|---|---|
| .claude-plugin | ||
| .github | ||
| _assembler | ||
| _blocks | ||
| _bridges | ||
| _capabilities | ||
| _manifests | ||
| _primitives | ||
| _roles | ||
| _schemas/fragments | ||
| _templates | ||
| _ts_packages | ||
| docs | ||
| hooks | ||
| install | ||
| scripts | ||
| skills | ||
| tasks/kei-prune-scaffold-w14 | ||
| tests | ||
| .dockerignore | ||
| .gitignore | ||
| CHANGELOG.md | ||
| install.sh | ||
| kei-architect.md | ||
| kei-code-implementer.md | ||
| kei-cost-guardian.md | ||
| kei-critic.md | ||
| kei-fal-ai-runner.md | ||
| kei-infra-implementer.md | ||
| kei-ml-implementer.md | ||
| kei-ml-researcher.md | ||
| kei-modal-runner.md | ||
| kei-researcher.md | ||
| kei-security-auditor.md | ||
| kei-validator.md | ||
| LICENSE | ||
| PLUGIN.md | ||
| README.md | ||
| settings-snippet.json | ||
KeiSeiKit
A local-first substrate that installs next to any LLM-based assistant and keeps its memory, accountability, and nightly learning persistent. Rust core (48 crates, ≤ 2 MB each), TypeScript plugin glue. MIT.
Primary target: Claude Code. Also compatible with Cursor, Continue, Zed, Aider, Windsurf via 11 cross-tool bridges, and with any OpenCode / OpenClaude / open-source Claude-Code clone that speaks the MCP server protocol + standard hook events.
One-line install (Claude Code)
/plugin marketplace add KeiSei84/KeiSeiKit
/plugin install keisei@keisei-marketplace
Twelve agents, 43 skills, 12 hooks, nightly consolidation wired in
60 seconds. Install paths for MCP-only, Cursor, Continue, Zed, Aider,
Docker, Nix — docs/INSTALL.md.
What it does (and where to verify)
DNA — persistent identity per agent run. Every invocation gets an 80-char deterministic string of the form:
<role>::<caps-bitmap>::<sha8-scope>::<sha8-body>-<hex8-nonce>
Example:
edit-local::NG-FW-FD-CP-CG-TG-ND-RF::5435F821::AC73A6A3-e9bf468d
role— which capability bundle the agent got (edit-local / read- only / auditor / merger / …).caps-bitmap— which policy fragments composed its prompt (no-git- ops, files-whitelist, constructor-pattern, cargo-check-green, …).scope— 32-bit hash of the files-whitelist + denylist. Same files → same scope regardless of who asks.body— 32-bit hash of the task description. Two people asking the same thing → same body.nonce— random per spawn. Distinguishes reruns of identical tasks.
Same scope+body → same problem space. You can ask "has this type of
task run before, how did it go" in one query, without embeddings,
without a vector DB, without round-tripping through an LLM. The index
is a plain 32-bit hash lookup against the SQLite ledger. kei-dna-index precedent --body <sha8> returns every past run with its status
merged / failed / running — instantly. Code: _primitives/_rust/kei- shared/src/dna.rs (format SSoT), _primitives/_rust/kei-dna-index/**
(queries), _primitives/_rust/kei-ledger/src/schema.rs (storage).
Git branch per work-unit. kei-fork create makes an atomic
triplet: a branch, a worktree under _forks/<agent-id>/, and a ledger
row. Agent writes in isolation, touches .DONE, kei-fork collect
atomically merges + archives + updates ledger. On any step failure,
everything rolls back. No more "the agent overwrote main". Code:
_primitives/_rust/kei-fork/**.
Persistent memory on disk. Three SQLite files:
~/.claude/agents/ledger.sqlite (who-did-what), ~/.claude/memory/ sessions.sqlite (JSONL traces + embedding cache), ~/.claude/memory/ kei-memory.sqlite (cross-session patterns). All backupable with
cp, portable with keisei mount, inspectable with kei-brain-view summary. Nothing in RAM-only; nothing in a cloud you don't control.
Code: _primitives/_rust/kei-{ledger,memory}/**.
Prompts composed from fragments. Agent prompts aren't hand-written
— they're assembled from _capabilities/<cat>/<slug>/text.md files at
spawn time. Edit a fragment, every agent inherits the change. Single
source of truth for prompt engineering. Code: _primitives/_rust/kei- agent-runtime/src/compose.rs.
Sleep — three phases of overnight consolidation. Your assistant keeps working while you're asleep, but on your rules, on your machine.
-
Phase A — incubation. Anytime during the day:
/sleep-on-it "write a 4-page literature review on …"adds a task to
~/.claude/memory/sleep-queue/. At 03:00 local, a scheduled agent picks up the queue (up to 5 tasks, ≤ 480 min total budget), works on each, checkpoints partial results every N minutes so a cut-short run still leaves a readable artefact. -
Phase B — REM. Same agent reads the day's JSONL traces under
~/.claude/memory/traces/, finds cross-session patterns ("you hit the same error three times this week", "these two tasks touched the same files"), and writes a morning report to~/.claude/memory/ sleep-reports/YYYY-MM-DD.md. Yougit pulland read. Nothing auto-injects into your next session — decisions stay with you. -
Phase C — NREM, every 7 days. A conflict-scan checks the whole substrate for drift: rules that contradict, hooks that overlap, duplicate capability fragments. A refactor-engine then proposes a clean-up branch — in plan-only mode (markdown proposal) or plan + fork mode (actual git branch with patch applied). You pick during
/sleep-setup.
Code + rule: docs/SLEEP-LAYER.md, hooks/ sleep-*.sh, _primitives/_rust/kei-conflict-scan/, _primitives/ _rust/kei-refactor-engine/.
Self-audit, silent-first. Three hooks — session-end-dump,
milestone-commit-hook, error-spike-detector — feed a retrospective.
Sessions 1–10 log without prompting. From session 11 on, if the same
mistake reappears twice, /escalate-recurrence offers to codify it
as rule + wiki entry + hook. Code: hooks/*.sh, skills/self-audit/,
skills/escalate-recurrence/.
Deployment modes
| Where | How | When you want it |
|---|---|---|
| Local laptop | /plugin install keisei |
Daily dev / research / writing |
| USB stick | keisei mount /Volumes/usb/brain |
Move between machines |
| iCloud / Dropbox | Same keisei mount on a cloud-synced folder |
Auto-backup + multi-device |
| Cloud VPS | ssh user@host && ./install.sh && keisei serve |
Always-on agent, tablet client, shared team brain |
| Docker | docker run -v ./brain:/home/kei/.claude keiseikit |
Ephemeral CI runs, reproducible test envs |
| MCP-only | ./install.sh --profile=mcp |
Plug the memory layer into a different assistant, skip the plugin |
Rust binaries are ≤ 2 MB each, statically linked where possible, no
Python runtime. Any x86_64 / arm64 host with git + SQLite works.
Bring your own API key (Anthropic / OpenAI / OpenRouter / local
Ollama) via ~/.claude/secrets/.env — the kit never ships keys.
Why Rust + TypeScript (no Python)
Rust for the engine — 47 crates covering ledger, memory, DNA,
fork, scheduler, watcher, assembler, CLI. The class of mistakes LLMs
make most often — None vs empty array, missing .await, unhandled
Result, mutex misuse — are compile-time errors in Rust. The LLM
literally cannot ship them. The type system is the fence.
TypeScript only for the thin adapter that talks to Claude Code's
Node-based plugin API. Three packages under _ts_packages/, each
≤ 300 LOC: marketplace manifest, installer helpers, plugin surface.
The substrate itself never assumes Node is running.
Why not Python — it's transformer math, not taste. Writing Rust
costs more tokens up-front (explicit types, explicit errors, explicit
ownership) but debugging costs ≈ 0 — the compiler is the fence.
Writing Python costs ~5 minutes (no types, no lifetimes, no compile
step), then debugging loops for hours: each failed run produces new
tokens the assistant must read, reason about, correct — often
triggering the next failure, another iteration, another token burn.
This isn't empirical. Python's tokenization (indentation-as-syntax,
runtime dynamic dispatch, late-binding names) leaves each token with
low semantic commitment, so the transformer must track more
conditional paths forward. Rust pins each token to a compile-time
shape: fewer open paths, fewer silent surprises, fewer debug loops.
Net cost of a shipped Rust primitive: predictable. Net cost of a
Python primitive: unbounded. RULE 0.2 enforces this with a hook that
blocks python / python3 / uv run python without an explicit
opt-in prefix. install.sh runs on a fresh host with zero Python
installed — if Python slips into this repo, it's a bug.
Probably fits — it's a way of working with AI as much as a tool
You'll like this if you prefer:
- Seeing what your AI did, rather than a dashboard that hides the mistakes. The ledger shows every agent run, every fork, every rollback. Honesty by construction.
- Your own machine over someone else's cloud. Brain lives on your
disk, backs up with
cp, moves on a USB. - Two install commands once, instead of a SaaS onboarding flow.
- One of: macOS, Linux, or Windows-via-WSL2. Native Windows is on the backlog.
- Owning your API keys — bring your own Anthropic / OpenAI / OpenRouter / local Ollama, never ours.
- Working across multiple AI assistants — Claude Code today, Cursor on the plane, an OpenCode fork next month; the substrate moves with you.
- A workflow that learns while you sleep rather than a tool you restart every morning.
If you'd rather have a hosted multi-tenant SaaS with a polished web UI and no CLI — this isn't that, and that's OK. Plenty of great tools in that space. KeiSeiKit is for the other camp.
What ships (run the command, get the number)
| Thing | Count | Verify |
|---|---|---|
| Rust crates (workspace) | 47 | ls -d _primitives/_rust/*/ | wc -l |
Tests green on cargo test --workspace |
801 | cd _primitives/_rust && cargo test --workspace |
| Agents | 12 | ls _agents/kei-*.md 2>/dev/null | wc -l |
| Skills | 43 | ls -d skills/*/ | wc -l |
| Hooks | 12 | ls hooks/*.sh | wc -l |
| Behavioural blocks | 82 | ls _blocks/*.md | wc -l |
| Capabilities | 11 | find _capabilities -name text.md | wc -l |
| Roles | 7 | ls _roles/*.toml | wc -l |
| Cross-tool bridges | 11 | ls _bridges/*.tmpl _bridges/*.mdc 2>/dev/null | wc -l |
Counts regenerate from source via scripts/regen-counts.sh.
Architecture in one paragraph
One hub crate (kei-entity-store) owns SQLite migrations, FTS
indexes, verb dispatch. Sibling store crates (chat, content, social,
crossdomain, task, scheduler) are thin shims over the hub — star
topology, zero sibling-to-sibling edges. DNA format is SSoT'd in
kei-shared (grep-verify: grep -l "kei_shared::dna" _primitives/ _rust/*/src/*.rs). Constructor Pattern is enforced pre-commit:
every file ≤ 200 LOC, every function ≤ 30 LOC. See
docs/ARCHITECTURE.md.
Verify everything works (60 seconds)
git clone https://github.com/KeiSei84/KeiSeiKit && cd KeiSeiKit
cd _primitives/_rust && cargo test --workspace
# Expect: test result: ok. 801 passed; 0 failed
cd .. && tests/substrate_integration.sh && tests/hook_wiring_integration.sh
# Expect: two PASS lines
If both pass, the repo you're reading matches the repo I'm describing.
Compared to similar tools
| KeiSeiKit | LangChain | AutoGen | MCP alone | |
|---|---|---|---|---|
| Local-first, no cloud required | ✓ | partial | ✓ | ✓ |
| Rust core, ≤ 2 MB binaries | ✓ | ✗ | ✗ | N/A |
| Per-run deterministic DNA | ✓ | ✗ | ✗ | ✗ |
| Git-fork work isolation | ✓ | ✗ | ✗ | ✗ |
| Three-phase nightly cycle | ✓ | ✗ | ✗ | ✗ |
| Capability-fragment prompts | ✓ | partial | partial | ✗ |
| Cross-tool bridges (Cursor, Zed, Aider, …) | 11 | ✗ | ✗ | ✗ |
| Works with OpenCode / OpenClaude clones | ✓ | ✗ | ✗ | ✓ |
| Enforced Constructor Pattern | ✓ | ✗ | ✗ | N/A |
Sits alongside these tools, not a replacement. Uses MCP where MCP fits; LangChain stays useful for its retriever zoo.
Docs
| PHILOSOPHY.md | The biological principles, in depth |
| INSTALL.md | All install paths, profiles, keisei CLI, hook controls |
| ARCHITECTURE.md | Build pipeline, bridges, meta-composer |
| REFERENCE.md | Every primitive, hook, skill with flags and exit codes |
| SLEEP-LAYER.md | Phase A / B / C nightly cycle + self-audit |
| TAXONOMY.md | The seven-facet vocabulary |
| SUBSTRATE-SCHEMA.md | Atom contract |
| SECURITY.md | Threat model + mitigations |
| USB-BRAIN-GUIDE.md | Portable brain — macOS / Linux / Windows |
| WHY.md | The full story of why this exists |
| CHANGELOG.md | What changed, version by version |
| PLUGIN.md | Anthropic plugin-format details |
Author
Built by Denis Parfionovich at KeiLab (parfionovich@keilab.io) while
running 4–8 parallel Claude Code terminals per day. Forks welcome.
MIT License. See LICENSE.