P5-02 — Global shell utilities
Source: approved Phase 5 plan. This checkpoint follows P5-01 8e56cea; no route, provider, storage, backend contract, notification producer or command catalogue was added. F04 and P2-D01 remain open. P5-03 and B07 have not started.
Result and preservation
The six existing commands and existing job/company results now appear in labelled Actions and pages, Jobs and Companies groups. Search retains the owned API client and 250 ms debounce. One aborted request pair per query prevents old results from replacing newer results or appearing after the dialog closes/account changes. A failed request shows a Retry alert; it is never represented as an empty result. The existing no-match state appears only after successful search. Arrow Up/Down, Home/End and Enter work from the search field and result buttons; IME composition is ignored. Ordinary Tab, Escape, initial focus and MUI focus return remain intact. The result announcer changes after the debounced search settles rather than on every keystroke.
The existing bell retains the same recent-notification endpoint, read/dismiss mutations and /operations link. Loads are cancelled when closed or replaced, private items clear on close, and late mutation completions cannot update the next panel generation. Unread items now have a text label independent of their selected surface colour. A load error keeps its Retry action and does not show an empty inbox. Opening a notification still marks it read where needed; it does not complete a task.
| PRES contract | Existing behavior retained | P5-02 change | Evidence |
|---|---|---|---|
| PRES-E07 | Six actions/pages, exact job/company destinations, keyboard trigger, reviewed Add Job | Group and keyboard navigation; distinguish loading/error/empty | quick-command-preservation.test.tsx; real-App four-locale/theme utility journeys and existing command/dirty-navigation browser cases |
| PRES-E08 | EN/Bokmål, light/dark, dialog/feedback and focus | Localized groups/status and inherited semantic focus/colour | Type/lint/browser scans; four-mode screenshots and keyboard review |
| PRES-E09 | Authenticated session isolation and private-tree disposal | Abort/ignore stale command and bell responses | Deferred-response tests; existing B02/session suite and browser account-switch coverage |
| PRES-J03/J08 | Add opens review without POST; existing job/company/notification navigation | Presentation only | Existing no-write command test, exact destination browser test, job/operation route tests |
| PRES-S02 | Owner-local notifications, read/dismiss/operation link | Explicit unread label and stale-load protection | notifications-popover.test.tsx read/dismiss/link/empty/error/stale cases |
| PRES-W11/W12 | Existing operation links and task state | Bell still routes to /operations; no task completion side effect |
Existing notification/operation tests; synthetic browser read/dismiss probe |
The route/provider tree, API authentication, notification store, command actions, shell header triggers and domain workflows are unchanged. Existing rendering is retained and consolidated; there is no new command platform, Documents/CV search, task producer, email delivery or global AI assistant.
Verification and visual evidence
The inherited P5-01 baseline is backend 918, frontend 365, browser 70 actual passes + unchanged P2-D01 expected failure, rate-limit 9, ingress 6, PDF 1, configuration 3. Final P5-02 counts and commands are recorded below after the final code change.
| Check | Final result |
|---|---|
| Backend Release tests | 918/918 passed, zero skipped; unchanged from P5-01 |
| Frontend Jest | 373/373 passed across 77 suites; +8 focused cases (search failure/retry, close/account and query races, input/result keyboard operation, stale notification load/read navigation, notification failure/retry) |
| Complete Chromium browser | 74 actual passes + unchanged P2-D01 expected failure, zero unexpected/flaky cases; +4 four-mode utility journeys from P5-01. PLAYWRIGHT_STATIC_EXPORT=true PLAYWRIGHT_PREBUILT_EXPORT=true npm.cmd run test:e2e -- --reporter=list,json; accepted result .artifacts/p5-02-browser-accepted.json |
| TypeScript / edited E2E TypeScript / lint | Passed (npm.cmd run typecheck; E2E tsc --project ../.artifacts/p5-00-e2e-tsconfig.json --noEmit; npm.cmd run lint) |
| Frontend production build / API Release build | Passed; API Release build -warnaserror has zero warnings/errors |
| Rate-limit / ingress / PDF / configuration | 9 / 6 / 1 / 3 passed using their existing local Playwright configurations and python scripts/test-ingress.py |
| Secret / whitespace / documentation links | Tracked-secret scan and working/staged git diff --check passed; current/root Markdown links 134 documents, zero missing local targets (historical archive excluded) |
Supply-chain, model-evaluation harness and browser-extension local checks passed 3 / 5 / 3. These do not certify live external providers. Accepted backend TRX and frontend JSON reports are in ignored .artifacts/redesign-p5-02/ and .artifacts/p5-02-jest-accepted.json.
The final production-browser run and a focused repeat passed four utility journeys: light/English and dark/English at 1440px; light/Bokmål and dark/Bokmål at 390px. They exercised search outage, keyboard command activation, unread/read/dismiss and captured both utility overlays. Scoped axe scans of the command error and notification panel had zero violations; their incomplete nodes are not counted as passes. Eight final-build captures are under visual/. Direct review confirmed the light desktop error alert remains readable and the dark Bokmål phone notification panel fits below the app bar without covering its own actions. Manual screen-reader operation, zoom/forced-colour behavior and provider outage timing remain explicit validation gaps.
Acceptance status: conditional. The approved plan requires a manual screen-reader command and notification task, or explicit blocking of accessibility acceptance pending operator proof. Automated axe and keyboard tests do not substitute for that task. A Windows operator should use Narrator/Edge or NVDA/Chrome on the committed build: open search with Ctrl+K, hear the dialog/search name and settled count, move between grouped actions with arrow/Home/End and Tab, activate a job/company result, close with Escape and confirm focus return; open the bell, hear loading/error/unread state, then read, dismiss and open an operation link. Repeat representative English/Bokmål and light/dark states. Record the spoken names/order, any silent state transition, and screenshot or short recording with credentials hidden. Connor subsequently clarified that this remains a mandatory P5-15 accessibility acceptance item but does not block independent P5-03 Jobs work; no manual screen-reader pass is claimed here.
Remaining boundaries
- P5-00-D02 Jobs browser Back focus and P4-05-O01 localized table display still gate P5-03 acceptance.
- P4-04-O02 SQLite concurrent-write contention remains a separate backend reliability defect. P5-02 adds no polling or writes; browser probes use local synthetic accounts and no external provider.
- F04 requires production ingress evidence. P2-D01 requires native package proof. Neither is closed by this UI checkpoint.
- P5-05 quick preview stays deferred; P5-04b Table/Board parity, P5-08b native package proof and P5-09–14 CV revision/rendering proof retain their separate gates.
Rollback is limited to the two utility components, their localized labels, and tests; all existing routes and data remain valid.