KeiSeiKit-1.0/CHANGELOG.md
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

22 KiB
Raw Blame History

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Entries are generated from the git history via _primitives/_rust/kei-changelog (a conventional-commits walker). Regenerate a single version block with, e.g.:

_primitives/_rust/target/release/kei-changelog \
  --from v0.14.2 --to v0.15.0 --version v0.15.0 --update CHANGELOG.md

Unreleased

Work in flight on feat/v0.16-changelog-gen and follow-up branches. Only placeholders — no corresponding commits exist yet. Any line that ships must be replaced with the real commit summary before release.

Added

  • primitives/keisei (v0.22 Track C — filesystem-type advisory): new fs_type.rs cube (<110 LOC) classifies the brain root via statfs(2) on macOS + Linux and returns FsWarning::{None,ExFat,Fat32,Unknown}. Windows support deferred (returns Unknown until GetVolumeInformationW lands). Brain::load now prints a stderr advisory when exFAT / FAT32 is detected — SQLite WAL shared-mmap is unreliable there and keisei mount (multi-client) WILL corrupt kei-memory / kei-artifact / kei-social-store DBs. Warning is non-blocking — single-client keisei attach on exFAT stays supported. New runtime dep libc = "0.2" (unix-only). Two new integration tests (brain_load_on_typical_filesystem_no_warn, fs_type_detection_returns_none_on_standard_fs) — suite now 32/32 pass.
  • tests/battle (v0.22 Track C — distro matrix): two new Dockerfiles alongside the existing ubuntu:24.04 image. Dockerfile.install-test-alpine (Alpine 3.19 — musl libc, exposes musl-static-link quirks in rusqlite / git2 / aws-sdk-s3). Dockerfile.install-test-debian (Debian 12 bookworm — glibc, different apt structure from Ubuntu). README.md documents the 3-image matrix and documents known musl-static-link failures as matrix signal rather than regression.
  • docs (v0.22 Track C — USB guide platform split): USB-BRAIN-GUIDE.md restructured into a TOC + platform-agnostic preamble (prerequisites, exFAT/FAT32 warning, invariants, troubleshooting). Three new platform-specific walkthroughs: USB-BRAIN-GUIDE-macos.md (Gatekeeper xattr, /Volumes/, diskutil), USB-BRAIN-GUIDE-linux.md (/media/$USER/, umount, ext4, optional systemd-udev auto-attach), USB-BRAIN-GUIDE-windows.md (PowerShell, drive letter, NTFS, Dismount-Volume, FS-advisory returns Unknown caveat).
  • primitives (v0.21 — keisei SSoT relocation + Scope enum):
    • Marker file relocated from ~/.claude/keisei-attached.toml to ~/.keisei/attached.toml. ~/.claude/ is Claude-Code-specific territory and should not host cross-adapter keisei state. config::read() performs a one-shot migration the first time it runs under v0.21: if the legacy file exists and the new location is empty, the marker moves over (new file written, legacy file deleted) and a stderr notice is emitted.
    • Scope enum (user / project) on the ClientAdapter trait. Adapters declare supported_scopes(); config_path(scope), attach(brain, scope), detach(brain_name, scope) are scope-aware. Claude Code and Cursor support both scopes; Continue and Zed are user-only. keisei attach gains --scope=<user|project> (default user); keisei mount stays host-wide (Scope::User fan-out by design).
    • Marker schema v3: each [[attachments]] entry carries scope = "user" | "project". Pre-v0.21 markers without the field default to Scope::User silently. New error variant Error::ScopeUnsupported { client, scope, supported } fires when a caller asks for a scope the adapter doesn't advertise.
  • primitives (v0.21 — kei-store real S3 backend):
    • S3CloudStore — functional S3 / R2 / MinIO / Wasabi backend via aws-sdk-s3 v1. GetObject / PutObject / ListObjectsV2 (paginated) / DeleteObject wired behind the existing MemoryStore trait (sync-over-async via a single-thread tokio runtime). Enables keisei attach s3://my-bucket/brain/ as a real cloud-mount path, not just a local stub.
    • Opt-in feature flag s3 on the kei-store crate — off by default so users who don't need cloud pay zero binary weight. Enabling adds tokio + hyper + rustls + aws-sdk-s3 (~5 MB release binary growth [estimate, E5 — not yet measured; would require cargo build --release before/after feature flag]).
    • AWS default credential chain honoured (env vars → ~/.aws/credentials → IMDS). No new credential format; RULE 0.8 secrets-single-source unchanged.
    • Endpoint override for non-AWS S3-compat providers via KEI_STORE_S3_ENDPOINT env var (runtime) or s3.endpoint in store-config.toml (persistent). Path-style addressing auto-enabled when a custom endpoint is set (MinIO / some R2 configs).
    • "Branch" semantics: S3 has no native branching, so a branch is modelled as a key prefix (<branch>/<path>). branch() sets the active prefix in-memory; default main.
    • Factory auto-routes: backend = "s3" + feature s3 + s3.bucket set → real cloud; otherwise falls back to the v0.14 local-manifest stub (still behind KEI_STORE_ALLOW_S3_STUB=1).
    • Path-traversal guard parity with FilesystemStore: absolute and ..-component paths rejected before keys are spliced.
  • tests/battle: Docker-based clean-Ubuntu install test — tests/battle/Dockerfile.install-test + verify.sh + battle-entry.sh + README. Builds a fresh ubuntu:24.04 image, runs install.sh --profile=<minimal|core|dev|full> under --yes, then asserts post-install counts (blocks ≥ 79, skills ≥ 39, top hooks ≥ 10, _lib hooks ≥ 2), runs hooks/_lib/test-gate.sh, and validates settings.json. First real-world "does it work on a fresh machine?" signal — CI previously only ran --no-execute dry-runs. v0.21 ship-blocker for any profile that regresses.
  • primitives (v0.20 — brain schema v2 + per-client hint):
    • Brain schema v2 with per-platform mcp_server dispatch — a single brain directory can now host binaries for darwin-arm64/darwin-x64/linux-x64/linux-arm64/windows-x64 and keisei attach picks the right one automatically. Schema v1 (single string) still accepted for backward-compat.
    • ClientAdapter::post_attach_hint() — per-client reload instruction, no more hardcoded Claude-Code string in the orchestrator.
  • primitives: keisei CLI MVP — attach <brain-path> + status subcommands for mounting a portable exobrain directory into Claude Code. First step of the v0.18 exobrain architecture (multi-client adapter surface prepared; only claude-code adapter ships in MVP).
  • primitives (v0.19 — multi-client exobrain):
    • keisei mount <brain-path> — attach a brain to EVERY detected AI client in one shot (Claude Code + Cursor + Continue + Zed).
    • keisei detach — remove the brain from every client recorded in the marker, preserving user's other MCP/context-server entries.
    • keisei list-adapters — tabular dump of every registered adapter and whether it's detected on this host.
    • 3 new ClientAdapter implementations: cursor (.cursor/mcp.json project-local or ~/.cursor/mcp.json global), continue (~/.continue/config.{yaml,json} — YAML preferred, JSON fallback), zed (~/Library/Application Support/Zed/settings.json on macOS or ~/.config/zed/settings.json on Linux, under context_servers).
    • keisei-attached.toml schema v2 — carries a list of [[attachments]] (client_type + config_path) instead of a single client_type. v1 markers read transparently (auto-migrated in memory).
    • New error variants: AdapterFailed { client, reason } and ConfigParseError { path, reason }.
  • Placeholder: CHANGELOG.md generation wired through kei-changelog (this file).
  • Placeholder: .github/workflows/release.yml — tag-driven multi-platform release.
  • Placeholder: pre-built-binary install path in install.sh (KEI_SKIP_RUST_BUILD=1).
  • added: kei-mcp-server single-binary compile for 5 platforms (linux/darwin/windows × x64/arm64 where available) via bun build --compile — v0.18 Phase 1 of the exobrain distribution architecture. Ships as bare binaries + .sha256 sums on every GitHub release; install.sh detects a dropped binary at _primitives/_rust/target/release/kei-mcp-server-<os>-<arch> and skips bun/npm build. Opt-out via KEI_SKIP_MCP_BUILD=1. See _ts_packages/packages/mcp-server/BUILD.md.

