{"$schema":"https://mfm.dev/schemas/skill.schema.json","generated":true,"source_of_truth":"https://github.com/MadeForMachine/mfm-skills","count":3,"skills":[{"slug":"atlas","name":"atlas","description":"Use when choosing, comparing, or integrating a third-party service, API, or SDK (auth, payments, email, storage, etc.). Query MadeForMachine Atlas — an intelligence engine for product and feature discovery and comparison — over MCP, jumping straight to the doc evidence for a capability instead of crawling a provider's docs or recalling from stale training data.","version":"0.1.0","latest_version":"0.1.0","status":"beta","connector":"mfm","requires":["atlas_capabilities","atlas_select","atlas_compare","atlas_provider","atlas_tree"],"license":"MIT","source_url":"https://github.com/MadeForMachine/mfm-skills/tree/main/skills/atlas","install":{"connector":"mfm","claude_path":".claude/skills/atlas/","agents_path":".agents/skills/atlas/"},"body":"You are about to evaluate an external service. Do **not** crawl the provider's docs and\ndo **not** answer from memory. Both fail the same way: docs overload you before you find\nthe part that matters, and recall is stale, version-blind, and unsourced.\n\nInstead, query **Atlas**, MadeForMachine's intelligence engine for product and feature\ndiscovery and comparison. It has already sent many agents through each provider's docs and\nrecorded, for every capability, **the exact doc node that evidences it**. Your job is not to\nre-read the docs — it is to let Atlas point you at the six URLs worth reading and skip the\nother fourteen hundred.\n\nThree things make this work, and you must respect all three:\n\n1. **Jump, don't crawl.** Every capability resolves to a grounded evidence URL. Follow the\n   jump; never start at a provider's docs root and walk down.\n2. **Read only what is pinned.** The doc tree flags which nodes carry evidence. Read the\n   pinned nodes and the reading list — nothing else.\n3. **Trust typed absence, not blank space.** A missing capability is one of two things:\n   `mined-absent` (\"we researched this area, it isn't there\" — a real non-feature) or\n   `dark` (\"we haven't researched here — unknown\"). **Never report `dark` as \"doesn't\n   support.\"** If a dark area decides the call, say so, or jump to that one provider URL and\n   read it yourself.\n\n## When to use\n\n- \"What should I use for X\", \"compare A vs B\", \"does X support Y\".\n- Before scaffolding an integration against a third-party service.\n- When pricing, limits, capabilities, or auth methods affect a decision.\n- When the user wants options weighed against real constraints, not one guess.\n\n## Tools (surgical — narrow input, exact answer)\n\nEach tool takes a tight query and returns a precomputed answer. Pass the narrowest input you\ncan; the power is in the precompute, not in options.\n\n1. `atlas_capabilities` — the controlled vocabulary: canonical capability terms and how many\n   providers ground each. Learn valid terms here *before* querying the field.\n2. `atlas_select` — query the whole field by **required** and **excluded** capabilities.\n   Returns matches **and** the transparent elimination: who was cut and on which missing\n   requirement, each absence typed `mined-absent` vs `dark`. The elimination is evidence,\n   not noise.\n3. `atlas_compare` — pivot a shortlist (2–4 providers) against one topic into a\n   capability-by-provider matrix. It also returns the **reading list**: the exact evidence\n   URLs to read to judge the topic across the shortlist. Read those, not the doc sites.\n4. `atlas_provider` — one provider's grounded capabilities, each with its evidence URL and the\n   coverage provenance (how thoroughly researched, which areas are dark).\n5. `atlas_tree` — the provider's **pinned** doc tree: depth-collapsed, each node flagged with\n   the capabilities grounded on it. Use it to find the one node to read when a `atlas_compare`\n   cell is dark or you need detail below a capability.\n\n## Workflow\n\n1. Restate the requirement as **hard constraints** (must-haves) vs **soft preferences**.\n2. If unsure of valid terms, call `atlas_capabilities` first — query the vocabulary, not free\n   text.\n3. `atlas_select` with the hard constraints. Read the elimination: a provider cut on a\n   `mined-absent` requirement is genuinely out; one cut on a `dark` area is *unknown*, not\n   out — flag it.\n4. Take the top 2–4 to `atlas_compare` on the deciding topic. Follow the **reading list** to\n   the evidence URLs; read those nodes, nothing more.\n5. Recommend one and say why — cite the capability terms, the evidence URLs, and the\n   coverage. Name the runner-up and the exact axis it lost on. If a `dark` area could change\n   the answer, say so plainly.\n\n## Rules\n\n- **Jump over crawl.** If you read a provider page, it should be one Atlas pointed you\n  to, not a page you found by walking their docs.\n- **`dark` is not `absent`.** Only a `mined-absent` edge is a real non-feature. Never let an\n  unresearched area read as \"doesn't support\" — that is the one mistake Atlas exists\n  to prevent.\n- **Cite the grounded URL.** Every capability claim you make should trace to an evidence node\n  Atlas returned, not to recall.\n- **The term-set is the summary.** Don't ask for or synthesise prose blurbs; compare on the\n  machine-readable capability terms.\n- **Don't invent.** No capability, limit, or price that isn't in a grounded answer.\n- **Surface coverage honestly.** If the field is thinly researched for this requirement, say\n  so and fall back to reading the specific provider URL — never to ungrounded recall.","changelog":"# Changelog — atlas\n\nAll notable changes to the Atlas skill. Entries marked **MAJOR** change the\nskill's behaviour or the tools it depends on; plan to re-read the skill after a\nmajor bump.\n\n## 0.1.0 — 2026-06-27 (pre-release)\n- Initial draft of the Atlas wayfinding skill: jump-don't-crawl, read-only-what-is-pinned,\n  and typed absence (`mined-absent` vs `dark`).\n- Renamed from `mfm-catalog` to `atlas` — Atlas is the engine's name, and the `mfm-` prefix\n  is redundant inside the mfm namespace.\n- Depends on the Atlas MCP tools (`atlas_capabilities`, `atlas_select`, `atlas_compare`,\n  `atlas_provider`, `atlas_tree`) — now reconciled with the served MCP surface: these are the\n  real read tools registered in `mcp/atlas_tools.py`, pass-throughs to the public `/v1/atlas`\n  plane.\n"},{"slug":"mfm-spec","name":"mfm-spec","description":"Use when working with hosted MFM Spec: a spec stored in the MadeForMachine service and read, mutated, validated, and versioned through MCP tools. Use for service-backed spec authoring, minimal-context reads, fine-grained spec mutations, validation, history, and evaluation notes. Do not use for local file-backed specs; use the mfm-spec-local skill for that.","version":"0.3.0","latest_version":"0.3.0","status":"alpha","connector":"mfm","requires":["mfm_spec_read","mfm_spec_validate","mfm_spec_mutate","mfm_spec_rename","mfm_spec_merge","mfm_spec_split","mfm_spec_retire","mfm_spec_write","mfm_spec_history","mfm_spec_import","mfm_spec_export"],"license":"MIT","source_url":"https://github.com/MadeForMachine/mfm-skills/tree/main/skills/mfm-spec","install":{"connector":"mfm","claude_path":".claude/skills/mfm-spec/","agents_path":".agents/skills/mfm-spec/"},"body":"MFM Spec is the hosted MadeForMachine product that uses the MFM Spec format as its\nportable artifact, but keeps the canonical working spec in a service-backed revision store.\nYour job is to steer the user's own agent: discuss, interrogate, read minimal context,\nmutate through deterministic MCP tools, and let server validation guard the graph.\n\nIf the `mfm_spec_*` MCP tools are not available, do not pretend to persist anything. You may\nshape the intended change in the conversation, but stop before commit and report that the\nMFM Spec connector/tooling is missing.\n\n## Scope\n\nWork at the MFM Spec MVP graph level:\n\n- **Components** — responsibility owners.\n- **Features** — observable behavior linked to the components they need.\n- **Evaluations** — feedback or judgment records against a feature, component, revision,\n  variant, or artifact.\n\nDo not choose technologies, UI layouts, data schemas, implementation plans, or code. Park\nthose as lower-layer details or open questions on the relevant node.\n\n## Read Small\n\nStart every session with `mfm_spec_read` using `view=map`. Keep the whole map in context:\nnode id, kind, status, parent, and edge summary. Load full bodies only for the active blast\nradius:\n\n- `view=node` for one full node,\n- `view=subtree` for a component branch,\n- `view=referrers` for everything pointing AT one node — children, dependents, touching\n  features, evaluation subjects — the blast radius to query before any identity change,\n- named projections such as `authoring-map`, `feature-work`, or `derivation-context` when\n  the task has a stable slice shape.\n\nThe persisted spec is the memory. The chat is disposable.\n\n## Interrogate First\n\nLet the user dump raw intent before formalizing. Classify it into components, features,\nevaluations, open questions, and lower-layer details. Propose the smallest touched node set,\nthen surface the one or two boundary questions that would change the graph.\n\nAlways name the touched nodes before mutating. A request rarely affects one node; trace the\nblast radius across dependencies, feature touches, and evaluation subjects.\n\n## Mutate Through Tools\n\nThe normal commit path is `mfm_spec_mutate`, not whole-node replacement. Use\n`mfm_spec_validate` first when the change is non-trivial or when you expect a repair loop.\nEvery mutation carries the `base_rev` from the last read.\n\nMVP operations are deliberately small and deterministic:\n\n- create node,\n- delete node,\n- move node,\n- set frontmatter field,\n- add/remove dependency,\n- add/remove feature touch,\n- replace or append a named body section,\n- record evaluation node.\n\nUse `mfm_spec_write` only for import/bootstrap or as an escape hatch when the user already\nintends to replace whole nodes. It is not the normal authoring primitive.\n\n## Reorganize Through Intents, Not Cascades\n\nA node's id is its identity. When the shape of the spec is wrong — a node is misnamed, two\nnodes are one, one node is two, a responsibility is gone — do NOT hand-compose the change\nfrom primitive ops, and never end an identity change in `delete_node`: that destroys the\nprovenance the graph is for. Use the dedicated intents:\n\n- `mfm_spec_rename` — recreates under the new id, repoints every live referrer, supersedes\n  the old id. Fully deterministic; you supply nothing but the ids.\n- `mfm_spec_merge` — you author the successor (`into`: a create payload, or an existing\n  node id to absorb into); the server wires: referrers repoint, each merged node gets\n  `status: superseded` and `superseded_by` → successor.\n- `mfm_spec_split` — you author the successor payloads and `reassign` each live referrer to\n  the successor it now needs; the server refuses to guess an unassigned referrer.\n- `mfm_spec_retire` — for a responsibility that is gone, not relocated. Refused while live\n  nodes still reference it; the refusal lists them.\n\nThe loop is always: `view=referrers` on the affected node → name the blast radius to the\nuser → issue the intent with the current `base_rev`. Superseded nodes stay in the graph as\nprovenance; evaluations keep pointing at them by design.\n\nIf a write is rejected because `base_rev` is stale, re-read the map and the changed nodes,\nreconcile the user's intent against the new head, and resend a fresh mutation batch. Never\nforce through a conflict.\n\n## Validation Boundary\n\n`mfm_spec_validate` and `mfm_spec_mutate` both apply the proposed operations to the base\nrevision, parse the resulting MFM Spec graph, and run the deterministic lint rules. A\nfailed validation changes nothing. Treat the error report as the source of truth for\nstructural validity; semantic quality remains your job.\n\nLoad-bearing errors:\n\n- exactly one root component,\n- all parents, dependencies, feature touches, and checked evaluation subjects resolve,\n- component and dependency graphs are acyclic,\n- component responsibilities, feature intents, and evaluation summaries are one sentence.\n\n## Evaluation Notes\n\nWhen feedback arrives, record it as an `evaluation` node instead of burying it in chat or\nrewriting intent silently. Evaluations may point at a component, feature, revision, variant,\nartifact, or any combination. They record what was learned; a later explicit mutation\npromotes that lesson into the spec.","changelog":"# Changelog — mfm-spec\n\n## 0.3.0 — 2026-07-02\n**MAJOR.** Reorganization becomes first-class: intents, not hand-composed cascades.\n- New required tools: `mfm_spec_rename`, `mfm_spec_merge`, `mfm_spec_split`,\n  `mfm_spec_retire` — deterministic server-side macros over the primitive ops; the agent\n  authors content (a merged responsibility, a split's division), the server does the wiring.\n- New `view=referrers` on `mfm_spec_read`: everything pointing at one node — the blast\n  radius to query before any identity change.\n- Identity changes supersede the predecessor (`status: superseded`, `superseded_by`)\n  instead of deleting it, per MFM Spec format v0.4; provenance stays queryable.\n- Driven by the reorg dogfood (`mfm-spec-reorg-dogfood`): a rename was a hand-traced 6-op\n  cascade, a merge 15 ops ending in a provenance-destroying delete.\n\n## 0.2.1 — 2026-06-30\n- Publishes the hosted MFM Spec skill for pilot setup.\n- Adds `mfm_spec_import` and `mfm_spec_export` to the declared tool requirements.\n- Documents that installation needs both the skill and the authenticated `mfm` MCP server.\n\n## 0.2.0 — 2026-06-29\n- Renames the hosted skill from `mrspec` to `mfm-spec`.\n- Renames required MCP tools from `mrspec_*` to `mfm_spec_*`.\n- Points local file-backed work to `mfm-spec-local`.\n\n## 0.1.0 — 2026-06-29\n- Initial alpha hosted-skill split from local MFM Spec.\n- Defines MFM Spec as the hosted MCP/database product using the MFM Spec format.\n- Makes `mfm_spec_mutate` the normal authoring primitive, with `mfm_spec_write` reserved for\n  import/bootstrap and escape-hatch whole-node replacement.\n"},{"slug":"mfm-spec-local","name":"mfm-spec-local","description":"Use when creating or evolving MFM Spec as local project files. Collaboratively turn rough software intent into a typed graph of components, features, and evaluation notes; design, architect, reorganize, review, trace feature/component impact, or document feedback against a spec revision. For hosted service-backed MFM Spec, use the mfm-spec skill instead.","version":"0.7.0","latest_version":"0.7.0","status":"mvp","connector":null,"requires":[],"license":"MIT","source_url":"https://github.com/MadeForMachine/mfm-skills/tree/main/skills/mfm-spec-local","install":{"connector":null,"claude_path":".claude/skills/mfm-spec-local/","agents_path":".agents/skills/mfm-spec-local/"},"body":"> Part of **MFM** · [mfm.dev](https://mfm.dev)\n\nThe local MFM Spec skill gets a software system out of your head and into a versioned,\nagent-readable specification: a typed graph of components, features, and evaluation\nnotes. It is precise enough for an agent to slice, validate, and later derive from,\nand clear enough for a human to read and argue with.\n\n## What you are doing\n\nYou are helping a user get software intent out of their head and into a valid\nMFM Spec — one precise enough for an agent to work against later, and clear\nenough for a human to read now.\n\nYour value is **not transcription — it is interrogation.** The user knows their\nsystem tacitly. Most of it is fuzzy and unexamined until they try to put it into\nwords; the act of articulating it is what exposes the gaps. Your job is to pull\nthat tacit understanding into the open, find the parts that are vague,\noverlapping, or contradictory, and shape it into a clean, well-reasoned spec graph.\nIf you find yourself just writing down what the user said without\nquestioning it, you have become a worse text editor. Push on it.\n\n## Scope: the MVP spec graph, and nothing below it\n\nWork at the MFM Spec MVP level:\n\n- **Components** — structural owners of responsibility. A component answers:\n  where does this responsibility live?\n- **Features** — observable behavior. A feature answers: what can an actor do or\n  observe, and which component capabilities does that behavior require?\n- **Evaluations** — lightweight feedback/judgment notes against a feature,\n  component, revision, variant, or artifact. An evaluation records what was learned;\n  it does not mutate intent by itself.\n\nAt this stage, do **not**:\n\n- choose technologies, frameworks, or libraries,\n- write UI/UX layouts,\n- design data schemas,\n- produce implementation plans,\n- write or scaffold any code.\n\nThose are lower layers. If the user drifts into \"Postgres or Mongo?\" or \"the login\nform needs a remember-me checkbox,\" don't follow them down. Capture the durable\nintent or open question on the relevant node and steer back to the graph. Keeping\nthis level free of implementation detail is what keeps it portable, sliceable, and\ncheap to revise.\n\n## What you produce: one file per node, two parts each\n\nFor every node, write a single file with two parts: structured **frontmatter**\nthat an agent reads, and a prose **body** that carries the reasoning a human reads.\nThe same content cannot serve both audiences well, so split it deliberately.\n\n```yaml\n---\nid: routing-engine          # stable, lowercase, hyphenated\ntitle: Routing engine\nkind: component             # every node declares its kind\nparent: api-service         # id of the parent component, or null at the root\nresponsibility: Decide where each inbound item is delivered.   # exactly one sentence\ntier: core                  # core | experimental\nstatus: open                # draft | open | decided | superseded\ndepends_on: [identity, delivery]   # ids of the components this one needs\nopen_questions:\n  - sync or async dispatch?\n  - retry policy on delivery failure?\n---\n\n## Why\nRouting is its own component because delivery rules change far more often than\nidentity or transport, and we want to change them without touching either.\n\n## Contract\nProvides: a delivery decision for each inbound item.\nConsumes: recipient identity from `identity`, transport channels from `delivery`.\n\n## Essential vs accidental\nEssential: every item is routed exactly once; routing decisions are pure (no I/O).\nAccidental: how dispatch is actually carried out — that is a lower-level choice.\n\n## Rejected\nFolding routing into a worker — it couples policy changes to infrastructure\nchanges, exactly the entanglement that makes a system hard to evolve.\n```\n\nFeature:\n\n```yaml\n---\nid: refund\ntitle: Refund a payment\nkind: feature\nparent: null\nintent: A customer can reverse a completed purchase and get their money back.\ntier: core\nstatus: open\ntouches:\n  - { component: payment, needs: reverse a captured charge }\n  - { component: inventory, needs: restock returned items }\nopen_questions:\n  - partial refunds, or full only?\n---\n\n## Behavior\nGiven a completed order, when a refund is requested within the allowed window, the\nmoney returns to the original method and stock is restored.\n\n## Acceptance\n- A refund never exceeds the original charge.\n- Stock is restored exactly once.\n\n## Rejected\nStore credit instead of money-back — changes the user's mental model of \"refund.\"\n```\n\nThe `touches` link has two halves: `needs` is the durable capability, while\n`component` is the current binding. \"Reverse a captured charge\" is a capability;\n\"call RefundService\" is an implementation-shaped demand and does not belong here.\n\nEvaluation:\n\n```yaml\n---\nid: refund-v1-evaluation\ntitle: Refund v1 evaluation\nkind: evaluation\nsubject:\n  feature: refund\n  rev: \"abc123\"\nverdict: mixed\nsummary: Customers understood refunds but expected partial refunds from day one.\nevidence:\n  - customer interviews\npromotes_to_spec:\n  - Partial refunds are core behavior.\nrejects:\n  - Full-refund-only MVP.\n---\n\n## Notes\nThe evaluation records the human/customer judgment. It does not rewrite the feature\nby itself; use it as evidence when evolving the spec.\n```\n\n**The body is the point.** Named sections (`## Why`, `## Contract`,\n`## Behavior`, `## Acceptance`, `## Notes`, `## Rejected`, `## Decisions`) are\nwhere tacit reasoning, behavior, and feedback get captured — the things normally\nlost when the conversation ends. A crisp frontmatter line with no reasoning is just\na ticket. Push for the reasoning, not just the label.\n\nStore one file per node. Component files mirror the component tree; feature files\nlive under `features/`; evaluation files live under `evaluations/`. The output\nconforms to **MFM Spec format v0.3** — the normative field set, body contract, and\nintegrity rules are in `SPEC.md`.\n\nA spec has **exactly one** `mfm-spec.yaml` root manifest, at its top level. Write\nit **only when starting a new spec**; if you are extending an existing spec it\nalready has one — never add a second. It declares the format version and names the\nsingle root component, so the spec is self-identifying:\n\n```yaml\nspec_format: \"0.3\"\nname: \"<the system's name>\"\nroot: <id of the root component>   # the one component whose parent is null\ncreated: \"<today, ISO date>\"\n```\n\n## Where the spec lives: local project files\n\nMFM Spec stores the spec as files in the user's project. There is no hosted backend in\nthis skill, no account, no connector, and no MCP write path. The source of truth is the\nspec directory itself: one `mfm-spec.yaml` manifest plus one Markdown file per node.\n\nDo not require git. If the project is a git repo, the user may version the spec with the\nrest of the project; if it is not, MFM Spec still works. Your hard guarantee is the\nreference linter, not a VCS.\n\n## First: new spec, or extending an existing one?\n\nFind out whether a MFM Spec already exists. Look for a `mfm-spec.yaml` or any node\nwhose `parent` is `null`.\n\n- **If one exists, you are *extending* it.** Read the existing manifest and map\n  first. New components attach under an existing component; new features live as\n  feature nodes (`parent: null` unless grouped under another feature); evaluations\n  live as evaluation nodes with a `subject`. Do **not** write a second\n  `mfm-spec.yaml`, and do **not** introduce a second component with `parent: null`.\n  A spec has exactly one root component.\n- **If none exists, you are *creating* a new spec.** Proceed below; you will write\n  the one root component (`parent: null`) and the one `mfm-spec.yaml` manifest.\n\nGetting this wrong is the most damaging mistake at this layer: a second root\nsilently forks the tree into two disconnected specs. The consistency check below\ncatches it — but recognize it here first.\n\n## How a session goes\n\n1. **Let the user dump.** Start by letting them describe what they want in their\n   own words, unstructured. Don't interrupt to formalize. You are trying to get\n   the raw material out first.\n\n2. **Classify before shaping — commit nothing yet.** Sort the raw material into:\n   components (responsibility owners), features (observable behavior), evaluations\n   (feedback/judgment), open questions, and lower-layer details to park. Then\n   propose the *fewest* components and features that cover what they said. Surface\n   the one or two questions whose answers would move boundaries or feature\n   acceptance. Write nothing yet.\n\n   The move looks like this:\n\n   > \"I'm hearing three components — Ingestion, Routing, Delivery — and one feature,\n   > Feed item delivery. The boundary question is the rules: if users author them,\n   > Account owns policy; if they're fixed, Routing owns it. Which is it?\"\n\n3. **Let them steer; revise.** They'll merge things, split things, correct\n   boundaries, add what you missed. Update the proposed tree in the conversation.\n\n4. **When they're happy, persist.** Only once the touched node set has settled do\n   you write the local node files and run the reference linter. One settled working\n   session should leave the spec directory valid.\n\n## Resist over-decomposition\n\nThe most common failure is splitting too early into too many components. **Start\ncoarse.** A component earns its own split only when something concrete forces it —\nnot because it \"feels like\" a separate thing. A sprawl of tiny components is how\narchitectures become unmanageable, and it is far easier to split a component later\nthan to merge two that should never have been separated. When in doubt, fewer.\n\n## Attend to the whole picture — that is your job, not theirs\n\nThe user cannot hold the entire system in their head; that is precisely why they\nneed you. So a new request almost never lands on a single node. When they say\n\"ingest YouTube, podcasts, and blogs, and show them in the feed,\" do not just add\na source adapter and move on. Trace the request across components and features,\nthen surface the ripples they didn't mention. For that example:\n\n- new source adapters affect **Ingestion**,\n- but the three media differ — video, audio, text — so the **content model** has\n  to handle heterogeneity,\n- and the **Feed item delivery** feature displays items, so its behavior and\n  acceptance are in the blast radius too.\n\nThen place each part where it belongs and update the dependency/feature edges.\n**Always tell the user which nodes a change touches, as a short list,** so they can\nsee — and check — that you saw the whole. Your catching the ripple they'd have\nforgotten is the main reason this is worth doing at all.\n\n## Keep the conversation steerable — offer actions\n\nAlongside normal discussion, give the user low-friction ways to steer you. Surface\nthem as short suggested actions when they fit the moment:\n\n- **direction:** \"go deeper here\", \"zoom out\", \"explore an alternative\", \"park this and move on\"\n- **stance:** \"challenge me\", \"push back harder\", \"steelman the opposite\"\n- **phase:** \"finalize this\"\n\nThe **stance** actions matter most, because they let the user dial how hard you\npress. Keep \"challenge me\" and \"push back harder\" always available — never withhold\nthem — because a too-agreeable assistant is exactly the one that won't think to\noffer them.\n\nAnd when you push back, push back **honestly.** \"Challenge me\" is a request for\nreal scrutiny, not manufactured opposition. Press where there is a genuine weak\nspot; when the reasoning holds, say so plainly — \"I leaned in here and it holds;\nthe one soft spot is X\" — rather than inventing a fight to look busy. Performative\ndisagreement is as useless as performative agreement.\n\nWhen the user picks **\"finalize this,\"** present what you are about to write — the\nnodes, their responsibilities/intents/verdicts, what changed, and which files you'll\ntouch — and let them confirm, or send you back for another round, before you commit.\n\n## Keep context small\n\nAlways keep the whole **map** in view: every node's id, kind, status, parent, and\nedge summary (`responsibility`/`depends_on`, `intent`/`touches`, or\n`summary`/`subject`). The map is small and lets you reason about the entire system\nat once. Load full **bodies** only for the nodes and sections you are actively\nworking on.\n\nIf a session runs long, **checkpoint** rather than letting it sprawl: persist\neverything decided so far to local files, write a short handoff note — what's\ndecided, what's still open, what's next — and suggest starting a fresh session that\npicks up from the persisted spec and the note. Nothing important should live only in\nthe conversation. The persisted spec is the memory; the chat is disposable.\n\n## Persistence\n\nThe tree rots silently if links break, so the spec must never be left inconsistent —\nand nothing important may live only in the chat. The authoritative integrity rules are in\n`SPEC.md`; the load-bearing errors are:\n\n- **exactly one root** — one component has `parent: null`, and the manifest's `root`\n  names it (`spec/single-root`); and **exactly one** `mfm-spec.yaml`\n  (`spec/declared-format`),\n- every `parent`, `depends_on`, `touches[].component`, `superseded_by`, and checked\n  evaluation subject resolves, and component/dependency graphs are acyclic,\n- every component `responsibility`, feature `intent`, and evaluation `summary` is\n  one sentence.\n\nWhen a reorganization renames, merges, splits, or retires a node, do not delete the\npredecessor: mark it `status: superseded`, list its successors in `superseded_by`,\nand repoint every live referrer to the successor — provenance stays in the graph\n(see \"Node lifecycle and supersession\" in `SPEC.md`).\n\nAnd the warnings worth heeding: two components sharing a responsibility\n(they are probably one), a feature without `## Acceptance`, an untouched live leaf\ncomponent in a feature-bearing spec, a live edge still pointing at a superseded node\n(a repoint the reorganization missed), and a `decided` node still carrying\n`open_questions` (it is `open`, not `decided`).\n\n- **Validate before finishing.** Run the reference linter over the spec dir and\n  make it pass with zero errors before calling the change done:\n\n      python3 mfm_spec_lint.py <spec-dir>\n\n- **Version only if available.** If the project uses git and the user expects commits,\n  commit the session at the level of decisions, not files: \"initial decomposition: 3\n  components, 4 open questions\" or \"resolved 2 open questions on routing.\" If there is no\n  git repo, do not invent one.\n- **Branch only when the user wants alternatives.** Branches are useful for exploring a\n  different architecture, but they are not part of the MFM Spec format.\n\nThe persisted spec is the memory, the chat is disposable.\n**Nothing is final** — a spec is one possible structure, and the user (or someone\nelse) may branch or revise it. Finalizing is provisional, not permanent: never treat\na decision as locked forever, and never stall waiting to be certain before you let\nthe user finalize.\n\n## What good looks like\n\nYou are doing well when the spec is something the user could not have written\nalone: the structure is cleaner than their first description, features traverse the\ncomponent graph without freezing an implementation, feedback is recorded as\nevaluations instead of vanishing into chat, and cross-cutting impacts were caught\nbefore they bit. The anti-patterns are the inverses — transcribing instead of\ninterrogating, over-splitting into tiny components, features that smuggle in\nimplementation, empty *whats* with no *why*, and smoothing over the boundary-\ndeciding questions to keep things pleasant.","changelog":"# Changelog — mfm-spec-local\n\nAll notable changes to the MFM Spec local skill. Entries marked **MAJOR** change the\nskill's behaviour or the MFM Spec format it targets; plan to re-read the skill\nafter a major bump. The skill version tracks the skill itself; the MFM Spec\nFormat version it targets is noted per release.\n\n## 0.7.0 — 2026-07-02\n**MAJOR.** Targets MFM Spec format **v0.4**, which adds node supersession —\nprovenance-preserving reorganization instead of hard deletes.\n- New `superseded` status and `superseded_by` edge: a renamed, merged, split, or\n  retired node stays in the graph and points at its successor(s).\n- New lint rules: `spec/superseded-by-exists` and `spec/superseded-shape` (errors),\n  `spec/live-edge-to-superseded` (warn — a repoint the reorganization missed).\n- `spec/component-untouched` now warns only on **live leaf** components, so grouping\n  parents introduced by a reorganization and superseded nodes stop emitting\n  unavoidable warnings.\n- `spec/distinct-responsibilities` likewise counts live components only — a rename's\n  tombstone keeps its responsibility as provenance, identical to its successor's.\n- v0.1–v0.3 specs remain valid; the change is additive.\n- Driven by the hosted reorg dogfood (`mfm-spec-reorg-dogfood`): merge previously\n  ended in `delete_node`, losing the record of what absorbed what.\n\n## 0.6.0 — 2026-06-29\n**MAJOR.** Renames the local skill from `specifold` to `mfm-spec-local`.\n- Keeps **MFM Spec** as the single product/format name.\n- Uses `mfm-spec.yaml`, `mfm-spec.schema.json`, and `mfm_spec_lint.py` for the local file format bundle.\n- Points hosted service-backed work to the separate `mfm-spec` skill.\n\n## 0.5.0 — 2026-06-29\n**MAJOR.** Splits hosted service authoring out of MFM Spec.\n- MFM Spec is now local-file-backed only: node files plus `mfm-spec.yaml` in the user's\n  project, validated by the bundled linter.\n- Git is optional, not a source-of-truth assumption.\n- The hosted MCP/database mode is now **MFM Spec** and lives in its own skill.\n\n## 0.4.0 — 2026-06-29\n**MAJOR.** Targets MFM Spec format **v0.3** and moves the skill from\ncomponent-only authoring to MVP graph authoring.\n- Adds `evaluation` nodes as the minimal durable feedback record: subject, verdict,\n  summary, evidence, promoted lessons, and rejected ideas.\n- The skill now classifies raw user input into components, features, evaluations,\n  open questions, and lower-layer details before shaping the spec.\n- Updates the bundled linter and schemas to understand v0.3 while keeping v0.1/v0.2\n  specs readable.\n\n## 0.3.0 — 2026-06-27\n**MAJOR.** Dual-backend persistence — one skill, two places a spec can live.\n- The interrogation brain is unchanged; only the **persistence tail** forks. The\n  backend is an explicit up-front choice (*\"local files or the MFM service?\"*), never\n  inferred from whether the MFM connector is configured.\n- **Local mode** is the existing behaviour: node files, the reference linter, git.\n- **Service mode** reads and writes the canonical server-stored spec through the\n  MadeForMachine MCP tools (`spec_read` / `spec_write`), validated server-side by\n  `spec-core` — the same rules as the local linter, so consistency can't drift\n  between backends. Covers the `base_rev` conflict and server-side validation loop.\n\n## 0.2.0 — 2026-06-27\n**MAJOR.** Targets MFM Spec format **v0.2** (architecture layer + feature layer).\n- Skill now lives in the `mfm-skills` repo at `skills/mfm-spec-local/` (was its own repo).\n- Primary install is the version-pinned [mfm.dev/skills/mfm-spec-local](https://mfm.dev/skills/mfm-spec-local)\n  page; manual clone of `mfm-skills` is the fallback.\n- Carries manifest frontmatter (`version`, `status`, `public`, `connector`, `requires`, `license`).\n\n## 0.1.0\n- Initial pilot release: architecture-layer interrogation with the bundled reference\n  linter (`mfm_spec_lint.py`) and the open MFM Spec format definition (`SPEC.md`).\n"}]}