Skip to content

feat(health): per-model context-rot warnings [GET-28]#57

Merged
DevanshuNEU merged 6 commits into
OpenCodeIntel:mainfrom
DevanshuNEU:feat/get-28-context-rot-per-model
Apr 28, 2026
Merged

feat(health): per-model context-rot warnings [GET-28]#57
DevanshuNEU merged 6 commits into
OpenCodeIntel:mainfrom
DevanshuNEU:feat/get-28-context-rot-per-model

Conversation

@DevanshuNEU

@DevanshuNEU DevanshuNEU commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Replaces the model-agnostic 70/90 health-indicator ceilings with per-model warn / critical thresholds grounded in Anthropic's published MRCR scores. Each Claude model on claude.ai now gets coaching copy tailored to its actual context-rot behavior, with claude.ai-specific actions (start a new chat, use Projects) instead of /compact instructions that only exist in Claude Code.

Type of Change

  • feat — New feature
  • fix — Bug fix
  • refactor — Code restructure, no behavior change
  • test — Tests only
  • chore — Build, CI, tooling, dependencies
  • docs — Documentation only

What Was Changed

New agentlib/context-rot-thresholds.ts. Single source of truth for per-model thresholds + coaching copy. Longest-prefix lookup, conservative fallback profile, detail-heavy adjustment (-15pp) with a 30% floor. Each profile carries optional mrcrAt1MPct / sourceUrl / sourceQuote provenance fields for the two Anthropic-published scores (Opus 4.6 = 76%, Sonnet 4.5 = 18.5%).

New specdocs/context-rot-thresholds-spec.md. Verbatim Anthropic quotes pinned, threshold derivation explained, drift policy documented. Same .gitignore exception pattern as attachment-cost-spec.md.

Health rewritelib/health-score.ts. HealthInput now requires model: string and isDetailHeavy: boolean. Two independent classifiers, more severe wins:

  • Primary (per-model utilization): three-zone classification, coaching copy from the threshold agent (cites MRCR when published, mentions compaction for 1M models).
  • Secondary (turn count, growth rate): forward-looking warnings. Generic copy that names the model but never quotes data it didn't consume.
  • TURN_AWARE_WARN_OFFSET = 10: a turn-aware degrading rule keeps the legacy "70% + 11 turns = degrading" coverage on Sonnet 4.5-class models without locking it to 70.
  • ABSOLUTE_CRITICAL_FLOOR = 90%: model-agnostic safety net.

Detail-heavy detectorlib/prompt-analysis.ts exports isDetailHeavy(promptText) and a DETAIL_HEAVY_KEYWORDS constant. Pure function; the bridge schema carries the precomputed flag so raw prompt text never crosses worlds. inject.ts mirrors the keyword list inline (no lib/ imports allowed in the MAIN world); a cross-file drift test asserts the mirror stays in sync.

Bridgelib/message-types.ts adds optional isDetailHeavy?: boolean to StreamCompletePayload. lib/bridge-validation.ts type-checks the new field.

Wiringentrypoints/claude-ai.content.ts plumbs model + isDetailHeavy into all four computeHealthScore call sites and resets lastDetailHeavy on SPA navigation. entrypoints/sidepanel/hooks/useDashboardData.ts passes the stored conversation's model with isDetailHeavy=false (no live draft on the side panel).

Tests — 52 new tests (44 for context-rot-thresholds, 7 for isDetailHeavy, 1 cross-file mirror drift assertion, plus a directly-exposed helper for the floor branch). All existing audit, integration, perf, fuzz, and smoke suites updated to pass the two new HealthInput fields. bun run test reports 1709 passing (+52 from baseline).

