Skip to content
bflo.sh

The map — Contract-First Agentic Delivery, drawn

The story of this site's delivery model in four diagrams: the ten-step Internals tour and its components, one feature's journey from Confirm to committed, and the engine room twice — scripted by the Workflow engine, then run as an agent team.

Adapted from the repo's docs/map.md — the design set's visual map, published as a case study. The full written story lives under Internals.

The story that Internals tells page by page — the Story Mode tour contract-first-delivery (ADR-0018), ten steps from the agent team to the machinery — captured in four diagrams. The flowchart is the map: the tour's path and the key components it walks past. The second is the plot: one feature's journey through the delivery model, beat by beat. The third and fourth are the plot, extended: the same journey seen from the engine room — how agents are spawned, what each one is told, and who talks to whom — first run on the Workflow engine (a deterministic script, the task DAG known up front), then as an agent team (named teammates coordinating by message, for work whose shape emerges as it goes). Companion reading: how-it-works (the machinery in detail), master-blueprint (the design of record), and orchestration (the playbook both engine-room diagrams draw).

The map — ten steps, four components

The tour's spine runs top to bottom; dotted edges point at the component each step reveals. The step titles are the story's key phrases.

flowchart TB
    subgraph TOUR ["The story — tour: contract-first-delivery"]
        direction TB
        S1(["1 · Internals — a site that explains itself"])
        S2(["2 · Overview — one repo, one boundary"])
        S3(["3 · Constitution — rules that bend for nobody"])
        S4(["4 · The agent team — six agents, one lead"])
        S5(["5 · Orchestration — phases open on the user's word"])
        S6(["6 · Rules of engagement — the spec never chases the code"])
        S7(["7 · The application — the application itself"])
        S8(["8 · Master blueprint — files, not forms"])
        S9(["9 · How it works — save, live in under 90 s"])
        S10(["10 · Decisions — every why, on record"])
        S1 --> S2 --> S3 --> S4 --> S5 --> S6 --> S7 --> S8 --> S9 --> S10
    end

    subgraph REPO ["The repo — four tiers, one bridge"]
        FE["frontend/"] -->|consumes| CT{{"contract/ — OpenAPI · AsyncAPI · Spectral"}}
        BE["backend/ — Http to Domain to Data"] -->|conforms to| CT
        INF["infra/ — DDEV topology, CI"] -. supports .-> FE
        INF -. supports .-> BE
    end

    subgraph TEAM ["The team — six agents, one lead"]
        YOU(("you")) -->|"confirms each phase"| LEAD["lead — orchestrates, verifies, never pushes"]
        LEAD --> CO["contract-owner"]
        LEAD --> DME["domain-engineer"]
        LEAD --> DTE["data-engineer"]
        LEAD --> BAE["backend-api"]
        LEAD --> FEE["frontend-engineer"]
        LEAD --> PLE["platform-engineer"]
        CO -->|"publishes versions of"| CT
    end

    subgraph LOOP ["The loop — save, live in under 90 s"]
        FILE[("content/*.md — the filesystem is the CMS")]
        FILE --> TICK["reindex tick — every minute"]
        TICK --> EVS["content.* events"]
        EVS --> HOOK["signed webhook"]
        HOOK --> TAGS["revalidateTag"]
        TAGS --> PAGE["the page you are reading"]
    end

    ADR[("ADRs 0001–0018 — every why, on record")]

    S2 -.-> REPO
    S4 -.-> TEAM
    S6 -.-> CT
    S9 -.-> LOOP
    S10 -.-> ADR
    CO -.->|"records decisions as"| ADR

Reading the map: steps 1–3 set the premise (the site, the repo, the constitution); steps 4–6 are the team and its rules — the contract in the middle is the only place two tiers ever meet, and it is versioned before anyone implements; steps 7–9 are the product — files in, pages out, freshness by webhook rather than deploys; step 10 is the ledger that keeps the whole thing honest.

The plot — one feature, beat by beat

How a feature actually travels through the model above. Every named rule in the story appears here as an action.

sequenceDiagram
    actor You
    participant Lead as lead
    participant CO as contract-owner
    participant Members as members (backend · frontend · platform)
    participant Contract as contract/
    participant Site as bflo.sh

    You->>Lead: request a feature
    Lead->>Lead: decompose by ownership, draft the phase task list
    Lead->>You: present the list — the phase gate
    You-->>Lead: Confirm
    Note over Lead: phases open on the user's word
    Lead->>CO: contract task (Workflow, per-task model and effort)
    CO->>Contract: design, version, lint, publish vX.Y.Z
    Note over CO,Contract: the spec never chases the code
    Lead->>Members: implement against vX.Y.Z, in parallel
    Members-->>Lead: faithful reports — green and red alike
    Lead->>Site: verify over real HTTP, never trust a mocked green
    Lead->>You: hand off for the browser pass
    Note over You: UI feel needs your eyes
    You-->>Lead: approve, then ask for the commit
    Lead->>Contract: commit on explicit request — never push
    CO->>Contract: the decision lands as an ADR
    Note over Contract: every why, on record
    You->>Site: later — save a content file
    Site-->>You: live in under 90 s, no deploys

The plot, extended — how the agents are spun (Workflow engine)

The middle beats of the plot ("implement against vX.Y.Z, in parallel") hide a whole machine. This is that machine in its deterministic mode — the Workflow engine, used when the task DAG is known up front — drawn from orchestration and a real delivery (Story Mode itself ran exactly this shape). The things to notice: every member is spawned as a fresh context — its task prompt carries the interface summary, its ownership walls, and the ground rules, because it remembers nothing else; the contract gate blocks every other lane until a version is published; reports are the only channel back — and when a member hits another owner's wall, the boundary becomes a routed task to the owning member, never a cross-edit.

sequenceDiagram
    actor You
    participant Lead as lead
    participant WF as Workflow engine
    participant CO as contract-owner
    participant DOM as domain-engineer
    participant DATA as data-engineer
    participant API as backend-api
    participant FE as frontend-engineer

    You-->>Lead: Confirm — the phase gate opens
    Lead->>WF: encode the task DAG as a script
    Note over Lead,WF: agentType, model, and effort chosen per task —<br/>mechanical work on smaller models, verification at higher effort

    WF->>+CO: spawn — fresh context: task, ownership walls, ground rules
    CO->>CO: design, version, lint
    CO-->>-WF: vX.Y.Z + interface summary for implementers
    Note over WF,CO: the contract gate — no other lane starts before this returns

    par backend chain — sequential, each spawn fed the previous report
        WF->>+DOM: spawn with the interface summary
        DOM-->>-WF: report: ports defined, expected downstream gap named honestly
        WF->>+DATA: spawn with domain's report
        DATA->>DATA: migrate, index, implement the port
        DATA-->>-WF: report + boundary hits: "route these one-liners to their owners"
        WF->>+API: spawn with both reports
        API-->>-WF: report: endpoint live over real HTTP, remaining reds named with owners
    and frontend lane — concurrent from the moment the gate lifted
        WF->>+FE: spawn with the interface summary
        FE->>FE: build against the contract shape, fixtures standing in for the unbuilt API
        FE-->>-WF: report incl. a blocker outside its walls — flagged, not "fixed" out of lane
    end

    WF-->>Lead: every report, verbatim

    Note over Lead,API: boundary hits become routed tasks to the owning member —<br/>spawned by name, continued via message, never respawned blind
    par routed follow-ups — surgical, small models for one-liners
        Lead->>DOM: one-line fix in your file (exact location, exact intent)
        DOM-->>Lead: diff + real test output
    and
        Lead->>DATA: extend your test's expected keys
        DATA-->>Lead: diff + real test output
    and
        Lead->>API: rate-limit carve-out in your routes
        API-->>Lead: diff + live rate-limit headers as proof
    end

    Lead->>Lead: integrate — full tier verifies + real-HTTP probes
    Lead->>You: outcome report — the browser pass is yours

The plot, extended again — the same engine room, run as a team

The Workflow engine fits a DAG you can script in advance. When the shape emerges as it goes — a feature negotiated between a producer and a consumer — the same rules run in conversational mode: teammates are spawned by name and continued by message (same memory, no respawn), work hangs on a task board whose dependencies encode tier order, and every cross-tier need travels as a message through contract-owner. Two hard-won lessons are drawn in deliberately: an ACK is not a start (each task needs its own explicit go-signal), and parallel members near adjacent files take worktree isolation.

sequenceDiagram
    actor You
    participant Lead as lead
    participant Tasks as task board
    participant CO as contract-owner
    participant BE as backend-api
    participant FE as frontend-engineer

    You->>Lead: a feature whose shape will emerge as it goes
    Note over Lead: no DAG to script up front — this runs as an agent team,<br/>not the Workflow engine
    Lead->>Tasks: TaskCreate, one task per member-sized unit —<br/>dependencies encode tier order, contract blocks implementation
    Lead->>+CO: spawn by name — a teammate, not a one-shot
    Lead->>+BE: spawn by name
    Lead->>+FE: spawn by name
    Note over CO,FE: fresh context once — afterwards continued via SendMessage,<br/>same memory, never respawned blind

    BE-->>Lead: ACK … then idles
    Note over Lead,BE: lesson, learned the hard way — an ACK is not a start:<br/>each task gets its own explicit go-signal
    Lead->>BE: go on the producer task

    FE->>CO: message — I need a field the contract does not publish
    Note over FE,CO: cross-tier needs travel as messages through contract-owner,<br/>never as edits to another member's files
    CO->>CO: judge — interface change, or implementation detail?
    CO->>Tasks: version the contract, route producer and consumer tasks
    CO-->>BE: message — vX.Y+1 published, implement the field
    CO-->>FE: message — consume vX.Y+1 once the producer reports green
    BE->>BE: implement in a worktree — parallel members, adjacent files
    BE-->>Lead: idle notification — task done, faithful report attached
    Lead->>FE: go — your dependency is met
    FE-->>Lead: report — consumed, verified in my lane

    Lead->>Lead: integrate — full tier verifies, real-HTTP probes
    Lead->>CO: stand down, close out
    CO-->>-Lead: final report
    Lead->>BE: stand down
    BE-->>-Lead: closed
    Lead->>FE: stand down
    FE-->>-Lead: closed
    Lead->>You: outcome report — the browser pass is yours

The four diagrams are deliberately the same story at three zoom levels: the map shows where everything lives, the plot shows when everything happens, and the two extended plots show who is told what, and who answers to whom — once as a scripted machine, once as a conversation. If they ever disagree with the code, the code is wrong or this file gets updated — same rule as every document in this set.