feat(code-review): walk the full class-refactoring lens on every CR#732
Conversation
The read-only `class-refactoring` lens (MODE=cr) was already in the
always-run set of all four CR skills, but every invocation described it
narrowly ("DRY duplication, single-responsibility breaches, oversized
methods") and the diff-scoped checklist in @rules/code-review/general.mdc
was a closed six-bullet list. A reviewer reading either literally walked a
fraction of what the skill defines, so the rest never reached the report.
- Open the closed lists: they are now the high-frequency subset, not the
boundary of the walk. Speculative interfaces, pass-through Actions,
>4 parameters -> DTO, Simplicity First, business-logic-layer placement,
Repository scope, query performance non-regression, intention-revealing
extraction, naming, and nesting depth are walked too.
- Add the Routing & no-drop contract (step 5 of the diff-scoped detail):
every returned item reaches the report — severity-declaring rules route
to their Critical / Moderate / Minor bucket with the four reproducer
fields (SQL perf to ## Database Analysis), the rest to Refactoring
(DRY / tech debt) / Refactoring proposals — and a violation already
raised by Core Analysis / Strict rule compliance is kept there rather
than duplicated, so each violation is reported exactly once.
- class-refactoring gains the matching Completeness contract in Modes and
returns the matched guideline with every item, so the CR can route and
de-duplicate it; the four CR output templates carry it in the `Why:` field.
…ontract
Resolves the three findings and the DRY item raised by the code review of
this PR.
- Critical: the new Completeness / Routing & no-drop contracts shipped with
no content-pin test, in a repo where that pin *is* the mechanism that stops
normative rule text from silently drifting — exactly the failure this PR
fixes. Adds `every CR walks the full class-refactoring guideline set and
drops no returned item` to tests/Installer/CodeReviewContentTest.php.
- Moderate: the Refactoring-section `Why:` field turned an `or` into a `plus`,
mandating a class-refactoring guideline on items the lens never produced
(->when() composition, Livewire/Blade splitting) and a Laravel architecture
reference on non-Laravel projects. Restores the alternative form across all
four CR templates.
- Moderate: the no-drop contract carried an escape hatch ("matched but produced
no reportable item ... is simply not rendered") that let a matched item be
dropped silently and contradicted Output Rules *Default severity for rule
violations*. Matched and dropped are now mutually exclusive; an exempt match
is rendered with its exemption cited.
- Refactoring (DRY): the normative guideline enumeration was duplicated across
five files. It now lives only in @rules/code-review/general.mdc; the four CR
skills reference that section. The reuse-first gate routing (issue #722) is
kept explicit in the GitHub / JIRA wrappers.
CR status — resolved itemsReview loop converged after 2 iterations: 0 Critical · 0 Moderate.
Reviewer threads: 0 (no line-anchored threads on this PR). |
CR status — final diff (head
|
Summary
The ask: every CR must run
class-refactoringin read-only mode and write the things that skill defines into the report.What I found: the lens was already wired in.
@skills/class-refactoring/SKILL.mdwithMODE=crsits in the Always run set of all four CR skills (code-review,code-review-github,code-review-jira,code-review-bugsnag). So the invocation was never the gap.The real gap: the lens was described narrowly at every call site — "surface DRY duplication, single-responsibility breaches, oversized methods" — and the diff-scoped checklist in
@rules/code-review/general.mdcwas a closed six-bullet list. A reviewer reading either one literally walked a fraction of what the skill actually defines, and everything outside that fraction never reached the published report. The skill defines far more: speculative interfaces, pass-through Actions,>4parameters → DTO, Simplicity First, business-logic-layer placement, Repository scope, query performance non-regression, intention-revealing extraction, naming, nesting depth.The fix — three changes:
Open the closed lists. Both the rule's checklist and each CR skill's invocation line now say explicitly that the enumeration is the high-frequency subset, not the boundary of the walk, and that the lens walks the skill's complete guideline set (Refactoring Guidelines + Laravel Context + the behavior-preservation clauses of Execution). A caller's one-line summary can no longer be read as permission to narrow it.
Routing & no-drop contract — new step 5 in
@rules/code-review/general.mdcRefactoring & Tech Debt (DRY) Analysis — diff-scoped detail. Every item the lens returns reaches the report:>4params, pass-through Action, Repository scope, read/write separation, layer placement, SQL perf non-regression) → the item goes to that Critical / Moderate / Minor bucket with the four reproducer fields; a SQL performance item goes to## Database Analysis;->when()composition) → Refactoring (DRY / tech debt) in-scope, Refactoring proposals out-of-scope;Completeness contract in the skill.
class-refactoringnow states in Modes thatMODE=crwalks its full guideline set and that the caller must render every returned item; each item carries the matched guideline so the CR can route and de-duplicate it. The four CR output templates carry that guideline in theWhy:field.Docs / prompt-contract change only — no PHP source touched.
Testing
composer skill-check→ 0 errors, 0 warnings, 62 skillsvendor/bin/pest --no-coverage tests→ 324 passed (1856 assertions)composer build→skill-check/composer-normalize/phpcs/pint/rector/phpstan/composer auditall clean;test:coveragecould not run locally (no PCOV driver in this environment — pre-existing, unrelated to this diff, which touches zero PHP source). CI runs it.How to verify the behavior change: run any CR (
/code-review,code-review-github, …) on a PR that contains, say, a single-consumer project interface or a 5-parameter constructor. Before this change the refactoring lens had no instruction to look for either; now it walks them, and the routing contract sends them to the Moderate / Critical buckets rather than letting them fall out of the report.Risk areas
TODO
code-review-bugsnagwrapper keeps its Refactoring analysis as a prose paragraph rather than the numbered checklist the GitHub / JIRA wrappers use. It now points at the canonical routing contract, but converging the three wrappers on one shared checklist would remove the remaining duplication. Deferred — it is a structural docs refactor beyond this assignment.