Four-eyes change
Two sequential, independent approvals, asked once the agent review loop has passed and the pull request is green on CI — the two-person rule that change-management processes ask for. Requesting changes — with a required note — sends the change back for a fix and CI, then both people sign off again; a rejection stops the run.
| Template | four-eyes |
| Works on | A git repository, cloned into an isolated Docker sandbox |
| Where a person acts | First sign-off — author / team-lead review — a person approves or rejects, waiting up to 24h Second sign-off — independent reviewer — a person approves or rejects, waiting up to 24h |
| Waits on systems | CI result, up to 4h |
The workflow
Section titled “The workflow”Drawn from the template spec at build time. Bookkeeping nodes that only record status are left out; amber nodes are where a person acts.
flowchart TD
n_validate["Validate"]
n_implement["Implement"]
n_review["Review"]
n_checkApproval{"Check approval?"}
n_openPR["Open PR"]
n_checkReviewLimit{"Check review limit?"}
n_waitForCI[/"Wait for CI<br/><small>waits up to 4h: CI result</small>"/]
n_lessonReviewFailed["Lesson review failed"]
n_reviewFix["Review fix"]
n_checkCI{"Check CI?"}
n_terminateCITimedOut(["Timed out<br/><small>ci timed out</small>"])
n_terminateReviewFailed(["Failed<br/><small>review failed</small>"])
n_firstSignoff>"First sign-off — author / team-lead review<br/><small>person: approval</small>"]
n_checkCILimit{"Check CI limit?"}
n_secondSignoff>"Second sign-off — independent reviewer<br/><small>person: approval</small>"]
n_terminateRejected(["Failed<br/><small>rejected</small>"])
n_checkSignoffLimit{"Check signoff limit?"}
n_terminateTimedOut(["Timed out"])
n_lessonCIFailed["Lesson CI failed"]
n_fetchLogs["Fetch logs"]
n_done(["Done"])
n_signoffFix["Signoff fix"]
n_terminateCIFailed(["Failed<br/><small>ci failed</small>"])
n_ciFix["CI fix"]
n_checkSignoffFixChanged{"Check signoff fix changed?"}
n_checkCiFixChanged{"Check CI fix changed?"}
n_repushAfterFix["Repush after fix"]
n_validate --> n_implement
n_implement --> n_review
n_review --> n_checkApproval
n_checkApproval -->|"yes"| n_openPR
n_checkApproval -->|"no"| n_checkReviewLimit
n_openPR --> n_waitForCI
n_checkReviewLimit -->|"yes"| n_lessonReviewFailed
n_checkReviewLimit -->|"no"| n_reviewFix
n_waitForCI -->|"received"| n_checkCI
n_waitForCI -->|"timed out"| n_terminateCITimedOut
n_lessonReviewFailed --> n_terminateReviewFailed
n_reviewFix --> n_review
n_checkCI -->|"yes"| n_firstSignoff
n_checkCI -->|"no"| n_checkCILimit
n_firstSignoff -->|"approved"| n_secondSignoff
n_firstSignoff -->|"rejected"| n_terminateRejected
n_firstSignoff --> n_checkSignoffLimit
n_firstSignoff -->|"timed out"| n_terminateTimedOut
n_checkCILimit -->|"yes"| n_lessonCIFailed
n_checkCILimit -->|"no"| n_fetchLogs
n_secondSignoff -->|"approved"| n_done
n_secondSignoff -->|"rejected"| n_terminateRejected
n_secondSignoff --> n_checkSignoffLimit
n_secondSignoff -->|"timed out"| n_terminateTimedOut
n_checkSignoffLimit -->|"yes"| n_terminateRejected
n_checkSignoffLimit -->|"no"| n_signoffFix
n_lessonCIFailed --> n_terminateCIFailed
n_fetchLogs --> n_ciFix
n_signoffFix --> n_checkSignoffFixChanged
n_ciFix --> n_checkCiFixChanged
n_checkSignoffFixChanged -->|"yes"| n_firstSignoff
n_checkSignoffFixChanged -->|"no"| n_repushAfterFix
n_checkCiFixChanged -->|"yes"| n_checkCILimit
n_checkCiFixChanged -->|"no"| n_repushAfterFix
n_repushAfterFix --> n_waitForCI
class n_firstSignoff,n_secondSignoff gate
class n_waitForCI wait
Maturity: built from the flagship steps
Section titled “Maturity: built from the flagship steps”Ships as a built-in template and reuses the engineering steps the flagship flow runs. This particular arrangement of them is not separately exercised end to end against a real repository. See product overview §8.
Use it
Section titled “Use it”Every built-in template is seeded into the workflow library and can be cloned, edited on the visual canvas, and versioned — see architecture for the node types. The spec lives in packages/shared/src/workflow/templates/fourEyes.ts.
© 2026 Jorge Barnaby
Source-available under FSL-1.1-MIT