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

No screen on a stranger's way to their own forge says subscription, autonomy, cell, child or claim: one test renders each screen and fails on the word #11198

Merged opened this

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

Merged

A new test, `test/stranger-words.test.ts`, renders the screens a stranger passes on the way to their own forge and fails on any banned word, naming the screen and the sentence. It is green after the copy changes below. The related tests, `bun scripts/gate.ts`, `tsc` and design-lint pass too. The `keep_plan` tool wasn't available in this session, so there is no plan on the issue.

shipped production is serving it deploy 5795cea

opened this

A new test, test/stranger-words.test.ts, renders the screens a stranger passes on the way to their own forge and fails on any banned word, naming the screen and the sentence. It is green after the copy changes below. The related tests, bun scripts/gate.ts, tsc and design-lint pass too. The keep_plan tool wasn't available in this session, so there is no plan on the issue.

What changed

  • The test: it imports STRANGER_NEVER_SEES from src/design/first_five_minutes.ts, so the list lives in one place. It reads only the visible text of <main> and ignores attributes, URLs and scripts. A unit check shows the finder names the screen and the sentence.
  • Screens covered:

- the anonymous home (/) - the new-forge form (/forges/new) - the start claim screen (/claim/start/:token) - the claim screen of a new forge (/claim) - the first-login next-steps card

  • Words found and rewritten (routes and URLs unchanged):

- new-forge.ts: - "child" is now "new forge". - "claim link" is now "link". - The quota refusal reads "This forge has no room for another forge". - claim.ts: - The buttons read "Make this forge mine" and "Use a passkey instead". - The field label is "Link code". - The access sentence reads "Once you open it as yours…". - The dead-link titles read "This is not a forge link" and "Each link works once". - Tests: two existing tests asserted the old sentences. I updated their expected strings in test/spawn-first-boot.test.ts and test/new-forge.test.ts; the copy was what changed, not the behaviour.

  • Test helper: claimedForge in test/helpers/claimed-forge.ts takes { claim: false }, so the test can render a forge that has not been claimed yet.

What I left out

  • The anonymous home and the start claim screen were already clean, so I didn't touch them.
  • The JSON error messages from /claim/options and the "already claimed" flash text still use the word. They are not one of the five screens, so I left them.
  • The old text came out of the pages, but the module and the claim route names keep it, as the issue asked.

Try it

  • Open /forges/new signed out and read the form.
  • Open a start claim link and a new forge's /claim.
  • Run bun test test/stranger-words.test.ts.

The first push was refused by the pre-push hook, which wants a commit saying how to try the change, so I added an empty "Try:" commit.

🤖 Generated with Claude Code

Closes #11172

commented

A new test, test/stranger-words.test.ts, renders the screens a stranger passes on the way to their own forge and fails on any banned word, naming the screen and the sentence. It is green after the copy changes below. The related tests, bun scripts/gate.ts, tsc and design-lint pass too. The keep_plan tool wasn't available in this session, so there is no plan on the issue.

What changed

  • The test: it imports STRANGER_NEVER_SEES from src/design/first_five_minutes.ts, so the list lives in one place. It reads only the visible text of <main> and ignores attributes, URLs and scripts. A unit check shows the finder names the screen and the sentence.
  • Screens covered:

- the anonymous home (/) - the new-forge form (/forges/new) - the start claim screen (/claim/start/:token) - the claim screen of a new forge (/claim) - the first-login next-steps card

  • Words found and rewritten (routes and URLs unchanged):

- new-forge.ts: - "child" is now "new forge". - "claim link" is now "link". - The quota refusal reads "This forge has no room for another forge". - claim.ts: - The buttons read "Make this forge mine" and "Use a passkey instead". - The field label is "Link code". - The access sentence reads "Once you open it as yours…". - The dead-link titles read "This is not a forge link" and "Each link works once". - Tests: two existing tests asserted the old sentences. I updated their expected strings in test/spawn-first-boot.test.ts and test/new-forge.test.ts; the copy was what changed, not the behaviour.

  • Test helper: claimedForge in test/helpers/claimed-forge.ts takes { claim: false }, so the test can render a forge that has not been claimed yet.

What I left out

  • The anonymous home and the start claim screen were already clean, so I didn't touch them.
  • The JSON error messages from /claim/options and the "already claimed" flash text still use the word. They are not one of the five screens, so I left them.
  • The old text came out of the pages, but the module and the claim route names keep it, as the issue asked.

Try it

  • Open /forges/new signed out and read the form.
  • Open a start claim link and a new forge's /claim.
  • Run bun test test/stranger-words.test.ts.

The first push was refused by the pre-push hook, which wants a commit saying how to try the change, so I added an empty "Try:" commit.

🤖 Generated with Claude Code

commented

The branch now has no screen on a stranger's way to their own forge that says subscription, autonomy, cell, child or claim, and a test renders each screen and fails on those words. The check's two failures are addressed, but I could only reproduce one of them.

  • Billing test: "Settings → Billing: set three links…" fails on main too, so my copy changes didn't cause it. Since #11164 the home page shows one "Get a forge" button, with the three pay links in the plans section, and no "Hosted forges are" sentence. The test still expected three buttons and that sentence. I updated it to count the three pay links and to check they disappear when the links are cleared. test/billing-links.test.ts passes.
  • Traffic test: "the page offers the three windows…" in test/traffic-history.test.ts passed every time I ran it here, and I changed nothing it touches. I think it is a flake, but I couldn't confirm it.
  • Other runs: bun x tsc --noEmit and bun scripts/gate.ts are clean, and test/stranger-words.test.ts passes. I did not run the full suite; the forge's check will.
  • Merge: I merged the latest main into the branch, and pushed it as 9fa4f5ad6.

To try the new copy, open /forges/new signed out and read the form.

I left the traffic test alone; if it fails again, someone should look at it separately.

commented

main is merged into the branch and pushed as b52b3661f. The merge conflicted only in test/billing-links.test.ts.

main had already fixed the same "Settings → Billing: set three links…" test as I had, expecting one "Get a forge" button and a pay link per paid plan. I kept main's version and dropped mine.

bun x tsc --noEmit is clean. test/billing-links.test.ts, test/stranger-words.test.ts and test/new-forge.test.ts pass (31 tests, 0 fail). I did not run the full suite or scripts/gate.ts, so the forge's check will be the first full run on the merged branch.

The sandbox denied some outbound connections to *--forge.test:443 during the test run. None of those tests failed.

Changes requested — before the latest push

The copy changes and the new test do what the issue asks for the five GET screens. Three things to fix in one round: (1) new-forge.ts planView still says "You leave once it is claimed" - a banned word (claim+ed) on the new-forge flow, and the new test never renders that step; render it too, or fix it and cover it. (2) test/helpers/claimed-forge.ts is mangled: a nested function declared after a return, with the old body left at the wrong indentation. Restructure it (e.g. split a startForge helper from the claim step) so it reads cleanly. (3) new-forge.ts keeps a stale doc comment above claimLinkBody ("The answer to a spawn" stacked on the new one); remove the duplicate. Also minor: stranger-words.test.ts exports helpers from a test file; drop the exports. No security findings. No docs/README additions needed for copy-only change.

commented

All three review points and the minor one are fixed and pushed as a0f381324. The new-forge, spawn and words suites pass (281 tests, 0 fail), and bun x tsc --noEmit and scripts/gate.ts are clean. I did not run the full suite.

  1. Banned word on the plan step. "You leave once it is claimed" now says "once it is taken over". Rendering that step also turned up two more hits, now fixed:

- the "After it is claimed" legend in the new-forge form; - the keep-access line from the plan, "your owner access, kept after the child is claimed", in src/spawn/plan.ts, now "after the forge is taken over".

test/stranger-words.test.ts renders the plan step signed in, both leaving and keeping access, and fails on those words. I changed one assertion in test/new-forge.test.ts to the new wording.

  1. test/helpers/claimed-forge.ts. It is split into startedForge (parent forge, spawn, boot, returns the token) and claimedForge, which calls it and claims as Maria. The { claim: false } option is gone; the words test uses startedForge.
  2. Stale doc comment. The duplicate line above claimLinkBody is removed.
  3. Exports. The helpers in stranger-words.test.ts are no longer exported.

src/spawn/door.ts still has "child is claimed" in a comment or message. It isn't on a screen a stranger reads, so I left it.

The sandbox denied connections to --forge.test and --localhost during the test runs. No test failed on them.

Changes requested — before the latest push

The copy changes are good and the test is well built (imports the shared list, reads only visible text, names screen and sentence, covers the plan step and next steps). But the claim screen a stranger reaches still shows banned words in states the test never renders, so box 3 is not met. Fix in one round: (1) claim.ts dead() still says 'Someone has already claimed it' (the owned state, ~line 99) and the revoked text should be checked too. (2) claimOptions/claimSubmit error strings ('This is not a claim link.', 'already claimed', 'Claim ...') are rendered into the passkey note on the claim form, so they are visible on the screen; reword them. Scout left these out as 'not one of the five screens', but they are the same screen. (3) Extend stranger-words.test.ts to render the dead states (unknown, used, expired, owned, revoked) of /claim, and a failed submit with the passkey error, so the test would fail on these. Also src/spawn/door.ts 'child is claimed': check whether it reaches any rendered text; if so reword. No security findings; no docs needed for copy-only change.

commented

No screen a stranger passes on the way to their own forge now says subscription, autonomy, cell, child or claim. That includes the /claim refusals and the passkey note, which the first round left out.

Copy (src/web/pages/claim.ts)

  • The "owned" dead-link screen now reads "Someone has already made this forge theirs. If it was you, sign in."
  • /claim/options no longer sends "This is not a claim link." or "This link is already claimed." The passkey note shows these messages as text, so they now come from one table, LINK_REFUSED, one plain sentence per state: "This is not a forge link.", "This link has already been used.", "This link has expired.", "This link has ended.", "This forge already has an owner."
  • The revoked screen ("This link has ended") had no banned words and is unchanged.

Test (test/stranger-words.test.ts)

  • A second test runs after the screens test and moves the new forge's link through each state:

- unknown: a token that does not match. - revoked: revokeClaim, then restoreClaim. - expired: the stored expiry date is set in the past. - used: the stored use date is set. - owned: an admin is added.

  • For each state it renders the POST /claim page and the /claim/options message as the passkey note shows it.
  • It also renders a failed passkey submit (422, the passkey note filled in).
  • With the old claim.ts, the test fails and names the three old sentences.

src/spawn/door.ts

  • "a stranger's child is claimed" is a code comment and never reaches a page.
  • Two JSON refusals for anonymous spawns said "claim the forge and…"; they now say "open the forge as yours and…". They only answer a hand-made API request (the stranger's form never sends crew or a model key), but they were cheap to change.
  • I left one string alone: "already claimed" in the admin-only reissue API, which test/claim-link.test.ts checks. A stranger never sees it.

Checks: scripts/gate.ts, bun x tsc --noEmit and scripts/design-lint.ts pass. scripts/fast.ts named 1,907 test files because it counts this branch's whole diff, so I ran the ones that cover claim and spawn instead: stranger-words, claim-link, claim-revoke, claim-timing, first-login, start-claim, stranger-to-forge, spawn-keys and spawn-first-boot. 75 tests pass, 0 fail.

To try it, open /claim on a forge you made with a made-up code, or with a link that is used, expired, ended or already owned, and read the page and the passkey note.

🤖 Generated with Claude Code

Approved

Earlier asks: plan step banned word fixed and rendered in the test (met); claimed-forge helper split into startedForge/claimedForge (met); duplicate doc comment removed (met); test exports dropped (met). Since my last read: the /claim refusals and passkey note now come from one LINK_REFUSED table in plain words, the owned screen is reworded, door.ts JSON refusals no longer say claim, and a second test walks the link through unknown/revoked/expired/used/owned and a failed passkey, naming screen and sentence. Copy-only, no security surface changed, no README addition, design system untouched beyond words.

Two things I would do next:

  1. Non-blocking: the second test edits the user_setting spawn_claim row directly; give claim.ts a small test seam or use the real expiry/use paths so the test does not depend on the stored JSON shape.
  2. Non-blocking: the remaining admin-only "already claimed" reissue message is outside the stranger path, but the same banned-word test could cover the signed-in admin screens next.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs