Skip to content

Latest commit

 

History

History
440 lines (326 loc) · 107 KB

File metadata and controls

440 lines (326 loc) · 107 KB

Changelog

All notable changes to this project are documented in this file.

Format inspired by Keep a Changelog, versions follow Semantic Versioning.

[Unreleased]

Changed

  • The ADR index invariant becomes a check (test/check-adr-index.sh, dogfood only). On 2026-09-21 an ADR landed on main without its row in docs/decisions/README.md and survived, because the only thing guarding that invariant was a line in the release checklist — read at release, days after the omission. A set comparison has exactly one correct answer, so it is a check, not a reminder, and not an eval case: an eval measures whether configuration changes behaviour, which is the wrong instrument for is every file listed. The script compares both directions — a file with no row, a row with no file — and flags duplicates, since a row listed twice reads as agreement until someone diffs them. Deterministic, offline, zero tokens; verified to fail as well as pass. It runs on every pull request (.github/workflows/adr-index.yml — one workflow, one job, one step; the stack is pure Markdown and JSON, so CI is a real surface and stays the size of the invariant it guards). The first placement considered was a git pre-commit hook, rejected on a mix of one sound reason and one that turned out false — corrected the same day, see below. core.hooksPath on the maintainer's machine does point at ggshield's directory, and that setting replaces the hooks directory rather than adding to it, so git itself never looks in .git/hooks. But the occupying script calls the repository's hook and fails the commit if it fails, so a local hook would have run after all. CI is the better instrument rather than the fallback: it travels with the clone, --no-verify cannot walk past it, and it fires at the pull request, which is where the omission landed. Proven both ways before shipping — a throwaway PR removing an index row went red naming the file, restoring the row turned the same workflow green. A workflow whose red has never been seen is a badge. The lesson generalises in docs/LEARNINGS.md, sharpened by the correction: read what occupies the slot — occupancy is not a second question, it answers the first. Whether your control runs is a property of the occupant's code, not of the configuration pointing at it; here the configuration said unreachable and the script said I call it myself. Skipping that read cuts the other way too: writing into the ggshield directory itself, where the entries are symlinks into dotfiles beside a .bak- from a previous overwrite, would have destroyed a working guard while reading as installed.
  • A false claim was recorded and corrected the same day, and the failure is logged (docs/AGENT-EVALS.md, 2026-09-21). The repository hooks are dead here half came from a peer, asserted from one measurement and generalised past it. It was not accepted blindly — the redirect, the directory listing and git rev-parse --git-path hooks were all checked, and all three were true. The conclusion drawn from them was not, and the file it was about was never opened. That is a variant of asserts without verifying that survives the usual guard, because verification happened on the premises: checking every fact a peer measured and adopting their inference is agreement with extra steps, and it feels like diligence. The tell is that the conclusion concerns something none of the checked commands touched. The decision did not move: CI still wins for the two reasons that were never about the slot — .git/hooks/ is not versioned and does not survive a clone, and --no-verify walks past any local hook including for whoever merges the PR that introduces the defect.
  • ADR 0045 states both of its conditions where they are read. Its heading announced additive, reversible, and under version control, while the condition that actually made the cut — does being locked block a methodology from starting — appeared only in the exclusion sentence below. A reader applying the announced criterion to close reaches the opposite conclusion from the one the ADR reached. Both conditions are now stated together, with close kept as the worked example: it is the safest skill in the plugin, proposing and never writing without confirmation, so on safety alone it would be the strongest candidate of the fifteen — and it stays locked because a locked close blocks nothing from starting. That is what shows the second condition is doing work rather than decorating the first.
  • Merging a PR is part of the orchestrated regime (operator, in-session, 2026-09-21; ADR 0046 decision 1b). The original wording said commits and pushes, which left merging undecided. It was practised as the completion of directed work and flagged as an interpretation each time rather than written down — codifying a widening of one's own permissions on a peer's request plus one's own inference is precisely what decision 3 of that ADR forbids, whatever the merits. The operator closed the gap through the channel decision 3 names. The reasoning that held in the meantime is recorded with it: the work is not delivered until it lands, so at zero required approvals the PR is a delivery mechanism, not an approval gate. main stays protected either way — merging the PR is how work lands, pushing to main remains something that does not happen.
  • The repo's working regime is orchestrated rather than supervised turn by turn (ADR 0046, amending ADR 0036's commit rule; set by the operator directly in-session, 2026-09-21; dogfood only — nothing the plugin generates changes). Work now arrives from the cockpit-devbox orchestrator and is reported back to it, the operator no longer reading each message. Commits and pushes follow the requested work: the ask for the work is the authorisation for the commit that carries it, which replaces the former commit/push only on explicit request in the Git workflow section and the commit only on explicit request clause of the Posture. main stays protected, so push still means short branch, push, PR — a repository constraint, not a permission lifted. Two things are deliberately kept, and written down as the price of the rest: refusing is retained and is the point — with nobody reading each message, an objection voiced to the orchestrator is the only remaining control, so a refusal left unsaid is a control removed; and authority never arrives through a peer — a change to what is permitted comes from the operator in-session, and a peer relaying the operator said that is still not an authorisation.
  • Five skills can now be invoked by the model, not only by a slash command (ADR 0045, amending ADR 0003). ADR 0003 settled manual invocation only in May, and its argument is about side effects — "there's no scenario where Claude should silently run bootstrap". It was written when the plugin had four skills; it now has fifteen, and every one had inherited the flag without its criterion ever being applied to them. The cost was measured on a project running the plugin for three weeks: docs/prd/ empty, loop/backlog.md empty, no loop ever run — every entry point into the methodology was waiting for a human to type a command, so the methodology could not start. The criterion is now applied per skill. bootstrap, migrate, adopt, slim and apply-best-practices stay locked, because a wrong firing restructures or damages a project. prd, realize, premortem, checkpoint and learn open, because they are additive, reversible and under version control. The back pressure that matters is untouched: realize still refuses [loop] on any task without a re-runnable stop condition, and run-loop.sh keeps its mandatory ceiling — those fire by construction, where a per-task human signature only delayed them. The slash command keeps working everywhere; this adds a second way in, and checkpoint's description no longer calls itself the manual complement. The tradeoff is real and reaches every user: a model may write a PRD nobody asked for — a markdown file under git, against three weeks of an empty docs/prd/.

[1.12.0] - 2026-09-11

Changed

  • Eval case 4 was rebuilt to recreate its failure, stayed green, and was retired. Its first form handed a fresh agent one insertion into a three-release changelog: 3/3 green, and worthless, since the recorded failure happened mid-session by a scripted string anchor into a large file under load. The rebuild recreated the pressure rather than the description — three simultaneous insertions into a seven-release file where each section name recurs seven times, exactly the shape that makes a scripted edit the tempting shortcut. Green 3/3 again, graded mechanically, published versions intact to the character. Six runs across two designs, zero reproductions, so the case is removed along with its fixture. The conclusion the evidence supports: this failure is a property of how a long-running agent edits under load — choosing a programmatic anchor over locating the section — which a fresh subagent given a focused task simply does not have, and it is not casable this way. Its verification becomes longitudinal: the guard is now actually loaded (the session-start fix below, absent when the failure recurred), and the measurement is whether it recurs. Weaker than a case, and what is actually available. The suite is three cases, not four — retiring one beats keeping a green that cannot fail.
  • The plugin was not applying to itself the most important thing it ships, and that is why a guard written on 2026-09-08 was broken on 2026-09-09. The generated template gives every project a ## Session start — read first list; the meta CLAUDE.md had none. So here, docs/LEARNINGS.md and docs/AGENT-EVALS.md were write-only — the agent was told where to record lessons and never told to read them — which made every guard in both files structurally unable to fire, and the capture ritual a filing habit rather than a feedback loop. The dogfood now carries the list it ships. Found while checking whether a proposed eval case could ever be meaningful: the case needed its guard to be loaded, and it was not. General rule in docs/LEARNINGS.mdname the file that will carry a rule into the next session, and check that something loads it, or you have written a note, not a guard.
  • A fourth eval case, and the most useful thing it produced is a verdict on the suite. Case 4 grades the duplicate-heading failure against a changelog fixture whose section name recurs once per release — the suite's first fully deterministic case, no judge, just count the headings. It is green 3/3, and the green is worthless: the recorded failure happened mid-session, inserting by a scripted string anchor into a large real file under load, while the case hands a fresh agent a small fixture and one instruction. Different task, easy green. That makes three of four greens green for the wrong reason — case 1's runs read the file grading them, case 2's first form was answerable without the plugin, case 4 does not reproduce its failure — against case 3, written the other way round with a prompt whose comfortable answer is wrong, and the only case that has ever produced a delta. Writing a case that reproduces a failure is much harder than writing one that describes it, and a green from a case that cannot fail is worse than a red because it is filed as evidence. Case 2 meanwhile reaches 3/3 at 6/6 in its sharpened form and its entry becomes probed; two of its runs turned up facts the case had not anticipated, including that this repository's own project-scope install is pinned at 1.10.0 while user scope is at 1.11.0 — the dogfood loading a plugin without close.
  • Eval case 2 sharpened onto a checkable false premise, and it now discriminates. In its first form both arms passed — the catalog-versus-install distinction is derivable from general knowledge of Claude Code, so the case measured competence rather than this plugin's configuration, and evals/README.md left the decision open rather than letting it sit green. The prompt now has the user's colleague date /groundrules:close to 1.10.0, when it shipped in 1.11.0: a fact verifiable from this repository and unknowable without it. First run, 6/6 with the plugin against 4/6 on the isolated baseline. The with-plugin arm opened by correcting the premise and proved it — git ls-tree on both tags — then drew a consequence the case had not anticipated: a catalog refreshed before the release could not have carried the version either. The baseline never questioned the figure, and invented a verification path (commands/close.md) for a plugin whose skills live under skills/<name>/. Its docs/AGENT-EVALS.md entry drops back to watching: the old 3/3 does not carry to a changed case, and a rate is what probed requires (ADR 0043).
  • A recurring insertion bug of the agent's own is logged (docs/AGENT-EVALS.md, 2026-09-09): adding an entry under ## [Unreleased] by anchoring on the literal ### Changed opened a second section of that name, leaving the release with Changed / Fixed / Changed. Caught and fixed on 2026-09-08, then repeated on 2026-09-09 — the first fix corrected the instance and left the habit. Sections merged; the guard is to anchor on something unique and to count after inserting, since the heading recurs once per released version and the first match is rarely the intended one.
  • validated is retired from docs/AGENT-EVALS.md (ADR 0043, amending ADR 0037 decision 2). ADR 0037's headline benefit was that a green case would give validated an operational meaning. The suite ran three times per case, and the promise came due: an entry names a behavioural classasserts / trusts without verifying first — while a case grades one instance. The class has unbounded instances, and it recurred on 2026-09-08, six days before its case went green 3/3, when this repository adopted a runner on the strength of its --help without invoking it. validated would have read green at the moment the guard was failing, which is worse than no status at all. The vocabulary is now watching — no case, or a case whose green is discounted for a stated reason — and probed: <case>, N/N since <date>, meaning one named instance at a measured rate and nothing about the class. A recurrence does not falsify a probe; it records that the class failed elsewhere, so the entry's history is the signal and the status merely indexes it. Cases 2 and 3 make their entries probed; case 1's stays watching, its green discounted because two of three runs read the file holding the expectations grading them. Nothing changes for users: AGENT-EVALS.md.tpl only ever used watching, so the retired word was never generated into a project.
  • Three runs per case: nine green with the plugin, and the suite earned its keep by finding two real defects. Cases 1, 2 and 3 each ran three times. All nine with-plugin arms passed. Case 3's three isolated baselines all failed the same way — refusing to commit, offering a Stop hook as a plausible mechanism, leaving the automatic reading open, one inventing a command name — so its delta is consistent rather than lucky. What the suite found, and what a green is worth, both matter more than the score. Several case-1 runs independently reported two defects in the shipped loop verifier, since confirmed against the files and now tracked in PLAN.md: verifier.md says the verifier receives the task line, the test and the diff "and nothing else", while its own checks 5 and 7 require reading CLAUDE.md## Invariants and a git diff against the committed test — an agent obeying the letter would skip two checks; and run-loop.sh runs one claude -p per iteration, not per role, so the maker and verifier passes share a context while LOOP.md claims the verifier runs fresh. Both reach every user who opts into the loop. Nothing moves to validated, and the reason is now sharper than a run count: a green validates the guard on that case's instance, not the behavioural class its AGENT-EVALS entry names. Case 3 grades one question; its entry is asserts without verifying, which recurred on 2026-09-08 when this repository adopted a runner on the strength of its --help. Three greens on a narrow instance, six days after the class failed on a wide one, is not evidence. Case 1's green is separately discounted: two of its three runs read evals/evals.json, the file holding the expectations grading them.
  • All three cases ran, and two of the three findings are about the cases rather than the agent. Case 1 passes 5/5 — the arm read both copies of the loop verifier, named the layer distinction, identified the shipped template as governing, and turned up a divergence the AGENT-EVALS entry had never recorded (the shipped Stage 1 carries seven checks to the prototype's five, including a is the test strong enough rejection and an invariants check the prototype lacks). Its baseline is inapplicable: the question is about files in this repository, and a shielded arm correctly refused — a baseline does not apply uniformly across case shapes, and claiming a delta there would manufacture one. Case 2 passes 4/4 with the plugin and 4/4 on a properly isolated baseline, so it does not discriminate: the catalog-versus-install distinction is derivable without this configuration, and the entry now needs a decision rather than a standing green. Its with-plugin arm did find a cause the case had not anticipated, now an expectation — the user's marketplace clone can itself be stale, so an update run before the release was published reinstalls the same old version — and one borderline expectation was reworded, since naming a restart after a real update is correct and was failing the case wrongly. The answer key is inside the repository under test: running case 1, the arm greps the repo and reads evals/evals.json, the file holding the expectations it is graded on. No clean fix exists while the suite lives where the cases explore; future greens from repo-reading cases are discounted accordingly.
  • The suite ran for the first time, and the first thing it caught was its own method — the baseline arm. Case 3 (does the capture ritual fire at session end? it cannot) was run in two arms. Both passed, so the delta read as zero, which would have meant the plugin changes nothing here. Wrong three times over: a subagent launched from this repository is handed the project CLAUDE.md before it does anything (a control confirmed it — three auto-loaded instruction blocks, quoted verbatim, and it named the section its knowledge of /groundrules:close came from, with zero tool calls); an isolated claude -p from an empty directory still found the repository, because the plugin is installed on this machine and its sources sit readable in the plugin cache; only with tools disallowed as well did an arm answer without the plugin — and it then failed the case, speculating that a Stop hook probably drives the capture, inventing a command name, and leaving the automatic reading open. So case 3 has a real delta: with the plugin 4/4 expectations, isolated baseline 3 failures. That is the suite's first signal and it is positive. Nothing moves to validated: one run is not a rate. The method, the three contamination channels and the confound that could not be removed — disallowing tools conflates no plugin with no ability to look anything up — are written into evals/README.md and docs/LEARNINGS.md.
  • The eval suite moved to a runner that is not gated (ADR 0042, amending ADR 0037 decision 1). claude plugin eval still prints "currently in early access" and does nothing — checked three times, the last after installing the official skill-creator plugin and restarting, which is what ruled out the hypothesis that the gate was tied to it. Everything downstream of that choice depended on being able to execute, so the suite now runs on skill-creator's own harness: for each case, two runs in the same turn, one with the plugin loaded and one without as a baseline, aggregated over repetitions. That is, in method, exactly what this repository had been doing by hand — every substantive defect fixed in 1.11.0 was found that way — with the two things the manual version lacked: the baseline arm, which measures whether the plugin changes behaviour at all, and repetition, which separates a real failure from noise. The three cases are transposed to evals/evals.json (prompt, expected_output, and a list of verifiable expectations), and the CLI-format files are deleted rather than maintained in parallel — two containers for one suite is what ADR 0034 exists to refuse, and the CLI's format had never been parsed by its tool either. Two deliberate deviations from skill-creator's conventions, both recorded: the suite sits at the repository root rather than under a skill, because two of the three cases are not about one skill and ADR 0037 scoped this to the plugin's configuration; and scripts/run_eval.py is unused, since it grades whether a skill's description triggers, where these are behavioural cases. Nothing here makes a case validated: no case has run under either runner, and no docs/AGENT-EVALS.md entry moves on the strength of one existing. The release checklist in the meta CLAUDE.md and the README's contributing note now name the harness instead of the gated command.

Fixed

  • The loop's verifier was never actually independent, and now is (ADR 0044). Both prompts insisted on it at length — "run as a separate subagent / fresh context", "never the maker's reasoning, its STATUS narrative or the commit message" — and run-loop.sh supplied none of it: one claude -p per iteration ran both passes, so the verifier had the maker's reasoning in full because it was the maker. That is the exact contamination the prompt spends a paragraph forbidding, and it is the back pressure ADR 0027 rests on. An iteration is now two invocations: the maker implements one task and leaves it uncommitted, then a separate verifier reads the working tree as the diff, finds the task and the committed acceptance test itself, judges, and holds the write — checking off and committing on PASS, leaving the tree alone on REJECT so the note carries into the next iteration. A DONE: backlog empty short-circuits before the verifier, so no call is spent on an empty backlog. The split is asserted, not assumed: test/loop/validate-runner.sh counts invocations — six for three iterations, one when the backlog empties — against a deterministic stub, at zero token cost. The cost is roughly double per iteration; that is the price of the property. Same change fixes the preamble's self-contradiction: "nothing else" becomes a bar on the maker's narration, never on the artifacts its own checks 5 and 7 require it to read. The frozen prototype keeps the one-invocation shape and its README now says so — giving it prompts describing a mechanism its runner lacks would transplant the defect. Found by evals/ case 1, reported independently by several runs: a case about reading the verifier found the defect in it.

[1.11.0] - 2026-09-08

Added

  • The first three eval cases are authored — and none of them can be run (ADR 0037). evals/ now holds one case per Status: watching entry of docs/AGENT-EVALS.md, exactly as the ADR specified: the observed failure becomes the prompt, the recorded guard becomes the grader. layer-ab-divergence asks about the loop's verifier and scores whether the agent says which of the two copies governs what users get, rather than reasoning from the frozen prototype. verify-installed-version poses the diagnostic question that once drew just restart three times, and scores whether the installed version is established before a fix is offered. verify-before-asserting asks whether the capture ritual fires at session end — it cannot — and scores whether the trigger is named or denied instead of assumed. Each pairs an LLM judge carrying the guard's rubric with a cheap deterministic grader as a floor under it. The blocker, recorded rather than glossed: claude plugin eval prints "currently in early access" and does nothing (verified 2026-09-08, Claude Code 2.1.265). ADR 0037 had called the runner verified present on the strength of its --help, which answers does this exist and not can this run — so the ADR gains a dated note suspending the operational meaning it gave to validated, and the reflex becomes a fourth AGENT-EVALS entry, a recurrence of asserts without verifying that the third case happens to grade. No entry moves to validated because a case exists: a case that has never been run is a written promise, not evidence, and the case format has never been parsed by the tool either.
  • The generated CLAUDE.md only carries the superpowers interop section when superpowers is actually in use (ADR 0039). That ### block — a heading, an intro and four bullets, eight lines — was unconditional in every project the plugin has ever generated, and it is pure noise for the majority who do not use superpowers. Worse than wasted: the <200-line doctrine and ADR 0021 exist because a longer file lowers adherence to every line in it. It is now gated on a new {{HAS_SUPERPOWERS}} placeholder and dropped at generation time, reusing the same section-drop mechanic as the global tailoring (ADR 0029) on a different trigger. Detected, never asked: docs/superpowers/plans|specs/ in the folder, else this folder's own .claude/settings.json (where a project-scope install is recorded), else the user's installed-plugin registry if the harness exposes one — user-scoped entries, or project-scoped to this folder, since reading it unfiltered would make every folder on the machine report true because one unrelated repository installed the plugin. Else false — a question would tax every user to spare a minority eight lines, and at bootstrap time it asks someone to predict a tooling choice rather than state a fact. The plugin already detected superpowers in four skills; this wires that same fact to the document describing it. A false negative is recoverable and says so: when the section is omitted the final recap gives one line naming the two ways back, and when it is kept the recap says nothing. CLAUDE.md.tpl is unchanged — it stays the single full source — and the four-word aside under ## Claude Code workflow stays too. Recorded top-level in .groundrules.json as superpowers: { detected, via } — never under answers, which holds what the user said, and nothing was asked; recording which signal fired is what makes a wrong detection debuggable. adopt uses the same flag. Validated before merge by two fresh-subagent dry runs (empty folder, and a folder carrying docs/superpowers/plans/): both behaved correctly, and returned nine instruction defects now fixed — the unfiltered registry scope above, a heading the drop rule could not match literally, a bullet count coupling the rule to the template body, Call 2c still keyed on one path rather than the flag, and a recap pointing at /groundrules:migrate, which has no superpowers awareness. The template heading also loses its now-stale hedge (if you use that plugin): the section only ships to projects where it does.
  • New skill /groundrules:close — reconcile PLAN.md against the diff, a check rather than a reminder (ADR 0038, from intake/2026-09-08-close-the-session-update-the-context.md). The generated CLAUDE.md asks the agent to keep a doc in sync in the same change that makes it stale — a reminder, and ADR 0022 already recorded why those don't fire: an agent can't perceive a session ending, nor reliably notice mid-task that a sentence in another file just became false. But this drift is computable — git says what changed, PLAN.md says what it believes — so it gets a check. Invoked by the human, it reads the changes since a baseline (argument, else the branch's merge-base, else the last tag): commit subjects, paths touched, [Unreleased] lines added. It compares them with the open items and shows the edit as a diff — tick, rewrite one sentence, or split a sub-bullet. One AskUserQuestion, one gesture; it never writes on its own inference, because PLAN.md is authored. It matches on paths, identifiers, ADR/PRD numbers and commit subjects, never on a filename — a check that cries wolf gets switched off, and is then worse than no check. PLAN.md and git metadata, nothing else: the plugin checks only what it generates. Reopens neither ADR 0022 (which refused an automatic trigger; this is invoked by the person who can perceive the end) nor ADR 0025 (nothing in band). checkpoint captures knowledge, close reconciles status: the generated CLAUDE.md checkpoint list and the meta one gain a fourth line naming it, and checkpoint's recap points to it. README: skill 15, the capturing paragraph, and a Reconciliation over reminders row with its Martraire reference.
  • An executable eval suite over the agent's configuration is adopted (ADR 0037, closes tensions 1 & 2 of intake/2026-09-02-ai-native-sdlc-evals-and-verification.md). The playbook's third control — "the eval suite says whether the agent still does the work to the same standard", triggered by a change to CLAUDE.md, a skill or a hook — lands as evals/ run with claude plugin eval (verified present in Claude Code 2.1.258). Three decisions worth naming: (1) no collision with ADR 0025 — it refused an in-band runtime hook, this is a CLI run out of band, the same post-hoc regime as verify-bootstrap, and the trigger is a convention at the release/PR gate, never a hook; (2) docs/AGENT-EVALS.md keeps its name and becomes the suite's source — an entry at Status: watching is a case candidate (failure mode = prompt, guard = grader), which finally gives validated an operational meaning, since today's guards are unfalsifiable; (3) the native case format is adopted as-is, no abstraction, no translatorportability is a property of what groundrules generates, not of how it is tested: the system under test is a Claude Code plugin (SKILL.md, plugin.json, slash commands), already irreducibly Claude-Code-specific, so ADR 0023 is not in play and a neutral format would buy nothing at the price ADR 0002/0034 exist to refuse. Nothing is generated into user projects and no skill invokes it — maintainer-side tooling only, offline-first untouched. CI on the config paths is deferred, with its reason (no .github/ yet, a secret, a per-PR cost, non-deterministic graders gating a merge). ADR only — the first cases are tracked in PLAN.md.

Changed

  • bootstrap defined its mode twice, and the two definitions disagreed (ADR 0040). One rule keyed resume mode on the state file, another on the folder merely being non-empty; for a non-empty folder groundrules had never touched, they gave opposite answers, and a fresh subagent executing the skill had to pick one — it chose the second "because it is the one that actually decides the mode". The right answer was neither: a non-empty folder with no groundrules history is exactly what ADR 0008 created /groundrules:adopt for, and calling it resume hid that behind a word promising the opposite. State and emptiness are now two questions asked in that order — state first, because the state file is itself a file — naming three modes: bootstrap, resume (state exists; the only thing that word now means, and a folder is never too empty to resume) and brownfield (say so, point at adopt first, then offer to continue anyway). Anything else in the folder ignores .git/, without which every git init followed by a bootstrap would be misrouted. The mode is brownfield, not foreign: foreign already names a file category in the same skill and in .groundrules.json's skippedFiles, so fixing one overloaded word with another would have been the same mistake in a new place. Never a refusal, never a silent resume; the offer is one question, choosing adopt stops the skill with the command to run, and the recommendation is made before the interview and repeated at the confirmation screen — an advisory given once has scrolled away by the time it decides anything.
  • bootstrap's Phase 4 recap gained the slot two earlier phases were already writing to. Call 2c routes a note there when loop scaffolding is deferred to superpowers, and the Call 3 note routes one about PLAN.md pointing rather than duplicating — but Phase 4 was a fixed three-item list with nowhere for either to land, so an executor had to invent structure. It now carries a Notes carried from the interview block — open, not a fixed list, so any decision an earlier phase reached that the file lists do not show lands there; omitted when empty. It must carry the planning-alias reconciliation in particular: detecting a TODO.md and then showing it among the ignored files like any other hid the one decision the user most needed before confirming. The recap also stops announcing git init when Phase 1 already found a repository.
  • /groundrules:migrate learned about superpowers. It had zero mentions of the plugin, so a project generated before ADR 0039 kept its unconditional interop section forever, or lost it only if the user happened to accept a whole-file CLAUDE.md overwrite — the benefit of that change reached new projects only. A project that predates it now runs the same detection as bootstrap Phase 1 and is offered the matching section-level edit: remove the block when superpowers is absent, add it when present, nothing otherwise. Triggered on the state, not on a version number — the pass runs when .groundrules.json has no superpowers key, since that key is written the first time the detection runs and its absence is "this project predates the change"; a hard-coded version would be wrong before the release and stale after it. Offered on its own, never folded into the whole-file arbitrationoverwrite this file and drop eight lines from it are not the same question, and Keep it stays a legitimate answer. Crucially, Phase 3 drops the same section before diffing when superpowers is absent: the template is the full source, so without that rule the section shows as a difference and a user answering Overwrite with the new template would silently re-add the very block just removed. The detection is recorded as { detected, via }, via being the signal that fired or null when none did.
  • /groundrules:close hardened by its own acceptance pass (ADR 0038). The five cases from intake/2026-09-08-close-the-session-update-the-context.md were exercised against two throwaway repositories by two fresh subagents given only the SKILL.md. All five pass. They also returned seven defects reading had missed, three of the silent-failure class: (1) the baseline's topic-branch rule resolved to HEAD on the default branch, producing an empty window and a confident "nothing changed" — the one failure this check could not distinguish from success (verified: zero commits in the window on this repo); (2) the no-tag fallback said "the last 15 commits", a window where a ref is requiredHEAD~15 does not resolve in a young repository, and the empty tree puts the commit that created PLAN.md inside its own diff; (3) "a path or directory is a match" contradicted "a filename is not a match" one paragraph later, on exactly the judgement the rule exists to settle — now stated as: what is forbidden is the reverse inference from name resemblance, and a path an item names as raw material is not its deliverable. Also added: a fourth leave as is outcome for an item that is touched but owed no edit; tick supersedes rewrite, dropping a status tail that the move would carry over as false; commit subjects and CHANGELOG lines demoted to pointers to confirm against the diff, since both over-claim; git diff hunks explicitly in bounds while opening files is not; and an absent CHANGELOG.md declared normal rather than degraded. The generated CLAUDE.md template said three questions while listing four — a regression from adding the close line — and skills/checkpoint/SKILL.md had carried the same stale count since its fourth bucket arrived in v1.4. Both corrected; ADR 0022 keeps its three questions, being the record of what was decided then. Method captured in docs/LEARNINGS.md.
  • An intake brief no longer names where it was written. intake/2026-09-02-ai-native-sdlc-evals-and-verification.md opened by attributing itself to a private working environment of the maintainer's, and closed the same sentence with "a session elsewhere cannot know how". Neither tells a reader anything they can use, and both describe a system this repository documents nowhere — the same defect that was cut out of ADR 0038 before it landed, in smaller form. The provenance is now stated as what it is: written away from this repository and brought into it. The filename is unchanged — it is cited from CHANGELOG.md, PLAN.md, ADR 0036 and ADR 0037. The brief's later mentions of a single operator stay: that is generic separation-of-duties vocabulary, used in ADR 0036 too, not a reference to anyone.
  • The loop's verifier is told what it must not receive (from intake/2026-09-02-ai-native-sdlc-evals-and-verification.md, tension 3). Both loop/LOOP.md and loop/verifier.md already asked for a fresh subagent; neither said what that subagent is handed. They now do: the task line, its pre-written acceptance test, and the diff — nothing else (not the maker's reasoning, its STATUS narrative, or the commit message). Those carry the author's framing, and a fresh agent fed the author's story is no longer a fresh one — the same reason the acceptance test is written at specification time, before the code, rather than composed afterwards from it. The prototype copy (docs/prototypes/loop/) also loses a stale fallback the shipped template had already dropped — "at minimum, switch fully into the verifier frame" — which is precisely the contaminated verifier this rule forbids; its verifier.md gains the fresh-context callout it never had.
  • ADR 0036 records the single-operator form of separation of duties (same brief, tension 4): the playbook rests that principle on code owners and a team; enforce_admins: true on a protected main is what supplies it for one operator — the agent structurally cannot land its own work. A sentence in Consequences, no new decision.
  • Git workflow conventions corrected against verifiable state (ADR 0036, supersedes ADR 0028). Two premises of 0028 had gone stale, both falsifiable against the machine: (1) branching — it claimed trunk-based direct pushes to main, but main is protected (PR required, enforce_admins: true, no force-push), so the real model is short branch + self-merged PR (0 approvals — a solo maintainer is never blocked); (2) AI attribution — it claimed "for this repo: attribute (no rule forbids it)", but the maintainer's global CLAUDE.md does forbid it (no Co-Authored-By, no Claude-Session:, no "Generated with Claude Code", commits/PRs/issues alike). 0028's conditional was right, only its facts were wrong. The policy is now recorded in the repo as policies.noAiAttribution: true in .groundrules.json — dogfooding ADR 0011's own persistence step, because a machine-local global file cannot be read by a fresh clone, a CI run or a subagent. Boundary commits (0028 point 2) carry over unchanged; no history rewrite. Meta CLAUDE.md Git workflow section updated. Dogfood only — no change to the plugin's output (the generated CLAUDE.md stays branching-neutral).

Fixed

  • /groundrules:migrate trusted one JSON key about what version produced a file. OLD came from groundrulesVersion and nothing ever confirmed the files agreed with it — a dry run hit exactly that, on a fixture where the file stamped with the newer version was the truncated one, so the signature was actively lying and nothing noticed. Phase 1 now cross-checks each generatedFiles entry's generated-by signature against OLD and reports a disagreement by name: signed newer (a partial earlier migration, a hand-edited signature, a file copied from another project), signed older (it missed a migration the state recorded as done), or unsigned (replaced by hand — treated as foreign, not arbitrated against a template). A dispute never stops the migration and never silently decides anything: the file is simply not offered Overwrite, the same protection accumulators get and for the same reason — a version number two sources disagree about is not a basis for replacing someone's file, and overwriting would resolve the disagreement by destroying one side of it.
  • The changelog range shown before a migration had an undefined boundary. "Entries between OLD and NEW" never said whether either end was included, nor what to do with ## [Unreleased] — so a run could omit everything the user was about to be asked about, or list unreleased work the installed plugin does not implement. It is now (OLD, NEW]: OLD excluded, being what the project already has, NEW included, being what it migrates to. [Unreleased] is never folded in — its entries belong to no released version — but when it is non-empty one line says so and names the case where it does apply: running the plugin from a source checkout rather than an installed release.
  • /groundrules:migrate could write a literal {{KEY}} into a user's file (ADR 0041). Its Phase 3 said, in one line, "substitute the placeholders with answers" — and answers is not sufficient by construction: bootstrap fills a template from the interview plus the folder scan ({{STACK}}), the clock ({{DATE}}), the global CLAUDE.md and the git remote, while a project bootstrapped by an older version can carry an answers object holding little more than projectName. Two harms followed. False differences: an unresolved {{STACK}} diffed against the real value the file already carries reports a difference that does not exist, and a recap padded with them trains the user to accept overwrites without reading. Then silent corruption: answering overwrite with the new template wrote a literal {{STACK}} over a correct value, in a file the user did not re-read because the migration had just called it an update. The plugin already held the doctrine — /groundrules:verify-bootstrap § 2.4 reports a bare placeholder as a failure — so this was the tool producing the exact defect it ships a detector for. Now: placeholders resolve through a ladder (the state file including intent; then the file on disk, the strongest source and the one bootstrap never has, recovered by anchoring on the template's literal text — recover, never guess; then re-derived non-interactive values), unresolved ones are masked on both sides before diffing so they cannot register as differences, and every write path degrades rather than damages: an overwrite is refused in favour of <file>.new, a create is skipped, and the missing values are named with where they would come from, since migrate is re-runnable by design. Never fabricated and never askedmigrate is not an interview, and an invented {{DESCRIPTION}} is worse than a visible gap because it looks authored. Found by a fresh-subagent dry run against a deliberately thin state file — and a second run, confirming the refusal worked, found three more, all fixed here. Masking blinded the guard: the phase never said which text it writes, and read as the masked text the guard finds no tokens and the overwrite proceeds — two opposite outcomes from one instruction; it now says always the substituted text, never the masked one. A second guard was missing entirely: the placeholder scan sees a broken value but not a correct one being thrown away, so PLAN.md sailed through and an overwrite replaced a real task with (add the first active tasks here). Overwrite is no longer offered on the files a project writes into — PLAN.md, CHANGELOG.md, LEARNINGS, AGENT-EVALS, VISION, INTENT, ADOPTION-LOG and docs/decisions/ — and the missing option is explained rather than silently absent. And the comparison text is now what bootstrap would produce for the project, not the raw template: bootstrap drops the sections a global covers, splices ## Invariants only for a scaffolded loop and drops the superpowers interop when absent, so diffing against the raw template reported all of those as differences the user never made. A section is dropped from the comparison only when the project file lacks it — dropping one the file has would let Overwrite silently delete the interop block whose removal is a separate question, which is the exact collision the separate question exists to avoid. Smaller: {{DATE}} comes from bootstrappedAt and never from the clock, since the template renders it as bootstrapped on; a derivation that legitimately finds nothing resolves to the empty string rather than blocking, because bootstrap defines {{STACK}} as stack or empty string; and a template that existed at the old version is reported as never generated for this project, not as new in a recent one.
  • Four SKILL.md descriptions were invalid YAMLadopt, idea, premortem, slim carried an unquoted : (colon + space) inside their description, which a strict parser rejects. They are now double-quoted (inner quotes escaped); the other ten were already clean. Also tightened the project's Bash(find * -type f *) allow rule to Bash(find . -type f *): a leading wildcard matches any option inserted before -type, so the rule approved more than it named.

