# P5-08b — Job sections and preserved domain content Implementation from `acd1d94` on `codex/ui-redesign-phase4`. This checkpoint owns deeper workspace presentation and URL composition only; P5-08a header/Overview context and every existing domain/data owner remain intact. No P5-09 or B07 work. ## Gates and composition The [readiness proof](../p5-08b-readiness/README.md) established native SQLite/ZIP contents, immutable readback after live-source mutation/deletion, attachments/ownership, numeric helper compatibility, history/query retention and scoped accessibility. P2-D01 is a genuine passing regression from that checkpoint. Seven approved top-level sections: Overview, Match, Application, Documents, Timeline, Notes & tasks, Interview. Application has URL-addressable CV, Letter, Answers and Submission subsections. Timeline has Activity and Correspondence. Existing legacy section URLs reveal their original owner without rewriting the incoming URL. The persisted numeric 0–9 route helper remains unchanged. Navigation preserves unrelated query metadata, including `followMode`, and Jobs return/focus state. The reviewed follow-up composer remains deferred to mail work. Presentation reuses MUI/Emotion, provisional primary and semantic surface/text/status tokens, Phase 4 PageSection/typography/focus. No new palette, font, cards framework or provider. Compact section summaries and restrained borders replace the old nested domain accordion collection; only job-detail disclosure remains in Overview. Each visible subsection mounts its existing owner, with existing letter/answer dirty guards covering subsection navigation. No implicit AI generation, freeze or sending. ## Preservation impact and discovered owners | Contracts | Existing owner / invariants | P5-08b change and evidence required | | --- | --- | --- | | PRES-W01, E07/E08/E09; J05/J06/J07 entry | Workspace page, URL adapter, jobWorkspaceRoute, protected provider tree | Seven sections; secondary `sub` URL; every legacy/numeric alias, query/history, permissions and Jobs Back-focus regression | | PRES-W02/W03 | JobDetails, Timeline, Analysis/Match/Strategy/StatusSuggestion | Overview detail owner retained; deterministic Match and stored Timeline events, source/unknown states; no new AI facts | | PRES-W04/W10/W11 | ApplicationChecklist, FollowUp, ApplicationCalendarActions | Notes & tasks and calendar grouping; human Notes stays Job.Notes and uses existing EditJobDialog; checklist remains its own data type | | PRES-W05/W06/W07; C01/C04/C05–C12 relationship entry | ApplicationCv/Tailoring, CoverLetter, PackageDrafts, SubmittedPackages | Application subsections; current selected CV/source vs draft vs immutable snapshot; attach/detach, versions, dirty cancel/leave, AI accept/reject and native package regression | | PRES-W08 | Attachments real upload/metadata/AI consent/preview/download/delete | Documents presentation and narrow local table scroll; preserve filenames, purpose and ownership | | PRES-W09/W10; M01/M02/M04/M05 entry | InterviewPrep/FollowUp, Correspondence/Gmail manual/provider paths | Scoped section surfaces, existing prep review and logged/imported history; no mail/provider/domain rewrite | | PRES-W12 adjacent | Existing asynchronous operation progress/notification owners | Entry and current error states retained; no background engine change | Data remains account-owned by the same server services. Application drafts are neither an external send nor a frozen package. Frozen readback uses the exact captured CV/version/HTML, letter, material JSON and archived binaries, never current Career Profile/CV data. Documents exposes current attachments separately from frozen package history. Submission owns the explicit Freeze action; viewing and downloading old packages remains read-only. ## Final section architecture and route compatibility | Entry | Visible content / existing data owner | |---|---| | `section=overview` | P5-08a identity, summary, progress and actions; existing full job-details disclosure remains | | `section=match` | Analysis, recorded CV match, strategy snapshot; no generation on mount | | `section=application&sub=cv` | Current selected CV, exact variant link, tailoring and existing review/save controls | | `section=application&sub=letter` | Current editable letter and existing AI proposal/accept/reject boundary | | `section=application&sub=answers` | Application answer and recruiter-message drafts; explicit Save/Discard and navigation guard | | `section=application&sub=submission` | Explicit Freeze action and immutable historical package readback/download | | `section=documents` | Current uploaded attachments, CV/letter entry links, read-only frozen history; no Freeze control here | | `section=timeline&sub=activity` | Stored milestones/events and existing category filters | | `section=timeline&sub=correspondence` | Existing logged/imported mail, provider status, import/link/unlink/manual entry and retained history | | `section=tasks` | Human Notes using existing EditJobDialog; independent checklist/progress/reorder/dismiss actions and calendar export/provider actions | | `section=interview` | Existing preparation, reviewed AI suggestions, manual answers/questions, readiness, debrief and follow-up | Legacy `analysis`/`match`, `cv`, `cover-letter`, `checklist`, `notes`, `documents`/`portfolio`, `timeline`, `communication`, `job-details`, `overview` and `interview` remain meaningful. Legacy CV/letter/correspondence keys take precedence over unrelated `sub` metadata. Unknown/prototype-like keys safely fall back to Overview. Canonical Application defaults to CV and Timeline defaults to Activity. The 0–9 helper still emits its original URLs, including the shared correspondence/follow-up destination. `/applications/:id` retains its existing compatibility redirect to `/jobs/:id`; no route/provider tree changes. Selecting a subsection writes durable `sub` URL state; selecting a primary section removes obsolete subsection state while retaining other query metadata and `location.state`. Back/Forward/reload and Jobs originating focus context remain protected. Direct deeper entry focuses the named panel only when focus is still on the document body; keyboard tab activation retains the tab focus. Existing overlay props are retained without adding a new host; hosted subsection state remains local because the existing callback only accepts a primary section. `followMode` round-trips unchanged and does not select a new compose mode. Connor's approved decision is **preserve compatibility metadata; defer mode-specific UI**. No follow-up send/generation is inferred from that query key. ## Domain preservation and presentation changes - **Timeline:** source event arrays/order/types/IDs are unchanged. Locale-aware day headings replace backend English day labels. Semantic ordered lists and `time` elements expose recorded timestamps with an explicit UTC label, consistent with the server's UTC day grouping. This is not a timezone-model migration; stored event descriptions and user content remain literal. - **Application/Documents:** selected current CV and editable letter/answer owners remain distinct from frozen history. Freeze is still an explicit existing operation, not proof of external submission. Frozen views show exact captured CV name/theme/version, archived HTML, original letter, material and file downloads. The existing embedded answer encoding is decoded for display into separate Notes/Answer headings without rewriting package JSON or stored data. Native manifests, filenames, byte content, version associations and owner filtering are unchanged. - **Notes/tasks/calendar:** Notes edits use the original job editor, and a native assertion compares application answers after that write. Checklist tasks remain their own domain, with completion/order/dismiss controls intact. Calendar actions still export/create the existing deadline/follow-up events; no interview appointment, external provider or notification model is invented. - **Correspondence/interview/AI:** existing manual/provider/import and review owners remain. AI suggestions still require their original explicit accept/reject flow; this slice never adds user facts, silently applies suggestions or sends mail. Provider-dependent behavior is covered by existing mocks where noted, not certified against live services. - **Loading/errors:** shared PageSection and continuously mounted ViewStateNotice provide consistent headings and loading/error semantics. Genuine initial attachment/mail read failures previously looked empty or escaped error handling; they now show a local error/Retry without hiding the available manual entry. Other owners retain their existing retry/mutation contracts. Partial failure is not converted into a fabricated empty result. The six existing component files changed outside the composition adapter are all approved deeper-section owners. `ApplicationAssets`, `ApplicationIntelligence` and `InterviewPrep` consolidate their local wrappers onto PageSection/ViewStateNotice; no new wrapper framework is introduced. `ApplicationChecklist` uses the same sections and responsive add form. `Attachments` and `Correspondence` remove legacy decorative shadows/glass and permit narrow reflow. `translations.ts` contains EN/NB presentation/accessibility/error strings only. Header/Overview business semantics, API endpoints, DTOs, database, auth, billing, renderer, AppShell and CI are unchanged. ### Scoped issues reproduced and resolved 1. Attachment rows had eight cells but seven headers. The existing upload date now has its translated header. All existing metadata/AI-use/action controls remain in a named, focusable local scroll region; the empty message is outside the wide table, so it stays readable at 320px. 2. Package View disables its invoking button during asynchronous detail loading, so default dialog focus restoration could miss it. A scoped button ref restores focus on dialog exit; native Escape proves return to that View button. This does not close unrelated shared confirmation timing observations. 3. Expanded populated Notes/tasks axe found completed text at **4.48:1**, below 4.5:1. Completed text now uses `text.secondary`, retaining checked state and strike-through; it is readable content, not a disabled action. The same expanded scan passes after the change. 4. The existing interview answer textarea used only a placeholder below its item title. Its accessible name now includes the recorded question title through EN/NB localisation. The interview loaded-state scan protects this boundary. ## Regression coverage The adapter tests were first run against the old five-section implementation and failed for the intended seven-section architecture/missing subsection resolver before implementation. Existing test assertions were migrated to the approved destinations, never replaced with generic visibility passes. Six new Jest cases: - `applicationWorkspace.test.ts`: legacy subsection precedence and canonical/unknown subsection handling (+2). - `application-workspace-overlay.test.tsx`: dirty answer subsection Cancel/Discard plus metadata/no writes; correspondence versus human Notes ownership (+2). - `application-assets.test.tsx`: read-only frozen history, exact captured content, separate Notes/Answer and no implicit capture/update (+1). - `attachments.test.tsx`: real read failure versus empty, retry recovery and no mutation (+1); existing metadata case also checks all eight headers. Five new native Chromium cases in `job-sections-presentation.spec.ts`: - Four EN/NB × light/dark journeys create real account/job/CV/letter/answers/file/task/prep/correspondence data, verify all seven sections and legacy entries, protect dirty answers, explicitly save/freeze, read frozen history, return dialog focus, complete a task, edit human Notes without changing answers, retain `followMode`, and exercise responsive navigation/local document scrolling. - One local fault-injection case holds then fails an attachment read, shows genuine error/Retry/recovery and independently fails correspondence reads. Only these read responses are mocked; it is not native archive/provider proof. Existing ordinary P2-D01 native browser proof still compares frozen CV/letter/material/binaries after live-source changes and reads the native ZIP. Existing readiness cases cover numeric aliases, history/reload and keyboard movement. Inherited AI rejection/edited acceptance, CV attachment/ownership, mail/import, calendar, Jobs Back focus and auth tests remain active. The 57-contract ledger remains the preservation source; mapping a contract here is not a claim of exhaustive coverage. ## Validation and evidence Inherited baseline: backend 936, frontend 412, browser 88 actual passes, rate 9, ingress 6, PDF 1, configuration 3. Final unit run: **418/418, 80 suites** (+6); backend: **936/936**, zero failures/skips. Final complete Chromium run: **93 actual passes** (+5), zero skipped, flaky, expected-failure or unexpected outcomes, 13.5 minutes. P2-D01 remains an ordinary passing case. TypeScript, lint, production export, edited-browser TypeScript and API Release build pass. Security suites remain **9 / 6 / 1**, configuration **3**, unchanged. All commands use `rtk proxy`; npm commands run in `job-tracker-ui`. Specialized browser suites share port 5302 and run sequentially. Disposable raw traces/cookies are ignored; only safe summaries, invariant records and synthetic screenshots are retained. | Final command | Result | |---|---| | `C:/Users/Connor/.dotnet/dotnet.exe test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj -c Release --no-restore --logger 'console;verbosity=minimal'` | 936 passed, 0 failed/skipped; unchanged count and native SQLite/ZIP proof retained | | `npm.cmd test -- --runInBand --silent --json --outputFile=../.artifacts/p5-08b-jest.json` | 418 passed / 80 suites, 0 failures; +6 cases described above | | `npm.cmd run test:e2e -- --reporter=line,json` | 93 actual passes, 0 expected failures/skips/flaky/unexpected; +5 new section cases | | `npm.cmd run typecheck` / `npm.cmd run lint` | Passed | | `npm.cmd run build`, `NEXT_PUBLIC_API_BASE_URL=http://localhost:5302/api` | Production static export passed | | `C:/Users/Connor/.dotnet/dotnet.exe build JobTrackerApi/JobTrackerApi.csproj -c Release --no-restore -warnaserror` | Passed, 0 warnings/errors | | `npm.cmd exec tsc -- --project ../.artifacts/p5-08b-e2e-tsconfig.json --noEmit --incremental false` | All edited permanent browser fixtures type-check using existing frontend types | | `npm.cmd run test:rate-limits -- --reporter=line` | 9 passed; same-IP account isolation, forged headers/session context and IP policy behavior | | `npm.cmd exec playwright test -- --config=playwright.ingress.config.ts --reporter=line` | 6 passed; application-level proxy/host/scheme/CORS regressions, not deployed topology proof | | `npm.cmd run test:pdf-admission -- --reporter=line` | 1 passed; actual cross-route render admission/recovery | | `python scripts/test-ingress.py` | 3 configuration/Compose checks passed | | `python scripts/test-supply-chain.py` / `python scripts/test-ollama-evaluation.py` / `node browser-extension/tests/capture-url.test.mjs` | 3 / 5 / 3 passed; local fixtures, not live provider certification | | `python scripts/supply-chain.py scan-secrets` | Staged candidate passed; no high-confidence credential patterns | | `git diff --check` / `git diff --cached --check` | Passed | | `python .artifacts/p4-04-check-doc-links.py` | 143 current/root Markdown files, zero missing local targets; historical archive excluded | Browser runs use `DOTNET_ROOT=C:/Users/Connor/.dotnet`, `DOTNET_HOST_PATH=C:/Users/Connor/.dotnet/dotnet.exe`, `PLAYWRIGHT_STATIC_EXPORT=true`, `PLAYWRIGHT_PREBUILT_EXPORT=true`; main JSON output is `test-results/p5-08b-final.json`. No dependency, CI, package script or production configuration change was needed. Code stayed unchanged throughout final validation and supplemental visual inspection. The [safe full-browser summary](evidence/final-browser-summary.json), [native invariant records](evidence/native-invariants.json), [accessibility summary](evidence/accessibility-summary.json) and [screenshot manifest](evidence/visual-manifest.json) contain no authentication storage or raw trace. The main run retains 74 synthetic viewport captures across the five new journeys. ### Accessibility evidence limits Eight new whole-mounted-page scans have **zero reported violations**, using WCAG 2 A/AA and 2.1 A/AA tags. Four scan populated EN/light Documents, Correspondence, Notes/tasks and Interview; four scan 320px Submission in all theme/language combinations. Inactive sections/provider dialogs are not scanned. **Every scan has incomplete checks**: 43 contrast node occurrences and 46 ARIA node occurrences across these captures, with repeated nodes counted per scan rather than unique defects. The ARIA incomplete findings identify existing Tooltip-cloned `aria-label` attributes on generic wrapper spans (45 checklist action wrappers, one interview Delete wrapper). The inner action buttons keep their independent accessible names; these findings are not declared passes or silently repaired here. Contrast incompletes include a short notification badge and overlapping field/background samples. Rendered review does not quantify every unresolved pair. Carry both rule types to the relevant shared-control/manual acceptance owners before P5-15. Keyboard tab activation, selected/panel naming, reload/history, Cancel/Discard, checklist actions, dialog Escape/return and local table scrolling have native browser evidence. Manual visual review means inspection of actual rendered captures. It is **not** a human screen-reader or physical touch session. P5-02 spoken names/live announcements remain mandatory and open for P5-15; no full assistive-technology acceptance is claimed. ## Rendered, responsive and localisation review The permanent four native journeys exercise 1440×900 desktop, 768×1024 intermediate, 390×844 phone and 320×844 narrow phone, in EN/NB × light/dark. They assert no global horizontal overflow; the existing status strip/tabs and attachment table use deliberate local scrolling instead of squeezing/removing content. Native numeric/history journeys also retain the earlier 1280px/390px coverage. Actions retain their existing permissions and independent accessible names. Inspected **21 of 94 retained captures individually**; the manifest marks precisely which were reviewed. The other captures are retained evidence, not asserted to have received individual visual sign-off. Representative review covers all four theme/language combinations: desktop Match, current CV, letter, recorded Timeline, completed tasks and Interview; reopened frozen version; focused section navigation at 320/390/768; long NB title/company; local document-table focus; mobile Notes/Interview/CV/answers; actual loading/error/Retry/empty content. Twenty supplemental captures reuse an ignored copy of the same five native fixtures, scroll the relevant content into view and wait for populated controls. They add mobile Notes, Interview, CV and Answers plus four actual read-state frames. The [supplemental summary](evidence/supplemental-visual-summary.json) records **5 passed**, separate from the permanent 93-case baseline. Exact command: `npm.cmd run test:e2e -- --config=../.artifacts/p5-08b-visual-config.ts --reporter=line,json`, with the same browser environment above; its reporter output resolves under `.artifacts/test-results/p5-08b-visual.json`. The first supplemental attempt had 4 passes and one **capture-helper** timeout: Playwright waited for the continuously rotating progress SVG to become stable before scrolling. The ignored helper now scrolls its stable parent; all loading/error assertions remain, and the five-case rerun passes without application/permanent-test changes. The failed log/report remain ignored locally; the safe summary preserves the outcome/reason. This failure is not relabelled as an application pass or added to the main baseline. Limits remain explicit: some original phone screenshots frame the preserved P5-08a header with the relevant state below the fold; separate `content-*` frames show that state. Long tab sets deliberately scroll locally (including keyboard selection), rather than show all seven labels simultaneously at 320px. Frozen HTML remains a white, scrollable document canvas even in dark mode; the iframe's original geometry/templates are untouched and not certified by this UI review. Stored backend-generated English descriptions/events remain English in NB; authored text/custom status values are not translated. No live provider, physical touch, browser zoom corpus or exhaustive template/output comparison is inferred. ## Files and rollback boundary Application changes: `src/applicationWorkspace.ts`, `src/views/ApplicationWorkspacePage.tsx`, `src/i18n/translations.ts`; existing `components/ApplicationAssets.tsx`, `ApplicationIntelligence.tsx`, `ApplicationChecklist.tsx`, `Attachments.tsx`, `Correspondence.tsx`, `InterviewPrep.tsx`. Five existing unit files and four existing browser files are adapted to the approved section composition; one new browser file supplies five cases. Documentation updates this scoped record/evidence, Phase 5 current index/open blockers, Phase 2 traceability and roadmap status. No shared AppShell, route table, dependency, CI, backend, schema or renderer file changed. Revert the adapter/composition and child presentation as one UI checkpoint if required; do not rewrite persisted packages/material or restore old data. If later compatibility links use `application/sub`, `timeline/sub` or the new primary sections, retain a route adapter exposing the original child when rolling presentation back. Existing legacy helper URLs must continue functioning in either direction. ## Open debt and next boundary F04 production ingress evidence remains open. Human screen-reader spoken names/live-state acceptance remains open for P5-15, separate from automated keyboard/axe. Native Board touch, Board full-result scaling, Dashboard preference-save 500/SQLite contention, P5-07/shared-confirmation focus timing and incomplete accessibility/manual checks are not silently closed. The pre-existing attachment-preview dialog's Download path still constructs ID 0; the ordinary table/archive download paths are separate and unchanged. Record that existing defect for the later attachment owner rather than repair it in this section migration. `followMode` mode-specific UI is deferred to mail work. P2-D01 is **closed/passing**, not open debt. **P5-08b scoped acceptance: complete**, subject to the explicitly retained manual/provider/accessibility limits. Job sections/routes/history, drafts/Notes separation, immutable package/version/file/ownership proof and native entry controls remain green. **P5-09: NO-GO until G-CV-REV and G-CV-RENDER are independently satisfied.** Missing proof includes cross-client stale save/restore rejection with unsaved-work recovery, and measured preview versus real PDF geometry/template/page-break fidelity across the agreed corpus. P5-08b does not resolve those contracts or authorise B07, a renderer replacement, schema changes, or CV editing redesign. Stop before P5-09.