portfolixir

ADR-0036: risk-tier work rides the batch — the dedicated-small-PR exception is withdrawn

Context

ADR-0026 moved feature trees onto epic branches accepted in one behavior-level review, and carved out an exception:

Risk-tier exceptions — these keep dedicated small PRs with real human review: ledger/money-domain math and domain invariants, security-relevant changes, dependency updates, and anything touching the import idempotency or projection semantics.

The exception assumed those small PRs would actually be read closely. Six weeks of practice say otherwise, and the reason is structural: this project has exactly one reviewer, and ADR-0026 itself was written because that reviewer’s attention is the scarce resource. Carving the highest-risk changes into their own queue did not add review capacity; it produced a backlog of micro-PRs competing for the same attention that was already the bottleneck.

Sprint 3 made the cost concrete. The plan (sprint-plan-2026-08-01.md) serialized three risk-tier items behind one reviewer and stated plainly that “three risk-tier PRs plus one large cross-cutting batch do not review in parallel through one person”. The owner then directed all lanes to run in parallel and land as one PR, and the same again for the #619 follow-on and for a dependency update that blocked CI — three deviations from the same clause within two days. A rule deviated from every time it binds is not a control; it is paperwork that makes the record less honest.

The owner’s own framing (2026-08-04): many small PRs simply do not get reviewed, so the choice is not between a carefully-read small PR and a skimmed large one. It is between an unread small PR and a large one whose risk-tier content is deliberately surfaced. With TDD-first discipline and the mandatory agentic review, a regression in money-domain code should be caught by a failing test and an adversarial reviewer, not by a human reading a diff they did not have time to read.

Decision

The risk-tier delivery exception is withdrawn. Ledger/money-domain math, security-relevant changes, dependency updates and import-idempotency / projection work ship inside the epic batch like everything else, on the same branch, in the same PR.

“Risk-tier” survives as an attention label, not a delivery mode. Marking a change risk-tier now means:

  1. Its own commit or commit group, never mixed into an unrelated commit, so it stays independently readable, revertable and cherry-pickable.
  2. Deeper agentic review. The ADR-0026 closing act is mandatory anyway; for risk-tier content it must include a dedicated verification pass on the invariant at stake — the money identity, the idempotency property, the projection semantics — with findings verified against code, tests and the governing ADR before they are surfaced.
  3. Explicit callout in the reviewer briefing, naming what changed, which invariant protects it, and which test pins it — so the owner’s behavior-level acceptance is aimed at the risky part instead of spread evenly.
  4. Decision gate unchanged. ADR-0026 step 1 still applies: risk-tier work that changes semantics needs its ADR signed off before the batch starts. Withdrawing the delivery exception does not withdraw the decision gate.

The compensating controls stop being aspirational. ADR-0026 listed them as things the workflow “leans on”; they are now the substitute for the withdrawn human read, and therefore blocking:

Consequences

References