How to Test

  1. bun run compile && bun run test && bun run build — all clean.
  2. Load the extension on claude.ai. Open a fresh chat on Sonnet 4.6 and watch the health indicator stay healthy until ~60% context.
  3. Open a chat on Opus 4.6 (or 4.7) and confirm the threshold is more permissive (~65% before degrading) and the approaching-zone copy mentions Anthropic's server-side compaction.
  4. On Sonnet 4.5, confirm the approaching-zone copy cites the Anthropic 8-needle 1M MRCR figure (18.5%) and points the user at "start a new chat now" without compaction language.
  5. Paste a code block in the compose box and submit; on the next health recompute, the threshold should shift earlier (detail-heavy adjustment).
  6. Confirm no zone or copy mentions /compact (Claude Code feature, not on the web).

Checklist

  • Tests pass locally (bun run test) — 1709 passing
  • TypeScript compiles clean (bun run compile)
  • Extension builds without errors (bun run build) — 73.99 KB content script
  • No secrets, hardcoded URLs, or sensitive tokens exposed
  • Comments are professional and clear — no emojis, no AI-generated filler
  • Commit messages follow conventional commits

Related Issues

Closes GET-28.

Notes for Reviewer

  • The thresholds (50/65/60 warn for the three Claude lines) are explicitly Saar coaching defaults, not Anthropic-published rot points. The spec doc explains the derivation. Only the two MRCR figures are sourced.
  • This PR does not touch the rendering layer; the existing health dot + coaching text picks up the new model-aware copy automatically.
  • Three orthogonal follow-ups stay out of scope: GET-36 (fresh-session false-rot, suspected mechanism doesn't exist on main), the "200% session %" calibration bug (weekly-cap display, not context rot), and detail-heavy detection on the draft (vs last-sent) prompt — Cycle 2.

Summary by CodeRabbit

  • New Features

    • Detects "detail-heavy" prompts (e.g., code/precision) and includes that signal in health computations
    • Model-aware health scoring with per-model warn/critical thresholds and tailored coaching messages
  • Documentation

    • New spec describing per-model context-rot thresholds, rationale, and update/drift policy
  • Tests

    • Expanded tests and benchmarks to validate per-model thresholds, detail-heavy behavior, and coaching copy
  • Validation

    • Bridge/schema now accepts and validates the new detail-heavy flag in stream completions

Pure agent. Single source of truth for per-model context-rot warn /
critical thresholds and coaching copy. Grounded in two Anthropic-published
MRCR scores (Opus 4.6 = 76%, Sonnet 4.5 = 18.5% on 8-needle 1M MRCR v2);
all other thresholds explicitly marked as Saar coaching defaults.

Lookup uses longest-prefix match so claude-sonnet-4-6-20250514 resolves
to the canonical claude-sonnet-4-6 entry. Detail-heavy adjustment
(-15pp) shifts thresholds earlier when the prompt demands precise
recall, floored at MIN_THRESHOLD_FLOOR (30%) to guard future tuning.
ABSOLUTE_CRITICAL_FLOOR (90%) acts as a model-agnostic safety net.

Coaching copy is claude.ai-specific: never mentions /compact (Claude
Code only), softens for compaction-aware models (Opus 4.7/4.6, Sonnet
4.6), points 200k models at "start a new chat" + "use Projects."

Spec doc pins verbatim Anthropic quotes and documents the threshold
derivation, so the runtime file stays terse and the rationale lives in
prose. Drift test enforces that every profile with an mrcrAt1MPct field
also carries a sourceUrl + sourceQuote, and that the quote contains the
figure verbatim.

44 unit tests covering lookup, threshold math, zone classification, copy
generation, and the floor branch via a directly-exposed helper.
…ET-28]

New pure function isDetailHeavy(promptText) returns true when the user's
turn demands precise / exhaustive recall on prior context. Two
independent triggers: a fenced code block (cheapest check) or any
DETAIL_HEAVY_KEYWORDS substring (case-insensitive after a single
toLowerCase). The Health Agent reads the resulting flag to shift its
per-model warn / critical thresholds earlier.

