Commit graph

53 commits

Author SHA1 Message Date
Parfii-bot
969ddf34cd Merge feat/v0.21-kei-store-s3 — real S3 backend (CHANGELOG conflict resolved)
Kept both Added blocks: v0.21 SSoT/Scope (from earlier merge) and
v0.21 kei-store S3. Both are part of the v0.21 ship.
2026-04-22 17:59:56 +08:00
Parfii-bot
e5cd0d6790 feat(v0.21): kei-store real S3 backend behind opt-in 's3' feature flag
Promotes S3 from MVP stub to functional via aws-sdk-s3. Default builds
unchanged (zero new deps). Feature flag ensures users who don't need
S3 don't pay the ~5MB binary / C-toolchain cost.

Cargo.toml: new [features] s3 = [...] gating 4 optional deps:
  aws-sdk-s3 = 1.130.0
  aws-config = 1.8.16 (with behavior-version-latest)
  tokio = 1.52.1 (current-thread runtime, no multi-threaded bloat)
  bytes = 1 (S3 body passthrough)

s3_cloud/ module (4 files, Constructor Pattern):
  mod.rs (190 LOC) — S3CloudStore + MemoryStore trait impl
  client.rs (81 LOC) — aws-config builder, KEI_STORE_S3_ENDPOINT
    override for R2 / Wasabi / MinIO / any S3-compat
  keys.rs (60 LOC) — path-traversal guard + DJB2 hash helper
  tests.rs (63 LOC) — builder + prefix + key-guard unit tests

Factory routing (factory.rs):
  with 's3' feature + bucket URL → S3CloudStore (real network)
  without 's3' feature → S3Store stub (existing MVP, preserved)

Security posture:
  - Branch-prefix isolation rejects  traversal at keys.rs layer
  - aws-config default credential chain (env → ~/.aws → IMDS);
    no bespoke credential handling
  - rustls, not OpenSSL (matches existing crate tree)

Tests: 22 existing + 11 new (4 keys + 3 client + 5 mod + 5 smoke)
  cargo test -p kei-store (default features): 9 passed
  cargo test -p kei-store --features s3: 22 + 9 + 5 = 36 passed
  cargo clippy -p kei-store --features s3: clean

Real stdout verified for all verify criteria. No fabrication.

MANIFEST.toml [primitive.kei-store] deps updated to reflect feature
opt-in model.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 17:59:11 +08:00
Parfii-bot
81e3b58533 feat(v0.21): keisei SSoT relocation + Scope enum (user/project)
Two architect-audit P1/P2 findings closed.

PART A — SSoT relocation
  Before: ~/.claude/keisei-attached.toml (baked Claude-Code subpath)
  After: ~/.keisei/attached.toml (client-neutral)
  config::migrate_from_legacy() runs inside config::read() — first
  call after v0.21 install reads legacy path, writes new path,
  deletes legacy, emits stderr notice.
  claude_code adapter's .claude/ subpath UNCHANGED — that's Claude
  Code's real config dir, not keisei's marker namespace.

PART B — Scope enum (architect P1)
  ClientAdapter trait gains:
    fn supported_scopes(&self) -> &[Scope] { &[Scope::User] }  // default
    fn config_path(&self, scope: Scope) -> PathBuf
    fn attach(&self, brain: &Brain, scope: Scope) -> Result<()>
    fn detach(&self, brain_name: &str, scope: Scope) -> Result<()>

  Per-adapter scope support:
    claude_code — [User, Project]  (~/.claude vs ./.claude)
    cursor      — [User, Project]  (~/.cursor vs ./.cursor)
    continue    — [User] only (Continue has no project concept)
    zed         — [User] only (Zed uses global settings)

  CLI: keisei attach <brain> --scope={user|project} (default user).
  keisei mount → always Scope::User (host-wide fan-out).
  Marker Attachment gains scope field with #[serde(default)] so
  v0.20 markers read as Scope::User (backward-compat).

  New Error::ScopeUnsupported { client, scope, supported } — blocks
  invalid combos (e.g. zed --scope=project) with clear message.

New module scope.rs (49 LOC) — Scope enum + serde + Display + FromStr.
paths.rs gains keisei_state_dir() returning $HOME/.keisei.

5 new integration tests:
  - legacy_marker_migrates_on_first_read
  - attach_with_project_scope_writes_local_config
  - attach_user_scope_still_default
  - scope_unsupported_by_adapter_errors
  - detach_respects_scope_from_marker

REAL VERIFIED cargo test -p keisei output: 28 passed; 0 failed.
cargo check -p keisei: clean.
grep /Users/denisparfionovich/ in edits: zero hits.

