Skip to content

feat(scoring): apply sqrt damping to density calculation#227

Merged
let-sunny merged 3 commits intomainfrom
claude/sqrt-damping-226
Mar 31, 2026
Merged

feat(scoring): apply sqrt damping to density calculation#227
let-sunny merged 3 commits intomainfrom
claude/sqrt-damping-226

Conversation

@let-sunny
Copy link
Copy Markdown
Owner

@let-sunny let-sunny commented Mar 31, 2026

Summary

  • Apply sqrt diminishing returns to density scoring per rule: |score| × sqrt(N) instead of |score| × N
  • Same rule triggered many times represents one systemic problem, not N× the difficulty
  • At low issue counts sqrt ≈ linear, preserving sensitivity for rare issues

Before → After (5 real fixtures)

Fixture Before After
desktop-pricing (273 nodes) D (52%) B (75%)
desktop-ai-chat (250 nodes) D (56%) B (76%)
mobile-landing (200 nodes) F (46%) C+ (73%)
desktop-product (300 nodes) F (45%) C+ (72%)
mobile-ai-chat (220 nodes) D (57%) B (78%)

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

  • 657 tests pass (pnpm test:run)
  • pnpm lint passes
  • Scoring tests updated for new density calculation

Closes #226

https://claude.ai/code/session_01H2EPyD3PhqkQFrk5BB4M4g

Summary by CodeRabbit

  • Improvements
    • Density scoring now applies per-rule square-root damping, reducing the cumulative impact of repeated issues while keeping near-linear effects for low counts.
  • Tests
    • Updated expectations to reflect the new damping behavior and added coverage for multi-issue and per-rule sqrt damping scenarios.

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
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 31, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3c0bf099-f353-4e24-b918-e6ebb312c808

📥 Commits

Reviewing files that changed from the base of the PR and between 8a47991 and 989a251.

📒 Files selected for processing (1)
  • src/core/engine/scoring.test.ts

📝 Walkthrough

Walkthrough

Density scoring changed from summing per-issue absolute scores to per-rule square-root damping: issues are grouped by ruleId within each category and weightedIssueCount is computed as the sum of |ruleScore| * sqrt(issueCount) per rule. Tests were updated to match the new expectations.

Changes

Cohort / File(s) Summary
Density Scoring Implementation
src/core/engine/scoring.ts
Replaced linear per-issue accumulation (+ Math.abs(issue.calculatedScore)) with per-rule grouping and sqrt damping: `weightedIssueCount = sum(
Test Expectations
src/core/engine/scoring.test.ts
Updated density-related assertions to reflect sqrt damping using base config.score (not calculatedScore): single-issue expectations adjusted (e.g., 15 → 10), within-severity expectations updated (e.g., 15/5 → 10/3), and new coverage added validating multi-issue sqrt behavior (e.g., ~5*sqrt(5), per-rule damping sums).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐇 I hopped through rules and counted tails,

sqrt softened thumps in lengthy trails.
Numbers now bend, repeat no more crime,
One rule, one beat — we save some time.
A gentle nibble, grading feels prime.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: applying sqrt damping to density calculation in the scoring system, which is the core objective of this PR.
Linked Issues check ✅ Passed The PR fully implements the requirements from issue #226: sqrt damping is applied per-rule in density scoring, test expectations are updated, and simulation results validate the grade improvements.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing sqrt damping for density calculation as specified in issue #226; no out-of-scope modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/sqrt-damping-226

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 | 🔵 Trivial

Consider 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 weightedIssueCount value 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

📥 Commits

Reviewing files that changed from the base of the PR and between 75461b8 and 0bc8d43.

📒 Files selected for processing (2)
  • src/core/engine/scoring.test.ts
  • src/core/engine/scoring.ts

Add toBeCloseTo assertion verifying weightedIssueCount = |score| × sqrt(count)
for repeated same-rule issues.

https://claude.ai/code/session_01H2EPyD3PhqkQFrk5BB4M4g
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 | 🔵 Trivial

Optional: 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

📥 Commits

Reviewing files that changed from the base of the PR and between 0bc8d43 and 8a47991.

📒 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
@let-sunny let-sunny merged commit cb562dd into main Mar 31, 2026
3 checks passed
@let-sunny let-sunny deleted the claude/sqrt-damping-226 branch March 31, 2026 11:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: apply diminishing returns (sqrt) to density scoring

2 participants