feat(recipes): components-touching-deprecated + refactor-risk-ranking (research note § 1)#65
Conversation
…nking Two new bundled recipes from research note § 1 — both XS effort, both ship against existing substrate (no schema bump, no new infra). § 1.1 components-touching-deprecated - UNION of hook path (components.hooks_used JSON overlap) + call path (calls.caller_name = component, callee_name = @deprecated symbol). - Hook-only variant would ship false-negatives — recipe spells out the explicit UNION per research note § 1.1 grill. - Output: {component, component_file, deprecated_symbol, deprecated_file, via} where via ∈ {'hook', 'call'}. - Action template: review-deprecation-impact. § 1.4 refactor-risk-ranking - Formula: (fan_in + 1) × (100 - avg_coverage_pct), per-file. - Three correctness fixes over the naïve "fan_in × (100 - coverage_pct)": - Orphans (fan_in=0) score on coverage alone via +1 - NULL coverage treated as 0% via COALESCE (otherwise row drops) - Files with no exports excluded (no public-API surface to refactor) - Empirical divergence from research note § 1.4: spec said per-symbol; testing on codemap's own index produced 30 rows from src/db.ts all tied at the same score (file-level fan_in inherited). Ships per-file ranking; per-symbol via calls is one of the documented tuning axes in the .md. - v1 trade-off: linear-in-fan_in. Tune via project-local recipe override (suggested axes spelled out in .md: log-scale, visibility weight, LOC weight, per-symbol via calls). - Action template: review-refactor-impact. Verification: - bun src/index.ts query --recipe components-touching-deprecated → [] on codemap's own index (no @deprecated symbols hit components; expected). SQL valid. - bun src/index.ts query --recipe refactor-risk-ranking → 30 distinct files ranked by score, src/db.ts top with risk_score=4500 (44 fan_in × 100 - 0% coverage). Sensible output. - bun run check passes (format, lint, typecheck, tests, all 23 golden queries). Rule 10 lockstep updates: - templates/agents/rules/codemap.md — added trigger-pattern + quick- reference table rows for both recipes. - templates/agents/skills/codemap/SKILL.md — recipe-id list extended. - .agents/rules/codemap.md + .agents/skills/codemap/SKILL.md — same mirrored updates per agents-first-convention. Patch changeset: pre-v1 lesson — additive bundled recipes don't break existing .codemap/index.db; no schema change. Patch suffices. Files: 5 new (2 .sql + 2 .md + 1 changeset), 4 lockstep edits.
🦋 Changeset detectedLatest commit: 332063a The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (9)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 0/1 reviews remaining, refill in 2 minutes and 41 seconds.Comment |
… on parser.ts Fact-checking against codebase post-PR-#69-and-#70 surfaced four stale spots; concise-comments rule re-applied to recently-authored parser.ts comments. DOCS LIFTED (post-FTS5 / Mermaid / complexity merge): - README.md (root) line 113 — --format enum was missing `mermaid`. Updated to <text|json|sarif|annotations|mermaid> + added the bounded-input contract one-liner + 50-edge ceiling note. Added --with-fts example block alongside (was missing entirely; README is the canonical CLI surface per docs/README.md Single source of truth table). - docs/architecture.md output-formatters paragraph — described only formatSarif + formatAnnotations; missing formatMermaid + bounded- input contract. Added formatMermaid description + MERMAID_MAX_EDGES reference + the no-auto-truncation reasoning (would be a verdict masquerading as output mode). Updated the --format CLI enum to include mermaid; same for the MCP tools format union. - .agents/skills/codemap/SKILL.md + templates/agents/skills/codemap/ SKILL.md — recipe-id list missed three coverage recipes (untested-and-dead, files-by-coverage, worst-covered-exports) shipped earlier in PR #65/#56 era. Lockstep update per Rule 10. Skill now lists 20 of 20 bundled recipe ids. CONCISE-COMMENTS SWEEP on parser.ts (recently authored): - Trimmed the 14-line complexityStack JSDoc block to 6 lines. Kept: the -1 sentinel rationale (non-obvious), the WeakMap rationale (the bug fix from PR #70 review). Cut: re-stating push/pop semantics obvious from method names + step-by-step "this then that" prose. - Removed the "Defer complexity push to..." comment in the VariableDeclaration handler. The 4-line block restated the design decision documented one screen up in the complexityStack jsdoc; cross-ref makes it redundant. Per concise-comments § "Cut" rule: "Cross-references that save grep time" — keep when they actually do; cut when they restate. Verification: - bun run check: format + lint + typecheck + 23/23 golden ✓ - Recipe count: SQL files = 20, skill mentions = 20 (1:1 match) ✓ - SCHEMA_VERSION = 8 in db.ts; docs/architecture.md says 8 ✓ - complexity column documented in architecture.md + glossary.md ✓ - --with-fts in README.md + architecture.md + glossary.md + roadmap.md (consumer-facing surfaces all aligned) ✓ - --format mermaid in README.md + architecture.md + glossary.md + agent rule/skill ✓
…sted recipe (research note § 1.4) (#70) * feat(complexity): cyclomatic complexity column + high-complexity-untested recipe Research note § 1.4 ship-pick (c) per § 5 cadence. Schema bump SCHEMA_VERSION 7 → 8. Schema: - symbols.complexity REAL column. NULL for non-function kinds and class methods (v1 limitation documented in recipe .md). Parser: - complexityStack maintained alongside scopeStack. Function entry pushes {symbolIndex, count: 1}; branching-node visitors increment top.count; function exit pops + writes count into the already- pushed symbol row's complexity field. - McCabe decision points counted: if, while, do-while, for, for-in, for-of, case X (not default:), &&/||/??, ?:, catch. Bundled recipe high-complexity-untested: - Joins symbols (complexity >= 10) with coverage (< 50%). - Combines structural + runtime evidence axes — surfaces refactor- priority candidates that untested-and-dead and worst-covered-exports miss (they catch dead-or-uncalled, this catches called-but-undertested- AND-branchy). Empirical sanity check on codemap's own index after reindex: - extractFileData (parser.ts main visitor) → complexity 108 ✓ - stringifyTypeNode → 42 ✓ - All non-function kinds have NULL complexity ✓ - high-complexity-untested recipe returns 7 functions all from src/parser.ts (which has 0% coverage; complexity ≥ 10) ✓ Lockstep updates per Rule 10 (templates/agents + .agents): - Trigger pattern row "What's high-complexity AND undertested?" - Quick reference row for SELECT name, complexity FROM symbols - Recipe-id list extended in SKILL.md Plus architecture.md (schema version 8, complexity column docs), glossary.md (cyclomatic complexity entry), patch changeset. Files changed: - src/db.ts (SCHEMA_VERSION + symbols.complexity column + insertSymbols bind + SymbolRow optional complexity field) - src/parser.ts (complexityStack + branching node visitors + push/pop in FunctionDeclaration / VariableDeclaration arrow-fn paths) - templates/recipes/high-complexity-untested.{sql,md} - docs/architecture.md (schema version + symbols column doc) - docs/glossary.md (new entry) - templates/agents/rules/codemap.md + .agents/rules/codemap.md (trigger + quick-ref rows) - templates/agents/skills/codemap/SKILL.md + .agents/skills/codemap/ SKILL.md (recipe-id list) - .changeset/cyclomatic-complexity.md (patch) Verification: - bun test: 754 pass - bun run check passes (format, lint, typecheck, 23/23 golden queries) - Live re-index against codemap source produces sensible complexity values (parser visitor itself is the highest at 108, which tracks) * docs(skill): add complexity column to symbols schema in skill files CodeRabbit catch on PR #70: the high-complexity-untested recipe row was added to .agents/skills/codemap/SKILL.md but the symbols table schema section (under "### `symbols` — Functions, types, ...") still listed columns through `visibility` only, missing the new `complexity REAL` column. Verified by reading the file — claim was correct. Both lockstep mirrors (.agents/ + templates/agents/) updated with the same row: | complexity | REAL | Cyclomatic complexity (`1 + decision points`) for function-shaped symbols. NULL for non-functions and class methods (v1). Powers --recipe high-complexity-untested. Decision points: if, while, do…while, for/for-in/for-of, case X: (not default:), &&/||/??/?:, catch | Per docs/README.md Rule 10 — agent rule + skill schema docs must stay in lockstep with code-side schema changes. The trigger-pattern row + recipe-id list were already updated; the schema-table row was the gap. * fix(complexity): per-function visitors fix multi-declarator misattribution + cleanups CodeRabbit raised three valid findings on PR #70. All fact-checked against the code; all correct. A) docs/architecture.md symbols schema table was malformed: - Markdown table separator row had extra `| --- | ---` segments because oxfmt mis-counted columns when the description contained `|` chars inside `&&`/`||`/`??` backtick spans. - The complexity row's description was split across THREE cells with broken backtick fences. - Fix: restored single-row layout (3 cells: Column | Type | Description) and rephrased the decision-point list to avoid `|` inside backticks ("short-circuit `&&` / `||` / `??`" instead of "`&&`/`||`/`??`"). B) src/parser.ts complexity misattribution on multi-declarator VariableDeclaration (e.g. `const a = () => {…}, b = () => {…};`): Pre-fix: VariableDeclaration enter pushed all declarators' complexity entries up front. Then visitor traversed `a`'s body — branches incremented top (= b's entry). Then `b`'s body. Exit pops in reverse → symbols[1].complexity = 3 (wrong), symbols[0].complexity = 1 (wrong). Real bug. Fix: push/pop complexity on the FUNCTION-shaped node visitors (ArrowFunctionExpression / FunctionExpression) — not on VariableDeclaration. The VariableDeclaration handler still creates the symbol row but only RECORDS the symbol → init-node mapping in a WeakMap. The ArrowFunctionExpression / FunctionExpression enter handler reads the WeakMap to know which symbol to write back to; anonymous arrow fns (callbacks, IIFEs) get -1 and just track count without persistence. Verified against fixture: const a = () => { if (1===1) {…} }, b = () => { if (2===2) {…} }, c = () => 5; → a=2, b=2, c=1 (correct; pre-fix was a=1, b=3, c=1) C) popComplexityInto guard was a no-op (callers passed top.symbolIndex, so the equality check was always true). Simplified to parameterless popComplexityTop() that always pops + writes back if symbolIndex >= 0. Folds naturally into the B refactor — every push/pop pair now lives in a function-shaped visitor. Also re-ran codemap query against codemap source post-fix: extractFileData=108, stringifyTypeNode=42, extractClassMembers=18, extractLiteralValue=15, extractObjectMembers=14 Same scores as pre-fix on these (no FunctionExpression / arrow nesting in those particular functions, so the bug didn't surface) — confirms the refactor is a strict improvement, not a regression. * docs: audit + lift remaining stale references; concise-comments sweep on parser.ts Fact-checking against codebase post-PR-#69-and-#70 surfaced four stale spots; concise-comments rule re-applied to recently-authored parser.ts comments. DOCS LIFTED (post-FTS5 / Mermaid / complexity merge): - README.md (root) line 113 — --format enum was missing `mermaid`. Updated to <text|json|sarif|annotations|mermaid> + added the bounded-input contract one-liner + 50-edge ceiling note. Added --with-fts example block alongside (was missing entirely; README is the canonical CLI surface per docs/README.md Single source of truth table). - docs/architecture.md output-formatters paragraph — described only formatSarif + formatAnnotations; missing formatMermaid + bounded- input contract. Added formatMermaid description + MERMAID_MAX_EDGES reference + the no-auto-truncation reasoning (would be a verdict masquerading as output mode). Updated the --format CLI enum to include mermaid; same for the MCP tools format union. - .agents/skills/codemap/SKILL.md + templates/agents/skills/codemap/ SKILL.md — recipe-id list missed three coverage recipes (untested-and-dead, files-by-coverage, worst-covered-exports) shipped earlier in PR #65/#56 era. Lockstep update per Rule 10. Skill now lists 20 of 20 bundled recipe ids. CONCISE-COMMENTS SWEEP on parser.ts (recently authored): - Trimmed the 14-line complexityStack JSDoc block to 6 lines. Kept: the -1 sentinel rationale (non-obvious), the WeakMap rationale (the bug fix from PR #70 review). Cut: re-stating push/pop semantics obvious from method names + step-by-step "this then that" prose. - Removed the "Defer complexity push to..." comment in the VariableDeclaration handler. The 4-line block restated the design decision documented one screen up in the complexityStack jsdoc; cross-ref makes it redundant. Per concise-comments § "Cut" rule: "Cross-references that save grep time" — keep when they actually do; cut when they restate. Verification: - bun run check: format + lint + typecheck + 23/23 golden ✓ - Recipe count: SQL files = 20, skill mentions = 20 (1:1 match) ✓ - SCHEMA_VERSION = 8 in db.ts; docs/architecture.md says 8 ✓ - complexity column documented in architecture.md + glossary.md ✓ - --with-fts in README.md + architecture.md + glossary.md + roadmap.md (consumer-facing surfaces all aligned) ✓ - --format mermaid in README.md + architecture.md + glossary.md + agent rule/skill ✓
Summary
Ships two new bundled recipes from the research note's § 1 capability inventory — both XS effort, both fully grilled in PR #58, both shipping against existing substrate (no schema bump, no new infra).
Recipes
components-touching-deprecated(research note § 1.1)UNION of two evidence axes:
components.hooks_usedJSON contains a@deprecatedsymbol's name (catches deprecated hooks likeuseDeprecatedThing).calls.caller_name = components.nameANDcallee_nameis@deprecated(catches regular deprecated functions called inside components).Why UNION: hook-only variants ship false-negatives — research note § 1.1 grill explicitly required both paths.
Action template:
review-deprecation-impact— agent flags the component for migration, doesn't auto-fix.refactor-risk-ranking(research note § 1.4)Per-file ranking by
(fan_in + 1) × (100 - avg_coverage_pct). Three correctness fixes over the naïve formula:fan_in = 0) score on coverage alone via the+1.coverage_pcttreated as0%viaCOALESCE(otherwise the row drops fromORDER BY).Empirical divergence from research note § 1.4 (documented in the recipe
.md): the research note specified per-symbol ranking. Testing on codemap's own index produced 30 rows fromsrc/db.tsall tied at the same score (file-level fan_in inherited from the dependencies table). Ships per-file ranking as the more useful default; per-symbol viacallsis one of the documented tuning axes for project-local override.Action template:
review-refactor-impact— agent flags the file for caller-review + test coverage before signature changes.Verification (locally pre-push)
bun src/index.ts query --recipe components-touching-deprecated→[]on codemap's own index (no@deprecatedsymbols hit components — expected; SQL valid).bun src/index.ts query --recipe refactor-risk-ranking→ 30 distinct files ranked by score,src/db.tstop withrisk_score = 4500(44 fan_in × 100 - 0% coverage). Sensible output, no ties from inherited file-level fan_in.bun run checkpasses — format, lint, typecheck, all 23 golden-query scenarios.Doc-governance compliance
templates/agents/(ships to npm viacodemap agents init) AND.agents/(this clone's mirror) updated:SKILL.mdextended<id>.{sql,md}file pairs..mdcarries action template via YAML frontmatter + caveats / tuning axes in the body..codemap/index.db; no schema change. Patch suffices.Test plan
bun run format:checkpassesbun run checkpasses (typecheck + 23/23 golden queries)bun src/index.ts query --recipe <id>runs both recipes end-to-end.mdfrontmatter shapesOut of scope (intentional follow-ups)
re_export_source; recursive-CTE design point.md; not bundled.