CI Factory: one app instead of two pages

The plan to replace /a/ci-factory and /a/ci-factory-floor with one clean app at factory.propflowai.co: what it answers, how it's built, and the order we ship it.

Plan · Oct 6, 2026 · Gera's CI session · nothing built yet · built by a Fable driver once approved

One app, three questions, four screens. Today two pages show about 30 panels, each on its own snapshot and its own time window. The app answers three questions instead, over any time range you pick: Is CI healthy right now? Is it getting better or worse? What should we fix next, and what is it costing us?

Detail

Why change: what's wrong today
The four screens (and what's on each)
ScreenAnswersOn itComes from today
Now (home)What's happening this minute?The floor: PRs moving through stations, the queue line, the deploy countdown, an alert bar (main red, the culprit just kicked out, cheap machines being lost)The floor engine, deploy card, culprit line
HealthBetter or worse?The 5 scorecard measures plus opened→live, each with target and trend; the queue pass-rate chart split into "PR's own fault" and "knock-on"Scorecard, flow strip, pass-rate chart
RedsWhat should we fix next?Red causes ranked by cost: still happening vs fixed, times it happened, runs taken down, ≈$, PR-hours; the flaky-test list"Why it went red", reds chart, flaky table
CostWhat does CI cost, and where is the waste?Machine $ per day, waste from red runs, review-bot spend, AWS breakdownSpend section, machine bays, cost tile

On every screen: one time-range picker (24h · 48h · 7d · 30d · all) that applies everywhere; PR search; every number has a hover that says exactly what it counts and links to the raw runs.

Click-through pages: a PR (its trip through each station, every queue run, why it was kicked out, time lost), a test (every failure, own vs knock-on, first and last seen, whether it's fixed), a run (jobs, the failing step, the log link).

Backend: one store of events, not six snapshots
Frontend
Order of work (each step ships on its own)
  1. Data: D1 schema, the collector writing events, the backfill. Check: totals match today's pages for the same 24 h.
  2. Reds screen + time-range picker, with the own vs knock-on split. First visible win, about 1–2 days in.
  3. Health screen: scorecard and trends over any range.
  4. Now screen: the floor moves over and becomes the home page.
  5. Cost screen + click-through pages.
  6. Retire the old pages: both URLs point to the app.

Each step is small PRs off main, reviewed, measured. Claimed in the engineering bridge first so CICD reviews instead of building in parallel.

Design: how it looks and stays calm

Five rules that keep it from overwhelming:

  1. Every screen opens with one sentence, the verdict. For example, "Queue 78% green today, up from 68% yesterday. Biggest cost: staff-desk test, 6 PRs kicked out, ≈$4, 3 PR-hours." Read that and stop, or scroll for why.
  2. At most six numbers above the fold. Each one shows its target and its change since the previous period (▲ 4 pts). Everything else is one click away, in a side drawer rather than another panel.
  3. One clock. The time range in the top bar drives every chart and table, and each is compared with the period before it.
  4. Noise is grey and folded by default. Knock-on failures and lost machines appear as grey or striped segments, apart from real red. "Probably fixed" causes are collapsed.
  5. Every number explains itself. A hover says what it counts, and a click shows the exact runs or PRs behind it.

Navigation: a slim left rail (bottom tabs on a phone): Now · Health · Reds · Cost. Top bar: time range (24h · 48h · 7d · 30d · All · custom), PR search (type #17039), a live status pill (main green/red · queue depth · next deploy in 12 min), theme.

Charts, one kind per job:

┌ Factory ───────────────────────────────── [24h|48h|7d|30d|All]  #____  ● main green · queue 9 · deploy 12m ┐
│ Now     │ HEALTH  Queue 78% green today, ▲10 pts. Opened→live 2.6 h, ▼0.2 h. 3 of 6 targets met.          │
│ Health ◀│ ┌Queue green┐┌Main green┐┌Fix main┐┌Wasted/PR┐┌Merged 1st┐┌Opened→live┐                      │
│ Reds    │ │ 78% ▲10   ││ 100%     ││ —      ││ 4 runs  ││ 81% ▲6   ││ 2.6h ▼0.2 │  ← target ✓/✗ each     │
│ Cost    │ └~~~~~~~~~~~┘└~~~~~~~~~~┘└~~~~~~~~┘└~~~~~~~~~┘└~~~~~~~~~~┘└~~~~~~~~~~~┘                      │
│         │ Pass rate by hour  ▇▇▅▇▇▇▃▇▇  green=pass red=own amber=knock-on grey=machine  - - 95% target  │
│ ⚙ Targets│ [click a tile → large chart drawer · click a bar → the runs in that hour]                     │
└─────────┴───────────────────────────────────────────────────────────────────────────────────────────────┘

Settings: kept small. Targets per measure, each change dated so history stays honest. Default range. Timezone (Central). Optional Slack alerts (main red > N min, queue green < X% for an hour).

As much data as is useful: every table sorts and filters and exports as CSV, and every chart point drills down to its rows. Depth lives behind clicks, never on the first screen.

Effort log: who tried what, and did it work

Gera: "right now we are kind of battling… I don't know who's doing what." The app gets a fifth screen, Log, plus markers on every chart.

Keep the feel, rebuild from scratch
Decisions (made Oct 6)

Done means: you can answer the three questions in under a minute, for any range, and the old pages are retired.

PropFlow Docs