Constructor Pattern: scope.rs 49 LOC, paths.rs 34 LOC, largest fn
migrate_from_legacy() 22 LOC.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 17:56:10 +08:00
Parfii-bot
909205f63b Merge feat/v0.20-schema-v2-multi-platform — schema v2 multi-platform + post_attach_hint
Conflicts resolved by composition (not picking sides):
  error.rs: keep ManifestTooLarge (v0.19.2) + NoPlatformBinary (v0.20);
    UnsupportedSchema message updated to 'need 1 or 2'.
  brain.rs: merged v0.19.2 invariants block + v0.20 platform-key docs
    into a single Invariants section listing both hardening constraints
    and v2 schema range.
  attach.rs: composed v0.19.2 sanitize_display wrapping with v0.20
    Result<PathBuf> handling — mcp_server_path errors now sanitized too.
  integration.rs: concatenated v0.19.2 (3 tests + helper) + v0.20
    (4 tests + 2 helpers) blocks preserving all 7 new cases.

Tests: 23/23 pass (16 existing + 3 v0.19.2 + 4 v0.20).
cargo check -p keisei: clean.

v1 brains still load, v2 brains dispatch per-platform, adapters have
client-specific post_attach_hint.
2026-04-22 17:23:18 +08:00
Parfii-bot
12e56d6590 feat(v0.20): Brain schema v2 per-platform mcp_server + post_attach_hint() trait
Closes 2 architect audit P3 findings. MVP on the USB-droppable brain
vision — one brain directory now serves every platform.

Schema v2 — per-platform mcp_server dispatch:
  [paths.mcp_server]
  darwin-arm64 = 'bin/kei-mcp-server-darwin-arm64'
  darwin-x64 = 'bin/kei-mcp-server-darwin-x64'
  linux-x64 = 'bin/kei-mcp-server-linux-x64'
  linux-arm64 = 'bin/kei-mcp-server-linux-arm64'
  windows-x64 = 'bin/kei-mcp-server-windows-x64.exe'

Schema v1 (single string) still accepted — v0.19 brains load unchanged.

Implementation:
  brain.rs — new McpServerPath enum (Single / PerPlatform BTreeMap<String, String>)
  with #[serde(untagged)]. Brain::current_platform_key() maps std::env::consts
  (macos→darwin, x86_64→x64, aarch64→arm64) to canonical key format.
  mcp_server_path() now returns Result — looks up current platform,
  returns Error::NoPlatformBinary { os, arch, available } if missing.
  Pre-canonicalized cache field removed so partial v2 brains load for
  status (just fail at actual resolve).
  brain_validate.rs — validate_schema accepts MIN..=MAX range (1 or 2);
  check_all_paths iterates v2 map entries for confinement check.

ClientAdapter::post_attach_hint() — default method + 4 overrides:
  claude_code: 'run /help in Claude Code to verify the MCP server is reachable'
  cursor: 'reload Cursor window (Cmd+Shift+P → Reload Window) to pick up the MCP server'
  continue_adapter: 'reload the Continue extension in VS Code (or restart) to pick up the MCP server'
  zed: 'run Zed :reload command to pick up the MCP server config'
  attach.rs prints adapter.post_attach_hint() instead of the hardcoded
  Claude-Code-specific string. No more client leak in orchestrator.

Error::NoPlatformBinary { os, arch, available } with thiserror Display.

Tests: 16 existing + 4 new = 20/20 pass.
  - schema_v2_current_platform_resolves
  - schema_v2_missing_current_platform_errors (macOS-gated)
  - schema_v1_still_readable_with_v2_code
  - post_attach_hint_is_adapter_specific

Constructor Pattern: all files <200 LOC (continue_adapter.rs 197 LOC
max). All fns <30 LOC (current_platform_key + check_all_paths 19 LOC max).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 17:19:58 +08:00
Parfii-bot
e43b13335e fix(v0.19.2): polish — marker perms 0600, ANSI sanitize, manifest size bound, dead-code cleanup
Closes remaining MEDIUM/LOW audit findings not in v0.19.0 security wave.

M1 — marker file 0600 perms (unix)
  config.rs::write() applies chmod 0o600 after write, cfg(unix) gated.
  Test marker_file_has_0600_perms_on_unix asserts mode & 0o777 == 0o600.

L9 — ANSI-escape sanitization
  New module display.rs (27 LOC) — sanitize_display(&str) replaces
  ASCII < 0x20 OR == 0x7F with '?', leaves space + unicode alone.
  Applied in status.rs + attach.rs to brain_name / brain_path /
  attached_at / client_type / config_path / mcp_path before print.
  Test status_sanitizes_control_chars_in_brain_name asserts
  sanitize_display('evil\x1b[2Jpayload') → 'evil?[2Jpayload'.

L12 — manifest size bound
  brain_validate.rs const MAX_MANIFEST_BYTES = 64 * 1024; metadata
  check before read_to_string. New Error::ManifestTooLarge { size, max }
  with thiserror Display impl. Test manifest_too_large_rejected
  writes 100 KB manifest, asserts error + marker not written.

Dead-code cleanup:
  - Error::NotAttached: #[allow(dead_code)] + comment (reserved for
    future detach subcommand when no marker exists)
  - config::has_client: #[allow(dead_code)] + comment (reserved for
    future multi-brain support)
  - mount.rs / detach.rs: dropped unused ClientAdapter import