[1.10.0] - 2026-07-23

Posture & positioning, harvested from the field. A third ## Posture axis in the generated CLAUDE.md (keep the diff small), a recorded decision to decline auto-capture memory layers (claude-mem class), and the canary adherence probe documented — three small, sourced refinements from reviewing community tools/patterns. No new skill, no runtime.

Changed

  • docs/CONTEXT-ECONOMY.md — the "canary" adherence probe documented as the detective complement to the preventive < 200-line budget. A canary is one trivial, glance-checkable instruction (e.g. "always greet me as <name>") whose only job is to signal when CLAUDE.md adherence decays (context saturation, competing instructions). Records the two subtle-but-true points: it's a passive probe not a guard (CLAUDE.md is context, not enforced config — to block, you need a PreToolUse hook, ADR 0025), and a root canary tests saturation not compaction (the project-root file survives /compact, re-read from disk). groundrules deliberately does not generate a canary (it costs the budget it watches and adds a competing instruction) — it's an opt-in technique. Docs only.
  • Positioning sharpened against auto-capture memory tools (records ADR 0035). After evaluating thedotmack/claude-mem (a popular persistent-memory system: lifecycle hooks auto-capture the agent's activity, AI-compress it into a machine-local SQLite + vector store behind a worker daemon, re-inject into future sessions), groundrules declines to add or depend on such a layer — it contradicts the repo is the only memory (ADR 0020), index over doc-search (ADR 0021), and no runtime hook (ADR 0025). docs/CONTEXT-ECONOMY.md gains a "What about an auto-capture memory layer?" section (the three-axis contrast + the honest convergence: their progressive disclosure is the same "index first, detail on demand" instinct as our context ladder), and the README "leaves out" line names it. Docs/positioning only — no code, no dependency.
  • Generated CLAUDE.md Posture gains a "Keep the diff small" axis (implements ADR 0034). The ## Posture section covered Push back and Stay reversible (social/safety register) but said nothing about the shape of the diff. Adds a third axis — simplicity first (minimum that solves the stated problem, no speculative abstraction), surgical changes (touch only what the task requires, match surrounding style), clean up only your own mess — led by a question ("would a senior call this overcomplicated?", consistent with the ADR 0032 reframing finding) rather than imperatives. Three bullets, folded into the existing section (no new section, respecting the ADR 0024 line budget). Harvested from forrestchang/andrej-karpathy-skills — its other two principles were already covered more deeply (Push back + /premortem; the loop). Dogfooded in this repo's own CLAUDE.md.

[1.9.0] - 2026-06-26

adopt Full adoption mode. A third adoption strategy for a project you fully own — consolidate and reformat everything onto the canonical groundrules layout, behind a single grouped confirmation. Implements ADR 0033.

Added

  • adopt — "Full adoption" mode (implements ADR 0033). A third adoption strategy alongside Map in place and Consolidate, for a project you fully own: it goes all the way — reformat is the default (sources are transformed into the groundrules template structure), merged sources are removed (git rm) for a clean canonical layout, and Call 3b pre-checks every applicable doc as a completeness pass. Everything lands behind a single grouped confirmation (the Phase 3 recap becomes the gate, enumerating every migrate/merge/reformat/removal) — informed and reversible via git history, never per-file, never silent. Selectable two ways: a third option in the Call 1 interview and a --full flag (composes with --dry-run). .groundrules.json records adoptionMode: "full". Extends the consolidate mechanics of ADR 0018 without a new skill.

[1.8.0] - 2026-06-23

/goal interop. The loop's swappable executor is now visible where users act — realize surfaces both launch options, and the generated loop docs explain when to reach for Claude Code's /goal vs the high-fidelity groundrules loop. Implements ADR 0031.

Added

  • /goal interop surfaced (implements ADR 0031). The loop's swappable executor is now visible where users act: /groundrules:realize's recap prints both launch options per [loop] task — light /goal "<command-based condition>" (derived from the task's acceptance command) and high-fidelity bash loop/run-loop.sh — framed choose by stakes. The generated loop/README.md gains a "Two ways to run the loop" section (light /goal = one task, transcript-judged vs high-fidelity loop = whole backlog, fresh context, verifier re-runs the oracle, parks decisions), with the honest tradeoff and an optional post-/goal verifier-gate note. README + QUICKSTART + TUTORIAL + the run-loop.sh header point to it. Docs + a recap enhancement only — no runtime, no detection, no new skill. PRD docs/prd/goal-interop.md.

[1.7.0] - 2026-06-20

Premortem & anti-sycophancy. A new skill and posture that make groundrules push back on plans, not just diffs — grounded in 2026 sycophancy research. Plus a field-test fix (commit the acceptance test before the loop) and an intro refresh.

Added

  • New skill /groundrules:premortem + anti-sycophancy posture (ADR 0032). Adopts Gary Klein's premortem as groundrules' reflection-side adversarial pass (the twin of the loop's verifier): point it at a plan / PRD / ADR / strategy and it assumes the thing already failed, enumerates causes ranked by probability × impact with the early signal for each, in a strictly adversarial register, then offers to fold the result into a PRD's Risks. Rationale is evidence-backed: sycophancy is measured (~50% more affirmation than humans, Science 2026) and reframing a claim as a question beats an explicit "don't be sycophantic" instruction (AISI 2026) — so a reframing technique outperforms our posture instruction alone. Also: a premortem hint in PRD.md.tpl Risks, a one-line premortem pointer in the generated CLAUDE.md Posture, and the README sycophancy row refreshed with the 2026 evidence (kept alongside Sharma 2023). Honest sourcing: premortem is an established technique (HBR 2007), never the mis-quoted "+30% on an LLM" (a 1989 human study).

Fixed

  • Commit the acceptance test before the loop (field-test finding). A real-world quickstart run converged correctly but left the pre-written test untracked — so the loop's commit held only the implementation, and the verifier's "acceptance test untampered" check (which compares via git diff) had no tracked baseline to guard against. Now: QUICKSTART/TUTORIAL commit the red test before launching; realize Phase 5 reminds to commit the test + backlog; verifier.md check 7 flags an untracked test; LOOP.md commits loop/lessons.md with the iteration (it's tracked on purpose). Captured in docs/LEARNINGS.md: a guard that compares against git only works on committed files.

Changed

  • README intro — replaced the flow one-liner ("Interview → … → optional remote", covered lower down) with a "shows its work" hook: the sourced concepts groundrules takes positions on (context rot, sycophancy + premortem, Nygard's ADRs, TDD as loop back pressure, write-loops-not-prompts) and what it deliberately rejects (no GraphRAG/graphify; no coercive mandatory-TDD), linking the receipts.

[1.6.1] - 2026-06-20

Loop docs + validation. A three-tier guide for the loop shipped in 1.6.0 (QUICKSTART → TUTORIAL → WALKTHROUGH), a deterministic runner test, and the /goal interop decision. Docs/tests only — no change to the plugin's skills, templates, or generated output.

Added

  • Loop quickstart — your first loop in 5 steps (test/loop/QUICKSTART.md). The everyday flow, conversational and short (~5 min): blank project → /groundrules:bootstrap (loop opt-in) → ask for something loopable in the chat → set up the loop (a failing acceptance test first, then /groundrules:realize) → launch it (light /goal "<condition>" or the full run-loop.sh — per ADR 0031) → check the commit. Positioned as the entry point; TUTORIAL.md (Game of Life) is the deeper path, WALKTHROUGH.md the validation reference. README + test/loop/README.md point newcomers here first.
  • Loop tutorial — build Conway's Game of Life with the loop (test/loop/TUTORIAL.md + fixtures/game-of-life/). A teaching walkthrough where you watch the loop engage: the fixture ships a PRD + go.mod + a pre-written red Go oracle (life_test.go: block · corner · blinker · glider) and no life.go — the loop writes it. Chosen because the tempting in-place implementation fails the blinker/glider tests, so go test (the deterministic oracle) has real work to do. Honest about outcomes (one-shot green or fail→fix→green — the test decides either way) with an opt-in Force the engage step that seeds the in-place bug to see the fix-arc deterministically. Oracle self-verified (red before code · green with a correct pure Step · naive in-place fails 2 tests); tutorial validated by a fresh-subagent replay running real go test. PRD docs/prd/loop-walkthrough.md.
  • Loop walkthrough + validation suite (test/loop/) — shows how to use the loop on a fresh project end-to-end (empty folder → bootstrap loop opt-in → /groundrules:realize → run the loop → a loop-authored commit → a BLOCKED → triage), doubling as a validation series. WALKTHROUGH.md narrates each step with its expected outcome (tagged [shell] / [agent] / [human]); validate-runner.sh is the deterministic layer — stubs claude to assert run-loop.sh's MAX cap, DONE stop, and per-iteration freshness (no LLM, 11 checks); fixtures provide a red slugify acceptance test + a mixed plan. The behavioural contract (converge / reject-gamed / block / TDD-gate / triage) runs live or subagent-replayed; outcomes are stated as invariants, not transcripts. PRD docs/prd/loop-walkthrough.md. The repo's first test/.

Decisions

  • ADR 0031-goal-interop-swappable-loop-executor.md (Accepted) — Claude Code's native /goal and the groundrules loop are two fidelity levels of a swappable executor, not competitors: /goal = the light loop (simple, transcript-verifiable goals; its evaluator judges the transcript), the groundrules loop (run-loop.sh + maker/verifier prompts) = the high-fidelity loop (independent re-run of the oracle, fresh context, decision-parking). groundrules always writes the goal (the pre-written red acceptance test, the partitioned backlog); only the runner differs. run-loop.sh repositioned as the high-fidelity executor and the harness-neutral fallback (M2). Implementation (realize emits a /goal-ready condition; interop notes in loop/README.md + README.md) deferred to a PRD. Index 0030 + 0031 backfilled in docs/decisions/README.md.

[1.6.0] - 2026-06-14

M1 — Loop-readiness. groundrules becomes the reflection layer a loop runs on: opt-in maker/verifier loop scaffolding, the /groundrules:realize forward bridge (with a TDD-before-loop gate), the blocked.md backward-crossing convention, and a generated CLAUDE.md that routes work by regime. Built brick by brick, each spec'd in a PRD and validated by an adversarial subagent E2E. See ADR 0027 (method) + ADR 0030 (loop namespace).

Added

  • M1 brick 5 — backward-crossing convention (triaging loop/blocked.md). A convention, not a skill (fork decided per ADR 0027 — the resolution work already lives in add-adr/realize/interactive). The generated loop/README.md gains a "Triaging blocked.md" section: three routes (too-big → re-decompose via realize · hidden decision → add-adr then re-add the task · human-only → fix interactively), the repo-gets-smarter principle (a decision becomes an ADR that makes the next run smarter), and a Resolution: field so blocked.md is an audit trail, not a graveyard — the maker now writes Resolution: (open — awaiting triage) when it parks. A one-line loop-conditional breadcrumb in CLAUDE.md points there. No automation, no new skill (triage is human-owned). PRD docs/prd/backward-crossing-convention.md.
  • M1 brick 4 — TDD-before-loop gate. /groundrules:realize's [loop] bar is hardened from "a stop condition exists" to a pre-written behavioural acceptance test, authored separately from the maker (writer ≠ maker), currently red (red-first proves it constrains; a build/lint is necessary-not-sufficient; a green/maker-authored test doesn't qualify). realize gains an interactive author-the-test step (draft from the spec → confirm red → [loop], else [supervised]). The loop templates sharpen the authoritative, immutable acceptance test vs the maker's assistive unit tests (verifier replays the former). PRD.md.tpl Success-criteria note + a loop-regime-only TDD line in loop/README.md (not a global rule — handoff-not-gospel). PRD docs/prd/tdd-gate.md.
  • M1 brick 3 — new skill /groundrules:realize. The forward bridge from an approved plan to an executable backlog: ingests a plan (paste · a PRD's Build plan · PLAN.md tasks), classifies each task [loop] (atomic · isolatable · verifiable · invariant-aware · no embedded decision) vs [supervised], refuses to tag [loop] anything without a re-runnable stop condition (the reflection-side back pressure), and on explicit confirmation writes the [loop] tasks into loop/backlog.md (maker-consumable, append/merge, idempotent) while tagging [supervised] in PLAN.md in place. Conservative default-to-[supervised], never auto-promotes (could-act ≠ cleared-to-act, ADR 0027 §4). Preconditions: requires loop scaffolding (offers inline generation if absent); defers to superpowers when present. Brick 3 only checks a stop condition exists — the TDD acceptance-test gate is brick 4. PRD docs/prd/realize-skill.md.
  • M1 brick 2 — opt-in loop scaffolding in bootstrap/adopt. A dedicated, off-by-default question (bootstrap Call 2c / adopt Call 3c) generates a loop/ namespace from the validated brick-1 contract: maker.md, verifier.md (independent, distrusts the maker's report, two-stage spec-then-quality, can reject a too-weak test), LOOP.md, a capped run-loop.sh (hard MAX), backlog.md (loop-safe tasks only — the loop reads this, never PLAN.md), loop/.gitignore, and a loop/README.md. Adds a conditional ## Invariants section to the generated CLAUDE.md (the verifier enforces it each iteration). The 3 brick-1 contract fixes are baked in (separate-context verifier · reject-too-weak-test · stage-the-diff-not-git add -A). Not offered when superpowers is detected (defer the whole realization). .groundrules.json gains loop.scaffolded; resume-safe (missing-only). Structure: ADR 0030. PRD docs/prd/loop-scaffolding-bootstrap-adopt.md. /groundrules:realize (auto-fill the backlog) is the next brick.
  • M1 brick 1 — minimal runnable loop prototype (docs/prototypes/loop/, not shipped, not wired into bootstrap/adopt yet). The maker/verifier loop contract as pure Markdown prompts (ADR 0002/0025): maker.md (4-status protocol DONE/DONE_WITH_CONCERNS/BLOCKED/NEEDS_CONTEXT), verifier.md (two-stage ordered review — spec THEN quality — that distrusts the maker's report and re-derives from the diff), LOOP.md (the per-iteration replay), a capped run-loop.sh (mandatory MAX anti-runaway), the blocked.md convention (the realization→reflection backward crossing), and a slugify fixture + pre-written acceptance test. Validated by subagent simulation on all three paths: good (converge), adversarial (verifier REJECTs a green-but-gamed diff), block (maker parks instead of guessing). Verdict + contract fixes captured in docs/LEARNINGS.md. PRD docs/prd/loop-minimal-runnable.md. See ADR 0027 / ROADMAP M1.

Changed

  • M1 brick 6 — generated CLAUDE.md routes work by regime. The flat "plan mode before any non-trivial task" bullet is sharpened (ADR 0027) into a routing list: a decision/fork → an ADR (add-adr) before acting · a non-trivial feature → a PRD (prd) first · an interactive non-trivial change → plan mode · an atomic/testable/isolatable task → (if loop/ scaffolding exists) /groundrules:realize → the loop, else just build it. The generated CLAUDE.md now teaches the reflection/realization model the rest of M1 implements. Wording refinement of one CLAUDE.md.tpl section; the loop route is an inline-conditional one-liner (no dangling reference for non-loop projects). PRD docs/prd/template-refinement-regimes.md.
  • README ## Built for the age of loops (after Why) — explains how groundrules fits the "write loops, not prompts" shift: the loop paradigm's "the model forgets, the repo remembers" is groundrules' own thesis (same context-rot evidence), groundrules generates the durable on-disk state a loop re-reads each iteration (loop-ready), and it's the antidote to the comprehension debt loops create ("loops write the code fast; groundrules keeps the understanding"). Honest about present (memory + reflection layer) vs roadmap (loop scaffolding — ADR 0027 / M1). Also added .gitattributes so GitHub Linguist shows Markdown, not "Go Template" (the {{KEY}} templates were mis-detected).
  • Skill description: fields rewritten WHEN-first (CSO) — all 12 skill descriptions now state when to use the skill, not a workflow summary (a summary can make Claude follow the description and skip the SKILL body — superpowers' writing-skills, see docs/LEARNINGS.md). New authoring rule in .claude/rules/plugin-meta.md; vision is the reference shape.
  • AGENT-EVALS guard hardening format — the AGENT-EVALS.md.tpl and the checkpoint skill now document an optional rationalization table (excuse-under-pressure → rebuttal) + red-flag stop-line for a stubborn guard that keeps getting rationalized away (borrowed from superpowers; formalizes the eval→guard loop, ADR 0022).

Decisions

  • ADR 0030-loop-namespace-and-backlog.md — for M1 brick 2: a single visible top-level loop/ is the loop's namespace; the loop reads loop/backlog.md (loop-safe tasks only), never PLAN.md directly (which only points to it). Rejected a hidden .groundrules/loop/ (treats the prompts as a black box, against handoff-not-gospel), docs/loop/ (wrong altitude for an executable), and a [loop]-tagged section of PLAN.md (the loop would race the human's surface + need a perfect tag-filter; our "compare by altitude" learning says separate the volatile/agent-touched from the durable/human-curated).

[1.5.0]

Added

  • adopt → opt-in docs/ADOPTION-LOG.md — at the end of an adopt run, offer to write a dated, frozen record of the run: what was here, what groundrules did (and why — skips/deferrals included), plus a Remarks section to annotate. Purpose: a field → plugin feedback channel — share the annotated log back to improve groundrules. Built from the scan + .groundrules.json (no new data, no network). New template ADOPTION-LOG.md.tpl. Distinct from AGENT-EVALS (agent behaviour) and apply-best-practices (external recs). Spec'd in docs/prd/adoption-log.md.
  • New skill /groundrules:vision — builds or refreshes docs/VISION.md through a guided interview (goal · users · constraints · V1 non-goals · acceptance criteria), reusing docs-VISION.md.tpl. Create-if-absent / refine-if-present (section-by-section, never silent overwrite). On-demand: for adopt/brownfield projects with no vision, or to deepen a thin one — complements bootstrap (no refactor of it). Borrows superpowers' interview discipline (2-3 framings + a recommendation, decompose over-scope, a pre-write self-review) while keeping groundrules' propose-don't-impose register. Spec'd in docs/prd/vision-skill.md. See ADR 0027 (method) + docs/LEARNINGS.md (borrowed patterns).

Changed

  • Content-aware CLAUDE.md tailoring — CLAUDE.lean.md.tpl retired (ADR 0029, supersedes 0009). The project CLAUDE.md no longer defers to a global by a boolean of presence (which left holes when the global was thin). Now there's one template (CLAUDE.md.tpl): bootstrap/adopt read the global's content and omit only the sections it actually covers (conservative set: Commits · Permissions · Verifying · Claude Code workflow · Git workflow; ## Don't always kept), always keeping groundrules' signature conventions (Posture, capture ritual, when-to-document, repo-is-memory, living docs) — bias-to-keep, with a user-facing omission list + veto. adopt's additions to an existing managed CLAUDE.md are now gap-driven (only what's missing). A thin global → output ≈ full; a rich global → ≈ the old lean; no holes.
  • Superpowers research captured (docs/LEARNINGS.md) — borrowable patterns (two-stage ordered verifier, distrust-the-report, evidence-before-claim gate, no-placeholder acceptance bar, maker four-status protocol; CSO authoring rule; interview principles) and explicitly-rejected ones (mandatory TDD, coercive gates, always-on bootstrap — conflict with handoff-not-gospel / no-runtime). docs/ROADMAP.md M1 gains a "verifier/maker contract" design note; M3 (cross-project dashboard, companion-tool) added.

Removed

  • skills/bootstrap/templates/CLAUDE.lean.md.tpl — replaced by content-aware tailoring of the single CLAUDE.md.tpl (see Changed / ADR 0029).

Decisions

  • ADR 0029-content-aware-claude-md-tailoring.md — retire the lean template; tailor one template against the global's content (omit only what it covers, bias-to-keep, omission list + veto). Supersedes ADR 0009 (presence-based lean), the disciplined way (header on 0009, index updated). Template-over-code (ADR 0002) preserved — the tailoring lives in SKILL instructions, not a template engine.
  • Plugin version bumped 1.4.0 → 1.5.0 across manifests, signatures (74 files), and .groundrules.json (+ migration entry). Shipped as boundary commits (ADR 0028) with consistent Co-Authored-By attribution.

[1.4.0]

Added

  • ## Posture in the generated CLAUDE.md (full + lean) — tells the agent to push back (challenge off-strategy/wrong/inconsistent plans, surface tradeoffs, ask before guessing, no sycophancy) and stay reversible (confirm before hard-to-undo actions; lean on git + /rewind). Harvested from intake/principles-claude-code.md. See ADR 0026.
  • New skill /groundrules:prd — writes a per-feature PRD (problem, success criteria, scope in/out, constraints, build plan, risks) to docs/prd/<feature>.md before building. Superpowers-aware: defers to superpowers' per-feature spec workflow when that plugin is present, provides the PRD itself when it isn't. New template PRD.md.tpl. See ADR 0026.
  • New skill /groundrules:idea — parks a one-line idea in PLAN.md's "Ideas — to triage" inbox (creates the section if absent; append-only). Prospective capture (forward ideas), the operational tool of the capture-before-it's-lost discipline and the complement to /groundrules:checkpoint (retrospective). PLAN.md.tpl gains the inbox section by default. See ADR 0027.

Changed

  • README: removed the version-by-version Roadmap (history lives in CHANGELOG.md); added a "What the research says" section mapping each design choice to published findings across three fields — language-model behavior (context rot, lost-in-the-middle, sycophancy, Anthropic's <200-line guidance), software-engineering economics (Boehm 1981, cost-of-defect → per-feature PRD), and usability (Nielsen heuristic #3 "user control and freedom" → reversibility) — and a separate "Established practices we adopt" section (ADRs/Nygard, Keep a Changelog, Conventional Commits, SemVer) that owns the recognized standards so they're never dressed up as lab science, plus a matching "References" bibliography. Makes explicit that the choices are evidence-driven, not marketing.

  • README ## Already using superpowers? — a section for superpowers users: the two work at different altitudes (superpowers owns realization; groundrules adds the durable why, the PRD-altitude above, and the cross-cutting "now"), framed as "superpowers builds the loop, groundrules keeps you the engineer".

  • Sharpened superpowers interop (verified against the obra/superpowers source) — superpowers creates specs + TDD plans (docs/superpowers/specs|plans/), not "PRDs", and imposes TDD + a maker/verifier; its spec omits risks / measurable success criteria / problem framing. So /groundrules:prd now: defers the whole realization (not just a spec), offers a thin PRD above for the missing altitude, and asks instead of presuming when the (overridable) detection path is absent. The generated CLAUDE.md interop note gains the "PRD altitude above" line; ROADMAP M1 notes loop scaffolding is the non-superpowers case. Facts captured in docs/LEARNINGS.md.

  • checkpoint skill — 4th bucket "shipped a user-facing surface → sync the doc" — the capture ritual now also nudges to keep README.md/docs in sync when a command, output, or config option ships (living docs), in the doc's existing voice (no regeneration). README gained the missing docs/prd/ row in What's generated. The meta CLAUDE.md release rule now also runs a mechanical ls skills/ ↔ README skill-list drift check.

  • Generated CLAUDE.md.tpl git workflow — replaced the dogmatic "feature branch for non-trivial changes" with a neutral, fillable branching note (trunk-based vs. feature-branch + PR, "pick one"), consistent with handoff-not-gospel and no opinionated config. The meta CLAUDE.md now also states the dogfood's own model (trunk-based on main), removing the template-vs-practice inconsistency. Lean template unchanged (git is deferred to the global CLAUDE.md there).

  • New docs/ROADMAP.md (dogfood) — long-term milestones distinct from PLAN.md's "now": M1 loop-readiness (loop scaffolding opt-in in bootstrap/adopt, /groundrules:realize, triage convention) and M2 multi-harness support. Multi-harness moved here out of PLAN.md to avoid duplication.

Decisions

  • ADR 0026-posture-and-per-feature-prd.md — the two additions, the superpowers-aware deferral, and why the reversibility tooling (deny-list / PreToolUse hook) is a pointer, not generated (ADR 0025 consistency).
  • ADR 0028-git-workflow-conventions.md — git practices for the repo: neutral branching (trunk-based dogfood), boundary commits (completed chunks + Conventional Commits + tag at release, not a mega-commit per release nor per-trivial-change; message references the CHANGELOG), and AI attribution by default deferring to any forbidding rule (global CLAUDE.md / policies.noAiAttribution, à la ADR 0011). No history rewrite. Consolidates the 3 git-workflow points incl. point 1 (branching), previously only in templates/CHANGELOG.
  • ADR 0027-reflection-realization-interactive-loop.md — the working-method + product model: reflection vs realization phases; the reflection doc as a method-agnostic contract consumed by an interactive or loop realization regime; the bidirectional frontier crossed on purpose (plan mode = native enforcement on the interactive side; a loop hitting a decision re-enters reflection); PRD (build) vs ADR (decision) both as reflection outputs; the "could-act ≠ cleared-to-act" guard as the back pressure of reflection (and inside a loop's verifier). Sets loop-readiness as a product direction (ADR 0025-consistent: no runtime hook; convention + on-demand skill), implementation deferred to PRDs. Validates the 2026-06-13 AGENT-EVALS guard entry.
  • Plugin version bumped 1.3.3 → 1.4.0 across manifests, signatures (71 files), and .groundrules.json (+ migration entry). First release under the boundary-commit convention (ADR 0028): the work shipped as 9 thematic commits with consistent Co-Authored-By attribution.

[1.3.3]

Decisions

  • ADR 0025-no-runtime-hook-no-watch.md — closed two long-standing backlog ideas as won't-do: the PreToolUse {{KEY}} hook (runtime machinery against "template over code"; verify-bootstrap covers it) and /watch-bootstrap (niche). docs/best-practices-pending.md queue is now empty.
  • Plugin version bumped 1.3.2 → 1.3.3 across manifests, signatures, and .groundrules.json (+ migration entry).

Fixed

  • verify-bootstrap false-positive on .gitignore — the signature check exempted only JSON, but .gitignore (generated from the plain gitignore.minimal, no HTML-comment signature) IS in a real project's generatedFiles, so every freshly-bootstrapped project got a spurious "signature missing". Now exempted, with the rule generalized to non-Markdown plain files. Caught by the first fresh-project E2E (the dogfood couldn't reveal it — its .gitignore is a foreign/skipped file).

Changed

  • verify-bootstrap placeholder check sharpened — the "leftover placeholder" rule is now explicit: a placeholder in backticks (`{{KEY}}`) is a documentation reference and is ignored; only a bare occurrence is a real unsubstituted placeholder. Avoids false positives on self-referential projects whose own CHANGELOG.md/PLAN.md mention groundrules placeholders by name. Surfaced by running the E2E on the dogfood (15/15 coherent).

[1.3.2]

Changed

  • README: added a "What it buys you" benefits summary under the Why section (sharper agents, knowledge that survives, lower token cost, no lock-in, docs that don't rot).
  • Plugin version bumped 1.3.1 → 1.3.2 across manifests, signatures, and .groundrules.json (+ migration entry).

[1.3.1]

Changed

  • README "Updating the plugin" hardened — the two-step update is now explicit (refresh the marketplace catalog then reinstall the plugin; marketplace update alone does not update the installed plugin), with a "check your installed version" tip (ls ~/.claude/plugins/cache/…) and the new-skill-needs-a-full-restart note. The Phase 0 update notices in bootstrap/adopt/migrate got the same clarification.

Fixed

  • adopt: stale Starter-kit role table header → groundrules role (rename leftover).

Dogfood

  • Captured the "marketplace update ≠ plugin update" trap that kept the maintainer on plugin 1.1.0 across two releases: a docs/LEARNINGS.md rule + a docs/AGENT-EVALS.md recurrence entry ("just restart" advised without verifying the installed version).
  • Plugin version bumped 1.3.0 → 1.3.1 across manifests, signatures, and .groundrules.json (+ migration entry).

[1.3.0]

Added

  • New skill /groundrules:slim — analyzes CLAUDE.md and proposes concrete optimizations to stay under the ~200-line budget (extract a bulky section to docs/, move file-type rules to .claude/rules/ with paths:, de-duplicate, compress), moving content never deleting it. verify-bootstrap's size warning now points to it. The generated CLAUDE.md is left untouched (no bloat). See ADR 0024.
  • Team-portability guidancebootstrap (Phase 8) and adopt (Phase 6) now suggest installing groundrules at Project scope (committed to .claude/settings.json, so collaborators are prompted to install on clone), only when not already done and never blocking. README Installation documents it. The generated CLAUDE.md is left untouched (no bloat — the advice lives in the skills' one-time output). See ADR 0023.

Decisions

  • ADR 0023-project-scope-for-team-portability.md — why project-scope install (not CLAUDE.md manual-fallback prose, not vendoring skills into the repo).
  • ADR 0024-slim-skill-claude-md-budget.md — a dedicated skill (not extending verify, not a CLAUDE.md pointer) to operationalize the 200-line budget.

Changed

  • Plugin version bumped 1.2.0 → 1.3.0 across plugin.json, marketplace.json, all template/doc signatures, and .groundrules.json (groundrulesVersion + new migration entry).

[1.2.0]

Added

  • New skill /groundrules:checkpoint — runs the capture ritual on demand (the manual complement to the agent's proactive trigger): gathers what changed since the last tag, then routes decided → ADR, learned/blockedLEARNINGS, agent driftAGENT-EVALS (offers to create it if absent). Described in the README ("Capturing knowledge as you go"). See ADR 0022.
  • Checkpoint-capture ritual in the generated CLAUDE.md (full + lean): the agent proactively proposes a 3-question capture (decidedadd-adr, learned / 30+ min blocker → learn, agent mistake/hallucination/driftAGENT-EVALS.md) at boundaries it can perceive — before a git push/tag/release (also wired into the RELEASE.md pre-release checklist) or a completed PLAN.md milestone. Anchored to those events because an agent can't perceive "session end". See ADR 0022.
  • docs/AGENT-EVALS.md — a new optional doc (placeholder {{HAS_AGENT_EVALS}}, wired into bootstrap Call 2b + adopt Call 3b + verify whitelist): a log of the agent's own failure modes on the project (mistakes, hallucinations, drifts) + the guard added. Distinct from LEARNINGS.md. Harvested (with the ritual) from an agent-memory article — its journal.md, .claude/memory/ location and @import auto-load were deliberately not adopted (ADRs 0020, 0021). See ADR 0022.
  • docs/CONTEXT-ECONOMY.md — a guide settling the "index vs documentation-search plugin" debate and "is too much context counterproductive?": separate storage (exhaustive, on disk) from loading (minimal, on-demand); an index + native Read wins for a project's own docs, doc-search/RAG is for large external corpora only; backed by the 2025 context-rot / lost-in-the-middle findings + Anthropic's < 200-line guidance. See ADR 0021.
  • "Map, not the territory" note in the generated CLAUDE.md templates (full + lean): keep the always-loaded file an index, read docs on demand, don't paste content "to be safe"; doc-search tools are for external corpora.

Changed

  • Interop pointer for graph/RAG toolsdocs/CONTEXT-ECONOMY.md now names the external-corpus tool class (doc-search MCP, GraphRAG/knowledge-graph tools such as graphify) for the case it covers, and adopt gains an optional, dependency-free hint to suggest such a tool when scanning a large unfamiliar codebase (upstream comprehension only — no graphify dependency, no generated artifact).
  • README: new "Why" section after the hook — the method's justification grounded in the context-rot / lost-in-the-middle research and Anthropic's own < 200-line guidance, linking to docs/CONTEXT-ECONOMY.md.
  • README restructured (pitch-before-install, inspired by obra/superpowers): new narrative "How it works" before installation, a numbered lifecycle "The workflow", a "Philosophy" section surfacing the principles from the ADRs, and a short "Contributing" section.
  • License: MIT — added LICENSE file + license field in plugin.json (was "To be defined").
  • plugin.json: dropped the "Formerly starter-kit" tail from the description (no external users to transition).
  • README: "Generated files" section restructured — a "folders" table explaining intake/docs/docs/decisions/ + docs/media/ and the flow between them, then a single unified file table (the three tables merged; "Condition" and "When to check it" merged into one "When created" column).
  • README: removed all legacy starter-kit transition messaging ("formerly" banner, old marketplace names note, roadmap phrasing) — the plugin had no external users before the rename, so there is no one to transition.
  • Dogfood: local folder and project name aligned on groundrules (was Starting-Claude) — doc titles, .groundrules.json projectName, meta CLAUDE.md paths. Historical ADRs untouched.
  • Memory hygiene (ADR 0020 applied to ourselves): machine-local project memories reduced to a single cross-project pointer — everything else was already recorded in the repo.
  • Plugin version bumped 1.1.0 → 1.2.0 across plugin.json, marketplace.json, all template/doc signatures, and .groundrules.json (groundrulesVersion + new migration entry).

Fixed

  • /groundrules:learn produced the old Context/Lesson format while the LEARNINGS.md template moved to the rule format (Why + When to apply) back in ADR 0019 — the skill was never updated. Now aligned: it collects Title / Why / When to apply and inserts a rule-format entry (date inside Why, not the title).

Dogfood

  • groundrules now runs its own checkpoint-capture ritual: added docs/AGENT-EVALS.md (first entry: "asserts/trusts without verifying") and a docs/LEARNINGS.md rule ("anchor agent rituals to observable events, never to session end") — captured before this push, as the ritual prescribes.

Decisions

  • ADR 0021-context-economy-index-over-doc-search.md — why groundrules generates an index + on-demand reads rather than a doc-search/RAG layer for a project's own docs.
  • ADR 0022-agent-evals-and-session-close.md — the two ideas adopted from an agent-memory article (session-close ritual, agent-evals log) and the three mechanics rejected (journal.md, .claude/memory/ location, @import auto-load).

[1.1.0]

Added

  • adopt adoption strategy: new Call-1 question — Map in place (default, previous behavior: duplicates tolerated and documented) or Consolidate (new Phase 4b: migrate role-mapped files to the canonical paths via git mv/merge, per-file confirmation, optional reformat to template structure, internal-reference sweep). .groundrules.json gains adoptionMode + migratedFiles. See ADR 0018.
  • Two new optional docs (bootstrap Call 2b + adopt Call 3b, placeholders {{HAS_PROCESS}}/{{HAS_RELEASE}}): docs/PROCESS.md (working-method contract: phases, validation gates, interview style) and RELEASE.md (operational runbook: environments, commands, checklist, rollback, fragilities — offered only when the project deploys). See ADR 0019.
  • "The repo is the only memory" convention in the generated CLAUDE.md (full + lean): all project knowledge lives in the repo docs — never in machine-local agent memory/plans; no ~/.claude/* references in repo docs; plan files worth keeping get copied in. Born from repatriating crm-heyjoe's external memories. See ADR 0020.

Changed

  • LEARNINGS.md template reworked: entries are now actionable rules with Why (story + cost) and When to apply (triggers), instead of journal notes (Context/Lesson). Harvested from a real project. See ADR 0019.
  • CLAUDE.md templates (full + lean): new "Session start — read first, in order" section (PLAN → LEARNINGS → VISION → in-progress artifacts).
  • PLAN.md template: status vocabulary ([~] delivered/in review; annotate reverts and key commits).
  • intake/ README: explicit read-only convention + binaries welcome.
  • Plugin version bumped 1.0.0 → 1.1.0 across plugin.json, marketplace.json, all template/doc signatures, and .groundrules.json (groundrulesVersion + new migration entry).

Decisions

  • ADR 0018-adopt-consolidation-mode.md — adoption strategies rationale.
  • ADR 0019-heyjoe-inspired-doc-improvements.md — what was harvested from crm-heyjoe and what was deliberately not.
  • ADR 0020-repo-is-the-only-memory.md — why agent-local project knowledge is forbidden.

[1.0.0]

BREAKING — plugin renamed starter-kitgroundrules (V1.0.0, ADR 0017)

Ground rules: the rules a team agrees on at the start and lives by afterwards — applying best practices of documentation and configuration is what this plugin is about.

  • Slash commands: /starter-kit:<skill>/groundrules:<skill> (all 7 skills; skill names unchanged).
  • State file: .starter-kit.json.groundrules.json, key starterKitVersiongroundrulesVersion. migrate renames it (git mv) and rewrites the key; all skills read the legacy file as fallback and point to migrate.
  • Signatures: new files carry <!-- generated-by: groundrules vX.Y.Z -->. The legacy starter-kit form is still recognized everywhere (resume mode, verify-bootstrap — reported as ⚠️ legacy, fixable with --fix; migrate offers a grouped rewrite).
  • Marketplace & repo: marketplace claude-code-starter-kitclaude-code-groundrules (the Claude Code distribution channel); repo lozit/claude-code-starter-kitlozit/groundrules — harness-neutral on purpose: extending groundrules to other harnesses is a post-1.0 direction (GitHub redirects old URLs). Install spec: /plugin install groundrules@claude-code-groundrules. Users must re-add the marketplace / reinstall the plugin.
  • Migration path: in each project, run /groundrules:migrate — it chains all historical renames and the V1.0 rename pass (state file, signatures, stale name references, command-prefix mentions) with per-step confirmation.
  • Manifests: English descriptions, "formerly starter-kit" noted, keywords extended.

Decisions

  • ADR 0017 implemented (was accepted in 0.12.0). ADR index, README, meta docs and dogfood fully rebranded (the repo migrated itself: .groundrules.json, signatures, prefix).

[0.12.0]

Added

  • Best-effort plugin update check (Phase 0) in bootstrap, adopt and migrate: compares the installed version against the latest published tag (git ls-remote, ~3s timeout, fail-silent offline) and prints a notice with the update commands when a newer version exists. migrate additionally warns that migrating with a stale plugin only brings the project up to the installed version. See ADR 0015.
  • README: new "Updating the plugin" section (manual marketplace update, auto-update toggle, project update via migrate).

Changed

  • Contact email in plugin.json (author) and marketplace.json (owner) switched to the public address guillaume.ferrari@protonmail.com.
  • Marketplace renamed starter-kit-localclaude-code-starter-kit (matches the GitHub repo; the old name was a leftover from the first local test). Install spec is now starter-kit@claude-code-starter-kit. Users who added the marketplace under the old name keep it locally (their update command still uses starter-kit-local) or can remove/re-add to pick up the new name. See ADR 0016.
  • Plugin version bumped 0.11.0 → 0.12.0 across plugin.json, marketplace.json, all template/doc signatures, and .starter-kit.json (starterKitVersion + new migration entry).

Decisions

  • ADR 0015-best-effort-update-check.md — why an in-skill check rather than a SessionStart hook or auto-update alone.
  • ADR 0016-rename-marketplace.md — marketplace rename rationale.
  • ADR 0017-plugin-rename-at-v1.md (Accepted) — the plugin will be renamed starter-kitgroundrules as the defining breaking change of V1.0.0 (namespace verified free: npm, PyPI, GitHub). starter-kit stays for the whole 0.x series; ~20 candidate names evaluated and recorded with verdicts (runner-up: charter).

[0.11.0]

Changed

  • brief/ renamed to intake/ — the upstream-notes folder is now generated as intake/ ("intake" = material received before processing), a clearer name than "brief" which suggests a single document. Template renames (brief-INTENT.md.tplintake-INTENT.md.tpl, brief-README.md.tplintake-README.md.tpl), {{INTENT_SOURCE}} values, and all path references updated across bootstrap/adopt, the generated templates, the public README, and the dogfood (git mv brief intake). See ADR 0014.
  • /starter-kit:migrate learns the rename: for a pre-rename project it offers git mv brief intake, fixes .starter-kit.json paths, and flags stale brief/ references in the project docs. Renames chain (a pre-0.7 brief/00-INTENT.md lands directly at intake/INTENT.md).
  • Plugin version bumped 0.10.1 → 0.11.0 across plugin.json, marketplace.json, all template/doc signatures, and .starter-kit.json (starterKitVersion + new migration entry).

Decisions

  • ADR 0014-rename-brief-to-intake.md — rationale and alternatives considered (intent/, inbox/, upstream/, …).

[0.10.1]

Changed

  • Meta: documented the batch-small-changes release cadence in the root CLAUDE.md (accumulate under [Unreleased]; bump/tag/release only on explicit request).

[0.10.0]

Fixed

  • /starter-kit:adopt now always offers the optional/specialized docs. Call 3 was gated on scan detection, so when nothing was detected the question was skipped and docs like DATA_MODEL/SECURITY/DESIGN_SYSTEM/ROADMAP/I18N/ARCHITECTURE/GLOSSARY/CHANGELOG were never proposed. Split into Call 3a (core missing docs) + Call 3b (mandatory multiSelect listing all optional docs) — detection only pre-checks, it no longer hides the list.

Added

  • "Living docs" rule in the generated CLAUDE.md (full + lean templates): every generated doc (VISION, ARCHITECTURE, DATA_MODEL, SECURITY, README, CHANGELOG, …) must be kept in sync in the same change that makes it stale — maintaining it is part of the task, not a follow-up.

Changed

  • Plugin version bumped 0.9.0 → 0.10.0 across plugin.json, marketplace.json, all template/doc signatures, and .starter-kit.json (starterKitVersion + new migration entry).

[0.9.0]

Changed

  • media/ moved to docs/media/ — the asset folder is now generated under docs/ instead of at the project root, to avoid colliding with a project's own top-level media/ or public/. Updated across bootstrap (scan + mapping), adopt, the CLAUDE.md/README templates, and the dogfood (media/README.mddocs/media/README.md via git mv). See ADR 0013.
  • /starter-kit:migrate learns the move: for a pre-0.9 project it offers to git mv a starter-kit media/ to docs/media/ (leaves a project's own unrelated media//public/ untouched).
  • Plugin version bumped 0.8.0 → 0.9.0 across plugin.json, marketplace.json, all template/doc signatures, and .starter-kit.json (starterKitVersion + new migration entry).

Decisions

  • ADR 0013-media-under-docs.md — rationale for moving the asset folder under docs/.

[0.8.0]

Changed

  • English-only — dropped the bilingual FR/EN support. All *.fr.tpl/*.fr.md templates removed; English is now the single template set (one .tpl per file, no language suffix; adr-template.md). Removed the {{LANG}} placeholder, the "language" interview question, and all per-language template selection across bootstrap/adopt/migrate/add-adr/learn. The 7 SKILL.md files and the dogfood docs (README, root CLAUDE.md, VISION, INTENT, rules, best-practices-pending) were translated to English. Rationale: all projects are done in English; maintaining two language variants was overhead for no benefit. See ADR 0012.
  • Plugin version bumped 0.7.0 → 0.8.0 across plugin.json, marketplace.json, all template/doc signatures, and .starter-kit.json (starterKitVersion + new migration entry; obsolete answers.lang dropped).

Migration note

  • /starter-kit:migrate on a pre-0.8 (bilingual) project does not overwrite French content with English: it reports language-change files for manual review and offers the new English template as <file>.new.

Decisions

  • ADR 0012-english-only.md — rationale for dropping the bilingual FR/EN templates and the {{LANG}} logic.

[0.7.0]

Added

  • Optional specialized docs in bootstrap (new interview call "Appel 2b", multiSelect): the skill can now generate, on demand, any of:
    • docs/DATA_MODEL.md — entities, relationships, row-level access rules, indexes, migrations
    • docs/SECURITY.md — authentication, authorization, personal data & GDPR, secrets, attack surface
    • docs/DESIGN_SYSTEM.md — colors/tokens, typography, spacing, components, accessibility
    • docs/ROADMAP.md — long-term milestones (distinct from the active PLAN.md)
    • docs/I18N.md — supported languages, translation organization, localized formats
  • Templates added (FR + EN): DATA_MODEL, SECURITY, DESIGN_SYSTEM, ROADMAP, I18N (10 files).
  • New bootstrap placeholders: {{HAS_DATA_MODEL}}, {{HAS_SECURITY}}, {{HAS_DESIGN_SYSTEM}}, {{HAS_ROADMAP}}, {{HAS_I18N}}.
  • "No AI attribution" policy detectionbootstrap/adopt read (read-only) the project + global CLAUDE.md for a rule forbidding AI attribution (no AI attribution, Co-Authored-By, Generated with Claude…) and set policies.noAiAttribution in .starter-kit.json. When set, commits made (bootstrap) or suggested (adopt, migrate) carry no AI attribution trailer/footer, overriding the agent's default. Skills still never auto-commit beyond bootstrap's own commit. See ADR 0011.
  • Deference to a tool-managed project CLAUDE.md — when bootstrap (resume) / adopt find a CLAUDE.md already present (no starter-kit signature, often tool-managed e.g. a corporate claude-manager), starter-kit never generates or overwrites it. It detects management markers + a free zone (END MANAGED / ## Project-Specific Notes) and offers (opt-in) to append a discoverability pointer to the starter-kit docs into the free zone only; if no free zone, it skips. Conflicts between managed rules and starter-kit conventions (e.g. commit AI-attribution) are surfaced, not resolved. Records adoptedFiles["CLAUDE.md"]. Takes precedence over the lean logic below. See ADR 0010.
  • Global/enterprise CLAUDE.md awarenessbootstrap/adopt detect a global CLAUDE.md (~/.claude/CLAUDE.md + OS-managed policy paths). When present, the generated project CLAUDE.md defers to it: a new lean template pair (CLAUDE.lean.md.{fr,en}.tpl) keeps only project-specific sections + a deference header ("loaded in addition to the global; on conflict the global/enterprise rule wins"), and the full template gains a {{GLOBAL_CLAUDE_NOTE}} placeholder (filled when a global is detected, empty otherwise). No enterprise file is ever overwritten (different path) or silently diluted (content). See ADR 0009.
  • New skill /starter-kit:adopt — onboards an existing (brownfield) project: scans, maps existing files to starter-kit roles (README, PLAN, backlog, intent-source, superpowers-interop), captures intent from existing docs, generates only what's missing, backfills .starter-kit.json with adopted: true + adoptedFiles. Never overwrites/deletes; no git init/remote; supports --dry-run. Fills the brownfield gap that migrate (refuses non-managed projects) and bootstrap (treats existing files as foreign) left open. See ADR 0008.
  • Pre-existing planning detection in bootstrap Phase 1 (and reused by adopt): detects PLAN.md aliases — now case-insensitive (plan.md), nested (docs/gtd/todos.md), and multiple at once (TODO.md, todos.md, TASKS.md, BACKLOG.md…). When found, Appel 3 asks a reconciliation question (adopt existing / create alongside / port content into PLAN.md) instead of the standard yes/no — never overwrites, never deletes the alias. Case-collision guard: never generates PLAN.md when a case-variant exists (avoids a cross-platform git hazard). docs/superpowers/plans/ is explicitly not treated as an alias (different altitude); PLAN.md is kept and should point to the active superpowers plan.

Changed

  • De-numbered the entry docs (dropped the 00- prefix): brief/00-INTENT.mdbrief/INTENT.md, docs/00-VISION.mddocs/VISION.md. The partial numbering scheme (only VISION/INTENT carried a number, no other doc did) provided no real ordering benefit. Updated across bootstrap/apply-best-practices/verify-bootstrap SKILLs, brief-INTENT templates, README.md, .starter-kit.json (generatedFiles), and the dogfood files themselves. Historical references (CHANGELOG [0.5.0], ADR 0005, the migration note, the peer-structure quote) kept verbatim.
  • Plugin version bumped 0.6.0 → 0.7.0 across plugin.json, marketplace.json, all template/doc signatures, and .starter-kit.json (starterKitVersion + new migration entry).
  • bootstrap/SKILL.md: Phase 1 scan list, Phase 2 interview (new Appel 2b), Phase 5 placeholders and conditional file mapping updated.
  • README.md: detailed "Fichiers générés" section extended with the 5 specialized docs.
  • CLAUDE.md.{fr,en}.tpl: added a conditional "Interop with superpowers" note clarifying that starter-kit's durable project docs and superpowers' per-feature docs/superpowers/specs|plans/ live at different altitudes (no duplication); PLAN.md should reference the active superpowers plan rather than duplicate tasks.

Decisions

  • ADR 0006-optional-specialized-docs.md — rationale for adding these docs as opt-in conditional templates (and for excluding tickets/, Salesforce-style and project-specific docs).
  • ADR 0007-denumber-entry-docs.md — rationale for dropping the 00- prefix on VISION/INTENT.
  • ADR 0008-adopt-brownfield-projects.md — rationale for a dedicated /starter-kit:adopt skill + broadened planning detection.
  • ADR 0009-global-claude-md-awareness.md — rationale for global CLAUDE.md detection + lean project CLAUDE.md.
  • ADR 0010-managed-project-claude-md-deference.md — rationale for deferring to an existing tool-managed project CLAUDE.md.
  • ADR 0011-detect-no-ai-attribution-policy.md — rationale for detecting a no-AI-attribution policy and adapting suggested commits.

[0.6.0]

Added

  • New skill /starter-kit:verify-bootstrap — validates the coherence of a starter-kit-bootstrapped project:
    • Per-file checks: existence, <!-- generated-by --> signature presence, version match against .starter-kit.json.starterKitVersion, no unsubstituted {{KEY}} placeholders.
    • Structural checks: .git/ present, CLAUDE.md ≤ 200 lines, JSON validity of .starter-kit.json/.claude/settings.json/.claude-plugin/plugin.json, intent ↔ vision coherence.
    • Output: ✅/⚠️/❌ checklist grouped by category.
    • --fix mode: corrects safe issues (signature version mismatches via Edit). Other issues remain manual (missing files, placeholders, invalid JSON, oversized CLAUDE.md).
    • Read-only by default; --fix requires explicit AskUserQuestion confirmation before applying.

Changed

  • Plugin version bumped 0.5.0 → 0.6.0 across plugin.json, marketplace.json, all template signatures, .starter-kit.json.
  • docs/best-practices-pending.md: the /verify-bootstrap recommendation is marked as implemented (struck through).
  • .starter-kit.json: V0.5 apply-best-practices appliedPractices entry updated — verify-bootstrap item moved from deferred to applied (V0.6).

[0.5.0] — internal, never released

Added

  • Intent capture in bootstrap (new Phase 3): the skill now asks if the user has a brief, accepts paste, file path, or in-interview questions (goal, users, constraints, non-goals, acceptance criteria). Produces:
    • brief/00-INTENT.md — raw source (when paste or file path)
    • docs/00-VISION.md — structured synthesis (always, unless skipped)
    • Templates: brief-INTENT.md.{fr,en}.tpl, docs-VISION.md.{fr,en}.tpl
  • New skill /starter-kit:apply-best-practices — fetches https://github.com/shanraisshan/claude-code-best-practice via WebFetch, passes the project's docs/00-VISION.md as context, returns recommendations grouped by category (CLAUDE.md sections, .claude/rules/, settings.json permissions, hooks, custom skills) with High/Medium/Low priority. User picks via multi-select. Safe items applied automatically; hooks and custom skills saved to docs/best-practices-pending.md for manual review.
  • .starter-kit.json schema extended with intent field (source, goal, users, constraints, nonGoals, acceptanceCriteria) and appliedPractices (array of {appliedAt, source, items[]}).

Changed

  • bootstrap/SKILL.md renumbered: Phase 3 (Intent) inserted, former Phase 3-7 shifted to Phase 4-8. Final recap (Phase 8) now suggests running /starter-kit:apply-best-practices.
  • Plugin version bumped 0.4.0 → 0.5.0 across plugin.json, marketplace.json, all template signatures, .starter-kit.json.

Dogfood

  • Backfilled brief/00-INTENT.md retroactively from the original prompt that started this project.
  • Synthesized docs/00-VISION.md capturing goal, 6 constraints, 5 non-goals, 7 acceptance criteria.
  • .starter-kit.json records the V0.2 manual integration of shanraisshan/howborisusesclaudecode best practices under appliedPractices (so a future /starter-kit:apply-best-practices run can diff against them and propose new items).

[0.4.0] — internal, never released

Added

  • New skill /starter-kit:migrate — upgrades a starter-kit-bootstrapped project to the current plugin version (diff per file, overwrite/keep/save-as-.new, --dry-run support, refuses downgrade).
  • .starter-kit.json schema extended: bootstrappedWithVersion (immutable) + migrations array (append-only).

[0.3.0] — internal, never released

Added

  • /starter-kit:add-adr — auto-incremented ADR creation with index update.
  • /starter-kit:learn — dated entry prepended to docs/LEARNINGS.md.
  • First two ADRs: 0001-marketplace-json-location.md, 0002-plain-text-placeholder-substitution.md.

[0.2.0] — internal, never released

Added

  • CLAUDE.md.{fr,en}.tpl restructured to integrate best practices from shanraisshan/claude-code-best-practice and howborisusesclaudecode.com:
    • "Setup / Build / Test" section at the top
    • "Mettre à jour ce fichier" philosophy (Boris Cherny)
    • References to .claude/settings.json, .claude/rules/*.md, <important if="..."> tags
    • "Vérifier le travail" / "Prove to me this works" section
    • "Workflow Claude Code" section: plan mode, /compact, /clear, git worktrees, delegation model
  • EN variants for all previously FR-only templates
  • adr-template.md split into adr-template.{fr,en}.md

Fixed

  • marketplace.json moved from repo root into .claude-plugin/
  • V0.1 gap: LANG=en producing FR-content files for non-CLAUDE templates

[0.1.0] — internal, never released

Added

  • Initial scaffolding: .claude-plugin/plugin.json, marketplace.json, skills/bootstrap/SKILL.md with 7-phase interactive workflow, 15 templates covering CLAUDE.md, README, ADR, LEARNINGS, brief, media, ARCHITECTURE, GLOSSARY, CHANGELOG, PLAN.
  • Two-layer architecture (plugin sources vs project docs), dogfood applied to the repo itself.