P7-01 — Authentication and account-security presentation
Status: public authentication sub-slice CONDITIONAL GO; account-security implementation/acceptance PENDING. This is the bounded execution/acceptance plan from the approved handoff. P7-00 27c54146ad6f9059295d169b533db7b1b6689210 is pushed and direct development/localHEAD/origin equality verified at2026-10-11 14:44:45UTC; main unchanged and worktree clean at entry. Its baseline and ledger satisfy entry. No new routes, identity/provider protocols or capability activation are included. Public source/results below are measured before their commit; the parent records its push receipt separately. This sub-slice does not complete P7-01.
Baseline and bounded commit scope
The inherited accepted runtime baseline is backend1,033, frontend521/85, ordinary browser159, sidecar49 and separate existing security/HTTP/fidelity lanes. P7-00 performed fresh identity/routes/matrix/static checks only. New affected runtime evidence begins here; every count delta must identify actual added/removed cases and avoid adding focused subsets to full totals.
| Coherent commit boundary within P7-01 | Existing source owners | Allowed presentation scope / exclusions |
|---|---|---|
| Public authentication | Login/Register, Forgot, Reset, Verify/email-change, Microsoft relink | Reuse existing shared page/forms/state/error patterns; coherent headings/names/labels/focus, responsive layout and translated feedback. Preserve safe from/query/hash/state, remember-me, registration/verification/token/Turnstile/2FA and provider exchange semantics |
| Account identity/security | Profile, AuthStatus, 2FA, Sessions | Shared theme/section hierarchy, honest status/error/retry, dialog-local failure, locale dates and long metadata reflow. Preserve identity-only profile payload/local preference ownership, avatar/crop/remove, email confirmation/password, recovery/trusted-device/current-session/revoke semantics |
| Shared provider consumers affected by either boundary | Google, Microsoft | Real consumers are LoginPage sign-in presentation and ProfilePage account-link presentation. Prove both after shared changes; preserve link password, popup origin/state, cancellation/no-exchange, safe return and unlink guards. Mailbox grants remain separate |
The exact checkpoint remains P7-01; these are reviewable commit boundaries, not additional phases. Account changes follow the public-auth commit to avoid conflicting shared-provider edits. Keep existing save/fetch/security owners; no dead-code cleanup or backend concurrency/provider redesign hidden in presentation.
Read-only source findings to reproduce before repair
| Observation at entry | Bounded correction candidate / required proof |
|---|---|
| TwoFactorSettingsCard status GET catches failure into null; null then selects Enable2FA action as though disabled | Distinct pending/known/failed status and deliberate retry; no misleading enabled/disabled assertion or setup action while unknown. Request counts, known enabled/disabled branch and failure→retry readback tests |
| Sessions revoke-others failure sets the global error rendered outside the still-open confirmation dialog | Durable alert inside that dialog, retained confirmation/retry/cancel and focus; no background-isolation workaround or automatic resend/revoke |
| AuthStatus signed-in sentence is a literal English sentence; account/security/provider dates use host-default locale | Existing i18n interpolation/natural EN/NB wording and explicit UI-locale date formatting; test actual two locales with fixed timestamps and shared provider presentations |
| Account child card headings default from typography variant; shell already owns page h1 and Profile has explicit contextual headings | Use existing section primitives and explicit contextual levels/names; prove loaded full hierarchy and preserve field/action names. Do not add a second h1/main |
| Profile load/avatar/remove/save/password errors still use raw response/message stringification, while email-change paths use shared helper | Reuse getApiErrorMessage with translated caller fallback and structured server explanations where reproduced; retained draft/local state and deliberate successful recovery. Do not change payload/save semantics |
| Trusted-device/session metadata uses absolute secondary-action list layout | Verify long device names/dates at320/390 and keyboard/zoom before any reflow repair; source layout alone is not measured overflow evidence |
Installed MUI Dialog generates aria-labelledby and DialogTitle inherits its ID. Missing explicit ID props alone do not establish an unnamed-dialog defect; actual named-dialog/description/focus/error tests determine whether a repair is required. Preserve recovery confirmation before dismissing codes, password/code clearing and no automatic sensitive action on entry.
Required automated and native evidence
| Scope | Existing anchors / additions needed |
|---|---|
| Local auth and safe navigation | Login tests, Verify tests, native auth return/expiry. Exercise login/register/reset/verify/relink loaded/error/expired/used-token states, remember-me, recovery/rate-limit and unsafe/nested return rejection without route/protocol changes |
| Account identity versus Career | Profile tests, native account isolation. Add identity-only save payload/readback, no canonical Career/CV/sibling write, local-only vs external read-only rules, pending email request/cancel/password failure/retry and owner-switch disposal |
| 2FA status/confirm/recovery/devices | 2FA tests currently cover enable→recovery and wrong-password disable. Add unknown/error/retry, known status, recovery acknowledgment/clear/cancel, trusted-device error/revoke and actual named modal trap/return; no real authenticator qualification claim |
| Sessions and sign-out | Add focused real Sessions/AuthStatus tests for load failure/retry, remote vs current revoke, canceled revoke-others/no-write, failed confirm within modal and deliberate retry/readback. Preserve clearAuthClientState/private-tree disposal with session-boundary tests |
| Shared providers | Current Login tests exercise real Google/Microsoft components under mocked external exchange; Profile tests mock Google. Add real account-link/unlink presentation/negative-path coverage so Login success cannot stand in for Profile compatibility. No actual provider call without separate authority |
| Responsive/localised/accessibility | EN/NB, light/dark,320/360–390/768/1024/1280/1440/wide representative states, long labels/device names, actual relevant zoom, keyboard/focus/errors/loading/retry and dialog state. Capture DOM names, root overflow, screenshot and axe contexts; use current theme/page/i18n owners |
Use owned synthetic fixtures and actual mutation/no-write/readback assertions. Run appropriate affected unit/native tests, app/browser TypeScript, lint/build and finite docs/secret/whitespace checks. A broader full runtime gate is required at P7-12; extra runs here need a new change/failure/unresolved concern. Preserve ordinary P2-D01, existing auth/tenant/AI/frozen/output guards and original PDF oracles.
Acceptance and remaining gates
- Public/auth and account commits have bounded diffs, real consumer regression, exact commands/results/count deltas, source identity and retained intermediate failures. Commit/push each completed unit and record immediate direct remote=HEAD in the ledger.
- Existing32 routes/aliases/search/history/state remain; no weakened authentication/authorization, canonical mutation, duplicate provider exchange/save owner or silent sensitive-action semantics change.
- EN/NB/theme/responsive names/headings/error/retry/focus behavior is verified in actual representative native states, with axe incomplete/violation contexts retained rather than disabled.
- Applicable E01–E06/E09 and shared E07/E08 plus S03 boundaries remain in the 57 matrix. Finite scoped repairs do not upgrade whole groups without missing mandatory evidence.
- Actual mail/OAuth/Turnstile/authenticator/device/reader results and M01–M12 remain explicit when unavailable. M13/P5-13 remains deferred do-not-execute. Keep all debt, production NO-GO and main unchanged; no Phase8 customization.
Public authentication implementation and acceptance
The public evidence manifest records the fresh final commands, source/export identity, all 61 affected unit assertions, 22 native assertions, two isolated SMTP workflows, 22 all-enabled axe attachments, exact geometry, image hashes and retained intermediate attempts. Public UI runtime files are copied to the immutable .artifacts/phase7/p7-01/public-final/ snapshot before account runs reuse the runner lanes; affected-unit/backend artifacts retain their unique original paths. Only manifest file references were rebased: raw reports retain original absolute execution/attachment paths internally, and commands, times, results and measured SHA256 values are unchanged. Portable PNG references resolve to the snapshot. The six public source files use UTF-8/LF normalization so their hashes remain stable when Git stages LF. The manifest is written with LF; no commit hash is inferred from its own contents.
The five existing view owners now use AuthPageFrame, the existing PageHeader/theme spacing and a bounded 520px form width. Each public page owns one named main landmark/H1. Recovery forms have durable page feedback, labelled local validation, focus on the failed field, retained input and explicit resubmission. Verification/email-change loading and success have named dynamic status; invalid/missing token pages retain a usable recovery action. Long action labels wrap at narrow widths. Existing route, command, token, Turnstile, remember-me, provider and safe-return owners remain in place.
Visual review of the first passing export found registration describing its password as “Current password.” Two ordinary password-intent unit cases reproduced the mismatch; registration now uses the existing “New password”/“Nytt passord” key while preserving new-password autocomplete. The final export and native/recovery runs below include that repair. No new translation key or hard-coded product string was required.
| Fresh bounded evidence | Observed final result | Scope / count explanation |
|---|---|---|
| Affected public Jest files | 61/61, four suites, zero failure/pending | Existing Login33 and Verify4 retained; Microsoft relink1→2; new public-presentation22. Compared with the inherited affected38 cases, +23 cases/+1 suite. This is not a fresh full frontend run |
| Ordinary public native pack | 22/22, zero skip/flaky/unexpected/retry | Fifteen finite presentation samples, two keyboard recovery/prefill/validation workflows, three real invalid-token HTTP400 workflows and two failed-login→explicit-success/return-context workflows. Fresh2026-10-11 18:40:40–18:41:10UTC |
| Isolated actual Identity + loopback SMTP pack | 2/2, zero skip/flaky/unexpected/retry | Missing-token/no-write plus real registration202, delivered verification link204, invalid link400, password-reset delivery/reset204/replay400, old password/session rejection and protected return. Fresh18:41:10–18:41:23UTC; separate from the22 ordinary cases |
| Loopback SMTP fixture helper | 6/6, zero fail/cancel/skip/todo | Fragmented commands/dot stuffing, envelope reset, oversize rejection, quoted-printable UTF-8, folded base64 and unsupported-MIME handling. Separate tooling cases |
| Backend auth/security subset | 87/87, zero failed/not-executed | Auth/session/local identity/context/2FA/email-ownership/authorization contracts at unchanged backend source; a subset of inherited1,033, not an additive total |
| App and browser TypeScript, lint, production frontend build | All exit0 | Final sequence18:40:04–18:40:39UTC; lint retains zero-warning policy. Browser config contents and command/log hashes are portable in the manifest |
Authoritative final build ID is rd_SQeVLwVwER9VMCc6XL. Canonical public six-file source digest is b330b233508ad5202a1f622ade4464103f7a986ee53648c8f16047f2a1d32586; the manifest records each file and its precise ordered digest algorithm. Static export74 files have measured raw-file digest dff031a52740a09359715a31456c9cec70f5aae6f9932c018af078215e973d67. These identify the tested public working tree, not a newly deployed or remotely pushed identity. P7-00 remains the recorded entry commit until a successor push receipt is recorded in the ledger.
Responsive, localisation and visual evidence
The native pack actually covers EN/NB and light/dark across320,360,390,768,1024,1280,1440 and1920px; the 1280×320 registration sample exercises short landscape height. It includes ready, registration-disabled, missing-link, local-validation, actual HTTP400 and actual HTTP401 states. Each of22 scans records one H1, named main and exact visible-control geometry; root/main overflow is0 throughout and visible controls remain within viewport tolerance. Public forms have no density control, so Comfortable/Compact is explicitly not applicable here. This is a finite sampling plan, not every route×theme×language×breakpoint combination, physical orientation or browser zoom acceptance.
The parent opened the eight exact final presentation-matrix PNGs with view_image: login NB/dark320; registration NB/light390 and NB/dark1280×320; forgot EN/dark360; reset EN/light320; verify NB/dark390; email-change EN/dark1024; Microsoft relink EN/dark1440. Final registration images visibly say “Nytt passord.” The reviewed samples have calm shared framing and reachable/wrapped labels/actions, with no new observed app-chrome overflow. The manifest records those eight exact raw PNG hashes. Other workflow screenshots were captured and hashed; individual visual inspection is not claimed for them.
The22 all-enabled axe scans contain 0 violation nodes and31 incomplete nodes, all color-contrast. Every retained check says the background could not be determined because another element overlaps it. Contexts include outlined empty/filled form inputs and two primary-button nodes in failed-login states. Exact targets, HTML, check IDs/messages/data, context and geometry are retained in the manifest; complete raw attachments remain embedded in the hashed native report. Reflow and zero reported violations do not prove contrast. M11 must qualify contextual contrast/forced colors; M09 must qualify spoken names/errors/state and possible duplicate route/error announcements. Browser zoom, human screen reader and physical/software-keyboard qualification remain unverified. No axe tag/rule was suppressed to obtain these results.
Frontend-owned copy uses the existing EN/NB keys. Actual invalid-token responses include existing server-authored English “Invalid or expired link.”/“Invalid email or token.” in NB samples; this is retained as a localisation qualification, not presented as translated server feedback. Actual external OAuth, Turnstile and production email delivery remain unqualified; the SMTP run uses the real application mail/Identity path against an owned local capture server, not an external service.
Retained failures and preservation
The first SMTP attempt passed0/2 because strict alert selectors also matched the established route announcer. The second passed1/2 because the fixture expected direct login where the protected-route handoff actually opens the existing Landing page. Scoped-main alert assertions and following that actual Landing handoff fixed the test assumptions; no product change was made for these failures. The third passed2/2 before the label repair, and the fresh final run passed2/2 after it. Their reports/logs/command records and whole output folders are retained under .artifacts/phase7/p7-01/public-final/attempts/; the manifest resolves archived attachment paths to their retained folders rather than later output files.
Intermediate public unit attempts are also retained, including the59-case run with one failure, the later59/59 run, and the password-label diagnostic RED with1 pass/1 failure/20 unselected pending cases. The final61-case affected run has zero pending/failure; diagnostic testNamePattern selection is not used for final acceptance. The first passing22-case public native run remains historical evidence and did not excuse the visually identified label defect.
The finite public checks preserve E01–E06/E09 and E07/E08/S03 boundaries, exact safe return/query/hash handling, real token failure/replay and old-session rejection. Backend routes/protocols and established link/exchange guards are retained. All 57 groups remain56 PARTIAL + C11 DEFERRED, and all32 routes remain retained with their existing qualifications. No whole-group upgrade or fresh full frontend/backend/browser/fidelity acceptance is inferred from these subsets. Ordinary P2-D01 remains required by the inherited baseline and future integrated gate; it was not rerun in this public pack.
Public sub-slice acceptance is CONDITIONAL GO for its completed development commit, with M01–M12, server-error language/reader/contrast/provider qualifications and inherited debt carried. Production remains NO-GO, main unchanged; M13/P5-13 remains deferred do-not-execute. Commit/push/remote receipt and finite hygiene checks are recorded by the parent in the ledger before account product work proceeds.
Account/security acceptance is PENDING: five new account-presentation RED cases and12 real-provider cases are prepared (eight existing provider behaviors pass; four provider presentation cases fail), plus six meaningful native account cases not yet executed. The parent owns those product repairs and the later fresh affected build/native evidence. This public result neither completes P7-01 nor changes the approved checkpoint order.