0012. Stages, gates and sign-offs count only on the default branch, with no unapproved self-review¶
- Status: Accepted
- Date: 2026-10-18 (fail-closed hardening on 2026-10-25)
Context¶
Plant design proceeds in stages (concept, basic, detail). With agents doing much of the work, a stage must not be declared done by the same actor that did it, and claims must be tied to an exact, reviewed state of the files.
Decision¶
- Stages are data in
plant.yaml; each has gates inchecks/checks.yaml(kinds such as rules, on-sheet, review, datasheets, maturity, issues), evaluated bycheme check. cheme check --writesigns a stage off intochecks/status.jsonwith provenance (signer, commit, gate results). It refuses a dirty tree, failing gates, a review record that is the signer's own (reviewer_kind: selfor the reviewer is the signer) without anapproved_bynaming someone else, and open critical/high review findings or ones "closed" by a commit not in HEAD's history.- A review counts only for the
scopeat itsreviewed_commitwith no changes since. A stage counts as reached only when its sign-off is on the default branch; stage work happens on a branch and is merged by a human or the reviewer, never the stage agent. - Gates and reviews fail closed: when git cannot tell, or a stage or gate is unknown, it does not pass.
Consequences¶
- Positive: separation of duties between author, reviewer and approver, enforced by the tool, with the evidence in git.
- Positive: gates are per stage, so artifacts of different maturities coexist.
- Negative: sign-off depends on git state and merge discipline; a repository without a protected default branch can still be bypassed by a person with push rights.
- Limitation: gates passing is not a review; independent review remains a human act (0013).
Evidence¶
- Review gate, stable review finding ids, sign-off with provenance refusing a self-signed review, branch and merge policy.
- Fail closed.
src/chemeascode/project/signoff.py,project/checks.py,foundation/reviews.py, the template'sSTAGES.mdandAGENTS.md,REFERENCE.md("check"), stages and gates.