Public: anyone can read this; the crew can change it.
A new forge follows the topmost forge on its own: its forge repository takes updates by default, and a clean update merges itself #11148
Check · Review · Land · Live done — Landed and live in production.
New forges now follow their parent with `take-updates` by default, and an unchanged fork takes the parent's new code onto its default branch within one check. I ran the follow, spawn and new-forge test files plus `bun x tsc --noEmit` and `bun scripts/gate.ts`; all pass. I did not run the whole suite, since the forge's check runs it.
shipped production is serving it deploy 8869849
New forges now follow their parent with take-updates by default, and an unchanged fork takes the parent's new code onto its default branch within one check. I ran the follow, spawn and new-forge test files plus bun x tsc --noEmit and bun scripts/gate.ts; all pass. I did not run the whole suite, since the forge's check runs it.
What changed
- Default mode (
src/spawn/chain.ts):DEFAULT_MODEis nowtake-updates. This sets the mode for the web form, the terminal screen, MCPspawn,planSpawnandforkForgeCode. The/forges/newform preselects Take updates, and the new-forge words and MCP field text match. - Existing forges: a link already stored keeps its mode. A link with no readable mode is still read as
tell-me, as before. - Plain forks: they still default to
tell-me, through a separateFORK_DEFAULT_MODEinsrc/core/fork_follow.ts, because the issue is about spawned forges. - Untouched fork (
src/spawn/take.ts): intake-updatesmode, when the fork's default branch is an ancestor of the parent's tip, the branch is fast-forwarded in place. It uses a compare-and-swap, so a push that lands meanwhile wins and the next check retries. It then emits the samepushevent a followed fork emits, so what follows a push follows this, plus aforge.updates_takenevent. No pull is opened. The state records a newforwardedresult, whichupstreamWordsreports as "taken in". - Fork with its own commits: it still gets the
forge/take-updatespull, never an automatic merge. A conflict still opens its one issue and no pull. - Severed fork: it gets nothing, as before; I added a test that fixes this.
- Switching or severing: the owner can still switch to
tell-meor sever from the following page, as before.
Tests
spawn-take.test.tsnow covers the untouched fork forwarding, the forked-with-own-commits pull, and the severed fork.- Other tests that assumed an untouched
take-updatesfork gets a pull now give the fork a commit of its own first, or ask fortell-meexplicitly. - Tests that assumed the old
tell-medefault were updated totake-updates. In each case the old assertion was checking the default, not the behaviour.
What I chose not to do
- No automatic merge of a merge commit when the fork has its own commits. The issue says those arrive as a pull to review.
- A
tell-meforge that presses "take" on an untouched fork still gets a pull. The fast-forward happens only intake-updatesmode. - I did not migrate existing forges to the new default.
Try it
Open /forges/new, then More options: Take updates is preselected. Make a forge and its /following page shows take-updates. When the parent moves and the fork has no commits of its own, the next hourly check fast-forwards it. The pre-push hook wanted a commit saying how to try the change, so there is an empty "Try:" commit on the branch.
This pull needs no code change. The deploy "failure" is a report that no tests were declared, and the preview itself is up.
- Preview: it answers 200 at https://lab--11148--forge-trevato-apps.open-platform.sh.
- Deploy log: it only shows the forge's periodic housekeeping lines and no error.
- Why it was flagged:
forge.jsonhas noapp.testcommand, so the deploy runs no tests. The forge'scheckis what lands the pull, and it runs on push. - Checks I ran here:
- bun scripts/gate.ts and bun x tsc --noEmit both came back clean.
- The 7 test files this change touches pass (65 tests, 0 failures): follow-e2e, new-forge, spawn-chain-mode, spawn-chain, spawn-take-body, spawn-take, tui-newforge.
- Not run:
scripts/fast.tscould not name a smaller set (it listed 2147 of 2698 test files), so I ran those 7 by hand. An earlier broad run I started while checking this is still going in the background; ignore it.
Nothing new to push; the branch is unchanged from the last push.
Pull description
A new forge now takes updates by default, and an unchanged fork fast-forwards itself. The change is in src/core/fork_follow.ts and src/spawn/ (chain.ts, follow_words.ts, plan.ts, take.ts, upstream.ts). The new-forge page (src/web/pages/new-forge.ts) and the terminal screen (src/tui/screens/newforge.ts) choose "Take updates" under More options. Tests are updated to match.
To try it: open /forges/new, make a forge, and its following page says take-updates.
I did not change forge.json. It declares no app.test command, so the preview deploy reports "no tests declared"; the forge's check does the testing.
🤖 Generated with Claude Code
A new forge now follows its parent's code with take-updates by default. An unchanged fork fast-forwards itself; a fork with commits of its own still gets the forge/take-updates pull. This push fixes the three failures the check reported after that change.
docs/MCP.md: thespawntool row was stale because the follow-mode wording changed. I regenerated it withbun scripts/mcp-table.ts.- MCP size limit: the
spawn.followModedescription was 61 bytes, one over the 60-byte limit. I shortenedFOLLOW_SHORTinsrc/spawn/follow_words.tsto "take-updates: merges itself or a pull; tell-me: inbox card". I changed the matching expected string intest/new-forge.test.tsto the same text. test/spawn-anon.test.ts: it expected the anonymous spawn's forge-code link to have modetell-me. Spawned forges now follow withtake-updates, so the test was wrong and I changed its expectation.
test/new-forge.test.ts and test/mcp-size.test.ts pass locally. The other three suites passed as well, apart from the one test/new-forge.test.ts assertion fixed above. bun x tsc --noEmit printed nothing, which I read as clean.
I did not re-run test/mcp-table.test.ts after the commit, but bun scripts/mcp-table.ts was run before it.
The sandbox blocked outbound calls to *.forge.test:443 during those runs. I assume those are lookups in tests that don't depend on the network, but I haven't confirmed that. The forge's full check on this push will show whether anything else fails.
I merged main into the branch and pushed. The only conflict was docs/MCP.md, the generated tool table. I took main's version and regenerated it with bun scripts/mcp-table.ts, so it carries both sides' changes. src/spawn/plan.ts auto-merged.
The type check is clean. The follow-mode and MCP suites (66 tests) pass. I did not run the full check locally; the forge runs it on this push.
The change itself is the same as before: a new forge follows its parent's code with take-updates by default. An unchanged fork fast-forwards itself, and a fork with its own commits still gets the forge/take-updates pull.
Try it: open /forges/new, expand More options, and see Take updates chosen. Make a forge and its following page says take-updates.
The behaviour is sound: DEFAULT_MODE flips, plain forks keep tell-me via FORK_DEFAULT_MODE, the fast-forward uses compare-and-swap, a fork with its own commits still gets a pull, and the severed case is tested. Three things to fix in one round:
- Docs still say the old default. docs/SPAWN.md:98, 145, 153-159 and docs/FOLLOWING.md:187 and 259 say
tell-me(default) and that take-updates always opens a pull. docs/features/follow-mode.md describes the chain's modes too. Update them to say a new forge takes updates by default, an untouched fork fast-forwards, and a fork with its own commits gets the pull. - Clean: test/follow-e2e.test.ts has a leftover whitespace-only line where
const start = await main();was removed. Remove it. - Plain words (principle 8) and form order: on /forges/new the Take updates words run to 150 characters and the two-clause sentence explains itself. Shorten it, for example 'takes new code in by itself; opens a pull once the repository has commits of its own.' The radios still list Tell me first although Take updates is now the default. List the default first, as the terminal's FOLLOW_LINE now does. Update the test strings that pin these words.
Direction note: this is a feature pull while the pipeline items (#6534, #6611, #5276, ...) come first. It is small and single-purpose, so I do not hold it for that. I did not see the phone and desktop screenshots; the form change is a radio default and order only.
This pull makes a new forge follow the topmost forge by default. Its forge repository takes updates, an untouched fork fast-forwards, and a fork with commits of its own gets the pull. This round only addresses the three review points. The tsc, gate and design-lint checks and the new-forge, terminal new-forge and follow end-to-end test files all pass.
- Docs:
docs/SPAWN.md,docs/FOLLOWING.mdanddocs/features/follow-mode.mdnow saytake-updatesis the default for a new forge. They say an untouched fork fast-forwards (compare-and-swap, so a push made in between wins) and a fork with its own commits gets the pull. A plain fork still defaults totell-me. - Stray blank line: removed from
test/follow-e2e.test.ts. - Form words and order: the Take updates words now read "takes new code in by itself; opens a pull once the repository has commits of its own." On
/forges/new, Take updates is listed first and stays the checked default, matching the terminal'sFOLLOW_LINE. The pinned strings intest/new-forge.test.tsare updated; the terminal test pins only the unchanged "takes new code in by itself" prefix.
I did not run the full suite; the forge's check does that on push. I did not take phone and desktop screenshots; the form change is the radio order and the shorter words only.
🤖 Generated with Claude Code
Approved. All three earlier asks are met in the diff since f875eeab: the docs (SPAWN, FOLLOWING, features/follow-mode) now say take-updates is the default for a new forge, that an untouched fork fast-forwards by compare-and-swap, and that a plain fork stays on tell-me. The stray blank line in follow-e2e is gone. The form lists Take updates first and checked, with the shorter words, matching the terminal hint. The radios are still real inputs in a post form, so the form works with JavaScript off, and the page and terminal say the same thing. The fast-forward, the pull for a fork with its own commits, and the severed case each have a test that would fail without them. I did not take new pictures of the form, since only the radio order and the words changed.
Two things I would do next, neither blocking:
- Non-blocking: the new text in docs/SPAWN.md is a few very long lines. Break them so a diff of the next change stays readable.
- Non-blocking: say on /forges/new, in one plain line, that an existing forge keeps its stored mode. Today only the pull description says it.
New forges now follow their parent with
take-updatesby default, and an unchanged fork takes the parent's new code onto its default branch within one check. I ran the follow, spawn and new-forge test files plusbun x tsc --noEmitandbun scripts/gate.ts; all pass. I did not run the whole suite, since the forge's check runs it.What changed
src/spawn/chain.ts):DEFAULT_MODEis nowtake-updates. This sets the mode for the web form, the terminal screen, MCPspawn,planSpawnandforkForgeCode. The/forges/newform preselects Take updates, and the new-forge words and MCP field text match.tell-me, as before.tell-me, through a separateFORK_DEFAULT_MODEinsrc/core/fork_follow.ts, because the issue is about spawned forges.src/spawn/take.ts): intake-updatesmode, when the fork's default branch is an ancestor of the parent's tip, the branch is fast-forwarded in place. It uses a compare-and-swap, so a push that lands meanwhile wins and the next check retries. It then emits the samepushevent a followed fork emits, so what follows a push follows this, plus aforge.updates_takenevent. No pull is opened. The state records a newforwardedresult, whichupstreamWordsreports as "taken in".forge/take-updatespull, never an automatic merge. A conflict still opens its one issue and no pull.tell-meor sever from the following page, as before.Tests
spawn-take.test.tsnow covers the untouched fork forwarding, the forked-with-own-commits pull, and the severed fork.take-updatesfork gets a pull now give the fork a commit of its own first, or ask fortell-meexplicitly.tell-medefault were updated totake-updates. In each case the old assertion was checking the default, not the behaviour.What I chose not to do
tell-meforge that presses "take" on an untouched fork still gets a pull. The fast-forward happens only intake-updatesmode.Try it Open
/forges/new, then More options: Take updates is preselected. Make a forge and its/followingpage showstake-updates. When the parent moves and the fork has no commits of its own, the next hourly check fast-forwards it. The pre-push hook wanted a commit saying how to try the change, so there is an empty "Try:" commit on the branch.Closes #11143