All notable changes to this project are documented in this file.
Format inspired by Keep a Changelog, versions follow Semantic Versioning.
- The ADR index invariant becomes a check (
test/check-adr-index.sh, dogfood only). On 2026-09-21 an ADR landed onmainwithout its row indocs/decisions/README.mdand 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 gitpre-commithook, rejected on a mix of one sound reason and one that turned out false — corrected the same day, see below.core.hooksPathon the maintainer's machine does point atggshield'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-verifycannot 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 indocs/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 theggshielddirectory itself, where the entries are symlinks intodotfilesbeside 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 andgit rev-parse --git-path hookswere 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-verifywalks 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
closereaches the opposite conclusion from the one the ADR reached. Both conditions are now stated together, withclosekept 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 lockedcloseblocks 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.
mainstays protected either way — merging the PR is how work lands, pushing tomainremains 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-devboxorchestrator 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.mainstays 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.mdempty, 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,slimandapply-best-practicesstay locked, because a wrong firing restructures or damages a project.prd,realize,premortem,checkpointandlearnopen, because they are additive, reversible and under version control. The back pressure that matters is untouched:realizestill refuses[loop]on any task without a re-runnable stop condition, andrun-loop.shkeeps 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, andcheckpoint'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 emptydocs/prd/.
- 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 firstlist; the metaCLAUDE.mdhad none. So here,docs/LEARNINGS.mdanddocs/AGENT-EVALS.mdwere 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 indocs/LEARNINGS.md— name 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 withoutclose. - 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.mdleft the decision open rather than letting it sit green. The prompt now has the user's colleague date/groundrules:closeto 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-treeon 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 underskills/<name>/. Itsdocs/AGENT-EVALS.mdentry drops back towatching: the old 3/3 does not carry to a changed case, and a rate is whatprobedrequires (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### Changedopened a second section of that name, leaving the release withChanged/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. validatedis retired fromdocs/AGENT-EVALS.md(ADR 0043, amending ADR 0037 decision 2). ADR 0037's headline benefit was that a green case would givevalidatedan operational meaning. The suite ran three times per case, and the promise came due: an entry names a behavioural class — asserts / 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--helpwithout invoking it.validatedwould have read green at the moment the guard was failing, which is worse than no status at all. The vocabulary is nowwatching— no case, or a case whose green is discounted for a stated reason — andprobed: <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 entriesprobed; case 1's stayswatching, its green discounted because two of three runs read the file holding the expectations grading them. Nothing changes for users:AGENT-EVALS.md.tplonly ever usedwatching, 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
Stophook 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 inPLAN.md:verifier.mdsays the verifier receives the task line, the test and the diff "and nothing else", while its own checks 5 and 7 require readingCLAUDE.md→## Invariantsand agit diffagainst the committed test — an agent obeying the letter would skip two checks; andrun-loop.shruns oneclaude -pper iteration, not per role, so the maker and verifier passes share a context whileLOOP.mdclaims the verifier runs fresh. Both reach every user who opts into the loop. Nothing moves tovalidated, and the reason is now sharper than a run count: a green validates the guard on that case's instance, not the behavioural class itsAGENT-EVALSentry 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 readevals/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-EVALSentry 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 readsevals/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.mdbefore it does anything (a control confirmed it — three auto-loaded instruction blocks, quoted verbatim, and it named the section its knowledge of/groundrules:closecame from, with zero tool calls); an isolatedclaude -pfrom 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 aStophook 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 tovalidated: 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 intoevals/README.mdanddocs/LEARNINGS.md. - The eval suite moved to a runner that is not gated (ADR 0042, amending ADR 0037 decision 1).
claude plugin evalstill prints "currently in early access" and does nothing — checked three times, the last after installing the officialskill-creatorplugin 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 onskill-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 toevals/evals.json(prompt,expected_output, and a list of verifiableexpectations), 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 fromskill-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; andscripts/run_eval.pyis 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 nodocs/AGENT-EVALS.mdentry moves on the strength of one existing. The release checklist in the metaCLAUDE.mdand the README's contributing note now name the harness instead of the gated command.
- 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
STATUSnarrative or the commit message" — andrun-loop.shsupplied none of it: oneclaude -pper 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. ADONE: backlog emptyshort-circuits before the verifier, so no call is spent on an empty backlog. The split is asserted, not assumed:test/loop/validate-runner.shcounts 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 byevals/case 1, reported independently by several runs: a case about reading the verifier found the defect in it.
- The first three eval cases are authored — and none of them can be run (ADR 0037).
evals/now holds one case perStatus: watchingentry ofdocs/AGENT-EVALS.md, exactly as the ADR specified: the observed failure becomes the prompt, the recorded guard becomes the grader.layer-ab-divergenceasks 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-versionposes 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-assertingasks 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 evalprints "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 tovalidated, and the reflex becomes a fourthAGENT-EVALSentry, a recurrence of asserts without verifying that the third case happens to grade. No entry moves tovalidatedbecause 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.mdonly 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 reporttruebecause one unrelated repository installed the plugin. Elsefalse— 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.tplis unchanged — it stays the single full source — and the four-word aside under## Claude Code workflowstays too. Recorded top-level in.groundrules.jsonassuperpowers: { detected, via }— never underanswers, which holds what the user said, and nothing was asked; recording which signal fired is what makes a wrong detection debuggable.adoptuses the same flag. Validated before merge by two fresh-subagent dry runs (empty folder, and a folder carryingdocs/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 2cstill 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— reconcilePLAN.mdagainst the diff, a check rather than a reminder (ADR 0038, fromintake/2026-09-08-close-the-session-update-the-context.md). The generatedCLAUDE.mdasks 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.mdsays 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. OneAskUserQuestion, one gesture; it never writes on its own inference, becausePLAN.mdis 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.mdand 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).checkpointcaptures knowledge,closereconciles status: the generatedCLAUDE.mdcheckpoint list and the meta one gain a fourth line naming it, andcheckpoint'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 toCLAUDE.md, a skill or a hook — lands asevals/run withclaude 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 asverify-bootstrap, and the trigger is a convention at the release/PR gate, never a hook; (2)docs/AGENT-EVALS.mdkeeps its name and becomes the suite's source — an entry atStatus: watchingis a case candidate (failure mode = prompt, guard = grader), which finally givesvalidatedan operational meaning, since today's guards are unfalsifiable; (3) the native case format is adopted as-is, no abstraction, no translator — portability 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 inPLAN.md.
bootstrapdefined 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:adoptfor, 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 atadoptfirst, then offer to continue anyway). Anything else in the folder ignores.git/, without which everygit initfollowed by a bootstrap would be misrouted. The mode isbrownfield, notforeign:foreignalready names a file category in the same skill and in.groundrules.json'sskippedFiles, 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, choosingadoptstops 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 aboutPLAN.mdpointing 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 aTODO.mdand then showing it among the ignored files like any other hid the one decision the user most needed before confirming. The recap also stops announcinggit initwhen Phase 1 already found a repository./groundrules:migratelearned 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-fileCLAUDE.mdoverwrite — the benefit of that change reached new projects only. A project that predates it now runs the same detection asbootstrapPhase 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.jsonhas nosuperpowerskey, 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 arbitration — overwrite this file and drop eight lines from it are not the same question, andKeep itstays 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 answeringOverwrite with the new templatewould silently re-add the very block just removed. The detection is recorded as{ detected, via },viabeing the signal that fired ornullwhen none did./groundrules:closehardened by its own acceptance pass (ADR 0038). The five cases fromintake/2026-09-08-close-the-session-update-the-context.mdwere exercised against two throwaway repositories by two fresh subagents given only theSKILL.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 toHEADon 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 required —HEAD~15does not resolve in a young repository, and the empty tree puts the commit that createdPLAN.mdinside 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 andCHANGELOGlines demoted to pointers to confirm against the diff, since both over-claim;git diffhunks explicitly in bounds while opening files is not; and an absentCHANGELOG.mddeclared normal rather than degraded. The generatedCLAUDE.mdtemplate said three questions while listing four — a regression from adding thecloseline — andskills/checkpoint/SKILL.mdhad 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 indocs/LEARNINGS.md.- An intake brief no longer names where it was written.
intake/2026-09-02-ai-native-sdlc-evals-and-verification.mdopened 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 fromCHANGELOG.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). Bothloop/LOOP.mdandloop/verifier.mdalready 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, itsSTATUSnarrative, 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; itsverifier.mdgains 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: trueon a protectedmainis 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, butmainis 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 globalCLAUDE.mddoes forbid it (noCo-Authored-By, noClaude-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 aspolicies.noAiAttribution: truein.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. MetaCLAUDE.mdGit workflow section updated. Dogfood only — no change to the plugin's output (the generatedCLAUDE.mdstays branching-neutral).
/groundrules:migratetrusted one JSON key about what version produced a file. OLD came fromgroundrulesVersionand 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 eachgeneratedFilesentry'sgenerated-bysignature 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 offeredOverwrite, 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:migratecould write a literal{{KEY}}into a user's file (ADR 0041). Its Phase 3 said, in one line, "substitute the placeholders withanswers" — andanswersis not sufficient by construction:bootstrapfills a template from the interview plus the folder scan ({{STACK}}), the clock ({{DATE}}), the globalCLAUDE.mdand the git remote, while a project bootstrapped by an older version can carry ananswersobject holding little more thanprojectName. 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 includingintent; then the file on disk, the strongest source and the onebootstrapnever 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, sincemigrateis re-runnable by design. Never fabricated and never asked —migrateis 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, soPLAN.mdsailed through and an overwrite replaced a real task with (add the first active tasks here).Overwriteis no longer offered on the files a project writes into —PLAN.md,CHANGELOG.md,LEARNINGS,AGENT-EVALS,VISION,INTENT,ADOPTION-LOGanddocs/decisions/— and the missing option is explained rather than silently absent. And the comparison text is now whatbootstrapwould produce for the project, not the raw template:bootstrapdrops the sections a global covers, splices## Invariantsonly 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 letOverwritesilently delete the interop block whose removal is a separate question, which is the exact collision the separate question exists to avoid. Smaller:{{DATE}}comes frombootstrappedAtand 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, becausebootstrapdefines{{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.mddescriptions were invalid YAML —adopt,idea,premortem,slimcarried an unquoted:(colon + space) inside theirdescription, which a strict parser rejects. They are now double-quoted (inner quotes escaped); the other ten were already clean. Also tightened the project'sBash(find * -type f *)allow rule toBash(find . -type f *): a leading wildcard matches any option inserted before-type, so the rule approved more than it named.
Posture & positioning, harvested from the field. A third
## Postureaxis in the generatedCLAUDE.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.
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 whenCLAUDE.mdadherence decays (context saturation, competing instructions). Records the two subtle-but-true points: it's a passive probe not a guard (CLAUDE.mdis context, not enforced config — to block, you need aPreToolUsehook, 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.mdgains 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.mdPosture gains a "Keep the diff small" axis (implements ADR 0034). The## Posturesection 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 fromforrestchang/andrej-karpathy-skills— its other two principles were already covered more deeply (Push back +/premortem; the loop). Dogfooded in this repo's ownCLAUDE.md.
adoptFull 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.
adopt— "Full adoption" mode (implements ADR 0033). A third adoption strategy alongsideMap in placeandConsolidate, 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--fullflag (composes with--dry-run)..groundrules.jsonrecordsadoptionMode: "full". Extends the consolidate mechanics of ADR 0018 without a new skill.
/goalinterop. The loop's swappable executor is now visible where users act —realizesurfaces both launch options, and the generated loop docs explain when to reach for Claude Code's/goalvs the high-fidelity groundrules loop. Implements ADR 0031.
/goalinterop 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-fidelitybash loop/run-loop.sh— framed choose by stakes. The generatedloop/README.mdgains 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-/goalverifier-gate note. README + QUICKSTART + TUTORIAL + therun-loop.shheader point to it. Docs + a recap enhancement only — no runtime, no detection, no new skill. PRDdocs/prd/goal-interop.md.
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.
- 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 inPRD.md.tplRisks, a one-line premortem pointer in the generatedCLAUDE.mdPosture, 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).
- 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/TUTORIALcommit the red test before launching;realizePhase 5 reminds to commit the test + backlog;verifier.mdcheck 7 flags an untracked test;LOOP.mdcommitsloop/lessons.mdwith the iteration (it's tracked on purpose). Captured indocs/LEARNINGS.md: a guard that compares against git only works on committed files.
- 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.
Loop docs + validation. A three-tier guide for the loop shipped in 1.6.0 (QUICKSTART → TUTORIAL → WALKTHROUGH), a deterministic runner test, and the
/goalinterop decision. Docs/tests only — no change to the plugin's skills, templates, or generated output.
- 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 fullrun-loop.sh— per ADR 0031) → check the commit. Positioned as the entry point;TUTORIAL.md(Game of Life) is the deeper path,WALKTHROUGH.mdthe validation reference. README +test/loop/README.mdpoint 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 nolife.go— the loop writes it. Chosen because the tempting in-place implementation fails the blinker/glider tests, sogo 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 pureStep· naive in-place fails 2 tests); tutorial validated by a fresh-subagent replay running realgo test. PRDdocs/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 →bootstraploop opt-in →/groundrules:realize→ run the loop → a loop-authored commit → aBLOCKED→ triage), doubling as a validation series.WALKTHROUGH.mdnarrates each step with its expected outcome (tagged[shell]/[agent]/[human]);validate-runner.shis the deterministic layer — stubsclaudeto assertrun-loop.sh'sMAXcap,DONEstop, and per-iteration freshness (no LLM, 11 checks); fixtures provide a redslugifyacceptance 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. PRDdocs/prd/loop-walkthrough.md. The repo's firsttest/.
- ADR
0031-goal-interop-swappable-loop-executor.md(Accepted) — Claude Code's native/goaland 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.shrepositioned as the high-fidelity executor and the harness-neutral fallback (M2). Implementation (realize emits a/goal-ready condition; interop notes inloop/README.md+README.md) deferred to a PRD. Index 0030 + 0031 backfilled indocs/decisions/README.md.
M1 — Loop-readiness. groundrules becomes the reflection layer a loop runs on: opt-in maker/verifier loop scaffolding, the
/groundrules:realizeforward bridge (with a TDD-before-loop gate), theblocked.mdbackward-crossing convention, and a generatedCLAUDE.mdthat 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).
- 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 inadd-adr/realize/interactive). The generatedloop/README.mdgains a "Triagingblocked.md" section: three routes (too-big → re-decompose viarealize· hidden decision →add-adrthen 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 aResolution:field soblocked.mdis an audit trail, not a graveyard — the maker now writesResolution: (open — awaiting triage)when it parks. A one-line loop-conditional breadcrumb inCLAUDE.mdpoints there. No automation, no new skill (triage is human-owned). PRDdocs/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.tplSuccess-criteria note + a loop-regime-only TDD line inloop/README.md(not a global rule — handoff-not-gospel). PRDdocs/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.mdtasks), 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 intoloop/backlog.md(maker-consumable, append/merge, idempotent) while tagging[supervised]inPLAN.mdin 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. PRDdocs/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 aloop/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 cappedrun-loop.sh(hardMAX),backlog.md(loop-safe tasks only — the loop reads this, neverPLAN.md),loop/.gitignore, and aloop/README.md. Adds a conditional## Invariantssection to the generatedCLAUDE.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.jsongainsloop.scaffolded; resume-safe (missing-only). Structure: ADR 0030. PRDdocs/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 intobootstrap/adoptyet). 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 cappedrun-loop.sh(mandatoryMAXanti-runaway), theblocked.mdconvention (the realization→reflection backward crossing), and aslugifyfixture + 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 indocs/LEARNINGS.md. PRDdocs/prd/loop-minimal-runnable.md. See ADR 0027 / ROADMAP M1.
- M1 brick 6 — generated
CLAUDE.mdroutes 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 → (ifloop/scaffolding exists)/groundrules:realize→ the loop, else just build it. The generatedCLAUDE.mdnow teaches the reflection/realization model the rest of M1 implements. Wording refinement of oneCLAUDE.md.tplsection; the loop route is an inline-conditional one-liner (no dangling reference for non-loop projects). PRDdocs/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.gitattributesso 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, seedocs/LEARNINGS.md). New authoring rule in.claude/rules/plugin-meta.md;visionis the reference shape. - AGENT-EVALS guard hardening format — the
AGENT-EVALS.md.tpland thecheckpointskill 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).
- ADR
0030-loop-namespace-and-backlog.md— for M1 brick 2: a single visible top-levelloop/is the loop's namespace; the loop readsloop/backlog.md(loop-safe tasks only), neverPLAN.mddirectly (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 ofPLAN.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).
adopt→ opt-indocs/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 templateADOPTION-LOG.md.tpl. Distinct fromAGENT-EVALS(agent behaviour) andapply-best-practices(external recs). Spec'd indocs/prd/adoption-log.md.- New skill
/groundrules:vision— builds or refreshesdocs/VISION.mdthrough a guided interview (goal · users · constraints · V1 non-goals · acceptance criteria), reusingdocs-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 — complementsbootstrap(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 indocs/prd/vision-skill.md. See ADR 0027 (method) +docs/LEARNINGS.md(borrowed patterns).
- Content-aware CLAUDE.md tailoring —
CLAUDE.lean.md.tplretired (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/adoptread the global's content and omit only the sections it actually covers (conservative set: Commits · Permissions · Verifying · Claude Code workflow · Git workflow;## Don'talways 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.mdM1 gains a "verifier/maker contract" design note; M3 (cross-project dashboard, companion-tool) added.
skills/bootstrap/templates/CLAUDE.lean.md.tpl— replaced by content-aware tailoring of the singleCLAUDE.md.tpl(see Changed / ADR 0029).
- 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 consistentCo-Authored-Byattribution.
## Posturein the generatedCLAUDE.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 fromintake/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) todocs/prd/<feature>.mdbefore building. Superpowers-aware: defers to superpowers' per-feature spec workflow when that plugin is present, provides the PRD itself when it isn't. New templatePRD.md.tpl. See ADR 0026. - New skill
/groundrules:idea— parks a one-line idea inPLAN.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.tplgains the inbox section by default. See ADR 0027.
-
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/superpowerssource) — 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:prdnow: 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 generatedCLAUDE.mdinterop note gains the "PRD altitude above" line; ROADMAP M1 notes loop scaffolding is the non-superpowers case. Facts captured indocs/LEARNINGS.md. -
checkpointskill — 4th bucket "shipped a user-facing surface → sync the doc" — the capture ritual now also nudges to keepREADME.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 missingdocs/prd/row in What's generated. The metaCLAUDE.mdrelease rule now also runs a mechanicalls skills/↔ README skill-list drift check. -
Generated
CLAUDE.md.tplgit 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 metaCLAUDE.mdnow also states the dogfood's own model (trunk-based onmain), 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 fromPLAN.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 ofPLAN.mdto avoid duplication.
- 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 consistentCo-Authored-Byattribution.
- 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.mdqueue is now empty. - Plugin version bumped 1.3.2 → 1.3.3 across manifests, signatures, and
.groundrules.json(+ migration entry).
verify-bootstrapfalse-positive on.gitignore— the signature check exempted only JSON, but.gitignore(generated from the plaingitignore.minimal, no HTML-comment signature) IS in a real project'sgeneratedFiles, 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.gitignoreis a foreign/skipped file).
verify-bootstrapplaceholder 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 ownCHANGELOG.md/PLAN.mdmention groundrules placeholders by name. Surfaced by running the E2E on the dogfood (15/15 coherent).
- 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).
- README "Updating the plugin" hardened — the two-step update is now explicit (refresh the marketplace catalog then reinstall the plugin;
marketplace updatealone 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 inbootstrap/adopt/migrategot the same clarification.
adopt: staleStarter-kit roletable header →groundrules role(rename leftover).
- Captured the "marketplace update ≠ plugin update" trap that kept the maintainer on plugin 1.1.0 across two releases: a
docs/LEARNINGS.mdrule + adocs/AGENT-EVALS.mdrecurrence 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).
- New skill
/groundrules:slim— analyzesCLAUDE.mdand proposes concrete optimizations to stay under the ~200-line budget (extract a bulky section todocs/, move file-type rules to.claude/rules/withpaths:, de-duplicate, compress), moving content never deleting it.verify-bootstrap's size warning now points to it. The generatedCLAUDE.mdis left untouched (no bloat). See ADR 0024. - Team-portability guidance —
bootstrap(Phase 8) andadopt(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 generatedCLAUDE.mdis left untouched (no bloat — the advice lives in the skills' one-time output). See ADR 0023.
- 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.
- 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).
- 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/blocked →LEARNINGS, agent drift →AGENT-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 (decided →add-adr, learned / 30+ min blocker →learn, agent mistake/hallucination/drift →AGENT-EVALS.md) at boundaries it can perceive — before agit push/tag/release (also wired into theRELEASE.mdpre-release checklist) or a completedPLAN.mdmilestone. 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 fromLEARNINGS.md. Harvested (with the ritual) from an agent-memory article — itsjournal.md,.claude/memory/location and@importauto-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 + nativeReadwins 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.mdtemplates (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.
- Interop pointer for graph/RAG tools —
docs/CONTEXT-ECONOMY.mdnow names the external-corpus tool class (doc-search MCP, GraphRAG/knowledge-graph tools such as graphify) for the case it covers, andadoptgains 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
LICENSEfile +licensefield inplugin.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-kittransition 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.jsonprojectName, 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).
/groundrules:learnproduced the oldContext/Lessonformat while theLEARNINGS.mdtemplate 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).
- groundrules now runs its own checkpoint-capture ritual: added
docs/AGENT-EVALS.md(first entry: "asserts/trusts without verifying") and adocs/LEARNINGS.mdrule ("anchor agent rituals to observable events, never to session end") — captured before this push, as the ritual prescribes.
- 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,@importauto-load).
adoptadoption strategy: new Call-1 question —Map in place(default, previous behavior: duplicates tolerated and documented) orConsolidate(new Phase 4b: migrate role-mapped files to the canonical paths viagit mv/merge, per-file confirmation, optional reformat to template structure, internal-reference sweep)..groundrules.jsongainsadoptionMode+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) andRELEASE.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.
LEARNINGS.mdtemplate 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.mdtemplates (full + lean): new "Session start — read first, in order" section (PLAN → LEARNINGS → VISION → in-progress artifacts).PLAN.mdtemplate: 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).
- 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.
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, keystarterKitVersion→groundrulesVersion.migraterenames it (git mv) and rewrites the key; all skills read the legacy file as fallback and point tomigrate. - Signatures: new files carry
<!-- generated-by: groundrules vX.Y.Z -->. The legacystarter-kitform is still recognized everywhere (resume mode,verify-bootstrap— reported as⚠️ legacy, fixable with--fix;migrateoffers a grouped rewrite). - Marketplace & repo: marketplace
claude-code-starter-kit→claude-code-groundrules(the Claude Code distribution channel); repolozit/claude-code-starter-kit→lozit/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.
- 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).
- Best-effort plugin update check (Phase 0) in
bootstrap,adoptandmigrate: 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.migrateadditionally 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).
- Contact email in
plugin.json(author) andmarketplace.json(owner) switched to the public addressguillaume.ferrari@protonmail.com. - Marketplace renamed
starter-kit-local→claude-code-starter-kit(matches the GitHub repo; the old name was a leftover from the first local test). Install spec is nowstarter-kit@claude-code-starter-kit. Users who added the marketplace under the old name keep it locally (theirupdatecommand still usesstarter-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).
- 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 renamedstarter-kit→groundrulesas the defining breaking change of V1.0.0 (namespace verified free: npm, PyPI, GitHub).starter-kitstays for the whole 0.x series; ~20 candidate names evaluated and recorded with verdicts (runner-up:charter).
brief/renamed tointake/— the upstream-notes folder is now generated asintake/("intake" = material received before processing), a clearer name than "brief" which suggests a single document. Template renames (brief-INTENT.md.tpl→intake-INTENT.md.tpl,brief-README.md.tpl→intake-README.md.tpl),{{INTENT_SOURCE}}values, and all path references updated acrossbootstrap/adopt, the generated templates, the public README, and the dogfood (git mv brief intake). See ADR 0014./starter-kit:migratelearns the rename: for a pre-rename project it offersgit mv brief intake, fixes.starter-kit.jsonpaths, and flags stalebrief/references in the project docs. Renames chain (a pre-0.7brief/00-INTENT.mdlands directly atintake/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).
- ADR
0014-rename-brief-to-intake.md— rationale and alternatives considered (intent/,inbox/,upstream/, …).
- Meta: documented the batch-small-changes release cadence in the root
CLAUDE.md(accumulate under[Unreleased]; bump/tag/release only on explicit request).
/starter-kit:adoptnow always offers the optional/specialized docs. Call 3 was gated on scan detection, so when nothing was detected the question was skipped and docs likeDATA_MODEL/SECURITY/DESIGN_SYSTEM/ROADMAP/I18N/ARCHITECTURE/GLOSSARY/CHANGELOGwere 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.
- "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.
- 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).
media/moved todocs/media/— the asset folder is now generated underdocs/instead of at the project root, to avoid colliding with a project's own top-levelmedia/orpublic/. Updated acrossbootstrap(scan + mapping),adopt, theCLAUDE.md/READMEtemplates, and the dogfood (media/README.md→docs/media/README.mdviagit mv). See ADR 0013./starter-kit:migratelearns the move: for a pre-0.9 project it offers togit mva starter-kitmedia/todocs/media/(leaves a project's own unrelatedmedia//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).
- ADR
0013-media-under-docs.md— rationale for moving the asset folder underdocs/.
- English-only — dropped the bilingual FR/EN support. All
*.fr.tpl/*.fr.mdtemplates removed; English is now the single template set (one.tplper file, no language suffix;adr-template.md). Removed the{{LANG}}placeholder, the "language" interview question, and all per-language template selection acrossbootstrap/adopt/migrate/add-adr/learn. The 7SKILL.mdfiles 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; obsoleteanswers.langdropped).
/starter-kit:migrateon 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.
- ADR
0012-english-only.md— rationale for dropping the bilingual FR/EN templates and the{{LANG}}logic.
- 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, migrationsdocs/SECURITY.md— authentication, authorization, personal data & GDPR, secrets, attack surfacedocs/DESIGN_SYSTEM.md— colors/tokens, typography, spacing, components, accessibilitydocs/ROADMAP.md— long-term milestones (distinct from the activePLAN.md)docs/I18N.md— supported languages, translation organization, localized formats
- Templates added (FR + EN):
DATA_MODEL,SECURITY,DESIGN_SYSTEM,ROADMAP,I18N(10 files). - New
bootstrapplaceholders:{{HAS_DATA_MODEL}},{{HAS_SECURITY}},{{HAS_DESIGN_SYSTEM}},{{HAS_ROADMAP}},{{HAS_I18N}}. - "No AI attribution" policy detection —
bootstrap/adoptread (read-only) the project + globalCLAUDE.mdfor a rule forbidding AI attribution (no AI attribution,Co-Authored-By,Generated with Claude…) and setpolicies.noAiAttributionin.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 beyondbootstrap's own commit. See ADR 0011. - Deference to a tool-managed project CLAUDE.md — when
bootstrap(resume) /adoptfind aCLAUDE.mdalready present (no starter-kit signature, often tool-managed e.g. a corporateclaude-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. RecordsadoptedFiles["CLAUDE.md"]. Takes precedence over the lean logic below. See ADR 0010. - Global/enterprise CLAUDE.md awareness —
bootstrap/adoptdetect 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.jsonwithadopted: true+adoptedFiles. Never overwrites/deletes; no git init/remote; supports--dry-run. Fills the brownfield gap thatmigrate(refuses non-managed projects) andbootstrap(treats existing files as foreign) left open. See ADR 0008. - Pre-existing planning detection in
bootstrapPhase 1 (and reused byadopt): detectsPLAN.mdaliases — 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 intoPLAN.md) instead of the standard yes/no — never overwrites, never deletes the alias. Case-collision guard: never generatesPLAN.mdwhen a case-variant exists (avoids a cross-platform git hazard).docs/superpowers/plans/is explicitly not treated as an alias (different altitude);PLAN.mdis kept and should point to the active superpowers plan.
- De-numbered the entry docs (dropped the
00-prefix):brief/00-INTENT.md→brief/INTENT.md,docs/00-VISION.md→docs/VISION.md. The partial numbering scheme (only VISION/INTENT carried a number, no other doc did) provided no real ordering benefit. Updated acrossbootstrap/apply-best-practices/verify-bootstrapSKILLs,brief-INTENTtemplates,README.md,.starter-kit.json(generatedFiles), and the dogfood files themselves. Historical references (CHANGELOG[0.5.0], ADR 0005, the migrationnote, 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-featuredocs/superpowers/specs|plans/live at different altitudes (no duplication);PLAN.mdshould reference the active superpowers plan rather than duplicate tasks.
- ADR
0006-optional-specialized-docs.md— rationale for adding these docs as opt-in conditional templates (and for excludingtickets/, Salesforce-style and project-specific docs). - ADR
0007-denumber-entry-docs.md— rationale for dropping the00-prefix on VISION/INTENT. - ADR
0008-adopt-brownfield-projects.md— rationale for a dedicated/starter-kit:adoptskill + 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.
- 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. --fixmode: corrects safe issues (signature version mismatches viaEdit). Other issues remain manual (missing files, placeholders, invalid JSON, oversized CLAUDE.md).- Read-only by default;
--fixrequires explicitAskUserQuestionconfirmation before applying.
- Per-file checks: existence,
- 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-bootstraprecommendation is marked as implemented (struck through)..starter-kit.json: V0.5 apply-best-practicesappliedPracticesentry updated —verify-bootstrapitem moved fromdeferredtoapplied (V0.6).
- 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— fetcheshttps://github.com/shanraisshan/claude-code-best-practicevia WebFetch, passes the project'sdocs/00-VISION.mdas 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 todocs/best-practices-pending.mdfor manual review. .starter-kit.jsonschema extended withintentfield (source, goal, users, constraints, nonGoals, acceptanceCriteria) andappliedPractices(array of{appliedAt, source, items[]}).
bootstrap/SKILL.mdrenumbered: 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.
- Backfilled
brief/00-INTENT.mdretroactively from the original prompt that started this project. - Synthesized
docs/00-VISION.mdcapturing goal, 6 constraints, 5 non-goals, 7 acceptance criteria. .starter-kit.jsonrecords the V0.2 manual integration of shanraisshan/howborisusesclaudecode best practices underappliedPractices(so a future/starter-kit:apply-best-practicesrun can diff against them and propose new items).
- 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-runsupport, refuses downgrade). .starter-kit.jsonschema extended:bootstrappedWithVersion(immutable) +migrationsarray (append-only).
/starter-kit:add-adr— auto-incremented ADR creation with index update./starter-kit:learn— dated entry prepended todocs/LEARNINGS.md.- First two ADRs:
0001-marketplace-json-location.md,0002-plain-text-placeholder-substitution.md.
CLAUDE.md.{fr,en}.tplrestructured to integrate best practices fromshanraisshan/claude-code-best-practiceandhowborisusesclaudecode.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.mdsplit intoadr-template.{fr,en}.md
marketplace.jsonmoved from repo root into.claude-plugin/- V0.1 gap: LANG=en producing FR-content files for non-CLAUDE templates
- Initial scaffolding:
.claude-plugin/plugin.json,marketplace.json,skills/bootstrap/SKILL.mdwith 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.