fix(ui): retain locale-aware document review labels

This commit is contained in:
cesnimda
2026-11-03 20:09:19 +01:00
parent 31ce702716
commit ccf8d26426
30 changed files with 1544 additions and 6 deletions
@@ -0,0 +1,15 @@
# IM10 initial localisation and preservation checkpoint
3 November 2026. Owner approved **"Approve IM09 and A3-IM10"**. Base `7a9de940dfdc41023f87a1ef38a5fd86a0b8e477` is published/remotely verified. This bounded checkpoint advances IM10; it does not complete cross-application or roadmap acceptance.
The reviewed attachment-size patch `1ce93ca0e3a906673e636e56f1b910756ca78bb2` was narrowly cherry-picked as `31ce70271663a5d57c7b2eb8f80cd69be5cc95ef`. Git reconciled the newer ApplicationAssets/test changes without conflict; the older branch tree was not merged. Fresh affected tests on this baseline: **63 PASSED**, zero failed/skipped, two suites. Original `docs/i18n/ATTACHMENT_SIZE_*` records bind the old isolated source and61-case run; they remain historical, not fresh integration evidence. Current source/evidence binding is the cross-app manifest.
Whole-document AI review displayed the internal `headline` ID when no title was supplied. It now falls back to the existing translated headline-override label. Supplied/original titles and unknown IDs keep existing behavior. A new regression failed before the fix and passes afterward: switching UI language changes only chrome, retaining the reviewed English proposal without another generation or apply. Full studio successor: **61 PASSED**, zero failed/skipped; existing direct-focus React act warnings remain. Total fresh unit coverage for this checkpoint is124 distinct cases/three suites, not the old61+new63+61 combined.
The existing AI/settings browser verifier was reused in an affected-review mode, with a separate output directory. **16 controlled journeys/16 axe scans** passed at320/390/768/1440, EN/NB and light/dark. Caption asserted, English output language retained under Norwegian UI, explicit review shown with zero mutations and16 synthetic proposal responses. No live model, semantic translation-quality, backend end-to-end, provider or physical-PDF claim. Original IM08 captures/manifests are not overwritten by this run. Native artifacts: `evidence/cross-app/browser-ai-review/REVIEW.json` and16 captures.
The TypeScript AST census confirms all34 inherited route patterns are registered. The complete57-group preservation register has the same LF-normalised hash as integration `d3d338376444b8abdcaf7200f682faa3daf1ad10`. Source statuses/required closures remain unchanged:56 PARTIAL/one DEFERRED. This is source membership and criteria preservation, not browser/auth/deployed or whole-capability acceptance. The approved design's frozen237c79b8 coverage pack was read for the full route/group map; no new design exploration or production-UI approval was inferred.
Typecheck, full lint, scoped verifier lint and static-export build PASSED. AST-only graph refreshed locally; optional SQL/symbol-less limits remain. Independent source/verifier/integration review found no actionable issues. Backend and physical-renderer sources are unchanged; no repeat backend/PDF run was justified for these display changes. Rollback reverts the caption patch and narrow attachment localisation integration; no database rollback.
Remaining authorised work: secondary-route connected/responsive/accessibility checks and an evidence-by-group reconciliation across the accepted A3 increments; combined affected regression and final A3 proposal. Native/human/provider, full European localisation, Phase10, Global Jobs dependencies, public homepage, final integrated security/recovery/hosted CI/release gates remain separate. Mounted AI entitlement refresh and granular Ghosted pause remain OPEN. Do not dispatch the general auth-changed event as a shortcut: it resets authResolved and can unmount drafts. No main merge, deployment, orchestrator or pre-P10 changes.
+14
View File
@@ -0,0 +1,14 @@
# A3-IM10 Cross-application qualification
3 November 2026. Owner explicitly approved **"Approve IM09 and A3-IM10"**. Isolated `codex/a3-ui-10` starts at published/remotely verified receipt `7a9de940dfdc41023f87a1ef38a5fd86a0b8e477`, from implementation `773c943165669bfc97bee46c53f73f124f398c0c`. Earlier A3 milestones are accepted; do not rerun their unaffected evidence or ask again.
- [x] Reconcile baseline and narrowly inspect attachment-size localisation1ce93ca0; cherry-picked only its reviewed delta as31ce70271663a5d57c7b2eb8f80cd69be5cc95ef. No wholesale merge of its older application tree. Fresh63 affected tests passed on this newer baseline; original61-case evidence remains historical.
- [ ] Correct remaining bounded presentation/localisation issues, including technical headline ID in whole-document AI review. Preserve UI vs output language and unchanged proposals during UI-language changes.
- [ ] Reconcile all57 preservation groups and34 inherited routes against current source and accepted evidence; keep PARTIAL/DEFERRED/native/provider qualification honest.
- [ ] Connected EN/NB, themes, phone/tablet/desktop, secondary-route/keyboard/accessibility coverage and combined affected regression. Reuse unchanged accepted evidence, qualify concrete affected changes.
- [ ] Types/lint/build, source/evidence identities, independent review, local commits, phase-branch publication and remote readback.
- [ ] Consolidated A3 acceptance proposal and remaining owner/technical gates. Final integrated security/recovery/release remain separate.
OPEN: granular per-user Ghosted pause lacks a persisted rules contract. Mounted AI entitlement refresh requires investigation that preserves current server authority and form lifetimes; blindly dispatching auth-changed resets authResolved and can unmount drafts. No inferred client-side entitlement grant or weakened auth guard is authorised as a shortcut. Native-language/human/device, real provider/model and hosted/production checks remain separate. The autonomous backlog orchestrator stays paused and untouched.
Initial bounded qualification: headline review caption fixed using the existing EN/NB label; fresh61 studio cases passed, including language-switch preservation. Combined with63 assets/attachments cases,124 distinct cases/three suites.16 controlled AI-review configurations/scans passed with zero writes and synthetic proposals only. Source census passed:57 unchanged preservation groups/34 registered route patterns; historical statuses not promoted. Independent review found no actionable issues. See CROSS_APP_LOCALISATION.md. Broader secondary-route/browser/combined qualification remains OPEN; this is not complete IM10 or a new acceptance request.
@@ -0,0 +1,14 @@
{
"date": "2026-11-03",
"branch": "codex/a3-ui-10",
"ownerApproval": "Approve IM09 and A3-IM10",
"base": "7a9de940dfdc41023f87a1ef38a5fd86a0b8e477",
"localisationDelta": { "original": "1ce93ca0e3a906673e636e56f1b910756ca78bb2", "integrated": "31ce70271663a5d57c7b2eb8f80cd69be5cc95ef", "scope": "Narrow cherry-pick, no wholesale older application merge", "freshCases": 63, "original61": "Historical isolated evidence, not fresh integration proof" },
"frontend": { "status": "PASSED", "distinctCases": 124, "suites": 3, "union": "63 application-assets/attachments +61 CV studio", "focused": "One new caption case overlaps61; red had one expected failure/60filtered NOT RUN", "warnings": "Existing studio direct-focus React act warnings; not warning-free" },
"browser": { "status": "PASSED", "configurations": 16, "scans": 16, "configuration": "320/390/768/1440 x EN/NB x light/dark", "mutations": 0, "proposals": "16 intercepted synthetic responses", "qualification": "Actual exported app; no backend/live model/semantic translation quality or physical PDF qualification" },
"sourceCensus": { "status": "PASSED", "groups": 57, "routePatterns": 34, "historicalStatuses": "56 PARTIAL/1 DEFERRED retained", "meaning": "Literal AST source membership and complete original register hash unchanged from d3d33837; not runtime/auth/whole-capability acceptance" },
"static": { "typecheck": "PASSED", "fullLint": "PASSED", "scopedVerifierLint": "PASSED", "build": "PASSED", "graph": "AST-only update completed locally; optional SQL parser absent and144 files yielded no symbols" },
"independentReview": "No actionable source/integration/verifier findings; no independent reruns added.",
"notRun": ["New backend or physical PDF run: sources unaffected", "Secondary-route connected browser qualification: still pending", "Native/human/European language qualification", "Real providers/models/hosted CI", "Integrated security/recovery/release/production"],
"remaining": ["Complete IM10 cross-application/secondary-route qualification", "Consolidated acceptance proposal", "AI mounted entitlement refresh and granular Ghosted pause remain open", "Full roadmap workstream gates remain separate"]
}
@@ -0,0 +1,915 @@
{
"base": "d3d338376444b8abdcaf7200f682faa3daf1ad10",
"policy": "Source membership and unchanged criteria only; no acceptance promotion.",
"sourceSha256": "a176e52d81c4b6ded63c5f38cb27e853aa09312f2cc45fc7e5b5e44573e0fef3",
"registerSha256": "a4c2a5a0244ea89381008218de32daee1f615a250eb3808b60e0ee103c674d4d",
"groups": [
{
"id": "PRES-E01",
"currentStatus": "PARTIAL",
"requiredClosure": "Public-page complete mobile/keyboard review and actual billing availability; no invented prices",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 0,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-E02",
"currentStatus": "PARTIAL",
"requiredClosure": "Real mail/reset submit/Turnstile and token expiry/used-token cases; query loss is repaired for its tested scope",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 1,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-E03",
"currentStatus": "PARTIAL",
"requiredClosure": "Actual consent/popups/revoked grants/relink; mailbox grants remain separate from sign-in",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 2,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-E04",
"currentStatus": "PARTIAL",
"requiredClosure": "Real authenticator/recovery and reader/trusted-device traversal; sensitive confirmations retained",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 3,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-E05",
"currentStatus": "PARTIAL",
"requiredClosure": "Native session-card refresh after remote revocation and complete device/AT acceptance",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 4,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-E06",
"currentStatus": "PARTIAL",
"requiredClosure": "Complete avatar/remove/password/email-change native flow; account identity remains distinct from career facts",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 5,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-E07",
"currentStatus": "PARTIAL",
"requiredClosure": "Spoken names/live state, settled drawer AX-name triage and historical command/dialog timing; no route silently hidden",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 6,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-E08",
"currentStatus": "PARTIAL",
"requiredClosure": "Full OS/locale/state cross-product, contrast/incomplete axe, reader/reflow; save feedback is distinct from server500 root-cause repair",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 7,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-E09",
"currentStatus": "PARTIAL",
"requiredClosure": "Broader BFCache/offline/old-bundle/deployed cases; presentation never becomes authorization",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 8,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-J01",
"currentStatus": "PARTIAL",
"requiredClosure": "Live NAV availability/freshness and long-result keyboard/narrow traversal",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 9,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-J02",
"currentStatus": "PARTIAL",
"requiredClosure": "Actual scheduler-to-owned-notification delivery, human/mobile delete acceptance and intended-provider qualification; deterministic runner is not live NAV",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 10,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-J03",
"currentStatus": "PARTIAL",
"requiredClosure": "Duplicate/company/date/interrupted creation and distinct creation-intent idempotency debt; preview/open is no-write",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 11,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-J04",
"currentStatus": "PARTIAL",
"requiredClosure": "Installed extension/share/no-replay and attachment failure recovery; keep payload and safe-return contracts",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 12,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-J05",
"currentStatus": "PARTIAL",
"requiredClosure": "Full saved-view CRUD/dirty page-size/history combinations and supported capacity; server query semantics unchanged",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 13,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-J06",
"currentStatus": "PARTIAL",
"requiredClosure": "Complete selected-scope/partial-failure/dirty/manual combinations; no hard-delete substitution",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 14,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-J07",
"currentStatus": "PARTIAL",
"requiredClosure": "Physical drag/touch/browser variants and O(N) full-array capacity; no capped hidden results or pipeline redefinition",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 15,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-J08",
"currentStatus": "PARTIAL",
"requiredClosure": "Scoped in-modal failure proof follows P6 manifest; complete contact/date/source-link and human acceptance remain",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 16,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-J09",
"currentStatus": "PARTIAL",
"requiredClosure": "Many-offer mobile/currency/date acceptance; no invented salary normalization",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 17,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-J10",
"currentStatus": "PARTIAL",
"requiredClosure": "Complete native roundtrip and target spreadsheet compatibility; job import is not account restore",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 18,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-W01",
"currentStatus": "PARTIAL",
"requiredClosure": "`followMode` metadata retained; compose consumer deferred. P5-05 optional preview lacks production host; full page remains",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 19,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-W02",
"currentStatus": "PARTIAL",
"requiredClosure": "Stored-event localisation/timezones/status-reload combinations ; job stale-replacement contract repaired within qualified MariaDB 12.2.2 scope",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 20,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-W03",
"currentStatus": "PARTIAL",
"requiredClosure": "Real-model truthfulness/freshness/cancel quality; route entry never auto-generates; unrelated AI survives C11 withholding",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 21,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-W04",
"currentStatus": "PARTIAL",
"requiredClosure": "Mobile interruption/edit/delete/reader; item identity and keyboard alternatives retained; no invented due-date schema",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 22,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-W05",
"currentStatus": "PARTIAL",
"requiredClosure": "**P2-D01 remains ordinary passing**; broader attach-render/model/deployed combinations remain; owner/job association unchanged",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 23,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-W06",
"currentStatus": "PARTIAL",
"requiredClosure": "Complete native history/reject/reader/model combinations; no canonical mutation or auto-send",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 24,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-W07",
"currentStatus": "PARTIAL",
"requiredClosure": "Actual production restore/rollback/all-storage combinations; current edits/delete cannot mutate frozen bytes; capture is not delivery",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 25,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-W08",
"currentStatus": "PARTIAL",
"requiredClosure": "Physical drop, full rename/download/reader and deployed storage; AI inclusion remains explicit",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 26,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-W09",
"currentStatus": "PARTIAL",
"requiredClosure": "Real-model and physical software-keyboard/reload/reader; preparation is not a scheduled interview",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 27,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-W10",
"currentStatus": "PARTIAL",
"requiredClosure": "Timezones/provider delivery; `followMode` reviewed compose UI remains deferred, no automatic send",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 28,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-W11",
"currentStatus": "PARTIAL",
"requiredClosure": "F21 DST/date-only/offsets, real provider events/scheduler delivery and historical unconfirmed Rules500 cause",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 29,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-W12",
"currentStatus": "PARTIAL",
"requiredClosure": "Disconnect/reconnect and F20 enabled-worker fault recovery; stable operation IDs/no duplicate starts",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 30,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-C01",
"currentStatus": "PARTIAL",
"requiredClosure": "Full long-tail mobile/human acceptance; canonical concurrency has bounded SQLite/MariaDB repair proof; singleton source distinct from identified variants",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 31,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-C02",
"currentStatus": "PARTIAL",
"requiredClosure": "Complete native historical restore/clipboard/avatar/reader; live inherited CVs may reflect later source changes",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 32,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-C03",
"currentStatus": "PARTIAL",
"requiredClosure": "Scanned/OCR corpus and complete low-confidence/discard/native-reader flow; extracted proposal is not canonical truth",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 33,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-C04",
"currentStatus": "PARTIAL",
"requiredClosure": "Many-item/delete/keyboard/human acceptance; SQLite compatibility repaired with owner SQL preserved, full frontend/production acceptance remains qualified",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 34,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-C05",
"currentStatus": "PARTIAL",
"requiredClosure": "Library migration not complete; publish/unpublish/old-slug revocation and every template combination required",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 35,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-C06",
"currentStatus": "PARTIAL",
"requiredClosure": "Physical keyboard/touch/AT and broader short-height/wrapped/deployed cases; one editor/save/preview owner",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 36,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-C07",
"currentStatus": "PARTIAL",
"requiredClosure": "Physical selection/drop/all-browser and exhaustive reset/inheritance combinations; sibling/canonical/frozen separation retained",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 37,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-C08",
"currentStatus": "PARTIAL",
"requiredClosure": "Production fonts/portraits/wrapped lines/custom color/reader; schematic gallery is not final-photo qualification",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 38,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-C09",
"currentStatus": "PARTIAL",
"requiredClosure": "Advanced cross-product/manual print/deployed fonts; UI locale distinct from document locale; no print geometry styling change",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 39,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-C10",
"currentStatus": "PARTIAL",
"requiredClosure": "Long offline/history and IF-CV-UNSAVED-01 trace; settings history is not immutable historical profile/PDF; profile/job saves remain separate",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 40,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-C11",
"currentStatus": "DEFERRED",
"requiredClosure": "**0/366 configured-target calls;0 human semantic reviews;review UI absent.** Production503 `cv_ai_unavailable`/no provider/no write remains; safe withholding is not generation acceptance",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 41,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-C12",
"currentStatus": "PARTIAL",
"requiredClosure": "Deployed Linux/font/photo/browser/manual-print qualification and complete revoke/busy-recovery cases; white print pages retained",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 42,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-M01",
"currentStatus": "PARTIAL",
"requiredClosure": "Full edit/delete/paste/reader native combinations; logging is not sending",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 43,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-M02",
"currentStatus": "PARTIAL",
"requiredClosure": "Actual provider threads/multi-account revoke/reconnect/sync failures; cross-job changes owner-bound",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 44,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-M03",
"currentStatus": "PARTIAL",
"requiredClosure": "Large mailbox/native attachments/complete reader acceptance; global inbox remains Phase7 migration",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 45,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-M04",
"currentStatus": "PARTIAL",
"requiredClosure": "Sandbox delivery/reconnect/dirty interruption; no automatic uncertain resend; reviewed `followMode` UI deferred",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 46,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-M05",
"currentStatus": "PARTIAL",
"requiredClosure": "Real provider and complete proposed-job create flow; route opening is no-write",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 47,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-M06",
"currentStatus": "PARTIAL",
"requiredClosure": "Real grants/revoke/token expiry/reconnect/IMAP safety; keep sign-in identity separate",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 48,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-S01",
"currentStatus": "PARTIAL",
"requiredClosure": "Exact cohort/timezone/sample/unsupported metrics and whole reader acceptance; no fabricated statistics or Analytics rebuild",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 49,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-S02",
"currentStatus": "PARTIAL",
"requiredClosure": "Historical500 causes unproved; full human/notification acceptance; order/resize/reset/cross-device design remains Phase8",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 50,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-S03",
"currentStatus": "PARTIAL",
"requiredClosure": "Language failure visibility is separate from RD11 server cause; RD12 notification locking/RD13 Rules500 and human/provider acceptance retained",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 51,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-S04",
"currentStatus": "PARTIAL",
"requiredClosure": "Checkout/webhook/portal and provider delivery; temporary C11 withholding cannot disable unrelated AI or imply successful review",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 52,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-S05",
"currentStatus": "PARTIAL",
"requiredClosure": "Current complete backup/restore/keys/tombstones/rollback and deletion/provider policy; downloading backup is not restore proof",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 53,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-A01",
"currentStatus": "PARTIAL",
"requiredClosure": "Mounted-role revoke/full persisted mutations/reset delivery; hiding navigation never authorizes API calls",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 54,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-A02",
"currentStatus": "PARTIAL",
"requiredClosure": "Native successful persisted undo/restore and unsupported-action denial; no generic undo semantics",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 55,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
},
{
"id": "PRES-A03",
"currentStatus": "PARTIAL",
"requiredClosure": "Actual guarded diagnostic/SMTP/model/maintenance and sensitive-output qualification; no production jobs launched",
"sourceCriterion": {
"path": "docs/redesign/phase-9/preservation.json",
"index": 56,
"originalCriteria": "docs/redesign/phase-2/PRESERVATION_MATRIX.md",
"laterResidual": "docs/redesign/phase-7/PRESERVATION.md"
}
}
],
"routes": [
{
"route": "/",
"owners": [
"Navigate",
"LandingPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/dashboard",
"owners": [
"DashboardView"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/analytics",
"owners": [
"AnalyticsPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/discover",
"owners": [
"JobDiscoveryPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/jobs",
"owners": [
"JobTable"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/jobs/:id",
"owners": [
"ApplicationWorkspacePage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/reminders",
"owners": [
"RemindersView"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/operations",
"owners": [
"OperationsPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/kanban",
"owners": [
"LegacyBoardRedirect"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/companies",
"owners": [
"CompaniesTable"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/offers",
"owners": [
"OfferComparisonPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/correspondence",
"owners": [
"CorrespondenceInboxPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/correspondence/review",
"owners": [
"LegacyCorrespondenceReviewRedirect"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/profile",
"owners": [
"ProfilePage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/applications/:id",
"owners": [
"LegacyApplicationRedirect"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/career",
"owners": [
"CareerWorkspacePage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/career/builder",
"owners": [
"CvBuilderPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/career/builder/:id",
"owners": [
"CvBuilderEditor"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/documents",
"owners": [
"DocumentsPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/admin/audit",
"owners": [
"AdminAuditPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/admin/users",
"owners": [
"AdminUsersPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/admin/system",
"owners": [
"AdminSystemPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/trash",
"owners": [
"JobTable"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/settings",
"owners": [
"SettingsView"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/settings/connected-accounts",
"owners": [
"ConnectedAccountsPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/login",
"owners": [
"LoginPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/register",
"owners": [
"LoginPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/forgot-password",
"owners": [
"ForgotPasswordPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/reset-password",
"owners": [
"ResetPasswordPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/verify-email",
"owners": [
"VerifyEmailPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/confirm-email-change",
"owners": [
"VerifyEmailPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/microsoft-legacy-relink",
"owners": [
"MicrosoftLegacyRelinkPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/cv/:slug",
"owners": [
"PublicCvPage"
],
"requiredClosure": "fresh route membership reconciliation plus affected connected workflow evidence; human checks remain distinct",
"sourceMembership": "PRESENT"
},
{
"route": "/admin/processing",
"owners": [
"AdminProcessingPage",
"AdminProcessingController"
],
"requiredClosure": "Human accessibility/device/native language and integrated acceptance remain separate.",
"sourceMembership": "PRESENT"
}
],
"limits": [
"57 historical group statuses and original criteria retained, not promoted.",
"Not browser/auth/provider/native/deployed or whole-capability acceptance. CalendarPage retains the original reminder route and owner internally."
]
}
@@ -0,0 +1,131 @@
{
"base": "7a9de940dfdc41023f87a1ef38a5fd86a0b8e477",
"policy": "LF-normalised text, raw PNG SHA256",
"scope": "Initial bounded IM10 checkpoint only, not final acceptance",
"sources": {
"job-tracker-ui/src/components/Attachments.tsx": "02081be8282cb3d1a525b336bededb8aabe561cc3b73e1b98e924f9ef945add1",
"job-tracker-ui/src/components/ApplicationAssets.tsx": "95465d9a881af97e55ad6f74ff283f81c452c645cc37ff28e7212ea7a32e9d57",
"job-tracker-ui/src/attachments.test.tsx": "89bb3e277ae7be652073eec6d3b6188bcbeaea8b29b07478ff5b21654be8e7c1",
"job-tracker-ui/src/application-assets.test.tsx": "d07f22661d8efbd65dbf4e92aa9722d6159438e6b354ed0c3c4a41c6d55b43ac",
"job-tracker-ui/src/views/CvBuilderEditor.tsx": "34672dabca47ac62d873e8d00842e71e82e668392b27a218b6d5641433200ca0",
"job-tracker-ui/src/cv-builder-deep-link.test.tsx": "75f1e8656be6e57e8ec38438009d59c5b179617b375fcdd01f75638a461ca14f",
"job-tracker-ui/src/cvBuilder.ts": "c021bafeabbc8ad3526d1b10b90ad8f7f0958ded8ed26eac8c1d28b53098b64d",
"job-tracker-ui/src/i18n/I18nProvider.tsx": "d22b5d033d0e405ffb5d581c752d61a24056d1e496f5f6a2f1baecef500f2113",
"job-tracker-ui/src/i18n/translations.ts": "d3167487ec82e302bb26c9269b4a79b03a269b85ed8414b11cf38a9bb8f3d0a7",
"job-tracker-ui/src/App.tsx": "a176e52d81c4b6ded63c5f38cb27e853aa09312f2cc45fc7e5b5e44573e0fef3",
"job-tracker-ui/scripts/verify-a3-ai-settings.mjs": "373a77fd91b8982be497039acc27ae9aa2fd3b21232c1255228d7bfe451cd47b",
"job-tracker-ui/scripts/verify-a3-preservation.mjs": "b0fd604c5ca42185b6985df27f0157ddd07caf1e578d55532b79d3d5eacf84c7",
"job-tracker-ui/package.json": "3745394e406cefa40d30a87e840bccb359be147bac6ffba736e2ae90898a8626",
"job-tracker-ui/package-lock.json": "bf31e90d7af03e8af059db2aaf893925b9e8881a30a1688034ed88ef45d4fcab",
"docs/pre-phase10-ux/preservation.json": "a4c2a5a0244ea89381008218de32daee1f615a250eb3808b60e0ee103c674d4d",
"docs/ui-modernisation/UI-10.md": "356a6fda1411d7bd98ac06629c65f7aa4d4f81de6a97f8971cc4b0b23302e04a",
"docs/ui-modernisation/CROSS_APP_LOCALISATION.md": "aaa4c0e515629e7836929b22f0401df9de43158f1d1a27db4d8d25be600fa659"
},
"evidence": {
"browser-ai-review/ai-review-en-dark-1440.png": "7049cc12f57b4796ed2b963f7739e44d684c03587e18c71543a45f8eaa5f7147",
"browser-ai-review/ai-review-en-dark-320.png": "a507bc60317ea10a3efb65656a6cdeae3c6e9a27add74d60eb1c0c8953b3c3c1",
"browser-ai-review/ai-review-en-dark-390.png": "74f232cb0fd7ab17fcc067d0b0c839bfb2b4ded0f8042ee2e2d626ed3fadd1b8",
"browser-ai-review/ai-review-en-dark-768.png": "36d9ca233d913fccfc98032c28b338d53195f1bd26a7ce9a39979252cd18abea",
"browser-ai-review/ai-review-en-light-1440.png": "200eba8c65fe2b82ea77c77ff77494b13b53103c58aa74f0dbc4d2198e190bdf",
"browser-ai-review/ai-review-en-light-320.png": "bdb9a967a5f4fd77c30e6c8a8a869b4f0d914c1a0fa00bb62f5f9abd49b49bb3",
"browser-ai-review/ai-review-en-light-390.png": "a23682d8d49b8f0e921abdc00b33ae885da40294b3fe87b2e93905e8c31fe8d6",
"browser-ai-review/ai-review-en-light-768.png": "26bfd9f664375bdb14d69f7304fc58955fe3ad4f66304c77b80de1b5631f56aa",
"browser-ai-review/ai-review-nb-dark-1440.png": "da58bfdca3a744cabad648f3443280f3fa4e4630598a0771a02b087ad7364902",
"browser-ai-review/ai-review-nb-dark-320.png": "e2daecb27a684092553b6adad3329875c2ba3b4fd6053fb27034423a9c9d89f3",
"browser-ai-review/ai-review-nb-dark-390.png": "32f88f046f6ff78b36448670038cb09f5f8c4bf42aefa85a329f9e9905b5095d",
"browser-ai-review/ai-review-nb-dark-768.png": "8db2b94c961f19c81d578faa820b18abbf5113a755715692d0430dc8e4dfdd7e",
"browser-ai-review/ai-review-nb-light-1440.png": "a37237174378812aaeef368010543287dc3317285f4008108637a6f05fc87637",
"browser-ai-review/ai-review-nb-light-320.png": "f489b8ee922f623665bf4613e1950eed84ea63371b1ab91c357f8f954c5f7c5a",
"browser-ai-review/ai-review-nb-light-390.png": "87b800ec333f11b9c4d259852c73ca9f4ab3715a0c2845a0d42d72e7ba7c35fb",
"browser-ai-review/ai-review-nb-light-768.png": "7deeadc4621ef7f03f71ec79927dae7fb02156cb21fa233298b278fb51b2e5b8",
"browser-ai-review/REVIEW.json": "6337675839aa1d46120b6304f17c222970a85e3895f9a8eb2fa46fee88677696",
"CHECKS.json": "2113dc38ab21551293b4502fe50e939c793c705a63626a4fa35e28d9b47247bb",
"frontend/a3-cross-app-cv-tests.json": "7c0a31af27cfbb78c2455581de338c00c325b67a62684724cc21b28d9fbde970",
"frontend/a3-cross-app-localisation-tests.json": "ff74557cf54632cd535b65de0661ae602fa329e15350625dcaf745e83724e332",
"frontend/a3-cross-app-review-focused.json": "19d8e8e7bc1b9a8ddf6911dea362f182b00dae7afb4fb5f27850bef72cefe1a1",
"frontend/a3-cross-app-review-red.json": "fb4ac8d49c691998d42aba7f57c3b83f98dc23f2fb2ddb18802c80e14f58fe9b",
"PRESERVATION_CENSUS.json": "759297e6578274efc0f0c6cfea67c9e08b7d425efa62d1d7a043b9eb9805808d"
},
"export": {
"404.html": "b4c33da6d53512a33d317e329653dfa129b158aeb18d1655377a31fbbebd7b58",
"__next.__PAGE__.txt": "51f937e04cc1bc639c851e5e736bdae59ba173018eee670ec42c70ddef1253a6",
"__next._full.txt": "82bffb4dc5832441a8d1451368558e3f4ec4cda2a3bc96072e5efe87a6cac0b5",
"__next._tree.txt": "8170048bddec2d4f65b53f1cf5ab69fc454081429a0ad9325cb57468110e5efa",
"_next/static/bn2MCY_eRqJUjw-m-UfIm/_buildManifest.js": "9476e0afd3f9da68a64e6ec58631191fd3eaca62c9f5a377e7517fe9a89e59ea",
"_next/static/bn2MCY_eRqJUjw-m-UfIm/_clientMiddlewareManifest.js": "5483e3295dc35dfe29ea932efc85341c916f10ff78ff5b0e965e003710893a4a",
"_next/static/bn2MCY_eRqJUjw-m-UfIm/_ssgManifest.js": "678f6ce2cb80b1fe72fc67e7412be6e2ab6ada083111b64f7c40d35e3cba5e00",
"_next/static/chunks/0-_aq6ipzcshj.js": "39f90c215bf52aef6274ed3dcc0f8af32e21a37fe8845b3bca0d6ea60da6a8c2",
"_next/static/chunks/0ah1fzqmie05a.js": "5c65505a7dcbac63ac71d254e619a4c800943bfb4fa16cd40c10cdbe7e9b6e31",
"_next/static/chunks/0bdt7ln111t48.js": "6184b1a61f22e2a640c17941634fdc75678ce93d142848d9f07f163e0d1fd201",
"_next/static/chunks/0bwvt3mysnclc.js": "7705667a1b75812b7833d9c9dff47fe023015e58e382c40f4507d9948c973af4",
"_next/static/chunks/0c-j9v44ea4gk.js": "d7e04926724f76dc50b5202522fab3bb553370d040396394e84c342de466512b",
"_next/static/chunks/0cz1d0mv5g_q7.js": "0973c1d64c88adc8e3c950410cb58b288f72118d5965b78049438deb8f2f9683",
"_next/static/chunks/0gamdsp7ql8cu.js": "f641cd9e2957f5c01234df02211a085f8e8fe2009cf84817e4143f3c477e1dc2",
"_next/static/chunks/0jcvc3qm6-lyk.js": "7c27e1fe373b822adc68c63096a5bf38444ad605b9743f0920271652989c56f1",
"_next/static/chunks/0q1wd_b10phzr.js": "307f4a4ed0f1ef2d87b9de51dbcac2382a39aa8bab359994ee7aa41529215b4e",
"_next/static/chunks/0q20g9o8x-k8z.js": "3d4d9086985419aa8866b032158196c774acb8bf318f3c8245508c8daa9c5148",
"_next/static/chunks/0q_pwu9jxv4-d.js": "42a43b3d7245a413c7c29b4cbe87823037a6dbc637e2e282c92405470e0f575d",
"_next/static/chunks/0yg1x7i96lj87.js": "2aad3c0f9e8b7b5a5123a2a439970c49db0be353236e22f9b6eafaaf01328c15",
"_next/static/chunks/14-lfugawba2w.js": "6a5780ca3c84d7f130f3c0a14431c85c7a1e799e2645b8c171161dab40a64360",
"_next/static/chunks/1435in_k_-dhc.js": "4757476512d5c4dd25f9264a18b304ed4824b23aff1c09e134fcbff21d9c36b6",
"_next/static/chunks/145oicobmjvm7.js": "d6bbbdeed1381652dc7412e5ce673a077579ecd5cee8934cb6b533c814098764",
"_next/static/chunks/14e7ovj0s3elm.js": "070567dd4d23fb9fa0b9ba132185a697af6578045d43b2b1c7bbb2a1594d935d",
"_next/static/chunks/16lfece6cnlln.js": "716363ba044f30b0e70440756b4e5eafa2d25f2e1628e855e3bc4ab9eabee3d3",
"_next/static/chunks/17eiliiibinqq.js": "790c342b1378a793260f9eac0b8c581261d517ee23320bb68995c43f9eaa36c1",
"_next/static/chunks/19zh-dmyml5oj.js": "2ab304f9b4155cdbac4d22e1b0b56b1c1f775c4bbb3ee93c425e297182bf522e",
"_next/static/chunks/1d0xrdyyzw7qc.js": "c11668ff1e152008e0d7b4454af12eb36c97df46a5860938e2eb5d8429b374a8",
"_next/static/chunks/1ke8pzecwofrg.css": "32e9ab963ebadebcbe2c68dffb24cfbfc8cc24255ad91b48b7941fc777bf7439",
"_next/static/chunks/1m4qrvmbq_fq9.js": "4d36c8ec83dc817f273178dc22f329ab026578075f58de68b6f133bcf911a8a1",
"_next/static/chunks/1req80b9jj38r.js": "eee4d2e3789e1215195dba99ad0f09d34f8c83da848322b76054722233e9dae3",
"_next/static/chunks/1wpxvpfa6li_4.js": "025ec0658f9480ccf14dd9be5cb28320ed14f4921c60ac9a2bf844d07bf4171b",
"_next/static/chunks/1xn023_28rgzj.js": "4f7f2108d030a48d039930736c92a55710975dddf419fe673f84d92899b1f575",
"_next/static/chunks/1xwc-b795syag.css": "f73c002233f931ca14d0ae58815c47ca9f2659f25b1547a6d1fdca12a2a00b3f",
"_next/static/chunks/1zi8i6dnxiac_.js": "8aea28bbe6a138e5d4b619429ca71570883a7aee974b86d5a4a746d90f704dbc",
"_next/static/chunks/22wx8--1b9tnq.js": "3f7d8e762371262c6a740b4dac21725b424847319afac46055e97074a99ff5f5",
"_next/static/chunks/2b49wlharl6fd.js": "40619f8a5a03fc7479b0679717b1e5ec0dea0a1944ce77f4ce9d29d2486fdb5c",
"_next/static/chunks/2br3ad_-bc7k9.js": "80fa55f7a32db4d743fda36747c36994fde00a0f53f2eb25b2a6d07c6fb97cd7",
"_next/static/chunks/2dmc6iqxm14fz.js": "3b20898e0cde315c48d6fd46abd562269bbf73c850528a4be2cfc2b9aa0c8f5e",
"_next/static/chunks/2ftgr1rx3r0dw.js": "8866e9ef62ab057bf9923604724edbb463bbdd6dd3fcbf614585f76005874811",
"_next/static/chunks/2ghgf2s9b2iou.js": "23d8ff31e2128d0541c1887785fb75885323fea7c5d4f35826513b75c12c2ae3",
"_next/static/chunks/2itnratrnd9c5.js": "8be0b191c2d54f7233ebf2f1e169b3bfef680fa93da21c08d8c43b05c3ec174f",
"_next/static/chunks/2kpcazmi6n6mk.js": "bea0de681fceff50056bfeccc5d035aff54d20918288051cb64bb259edd250c7",
"_next/static/chunks/2r6jrtuxq0e_x.js": "ac31577d9e5663a8f82645117a15743264054e5098b707c576e4e505398cc672",
"_next/static/chunks/2s2gjr6ro25dj.js": "7489e2ac285a05b563c2bcb4eaf9274bf930f2a7385f17d6d5e6850064b88b10",
"_next/static/chunks/2u5qve004opku.js": "be388d9a6aa423082bafb4584c3facc65ddfed71bcfa5c1d06b097b408c5ff97",
"_next/static/chunks/2xkey6z2nw7xp.js": "0f25bf09513b31298148cd262507b20b5a9ca5533317168c16481c544c6ffd6f",
"_next/static/chunks/2z42el0b2mp8_.js": "86ff990ef32c90c4839583e4f1d1bcbddb165dad3141b9fcd2ecec67f4ff24b8",
"_next/static/chunks/2z9e_b61gtc22.js": "b9d717dad26828438d4ff56cabca41a8055f5eaa54420fd0aeb6b4ba7d5baa0d",
"_next/static/chunks/31n24zcvyae0y.js": "110921bad10425af1d689cb939d97be75c7c0af9c35f8b16c5ff237db6fce893",
"_next/static/chunks/324qfub45abd6.js": "77ef8e17b89234fb19a80796d5d04d3e297c459e5cb41b35b5bc78c0b10b4984",
"_next/static/chunks/32_ah983ce851.js": "0c3cd0d2a5ad789e31226a9ea0506c50016804311a58548c7784b7b45aaecd14",
"_next/static/chunks/3329nxgnx3721.js": "ceedc7c69bf0617733b65bbf9f6a682a5d53177d4e8fdb86b8982cda2175f232",
"_next/static/chunks/357yqeklh7414.js": "0192ab7198ebbe299d34a934c504dd4b562d1cccebb6e9d4c5163930c881b14c",
"_next/static/chunks/3721l8sfm8icl.js": "06b67611b3a93515a375b803b54fe7063c049824f1ebf5c7f7db8701b5091e7c",
"_next/static/chunks/3bqn9b34na0b9.js": "f1b8ebcc1b22251c33c9f3a5d11c1f893cad2da2e8744a441e790f7347aa9e73",
"_next/static/chunks/3ckk_j5ril9ag.js": "87f631dae7b648d32171e9e05a3e000753ecb54f8d3b86a4401c0e4ab4d73553",
"_next/static/chunks/3gkylew_qn7cw.js": "7e6c74c81be0c41ab433e36d65b914f62c48f332922e27f7cc953476f4dd78cb",
"_next/static/chunks/3la4obitihzpv.js": "9a5a57b46db389b98f1fd5baa86eba1a360300dae9d1ff3ffeae7bc3378135b9",
"_next/static/chunks/3q4v10rrqy40n.js": "d87ff7b7a0f07d0d92eab3876481eb686a12d9c43d8b92cbe406aefa227a11c1",
"_next/static/chunks/3s4-jswh8gd_0.js": "38f29a1630a295d009178de7353b0138f8664a421ddf7f6adb7d6105ff747a68",
"_next/static/chunks/3u61o8t7m_jza.js": "86231c12e0f8cacc8638bed0bc4b34f645fc35e60de342dc154d3cce0c9a5afa",
"_next/static/chunks/40y_aqqilokr2.js": "1f5a5260316134d6bffe949400752ee6b42addf908ae714ef4ae4ebde916dddd",
"_next/static/chunks/43b5x8qjjh3ax.js": "6ee7261cf9a63e0e6ea181bbb09125e09948588b6e10b5c02727c686a6062a3a",
"_next/static/chunks/turbopack-25fzg9ay_1ss-.js": "c40f39e993a30c96d6247bb3a7b581538bb046efe8ef8ec07bea3ba32291750f",
"_not-found/__next._full.txt": "f9f9ca590aca43147f8296a55055a2d74adb084b15b1aa96aeb3824e2611c7e1",
"_not-found/__next._not-found/__PAGE__.txt": "9f06d77af71b3cb0cee6ed97464b8126c0a12d49a562ea4b96454b1854ad5253",
"_not-found/__next._tree.txt": "c24fdf123693e1e12f27fde3e9918c2c41030608b4e7883e133ee0cf268e9ca8",
"_not-found.html": "b4c33da6d53512a33d317e329653dfa129b158aeb18d1655377a31fbbebd7b58",
"_not-found.txt": "f9f9ca590aca43147f8296a55055a2d74adb084b15b1aa96aeb3824e2611c7e1",
"favicon.ico": "8d4923e2c487805ea9f852a685b2cf0fb10512ded8290d2a5c37d1cc8fd0702a",
"favicon.svg": "63ecf8f37f8bb146ecfae3917187c6b692d4e801641e8a314486a4007912f3a3",
"index.html": "4e4fde1f40864f519f0552becde231b341e1e9637d66c136ba7e367cbafdfdd1",
"index.txt": "82bffb4dc5832441a8d1451368558e3f4ec4cda2a3bc96072e5efe87a6cac0b5",
"logo192.png": "bc652031597fabd19b9f14e22a71f809490d218037521b3b64d013418c1390b4",
"logo512.png": "5129e9bc1ba812b711fd9a646d3a38a906d365a26ee685df183b8752458944d4",
"manifest.json": "2667ce63c2e0835b7007239816a5597639321d333da396a78638dfa9e8a7c935",
"mockups/dashboard.svg": "318be3adb1324c26eb30f05572a29528a3e38331c6a604652eef75b54f8c29dc",
"mockups/pipeline.svg": "db2ef41faabeb90e7ce85413e168581686c54535d970fc7d8deda3888a479de4",
"mockups/workspace.svg": "9bbab22349147c7b01d6e18c93c622a6f8aed6dedaf23715189ab54d60e1ddbd",
"robots.txt": "e5ab0d231eeb01b4a982d1c79a6729cac9797ad15a69247e4f28ba6afc149b4c"
}
}
@@ -0,0 +1,387 @@
{
"screens": [
{
"width": 320,
"language": "en",
"mode": "light",
"state": "ai-review",
"violations": []
},
{
"width": 320,
"language": "en",
"mode": "dark",
"state": "ai-review",
"violations": []
},
{
"width": 320,
"language": "nb",
"mode": "light",
"state": "ai-review",
"violations": []
},
{
"width": 320,
"language": "nb",
"mode": "dark",
"state": "ai-review",
"violations": []
},
{
"width": 390,
"language": "en",
"mode": "light",
"state": "ai-review",
"violations": []
},
{
"width": 390,
"language": "en",
"mode": "dark",
"state": "ai-review",
"violations": []
},
{
"width": 390,
"language": "nb",
"mode": "light",
"state": "ai-review",
"violations": []
},
{
"width": 390,
"language": "nb",
"mode": "dark",
"state": "ai-review",
"violations": []
},
{
"width": 768,
"language": "en",
"mode": "light",
"state": "ai-review",
"violations": []
},
{
"width": 768,
"language": "en",
"mode": "dark",
"state": "ai-review",
"violations": []
},
{
"width": 768,
"language": "nb",
"mode": "light",
"state": "ai-review",
"violations": []
},
{
"width": 768,
"language": "nb",
"mode": "dark",
"state": "ai-review",
"violations": []
},
{
"width": 1440,
"language": "en",
"mode": "light",
"state": "ai-review",
"violations": []
},
{
"width": 1440,
"language": "en",
"mode": "dark",
"state": "ai-review",
"violations": []
},
{
"width": 1440,
"language": "nb",
"mode": "light",
"state": "ai-review",
"violations": []
},
{
"width": 1440,
"language": "nb",
"mode": "dark",
"state": "ai-review",
"violations": []
}
],
"journeys": [
{
"width": 320,
"language": "en",
"mode": "light",
"translatedReviewCaption": "PASS",
"explicitReviewWithoutApply": "PASS",
"uiLanguageDistinctFromOutputLanguage": "PASS"
},
{
"width": 320,
"language": "en",
"mode": "dark",
"translatedReviewCaption": "PASS",
"explicitReviewWithoutApply": "PASS",
"uiLanguageDistinctFromOutputLanguage": "PASS"
},
{
"width": 320,
"language": "nb",
"mode": "light",
"translatedReviewCaption": "PASS",
"explicitReviewWithoutApply": "PASS",
"uiLanguageDistinctFromOutputLanguage": "PASS"
},
{
"width": 320,
"language": "nb",
"mode": "dark",
"translatedReviewCaption": "PASS",
"explicitReviewWithoutApply": "PASS",
"uiLanguageDistinctFromOutputLanguage": "PASS"
},
{
"width": 390,
"language": "en",
"mode": "light",
"translatedReviewCaption": "PASS",
"explicitReviewWithoutApply": "PASS",
"uiLanguageDistinctFromOutputLanguage": "PASS"
},
{
"width": 390,
"language": "en",
"mode": "dark",
"translatedReviewCaption": "PASS",
"explicitReviewWithoutApply": "PASS",
"uiLanguageDistinctFromOutputLanguage": "PASS"
},
{
"width": 390,
"language": "nb",
"mode": "light",
"translatedReviewCaption": "PASS",
"explicitReviewWithoutApply": "PASS",
"uiLanguageDistinctFromOutputLanguage": "PASS"
},
{
"width": 390,
"language": "nb",
"mode": "dark",
"translatedReviewCaption": "PASS",
"explicitReviewWithoutApply": "PASS",
"uiLanguageDistinctFromOutputLanguage": "PASS"
},
{
"width": 768,
"language": "en",
"mode": "light",
"translatedReviewCaption": "PASS",
"explicitReviewWithoutApply": "PASS",
"uiLanguageDistinctFromOutputLanguage": "PASS"
},
{
"width": 768,
"language": "en",
"mode": "dark",
"translatedReviewCaption": "PASS",
"explicitReviewWithoutApply": "PASS",
"uiLanguageDistinctFromOutputLanguage": "PASS"
},
{
"width": 768,
"language": "nb",
"mode": "light",
"translatedReviewCaption": "PASS",
"explicitReviewWithoutApply": "PASS",
"uiLanguageDistinctFromOutputLanguage": "PASS"
},
{
"width": 768,
"language": "nb",
"mode": "dark",
"translatedReviewCaption": "PASS",
"explicitReviewWithoutApply": "PASS",
"uiLanguageDistinctFromOutputLanguage": "PASS"
},
{
"width": 1440,
"language": "en",
"mode": "light",
"translatedReviewCaption": "PASS",
"explicitReviewWithoutApply": "PASS",
"uiLanguageDistinctFromOutputLanguage": "PASS"
},
{
"width": 1440,
"language": "en",
"mode": "dark",
"translatedReviewCaption": "PASS",
"explicitReviewWithoutApply": "PASS",
"uiLanguageDistinctFromOutputLanguage": "PASS"
},
{
"width": 1440,
"language": "nb",
"mode": "light",
"translatedReviewCaption": "PASS",
"explicitReviewWithoutApply": "PASS",
"uiLanguageDistinctFromOutputLanguage": "PASS"
},
{
"width": 1440,
"language": "nb",
"mode": "dark",
"translatedReviewCaption": "PASS",
"explicitReviewWithoutApply": "PASS",
"uiLanguageDistinctFromOutputLanguage": "PASS"
}
],
"errors": [],
"unexpectedWrites": [],
"writes": [],
"proposals": [
{
"width": 320,
"language": "en",
"mode": "light",
"outputLanguage": "en"
},
{
"width": 320,
"language": "en",
"mode": "dark",
"outputLanguage": "en"
},
{
"width": 320,
"language": "nb",
"mode": "light",
"outputLanguage": "en"
},
{
"width": 320,
"language": "nb",
"mode": "dark",
"outputLanguage": "en"
},
{
"width": 390,
"language": "en",
"mode": "light",
"outputLanguage": "en"
},
{
"width": 390,
"language": "en",
"mode": "dark",
"outputLanguage": "en"
},
{
"width": 390,
"language": "nb",
"mode": "light",
"outputLanguage": "en"
},
{
"width": 390,
"language": "nb",
"mode": "dark",
"outputLanguage": "en"
},
{
"width": 768,
"language": "en",
"mode": "light",
"outputLanguage": "en"
},
{
"width": 768,
"language": "en",
"mode": "dark",
"outputLanguage": "en"
},
{
"width": 768,
"language": "nb",
"mode": "light",
"outputLanguage": "en"
},
{
"width": 768,
"language": "nb",
"mode": "dark",
"outputLanguage": "en"
},
{
"width": 1440,
"language": "en",
"mode": "light",
"outputLanguage": "en"
},
{
"width": 1440,
"language": "en",
"mode": "dark",
"outputLanguage": "en"
},
{
"width": 1440,
"language": "nb",
"mode": "light",
"outputLanguage": "en"
},
{
"width": 1440,
"language": "nb",
"mode": "dark",
"outputLanguage": "en"
}
],
"unavailableReads": [
"/api/companies",
"/api/companies",
"/api/companies",
"/api/companies",
"/api/companies",
"/api/companies",
"/api/companies",
"/api/companies",
"/api/companies",
"/api/companies",
"/api/companies",
"/api/companies",
"/api/companies",
"/api/companies",
"/api/companies",
"/api/companies"
],
"blockedExternal": [
"https://fonts.googleapis.com",
"https://fonts.googleapis.com",
"https://fonts.googleapis.com",
"https://fonts.googleapis.com",
"https://fonts.googleapis.com",
"https://fonts.googleapis.com",
"https://fonts.googleapis.com",
"https://fonts.googleapis.com",
"https://fonts.googleapis.com",
"https://fonts.googleapis.com",
"https://fonts.googleapis.com",
"https://fonts.googleapis.com",
"https://fonts.googleapis.com",
"https://fonts.googleapis.com",
"https://fonts.googleapis.com",
"https://fonts.googleapis.com"
],
"limits": [
"All API, AI and preview results are synthetic fixtures. No model activation, semantic translation quality, backend end-to-end or physical PDF qualification.",
"No native device, screen reader, provider, integrated security, deployment or release acceptance."
]
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -7,7 +7,8 @@ import fs from 'node:fs';
import path from 'node:path'; import path from 'node:path';
const compiled = ts.transpileModule(fs.readFileSync(new URL('../src/i18n/translations.ts', import.meta.url), 'utf8'), { compilerOptions: { module: ts.ModuleKind.ESNext } }).outputText; const compiled = ts.transpileModule(fs.readFileSync(new URL('../src/i18n/translations.ts', import.meta.url), 'utf8'), { compilerOptions: { module: ts.ModuleKind.ESNext } }).outputText;
const { translations } = await import(`data:text/javascript;base64,${Buffer.from(compiled).toString('base64')}`); const { translations } = await import(`data:text/javascript;base64,${Buffer.from(compiled).toString('base64')}`);
const out = path.resolve(import.meta.dirname, '../../docs/ui-modernisation/evidence/ai-settings/browser'); const reviewOnly = Boolean(process.env.A3_AI_REVIEW_ONLY);
const out = path.resolve(import.meta.dirname, reviewOnly ? '../../docs/ui-modernisation/evidence/cross-app/browser-ai-review' : '../../docs/ui-modernisation/evidence/ai-settings/browser');
fs.mkdirSync(out, { recursive: true }); fs.mkdirSync(out, { recursive: true });
const report = { screens: [], journeys: [], errors: [], unexpectedWrites: [], writes: [], proposals: [], unavailableReads: [], blockedExternal: [] }; const report = { screens: [], journeys: [], errors: [], unexpectedWrites: [], writes: [], proposals: [], unavailableReads: [], blockedExternal: [] };
const browser = await chromium.launch(); const browser = await chromium.launch();
@@ -21,7 +22,7 @@ try {
await page.addInitScript(({ language, mode }) => { localStorage.setItem('uiLanguage', language); localStorage.setItem('jobtracker.themeMode', mode); }, { language, mode }); await page.addInitScript(({ language, mode }) => { localStorage.setItem('uiLanguage', language); localStorage.setItem('jobtracker.themeMode', mode); }, { language, mode });
let notifications = { emailFollowUpRemindersEnabled: true }; let notifications = { emailFollowUpRemindersEnabled: true };
let privacy = { enabled: true, externalProcessingAllowed: false, externalProcessingAvailable: false, effectiveExternalProcessing: false, provider: 'local' }; let privacy = { enabled: true, externalProcessingAllowed: false, externalProcessingAvailable: false, effectiveExternalProcessing: false, provider: 'local' };
let variant = { id: 3, name: 'Teacher CV', version: 4, settings: { language: 'en', themeId: 'modern', showPhoto: false, showPageNumbers: false, showIcons: true, sections: [], overrides: {}, customSections: [] }, isPublic: false, publicSlug: 'synthetic', jobApplicationId: null, updatedAtUtc: '2026-11-03T10:00:00Z' }; let variant = { id: 3, name: 'Teacher CV', version: 4, settings: { language: 'en', themeId: 'modern', showPhoto: false, showPageNumbers: false, showIcons: true, sections: [], overrides: {}, customSections: [], ...(reviewOnly ? { headline: 'Manual teacher headline' } : {}) }, isPublic: false, publicSlug: 'synthetic', jobApplicationId: null, updatedAtUtc: '2026-11-03T10:00:00Z' };
let proposal; let proposal;
const writes = [], proposals = []; const writes = [], proposals = [];
await page.route('**/*', route => { await page.route('**/*', route => {
@@ -73,6 +74,7 @@ try {
if (width >= 600) await page.getByRole('tab', { name: t(key), exact: true }).click(); if (width >= 600) await page.getByRole('tab', { name: t(key), exact: true }).click();
else { await page.getByRole('combobox', { name: t('settingsNavigation'), exact: true }).click(); await page.getByRole('option', { name: t(key), exact: true }).click(); } else { await page.getByRole('combobox', { name: t('settingsNavigation'), exact: true }).click(); await page.getByRole('option', { name: t(key), exact: true }).click(); }
}; };
if (!reviewOnly) {
await page.goto('http://localhost:4338/settings'); await page.goto('http://localhost:4338/settings');
await settingsSection('settingsTabAutomation'); await settingsSection('settingsTabAutomation');
const reminder = page.getByRole('switch', { name: t('settingsNotificationsFollowUpReminders'), exact: true }); await reminder.uncheck(); assert.equal(writes.length, 0); const reminder = page.getByRole('switch', { name: t('settingsNotificationsFollowUpReminders'), exact: true }); await reminder.uncheck(); assert.equal(writes.length, 0);
@@ -85,8 +87,14 @@ try {
await page.getByRole('tab', { name: t('cvEditorContent'), exact: true }).click(); await page.getByRole('tab', { name: t('cvEditorContent'), exact: true }).click();
await page.getByRole('textbox', { name: t('cvEditorHeadlineOverride'), exact: true }).fill('Manual teacher headline'); await expect.poll(() => variant.version, { timeout: 15000 }).toBe(5); assert.equal(proposals.length, 0); await scan('manual-fallback'); await page.getByRole('textbox', { name: t('cvEditorHeadlineOverride'), exact: true }).fill('Manual teacher headline'); await expect.poll(() => variant.version, { timeout: 15000 }).toBe(5); assert.equal(proposals.length, 0); await scan('manual-fallback');
await page.goto('http://localhost:4338/settings'); await page.getByRole('switch', { name: t('settingsAiEnabled'), exact: true }).check(); await page.getByRole('button', { name: t('settingsAiSave'), exact: true }).click(); await expect.poll(() => privacy.enabled).toBe(true); await page.goto('http://localhost:4338/settings'); await page.getByRole('switch', { name: t('settingsAiEnabled'), exact: true }).check(); await page.getByRole('button', { name: t('settingsAiSave'), exact: true }).click(); await expect.poll(() => privacy.enabled).toBe(true);
}
await page.goto('http://localhost:4338/career/builder/3'); await page.getByRole('tab', { name: t('cvEditorAiTools'), exact: true }).click(); await page.goto('http://localhost:4338/career/builder/3'); await page.getByRole('tab', { name: t('cvEditorAiTools'), exact: true }).click();
await page.getByRole('button', { name: t('cvDocumentAiReview'), exact: true }).first().click(); await expect(page.getByRole('button', { name: t('cvAiApply'), exact: true })).toBeVisible(); assert.equal(writes.length, 4); await scan('ai-review'); await page.getByRole('button', { name: t('cvDocumentAiReview'), exact: true }).first().click(); await expect(page.getByRole('button', { name: t('cvAiApply'), exact: true })).toBeVisible(); assert.equal(writes.length, reviewOnly ? 0 : 4);
await expect(page.locator('#cv-studio-panel-3').getByText(t('cvEditorHeadlineOverride'), { exact: true })).toBeVisible(); await scan('ai-review');
if (reviewOnly) {
assert.deepEqual(writes, []); assert.deepEqual(proposals, ['en']);
report.journeys.push({ width, language, mode, translatedReviewCaption: 'PASS', explicitReviewWithoutApply: 'PASS', uiLanguageDistinctFromOutputLanguage: 'PASS' }); await context.close(); continue;
}
await page.getByRole('combobox', { name: new RegExp(`^${t('cvAiLanguage')}`) }).click(); await page.getByRole('option', { name: t('languageNorwegianBokmal'), exact: true }).click(); await page.getByRole('combobox', { name: new RegExp(`^${t('cvAiLanguage')}`) }).click(); await page.getByRole('option', { name: t('languageNorwegianBokmal'), exact: true }).click();
await expect(page.getByRole('button', { name: t('cvAiApply'), exact: true })).toHaveCount(0); assert.equal(proposals.length, 1); assert.equal(variant.settings.headline, 'Manual teacher headline'); await scan('language-discard'); await expect(page.getByRole('button', { name: t('cvAiApply'), exact: true })).toHaveCount(0); assert.equal(proposals.length, 1); assert.equal(variant.settings.headline, 'Manual teacher headline'); await scan('language-discard');
await page.getByRole('button', { name: t('cvDocumentAiReview'), exact: true }).first().click(); await page.getByRole('button', { name: t('cvAiApply'), exact: true }).click(); await expect.poll(() => variant.version).toBe(6); await page.getByRole('button', { name: t('cvDocumentAiReview'), exact: true }).first().click(); await page.getByRole('button', { name: t('cvAiApply'), exact: true }).click(); await expect.poll(() => variant.version).toBe(6);
@@ -94,10 +102,10 @@ try {
assert.deepEqual(writes, ['notificationPreference', 'aiPreference', 'manualCvSave', 'aiPreference', 'explicitAiApply']); assert.deepEqual(proposals, ['en', 'nb-NO']); assert.deepEqual(writes, ['notificationPreference', 'aiPreference', 'manualCvSave', 'aiPreference', 'explicitAiApply']); assert.deepEqual(proposals, ['en', 'nb-NO']);
report.journeys.push({ width, language, mode, manualFallback: 'PASS', languageDiscardWithoutApply: 'PASS', explicitTokenApply: 'PASS', aiSettingsKeyboardFocus: 'PASS' }); await context.close(); report.journeys.push({ width, language, mode, manualFallback: 'PASS', languageDiscardWithoutApply: 'PASS', explicitTokenApply: 'PASS', aiSettingsKeyboardFocus: 'PASS' }); await context.close();
} }
assert.equal(report.screens.length, configurations.length * 6); assert.equal(report.journeys.length, configurations.length); assert.equal(report.writes.length, configurations.length * 5); assert.equal(report.proposals.length, configurations.length * 2); assert.equal(report.screens.length, configurations.length * (reviewOnly ? 1 : 6)); assert.equal(report.journeys.length, configurations.length); assert.equal(report.writes.length, reviewOnly ? 0 : configurations.length * 5); assert.equal(report.proposals.length, configurations.length * (reviewOnly ? 1 : 2));
assert.deepEqual(report.errors, []); assert.deepEqual(report.unexpectedWrites, []); assert.ok(report.blockedExternal.every(origin => origin === 'https://fonts.googleapis.com')); assert.deepEqual(report.errors, []); assert.deepEqual(report.unexpectedWrites, []); assert.ok(report.blockedExternal.every(origin => origin === 'https://fonts.googleapis.com'));
console.log(`PASS:${report.journeys.length} controlled journeys,${report.screens.length} axe scans/captures.`); console.log(`PASS:${report.journeys.length} controlled journeys,${report.screens.length} axe scans/captures.`);
} finally { } finally {
fs.writeFileSync(path.join(out, process.env.A3_PILOT ? 'PILOT.json' : 'BROWSER.json'), JSON.stringify({ ...report, limits: ['All API, AI and preview results are synthetic fixtures. No model activation, semantic translation quality, backend end-to-end or physical PDF qualification.', 'No native device, screen reader, provider, integrated security, deployment or release acceptance.'] }, null, 2)); fs.writeFileSync(path.join(out, reviewOnly ? 'REVIEW.json' : process.env.A3_PILOT ? 'PILOT.json' : 'BROWSER.json'), JSON.stringify({ ...report, limits: ['All API, AI and preview results are synthetic fixtures. No model activation, semantic translation quality, backend end-to-end or physical PDF qualification.', 'No native device, screen reader, provider, integrated security, deployment or release acceptance.'] }, null, 2));
await browser.close(); await browser.close();
} }
@@ -0,0 +1,37 @@
// Read-only source census. Route presence does not establish workflow or security acceptance.
import fs from 'node:fs';
import path from 'node:path';
import crypto from 'node:crypto';
import assert from 'node:assert/strict';
import { execFileSync } from 'node:child_process';
import ts from 'typescript';
const root = path.resolve(import.meta.dirname, '../..');
const registerPath = 'docs/pre-phase10-ux/preservation.json';
const registerBytes = fs.readFileSync(path.join(root, registerPath));
const register = JSON.parse(registerBytes);
const base = 'd3d338376444b8abdcaf7200f682faa3daf1ad10';
const digest = bytes => crypto.createHash('sha256').update(bytes.toString('utf8').replace(/\r\n/g, '\n')).digest('hex');
assert.equal(digest(registerBytes), digest(execFileSync('git', ['show', `${base}:${registerPath}`], { cwd: root })), 'Original preservation register must remain unchanged');
assert.equal(register.groups.length, 57); assert.equal(register.routes.length, 34);
const source = fs.readFileSync(path.join(root, 'job-tracker-ui/src/App.tsx'), 'utf8');
const ast = ts.createSourceFile('App.tsx', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
const declared = new Set();
function visit(node) {
if (ts.isJsxAttribute(node) && node.name.getText(ast) === 'path' && node.initializer && ts.isStringLiteral(node.initializer)) declared.add(node.initializer.text);
if (ts.isPropertyAssignment(node) && node.name.getText(ast) === 'path' && ts.isStringLiteral(node.initializer)) declared.add(node.initializer.text);
ts.forEachChild(node, visit);
}
visit(ast);
const missing = register.routes.filter(item => !declared.has(item.route));
assert.deepEqual(missing, [], 'All inherited route patterns must remain registered');
const result = {
base, policy: 'Source membership and unchanged criteria only; no acceptance promotion.',
sourceSha256: digest(source), registerSha256: digest(registerBytes),
groups: register.groups.map(({ id, currentStatus, requiredClosure, sourceCriterion }) => ({ id, currentStatus, requiredClosure, sourceCriterion })),
routes: register.routes.map(({ route, owners, requiredClosure }) => ({ route, owners, requiredClosure, sourceMembership: 'PRESENT' })),
limits: ['57 historical group statuses and original criteria retained, not promoted.', 'Not browser/auth/provider/native/deployed or whole-capability acceptance. CalendarPage retains the original reminder route and owner internally.'],
};
const out = path.join(root, 'docs/ui-modernisation/evidence/cross-app');
fs.mkdirSync(out, { recursive: true });
fs.writeFileSync(path.join(out, 'PRESERVATION_CENSUS.json'), JSON.stringify(result, null, 2));
console.log('PASS:57 unchanged preservation groups,34 inherited route patterns present in the TypeScript AST.');
@@ -5,6 +5,7 @@ import { createMemoryRouter, RouterProvider } from 'react-router-dom';
import CvBuilderEditor from './views/CvBuilderEditor'; import CvBuilderEditor from './views/CvBuilderEditor';
import { I18nProvider } from './i18n/I18nProvider'; import { I18nProvider } from './i18n/I18nProvider';
import { translations } from './i18n/translations';
import { ToastProvider } from './toast'; import { ToastProvider } from './toast';
import { api } from './api'; import { api } from './api';
import { emptyCvVariantSettings } from './cvBuilder'; import { emptyCvVariantSettings } from './cvBuilder';
@@ -1117,6 +1118,17 @@ test('changing whole-document output language discards the previous-language rev
expect(mockedApi.post.mock.calls.filter(([url]) => url === '/cv/ai/assist')).toHaveLength(1); expect(mockedApi.post.mock.calls.filter(([url]) => url === '/cv/ai/assist')).toHaveLength(1);
}); });
test('whole-document review labels follow UI language without translating or discarding the proposal', async () => {
await reviewDocumentSuggestion(JSON.stringify([{ id: 'headline', items: ['Reviewed headline'] }]));
const review = screen.getByText('Review 1 proposed change(s)').closest('.MuiPaper-root') as HTMLElement;
expect(within(review).getByText('Headline override')).toBeVisible();
act(() => window.dispatchEvent(new StorageEvent('storage', { key: 'uiLanguage', newValue: 'nb' })));
expect(within(review).getByText(translations.nb.cvEditorHeadlineOverride)).toBeVisible();
expect(within(review).getByText('Reviewed headline')).toBeVisible();
expect(mockedApi.post.mock.calls.filter(([url]) => url === '/cv/ai/assist')).toHaveLength(1);
expect(mockedApi.post.mock.calls.filter(([url]) => url === '/cv/variants/3/ai/apply')).toHaveLength(0);
});
test.each(['Apply', 'Reject'])('[PRES-C11 PRES-C07] whole-document AI %s changes only an explicitly accepted CV override', async action => { test.each(['Apply', 'Reject'])('[PRES-C11 PRES-C07] whole-document AI %s changes only an explicitly accepted CV override', async action => {
await reviewDocumentSuggestion(JSON.stringify([{ id: 'headline', items: ['Reviewed headline'] }])); await reviewDocumentSuggestion(JSON.stringify([{ id: 'headline', items: ['Reviewed headline'] }]));
expect(await screen.findByText('Review 1 proposed change(s)')).toBeInTheDocument(); expect(await screen.findByText('Review 1 proposed change(s)')).toBeInTheDocument();
+2 -1
View File
@@ -985,7 +985,8 @@ function DocumentAiTab({ settings, outline, onGenerate, onAccept }: CvAiCallback
<Stack spacing={1} sx={{ maxHeight: 360, overflowY: "auto" }}> <Stack spacing={1} sx={{ maxHeight: 360, overflowY: "auto" }}>
{changed.map((block) => { {changed.map((block) => {
const original = originals.find((item) => item.id === block.id); const original = originals.find((item) => item.id === block.id);
return <Paper key={block.id} variant="outlined" sx={{ p: 1 }}><Typography variant="caption" sx={{ fontWeight: 800 }}>{block.title ?? original?.title ?? block.id}</Typography><Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr" }, gap: 1, mt: 0.5 }}><Typography variant="body2" sx={{ whiteSpace: "pre-wrap", color: "text.secondary" }}>{[original?.subtitle, ...(original?.items ?? [])].filter(Boolean).join("\n")}</Typography><Typography variant="body2" sx={{ whiteSpace: "pre-wrap" }}>{[block.subtitle, ...(block.items ?? [])].filter(Boolean).join("\n")}</Typography></Box></Paper>; const label = block.title ?? original?.title ?? (block.id === "headline" ? t("cvEditorHeadlineOverride") : block.id);
return <Paper key={block.id} variant="outlined" sx={{ p: 1 }}><Typography variant="caption" sx={{ fontWeight: 800 }}>{label}</Typography><Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr" }, gap: 1, mt: 0.5 }}><Typography variant="body2" sx={{ whiteSpace: "pre-wrap", color: "text.secondary" }}>{[original?.subtitle, ...(original?.items ?? [])].filter(Boolean).join("\n")}</Typography><Typography variant="body2" sx={{ whiteSpace: "pre-wrap" }}>{[block.subtitle, ...(block.items ?? [])].filter(Boolean).join("\n")}</Typography></Box></Paper>;
})} })}
</Stack> </Stack>
)} )}