How PFactory plans — and why you can trust the plan

This page is deliberately transparent. It explains exactly how PFactory turns a spec into an execution and test plan, every choice it makes, and the checks it runs to prove the plan is buildable and testable before any code is written. Nothing here is aspirational — each step maps to a named module and a named gate you can inspect.

The short version: PFactory does not “decide by vibes.” It decomposes deterministically, maps every acceptance criterion to work, derives the test lanes and toolchain from the plan, and then submits the plan to a hard readiness gate of explicit, named checks. A plan that is missing information cannot be emitted just because it scored well on a review — a blocking check has teeth, and overriding it requires a recorded, audited human waiver.

1. The planning pipeline

flowchart TD
    S[Spec / issue / document] --> N[Normalize<br/>plan.models.NormalizedPlan]
    N --> R[Recon: static read-only RepoMap<br/>change_mode + IaC inventory<br/>RFC-0010]
    R --> AC[Extract acceptance criteria<br/>C1..Cn, mapped to real files]
    AC --> D{LLM decomposer available?}
    D -- yes --> L[decompose_with_llm<br/>one feature child per criterion]
    D -- no / on any error --> H[heuristic_decompose<br/>deterministic: one child per criterion]
    L -. fallback on parse/timeout .-> H
    H --> EP[Dependency layers<br/>phases ordered by deps]
    L --> EP
    EP --> EM[Emit contract blocks]
    EM --> E1[execution profile<br/>cost-aware model routing RFC-0014]
    EM --> E2[tfactory lanes + frameworks<br/>unit / api / browser / integration]
    EM --> E3[environment manifest<br/>toolchain + nix provisioning]
    EM --> E4[access block<br/>RFC-0007 auth requirements]
    EM --> E5[deployment block<br/>RFC-0013, derived from recon]
    E1 & E2 & E3 & E4 & E5 --> G[Readiness + review gate<br/>incl. adversarial Red Team lens RFC-0015]
    G --> V{Ready?}
    V -- hard fail --> W[Block emission<br/>require audited human waiver]
    V -- ready / advisory only --> SIGN[Sign contract HMAC + emit]
    SIGN --> HO[Hand over to AIFactory]

What is deterministic vs model-driven (stated plainly):

2. How the test lanes and toolchain are chosen

Lane selection is a transparent, inspectable derivation in plan/emit/tfactory_block.py — not a black box:

The environment manifest (plan/emit/environment_block.py) is then derived from those lanes: a browser lane adds chromium and a Playwright verify command and sets the network posture; the toolchain language follows the unit framework. This manifest is the single source of truth the build (AIFactory) and verify (TFactory) sides both turn into the same flake.nix — see the hub guide “Reproducible test environments”.

3. The trust gate — how we verify we have everything to code and test

Before a contract is emitted, the plan passes through two orthogonal layers (plan/review/gates.py):

  1. A scored multi-lens review (architecture, security, feasibility, testing, cicd; code lenses apply only to software plans) plus a deterministic rules engine and external policy (OPA / Checkov) for secrets, public exposure, missing resource limits, rollback, and feasibility (cost/effort/access).
  2. A hard readiness/completeness report (plan/review/readiness/checks.py) that is independent of the review score. The critical property: a high aggregate score cannot mask a missing-information blocker.
flowchart TD
    P[Plan + epic] --> R[Scored lenses + rules + OPA/Checkov]
    P --> RC[Readiness checks]
    R --> BF[Blocking findings<br/>e.g. plaintext secret]
    BF --> RC
    RC --> C1[children-present]
    RC --> C2[criteria-present]
    RC --> C3[ac-child-coverage<br/>lists every UNCOVERED criterion]
    RC --> C4[deps-sound]
    RC --> C5[access-granted / access-verified]
    RC --> C6[enrichment-integrity]
    RC --> C7[no-blocking-findings<br/>never waivable]
    RC --> C8[decompose-trustworthy<br/>flags LLM fallback]
    RC --> C9[ac-testable advisory]
    C1 & C2 & C3 & C4 & C5 & C6 & C7 & C8 --> H{Any HARD fail?}
    C9 -. advisory: informs, never blocks .-> RPT[Readiness report]
    H -- yes --> WV{Audited human waiver recorded?}
    WV -- no --> STOP[HALT: do not emit]
    WV -- yes --> RPT
    H -- no --> RPT
    RPT --> OUT[is_ready -> emit signed contract]

Every check returns a structured, human-readable line: check_id, title, pass/fail, severity, detail, remediation, and evidence. That is the transparency contract — you can read precisely why a plan was or was not considered ready. Examples:

A blocking fail is overridden only by a waiver (plan/review/readiness/waiver.py): a deliberate, audited override bound to the plan’s hash (so it cannot silently carry over to an edited plan). The emitted contract is HMAC-signed, so AIFactory and TFactory can verify it is the exact plan that passed the gate.

4. Why this is trustworthy (the honest version)

Known limitations we do not paper over:

4.5 Cost is a running figure, not a terminal one

A plan session runs a real LLM pipeline — detect, decompose, synthesize, and the governance gates above — and most of that cost is spent before a human ever approves anything. A plan can sit at processed awaiting approval, or be abandoned, and still have cost real money to produce.

So PFactory reports cost as it accrues, not only on a terminal outcome. The moment a session reaches processed (post-pipeline, awaiting approval), it emits a non-terminal usage snapshotplan.completion.emit_usage_snapshot, carried on the same signed completion envelope as the terminal events, with the session’s current status and accrued token usage. CFactory records usage from any event that carries it, so the cockpit shows the planning-and-gate cost of a plan regardless of whether it is later approved, rejected, or simply left parked. This mirrors AIFactory’s running-cost emit on the build side, so the same plan’s cost reads consistently across the fleet.

The honest line on figures: a money number only appears for metered billing modes (API / managed cloud). On a subscription or a local model the snapshot reports tokens and wall-clock, not a notional dollar amount — because inventing a price for a flat-rate plan would be a worse answer than the truth.

5. What teams do

  1. Write specs with clear, testable acceptance criteria (one measurable statement per line reads best; ac-testable will nudge you on vague ones).
  2. Read the readiness report. If a hard check fails, fix the spec — do not reach for a waiver unless the override is a genuine, owned decision (it is audited).
  3. For UI behaviour, describe it concretely (titles, headings, button actions) so the browser lane is selected and the environment manifest carries a browser toolchain.

See also: the fleet guide “Reproducible test environments” (how the manifest becomes a Nix flake and runs in an ephemeral Job), and RFC-0002 (the Task Contract).