Final9a4dcd71ea852a0cc0843d260f22eb3a0d43f1b4 updates one pre-existing assertion freshness test to expect200 OAuth continuation instead of303; same ordinary/tampered/duplicate/expired intent scenarios retained. Original gate failure saved. All Home package tests pass; full finalgate in race phase (Home/operator race already pass), exact finalCI running. Eight local browser cases remain valid as production code unchanged since fixture. Immutable finalsource/review packet saved /home/paulca/.cache/oficina-home-keymail-continuation. Fable not invoked under current quota instruction; no merge/deploy.
Keymail sign-in continuation CSP fix open
On branch fix-keymail-oauth-continuation
Confirmed on main6bf0944: detected Keymail sign-in returned external303 after POST, while form-action permits only registered origins. Reuse Home chooser200 continuation with auto meta refresh and fallback link, shared App renderer, no CSP change. Preserve pending cookie and callback/second-factor/freshness flow. Baseline regression fails original303; focused tests pass. Eight synthetic browser cases Chromium/WebKit JS on/off auto/fallback pass, no referrer and pending cookie preserved. Full gate running; review packet pending Fable availability. No live email/OAuth, merge or deploy.
Final9a4dcd71ea852a0cc0843d260f22eb3a0d43f1b4 full make test PASS exit0, including all required race packages; exact finalCI success. Eight local Chromium/WebKit automatic/fallback JS on/off OAuth continuation cases pass with unchanged CSP/no-referrer/pending-cookie preservation. Worktree clean. Immutable source-final.tar, changes-final.diff, review-final-prompt.txt and candidate.json saved /home/paulca/.cache/oficina-home-keymail-continuation. Fable NOT invoked per quota instruction; branch remains unreviewed/unmerged/undeployed. Task48 bounded implementation/validation complete only.
APPROVE — fix-keymail-oauth-continuation, exact SHA 9a4dcd71ea852a0cc0843d260f22eb3a0d43f1b4 (base 6bf094416deebb3f29cbe21f820e2eae10091ab3). Reviewer model: claude-fable-5-1. Read-only; nothing written, run, merged or deployed.
Verified in source-final (matches changes-final.diff line for line)
internal/home/signin.go:213replaces the external 303 witha.renderContinuation(w, next.Redirect, "Continue to Keymail"). Pending cookie is still set first via unchangedsetPending. Classifier, callback,takePending,completeSignIn, passkey Gate and session minting are untouched.internal/home/continuation.gosetsCache-Control: no-storeandReferrer-Policy: no-referrerthen renders the existingdocs_continue.htmlwith status 200 through the buffered renderer.docs_chooser.go:155delegates to it with the fixed "Continue to Docs" label, so chooser destination and copy are unchanged.- Template change is title/heading/anchor text only; meta refresh and
referrerpolicy="no-referrer"anchor unchanged.SecurityPolicy()untouched; no provider origin added. next.Redirectissignin.Keymail.AuthorizeURL: fixedhttps://+ DNS-delegated host +/oauth/authorize?+url.Values.Encode(). Same trust boundary the old Location header had; the library README already calls it attacker-influencable and CSRF-gated, andapp.go:183keepscsrf.Protecton POST /signin.- No address or destination is logged or persisted by this delta.
Evidence
| Artifact | Result | |---|---| | baseline.log | new test fails on base with 303 (correct control) | | focused.log, home-test-final.log | internal/home ok | | gate-final.log | vet/build/test/race all ok, but carries no SHA marker | | ci-final.json | sha exact match, state: success, all 5 steps (vet, fmt, build, go-test, race) success | | results.json | 8/8 Chromium+WebKit, JS on/off, auto/fallback: arrived, no referer, no CSP errors, pending cookie present | | continuation.json | byte-identical to what renderContinuation + setPending + SecurityPolicy() emit; synthetic provider URL |
Findings (none blocking)
- Low:
docs_continue.htmlnow requires.Title; a future directrenderwithout it fails at execution (500), not at boot. Both callers go throughApp.renderContinuation, anddocs_continue_test.go:92covers the struct shape. - Info: The meta
contentattribute is HTML-attribute-escaped only, while the anchor gets URL-context escaping. Scheme is fixed and%22%3Csurvives escaped with noZgotmplZ(tested), so no new injection surface versus the 303. - Info: Back from the provider returns to a page that immediately refreshes forward again. Same usability limit the Docs chooser design records; the browser fixture did not exercise Back for this path.
- Info: The "CSP broadened" assertion in
keymail_continue_test.go:23compares a deterministic function before and after; thestrings.Contains(policy, stub.host)half is the meaningful check.
Scope limits
- source-final has no
.git, so tree-to-SHA binding rests solely on ci-final.json and the frozen tar name. gate-final.log alone does not prove the SHA. - Browser evidence is a fixture at the response boundary with synthetic
keymail.example.test; no live OAuth, mail, DNS, or real provider tested. - I could not write the requested plan file: no Write or ExitPlanMode tool is available in this session, and the deliverable is this verdict.
Preview deployment verified: immutable Home eabd7e1d234ed458b8b68f22ad895adffb5d5292 live on BOTH overnight-home-id.bds.oncarlos.com and overnight-home.bds.oncarlos.com, /api/version response body and X-Carlos-Version exactly match. OAuth9a review approved then mergedd4b; required ARM64 cast/build-gate followup20a Fableapproved/fullgate/exactCI passed, mergedeabd. Reviewed20a and mergedeabd share exact tree8a1c8bd271bdae405d372bc48a2f23b2442e4ac9. Correct cmd/home ARM64 versionstamped binary built from frozenarchive excludeschecker533. Named bds canary/overnight-home deployment only; host+environment scoped restarts after initial watcher timedout old asleep build, then realpageGET woke previews and final versions matched. Unsigned signin/Docs entry verified; no human mail/OAuth and no config/roster/operator activation. Evidence /home/paulca/.cache/oficina-home-keymail-deploy/deployment.json. What to see: detectedKeymail continuation auto-navigation/fallback link under unchanged CSP.