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

Boards, step 6b: the Releases and Apps starting boards #2473

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

The forge now writes **Releases** and **Apps** starting boards on boot, the same way 6a writes Usage and Crew. `.offered` still records them, so an edit stays and a deletion sticks. Tests and the type check pass.

shipped production is serving it deploy 2fa0c24

opened this

The forge now writes Releases and Apps starting boards on boot, the same way 6a writes Usage and Crew. .offered still records them, so an edit stays and a deletion sticks. Tests and the type check pass.

  • Releases (30 days):

- Deploys per day, split by state. - Deploys by state. - Deploys gone live per day. - Slowest decision per day, in ms. - Decider time per hour, in ms, by kind.

  • Apps (7 days):

- Apps made per day, split by access. - Apps by access. - Wakes and sleeps per app, split by environment. - Wakes per hour. - Requests per hour by surface.

  • New board sources: wakes and sleeps are two views of the meter table, one row per awake interval. A wake is the row's start and a sleep is its end, each timed by its own edge. They read through the repo scope like the other repo sources.
  • Test: the 6a test now expects all four boards on a fresh forge and runs every panel of all of them without error. The README sentence is updated.

What I left out:

  • Time from ask to live: the query layer can only aggregate real columns, so there is no panel for a deploy's serving_at − created_at. I charted deploys going live and the decider's ms from decisions instead. A true ask-to-live panel needs a computed column, which I'd do in a follow-up.
  • Per-app request counts: usage_count has no app column, so Apps shows requests by surface rather than per app.
  • App names: the per-app panels group by repo_id, because app slugs are free text that sources deliberately don't list.

To try it: boot with an admin, open /boards, and you'll see Apps, Crew, Releases and Usage.

Closes #2459

commented

The forge now writes Releases and Apps starting boards on boot, the same way 6a writes Usage and Crew. .offered still records them, so an edit stays and a deletion sticks. Tests and the type check pass.

  • Releases (30 days):

- Deploys per day, split by state. - Deploys by state. - Deploys gone live per day. - Slowest decision per day, in ms. - Decider time per hour, in ms, by kind.

  • Apps (7 days):

- Apps made per day, split by access. - Apps by access. - Wakes and sleeps per app, split by environment. - Wakes per hour. - Requests per hour by surface.

  • New board sources: wakes and sleeps are two views of the meter table, one row per awake interval. A wake is the row's start and a sleep is its end, each timed by its own edge. They read through the repo scope like the other repo sources.
  • Test: the 6a test now expects all four boards on a fresh forge and runs every panel of all of them without error. The README sentence is updated.

What I left out:

  • Time from ask to live: the query layer can only aggregate real columns, so there is no panel for a deploy's serving_at − created_at. I charted deploys going live and the decider's ms from decisions instead. A true ask-to-live panel needs a computed column, which I'd do in a follow-up.
  • Per-app request counts: usage_count has no app column, so Apps shows requests by surface rather than per app.
  • App names: the per-app panels group by repo_id, because app slugs are free text that sources deliberately don't list.

To try it: boot with an admin, open /boards, and you'll see Apps, Crew, Releases and Usage.

Changes requested — before the latest push

The two boards boot and every panel runs, but two things need fixing before this lands.

  1. wakes and sleeps list env as a column, and the Apps board groups its series by it. The header of src/boards/sources.ts says an environment slug is free text and is never listed, because a board that groups by it reads it back out. Environments are named by branch or pull, so this breaks that rule. Drop env from both sources and from the two series. If per-environment counts matter, placement (owned or cloud) is the safe split.
  2. Nothing tests the new sources. The start-of-boot test only proves the panels run without error. Add a test that fails without the change. Seed meter rows, one open and one ended. Assert that a wake counts both rows by started_at, that a sleep counts only the ended row by ended_at, and that the repo scope narrows both. Without it, the where and time edges are unpinned.

Smaller points:

  • The per-app panels show opaque repo_id values to a person, who cannot read them as apps. Say so in the panel title or note it in the README, until a source exposes a safe name.
  • The test header comment has typos: 'the the four starting boards boards'.
  • Neither board has a terminal or MCP door beyond the existing Boards screen, which is fine since they are ordinary boards.
commented

I've addressed all of juniper's points and pushed. The boards tests and the type check pass.

  • env removed: wakes and sleeps no longer list env, so a board can't group by it. The Apps board's per-app panels now split their series by placement (owned or cloud).
  • New test for the sources: test/boards-query.test.ts seeds meter rows, one open and one ended for r1, plus one ended for r2. It checks four things:

- A wake counts both r1 rows by started_at. - A sleep counts only the ended rows, by ended_at. - The repo scope narrows both. - A query using env as a series is refused.

  • Opaque repo ids: the panel titles now read "Wakes per app (by repo id)" and "Sleeps per app (by repo id)". The README says the same, until a source exposes a safe name.
  • Typo: the header comment in test/boards-starting.test.ts is fixed.
Approved — before the latest push

Reads clean against the direction. Releases and Apps are plain starting boards, .offered keeps edits and deletions, and boards stay admin-only on the page, the API, MCP and the terminal, so nothing new opens to guests. wakes and sleeps are two sources over one table with env left unlisted, and the new tests seed meter rows and cover timing by each edge, the repo scope and the refused env series. The starting-boards test runs every panel of all four boards. No dependency was added and the README is updated. I judged this from the diff and the green check. The preview needs an admin session, so I did not open the boards there, and I did not read the screenshots.

Two things I would do next:

  1. Add a computed column or a safe app-name source, so the per-app panels read as names instead of repo ids, and a real time-from-ask-to-live panel becomes possible.
  2. Give the filter serving_at gt "" on the "gone live" panel its own assertion that a deploy with no serving_at is excluded. Today the panel is only proven to run, not to count correctly.
commented

I merged main into the branch, resolved the three conflicts, and pushed. The boards tests (116) and the type check pass.

The conflicts were all in the same place: main added a Security starting board while this branch added Releases and Apps. I kept both, so the forge now writes five starting boards: Usage, Crew, Releases, Apps and Security.

  • README.md: one sentence now covers all five boards. It keeps the Security note (no token text, hash, payload or IP) and the Apps note that per-app panels show repo ids.
  • src/boards/starting.ts: only the header comment conflicted. I updated it to list all five boards.
  • test/boards-starting.test.ts: I merged the header comment and the fresh-boot test, which now expects all five slugs. The panel count sums over every board in STARTING_BOARDS, so it no longer needs updating each time a board is added.

I didn't run the full bun test suite, only the boards tests; the forge runs the whole check on the push.

Approved — before the latest push

Approved from the diff. I could not open the preview or the screenshots from this sandbox (network and file reads denied), so I did not check the rendered boards by eye.

The wakes and sleeps sources read only repo_id, placement and the two times, so env is not exposed. Both go through the owner scope. Their tests would fail without them, and the starting-boards test runs every panel of all five boards. The README and the header comments match the code. No dependency was added, and the boards stay admin-only through the existing doors, including the terminal Boards screen.

Two things I would do next:

  1. Add a safe app-name column to a source, so the per-app panels read as names rather than repo ids. For the zero-technical-client pillar, raw ids are the least plain thing on the Apps board.
  2. Add a computed ask-to-live column (serving_at minus created_at), so Releases can show real time to live instead of the decider ms stand-in.
commented

I merged main into the branch again and pushed. The boards tests (121) and the type check pass. I didn't run the full bun test, only the boards tests; the forge runs the whole check on the push.

This time main had added a Throughput board (items entering each stage, from the stages source). The three files conflicted the same way as before, and I kept both sides' boards, so the forge now writes six starting boards: Usage, Crew, Releases, Apps, Security and Throughput.

  • README.md: one sentence lists all six, keeping the Apps repo-id note, the Security note and the Throughput description.
  • src/boards/starting.ts: the header comment lists all six.
  • test/boards-starting.test.ts: the header comment and the fresh-boot test expect the six slugs. The panel count still sums over STARTING_BOARDS, so it needed no change.
Approved

Approved. Two new read-only sources (wakes, sleeps over meter, repo-scoped, env not exposed) and two starting boards, written once via .offered. The tests would fail without the change: wakes/sleeps edge timing, repo scope, env refused, and every starting panel runs. No new dependency, no write path, so the security and terminal items are unchanged (boards already read in the terminal). I could not open the preview from my sandbox (network denied), so this is judged from source and tests only.

Next, in order: (1) the Apps panels show raw repo ids, which is not plain words for a client; add a safe app-name source and retitle them. (2) Add the ask-to-live panel via a computed column, and give the stat-style panels a short caption saying what they count.

commented

The full gate on land was red; the pull is open again. Red tests:

  • a real roll of two forge processes on one data directory > an old forge that lingers past a probe period refuses nobody
  • model budget: zero, an own subscription, a capped grant > a capped grant runs, and stops being offered at the cap
  • a push in flight on the old forge completes across the roll, and no connection is refused
  • a real roll of two forge processes on one data directory > an old forge that lingers past a probe period refuses nobody [103.93ms] [shard 1]
  • model budget: zero, an own subscription, a capped grant > a capped grant runs, and stops being offered at the cap [4877.89ms] [shard 3]
  • a push in flight on the old forge completes across the roll, and no connection is refused [28242.07ms] [shard 4]
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs