# P5-15 — human and device acceptance plan Planning-only P5-15-00, 2026-10-09; source `46a0c0c6d23464869f50c0d88552963c29cfdacf` on `codex/ui-redesign-phase4`. **Every human/device result below is NOT VERIFIED.** This file supplies executable acceptance scripts, not completed testing or a release verdict. No application/test change, test execution, live infrastructure/provider access, Docker operation, production action or semantic-model run occurred in this checkpoint. Production remains **NO-GO**; full Phase 5 acceptance remains **CONDITIONAL / PARTIAL**. The requirements come from [Phase 3 accessibility](../../phase-3/ACCESSIBILITY_PLAN.md), [responsive strategy](../../phase-3/RESPONSIVE_STRATEGY.md), [AI interaction contract](../../phase-3/AI_INTERACTION_MODEL.md), [P4-06](../../phase-4/p4-06/README.md), [P5 visual acceptance](../VISUAL_ACCEPTANCE.md), [P5-14](../p5-14/README.md), and the [57-group preservation review](../release-readiness/PRESERVATION_REVIEW.md). Follow the [debt register](READINESS_DEBT.md) for owners and closure proof. The mapped groups and retained routes are not an exhaustive coverage percentage. ## Evidence already available and its limits P4-06 retained 33 images, automated keyboard journeys and a manual in-app-browser UI/accessibility-tree observation. That observation was **not NVDA/Narrator acceptance**. P5-14 supplies final automated keyboard/pointer geometry, five new responsive journeys (one Chromium touch-emulation journey), 33 retained images, 117 actual browser passes, and scoped nested-drop/default-cancellation proof. The reproduced inaccessible return control, preview scroll loss and boundary-key failures have bounded successor evidence; their historical failed runs remain preserved. These sources are prior evidence, not fresh P5-15 execution. Actual physical touch/drag, software keyboards, human spoken names/live announcements, mobile screen readers, 200%/400% browser zoom, forced colors, text spacing and deployed Linux/font/photo behavior remain **NOT VERIFIED**. A screenshot, accessibility-tree inspection, emulated tap or automated key press does not fill those gaps. The 320px CV's 34% automatic fit is an overview; legible reading of the document still needs acceptance. ## Axe incomplete census and triage Derived by reading every `scans` entry in [P5-14 axe JSON](../p5-14/evidence/axe-summary.json), rather than copying a historical aggregate: `len(scans) = 242`; `sum(len(scan.violations)) = 0`; and `sum(len(rule.targets) for every scan.incomplete rule) = 1,839`. A target array is one node occurrence, including iframe selector paths. Repeated scans and selectors are **occurrences, not unique issues**. Zero reported violations does not mean incompletes passed. The JSON sets `incompleteAccepted=false` and `humanScreenReaderAcceptance="open"`. No check was run here. | Rule | Incomplete node occurrences | Recorded contexts | Action and acceptance boundary | |---|---:|---|---| | `color-contrast` | **1,574** | Badges, Jobs filters/table/card actions, CV tabs/fields/undo tooltips, shell/menu text and preview iframe headings; all 16 scanned browser files | **Manual visual/computed-color review. Potential serious readability issue** if active text/control/focus is below the Phase 3 target. Measure actual settled rendered foreground/background, overlays, disabled explanations, hover/focus and document ink separately in light/dark. Hidden badges, CSS/iframe backgrounds and transition states can exceed automation's ability to calculate contrast; demonstrate why a specific node is inactive or review it, never dismiss all occurrences as false positives. Ordinary text target 4.5:1, large text 3:1, essential controls/focus 3:1. | | `aria-hidden-focus` | **34** | `#menu-` 16, modal-isolated `#root` 12, `.MuiPopover-root` 4, `.MuiDrawer-modal` 2; company/command dialogs, CV/settings menus, phone row menus and Dashboard menu | **Potential serious focus/AT isolation problem.** Inspect each open/closed/entering/exiting context: Tab and virtual cursor must not reach hidden background or dismissed controls; focus must remain visible in the active modal and return to its trigger. Modal isolation or mounted exit content is a context to investigate, not proof of correctness. Do not remove `aria-hidden` to make a scan green. | | `aria-prohibited-attr` | **209** | Named tooltip `span` wrappers for CV Undo/Redo (158 EN/NB occurrences), checklist Move up/down/not-relevant and Delete wrappers, Board empty chip, notification paper | **Semantic/AT investigation; potentially serious when the actionable name is lost or misleading.** Inspect rendered role/name and both wrapper and inner button, including disabled controls. Current `CvBuilderEditor` and checklist source place names on inner buttons; Tooltip can contribute wrapper attributes. Confirm the human hears the actionable name once with correct disabled state. Notification paper/Board chip names need their own role/name review. The summary omits raw check messages, so it cannot establish harmlessness or a required code fix by itself. | | `aria-valid-attr-value` | **18** | Command dialog paper in populated/empty/error states: `.MuiPaper-elevation24` 14, `.MuiPaper-rounded` 4 | **Potential serious dialog relationship issue.** Inspect actual attributes and each referenced ID while open and after query/state changes. `QuickCommandDialog` supplies a paper `aria-label` without a `DialogTitle`; inspect MUI's rendered relationships rather than guessing from the generated selector. Human must hear a named dialog and search field, state/result count and selected result. The collected JSON does not retain the offending value/check details; obtain them during the authorized reproduction. | | `th-has-data-cells` | **4** | `table-density.spec.ts`, `list-error-*-axe`, `table`, one per theme/locale | **Automation/context limit with manual table review required.** The failing-load table may retain headers without data cells. Read error/Retry once and check the unloaded table is not presented as populated. Then load rows and verify header-to-cell associations, sort/selection/action names in both densities. Empty/error context is not proof that loaded-table semantics pass. | | **Total** | **1,839** | **242 scans, 0 reported violation entries** | All five rule dispositions remain **OPEN / NOT VERIFIED** pending contextual proof; no unique-defect count is asserted. | Record a result per source file + case + state + target + theme/locale. Deduplicate only after inspection establishes the same root cause; keep the original occurrence census. Retain raw rule/check messages locally during future reproduction, with no cookies/private user text in committed evidence. A verified hidden/decorative node can receive a bounded disposition; it cannot close sibling contexts or the whole rule. ## Execution matrix and recording rules Use an authorized isolated synthetic fixture with account A/B, an admin and non-admin, a Free/locked and eligible account, empty and populated Jobs, custom statuses/long Norwegian titles, source/sibling CVs, a long multipage CV, attachments/frozen package and safe dirty drafts. Real provider sends, production mutations, model qualification and deletion activation require their separate authorization. Fault-state scripts use bounded local failure/held-request fixtures; their results establish UI handling only. Never substitute an empty shell for loaded content. Run each numbered script in **EN and Bokmål × light and dark × desktop, tablet and phone**: 1440×900, 768×1024 plus 1024×768, and 390×844 plus 320 CSS-px reflow. Record actual dimensions, not just device names. Inspect just below/above 768, 899/900 and 1023/1024 for shell/editor transitions; add 844×390 landscape for CV and long dialogs. Cover 430px phone, 1280px laptop and 1920px wide when their distinct layout is exposed. A variant not executed stays NOT VERIFIED; a representative sample cannot be labelled the full cross-product. Desktop screen-reader lane: a human using NVDA or Narrator on Windows, with exact browser/OS/AT version and browse/focus mode recorded. Physical mobile lane: an actual phone/tablet, actual browser, software keyboard and VoiceOver or TalkBack. At least one supported alternate desktop browser is a separate compatibility lane. Select devices at the authorized execution checkpoint; unavailable access remains an explicit gap. For each run retain: script/step, SHA/build, route/query, fixture/state, locale/theme, viewport/zoom/input/AT/version, exact actions, expected and observed result, pass/fail/not-verified, screenshot or short sanitized video/AT transcript, target/debt link, reviewer/date and retest result. Record defects before rerunning; passing reruns do not erase intermittent failures. A human signs their own AT/device result; an assistant cannot fill it. No public accessibility certification follows from these scripts. ## Numbered manual scripts ### M01 — AppShell and route continuity (PRES-E07/E08/E09) 1. Sign in as A, wait for real data, inspect landmarks/headings with the screen reader; use the skip link and hear one main and the correct route heading. Open each grouped destination, confirm current-page/parent semantics and route-heading focus. 2. Collapse to rail, reload, resize to phone, open drawer and Tab through labels/actions; close with Escape and verify trigger return. While drawer is open resize to desktop and back. Inspect long admin badge separately. All focused targets must be visible and hit-testable below the actual fixed header. 3. Use browser Back/Forward and legacy links from the [route mapping](../../audit/ROUTE_MAP.md); preserve route/query and meaningful return focus. Open account/theme/language menus with keyboard and AT, choose a value and verify announced selection and close/return behavior. 4. Logout A, sign in B, then return A; check shell counts, command/notification content and drafts are not A's while B is active. A delayed result or session change must not repopulate private stale content. **Expected:** accessible equivalent destinations, visible focus and retained owner boundary. **Status: NOT VERIFIED.** ### M02 — Commands, notifications and operation destinations (P5-02-D01) 1. Open Ctrl/Cmd+K and the visible search control. Hear dialog/search names, grouped results and selected result; use arrows/Home/End/Enter, ordinary Tab and Escape. Enter a Norwegian query and IME composition where available. Keep focus visible through entry/exit animations; repeat the P5-04b-R01 timing path. 2. Exercise loaded results, no result, delayed query A→B, error and Retry, then close during loading. Hear loading/count/error without repeated announcements on every keystroke; late/aborted results must not reappear. Keyboard activation must navigate once and return/focus meaningfully. 3. Open bell/popover; hear unread state, title/message/date and distinguish Open, Mark read and Dismiss. Use keyboard/AT through loading/empty/error/retry/busy states and Escape. Mark read must not complete the underlying task; dismiss must not delete the underlying job. Open View all and confirm existing `/operations` owner and content. 4. Reopen during a delayed read/action and switch account/expire session. **Expected:** correct names, state announcements, accessible scroll, no focus theft or stale private output. **Status: NOT VERIFIED; mandatory P5-15 human gate.** ### M03 — Jobs Table, cards, Board and Trash (PRES-J05–J08/W01) 1. At desktop/tablet use Comfortable/Compact table: hear column/sort state, role/company/status/applied/deadline, selection and named row actions. Sort/page, filter search/status/company/readiness and inspect same committed result set. Select a row without opening it; invoke row link/action explicitly. 2. At phone verify cards expose the same information/actions with localized names, long/custom statuses and dates. Open action/filter menus/sheets; cancel draft filters and keep prior committed results. Save/apply a supported filter and switch Table↔Board; retain URL/query/history and selection lifetime as documented. 3. Open a job then explicit Back and browser Back; wait for load and verify originating row focus is visible. Exercise empty/no-query-match/loading/error/Retry and partial bulk-failure: retain failed IDs and retry only the intended action. 4. On Board read all columns, including custom/Other; use an exact-status menu or keyboard alternative to move a card. Read the resulting status/order and verify persistence; native pointer drag is an additional lane. Scroll columns without losing actions. Test Trash restore through a disposable fixture, with focus/error feedback. **Expected:** equivalent tasks without mandatory dragging or color-only meaning. **Status: NOT VERIFIED; physical Board drag and full-array scaling are separate debt.** ### M04 — Dashboard and Analytics (PRES-S01/S02/J09) 1. Load populated/empty/fresh-account states, read snapshot/window captions, population/sample/period, current statuses and source limitations. Compare chart text/values tables to fixture values using AT; exact values cannot require hover or color. 2. Open each values disclosure/legend and keyboard drill-down; confirm Jobs membership and return. Toggle each of five existing owner-local Dashboard visibility flags; reload and switch A/B/A to verify retention/isolation. Do not expect Phase 8 ordering/resizing/cross-device persistence. 3. Trigger an independent report error while others remain loaded; hear error/Retry once, retain available reports and verify no misleading zero-success metric. Change language during reads in the separate reliability probe (M07); do not silently count a failed native preference save as correct persistence. **Expected:** truthful reports and reachable independent actions. **Status: NOT VERIFIED.** ### M05 — Job workspace header, Overview and deeper sections (PRES-W01–W11) 1. Open an owned job via list, Board, compatibility alias and deep query; read role/company/status/date context and actions. Traverse the seven current sections: Overview, Match, Application, Documents, Timeline, Notes & tasks, Interview. Within Application visit CV/Letter/Answers/Submission; within Timeline visit Activity/Correspondence. Exercise legacy section aliases and the existing numeric 0–9 route helper (these are helper arguments, not `section=3` URLs); retain query/history and `followMode` metadata. Mode-specific compose UI is deferred, not an expected feature. 2. Read progress and next-task destinations; keyboard-scroll the named progress strip. Traverse description/analysis/match, notes/checklist, documents/attachments/submitted package, cover letter/answers, interview preparation and communication/timeline. Verify disclosure/region names, heading hierarchy and text alternatives. 3. Edit a long draft, change section/viewport and try to navigate away; review dirty confirmation, Cancel/Stay and explicit discard/save. Error must retain draft and identify the failed action. Reorder checklist with named alternatives and confirm moved-item focus, spoken target/order, busy/error state and persistence. 4. Rename/purpose/delete a disposable attachment using prompt/confirmation; check initial/trapped/return focus and Shift+Tab-to-Delete (P5-07-O01). Read frozen submitted material after editing current sources; do not send mail. **Expected:** retained domain/dirty/source boundaries and accessible deeper tasks. **Status: NOT VERIFIED.** ### M06 — Complete implemented CV editing→preview→history→export (PRES-C05–C12) 1. Open current variant with canonical Career Profile and a sibling readback. Hear source versus CV-only overrides and inclusion/hidden states; edit a field, custom section, entry title and long rich text. Use section navigation/expand, add/remove controls and named entry/section reorder alternatives. The moved item keeps meaningful focus/order; canonical and sibling data stay unchanged. 2. Exercise native pointer entry/section reorder, cancel, and unsupported foreign/cross-section/text/title drop separately; source order, foreign editable title and persisted content must remain unchanged for unsupported drops. These P5-14 scoped automated cases do not certify every physical/browser gesture. 3. While a safe local save is held, switch Edit/Preview and resize through 320/390/768/899/900/1024/1440 and 844×390. Draft/save owner remains intact. Keyboard enters the named preview, PageDown/Home/End/Ctrl+Home/End scroll its document, including at start/end, without moving the outer page unexpectedly; Tab exits, return-to-editor is visible below shell, and focus returns to the right field. 4. Read first/middle/last pages and preview status in loading/error/Retry; last-good content/scroll remains while stale page counts are not announced. Assess 320px fit readability by zoom/scroll; a fit thumbnail does not satisfy readable document text. Inspect one-page/long documents and keyboard escape from each iframe. 5. Use templates/locked capabilities, accent/fonts/photo, A4/Letter, margins/density/dates/document-language controls; hear labels/help/reset effects, retain inclusion/content, and separate UI language from document language. Undo/Redo and history restore use the existing revision owner; a stale conflict keeps draft/downloadable local copy until explicit reviewed reload. 6. Export private/public PDF using the safe fixture; compare page/content/order and non-ASCII text, fonts/photo, page size and print against actual preview and retained numerical corpus. Do not publish real data. **Expected:** complete implemented workflow and scope preservation. **Status: NOT VERIFIED; production font/photo/manual print and other-browser lanes remain separate.** ### M07 — Settings, company dialogs and shared form failure paths 1. On Settings use desktop tabs and phone selector, heading/label/help/error relationships, dates/selects and independent Save actions. Keep a long Norwegian rule draft through resize. Trigger local rules-save failure, retain draft, hear durable error, retry explicitly, read back and reload; record P2-O01 if it recurs. 2. Save notification preferences; wait for the actual PUT response before readback, then separately reproduce overlapping reads/writes in an authorized disposable API probe. A 500 is a failure, not a retry-success pass. The known SQLite error-5 contention remains open even if the sequential human flow succeeds. 3. Change language, check actual server response, reload and reauthenticate/read persisted preference. Current `I18nProvider.setLanguage` applies local UI/storage first and ignores failed PUT; surface this discrepancy in evidence. A localized screenshot cannot prove successful persistence. No runtime diagnosis is claimed here. 4. Open a company form from retained navigation/command results; trigger a safe failed save while modal is active. Inspect label, draft, initial/trap/return focus and visible/spoken error. P4-02-D02 currently puts transient feedback outside the accessible modal; if the error cannot be heard/recovered it stays failed. Inspect notification/rules/config/provider/disabled deletion explanations, without enabling billing/deletion/providers. **Expected:** truthful save state, actionable in-context errors and retained drafts. **Status: NOT VERIFIED.** ### M08 — Untouched destinations through redesigned entry points 1. Use shell/commands/job/CV links to retained Career Profile, CV library, Companies, Reminders, mail, Connected Accounts, Operations, account/security and admin-only routes from [ROUTE_MAP](../../audit/ROUTE_MAP.md). Confirm entry/current heading/return/access denial without claiming those pages were redesigned. 2. For each accessible destination sample loaded/empty/error, main landmark, long labels, keyboard scroll, route/query and A/B separation. Read charts/permission/last-admin warnings if present; no private aggregate data may leak to a denied user. 3. Verify existing privacy/Free/locked/unavailable controls have meaningful names and explanations, manual fallback and no false success; no provider operation is implied. **Expected:** new shell/header/theme/dialog composition preserves existing destinations. **Status: NOT VERIFIED; Phase 7 redesign remains out of scope.** ### M09 — Screen-reader forms, dialogs and async announcements (cross-screen) 1. With the real AT running, repeat M01–M08 at loaded names/actions, headings/landmarks, tables/regions and modal boundaries; record exact spoken text and reading order. A role/name inspection alone cannot pass this step. 2. Exercise validation on required text, dates, autocomplete/select and long rich-text fields. Hear label, required/error/help association and retain the draft. Check each current form against the proposed Phase 3 error-summary/first-invalid-field focus target; record missing or unsupported behavior as an acceptance gap, not an existing capability. Inspect duplicate/missing references in all five incomplete-rule contexts above. 3. Open nested dirty confirmation, prompt, row menu and add-content dialog in their actual owners. Verify one active modal trap, initial focus, Tab/Shift+Tab, Escape policy, trigger return and no hidden/invisible focus targets during exit. Repeat the command and attachment focus observations rather than relying on earlier passing reruns. 4. Hold/load/fail/save/retry/import/render within local fixtures. Hear busy, completion and actionable failure once at the appropriate time, with no focus theft or false completion after an error. Notifications/report refresh must not announce every keystroke. Honor reduced motion while retaining outcomes. **Status: NOT VERIFIED.** ### M10 — Browser zoom and text spacing (cross-screen) 1. Use actual browser zoom at **200% and 400%**, not viewport emulation, at a recorded starting desktop size; repeat primary M01–M08 tasks and 320 CSS-px reflow. Inspect menus/dialogs/dirty errors/long NB labels and actions, not just body overflow. Intentional Board/table/document scrolling must be named; ordinary content must not need sideways scrolling. 2. In a bounded local test apply text spacing: line height 1.5× font size, paragraph spacing 2×, letter spacing 0.12× and word spacing 0.16×. Repeat forms, loaded tables/cards, Dashboard captions, workspace disclosures and CV chrome; restore afterwards. No clipped/overlapping text, lost function or unreachable Save/Cancel/error. 3. Test Tab/focus scroll at top/bottom, wrapped header and sticky footers. Keep focused field/action visible beneath shell and within dialog; scroll preview independently. **Status: NOT VERIFIED; screenshots at narrow width cannot pass these steps.** ### M11 — Forced colors, contrast and motion (cross-screen) 1. Enable actual OS/browser forced-colors mode and repeat M01–M08 primary navigation/forms/actions. Confirm visible focus, borders/selected/current/error/inclusion states and non-color status meaning; icons and disabled explanations remain understandable. 2. Measure the settled active text/control/focus contexts from the 1,574 contrast occurrences in both modes, including hover/focus/selected/busy/error. Review photos/document colors separately from app theme. Retain ratios and target screenshots; do not assume every hidden badge or iframe incomplete is a defect or a pass. 3. Enable reduced motion, repeat drawer/menu/dialog/reorder/load completion and confirm no information depends on animation. Inspect focus during normal transitions too. **Status: NOT VERIFIED.** ### M12 — Physical touch, software keyboard and orientation 1. On actual phone/tablet repeat M01–M08 primary tasks with touch: drawer/command/bell, filters/cards/Board, Dashboard values, job sections and CV editor/preview/settings. Record physical device/input; Chromium `hasTouch` is inherited emulation only. 2. Open software keyboard in long NB text/date/select/search/rich-text fields, near document/form bottom and inside add-content/dirty dialogs. Scroll to help/error and Save/Cancel; neither keyboard nor sticky shell/footer may cover focused field/action. Dismiss/reopen keyboard and keep draft/caret/focus. 3. Rotate portrait↔landscape with dirty/held-save CV draft and open long dialog; retain pane/section/scroll/order and reachable preview/editor return. Test touch selection without accidental drag; try actual entry/section and Board drag/cancel, then named reorder/status alternatives. Unavailable native drag remains separate from passing alternatives. 4. With VoiceOver/TalkBack, read names/order, activate menus/dialogs/reorder/preview and verify loading/error announcements and focus return. **Status: NOT VERIFIED; emulation cannot fill any physical/AT step.** ### M13 — Deferred AI acceptance return script (blocked, do not execute now) 1. Only after the [P5-13 return conditions](../OPEN_BLOCKERS.md#p5-13-deferred-debt-and-return-conditions--2026-10-08) pass and review UI is implemented, exercise Current/Proposed/Sources, explicit target, compare/edit/Accept/Reject/Close/Regenerate and short/long diff in the entire matrix. 2. Verify insert/delete meaning without color, keyboard/AT review, original retention on failed/unavailable/locked/cancel, fresh-source rejection, no stale/account-switched Apply and no automatic save/send. Keep output language separate from UI language. 3. Complete actual configured-model identity, **366 uncached required calls** and human output reviews under the frozen corpus/rubric; deterministic mock review/no-write tests are separate. **Status: BLOCKED / NOT QUALIFIED / NOT IMPLEMENTED; 0/366 calls, 0 human reviews.** No fabricated UI/synthetic pass may replace this step. ## Closure rule A script passes only when its actual matrix rows and required human/device lane have dated evidence with no unresolved preservation regression. Missing lanes stay NOT VERIFIED. Confirm each incomplete context or file a scoped defect with owner/exit proof. Re-run affected regressions after an authorized fix; this planning checkpoint authorizes none. Full Phase 5 cannot receive unconditional GO while mandatory manual or P5-13 scope remains unmet; production safety uses its separate checklist in [READINESS_DEBT](READINESS_DEBT.md#production-readiness-operator-checklist--prepared-not-executed).