diff --git a/docs/redesign/phase-2/TRACEABILITY.md b/docs/redesign/phase-2/TRACEABILITY.md index 06ac752..97b960b 100644 --- a/docs/redesign/phase-2/TRACEABILITY.md +++ b/docs/redesign/phase-2/TRACEABILITY.md @@ -1,6 +1,6 @@ # Redesign traceability -Successor planning checkpoint: [Phase 3 impact matrix and architecture](../phase-3/PRESERVATION_IMPACT_MATRIX.md). It maps all 57 contracts to proposed destinations/validation, without changing their requirements or claiming implemented/visual parity. The subsequent [P4-01 trace sheet](../phase-4/p4-01/TRACEABILITY.md), [P4-02 named-control/modal record](../phase-4/p4-02/README.md) and [P4-03 preview keyboard record](../phase-4/p4-03/README.md) link shared foundation changes to regression and representative visual evidence. P4-04 remains unstarted. +Successor planning checkpoint: [Phase 3 impact matrix and architecture](../phase-3/PRESERVATION_IMPACT_MATRIX.md). It maps all 57 contracts to proposed destinations/validation, without changing their requirements or claiming implemented/visual parity. The subsequent [P4-01 trace sheet](../phase-4/p4-01/TRACEABILITY.md), [P4-02 named-control/modal record](../phase-4/p4-02/README.md), [P4-03 preview keyboard record](../phase-4/p4-03/README.md) and [P4-04 Settings layout/typography record](../phase-4/p4-04/README.md) link shared foundation changes to regression and representative visual evidence. P4-05 remains unstarted. Phase 2 starts at `2d0f131`. The [preservation matrix](PRESERVATION_MATRIX.md) is the stable baseline: **PRES-E01…PRES-A03**, in the original ledger's groups (not one contiguous numeric range). Old references such as C07 remain valid aliases. Subdivide a later workflow with a suffix, for example `PRES-C07.override-reset`; do not reuse an ID or silently change its meaning. diff --git a/docs/redesign/phase-4/README.md b/docs/redesign/phase-4/README.md index 1f27435..bd0980f 100644 --- a/docs/redesign/phase-4/README.md +++ b/docs/redesign/phase-4/README.md @@ -6,5 +6,6 @@ Phase 4 starts from `f696f23` on `codex/ui-redesign-phase4`. The 57 preservation - [P4-01 preservation and visual evidence](p4-01/TRACEABILITY.md) - [P4-02 named controls and modal state](p4-02/README.md) - [P4-03 builder preview keyboard boundary](p4-03/README.md) +- [P4-04 page layout and typography primitives](p4-04/README.md) -P4-02 is locally validated after `115441a` and the separate documentation restructure `682a302` on the same Phase 4 branch. P4-03 follows the P4-02 checkpoint `ebd4a3e`, adding preview keyboard access and preserving focused panes through viewport transitions. P4-04 remains unstarted. No route/layout redesign, CV margin/template rendering correction, B07, backend/schema behaviour changes or production deployment is included. F04 remains open pending actual production ingress evidence. +P4-02 is locally validated after `115441a` and the separate documentation restructure `682a302` on the same Phase 4 branch. P4-03 follows the P4-02 checkpoint `ebd4a3e`, adding preview keyboard access and preserving focused panes through viewport transitions. P4-04 follows `806eee4e`, introducing opt-in shared page/section typography and layout with Settings as the sole consumer. Its baseline is 916 backend / 348 frontend / 47 actual browser passes plus unchanged P2-D01 expected failure. P4-05 remains unstarted. No broader page migration, CV margin/template rendering correction, B07, backend/schema behaviour change or production deployment is included. F04 remains open pending actual production ingress evidence. diff --git a/docs/redesign/phase-4/p4-04/README.md b/docs/redesign/phase-4/p4-04/README.md new file mode 100644 index 0000000..87e8ff4 --- /dev/null +++ b/docs/redesign/phase-4/p4-04/README.md @@ -0,0 +1,181 @@ +# P4-04 — Page layout and typography primitives + +Implemented and locally validated on 2026-09-12 from `806eee4e1ea44cd15c75cc73467b1101a7bd8d2c` on `codex/ui-redesign-phase4`. Settings (`/settings`) is the only representative consumer. The commit containing this record is the P4-04 checkpoint (`git log -- docs/redesign/phase-4/p4-04`). P4-05, Phase 5 migration and B07 have not begun; no production deployment was performed. F04 remains open. + +Approved sources: [P4-04 scope](../../phase-3/PHASE4_IMPLEMENTATION_PLAN.md), [design system](../../phase-3/DESIGN_SYSTEM_ARCHITECTURE.md), [component architecture](../../phase-3/COMPONENT_ARCHITECTURE.md), [responsive strategy](../../phase-3/RESPONSIVE_STRATEGY.md), [accessibility plan](../../phase-3/ACCESSIBILITY_PLAN.md), [preservation impact](../../phase-3/PRESERVATION_IMPACT_MATRIX.md) and the [57-contract baseline](../../phase-2/PRESERVATION_MATRIX.md). + +## Selection and implementation boundary + +Settings exercises heading/description, independent sections/actions, bounded reading width, desktop tabs/mobile selector, preferences, loading/error and permission-dependent controls. Its subcards have no other production callers. Existing save handlers and endpoint contracts do not require refactoring. Inspection found an h5 shell title, non-heading section labels, nested padding and 240px minimum form widths. Retain the existing route, tab state/unmount behavior, independent requests and all controls. The shell opts only this route into the new header/width contract; other pages retain their existing presentation. + +Use current Archivo/system fonts, semantic palette and focus treatment. Introduce opt-in MUI page-title/section-title/description variants rather than globally resizing legacy headings. Alias bounded reading/data/editor widths beside the existing theme gutter/section variables. Consolidate repeated section presentation into a small PageSection; it does not own requests, drafts or saves. Settings has no page-wide transaction: keep its save actions in their existing sections, with no invented global Save. Test the shared optional header action layout with a non-production component fixture. + +## Preservation impact recorded before implementation + +All IDs retain their complete Phase 1/2 contracts. The following are directly affected or contained within the Settings consumer; no source/resource or permission semantics change. + +| PRES IDs | Existing behavior → P4-04 change | Existing automated evidence / additional proof | +|---|---|---| +| E07, E08 | Same route, sidebar, header utilities, theme and EN/NB → opt-in semantic h1 and theme typography; responsive page/section rhythm | sidebar-active-nav, theme-state/contrast, i18n-provider, P4-01/02 browser; add real Settings loaded/reflow/keyboard evidence | +| S03, J05, W11 | Independent table/theme/language/rules/notification settings → same controls within shared layout | settings-view (failed save/retry, scenario payload); redesign-preservation browser (resize draft, native save); add table/theme callback proof before edits | +| S04 | AI privacy, usage, billing availability → same state owners in named sections | settings-view, ai-usage-card, server privacy/entitlement tests; loaded zero-usage/locked and failure browser states | +| S05 | Export/encrypted backup/deletion safeguards → section heading/action wrapping only | account-data-export and server export/backup/deletion suites; browser no-data export and disabled deletion access | +| J10, J04 | CSV/JSON tools and capture bookmarklet → retained nested controls and headings | csv-export, capture tests and existing CSV browser; no serializer/capture edits | +| M06 | Connected account navigation → action retained in its section | email-provider-connections and new actual Settings navigation check; provider connectivity remains unverified | +| E09 | Account identity governs all requests/caches → unchanged private tree and B02 context | account-isolation browser and server session-boundary regressions | + +High-risk saving and lifecycle behavior already has focused tests. Before presentation changes, the added independent table/theme callback case and the existing Settings, usage, CSV and account-export cases passed: 13 tests in four suites. The final checkpoint adds presentation/real-browser evidence rather than rewriting these owners. + +## Shared architecture and changed files + +- [PageLayout.tsx](../../../../job-tracker-ui/src/layout/PageLayout.tsx): two small compositions, `PageHeader` and `PageSection`, and the `PageWidth` union. Header text wraps without truncation; optional actions wrap independently. Sections have generated heading IDs and semantic `section`/h2/h3 structure. Neither headings nor noninteractive sections acquire tab stops. A section is plain by default; Settings explicitly requests the existing semantic paper surface/base theme radius. No mandatory nested card, data fetching, form state or new provider is introduced. +- [theme.ts](../../../../job-tracker-ui/src/theme.ts): opt-in `pageTitle`, `sectionTitle`, `pageDescription` MUI typography variants and three page-width CSS aliases. Existing palettes, focus overrides, legacy typography variants, Archivo/system font stack, provisional hue and font hosting are unchanged. `mui-theme.d.ts` replaces `theme.d.ts`: the old declaration filename collided with `theme.ts` and TypeScript omitted it from the compilation. Giving it a distinct name enables the new variant augmentation while retaining P4-01 palette declarations. No tsconfig weakening or `as any` workaround was added. +- [App.tsx](../../../../job-tracker-ui/src/App.tsx): only the Settings description and opt-in `pageLayout="reading"` prop for `/settings` and its existing trailing-slash equivalent. Query strings, route declarations, auth/providers, global actions and navigation handlers are untouched. +- [AppShell.tsx](../../../../job-tracker-ui/src/layout/AppShell.tsx): the optional page-layout prop selects shared width/header styling. The existing main/gutter, toolbar, breadcrumbs, sidebar, drawer, user menu and their handlers remain. **Other routes still use their old width and title markup.** Connected Accounts is not migrated by the `/settings` opt-in. +- [SettingsView.tsx](../../../../job-tracker-ui/src/components/SettingsView.tsx): remove local SectionCard duplication and the second outer padded Paper; use shared section spacing, headings and shrinkable preference columns. Preserve desktop tabs/mobile selector and their tab state. The desktop tablist gains a translated name distinct from the existing mobile selector. Connected Accounts uses the shared section-header action slot, wrapping below the description on narrow screens; its route/callback is unchanged. +- Settings-only subcomponents `AiPrivacySettingsCard`, `AiUsageCard`, `QuickCaptureCard`, `RulesSettingsCard`, `BackupCard` and nested `ImportExportJobs`: replace repeated section presentation/heading markup. Usage plan metadata occupies the header's trailing slot. No API call, payload, entitlement, download, serialization, bookmarklet, confirmation or save implementation changes. +- `i18n/translations.ts`: one truthful Settings description in English and Bokmål. No new font or final branding choice. +- Tests: new `src/page-layout.test.tsx`, one additional `src/settings-view.test.tsx` case and new `e2e/settings-page-layout.spec.ts`. The inherited `e2e/redesign-preservation.spec.ts` Settings case now explicitly awaits/asserts the notification PUT before its existing readback/reload checks; the separately discovered SQLite contention is documented below. Documentation: this record/evidence, Phase 4 index, Phase 2 trace link and active TODO status. + +### Typography and rhythm + +| Role | Opt-in value / responsibility | +|---|---| +| Page title | h1 semantics; 24/30 px equivalent on phone, 28/34 from 768px; weight 700; rem sizes | +| Section title | h2/h3 chosen by hierarchy; 18/24 px equivalent, weight 600 | +| Description | 14/20 px equivalent, weight 400, semantic secondary text; at most 75ch; long words may wrap | +| Reading width | 60rem, matching Settings' existing nominal 960px cap; header and body now align | +| Data/editor aliases | 82.5rem / 100%; future opt-in contracts only. No table/editor migrated or certified here | +| Page gutters | Existing 16/24/32px theme variables; owned once by the shell | +| Sections | Existing 24px section gap; 16px header/content gap; optional surface uses existing 16/20px card padding and base theme radius | + +No global body/legacy-heading resize, new palette, motion, density preference or competing token system. The first visual review caught the MUI numeric radius multiplier creating overly rounded new sections; using the existing base radius corrected that before the complete checkpoint. Section grid alignment also avoids distributing spare vertical space inside unequal-height columns. + +## Regression and visual method + +The two component tests prove full localized heading names/semantic levels, independent actions, disabled actions, nonfocusable sections and unmodified `ViewStateNotice` loading/error/retry/empty transitions. The new Settings callback test protects separate table-size, column and theme changes without backend preference writes. + +Four real Chromium workflows cover **light/English, light/Bokmål, dark/English and dark/Bokmål**, each through desktop and phone. Each creates its own non-admin account in the disposable local API database, uses real authentication/B02 context and blocks outbound browser traffic. No production/provider credentials or services are used. + +Coverage includes: + +1. Loaded real Settings: one h1, named section headings, actual zero-usage Free state and unavailable external AI. The zero-usage state is not a simulated provider success. +2. 1920/1440/1024/768/767/390/320px General reflow; 320/390/768/1024/1440px rule editing without losing the draft. The overflow oracle checks actual ordinary descendants against the main/viewport edges, so the inherited body overflow rule cannot disguise clipping. +3. A synthetic long English/Bokmål title at 320px to stress wrapping. Only title text is substituted in the test; no CSS injection, hidden controls or production fixture route. Reload restores actual copy. +4. Keyboard mobile-section selection and focus return. Existing initial rules error/re-entry recovery, followed by native scenario save; the native API confirms the changed value. +5. Held notification read/skeleton in the same page layout; one injected local 503 save failure preserves the unchecked draft; explicit retry persists it and reload proves it remains saved. Initial validation showed that error clearance alone was insufficient save proof because it occurs before request completion. The permanent oracle waits for the exact PUT response and checks its status before reading persisted state; the separate backend contention evidence is retained below. +6. Backup headings/actions at 320px, actual no-job account ZIP download and server-disabled deletion. Existing unit/server tests retain recent-auth, exact confirmation and enabled deletion coverage; no destructive browser operation is attempted. +7. Real Connected Accounts navigation through the responsive section action, inherited keyboard outline, and continued non-admin API denial. Provider connection functionality itself remains under its existing tests and operational gap. + +The shared header's optional page action uses the same composition as the real Connected Accounts section action. Settings has no artificial top-level Save button. Component tests also exercise a long localized page-action label. All screenshot data is synthetic; authenticated traces and databases remain ignored. + +## Intentionally retained debt and Phase 5 implications + +- This is a single Settings-page migration. Secondary navigation reorganisation, moving account/security sections, new settings routes, shell/sidebar redesign, command expansion and the other pages remain Phase 5+ work. P4-05 density has not begun. +- Initial notification/AI-privacy load failures still use their existing error/skeleton behavior; no new retry or completion-announcement contract is claimed. Rules reload through existing section re-entry. Unsaved rules still unmount when deliberately changing sections, as recorded in Phase 2; viewport changes retain them. Shared layout must not silently invent draft persistence. +- Existing import file-label keyboard semantics, full JSON roundtrip, encrypted restore, enabled paid-account deletion, provider connectivity/billing and real delivery require their separately scoped evidence. The CSV serializer and B01–B05 controls are unchanged. +- Existing P2-D01 expected failure, P4-02-D01–D04 and P4-03-D01 remain explicit. CV margins/templates/pagination correctness is dedicated later work. No unrelated accessibility suppression or defect fix is included. +- **P4-04-O01 — existing fixed-toast overlap:** visual review observed the export-success toast covering the bottom Connected Accounts action briefly. `toast.tsx` and its placement/timing are unchanged. The final fixture waits for normal dismissal, then checks the focused button receives hit testing before capture. This is not a claim that all transient toast overlap is repaired; review shared feedback placement with the later shell work. +- **P4-04-O02 — existing SQLite notification-save contention:** concurrent request evidence and investigation are recorded below. The backend and application save handler are unchanged. Do not claim concurrent preference writes/reads are reliable based on the sequential preservation fixture; investigate in a separate backend reliability ticket without folding it into P4-05. +- Browser viewport/keyboard and axe evidence do not certify Narrator/NVDA, real mobile touch/software keyboards, screen-reader behavior, browser 200%/400% zoom or forced colors. Those remain manual validation gaps. Data/editor width aliases still need their actual consumer fixtures before adoption. +- **F04 remains open:** no deployed ingress, firewall, DNS or TLS evidence was collected. Feature-branch push does not deploy or close it. +- Phase 5 can opt each reviewed consumer into the header/width/section contract, preserving its domain state and adding its own tests. Do not enable the new header globally or migrate the provider tree as a side effect. + +Rollback is limited to this presentation/test slice and restoring the declaration filename if reverting the entire change. There is no schema, storage format, package, CI, infrastructure or backend-contract change. + +## Final verification + +| Validation | Inherited P4-03 baseline | P4-04 result | +|---|---|---| +| Backend Release regression | 916 | **916 passed**, zero failed/skipped | +| Frontend Jest | 345 | **348 passed in 74 suites**: two new shared-composition cases and one independent Settings-preference case | +| Full Chromium suite | 43 actual passes + P2-D01 expected failure | **47 actual passes + unchanged P2-D01 expected failure**: four new Settings workflows, no inherited test removed or reclassified | +| Final focused Settings repeat | Not additional cases | **4 passed**, the same four cases repeated after strengthening post-scroll focus hit testing | +| Account/IP rate-limit HTTP | 9 | **9 passed** | +| Production-mode ingress HTTP | 6 | **6 passed** locally; does not close deployed F04 | +| Shared PDF admission HTTP | 1 | **1 passed** | +| Effective Compose/config adversarial checks | 3 | **3 passed** | +| TypeScript | Pass | **Pass**, standalone frontend and the additional scoped E2E type check | +| ESLint | Pass | **Pass**, zero warnings allowed | +| Frontend production build | Pass | **Pass**, Next static production export used by the browser runs | +| API Release build | Pass | **Pass**, zero warnings/errors with `-warnaserror` | +| Additional repository checks | Existing gates retained | Supply-chain tests **3**, Ollama evaluation harness tests **5**, extension tests **3**, all passed | +| Repository hygiene | Pass | Tracked-secret scan, working/staged whitespace and local Markdown targets passed; **120** current/root Markdown documents checked, historical archive excluded | + +The full backend suite includes the existing B01 destination, B02 account/session, B03 admission, B04 partition and export coverage. The frontend/browser suites retain B02 switching, CSV safety and the existing CV/public-PDF flows. No application, backend, package, CI or infrastructure change followed these baseline runs. Browser-only refinements strengthen response synchronization and screenshot/focus proof. The final complete browser run uses both the new fixture and the explicitly sequential inherited Settings check described below. + +Playwright's list summary counts the expected failure as a successful test outcome. The JSON [SCAN_RESULTS.json](SCAN_RESULTS.json) explicitly records **47 `passed → passed` and one `failed → failed`**, not 48 successful workflows. P2-D01 still reaches the existing SQLite submitted-package failure; its historical-binary follow-on proof remains blocked. + +### Rendered review and accessibility evidence + +The final four Settings cases produced **36 synthetic screenshots**, **60 geometric reflow checks with zero out-of-bounds nodes**, and **20 full tagged axe scans with zero violations and no rule/element exclusions**. All 20 scans contain incomplete contrast checks; `aria-hidden-focus` also appears as incomplete. These remain review items, not automated passes. Raw incomplete details are retained in [SCAN_RESULTS.json](SCAN_RESULTS.json). Representative rendered images were inspected for hierarchy, density, wrapping, semantic surfaces, secondary-text readability and unclipped keyboard focus in both themes/locales. + +| PRES IDs → preserved behavior | Automated evidence | Representative rendered evidence | +|---|---|---| +| E07/E08 → Settings route, theme/language and existing navigation | Four new browser cases: one h1; EN/NB; 320–1920px reflow; keyboard section selection/focus return; non-Settings route retained | [Desktop light/NB](visual/general-1440-light-nb.png), [desktop dark/EN](visual/general-1440-dark-en.png), [phone dark/EN](visual/general-390-dark-en.png), [phone light/NB](visual/general-320-light-nb.png) | +| S03/J05/W11 → independent preferences, rule draft survives resize, native save/retry/reload | New preference unit case; Settings browser API readback; inherited settings-view/redesign-preservation coverage | [Long NB heading](visual/long-heading-light-nb.png), [rules error dark/NB](visual/rules-error-dark-nb.png), [notification skeleton light/EN](visual/notifications-loading-light-en.png), [failed save dark/EN](visual/notifications-error-dark-en.png) | +| S04 → real zero-usage Free state, external AI remains disabled | Actual native account/usage response, disabled switch; existing ai-usage-card/privacy/entitlement cases | [Usage and capture at 320px](visual/connected-action-dark-nb.png); this is not provider or paid-plan certification | +| S05/J10/J04 → account export, deletion gate, existing import/capture | Actual ZIP download and disabled deletion; unchanged CSV/capture unit/backend tests | [Backup light/NB](visual/backup-light-nb.png), [backup dark/EN](visual/backup-dark-en.png), [export controls desktop](visual/general-1440-light-en.png) | +| M06/E09 → Connected Accounts action, session-owned API access | Keyboard activation opens existing route, focus outline/hit-test, non-admin API 403; existing account-isolation/provider tests | [Connected action light/EN](visual/connected-action-light-en.png), [Connected action dark/NB](visual/connected-action-dark-nb.png) | + +All screenshots use 900px height; widths are in names or 320px for error/loading/backup/connected/long-heading captures. The remaining combinations are in [visual/](visual/). Existing source controls and the mobile section chooser remain; no action is hidden to pass reflow. Post-scroll hit testing uses retrying assertions to wait for the rendered position to settle. The initial immediate assertion sampled before that stable position; no application workaround or style injection was added. + +This validates the shared primitives and the single Settings consumer, not every application's visual parity. Reading width is exercised here; data/editor aliases are reserved for separately validated consumer migrations. Manual assistive-technology and the explicitly retained debt above remain open. + +### P4-04-O02 investigation and test-boundary correction + +A complete rerun failed the inherited `[PRES-S03 PRES-W11] responsive settings navigation keeps rule edits and persists notification preferences` case. Its native readback remained `true`; the browser had an unchecked draft and a visible save-error alert. The trace proved the click reached the API: `PUT /api/notification-settings` returned **500**, while the test's overlapping GETs returned **200** with the old value. This was neither a lost click nor a successful save hidden by presentation. + +Repeating that unchanged fixture ten times with API console capture yielded **eight passes and two failures**. Both server failures were `DbUpdateException` with SQLite error 5, `database is locked`, through `UserStore.UpdateAsync` and [NotificationSettingsController.Put](../../../../JobTrackerApi/Controllers/NotificationSettingsController.cs). This controller, its Identity/database configuration and the Settings save handler are unchanged from `806eee4e`. The original trace is `.artifacts/p4-04-settings-failure-trace.zip`; the failing full run is preserved as `p4-04-browser-intermittent.json/.log`, and the repeated API diagnostics as `p4-04-settings-diagnostic.json/.log`. These synthetic traces/logs remain ignored rather than publishing session credentials. + +The inherited test began native GET polling immediately after clicking Save, before the PUT completed. That added concurrent read traffic unrelated to its sequential UI preservation contract. It now awaits the exact PUT and **requires HTTP 200**, then retains the existing native readback and reload checks. No 500 is accepted, retried or converted to an expected failure. P2-D01 is unchanged. The four new Settings cases already await their PUT responses and explicitly verify error/draft/retry behavior. + +The corrected sequential case passed **ten of ten repeats**, with API console capture and no notification-save 500. These are diagnostic repeats of one inherited case, not ten new tests. The subsequent complete suite is the final checkpoint result in the table above. + +This correction isolates the intended sequential test; it does **not** repair or dismiss the backend contention. Further work must reproduce the concurrent API condition, identify the locking/transaction cause and verify a bounded backend solution. No schema, retry policy, SQLite mode or server synchronization change is included here. The original fixture is recoverable from `806eee4e:job-tracker-ui/e2e/redesign-preservation.spec.ts` for the same ten-repeat local probe. + +### Commands + +Run from repository root unless a directory change is shown. Output logs/TRX/JSON are retained under ignored `.artifacts/`; the scan evidence and synthetic screenshots are committed here. Existing installed dependencies were used; there were no CI/package/infrastructure changes or remote-provider calls. + +```powershell +$env:DOTNET_ROOT='C:/Users/Connor/.dotnet' +& C:/Users/Connor/.dotnet/dotnet.exe test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --configuration Release --no-restore --logger 'trx;LogFileName=p4-04.trx' --results-directory .artifacts/redesign-p4-04 -- xUnit.parallelizeTestCollections=false xUnit.maxParallelThreads=1 +# Final repeat after the browser-only correction, using the unchanged Release build: +& C:/Users/Connor/.dotnet/dotnet.exe test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --configuration Release --no-build --no-restore --logger 'trx;LogFileName=p4-04-final.trx' --results-directory .artifacts/redesign-p4-04 -- xUnit.parallelizeTestCollections=false xUnit.maxParallelThreads=1 +& C:/Users/Connor/.dotnet/dotnet.exe build JobTrackerApi/JobTrackerApi.csproj --configuration Release --no-restore -warnaserror +python scripts/test-ingress.py +python scripts/test-supply-chain.py +python scripts/test-ollama-evaluation.py +node --test browser-extension/tests/*.test.mjs +Set-Location job-tracker-ui +npm test -- --watchAll=false --runInBand --json --outputFile=../.artifacts/p4-04-jest.json +npm run typecheck +node node_modules/typescript/bin/tsc --project ../.artifacts/p4-04-e2e-tsconfig.json +npm run lint +$env:NEXT_PUBLIC_API_BASE_URL='http://localhost:5302/api' +$env:NEXT_TELEMETRY_DISABLED='1' +npm run build +$env:DOTNET_HOST_PATH='C:/Users/Connor/.dotnet/dotnet.exe' +$env:PLAYWRIGHT_STATIC_EXPORT='true' +$env:PLAYWRIGHT_PREBUILT_EXPORT='true' +$env:P4_04_CAPTURE='true' +$env:PLAYWRIGHT_JSON_OUTPUT_FILE='../.artifacts/p4-04-browser.json' +node node_modules/@playwright/test/cli.js test --reporter=list,json +$env:PLAYWRIGHT_JSON_OUTPUT_FILE='../.artifacts/p4-04-final-focused.json' +node node_modules/@playwright/test/cli.js test e2e/settings-page-layout.spec.ts --reporter=list,json +# Diagnostic: executed before and after the inherited Settings response barrier; +# the first run reproduced O02. No retry option or expected failure was added. +$env:DEBUG='pw:webserver' +node node_modules/@playwright/test/cli.js test e2e/redesign-preservation.spec.ts --grep 'responsive settings navigation' --repeat-each=10 --reporter=list,json +Remove-Item Env:DEBUG +node node_modules/@playwright/test/cli.js test --config=playwright.rate-limits.config.ts +node node_modules/@playwright/test/cli.js test --config=playwright.ingress.config.ts +node node_modules/@playwright/test/cli.js test --config=playwright.pdf.config.ts +Set-Location .. +python scripts/supply-chain.py scan-secrets +git diff --check +git diff --cached --check +``` + +The ignored E2E type config extends the existing frontend configuration, includes the new Settings spec, the affected inherited preservation spec and MUI augmentation, disables incremental caching and resolves frontend Node types. It adds no test exclusion or production compiler change. diff --git a/docs/redesign/phase-4/p4-04/SCAN_RESULTS.json b/docs/redesign/phase-4/p4-04/SCAN_RESULTS.json new file mode 100644 index 0000000..d04f1ee --- /dev/null +++ b/docs/redesign/phase-4/p4-04/SCAN_RESULTS.json @@ -0,0 +1,2418 @@ +{ + "date": "2026-09-12", + "source": ".artifacts/p4-04-browser.json", + "outcomes": { + "passed -> passed": 47, + "failed -> failed": 1 + }, + "focusedSource": ".artifacts/p4-04-final-focused.json", + "focusedOutcomes": { + "passed -> passed": 4 + }, + "note": "Scans, reflow checks and screenshots come from the final complete-suite rerun after strengthening post-scroll focus hit testing. The focused repeat uses the same four Settings cases, not additional tests.", + "diagnosticHistory": [ + { + "source": ".artifacts/p4-04-browser-intermittent.json", + "outcomes": { + "passed -> passed": 46, + "failed -> failed": 1, + "passed -> failed": 1 + } + }, + { + "source": ".artifacts/p4-04-settings-diagnostic.json", + "outcomes": { + "passed -> passed": 8, + "passed -> failed": 2 + } + }, + { + "source": ".artifacts/p4-04-settings-sequential.json", + "outcomes": { + "passed -> passed": 10 + } + } + ], + "diagnosticFinding": "P4-04-O02: the inherited Settings case exposed SQLite error 5 during overlapping read/write traffic. The sequential test now requires the PUT response before readback. Backend contention remains open; no failure suppression or new expected failure was added.", + "settingsCases": [ + { + "title": "[PRES-E07 E08 E09 S03 S04 S05 J05 J10 M06 W11] light/en Settings headings, reflow and retained actions", + "file": "settings-page-layout.spec.ts", + "expected": "passed", + "actual": "passed" + }, + { + "title": "[PRES-E07 E08 E09 S03 S04 S05 J05 J10 M06 W11] light/nb Settings headings, reflow and retained actions", + "file": "settings-page-layout.spec.ts", + "expected": "passed", + "actual": "passed" + }, + { + "title": "[PRES-E07 E08 E09 S03 S04 S05 J05 J10 M06 W11] dark/en Settings headings, reflow and retained actions", + "file": "settings-page-layout.spec.ts", + "expected": "passed", + "actual": "passed" + }, + { + "title": "[PRES-E07 E08 E09 S03 S04 S05 J05 J10 M06 W11] dark/nb Settings headings, reflow and retained actions", + "file": "settings-page-layout.spec.ts", + "expected": "passed", + "actual": "passed" + } + ], + "settingsScanCount": 20, + "settingsViolationCount": 0, + "scansWithIncompleteRules": 20, + "reflowChecks": [ + { + "name": "general-1920-light-en-reflow", + "outsideBounds": [] + }, + { + "name": "general-1440-light-en-reflow", + "outsideBounds": [] + }, + { + "name": "general-1024-light-en-reflow", + "outsideBounds": [] + }, + { + "name": "general-768-light-en-reflow", + "outsideBounds": [] + }, + { + "name": "general-767-light-en-reflow", + "outsideBounds": [] + }, + { + "name": "general-390-light-en-reflow", + "outsideBounds": [] + }, + { + "name": "general-320-light-en-reflow", + "outsideBounds": [] + }, + { + "name": "long-heading-light-en-reflow", + "outsideBounds": [] + }, + { + "name": "rules-320-light-en-reflow", + "outsideBounds": [] + }, + { + "name": "rules-390-light-en-reflow", + "outsideBounds": [] + }, + { + "name": "rules-768-light-en-reflow", + "outsideBounds": [] + }, + { + "name": "rules-1024-light-en-reflow", + "outsideBounds": [] + }, + { + "name": "rules-1440-light-en-reflow", + "outsideBounds": [] + }, + { + "name": "notifications-error-light-en-reflow", + "outsideBounds": [] + }, + { + "name": "backup-light-en-reflow", + "outsideBounds": [] + }, + { + "name": "general-1920-light-nb-reflow", + "outsideBounds": [] + }, + { + "name": "general-1440-light-nb-reflow", + "outsideBounds": [] + }, + { + "name": "general-1024-light-nb-reflow", + "outsideBounds": [] + }, + { + "name": "general-768-light-nb-reflow", + "outsideBounds": [] + }, + { + "name": "general-767-light-nb-reflow", + "outsideBounds": [] + }, + { + "name": "general-390-light-nb-reflow", + "outsideBounds": [] + }, + { + "name": "general-320-light-nb-reflow", + "outsideBounds": [] + }, + { + "name": "long-heading-light-nb-reflow", + "outsideBounds": [] + }, + { + "name": "rules-320-light-nb-reflow", + "outsideBounds": [] + }, + { + "name": "rules-390-light-nb-reflow", + "outsideBounds": [] + }, + { + "name": "rules-768-light-nb-reflow", + "outsideBounds": [] + }, + { + "name": "rules-1024-light-nb-reflow", + "outsideBounds": [] + }, + { + "name": "rules-1440-light-nb-reflow", + "outsideBounds": [] + }, + { + "name": "notifications-error-light-nb-reflow", + "outsideBounds": [] + }, + { + "name": "backup-light-nb-reflow", + "outsideBounds": [] + }, + { + "name": "general-1920-dark-en-reflow", + "outsideBounds": [] + }, + { + "name": "general-1440-dark-en-reflow", + "outsideBounds": [] + }, + { + "name": "general-1024-dark-en-reflow", + "outsideBounds": [] + }, + { + "name": "general-768-dark-en-reflow", + "outsideBounds": [] + }, + { + "name": "general-767-dark-en-reflow", + "outsideBounds": [] + }, + { + "name": "general-390-dark-en-reflow", + "outsideBounds": [] + }, + { + "name": "general-320-dark-en-reflow", + "outsideBounds": [] + }, + { + "name": "long-heading-dark-en-reflow", + "outsideBounds": [] + }, + { + "name": "rules-320-dark-en-reflow", + "outsideBounds": [] + }, + { + "name": "rules-390-dark-en-reflow", + "outsideBounds": [] + }, + { + "name": "rules-768-dark-en-reflow", + "outsideBounds": [] + }, + { + "name": "rules-1024-dark-en-reflow", + "outsideBounds": [] + }, + { + "name": "rules-1440-dark-en-reflow", + "outsideBounds": [] + }, + { + "name": "notifications-error-dark-en-reflow", + "outsideBounds": [] + }, + { + "name": "backup-dark-en-reflow", + "outsideBounds": [] + }, + { + "name": "general-1920-dark-nb-reflow", + "outsideBounds": [] + }, + { + "name": "general-1440-dark-nb-reflow", + "outsideBounds": [] + }, + { + "name": "general-1024-dark-nb-reflow", + "outsideBounds": [] + }, + { + "name": "general-768-dark-nb-reflow", + "outsideBounds": [] + }, + { + "name": "general-767-dark-nb-reflow", + "outsideBounds": [] + }, + { + "name": "general-390-dark-nb-reflow", + "outsideBounds": [] + }, + { + "name": "general-320-dark-nb-reflow", + "outsideBounds": [] + }, + { + "name": "long-heading-dark-nb-reflow", + "outsideBounds": [] + }, + { + "name": "rules-320-dark-nb-reflow", + "outsideBounds": [] + }, + { + "name": "rules-390-dark-nb-reflow", + "outsideBounds": [] + }, + { + "name": "rules-768-dark-nb-reflow", + "outsideBounds": [] + }, + { + "name": "rules-1024-dark-nb-reflow", + "outsideBounds": [] + }, + { + "name": "rules-1440-dark-nb-reflow", + "outsideBounds": [] + }, + { + "name": "notifications-error-dark-nb-reflow", + "outsideBounds": [] + }, + { + "name": "backup-dark-nb-reflow", + "outsideBounds": [] + } + ], + "scans": [ + { + "name": "general-light-en-axe", + "violations": [], + "incomplete": [ + { + "id": "color-contrast", + "impact": "serious", + "tags": [ + "cat.color", + "wcag2aa", + "wcag143", + "TTv5", + "TT13.c", + "EN-301-549", + "EN-9.1.4.3", + "ACT", + "RGAAv4", + "RGAA-3.2.1" + ], + "description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds", + "help": "Elements must meet minimum color contrast ratio thresholds", + "helpUrl": "https://dequeuniversity.com/rules/axe/4.13/color-contrast?application=playwright", + "nodes": [ + { + "any": [ + { + "id": "color-contrast", + "data": { + "contrastRatio": 0, + "fontSize": "10.5pt (14px)", + "fontWeight": "normal", + "messageKey": "bgOverlap", + "expectedContrastRatio": "4.5:1" + }, + "relatedNodes": [], + "impact": "serious", + "message": "Element's background color could not be determined because it is overlapped by another element" + } + ], + "all": [], + "none": [], + "impact": "serious", + "html": "