Commit graph

33 commits

Author SHA1 Message Date
Parfii-bot
9622d41bb6 refactor(wave17): cleanup — kei-shared SSoT + MEDIUM audit residuals + docs drift
47 crates, 771 tests green (up from 753 at v0.33.0). Zero new
features — pure hygiene.

## kei-shared extract (SSoT for DNA format)

New crate `kei-shared` consolidates DNA-parse logic that was duplicated
across kei-agent-runtime + kei-dna-index. Both consumers migrated to
import ParsedDna / parse_dna / is_hex8 from kei_shared.

- 12 tests (10 integration + 2 unit)
- kei-dna-index LOC reduction: -60 in parsed.rs (body replaced by wrapper)
- kei-agent-runtime preserves lenient DnaError (legacy 4-hex parse path)
- Format-string SSoT: kei_shared::compose_dna is sole source

## MEDIUM audit residuals closed (kei-entity-store)

A. DDL panic coverage — verified exhaustive match across all 12
   FieldKind variants; new test ddl_never_panics_on_any_fieldkind
   compile-time-breaks if a variant added without test update.
B. Update FTS reindex invariant — doc + new update_invariant.rs module
   with debug_assert validating non-input FTS columns don't drift
   pre/post UPDATE. Zero release-mode cost (cfg-gated).
C. WAL fallback — wal_pragma_fallback_keeps_store_usable test (cfg(unix))
   verifies read-only-parent dir doesn't brick Store::open.
D. Search Unicode edge cases — 4 new tests (punctuation, emoji,
   zero-width, mixed RTL). has_searchable_token already correct, no
   source change needed; tests pin current behavior.

Added: residual_audit_smoke.rs (8 tests), update_invariant.rs module.
kei-entity-store: 57 → 65 tests.

## Docs drift fixed (count claims → reality)

- README.md: "36 crates → 47 crates", "500+ tests → 800+ tests"
- PLUGIN.md, docs/INSTALL.md, docs/REFERENCE.md, docs/SUBSTRATE-SCHEMA.md
  all synced to real counts.
- CHANGELOG.md: 6 new version blocks (v0.28 → v0.33) consolidated
  in existing style.
- Historical snapshots (HANDOFF-WAKE v0.29, CONVERGENCE-PLAN, etc)
  deliberately preserved — they're version-scoped, not drift.

## Known deviation from task spec

kei-shared's [workspace] table was dropped (Cargo rejected "multiple
workspace roots" when parent workspace pulls via path dep). Crate
registered in workspace.members instead. Verified cargo check + test
clean in both modes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 20:34:43 +08:00
Parfii-bot
47317ab708 docs: refresh HANDOFF-WAKE for v0.29.0 (Wave 13 shipped)
- Real crate count: 39 (was claimed 18 pre-audit; README agent caught it)
- 620 tests green (up from 538 at v0.28)
- Wave 13 entry added with 3 primitives + 2 HIGH fixes

Known follow-ups for v0.29.1:
- HttpDriver re-run (worktree lost mid-session)
- agent_id path-traversal validator re-run (worktree lost mid-session)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 15:56:31 +08:00
Parfii-bot
f2358397c9 docs: README bio-framing + PHILOSOPHY + security hardening
- README rewritten with bioinspired framing: KeiSeiKit as living
  neural structure of Kei (DNA / REM / Deep Sleep / creator lineage).
  All counts verified against source: 36 crates, 12 agents, 43 skills,
  12 hooks, 82 blocks.

- docs/PHILOSOPHY.md new 11.4 KB deep-dive on the substrate
  thesis, the 4-layer architecture, and roadmap (federation / signing
  / marketplace / visualization as Wave 14+).

- .gitignore hardened: .env, secrets/, *.pem, *.key, id_rsa*,
  id_ed25519*, .claude/secrets/ — public-repo safe. .env.example
  and .env.template re-included.

- docs/SECURITY.md: secret hygiene section with revoke-and-rotate
  protocol + canonical ~/.claude/secrets/.env reference (RULE 0.8).

Verified clean: defensive grep for sk-ant-, ghp_, private keys,
token/key assignments = zero hits across tree.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 15:44:52 +08:00
Parfii-bot
700d8143ea docs: refresh HANDOFF-WAKE for v0.28.0 (wave 12 shipped)
- 6 tags summary (v0.23 → v0.28)
- 538 tests, 18 crates, 12/12 agents substrate-native
- Wave 11 + Wave 12 closure noted
- 2 open follow-ups: HttpDriver + Wave 13 scaffolds
- Security note on mid-session API key leak

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 15:16:39 +08:00
Parfii-bot
5113c35914 docs(w12b): refresh counts across README / INSTALL / REFERENCE after v0.23-v0.27
9 stale count references updated:
- README.md: 12 agents / 43 skills / 12 hooks / 82 blocks / 36 primitives
- docs/INSTALL.md: 33→36 (full profile), new crates enumerated
- docs/REFERENCE.md: 25→36 crates, 10→12 hooks, 39→43 skills; v0.27
  note on 11 crates awaiting full per-crate REFERENCE entries
- docs/ARCHITECTURE.md: 10→12 hooks (added capability hooks)
- docs/SUBSTRATE-SCHEMA.md: 25→36 crates (count-only refresh, locked)
- docs/SECURITY.md: battle matrix floors 79/39/10 → 82/43/12
- PLUGIN.md: 24→36 Rust primitives

NOT modified (intentional):
- CHANGELOG.md (auto-generated by kei-changelog)
- docs/WHY.md (stable philosophy)
- docs/TAXONOMY.md (vocab stable)
- docs/HANDOFF-WAKE.md (historical snapshot, frozen by design)
- docs/CONVERGENCE-PLAN.md (strategy analysis, frozen)
- docs/AGENT-SUBSTRATE-SCHEMA.md (phase plan counts are plan-of-record,
  not current state)
- SCHEMA-LOCKED.md / SCHEMA-UNLOCKED.md / AGENT-ROLES.md (registry)
- USB-BRAIN-GUIDE-* (platform guides, no counts)

Follow-up flagged: REFERENCE.md needs per-crate expansion for 11 new
crates (kei-agent-runtime, kei-capability, kei-provision, etc). That's
doc rewrite not audit — separate PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 14:44:31 +08:00
Parfii-bot
ca8833b582 feat(p-install): register 8 new crates in MANIFEST.toml + profile selection
Added [primitive.*] entries for kei-agent-runtime, kei-capability,
kei-provision, kei-entity-store, kei-pipe, kei-cache, kei-spawn,
kei-replay. Profile memberships:
- ops: +kei-provision (total 9)
- dev: +7 substrate+automation primitives (total 17)
- full: +8 (total 46)

docs/INSTALL.md + README.md updated with new counts.

Not registered (lib-only, no main.rs): kei-atom-discovery.
Flag for follow-up: kei-forge + kei-runtime are in workspace but not
in MANIFEST (were before my scope). regen-counts.sh will soft-warn.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 14:26:11 +08:00
Parfii-bot
ddea993385 docs: final HANDOFF-WAKE for v0.26.0 — 4 tags overnight, 1 remaining architectural decision
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 14:09:26 +08:00
Parfii-bot
c212da8fe7 feat(w10c): migrate remaining 7 non-core agents to substrate_role
All 12 kit-shipped agents now declare substrate_role:
- 7 read-only: kei-cost-guardian, kei-ml-researcher, kei-researcher,
  kei-critic, kei-architect, kei-security-auditor, kei-validator
- 5 edit-local: kei-modal-runner, kei-fal-ai-runner, kei-infra-implementer,
  kei-ml-implementer, kei-code-implementer

Assembler regenerated 7 new .md files with # AGENT SUBSTRATE — role header.
docs/AGENT-ROLES.md: 12-row table + maintenance note.
substrate_integration.sh: migrated floor 5 → 12.
assembler tests (non_migrated) adjusted to strip substrate_role from
temp kit copy since all shipped manifests are now migrated.

cargo test agent-assembler: 47/47 (was 40, +7 regenerate tests).
cargo check --workspace: PASS.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 13:59:06 +08:00
Parfii-bot
78f241dbfc docs: update HANDOFF-WAKE for v0.25.0 landing
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 13:48:44 +08:00
Parfii-bot
e0e6e1720d docs: HANDOFF-WAKE summary of autonomous Wave 8
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 12:19:07 +08:00
Parfii-bot
948f07bfa8 Merge E2 — kei-capability fork subcommand 2026-04-23 10:22:38 +08:00
Parfii-bot
6e7e517f83 feat(e2): kei-capability fork subcommand + lineage stamping
New 'fork' subcommand copies capability dir + rewrites capability.toml
with [lineage].fork_from + parents + creator + created. Refuses
clobber, validates slug regex.

Tests: 4 integration + 2 unit (epoch_to_iso, split_cap_name) = 6/6.

Doc update in AGENT-SUBSTRATE-SCHEMA.md §Orchestrator ergonomics.

Zero-chrono ISO-8601 via Hinnant's algorithm (single-file).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 10:21:45 +08:00
Parfii-bot
e418f1247c feat(tx1): taxonomy + lineage facets schema extension
Optional [taxonomy] + [lineage] TOML sections on capability.toml and
atom .md frontmatter. Backward-compat — all fields optional, existing
files parse unchanged.

TaxonomyFacets struct (7 facets): kingdom, mechanism, domain, layer,
stage, stability, language.
Lineage struct: parents[], creator, created, fork_from.

AtomMeta extended with taxonomy: Option<TaxonomyFacets> + lineage:
Option<Lineage>.

docs/TAXONOMY.md — canonical vocabulary. Graph-based (DAG with typed
edges), not tree. Multi-faceted nodes allowed.

3 pilot primitives tagged: policy::no-git-ops, quality::cargo-check-green,
tools::bash-allowlist.

Tests: 16/16 (was 12, +4: full/partial/no-facets/parents-array).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 06:10:58 +08:00
Parfii-bot
84319efcb6 feat(convergence/p3): Role expression (extends/relaxes) + DNA identity
Layer E + G. Role TOML gains extends/relaxes for parent-role
composition; agent spawn gets self-describing DNA identity alongside
UUID.

Role expression:
- _roles/*.toml gain optional `extends = "<parent>"` + `relaxes = [...]`
- compose.rs + verify.rs delegate to new role::resolve_role() with
  recursive extends-chain resolution + cycle detection
- explorer.toml: 28→18 LOC (extends read-only)
- edit-shared.toml: 31→23 LOC (extends edit-local, relaxes
  scope::files-whitelist for task-param override)

DNA identity:
- new dna.rs (159 LOC) — compose/render/parse round-trip
- AgentInvocation carries dna field (prepare.rs)
- Format: <role>::<caps-bitmap>::<sha4-scope>::<sha4-body>-<hex4-nonce>
- ≤ 80 chars total, greppable, parseable
- 11 capability codes in CAP_CODES table: NG, FW, FD, CP, CG, TG, ND,
  RF, SG, DT, BA

kei-ledger schema v2:
- ADD COLUMN dna TEXT + prefix index
- `kei-ledger fork --dna <string>` optional flag
- AgentRow.dna: Option<String>
- Backward compat: schema migration detects + applies on open

Docs: AGENT-SUBSTRATE-SCHEMA.md Layer E + Layer G sections + CAP_CODES table.

New deps: sha2 (workspace), rand 0.8.

Tests: kei-agent-runtime 50 (was 41, +9: 4 role + 5 DNA), kei-ledger
10 (was 9, +1 DNA roundtrip).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 04:46:48 +08:00
Parfii-bot
c3537f9dd4 docs(schema): REVOKE both schema locks — calendar weeks ≠ actual velocity
Both atom substrate (6-week lock) and agent substrate (3-week lock) were
calibrated for calendar windows that were 30-100× slower than actual
execution. Phases shipped in hours, not weeks. Keeping calendar locks
delays breaking consolidations that can safely ship now.

Unlocks: verb templates, schema fragments, PatternGate, CommandVerify,
role expression, DNA identity — all can ship as breaking changes with
standard review gate (audit + integration tests).

No more calendar-week locks. Future locks: agent-hours or
"until declared phases land."

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 04:31:20 +08:00
Parfii-bot
4658297232 Merge feat/convergence-u3-provision — unify hetzner+vultr into Rust crate 2026-04-23 03:43:51 +08:00
Parfii-bot
64ffe39e01 feat(convergence/u3): kei-provision Rust crate — unify hetzner+vultr provisioners
Pre-unlock wave U3 (highest-ROI). Task 7 from CONVERGENCE-PLAN —
consolidate 2 provision-*.sh scripts into Rust via Backend trait.

Old shells (provision-hetzner.sh, provision-vultr.sh) had identical
6-subcommand surface (create|status|destroy|list), log/die/check_deps
helpers, idempotency contract. Sole delta: hcloud vs vultr-cli. RULE 0.2
says Rust-first when >50 LOC + growth expected.

New crate _primitives/_rust/kei-provision/:
- src/backend.rs (58 LOC) — Backend trait: create/status/destroy/list;
  CreateOpts and ServerInfo structs
- src/backends/hetzner.rs (143 LOC) — shells to `hcloud server ...`
  --output=json, parses JSON response, honors HCLOUD_TOKEN env (RULE 0.8)
- src/backends/vultr.rs (189 LOC) — same pattern, `vultr-cli instance`,
  honors VULTR_API_KEY env
- src/exec.rs (100 LOC) — Command runner + PATH-aware env preservation
- src/b64.rs (49 LOC) — minimal user-data base64 encoder; zero
  transitive deps
- src/main.rs (141 LOC) — clap CLI `kei-provision <backend> <cmd>`
- tests/backend_smoke.rs (184 LOC) — tempdir PATH-inject fake hcloud +
  fake vultr-cli, no real cloud. Mutex-serialized (Rust test parallelism).

Tests: 11/11 (3 b64 unit + 8 backend_smoke integration). Coverage:
hetzner status present/absent/list, vultr status found/absent/destroy
idempotent, unknown-backend error, CreateOpts default.

Old shells kept with superseded-v0.17 header — install.sh still copies
them, legacy scripts still work. New users get kei-provision binary.
harden-base.sh untouched (different lifecycle — runs on target VPS).

Backend trait factored to accept aws/doctl/linode follow-ups without
re-architecture.

Workspace Cargo.toml: +kei-provision member (1 line).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 03:43:40 +08:00
Parfii-bot
e4b64418fc feat(convergence/u2): capability renames + back-compat aliases
Pre-unlock wave U2. Task 3 from CONVERGENCE-PLAN — rename misleading
capability names, keep old names as deprecated aliases.

Renames:
- tools::read-only → tools::deny-tools (mechanism is tool-name denial,
  not "read-only" metaphor)
- tools::cargo-only-bash → tools::bash-allowlist (mechanism is Bash
  pattern allow-list; cargo-only is one config value)

Back-compat via registry.resolve_alias():
- Old dir _capabilities/tools/{read-only,cargo-only-bash}/ retained with
  capability.toml-only stub: `alias = "<new-name>"` + `deprecated` field
- registry.rs loads alias stubs, redirects lookup before dispatch
- warn_deprecated_once() emits single-shot stderr per alias per process
  via OnceLock<Mutex<HashSet>>
- Zero breaking change to existing manifests / task.toml referencing
  old names

Rust impl files renamed in place:
- gates/tools_read_only.rs → gates/tools_deny_tools.rs (struct
  DenyTools)
- gates/tools_cargo_only_bash.rs → gates/tools_bash_allowlist.rs
  (struct BashAllowlist)
- gates/mod.rs + registry.rs + gate_smoke.rs updated

Roles updated (3): read-only.toml, explorer.toml, edit-local.toml —
reference new names directly.

Tests: kei-agent-runtime 41/41 (was 40, +1 deprecated_aliases_resolve
_to_new_names), _assembler 40/40 unchanged (substrate role expansion
follows new paths).

Docs updated: AGENT-ROLES.md, AGENT-SUBSTRATE-SCHEMA.md, 4 _manifests
referencing the old names (comment-only annotations).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 03:43:40 +08:00
Parfii-bot
0b47616b06 docs(convergence): synthesis of 2 audit waves — 75 → ~52 primitives plan
User hypothesis: "if substrate is right, primitives converge, not expand".
Directional yes, magnitude calibrated below initial guess (75→35).
Reality: 75 → ~52 (−31%) across atoms + capabilities + skills.

Atoms (25 → 15-17):
- 6 SQLite-CRUD → 1 kei-entity-store + 6 plugins (piggyback Stream B)
- 3 provisioners → 1 kei-provision <backend> (harden-base stays)
- 4 frontend → meta-dispatcher shim

Capabilities (11 → 7):
- scope::files-{whitelist,denylist} → scope::path-filter (post-unlock)
- quality::cargo-{check,tests}-green → quality::cargo-green (post-unlock)
- Kept separate (justified): output::*, tools::*, policy::*
- Rename cargo-only-bash → bash-allowlist (pre-unlock, non-breaking)

Skills (39 → ~28):
- /audit <target> + checklists registry (6 skills → 1 + 6 data files)
- Deprecate /site-builder, /competitor-analysis, /design-inspiration
- Add /animate gateway (keep 4 motion-family skills underneath)
- Setup pipelines (ci/auth/obs/docs/schema) stay separate — domain-disjoint

Three techniques catalogued:
1. Verb parameterization (>50% LOC overlap)
2. Block extraction (shared preamble, different body)
3. Subset deprecation (one is proper subset of another)

Execution 3-phase:
- Pre-unlock (ship NOW): 7 tasks, ~3 days parallel — block extraction +
  renames + deprecations + provisioner unification
- Mid-cycle (parallel Stream B): 2-3 days — entity-store engine
- Post-unlock (after 2026-06-03): 4 tasks, ~5-6 days — schema amendments

Honest gaps from both audits:
- 4 of 10 LBM-port crates not enumerated (follow-up)
- _capabilities/*.md not directly read by critic (manifest-inferred)
- LOC estimates ±20%
- Both audits E2-E4, not E1 (which requires running the consolidation)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 03:28:39 +08:00
Parfii-bot
d72ae51f16 feat(agent-substrate/wrapper): kei-agent-runtime prepare — orchestrator ergonomics
Single-command "prepare spawn" that emits everything orchestrator needs
to invoke the Agent tool: composed prompt, subagent_type (from role's
new claude-subagent-type field), isolation mode, verify command,
ledger row.

Before this: orchestrator ran compose + read prompt + manually
constructed Agent tool call + manually built verify command. 4 steps.

After: `kei-agent-runtime prepare <task.toml> --format=human` outputs
a single copy-paste-ready block. Orchestrator pastes into Agent tool
and records the verify command for return.

Files:
- src/prepare.rs (170 LOC) — prepare() returns AgentInvocation struct
  (agent_id, prompt, subagent_type, isolation, description,
  verify_command, ledger_row)
- src/main.rs (+39 LOC) — Prepare subcommand with --format=human|json|toml
- src/lib.rs (+2 LOC — pub mod prepare)
- _roles/*.toml (5 files) — new optional claude-subagent-type field:
  - edit-local / edit-shared → "code-implementer"
  - read-only → "critic" (default; "architect" override possible)
  - explorer → "Explore"
  - git-ops → "NOT-SPAWNABLE" (refused by prepare with RULE 0.13)
- tests/prepare_smoke.rs (3 tests) — happy path, unknown role, non-spawnable refusal
- docs/AGENT-SUBSTRATE-SCHEMA.md (+ ## Orchestrator ergonomics section)

Tests: 40/40 (was 37, +3 prepare_smoke). Same path exercised in tempfile
fixtures that the real CLI would hit end-to-end.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 03:25:14 +08:00
Parfii-bot
329d7e2a4d feat(agent-substrate/phase-5): migrate 5 kit agents to role+task-spec — substrate v1 FULL
Final phase of agent substrate v1. 5 shipped agents now declare role at
manifest level; assembler expands role's capability text fragments into
the generated .md at a new `# AGENT SUBSTRATE — role <name>` section.
Non-migrated agents byte-identical (golden snapshots green).

Migrated agents:
- kei-code-implementer → edit-local (8 caps: no-git-ops + scope/* +
  quality/* + safety::no-dep-bump + report-format)
- kei-critic → read-only (tools::read-only + output::report-format +
  output::severity-grade)
- kei-architect → read-only
- kei-security-auditor → read-only
- kei-validator → read-only

_assembler/ extensions:
- manifest.rs: substrate_role: Option<String>
- assembler.rs: write_substrate() before blocks (backward-compat; no
  role = no substrate section)
- substrate.rs (new, 102 LOC): loads _roles/<name>.toml, iterates
  capabilities.required, reads _capabilities/<cat>/<slug>/text.md,
  joins with \n\n---\n\n separator
- validator.rs: substrate role existence + cap-text presence check
- tests/substrate_role.rs (4 tests): happy path, unknown role, missing
  capability text, byte-parity on non-migrated
- tests/regenerate_migrated.rs (ignored by default): regeneration gate

_templates/task-examples/ — 5 example task.toml per migrated agent
showing orchestrator the valid invocation shape.

docs/AGENT-SUBSTRATE-SCHEMA.md: Phase 5 row ticked ✓ + Migrated agents
subsection listing 5 agents with roles + pointer to examples.

tests/substrate_integration.sh: +8 Phase-5 assertions
- All 5 migrated .md files contain "# AGENT SUBSTRATE — role"
- kei-code-implementer.md contains "MUST NOT invoke git" (policy::no-git-ops)
- Every _templates/task-examples/*.toml parses as valid TOML
- cargo check --workspace still passes post-migration
- kei-agent-runtime compose works on edit-local-forge.toml example

Tests: assembler 40/40 (was 30, +4 substrate_role + +1 ignored regen),
kei-agent-runtime + kei-capability 37/37 preserved.

Deferred: remaining 7 non-core agents (cost-guardian, modal-runner,
fal-ai-runner, infra/ml-implementer, ml-researcher, researcher) migrate
in v0.24 wave.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 03:07:18 +08:00
Parfii-bot
aa8333ccda feat(agent-substrate/phase-4): hook wiring — 3-line glue for kei-capability
PreToolUse hooks route through kei-capability check when orchestrator
registers a capability via KEI_CAPABILITY_NAME env var on agent spawn.

hooks/agent-capability-check.sh (22 LOC):
- Pass-through (exit 0) when KEI_CAPABILITY_NAME unset — no-op by default
- Fail-open (exit 0) when kei-capability binary missing — kit convention
- Sources _lib/gate.sh for KEI_DISABLED_HOOKS / KEI_HOOK_PROFILE respect
- exec kei-capability check "$CAP_NAME" when active

hooks/agent-capability-verify.sh (24 LOC):
- Orchestrator-driven, NOT a Claude Code native hook
- Carries env: AGENT_ID, TASK_TOML, WORKTREE_PATH, MAIN_REPO, RUN_MODE
- exec kei-capability verify "$CAP_NAME"

Registered in hooks/hooks.json + settings-snippet.json under both
PreToolUse:Bash and PreToolUse:Edit|Write matchers. Internal NotApplicable
returns exit 0 so non-matching tool calls cost nothing.

install.sh unchanged — hooks/*.sh glob picks up both new files.

tests/hook_wiring_integration.sh (64 LOC) — 3 contract assertions:
  (1) pass-through on unset KEI_CAPABILITY_NAME
  (2) deny+exit 2 on git-op pattern
  (3) allow+exit 0 on cargo-check pattern

Multi-capability routing (for phase 5): KEI_CAPABILITY_NAME currently
holds ONE name. When a role requires N capabilities, orchestrator will
either iterate or kei-capability gains a compose subcommand. Design
note left for phase 5.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 02:51:10 +08:00
Parfii-bot
dc83cb2117 feat(agent-substrate/phase-2): role matrix — 5 roles + AGENT-ROLES.md
5 _roles/*.toml per locked §Initial role inventory:

- read-only     → tools::read-only + output::report-format + severity-grade
- explorer      → read-only caps + tools::cargo-only-bash
- edit-local    → no-git-ops + scope::files-{white,deny}list + quality::*
                  + safety::no-dep-bump + output::report-format
- edit-shared   → edit-local caps + relaxed SSoT whitelist (task-time param)
                  + escalation tightened to orchestrator-notify
- git-ops       → spawnable = false, documentation-only

All 11 capability names referenced match phase-1 deliverable path
_capabilities/<cat>/<slug>/ (cross-ref verified before commit).

docs/AGENT-ROLES.md (223 LOC) — human-readable matrix: per-role sections
+ cross-role capability matrix + explicit non-spawnable-git-ops block.

Drift note for orchestrator integration review: edit-local/edit-shared
use inline bash-patterns-allowed = ['^cargo( |$)', '^mkdir( |$)',
'^rm -rf /tmp/'] instead of composing with tools::cargo-only-bash
capability (extra patterns not in that atom). Agent footnoted —
resolution deferred to post-integration (either parameterize the cap
or introduce tools::cargo-plus-basic-bash variant).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 02:35:52 +08:00
Parfii-bot
a25c282dca feat(agent-substrate): LOCK schema — 8 decisions resolved, 3-phase parallel window opens
Resolved per user review 2026-04-23:

- Layout: declarative (capability.toml + text.md) + Rust modules in
  kei-agent-runtime (not 3 bash files — user pushed for Rust)
- Gate: Rust via kei-capability binary, shell hook = 3-line exec glue
- Verify: Rust same binary, subcommand verify
- Config: TOML (user asked discount between TOML vs YAML — explained
  type-safety + Cargo-native parsing wins)
- Capability ID: :: separator (confirmed)
- Nested path layout
- 200 words/capability text cap
- Verify: worktree short-circuit → simulated-merge (catches
  E1-jsonschema-class integration regressions before main merge)

Phase 3 revised up from 3-4 days to 5-6 due to Rust gate/verify logic
+ simulated-merge executor. Offset by phase 4 dropping from 1 day to
0.5 (shell hooks now thin glue).

3 phases parallelizable immediately after this lock:
- Phase 1: 20 declarative files (capability.toml + text.md × 10)
- Phase 2: 5 role TOML + docs/AGENT-ROLES.md
- Phase 3: kei-agent-runtime + kei-capability binaries + 14 Rust capability modules

Phase 4 + 5 sequential after.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 02:05:21 +08:00
Parfii-bot
372bbc8320 docs(agent-substrate): v1 schema DRAFT — capability triplet + role + task spec + runtime contract
Sibling SSoT to SUBSTRATE-SCHEMA.md (atom substrate). This one decomposes
agent invocations rather than code primitives.

Core contribution — the capability TRIPLET, not just text:
- text.md      — what agent reads (prompt fragment)
- gate.sh      — PreToolUse hook (runtime enforcement)
- verify.sh    — on-return predicate run from main repo (not worktree)

Motivation from substrate v1 orchestration audit:
- 40% prompt boilerplate across 7 spawns (git-ban + constructor-pattern +
  report format etc. copy-pasted each time)
- Self-reported green tests broke at integration (E1 jsonschema
  regression — agent claimed PASS from worktree but main workspace
  failed; caught only by integration test)
- Scope violations (E1 touched invoke.rs when E3 was supposed to own it;
  surfaced only at merge)

Triplet closes all three gaps: capabilities aren't promises agents make
in prose, they're enforced by gate hooks pre-exec and verified by
predicates on return from main branch clean state.

Schema specifies:
- Capability atom layout: _capabilities/<category>/<slug>/
- capability.toml frontmatter shape
- text.md / gate.sh / verify.sh contracts
- Role = bundle of capabilities (5 roles: read-only, explorer, edit-local,
  edit-shared, git-ops)
- task.toml shape (orchestrator-written per spawn; parameterizes roles)
- kei-agent-runtime crate contract: compose + spawn + verify + run
- Initial 10-capability inventory for phase 1
- 6-question decision log with defaults
- 5-phase parallel build plan (phases 1-4 parallel, ~5-7 days wall time)

Open questions flagged at bottom for review before AGENT-SCHEMA-LOCKED.md.

Once locked: sibling SSoTs (atoms + agents) evolve symmetrically — agents
compose atoms, atoms compose agents (ultimate goal).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 01:39:23 +08:00
Parfii-bot
f7e4725573 fix(substrate): amendment A-1 (input/output required all kinds) + integration test + jsonschema 0.18 relative-$id bug
Three post-E1/E2/E3-merge items:

1. Schema amendment A-1 (architect P0-a, non-breaking clarification):
   input.schema and output.schema are REQUIRED for all atom kinds. The
   shared kei-atom-discovery parses them as Option<PathBuf> only to allow
   tolerant skip-on-missing (stderr warn), not to permit absent schemas.
   Resolves Stream C / Stream D enforcement asymmetry documented in
   critic finding #6.

2. Cross-stream integration test (architect P0-b): tests/substrate_integration.sh
   builds release binaries, scaffolds a test atom corpus, runs
   schema-lint + list-atoms + atoms-discover + invoke; asserts all four
   streams agree on the same atom corpus and exit codes honour the
   locked §Runtime contract. Previously missing — only manual smoke
   checks existed.

3. Fix regression introduced by E1's jsonschema 0.18 upgrade:
   "relative URL without a base" on compile when schema declared a
   relative $id like "kei-task/atoms/schemas/create-input.json".
   validate.rs now synthesises an absolute file:// $id from the
   canonicalised schema path before compile. Internal $refs still
   resolve relative to the schema file; LocalFileResolver still confines
   to the schema's parent dir. Integration test catches this.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 00:56:27 +08:00
Parfii-bot
ae4f5b9813 feat(substrate): LOCK schema — 6-week parallel Stream A/B/C/D window opens
Schema at SUBSTRATE-SCHEMA.md (revised 2026-04-22) is immutable until
~2026-06-03 or explicit user revocation. 4 parallel streams may now
proceed independently against this contract.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 00:00:33 +08:00
Parfii-bot
559db303e1 feat(substrate): apply user decisions + ship atom template + generator
Schema revisions per user review 2026-04-22 (all 6 open questions resolved
— see §Decision log in SUBSTRATE-SCHEMA.md):

- #3 side_effects: string tags → structured { op, domain } objects (user:
  "лучше сразу с запасом")
- #4 capabilities.toml: DROPPED entirely (user: "почему не мд?"). SSoT is
  atoms/*.md. Crate-level metadata moves to Cargo.toml
  [package.metadata.keisei] — Cargo-native, no drift, no build.rs, no
  generated files to commit. kei-sage + kei-runtime walk atoms/*.md
  directly.
- #5 atom template: shipped in this PR (user: "ui же параллельно! создавай
  все!") so Streams B/C/D can scaffold atoms from day 0 without waiting
  for Stream A (kei-forge UI).
- #1/#2/#6 confirmed as drafted (draft-07, `::` separator, per-atom errors).

New files:

- _templates/atom/ — 5-file template set with placeholder substitution
  (__CRATE__, __VERB__, __KIND__, __DESCRIPTION__ etc). Covers
  atoms/<verb>.md, schemas/<verb>-{input,output}.json, src/atoms/<verb>.rs,
  tests/<verb>_smoke.rs. Each file is a minimal working skeleton.
- scripts/new-atom.sh — POSIX bash generator (bash for $'\n' / readonly /
  trap). Validates verb is lowercase kebab-case, kind is one of
  command|query|stream|transform. Refuses to overwrite existing files.
  Rolls back on any failure (trap ERR deletes all generated files so no
  half-scaffolded state). Tested: produces 5 files, placeholder
  substitution correct on smoke-test crate.

Stream B (atoms refactor) updated to drop the "generates capabilities.toml
via build.rs" wording — now just "writes atoms/*.md + updates Cargo.toml
[package.metadata.keisei]". Stream D reads atoms/*.md + Cargo.toml, not
capabilities.toml.

Schema status: revisions applied, decision log complete. Ready for
SCHEMA-LOCKED.md marker commit once user signs off on revised doc.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 23:53:26 +08:00
Parfii-bot
58944e15bd docs(substrate): v1 atom/capability/graph SSoT schema — DRAFT for review
Substrate thesis requires a single source of truth before parallel work
streams (UI/Atoms/Graph/Runtime) can proceed independently without drift.
This document is that SSoT.

Key decisions baked in (open to revision before lock):

- Atom = one verb on a primitive, not one crate. Target ~150 atoms
  across current 25 crates. Crate = physical container, atom = unit of
  composition.

- File layout: src/atoms/<verb>.rs (code) + atoms/<verb>.md (docs with
  machine-parseable YAML frontmatter) + atoms/schemas/*.json (JSON
  Schema draft-07 for input/output) + capabilities.toml (auto-generated
  aggregator, committed to repo).

- Atom kinds: command / query / stream / transform. Combined with
  side_effects[] and idempotent flag, runtime decides retry safety,
  parallelism, caching.

- Naming: <crate>::<verb> globally unique. Rust :: separator keeps it
  native-feeling.

- Versioning: atoms inherit crate SemVer. Breaking change to an atom =
  new atom (create-v2), old marked deprecated.

- Runtime contract: `kei-runtime invoke <atom-id> --input <json>` with
  schema validation at entry + exit, ledger row per invocation.

- Graph contract: kei-sage auto-walks atoms/*.md, resolves [[atom-id]]
  wikilinks, exposes rank / related / search / graph over atom corpus.

- UI contract: kei-forge web wizard generates .md + .json + .rs + test
  from form input; postcondition cargo check + kei-schema-lint pass.

Document declares 4 stream interfaces explicitly — each stream knows
what it reads from this schema, what it writes, what it does NOT depend
on from other streams. Enables true parallel work.

6 open questions flagged for user review at bottom:
1) JSON Schema draft-07 vs 2020-12
2) Atom ID separator :: vs /
3) side_effects strings vs structured
4) capabilities.toml committed vs gitignored
5) kei-atom-template in this PR or defer to Stream A
6) Error model per-atom vs shared registry

STATUS: DRAFT — awaits user approval + SCHEMA-LOCKED.md marker before
parallel streams start. Once locked, breaking changes require explicit
revocation + all-streams sync.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 23:39:24 +08:00
Parfii-bot
ce9ba61ee0 docs(readme): split 89 KB monolith into hero-pitch + 6 docs/ files
README down from 89 KB to 7.8 KB (11x reduction, target was 10-15 KB).
Visitor-facing README now loads in one screen — hero + 3 killer features
+ what-it-solves + quick install + docs index.

Extracted 6 new files under docs/:

- INSTALL.md (15 KB) — prerequisites, profiles, interactive install,
  MCP binary, keisei CLI intro, runtime hook controls, what-you-get table
- REFERENCE.md (35 KB) — every one of 25 Rust primitives + 13 shell
  primitives + 10 hooks + 39 skills with actual CLI surface (clap flags,
  exit codes, env vars, state paths), keisei CLI deep-dive, 12 pipelines
- ARCHITECTURE.md (11 KB) — build pipeline, creating-a-new-agent,
  adding custom blocks/manifests, agents overview, cross-tool bridges,
  meta-composer, regen counts, workflow-file editing protocol
- SLEEP-LAYER.md (11 KB) — three-phase nightly cycle diagram,
  session self-audit (RULE 0.14), Cloud REM sync, sleep-on-it incubation,
  deep-sleep NREM consolidation with 4-primitive pipeline + example
- SECURITY.md (7.6 KB) — threat surface table + 8 mitigations in detail
  (memory-repo privacy, secrets-guard patterns, supply-chain SHA pinning,
  S3 SSRF, brain path/name validation, exFAT warning, battle matrix)
- WHY.md (3.6 KB) — full 'From the author' manifesto restored from
  git history (pre-1f3aaca product pivot). Medium/dev.to-friendly for
  virality, separate from the product README

New docs cross-link each other + README has docs index in tail.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 22:20:22 +08:00
Parfii-bot
5993f32146 feat(v0.22): FS warn + battle-test matrix + USB docs platform split (Track C)
1. Filesystem type detection (architect P2 finding)
   _primitives/_rust/keisei/src/fs_type.rs (NEW, 103 LOC)
     - statfs(2)-based detection on unix (libc = '0.2' under
       [target.'cfg(unix)'.dependencies])
     - Recognizes exfat / msdos (FAT32) via f_fstypename on macOS,
       via f_type magic numbers on Linux (0x4d44, 0x2011bab0)
     - Windows stub returns Unknown (GetVolumeInformationW TBD)
     - warn_on_unsafe_fs(root) emits stderr warning on ExFat/Fat32
   brain.rs::load calls warn_on_unsafe_fs after canonicalize+symlink
     checks. Warning NOT fatal — user can opt into single-client use.

2. Battle-test matrix (architect P3 finding)
   tests/battle/Dockerfile.install-test-alpine (NEW)
     - alpine:3.19 + apk rust/cargo/pandoc
     - Exposes musl-vs-glibc issues in aws-sdk-s3, rusqlite, git2
   tests/battle/Dockerfile.install-test-debian (NEW)
     - debian:12 + rustup stable + pandoc
     - Default server distro, different apt structure from Ubuntu
   tests/battle/README.md rewritten — 3-distro matrix with run script

3. USB-BRAIN-GUIDE platform split
   docs/USB-BRAIN-GUIDE.md — restructured as TOC + platform-agnostic
     preamble + exFAT warning + cross-platform troubleshooting
   docs/USB-BRAIN-GUIDE-macos.md (NEW, 97 LOC) — Gatekeeper, diskutil,
     /Volumes, xattr -d com.apple.quarantine
   docs/USB-BRAIN-GUIDE-linux.md (NEW, 98 LOC) — /media/$USER,
     umount, ext4 recommended, systemd-udev auto-mount note
   docs/USB-BRAIN-GUIDE-windows.md (NEW, 115 LOC) — PowerShell
     Dismount-Volume, NTFS, FS-advisory Unknown caveat

REAL VERIFICATION (paste from agent):
  cargo check -p keisei: Finished (clean)
  cargo test -p keisei --release: 32 passed 0 failed (30 existing + 2 new)
  docker buildx outline: both new Dockerfiles parse

Constructor Pattern:
  fs_type.rs 103 LOC, brain.rs 198 LOC (at limit 200, held the line)
  All fns <30 LOC. Each USB guide sub-doc 97-115 LOC.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 20:56:42 +08:00
Parfii-bot
f12eb9f83c fix(v0.21.1): wave-audit consolidated — 5 critic HIGH + 2 security HIGH + 3 polish
Closes 10 audit findings from 4-agent wave (critic + security +
architect + validator) on v0.21.0.

CRITIC HIGH (5):
  H1 s3_cloud::commit() was listing with delimiter='/' — nested
     writes silently dropped from manifest hash. Added
     list_recursive() (no delimiter), filter manifest-*.json from
     hash input.
  H2 S3Cfg access_key_env + secret_key_env were advertised in TOML
     but never read. Wired via resolve_explicit_creds() with
     aws-credential-types. Partial-set or empty-resolve → error.
  H3 display::sanitize_display missing in detach.rs + mount.rs
     (regression of v0.19.2 L9 ANSI injection fix). Applied at 8
     print sites. 2 new integration tests.
  H4 adapters/jsonmcp.rs RESTORED (was lost in earlier merge).
     107 LOC shared module: load_json_or_empty / upsert_under_key /
     remove_under_key / persist. claude_code 163→105, cursor 165→106,
     zed 178→114. Unified error handling via ConfigParseError.
  H5 ENV_LOCK shared across kei-store tests. New test_env.rs (24 LOC)
     exposed under cfg(any(test, feature='s3')). github.rs +
     s3_cloud/tests.rs + s3_smoke.rs all use shared mutex. Fixes
     parallel-test race on KEI_STORE_S3_ENDPOINT.

SECURITY HIGH (2):
  SEC-H1 scripts/install-actionlint.sh — added sha256 verify
     (shasum/sha256sum) before extract. ACTIONLINT_SHA256_OVERRIDE
     env var for CI injection. Per-platform constants marked
     [UNVERIFIED: SKIP] pending live checksums.txt fetch (agent had
     no WebFetch this session — user follow-up: paste from
     https://github.com/rhysd/actionlint/releases/download/v1.7.12/checksums.txt).
  SEC-H2 S3 SSRF/IMDS guard. validate_endpoint() rejects:
     loopback (127/8, ::1, localhost), link-local (169.254/16,
     fe80::/10), metadata hostnames (google/azure). Override via
     KEI_STORE_S3_ALLOW_INTERNAL=1. HTTP rejected unless
     KEI_STORE_S3_ALLOW_INSECURE=1. Custom endpoint now REQUIRES
     explicit creds (no IMDS chain leak via third-party endpoint).
     4 reject + 3 accept tests pass.

POLISH (3):
  D1 docs/USB-BRAIN-GUIDE.md — ⚠️ WARNING block under Prerequisites:
     exFAT/FAT32 NOT safe for multi-client attach (SQLite WAL needs
     shared-mem mmap). Use ONE client at a time on those FSes.
     New Troubleshooting entry 'SQLite corruption on mount-attach'.
  D2 '~5 MB release binary growth' now labelled [estimate, E5 —
     not yet measured] in CHANGELOG.md + s3_cloud/mod.rs header.
  D3 scripts/validate-workflow-shas.sh exits 2 (not 0) when
     UNVERIFIED_COUNT > 0 and GITHUB_TOKEN absent. Distinguishes
     'network denied' from 'all good'.

REAL VERIFICATION (pasted by agent):
  cargo check -p keisei -p kei-store: Finished (clean)
  cargo test -p keisei --release: 30 passed 0 failed
  cargo test -p kei-store --release: 10 + 9 passed (default features)
  cargo test -p kei-store --features s3 --release:
    31 + 9 + 6 = 46 passed (with s3)
  bash -n scripts/*.sh: OK
  regen-counts.sh --check: no drift

Constructor Pattern: largest new src 200 LOC (s3_cloud/mod.rs, at
limit). jsonmcp.rs 107 LOC. test_env.rs 24 LOC.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 20:03:17 +08:00
Parfii-bot
2b3ba50ccb docs(v0.21): .dockerignore + USB brain step-by-step guide
.dockerignore — trim Docker build context (was trying to pack
2.6 GB target/ + 6 GB .claude/worktrees/ + 212 MB node_modules/
on 2026-04-22, causing daemon I/O error). Excludes Rust target,
TS node_modules/dist/.turbo, agent worktrees, .git, IDE files,
logs. Essential before any tests/battle/* docker build.

docs/USB-BRAIN-GUIDE.md — 11-step recipe for the physical-USB
exobrain workflow:
  1-4. Prepare + download 5 platform binaries + verify sha256
  5-6. keisei attach --scope=user → verify in Claude Code
  7.   keisei mount for multi-client fan-out
  8.   --scope=project for per-repo brains
  9-10. status + detach cleanup
  11.  safe eject
Plus Troubleshooting section (7 common errors with fixes),
plus What-this-tests-end-to-end checklist (6 v0.21 features
exercised).

Target audience: first-time user of v0.21 exobrain feature on
macOS (Linux adaptation notes inline).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 18:47:12 +08:00