You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(v0.9.11): retire rule copying — hook injection is the sole rule mechanism
Closes the stale-rules gap: init-copied rules in .claude/rules/ never updated
on plugin upgrade and (since v0.9.9) duplicated/contradicted hook-injected
rules while bypassing maturity gating.
- /add:init Phase 2.5: no longer copies rules; detects + offers removal of
leftovers from older inits (adoption-mode flow likewise stops copying)
- load-rules.sh: per-session warning for stale ADD copies (plain + add-
prefixed; user-authored rules ignored) — +2 loader tests
- migration hop 0.9.10→0.9.11 with new remove_stale_rule_copies action
(confirm-once, backup-before-delete, defined in version-migration.md)
Reported-by: Tomasz Dmitruk <@tdmitruk>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+13Lines changed: 13 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,19 @@ All notable changes to ADD are documented here. Format loosely follows [Keep a C
4
4
5
5
For commit-level detail see `git log`.
6
6
7
+
## [0.9.11] — 2026-07-16
8
+
9
+
Closes the stale-rules gap reported by Tomasz Dmitruk ([@tdmitruk](https://github.com/tdmitruk)): `/add:init` used to copy 10 ADD rules into the consumer project's `.claude/rules/`, where they auto-loaded forever at the version they were copied — never updated by plugin upgrades, and (since v0.9.9) duplicating and eventually contradicting the fresh rules the SessionStart hook injects. Copies also bypassed maturity gating entirely.
10
+
11
+
### Changed
12
+
13
+
-**Rule copying is retired.** The SessionStart hook (`load-rules.sh`) is the sole rule-distribution mechanism — always current with the installed plugin, maturity-gated, zero drift. `/add:init` Phase 2.5 no longer writes to `.claude/rules/`; it now only detects leftovers from older inits and offers a batched removal. The adoption-mode "Handling Existing Rules" flow likewise stops copying — user-authored rules are analyzed for overlap but never replaced by file copies.
14
+
15
+
### Added
16
+
17
+
-**Stale-copy warning** — `load-rules.sh` flags files in `.claude/rules/` matching plugin rule names (incl. `add-` prefixed) every session until they're removed, so the conflict is visible instead of silent (+2 loader tests).
18
+
-**Migration hop 0.9.10 → 0.9.11** with a new `remove_stale_rule_copies` action (defined in `version-migration.md`): lists matches, requires one explicit user confirmation, backs up before deleting, never touches user-authored rules.
19
+
7
20
## [0.9.10] — 2026-07-12
8
21
9
22
Dedup + hygiene release closing the three-release token-audit arc (v0.9.8 correctness → v0.9.9 token architecture → v0.9.10 slimming). The five heaviest skills lose ~35–45% of their lines to extraction; security patterns lose their false-positive noise; the hooks and CI lose their soft spots.
Copy file name to clipboardExpand all lines: CONTRIBUTORS.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,7 +12,7 @@ Thank you to everyone who helps make ADD better.
12
12
-**Caleb Dunn** ([@finish06](https://github.com/finish06)) — `/add:docs` skill with archetype-aware discovery. Generates architecture diagrams, API docs, and README drift detection for any project type (web APIs, libraries, CLIs, data pipelines, monorepos). Validated against Home Assistant core and personal projects. (v0.6.0)
13
13
-**Piotr Pawluk** ([@piotrpawluk](https://github.com/piotrpawluk)) — `/add:roadmap`, `/add:milestone`, and `/add:promote` skills. Fills the milestone/maturity workflow gap: interactive roadmap horizon management, tactical milestone operations (list/switch/split/rescope), and evidence-based maturity promotion with 14-category gap analysis. (v0.6.0)
14
14
-**David Giambarresi** ([@dgiambarresi](https://github.com/dgiambarresi)) — `/add:ux` skill: a design sign-off gate before implementation. Iterates on wireframes with the human and blocks UI feature implementation at Alpha+ without an approved UX artifact. Prevents the most expensive class of rework: building the right thing wrong. (v0.6.0)
15
-
-**Tomasz** ([@tdmitruk](https://github.com/tdmitruk)) — README plugin update instructions (v0.7.3); learnings optimization with hook-driven pre-filtering and `/add:learnings` skill (v0.8.0). Context-window reduction via pre-filtered active views and archival system — 62-82% token savings as learnings accumulate.
15
+
-**Tomasz** ([@tdmitruk](https://github.com/tdmitruk)) — README plugin update instructions (v0.7.3); learnings optimization with hook-driven pre-filtering and `/add:learnings` skill (v0.8.0). Context-window reduction via pre-filtered active views and archival system — 62-82% token savings as learnings accumulate. Reported the stale-rules gap — init-copied rules in `.claude/rules/` never updated on plugin upgrade and conflicted with hook-injected rules — fixed in v0.9.11 (rule copying retired).
Copy file name to clipboardExpand all lines: core/rules/version-migration.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -29,6 +29,7 @@ On **every session start**, before any other work:
29
29
-`restructure` — ensure markdown has required sections
30
30
-`rename_fields` — move JSON fields to new keys
31
31
-`remove_fields` — delete deprecated JSON fields
32
+
-`remove_stale_rule_copies` — find files in `.claude/rules/` whose basename matches a plugin rule in `${CLAUDE_PLUGIN_ROOT}/rules/` (also `add-` prefixed variants; user-authored files never match). List the matches and ask the user ONCE for confirmation; on yes, back each up per step 2, then delete. NEVER delete without explicit confirmation.
32
33
33
34
4.**Update version** in config after all steps succeed. On partial failure, stay at last successful hop.
Copy file name to clipboardExpand all lines: core/skills/init/SKILL.md
+25-63Lines changed: 25 additions & 63 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -214,25 +214,26 @@ Then ask the 3 process questions from Section 3 (autonomy, quality mode, team si
214
214
215
215
### Handling Existing Rules
216
216
217
-
For each ADD rule, check for equivalent coverage in `.claude/rules/`:
217
+
ADD's rules are NOT copied into the project — they are injected each session by the plugin's SessionStart hook (`load-rules.sh`), maturity-gated, and update automatically with the plugin. `/add:init` never writes to `.claude/rules/`.
218
218
219
-
-**If equivalent rule exists:** Ask the user:
219
+
For each existing rule in the project's `.claude/rules/`, check for overlap with ADD's rule set:
220
+
221
+
-**If an existing project rule covers similar ground as an ADD rule:** Ask the user:
220
222
```
221
223
You have an existing rule: {existing_rule.md}
222
-
This covers similar ground as ADD's {add_rule}.
224
+
This covers similar ground as ADD's {add_rule} (injected automatically each session).
223
225
224
226
Options:
225
-
a) Keep your existing rule, skip ADD's version
226
-
b) Use ADD's version (newer, aligned with ADD system)
227
-
c) Merge — I'll combine the best of both
227
+
a) Keep your rule as-is — it takes precedence where they conflict
228
+
b) Trim your rule to only the parts ADD doesn't cover
229
+
c) Remove your rule — rely on ADD's injected version
228
230
```
229
231
230
-
-**If no overlap:** Add the ADD rule to `.claude/rules/` with a clean name (no `add-` prefix needed if there's no conflict).
231
-
232
-
-**Naming convention:** If there's potential confusion with existing rules, ADD rules get an `add-` prefix:
233
-
-`add-human-collaboration.md`
234
-
-`add-learning-checkpoints.md`
235
-
-`add-quality-gates.md`
232
+
-**If a stale ADD rule copy exists** (same name as a plugin rule, or `add-` prefixed — left behind by an ADD version before v0.9.11 that copied rules): recommend removal, since the hook now injects the current version and the copy will drift:
233
+
```
234
+
.claude/rules/{name}.md matches an ADD plugin rule. ADD now injects rules
235
+
at session start — this copy is redundant and will go stale. Remove it?
236
+
```
236
237
237
238
### Handling Existing Skills
238
239
@@ -485,60 +486,21 @@ tests/screenshots/errors/
485
486
# tests/screenshots/{feature}/
486
487
```
487
488
488
-
## Phase 2.5: Install ADD Methodology Rules
489
-
490
-
Plugins cannot distribute rules directly. This phase copies ADD's rules into the consumer project's `.claude/rules/` directory so they take effect.
491
-
492
-
### Step 2.5.1: Create Rules Directory
493
-
494
-
```bash
495
-
mkdir -p .claude/rules
496
-
```
497
-
498
-
### Step 2.5.2: Copy ADD Rules
489
+
## Phase 2.5: Verify Rule Loading (no copying)
499
490
500
-
For each of the 10 ADD rule files, read from the plugin and write to the consumer project:
501
-
502
-
```
503
-
Rule files to install:
504
-
1. spec-driven.md
505
-
2. tdd-enforcement.md
506
-
3. human-collaboration.md
507
-
4. agent-coordination.md
508
-
5. source-control.md
509
-
6. environment-awareness.md
510
-
7. quality-gates.md
511
-
8. learning.md
512
-
9. project-structure.md
513
-
10. maturity-lifecycle.md
514
-
```
515
-
516
-
For each rule file:
517
-
518
-
1. Read `${CLAUDE_PLUGIN_ROOT}/rules/{name}.md`
519
-
2. Check if `.claude/rules/{name}.md` already exists in the consumer project
520
-
521
-
**If no conflict (file does not exist):**
522
-
- Write the rule to `.claude/rules/{name}.md`
523
-
- Track as "installed"
524
-
525
-
**If conflict (file already exists):**
526
-
- Use AskUserQuestion with 3 options:
527
-
```
528
-
You already have a rule at .claude/rules/{name}.md.
529
-
ADD also provides a rule with this name.
530
-
```
531
-
- "Keep existing — skip ADD's version"
532
-
- "Use ADD's version — overwrite mine"
533
-
- "Install ADD's version with `add-` prefix (as .claude/rules/add-{name}.md)"
534
-
- Track the user's choice for each conflict
491
+
ADD rules are NOT copied into the project. The plugin's SessionStart hook (`load-rules.sh`) injects the active rule set every session, gated by the project's maturity level — rules stay current with the plugin and never drift. (Versions before v0.9.11 copied 10 rules into `.claude/rules/`; that mechanism is retired because copies went stale and, after v0.9.9, duplicated the hook injection.)
535
492
536
-
### Step 2.5.3: Track Results
493
+
This phase only checks for leftovers:
537
494
538
-
Maintain a results summary for Phase 5:
539
-
-**Installed:** rules written without conflict
540
-
-**Skipped:** rules the user chose to keep their existing version
541
-
-**Prefixed:** rules installed with `add-` prefix to avoid conflict
495
+
1. If `.claude/rules/` exists, list its files and compare basenames against `${CLAUDE_PLUGIN_ROOT}/rules/` (also match `add-` prefixed variants).
496
+
2. For each match — a stale ADD copy from an older init — ask the user once (batch, not per-file):
497
+
```
498
+
Found {N} ADD rule copies in .claude/rules/ from an earlier ADD version:
499
+
{list}
500
+
ADD now injects current rules at session start, so these are redundant
501
+
and will go stale. Remove them? (user-authored rules are untouched)
502
+
```
503
+
3. Track for the Phase 5 summary: **Removed** / **Kept** (user declined).
Copy file name to clipboardExpand all lines: core/templates/migrations.json
+15-1Lines changed: 15 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
{
2
2
"schema_version": "1.0.0",
3
-
"plugin_version": "0.9.10",
3
+
"plugin_version": "0.9.11",
4
4
"migrations": [
5
5
{
6
6
"from": "0.1.0",
@@ -278,6 +278,20 @@
278
278
"to": "0.9.10",
279
279
"steps": [],
280
280
"description": "v0.9.10 \u2014 dedup + hygiene release closing the token-audit arc. Heaviest skills slimmed ~35-45% (init 1093\u2192638, deploy 874\u2192557, verify 761\u2192432, cycle 659\u2192462, docs 582\u2192352 lines) via extraction to templates/ (init-interview, init-output-examples, commit-message, deploy-reference, cycle-plan, verify-report) and references/ (skill-epilogue, secrets-gate, docs-archetypes). Skill version literals normalized to {{VERSION}} (compile substitutes; can't drift). Injection patterns de-noised (ignore-previous noun now required, and a false negative on the canonical injection phrase was closed; base64 blob info@120+; system-heading anchored); audit-log redaction unified with the secret-patterns catalog; PASSWORD_KV case-insensitive; .secretsignore negations warn loudly. CHANGELOG reminder hook moved to PreToolUse (fires BEFORE push); post-write auto-fix now opt-in via hooks.autofix (default false \u2014 linters advise, don't rewrite). CI: marketplace-validate fails loudly instead of skipping green; new hooks-json + load-rules + compile suites in the guardrails matrix. Optional new consumer config key: hooks.autofix. Consumers using the stock .secretsignore template: negation lines were removed (they never worked)."
281
+
},
282
+
{
283
+
"from": "0.9.10",
284
+
"to": "0.9.11",
285
+
"steps": [
286
+
{
287
+
"file": ".claude/rules/",
288
+
"action": "remove_stale_rule_copies",
289
+
"params": {
290
+
"reason": "ADD versions before v0.9.11 copied rules into .claude/rules/ at init. Those copies auto-load stale content alongside (and eventually contradicting) the fresh rules the SessionStart hook injects since v0.9.9, and they bypass maturity gating. The injected rules are canonical."
291
+
}
292
+
}
293
+
],
294
+
"description": "v0.9.11 \u2014 retire rule copying (closes the stale-rules gap reported by @tdmitruk). /add:init no longer writes ADD rules into .claude/rules/ (Phase 2.5 now only detects and offers to remove leftovers); load-rules.sh warns each session while stale copies remain; this migration hop offers a one-time confirmed cleanup. User-authored rules are never touched."
Generate a portable [`AGENTS.md`](https://agents.md) at project root from the project's `.add/` state. `AGENTS.md` is the cross-tool open standard for project-level agent instructions — any agent (Claude Code, Cursor, Codex CLI, Windsurf, Amp, Devin, Copilot) will read it on session start. Publishing one lets mixed-toolchain teams respect the same invariants without installing ADD.
0 commit comments