Repository navigation
Releases
ts-react-linter-driven-development v2.1.0 — one set of thresholds, mixed-diff routing, hunter listings
[2.1.0] - 2026-10-18
Changed
- A whole-repository review leaves the mutant question to scoped reviews. On
--all, the hunter does not judge the question "does a mutant survive a leaf's
tests?". Its receipt readsper-leaf, not judged, and itsnot reached:line names
the three leaf directories with the most hits, each as the scoped review that
judges it (/tsr-ldd-review <dir>). A scoped review judges the question in full. The lead for
the mutant question also skips.tsxfiles,components/,hooks/andcontext/. - The god file has a mechanical lead. The question "is one feature's code spread
across layer directories?" lists the longest files in scope withwc -land checks
each againstsonarjs/max-lines(600). A file over the limit, or with
amax-linesdirective that silences the rule, is a violation when it stands in for the
whole slice. - The review command says how to cover a large repository. On a repository
larger than a few dozen source files,--allreportsPARTIAL coverage. The
command names the form that covers everything: one review per directory
(/tsr-ldd-review <dir>).
Fixed
- A claim that something is missing needs a listing. A rule hunter that reports
a missing test file, doc, case or cleanup now carries thels,findorgrep
command that looked for it, run over the repository and not only the review's
bundle, and that command's output. Without the listing there is no finding. A
hunter once reported a test file as missing when it existed outside the scope.
When the hunter's budget leaves no call for the listing, the claim appears in the
hunter'snot reached:line asunverified; the report never drops it. - A cluster title carries its rule ids. The review reference shows every cluster
title as🔗 CLUSTER: <anchor> — <rules>, the same form as the skill. Agents
followed the reference, so the rule ids were on the lines below the title, and the
report graders missed correct clusters. - The mutant hand check reads the error assertions. The hand check opens the
leaf's test file, also when the file is outside the review's scope, and reads each
error assertion. An assertion that matches only a word all the leaf's errors share
(toThrow('tenant')) lets a removed check or a changed message survive, and it is a
violation.
ts-react-linter-driven-development v2.0.0 — generated from the shared core
[2.0.0] - 2026-10-06
Changed
- Generated from the shared core. The plugin is rendered from the same core as
go-linter-driven-developmentandpython-linter-driven-development— twelve
rules, the maxims, the design, TDD, refactoring, testing, review and documentation
skills, the hunter/skeptic/critic review and the repo-brain gate — with TypeScript
and React knowledge. Every canonical example is TypeScript in a React repository;
every falsifying question carries a detect line over.tsand.tsxfiles. @component-designingis@code-designing. The design skill carries the
core's name; the other five skill names are unchanged.- No
CLAUDE.mdin the plugin directory. The 1.x file that instructed Claude to
invoke the orchestrator for every change is gone; the orchestrator skill
auto-triggers in a React project instead. - Commands carry the
tsr-lddprefix./tsr-ldd-autopilot,/tsr-ldd-quickfix,
/tsr-ldd-prepare,/tsr-ldd-analyze,/tsr-ldd-review,/tsr-ldd-status;
/wire-repo-brainstays unprefixed, as in the Go and Python plugins.
Added
- The twelve rules under
rules/, R1-primitive-obsession through
R12-mutation-discipline, each a self-contained hunter rulebook with a TypeScript
canonical example and a detect line on every falsifying question. - The review's detection pass and scope bundle are scripts.
scripts/ldd-scope.sh
writes the bundle from the review's scope rung — a file list, the working tree, the
branch against its base, or the whole repository — with the added comment lines
the critic judges incomments.txt, and prints one summary line.
scripts/ldd-detect.shruns every detect line over the bundle and writes
hits.tsv,hits-all.tsvandcounts.tsv, with the suppression scan as a row;
two runs over one tree write identical counts. Every falsifying question in
rules/R1toR12carries a detect line beside its prose — agreppattern over
.tsand.tsxfiles, apathpattern over their paths, a reference to one of
the R9 gate's questions, or the wordjudgmentfor a question the hunter can only
read. The pre-commit review's first step runs both scripts and reads the counts
table they print; a rule family with a hit gets one hunter carrying its rule files
by path and its family's rows of the hits table, and the comment critic reads the
bundle's comment lines as its inventory. What each question asks is unchanged. - R1 catches containers of primitives. Two falsifying questions: Q7, a nested
container in a signature or a field (Map<string, string[]>,
Record<string, Record<string, number>>), always a finding; Q8, a flat
string[],Record<string, string>or tuple crossing a function boundary, judged
by what its receivers do with it — a lookup, a membership test, a loop that
filters and extracts, each one a method of a type that does not exist yet. The
move is Name the Container; the lint-fixer's routing table, the refactoring
routing table and the design skill's linter triggers carry it as a review-only
row, because ESLint has no rule for it. - R7's mutation question. Q7 asks whether a mutant survives a leaf type's
tests: coverage is the floor, the mutation score the claim, and the move is Kill
the surviving mutant. The TypeScript mechanics name Stryker —npx stryker run
withmutatenaming leaf modules only, never pages, hooks or the wholesrc/
tree — and every survivor is triaged as a missingit.eachrow, dead logic or a
recorded equivalent mutant. The workflow's pre-flight discovers amutateor
strykertarget beside the test and lint commands, and the testing reference's
checklist carries the row. coding-rules/ts-react.md, the TypeScript + React coding-rules handbook. The
twelve rules with TypeScript examples and the binding's positions as asides, the
house rules with their TypeScript spelling, a self-review checklist and the
mechanics; generated fromcore/handbook/andlang/ts-react/handbook/in the
same run as the plugin, and read by a team that does not develop with it.- Nine positions where the rules meet TypeScript and React idiom, recorded in
the main repository'sdocs/language-residue.md:undefinedis the declared
absence andnullstops at the boundary; an optional collaborator is a module
constant supplied by a destructuring default; a self-validating type is the one
function that builds the value,parseX(raw: unknown)at the boundary and
readonlyfields after; the JSDoc summary line is the contract; the kept switch
is over a discriminated union closed byassertNever; effects, timers and queries
have owners and cleanups, and the race is the stale closure and the out-of-order
response; module state is silent for constants and types, silent inmain.tsx
for configuration and wiring, and reported everywhere else; a component is an
orchestrator whose logic lives in hooks and pure functions placed by R4's ladder;
MSW is the real layer for HTTP andvi.mockof an internal module is R6's seam. - Linter routing keyed by ESLint rule ids. The SonarJS complexity family and
react/no-unstable-nested-componentsroute to R3,max-paramsto R1,
sonarjs/max-linesandreact/no-multi-compto R5, the typescript-eslint
no-unsafe-*family at a boundary to R2, exhaustiveness and nested switches to
R11,react-hooks/*and the floating-promise rules to R10,
import/no-mutable-exportsto R8,no-param-reassignand
sonarjs/prefer-read-only-propsto R12. Every suppression form —
eslint-disablein all its spellings,@ts-expect-error,@ts-ignore,
@ts-nocheck,prettier-ignore— is one the lint-fixer never adds. - The agents:
rule-hunter,overabstraction-skeptic,comment-criticand
lint-fixer, each spawned in an isolated context and pointed by path at its rule
files — a hunter gets its rule family's, four hunters at most, with its family's
rows of the detection pass's hits table; the critic gets the bundle's comment
lines. - Seven slash commands:
/tsr-ldd-autopilot,/tsr-ldd-quickfix,
/tsr-ldd-prepare,/tsr-ldd-analyze,/tsr-ldd-review,/tsr-ldd-statusand
/wire-repo-brain. - Repo-brain gate with the TypeScript adapter.
scripts/check-repo-brain.sh
resolves backticked symbols against functions, variables, classes and their
members, interfaces, types and enums, owned by their module and their directory;
apackage.jsondirectory outsidenode_modulesmarks a sub-project. - The six case studies under
examples/, in TypeScript. The over-abstraction
rejection is areadonlyconfig against aCIDRPresencewrapper; the storify
case extracts anIPConfigleaf from a settings hook; the anti-if case dispatches
through aRecord<Channel, …>and aswitchclosed byassertNever; the
switch-to-polymorphism case movesfillUpdateonto the patch kinds; dependency
rejection replacesimport.meta.envreads with oneAppConfigbuilt in
main.tsx; the comment-noise verdicts fall on non-exported JSDoc.
Removed
- The hand-written six-skill text. The 1.x
SKILL.md,reference.mdand
examples.mdfiles are replaced by the rendered core; nothing from them is
carried over verbatim. - Storybook generation as a documentation step. A story is the runnable example
only where the repository has Storybook; the documentation skill no longer
writes.stories.tsxfiles on its own. - The accessibility review checklist. Accessibility is enforced in the linter
phase through the repository'sjsx-a11yconfiguration, where a failing rule is
a mechanical fix, not a review hunter's finding.
Measured against 1.x
Both plugins reviewed the ts-react-mini eval fixture (164 planted violations and
controls, in buzzdan/ldd-evals) under the
same prompt and model (claude-sonnet-5): eight review cases whose prompt names no
slash command and whose graders carry no rule ids, then refereed finding by finding
against the manifest, by substance.
- Whole repository. 1.x found 53 of the 129 planted diseases a review must find,
2.0 found 89: 42 by both, 11 by 1.x alone, 47 by 2.0 alone, 29 by neither. False
positives on the 30 controls: 3 against 1. Cost $3.22 against $6.30. - Scoped cases. 2.0 found as many or more in six of seven (retention 4/3,
endpoint 4/2, ceremony 4/2, optional collaborators 6/4, globals 4/4, the
798-line centerpiece 34/11 of 45); 1.x was ahead on the placement picker (3/2). - What 2.0 sees that 1.x never names: tests (fused success/error tables, call
counts on doubles, sleep-then-assert,vi.mockof an internal hook beside MSW
handlers), test seams (an interface with one production implementer, hand
doubles, a false "avoids an import cycle"), documentation (the orphan doc, its
file:linecitation and phantom symbol, the unwiredCLAUDE.md), suppressions
as findings, the comment critic's verdicts, role-named directories and the
layer-versus-slice split, and three concurrency plants (an interval started in a
constructor and never cleared, a check-then-await race, bare sleeps in retries). - What 1.x sees that 2.0 does not: accessibility (no hunter owns it; 2.0 relies
on the repository'sjsx-a11yrules, which the fixture disables as the house
style does), and the React tree in the whole-repository run, where 2.0's types
hunter declared partial coverage and did not reachcomponents/,hooks/or
pages/DeviceView/, so the nested-component, prop-drilling and sort-in-render
plants went unseen rather than misjudged. 1.x also raised several real bugs
outside the manifest (a cross-tenantlastSeenkey, a score recomputed by hand
and drifting,NaNpassing a port check). - 2.0 weaknesses the run exposed: it asserted a test file was missing that exist...
go-linter-driven-development v2.9.1 — visibility default: private symbols get no comment
A real 143-line file surfaced the gap v2.9.0 left open: every one of its nine unexported symbols carried a comment — one of them 22 prose lines — because the tier budget caps a comment's size but nothing decided whether it should exist.
Added
- Visibility default (R9) — unexported symbols get no comment. The name is the documentation; a name that needs a comment wants a rename or an extraction (R3) first. The special case is one line carrying a very high-value toolbox item: an ordering constraint, an external library quirk, the WHY of a magic number, the package's one real policy. Anything more moves to the exported caller, the package doc, or the feature doc. The tier table now explicitly prices exported API only.
- New case file
examples/private-comment-noise.md— the nine-helper file with per-symbol verdicts (four one-liners survive, five comments deleted; ~68 comment lines become 4) and the full "after". Rides in the comment-critic's spawn payload from both @pre-commit-review and @documentation. - New anti-toolbox entry: review-defense narration — the writer arguing with an imagined reviewer ("bounds-checked: it never indexes an empty slice", "deliberately narrow — not a generalized table"). The code shows its own safety; a design choice worth defending is defended in the feature doc.
- Critic bias for unexported symbols — the question is existence, not size: default verdict DELETE; TRIM down to the one high-value line only when it already exists; never grow a private comment.
- @documentation writes accordingly — FEATURE step 3 writes godocs for exported symbols only by default, so the noise is not written in the first place.
Field test
Run without the answer key (case file withheld from the payload): 9 comments — 0 KEEP / 3 TRIM / 2 REWRITE / 4 DELETE, matching the case file on 8 of 9 verdicts. The critic also routed the one over-budget-but-genuine WHY up to the exported caller instead of deleting the knowledge.
Full details in CHANGELOG.md.
go-linter-driven-development v2.9.0 — empathy test + when-in-Rome check
Lessons from a repo owner's hard review of a large generated PR: the code was mergeable, but "could not reasonably ask another human to maintain the result".
Added
- Empathy test — R9's test 3 (plain-English) grows teeth: write for a fresh graduate whose first language may not be English; unexplained acronyms and insider jargon fail, in comments and in the symbol names they document; and self-standing — a comment you can only understand after reading the code (or another comment) has negative value. The comment-critic now reads each comment before the surrounding code, and notes a rename recommendation when the jargon lives in the symbol name.
- Decoder-ring references join the provenance anti-toolbox: plan/decision/test-plan IDs, requirement tags, spec section refs fail even when they resolve inside a repo doc — fact as plain prose, doc via one See-edge. Worked ❌/✅ example in the catalog.
- Restated repo idiom is a new floor failure mode: a convention the repo applies everywhere is never re-justified at a use site, even though it is technically a WHY. The critic greps the repo for the pattern before crediting.
- See-edge placement rule: the
See docs/<feature>.mdline is budget-free only as its own trailing line, never woven into the summary sentence. - When-in-Rome check (@pre-commit-review) + new 🟠 New Practice finding category: test mechanisms, dependencies, or conventions the host repo does not already use are adoption decisions for the repo owner — discussion or separate PR, never silent inclusion.
- Two new maxims: "Empathy is a core engineering value" and "When in Rome, code as the Romans do".
Field test
The critic ran with the new payload against the reviewed PR's five comment-heaviest files: 49 comments — 7 KEEP / 19 TRIM / 19 REWRITE / 4 DELETE. It caught every comment the human reviewer flagged, plus ~20 more with the same problems. The one miss (jargon in a symbol name) became the rename-note addition.
Full details in CHANGELOG.md.
go-linter-driven-development v2.8.0 — Comment Value Toolbox + comment-critic
The comment-quality release: v2.7.0 + v2.8.0 together. Godoc comments get a hard tiered budget, a named value standard (the Comment Value Toolbox), and an adversarial reviewer — the comment-critic joins the hunter/skeptic review architecture. Field-tested against the real PR review that motivated it: 3/3 human-flagged comments caught, 0 false positives.
[2.8.0] - 2026-07-20
Added
- Comment Value Toolbox + comment-critic — comments now have an adversarial
reviewer. Reviewers reported ldd-written comments as noise: restated code,
filled templates, no context. Root cause was architectural: @pre-commit-review
runs in Phase 4, @documentation writes godocs in Phase 5 — comments were never
adversarially reviewed, only self-checked by their writer.- The Comment Value Toolbox: a named, growable catalog of the ways a comment
delivers value — WHY-not-WHAT, wider context, use cases/flows, boundary
contract, guarantees, network edge. Normative kinds list in R9's comment
policy; the catalog with worked examples lives in @documentation's
reference.md and is designed to grow. - Three-test standard (normative in R9): toolbox-value (floor: a prose line
delivering no toolbox value is cut; ceiling: the comment must carry the
highest-value items for its symbol's tier — short-but-dodging fails too),
tier budget (from v2.7.0), and plain English (everyday words, short
sentences — not all readers are native speakers; applies to godocs AND
feature docs). The floor names provenance a failure mode — PR numbers,
review items, "the previous behavior" narration — under the 5-year reader
lens: readers care how the product behaves now, not which review round
produced it; history is rewritten as present-tense rationale, and
incident/ticket refs survive only as rationale. Falsifying questions
unchanged. - New
comment-criticagent: read-only, single obsession — comment value.
Judges every comment in the diff (godoc, in-body, test) against the three
tests; verdicts KEEP / TRIM / REWRITE / DELETE with evidence; every rewrite
names the toolbox item it delivers. In-body block-narration comments route to
R3 (extraction candidates). Adversarial default: uncertain → fails. - @documentation closes the timing gap: write-time three-test gate in
step 3, then a critique loop — spawn the critic on the full diff, auto-apply
every non-KEEP verdict, re-critique once to confirm; report carries the delta
(N deleted · M trimmed · K rewritten). Philosophy gains "plain words over
clever words". - @pre-commit-review spawns the critic on the standalone/PR path whenever
the diff contains comments; verdicts land as 🟡 Readability Debt, advisory.
- The Comment Value Toolbox: a named, growable catalog of the ways a comment
Changed
Task→Agenttool rename across all skill and command frontmatter and
prose: Claude Code renamed the subagent-spawning tool in v2.1.63;Taskstill
works as a backward-compat alias, but the plugin now uses the canonical name.
[2.7.0] - 2026-07-20
Changed
- Tiered godoc budget — R9's comment policy now has hard numbers. Generated
godoc comments were verbose enough to slow human review; "menus, not forms" was
guidance without a bound. R9's rung-1 comment policy is now a 1–5 prose-line
budget scaled by the symbol's role: helpers 0–1 line, contract types (parsing
constructors, self-validating types) 2–3, crossroads (entry points, orchestrators,
feature front doors) up to 5. Blank//lines, theSee docs/<feature>.mdedge,
and short inline examples (2–4 lines) are free; overflow moves to the feature
doc — the placement rule made operational at write time. Two bounded escape
hatches: a package that genuinely earns more moves its godoc to a dedicated
doc.go(~20–30 lines), and a crossroads that deserves richer inline godoc gets
an optional expand recommendation in @documentation's FEATURE report instead
of extra lines — a human decides. Guidance-only: falsifying questions, hunters,
and the skeptic are unchanged.@documentationFEATURE step 3 applies the budget; its report format gains an
optionalExpand recommendationssection.- reference.md godoc menus annotated with tier budgets; new
doc.gohatch note,
checklist budget items, and an over-budget → trimmed-to-tier worked example. - Root
coding_rules.mdComments section aligned with the budget.
go-linter-driven-development v2.0.0 — rules as data
go-ldd v2 — the rules-as-data release. Each design principle now lives exactly once, as data in rules/R1–R9; skills are thin directional views over the rules, and review is done by parallel single-obsession hunters plus an over-abstraction skeptic.
⚠️ Breaking change
The quality-analyzer and go-code-reviewer agents were removed. If you invoked them directly (or reference them in your own CLAUDE.md / custom commands), migrate:
| You used | Use instead |
|---|---|
quality-analyzer |
/go-ldd-analyze — read-only tests + lint + hunter/skeptic review, combined report |
go-code-reviewer |
@pre-commit-review — the hunter/skeptic review |
Everything else is a drop-in upgrade: plugin name, all six skill names, all five existing /go-ldd-* commands, auto-detection triggers, and zero-configuration discovery are unchanged.
Upgrade
/plugin update go-linter-driven-development@ai-coding-rules
What's new
rules/R1–R9 — the single source of truth. Each rule ships its Principle, Why, canonical before/after, forward Design guidance, backward Fix pattern, and Falsifying questions with grep-able detection commands.examples/case law — deep worked studies the rules cite:storify-leaf-type,overabstraction-cidr,dependency-rejection.- Hunter/skeptic review —
@pre-commit-reviewgrep-prefilters the diff per rule, spawns one parallelrule-hunterper rule with hits (each fed a single rule file as its entire rulebook), then anoverabstraction-skepticthat tries to kill every proposed extraction. Findings are categorized (🐛 Bugs / 🔴 Design Debt / 🟡 Readability / 🟢 Polish) and advisory — nothing blocks your commit. - Isolated
lint-fixeragent — the full-repo lint-fix loop runs out-of-conversation; mechanical issues get fixed, design failures get escalated with a rule route. - Per-behavior TDD loop — the orchestrator now runs RED→GREEN→REFACTOR per behavior with package-scoped lint each cycle; full-repo lint happens once, in Phase 3.
- New command
/wire-repo-brain [path]— bootstrap the R9 documentation network on an existing repo in one pass (code→docs edges,index.md, CLAUDE.md wiring). Run it once to make a repo AI-navigable. - Composition-ladder testing —
@testingnow teaches testing each behavior at the lowest rung that contains it, with rung-tagged reusable patterns.
Full details in CHANGELOG.md and the plugin README.