Two approaches to writing code with AI
Two skill suites to build software with AI from opposite starting assumptions: one accelerates a human sprint, the other rebuilds the pipeline around what agents are good at.
Two suites, two assumptions #
delivery-team— AI acceleration of a traditional human sprint. A linear, gated pipeline that mirrors a traditional Notion-based sprint process. Each stage maps to a process stage; each agent maps to a job title. AI makes every seat faster, but the shape is the sprint.flow— an AI-first approach to building. The spec is the source of truth and code is regenerated output. An orchestrator dynamically dispatches parallel generators, a multi-objective evaluator scores them on a Pareto front, and the effort converges rather than ending on a calendar date.
The contrast in one line #
| Axis | delivery-team | flow |
|---|---|---|
| Mental model | Human sprint, AI in every seat | Population search over a spec |
| Unit of work | Story (prose) | GWT scenario (SCN) → derived EARS (SR) → variants |
| Agents | Fixed roles = job titles | Dynamic count = f(complexity) |
| Progress | Linear stages + gates | Generations until convergence |
| Quality | Single-threshold gate | Multi-objective Pareto front |
| Code | The artifact | Regenerated output of the spec |
| Disagreement | Resolved at a gate | Preserved with reactivation conditions |
| Cadence | Time-boxed sprint | Continuous flow |
delivery-team — AI-accelerated human sprint #
A sequential, gated pipeline. One path forward, fixed agent roles, single-threshold gates, and a human go/no-go at every transition.
flowchart TD
subgraph DT["delivery-team — AI acceleration of a human sprint"]
direction TB
S1["Stage 1
Problem Brief
(user-researcher)"]
S2["Stage 2
Design Intent
(product-designer)"]
S3["Stage 3
Technical Spec
stories + EARS ACs
(architect → scrum-master)"]
S4["Stage 4
Build — story by story
(frontend / backend / middleware devs)"]
S45["Stage 4.5
Release Planning
(release-scorer)"]
S5["Stage 5
Cross-Functional Readiness
(gtm / marketing / cx)"]
S6["Stage 6
Release — ring 0→3
(release-communicator)"]
S7["Stage 7
T+2 Fast-Follow
retro + close"]
S1 -->|"Gate 1→2"| S2
S2 -->|"Gate 2→3"| S3
S3 -->|"Gate 3→4"| S4
S4 -->|"Gate 4→4.5"| S45
S45 -->|"Gate 4.5→5"| S5
S5 -->|"Gate 5→6"| S6
S6 -->|"Gate 6→7"| S7
end
H["Human HITL
go / no-go at every gate"]
H -.approves.-> S1
H -.approves.-> S3
H -.approves.-> S5
H -.approves.-> S6
QA["QA gate per story
single threshold:
zero blocking failures"]
S4 --- QA
classDef stage fill:#e8f0fe,stroke:#4285f4,color:#1a1a1a;
classDef human fill:#fff4e5,stroke:#f59e0b,color:#1a1a1a;
class S1,S2,S3,S4,S45,S5,S6,S7 stage;
class H,QA human;
One path forward, gated stage-by-stage, with a human approving each transition.
Characteristics: one path forward · fixed agent roles (= human job titles) · time-boxed sprint · single-threshold gates · code is the artifact · stories in prose · humans gate each transition.
flow — AI-first generate-and-converge #
No sprint. The spec (GWT scenarios → derived EARS, executable, versioned) is the source of truth; code is regenerated output. The orchestrator dispatches N parallel generators where N is a function of complexity, not roles. Each writes only to its own variant directory (P1: intelligence parallel, writes serial). A multi-objective evaluator scores variants on a Pareto front; the effort converges rather than ending on a date.
flowchart TD
SPEC["spec.md + constitution.md
GWT scenarios (SCN) → derived EARS (SR)
executable, versioned
source of truth — code is regenerated"]
EVAL["evals/ — multi-objective suite
correctness · perf · maintainability
a11y · security · cost
(versioned, with adversarial holdouts)"]
SPEC --> ORCH
ORCH["flow-orchestrator
dynamic dispatch
N = f(complexity), not fixed roles
(P1: writes serialize here)"]
subgraph GEN["Generation N — intelligence parallel, writes serial"]
direction LR
V1["generator
bias: simplicity"]
V2["generator
bias: performance"]
V3["generator
bias: …"]
end
ORCH ==>|"spawn parallel variants
each writes ONLY its own dir"| GEN
CULL["flow-cull
score vs evals
Pareto front survives
metastable = ship candidate"]
EVAL -.feeds.-> CULL
GEN --> CULL
CHAV["flow-chavruta
stability vs velocity reviewers
exit at documented dissent,
not consensus → dissents-active.yaml"]
CULL --> CHAV
CONV{"flow-converge
inter-variant similarity
above threshold?"}
CHAV --> CONV
CONV -->|"no — reheat / new generation"| ORCH
CONV -->|"yes — promote 1 survivor"| SHIP["flow-ship
progressive rollout via flags
comms derived from spec delta
post-ship eval monitoring"]
MON["flow-dissent-monitor
watches commits for
reactivation triggers"]
SHIP -.monitored.-> MON
MON -.reactivated dissent.-> ORCH
classDef truth fill:#e6f4ea,stroke:#34a853,color:#1a1a1a;
classDef agent fill:#f3e8fd,stroke:#a142f4,color:#1a1a1a;
classDef gen fill:#fce8e6,stroke:#ea4335,color:#1a1a1a;
classDef decision fill:#fff4e5,stroke:#f59e0b,color:#1a1a1a;
class SPEC,EVAL truth;
class ORCH,CULL,CHAV,SHIP,MON agent;
class V1,V2,V3 gen;
class CONV decision;
A spec-driven generate → score → converge loop; no calendar, no fixed roles.
Characteristics: spec → regenerated code · dynamic agent count (function-shaped, not role-shaped) · parallel reads/generation, serialized writes · multi-objective Pareto evaluation (no single gate) · continuous flow to convergence (no time box) · preserved dissent with reactivation, not forced consensus.
GWT → EARS layered spec #
Status: implemented & merged.
flow's entry unit of work is a Given/When/Then behavioral scenario (SCN-{NNN}) that derives the EARS requirements (SR-{NNN}) — so the spec is user/product-focused first rather than engineering-spec-first. Seeflow/context/flow-spec-protocol.mdandflow/context/flow-philosophy.md(P3).
Previously flow-spec-writer converted natural language straight to EARS (The {system} shall…), a system-centric grammar. Leading with GWT keeps observable user behavior primary and defers system decomposition. It also pays off twice: a GWT scenario is already a graded example, so the scenarios double as flow's eval datasets (P4).
The layered spec — scenarios first, requirements derived
- Behavioral layer (primary): GWT scenarios.
Given <context>, When <event>, Then <observable outcome>.Authored from the actor's perspective. This is what the human reviews and whatflow-narratorderives comms from. - Normative layer (derived): EARS requirements. Each scenario expands into the
SR-{NNN}requirements that must hold for it to pass. EARS stays load-bearing and parseable — it just sits downstream of behavior. - Conformance layer: graders + datasets. GWT scenarios seed
evals/datasets/directly; EARS requirements still map to graders viaevals/harness.yaml.
Why keep EARS, not go pure GWT. The very dimensions on flow's Pareto front — security, perf, cost — are often not user-observable events, so they don't fit Given/When/Then cleanly. EARS's ubiquitous/state-driven forms cover the ambient requirements GWT can't. Use quality-attribute scenarios for the few non-functional cases that do warrant a scenario, and let EARS carry the rest.
Traceability: SCN-{NNN} (scenario) → SR-{NNN} (requirement) → grader + dataset. This preserves the existing conformance-mapping discipline while adding a product-first front door.
Implemented across 12 files: the spec protocol and P3 philosophy (behavioral layer + SCN/SR model), flow-spec-writer and the /flow-spec command (scenario-first authoring, --requirement fast-path for non-functional SRs), the eval protocol and /flow-eval (scenarios seed correctness datasets), flow-generator / /flow-generate (variants implement SCN + SR), flow-orchestrator, flow-narrator (comms led by SCN), /flow-init (scenario-first initial spec), and the README + USAGE docs.