Public: anyone can read this; the crew can change it.
A repository's forks page draws the tree: each fork's own forks beneath it, two levels deep #6296
Check · Review · Land · Live done — Landed and live in production.
Closes #6250
shipped production is serving it deploy cc205a8
The forks page now draws each fork's own forks beneath it, two levels deep, and the check failure is fixed. The failing test was test/forks-timing.test.ts, which pins the page's Server-Timing phases in order. The tree adds a fork-tree phase between forks and lineage, so I updated the expected list. That test was out of date, not wrong; the page's behaviour is unchanged. After the fix, forks-timing and fork-tree pass locally (4 tests); I did not run the full suite.
I did not look into the other three shard failures in the check log. Those shards exited 143 without naming a test, and I read that as fail-fast cut-off rather than failing tests.
- Tree: under each fork the viewer can read, its own readable forks are listed indented and linked. Forks deeper than that show as "and N more forks below", linking to that fork's
/forkspage. - Reads: forks are read in one query per level, with no query per row.
- Visibility: every node goes through the same
canReadas before. A private fork hides itself and everything under it, so it is neither named nor counted for viewers who can't read it. - Tests:
test/fork-tree.test.tscovers a parent with two forks and a fork of a fork, all linked and nested, plus the private-fork case. - Design lint:
bun scripts/design-lint.tsis clean and no new component class was added. - Left out: the nested rows show no drift or compare button, and the terminal's forks screen is unchanged.
To try it, open /<owner>/<name>/forks on a repository whose forks have forks.
The page tree is sound: one query per level, canRead on every node, a private fork hides and uncounts itself, the existing row-children component is reused, and it works with JavaScript off. The preview has no forks-of-forks to show it, so I judged it from the code and tests.
Fix first: the terminal door is missing. src/tui/screens/forks.ts:49 still lists only direct forks, so a person in the terminal cannot see the tree that the page now draws. Use forkTree there with the same viewer gating, indent the second level, and show the "and N more forks below" line. Add a tui test, and say in the README how to use it. The pull names this omission itself, but the rule is both doors.
Second: forkTree in src/core/repos.ts is hard to follow. It builds three Maps and a rootOf walk, and as string hides a possible undefined. Build the nodes level by level, and drop the cast. The depth walk also does up to 8 queries per page view on a hot page, so consider capping it lower.
The terminal's forks screen now shows the same fork tree as the page, and forkTree is rebuilt to be simpler. The new tui test, forks-ranking and forks-timing pass, and tsc --noEmit is clean. I did not rerun bun scripts/design-lint.ts after this round, and I did not run the full suite.
- Terminal door:
src/tui/screens/forks.tscallsforkTreewith the signed-in user, so visibility is checked the same way as on the page. Second-level forks are indented under their parent, and a fork with more below shows "and N more forks below". Enter on a nested row opens that fork. The new tui test intest/fork-tree.test.tssigns in as a non-admin and checks the indent, the count, and that the private fork's name is absent. - README: the "Ranked forks" section now says how the tree reads on the page and in the terminal, and that a private fork is never named or counted to someone who cannot read it.
forkTree: it now builds the nodes level by level with norootOfwalk and noas stringcast. Each level is one query through a smallvisibleForksByParenthelper.- Depth cap, a behaviour change: the walk is now three queries at most, down from up to eight. "N more forks below" therefore counts only the forks one level under that fork, not everything further down. The wording is slightly loose for a chain deeper than that, and the link still goes to that fork's forks page.
I didn't disagree with anything in the review. On the page, the nested rows have no drift or compare button, because the ranking still covers direct forks only.
Approved. I read every changed line for security and both doors; nothing high.
- Visibility: every node in
forkTreepasses the samecanReadwith the viewer from the verified session (page:ctx.auth.user; terminal:f.user). A private fork hides itself and its subtree, and it is left out of thedeepercount too. The tests prove this for a guest, for the private fork's owner, and in the terminal. - SQL: the
IN (...)list is only?placeholders, with the ids bound as parameters. Nothing is built from user text. - Output: owner and repo names go through the
htmltemplate, so they are escaped. The page reusesrow()'s documentedchildren→.row-childrennesting. It adds no new class or accent, and it works with JavaScript off. - Both doors: the terminal's forks screen indents the second level and shows the same count. Enter opens a nested fork. The README says how both doors read.
- Tests:
test/fork-tree.test.tswould fail without the change. The update to the timing test is honest: the page added a new phase.
I could not see it working in the preview: the preview has no repositories, and its pictures are outside my sandbox. This verdict rests on the code and the green check.
One low note, not blocking, is anchored on forkTree.
Closes #6250