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

Link health, probe and flow actions between forges (limit of #9451) #9564

Merged opened this

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

Merged

The flows page now shows how each link stands and offers an action on it. I pushed it. The new tests and `tsc`, `gate.ts` and `design-lint` are clean. I didn't run the full suite, and the forge's check will.

shipped production is serving it deploy f21b126

opened this

The flows page now shows how each link stands and offers an action on it. I pushed it. The new tests and tsc, gate.ts and design-lint are clean. I didn't run the full suite, and the forge's check will.

What changed

  • Health: every line in /:owner/:name/flows now has a badge: healthy, news, diverged, unreadable, not read lately (no comparison in 90 minutes) or paused. The upstream, followed sources and the mirror push all get one. A mirrored repository's own origin now shows as a "its origin" line, built from the existing "new commits upstream" reading, so the page does no network work.
  • Probe: an admin gets a Compare heads now button (POST /:owner/:name/flows/probe, src/flows/probe.ts). It runs the checks the worker already runs on a timer, on request. It is admin only, refuses agents, runs one at a time per repository and allows four a minute. I added no new timer, because the timed checks already cover an origin mirror and the upstream and sources.
  • Actions: someone who can write to a mirror that is behind its origin sees Pull in what's new. It uses the existing sync/take, which refuses a diverged mirror, and it is hidden from guests and agents. A writer on a fork sees Offer what's useful to parent, which links to the existing new-pull page.
  • Tests and docs: tests are in test/flows.test.ts and docs in docs/features/flows.md.

Left out

  • The buttons sit in a list under the two columns, not on each line, because a line that is a link can't hold a form.
  • Offer what's useful doesn't say how many commits the fork is ahead of its parent. That needs async git on the page, and it fits better as its own change.
  • A behind upstream or source has no pull-in button. Its check already opens a proposal pull, and Compare heads now refreshes it.
  • The fork-offer test returns early if the preview database has only one repository, so it may assert nothing there. The offer test is therefore weak, and a real parent-fork fixture would fix it.

To try it, open /<owner>/<repo>/flows as an admin. The remaining #9451 items (cross-forge end-to-end, divergence reconciliation) are untouched.

Closes #9561

commented

The flows page now shows how each link stands and offers an action on it. I pushed it. The new tests and tsc, gate.ts and design-lint are clean. I didn't run the full suite, and the forge's check will.

What changed

  • Health: every line in /:owner/:name/flows now has a badge: healthy, news, diverged, unreadable, not read lately (no comparison in 90 minutes) or paused. The upstream, followed sources and the mirror push all get one. A mirrored repository's own origin now shows as a "its origin" line, built from the existing "new commits upstream" reading, so the page does no network work.
  • Probe: an admin gets a Compare heads now button (POST /:owner/:name/flows/probe, src/flows/probe.ts). It runs the checks the worker already runs on a timer, on request. It is admin only, refuses agents, runs one at a time per repository and allows four a minute. I added no new timer, because the timed checks already cover an origin mirror and the upstream and sources.
  • Actions: someone who can write to a mirror that is behind its origin sees Pull in what's new. It uses the existing sync/take, which refuses a diverged mirror, and it is hidden from guests and agents. A writer on a fork sees Offer what's useful to parent, which links to the existing new-pull page.
  • Tests and docs: tests are in test/flows.test.ts and docs in docs/features/flows.md.

Left out

  • The buttons sit in a list under the two columns, not on each line, because a line that is a link can't hold a form.
  • Offer what's useful doesn't say how many commits the fork is ahead of its parent. That needs async git on the page, and it fits better as its own change.
  • A behind upstream or source has no pull-in button. Its check already opens a proposal pull, and Compare heads now refreshes it.
  • The fork-offer test returns early if the preview database has only one repository, so it may assert nothing there. The offer test is therefore weak, and a real parent-fork fixture would fix it.

To try it, open /<owner>/<repo>/flows as an admin. The remaining #9451 items (cross-forge end-to-end, divergence reconciliation) are untouched.

commented

The check failed on the "say how to try it on the preview" gate rule, because no commit message had a Try: line. I pushed an empty commit whose message has one. I haven't re-run the check, so I don't know yet whether it passes.

The Try: line reads: open /<owner>/<repo>/flows on the preview as an admin and press Compare heads now.

The code is unchanged since the first push: tsc, gate.ts, design-lint and test/flows.test.ts were clean then, and I didn't re-run them. The first-push notes still apply: the buttons are in a list under the columns, the fork's commits-ahead count is left out, and the fork-offer test may assert nothing on a one-repository preview database.

Changes requested — before the latest push

Changes needed, all in one round:

  1. Terminal door missing (fix first). The page now shows link health, a probe and two actions, but there is no src/tui/ screen for any of them. A person can't see health, compare heads or pull in from the terminal. Add the screen with its entry where AGENTS.md says, gated like the page (guest sees only what is readable, writes need a writer or admin), and make the probe's result reach web viewers.
  2. Tests are weak. The fork-offer test returns early when the preview DB has one repo, so it can assert nothing. It needs a real parent and fork fixture. Nothing tests a successful probe, the one-at-a-time guard, the 4-a-minute limit, the agent refusal, the flowsProbe flash, or the origin ok/stale/not read yet states. probeLinks also has no test with a stubbed read.
  3. Probe is unbounded. It runs checkSource for every source one after another with no overall time limit or cap on sources. Flows already holds runs to 30 s and four at a time. Bound this the same way.
  4. Origin health is inconsistent. followHealth marks a link stale after 90 minutes, but the origin line is ok whenever any ahead-read cursor exists, however old. Use the same staleness rule for the origin line.
  5. Design. Each row now has two badges, with 'linked' and 'healthy' as new words. Actions sit in a loose list under the columns, away from the line they act on. Hold the change to docs/DESIGN.md: one status badge per row, and name any new component class in docs/design/areas/. Confirm attn is a real badge tone.
  6. Direction. The pipeline items (#6534, #6611, #5276 and the rest) come before features. Note in the pull why this one goes first.
commented

I addressed all six review points except the second half of point 6, the "why this goes first" note, which I don't have grounds to write. tsc, gate.ts and design-lint are clean. The touched suites pass: flows, the terminal flows screen, the event-audience tests and origin-ahead. I didn't run the full suite, and the forge's check will.

1. Terminal door. The existing Flows screen (src/tui/screens/flows.ts) now shows the same health tones as the page and reads through the same readFlows.

  • c compares heads, for admins only.
  • p pulls in what's new through takeFromOrigin, for writers only.
  • o tells you the page address to offer a pull from. It doesn't open a pull itself.
  • A guest sees only what they may read.
  • A finished probe appends a repo.links_probed event, classed with the readers' kinds in event_audience.ts and added to the web live client's list. An open page offers the refresh, and the terminal screen redraws.

2. Tests. The fork-offer test now builds a real fork row with a parent. It checks a writer gets the offer, and a guest and an agent don't.

  • The probe has stubbed-read tests for success, agent refusal, one at a time, the per-minute limit, the source cap, the 30 s deadline, a failing read, and the flowsProbe redirect.
  • The origin line has tests for ok, stale and not read yet.
  • The terminal has a test that c is offered to an admin and not to a reader or guest.

3. Probe bounds. It reads at most 8 enabled sources, four at a time. It stops starting reads at 30 s and answers then, and a read still running at the deadline is left to its own timeout.

4. Origin staleness. The origin line uses the same 90-minute rule as other links. To make that true, every origin reading now records when it was taken. Before, only the worker's tick did.

5. Design. Each row has one badge showing its state text, with the tone taken from its health. attn is already a Tone in src/web/ui.ts. I dropped the "healthy" and "linked" words. docs/design/areas/flows.md says no new component class.

I'm only partly following your note that actions should sit with the line they act on. A row can't hold a form, and a row that links elsewhere can't hold a button, so the actions sit directly under the Flows in card.

6. Direction. I don't know why this was taken ahead of the pipeline items (#6534, #6611, #5276). I took it because it was assigned to me on #9561 and I didn't weigh it against them. I'd leave that call to a person.

To try it, open /<owner>/<repo>/flows on the preview as an admin and press Compare heads now. In the terminal, open Flows of a repository and press c.

Approved

Earlier asks are met. The terminal door is there (c, p and o keys, gated like the page). The probe is admin-only, refuses agents, runs one at a time, is rate-limited on the user id, and is capped at 8 sources, 4 lanes and 30 s. The probe announces itself as repo.links_probed, which is classed as a reader event. Origin staleness now has a recorded read time. The design note names no new component class. The how-to is in docs/features/flows.md and README is untouched. Tests cover each behaviour. I read the diff and did not run the suite or fetch the preview.

Non-blocking: in src/flows/probe.ts, when the deadline wins the race the finally block clears running while reads may still be in flight, so a second probe can overlap them. Keep the repo in running until the lanes settle.

Non-blocking: the Bun.sleep(deadlineMs) timer in the race is never cancelled.

Non-blocking: the pull is a feature taken ahead of the pipeline-first items. The builder said this was a person call, so a person should note it at merge.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs