ADR-0046: Four-Eyes — Submitter Excluded from Approval¶
- Status: superseded by ADR-0047
- Superseded by: ADR-0047 (submitter-only exclusion — author exclusion removed)
- Superseded in part by: ADR-0096 (transition semantics: the ADR-0030/0046-lineage transition-permission reading is replaced by deny-unless-granted)
- Date: 2026-07-03
- Deciders: Nicolas Burri
- Refines: ADR-0030 (approve gate), ADR-0035 (author-excluded thresholds)
Context¶
Live testing (2026-07-03) reproduced a four-eyes bypass: ben authors a draft, anna submits it,
anna approves and releases it. The four-eyes gate checked only approver ≠ version.author, but
submit is the content-freezing act and is not restricted to the author — and any EDIT_DRAFT
holder may edit any draft. One person could therefore control content and approval end to end
while the flag read as satisfied.
Options considered: (O1) exclude every audit-recorded content contributor (author, all draft/ attachment editors, submitter) — strongest independence, but in small teams several people legitimately co-edit one document and O1 could leave no eligible approver; (O2) exclude author + the current round's submitter; (O3) restrict submit to the author — breaks delegation and still leaves the editing hole.
Decision¶
O2. When the effective policy demands four-eyes, the approver must differ from both the
version's author and the submitter of the current review round. The submitter is recovered
from the audit trail (the round's SUBMITTED event actor) — the audit record is the enforcement
source; no schema change. The reflection surface (approveBlockedReason) reports the exclusion
before the user attempts the action, like the existing author case.
Nicolas, on O1: "for small teams that might become a problem if multiple persons worked on the document. For now, I'd accept 2 different people for submit and review." O1 remains the documented tightening path (e.g. as a per-policy strictness level) if a regulated deployment demands contributor-level independence — a future refining ADR.
Consequences¶
- The reproduced scenario is closed: a submitter cannot approve that round. An editor who neither authored nor submitted CAN still approve — accepted for team-size pragmatics, and the full contribution history stays in the audit trail for review scrutiny.
- Approve gate, reflection DTO, and the review-progress UI messages gain the second exclusion; regression test = the exact ben/anna scenario.
- Per-round semantics: a rejected round's submitter is excluded only for rounds they submitted; resubmission by someone else refreshes the exclusion to the new submitter.