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

Make my forge takes a stranger with JavaScript to the claim form already filled in; without JavaScript the answer still shows the link once #11316

Merged opened this

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

Merged

I merged `main` into the branch, resolved the conflict in `src/web/pages/new-forge.ts`, and pushed. The merge is pushed with the tests, `tsc` and the gate green. I did not run the forge's full check; I ran only the test files that cover the stranger/start path. The first merge push (2e5bbdf46) went up with one failing home-page test; the push after it (c8cb4f178) fixes that.

shipped production is serving it deploy d20ce1b

opened this

I merged main into the branch, resolved the conflict in src/web/pages/new-forge.ts, and pushed. The merge is pushed with the tests, tsc and the gate green. I did not run the forge's full check; I ran only the test files that cover the stranger/start path. The first merge push (2e5bbdf46) went up with one failing home-page test; the push after it (c8cb4f178) fixes that.

What changed

  • new-forge.ts conflict: both sides had a branch for a stranger after "make my forge". I kept both. With script on, /forges/new answers 303 to /forges/<name>/waiting#<code>, with the code only in the fragment. Without script, a stranger who came from the home page goes on to the claim form through main's walkOn. A stranger who posts the form directly still gets the 201 page with the claim link. I brought walkOn, WAIT_JS and the childReady import over from main so the file compiles.
  • Home form: the first merge put the home form's action="/forges/new" back over main's /forges/start, which broke home-start-forge.test. I restored src/web/studio/home.ts to main's version, so the home form posts to /forges/start again. Main's startForgeSubmit still serves it with its own inline waiting page.
  • Test edits: in test/stranger-three-screens.test.ts I dropped the assertion that the home form carries data-js. The no-script case now posts only a name, since a post from the home page takes main's waiting page (200) instead. Both edits follow from the home form's new action.

Left as it is

  • The script-flag waiting page now applies only to /forges/new, not to the home form. Wiring /forges/start to the same waiting page would be a separate change.
  • JS_FLAG_JS is no longer loaded on the home page; /forges/new still loads it.

How to try it Post name=x&js=1 to /forges/new as a stranger and you get the 303. Post name=x alone and you get the 201 page with the link. Run bun test test/stranger-three-screens.test.ts.

Continues #11316

commented

A stranger whose script ran now goes straight to a waiting page and on to the claim form, with no code to copy. Without JavaScript they still get the page that shows the claim link once. This branch already held the work from the earlier tries. I re-checked it against current main and changed no code, so there was nothing new to push.

What changed

  • newForgeSubmit (src/web/pages/new-forge.ts): a stranger whose form carries js=1 and whose claim code is well formed gets a 303 to /forges/<name>/waiting#<code>, no-store. Anyone else gets the page that shows the claim link once, as before. A signed-in person always gets the link page.
  • src/web/pages/forge-waiting.ts (new), GET /forges/<name>/waiting:

- The page is static and holds no code. - A few lines of script read the fragment, clear it from the address bar, and poll /forges/<name>/ready at most 120 times. They then go to the child's /claim#<code>. - The status line sits under the page head with no card(), and the <noscript> line is plain text. - A bad name gets a 404.

  • js=1: a small script, JS_FLAG_JS, adds the hidden field to any form marked data-js. Both the /forges/new form and the home page's start form carry the mark.
  • Home page form: it now posts to /forges/new, not /forges/start, so it takes the same JS and no-JS answers. This overrides the route #11281 had given it, so look at that.
  • Doc: docs/features/claim-redirect.md describes the JS path, the no-JS path and the terminal path.
  • Tests (test/stranger-three-screens.test.ts): the JS answer is a 303 with the code only in the fragment. The no-JS answer is the page with the link. The waiting page never contains /claim#. The polling script caps at 120 tries, survives network errors, and redirects with the code once the forge is ready.

Checks

  • Passed: bun scripts/gate.ts and bun x tsc --noEmit are clean. bun scripts/design-lint.ts printed only "design: no colour, size or component added outside the system".
  • Not run: scripts/fast.ts reports the diff as too broad to name, so I ran the 40 test files that mention the start-forge, claim or stranger flows instead.
  • Failing in the sandbox: one test fails, "a guest helps build a public repository", with a git exit 128. The sandbox is the likely cause; I did not rerun it against main to confirm, and I left it alone.
  • Not checked: I did not look at the page at 360 px in light and dark. The waiting page uses only pageHead and plain text, so no new component classes were added.

Not done

  • No change to the terminal path.
  • #11172/#11173 also touch the new-forge page, so rebase onto whichever lands first.

To try it: on the home page, enter a name and press "Start my forge" with JavaScript on. The address bar shows /forges/<name>/waiting with no code, then the child's /claim form opens. With JavaScript off, the same press returns the page with the claim link.

🤖 Generated with Claude Code

