oficina / estilo Public

Spec: carry local-mode return_to in a cookie; previews redirect to root

Addresses the delta review on #9: rastrillo auth.Verify lands on a fixed
SignedInPath, so return_to can't ride the emailed link. Docs reuses its
sealed return cookie at /auth/local/complete; standalone Docs chooses
its own cookie or /. Preview /apps/<slug> redirects to the root like
production, removing the dependency on the signed-in check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Paul Campbell pushed by paul@keymail.dev 49c7b01c8ce91bc6aa2d8f24f54dc740bff84bb7 parent 6520ab4
1 file changed, +23 −3
  • docs/superpowers/specs/2026-09-23-shared-chrome.md +23 −3

CI passed — run details

CI log
=== vet ===
CGO_ENABLED=0 go vet ./...
=== fmt ===
=== build ===
CGO_ENABLED=0 go build ./...
=== go-test ===
CGO_ENABLED=0 go test -count=1 ./...
ok  	amadan.net/oficina/estilo.git/callui	0.003s
?   	amadan.net/oficina/estilo.git/cmd/oficina-notices	[no test files]
ok  	amadan.net/oficina/estilo.git/credits	0.005s
ok  	amadan.net/oficina/estilo.git/credits/catalog	0.004s
ok  	amadan.net/oficina/estilo.git/homeconnect	0.004s
ok  	amadan.net/oficina/estilo.git/internal/lint	0.003s
ok  	amadan.net/oficina/estilo.git/savestatus	0.067s
ok  	amadan.net/oficina/estilo.git/theme	0.003s
diff --git a/docs/superpowers/specs/2026-09-23-shared-chrome.md b/docs/superpowers/specs/2026-09-23-shared-chrome.md
index e59cdd8..b83f983 100644
--- a/docs/superpowers/specs/2026-09-23-shared-chrome.md
+++ b/docs/superpowers/specs/2026-09-23-shared-chrome.md
@@ -671,7 +671,9 @@ it gates Docs:
- **(b)** `/apps/<slug>` honours the preview overrides the same way the
catalog does. When `appPreviewOrigins[slug]` (or
`docsPreviewOrigin` for Docs) is set, it redirects to
- `<preview origin>/signin`. The validation is the existing
+ `<preview origin>/`, the same root as (a), so (b) doesn't depend on
+ ยง9.4's already-signed-in check to avoid a needless exchange. The
+ validation is the existing
`validAppPreviews`.
- **(c)** The step-2 hop through the directory session stays. The
directory can't mint its own session without an assertion, and making
@@ -1192,8 +1194,26 @@ shows at once.
- Local mode: each app's own sign-in handler checks the session first.
Slides' `signin` (`auth.go:553`) is the one the audit caught; each
adopter checks its own.
-- **Local mode** carries `return_to` through Begin โ†’ emailed link โ†’
- Verify, falling back to `/`. Calls' join-link cookie path keeps working.
+- **Local mode** lands the person on the `return_to` they arrived with,
+ falling back to `/`. rastrillo's `auth.Verify` always lands on a fixed
+ `SignedInPath` and never reads `return_to`, so the value can't ride
+ the emailed link. It is carried in a short-lived, sealed, same-origin
+ cookie set on `GET /signin?return_to=` (after `SafePath`) and read at
+ the landing. Calls' join-link cookie path keeps working.
+ - **Docs** already has that cookie: `rememberReturn` stores
+ `__Host-oficina-docs-home-return` on `GET /signin?return_to=`. Its
+ local-link completion (`/auth/local/complete`) should default to
+ `returnPath(r)` instead of `/`, keeping `/account/home` first when
+ the link-start marker is present. **Do not** relax
+ `home_local_navigation.go`'s guard (it 303s to `/` on any query
+ string) to accept `?return_to=`. That is the wrong fix.
+ - **Standalone Docs** (no Home configured) builds no
+ `localLinkNavigation` and its `SignedInPath` is `/`. It gets a small
+ return cookie of its own with the same shape, or lands on `/`. The
+ Docs adopter picks one and records which in the branch discussion.
+ - The return cookies live 600 s. A link opened after ten minutes, or
+ in another browser, lands on `/`. That's intended, and the
+ Playwright gate below completes sign-in inside the window.
- **Docs has a documented reason on this path, so it's addressed, not
reversed silently.** `auth_navigation.go:55-56` says a destination
"never comes from return_to or another submitted URL". Read in