The software factory

Every station is an existing platform behind an adapter. Agents do the work; people decide at two points, intent and release. What runs comes back as new work along the blue line.

01

Intake 4

mail, calls, feedback, requests

i-20261030-05 · ops
factory-sample test is down
i-20261030-06 · ops
factory-sample stg is down
i-20261030-07 · ops
factory-sample prod is down
i-20261030-08 · files
A wishlist on the product pages
02

Shape 0

spec and frozen acceptance tests

human: intent 03

Build 1

agent on its own branch

t-0002
Truncate long order titles
gate:red PR #2 red-team
0s of 5m
04

Verify 0

gate, browser tests, evidence

05

Preview 0

own URL per change

06

Show 0

demo, click, annotate

human: release 07

Release 0

test, then stg and prod by PR

08

Operate 3

health, usage, cost

t-0001
Readable URL slugs for order pages
gate:auto verify passed PR #1 claude
16s of 20m · $0.18
t-0003
A page per product with a readable URL
gate:auto verify passed PR #3 claude
25s of 20m · $0.20
t-0004
Initials for customer badges
gate:auto verify passed PR #4 herdr
19s of 15m
feedback loop: customers, alerts, schedules, outcomes

Shared context · specs, frozen acceptance tests, evidence and decisions live in git. Every agent reads it; every loop grows it.

Cost meter

1m 0s · $0.38

agent time and model cost over 4 tickets · 0 over budget

A ticket at its budget stops and goes back to shape. Hosting, gateway spend and review minutes join as their adapters go live.

Environments

test
healthy
live sha-4019d27 · pinned at snapshot sha-25ecdc4
https://factory-sample-test.mj.mijp.nl
stg
healthy
live sha-cb12c5e · pinned at snapshot sha-cb12c5e
https://factory-sample-stg.mj.mijp.nl
prod
healthy
live sha-436a003 · pinned at snapshot sha-436a003
https://factory-sample.mj.mijp.nl

Platforms behind the stations

#StationPlatformAdapterDirectionStatus
1IntakeFasterFixes feedback widgetfasterfixes: GET /api/v1/agent/feedbacks?project=&status=new → intake/<id>.md, key ff:<id>readfake
1IntakeParaaf annotations on a published pageparaaf: GET /api/paraaf/annotaties?slug=&ongeharvest=1 → intake, key paraaf:<id>readfake
1IntakeOffer requests, mail, call transcriptsfiles: markdown or JSON files dropped in a directory (the offer inbox, gog gmail search … -j output, transcribe-skill output) → intake, key file:<sha>readlive
1IntakeOperate signalsoperate.Plan: env down, over budget, success due, errors, usagereadlive (env, budget, success)
2ShapeOpenSpec + blueprintfactory shape writes a ticket with spec, frozen acceptance, scope, risk, budget, success; OpenSpec changes for behaviour in the target repoownlive
3BuildPaperclip agents (primary)runner paperclip: issue in a project with a git workspace, assignee agent, branch runner/<id>, cost-summary for costwrite (own repo)fake
3Buildherdr, smithy, Claude Code CLIrunners herdr, smithy, claude, scriptwrite (own repo)live (claude, herdr, script)
4TestGitHub Actionsfactory-verify.yml: the gate, judged with the base commit's factoryownlive
4TestPlaywrighte2e/: browser tests against a URL (BASE_URL), screenshots as evidence, after a preview or a test releasereadlive
5PreviewAppHaven preview/*apphaven: push preview/<id>, read apphaven status <app> --json for the URLwrite (own repo)fake
5PreviewCluster fallbackthe preview-mj ResourceSet: image pr-<n>-<sha7> for PRs labelled previewownlive
6ShowFeedback widget in the previewthe sample app loads the FasterFixes widget when FF_PROJECT_ID and FF_WIDGET_SRC are set; feedback comes back through station 1readfake
6ShowParaaf portalparaaf show: a demo page as a draft (markdown in the PR), published to Paraaf by a humandraftplanned
6ShowGitHub PR + boardevidence, gate, preview URL and success measure on the PR and on the boardownlive (PR)
7ReleaseFlux from ./deploypins per environment, factory promoteownlive
8Operateplatform API (platform CLI)platform: urls per app → url-dead:<host>, usage → hosting costreadlive
8OperateTraceway (OpenTelemetry)traceway: traceway exceptions list -o json --project → errors:<app> signalreadfake
8OperateUmamiumami: GET /api/websites/{id}/stats → unused:<app>:<week> when a week stays under the thresholdreadfake
8CostLiteLLM gatewaylitellm: spend per tag ticket:<id>readlive (no tagged calls yet)
8CostPaperclipcost-summary per issue (from the runner)readfake
8CostMoneyMonkfactory hours: hours per ticket as a CSV draft for manual entry (MoneyMonk has no public API)draftlive