The Guarded PARR Pipeline
How a unit of work travels from a handover through PFactory (plan & govern) → AIFactory (build) → TFactory (verify) → a reviewed, merged PR — and exactly where, why and how execution is guarded at every hop.
PARR = Prepare · Act · Reflect · Review. Each factory owns one stage; a cryptographically-signed contract carries trust between them; humans stay in control at the decisions that matter.
End to end — every step and decision gate
Every arrow is cheap; every diamond is a guard. This is where “let an agent build it” becomes a governed process.
has a task or plan]) --> HO1 subgraph HO["1 · Handover"] HO1["/handover or /parr-run
plan brief + acceptance criteria"] end HO1 --> PF1 subgraph PF["2 · PFactory — Plan and Govern"] PF1["ingest: parse ACs,
decompose to epic + child issues"] PF1 --> PF2{"Hard readiness checks?
criteria present · AC to child coverage
· deps acyclic · no silent fallback"} PF2 -- fail --> PFX["Reject / revise brief"] PF2 -- pass --> PF3["process: governance lenses
security · feasibility · cost · architecture"] PF3 --> PF4{"aggregate over 0.75
AND no blocking findings?"} PF4 -- no --> PFX PF4 -- yes --> PF5["Human approve
(approver + plan-hash recorded)"] PF5 --> PF6["emit-contract:
RFC-0002 Task Contract v2
+ HMAC-SHA256 signature"] end PF6 -->|"POST /from-plan
signed contract"| AF1 subgraph AF["3 · AIFactory — Build"] AF1{"Signature verifies?
shared key per authority"} AF1 -- no --> AFB["FALLBACK: create-and-run
re-plan from scratch
(contract discarded)"] AF1 -- yes --> AF2["TRUSTED fast path:
install plan + spec.md,
persist contract to context/,
SKIP the spec pipeline"] AF2 --> AF3["Build in dependency waves
model from contract (Gemini/Claude)
coder implements subtasks"] AFB --> AF3 AF3 --> AF4["QA reviewer to QA fixer loop"] end AF4 --> AF5{"auto-handover
to TFactory?"} AF5 -- no --> DoneB([Stop at build —
human review / manual PR]) AF5 -- yes --> TF1 subgraph TF["4 · TFactory — Verify"] TF1["ingest spec + contract
to context/task_contract.json"] TF1 --> TF2["Planner AUTO-runs;
reads DECLARED test profile
(lanes · frameworks · ac_to_code_map)"] TF2 --> TF3["Generate + run tests"] TF3 --> TF4{"Tests pass?"} TF4 -- no --> TF5{"handback cycles under 2?"} TF5 -- yes --> HB["apply-correction to
AIFactory QA fixer to re-test"] HB --> TF3 TF5 -- no --> NH["needs_human
(RFC-0001 event)"] end TF4 -- yes --> PR1 subgraph PRE["5 · PR Endgame"] PR1["Open PR
(gh auth setup-git + push)"] PR1 --> PR2["Pre-merge reviewer
AIFactory engine / Copilot / any"] PR2 --> PR3{"Verdict?"} PR3 -- "changes requested" --> PR4{"fix cycles under 2?"} PR4 -- yes --> PR5["auto-fix to push to re-review"] PR5 --> PR2 PR4 -- no --> NH PR3 -- "approved / ready" --> PR6{"auto-merge
enabled?"} PR6 -- no --> DoneR([PR left OPEN —
human merges]) PR6 -- yes --> PR7{"Mergeable?"} PR7 -- "behind base" --> PR8["update-branch + retry"] PR8 --> PR7 PR7 -- "true conflict" --> NH PR7 -- clean --> PR9["Merge to re-test on main"] end PR9 --> EndM([Merged]) NH --> EndH([Human takes over]) classDef gate fill:#3a3115,stroke:#fabd2f,stroke-width:2px,color:#f6dd98; classDef stop fill:#3d1f1c,stroke:#fb4934,stroke-width:2px,color:#f5a99f; classDef good fill:#33360f,stroke:#b8bb26,stroke-width:2px,color:#e2e4a0; class PF2,PF4,AF1,AF5,TF4,TF5,PR3,PR4,PR6,PR7 gate; class PFX,NH,EndH stop; class AF2,PR9,EndM good; classDef pf fill:#2b3a37,stroke:#83a598,stroke-width:2px,color:#cfe6de,font-weight:bold; classDef af fill:#3a2b18,stroke:#fe8019,stroke-width:2px,color:#f6cfa6,font-weight:bold; classDef tf fill:#33360f,stroke:#b8bb26,stroke-width:2px,color:#e2e4a0,font-weight:bold; classDef cf fill:#3a3115,stroke:#fabd2f,stroke-width:2px,color:#f6dd98,font-weight:bold; classDef pfbox fill:#262c2b,stroke:#83a598,stroke-width:2px,color:#83a598; classDef afbox fill:#2e261c,stroke:#fe8019,stroke-width:2px,color:#fe8019; classDef tfbox fill:#2b2c14,stroke:#b8bb26,stroke-width:2px,color:#b8bb26; class PF pfbox; class PF1 pf; class PF3 pf; class PF5 pf; class PF6 pf; class AF afbox; class AFB af; class AF3 af; class AF4 af; class HB af; class PR2 af; class TF tfbox; class TF1 tf; class TF2 tf; class TF3 tf;
The guards — what is protected, why, and how
| # | Guard | Why it exists | How it’s enforced |
|---|---|---|---|
| G1 | Acceptance criteria required | You can’t verify what you didn’t specify | PFactory hard-fails a brief with no ## Acceptance Criteria; every AC maps to a child issue |
| G2 | Governance lenses | Catch risk before code exists | process scores security · feasibility · cost · architecture; aggregate must clear 0.75 with no blocking findings |
| G3 | Live-infra / access checks | Don’t promise cloud actions you can’t perform | Unverified IAM/cloud actions are flagged (surfaced, not hidden); soft/waivable when air-gapped |
| G4 | Human approval | A person owns the go/no-go | approve records approver + plan-hash; nothing is signed until then |
| G5 | HMAC-signed contract | Tamper-proof handover; downstream trusts content, not the caller | RFC-0002 v2, signed with a per-authority shared key |
| G6 | Verify or fallback | A forged/edited contract must not skip planning | Valid signature → trusted fast path; invalid → safe re-plan fallback |
| G7 | OAuth-only auth | Agents must not silently bill a raw API key | API key scrubbed by default; direct-key billing is opt-in (AIFACTORY_ALLOW_API_KEY) |
| G8 | Agent env scrub | A prompt-injected agent can’t exfiltrate host secrets | Control-plane tokens, DB URLs, cloud creds, provider keys blanked from the agent env |
| G9 | Allowlist + FS jail | Limit blast radius of generated commands | Per-stack command allowlist; filesystem restricted to the workspace; bash isolated by the pod boundary |
| G10 | Worktree isolation | One build can’t corrupt another or your tree | Each spec builds in its own git worktree/branch; merge only on explicit action |
| G11 | Declared-AC testing | Test what was promised, not a guess | The contract’s tfactory block (lanes/frameworks/ac_to_code_map) drives test generation |
| G12 | Bounded handback | Self-correction must not loop forever | TFactory→AIFactory correction capped (≤2) → terminal needs_human |
| G13 | Reviewer-gated merge | Nothing merges unreviewed | Merge needs the configured reviewer’s verdict; changes-requested → bounded auto-fix |
| G14 | Never force-merge | Protect main from unsafe automation |
On a true conflict: update-branch once, then human-stop — never --force |
| G15 | Full audit trail | Enterprises need provenance | Every transition emits RFC-0001 events in the CFactory cockpit, keyed by correlation_key |
| G16 | Completion evidence gates | “Reached a terminal state” must not be mistaken for “did the work” | A stage claims success only with proof — issues created (plan), non-zero tokens + completed phases (build), non-null verdict + executed tests (verify); consumers render success-without-evidence as unproven. RFC-0001a |
Two independent layers of defense
The trust chain governs what crosses factory boundaries (a signed, human-approved contract). The execution sandbox governs what a single agent can do on a machine. Even a fully compromised agent prompt is boxed by the sandbox; even a forged contract is rejected by the trust chain.
The signed handshake + self-correcting verify loop
Who it’s for — real scenarios
The solo builder
Maya maintains side-projects alone on a subscription, no API budget. She
/handovers a feature with ACs and goes to dinner. OAuth-only auth uses her
subscription (never a metered key); the build runs in an isolated worktree;
TFactory tests the AC she declared; the PR is left open because she hasn’t
enabled auto-merge. Saturday morning: a green, tested PR awaiting a 30-second
review. No surprise bills, no broken main.
The developer in a team
Raj is blocked on a frontend change he lacks context for. He hands a short
brief to PFactory instead of context-switching. Required ACs make the intent
unambiguous; the architecture lens checks it fits; the ac_to_code_map
makes TFactory write the exact test; a bounded handback fixes a flaky
selector automatically. Raj stays in flow; the change lands as a reviewed PR.
The squad
A platform squad runs a sprint with 12 stories, 4 independent. The lead approves a multi-service epic; the acyclic dependency check proves the graph is safe before any code; each story builds in its own worktree; the CFactory cockpit shows every story’s live stage. Four merge themselves overnight with passing tests; standup is about the one exception, not status-reporting twelve.
The enterprise
A regulated org adopts the Factory as its standard ticket-to-merge process. The
security lens + threshold blocks risky plans before code; human approval
with recorded approver + plan-hash is the change-control record; the HMAC
contract ties every build to a signed, approved plan; scrub + allowlist + FS
jail mean agents can’t leak secrets or run arbitrary commands;
never-force-merge + the reviewer gate protect main; the RFC-0001 audit
trail is the auditor’s evidence. AI does the toil; the process is enforced by
the tool, not by hope.
Source: AIFactory/guides/parr-pipeline-and-guards.md. Every guard here is implemented and verified in the running cluster.