feat(jobs): complete workspace draft parity
CI and Deploy / test (pull_request) Successful in 5m4s
CI and Deploy / deploy (pull_request) Has been skipped

This commit is contained in:
cesnimda
2026-08-15 17:34:32 +02:00
parent 3b86ea2da0
commit deed948183
28 changed files with 676 additions and 131 deletions
+18 -7
View File
@@ -6,7 +6,7 @@
## What it is
A dedicated surface for one `JobApplication` at `/applications/{id}`, so an application is a place you
A dedicated surface for one `JobApplication` at `/jobs/{id}`, so an application is a place you
work rather than a row you edit in a modal. Job tracking stays the product; the workspace is the
application's home.
@@ -23,6 +23,7 @@ The workspace **owns no data and duplicates none**. It is an aggregate read plus
| Checklist | `ApplicationChecklistItem` — completion state only, seeded from the readiness signals |
| CV | Phase 4 `CvVariant` — a lens over the master `CareerProfile`; the application only points at one |
| Cover Letter | `JobApplication.CoverLetterText` + `CoverLetterVersions` history |
| Application answers / recruiter draft | compatibility fields on `JobApplication`, exposed as separate workspace fields |
| Analysis / Match / Interview | Phase 5 `AiWorkspacePanel` + `AiInteraction` history |
| Documents | `Attachment` |
| Communication | `Correspondence` |
@@ -134,13 +135,14 @@ rejecting a duplicate system key, and NULL system keys not colliding.
## Frontend
`ApplicationWorkspacePage` (`/applications/:id`) — a left nav plus a content pane, section selected by
`?section=`, so a section is linkable and survives refresh. Reached from the job dialog's "Open
application workspace" button.
`ApplicationWorkspacePage` (`/jobs/:id`) — a left nav plus a content pane, section selected by
`?section=`, so a section is linkable and survives refresh. The whole application row/card opens this
route; the legacy job-details dialog is not part of the production navigation flow.
The dialog passes an optional `onOpenWorkspace` callback rather than calling `useNavigate` itself:
`JobDetailsDialog` must stay renderable without a `<Router>` (several suites mount it standalone), so
router context belongs to the caller.
Cover-letter and application-package editors report dirty state to the workspace. Section changes,
Back/Forward navigation and application exit use the shared application confirmation dialog, while a
hard refresh receives the browser's unload warning. Returning through the workspace Back action
restores focus to the originating application row.
The Checklist section (`ApplicationChecklist`) groups items by category, shows a completion bar, and
supports tick/untick, add, remove and reorder. System items are labelled "Detected" when a signal
@@ -289,6 +291,15 @@ the builder. Nothing auto-applies, and no suggestion mutates a variant or the pr
Creation methods: write it, start from the built-in template, or generate from the AI panel below the
editor. The editor is always the user's; generation is never triggered by opening the page.
### Application answers and recruiter message
The Cover Letter section also owns the saved application answer and recruiter-message editors that
were previously reachable only through the retired modal. The existing database representation is
kept for compatibility: the application answer remains a marked block in `JobApplication.Notes`, but
the workspace aggregate separates it from human notes and the API owns insertion/removal. General job
edits preserve the answer, and the ordinary Notes UI never exposes the storage markers. Empty saves
can intentionally clear either draft.
### Documents
Unchanged. The existing `Attachments` component and `/api/attachments` already handle CV, cover
+1
View File
@@ -200,3 +200,4 @@ Output was reduced to filenames and commit counts. The token artifact appears un
| V-166 | Focused/full backend and frontend tests; optimized frontend build/TypeScript; diff review | Repository root / `job-tracker-ui` | Verify an administrator can identify the deployed application version without exposing build metadata in the normal-user UI/API bootstrap | PASS — focused Auth/System 36/36 and AppShell 2/2; backend 640/640; frontend 53 suites/221 tests; production build passes. Configured version/commit reaches admin `/api/auth/me`, normal users receive no configured metadata, and the responsive header badge is absent unless the admin-owned prop is supplied | Local/JSDOM evidence only; remote CI and deployed version comparison remain. Jest retains the documented force-exit/open-handle notice | Priority repository increment verified; ship proof remains |
| V-167 | Failing Career round-trip reproduction; affected/full backend; focused Career/Profile Jest; persistence-consumer and diff review | Repository root / `job-tracker-ui` | Preserve every reviewed Career text value across save/get/version/projection/import use without weakening extraction cleanup or write bounds | PASS — pre-fix location became `Oslo, Norway and` and the test failed; post-fix affected backend 112/112, backend 642/642 and Career/Profile UI 17/17 pass. Website path/query, remote location, free-form date, custom language and incomplete WIP entry round-trip; oversized website is rejected explicitly | Local SQLite/JSDOM only; no real private CV/model/provider/production data. One initial Jest command used nonexistent paths and was corrected; the correct files passed | Reviewed/extracted normalization boundary verified locally |
| V-168 | Failing renderer contrast test; focused/full backend; CV Builder/public Jest; real Chromium computed-style/overflow probe; pathological A4 PDF export and text inspection | Repository root / `job-tracker-ui` | Make header/sidebar contact text readable for theme and custom palettes while keeping public renderer settings inert | PASS — renderer/settings 25/25, backend 644/644 and CV UI 22/22. Chromium computed white on Modern blue, black on `#f8fafc`, white on Technical sidebar, with zero element overflow. A 14-role/75-skill fixture produced a 17-page 259,447-byte A4 PDF with 1,685 final-page characters. CSS-like accent/font payloads normalize to null | Synthetic local data/browser only; authenticated application journey and production browser binary remain unverified. A direct PowerShell assembly probe failed to load dependencies before the compiled temporary test probe passed; temporary proof cleanup was blocked by execution policy | Renderer contrast/public-setting boundary verified locally |
| V-169 | Legacy-vs-dedicated workspace trace; failing package DTO/UI regressions; focused/full backend and frontend; optimized build; authenticated Playwright application journey; diff review | Repository root / `job-tracker-ui` | Close JOBS-002 application-package parity, marker encapsulation, dirty navigation, focus return, responsive/theme/history/error and tenant-safety gaps | PASS — focused backend 30/30, focused frontend 28/28 plus route/focus 6/6, backend 647/647, frontend 54 suites/227 tests, build and Playwright 7/7. Chromium covers keyboard row entry, Back/Forward, saved refresh, dirty-edit cancel, focus return, missing job and long data at 375/768/1440 in explicit light/dark with zero overflow. Cross-owner workspace read and draft write return not found | Synthetic local SQLite/account/browser only; no production/provider/private data. Two targeted browser iterations corrected locators, and a transient SQLite company-create 500 led to bounded idempotent setup retry; behavior assertions were not weakened. Existing GSI and Jest open-handle warnings remain | JOBS-002 repository/browser scope verified; production/native assistive-device gates remain |
@@ -25,17 +25,25 @@ Updated: 2026-08-15
- The header bell opens a theme-aware notification popover anchored to the bell. It supports loading/error/empty states, mark-read, dismiss, notification-owned destinations and a separate link to the global Operations page.
- Return navigation preserves the complete URL-owned list state, including when a workspace section changes.
## Increment 3 — application-package parity and navigation safety
- Application answers and recruiter messages are editable on the dedicated page beside the versioned cover-letter workflow. Empty saves intentionally clear drafts.
- Internal application-answer markers no longer render in Job Details or the general edit dialog. Editing ordinary notes preserves the stored answer instead of deleting it.
- Cover-letter and application-draft dirty state blocks section, Back/Forward and exit navigation through the shared confirmation dialog; hard refresh/close receives the browser unload warning.
- Returning with the workspace Back action restores keyboard focus to the originating row/card.
- The application-drafts mutation and workspace aggregate are tenant-filtered; direct cross-owner reads/writes return not found.
## Verification
- Focused Jest: workspace/table and workflow routing — 8/8 pass.
- Focused backend workspace aggregate: 9/9 pass.
- Production build: pass. Standalone repository-wide `tsc --noEmit` still exposes pre-existing React Router test-prop and target errors; no new application-source error was reported.
- Focused Jest: workspace/assets/storage helpers and legacy compatibility — 28/28 pass; focused route/focus/dirty regression 6/6 pass.
- Focused backend workspace/application-draft/controller behavior — 30/30 pass.
- Full backend 647/647; full frontend 54 suites and 227/227 tests; optimized production build/TypeScript pass.
- Real Chromium application journey passes at 375/768/1440 in explicit light and dark modes with no horizontal overflow. It covers keyboard row entry, Back/Forward, dark refresh, saved draft reload, unsaved-change cancel, long company/title/advert/URL content, focus return, valid section deep links and a missing-job error state.
- Complete Playwright suite: 7/7 pass.
- Notification/AppShell/Operations focused Jest: 3 suites and 6/6 pass.
- Evidence: V-158V-163 in `docs/audits/verification-log.md`.
## Remaining before completion
## Remaining before production completion
- URL-owned list state is implemented for search, status, company, location, follow-up, readiness, deleted visibility, sort/direction and page. Direct hydration and dedicated-page return pass focused tests; real-browser refresh/history remains.
- Confirm the existing section-level save/dirty behavior does not need an additional workspace-level navigation guard.
- Add real-browser 375/768/1440, light/dark, keyboard/focus restoration, refresh/history, error and long-content evidence.
- Run tenant-authorization regressions and the production smoke gate.
- Run the authenticated production application/workspace smoke after this branch is merged and deployed.
- Native screen-reader/mobile assistive-technology behavior is not claimed by Chromium automation and remains an operator/device spot check.
+10
View File
@@ -699,3 +699,13 @@
- **Consequences:** preview, public HTML and PDF retain one render path; normal entries avoid awkward splits while large content can cross pages safely. Existing variants remain compatible and acquire shared custom ordering on edit.
- **User approval required:** No; this implements the requested CV rework without schema, dependency or production changes.
- **Reversible:** Revert the renderer/editor/resolver checkpoint; stored settings remain compatible because the existing `Sections` and `custom:<key>` contract is used.
## DEC-071 — Encapsulate application-answer compatibility storage
- **Date:** 2026-08-15
- **Decision:** Keep the existing marked answer block in `JobApplication.Notes` for storage compatibility, but make the backend the owner of extracting, removing and updating it. Expose human notes and application answers as separate workspace fields, and preserve the answer through the general application editor.
- **Reason/evidence:** the retired modal was the only editor that understood the marker. The dedicated page displayed markers as ordinary notes, and saving the general editor could erase the answer. A new schema/table would add migration risk for one text value while the existing representation remains adequate behind a clean boundary.
- **Alternatives considered:** expose the marker format in every editor; create a second application-package table immediately; copy the retired modal wholesale. These leak implementation details, add avoidable migration/state duplication, or restore the popup architecture the user rejected.
- **Consequences:** the dedicated page edits and clears answer/recruiter drafts directly, ordinary notes remain readable, existing rows require no migration, and legacy calls continue to work. A future normalized column/table can migrate behind the same API without another UI change.
- **User approval required:** No; this is compatibility-safe implementation of the requested dedicated workspace.
- **Reversible:** Revert the workspace/API boundary; no schema or stored-data rewrite occurred.
+5 -5
View File
@@ -2,17 +2,17 @@
Updated: 2026-08-15
- **Overall programme status:** Active. Seven packages are locally verified; twenty-two are implemented with verification incomplete; JOBS-002 is in progress. The prioritized admin-only version indicator is implemented and focused-tested on the release branch; the current branch still requires full/remote gates and production verification.
- **Current work package:** `JOBS-002` — applications table and dedicated workspace (`IN PROGRESS`). The canonical page/table/sidebar integration exists; remaining parity, dirty-edit, tenant-authorization and browser regression work is tracked in the immediate queue.
- **Overall programme status:** Active. Seven packages are locally verified; twenty-two are implemented with verification incomplete; UX-002 is in progress. The prioritized admin-only version indicator and the repository/browser JOBS-002 scope are implemented on the release branch; remote and production verification remain.
- **Current work package:** `UX-002`cross-application contrast/accessibility completion (`IN PROGRESS`). JOBS-002 now has application-package parity, dirty-navigation protection, tenant regressions and real-Chromium responsive/theme/history/error evidence.
- **Completed work packages:** None are `DONE`; all repository security/AI packages still have applicable browser, provider and/or production gates.
- **Locally verified work:** SEC-001, SEC-002, SEC-003, SEC-005A, CORE-001, PROD-002 and DEP-001 (`VERIFIED LOCALLY`).
- **Implemented, verification incomplete:** SEC-004, SEC-005B, SEC-008, CORE-002, BG-001, OPS-001A/B/C, POL-001/002, AI-001/002/003/004, UX-001/002/003, QA-001, CAREER-001/002, MAIL-001 and JOBS-001 (`IMPLEMENTED — NOT VERIFIED`). UX-003 safe local/browser scope is implemented; production/native-device gates remain.
- **Implemented, verification incomplete:** SEC-004, SEC-005B, SEC-008, CORE-002, BG-001, OPS-001A/B/C, POL-001/002, AI-001/002/003/004, UX-001/003, QA-001, CAREER-001/002, MAIL-001 and JOBS-001/002 (`IMPLEMENTED — NOT VERIFIED`). JOBS-002 and UX-003 safe local/browser scope is implemented; production/native-device gates remain.
- **Production-verified work:** None.
- **Blocked work:** SEC-006 parser upgrades remain outside the scoped frontend advisory permission; PROD-001/003/004 and REL-001 require documented production access and unfinished dependencies. Real provider, SMTP/MariaDB and production environments are unavailable; DEP-001 awaits approved merge/live verification. The in-app browser is available for local UI checks.
- **Deferred work:** None. Conditional multi-replica coordination, model deletion, realtime operation delivery and unrelated production changes remain outside current packages.
- **Immediate order:** JOBS-002 parity/regression; cross-app contrast/accessibility; PRODUCT-001; VER-001. Admin version (`a6cffe0`), Career lossless persistence (`f0b9b22`) and CV contact contrast are locally complete. External-only work remains skipped, not allowed to stall this queue.
- **Immediate order:** cross-app contrast/accessibility; PRODUCT-001; VER-001; tracking/blocker reconciliation. Admin version (`a6cffe0`), Career lossless persistence (`f0b9b22`), CV contact contrast (`3b86ea2`) and JOBS-002 repository/browser scope are locally complete. External-only work remains skipped, not allowed to stall this queue.
- **Status counts:** 7 `VERIFIED LOCALLY`; 22 `IMPLEMENTED — NOT VERIFIED`; 1 `IN PROGRESS`; 4 `NOT STARTED`; 5 `BLOCKED`; 0 `DONE`; 0 `DEFERRED`.
- **Test status:** backend 644/644; CV renderer/settings 25/25; CV Builder/public UI 22/22; affected Career/import/profile/job paths 112/112; Career/Profile UI 17/17; prior frontend 53/53 suites and 221/221 tests plus optimized production build/TypeScript pass. Real Chromium contrast/overflow checks pass and the harder pathological fixture exports a 17-page A4 PDF with final-page text. Prior AI sidecar 22/22, Playwright 6/6 and npm audit 0 evidence remain current. Historical JT-019 and Jest force-exit/open-handle behavior remain recorded.
- **Test status:** backend 647/647; frontend 54/54 suites and 227/227 tests; optimized production build/TypeScript pass; Playwright 7/7. The application workspace journey passes keyboard entry, Back/Forward, focus return, unsaved navigation, saved-draft refresh, missing-job handling, long data, and explicit light/dark 375/768/1440 no-overflow checks. CV renderer/settings 25/25, CV Builder/public UI 22/22, AI sidecar 22/22 and npm audit 0 evidence remain current. Historical JT-019 and Jest force-exit/open-handle behavior remain recorded.
- **Deployment status:** Gitea pull-request run 609 passed the complete CI job in 4m20s. Deploy was intentionally skipped because the workflow deploys only a `push` to `main`; live remains unchanged. No merge/deployment was performed directly, no production migrations were run and the AI operation worker remains disabled by default.
- **Production status:** Unchanged and unverified. No provider/model call, model pull, external request or paid API occurred.
- **Known regressions:** None found by automated/local browser checks. Jest still needs `--forceExit` and reports its existing open-handle notice. Email-provider/send tests are fake/local only; real delivery is not claimed. Current MAIL browser evidence is 1280×720 only because the browser surface could not resize or perform native Tab traversal. Interrupted attempts are aged after 15 minutes and notified without retry; the five-minute scan is unmeasured on a large ledger. Direct clean EF-only SQLite migration still hits the pre-existing historical blank-chain defect before later migrations; normal startup owns reconciliation. Cross-feature monthly AI usage accounting remains a rollout gap.
+6 -6
View File
@@ -16,7 +16,7 @@ Allowed statuses are `NOT STARTED`, `IN PROGRESS`, `IMPLEMENTED — NOT VERIFIED
`DONE` requires every applicable acceptance criterion, focused and regression tests, browser/accessibility/theme/mobile checks, tenant and entitlement checks, documentation, migration/rollback evidence, and production verification. Repository-only work that still requires production is at most `VERIFIED LOCALLY`.
Exactly one implementation item may be `IN PROGRESS`. As of this revision it is **JOBS-002**.
Exactly one implementation item may be `IN PROGRESS`. As of this revision it is **UX-002**.
## Consolidated dependency order
@@ -57,8 +57,8 @@ This queue records the highest-value work that can proceed without production cr
| 1 | Admin-only deployed-version indicator in the application header | DEP-001, VER-001 | Implemented with authenticated API and shell tests. The badge shows the CI deployment version and exposes the commit SHA in its accessible label/tooltip only for administrators; full regression, remote CI and deployment smoke remain. |
| 2 | Lossless Career field persistence | CAREER-001 | Implemented and locally verified. Manual website/location/contact/date/language values now use a reviewed-data persistence boundary; extraction heuristics remain isolated to extraction. Full remote/production smoke remains. |
| 3 | CV contact/header/sidebar contrast correction | CAREER-002 | Implemented and locally verified. Header/custom-accent and sidebar palettes own readable foregrounds; real Chromium computed-style/overflow checks and a 17-page A4 PDF proof pass. |
| 4 | Dedicated Job Details parity and JOBS-002 closure | JOBS-002 | Next implementable package and in progress. Finish any remaining legacy follow-up/application-package parity, dirty-edit behavior, tenant authorization and 375/768/1440 theme/keyboard/history/error/long-data verification. |
| 5 | Cross-application contrast/accessibility pass | UX-002, UX-003, VER-001 | Queued after the scoped Career/CV corrections. Audit semantic alerts, secondary text, focus, loading/empty/error states and remaining hardcoded colors before documenting larger redesigns. |
| 4 | Dedicated Job Details parity and JOBS-002 closure | JOBS-002 | Locally complete. Application answers/recruiter drafts now live on the dedicated page, note markers are encapsulated, edits are lossless, dirty navigation is guarded, focus returns to the row, tenant regressions pass, and Chromium covers 375/768/1440 light/dark/history/error/long data. Production smoke remains. |
| 5 | Cross-application contrast/accessibility pass | UX-002, UX-003, VER-001 | In progress. Audit semantic alerts, secondary text, focus, loading/empty/error states and remaining hardcoded colors before documenting larger redesigns. |
| 6 | Honest Free/Pro homepage and upgrade surfaces | PRODUCT-001 | Not started. Inventory existing claims first; do not invent pricing, limits or trial terms before billing configuration is real. |
| 7 | Complete application action matrix and full regression | VER-001 | Not started. Populate incrementally, then run the complete backend/frontend/sidecar/E2E gates and accurately classify external production/provider checks. |
| 8 | Tracking and blocker reconciliation | All | Keep this plan, progress, handoff, verification log and `BLOCKERS.md` aligned after every logical increment; remove stale CI/dependency statements only when current evidence proves them obsolete. |
@@ -700,11 +700,11 @@ This queue records the highest-value work that can proceed without production cr
- **Required tests:** route/history/filter persistence/focus/unsaved/direct link/mobile, tenant authorization.
- **Required browser verification:** three widths/themes/keyboard/back-forward/refresh/error/long data.
- **Required production verification:** existing application/workspace smoke.
- **Status:** `IN PROGRESS`.
- **Blocker:** none after dependencies.
- **Status:** `IMPLEMENTED — NOT VERIFIED`.
- **Blocker:** authenticated production smoke remains external.
- **Evidence:** V-158V-162; `docs/verification/jobs-002-application-workspace.md`.
- **Commit:** `bd5362c` (URL-owned list state), `109745e` (canonical dedicated page/table/sidebar integration).
- **Remaining work:** canonical `/jobs/:id`, row/card navigation, compact priority columns, richer job details, contextual links, sidebar cleanup and notification popover are implemented. Still required: confirm section dirty-edit behavior; browser widths/themes/keyboard/history/error/long-data checks; authorization regression and production smoke. Do not place every field in the table or duplicate workspace data.
- **Remaining work:** repository and real-Chromium scope is locally complete, including application-package parity, dirty navigation, focus return, tenant denial, three widths/themes/history/error/long data. Authenticated production smoke and a native assistive-technology spot check remain. Do not place every field in the table or duplicate workspace data.
### UX-003 — Kanban theme-state correction
+8 -8
View File
@@ -2,17 +2,17 @@
Updated: 2026-08-15
- **Exact current task:** commit/push the CV contrast/public-render hardening increment, then continue JOBS-002 parity and regression closure.
- **Last completed step:** fixed header/sidebar contact contrast, added automatic custom-accent foreground selection, and restricted public renderer colour/font overrides to safe supported values.
- **Files currently modified:** CV settings normalization, themed renderer, renderer regressions and CAREER-002/work-programme evidence.
- **Commands already run:** failing renderer contrast reproduction; renderer/settings 25/25; full backend 644/644; CV Builder/public UI 22/22; real Chromium computed-style/overflow and 17-page PDF proof; diff check.
- **Test results:** all repository tests listed above pass. Chromium computed expected white/dark/white foregrounds for Modern/default, Modern/light override and Technical/sidebar, with zero overflow; the 259,447-byte A4 PDF has 17 pages and extractable final-page text. Jest retains the documented force-exit/open-handle notice.
- **Exact current task:** commit/push JOBS-002 application-package parity and navigation-safety closure, then continue the cross-application contrast/accessibility pass.
- **Last completed step:** moved application-answer/recruiter drafts onto the dedicated workspace, encapsulated legacy note markers, preserved answers through ordinary edits, guarded dirty navigation and restored list focus.
- **Files currently modified:** workspace/draft backend and UI boundaries, route/focus behavior, unit/Chromium regressions, application-workspace architecture and programme evidence.
- **Commands already run:** focused backend 30/30; focused frontend 28/28 plus route/focus 6/6; full backend 647/647; full frontend 54 suites/227 tests; optimized build; full Playwright 7/7; repeated targeted workspace Chromium passes; diff review pending after documentation.
- **Test results:** all repository tests listed above pass. Workspace Chromium covers explicit light/dark at 375/768/1440, keyboard entry, Back/Forward, focus return, refresh, dirty-edit cancel, long data, missing-job handling and zero horizontal overflow. Jest retains the documented force-exit/open-handle notice.
- **Services currently running:** none on task-owned ports 3000/5202. Playwright stopped its disposable API/Next servers. Pre-existing Docker services were not changed.
- **Temporary files or processes:** no task-owned process is running and the failed disposable migration database was removed. Existing synthetic browser evidence/account and startup-created local backup remain documented. No provider account, real email, private content, paid service or production service was accessed.
- **Production changes currently active:** none. No deployment, migration, provider connection/sync/send or production payload occurred.
- **Rollback status:** downgrade `20260810080858_AddEmailDraftClientRequestId`, then `20260810075206_AddEmailDrafts`, before reverting draft commits; then follow the existing MAIL rollback order (`ee5ef7e`, `449faeb`, `123fc55`/`e9937ac`, ledger downgrade before `653f011`). No production migration/deploy/provider grant occurred.
- **Uncommitted changes:** V-168 CV contrast and renderer-setting hardening; no dependency/schema/config/migration change. V-166/V-167 are pushed as `a6cffe0`/`f0b9b22`.
- **Uncommitted changes:** V-169 JOBS-002 parity/navigation increment; no dependency/schema/config/migration change. V-166/V-167/V-168 are pushed as `a6cffe0`/`f0b9b22`/`3b86ea2`.
- **Known failures:** live deployment is not verified because PR deploy is intentionally skipped and the active branch is not approved for merge. Draft export/API/UI, full thread/category actions and non-Gmail review remain; existing accounts need re-consent and IMAP stays read-only. A clean full-chain SQLite apply fails in the pre-existing JT-019 migration before the new draft migration. Browser/provider/MariaDB/production unavailable or unverified; recovery scan performance is unmeasured at large ledger scale; Jest open handles; SEC-006 parser dependency work is still separately gated; parser isolation remains SEC-007.
- **Exact next action:** review, commit and push V-168; then trace the remaining legacy-vs-dedicated Job Details feature parity and close the highest-value JOBS-002 gap.
- **Work that can continue independently:** the immediate queue in the master plan: Career lossless persistence, CV contrast, JOBS-002 closure, cross-app contrast/accessibility, PRODUCT-001 and VER-001. UX/JOBS production, MAIL provider mutations, SEC-006/007 and PROD packages retain their recorded external gates.
- **Exact next action:** review, commit and push V-169; then execute the scoped cross-application contrast/accessibility inventory and corrections under UX-002/UX-003/VER-001.
- **Work that can continue independently:** cross-app contrast/accessibility, PRODUCT-001, VER-001 and tracking reconciliation. UX/JOBS production, MAIL provider mutations, SEC-006/007 and PROD packages retain their recorded external gates.
- **Decisions still required from the user:** none for synthetic/code-inspected repository work. Any provider connection or send test, internet/package upgrades, private data, external/paid providers and production actions retain explicit approval/safety gates; SEC-009 retention/legal policy remains unresolved.