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.
The consolidation of the Knowledge OS into a single npm-workspaces monorepo with one
unified CLI. Three previously-separate packages and the live runtime hook now live and
ship together under loadout-os.
- Workspace monorepo —
packages/{kernel,memories,rules,cli}+apps/hookwired under one npm-workspaces root, with an intentional topological build order (kernel → memories → rules → cli) so the adapters build against the kernel's dist. - Unified
@mcptoolshop/loadout-osCLI (packages/cli) — one binary that wraps the three library surfaces (kernel = ai-loadout, memories, rules) and absorbs the operational rituals:- Namespaced adapter surfaces:
memories <index|validate|stats|health>andrules <analyze|validate|stats|split>. - Flat kernel verbs:
resolve,explain,usage,dead,overlaps,budget,validate(the kernel index-structure validator — the flat-vs-namespaced split is how thevalidatename collision is resolved). doctor— a read-only 8-check health screen over the live store, global index, runtime-hook drift, resolver layers, core entries, observability loop, hook wiring, and usage growth. Never writes.report— read-only observability overusage.jsonl: usage summary, dead entries, token budget, and a score distribution for calibrating the hook floor.refresh— the Index Freshness Ritual (index → validate → publish) folded into one command, with an andon halt on validation failure and a<dest>.bakcompensator on the one irreversible write.hook test— drive the runtime hook on a sample prompt in an isolated HOME.
- Namespaced adapter surfaces:
- Runtime hook unified (
apps/hook/loadout-hook.mjs) — theUserPromptSubmithook that injects ≤5 pointer lines (≤200 tokens). Fail-silent: every error path exits0. - Shared CLI substrate — one arg parser, one structured
CliError { code, message, hint }shape routed at the process boundary (no raw stack traces), and per-command--helpwith synopsis, arguments, flags, an example, and exit codes for every leaf command. - Documentation — a Starlight handbook (overview, getting started, architecture,
command reference, rituals, migration) connected to the landing page, plus a root
SECURITY.mdcovering the consolidated attack surface.
-
Index entries recorded the raw pointer instead of the resolved file (FT-MR11) —
generateIndexresolved each MEMORY.md reference correctly (trying the store dir, then its parent) and then discarded the result, storingref.pathverbatim. The store's own convention writes pointers asmemory/foo.md, wherememory/is a namespace label for the store rather than a subdirectory of it, sorefresh'srewritePathsAbsolutere-applied the prefix and emitted a doubled…/memory/memory/foo.md. On the canonical store that left 420 of 492 published entries (85%) pointing at files that do not exist — and because the UserPromptSubmit hook reads that published index on every prompt, every session was silently handed dead paths and fell back to paraphrasing one-line summaries, which is precisely what the store's own rule forbids. Entries now record the location that actually resolved, relative to the store root with POSIX separators, so both store layouts resolve. Live index went 72/492 → 492/492. Regression fixturefixtures/flat-store/pins the shape the original fixture never exercised: the previous fixture put MEMORY.md above itsmemory/directory, so every ref matched on the first base and the parent-base fallback was never under test. -
DEFAULT_STOREhardcoded one machine's home directory — the shipped default store path was an absolute literal containing a username, so it resolved on exactly one computer and leaked that username into a public package. It is now derived fromhomedir(), matchingdefaultDest()directly below it. -
Matcher recall (FT-K1) — domain entries were scored by pure coverage (
matched / declared keyword count), which starved keyword-rich entries: a genuine 2–3 keyword match on the live 30+-keyword entries scored below the 0.1 inclusion floor. The matcher now blends coverage with an absolute recall signal (max(coverage, matched / 5)), so real multi-keyword matches are reachable while single incidental hits stay quiet.
- The three legacy bins (ai-loadout, claude-memories, claude-rules) keep working until
their planned retirement; the unified
loadout-ospackage ships from this repo. The published upstream today remains@mcptoolshop/ai-loadout(the kernel).