Cross-repo architecture
Factory is a program / meta repository — it ships documentation, RFCs and cross-cutting plans, not running software. Its architecture is the PARR pipeline: four independently useful products that hand one unit of work off to one another, with a fifth concern — observability — watching over all of them from CFactory, the control tower.
Prepare · Act · Reflect · Review — one stage per product.
The PARR flow
:3114 · :3115"] end subgraph A[" Act"] AF["AIFactory
:3101"] end subgraph R[" Reflect / Verify"] TF["TFactory
:3103"] end PF -- "governed GitHub issue" --> AF AF -- "merge-ready branch / PR" --> TF TF -. "handback · failing verdict" .-> AF CF[" CFactory — control tower
:3110 API · :3111 stream"] PF -. "completion event" .-> CF AF -. "completion event" .-> CF TF -. "completion event" .-> CF classDef tower fill:#1d2b3a,stroke:#5aa9e6,stroke-width:2px,color:#cde4ff; class CF tower; 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; class PF pf; class AF af; class TF tf;
Prepare → Act → Reflect run left to right. The dotted return arrow is the handback: when TFactory’s verdict fails, it routes a bounded correction request back to AIFactory’s QA fixer. Every stage emits a completion event to CFactory, which observes and steers the whole pipeline from the side.
| Stage | Product | Inputs → Outputs |
|---|---|---|
| Prepare | PFactory | plan (docx/pdf/md, MCP, issue) → enrich (live cloud/Backstage) → reconnoiter the target repo statically (RFC-0010, code-aware) → review gates (cited) → human approval → governed GitHub issues |
| Act | AIFactory | governed issue → spec → code in isolated worktree → QA → merge-ready branch / PR |
| Reflect | TFactory | finished feature on a branch → generate + run tests across modality lanes → 5-signal verdict + triage report |
| Review | CFactory | reads completion events + state from all three → one cockpit WorkItem view + advise-and-confirm copilot |
CFactory: the control tower
CFactory never sits in the critical path — it watches it. Each product fires
one terminal completion event when its stage finishes, best-effort over a
webhook (with a same-host COMPLETED.json sentinel as fallback). CFactory dedups
them idempotently and threads them into a single WorkItem view.
(same-host fallback)" .-> COL subgraph CF["CFactory control tower · :3110 / :3111"] direction TB COL["Completion-event collector"] IDEM["Idempotent dedup
(service, correlation_key, status)"] STORE["WorkItem store
keyed by correlation key"] COCKPIT["Cockpit + advise-and-confirm copilot"] COL --> IDEM --> STORE --> COCKPIT end classDef tower fill:#1d2b3a,stroke:#5aa9e6,stroke-width:2px,color:#cde4ff; class CF tower; 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; class PF pf; class AF af; class TF tf;
Events are idempotent by (service, correlation_key, status) and consumers
must ignore unknown fields, so adding a new product — or a new field — never forces
a breaking change. See RFC-0001.
A successful terminal event must also carry evidence that the stage really ran — issues created (plan), non-zero tokens and completed phases (build), a non-null verdict and executed tests (verify). Consumers treat a “passed” without satisfying evidence as unproven, never green. This rule is implemented across all three producers; see RFC-0001a — completion-event evidence gates.
The correlation key — the thread through everything
The connective tissue is a single correlation key: the GitHub issue number of
the governed work item, threaded end to end. Before an issue exists, services emit
a stable synthetic key (pf-…, af-…, tf-…) and reconcile to the real number
once assigned.
session_id"] --> B["GitHub
issue #"] B --> C["aifactory
task_id"] C --> D["branch /
PR #"] D --> E["tfactory
spec_id"] classDef key fill:#2a2a1a,stroke:#fabd2f,color:#fdf3c5; class B key; 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; class A pf; class C af; class E tf;
That one key is what lets CFactory show — and steer — plan → code → branch/PR →
tests from a single place. It is also what lets the cockpit draw a live
execution diagram per unit of work: each producer exposes its subtask graph and
timing on a shared graph field of /api/workitems/{key}/process, and the
task-detail view animates whichever stage is furthest along (test → code → plan).
See the live execution diagrams design.
Canonical local port map
Fixed, non-overlapping ports let all four products run side by side and let CFactory reach them all.
| Product | Backend port(s) | Stage |
|---|---|---|
| AIFactory | 3101 |
Act |
| TFactory | 3103 |
Verify |
| CFactory | 3110 (API) / 3111 (stream) |
Cockpit |
| PFactory | 3114 (API) / 3115 (frontend) |
Plan |
Going deeper
- RFC-0001 — correlation key & completion event
- RFC-0002 — Factory Task Contract v2
- RFC-0005 — environment manifest & toolchain provisioning
- RFC-0006 — verification assurance levels & honest reporting
- RFC-0007 — access discovery & authenticated-test provisioning
- RFC-0010 — code-aware planning over existing repositories
- How they cooperate · Run locally · Roadmap