KeiSeiKit-1.0/CHANGELOG.md
Parfii-bot 4f6cbfd305 Merge docs/v0.22-reference-section — README Reference section (conflict resolved)
CHANGELOG: Reference entry folded into Track A's block.
README: auto-merged cleanly (agent appended the 670-LOC Reference
section after 'What you get' table, untouched by Track A/B/C).

wc -l README.md: 1233 (was 563 pre-session — 2.2x growth from product
rewrite + USB guide + exobrain CLI docs + Reference section).
2026-04-22 21:11:21 +08:00

233 lines
29 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
Entries are generated from the git history via
`_primitives/_rust/kei-changelog` (a conventional-commits walker).
Regenerate a single version block with, e.g.:
```bash
_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.
### Changed
- **primitives (v0.22 — `keisei` schema v4, BREAKING marker shape):**
- Marker schema bumped from v3 to v4. The top-level `brain_path` / `brain_name` / `attached_at` fields are gone; every `[[attachments]]` entry now owns its own `brain_path`, `brain_name`, and `attached_at`. Consequence: one marker can track multiple brains wired to different clients at the same time (e.g. brain-A on Claude Code at user scope + brain-B on Cursor at project scope). `config::AttachRecord::new(attachments)` is the fresh constructor; raw struct literals no longer compile.
- `ClientAdapter::post_attach_hint` signature widened from `fn (&self) -> &'static str` to `fn (&self, brain: &Brain, scope: Scope) -> String` so adapters can interpolate the brain's name and the resolved scope into the reload instruction. Implementations of the trait outside this crate need to update.
- Adapter enumeration centralised in `adapters/_registry.rs::all_adapters`. `adapter::all()` now delegates; the "add a 5th adapter" touchpoint drops from three files to one. Public API of `adapter::all()` unchanged.
- **primitives (v0.22 — `config.rs` decomposition):**
- Schema-migration logic extracted from `config.rs` into `config_migrate.rs` (pure functions on `WireRecord``AttachRecord`). Time helpers extracted into `time.rs` with a 5-test anchor suite covering epoch-0, leap day 2020-02-29, century non-leap 2100-03-01, an arbitrary recent timestamp, and `civil_from_days` direct invariants. `config.rs` drops from 224 LOC to 197 LOC, below the 200-LOC Constructor Pattern ceiling.
### Added
- **primitives/keisei (v0.22 Track A — schema v4 multi-brain marker):** `AttachRecord` inverted so every `Attachment` carries its own `brain_path` + `brain_name` + `scope` + `attached_at`. Enables brain-A attached to Claude Code (user scope) + brain-B attached to Cursor (project scope) simultaneously in ONE marker. v1/v2/v3 readers transparent via `#[serde(untagged)]` — auto-migrate silently on first v0.22 `config::read()` with one-line stderr notice.
- **primitives (v0.22 — `Scope::Auto` CLI default):**
- `keisei attach <brain>` without `--scope` now defaults to `auto`. Each adapter exposes `auto_scope()`; Claude Code returns `Scope::Project` when CWD has `.claude/` (dir or `settings.json`), Cursor when CWD has `.cursor/`. Continue + Zed stay on user-scope default. Team workflow `cd team-repo; keisei attach brain` now picks project-scope without an extra flag.
- `Scope::Auto` is a CLI-level intent only — `attach.rs` resolves it to a concrete `User` / `Project` before writing the marker. The persisted marker never contains `auto`.
- **primitives (v0.22 — `keisei mount` per-adapter scope resolution):**
- `mount` now resolves scope per-adapter via `auto_scope()` instead of forcing `Scope::User` across the fan-out. A single `keisei mount brain` inside `team-repo/` can wire Cursor at project scope and Claude Code at user scope (or both at project, depending on CWD).
- **primitives (v0.22 — templated `post_attach_hint`):** `fn post_attach_hint(&self, brain: &Brain, scope: Scope) -> String` interpolates the brain name + resolved scope into the per-adapter reload instruction. No more Claude-Code-specific string in the orchestrator.
- **primitives (v0.22 — adapter registry):** new `adapters/_registry.rs` (32 LOC) is the single canonical adapter list. `adapter::all()` delegates. Adding a 5th adapter is one line, one place.
- **primitives (v0.22 — `config.rs` decomposition):** `config.rs` 224 → 197 LOC. Extracted `time.rs` (90 LOC — `now_utc_string` + `format_epoch_utc` + `civil_from_days` + 5 unit tests covering epoch-0, leap-day 2020-02-29, century-non-leap 2100-03-01, arbitrary 2026-04-22, RFC3339 shape) and `config_migrate.rs` (114 LOC — `WireRecord` v1→v4 migration).
- **docs (v0.22 — README `## Reference` section):** major new section appended before `## Runtime hook controls`. Documents the actual CLI surface of every shipped component: 25 Rust primitives (clap subcommands + flags + state paths + exit codes extracted from `_primitives/_rust/*/src/main.rs`), 13 shell primitives (header docstrings + flags), all 10 hooks (event + severity + bypass table), 39 skills grouped into 6 collapsible categories, and a deep-dive on the `keisei` exobrain CLI (real flag matrix, exit codes, env vars, marker SSoT, v0.19 security hardening). Every claim is source-verified — flags not present in code are marked absent, not fabricated. Adds ~670 LOC to README.md; collapsible `<details>` used for the 39-skill table to keep scroll length reasonable.
- **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`).
- **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).
### Removed
- **primitives (v0.22 dead `Error` variants):**
- `Error::NotAttached` never surfaced; `detach` prints "nothing to detach" and returns `Ok(())`.
- `Error::AdapterFailed { client, reason }` never constructed; `mount` / `detach` orchestration carried `(client, reason)` tuples instead. Downstream matches on these variants won't compile against v0.22.
### Added (pre-v0.22)
- **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
- **primitives (v0.22 Track B — `kei-store` AsyncBackend trait + shared tokio runtime):**
- New `async_backend` module (gated behind `s3` feature) — introduces an `AsyncBackend` sub-trait (4 async methods: `get`/`put`/`list`/`list_recursive` + `label`) and a generic `AsyncBackendStore<B: AsyncBackend>` wrapper that implements `MemoryStore` on top of any backend. Adding a new cloud backend (GCS, Azure Blob, Bunny Storage, …) is now 6 methods, not a re-invention of the sync-over-async bridge.
- Shared process-global multi-thread tokio runtime via `OnceLock<Runtime>` — 2 worker threads, `enable_io + enable_time`. Replaces the previous per-instance `current_thread` runtime inside `S3CloudStore`, which caused a `block_on` panic when two `S3CloudStore` instances in one process interacted across threads (N=2-Store footgun).
- `S3CloudStore` is now `pub type S3CloudStore = AsyncBackendStore<S3AsyncBackend>`. Public API (`S3CloudStore::new(cfg)`, `.branch()`, `.current_branch()`, `.key()`, `.backend_name()`) preserved. New `S3AsyncBackend` struct in `s3_cloud/backend.rs` holds the `aws-sdk-s3::Client` and the bucket name; the sync wrapper handles branch-prefix + path-validation + commit-manifest.
- `validate_rel`, `short_hash`, `is_manifest_key` helpers moved from `s3_cloud/keys.rs` into `async_backend` (single source of truth for every future cloud backend). `s3_cloud/keys.rs` kept as a thin re-export shim so external callers and its unit tests keep working unchanged.
- New deps under `s3` feature: `async-trait 0.1` + `tokio` feature `rt-multi-thread`. No change to the default-feature dep graph.
- +7 tests (5 async_backend units + `two_store_instances` + `runtime_is_multi_thread`). Existing 46 tests (31 unit + 9 integration + 6 smoke) unchanged and green.
- 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`)
[Unreleased]: https://github.com/KeiSei84/KeiSeiKit/compare/v0.15.0...HEAD
[0.15.0]: https://github.com/KeiSei84/KeiSeiKit/compare/v0.14.2...v0.15.0
[0.14.2]: https://github.com/KeiSei84/KeiSeiKit/compare/v0.14.1...v0.14.2
[0.14.1]: https://github.com/KeiSei84/KeiSeiKit/compare/v0.14.0...v0.14.1
[0.14.0]: https://github.com/KeiSei84/KeiSeiKit/compare/v0.13.0...v0.14.0
[0.13.0]: https://github.com/KeiSei84/KeiSeiKit/compare/v0.12.0...v0.13.0
[0.12.0]: https://github.com/KeiSei84/KeiSeiKit/compare/v0.11.0...v0.12.0
[0.11.0]: https://github.com/KeiSei84/KeiSeiKit/compare/v0.10.0...v0.11.0
[0.10.0]: https://github.com/KeiSei84/KeiSeiKit/compare/v0.9.1...v0.10.0
[0.9.1]: https://github.com/KeiSei84/KeiSeiKit/compare/v0.9.0...v0.9.1
[0.9.0]: https://github.com/KeiSei84/KeiSeiKit/compare/v0.8.0...v0.9.0
[0.8.0]: https://github.com/KeiSei84/KeiSeiKit/releases/tag/v0.8.0