Why this lives in prompt-analysis: prompt inspection is the Prompt
Agent's job, the rot agent only consumes a flag. Keeps each lib file
focused on one input shape.

Tests: 7 cases plus a cross-file mirror drift guard. inject.ts
duplicates DETAIL_HEAVY_KEYWORDS inline (no lib imports allowed in the
MAIN world), so the test reads inject.ts as text and asserts every
keyword on the lib side appears verbatim there. Same pattern as the
SHORT_FOLLOWUP_MAX_CHARS comment but with a real assertion behind it.
Add an optional isDetailHeavy boolean to StreamCompletePayload. inject.ts
computes it from the live promptText (mirrored keyword list, code-fence
check) before posting; raw prompt text never crosses the bridge.
bridge-validation.ts type-checks the new field to keep the Layer-5
schema validator strict.

The mirrored keyword list in inject.ts is guarded by the cross-file
drift test added alongside lib/prompt-analysis.ts isDetailHeavy().
Replace the model-agnostic 70/90 ceilings with per-model warn / critical
thresholds from lib/context-rot-thresholds.ts. HealthInput now requires
two new fields:

  - model: string  (from SSE message_start; "" falls back to the
    conservative 200k profile)
  - isDetailHeavy: boolean  (from inject.ts on STREAM_COMPLETE)

Computation is two independent classifiers, more severe wins:

  PRIMARY (per-model utilization). Three-zone classification: healthy
  / approaching / in-rot. The approaching and in-rot zones use the
  per-model coaching string (cites MRCR when published, mentions
  compaction for 1M models, points 200k models at Projects + new chat).

  SECONDARY (turn count, growth rate). Catches the cases the primary
  classifier misses: a long conversation with low context still shows
  attention drift, and a fast-filling short conversation deserves a
  forward-looking warning before the per-model warn fires. Secondary
  rules use generic copy with the model name; they never quote MRCR
  data they did not consume.

  TURN_AWARE_WARN_OFFSET (10pp): a turn-aware degrading rule fires when
  context is within 10 points of warn AND turnCount > TURN_HEALTHY_CEIL.
  This preserves the legacy "70% + 11 turns = degrading" coverage on
  Sonnet 4.5-class models without locking it to 70.

Critical: the absolute floor at 90% (DEGRADING_CEIL, re-exported for
back-compat) always trips, even on the most-permissive 1M profile.

Content script (claude-ai.content.ts) now plumbs model + isDetailHeavy
into all four computeHealthScore call sites: page-load restore,
async restore, post-STREAM_COMPLETE recompute, and SPA-navigation
restore. lastDetailHeavy is reset alongside other per-conversation
state on SPA navigation. Side panel (useDashboardData.ts) passes the
stored conversation's model with isDetailHeavy=false (no live draft).

Tests rewritten to use named models (Sonnet 4.5 as the rot exemplar,
Opus 4.6 for differentiated behavior, Sonnet 4.6 for compaction-aware
copy assertions). Audit, integration, perf, fuzz, and smoke suites all
updated to pass the two new fields. 1709 passing, +52 from baseline.
@vercel

vercel Bot commented Apr 28, 2026

Copy link
Copy Markdown

@DevanshuNEU is attempting to deploy a commit to the Dev's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Apr 28, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@DevanshuNEU has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 51 minutes and 11 seconds before requesting another review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6a360d44-1519-4e82-95c2-b1fc6bd1a009

📥 Commits

Reviewing files that changed from the base of the PR and between 76d7085 and 188981a.

📒 Files selected for processing (1)
  • lib/context-rot-thresholds.ts
📝 Walkthrough

Walkthrough

This PR adds model-aware context-rot thresholds and detail-heavy prompt detection. It introduces a new thresholds module, propagates an isDetailHeavy flag through the bridge, refactors health scoring to use per-model thresholds and detail adjustments, and updates tests and docs to verify provenance and behavior.

Changes

Cohort / File(s) Summary
Specification & Documentation
docs/context-rot-thresholds-spec.md
New spec documenting per-model context-rot profiles, MRCR citations, coaching zones, provenance and drift-sync policy.
Core Threshold Module
lib/context-rot-thresholds.ts
New exported types/constants and profile data; longest-prefix model lookup; detail-heavy adjustment, flooring rules, zone classification, and coaching text/formatting with MRCR and compaction-aware variants.
Health Scoring
lib/health-score.ts
Refactored to require model and isDetailHeavy; primary classification via getRotZone; secondary downgrade heuristics updated; constants adjusted to use absolute critical floor.
Prompt Analysis & Detection
lib/prompt-analysis.ts, entrypoints/inject.ts
Added DETAIL_HEAVY_KEYWORDS and isDetailHeavy(); injection script computes isDetailHeavy (fenced code detection + keyword substring matching) and includes it in STREAM_COMPLETE.
Bridge Typing & Validation
lib/message-types.ts, lib/bridge-validation.ts
Extended StreamCompletePayload with optional isDetailHeavy?: boolean and validator enforcement for boolean when present.
Entrypoint Integration
entrypoints/claude-ai.content.ts, entrypoints/sidepanel/hooks/useDashboardData.ts
Propagate isDetailHeavy and model into health computations; persist last-detail-heavy for stream completion and use false for restored/historical drafts.
Tests — Unit / Thresholds
tests/unit/context-rot-thresholds.test.ts
New unit tests for profile lookup, threshold math, zone classification, coaching text (MRCR and compaction rules), and provenance/drift guards over ROT_PROFILES.
Tests — Health / Prompt
tests/unit/health-score.test.ts, tests/unit/prompt-analysis.test.ts
Updated health-score tests to be model-aware and cover detail-heavy shifts; added prompt-analysis tests and a drift-guard ensuring keyword parity with injected script.
Integration, Audit & Perf Tests
tests/integration/..., tests/audit/..., tests/perf/..., tests/memory.test.ts
Updated many call sites and expectations to pass model and isDetailHeavy, refactored audit assertions to validate per-model thresholds, and updated benchmarks/memory tests accordingly.
Fuzz & Smoke
tests/audit/fuzz.test.ts, tests/audit/smoke.test.ts
Extended fuzz and smoke callers to include model and isDetailHeavy.

Sequence Diagram

sequenceDiagram
    participant User
    participant ContentScript as Content Script<br/>(inject.ts)
    participant Bridge as Message Bridge
    participant HealthAgent as Health Agent
    participant ThresholdModule as Context-Rot<br/>Thresholds
    participant Coaching as Coaching<br/>Generator

    User->>ContentScript: Submit prompt
    ContentScript->>ContentScript: isDetailHeavy detection<br/>(code fence + keywords)
    ContentScript->>Bridge: STREAM_COMPLETE (model, isDetailHeavy, contextPct)
    Bridge->>HealthAgent: deliver STREAM_COMPLETE
    HealthAgent->>ThresholdModule: getRotProfile(model)
    ThresholdModule-->>HealthAgent: profile (warn/crit, compaction, MRCR)
    HealthAgent->>ThresholdModule: getEffectiveThresholds(model, isDetailHeavy)
    ThresholdModule-->>HealthAgent: adjusted warn/crit
    HealthAgent->>ThresholdModule: getRotZone(model, contextPct, isDetailHeavy)
    ThresholdModule-->>HealthAgent: zone (healthy/approaching/in-rot)
    alt zone is approaching/in-rot or turn-growth escalation
        HealthAgent->>Coaching: getRotCoaching(model, contextPct, isDetailHeavy)
        Coaching-->>HealthAgent: model-aware coaching (MRCR/compaction-aware)
    end
    HealthAgent-->>Bridge: health result
    Bridge-->>User: display health + coaching
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Poem

🐰 I counted keywords, fences, and lines,

A rabbit that watches the context decline.
Sonnet and Opus each get their chart,
Warnings arrive before things fall apart,
Hop, adjust, and coach — brief, precise, and smart.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 73.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: introducing per-model context-rot warnings to replace the prior model-agnostic approach, which aligns with the substantial refactoring across health-score computation, new threshold configuration, and model-aware coaching copy.
Description check ✅ Passed The PR description thoroughly covers all template sections: clear summary, feature type selected, detailed list of changed files with rationale, step-by-step testing instructions, completed checklist with test results, related issue link, and comprehensive reviewer notes explaining thresholds derivation and scope boundaries.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/context-rot-thresholds-spec.md (1)

1-257: ⚠️ Potential issue | 🟡 Minor

Remove em dashes from the spec copy.

This markdown file uses em dashes in several sections, which violates the repo rule for *.md. Please rewrite them with periods, semicolons, or commas. As per coding guidelines, no em dashes. Use colons, semicolons, or rewrite the sentence.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/context-rot-thresholds-spec.md` around lines 1 - 257, The spec file uses
em dashes throughout (e.g., in headings/sections like "What is NOT an Anthropic
fact", "Why -15 percentage points for detail-heavy", and sentences such as
"Compaction provides server-side summarization — that automatically
condenses..."), which violates the markdown rule; find and replace all em dashes
(—) with appropriate punctuation (periods, commas, colons, or semicolons) or
rewrite the sentences to remove the dash while preserving meaning, updating
occurrences in paragraphs under headings like "What problem are we solving",
"Anthropic-published facts we rely on", "What is NOT an Anthropic fact", "Why
-15 percentage points for detail-heavy", and "Coaching copy contract".
🧹 Nitpick comments (2)
lib/context-rot-thresholds.ts (1)

357-363: Centralize the low-context cutoff to prevent cross-file drift.

30 is hardcoded here while lib/health-score.ts defines LOW_CONTEXT_REASSURANCE_CEIL = 30. Using one exported constant would keep coaching and secondary-rule behavior aligned over time.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/context-rot-thresholds.ts` around lines 357 - 363, Replace the hardcoded
30 in the healthy-zone low-context check with the centralized exported constant
LOW_CONTEXT_REASSURANCE_CEIL from lib/health-score.ts: update the condition in
the zone === 'healthy' branch (currently contextPct < 30) to use
LOW_CONTEXT_REASSURANCE_CEIL, add the appropriate import for
LOW_CONTEXT_REASSURANCE_CEIL at the top of lib/context-rot-thresholds.ts, and
keep the surrounding logic that returns the reassurance message using
pctRounded, profile.label and windowLabel unchanged.
tests/unit/context-rot-thresholds.test.ts (1)

57-63: Add a non-boundary prefix regression case.

Please add a test that a model like claude-sonnet-4-50 does not resolve to the claude-sonnet-4-5 profile. This protects lookup behavior from partial-prefix collisions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/context-rot-thresholds.test.ts` around lines 57 - 63, Add a
regression test that calls getRotProfile('claude-sonnet-4-50') and asserts it
does NOT resolve to the shorter prefix 'claude-sonnet-4-5' (e.g.,
expect(p.modelPrefix).not.toBe('claude-sonnet-4-5')); use the same test
structure as the existing cases so you verify getRotProfile and its modelPrefix
field avoid partial-prefix collisions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/context-rot-thresholds.ts`:
- Around line 260-263: The current prefix match in the ROT_PROFILES loop uses
normalized.startsWith(profile.modelPrefix) which can falsely match longer
versioned names (e.g. "claude-sonnet-4-50" matching "claude-sonnet-4-5"); update
the condition to only accept the prefix when either normalized.length ===
profile.modelPrefix.length or the character immediately after the prefix is not
a digit (i.e. check normalized[profile.modelPrefix.length] and reject when it's
a numeric char). Apply this boundary check before assigning best so
profile.modelPrefix, normalized, ROT_PROFILES and best are used to locate and
fix the logic.

In `@lib/health-score.ts`:
- Around line 207-215: The coaching string can show "0 messages" because
remaining is computed with Math.round(headroom / growthRate) and can be 0 even
when not at warn threshold; in the block that returns the degrading warning
(uses growthRate, FAST_GROWTH_PCT, contextPct, thresholds.warnAtPct, remaining,
target, profile.label), ensure remaining is at least 1 before formatting the
message (e.g., compute remaining = Math.max(1, Math.round(headroom /
growthRate)) or conditionally set remainingForDisplay = remaining === 0 ? 1 :
remaining) and choose the correct singular/plural target based on that display
value so the coaching text never says "0 messages."

In `@lib/prompt-analysis.ts`:
- Around line 75-103: Update the documentation block above the
DETAIL_HEAVY_KEYWORDS constant to state that the matching is substring-based
(case-insensitive includes()), not word-bounded, and adjust the explanatory text
about single-word vs multi-word triggers accordingly; then remove the entry
'comprehensive' from the DETAIL_HEAVY_KEYWORDS array so the list no longer
contains that AI-filler term.

In `@tests/audit/health-score-audit.test.ts`:
- Around line 51-57: The test "just below DEGRADING_CEIL is not automatically
critical from this rule" uses computeHealthScore(input({ contextPct: 89.9,
model: OPUS_46 })) but does not isolate DEGRADING_CEIL because OPUS_46 already
triggers its per-model critical threshold; either remove the test or update it
to accurately reflect what it verifies: rename the test and update its comment
to state it asserts that the per-model rule (for OPUS_46) takes precedence over
the floor, and keep the call to computeHealthScore/input/OPUS_46 and the
expectation as-is, or alternatively replace OPUS_46 with a model whose per-model
critical threshold is above 89.9 if the intention is to test the floor
specifically.

---

Outside diff comments:
In `@docs/context-rot-thresholds-spec.md`:
- Around line 1-257: The spec file uses em dashes throughout (e.g., in
headings/sections like "What is NOT an Anthropic fact", "Why -15 percentage
points for detail-heavy", and sentences such as "Compaction provides server-side
summarization — that automatically condenses..."), which violates the markdown
rule; find and replace all em dashes (—) with appropriate punctuation (periods,
commas, colons, or semicolons) or rewrite the sentences to remove the dash while
preserving meaning, updating occurrences in paragraphs under headings like "What
problem are we solving", "Anthropic-published facts we rely on", "What is NOT an
Anthropic fact", "Why -15 percentage points for detail-heavy", and "Coaching
copy contract".

---

Nitpick comments:
In `@lib/context-rot-thresholds.ts`:
- Around line 357-363: Replace the hardcoded 30 in the healthy-zone low-context
check with the centralized exported constant LOW_CONTEXT_REASSURANCE_CEIL from
lib/health-score.ts: update the condition in the zone === 'healthy' branch
(currently contextPct < 30) to use LOW_CONTEXT_REASSURANCE_CEIL, add the
appropriate import for LOW_CONTEXT_REASSURANCE_CEIL at the top of
lib/context-rot-thresholds.ts, and keep the surrounding logic that returns the
reassurance message using pctRounded, profile.label and windowLabel unchanged.

In `@tests/unit/context-rot-thresholds.test.ts`:
- Around line 57-63: Add a regression test that calls
getRotProfile('claude-sonnet-4-50') and asserts it does NOT resolve to the
shorter prefix 'claude-sonnet-4-5' (e.g.,
expect(p.modelPrefix).not.toBe('claude-sonnet-4-5')); use the same test
structure as the existing cases so you verify getRotProfile and its modelPrefix
field avoid partial-prefix collisions.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d24f57f9-c379-4ac4-98eb-db7550e57bcd

📥 Commits

Reviewing files that changed from the base of the PR and between 0be8ed8 and 3c65935.

📒 Files selected for processing (20)
  • docs/context-rot-thresholds-spec.md
  • entrypoints/claude-ai.content.ts
  • entrypoints/inject.ts
  • entrypoints/sidepanel/hooks/useDashboardData.ts
  • lib/bridge-validation.ts
  • lib/context-rot-thresholds.ts
  • lib/health-score.ts
  • lib/message-types.ts
  • lib/prompt-analysis.ts
  • tests/audit/fuzz.test.ts
  • tests/audit/health-score-audit.test.ts
  • tests/audit/smoke.test.ts
  • tests/integration/agent-pipeline.test.ts
  • tests/integration/restore-pipeline.test.ts
  • tests/integration/session-state.test.ts
  • tests/perf/benchmarks.bench.ts
  • tests/perf/memory.test.ts
  • tests/unit/context-rot-thresholds.test.ts
  • tests/unit/health-score.test.ts
  • tests/unit/prompt-analysis.test.ts

Comment thread lib/context-rot-thresholds.ts Outdated
Comment thread lib/health-score.ts
Comment thread lib/prompt-analysis.ts
Comment thread tests/audit/health-score-audit.test.ts Outdated
Seven small fixes from the second pipeline pass, none behavior-breaking.

1. getRotProfile prefix match now requires a digit boundary, so a
   hypothetical "claude-sonnet-4-50" cannot silently match the
   "claude-sonnet-4-5" profile and inherit its 200k-window coaching.
   Two regression tests pin this and the still-valid date-suffixed form.

2. Centralize LOW_CONTEXT_REASSURANCE_CEIL in context-rot-thresholds.ts
   and import it from health-score.ts so both the coaching layer and the
   fast-growth rule see the same value. (Cannot import the other
   direction without a circular dep, hence the move.)

3. Fast-growth coaching no longer says "About 0 messages until the rot
   zone". Floors the displayed count at 1 since rounding can produce 0
   when headroom is small relative to growth rate.

4. DETAIL_HEAVY_KEYWORDS docstring corrected: matching is substring via
   String.prototype.includes, not word-bounded as the comment claimed.
   Removed 'comprehensive' from the keyword list (filler-y trigger,
   produces false positives on prose like 'comprehensive overview').
   Mirror in inject.ts updated; the cross-file drift test still passes.

5. Audit test "just below DEGRADING_CEIL is not automatically critical"
   was misleading: it asserts critical and the assertion is correct
   (Opus 4.6's per-model crit at 85 fires before the 90 floor). Renamed
   and clarified the comment.

6. Two em dashes in the spec doc replaced with periods.

1711 tests passing.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/context-rot-thresholds.ts`:
- Around line 118-126: Fix the typo in the doc comment for the constant
LOW_CONTEXT_REASSURANCE_CEIL: change "precentage" to "percentage" in the comment
describing the threshold so the documentation reads correctly; locate the
comment block above the exported constant LOW_CONTEXT_REASSURANCE_CEIL and
update the misspelled word.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: eb6128b9-b512-4eff-bc3d-49cee754e80a

📥 Commits

Reviewing files that changed from the base of the PR and between 3c65935 and 76d7085.

📒 Files selected for processing (7)
  • docs/context-rot-thresholds-spec.md
  • entrypoints/inject.ts
  • lib/context-rot-thresholds.ts
  • lib/health-score.ts
  • lib/prompt-analysis.ts
  • tests/audit/health-score-audit.test.ts
  • tests/unit/context-rot-thresholds.test.ts
✅ Files skipped from review due to trivial changes (1)
  • docs/context-rot-thresholds-spec.md

Comment thread lib/context-rot-thresholds.ts
@vercel

vercel Bot commented Apr 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
getsaar Ready Ready Preview, Comment Apr 28, 2026 8:25pm

@DevanshuNEU DevanshuNEU merged commit c5873fa into OpenCodeIntel:main Apr 28, 2026
6 of 7 checks passed
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.

1 participant