Public: anyone can read this; the crew can change it.
A sign-in flow's expiry sentences live in one module, read by the parent sign-in and an app's scaffold #5602
Check · Review · Land · Live done — Landed and live in production.
The two sign-in failure sentences, "This sign-in did not start in this browser." and "This sign-in took too long or was already used.", now live in one new module, `src/kernel/signin_words.ts`, as `SIGNIN_NOT_THIS_BROWSER` and `SIGNIN_EXPIRED`. No existing module owned words like these, so the module is new.
shipped production is serving it deploy e36361f
The two sign-in failure sentences, "This sign-in did not start in this browser." and "This sign-in took too long or was already used.", now live in one new module, src/kernel/signin_words.ts, as SIGNIN_NOT_THIS_BROWSER and SIGNIN_EXPIRED. No existing module owned words like these, so the module is new.
What moved:
src/http/rp.ts: the parent sign-in's callback imports both constants, at its two refusals.src/apps/scaffold.ts: the sentences sit inside the template for the generated app'ssignin.ts, which can't import from the forge. So the template fills them in with${JSON.stringify(...)}, which writes the same double-quoted text as before. I dumpedscaffoldFiles(...)before and after the change and the output is byte-identical.
grep -rn for either sentence under src/ now finds only the new module. No wording changed, and only the import lines and the lines carrying the sentences were touched.
The new test/signin-words.test.ts checks that each exported sentence is non-empty. It also reads rp.ts and scaffold.ts as text and fails if either stops importing the module or contains a sentence typed out again.
Checks run: bun x tsc --noEmit is clean. The new test and the existing tests for both files (forge-signin, forge-signin-signup, linked-signin, parent-link, signup-gate-parent, scaffold, scaffold-webspec) pass, 46 of 46, none edited. src/web/ is untouched, so design-lint was not needed.
To try it: bun test test/signin-words.test.ts, then type either sentence back into src/http/rp.ts and it goes red.
🤖 Generated with Claude Code
The two sign-in failure sentences, "This sign-in did not start in this browser." and "This sign-in took too long or was already used.", now live in one new module, src/kernel/signin_words.ts, as SIGNIN_NOT_THIS_BROWSER and SIGNIN_EXPIRED. No existing module owned words like these, so the module is new.
What moved:
src/http/rp.ts: the parent sign-in's callback imports both constants, at its two refusals.src/apps/scaffold.ts: the sentences sit inside the template for the generated app'ssignin.ts, which can't import from the forge. So the template fills them in with${JSON.stringify(...)}, which writes the same double-quoted text as before. I dumpedscaffoldFiles(...)before and after the change and the output is byte-identical.
grep -rn for either sentence under src/ now finds only the new module. No wording changed. The new test/signin-words.test.ts checks that each exported sentence is non-empty. It also reads both files as text and fails if either stops importing the module or contains a sentence typed out again.
A second commit fixes a limit the first one ran into. parseShardSpec in scripts/shards.ts only accepted shard numbers up to three digits. The new test file is the gate's 999th, so the audit test in test/shards.test.ts asked for slice 1000/1000 and was refused. The parser now takes up to four digits, and test/shards.test.ts has one new line checking that 1000/1000 parses. The failing test itself was right and is unchanged.
Checks run: bun x tsc --noEmit is clean. test/shards.test.ts passes (69 tests), as do the new test and the existing tests for both files I moved the sentences out of (46). src/web/ is untouched, so design-lint was not needed.
To try it: bun test test/signin-words.test.ts, then type either sentence back into src/http/rp.ts and it goes red.
🤖 Generated with Claude Code
Clean, and it does what #5585 asks. Both sentences now live once in src/kernel/signin_words.ts. rp.ts imports them. The scaffold template fills them in with ${JSON.stringify(...)}, which inside the template literal writes the same double-quoted literal into the generated app's signin.ts, so the generated app still has no import back into the forge. Security is unchanged: no new input, no new output path, the messages are constants, and the state/cookie checks around them are untouched. The preview answers / with 200, and /signin/parent/callback?state=x&code=y with no state cookie still says "This sign-in did not start in this browser." The source-text test is the guard the issue specified and goes red if a copy is typed back. The parseShardSpec widening to four digits is outside the issue but needed (the gate audit asks for slice 1000/1000 once this file lands), it is explained in the pull, and it is covered by the new 1000/1000 assertion. The terminal and README are not affected: this changes no behaviour.
The two sign-in failure sentences, "This sign-in did not start in this browser." and "This sign-in took too long or was already used.", now live in one new module,
src/kernel/signin_words.ts, asSIGNIN_NOT_THIS_BROWSERandSIGNIN_EXPIRED. No existing module owned words like these, so the module is new.What moved:
src/http/rp.ts: the parent sign-in's callback imports both constants, at its two refusals.src/apps/scaffold.ts: the sentences sit inside the template for the generated app'ssignin.ts, which can't import from the forge. So the template fills them in with${JSON.stringify(...)}, which writes the same double-quoted text as before. I dumpedscaffoldFiles(...)before and after the change and the output is byte-identical.grep -rnfor either sentence undersrc/now finds only the new module. No wording changed, and only the import lines and the lines carrying the sentences were touched.The new
test/signin-words.test.tschecks that each exported sentence is non-empty. It also readsrp.tsandscaffold.tsas text and fails if either stops importing the module or contains a sentence typed out again.Checks run:
bun x tsc --noEmitis clean. The new test and the existing tests for both files (forge-signin,forge-signin-signup,linked-signin,parent-link,signup-gate-parent,scaffold,scaffold-webspec) pass, 46 of 46, none edited.src/web/is untouched, so design-lint was not needed.To try it:
bun test test/signin-words.test.ts, then type either sentence back intosrc/http/rp.tsand it goes red.🤖 Generated with Claude Code
Closes #5585