Changed

  • Placeholder: plugin / block format refresh targeted for v0.16.0.

Security

  • primitives/keisei (v0.19.2 audit polish — M1): keisei-attached.toml marker is now chmod 0o600 on unix (Windows unchanged — no equivalent bit). The marker carries the resolved brain_path and every attached client's config path; restricting it to owner-only closes the residual "other local user can enumerate attached brains" surface.
  • primitives/keisei (v0.19.2 audit polish — L9): every manifest-sourced string printed by status and attach (brain name, brain path, client/config paths) is now scrubbed through display::sanitize_display, which replaces every ASCII control byte (< 0x20 or == 0x7F) with ?. Closes the escape-sequence injection surface from a malicious brain.name like "evil\x1b[2Jpayload" that would otherwise clear the user's terminal or rewrite already-printed lines.
  • primitives/keisei (v0.19.2 audit polish — L12): manifest.toml is now capped at 64 KiB (Error::ManifestTooLarge { size, max }). The check runs off fs::metadata before read_to_string so an attacker-supplied 1 GB file can't exhaust memory inside the toml parser. Legit manifests are ~1 KB; the cap is three orders of magnitude of headroom.

Fixed

  • Placeholder: hook-bypass edge case follow-up to v0.15.1.
  • primitives/kei-store (v0.21.1 audit wave, HIGH-1): S3CloudStore::commit() now calls a new list_recursive(prefix) helper (ListObjectsV2 without delimiter) so every nested key under the branch — e.g. write("traces/x.jsonl", ...) — contributes to the manifest hash. The previous implementation called list("") which under the hood used delimiter="/" and hid all sub-directory writes from the commit, silently breaking hash-stability. commit() ALSO strips any existing manifest-*.json entries from the input so the hash is stable across repeated commits on unchanged data.
  • primitives/kei-store (v0.21.1 audit wave, HIGH-2): S3Cfg::access_key_env + S3Cfg::secret_key_env are now wired through to the aws-sdk-s3 builder. When both are set, we resolve the named env vars into an explicit Credentials provider and overlay it on the SDK config. Partial configuration (only one of the two set) now returns an error rather than silently ignoring it. Previously both fields were dead — configured users were getting the ambient AWS default chain instead of the named pair.
  • primitives/kei-store (v0.21.1 audit wave, HIGH-5): all tests that mutate process env on KEI_STORE_* vars now take a shared test_env::ENV_LOCK mutex (exposed under cfg(any(test, feature = "s3"))). Prevents cargo-test parallelism from racing multiple tests on the same env state. github.rs dedups onto the shared lock; s3_cloud/tests.rs + tests/s3_smoke.rs now use it.
  • primitives/keisei (v0.21.1 audit wave, HIGH-3): detach.rs + mount.rs now scrub every manifest-sourced string (brain name, brain path, config path, client type, error reason) through display::sanitize_display before println! / eprintln!. status.rs + attach.rs were already compliant; this closes the L9 regression gap for the other two print sites. Two new integration tests (detach_sanitizes_control_chars_in_marker_fields, mount_sanitizes_control_chars_in_error_reason) assert source-level guard presence.
  • primitives/keisei (v0.21.1 audit wave, HIGH-4): extracted adapters/jsonmcp.rs (~107 LOC) as the shared JSON merge/remove/persist helper used by the claude-code, cursor, and zed adapters. All three adapters drop from ~170 LOC to ~105 LOC each and share a uniform error-surfacing contract (Error::ConfigParseError { path } rather than raw serde_json on parse failure). continue_adapter.rs is YAML-based and is unaffected.
  • security (v0.21.1 audit wave, H1): scripts/install-actionlint.sh now verifies SHA-256 of the downloaded tarball before extraction. Per (OS, ARCH) hashes are pinned at the top of the script and documented as the output of checksums.txt on the upstream release page. If a hash is marked SKIP (documented as [UNVERIFIED] pending live fetch), the installer prints a WARNING. Missing shasum / sha256sum is a hard exit 2 — refuses to install an unverified binary. Env override ACTIONLINT_SHA256_OVERRIDE=<hex> lets CI inject the hash at runtime.
  • security (v0.21.1 audit wave, H2): kei-store::s3_cloud::client::validate_endpoint rejects loopback / link-local / metadata hosts (127.0.0.0/8, ::1, 169.254.0.0/16, fe80::/10, metadata.google.internal, etc.) and plain-HTTP URLs by default. Closes the SSRF / IMDS-leak surface where an attacker-controlled KEI_STORE_S3_ENDPOINT pointed at http://169.254.169.254 would cause the AWS default credential chain to sign requests against the instance metadata endpoint and leak IMDS creds. Env overrides: KEI_STORE_S3_ALLOW_INTERNAL=1 (local MinIO / tests), KEI_STORE_S3_ALLOW_INSECURE=1 (plain-HTTP). When a custom endpoint is set, explicit access_key_env + secret_key_env are REQUIRED — the default credential chain is no longer consulted for non-AWS endpoints.
  • docs (v0.21.1 audit wave, D1): docs/USB-BRAIN-GUIDE.md now warns that exFAT / FAT32 are NOT safe for multi-client attach — SQLite WAL shared-memory mmap doesn't work reliably on those filesystems. Recommends APFS / ext4 / NTFS for keisei mount. Troubleshooting entry "SQLite corruption on mount-attach" added with recovery steps.
  • docs (v0.21.1 audit wave, D2): the "~5 MB release binary growth" claim for the s3 feature is now labelled [estimate, E5 — not yet measured] in both CHANGELOG.md and the s3_cloud module doc-comment. Prevents over-claim until a real cargo build --release before/after comparison is landed.
  • scripts (v0.21.1 audit wave, D3): scripts/validate-workflow-shas.sh now exits 2 when UNVERIFIED pins exist AND no GITHUB_TOKEN was provided (rate-limit path). Previously silently returned 0 which masked incomplete verification in CI.
  • primitives/keisei (v0.19 audit hardening): close 3 Security HIGH + 3 Critic HIGH + 2 Critic MEDIUM findings. Path-escape guard on mcp_server + memory/artifacts/manifests (absolute / .. / canonical-mismatch → PathEscape); brain-name regex ^[a-z][a-z0-9_-]{0,63}$ (InvalidName); symlink-rooted brain inputs rejected (BrainIsSymlink — closes USB → $HOME pivot); MCP-entry collision check across all 4 adapters (NameConflict instead of silent clobber); dropped unused rusqlite dep (no C toolchain tail); BrainPaths.{memory,artifacts,manifests} relaxed to Option<String>; $KEISEI_HOME/$HOME resolver deduped into paths.rs SSoT; fsx::write_atomic rewritten on tempfile::NamedTempFile for Windows + cross-fs correctness; 5 adversarial integration tests added (16 total pass).
  • primitives/keisei (v0.19.2 polish): dropped unused ClientAdapter imports from mount.rs + detach.rs; Error::NotAttached and AttachRecord::has_client now carry explicit #[allow(dead_code)] markers documenting that they're reserved for future callers / test-only respectively. cargo check -p keisei is warning-clean; integration suite is 19/19 pass (3 new: marker_file_has_0600_perms_on_unix, status_sanitizes_control_chars_in_brain_name, manifest_too_large_rejected). brain.rs module-level doc-comment now lists the v0.19 invariants (path confinement / symlink reject / name regex / manifest size cap) and flags schema v2 as v0.20.

Security

  • Pinned all GitHub Actions (ci.yml, release.yml) by full commit SHA to defend against CVE-2025-30066-class supply-chain attacks via mutable tag re-pointing.
  • Removed || bun install fallback from release.yml build-mcp-binary job — lockfile is now strictly REQUIRED (H4 audit finding).
  • Added .github/dependabot.yml for weekly SHA update PRs on github-actions, npm, and cargo ecosystems.
  • v0.20.1 — workflow validation defense-in-depth: motivated by the 2026-04-22 incident where dtolnay/rust-toolchain@3c5f7ea... SHA-pinned a specific Rust version (1.94.1 branch tip) instead of "install current stable", breaking CI for 4 jobs. Added three gates against the incident class: scripts/install-actionlint.sh (pinned v1.7.12 installer, macOS-arm64 + linux-x64), scripts/lint-workflows.sh (actionlint runner, advisory if binary missing), scripts/validate-workflow-shas.sh (git-ls-remote every uses: <repo>@<sha40> pin; exits 1 on SHA MISSING, soft-continues on network errors with [UNVERIFIED]), scripts/pre-commit-workflow-lint.sh (symlink-to-install pre-commit hook, fires only when workflow files are staged), and new workflow-lint CI job running the two validators on every push + PR.

0.15.0 — 2026-04-22

Added

  • primitives: kei-artifact typed handoff pipeline (BMAD-style doc passthrough) (3f303b7)
  • blocks: 5 cognitive mode blocks + 2 manifest wirings (fdfc690)

0.14.2 — 2026-04-22

Added

  • hooks: runtime controls via KEI_DISABLED_HOOKS + KEI_HOOK_PROFILE (v0.14.2) (1a448e8)

Removed

  • genesis-scan from public kit (internal tool, Bundle-only) (268226b)

0.14.1 — 2026-04-22

Added

  • ci: GitHub Actions workflows + .claude/worktrees gitignore (407e8b7)

Changed

  • readme + install: reconcile all count drift (F4 RELEASE BLOCKER) (0199fd4)
  • rust: misc schema/main refactor in 8 crates (assorted CP splits) (61448b9)
  • mock-render: split main.rs 227 LOC into 4 cubes (F5a Constructor Pattern) (ad5977d)

Fixed

  • kei-auth: remove --key CLI flag (F12 HIGH — /proc/cmdline leak) (b449587)
  • kei-refactor-engine: retract 'git apply-ready' claim (F1 RELEASE BLOCKER) (f50ef43)
  • kei-store: path-traversal guard (F2 RELEASE BLOCKER) + S3 stub gate (F7) + GitHub RULE 0.1 guard (F8) (ad9c53f)

0.14.0 — 2026-04-22

Added

  • primitives: 10 Rust crates extracted from LBM (Genesis-scrubbed) (a5e6649)
  • ts-packages: 6 TS packages — MCP server + 5 external-API adapters (7b647d5)

Changed

  • rust-core: Constructor-Pattern splits in kei-router + kei-auth (afed921)

0.13.0 — 2026-04-22

Added

  • integration: deep-sleep wired into MANIFEST + sleep-setup Phase 3b + README (bcd80f6)
  • primitives: 4 Rust crates for deep-sleep — conflict-scan, refactor-engine, graph-check, store (0f75493)
  • skills: /onboard auto-project-analyze with 3-mode apply (full-auto / step-by-step / full-manual) (1396139)

Changed

  • readme: "Why Rust, not Python" paragraph in author note (92c918a)
  • readme: clarify "my sample, not claim of originality" in author note (47d2448)
  • readme: add "double sorry" disclaimer in author note (3d5d768)
  • readme: move "From the author" to opening, expand with transformer-error context (fd67315)
  • readme: add "From the author" note (b103c3d)

0.12.0 — 2026-04-22

Added

  • integration: Phase A incubation wired into trigger + install + README (d72de64)
  • skills: /sleep-on-it 6-phase wizard + kei-sleep-queue CRUD + incubation prompt (30df6cb)

0.11.0 — 2026-04-22

Added

  • integration: --with-sleep-sync flag + README Cloud REM sync section (1dd05c6)
  • skills: /sleep-setup 5-phase wizard (click + 1 free-text URL) (b658f81)
  • hooks: session-end-dump calls kei-sleep-sync after ingest (1ab39d5)
  • primitives: kei-sleep-setup wizard + kei-sleep-sync helper + trigger template (4fdaab6)

0.10.0 — 2026-04-22

Added

  • integration: register genesis-scan in MANIFEST core+full + README + install.sh sizing (93ba0a0)
  • hooks: git-pre-commit-genesis — template for repo symlink into .git/hooks/pre-commit (670af3f)
  • primitives: genesis-scan Rust — patent-IP leak detector (CI / pre-commit) (5db8548)
  • integration: wire kei-memory into MANIFEST + settings-snippet + README for v0.10 (0b5da5a)
  • skills: /self-audit 5-phase triage pipeline (334a867)
  • hooks: 3 self-audit triggers — stop / milestone / error-spike (a5c3896)
  • primitives: kei-memory Rust crate — offline session analyzer (Genesis-clean) (448fc07)

0.9.1 — 2026-04-21

Added

  • install: interactive menu (whiptail / dialog / plain) + confirm screen + --yes / --no-execute (4809269)

0.9.0 — 2026-04-21

Added

  • install: modular profiles + --add / --remove / --list incremental install (b1b8de0)
  • primitives: MANIFEST.toml — SSoT for 21 primitives + 6 profiles (764a999)

Changed

  • readme: install profiles table + migration note for v0.9.0 (47931a3)

BREAKING: default install profile is now minimal (was full). Re-run with --profile=full to preserve prior behaviour.

0.8.0 — 2026-04-21

Added

  • install: copy _primitives/ + build Rust workspace; register agent-fork-logger + site-wysiwyd hooks (b0d9389)
  • hooks: site-wysiwyd-check PostToolUse(Edit | Write) drift advisory (c2041b4)
  • skills: /site-create pipeline (phases 04 — phases 56 deferred) (839ae57)

Changed

  • compose-solution: prior-art grep paths + phase-5 cross-refs for 10 pipelines + 21 primitives (f664cbc)
  • readme: v0.8.0 — 73 blocks / 34 skills / 21 primitives / 6 hooks / 11 bridges + pipelines section (ed7d566)