Skip to content

Make review findings the load-bearing artifact #162

Description

@aaddrick

Problem

Review findings are collected, counted, and then discarded. grep -n "\.issues" workflows/ticketmill.js finds exactly one consumer in the pipeline: the recordGateOutcome tally at :4669.

What the fix stages actually receive is reviewer prose:

  • runQualityLoop :2962 passes String(rev.comments || rev.summary || 'No comments')
  • reviewAndMerge :4680-4681 passes String(spec.comments || spec.summary) and String(code.comments || code.summary)
  • the test loop :3484 passes String(v.comments || v.summary || 'Fix test quality issues')

And loop control never reads findings either:

  • :2954 if (rev.result === 'approved')
  • :3477 if (v.result === 'approved')
  • :4667 spec.result === 'approved' && code.result === 'approved'

REVIEW_SCHEMA.issues at :638 is { type: 'array', items: {} }, untyped, with no severity field. That is why gate_findings['pr-review'].severity reports zeros across the board, documented as expected at :2021-2027.

Two consequences. Nothing downstream can address a specific finding, because findings have no identity. And a gate cannot terminate on findings being resolved, only on a reviewer changing its own verdict string.

Change

  1. Type REVIEW_SCHEMA.issues with the shape CHALLENGE_SCHEMA.findings already uses at :599: objects with severity (critical/major/minor), summary, and an optional recommendation. Give each finding a stable id within its gate iteration so later stages can reference one.
  2. Ask for it in the prompts that produce a REVIEW_SCHEMA result: spec review :4613, code review :4633, quality review :2934, test validation :3452.
  3. Feed the three fix stages from the structured array instead of the prose blob. Keep rendering comments as context, but the findings array becomes the input of record.
  4. Move the three loop predicates to "approved, or zero surviving findings."

Acceptance criteria

  • REVIEW_SCHEMA.issues is typed and the four producing prompts ask for it.
  • All three fix stages receive the structured findings; comments still appears as context.
  • All three loop predicates accept a clean pass on either condition.
  • gate_findings['pr-review'].severity reports real counts in a live run, and the note at :2021-2027 is updated to match.
  • A reviewer that returns changes_requested with an empty findings array still terminates the loop rather than running a fix stage with nothing to fix.
  • A reviewer that omits issues entirely degrades to today's behaviour rather than throwing. recordGateOutcome already tolerates a missing severity.
  • node --test stays green. Extend tests/pr-review-gate.test.js, tests/quality-loop.test.js, tests/test-loop.test.js, and tests/gate-findings.test.js.

Why this one leads

Every other structural improvement in this set needs finding identity. A fix stage cannot rebut a specific finding if it received a prose blob, and a re-raised finding cannot be detected across gates if findings are not addressable. It also removes the severity blind spot at the merge gate, which is currently the only gate whose findings carry no severity at all.

Out of scope

No suppression or filtering of findings. This issue only makes findings load-bearing. Whether volume needs reducing is a separate question that needs data this change produces.

Documentation target

Document in CHANGELOG.md and in a new page docs/architecture/gate-hygiene.md (create it), adding its row to docs/architecture/index.md's file map.

Do NOT edit docs/architecture/pipeline.md, metrics.md, or failure-semantics.md. Their moved prose is hash-frozen by tests/architecture-provenance.test.js, and since the tech-docs stage runs at :4707, after the last test-loop execution, a frozen-prose edit surfaces only as a red CI check on the batch PR. New pages are authored text and are explicitly allowed; see docs/architecture/CLAUDE.md.

Metadata

Metadata

Assignees

Labels

gate-hygieneGate hygiene: findings, caps, and per-problem budgets (sequenced)

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions