Public: anyone can read this; the crew can change it.

One pipeline model: stage events, throughput, wait and failure reasons, behind the chart, boards, home and MCP #7562

Closed opened this has it
opened this

Part of the epic #7553. First child: everything else reads this.

Problem

The forge has two stage lists (src/flow/pipeline.ts:20, 8 keys; src/flow/stage.ts:13, 6 keys) that give counts now, but no history: no throughput per stage, no wait-time distribution, no failure reasons, and nothing for "released" or "verified live". The bottleneck chart, boards, home and MCP each compute their own view (src/flow/vitals.ts, src/web/pages/flow-panel.ts, src/http/mcp/tools/flow.ts).

Build

  • One stage list: ready, building, checking, reviewing, gating, landed, released, verified live (map the existing keys onto it; keep old keys as aliases until their readers move).
  • A pipeline_event table (item kind and id, stage, entered_at, left_at, outcome, reason code) written where the transitions already happen (run start/finish, review verdict, queue gate result, merge, release cut, verify result). Reasons are a small fixed list (red functional, red budget, red infra, conflicted, held, changes requested, timeout) so they can be grouped.
  • Reads in a new module (src/pipeline/): per stage, for 1 h / 6 h / 24 h — throughput, WIP, wait p50/p95, failure reasons by count; the bottleneck stage is the one with the longest wait among waiting items (keep today's rule from pipeline.ts:6).
  • GET /api/v1/pipeline and MCP tool pipeline (new files under src/http/ and src/http/mcp/tools/, not in api.ts).
  • The existing bottleneck chart, the forge/boards sources (src/boards/sources.ts) and the home KPIs read it; delete the duplicate math they carry.
  • Backfill from run, review, issue, pull for the last 7 days so charts are not empty on day one.

Done when

  • One stage list exists in code, with aliases for the old keys.
  • /api/v1/pipeline and MCP pipeline return per-stage throughput, WIP, wait p50/p95 and failure reasons for 1/6/24 h; the bottleneck stage named there is the one the chart and the home bottleneck sentence name (same numbers, one reader).
  • A board source pipeline can be queried by a forge/boards JSON board.
  • Tests: test/pipeline-model.test.ts (stage mapping; a pull's whole life writes ordered events), test/pipeline-reasons.test.ts (each reason code produced by its cause), test/pipeline-backfill.test.ts (7-day backfill matches live counts), test/pipeline-one-reader.test.ts (chart, home and MCP agree on a seeded db).
  • New code in its own files; hot files src/http/api.ts and src/web/pages/repo.ts get at most one route-registration line.
  • Overlap: #5930 (alarms) keeps its four alarms and reads this; do not rewrite them here.
commented

duplicate of #7554

commented

The owner, 2026-10-27 22:50Z: "i am interested in observability into the CI pipe. i want to see it still churning when the subscription is off so i can understand clearly what is getting shipped and what the lag is in real terms."

So the pipeline model must answer, in wall-clock terms and with no model running:

  • What shipped: each release, with the pulls in it (title and author), and what's on main but not yet live (count, oldest).
  • The lag per pull, from its timestamps:

- opened → approved - approved → landed (queue wait) - landed → live (release lag) - opened → live (end to end) - Reported as p50/p90 per day.

  • Churn: checks, gates and landings per hour, and the queue depth. A page reading only the database (no agent calls) on /pipeline, phone width, live-updating.
  • When the subscription is out, the page says so ("builders and reviewers paused: subscription limit") and still shows the queue landing and releases going out.

Tests: a fake history of pulls with known timestamps gives the exact p50/p90 for each lag, and the page renders it with no agents configured.

commented

The owner, 22:55Z: "thats also the line between the deterministic autonomy of the forge and the undeterministic generative power of the crew. seeing that clearly is important to me"

The pipeline page draws that line. Every stage is marked either:

  • Engine (deterministic, no model): checks, the merge queue, landing, releases and verification.
  • Crew (generative, needs the subscription): building, reviewing, rebases and triage.

Each side shows its own throughput, and when the subscription is out, the crew side goes visibly idle while the engine side keeps moving. The same split goes on the boards and in MCP pipeline.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs