adr: a decided record needs assent from a second account (four-eyes, token comment) #528
Labels
No labels
breaking
bug
documentation
enhancement
epic
good first issue
help wanted
refactoring
resolution/duplicate
resolution/invalid
resolution/wontfix
security
severity/critical
severity/high
severity/low
severity/medium
status/abandoned
status/blocked
status/needs-decision
status/needs-info
status/needs-verification
testing
upstream
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
sixfold-space/madtea#528
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
adr checkverifies that an undecided record is tracked by open issues (#483). It does not verify how a record became decided. Today one actor writes the record, setsstatus: "accepted", and merges it. When that actor is an agent, the record is self-approved: it says a decision was made, and nothing outside the file says who made it.That is the failure I care about. An over-eager agent archives its own reasoning as settled doctrine, and the tree then reads as if I ruled on it.
Rule
A record in a DECIDED status must link assent from an account that is not the record's author.
accepted,rejected,deprecated,superseded by ADR-NNNN.## More Information, carrying the exact tokenADR-ACCEPT <record>(orADR-REJECT <record>forrejected).<record>is the four-digit number, optionally prefixed by the repo (0007orrubric/0007). A prefix that names a different repo does not match.Four eyes, and no configuration. There is no decider allowlist, no named-human setting, nothing a project has to set up to be protected. The property that binds is authorship, which the writing account cannot forge.
Why a token and not a phrase
I considered matching a list of words (
approved,ratified,looks good). It fails in the dangerous direction: "this looks good but the second option is wrong" reads as assent, silently. An exact token is typed only on purpose, and a missing token fails loudly.Non-goals
Acceptance criteria
ADR-REJECTis required forrejected;ADR-ACCEPTfor the other decided statuses.--skip-remote-issuesskips this rule with the existing skip line, since it needs the forge.proposedis unaffected.madt_help topic=adr, the CLI help, and the README document the token and the four-eyes rule.Out of scope
Single-identity repositories
Some projects have exactly one actor. One maintainer, one account, every commit and every comment under that name. The rule cannot bind there: the record's author and the assent comment's author are the same account by construction. SLSA takes the same position on two-party review, which it keeps as a separate policy rather than a level, so levels 1 to 3 stay reachable by a single-maintainer project (https://slsa.dev/spec/v1.2/source-requirements).
So
checkreports "not applicable" there instead of failing. Two things stop that from becoming a hiding place.The exemption is computed, never configured. No flag, no setting.
checkcollects the distinct actors it can see: the authors of the commits that touched each record, and the authors of the comments on the linked issues. One distinct actor means not applicable. Two or more means the rule is enforced from then on, including on records written while the repository was still single-identity, and a decided record whose assent comment shares its author fails like any other violation. A project cannot declare itself single-identity. It either is or it is not, by its own history.That is the part that matters for automation. An agent with its own account cannot quietly do everything under the maintainer's name to stay exempt: one use of its own account, anywhere in the repository, turns the rule on for good. Using the maintainer's credentials instead is impersonation, which the issue already lists as out of scope.
It says so on every run, and names the way out. The check prints its posture rather than staying silent:
or
The second form is a warning on every run, not a quiet skip. A project running automation under the maintainer's account gets told, every time, that it is one account away from a real check.
Acceptance criteria, added to the list in the body
checkrun in MADR mode, in both states.--skip-remote-issuesreports that the posture could not be determined, since the actor set needs the comments.Decided in 0047-decided-record-needs-assent-from-a-second-contributor (ADR 0047). The record holds the design, with these changes from the text above: the author of a decided status is the forge account that opened the PR that set it; only accounts with more than read access to the repo count as contributors; a single-contributor repo reports the rule as not applicable, and a plugin hook asks the person for the token before an agent can commit the change;
ADR-DEPRECATE NNNNcovers a deprecated record. The build gets its own epic.