Public: anyone can read this; the crew can change it.
small: The fork tree names how each fork follows its upstream in one word #11440
Check · Review · Land · Live done — Landed and live in production.
Each fork in the family tree on a fork's `/forks` page now shows one word for how it follows its parent: `follows`, `proposes` or `severed`. A severed fork says `severed` rather than showing nothing. The tree root has no word, since it follows nothing.
shipped production is serving it deploy abf00b0
Each fork in the family tree on a fork's /forks page now shows one word for how it follows its parent: follows, proposes or severed. A severed fork says severed rather than showing nothing. The tree root has no word, since it follows nothing.
- Words:
FOLLOW_WORDinsrc/actions/follow_words.tsmapstake-updatestofollows,tell-metoproposesanddont-followtosevered. It sits besidefollowModeWords.src/spawn/follow_words.tsonly knows the two chain modes, so it has nodont-followto build on. - Data:
lineageOfinsrc/core/following.tsreads every fork's stored mode in a singleforkFollowModesquery after the tree is built, andLineageNodegains an optionalmode. A fork that never chose gets the default,proposes. There is no query per node. - Page:
lineageCardinsrc/web/pages/following.tsrenders the word as an outline badge next to the existing relation badge. - Test: the new case in
test/forks-lineage-timing.test.tssets modes on a 32-fork tree and checks the node modes and the three words in the card markup. It also checks the whole tree costs no more queries than a single leaf's view of it, and a lone leaf stays at four or fewer. It fails without the change. The related fork-tree web and timing tests,tsc --noEmit,design-lintand the gate all pass.
- Left out: the terminal's fork tree (
src/tui/screens/fork_tree.ts), the MCPfork_treetool and the studio card still use their own words (offers,dont-follow,off). I left them alone to keep this small, but they could readFOLLOW_WORDas a follow-up. - No change:
tree_cache.tsis about cached file listings and has nothing to do with the fork tree. - Push: the pre-push hook required a commit saying how to try the change, so there is an empty "Try:" commit on the branch.
To try it: open /<owner>/<fork>/forks on a fork with descendants and read the badge beside each node.
🤖 Generated with Claude Code
The web tree works and is cheap (one forkFollowModes query, test pins it). Two things block it. First: the terminal door is left out. The fork tree screen src/tui/screens/fork_tree.ts, the MCP fork_tree tool and the studio card still use other words (offers/dont-follow/off), so the page and the terminal now disagree about the same fork. Make them read FOLLOW_WORD from the same source, with a test on the terminal screen. Second: docs/features/fork-tree.md does not mention the word; add a line there. Also the direction is pipeline first; this is a small feature, so keep it to this and nothing more.
The fork tree now says the same word, from FOLLOW_WORD in src/actions/follow_words.ts, on the web, in the terminal, in the MCP tool and on the studio card. Type check, the design lint and the fork-tree reader and web tests pass. The studio card change has no test of its own: it is covered only by the 50 tests that passed on the first run. I did not re-run those 50 after fixing the terminal test, and the repo's gate script (bun scripts/gate.ts) printed nothing, so I can't confirm it passed.
- Terminal:
src/tui/screens/fork_tree.tsprintsfollows,proposesorseveredbeside each node, and nothing for the root.test/fork-tree-reader.test.tspins* bob/app proposesand* dan/app follows, and checks thatoffersno longer appears. - MCP
fork_tree: each node gains awordfield, empty for the root. I keptfollow(take-updates,offers,dont-follow,autonomous) unchanged so existing clients don't break. The reader test pinswordon three nodes. - Studio card: it shows
word, and falls back to its old labels only if an older server omits it. - Web page: the word is now muted text in the row (
src/web/pages/following.ts) instead of a second outline badge, so it sits beside the relation badge without adding noise. - Docs:
docs/features/fork-tree.mdnames the three words and the newwordfield.
I left out anything beyond this: no change to the stored modes, and no renaming of follow.
I merged main into the branch and pushed it. The type check and the three fork-tree test files pass, as do the 86 tests in the merge-touched files that passed before my fixture fix, but I did not run the whole suite. Of the checks I ran, bun scripts/design-lint.ts is clean. I did not run the gate script (bun scripts/gate.ts).
Two files conflicted, and in both I kept what each side added:
src/tui/screens/fork_tree.ts: a row now shows(you)for the viewer's own forks, which came frommain, followed by theFOLLOW_WORDword (follows,proposesorsevered) from this branch.src/web/pages/following.ts: theyoubadge frommainstays. The follow word stays as muted text beside it, not a second outline badge, as Juniper asked.
One fix came with the merge. A fixture in test/fork-tree-links.test.ts built tree nodes without the new word field. That broke the type check and printed undefined in the terminal output, so I gave those nodes word: "".
The failing check was test/mcp-forks-card.test.ts. It still expected the studio card to say "offers updates" for a fork that proposes. The card now says proposes, the shared FOLLOW_WORD word this pull introduced, so I changed that expectation to proposes. The old test was out of date, not the code.
After the change that file passes (4 of 4) and bun x tsc --noEmit is clean. I have pushed it. I did not re-run any other tests.
I also searched the tests for other places that pin the old follow words ("offers updates", "takes updates", "follows on its own"). test/flows-lines.test.ts and test/family-heartbeat.test.ts contain them, but I did not open them. The check reported only the one failure, so I assume they cover a different code path.
Earlier asks are met: the word is muted text, not a second badge; the terminal, MCP tool and studio card now read FOLLOW_WORD; the severed fork says severed; the mode read is one query, pinned by the timing test; the stale card test was the test that was wrong. Docs are in docs/features/fork-tree.md, not README. Next two things: (1) Non-blocking: wrap the long lines in docs/features/fork-tree.md. (2) Non-blocking: the studio card keeps a fallback to the old labels for older servers; drop it once none remain.
Each fork in the family tree on a fork's
/forkspage now shows one word for how it follows its parent:follows,proposesorsevered. A severed fork saysseveredrather than showing nothing. The tree root has no word, since it follows nothing.FOLLOW_WORDinsrc/actions/follow_words.tsmapstake-updatestofollows,tell-metoproposesanddont-followtosevered. It sits besidefollowModeWords.src/spawn/follow_words.tsonly knows the two chain modes, so it has nodont-followto build on.lineageOfinsrc/core/following.tsreads every fork's stored mode in a singleforkFollowModesquery after the tree is built, andLineageNodegains an optionalmode. A fork that never chose gets the default,proposes. There is no query per node.lineageCardinsrc/web/pages/following.tsrenders the word as an outline badge next to the existing relation badge.test/forks-lineage-timing.test.tssets modes on a 32-fork tree and checks the node modes and the three words in the card markup. It also checks the whole tree costs no more queries than a single leaf's view of it, and a lone leaf stays at four or fewer. It fails without the change. The related fork-tree web and timing tests,tsc --noEmit,design-lintand the gate all pass.src/tui/screens/fork_tree.ts), the MCPfork_treetool and the studio card still use their own words (offers,dont-follow,off). I left them alone to keep this small, but they could readFOLLOW_WORDas a follow-up.tree_cache.tsis about cached file listings and has nothing to do with the fork tree.To try it: open
/<owner>/<fork>/forkson a fork with descendants and read the badge beside each node.🤖 Generated with Claude Code
Closes #11421