diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 320b07a..c7f6166 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -8,7 +8,7 @@ }, "homepage": "https://github.com/KeiSei84/KeiSeiKit", "repository": "https://github.com/KeiSei84/KeiSeiKit", - "license": "MIT", + "license": "Apache-2.0", "keywords": [ "constructor-pattern", "agents", diff --git a/README.md b/README.md index 996d3d1..371948d 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,13 @@ Works first-class with Claude Code; MCP-compatible bridges generate context for Cursor / Continue / Zed / Aider / Windsurf / Cline / OpenClaw / Kimi from the same source-of-truth. -**Apache 2.0** — explicit patent grant + retaliation clause. 102 Rust -crates (~132K LOC), 67 skills, 35 hooks, 37 agent manifests, 82 -substrate blocks, 18 capability bundles, 7 substrate roles. Self- -indexing via kei-registry SQLite (currently 495 active DNAs across the -public substrate). Three-phase nightly consolidation. Foreign-project -ingestion runtime (`kei-import `). +**Apache 2.0** — explicit patent grant + retaliation clause. 105 Rust +crates (workspace member count via `grep -E '^\s*"[a-z-]+",' _primitives/_rust/Cargo.toml | wc -l`), +68 skills, 38 hooks, 38 agent manifests, 85 substrate blocks, 18 +capability atoms, 7 substrate roles. Self-indexing via kei-registry +SQLite (565 active DNAs as of 2026-05-03 per `docs/DNA-INDEX.md` +header). Three-phase nightly consolidation. Foreign-project ingestion +runtime (`kei-import `). ## Maturity matrix @@ -33,7 +34,7 @@ production work. | | | |---|---| | **Persistent memory** | SQLite ledger + content-addressable memory store, session-spanning context, cross-machine sync via memory-repo | -| **Agent DNA** | Deterministic 80-char identity per invocation: `::::::-`. Same task → same prefix → "did this run before?" via SQL, no embeddings | +| **Agent DNA** | Deterministic variable-length identity per invocation: `::::::-` (≥33 chars; role + caps slugs are variable). Same task → same prefix → "did this run before?" via SQL, no embeddings. See [`docs/DNA-FORMAT.md`](./docs/DNA-FORMAT.md) for the wire spec. | | **Constructor Pattern for prompts** | Agent `.md` files composed from manifests + blocks + capability bundles + rule fragments. Edit a block → all agents using it recompose. Single source of truth | | **kei-fork** | Atomic git triplet (branch + worktree + ledger row) for parallel agent runs. Atomic rollback. No main-branch collisions across 4-8 simultaneous Claude sessions | | **Three-phase sleep** | Phase A incubation (queued tasks) → Phase B REM consolidation (analyzes last 30 sessions, writes morning markdown report) → Phase C NREM deep-sleep (every 7 days, conflict scan + refactor proposals). No feedback loop — outputs are markdown, you decide what to keep | @@ -67,10 +68,15 @@ cd KeiSeiKit-1.0 ./install.sh --profile=minimal ``` -37 agents + 67 skills + 35 hooks + nightly consolidation wired in -60 seconds. Eleven install profiles (`minimal` → `core` → `full` + -MCP-only / Cortex / Cursor / Continue / Zed / Aider / Docker / Nix) -documented in [`docs/INSTALL.md`](./docs/INSTALL.md). +38 agents + 68 skills + 38 hooks + nightly consolidation wired in +~60 seconds. Twelve install profiles (`outcome-only`, `minimal`, +`core`, `frontend`, `ops`, `dev`, `mcp`, `cortex`, `local-mirror`, +`dashboard`, `full-hub`, `full`) defined in +`_primitives/MANIFEST.toml` and documented in +[`docs/INSTALL.md`](./docs/INSTALL.md). For non-Claude-Code clients +(Cursor / Continue / Zed / Aider) the bridges format the same source +into client-native config — those are bridge targets, not separate +profiles. ### Outcome-only — try just the outcome loop (5 files, ~200 LOC) diff --git a/_primitives/_rust/Cargo.toml b/_primitives/_rust/Cargo.toml index 63c0049..6c0ea2a 100644 --- a/_primitives/_rust/Cargo.toml +++ b/_primitives/_rust/Cargo.toml @@ -210,7 +210,7 @@ flate2 = "1" walkdir = "2" pretty_assertions = "1" # Shared async + HTTP deps (Waves 31/32/33/35/36 etc — kei-tty / kei-router / etc) -tokio = { version = "1", features = ["rt-multi-thread", "macros", "signal", "net", "time", "process", "fs", "io-util", "sync"] } +tokio = { version = "1", features = ["rt-multi-thread", "macros", "signal", "net", "time", "process", "fs", "io-util", "io-std", "sync"] } tokio-stream = "0.1" futures = "0.3" reqwest = { version = "0.12", features = ["json", "stream", "multipart", "rustls-tls"], default-features = false } diff --git a/_primitives/_rust/kei-mcp/Cargo.toml b/_primitives/_rust/kei-mcp/Cargo.toml index b697a01..919937b 100644 --- a/_primitives/_rust/kei-mcp/Cargo.toml +++ b/_primitives/_rust/kei-mcp/Cargo.toml @@ -25,7 +25,8 @@ kei-skills = { path = "../kei-skills" } [dev-dependencies] tempfile = { workspace = true } -tokio = { workspace = true } +# test-util: needed by tests/tools_call_timeout.rs for tokio::time::advance + Builder::start_paused +tokio = { workspace = true, features = ["test-util"] } [package.metadata.keisei] backend = "none" diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 13912b5..0d0aeb1 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -315,4 +315,4 @@ Cross-references to the rules that govern git state: - **RULE 0.12** — agent-fork lifecycle (6-file bundle + ledger row + merge ceremony). - **RULE 0.13** — orchestrator owns branch + commits + pushes; agents write files only. -The `checkpoint:`, `feat:`, `refactor:`, `audit:`, and `fix:` commit prefixes are SSoT'd in [`~/.claude/rules/git-conventions.md`](https://example.invalid/git-conventions). `kei-changelog` walks Conventional Commits to regenerate `CHANGELOG.md` blocks; `kei-fork validate` checks the 6-file bundle on every merge. +The `checkpoint:`, `feat:`, `refactor:`, `audit:`, and `fix:` commit prefixes are SSoT'd in `~/.claude/rules/git-conventions.md` (a per-user rule file installed outside this public repo; see `_blocks/` for the in-repo block-format SSoT). `kei-changelog` walks Conventional Commits to regenerate `CHANGELOG.md` blocks; `kei-fork validate` checks the 6-file bundle on every merge. diff --git a/docs/DNA-INDEX.md b/docs/DNA-INDEX.md index f8826e8..7a4840c 100644 --- a/docs/DNA-INDEX.md +++ b/docs/DNA-INDEX.md @@ -1,6 +1,6 @@ # KeiSeiKit DNA Encyclopedia -> Auto-generated from kei-registry. Last regenerated: 2026-05-03T07:06:44Z. +> Auto-generated from kei-registry. Last regenerated: 2026-05-03T10:59:45Z. > Total blocks: 565. Per-type breakdown: | Type | Count | @@ -113,7 +113,7 @@ Sorted alphabetically by name. | kei-replay::kei-replay | primitive::_::e59b33… | _primitives/_rust/kei-replay/Cargo.toml | 4e8b77cb | | kei-router::kei-router | primitive::_::1e654e… | _primitives/_rust/kei-router/Cargo.toml | 98ab93cd | | kei-runtime-core::kei-runtime-core | primitive::_::3cf11b… | _primitives/_rust/kei-runtime-core/Cargo.toml | 10186e32 | -| kei-runtime::kei-runtime | primitive::_::4d8427… | _primitives/_rust/kei-runtime/Cargo.toml | 4b3abe12 | +| kei-runtime::kei-runtime | primitive::_::4d8427… | _primitives/_rust/kei-runtime/Cargo.toml | 5fcf7642 | | kei-sage::kei-sage | primitive::_::176fa2… | _primitives/_rust/kei-sage/Cargo.toml | df35dc55 | | kei-scheduler::kei-scheduler | primitive::_::2b15c6… | _primitives/_rust/kei-scheduler/Cargo.toml | ef89066d | | kei-search-core::kei-search-core | primitive::_::bd14ad… | _primitives/_rust/kei-search-core/Cargo.toml | ff60e666 | @@ -1117,13 +1117,13 @@ Sorted alphabetically by name. - `STACK — Python ML (PyTorch / JAX)` — 2 versions: ceb1fc98 → 4afd934a - `Schema-Design — Relational Schema & Migration Pipeline (index)` — 2 versions: 06a0f2c0 → 8d662c40 - `Self-Audit — Session Retrospective Triage (index)` — 3 versions: 339cb507 → 38fd80b7 → 44427a22 -- `Sleep On It — Incubation Wizard (index)` — 2 versions: c62ae34a → e1553680 +- `Sleep On It — Incubation Wizard (index)` — 3 versions: c62ae34a → e1553680 → 5fc186c9 - `Sleep Setup — Cloud REM Sync Wizard (index)` — 2 versions: 470f7902 → d9877f2a - `Test Generation Workflow` — 2 versions: a3a67707 → 6c187beb - `agent-event-done` — 3 versions: ef70393c → 598bc917 → aa05dec9 - `agent-event-spawn` — 3 versions: b4573a30 → fb3603c7 → 1f32efc5 - `agent-heartbeat-tick` — 2 versions: 5eb00dc3 → 560fa0f8 -- `agent-outcome-backfill` — 2 versions: 0e00d9ca → c901aaf2 +- `agent-outcome-backfill` — 3 versions: 0e00d9ca → c901aaf2 → a11281aa - `agent-stub-scan` — 2 versions: 8a9fc155 → 4098a307 - `alignment-check` — 3 versions: 4e7389b1 → b1e18549 → 31600957 - `auditor` — 2 versions: 7eb6ab3a → 74d9689e @@ -1281,7 +1281,7 @@ Sorted alphabetically by name. - `kei-runtime` — 3 versions: 44b695ea → c19f68cf → b372ab7c - `kei-runtime-core` — 3 versions: 100eec0c → dedb3de0 → b9a37dea - `kei-runtime-core::kei-runtime-core` — 9 versions: 7980a704 → d64f3fbc → 9822303c → 80ad147f → ee80f871 → 663b5308 → 143c08b7 → ecfcc56c → 10186e32 -- `kei-runtime::kei-runtime` — 14 versions: e23e203b → 45e2bb3a → 93b703b3 → bd5a94ce → 15d85045 → 2aa2f1e3 → 2aa2f1e3 → 23f2ee6a → 37dc01f8 → bb9a2e8d → e013e322 → 70fd5389 → 67644265 → 4b3abe12 +- `kei-runtime::kei-runtime` — 15 versions: e23e203b → 45e2bb3a → 93b703b3 → bd5a94ce → 15d85045 → 2aa2f1e3 → 2aa2f1e3 → 23f2ee6a → 37dc01f8 → bb9a2e8d → e013e322 → 70fd5389 → 67644265 → 4b3abe12 → 5fcf7642 - `kei-sage` — 3 versions: 773af2fd → e7617e42 → 70873353 - `kei-sage::kei-sage` — 2 versions: df35dc55 → df35dc55 - `kei-scheduler` — 3 versions: 589d4c96 → b20fdba2 → f1f1ebf8 diff --git a/docs/PHILOSOPHY.md b/docs/PHILOSOPHY.md index 1f34827..14a283a 100644 --- a/docs/PHILOSOPHY.md +++ b/docs/PHILOSOPHY.md @@ -36,7 +36,7 @@ The rest of this document maps each property to the shipped code. ## 1. Identity — DNA -Every agent invocation resolves to a deterministic 80-character string: +Every agent invocation resolves to a deterministic variable-length string (≥33 chars; role + caps slugs are variable): ``` ::::::- diff --git a/docs/PROFILE-OUTCOME-ONLY.md b/docs/PROFILE-OUTCOME-ONLY.md index 4e820a7..6624608 100644 --- a/docs/PROFILE-OUTCOME-ONLY.md +++ b/docs/PROFILE-OUTCOME-ONLY.md @@ -81,7 +81,14 @@ recreates an empty schema, no other side effects. rm -f ~/.claude/hooks/agent-outcome-backfill.sh rm -f ~/.claude/hooks/error-spike-detector.sh rm -f ~/.claude/agents/ledger.sqlite -sed -i.bak '/outcome-only profile (KeiSeiKit)/,+1 d' ~/.claude/CLAUDE.md +rm -f ~/.claude/memory/time-metrics/agent-toolstats.jsonl +# CLAUDE.md cleanup — portable across BSD (macOS) and GNU sed via awk. +# The original line `sed -i.bak '/.../,+1 d'` used the GNU `,+N` address +# extension which BSD sed does NOT support; on macOS it silently no-ops, +# leaving an orphan instruction. The awk recipe below works on both. +awk 'BEGIN{skip=0} // {skip=2; next} skip>0 {skip--; next} {print}' \ + ~/.claude/CLAUDE.md > ~/.claude/CLAUDE.md.tmp \ + && mv ~/.claude/CLAUDE.md.tmp ~/.claude/CLAUDE.md ``` Both hooks exit 0 immediately when their target script is missing, so @@ -89,6 +96,10 @@ the `~/.claude/settings.json` jq-merge entries are harmless after `rm`. To scrub those too, drop `agent-outcome-backfill.sh` / `error-spike-detector.sh` lines from `settings.json` by hand. +The 5th `rm` removes the sidecar telemetry JSONL the backfill hook +writes (per-agent token counts + tool stats; local-only, no network +egress, but worth deleting if you uninstalled for privacy reasons). + ## Why this profile exists A kit with 100 crates / Forgejo / launchd plists is too heavy to diff --git a/docs/encyclopedia/substrate-overview.md b/docs/encyclopedia/substrate-overview.md index 08bcbea..9ac6f70 100644 --- a/docs/encyclopedia/substrate-overview.md +++ b/docs/encyclopedia/substrate-overview.md @@ -187,11 +187,11 @@ KeiSeiKit is a **multi-tier agent composition substrate** built on four mutually | Package | Version | Purpose | Key Dependencies | Build Target | |---------|---------|---------|------------------|--------------| | **@keisei/mcp-server** | 0.14.0 | MCP server exposing KeiSeiKit Rust primitives as tools | @modelcontextprotocol/sdk ^1.0.0, execa ^9.0.0, zod ^3.23.0 | Node.js ≥18.0.0; native binaries via bun compile (darwin/linux/windows) | -| **@keisei/gmail-adapter** | 0.5.2 | Gmail API integration for email-based task intake | @google-cloud/gmail ^1.3.0, nodemailer-mock ^2.0.0 | Node.js ≥18.0.0 | -| **@keisei/grok-adapter** | 0.3.1 | Grok (xAI) LLM provider bridge | openai-compatible ^1.0.0 | Node.js ≥18.0.0 | -| **@keisei/telegram-adapter** | 0.6.0 | Telegram Bot API integration for notifications + input | telegram-typings ^4.10.0, node-telegram-bot-api ^0.65.0 | Node.js ≥18.0.0 | -| **@keisei/recall-adapter** | 0.2.1 | Recall.ai (browser automation) integration | recall-ai-sdk ^1.0.0 | Node.js ≥18.0.0; browser environment recommended | -| **@keisei/youtube-adapter** | 0.1.8 | YouTube API integration for video transcript + metadata | googleapis ^118.0.0 | Node.js ≥18.0.0 | +| **@keisei/gmail-adapter** | 0.14.0 | Gmail API integration for email-based task intake | googleapis ^144.0.0, zod ^3.23.0 | Node.js ≥18.0.0 | +| **@keisei/grok-adapter** | 0.14.0 | Grok (xAI) LLM provider bridge | zod ^3.23.0 (uses fetch directly, no SDK) | Node.js ≥18.0.0 | +| **@keisei/telegram-adapter** | 0.14.0 | Telegram Bot API integration for notifications + input | grammy ^1.28.0, zod ^3.23.0 | Node.js ≥18.0.0 | +| **@keisei/recall-adapter** | 0.14.0 | Recall.ai (browser automation) integration | zod ^3.23.0 (uses fetch directly, no SDK) | Node.js ≥18.0.0 | +| **@keisei/youtube-adapter** | 0.14.0 | YouTube API integration for video transcript + metadata | googleapis ^144.0.0, youtube-transcript ^1.2.1, zod ^3.23.0 | Node.js ≥18.0.0 | **Notes:** - All packages scoped under `@keisei/` on npm (published to keigit.com npm registry) diff --git a/hooks/agent-outcome-backfill.sh b/hooks/agent-outcome-backfill.sh index b0d4482..58367bc 100755 --- a/hooks/agent-outcome-backfill.sh +++ b/hooks/agent-outcome-backfill.sh @@ -106,8 +106,17 @@ STUBS=$(printf '%s' "$RESPONSE" \ # Idempotent UPDATE. Failure (locked DB, no row, etc.) → advisory only, # never blocks the originating tool call. +# +# Audit fix 2026-05-03 (RULE 0.4 / SQLi): TOOL_USE_ID is unsanitised JSON +# input (potential `'` injection); SHIPPED is allowlist-validated above +# but defensive escape costs nothing. Replace single-quote with two +# single-quotes (SQL-standard escape) for ALL string-context variables. +# STUBS is integer-validated by `grep -oE '[0-9]+'` — already safe. +_sql_esc() { printf "%s" "$1" | sed "s/'/''/g"; } +SHIPPED_ESC=$(_sql_esc "$SHIPPED") +TOOL_USE_ID_ESC=$(_sql_esc "$TOOL_USE_ID") sqlite3 "$DB" \ - "UPDATE agents SET outcome='$SHIPPED', stubs_count=$STUBS WHERE id='$TOOL_USE_ID';" \ + "UPDATE agents SET outcome='$SHIPPED_ESC', stubs_count=$STUBS WHERE id='$TOOL_USE_ID_ESC';" \ 2>/dev/null || { printf '[agent-outcome-backfill] UPDATE failed for id=%s\n' "$TOOL_USE_ID" >&2 exit 0 diff --git a/install/lib-profile-outcome-only.sh b/install/lib-profile-outcome-only.sh index db50971..24832b8 100644 --- a/install/lib-profile-outcome-only.sh +++ b/install/lib-profile-outcome-only.sh @@ -133,8 +133,17 @@ install_profile_outcome_only() { cp -f "$snippet" "$HOME_DIR/.claude/settings.json" \ && say "created settings.json from outcome-only snippet" else - backup_file "$HOME_DIR/.claude/settings.json" - _jq_merge_hooks "$snippet" "$HOME_DIR/.claude/settings.json" || true + # Audit fix 2026-05-03: backup_file MOVES the target. We need the file + # still in place for jq to read during merge — copy aside instead so + # _jq_merge_hooks reads the original. The trap-pair entry registered + # by backup_file restores on rollback if the merge fails. + cp -p "$HOME_DIR/.claude/settings.json" \ + "$HOME_DIR/.claude/settings.json.bak-$(date +%s)" + if ! _jq_merge_hooks "$snippet" "$HOME_DIR/.claude/settings.json"; then + err "settings.json merge failed; the .bak file remains as recovery" + rm -f "$snippet" + return 1 + fi fi rm -f "$snippet" say "outcome-only profile installed." diff --git a/install/sql/outcome-only-schema.sql b/install/sql/outcome-only-schema.sql index 44d9698..cd7e200 100644 --- a/install/sql/outcome-only-schema.sql +++ b/install/sql/outcome-only-schema.sql @@ -66,4 +66,10 @@ CREATE INDEX IF NOT EXISTS idx_skill_invocations_name_ts CREATE INDEX IF NOT EXISTS idx_skill_invocations_success ON skill_invocations(skill_name, success); +-- Audit fix 2026-05-03: bump user_version to 9 so a later `kei-ledger init` +-- short-circuits via the `current >= 9` gate instead of replaying v1..v9 +-- migrations whose ALTER TABLE ADD COLUMN steps would error with "duplicate +-- column" against the already-flat schema this file installed. +PRAGMA user_version = 9; + COMMIT; diff --git a/skills/sleep-on-it/SKILL.md b/skills/sleep-on-it/SKILL.md index d84ba60..57640d0 100644 --- a/skills/sleep-on-it/SKILL.md +++ b/skills/sleep-on-it/SKILL.md @@ -12,8 +12,11 @@ argument-hint: (no arguments) - Queuing up to 5 tasks per night (15 min each) to be processed before the REM consolidation pass. - Requires v0.11 sleep-sync already configured; use `/sleep-setup` first if not. -Biological analog: the REM-sleep "sleep on it" effect — insight generation -during incubation (Wagner et al. 2004, *Nature*). During the day the user +Biological analog: the "sleep on it" insight effect documented by +Wagner et al. 2004, *Nature* 427:352–355 +[VERIFIED: doi:10.1038/nature02223] (the original paper showed insight +gain after a sleep period that included slow-wave sleep, not strictly +REM; our metaphor is a loose mapping). During the day the user submits open questions, research tasks, or design comparisons via this wizard; the nightly cloud agent processes the queue before its existing REM consolidation pass and writes results to `sync-repo/sleep-results/`.