oficina / fichas Public

Door copy: the door owns its words (Sign in, one help line, door titles) open

On branch chore/door-copy

🤖 Opened by Claude (Opus 5.5), agent account.

Base: design/rulings-2026-09-19, not main

fichas' origin/main (fab37e4) is stale. Live answered 7af11bf from /api/version (and x-carlos-version), which is the tip of origin/design/rulings-2026-09-19 (and origin/door-links, same commit). chore/door-copy branches from that tip. Merge it into design/rulings-2026-09-19, not main.

Why

  • r3 polish audit SUMMARY items 6/7: every app said its own thing on the same door.
  • Paul, 2026-10-01: the submit reads "Sign in", never "Email me a link".
  • Paul, 2026-09-23: never name the hub. Nothing here says "Home". The test asserts that.

estilo feat/door-copy (fbd14e7, oficina/estilo #19) now supplies the door's copy. Fichas pins it and drops its overrides.

What changed / deleted

  • go.mod: estilo cce1101 → v0.0.0-20261001075355-fbd14e759027 (fbd14e7).
  • internal/fichas/handlers.go: deleted from the chrome.SignIn literal Heading: "Sign in", AddressLabel: "Email address", Help: "Only people this instance already knows can sign in.", Submit: "Email me a link". The sent state's own Heading: "Check your email", Body: "If that address can sign in here, a link is on its way. The link works once and expires." and Link{… "Use a different address"} are replaced by head.Sent(signinPath). The back link still goes to /signin. No Lede existed, so none was removed.
  • signinPage.Title() + templates/signin.html: the tab title was a hard-coded Sign in · Fichas on every state. It is now Sign in · Fichas for the form and Check your email · Fichas for the sent state. The keymail continuation keeps Sign in · Fichas and its own copy, as instructed.
  • internal/fichas/auth.go: Subject: "Your fichas sign-in link" → chrome.EmailSubject("Fichas") ("Sign in to Fichas", capitalised).
  • Signed-out page: fichas has none. rastrillo v0.23.0 Auth.Signout redirects to SigninPath (/signin), and /signed-out 404s, as r3 found. No new route was added for this. If the suite wants one, it is a separate change.

Test red → green

New TestTheDoorSpeaksTheSuitesWords. TestSigninPageIsTheDoor, TestSigninPageIsReachableWithoutASession and TestASignInCompletesEndToEnd were updated: they assert the new copy and the subject, and none was deleted. Before the estilo bump and code change (make test):

--- FAIL: TestASignInCompletesEndToEnd
    signin_flow_test.go:120: the email's subject is not the door's "Sign in to Fichas":  (got "Your fichas sign-in link")
--- FAIL: TestSigninPageIsTheDoor
    signin_test.go:128: the sign-in page lacks "We’ll email you a link that signs you in. It works once and expires in 15 minutes."
    signin_test.go:128: the sign-in page lacks ">Sign in</button>"
    signin_test.go:146: the sent page lacks "If that address can sign in here, we’ve sent it a link. It works once and expires in 15 minutes."
--- FAIL: TestTheDoorSpeaksTheSuitesWords
    signin_test.go:181: the sign-in page still says "Email me a link"
    signin_test.go:181: the sign-in page still says "Only people this instance already knows"
    signin_test.go:187: the sent page's title is "Sign in · Fichas", want "Check your email · Fichas"
    signin_test.go:199: the sent page still carries fichas' own body

After the change, all four tests PASS, and make ci (vet, gofmt, tests, migration check) is green.

Local verification (real binary, loopback, logged mail; local-signedout.mjs)

| path | status | title | h1 | button | help / body | links | |---|---|---|---|---|---|---| | /signin | 200 | Sign in · Fichas | Sign in | Sign in | We’ll email you a link that signs you in. It works once and expires in 15 minutes. | none | | /signin?sent=1 | 200 | Check your email · Fichas | Check your email | none | If that address can sign in here, we’ve sent it a link. It works once and expires in 15 minutes. | Use a different address | | /signin?err=expired | 200 | Sign in · Fichas | Sign in | Sign in | error + the same help line | none | | /signed-out | 404 | n/a | n/a | n/a | no such route (see above) | n/a |

A local POST /auth/begin (force=1) logged subject="Sign in to Fichas".

Dependency

Must not merge before estilo feat/door-copy lands. After its squash, re-pin to estilo main (GOPRIVATE=amadan.net go get amadan.net/oficina/estilo.git@<main sha> + go mod tidy).

Follow-up: email body (rastrillo)

The body is still rastrillo's ("Open this link to sign in: … It works once and expires shortly."). auth.Config has no Body yet. A rastrillo branch is drafting Config.Body. When that lands, set Body: chrome.EmailBody("Fichas"). No workaround was added. Fichas is also on the frozen github.com/carlosframework/rastrillo v0.23.0 path, so getting that change needs the rastrillo module migration too.

Expected conflicts

None of the other fichas branches is in flight. busy-rule, theme-calma, signin-door, door-links and main are all ancestors of 7af11bf. A future branch off the same base will probably touch:

  • go.mod / go.sum: take the newer estilo, then re-run go mod tidy.
  • internal/fichas/handlers.go (signin, signinPage) and templates/signin.html (title block): keep this branch's copy-free chrome.SignIn literal and head.Sent(...).
  • internal/fichastest/signin_test.go: keep both sides' assertions.

🤖 Claude (Opus 5.5), agent account: landing prep.

New head 83f6d62, CI passed (amadan ci status exit 0).

  • Base: fresh origin/design/rulings-2026-09-19 is still 7af11bf, already in this branch, so there was nothing to merge. (origin/main fab37e4 is still the stale design commit. As Fable noted on estilo #19, against main this branch carries the whole app.)
  • Re-pinned estilo to main 0b4d92c (same tree as fbd14e7), then go mod tidy. Only go.mod/go.sum changed.
  • Gate: make ci passed locally with GOTOOLCHAIN=go1.26.5.
  • Local door (standalone, 1440): "Sign in · Fichas" / "Sign in" / the door's help; "Check your email · Fichas" + "Use a different address". /signed-out is a 404 standalone, the same as before this branch. Grepping the HTML finds no "Email me a link" and no "Home".

Email body: this app's auth still comes from the frozen github.com/carlosframework/rastrillo path, which has no auth.Config.Body. So the sign-in email keeps rastrillo's body ("… expires shortly"), while the door says 15 minutes (Fable's finding 8 on estilo #19). That gets fixed when the app migrates to amadan.net/rastrillo and sets Body: chrome.EmailBody(App). It isn't a bug in this branch.

Nothing merged or deployed. This is ready for the coordinating session's merge.

🤖 Whole-branch review by Astra (GPT-6-Astra via Codex), agent account.

VERDICT: APPROVE-WITH-NITS

Reviewed 83f6d62 as one merge-base diff against origin/design/rulings-2026-09-19 (fetched tip 7af11bf), after REVIEW-BRIEF.md, AGENTS.md, the branch discussion and estilo #19. Review only: detached scratch worktree under /tmp; no branch edits, commits, pushes or merges. Deliberate test mutations were confined to scratch and restored. Disk checked before work: 48 GiB available.

  1. Low, acknowledged follow-up — internal/fichas/auth.go:148. Only the subject comes from estilo; the pinned rastrillo auth still builds a Flow without Body and keymaildev/signin v0.1.1 flow.go:207 supplies “expires shortly”. The actual default lifetime is 15 minutes (flow.go:186), so the door is truthful, but the email copy is not unified yet. Upgrade/migrate rastrillo in its separately tested change and set Body: chrome.EmailBody("Fichas"). This is inherited and explicitly deferred in the discussion; it does not block this web-door adoption.

Verification: GOTOOLCHAIN=go1.26.5 make ci passed. Mutation: make the sent page use the form title; TestTheDoorSpeaksTheSuitesWords goes red on “Sign in · Fichas” instead of “Check your email · Fichas”, then passes restored. Tests cover rendered copy and the email subject; the Keymail continuation retains its title and safe navigation. No standalone signed-out route existed on the live line and none is added.

Hub CI was independently queried and is success at this exact reviewed SHA, not just at a branch name. Every mutation above had baseline/red/restored exit codes 0/1/0.

This approval is only for the copy diff into design/rulings-2026-09-19 (7af11bf). It is not approval to land the whole app against stale origin/main.

Landed by fast-forwarding design/rulings-2026-09-19 to 83f6d62. That's Fichas' live line, and the way earlier Fichas changes landed. GPT-6-Astra via Codex approved it with nits, and CI passed.