Skip to content

ADR-0041: Cross-Harness Severity Ladder

Accepted Town-crier Cross-Harness Contract

Date: Ratified TC-0036 2026-07-03 (both owners); our skills migrated same day; ADR crystallizes 2026-07-10. Tracks: kendo TC-0036 (the ladder + riders R1–R4), TC-0040 (enum schema on the wire) — script instance, project 13, contract-decision. Reasoning: project_town_crier_contract_decision_log memory; /registry/general-review-voice.md (the ladder as the General executes it).

Status note. A cross-harness contract: for findings from independently-run harnesses to compose — to confirm or deny one another on a shared thread (ADR-0040) — a "Major" from one harness must mean the same as a "Major" from another. Ratified with Jasper on the contract-decision log (TC-0036, Done = binding record); our review skills (general-review-voice, /pr-review-sweep, /bus-review) were migrated onto it the same day. This ADR crystallizes the ratified end-state per ADR-0015. It is the vocabulary layer: the tiers it defines are what ADR-0039's gate derives from and what rides ADR-0040's submit.

Context

Several harnesses review the same PR on one serialized thread (ADR-0040). For their findings to compose — for a second harness's turn to confirm or deny a first harness's finding — they need a shared severity scale. Before TC-0036, each harness carried its own vocabulary (the war room's was Blocker/Concern/Nit; others differed), so a cross-harness "confirm" was apples-to-oranges: the same defect could be a Concern here and a Major there, and the merge gate had no common tier to key on. Detection stays per-harness — each finds defects its own way, and that diversity is the value — but the scale that names a finding's consequence must be shared. That is the whole of this ADR.

Decision

1. A four-tier, first-match ladder (top-down; first match wins)

  • 🛑 Blockership test: on a realistic path — wrong output, a security / privacy / data-integrity breach, a regression of a working flow, or an unmet stated acceptance criterion.
  • 🔴 Majoredge / latent / contract test: real impact via a plausible edge case; a latent footgun likely to become a blocker; or a violated established contract/convention at real cost.
  • 🟡 Minorobjective-quality test: correctness-neutral but an objective improvement (reuse over duplication, dead code, a non-critical test gap, readability).
  • Nit — taste / cosmetic / preference. Author's call.
  • Praise (outside the ladder) — load-bearing decisions worth naming, brief. Standard wins ("uses a DTO") don't qualify; non-obvious correctness wins do.

2. One ladder for all categories

Severity is consequence, never type. Security, performance, and test-gap findings all tier on the same scale by what happens if the finding is true — a cosmetic security-adjacent nit is a Nit, not a Blocker-because-security.

3. Severity is assigned as-if-true

A finding is tiered as if it is true; uncertainty is never laundered into a lower tier ("it's probably a bug so I'll call it a Minor to be safe" is forbidden). Uncertainty lives in the confidence tag (§4), not the severity.

4. Two tags: confidence and provenance

  • confidenceConfirmed (a path:line citation or a reproduced command backs the claim) / Unconfirmed (plausible-as-if-true, with the verification stated). A second harness's turn promotes or kills an Unconfirmed finding — this is the decorrelated-verification value (ADR-0040 §4 guarantees the second turn is a different author).
  • provenanceintroduced (the defect line is in the diff) / adjacent (in code the diff touches) / pre-existing. Strict: only introduced lines carry blocking weight; boy-scout observations on adjacent/pre-existing code stay legal as suggestions, never as blocking findings — a small PR is not buried under a file's pre-existing sins.

5. Tie-break: round down, except round up for the high-stakes set

When torn between two tiers, round downexcept anything touching security, data-integrity, an acceptance criterion, or a regression of a working flow (R3), which rounds up. The asymmetry biases toward catching the consequences that are expensive to miss.

6. The ratified riders (R1–R4)

  • R1 — verdict binding. Interim (TC-0036): Blocker was the only verdict-forcing tier (Confirmed Blocker → REQUEST_CHANGES; Unconfirmed Blocker caps at COMMENT + a validation ask; Majors/Minors/Nits inform, never force). Superseded operationally by ADR-0039: the merge gate now derives BLOCKED/HELD from findings and binds bus machinery (suppresses consensus auto-resolve), while the R1 principle it preserves — the gate never forces a harness's stance — carries through unchanged.
  • R2 — invisible acceptance criteria. The acceptance-criterion Blocker clause (§1) applies only when the criteria are visible from the PR/thread; otherwise it is explicitly N/A, stated, never silently skipped or guessed.
  • R3 — regressions round up. A regression of a working flow joins the round-up set (§5) — folded into the ladder above.
  • R4 — approve-with-residuals. An APPROVE that carries actionable Minors/Nits marks them non-blocking, author's choice (fold here or follow-up); the reviewer never arms auto-merge on another's PR; at thread-resolve, surviving residuals carry to a disposition (fixed / follow-up / declined — never undecided). Operationalized by ADR-0039's disposition lifecycle (dispositions[] + residual-drain).

7. The scale is the registered vocabulary

TC-0040 enum-backs tier / confidence / provenance on the submit wire (ADR-0039 §1), retiring the copied BADGE_RE prose-parsing every harness carried. The enums are the single registered naming. Honest limit: the schema forces vocabulary, not calibration — a wrong tier on a real finding still ships; correct tiering stays the confirm/deny turn, now disputing tiers on specific finding rows rather than parsing prose.

Options Considered

OptionVerdictReason
Per-harness vocabularies (status quo)RejectedFindings can't compose; a cross-harness confirm/deny is apples-to-oranges; the merge gate has no shared tier to key on.
Severity by category (security always Blocker, etc.)RejectedSeverity is consequence, not type (§2). A cosmetic security-adjacent nit is not a Blocker.
Downgrade-with-note for uncertain findingsRejectedLaunders confidence into severity. The as-if-true tier + separate confidence tag (§3–4) is the honest split.
Confidence as a 3+-level scale / category as a third tagRejectedJasper's tag call: confidence YES (2-level), provenance YES (strict), category NO — a third axis with no consumer is noise.
Shared four-tier ladder, as-if-true, confidence+provenance tags, enum-on-wireAcceptedFindings compose across harnesses; the gate can derive from shared tiers; as-if-true kills confidence-laundering; provenance-strict protects small PRs.

Consequences

Positive

  • Findings compose across harnesses — a "confirm" means the same thing on both sides.
  • The merge gate can existADR-0039 derives BLOCKED/HELD from tiers because the tiers are shared and enum-registered.
  • As-if-true kills the confidence-laundering failure mode — uncertain findings keep their real severity and carry an explicit confidence tag instead of being quietly demoted.
  • Provenance-strict protects small PRs — a diff isn't buried under a file's pre-existing debt.

Negative

  • It is a shared contract — a harness that tiers to its own scale breaks composition. Mitigation: enum on the wire + the confirm/deny turn disputes mis-tiers.
  • Calibration is not enforced — only vocabulary. A mis-tiered finding ships; the schema can't catch it.

Risks

  • Mis-tiering ships. Mitigation: the decorrelated confirm/deny turn (ADR-0040 §4) is the calibration backstop — not the schema.

Enforcement

WhatMechanismLevel
tier / confidence / provenance enum-validated on the submit wireSubmitReviewRequestRequest + FormRequestsTest (via ADR-0039)1 / 3
The ladder + tags + riders as the review register/registry/general-review-voice.md · /pr-review-sweep · /bus-review skills4
Cross-harness ratification (both owners), riders foldedcontract-decision log TC-0036 (kendo-script project 13)5

Implementation

TerritoryStateNotes
town-crierRATIFIED + IN USETC-0036 signed both owners 2026-07-03; our general-review-voice + /pr-review-sweep + /bus-review migrated same day; enum-enforced on the wire via TC-0040 / ADR-0039. Foreign harnesses declare structured findings on the same enums (verified live 2026-07-09/10).

References

  • Originating tickets: TC-0036 (ladder + R1–R4), TC-0040 (enum schema) — kendo-script project 13, contract-decision label.
  • Related ADRs: Cross-Harness Merge Gate (ADR-0039 — derives the gate from these tiers, operationalizes R1/R4), Cross-Harness Thread & Turn-Lock Protocol (ADR-0040 — the thread the reviews ride; its no-two-turns rule is what makes confidence promotion decorrelated), ADR Governance (ADR-0015).
  • Reasoning / execution: project_town_crier_contract_decision_log memory; /registry/general-review-voice.md.

Architecture documentation for contributors and collaborators.