Skip to content

Burden-forecast medium tier ignores queueGrowthRisk, under-classifying queue-growth pressure #465

Description

@joaovictor712

Repo: JSONbored/gittensory
File: src/signals/engine.ts (buildBurdenForecast, the level ternary)
Severity: low–medium (maintainer-facing forecast under-reports; see confidence caveat)

Summary

The forecast level ternary OR's queueGrowthRisk into the critical and
high tiers but omits it from the medium tier, which only checks
projectedReviewLoad. A repo with moderate queue-growth risk
(queueGrowthRisk in [25, 55)) but low review load is therefore classified
"low" instead of "medium", losing an early signal that the queue is
building avoidable triage pressure.

Evidence

// src/signals/engine.ts (buildBurdenForecast)
const projectedReviewLoad = clamp(openPrs.length * 3 + updatedRecently * 2 + collisions.summary.highRiskCount * 4 + stalePrs, 0, 100);
const queueGrowthRisk = clamp((openPrs.length - queueHealth.signals.likelyReviewablePullRequests) * 5 + collisions.summary.clusterCount * 7, 0, 100);
const level =
  projectedReviewLoad >= 80 || queueGrowthRisk >= 80 ? "critical"
  : projectedReviewLoad >= 55 || queueGrowthRisk >= 55 ? "high"
  : projectedReviewLoad >= 25 ? "medium"   // <-- queueGrowthRisk dropped here only
  : "low";

The two higher tiers combine both risk dimensions with ||; the medium tier
uses only projectedReviewLoad. It is the single tier that breaks the pattern.

Concrete trace

Repo with 3 open PRs, none likely-reviewable (no linked issues / stale), and 3
duplicate-collision clusters, no high-risk collisions:

  • queueGrowthRisk = (3 - 0) * 5 + 3 * 7 = 15 + 21 = 36
  • projectedReviewLoad = 3*3 + 0 + 0 + 0 = 9
current with fix
level "low" (PRL 9 < 25, QGR not considered) "medium" (QGR 36 ≥ 25)

So a queue with real growth pressure (unreviewable PRs + duplicate clusters)
reports a "low" maintainer-load forecast.

Test status

Not locked in. test/unit/burden-forecast.test.ts only asserts the low
(empty queue) and critical (120-PR queue) cases from buildBurdenForecast;
the "medium"/"high" strings elsewhere in that file are hardcoded fixture
payloads
for the loader/cache path, not computed levels. The QGR-driven medium
case is never exercised, and the suggested fix leaves the existing low/critical
assertions unchanged.

Suggested fix

Make the medium tier consider queueGrowthRisk, consistent with the two tiers
above it:

  : projectedReviewLoad >= 25 || queueGrowthRisk >= 25 ? "medium"

Add a fixture with a small-but-unreviewable, collision-heavy queue
(projectedReviewLoad < 25, queueGrowthRisk in [25, 55)) asserting
level === "medium".

Confidence caveat (not a slam-dunk)

This is a reasonable, fully in-repo internal inconsistency (no external
canonical needed), but it is not airtight:

  • For "bug": levels and findings are separate concerns, and the OR-symmetry
    at the critical/high tiers strongly implies the medium tier was intended to OR
    queueGrowthRisk as well — a classic incomplete-pattern omission.
  • For "intentional": the separate queue_growth_risk finding only emits at
    queueGrowthRisk >= 55 (aligned with the high tier), so one could argue
    queueGrowthRisk was deliberately designed as a high/critical-only escalator
    that should not influence the medium baseline.

Recommend confirming intended semantics with the maintainer before merging a fix
(does queueGrowthRisk belong in the medium tier, or is it deliberately a
high/critical-only signal?).

Metadata

Metadata

Assignees

No one assigned

    Labels

    slopAI slop and/or attempts to game additional points via manipulation or alt profiles.

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions