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

Shipped this week, and what a shipped change cost, are counted not sampled #106

shipped production is serving it opened this has it
opened this

Shipped and the cost per shipped change sit beside Runs and Spent, and they are sampled the same way.

studioApp (src/web/studio/app.ts:101-104) counts them as listPulls(db, repo.id, { state: "closed", limit: 100 }).filter(p => p.mergedAt !== null && p.mergedAt >= week).length. Past a hundred closed pulls — merged or abandoned, they share the page — the week's shipping under-reports, and the per-change cost that divides spend by it reads high with nothing saying why.

This is the second of the four issues #91 was split into. It waits on the runs aggregate so the two land in one panel without fighting over the same lines.

Acceptance

  • [ ] A new aggregate in src/core/pulls.ts — one query — counts pulls of one repository with merged_at at or after a given ISO instant.
  • [ ] studioApp uses it for Shipped and for the cost of a shipped change; the limit: 100 scan is gone from that path.
  • [ ] A test seeds 150 closed pulls inside the window, plus a closed-unmerged one and a merged one older than the window, and asserts Shipped counts exactly the 150 — it fails on today's code.
  • [ ] bun test green.

Files I expect to change

src/core/pulls.ts, src/web/studio/app.ts, test/studio.test.ts.

Risks

Closed is not shipped: a pull closed without a merge has no merged_at and must not be counted. Cost per shipped change divides by a count that can be zero — keep whatever the page does today for that case, and let a test hold it.

Suggested: Mason.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs