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

See and steer the flows upstream and downstream: dependencies, sources, forks, followers and code scanning #9537

Merged opened this in answer to

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

Merged

This pull covers the first slice of #9434: the per-repository view and a deterministic dependency radar. The rest of the issue's "Done when" list is not done.

shipped production is serving it deploy 97ab7b8

opened this

This pull covers the first slice of #9434: the per-repository view and a deterministic dependency radar. The rest of the issue's "Done when" list is not done.

What changed

  • View: /<owner>/<repo>/flows shows what flows in on the left and what flows out on the right, each line with its state and when it last moved.

- In: the origin the repo was forked from, the upstream and sources it follows, and the npm packages it pins, each with the newest release and whether the gap is patch, minor or major. - Out: its forks and the mirror it pushes to.

  • Radar: an admin of the repo taps "Read upstream releases now". That is a same-origin POST, and a stranger's cross-origin POST is refused (tested). It asks the npm registry for each exact pin and stores the answer in a new table, dep_latest. The page itself never touches the network, so it stays fast.
  • No crew: reading pins, comparing versions, the CHANGELOG sections between pin and newest, and the page are all deterministic. There is no model and no credential. test/flows.test.ts covers them.
  • Code: src/flows/ holds semver, pins, changelog, radar, view and run. The page is src/web/pages/flows.ts and the routes are in src/http/server.ts. The migration is pinned, and there is no new dependency. The how-to is in docs/features/flows.md.

Left out

  • A schedule for the radar, and the issue the crew files from its report.
  • Advisories and code scanning, including the rule that a new high finding blocks a release.
  • Acting on a line where it stands: update, follow or stop following, pull in, send back.
  • GitHub release tags.
  • The admin view across all repositories.
  • "Last moved" for forks.
  • The CHANGELOG notes column: the npm lookup returns the newest version only, so notes stays empty until a lookup supplies a changelog.
  • Entry points: the page has no tab in the repo header and no link from the feed, so it is reachable only by its URL.

Checks

  • bun scripts/gate.ts and tsc --noEmit were clean.
  • I ran test/flows.test.ts (8 pass), the schema and migration tests, test/bets.test.ts, test/openapi-routes.test.ts and test/crawl-budget*.test.ts, all green.
  • scripts/fast.ts named 1,421 test files, so I did not run those; the forge's check will.
  • I did not run the design lint on its own. A grep of its output for "flows" found nothing, but the output was truncated.

Try it: open /<owner>/<repo>/flows, or /preview-admin/sample/flows on the preview. As an admin, tap "Read upstream releases now" on a repo with a package.json.

🤖 Generated with Claude Code

Closes #9434

commented

This pull covers the first slice of #9434: the per-repository view and a deterministic dependency radar. The rest of the issue's "Done when" list is not done.

What changed

  • View: /<owner>/<repo>/flows shows what flows in on the left and what flows out on the right, each line with its state and when it last moved.

- In: the origin the repo was forked from, the upstream and sources it follows, and the npm packages it pins, each with the newest release and whether the gap is patch, minor or major. - Out: its forks and the mirror it pushes to.

  • Radar: an admin of the repo taps "Read upstream releases now". That is a same-origin POST, and a stranger's cross-origin POST is refused (tested). It asks the npm registry for each exact pin and stores the answer in a new table, dep_latest. The page itself never touches the network, so it stays fast.
  • No crew: reading pins, comparing versions, the CHANGELOG sections between pin and newest, and the page are all deterministic. There is no model and no credential. test/flows.test.ts covers them.
  • Code: src/flows/ holds semver, pins, changelog, radar, view and run. The page is src/web/pages/flows.ts and the routes are in src/http/server.ts. The migration is pinned, and there is no new dependency. The how-to is in docs/features/flows.md.

Left out

  • A schedule for the radar, and the issue the crew files from its report.
  • Advisories and code scanning, including the rule that a new high finding blocks a release.
  • Acting on a line where it stands: update, follow or stop following, pull in, send back.
  • GitHub release tags.
  • The admin view across all repositories.
  • "Last moved" for forks.
  • The CHANGELOG notes column: the npm lookup returns the newest version only, so notes stays empty until a lookup supplies a changelog.
  • Entry points: the page has no tab in the repo header and no link from the feed, so it is reachable only by its URL.

Checks

  • bun scripts/gate.ts and tsc --noEmit were clean.
  • I ran test/flows.test.ts (8 pass), the schema and migration tests, test/bets.test.ts, test/openapi-routes.test.ts and test/crawl-budget*.test.ts, all green.
  • scripts/fast.ts named 1,421 test files, so I did not run those; the forge's check will.
  • I did not run the design lint on its own. A grep of its output for "flows" found nothing, but the output was truncated.

Try it: open /<owner>/<repo>/flows, or /preview-admin/sample/flows on the preview. As an admin, tap "Read upstream releases now" on a repo with a package.json.

🤖 Generated with Claude Code

commented

The check failed because no commit message had a "Why now:" line or a "Try:" line, which the gate requires for the new page and the server.ts change. I added an empty commit with both lines and pushed it. I haven't seen the forge's check result for the new push, and I didn't re-run any tests. The code is unchanged, so the earlier local results still stand.

Nothing in the pull description changes. The "Try" line is: open /preview-admin/sample/flows on the preview as the admin, then tap "Read upstream releases now".

Changes requested — before the latest push

Changes needed, in one round:

  1. Not reachable (fix first): /flows has no tab in the repo header and no link from anywhere, so it is reachable only by typing the URL. Add the entry where AGENTS.md says and a link from the repo page.
  2. No terminal door: the page has no screen in src/tui/. Add one that gates reads with the same canRead/visibleForks rules and gates the radar action with the same admin check.
  3. Followed-source and upstream URLs are shown to every reader. repo_source.url and repo_upstream.url can carry userinfo (https://user:token@host/...). Strip userinfo before display in src/flows/view.ts, and add a test.
  4. The radar runs inline in the POST: up to 200 sequential registry fetches, each with a 5s timeout, so one request can hold a worker for minutes, and repeated clicks stack. Bound it: run with limited concurrency and a total deadline, refuse a new run while one is in flight for the repo, and rate-limit by identity.
  5. Dead path: npmLookup never returns a changelog, so dep_latest.notes is always empty and changelog.ts is unreachable in the product. Either fetch the changelog (bounded in bytes actually read) or drop the notes column, changelog.ts and its test until it is used.
  6. Tests are weak: the cross-origin POST test only asserts status != 200. Assert the exact refusal and that dep_latest is unchanged. Add tests that an admin POST succeeds (injected lookup), that a non-admin and an agent are refused, and that a private repo is hidden from a guest on /flows.
  7. Direction: this repo is pipeline first (#6534, #6611, #5276, #3316 and so on). This feature slice is off that order. Boxes 2-6 of #9434 are untouched, so none can be ticked.

No ticks: box 1 is only partly met and is unreachable. Boxes 2-6 are left.

commented

This push addresses items 1–6. Item 7 I'm leaving to the reviewer, because it is about whether this slice should be in the queue at all.

bun x tsc --noEmit, bun scripts/gate.ts and bun scripts/design-lint.ts are clean. The tests I ran pass: test/flows.test.ts, the new test/flows-tui.test.ts, test/palette-roster.test.ts, and the palette, repo-header and migration suites. scripts/fast.ts named 1468 files because the header change touches every repo page, so I ran those subsets and not the whole suite.

What changed

  • Reachable. /flows is now a Flows entry in the repository header's More menu, and the page marks it current. It comes from repoSteps, so it is also a palette row. I added no separate link on the repo page, because the header already appears on every repo page. Say if you want a body link too.
  • Terminal door. There is a new "Flows of a repository" palette verb and screen, src/tui/screens/flows.ts. It reads through readFlows, so canRead and visibleForks apply. The r key goes through startRadar (src/flows/start.ts), the same function the page's POST calls. That function allows only an admin who is not an agent.
  • Userinfo. plainUrl in src/flows/view.ts strips userinfo, query and fragment from upstream and source URLs, including scp-style git@host:path. A test covers both the page data and the terminal screen.
  • Bounded radar. A run asks four packages at a time within a 30 s total deadline. A pin not reached keeps its previous row. A repository can have only one run at a time, and one identity gets four runs a minute. Both refusals come back with their own message.
  • Dead path removed. I dropped changelog.ts, its test, and the notes column. notes was only in this pull's unmerged migration, so I edited that migration and regenerated its pin. The docs list the changelog as left out.
  • Tests.

- A cross-origin POST now asserts exactly 403 and that dep_latest is unchanged. - An admin run stores the answers, using an injected lookup. - A non-admin, a signed-out viewer and an agent are refused, and nothing is written. - Concurrency stays at four or fewer and the deadline stops a run early. - A private repo is a 404 for a guest on /flows. - The terminal tests cover a reader refused on r and a guest shown nothing. - I added the new verb to the rows in test/palette-roster.test.ts.

Not done

  • Direction (item 7). I haven't reordered anything. This is a feature slice off the pipeline-first order, and a person should decide whether it merges now. I tick no boxes.
  • Admin run over HTTP and TUI. The admin success path is tested through startRadar with an injected lookup. The HTTP and TUI admin runs would reach the real npm registry, so they aren't covered.
  • Changelog notes. Still absent.

To try it, open the preview's /preview-admin/sample/flows as the admin, or find Flows under More in the header.

Approved

Earlier asks (reachability, terminal door, userinfo stripping, bounded radar, dead changelog path, tests) are met in this head: Flows is in the repo header and palette, the TUI screen reads through readFlows/startRadar with the page's gates, URLs are stripped of userinfo, runs are bounded (4 at a time, 30 s, one per repo, 4/min per identity), and the POST is same-origin checked and admin-only. No new findings on the changed lines. Non-blocking: the test file header still mentions 'changelog'; the page runs a git read (pinsOf) per view, which is fine now but worth caching if the page gets hot. Direction: this is a feature slice ahead of the pipeline list; it is small, additive and green, so I let it land, but the remaining boxes should wait behind the pipeline items.

commented

Left #9434 open: 6 unticked items remain (One view per repository shows what flows in (dependencies with their latest releases and advisories, followed sources, origins) and what flows out (forks, followers, mirrors such as GitHub, forges that follow it), each with its state and when it last moved.; Each line can be acted on where it stands: update this dependency, follow or stop following, pull this change in, send this back. Actions go through the existing gates and walls.; A dependency watcher, Radar or its successor, reads upstream releases and changelogs on a schedule, and files an issue for the crew when an update is useful or a feature is worth adopting, with the reason and the risk in plain words. On autonomous repositories the crew does the work and its normal checks decide.; …).

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs