# Changelog All notable changes to claude-faf-mcp will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [7.0.1] - 2026-09-30 **faf-cli 8.0.1 inside: pnpm installs work, and fast-uri is out of two moderate advisories.** Patch — inherits The Always33 Edition. 513 tests. ### Fixed - **faf-cli 8.0.1.** faf-cli 8.0.0 pointed at a `vendor/` folder inside its own package, so pnpm installs of claude-faf-mcp (and Glama's pnpm build) stopped with `ERR_PNPM_LINKED_PKG_DIR_NOT_FOUND`. The lockfile and the Claude Desktop `.mcpb` now carry faf-cli 8.0.1, which gets `faf-scoring-kernel` from npm. `package.json` keeps `faf-cli ^8.0.0`. - **fast-uri 4.2.1** (runtime, through `ajv`): out of GHSA-hrr3-gc8f-f4qj and GHSA-jvvf-x445-j334, both moderate. The override is now `>=4.1.5`, the first release outside both. `npm audit` reports 0 vulnerabilities. - `brace-expansion` 1.1.21 and 2.1.7 (dev only, #128) and `ip-address` 10.7.2. ### Tests - #80 reads `npm pack --json` from npm 10 (an array) and npm 12 (an object keyed by name). - The major-release callout check names the major (7.0.0), so a patch keeps it. ## [7.0.0] - 2026-09-26 — The Always33 Edition **One engine, one number: claude-faf-mcp 7 scores with faf-cli 8's always-33 kernel — the same score faf-cli and faf-kernel give.** 513 tests. **7.0.0 is a major release because scores can move.** A `.faf` without the 12 enterprise `slotignored` markers now counts them as empty (21 filled = 64%). Run `faf_auto` — it writes the markers and the score returns (a v7-era faf-python-sdk file: 56% → ✪ 100%). Anything that gates on `faf_score` should re-check its threshold. ### Changed - **The always-33 engine.** claude-faf-mcp composes **faf-cli ^8.0.0** (was ^7.13.1, which could never resolve 8.x). Every tool's score is faf-cli 8's `scoreFafYaml`: all 33 Mk4 slots, one Rust kernel (`faf-scoring-kernel` 3.0.0). Verified live: `faf_score` on faf-python-sdk 56, mcp-context-card 56, faf-cli ✪ 100 — identical to faf-cli 8.0.0 and the reference always-33 scorer. - **The 12 enterprise slots stay in view.** faf-cli fills the 21 base slots and marks the 12 enterprise slots `slotignored` unless your app-type uses them; `faf_score` scores against all 33, and `slotignored` slots drop out of the denominator. - `tbd` and `todo` (any case) count as empty (faf-cli 8). - Compose floor: `faf-cli ^8.0.0`, pinned by `tests/wjttc-600-r2-closed-list.test.ts` (R2-8). ### Tests - The 100% fixtures are written the faf-cli way — 21 slots + the 12 enterprise markers. ## [6.0.0] - 2026-09-13 — The Earned Badge Edition **Every badge earned, none claimed: claude-faf-mcp 6.0 composes faf-cli, touches only what it wrote, and every tool tells the truth — one score, facts from repo, nothing from your PATH.** **6.0.0 is a major release.** It needs Node 22 or later. Four tools and the interop imports are retired (see Removed). The `.mcpb` runs the server bundled inside it. The npx config and the SessionStart hook stay unpinned, so an install that runs `npx -y claude-faf-mcp` moves to 6.x on its next start. ### Security - Every read of project context and every write goes through faf-cli's safe path. A project.faf, CLAUDE.md, AGENTS.md, soul.fafm, .faf-dna, MEMORY.md or .claude/settings.json that is a link out of the project is refused: never read into a reply, never written through (faf_status, faf_dna, faf_sync, faf_auto, faf_etch, faf_tri_sync, faf_setup and the SessionStart hook). - The copilot and conductor exports make their folder inside the project, and a `.github` or `conductor` that links out of it is refused. - faf_debug no longer writes and deletes a probe file to test write access. It asks the OS, so a `.claude-faf-test` of yours, or a link by that name, is left alone. - Correction to the 5.x path-confinement note below: it covered only the `path` argument. A context file that was itself a link out of the project was still followed until this release. - One path resolver for every tool. Your home folder and the filesystem root are refused by faf-cli's device-and-inode check, so no other spelling of home (upper case, a link) gets past it. It covers every writer and the SessionStart hook, and it refuses before the active project moves: a refused call leaves the active project where it was. - faf_go answers take only slot paths faf-cli knows (its interview and its slot table), the caller's own keys, and text. `__proto__`, `constructor` and `prototype` are refused at any depth, so an answer can no longer turn on another tool's `force` or change its path. One bad key refuses the whole call, and nothing is written. - Tool arguments are read as the caller's own keys only: a flag or a path the caller did not send is never read from Object.prototype. - faf_read and faf_list reach only the active project and FAF_ALLOWED_ROOTS: no temp folders, never your home folder or the filesystem root. A relative path resolves against the active project. faf_list is confined like faf_read and lists a link without following it. (The 5.x note below said cwd plus the system temp folders.) - faf_git checks out a repo's links as plain files, so a link in a repo can never make faf read a file outside the clone. - A test clones a real repo whose README.md is a link to a secret file outside it: the secret's text is in no reply and no file. Without `core.symlinks=false` the same test fails. - The registry workflows pin mcp-publisher (v1.8.1) and check its sha256, pin trufflehog to a commit, pass the DNS key through the environment (never a command line), and pass the sibling workflow's inputs through the environment instead of into the script. - The dependency tree passes `npm audit --audit-level=high` again: js-yaml 4.3.2 (through eslint, a dev dependency) and hono 4.13.7 (through @modelcontextprotocol/sdk; the override floor is now >=4.13.5), and tmp >=0.2.6 for @anthropic-ai/mcpb's prompt library. ### Fixed - Every write is atomic. A full disk, a quota or a read-only file leaves the file exactly as it was, and the message says "not written; original kept". - faf_human_add, faf_go answers and faf_readme edit project.faf in place through faf-cli. Comments, key order, exact values (`1.10`, a 20-digit id, `0x1F90`), anchors and your own `_meta` survive, and a change that changes nothing writes nothing. - faf_auto names every value the file held that the fill changed, instead of saying "existing values kept". A typed None or placeholder word is an empty slot and scores 0: in a tech slot the app-type uses, only a repo fact replaces it, and with no fact it stays as typed; in a tech slot the app-type leaves out, faf_auto writes `slotignored`; a 6W keeps your words (faf_go asks). - faf_auto reports each file on its own ("project.faf updated; CLAUDE.md not written: …"), so a CLAUDE.md that cannot be written never hides a project.faf that was. - faf_agents, faf_cursor, faf_gemini and the copilot export no longer refuse an existing file or take `force`. They put faf's block on top (or update it in place) and keep every other byte. - faf_etch and faf_recall use faf-cli's soul. A hand-kept index, comments, the version, facts or sessions in another shape and unknown keys survive an etch; re-etching an id merges into that fact; faf_recall prints bare-string facts; faf_etch creates no folders. The local soul copy is gone. - faf_conductor writes one faf-managed block into each conductor/ file and keeps every line you wrote. `force` is gone. The content comes from project.faf's own keys: goal, language, stack, commands and the 6Ws. - faf_readme apply fills only empty human_context slots, never replaces a value you wrote, lists what it filled, and writes nothing when nothing changed. `force` is gone. - faf_quick builds on faf-cli's detection: no invented TypeScript or "cloud", no timestamp, server-version or `initialized_by` keys, and a framework goes in stack.frontend or stack.backend only when faf-cli knows which (otherwise it says so). It refuses a folder that already has a project.faf or .faf (use faf_auto) and your home folder. `force` is gone. - Advice points at the fix. A YAML error names the file:line:col to edit by hand, a comments-only file is called "no keys", and no message tells you to force or recreate a file you wrote (faf_score, faf_doctor, faf_init, faf_sync and the exports). - faf_init `force: true` replaces project.faf with a fresh one, after copying the old file to `project.faf.bak-