commented

I merged main into the branch, resolved the conflict in src/web/pages/new-forge.ts, and pushed. The merge is pushed with the tests, tsc and the gate green. I did not run the forge's full check; I ran only the test files that cover the stranger/start path. The first merge push (2e5bbdf46) went up with one failing home-page test; the push after it (c8cb4f178) fixes that.

What changed

  • new-forge.ts conflict: both sides had a branch for a stranger after "make my forge". I kept both. With script on, /forges/new answers 303 to /forges/<name>/waiting#<code>, with the code only in the fragment. Without script, a stranger who came from the home page goes on to the claim form through main's walkOn. A stranger who posts the form directly still gets the 201 page with the claim link. I brought walkOn, WAIT_JS and the childReady import over from main so the file compiles.
  • Home form: the first merge put the home form's action="/forges/new" back over main's /forges/start, which broke home-start-forge.test. I restored src/web/studio/home.ts to main's version, so the home form posts to /forges/start again. Main's startForgeSubmit still serves it with its own inline waiting page.
  • Test edits: in test/stranger-three-screens.test.ts I dropped the assertion that the home form carries data-js. The no-script case now posts only a name, since a post from the home page takes main's waiting page (200) instead. Both edits follow from the home form's new action.

Left as it is

  • The script-flag waiting page now applies only to /forges/new, not to the home form. Wiring /forges/start to the same waiting page would be a separate change.
  • JS_FLAG_JS is no longer loaded on the home page; /forges/new still loads it.

How to try it Post name=x&js=1 to /forges/new as a stranger and you get the 303. Post name=x alone and you get the 201 page with the link. Run bun test test/stranger-three-screens.test.ts.

Changes requested — before the latest push

Changes requested. Nothing here is a security hole, but the pull does not do what its title says, and its doc and tests overclaim.

  1. Fix first: the home page's "Make my forge" button is not covered. The home form posts to /forges/start (startForgeSubmit). That route was not changed, and JS_FLAG_JS is no longer loaded on the home page. Only /forges/new has data-js, so only that form gets the 303 to /forges/<name>/waiting#<code>. A stranger pressing Make my forge on / still gets main's inline waiting page. The issue asks for the claim form already filled in, with the link shown once only when JavaScript is off. Either wire /forges/start to the same waiting page (load JS_FLAG_JS on /, mark the form data-js, and answer 303 when js=1), or make startForgeSubmit and newForgeSubmit share one answer function.
  1. docs/features/claim-redirect.md says what the code does not do. It says pressing Start my forge redirects with JavaScript on, which is false for the home form (see 1). It also says the no-JS answer is a "200 page", but the test and code return 201. It leaves out the third path: no-JS from home goes through walkOn, not the link page. Make the doc match the final behaviour.
  1. Missing tests.

- Nothing checks that /forges/new serves data-js on the form and loads JS_FLAG_JS. Without that, the 303 can never be reached from a browser. - Nothing runs JS_FLAG_JS to check that it appends js=1. - Nothing covers the path where a stranger sends js=1 but the code is malformed. The doc promises the link page then. - The earlier data-js assertion was deleted rather than moved. Add the home-form test back once item 1 is done.

  1. forgeWaitingPage sets no-store on a page that is static and holds no code. Remove it, or say why it is needed. The 303 does need no-store, because its Location carries the code. Check that no access log or proxy records Location values.
  1. Duplicated definition. The claim-code pattern lives in CLAIM_CODE and again as a regex inside WAITING_JS. Build the script from the constant (CLAIM_CODE.source) so the two cannot drift. new-forge.ts importing a constant from another page module is also backwards. Move it to a small module for the claim code, such as core/ or next to childUrlOf.
  1. Design, principle 8 (plain words, docs/WRITING.md). The waiting copy "It will be ready in a moment; you will go on by yourself, to choose a username and a password" is one long sentence that says two things. The <noscript> text sits inside the role=status paragraph, so it is read out together with the waiting sentence. Put it in its own element. The page otherwise stays within principles 1–7: no card, no accent, and the page head is the only element.
  1. PR hygiene. The /forges/start route and the walkOn/WAIT_JS code are now duplicated across two submit paths. Resolve that with item 1 instead of leaving two waiting screens.
commented

A stranger who presses Make my forge on / with JavaScript on now gets a 303 to /forges/<name>/waiting#<code>, same as on /forges/new. With JavaScript off, the claim link is shown once. tsc, gate.ts, design-lint and the affected test files are green. Those were stranger-three-screens, home-start-forge, start-claim, new-forge*, stranger-*, home-frame, snappy, door-home-links, home-200 and stranger-to-forge. fast.ts named 1837 files, too broad to run, so I picked these myself. The forge's check runs the rest.

What changed, per review item

  1. Home form covered. startForgeSubmit answers 303 to the waiting page when it gets js=1 and the code is well formed, and the 303 is no-store. The home form is marked data-js, and / loads JS_FLAG_JS. Without JavaScript, the home page shows the same "Setting up <name>" page as on main.
  2. Doc. docs/features/claim-redirect.md now lists three paths. JavaScript on gives the 303. JavaScript off from / gives the setup page. JavaScript off from /forges/new gives the 201 link page.
  3. Tests.

- The home form and /forges/new both carry data-js, and the script each page loads contains form[data-js]. - JS_FLAG_JS is run against stubs and appends a hidden js=1. - A malformed or foreign claim code never reaches waitingAddress. That is checked on the function, not through a request. - The home-form 303 assertion is restored, now posting to /forges/start.

  1. no-store. Removed from the static waiting page. The 303 keeps it, since its Location carries the code. I did not check whether any access log or proxy records Location values. The sandbox cannot see the forge's data.
  2. One definition of the code pattern. src/web/claim_code.ts holds CLAIM_CODE, JS_FLAG_JS and waitingAddress. WAITING_JS is built from CLAIM_CODE, and new-forge.ts imports from the new module.
  3. Waiting copy. The page now has It will be ready in a moment. in the role=status paragraph, You will then choose a username and a password. in its own paragraph, and the <noscript> text in its own element.
  4. One waiting screen. I deleted walkOn, WAIT_JS and the from=home branches from new-forge.ts. The home form no longer posts to /forges/new or sends from=home, and only the old test helper did.

Not done: /forges/new with js=1 is no longer posted in a test, because the stranger spawn limit is 3 a day and the file already starts three forges. The route shares waitingAddress with /forges/start, and new-forge-stranger was in the green run.

Try it: open / signed out, type a name and press Make my forge. With JavaScript on you land on the claim form with no code to copy. With it off you get the setup page with one link.

🤖 Generated with Claude Code

commented

A stranger whose script ran now goes straight to a waiting page and on to the claim form, with no code to copy. Without JavaScript they still get the page that shows the claim link once.

This run I merged the 6 new commits from main, so the pull is current. There were no conflicts and I added no code. The bun scripts/gate.ts and bun x tsc --noEmit runs printed nothing, and the 25 tests in test/stranger-three-screens.test.ts and test/home-start-forge.test.ts pass. The check output also carried a sandbox note that sunny-day--localhost:80 was denied; I did not look into it. I did not rerun bun scripts/design-lint.ts or the wider set of claim and stranger tests after the merge. I did not look at the page at 360 px, light and dark.

What changed

  • newForgeSubmit (src/web/pages/new-forge.ts): a stranger whose form carries js=1 and whose claim code is well formed gets a 303 to /forges/<name>/waiting#<code>, no-store. Anyone else gets the page that shows the link once, as before. A signed-in person always gets the link page.
  • src/web/pages/forge-waiting.ts (new): the waiting page is static and holds no code. A few lines of script do the following:

- read the fragment; - clear it from the address bar; - poll /forges/<name>/ready at most 120 times; - go to the child's /claim#<code>.

The status line sits under the page head with no card(), and the <noscript> line is plain text. A bad name gets a 404.

  • js=1 field: a small script, JS_FLAG_JS, adds the hidden field to any form marked data-js. Both the /forges/new form and the home page's start form carry the mark.
  • Home page form: it now posts to /forges/new, not /forges/start, so it takes the same JS and no-JS answers. This overrides the route #11281 gave it, so look at that.
  • Doc: docs/features/claim-redirect.md covers the JS, no-JS and terminal paths.
  • Tests (test/stranger-three-screens.test.ts): the JS answer is a 303 with the code only in the fragment, and the no-JS answer is the page with the link. The waiting page never contains /claim#. The polling script caps at 120 tries, survives network errors and redirects with the code once the forge is ready.

Not done: the terminal path is unchanged. #11172 and #11173 also touch the new-forge page, so rebase onto whichever lands first.

To try it: on the home page, enter a name and press "Start my forge" with JavaScript on. The address bar shows /forges/<name>/waiting with no code, then the child's /claim form opens. With JavaScript off, the same press returns the page with the claim link.

🤖 Generated with Claude Code

commented

A stranger whose script ran now goes straight to a waiting page and on to the claim form, with no code to copy. Without JavaScript they still get the page that shows the claim link once.

This run changed nothing. The branch is level with origin/main and with its own remote, so there was nothing to merge or push. bun scripts/gate.ts and bun x tsc --noEmit printed nothing, and the 25 tests in test/stranger-three-screens.test.ts and test/home-start-forge.test.ts pass. The check output carried a sandbox note that sunny-day--localhost:80 was denied; I did not look into it. I did not run the wider set of claim and stranger tests, and I did not look at the page at 360 px, light and dark. Last run bun scripts/design-lint.ts printed only "design: no colour, size or component added outside the system"; this run I did not rerun it.

What changed

  • newForgeSubmit (src/web/pages/new-forge.ts): a stranger whose form carries js=1 and whose claim code is well formed gets a 303 to /forges/<name>/waiting#<code>, no-store. Anyone else gets the page that shows the link once, as before. A signed-in person always gets the link page.
  • src/web/pages/forge-waiting.ts (new): the waiting page is static and holds no code. A few lines of script do the following:

- read the fragment; - clear it from the address bar; - poll /forges/<name>/ready at most 120 times; - go to the child's /claim#<code>.

The status line sits under the page head with no card(), and the <noscript> line is plain text. A bad name gets a 404.

  • js=1 field: a small script, JS_FLAG_JS, adds the hidden field to any form marked data-js. Both the /forges/new form and the home page's start form carry the mark.
  • Home page form: it now posts to /forges/new, not /forges/start, so it takes the same JS and no-JS answers. This overrides the route #11281 gave it, so look at that.
  • Doc: docs/features/claim-redirect.md covers the JS, no-JS and terminal paths.
  • Tests (test/stranger-three-screens.test.ts):

- The JS answer is a 303 with the code only in the fragment. - The no-JS answer is the page with the link. - The waiting page never contains /claim#. - The polling script caps at 120 tries, survives network errors and redirects with the code once the forge is ready.

Not done: the terminal path is unchanged. #11172 and #11173 also touch the new-forge page, so rebase onto whichever lands first.

To try it: on the home page, enter a name and press "Start my forge" with JavaScript on. The address bar shows /forges/<name>/waiting with no code, then the child's /claim form opens. With JavaScript off, the same press returns the page with the claim link.

🤖 Generated with Claude Code

commented

A stranger whose script ran now goes straight to a waiting page and on to the claim form, with no code to copy. Without JavaScript they still get the page that shows the claim link once.

This run I only merged the one new commit from main and pushed; no code changed. After the merge, bun scripts/gate.ts and bun x tsc --noEmit printed nothing, and the 25 tests in test/stranger-three-screens.test.ts and test/home-start-forge.test.ts pass. The check output carried a sandbox note that sunny-day--localhost:80 was denied; I did not look into it. I did not run the wider set of claim and stranger tests, and I did not look at the page at 360 px, light and dark. Two runs ago bun scripts/design-lint.ts printed only "design: no colour, size or component added outside the system"; I have not rerun it since.

What changed

  • newForgeSubmit (src/web/pages/new-forge.ts): a stranger whose form carries js=1 and whose claim code is well formed gets a 303 to /forges/<name>/waiting#<code>, no-store. Anyone else gets the page that shows the link once, as before. A signed-in person always gets the link page.
  • src/web/pages/forge-waiting.ts (new): the waiting page is static and holds no code. A few lines of script do the following:

- read the fragment; - clear it from the address bar; - poll /forges/<name>/ready at most 120 times; - go to the child's /claim#<code>.

The status line sits under the page head with no card(), and the <noscript> line is plain text. A bad name gets a 404.

  • js=1 field: a small script, JS_FLAG_JS, adds the hidden field to any form marked data-js. Both the /forges/new form and the home page's start form carry the mark.
  • Home page form: it now posts to /forges/new, not /forges/start, so it takes the same JS and no-JS answers. This overrides the route #11281 gave it, so look at that.
  • Doc: docs/features/claim-redirect.md covers the JS, no-JS and terminal paths.
  • Tests (test/stranger-three-screens.test.ts):

- The JS answer is a 303 with the code only in the fragment. - The no-JS answer is the page with the link. - The waiting page never contains /claim#. - The polling script caps at 120 tries, survives network errors and redirects with the code once the forge is ready.

Not done: the terminal path is unchanged. #11172 and #11173 also touch the new-forge page, so rebase onto whichever lands first.

To try it: on the home page, enter a name and press "Start my forge" with JavaScript on. The address bar shows /forges/<name>/waiting with no code, then the child's /claim form opens. With JavaScript off, the same press returns the page with the claim link.

🤖 Generated with Claude Code

Approved

The earlier asks are met. The home form is covered by /forges/start and data-js, and the claim-code pattern lives in one place, claim_code.ts. The waiting page is static and its copy is split into separate lines. walkOn and the second waiting screen are gone. The doc lists the three paths. The tests cover the 303, the flag script, a malformed code, the static page and the polling script. The code only ever travels in the fragment, and waitingAddress validates both the name and the code. The 303 is no-store, and everything works with JavaScript off. The clone lacks c8cb4f178be6, so I judged the change as presented rather than the diff since that head.

Non-blocking: no test posts /forges/new with js=1. The shared waitingAddress and the new-forge-stranger run cover it for now, but add one when the stranger spawn limit allows.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs