feat(scoring): apply sqrt damping to density calculation#227
Conversation
Same rule triggered N times now contributes |score| × sqrt(N) instead of |score| × N. This prevents repeated issues (e.g., raw-value ×79) from destroying category scores while preserving sensitivity for rare issues where sqrt ≈ linear. Before: Community design system files score D/F (45-57%) After: Same files score B/C+ (72-78%) https://claude.ai/code/session_01H2EPyD3PhqkQFrk5BB4M4g
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughDensity scoring changed from summing per-issue absolute scores to per-rule square-root damping: issues are grouped by Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/core/engine/scoring.test.ts (1)
119-135: 🧹 Nitpick | 🔵 TrivialConsider adding an explicit test for sqrt damping with multiple same-rule issues.
The test verifies relative ordering (many > few issues decreases density score), but doesn't assert the exact
weightedIssueCountvalue that demonstrates sqrt damping. Adding an assertion would strengthen confidence in the formula:// 5 issues of rule with score -5: weightedIssueCount = |5| × sqrt(5) ≈ 11.18 expect(many.byCategory["pixel-critical"].weightedIssueCount).toBeCloseTo(5 * Math.sqrt(5), 1);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/core/engine/scoring.test.ts` around lines 119 - 135, Add an explicit assertion to the test that verifies the sqrt damping calculation for multiple identical-rule issues: after computing `many = calculateScores(makeResult([...], 100))`, assert that `many.byCategory["pixel-critical"].weightedIssueCount` is approximately equal to 5 * Math.sqrt(5) (use toBeCloseTo with an appropriate precision), in addition to the existing densityScore comparison; this uses the existing helpers `calculateScores`, `makeResult`, and `makeIssue`.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@src/core/engine/scoring.test.ts`:
- Around line 119-135: Add an explicit assertion to the test that verifies the
sqrt damping calculation for multiple identical-rule issues: after computing
`many = calculateScores(makeResult([...], 100))`, assert that
`many.byCategory["pixel-critical"].weightedIssueCount` is approximately equal to
5 * Math.sqrt(5) (use toBeCloseTo with an appropriate precision), in addition to
the existing densityScore comparison; this uses the existing helpers
`calculateScores`, `makeResult`, and `makeIssue`.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: dbface2f-dae1-49c0-8147-4cb8f38e831b
📒 Files selected for processing (2)
src/core/engine/scoring.test.tssrc/core/engine/scoring.ts
Add toBeCloseTo assertion verifying weightedIssueCount = |score| × sqrt(count) for repeated same-rule issues. https://claude.ai/code/session_01H2EPyD3PhqkQFrk5BB4M4g
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/core/engine/scoring.test.ts (1)
119-137: 🧹 Nitpick | 🔵 TrivialOptional: Consider adding multi-rule sqrt damping test.
The current test coverage is solid and validates the core sqrt damping behavior. For comprehensive coverage, you might consider adding a test that explicitly verifies sqrt damping across multiple rules in the same category, e.g.:
it("applies sqrt damping independently per rule", () => { const issues = [ // 4 issues of rule A (score -5) ...Array(4).fill(null).map(() => makeIssue({ ruleId: "no-auto-layout", category: "pixel-critical", severity: "blocking", score: -5 })), // 9 issues of rule B (score -3) ...Array(9).fill(null).map(() => makeIssue({ ruleId: "non-layout-container", category: "pixel-critical", severity: "risk", score: -3 })), ]; const scores = calculateScores(makeResult(issues, 100)); // Expected: 5×sqrt(4) + 3×sqrt(9) = 5×2 + 3×3 = 10 + 9 = 19 expect(scores.byCategory["pixel-critical"].weightedIssueCount).toBeCloseTo(19, 1); });However, this is truly optional—the existing tests adequately cover the sqrt damping feature.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/core/engine/scoring.test.ts` around lines 119 - 137, Add an optional unit test that verifies sqrt damping is applied per-rule within a category by creating multiple issues across different ruleIds and asserting the category weightedIssueCount equals the sum of each rule's (abs(score) × sqrt(count))—for example, create 4 issues with score -5 for ruleId "no-auto-layout" and 9 issues with score -3 for ruleId "non-layout-container", call calculateScores(makeResult(issues, 100)) and assert scores.byCategory["pixel-critical"].weightedIssueCount isCloseTo( (5 * Math.sqrt(4)) + (3 * Math.sqrt(9)), 1 ); use existing helpers makeIssue, makeResult and calculateScores and name the test something like "applies sqrt damping independently per rule".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/core/engine/scoring.test.ts`:
- Around line 89-102: Update the inline comment near the test case that sets
heavyIssue.calculatedScore to -15 to explicitly state that the entire
calculatedScore field is ignored for density calculations (not just the depth
component); modify the comment in the test around heavyIssue/calculatedScore in
scoring.test.ts to read something like "calculatedScore is ignored for density —
density uses the base score (score = -10), so |−10| × sqrt(1) = 10" to make
intent clear when reading the calculateScores/byCategory assertions.
---
Outside diff comments:
In `@src/core/engine/scoring.test.ts`:
- Around line 119-137: Add an optional unit test that verifies sqrt damping is
applied per-rule within a category by creating multiple issues across different
ruleIds and asserting the category weightedIssueCount equals the sum of each
rule's (abs(score) × sqrt(count))—for example, create 4 issues with score -5 for
ruleId "no-auto-layout" and 9 issues with score -3 for ruleId
"non-layout-container", call calculateScores(makeResult(issues, 100)) and assert
scores.byCategory["pixel-critical"].weightedIssueCount isCloseTo( (5 *
Math.sqrt(4)) + (3 * Math.sqrt(9)), 1 ); use existing helpers makeIssue,
makeResult and calculateScores and name the test something like "applies sqrt
damping independently per rule".
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 8497d683-3d98-4b55-be79-9a575d6c6e73
📒 Files selected for processing (1)
src/core/engine/scoring.test.ts
- Clarify comment: calculatedScore is fully ignored for density - Add multi-rule test verifying per-rule independent damping https://claude.ai/code/session_01H2EPyD3PhqkQFrk5BB4M4g
Summary
|score| × sqrt(N)instead of|score| × NBefore → After (5 real fixtures)
Why
raw-value-4 × 79건 = -316 weight against 273 nodes → density destroyed.With sqrt: -4 × √79 ≈ -36 → reasonable penalty for a systemic issue.
B→A remains hard (low issue counts, sqrt ≈ linear) — this is intentional. A requires genuinely well-structured designs.
Test plan
pnpm test:run)pnpm lintpassesCloses #226
https://claude.ai/code/session_01H2EPyD3PhqkQFrk5BB4M4g
Summary by CodeRabbit