Skip to content

doctor's runtime is unmeasured, and squash-conservation silently truncates its scan at 200 branches #472

Description

@MongLong0214

doctor's own performance is an assertion with no measurement behind it, and one check quietly narrows what it looked at: squash-conservation slices its branch list at MAX_SQUASH_CANDIDATE_BRANCHES = 200 (.slice(0, 200) in squashCandidates) and then reports over the subset without saying a subset existed. PRD §10.3 names that for what it is: "an ok over an unstated subset is the §8.3 rule violated in miniature."

Why this exists

  • PRD §10: "Unmeasured today; made measurable by §1.5, then fixed." The ADR's consequences section ties the move to precedent: per-check timing "is how the PRD's budget stops being an assertion (the same move as commit 1f8b4be made for the 100k-commit criterion)."
  • ADR falsification 6 is the stake: a full check set measured slow enough that users skip running doctor reopens the profiles rejection — with the measurement it asked for. Without this ticket that condition can never be tested.
  • index --rebuild reports unqualified success on a mirror it could not read, and cli.md says it always can #400 is the shape of the truncation half: unqualified success over a source the command did not fully read.

Scope

  1. The budget (PRD §10.1). Measure a full doctor run on this repository — the same reference the RELEASE-GATE fresh-clone row uses — and record the budget in the acceptance test as measured baseline plus headroom. The PRD deliberately refuses to invent the number before the instrument exists, and so does this ticket: the number enters the test at measurement time, with the method, environment class, and date in a comment beside it.
  2. Attribution (PRD §10.2). summary.durationMs === Σ per-check durationMs is already asserted in the envelope ticket; this ticket makes a budget failure name its check — the failing test's output prints per-check durations sorted descending.
  3. Truncation disclosure (PRD §10.3). When for-each-ref lists more than 200 branches: evidence gains branches_seen and branches_checked, and the detail names the limit. The ≤ 200 case stays byte-identical — this is the one deliberate detail-string addition, and it fires only in the state that is silent today. The cap itself does not change.

Acceptance criteria

  • A timed acceptance test runs the full check set against the reference repository shape and fails when the run exceeds the recorded budget; the budget's provenance (baseline, headroom, method, date) is in the test.
  • On budget failure, the test output names the slowest checks with their durationMs — a regression is attributable without re-instrumenting.
  • A fixture with 201 local branches: squash-conservation evidence carries branches_seen: "201" and branches_checked: "200", and the detail names the 200-branch limit. Status semantics unchanged — disclosure, not a new verdict.
  • A fixture with 200 local branches: output byte-identical to today, no truncation wording.
  • MAX_SQUASH_CANDIDATE_BRANCHES is unchanged.

Tests that must exist

case what it catches
201 local branches: the scan says it truncated today's silent .slice(0, 200) — the miniature #458 the PRD names. This is the fails-if-wrong case: it fails against the shipping implementation and against any future edit that re-silences the cap
200 local branches: no truncation text the disclosure over-firing and changing the common case §9 froze
full run completes within the recorded budget the regression ADR falsification 6 asks to be able to observe — doctor becoming slow enough to skip, invisibly
budget failure output ranks checks by duration a red budget test that says only "too slow" — unattributable, so unfixable without re-work

Open question — flagged, not decided here

PRD §10.1 leaves the headroom multiplier and the treatment of CI-runner variance (fixed ms vs. relative-to-baseline) open. Record whichever is chosen next to the number; do not spread the choice across tests.

Depends on

Out of scope

  • Changing the 200-branch cap, optimizing any check, profiles (still a non-goal — this ticket produces the measurement its reopening condition requires, nothing more), trend history (non-goal).

Traceability: PRD §1.5, §10, §11 ("budget"); ADR-0032 consequences and falsification 6.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions