Skip to content

doctor's text report has no first line that matters: a user reads thirteen rows to find the one thing to fix #470

Description

@MongLong0214

doctor's text report starts with the first check and ends with the last one. There is no headline, no summary, no ordered fix plan — a user reads thirteen rows and does the triage themselves. #458's user had the answer in row nine of a report whose every row said ok; the rebuilt model can now say pending-backlog first, but nothing renders it.

This is the ticket that deliberately changes the shipping text output. Every earlier ticket in the milestone held it byte-identical against a pinned snapshot; this one updates the snapshot, on purpose, with review.

Why this exists

  • PRD Goal: "A user who runs commitlore doctor learns, in one screen, whether this repository can carry and share records — and when it cannot, the first line tells them the one thing to fix first."
  • PRD §6 fixes the layout; §4.3 fixes the fix-plan rendering and its dedup — "one dead hook runtime is one instruction, not four warnings" is only true once the renderer prints it that way.

Scope

src/commands/doctor/render.ts (formatReport keeps its name and export path through the shim).

  1. Line one: headline. Line two: the summary roll-up, PRD's example form: 9 ok, 2 warnings, 1 failed, 1 skipped (412ms).
  2. Then the fix plan, one line per entry — N. [status] id — detail (fix) — with each distinct fix string printed once, on its first appearance (the seen-set dedup PRD §4.3 specifies).
  3. Then one line per check in registry order, in the current format — status padded to 8, title — detail, the fixed by --fix and fix: continuation lines — with the current detail strings, unchanged (PRD §6.2).
  4. --verbose adds evidence keys, skipReason, and durationMs under each check; the default stays one line per check (PRD §6.3).
  5. No color unless stdout is a TTY, and none under NO_COLOR; plain output is byte-stable for the release gate (PRD §6.4).

Acceptance criteria

  • §6.1–§6.4 implemented exactly; the new snapshot is reviewed as the deliberate contract change it is.
  • The per-check block (item 3) is byte-identical to the pre-ticket report — only the header block (headline, summary, fix plan) is new.
  • Plain (non-TTY) output is identical with and without NO_COLOR set, and contains no ANSI sequences.
  • Two findings sharing one fix string print it once.
  • The CI fresh-clone step (.github/workflows/ci.yml, "A fresh clone runs...") passes: doctor on the clone still exits 0 and the step's set -euo pipefail sees nothing new.
  • --verbose output is snapshot-pinned; default output gains no per-check lines.

Tests that must exist

case what it catches
headline is line one, summary is line two over a mixed-status fixture the report reverting to check-list-first — the triage going back to the user
four findings, one shared fix string, printed once the wall of text the dedup exists to control — four commitlore hooks install lines where one is the instruction
degraded with no actionable entry renders usable-not-verified, never the healthy wording PRD §4.4's "Never 'healthy' while status is non-ok" — the rendered form of the #402 defect (a ready that is not ready). This is the fails-if-wrong case
NO_COLOR and non-TTY outputs are byte-identical ANSI leaking into the plain stream the release gate and init consume
the per-check tail is byte-identical to the pre-ticket rows (line-wise diff against the old snapshot) an accidental reflow of shipping detail strings smuggled in with the header
--verbose lists evidence keys, skipReason, durationMs; default does not the verbose surface bleeding into the one-line default

Open question — flagged, not decided here

src/commands/init.ts prints formatReport(report) lines under its doctor step, and test/init-output.test.ts pins plain init to six lines — a deliberate contract (#402 records why changing that budget is its own decision). The PRD does not say whether init's embedded rendering gains the headline/summary block. Options: init consumes an exported checks-only renderer, or accepts the new block under --verbose only. Decide with the #402 lesson in view — in its own reviewed change if the line budget moves — not silently here.

Depends on

Out of scope

  • Changing any per-check detail string; changing init's line budget (see above); HTML or any other output form (PRD non-goal); the N of M checks run headline prefix (filters ticket).

Traceability: PRD Goal, §4.3, §4.4, §6; ADR-0032 consequences.

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