brain.rs module doc-comment expanded — lists all v0.19 invariants:
path confinement, symlink reject, name regex, 64 KiB manifest cap,
schema v1; notes v2 (multi-platform) lands in v0.20.

Tests: 16 existing + 3 new = 19/19 pass.
cargo check -p keisei: zero warnings in keisei crate.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 17:17:14 +08:00
Parfii-bot
3ad64332bc Merge fix/v0.19-audit-hardening — security HIGH + critic HIGH consolidated (conflicts resolved)
4 adapter conflicts resolved by taking fix-wave version — preserves
security hardening (path confinement, name validation + collision
refuse, paths::resolve_home SSoT, fsx::write_atomic_json via
NamedTempFile). jsonmcp.rs from v0.19 refactor commit fa253d0
became dead code post-merge; deleted + unregistered from adapters/mod.rs.

If future iteration wants jsonmcp-style shared merge, it should
layer on top of the security-hardened adapter inline logic, not
replace it.

Tests: 16/16 pass (11 pre-existing + 5 new adversarial).
cargo check -p keisei: clean (4 pre-existing dead-code warnings,
not introduced by this merge).
2026-04-22 16:37:19 +08:00
Parfii-bot
d32ca0bc28 fix(v0.19): audit hardening — 3 security HIGH + 3 critic HIGH + 2 critic MEDIUM
Closes consolidated findings from wave-audit (critic + security + architect):

SECURITY HIGH:
  H1 path escape — Brain::load rejects absolute mcp_server paths +
    any containing '..'; canonicalize + starts_with(root) assertion;
    new Error::PathEscape variant.
  H2 brain name validation + clobber refuse — regex ^[a-z][a-z0-9_-]{0,63}$
    enforced at Brain::load; adapters refuse to overwrite existing
    mcpServers[name] with NameConflict (unless same content).
  H3 symlink reject at canonicalize — std::fs::symlink_metadata()
    called before canonicalize; Error::BrainIsSymlink with resolved
    target path; prevents USB → $HOME pivot.

CRITIC HIGH:
  #1 rusqlite dep deleted (zero uses in src/, pulls C toolchain).
  #3 BrainPaths memory/artifacts/manifests now Option<String>
    (only mcp_server required; schema no longer lies about contract).

CRITIC MEDIUM:
  #1 _primitives/_rust/keisei/src/paths.rs (new, 23 LOC) — SSoT for
    $KEISEI_HOME/$HOME resolver; config.rs and claude_code.rs
    delegate instead of duplicating 7-line block.
  #2 canonicalize error preserves io::Error via new Error::BrainLoad
    { path, source } with #[source] attribute.
  #5 fsx::write_atomic_json rewrite via tempfile::NamedTempFile
    + persist — Windows-safe, cross-fs-fallback handling.

New module split (Constructor Pattern): brain.rs (104 → 122) now a
thin orchestrator over brain_validate.rs (108 LOC) which owns
symlink-reject / canonicalize-root / read-manifest / validate-schema
/ validate-name / check-relative-in-root / canonicalize-in-root.

Deps: regex = { workspace = true }, tempfile = "3" (runtime).
Workspace-level regex = "1.10" added.
MANIFEST.toml [primitive.keisei] deps updated.

Tests: 11 pre-existing + 5 adversarial:
  - manifest_with_absolute_mcp_server_rejected — proves /usr/bin/python3
    CANNOT land in settings.json (PathEscape + marker absent asserts)
  - manifest_with_parent_traversal_rejected — ../../etc/passwd rejected
  - manifest_with_invalid_name_rejected — 'claude-ide!' rejected
  - brain_path_is_symlink_rejected — USB → $HOME pivot blocked
  - attach_refuses_to_clobber_existing_mcp_entry — NameConflict on diff

All 16 pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 16:36:11 +08:00
Parfii-bot
fa253d04cc refactor(v0.19): extract adapters/jsonmcp.rs shared MCP entry merge/remove
v0.19 agent's additional factorization that wasn't captured in the
initial branch commit. Extracts shared merge/remove-named helpers
for claude-code/cursor/zed into adapters/jsonmcp.rs (70 LOC). 3
adapters simplify significantly (-65/-68/-102 LOC each).

Also: #[allow(dead_code)] on Error::AdapterFailed (surfaced by
mount/detach orchestration; reserved for library consumers).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 16:35:02 +08:00
Parfii-bot
e6cab72587 feat(v0.19): multi-client adapters + detach/mount/list-adapters + schema v2
Extends keisei CLI from single-client (v0.18) to multi-client exobrain:
new subcommands detach/mount/list-adapters, 3 new adapters (Cursor,
Continue, Zed), schema v2 for ~/.claude/keisei-attached.toml with
[[attachments]] array (v1 backward-compat via untagged serde).

New subcommands:
  detach — iterate marker attachments, call adapter.detach() on each,
    then delete marker. Real strip of mcpServers entry per adapter.
  mount <brain> — auto-attach to ALL detected clients in one call.
  list-adapters — tabular status (name / detected / config path).

New adapters (each <130 LOC mirrors claude_code.rs pattern):
  adapters/cursor.rs — .cursor/mcp.json project-local, fallback
    ~/.cursor/mcp.json global.
  adapters/continue_adapter.rs — ~/.continue/config.json with
    experimental.modelContextProtocolServers key.
  adapters/zed.rs — ~/.config/zed/settings.json (Linux) or
    ~/Library/Application Support/Zed/settings.json (macOS) with
    context_servers key. Zed schema marked [UNVERIFIED] pending docs.

Schema v2 (~/.claude/keisei-attached.toml):
  [[attachments]]
  client_type = "claude-code"
  config_path = "/Users/.../.claude/settings.json"
  [[attachments]]
  client_type = "cursor"
  config_path = "/Users/.../proj/.cursor/mcp.json"

v1 marker migration: untagged serde accepts legacy client_type=string,
upgrades to single-entry attachments[] on next write.

Tests: 5 (v0.18) + 6 new = 11 integration tests, all pass:
  - attach_then_status_happy_path
  - attach_missing_manifest_errors
  - attach_unsupported_schema_errors
  - status_without_attach_is_clean
  - attach_writes_marker_with_expected_fields
  - mount_with_claude_code_only_detected (new)
  - mount_with_no_client_detected (new)
  - detach_round_trip (new)
  - detach_preserves_other_mcp_servers (new)
  - list_adapters_prints_expected_rows (new)
  - schema_v1_to_v2_migration (new)

Known issues (defer to follow-up commit):
  - CRITIC HIGH#1: rusqlite declared but unused
  - CRITIC HIGH#3: BrainPaths fields required but only mcp_server used
  - SECURITY H1/H2/H3: brain path/name not validated before writing
    into client config — will be addressed before tagging v0.19.0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 16:04:45 +08:00
Parfii-bot
3bb9ba7911 feat(v0.18): keisei CLI MVP — exobrain attach/status
Phase 3 of exobrain architecture. Ships the entry-point CLI
that mounts a portable brain (memory + artifacts + manifests +
mcp-server) into an AI client via one command.

MVP scope: 2 subcommands (attach, status), 1 adapter (claude-code).
detach + mount + multi-client deferred to v1.0.

New Rust crate _primitives/_rust/keisei/ — 10 src files + 1 tests
(Constructor Pattern: all files <150 LOC, all fns <=23 LOC).
  main.rs (53 LOC) — clap dispatch
  error.rs (36 LOC) — thiserror enum (BrainNotFound,
    UnsupportedSchema, NoClientDetected, Io/Toml/Json #[from])
  brain.rs (103 LOC) — Brain::load() reads brain/manifest.toml
    schema_v1 (name, created, paths.{memory,artifacts,manifests,
    mcp_server})
  adapter.rs (38 LOC) — ClientAdapter trait (detect/attach/
    detach/config_path) + registry
  adapters/claude_code.rs (121 LOC) — writes MCP server entry
    into ~/.claude/settings.json via merge_mcp_entry (23 LOC,
    mirrors jq-merge pattern from install/lib-hooks.sh)
  attach.rs (44 LOC) — load brain, detect client, call adapter,
    write SSoT ~/.claude/keisei-attached.toml
  status.rs (62 LOC) — read SSoT, print brain name/path/client/
    timestamp + health check (mcp_server binary exists?)
  config.rs (97 LOC) — KeiseiAttached TOML struct + KEISEI_HOME
    env hook for test isolation
  tests/integration.rs (142 LOC) — 5 cases via tempfile + Mutex
    env guard: happy-path, missing-manifest, unsupported-schema,
    no-attach-state, marker-field verification

Workspace: keisei added to _primitives/_rust/Cargo.toml members.
MANIFEST.toml: [primitive.keisei] rust kind, kei-ledger-style
deps (rusqlite bundled, stub for future artifact reads), added
to full profile (standalone opt-in via --add=keisei).

README Rust crates table gains 1 row; count marker untouched.
CHANGELOG [Unreleased] bullet added.

Usage:
  keisei attach /path/to/brain    # mounts into current Claude Code
  keisei status                   # shows mounted brain + health

Next (v0.18 follow-ups): detach impl, cursor/continue adapters,
list-adapters subcommand.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 15:52:40 +08:00
Parfii-bot
14ae1af585 Merge feat/v0.16.1-polish — dynamic schema + mode matrix Phase 3.6 2026-04-22 15:13:05 +08:00
Parfii-bot
d95a3ba48c feat(v0.16.1): dynamic schema SSoT + KNOWN_SCHEMAS drift-test + mode-matrix Phase 3.6
Three polish items from post-audit parallel agent.

1. Dynamic schema whitelist (drops hardcoded const drift)
   _assembler/src/schemas_export.rs (NEW, 136 LOC) — loader cube,
     priority path $AGENT_ROOT/artifacts/schemas.json →
     ~/.claude/agents/artifacts/schemas.json → BUILTIN fallback.
     Hand-rolled JSON parser (no serde_json dep).
   _assembler/src/validator.rs delegates to schemas_export::load,
     keeps KNOWN_ARTIFACT_SCHEMAS alias for back-compat.
   _primitives/_rust/kei-artifact/src/export.rs (NEW, 82 LOC) —
     write() + render() + default_path().
   _primitives/_rust/kei-artifact/src/cli_cmds.rs (NEW, 126 LOC) —
     extracted cmd_emit/get/list/chain so main stays <200 LOC.
   ExportSchemas + ListSchemas subcommands; cmd_register
     auto-refreshes export file (best-effort).

2. KNOWN_SCHEMAS SSoT — documented-dual-const + drift-test
   (Option "simpler than new crate"). SSoT in kei-artifact's
   BUILTIN; schemas_export::BUILTIN is a documented mirror;
   builtin_schemas_do_not_drift_from_kei_artifact test in
   validator.rs parses the primitive's source at test time and
   diffs. <30 LOC change. No workspace structural change —
   assembler stays decoupled from runtime primitive.

3. Agent-to-mode matrix + wizard Phase 3.6
   _blocks/mode-matrix.md (NEW, 24 LOC) — 11-row table mapping
     agent role × recommended mode blocks.
   skills/new-agent/SKILL.md — new Phase 3.6 (between name-confirm
     3.5 and manifest-write 4). AskUserQuestion with 5
     cognitive-mode options (skeptic/devils-advocate/minimalist/
     maximalist/first-principles, multiSelect). Appends picked
     labels to manifest's blocks array. Defaults to NONE.
   _blocks/README.md adds one-line reference to the matrix.
   _assembler/tests/mode_blocks.rs (NEW, 78 LOC) — 3 integration
     tests lock the wiring.

README.md — all accumulated count + pre-built-binaries + plugin
section edits from the v0.16 cycle consolidated here (will be
replaced by markers in v0.17 counts-autogen refactor).

Tests: assembler 24 → 33 (+9), kei-artifact 24 → 31 (+7), total
48 → 64. cargo check --workspace clean.

Constructor Pattern: largest new file validator.rs 180 LOC.

Pre-existing flagged for separate refactor: kei-artifact
validate.rs 268 LOC (not touched by this polish).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 15:10:46 +08:00
Parfii-bot
f77c1b7fdc fix(v0.15.1): RED-1 CVE + typed-handoff + schema minItems
Security hotfix — v0.15.1 Wave 1 fixes from 4-parallel audit.

RED-1 (CVE): KEI_DISABLED_HOOKS tokenized match — was `*all*`
substring-glob (trivially bypassable via "install", "wall-clock", etc.),
now exact-token split on comma/space. Patched in all 9 hooks:
no-hand-edit-agents, assemble-agents, assemble-validate, tomd-preread,
agent-fork-logger, site-wysiwyd-check, error-spike-detector,
milestone-commit-hook, session-end-dump.

RED-2 (observability): minimal profile whitelist now includes
agent-fork-logger and session-end-dump (ledger + trace paths) so
observability is not silently lost on minimal installs.

HIGH: review.json schema minItems:1 on findings — rejects empty
reviews; new Rust test review_schema_rejects_empty_findings.

HIGH: typed-handoff wire-up — produces_artifact declared at top
level on 5 manifests (kei-security-auditor, kei-validator,
kei-architect, kei-code-implementer, kei-critic); duplicate
per-handoff declarations removed.

MED: kei-artifact validate.rs gains warn_unsupported_keywords —
non-fatal stderr warning when schema uses keywords outside the
hand-rolled 2020-12 subset.

LOW: CI Node matrix dropped 18, now ['20','22'].

Doc drift: skills/hooks-control/SKILL.md reflects tokenized-match
semantics and updated minimal-profile hook list.

Tests: 191 Rust workspace + 30 assembler (both pass). RED-1
reproducer 10/10 (4 former-CVE vectors blocked, 5 legit vectors
accepted, empty passes).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 15:08:51 +08:00
Parfii-bot
59725ae021 Merge branch 'feat/v0.15-artifact-handoff' — kei-artifact typed handoff pipeline
# Conflicts:
#	_primitives/MANIFEST.toml
2026-04-22 14:15:17 +08:00
Parfii-bot
24c584ee50 fix: remove genesis-scan from public kit (internal tool, Bundle-only)
Per user decision: publishing the sensitive IP pattern blocklist via public
scanner is leak of the blocklist itself (attack surface). genesis-scan
remains in PROJECT-E (private); user-global
~/.claude/hooks/genesis-leak-guard.sh (runtime hook) separate.

Deleted:
- _primitives/_rust/genesis-scan/ (whole crate, 5 files)
- hooks/git-pre-commit-genesis.sh (scanner companion)

Modified:
- workspace Cargo.toml -1 member (24→23)
- MANIFEST.toml — removed [primitive.genesis-scan] + core/full profile refs
- .github/workflows/ci.yml — removed genesis-scan job
- README.md — 7 count/description edits (24→23 rust, 10→9 hooks, 37→36 full)
- install.sh — 5 edits (--help + menus)
- mcp-server tool-registry.ts + test — scanner removed from MCP surface
- kei-sleep-queue.sh — removed scan_prompt() pre-submit hook
- 2 sleep-on-it skill phases — removed genesis-scan references

Tests: 160 Rust (was 167, -7 genesis-scan tests as expected), 24 assembler unchanged.
2026-04-22 14:11:22 +08:00
Parfii-bot
537589e6a7 feat(primitives): kei-artifact typed handoff pipeline (BMAD-style doc passthrough)
- kei-artifact Rust crate (25th): schema registry + artifact store + SHA-256 id + chain walker
- 5 schemas (JSON Schema 2020-12 strict): spec / plan / patch / review / research
- Manifest extension: optional produces_artifact + expects_artifact per handoff (non-breaking)
- Validator extension: KNOWN_ARTIFACT_SCHEMAS whitelist check + 4 new tests
- 3 kei-* manifests updated with typed handoff (architect→code-implementer→critic chain)
- compose-solution phase-5 cross-ref to kei-artifact

Tests: 189 Rust workspace (was 167, +22 artifact tests) + 24 assembler (was 20, +4 validator tests)
2026-04-22 14:10:08 +08:00
Parfii-bot
81462a03ef chore(rust): misc schema/main refactor in 8 crates (assorted CP splits)
kei-chat-store, kei-content-store, kei-crossdomain, kei-curator, kei-router, kei-sage, kei-search-core, kei-social-store, kei-task — small schema + main refactors for test pass parity (167 Rust tests, 20 assembler).
2026-04-22 13:36:17 +08:00
Parfii-bot
37c8e857d7 refactor(mock-render): split main.rs 227 LOC into 4 cubes (F5a Constructor Pattern)
main.rs 227→55 + cli_args.rs + cmd_screenshot.rs + cmd_lock.rs + cmd_verify.rs (each <100 LOC).
2026-04-22 13:36:17 +08:00
Parfii-bot
ff10f76469 fix(kei-auth): remove --key CLI flag (F12 HIGH — /proc/cmdline leak)
KEI_AUTH_KEY env only. On missing env, explicit error with openssl rand suggestion + RULE 0.8 SSoT pointer.
2026-04-22 13:36:17 +08:00
Parfii-bot
363352e7bf fix(kei-refactor-engine): retract 'git apply-ready' claim (F1 RELEASE BLOCKER)
Output renamed plan-autoresolve.md; header changed to '# AUTO-RESOLVABLE items' (no fake --- a/ /+++ b/ wrapper).
Added test autoresolve_output_is_not_claimed_as_diff.
Template updated: user manually applies, not via git apply.
2026-04-22 13:36:17 +08:00
Parfii-bot
ef95bf2a7c fix(kei-store): path-traversal guard (F2 RELEASE BLOCKER) + S3 stub gate (F7) + GitHub RULE 0.1 guard (F8)
F2: filesystem.rs + s3.rs 'fn full' now Result<PathBuf>, rejects absolute + ParentDir components. 7 new unit tests.
F7: factory.rs rejects 'backend=s3' without KEI_STORE_ALLOW_S3_STUB=1; backend_name() = 's3-local-stub'.
F8: github.rs push() blocks github.com unless KEI_STORE_ALLOW_GITHUB_PUSH=1 (RULE 0.1).
2026-04-22 13:36:17 +08:00
Parfii-bot
a3769ebbb6 refactor(rust-core): Constructor-Pattern splits in kei-router + kei-auth
- kei-router: extract kw_tables.rs from keywords.rs (keep <200 LOC)
- kei-auth: extract new_payload + encode_token helpers
2026-04-22 12:57:12 +08:00
Parfii-bot
adc007b7b0 feat(primitives): 10 Rust crates extracted from LBM (Genesis-scrubbed)
- kei-router — keyword-dispatch meta-tool (CfC ML fallback removed)
- kei-sage — Obsidian-style knowledge graph, FTS5 + BFS + PageRank
- kei-task — task DAG with deps, milestones, dependency-chain queries
- kei-chat-store — Claude conversation session persistence + FTS search
- kei-crossdomain — typed-edge store + BFS cross-domain glue
- kei-search-core — 3-wave deep research with microcent budget cap
- kei-content-store — asset + prompt + campaign registry
- kei-social-store — people + interactions CRM (lite)
- kei-curator — edge-decay graph hygiene utility
- kei-auth — multi-tenant session tokens (replaces single-bearer)

Genesis-scan pre-import pass: skipped pkg/mxl1/*, pkg/inference/*, pkg/trainer/*,
pkg/nc01/*, internal/ml/* (all Genesis/CfC adjacent, sensitive IP).
Security: skipped tools_threat/radio/protocol/med/mlreg (offensive/banned).
Domain verticals skipped: hr/legal/infra/ops/api/osint/edu/geo/hw/finance.

New 'mcp' profile in MANIFEST.toml bundles all 10 for MCP server deployment.

Workspace now 24 crates, cargo check --workspace clean, 94 workspace tests pass.
2026-04-22 12:48:56 +08:00
Parfii-bot
88a59f017f feat(integration): deep-sleep wired into MANIFEST + sleep-setup Phase 3b + README 2026-04-22 08:28:22 +08:00
Parfii-bot
19ee220e0a feat(primitives): 4 Rust crates for deep-sleep — conflict-scan, refactor-engine, graph-check, store
- kei-conflict-scan: rules/hooks/blocks/orphans/CP detection (6 tests)
- kei-refactor-engine: plan-mode + advisory patch format, zero-conflict guarantee (5 tests)
- kei-graph-check: wikilinks/handoffs/block-refs validator (4 tests)
- kei-store: trait + 5 backends (filesystem/github/forgejo/gitea prod, s3 stub) (8 tests)

1916 LOC Rust total; all files <200 LOC; 23/23 tests pass.
2026-04-22 08:28:22 +08:00
Parfii-bot
3cead09520 feat(integration): Phase A incubation wired into trigger + install + README 2026-04-22 02:30:04 +08:00
Parfii-bot
3d928b41db feat(skills): /sleep-on-it 6-phase wizard + kei-sleep-queue CRUD + incubation prompt
Priority-scaled time budgets (quick/standard/deep/marathon/weekly),
marathon-mode for hard derivations (skips Phase B REM for one task),
checkpointing every N minutes via partial commits.
2026-04-22 02:30:04 +08:00
Parfii-bot
9450ef0b95 feat(primitives): kei-sleep-setup wizard + kei-sleep-sync helper + trigger template 2026-04-22 01:34:42 +08:00
Parfii-bot
48b1a8cdcf Merge branch 'feat/v0.10-genesis-scan' — kei-memory + genesis-scan v0.10.0 reconciled 2026-04-22 01:04:32 +08:00
Parfii-bot
c436eb105d feat(integration): register genesis-scan in MANIFEST core+full + README + install.sh sizing 2026-04-22 01:01:56 +08:00
Parfii-bot
10bc799d26 feat(primitives): genesis-scan Rust — sensitive IP leak detector (CI/pre-commit)
26 forbidden patterns synced with ~/.claude/hooks/genesis-leak-guard.sh.
7 exempt scopes (KeiLab/theory/ml-keilab chatlogs/keinet-cfc-eigen/keinet-gpu-wgpu).
CLI: --path, --staged, --stdin, --format=human|json|github-actions, --exit-on-hit.
Self-reference resolved via EXEMPT_SUBSTRINGS + tempfile fixtures with runtime-assembled strings.
7/7 tests pass.
2026-04-22 01:01:56 +08:00
Parfii-bot
edeca916db feat(integration): wire kei-memory into MANIFEST + settings-snippet + README for v0.10 2026-04-22 00:50:04 +08:00
Parfii-bot
040e189b80 feat(primitives): kei-memory Rust crate — offline session analyzer (Genesis-clean) 2026-04-22 00:50:04 +08:00
Parfii-bot
d75d782902 feat(primitives): MANIFEST.toml — SSoT for 21 primitives + 6 profiles 2026-04-21 23:00:32 +08:00
Parfii-bot
c89352c87c Merge branch 'feat/frontend-v040' — 4 stacks + 3 Rust + 5 shell + 17 skills + /site-create (partial)
Cargo.lock regenerated after 8-crate workspace merge.
2026-04-21 21:17:19 +08:00
Parfii-bot
19850e1a45 Merge branch 'feat/v0.5-vm-security' — 7 blocks + 3 shell + 2 Rust + /vm-provision
Workspace Cargo.toml reconciled: all 8 crates (kei-ledger, kei-migrate, kei-changelog, ssh-check, firewall-diff, mock-render, visual-diff, tokens-sync) as members.
2026-04-21 21:15:49 +08:00
Parfii-bot
e5d565a11e Merge branch 'feat/v0.7-docs' — 5 blocks + kei-docs-scaffold + kei-changelog Rust + /docs-scaffold 2026-04-21 21:15:05 +08:00
Parfii-bot
f205a12348 Merge branch 'feat/v0.6-database' — 5 blocks + kei-migrate Rust + /schema-design 2026-04-21 21:14:50 +08:00
Parfii-bot
62e28450bc Merge branch 'feat/rule-0.12-agent-git-model' — kei-ledger Rust + hook + /new-project 2026-04-21 21:13:40 +08:00
Parfii-bot
5d61866618 Merge branch 'feat/v0.6-cicd' — 4 blocks + kei-ci-lint + /ci-scaffold 2026-04-21 21:11:17 +08:00
Parfii-bot
8c60085862 feat(primitives): 5 shell primitives — design-scrape, live-preview, figma-tokens, frontend-inspect, screenshot-decode 2026-04-21 21:07:45 +08:00
Parfii-bot
ebf841c7d9 feat(primitives): 3 Rust cubes — mock-render, visual-diff, tokens-sync 2026-04-21 21:07:45 +08:00
Parfii-bot
be20f5ba46 feat(primitives): kei-docs-scaffold shell + kei-changelog Rust 2026-04-21 21:01:28 +08:00
Parfii-bot
521659bbfb feat(primitives): 2 Rust verification cubes
- ssh-check — parse sshd_config + drop-ins, merge last-wins, lint against
  hardened baseline (pw-auth=no, root=prohibit-password, maxauthtries≤3,
  AllowUsers whitelist, no CBC ciphers, ETM MACs, no ssh-rsa host key).
  4 modules: main (clap CLI) + parse + rules + check. Tests: 9 pass
  (hardened baseline, password-auth-yes-fails, cbc-cipher-fails,
  allow-users-not-in-whitelist-fails, missing-required-fails, etc.).

- firewall-diff — diff intent YAML against `ufw status numbered` output.
  Defensive-only (never runs ufw). Stdin or --status-file input. Parses
  (v6) families, normalises "Anywhere"→"any". Exit 2 on any missing/
  extra rule. 4 modules: main + intent + ufw + diff. Tests: 8 pass
  (load-minimal-intent, exact-match-clean, missing-rule-surfaced,
  extra-live-rule-surfaced, inactive-ufw-fails, integration).

Workspace: clap 4 + serde + serde_yaml + serde_json. release opt-level=z,
LTO, strip. Constructor Pattern: largest file check.rs 213 LOC (93 non-
test); every function under 30 LOC.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 21:00:01 +08:00
Parfii-bot
969e24c6c4 feat(primitives): 3 shell provisioning + hardening
- provision-hetzner.sh — idempotent hcloud wrapper; create/destroy/status/list
  * HCLOUD_TOKEN from ~/.claude/secrets/.env (RULE 0.8)
- provision-vultr.sh — idempotent vultr-cli wrapper; Vultr resolves IP async
  * VULTR_API_KEY from ~/.claude/secrets/.env (RULE 0.8)
- harden-base.sh — Debian/Ubuntu baseline; apt → ssh → ufw → fail2ban →
  auditd → unattended-upgrades; idempotent; ports generic patterns from
  vortex/control/setup/setup.sh:13-53 (no Xray/sing-box/WG steps)

All three reject unsupported platforms early; harden-base.sh never
auto-reboots (surfaces needrestart hints only).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 20:59:38 +08:00
Parfii-bot
7e2afc366b feat(primitives): kei-ci-lint workflow YAML validator 2026-04-21 20:56:24 +08:00
Parfii-bot
c801715a49 feat(primitives): kei-ledger Rust SQLite agent ledger
SSoT for RULE 0.12 (agent git-model). Every non-trivial Agent invocation
logs a fork row; merge ceremony validates the 6-file artefact bundle.

CLI: init / fork / done / fail / merged / list / tree / validate.
Storage: ~/.claude/agents/ledger.sqlite (override via KEI_LEDGER_DB).
Schema versioned via PRAGMA user_version.

Tests: 9/9 passing (fork+done, fail flow, tree walk, list filter,
validate missing/complete, duplicate-id reject, done idempotency,
merged transition). cargo test --release 0.01s.

Constructor Pattern: schema.rs 50, ledger.rs 170, main.rs 177,
integration.rs 147 — all under 200 LOC.

Workspace update: adds kei-ledger to _primitives/_rust members list.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 20:52:20 +08:00
Parfii-bot
e49660cd69 feat(primitives): metrics-scrape + log-ship shell primitives 2026-04-21 20:41:17 +08:00
Parfii-bot
df857923d4 feat(primitives): kei-migrate Rust universal migration runner
Single binary, three backends (Postgres/SQLite/MySQL) autodetected
from DATABASE_URL scheme. Sequential .sql migrations tracked in
_kei_migrations with SHA-256 checksums.

Commands:
  kei-migrate up              — apply pending
  kei-migrate down [n]        — revert last N (requires .down.sql)
  kei-migrate status          — list applied vs pending
  kei-migrate create <name>   — scaffold up+down pair with UTC ts

Constructor Pattern: 10 source files, all <90 LOC, functions <30 LOC.
Deps: sqlx 0.8 (any+postgres+sqlite+mysql, rustls), clap 4, chrono,
sha2, anyhow, tokio.

Tests: 9/9 passing (cargo test, SQLite backend).
Clippy clean: cargo clippy --all-targets -- -D warnings.

Safety features:
- checksum drift detection on applied migrations
- IRREVERSIBLE marker blocks down-revert
- duplicate version detection at scan time
- each migration in its own transaction

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 20:35:29 +08:00