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>
22 KiB
22 KiB
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-genand 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.rscube (<110 LOC) classifies the brain root viastatfs(2)on macOS + Linux and returnsFsWarning::{None,ExFat,Fat32,Unknown}. Windows support deferred (returnsUnknownuntilGetVolumeInformationWlands).Brain::loadnow prints a stderr advisory when exFAT / FAT32 is detected — SQLite WAL shared-mmap is unreliable there andkeisei mount(multi-client) WILL corruptkei-memory/kei-artifact/kei-social-storeDBs. Warning is non-blocking — single-clientkeisei attachon exFAT stays supported. New runtime deplibc = "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.04image.Dockerfile.install-test-alpine(Alpine 3.19 — musl libc, exposes musl-static-link quirks inrusqlite/git2/aws-sdk-s3).Dockerfile.install-test-debian(Debian 12 bookworm — glibc, different apt structure from Ubuntu).README.mddocuments 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.mdrestructured into a TOC + platform-agnostic preamble (prerequisites, exFAT/FAT32 warning, invariants, troubleshooting). Three new platform-specific walkthroughs:USB-BRAIN-GUIDE-macos.md(Gatekeeperxattr,/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 returnsUnknowncaveat). - primitives (v0.21 — keisei SSoT relocation +
Scopeenum):- Marker file relocated from
~/.claude/keisei-attached.tomlto~/.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. Scopeenum (user/project) on theClientAdaptertrait. Adapters declaresupported_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 attachgains--scope=<user|project>(defaultuser);keisei mountstays host-wide (Scope::Userfan-out by design).- Marker schema v3: each
[[attachments]]entry carriesscope = "user" | "project". Pre-v0.21 markers without the field default toScope::Usersilently. New error variantError::ScopeUnsupported { client, scope, supported }fires when a caller asks for a scope the adapter doesn't advertise.
- Marker file relocated from
- primitives (v0.21 —
kei-storereal S3 backend):S3CloudStore— functional S3 / R2 / MinIO / Wasabi backend viaaws-sdk-s3v1. GetObject / PutObject / ListObjectsV2 (paginated) / DeleteObject wired behind the existingMemoryStoretrait (sync-over-async via a single-thread tokio runtime). Enableskeisei attach s3://my-bucket/brain/as a real cloud-mount path, not just a local stub.- Opt-in feature flag
s3on thekei-storecrate — 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 requirecargo build --releasebefore/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_ENDPOINTenv var (runtime) ors3.endpointinstore-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; defaultmain. - Factory auto-routes:
backend = "s3"+ features3+s3.bucketset → real cloud; otherwise falls back to the v0.14 local-manifest stub (still behindKEI_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 freshubuntu:24.04image, runsinstall.sh --profile=<minimal|core|dev|full>under--yes, then asserts post-install counts (blocks ≥ 79, skills ≥ 39, top hooks ≥ 10,_libhooks ≥ 2), runshooks/_lib/test-gate.sh, and validatessettings.json. First real-world "does it work on a fresh machine?" signal — CI previously only ran--no-executedry-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_serverdispatch — a single brain directory can now host binaries for darwin-arm64/darwin-x64/linux-x64/linux-arm64/windows-x64 andkeisei attachpicks 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.
- Brain schema v2 with per-platform
- primitives:
keiseiCLI MVP —attach <brain-path>+statussubcommands for mounting a portable exobrain directory into Claude Code. First step of the v0.18 exobrain architecture (multi-client adapter surface prepared; onlyclaude-codeadapter 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
ClientAdapterimplementations:cursor(.cursor/mcp.jsonproject-local or~/.cursor/mcp.jsonglobal),continue(~/.continue/config.{yaml,json}— YAML preferred, JSON fallback),zed(~/Library/Application Support/Zed/settings.jsonon macOS or~/.config/zed/settings.jsonon Linux, undercontext_servers). keisei-attached.tomlschema v2 — carries a list of[[attachments]](client_type + config_path) instead of a singleclient_type. v1 markers read transparently (auto-migrated in memory).- New error variants:
AdapterFailed { client, reason }andConfigParseError { 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-serversingle-binary compile for 5 platforms (linux/darwin/windows × x64/arm64 where available) viabun build --compile— v0.18 Phase 1 of the exobrain distribution architecture. Ships as bare binaries +.sha256sums on every GitHub release;install.shdetects a dropped binary at_primitives/_rust/target/release/kei-mcp-server-<os>-<arch>and skips bun/npm build. Opt-out viaKEI_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.tomlmarker is nowchmod 0o600on unix (Windows unchanged — no equivalent bit). The marker carries the resolvedbrain_pathand 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
statusandattach(brain name, brain path, client/config paths) is now scrubbed throughdisplay::sanitize_display, which replaces every ASCII control byte (< 0x20or== 0x7F) with?. Closes the escape-sequence injection surface from a maliciousbrain.namelike"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.tomlis now capped at 64 KiB (Error::ManifestTooLarge { size, max }). The check runs offfs::metadatabeforeread_to_stringso 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 newlist_recursive(prefix)helper (ListObjectsV2 withoutdelimiter) so every nested key under the branch — e.g.write("traces/x.jsonl", ...)— contributes to the manifest hash. The previous implementation calledlist("")which under the hood useddelimiter="/"and hid all sub-directory writes from the commit, silently breaking hash-stability.commit()ALSO strips any existingmanifest-*.jsonentries 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_envare now wired through to the aws-sdk-s3 builder. When both are set, we resolve the named env vars into an explicitCredentialsprovider 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 sharedtest_env::ENV_LOCKmutex (exposed undercfg(any(test, feature = "s3"))). Prevents cargo-test parallelism from racing multiple tests on the same env state.github.rsdedups onto the shared lock;s3_cloud/tests.rs+tests/s3_smoke.rsnow use it. - primitives/keisei (v0.21.1 audit wave, HIGH-3):
detach.rs+mount.rsnow scrub every manifest-sourced string (brain name, brain path, config path, client type, error reason) throughdisplay::sanitize_displaybeforeprintln!/eprintln!.status.rs+attach.rswere 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 theclaude-code,cursor, andzedadapters. 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.rsis YAML-based and is unaffected. - security (v0.21.1 audit wave, H1):
scripts/install-actionlint.shnow 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 ofchecksums.txton the upstream release page. If a hash is markedSKIP(documented as[UNVERIFIED]pending live fetch), the installer prints a WARNING. Missingshasum/sha256sumis a hard exit 2 — refuses to install an unverified binary. Env overrideACTIONLINT_SHA256_OVERRIDE=<hex>lets CI inject the hash at runtime. - security (v0.21.1 audit wave, H2):
kei-store::s3_cloud::client::validate_endpointrejects 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-controlledKEI_STORE_S3_ENDPOINTpointed athttp://169.254.169.254would 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, explicitaccess_key_env+secret_key_envare REQUIRED — the default credential chain is no longer consulted for non-AWS endpoints. - docs (v0.21.1 audit wave, D1):
docs/USB-BRAIN-GUIDE.mdnow 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 forkeisei 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
s3feature is now labelled[estimate, E5 — not yet measured]in both CHANGELOG.md and thes3_cloudmodule doc-comment. Prevents over-claim until a realcargo build --releasebefore/after comparison is landed. - scripts (v0.21.1 audit wave, D3):
scripts/validate-workflow-shas.shnow exits 2 when UNVERIFIED pins exist AND noGITHUB_TOKENwas 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 →$HOMEpivot); MCP-entry collision check across all 4 adapters (NameConflictinstead of silent clobber); dropped unusedrusqlitedep (no C toolchain tail);BrainPaths.{memory,artifacts,manifests}relaxed toOption<String>;$KEISEI_HOME/$HOMEresolver deduped intopaths.rsSSoT;fsx::write_atomicrewritten ontempfile::NamedTempFilefor Windows + cross-fs correctness; 5 adversarial integration tests added (16 total pass). - primitives/keisei (v0.19.2 polish): dropped unused
ClientAdapterimports frommount.rs+detach.rs;Error::NotAttachedandAttachRecord::has_clientnow carry explicit#[allow(dead_code)]markers documenting that they're reserved for future callers / test-only respectively.cargo check -p keiseiis 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.rsmodule-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 installfallback fromrelease.ymlbuild-mcp-binary job — lockfile is now strictly REQUIRED (H4 audit finding). - Added
.github/dependabot.ymlfor 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 everyuses: <repo>@<sha40>pin; exits 1 onSHA 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 newworkflow-lintCI job running the two validators on every push + PR.
0.15.0 — 2026-04-22
Added
- primitives:
kei-artifacttyped 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/worktreesgitignore (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.rs227 LOC into 4 cubes (F5a Constructor Pattern) (ad5977d)
Fixed
- kei-auth: remove
--keyCLI flag (F12 HIGH —/proc/cmdlineleak) (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:
/onboardauto-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-it6-phase wizard +kei-sleep-queueCRUD + incubation prompt (30df6cb)
0.11.0 — 2026-04-22
Added
- integration:
--with-sleep-syncflag + README Cloud REM sync section (1dd05c6) - skills:
/sleep-setup5-phase wizard (click + 1 free-text URL) (b658f81) - hooks:
session-end-dumpcallskei-sleep-syncafter ingest (1ab39d5) - primitives:
kei-sleep-setupwizard +kei-sleep-synchelper + trigger template (4fdaab6)
0.10.0 — 2026-04-22
Added
- integration: register
genesis-scanin MANIFEST core+full + README +install.shsizing (93ba0a0) - hooks:
git-pre-commit-genesis— template for repo symlink into.git/hooks/pre-commit(670af3f) - primitives:
genesis-scanRust — patent-IP leak detector (CI / pre-commit) (5db8548) - integration: wire
kei-memoryinto MANIFEST + settings-snippet + README for v0.10 (0b5da5a) - skills:
/self-audit5-phase triage pipeline (334a867) - hooks: 3 self-audit triggers — stop / milestone / error-spike (
a5c3896) - primitives:
kei-memoryRust 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/--listincremental 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(wasfull). Re-run with--profile=fullto preserve prior behaviour.
0.8.0 — 2026-04-21
Added
- install: copy
_primitives/+ build Rust workspace; registeragent-fork-logger+site-wysiwydhooks (b0d9389) - hooks:
site-wysiwyd-checkPostToolUse(Edit | Write) drift advisory (c2041b4) - skills:
/site-createpipeline (phases 0–4 — phases 5–6 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)