From f7f6b774b912649116621de027474e9cfed33bec Mon Sep 17 00:00:00 2001 From: cesnimda Date: Mon, 12 Oct 2026 13:32:55 +0200 Subject: [PATCH] feat(ui): migrate Career Profile structured editor --- docs/redesign/phase-7/COMMITS.md | 6 +- docs/redesign/phase-7/DEBT.md | 6 +- docs/redesign/phase-7/PRESERVATION.md | 6 +- docs/redesign/phase-7/README.md | 2 +- docs/redesign/phase-7/p7-03/README.md | 52 +- .../p7-03/evidence/editor-results.json | 7123 +++++++++++++++++ .../p7-03/evidence/editor-static-checks.json | 104 + .../p7-03/evidence/entry-baseline.json | 145 +- .../p7-03/evidence/source-id-results.json | 47 +- docs/roadmap/todo.md | 2 +- .../e2e/phase7-career-editor.spec.ts | 407 + job-tracker-ui/src/career-editor.test.tsx | 285 + .../src/career-workspace-page.test.tsx | 12 +- job-tracker-ui/src/i18n/translations.ts | 20 +- job-tracker-ui/src/profile-page.test.tsx | 4 +- .../src/views/CareerProfilePage.tsx | 96 +- .../views/career/CareerProfileSections.tsx | 155 +- 17 files changed, 8314 insertions(+), 158 deletions(-) create mode 100644 docs/redesign/phase-7/p7-03/evidence/editor-results.json create mode 100644 docs/redesign/phase-7/p7-03/evidence/editor-static-checks.json create mode 100644 job-tracker-ui/e2e/phase7-career-editor.spec.ts create mode 100644 job-tracker-ui/src/career-editor.test.tsx diff --git a/docs/redesign/phase-7/COMMITS.md b/docs/redesign/phase-7/COMMITS.md index e59a8a7..4c9d71d 100644 --- a/docs/redesign/phase-7/COMMITS.md +++ b/docs/redesign/phase-7/COMMITS.md @@ -14,9 +14,11 @@ Entry is the completed Phase6 successor receipt `b5319981ad3d1bd635daff861453d23 | P7-02 Career overview/evidence and final implemented checkpoint outcome | `8b4d5c21125e800199d3ecc2d9c059a80ac5125d` | [Report](p7-02/README.md#career-overviewevidence-commit), [frozen finite evidence](p7-02/evidence/career-results.json): affected46/3 (+14 cases), native14 and fresh ordinary P2-D01/mobile-override2, types/lint/build pass; all22 final PNGs actually inspected. BuildqG82wPnFf-IsAkFvXkmn6,75-file export;0 violations/99 incompletes and M09/M11/manual/provider qualifications retained. Actual Delete-cancel RED/repair and Windows CRLF test correction retained. Implemented P7-02 CONDITIONAL GO; [final Career hygiene](p7-02/evidence/career-static-checks.json) PASS05:48:32UTC (four commands0,9docs347links0errors/57+32 retained); normal push directly verified2026-10-12 05:51:04.849644UTC: localHEAD=origin=live development8b4d5c2, local/origin/live main27657f3 unchanged, worktree clean at observation. Actual receipt appended by successor; P7-03 entry satisfied with mandatory stable-ID/concurrency conditions. Fullfrontend610/backend1,034 derived only;57/32 unchanged/main NO-GO | -| P7-03 separate forward source-ID/null-metadata compatibility repair | `3047b6c4a87c43de6f397e4a3d109be9ce3ddeca` (local/unpushed) | [Prerequisite report](p7-03/README.md#prerequisite-runtime-and-finite-acceptance), [frozen finite results](p7-03/evidence/source-id-results.json): unit46/3 (+8/+1 suite), native2 and fresh ordinary preservation2, types/lint/build pass; all11 readback flagsTRUE and two final PNGs inspected with capture qualifications. One frontend normalizer owner only; API binary unchanged/no new backend build. BuildbzQiDlr6LeM9Gsel4WRS8;0 new axe attachments. Bounded forward repair GO; [final static checks](p7-03/evidence/source-id-static-checks.json) PASS06:21:53UTC at earlier scope. Later staged whitespace reported1; root committed despite failure. Historical committed check actualexit2 reports only new EOF blank line75. Repair remains unpushed pending a normal whitespace/docs successor and fresh staged gate; no runtime/assertion change. Old orphaned overrides and concurrency remain unrepaired; full618/90/browser216/backend1,034 derived only;57/32 unchanged/main NO-GO | +| P7-03 separate forward source-ID/null-metadata compatibility repair | `3047b6c4a87c43de6f397e4a3d109be9ce3ddeca` | [Prerequisite report](p7-03/README.md#prerequisite-runtime-and-finite-acceptance), [frozen finite results](p7-03/evidence/source-id-results.json): unit46/3 (+8/+1 suite), native2 and fresh ordinary preservation2, types/lint/build pass; all11 readback flagsTRUE and two final PNGs inspected with capture qualifications. One frontend normalizer owner only; API binary unchanged/no new backend build. BuildbzQiDlr6LeM9Gsel4WRS8;0 new axe attachments. Bounded forward repair GO; [final static checks](p7-03/evidence/source-id-static-checks.json) PASS06:21:53UTC at earlier scope. Later staged whitespace reported1; root committed despite failure. Historical committed check actualexit2 reports only new EOF blank line75. Repair was held unpushed at that failure gate; subsequent hygiene704637a and normal two-commit push are directly verified in the next row. No runtime/assertion change. Old orphaned overrides and concurrency remain unrepaired; full618/90/browser216/backend1,034 derived only;57/32 unchanged/main NO-GO | -| P7-03 repair hygiene successor | PENDING normal commit/push | Remove exactly one final blank line from the new profileCv.test.ts; preserve as-run immutable test/source/runtime identity and record the unhandled staged failure/local3047b6c4 honestly. No logic/assertion/count change, no test/build/native rerun. [Fresh corrected staged static checks](p7-03/evidence/source-id-hygiene-correction-static-checks.json) PASS06:32:12UTC (four commands0,10docs374links0errors/57+32 retained); normal hygiene successor commit and two-commit push pending; no amend/reset/force push/main change | +| P7-03 repair hygiene successor | `704637ab375c32d14aa46f9d4ef0f210136de4d9` | Remove exactly one final blank line from the new profileCv.test.ts; preserve as-run immutable test/source/runtime identity and record the unhandled staged failure/local3047b6c4 honestly. No logic/assertion/count change, no test/build/native rerun. [Fresh corrected staged static checks](p7-03/evidence/source-id-hygiene-correction-static-checks.json) PASS06:32:12UTC (four commands0,10docs374links0errors/57+32 retained); normal hygiene successor704637a and chronological repair3047+7046 push directly verified2026-10-12 06:34:48.620963UTC: localHEAD=origin=live704637a, local/origin/live main unchanged27657f3, clean worktree at observation; no amend/reset/force push/main change | + +| P7-03 structured-editor presentation | PENDING normal commit/push | [Final report](p7-03/README.md#final-structured-editor-result), [immutable finite evidence](p7-03/evidence/editor-results.json): affected54/4 (+8/+1 suite), editor11/source-ID2/Career14/ordinary preservation2, fresh types/lint/build pass on W4fUO7_GUC0Qh5FuL3qVL; all13 final PNGs actually reviewed. Editor13 scans0violations/377 incompletes and separate Career22 scans0/99 retained with M09/M11/manual gates. Expanded raw/dirty-locale/pending/failure/readback proof passes; meaningful RED and coverage-limited historical captures remain. Implemented editor CONDITIONAL GO; final staged hygiene and normal push PENDING. Import/history and whole P7-03 unfinished; full626/91/browser227/backend1,034 derived only;57/32 unchanged/main NO-GO | Hashes and remote receipts are appended by a successor to avoid self-referential commit hashes. Each row records actual commands/results, source scope, remaining conditions, normal push and immediate direct remote identity; partial or blocked evidence is recorded without inventing success. Subsequent receipt metadata is a separately reviewable documentation unit, with its own hash reported after push rather than an endless receipt chain. diff --git a/docs/redesign/phase-7/DEBT.md b/docs/redesign/phase-7/DEBT.md index 9241849..d186b26 100644 --- a/docs/redesign/phase-7/DEBT.md +++ b/docs/redesign/phase-7/DEBT.md @@ -101,10 +101,14 @@ Two independent read reviews identify the existing normalizer dropping job/educa ### P7-03 forward-ID repair disposition -[Source-ID results](p7-03/evidence/source-id-results.json) reproduce ID/override loss and null→0 metadata before a bounded frontend normalizer correction; final unit46/3, native2/preservation2, types/lint/build and11 exact readback flags pass. The +8/+1-suite addition gives only derived618/90; browser216/backend1,034 likewise are not new full runs. Prior API DLL/91 targeted guard evidence is inherited unchanged. No automatic unsafe matching/remap of older orphaned overrides occurs; historical records stay. [Final source-ID hygiene](p7-03/evidence/source-id-static-checks.json) PASS at earlier observation; final staged EOF whitespace failed, local3047b6c4 remains unpushed pending the transparent test-whitespace/docs successor and normal push; [fresh corrected staged gate](p7-03/evidence/source-id-hygiene-correction-static-checks.json) PASS (four commands0,10docs374links0errors). No runtime/assertion change or evidence loss. +[Source-ID results](p7-03/evidence/source-id-results.json) reproduce ID/override loss and null→0 metadata before a bounded frontend normalizer correction; final unit46/3, native2/preservation2, types/lint/build and11 exact readback flags pass. The +8/+1-suite addition gives only derived618/90; browser216/backend1,034 likewise are not new full runs. Prior API DLL/91 targeted guard evidence is inherited unchanged. No automatic unsafe matching/remap of older orphaned overrides occurs; historical records stay. [Final source-ID hygiene](p7-03/evidence/source-id-static-checks.json) PASS at earlier observation; final staged EOF whitespace failed, local3047b6c4 remains unpushed at that failure gate; the transparent test-whitespace/docs successor704637a and normal repair3047+7046 push are now directly verified06:34:48UTC, main unchanged/clean at observation; [fresh corrected staged gate](p7-03/evidence/source-id-hygiene-correction-static-checks.json) PASS (four commands0,10docs374links0errors). No runtime/assertion change or evidence loss. RD21 now has actual stale200/last-writer/append-restore/raw-current/owner-denial characterization, retaining its concurrency risk before any save/history semantics change. Dirty-locale and held-PUT/pending-write ownership/recovery still require proof for the presentation slice. Two final PNG reviews remain qualified: original editor sticky-scroll capture and blended frozen-dialog/workspace image, with transition cause unconfirmed. No new axe attachments or human/device/theme/settled-dialog acceptance; RD06/RD07/RD14/P7-06/P7-11 requirements remain. Source-ID forward repair does not close full C01/C07 or import/history/production obligations. +### P7-03 structured-editor conditional disposition + +[Final editor evidence](p7-03/evidence/editor-results.json) adds bounded dirty-locale/no-refetch, held structured/raw editing locks, localized generic fallback and durable server-detail retry proof: affected54/4, ordinary editor11 plus applicable source-ID2/Career14/preservation2, fresh types/lint/build PASS; all13 final PNGs actually reviewed. Root-overflow is0 for the finite samples. Editor13 scans retain0violations/377 incompletes (362overlap,13short badge,1obscured actual400 context,1hidden import-select portal); separate Career22 scans retain0/99 including3hidden evidence-select portals. M09/M11 and capture-context focus, humanAT/touch/zoom/provider/output requirements remain open. Expanded raw-helper RED and earlier collapsed-panel coverage gap are preserved; original first-build export loss remains explicit. Implemented editor CONDITIONAL GO with final staged hygiene/push PENDING. No RD21 concurrency repair, automatic orphan remap, full regression, import/history closure or production GO is inferred; all57/32 statuses and C11/Phase8 gates remain. + The early Phase6 runner retained exact failure commands/reports/logs but reused result folders, so not all old screenshots/traces/error-context paths remain resolvable. Later runs archive the whole previous output; current successful attachments have exact provenance. Preserve that limit rather than claiming complete old failure-trace retention. Native Windows Chromium/local SQLite/synthetic fixtures and finite PDF oracles do not establish deployed Linux, human semantics, physical devices, real provider quality or production load. API transferSize0 is unavailable cross-origin timing information, not zero network bytes. CDP document/node/heap snapshots can retain earlier navigation/CV iframe documents and do not prove leak/growth. The existing measured Board/Dashboard candidates require baseline/comparative evidence before a repair or capacity claim. diff --git a/docs/redesign/phase-7/PRESERVATION.md b/docs/redesign/phase-7/PRESERVATION.md index 204391a..24cb60c 100644 --- a/docs/redesign/phase-7/PRESERVATION.md +++ b/docs/redesign/phase-7/PRESERVATION.md @@ -115,7 +115,11 @@ Stable job/education/certification/project IDs dropped by the existing normalize ### P7-03 forward-ID prerequisite reconciliation -[Finite repair evidence](p7-03/evidence/source-id-results.json) adds ordinary unit46/3 (+8 cases/+1 suite) and native2 plus fresh P2-D01/mobile-override2 with types/lint/build passing. C01/C02/C07/E09 optional source IDs/nullable metadata, canonical payload/readback and selected/sibling/history/frozen boundaries are preserved; all11 final flags areTRUE. The second case characterizes stale200/append-restore/raw-current/foreign-owner denial; it does not close RD21 concurrency. No schema/backend contract or PDF/model action changes. Both lanes have0 axe attachments, and two inspected PNGs remain finite capture qualifications, not settled-dialog/design conformance. [Final source-ID hygiene](p7-03/evidence/source-id-static-checks.json) PASS at earlier observation; later staged EOF whitespace failure requires a transparent normal hygiene successor/fresh staged recheck before push. [Corrected staged gate](p7-03/evidence/source-id-hygiene-correction-static-checks.json) now PASS (four commands0,10docs374links0errors), normal hygiene successor/push pending. As-run hashes remain immutable; all57 statuses/32 routes unchanged. Older orphaned overrides require separate justified recovery, and P7-03 structured/import presentation remains pending. +[Finite repair evidence](p7-03/evidence/source-id-results.json) adds ordinary unit46/3 (+8 cases/+1 suite) and native2 plus fresh P2-D01/mobile-override2 with types/lint/build passing. C01/C02/C07/E09 optional source IDs/nullable metadata, canonical payload/readback and selected/sibling/history/frozen boundaries are preserved; all11 final flags areTRUE. The second case characterizes stale200/append-restore/raw-current/foreign-owner denial; it does not close RD21 concurrency. No schema/backend contract or PDF/model action changes. Both lanes have0 axe attachments, and two inspected PNGs remain finite capture qualifications, not settled-dialog/design conformance. [Final source-ID hygiene](p7-03/evidence/source-id-static-checks.json) PASS at earlier observation; later staged EOF whitespace failure requires a transparent normal hygiene successor/fresh staged recheck before push. [Corrected staged gate](p7-03/evidence/source-id-hygiene-correction-static-checks.json) now PASS (four commands0,10docs374links0errors), normal repair3047+hygiene704637a push directly verified06:34:48UTC, main unchanged/clean at observation. As-run hashes remain immutable; all57 statuses/32 routes unchanged. Older orphaned overrides require separate justified recovery, and P7-03 structured/import presentation remains pending. + +### P7-03 structured-editor reconciliation + +[Final editor evidence](p7-03/evidence/editor-results.json) records affected54/4 and native editor11/source-ID2/Career14/preservation2 PASS, with fresh types/lint/build and13 actual final image reviews. C01/C02/E08/E09 retain canonical fields, contextual actions, structured/raw dirty-locale drafts, held-save locks/snapshot ownership, recoverable500/actual400 feedback, keyboard/labels and finite320–1920 reflow. C07/W07 retain matching source IDs, sibling overrides and ordinary frozen P2-D01/mobile-override readback. No schema, authorization, data-saving, document-renderer or model qualification change occurs. Editor13 all-enabled scans0/377 and separate Career22 scans0/99 retain every incomplete category and M09/M11 contextual/reader qualification; source-ID/preservation have0axe scans. Implemented editor CONDITIONAL GO, final staged hygiene/normal push PENDING; import/history and whole P7-03 unfinished. All57 rows remain56 PARTIAL/C11 DEFERRED and32 routes retained; no wholesale PASS follows. [INVENTORY.md](p7-00/INVENTORY.md#current-route-coverage) reconciles exactly32 current App patterns against [route acceptance](../phase-5/p5-15/ROUTE_ACCEPTANCE.md); all whole-route groups remain PARTIAL. Preserve Board/Application/mail aliases and actual query/hash/state behavior, section/sub precedence, safe internal from, numeric navigation-helper output, capture consumption, focusJobId and provider/token destinations. No Documents/Notifications/aggregate Admin/new Career destination is inferred without contract/content evidence. diff --git a/docs/redesign/phase-7/README.md b/docs/redesign/phase-7/README.md index 06ee23d..aea77ad 100644 --- a/docs/redesign/phase-7/README.md +++ b/docs/redesign/phase-7/README.md @@ -11,7 +11,7 @@ The entry commit is `b5319981ad3d1bd635daff861453d23c0de5320b` on `codex/ui-rede | [P7-00](p7-00/README.md) | Fresh scope inventory and fixture baseline | Complete finite identity/route/matrix/static checks; inherited runtime separated. Push receipt recorded by the successor before page changes | | [P7-01](p7-01/README.md) | Authentication and account-security presentation | Public sub-slice CONDITIONAL GO, pushed8ad720d with direct receipt; account implementation/runtime/actual8-image review CONDITIONAL GO (573/89 +6/22/10); pushedad7b419 with final static PASS/direct receipt19:16:15UTC; main unchanged | | [P7-02](p7-02/README.md) | Onboarding and Career overview/evidence | Entryad7b419 pushed/verified; bounded onboarding CONDITIONAL GO32/13/4+types/lint/build/13 actual PNG inspections, hygiene PASS and d21501aa push verified23:55:12UTC. Separate SQLite evidence-list repair91 guards/HTTP1/Release passed, pushed01281f52/direct receipt00:06:47UTC with unfinished Career work preserved. Career affected46/3/native14/preservation2/types/lint/build and actual22-image review pass; implemented checkpoint CONDITIONAL GO with99 incompletes/manual gates. Career final hygiene PASS (four commands0,9docs347links0errors); normally pushed8b4d5c2/direct localHEAD=origin=live receipt05:51:04UTC, clean worktree/main unchanged | -| [P7-03](p7-03/README.md) | Career structured editing and import review | P7-02 pushed8b4d5c2; separate forward ID/null-metadata repair unit46/native2/preservation2/types/lint/build and finite readback/image review pass; local repair3047b6c4 unpushed after final staged EOF whitespace failure, corrected full staged hygiene PASS06:32:12UTC (four commands0,10docs374links0errors), normal hygiene successor/push pending. Stale contract characterized without concurrency repair; dirty-locale/pending-write proof precedes structured/import presentation; planned | +| [P7-03](p7-03/README.md) | Career structured editing and import review | Forward-ID/null-metadata repair3047 and hygiene704637a normally pushed/directly verified06:34:48UTC; original staged EOF failure retained. Structured-editor implemented scope CONDITIONAL GO: affected54/4, native editor11/source-ID2/Career14/preservation2, types/lint/build PASS; all13 final PNGs inspected,13 scans0violations/377 incompletes retained. Final staged hygiene/normal push PENDING; import/history presentation remains PENDING. Stale contract characterized without concurrency repair; manual/provider/production gates remain | | P7-04 | CV library and public entry | Existing gallery/editor and P7-03 source language; planned | | P7-05 | Discovery, Companies, Offers and Reminders | Existing domain owners and Jobs return context; planned | | P7-06 | Remaining Application forms and global correspondence | Existing seven-section workspace, immutable packages and draft/send owners; planned | diff --git a/docs/redesign/phase-7/p7-03/README.md b/docs/redesign/phase-7/p7-03/README.md index aa69355..ff82d27 100644 --- a/docs/redesign/phase-7/p7-03/README.md +++ b/docs/redesign/phase-7/p7-03/README.md @@ -1,6 +1,6 @@ # P7-03 — Career structured editing and import review -**Status: accepted entry with mandatory dependencies; implementation/verification results PENDING.** Follow the [approved handoff](../../phase-6/p6-05/PHASE7_HANDOFF.md#migration-order-and-commit-boundaries): a structured-editor presentation commit, then a separate import/history presentation commit. The newly identified source-ID prerequisite is a separate bounded repair before those presentation changes; it does not introduce another checkpoint or schema. +**Status: structured editor CONDITIONAL GO; final staged hygiene PASS, normal push PENDING. Import/history presentation remains PENDING.** Follow the [approved handoff](../../phase-6/p6-05/PHASE7_HANDOFF.md#migration-order-and-commit-boundaries): a structured-editor presentation commit, then a separate import/history presentation commit. The source-ID prerequisite was a separate bounded repair before those presentation changes; it does not introduce another checkpoint or schema. ## Accepted entry and evidence limits @@ -18,7 +18,7 @@ First reproduce the loss in ordinary normalizer/payload and actual local canonic The initial bounded unit RED at2026-10-12 05:54:52UTC passes25/fails5 of30 ordinary cases: six new normalizer cases plus existing24 Profile cases with the canonical payload assertion strengthened. Actual native baseline06:06:22–06:06:36UTC passes1/fails1 on unchangedqG82; a selected-DTO association timestamp fixture flaw was then corrected. Authoritative native RED06:08:57–06:09:10UTC again passes1/fails1: requested/persisted IDs fail, override title/bullet change from matching to nonmatching, and three null metadata fields become0. Selected/sibling DTOs, both histories and frozen content remain unchanged in the corrected proof. Separate first/corrected command/report/log/trace/embedded-attachment capsules are preserved under `.artifacts/phase7/p7-03/source-id-repair/baseline/` with0skip/retry/flaky; no PDF or concurrency repair follows. -Two metadata cases extend the bounded new normalizer suite to8; revised unit RED06:08:59UTC passes26/fails6 of32 cases, including valid0/finite/numeric-string preservation. The approved frontend compatibility repair includes eight optional-ID additions and four nullish metadata guards in profileCv.ts, retaining existing field/payload contracts and valid numeric behavior. Baseline profileCv/CareerProfilePage raw snapshots match git show8b4d5c2 canonical LF bytes. Fresh **unit46/3 GREEN passed06:10:43UTC** (normalizer8+existingProfile24+workspace14); final native2/preservation2 and app/browser types/lint/build pass; later final staged whitespace failed; corrected full staged recheck PASS; normal hygiene successor/push remains **PENDING**. Null confidence is unit-proven; native RED captures the other three null fields. Planned618/90 adds eight cases/one suite to prior derived610/89, superseding the earlier six-case616 expectation; neither is a fresh full run. Forward ID preservation cannot safely remap older orphaned overrides automatically: historical records remain, with recovery requiring a separate justified decision. +Two metadata cases extend the bounded new normalizer suite to8; revised unit RED06:08:59UTC passes26/fails6 of32 cases, including valid0/finite/numeric-string preservation. The approved frontend compatibility repair includes eight optional-ID additions and four nullish metadata guards in profileCv.ts, retaining existing field/payload contracts and valid numeric behavior. Baseline profileCv/CareerProfilePage raw snapshots match git show8b4d5c2 canonical LF bytes. Fresh **unit46/3 GREEN passed06:10:43UTC** (normalizer8+existingProfile24+workspace14); final native2/preservation2 and app/browser types/lint/build pass; later final staged whitespace failed; corrected full staged recheck PASS; normal chronological repair3047b6c4/hygiene704637a push directly verified06:34:48UTC. Null confidence is unit-proven; native RED captures the other three null fields. Planned618/90 adds eight cases/one suite to prior derived610/89, superseding the earlier six-case616 expectation; neither is a fresh full run. Forward ID preservation cannot safely remap older orphaned overrides automatically: historical records remain, with recovery requiring a separate justified decision. ### Prerequisite runtime and finite acceptance @@ -28,7 +28,7 @@ Root verified all11 readback flags TRUE: IDs match all three recorded source sna Root actually opened two final PNGs plus the corrected-RED failure viewport image. The final390x4683 existing-editor image reaches Save/content and captures sticky chrome at current scroll. The frozen-package image blends underlying workspace/chrome through the dialog; its possible transition cause is undiagnosed and settled-dialog visual acceptance remains P7-06/P7-11 qualification. These finite inspections are not a cosmetic migration or new responsive/theme/human acceptance. Both native lanes contain **0 axe attachments**; the earlier P7-02 incomplete inventory/manual gates remain, and no new axe clearance is inferred. -**Bounded runtime compatibility repair GO; corrected full staged hygiene PASS, normal hygiene successor/push PENDING.** Structured-editor and import/history presentation, old orphaned-override recovery and all manual/production gates remain pending. Fullfrontend618/90 and ordinarybrowser216 are derived only after this +8/+1-suite addition; no fresh full-suite result replaces inherited573/89. +**Bounded forward compatibility repair GO; corrected full staged hygiene PASS, normal repair/hygiene push verified.** Structured-editor and import/history presentation, old orphaned-override recovery and all manual/production gates remain pending. Fullfrontend618/90 and ordinarybrowser216 are derived only after this +8/+1-suite addition; no fresh full-suite result replaces inherited573/89. Slice-specific [source-ID static checks](evidence/source-id-static-checks.json) passed2026-10-12 06:21:50–06:21:53UTC: four secret/working/staged/entry-whitespace commands exit0;10 Markdown documents/370 local links checked with0errors at observation;57 qualified groups/32 routes retained, main unchanged. Canonical UTF-8/LF SHA256 is `3a910cd0041f2cf855484c161b21bc4f4b1de7446af80600315b4fcf18e76863`; exact static snapshot/log bytes are retained in the final capsule. Root independently verified81 refs/62 unique files and75-file frozen export before later review/receipt metadata. Normal push receipt remains pending; no new runtime or manual claim follows. @@ -38,10 +38,52 @@ Root created local **unpushed** repair `3047b6c4a87c43de6f397e4a3d109be9ce3ddeca As-run test bytes/hashes remain frozen at3047b6c4; the original normalizer-test canonical hash now points to its immutable snapshot. Corrected test raw/LF metadata and exact historical failure command/log are recorded separately in the manifest. A normal successor commit will contain only this test whitespace and transparent evidence/docs correction after a **fresh full staged gate**. Both commits remain chronological, with no rewrite/force push. Prior06:21 static PASS is historical, not the corrected final gate; fresh corrected full staged gate now passes; normal hygiene successor commit and normal push remain pending. -Fresh [hygiene-correction static checks](evidence/source-id-hygiene-correction-static-checks.json) passed2026-10-12 06:32:09–06:32:12UTC with all four commands0,10docs/374 local links0errors at observation,57 groups/32 routes retained and main unchanged. Canonical UTF-8/LF SHA256 is `24c3147e21e266e2b2d9e22cc1f0f716da791b730d280328d3ceae02fb5e67e1`; exact static/log bytes are frozen separately. Original failure,3047 source applicability and all as-run snapshots remain unchanged. The normal hygiene successor and subsequent two-commit push are pending. +Fresh [hygiene-correction static checks](evidence/source-id-hygiene-correction-static-checks.json) passed2026-10-12 06:32:09–06:32:12UTC with all four commands0,10docs/374 local links0errors at observation,57 groups/32 routes retained and main unchanged. Canonical UTF-8/LF SHA256 is `24c3147e21e266e2b2d9e22cc1f0f716da791b730d280328d3ceae02fb5e67e1`; exact static/log bytes are frozen separately. Original failure,3047 source applicability and all as-run snapshots remain unchanged. They were pending at this staged-gate observation; the actual normal two-commit push is recorded in the structured-editor entry below. Before changing save/history ownership, resolve or explicitly bound RD21 canonical profile/job stale-save and creation-intent behavior with actual stale-write/recovery tests. Prove dirty drafts survive UI-locale changes and relevant read-retry/navigation boundaries; prove held-PUT/pending-write snapshots, edit/save completion ownership and recoverable failure. Existing verified CV revision handling is a different contract. Presentation migration must retain current data-saving semantics and existing guards; do not infer a missing server token or invent one. +## Structured-editor entry after prerequisite push + +Actual normal push2026-10-12 06:34:48.620963UTC includes repair `3047b6c4a87c43de6f397e4a3d109be9ce3ddeca` and hygiene successor `704637ab375c32d14aa46f9d4ef0f210136de4d9`: localHEAD=origin=live development704637a, local/origin/live main27657f3 unchanged and clean worktree at observation. The successor appends this receipt; both commits and the unhandled original whitespace failure remain chronological. All three measured test canonical references now use their immutable as-run snapshots after legitimate editor-test changes; source3047 and corrected hygiene test metadata remain distinct, with no hash/runtime reinterpretation. + +CareerProfilePage/CareerProfileSections raw baselines are frozen under `.artifacts/phase7/p7-03/editor/baseline/source/`, canonical LF equal git show704637a. Baseline translations are the **committed Git blob**, SHA256 `fea1eb8ba58a5b4ff86c33fa651ec542fe6df46dcbade226790737dc5994d30c`, rather than the already edited worktree catalog. Root prepared five new bilingual keys and five existing-copy entries for meaningful unit RED expectations. Native baseline uses unchanged prebuiltbzQi/704637a old labels and H3/UI contract; no presentation PASS follows from the new test catalog. Existing75-file export is referenced without duplication. Initial editor RED is recorded below; implementation and final acceptance remain **PENDING**. Latest full573/89 remains inherited and618/90/browser216/backend1,034 are derived only. + +### Structured-editor failing baseline + +Actual first native execution2026-10-12 06:38:45–06:40:15UTC fails all11 ordinary cases, with0passes/skips/flaky/retries. The affected unit pack06:40:10–06:40:44UTC passes38/fails8 of46 cases across3 suites: new editor1/7, existing Profile23/1 and workspace14/0;0pending/todo or console errors. The deliberate old-copy expectation failure remains visible. Raw commands/reports/logs, the entire native results/trace folder,28 decoded attachments including12 PNGs, and seven as-run source/test/catalog owners are frozen under `.artifacts/phase7/p7-03/editor/baseline/native-first/`. Product page/sections snapshots still equal the accepted704637a baseline. Native raw report SHA256 is `66aa335e861d61d7255ae93875a850e63788aafb93d1066f96d62febdc4ce55a`; `baseline-results.json` preserves full rule/node/check vectors and exact provenance. + +The reproduction shows a locale change repeating GET and overwriting phone/raw drafts, held PUT leaving35 fields/26 actions and raw editing enabled while Bold changes the draft, and an actual controlled400 showing no form error. Root actually inspected only the320px NB/dark baseline image: its350px-wide full-page capture shows30px overflow while the form fields remain inside. Other PNGs are retained without claiming individual inspection. Twelve all-enabled scans record0violation nodes/**408 incomplete contrast occurrences**:396 overlapping-background checks and12 short-text badges. Per-state counts are6 for the locale view,37 for six narrow/pending/error views and36 for five desktop/tablet views; M09/M11 contextual/human qualification remains. These failing results establish the bounded repair scope; they provide no editor GO, settled visual conformance or import/history acceptance. + +A separate overlapping narrow diagnostic executed2026-10-12 10:37:40–10:37:51UTC fails the same320px NB/dark ordinary case, with0skip/flaky/retry. Its raw report/log/command/results/trace, diagnostic audit and PNG are frozen under `.artifacts/phase7/p7-03/editor/baseline/native-narrow/`; raw report SHA256 `d4e2a23c3ad880c50a7a23cc3e5cb9da02f740caac347cc52893074a313a77a8`. The actual DOM records30px root overflow and20 overflowing elements, including outer navigation/editor boxes ending at349.6875px, while all35 form fields end at or before314.6875px. This establishes geometry, with source cause/repair requiring separate review. Its single scan retains0violations/37 incomplete contrast occurrences; it overlaps the first baseline and adds no test or independent full-scope acceptance count. No individual inspection of its new PNG is claimed. + +### Structured-editor unit-green candidate + +Fresh affected unit execution2026-10-12 10:46:11–10:46:43UTC passes54/4 with0failed/pending/todo: editor8+existing Profile24+workspace14+normalizer8. App TypeScript exits0 at10:46:21–10:46:32UTC. Three product owners, four unit owners and the native spec, plus exact command/report/log bytes, are snapshotted under `.artifacts/phase7/p7-03/editor/candidate-20261012T104643Z/`. This is a **candidate**, awaiting final browser TypeScript/lint/build, ordinary native editor11/sourceID2/Career14/preservation2, actual visual/axe contextual review and staged hygiene/push. The eight added editor cases/one suite yield frontend626/91 as a derived expectation only; existing Profile/workspace expectation updates add no cases. Import/history presentation and manual/production gates remain pending. + +### Native candidate history; acceptance withheld + +The first post-implementation ordinary editor run10:47:48–10:48:38UTC passes8/fails3 of11 with0skip/flaky/retry. Actual durable-error alerts omitted the general failure heading beside server detail, and a320px ProFeatureNotice message was scrollable without keyboard focus. Its12 scans retain8 violations (7 inactive helper-text contrast and1 scrollable-region focusability) plus374 incomplete contrast occurrences. Root then corrected the local notice wrapping and error heading. The earlier browser TypeScript duplicate diagnostic property TS1117 failure is retained; removing only the duplicate property left the stronger diagnostic and fresh browser typecheck passed. Raw commands/reports/logs/results/traces, decoded evidence and parent-confirmed original candidate sources remain under `.artifacts/phase7/p7-03/editor/attempt1-20261012T104838Z/`. **Original DwxCC BUILD_ID/export bytes were overwritten by the corrected build before the freeze could copy them**; exact build command/log and directly observed identity remain, with no retroactively reconstructed export claim. + +The corrected `jjBcTV3XoPOhWzOYiJ0FR` candidate passes affected54/4 and app/browser types/lint/build, then ordinary editor11/sourceID2/Career14/preservation2 at10:52:33–10:54:46UTC:29 finite overlapping cases,0skip/flaky/retry. Its75-file export, source/tests/API/config, reports and decoded evidence are frozen under `.artifacts/phase7/p7-03/editor/attempt2-20261012T105446Z/` as a **historical attempt with acceptance withheld**; the [current editor evidence](evidence/editor-results.json) records the final superseder below. Editor12 all-enabled scans retain7 actual held-save helper-text contrast violations: six4.48:1 on white and one4.14:1 on the secondary surface, all `.Mui-disabled` “One item per line.” descriptions. They are retained rather than silently excluded. Incompletes374 comprise361 background overlaps,12 short-text badges and1 partially obscured error alert. The separate22 Career regression scans retain0violations/99 incompletes; source-ID/preservation lanes contain0axe scans. All12 editor root-overflow measurements are0, but native PASS alone supplies no axe or manual GO. Parent viewed three images (NB320, EN360 and EN1920); nine others have no individual review claim at that observation. Further corrections and final acceptance follow below. Whole P7-03 import/history remains incomplete. + +### Final structured-editor result + +[Final editor evidence](evidence/editor-results.json) records three changed product owners and five measured test owners, preserved under `.artifacts/phase7/p7-03/editor/final-expanded/`. The editor now uses shared sections and semantic headings, contextual remove actions, localized instructions and save/error feedback, and narrow layouts. UI-locale changes retain structured/raw dirty drafts without repeating their source GET. Held saves lock the submitted editing surface, including rich-text and expanded raw controls; durable failures retain draft and server detail with a localized heading/retry. Generic fallback errors follow the current UI locale. The local ProFeatureNotice wraps, and disabled helpers use the existing text-secondary token in both structured and raw sections. Canonical saving, source IDs, sibling overrides, histories and frozen documents keep their established owners and semantics. + +Fresh affected **54/4 PASS** at2026-10-12 11:13:30–11:14:03UTC comprises eight new editor cases plus existing Profile24/workspace14/normalizer8, with0failed/pending/todo. App/browser TypeScript, lint and production build exit0; the latest browser TypeScript at11:16:54–11:16:58 covers the final native oracle. Build `W4fUO7_GUC0Qh5FuL3qVL` has75 frozen exported files/digest `6e60c305555153d3379be3dac24c0845cf7665855bb7bcba95b26b9131cfd33c`; three-product LF digest `75fa95c655d9e3361af9209a82ce9e64f9a6091a4806752bdb32fa76a7be5b1a`. API identity is unchanged; no new backend build/test is claimed. + +Final ordinary editor **11/11 PASS** at11:16:54–11:17:44UTC includes13 captured states. Its strengthened oracle requires the raw disclosure expanded, textarea visible/in viewport, nonempty field inventories in both areas, expected raw label and0axe violations in every captured state. Source-ID2/Career14/ordinary P2-D01 and mobile-override2 also pass on the same unchanged export at11:14:58–11:16:22UTC. These29 finite overlapping cases have0skipped/unexpected/flaky/retries; the final editor rerun supersedes its earlier test-only capture/geometry oracle, while the other18 unchanged-source results remain applicable. Full frontend **573/89 remains inherited**; **626/91**, browser227 and backend1,034 are derived expectations only. Added editor8/+1 suite and native11 are the only new count increments here. + +Root actually inspected **all13 final PNGs**: locale/held structured/held expanded raw/failed save/actual400 plus eight finite width-language-theme samples spanning320–1920px and1280x320 landscape. Recorded geometry has0accidental root overflow. Expanded raw held390 visibly contains the disabled textarea/readable helper; locale1440 retains the dirty raw draft. Deep-scroll/full-page sticky chrome, visible skip-link and toast overlays retain capture/focus qualifications. Controlled500 and actual400 English server details are retained provenance, alongside localized product headings/fallbacks. No physical input, browser zoom, human assistive technology, density matrix, provider or production qualification is inferred. + +Editor **13 all-enabled axe scans** retain **0violation nodes/377 incomplete occurrences**:362 contrast background overlaps,13 invisible-badge short-text checks, one partially obscured actual400 toast/alert context and one aria-hidden-focus context at the hidden MUI select portal `#menu-` (`li[data-value=import]`, tabindex0). The separate Career22 scans retain0/99 (74contrast overlaps,22badges,3hidden evidence-select portal contexts); source-ID/preservation lanes have0axe attachments. Every category/context remains retained, with full vectors in hashed raw/extracted reports. M09/M11 reader/portal-focus and contextual contrast/forced-colors requirements remain open; these contexts are neither hidden nor treated as established new defects. + +History retains meaningful generic-locale unit6PASS/2FAIL and native10PASS/1FAIL helper contrast RED, as well as raw-expanded0/1 RED (one4.48:1 helper contrast failure) before the final scoped correction. Earlier13-capture PASS with a collapsed raw panel remains coverage-limited. Old0UBD12-state source/export/results are retained consistently under `attempt3-20261012T110336Z`, with original metadata bytes and explicit reference-prefix relocation; the final W4 capsule uses `final-expanded`, so old source/export hashes are never relabelled current. The original DwxCC export retention gap above remains. Invalid runner aliases asserted before launch; an initially wrong unit selector produced46/3 and was corrected to54/4. These tooling/selection corrections add no skipped cases or passing scope. Root and this agent independently verified **290 references/197 unique files,75 exported files and eight current source/test files**; the checker's Windows-path ordering correction changed no measured bytes. + +**Structured-editor implemented scope CONDITIONAL GO; final staged hygiene PASS, normal commit/push PENDING.** Import review/history presentation remains the separate approved next slice; whole P7-03 is unfinished. RD21 stale-save/idempotency, old orphaned override recovery, M01–M12/manual/provider/output requirements, deferred M13/P5-13 and production NO-GO remain. All57 PRES statuses remain56 PARTIAL/C11 DEFERRED and32 routes retained. No Phase8 implementation or main push follows. + +[Final staged editor static checks](evidence/editor-static-checks.json) passed2026-10-12 11:30:01–11:30:04UTC: all four secret/working/staged/entry-whitespace commands exit0;10 Markdown documents/384 local links checked with0errors,57 qualified groups/32 routes retained and main unchanged. Canonical UTF-8/LF SHA256 is `18cb0a46e035d6af96b1489509aab0f5979db2a81b635df164bb9759a33b23c5`. Exact JSON and four raw logs are frozen separately in `final-expanded/static/20261012T113001Z`; no new runtime or human acceptance follows. Normal commit/push is pending its actual receipt. + ## Approved presentation boundaries | Boundary | Existing owners and bounded change | Required finite acceptance | @@ -57,4 +99,4 @@ Existing [profile tests](../../../../job-tracker-ui/src/profile-page.test.tsx), C01–C04/E08/E09 and relevant C07/W07 frozen/override boundaries remain qualified in the [matrix](../PRESERVATION.md). Record raw commands/results/attempts, measured source/build/export identity and every axe violation/incomplete category/context; retain full vectors in hashed immutable reports. Native emulation and finite images do not supply human screen-reader, zoom/reflow, physical touch/software-keyboard, real provider, production-font/photo or deployed-output acceptance. Density is tested only where an actual control applies. -The source-ID prerequisite has bounded runtime/readback GO; local repair3047b6c4 is unpushed; corrected full staged recheck PASS, normal hygiene successor/push pending. Structured-editor and import/history presentation remain **PENDING**. [Debt](../DEBT.md) retains RD21 separately, M01–M12 manual requirements, deferred M13/P5-13, optional P5-05/`followMode`, production NO-GO and Phase8 separation. Conditional development entry authorizes independent bounded work; it does not declare these gates complete. +The source-ID prerequisite has bounded runtime/readback GO; repair3047b6c4 plus hygiene704637a are normally pushed/directly verified; original whitespace failure and exact snapshot relation remain recorded. Structured-editor implemented scope is CONDITIONAL GO with final staged hygiene PASS/normal push pending; import/history presentation remains **PENDING**. [Debt](../DEBT.md) retains RD21 separately, M01–M12 manual requirements, deferred M13/P5-13, optional P5-05/`followMode`, production NO-GO and Phase8 separation. Conditional development entry authorizes independent bounded work; it does not declare these gates complete. diff --git a/docs/redesign/phase-7/p7-03/evidence/editor-results.json b/docs/redesign/phase-7/p7-03/evidence/editor-results.json new file mode 100644 index 0000000..b625b78 --- /dev/null +++ b/docs/redesign/phase-7/p7-03/evidence/editor-results.json @@ -0,0 +1,7123 @@ +{ + "schemaVersion": 1, + "checkpoint": "P7-03", + "slice": "Structured Career editor presentation", + "collectedUtc": "2026-10-12T11:20:04.275634+00:00", + "acceptance": "CONDITIONAL_GO_EDITOR_ONLY;FINAL_STAGED_HYGIENE_PASS;NORMAL_PUSH_PENDING", + "entryCommit": "704637ab375c32d14aa46f9d4ef0f210136de4d9", + "identity": { + "sourceFiles": [ + { + "originalSourcePath": "job-tracker-ui/src/views/CareerProfilePage.tsx", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/source/job-tracker-ui/src/views/CareerProfilePage.tsx", + "sha256": "53ec4dd218bc868c81cf1d84a897f32e1dca358f74a2ee4fa02b3b83554bad64", + "bytes": 50287, + "hashPolicy": "Exact saved raw bytes" + }, + "canonicalLf": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/source/job-tracker-ui/src/views/CareerProfilePage.tsx", + "sha256": "e915b24ab000a6d8b5c2c8c3aaef2f81ddaa2c434a31c6edb0ff4aded1ea5b24", + "bytes": 49443, + "hashPolicy": "UTF-8 text CRLF normalized to LF" + } + }, + { + "originalSourcePath": "job-tracker-ui/src/views/career/CareerProfileSections.tsx", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/source/job-tracker-ui/src/views/career/CareerProfileSections.tsx", + "sha256": "0c772feb6bde8324676b0884aaf343283465c5cd3b3318128363063df4ea22ab", + "bytes": 20375, + "hashPolicy": "Exact saved raw bytes" + }, + "canonicalLf": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/source/job-tracker-ui/src/views/career/CareerProfileSections.tsx", + "sha256": "aa3acbe472d34074a517a566c77983e7d95f8ec1df9ee37e47537ad96beffd0e", + "bytes": 20131, + "hashPolicy": "UTF-8 text CRLF normalized to LF" + } + }, + { + "originalSourcePath": "job-tracker-ui/src/i18n/translations.ts", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/source/job-tracker-ui/src/i18n/translations.ts", + "sha256": "12f9b533eebae9eb3d7695ce6a6bad44540ca7f91bcdafbbf169bd05b0e69e73", + "bytes": 314338, + "hashPolicy": "Exact saved raw bytes" + }, + "canonicalLf": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/source/job-tracker-ui/src/i18n/translations.ts", + "sha256": "3f737cdfb26c2ca654ab19089b1987fb973e05611a07e5597f2d0e199c28bd9f", + "bytes": 309142, + "hashPolicy": "UTF-8 text CRLF normalized to LF" + } + }, + { + "originalSourcePath": "job-tracker-ui/src/career-editor.test.tsx", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/source/job-tracker-ui/src/career-editor.test.tsx", + "sha256": "66ae5cb823a4bfcf1c18180b500b036f3eadca03417da5baf7ce1de67ddeedb9", + "bytes": 17152, + "hashPolicy": "Exact saved raw bytes" + }, + "canonicalLf": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/source/job-tracker-ui/src/career-editor.test.tsx", + "sha256": "66ae5cb823a4bfcf1c18180b500b036f3eadca03417da5baf7ce1de67ddeedb9", + "bytes": 17152, + "hashPolicy": "UTF-8 text CRLF normalized to LF" + } + }, + { + "originalSourcePath": "job-tracker-ui/src/profile-page.test.tsx", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/source/job-tracker-ui/src/profile-page.test.tsx", + "sha256": "29fe3c4a89bf19ac77efd0f8f74179dcf5e74c48d53597fa0a8520d107dc5548", + "bytes": 30571, + "hashPolicy": "Exact saved raw bytes" + }, + "canonicalLf": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/source/job-tracker-ui/src/profile-page.test.tsx", + "sha256": "ae244cac87612dac140e0e3938c56e4bccad89d8d1006e2ee34d073c18be9666", + "bytes": 30010, + "hashPolicy": "UTF-8 text CRLF normalized to LF" + } + }, + { + "originalSourcePath": "job-tracker-ui/src/career-workspace-page.test.tsx", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/source/job-tracker-ui/src/career-workspace-page.test.tsx", + "sha256": "628512985a14e71d0d34bf1e3e0e77d948ad7d5c3eb608de482051f2aedf3052", + "bytes": 14421, + "hashPolicy": "Exact saved raw bytes" + }, + "canonicalLf": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/source/job-tracker-ui/src/career-workspace-page.test.tsx", + "sha256": "d2a27946a0891742a18a28ec2ec87d6742ad413aae4aa5fdad0f2bb0a47c124b", + "bytes": 14210, + "hashPolicy": "UTF-8 text CRLF normalized to LF" + } + }, + { + "originalSourcePath": "job-tracker-ui/src/profileCv.test.ts", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/source/job-tracker-ui/src/profileCv.test.ts", + "sha256": "c1c482bed380429489f1757852811e0d1e7f48b71af2bd7899693d2e8475ac9d", + "bytes": 4316, + "hashPolicy": "Exact saved raw bytes" + }, + "canonicalLf": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/source/job-tracker-ui/src/profileCv.test.ts", + "sha256": "c1c482bed380429489f1757852811e0d1e7f48b71af2bd7899693d2e8475ac9d", + "bytes": 4316, + "hashPolicy": "UTF-8 text CRLF normalized to LF" + } + }, + { + "originalSourcePath": "job-tracker-ui/e2e/phase7-career-editor.spec.ts", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/source/job-tracker-ui/e2e/phase7-career-editor.spec.ts", + "sha256": "dfc696107e8ad9adf265a5bae885407afd09f1be3b507de8ff03739b39a7f0b1", + "bytes": 29805, + "hashPolicy": "Exact saved raw bytes" + }, + "canonicalLf": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/source/job-tracker-ui/e2e/phase7-career-editor.spec.ts", + "sha256": "dfc696107e8ad9adf265a5bae885407afd09f1be3b507de8ff03739b39a7f0b1", + "bytes": 29805, + "hashPolicy": "UTF-8 text CRLF normalized to LF" + } + } + ], + "sourceSha256Lf": "75fa95c655d9e3361af9209a82ce9e64f9a6091a4806752bdb32fa76a7be5b1a", + "sourceDigestPolicy": "Ordered original product path + TAB + canonical-LF file SHA256 + LF records", + "buildId": "W4fUO7_GUC0Qh5FuL3qVL", + "buildIdRaw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/BUILD_ID", + "sha256": "b0c4ad0d8f2cf43cef1bdc1bbb6b323c73940d22abbfde2fe9086aaac264567c", + "bytes": 21, + "hashPolicy": "Exact saved raw bytes" + }, + "exportFiles": [ + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/404.html", + "sha256": "44ec8adeb781507e25f7fc639c2e11acbdb9c245343cbb5dde08090b36f2d636", + "bytes": 12482, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/__next.__PAGE__.txt", + "sha256": "60f193f3b7704ceca61b8374155c22e51dddfe8080d7a738a49e169a751c9ced", + "bytes": 5511, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/__next._full.txt", + "sha256": "15fc7ff6b44678ac140b45e0caeeee45e7ec22d974d0a1c23448ea658688c5d8", + "bytes": 6026, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/__next._tree.txt", + "sha256": "ca8f0ddb07b6eb09f417300b8a103175a322af70ac09d74445b3308ca99bd659", + "bytes": 351, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/02mwb4hjks52g.js", + "sha256": "e131c5847ddf632dab1d077fa638a06af4728ad88163bccc93a9d9ed30e8be94", + "bytes": 53894, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/08ydkbcc5f93r.js", + "sha256": "6b660d5f902d33aad41e6f326a9869e54a489a21181753862ac6abe71f8eba40", + "bytes": 141944, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/091poeh_7k8jp.js", + "sha256": "a6aacb5594c32836ed8721a00d462c9a4003c1fcf1baae401dbaf063109df392", + "bytes": 17603, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/0cz1d0mv5g_q7.js", + "sha256": "0973c1d64c88adc8e3c950410cb58b288f72118d5965b78049438deb8f2f9683", + "bytes": 112594, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/0ebmk6vliyxfa.js", + "sha256": "f35e3a6b2056a8a0d84b121509eced7327f86585241d373b63b8c98632bdc002", + "bytes": 434049, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/0f20amr0-m-zl.js", + "sha256": "70b0fb6db2fa0749d01768823746641975bfc42a65e133a2b138e4aae0ba660b", + "bytes": 49416, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/0g8jdam99b7-z.js", + "sha256": "94264307de5eb80b0e87dfd263607fe24b5cb19d6008184ab6b107a4873b49ac", + "bytes": 54284, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/0lfuwd98rim9r.js", + "sha256": "db3216f3501d53c517031483d281466eb08c5054d83bb0d5009731e5fbaf3a1f", + "bytes": 28085, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/0m7vi4hs61md9.js", + "sha256": "b098d60b98930bfa895489a42ae534227e2e44e2c888aaa1a139fadbe700d119", + "bytes": 32405, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/0nb4syhs2ze1s.js", + "sha256": "20b2e2f1195168f16752da3fe651e6d6f0e2561b0139de4042e7faee590114a7", + "bytes": 1112, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/0swqvzc1gm8tm.js", + "sha256": "ace5778cc960bb904ab2b77085d6c6ee4b9efc9d95023d3100a8f850af6512b0", + "bytes": 257660, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/0w3y5uv0hr947.js", + "sha256": "94b0774abaaa0aaf1f6f324d72982fcec39061a97602b8d27d7550e2076ab0c0", + "bytes": 23683, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/0xj7pytmwb27r.js", + "sha256": "83ba726bbf10cc9eb7375f21db41ccb59491ef31cd0031e0bd3fde67c49ed547", + "bytes": 2312, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/1-bjgejrqfcdt.js", + "sha256": "f3eb6b9bfc32c1e454abcf45ba3217afff46c2feb8d35de6a689b8e12bb95717", + "bytes": 69675, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/100y3nigll5ap.js", + "sha256": "49c825c42cc40fbf26b5780f710234537974fd99792119db43ffc29c666141ae", + "bytes": 7081, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/1bo5vruln9ro7.js", + "sha256": "d3c3fd8cd9086e741993371e2a1c847f9262a11c5ff4ac15ca956143a8ad68e2", + "bytes": 32051, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/1cvrle64fmqrg.js", + "sha256": "56974623edad860b8a577d4a28f0b30514db3b1e2ac6f846d7312faa832b06eb", + "bytes": 2764, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/1emuuo-0m8vez.js", + "sha256": "4c21bf2a07fcdc992e3e74d65c78b33bb6c44a14298f641aa0008aa8f2187416", + "bytes": 17565, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/1jhpn3g6nuazw.js", + "sha256": "f4aefb7dd17514ff4fa66d3e1f51e3b817de5748b56f38c1032bdc3afd8b16a0", + "bytes": 45306, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/1k_5axiqq7um2.js", + "sha256": "d4cc9b89e854d02a65428f540dbda1845849d96e994a56a20c5e441db99e2f23", + "bytes": 37926, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/1ocp5iwqw5t8n.js", + "sha256": "5770e4f6c9b589511b855e40fd717ee066d543fa6e4e6cc54cc5bd252bbe47a1", + "bytes": 24802, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/1ookeyi94iiwv.js", + "sha256": "883db2ccfca25d90c8b00472e71c3c2c4c068460911ef850f7a9e9e9f19fcbe9", + "bytes": 4800, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/1owxpom4r3xpr.js", + "sha256": "372368d3aba84cb4a23eca2694bc554d50575b341a8b73e2074c4fac820beb7b", + "bytes": 3560, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/1wn9plf_g3dwv.js", + "sha256": "a56a34c253983d23225447640cd7ee4a6a4e6ed62d83577640e3d557cc0be6d5", + "bytes": 39663, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/1xwc-b795syag.css", + "sha256": "f73c002233f931ca14d0ae58815c47ca9f2659f25b1547a6d1fdca12a2a00b3f", + "bytes": 293, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/1yr2lgiku_lgn.js", + "sha256": "0869486e8c706cf09cef4ff7c21a72dcb51af1b0aff61154ae7ef653a3fb892e", + "bytes": 34520, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/24lsivow0-r0-.js", + "sha256": "b9f7534286f4ebd10f0ecd6f867e6edba5b7ccec02f3b6082e930f8b4e2ca46b", + "bytes": 31624, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/2e2n0wy891_-d.js", + "sha256": "3436d9be1827de975577e7fcc84eaf322dcd2ab163c3534fd4b485814e7e831f", + "bytes": 14467, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/2fjpwi22kr5uy.js", + "sha256": "38ba6df82e11dd976fbc93026a9cfc8e1523537b9a4324a2f1d90883dee84884", + "bytes": 207715, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/2hhjn96fczjvs.js", + "sha256": "589c85f58bad63587b2822add77b37080bc573a1f7ad90f8d3e691a22f095456", + "bytes": 41242, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/2odl1ntxuei21.js", + "sha256": "c070c582a473f58c50d3963943d7029a94f335158815e8bf26ab47675249f084", + "bytes": 4918, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/2q65uitl2oksj.js", + "sha256": "f47d839bc4ca7396d870f0b27c9b0bb070860b978ab137c576927effb9720192", + "bytes": 17234, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/2vlttipo05xfv.js", + "sha256": "a17d6235f5f3d618b8d0c03fcafe6ee624088571c8b29f1f6d8800f8f57bccf2", + "bytes": 19557, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/2vlvgi2hbk32a.js", + "sha256": "10157c67f2fdbecef54efa23ba15ea21513f773af8787b594e87133c45a45cd1", + "bytes": 177687, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/3--i00i4av4q_.js", + "sha256": "79902e86c8d920115cba0abc6e6b787eca1d8aa59b687a94ce889f270a3cf600", + "bytes": 24247, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/3-8sli__93ru0.js", + "sha256": "a76c7a411c8352b9b9b1ce07e737b496f5e4023e399c27aa04007e88754c3f0a", + "bytes": 4110, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/31nkei43jjbv6.js", + "sha256": "396e43ac57c3488d26b3dda208f3a23a4d3e0d2d527e9553fdef7932210753d2", + "bytes": 11304, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/39qtpg2zpb1d8.js", + "sha256": "b7e1066bd4d6cd5cf6c2448bf89c5a008e5c189e58b7b7b25791b9bdb100f39c", + "bytes": 37956, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/3d1sq_9gctax5.js", + "sha256": "98b9561a1ee4177229295eca3efa72ff36466f1b392f617af26a15817f402cba", + "bytes": 6155, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/3dq3l-or19e0_.js", + "sha256": "1f05bc4dd91710507a63e773b3a878f7925765e568f673aa17cb7cdc8d1e2c68", + "bytes": 4834, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/3f82vakjf_7-4.js", + "sha256": "dd882483d27fd161d7fe8bf3031eac9d21b9d04fe85bd2b600e8a345156ff80e", + "bytes": 61704, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/3gf4f1j6l-alg.js", + "sha256": "30ed0f30bd9de0f1229caa107a98ce7e5695227ac4b9e7f3272f7b10eaa866dd", + "bytes": 118155, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/3nrlrkxac2pon.js", + "sha256": "751243327443f5ccdd8b5f3df50b32ab3d2744dcdf7e40b002b7f432f34b06f6", + "bytes": 11919, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/3oic_1dun0n0c.js", + "sha256": "dc3c80dcc93f8d7bc5209cb6310dcf035cdcadc9630cdcc9663032af5788f55c", + "bytes": 417662, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/3pd_mozp76yih.js", + "sha256": "0f1d6719ed49d8ac6f2b98974dd1be831982bcea2b1955efb97b2bf178fdce18", + "bytes": 228034, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/3q6k02svdfjz4.js", + "sha256": "55a0099595493aff2d0a121d91ef55d4e7748180ad87bd0ed077d6ab84586f62", + "bytes": 245, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/3t4zlerpupcoq.js", + "sha256": "b1b1cc211c58922939677aaad111dd106a98ffd9e08a40dff208f8c4d9e7a95b", + "bytes": 25352, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/3w3_838sob_8v.js", + "sha256": "9b555acff01b2a177ab3bca6c850b39902795c12d1a1b41bbbbb3be20b1f3061", + "bytes": 55923, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/3wi4ei8dsihay.js", + "sha256": "56ff128469b14721092d27a5644f1eb532bd3d81430edccc854817ce0cfaedc5", + "bytes": 11665, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/3y9_6i44vsn5e.js", + "sha256": "8344e681e09c997ec542b3342f5beb2df4be04381cad079fa44112b60b813d93", + "bytes": 12492, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/406gm9r2rgjcf.js", + "sha256": "c165b5e9dced109c6faf32b8bdcbe2050471f67c5bc37c8349404827d4575ca1", + "bytes": 158095, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/chunks/turbopack-14p19yf3yful3.js", + "sha256": "79ab929130be94debf628997bd7a90fa07b385be7eb4a27928068daa4f597706", + "bytes": 9886, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/W4fUO7_GUC0Qh5FuL3qVL/_buildManifest.js", + "sha256": "9476e0afd3f9da68a64e6ec58631191fd3eaca62c9f5a377e7517fe9a89e59ea", + "bytes": 219, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/W4fUO7_GUC0Qh5FuL3qVL/_clientMiddlewareManifest.js", + "sha256": "5483e3295dc35dfe29ea932efc85341c916f10ff78ff5b0e965e003710893a4a", + "bytes": 96, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_next/static/W4fUO7_GUC0Qh5FuL3qVL/_ssgManifest.js", + "sha256": "678f6ce2cb80b1fe72fc67e7412be6e2ab6ada083111b64f7c40d35e3cba5e00", + "bytes": 80, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_not-found/__next._full.txt", + "sha256": "636a6fcc980abc185c62ec190777779c67387bb601544bf6c5ffeba06deaedc4", + "bytes": 7488, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_not-found/__next._not-found/__PAGE__.txt", + "sha256": "9ce79e3a0d575f58a56b2e672707073a1086b3b37e557397f4513111a1e354c8", + "bytes": 6454, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_not-found/__next._tree.txt", + "sha256": "ff339a04e749c3ec040bcef585259abe17bb688490f81483422d5e387a3aab8d", + "bytes": 429, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_not-found.html", + "sha256": "44ec8adeb781507e25f7fc639c2e11acbdb9c245343cbb5dde08090b36f2d636", + "bytes": 12482, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/_not-found.txt", + "sha256": "636a6fcc980abc185c62ec190777779c67387bb601544bf6c5ffeba06deaedc4", + "bytes": 7488, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/favicon.ico", + "sha256": "8d4923e2c487805ea9f852a685b2cf0fb10512ded8290d2a5c37d1cc8fd0702a", + "bytes": 147708, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/favicon.svg", + "sha256": "f46bb75bd17edaa86713a92b40774be5055bc2bd5f49223b3891fbe9a5d068cb", + "bytes": 1002, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/index.html", + "sha256": "8b84d6e27d43917d2b8b3ad7c42483080db0ddcfe76506b6e3cfd8a4648199d6", + "bytes": 10130, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/index.txt", + "sha256": "15fc7ff6b44678ac140b45e0caeeee45e7ec22d974d0a1c23448ea658688c5d8", + "bytes": 6026, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/logo192.png", + "sha256": "bc652031597fabd19b9f14e22a71f809490d218037521b3b64d013418c1390b4", + "bytes": 32284, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/logo512.png", + "sha256": "5129e9bc1ba812b711fd9a646d3a38a906d365a26ee685df183b8752458944d4", + "bytes": 133453, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/manifest.json", + "sha256": "2667ce63c2e0835b7007239816a5597639321d333da396a78638dfa9e8a7c935", + "bytes": 956, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/mockups/dashboard.svg", + "sha256": "318be3adb1324c26eb30f05572a29528a3e38331c6a604652eef75b54f8c29dc", + "bytes": 9130, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/mockups/pipeline.svg", + "sha256": "db2ef41faabeb90e7ce85413e168581686c54535d970fc7d8deda3888a479de4", + "bytes": 7889, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/mockups/workspace.svg", + "sha256": "9bbab22349147c7b01d6e18c93c622a6f8aed6dedaf23715189ab54d60e1ddbd", + "bytes": 10361, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/export/robots.txt", + "sha256": "90d24bc3bf698ac1e173739502298ccca72adf1f564fab05f484b8c48d1cadd2", + "bytes": 67, + "hashPolicy": "Exact saved raw bytes" + } + ], + "exportFileCount": 75, + "exportSha256": "6e60c305555153d3379be3dac24c0845cf7665855bb7bcba95b26b9131cfd33c", + "exportHashPolicy": "SHA256 of sorted original job-tracker-ui/out relative path + TAB + raw file SHA256 + LF records", + "apiBinary": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/api/JobTrackerApi.dll", + "sha256": "d2da64748364880d471d2087d5aa101ce749b26966beed13d9e9dbaa3b92512b", + "bytes": 4026368, + "hashPolicy": "Exact saved raw bytes" + }, + "apiQualification": "Unchanged P702 repair binary; no new backend build/test execution." + }, + "commands": { + "typecheck": { + "record": { + "name": "typecheck", + "command": [ + "rtk", + "proxy", + "npm.cmd", + "run", + "typecheck" + ], + "startedUtc": "2026-10-12T11:13:30.672991+00:00", + "finishedUtc": "2026-10-12T11:13:40.714364+00:00", + "exitCode": 0 + }, + "recordRaw": { + "path": ".artifacts/phase7/p7-03/editor/candidate-expanded-20261012T111403Z/typecheck-command.json", + "sha256": "4c112c2b2e74585a95d1a680e7c3664943536f9350edbf6b17d89923c074f13e", + "bytes": 247, + "hashPolicy": "Exact saved raw bytes" + }, + "logRaw": { + "path": ".artifacts/phase7/p7-03/editor/candidate-expanded-20261012T111403Z/typecheck.log", + "sha256": "89b0ec97b537eca6560c13ca2dfea9e3a97dd1bb35580c4ff39d2462db25e080", + "bytes": 148, + "hashPolicy": "Exact saved raw bytes" + } + }, + "browser-typecheck": { + "record": { + "name": "browser-typecheck", + "command": [ + "rtk", + "proxy", + "npm.cmd", + "exec", + "tsc", + "--", + "--project", + "../.artifacts/phase7/e2e-tsconfig.json", + "--noEmit" + ], + "startedUtc": "2026-10-12T11:16:54.890230+00:00", + "finishedUtc": "2026-10-12T11:16:58.768748+00:00", + "exitCode": 0 + }, + "recordRaw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/browser-typecheck-command.json", + "sha256": "446e1dd54aead34833857d5fde704c8c3f7895a8330ca205200e5c87bd338b0c", + "bytes": 343, + "hashPolicy": "Exact saved raw bytes" + }, + "logRaw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/browser-typecheck.log", + "sha256": "d2993bc68ad9a63f711c8f5473155e2ba00fdcd461220cc3849185f2f9ad93e6", + "bytes": 78, + "hashPolicy": "Exact saved raw bytes" + } + }, + "lint": { + "record": { + "name": "lint", + "command": [ + "rtk", + "proxy", + "npm.cmd", + "run", + "lint" + ], + "startedUtc": "2026-10-12T11:13:04.317243+00:00", + "finishedUtc": "2026-10-12T11:13:24.023145+00:00", + "exitCode": 0 + }, + "recordRaw": { + "path": ".artifacts/phase7/p7-03/editor/candidate-expanded-20261012T111403Z/lint-command.json", + "sha256": "35f3e757dfa8d7b645d7c05ec6ce3baac808366a4b63ce803a9e2841af2e4acf", + "bytes": 237, + "hashPolicy": "Exact saved raw bytes" + }, + "logRaw": { + "path": ".artifacts/phase7/p7-03/editor/candidate-expanded-20261012T111403Z/lint.log", + "sha256": "b040dbeca9b4adb3f6f4c25ac49de0d37e921375b2d9b57e87b542a10f599913", + "bytes": 136, + "hashPolicy": "Exact saved raw bytes" + } + }, + "build": { + "record": { + "name": "build", + "command": [ + "rtk", + "proxy", + "npm.cmd", + "run", + "build" + ], + "startedUtc": "2026-10-12T11:13:04.646385+00:00", + "finishedUtc": "2026-10-12T11:13:12.588606+00:00", + "exitCode": 0 + }, + "recordRaw": { + "path": ".artifacts/phase7/p7-03/editor/candidate-expanded-20261012T111403Z/build-command.json", + "sha256": "f3d76edbdd544d33d0d587736fe3a0b0c479096c371b79d3174bacc2a8fd231f", + "bytes": 239, + "hashPolicy": "Exact saved raw bytes" + }, + "logRaw": { + "path": ".artifacts/phase7/p7-03/editor/candidate-expanded-20261012T111403Z/build.log", + "sha256": "606ef19237da46261b2fb70b430cecd2f3874e4205795e761fa51471fc717d42", + "bytes": 670, + "hashPolicy": "Exact saved raw bytes" + } + } + }, + "affectedFrontend": { + "raw": { + "path": ".artifacts/phase7/p7-03/editor/candidate-expanded-20261012T111403Z/career-editor-expanded-final-20261012T111330Z.json", + "sha256": "b1e8ac89e147c9cbe282c4d5d23600f78c40154109d0f89d338691b3191971cd", + "bytes": 22549, + "hashPolicy": "Exact measured raw bytes" + }, + "startedUnixMs": 1791803611355, + "passed": 54, + "failed": 0, + "pending": 0, + "total": 54, + "suites": 4, + "cases": [ + { + "name": "meaningful identity initials use a readable foreground/background pair in [Function CareerProfilePage]", + "status": "passed" + }, + { + "name": "meaningful identity initials use a readable foreground/background pair in [Function ProfilePage]", + "status": "passed" + }, + { + "name": "Career Profile section headings describe the visible hierarchy without changing editing fields", + "status": "passed" + }, + { + "name": "account headings separate identity from security sections", + "status": "passed" + }, + { + "name": "account CV text status in en does not claim the CV library is empty", + "status": "passed" + }, + { + "name": "account CV text status in nb does not claim the CV library is empty", + "status": "passed" + }, + { + "name": "[PRES-E02/E09/C01] account save carries four identity fields and keeps career, email and CV writes separate", + "status": "passed" + }, + { + "name": "[PRES-E02/E08/E09] failed account save keeps a scoped error and the identity draft for explicit retry", + "status": "passed" + }, + { + "name": "[PRES-E02/E08] failed password update keeps a scoped error and secret draft until explicit retry succeeds", + "status": "passed" + }, + { + "name": "profile page loads persisted structured cv and can re-parse it", + "status": "passed" + }, + { + "name": "saving the career profile PUTs the structured profile and cv text unchanged (Phase 1 refactor invariant)", + "status": "passed" + }, + { + "name": "editing a field in an extracted section updates parent state and flows into save (Phase 1 increment 2)", + "status": "passed" + }, + { + "name": "profile page can reprocess from stored artifact history", + "status": "passed" + }, + { + "name": "active extraction polling refreshes run status without resetting unsaved career fields", + "status": "passed" + }, + { + "name": "profile page shows durable CV operation state and retries a failed run", + "status": "passed" + }, + { + "name": "profile page keeps raw extraction collapsed until expanded", + "status": "passed" + }, + { + "name": "saving the master profile (career) persists the structured profile via /career/profile", + "status": "passed" + }, + { + "name": "/career shows the profile completeness overview", + "status": "passed" + }, + { + "name": "/career profile exposes extraction progress", + "status": "passed" + }, + { + "name": "/career profile can queue a CV upload without visiting import review first", + "status": "passed" + }, + { + "name": "/career localizes completeness and review confidence without changing CV data", + "status": "passed" + }, + { + "name": "/career separates overview, profile and import while preserving unsaved profile edits", + "status": "passed" + }, + { + "name": "pending CV extraction can be reviewed and applied", + "status": "passed" + }, + { + "name": "account email changes require a password and use the confirmation flow", + "status": "passed" + }, + { + "name": "a locale update retains dirty structured and raw drafts without reading their source again", + "status": "passed" + }, + { + "name": "a pending initial read keeps one request and reports its failure in the latest locale without language writes", + "status": "passed" + }, + { + "name": "a held Save locks every editor mutation, raw input and history restore until its snapshot settles", + "status": "passed" + }, + { + "name": "two Save activations before React commits pending state send only one canonical PUT", + "status": "passed" + }, + { + "name": "a failed Save retains a scoped localized error and draft for retry through the same Save button", + "status": "passed" + }, + { + "name": "the editor exposes named H2/H3 groups and contextual repeated-item remove controls", + "status": "passed" + }, + { + "name": "manual edits preserve long-tail data, custom links, opaque IDs and modeled fields without editor controls", + "status": "passed" + }, + { + "name": "a read-only provider cannot edit canonical fields or trigger canonical writes", + "status": "passed" + }, + { + "name": "first-run workspace presents concise profile, import, general CV and job-specific actions", + "status": "passed" + }, + { + "name": "career workspace overview and import state render in Bokmål", + "status": "passed" + }, + { + "name": "returning workspace shows missing profile information and recent general and job-specific CVs", + "status": "passed" + }, + { + "name": "workspace exposes the pending_review import state as a resumable action", + "status": "passed" + }, + { + "name": "workspace exposes the queued import state as a resumable action", + "status": "passed" + }, + { + "name": "workspace exposes the failed import state as a resumable action", + "status": "passed" + }, + { + "name": "workspace represents loading and profile-load errors without inventing status", + "status": "passed" + }, + { + "name": "a settled failed profile read hides the completeness score and retries only through its existing owner", + "status": "passed" + }, + { + "name": "an unknown import read cannot claim no imports, completion or first-run guidance", + "status": "passed" + }, + { + "name": "a failed import read stays unknown and keeps its own retry separate from the profile read", + "status": "passed" + }, + { + "name": "failed recent-CV reads do not imply first-run and retry the same list without writes", + "status": "passed" + }, + { + "name": "the parent exposes failed import-read retry without canonical saves or history restores", + "status": "passed" + }, + { + "name": "changing language in overview cannot refetch or overwrite a dirty canonical draft", + "status": "passed" + }, + { + "name": "visited evidence keeps its draft across sections without an unvisited or repeated list request", + "status": "passed" + }, + { + "name": "preserves the server item ID when normalizing jobs", + "status": "passed" + }, + { + "name": "preserves the server item ID when normalizing education", + "status": "passed" + }, + { + "name": "preserves the server item ID when normalizing certifications", + "status": "passed" + }, + { + "name": "preserves the server item ID when normalizing projects", + "status": "passed" + }, + { + "name": "legacy structured items without IDs remain usable and acquire no client-generated IDs", + "status": "passed" + }, + { + "name": "legacy parsed sections keep their facts without inventing structured item IDs", + "status": "passed" + }, + { + "name": "API null and missing numeric metadata remain absent rather than becoming zero", + "status": "passed" + }, + { + "name": "zero, finite numbers and numeric strings keep the established metadata number conversion", + "status": "passed" + } + ] + }, + "affectedCommand": { + "command": [ + "rtk", + "proxy", + "npm.cmd", + "test", + "--", + "--runInBand", + "--watchAll=false", + "--json", + "--outputFile=E:\\Storage\\Projects\\Active\\Job tracker\\.artifacts\\phase7\\current\\unit\\career-editor-expanded-final-20261012T111330Z.json", + "src/career-editor.test.tsx", + "src/profile-page.test.tsx", + "src/career-workspace-page.test.tsx", + "src/profileCv.test.ts" + ], + "startedUtc": "2026-10-12T11:13:30.384304+00:00", + "finishedUtc": "2026-10-12T11:14:03.488824+00:00", + "exitCode": 0, + "counts": { + "numPassedTests": 54, + "numFailedTests": 0, + "numPendingTests": 0, + "numTodoTests": 0, + "numPassedTestSuites": 4, + "numFailedTestSuites": 0 + } + }, + "affectedCommandRaw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor-expanded-final-20261012T111330Z-command.json", + "sha256": "70b827c08adbdc84a891b68c42abd79941f7d4637ea1c7b2aa176973b13f10d8", + "bytes": 756, + "hashPolicy": "Exact saved raw bytes" + }, + "affectedUnitLogRaw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor-expanded-final-20261012T111330Z.log", + "sha256": "69be57aea806b9b221b7f3dbae71baae9c1052eb753d10e472b98aa8d7be6f20", + "bytes": 769, + "hashPolicy": "Exact saved raw bytes" + }, + "environment": { + "appliedRunnerEnvironment": { + "browser": "Native Windows Chromium/local SQLite; original runner/config frozen", + "NEXT_PUBLIC_API_BASE_URL": "http://localhost:5302/api", + "PLAYWRIGHT_STATIC_EXPORT": "true", + "PREBUILT_EXPORT": "true", + "REUSE_SERVERS": "false", + "Workers__SavedJobSearchAlertsEnabled": "false", + "qualification": "Applied runner environment; not deployed/provider/device evidence" + }, + "frozenRefs": [ + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/environment/.artifacts/phase7/current/run-ui.py", + "sha256": "aad2211171c2bb8e012afb3aa9b28d5ef5c7f272d0e22aea723bd14c64c6ca29", + "bytes": 4863, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/environment/.artifacts/phase7/e2e-tsconfig.json", + "sha256": "55fa6fffaed1e76a32657edfffcc501cd8bd87330bda2c3a3944f8f89d4019e2", + "bytes": 572, + "hashPolicy": "Exact saved raw bytes" + } + ], + "regressionSourceRefs": [ + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/regression-source/job-tracker-ui/e2e/phase7-career-overview.spec.ts", + "sha256": "175e3081bb05c19675fb088b78f21e513b5f925848c4ab0a23272577cb59a169", + "bytes": 25884, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/regression-source/job-tracker-ui/e2e/phase7-career-source-ids.spec.ts", + "sha256": "92bc8f1b4c82210207071c56940813dfece3136832ba09ebd1e6c3471d8d7945", + "bytes": 20601, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/regression-source/job-tracker-ui/e2e/redesign-preservation.spec.ts", + "sha256": "997b01c7e2a313e5f590820bad6b630af7eec67e782df7a786ccce6ebd569da0", + "bytes": 23275, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/regression-source/job-tracker-ui/playwright.config.ts", + "sha256": "80da205d1b692b0d1c317772fdeda618a0e848d8c25625f8097a0e33ff2456e1", + "bytes": 2554, + "hashPolicy": "Exact saved raw bytes" + } + ] + }, + "nativeLanes": { + "career-editor": { + "command": { + "name": "career-editor", + "command": [ + "rtk", + "proxy", + "node", + "node_modules/@playwright/test/cli.js", + "test", + "e2e/phase7-career-editor.spec.ts", + "--retries=0", + "--reporter=list,json", + "--output=E:\\Storage\\Projects\\Active\\Job tracker\\.artifacts\\phase7\\current\\ui\\career-editor-results" + ], + "startedUtc": "2026-10-12T11:16:54.891737+00:00", + "finishedUtc": "2026-10-12T11:17:44.198980+00:00", + "exitCode": 0, + "stats": { + "startTime": "2026-10-12T11:16:55.417Z", + "duration": 48725.924, + "expected": 11, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + } + }, + "commandRaw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor-command.json", + "sha256": "43c98dea2a5617d1290e51905861c802372869d1e4795b613018f1268099c1ea", + "bytes": 654, + "hashPolicy": "Exact measured raw bytes" + }, + "reportRaw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "logRaw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.log", + "sha256": "d759d6bc4396ce8987bf41a88684aff920722b30d48c8a06cc9e3a73753f6e38", + "bytes": 2465, + "hashPolicy": "Exact measured raw bytes" + }, + "stats": { + "startTime": "2026-10-12T11:16:55.417Z", + "duration": 48725.924, + "expected": 11, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "cases": [ + { + "title": "[P7-03 PRES-C01 C02 E08] structured and raw drafts survive English to Bokmål without canonical refetch or write", + "file": "phase7-career-editor.spec.ts", + "line": 161, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 4326 + }, + { + "title": "[P7-03 PRES-C01 C02 E08] held save locks edits and duplicate writes; failed save retains its snapshot for explicit identical-body retry", + "file": "phase7-career-editor.spec.ts", + "line": 211, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 7690 + }, + { + "title": "[P7-03 PRES-C01 C02 E08] actual validation400 retains draft and source; corrected explicit save persists once", + "file": "phase7-career-editor.spec.ts", + "line": 321, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 4139 + }, + { + "title": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry nb/dark/320x844", + "file": "phase7-career-editor.spec.ts", + "line": 381, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 2721 + }, + { + "title": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry en/light/360x800", + "file": "phase7-career-editor.spec.ts", + "line": 381, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 2978 + }, + { + "title": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry nb/light/390x844", + "file": "phase7-career-editor.spec.ts", + "line": 381, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 2795 + }, + { + "title": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry en/dark/768x1024", + "file": "phase7-career-editor.spec.ts", + "line": 381, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 3166 + }, + { + "title": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry nb/dark/1024x768", + "file": "phase7-career-editor.spec.ts", + "line": 381, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 3009 + }, + { + "title": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry en/light/1280x320", + "file": "phase7-career-editor.spec.ts", + "line": 381, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 3231 + }, + { + "title": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry nb/light/1440x900", + "file": "phase7-career-editor.spec.ts", + "line": 381, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 3077 + }, + { + "title": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry en/dark/1920x1080", + "file": "phase7-career-editor.spec.ts", + "line": 381, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 3318 + } + ], + "reportErrors": [], + "configuration": { + "version": "1.62.1", + "workers": 1, + "projects": [ + { + "name": "chromium", + "retries": 0 + } + ] + }, + "auditSummaries": [ + { + "test": "[P7-03 PRES-C01 C02 E08] structured and raw drafts survive English to Bokmål without canonical refetch or write", + "attachment": "p7-career-editor-nb-light-1440-locale-retained-raw-draft-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/002-p7-career-editor-nb-light-1440-locale-retained-raw-draft-audit.json", + "sha256": "b4d6a68c1836e89abd678dd22933e4dc0a90df22c32f917ec4826b90f1d0f3ee", + "bytes": 9614, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "nb", + "theme": "light", + "width": 1440, + "height": 900 + }, + "state": "locale-retained-raw-draft", + "qualifications": [ + "Automated Chromium evidence only; no human screen reader or physical touch/software keyboard", + "No actual browser zoom, production font/photo, PDF, model/provider or production acceptance" + ] + }, + "geometry": { + "width": 1440, + "height": 900, + "rootOverflow": 0, + "overflowElements": [], + "visibleFields": [ + { + "name": "Profil-CV / hovedtekst for CV", + "left": 350, + "right": 1344, + "width": 994 + } + ] + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 6, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 6 + } + ] + }, + { + "test": "[P7-03 PRES-C01 C02 E08] held save locks edits and duplicate writes; failed save retains its snapshot for explicit identical-body retry", + "attachment": "p7-career-editor-en-light-390-held-save-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/005-p7-career-editor-en-light-390-held-save-audit.json", + "sha256": "1ecf582f10129d88696b80f697570b2e27cc743e732b13c4b71c9d21c8d7db79", + "bytes": 13886, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "light", + "width": 390, + "height": 844 + }, + "state": "held-save", + "qualifications": [ + "Automated Chromium evidence only; no human screen reader or physical touch/software keyboard", + "No actual browser zoom, production font/photo, PDF, model/provider or production acceptance" + ] + }, + "geometry": { + "width": 390, + "height": 844, + "rootOverflow": 0, + "overflowElements": [], + "visibleFields": [ + { + "name": "Full name", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Professional headline", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Contact email", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Phone", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Location", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Website", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "LinkedIn", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "GitHub", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Label", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "URL", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Professional summary", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Skills", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Interests", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Awards", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Publications", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Organisations", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "References", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Language", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Level", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Notes", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Job title", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Company", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Location", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Start", + "left": 72, + "right": 181, + "width": 109 + }, + { + "name": "End", + "left": 209, + "right": 318, + "width": 109 + }, + { + "name": "Job bullets", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Job skills", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Qualification", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Institution", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Location", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Start", + "left": 72, + "right": 181, + "width": 109 + }, + { + "name": "End", + "left": 209, + "right": 318, + "width": 109 + }, + { + "name": "Education details", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Section title", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Section items", + "left": 72, + "right": 318, + "width": 246 + } + ] + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 2, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 2 + } + ] + }, + { + "test": "[P7-03 PRES-C01 C02 E08] held save locks edits and duplicate writes; failed save retains its snapshot for explicit identical-body retry", + "attachment": "p7-career-editor-en-light-390-held-save-raw-import-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/007-p7-career-editor-en-light-390-held-save-raw-import-audit.json", + "sha256": "74b00f89296f46c1b55769de8b30cac678b82ee349a6c26672070aca9014ca21", + "bytes": 7635, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "light", + "width": 390, + "height": 844 + }, + "state": "held-save-raw-import", + "qualifications": [ + "Automated Chromium evidence only; no human screen reader or physical touch/software keyboard", + "No actual browser zoom, production font/photo, PDF, model/provider or production acceptance" + ] + }, + "geometry": { + "width": 390, + "height": 844, + "rootOverflow": 0, + "overflowElements": [], + "visibleFields": [ + { + "name": "Profile CV / master resume text", + "left": 68, + "right": 322, + "width": 254 + } + ] + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 3, + "byRule": [ + { + "kind": "incomplete", + "id": "aria-hidden-focus", + "nodes": 1 + }, + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 2 + } + ] + }, + { + "test": "[P7-03 PRES-C01 C02 E08] held save locks edits and duplicate writes; failed save retains its snapshot for explicit identical-body retry", + "attachment": "p7-career-editor-en-light-390-failed-save-retained-draft-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/009-p7-career-editor-en-light-390-failed-save-retained-draft-audit.json", + "sha256": "59755c41b881d99ddca0468f8e8567bce43086c8fb093c5d681529d5fc3aec48", + "bytes": 40033, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "light", + "width": 390, + "height": 844 + }, + "state": "failed-save-retained-draft", + "qualifications": [ + "Automated Chromium evidence only; no human screen reader or physical touch/software keyboard", + "No actual browser zoom, production font/photo, PDF, model/provider or production acceptance" + ] + }, + "geometry": { + "width": 390, + "height": 844, + "rootOverflow": 0, + "overflowElements": [], + "visibleFields": [ + { + "name": "Full name", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Professional headline", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Contact email", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Phone", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Location", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Website", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "LinkedIn", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "GitHub", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Label", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "URL", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Professional summary", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Skills", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Interests", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Awards", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Publications", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Organisations", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "References", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Language", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Level", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Notes", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Job title", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Company", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Location", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Start", + "left": 72, + "right": 181, + "width": 109 + }, + { + "name": "End", + "left": 209, + "right": 318, + "width": 109 + }, + { + "name": "Job bullets", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Job skills", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Qualification", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Institution", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Location", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Start", + "left": 72, + "right": 181, + "width": 109 + }, + { + "name": "End", + "left": 209, + "right": 318, + "width": 109 + }, + { + "name": "Education details", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Section title", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Section items", + "left": 72, + "right": 318, + "width": 246 + } + ] + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 37, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 37 + } + ] + }, + { + "test": "[P7-03 PRES-C01 C02 E08] actual validation400 retains draft and source; corrected explicit save persists once", + "attachment": "p7-career-editor-nb-dark-390-actual-validation400-retained-draft-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/012-p7-career-editor-nb-dark-390-actual-validation400-retained-draft-audit.json", + "sha256": "1e4d41575cc38bc9e7a576ff452c60a5a92672b0ed507f782219af055e1caf55", + "bytes": 41149, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "nb", + "theme": "dark", + "width": 390, + "height": 844 + }, + "state": "actual-validation400-retained-draft", + "qualifications": [ + "Automated Chromium evidence only; no human screen reader or physical touch/software keyboard", + "No actual browser zoom, production font/photo, PDF, model/provider or production acceptance" + ] + }, + "geometry": { + "width": 390, + "height": 844, + "rootOverflow": 0, + "overflowElements": [], + "visibleFields": [ + { + "name": "Fullt navn", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Profesjonell overskrift", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Kontakt-e-post", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Telefon", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Sted", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Nettsted", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "LinkedIn", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "GitHub", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Etikett", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "URL", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Sammendrags-punkter", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Kjernekompetanse", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Interesser", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Priser og utmerkelser", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Publikasjoner", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Organisasjoner", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Referanser", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Språk", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Nivå", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Notater", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Stillingstittel", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Selskap", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Sted", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Start", + "left": 72, + "right": 181, + "width": 109 + }, + { + "name": "Slutt", + "left": 209, + "right": 318, + "width": 109 + }, + { + "name": "Jobbpunkter", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Ferdigheter for jobben", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Kvalifikasjon", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Institusjon", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Sted", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Start", + "left": 72, + "right": 181, + "width": 109 + }, + { + "name": "Slutt", + "left": 209, + "right": 318, + "width": 109 + }, + { + "name": "Detaljer om utdanning", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Seksjonstittel", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Seksjonsinnhold", + "left": 72, + "right": 318, + "width": 246 + } + ] + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 38, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 38 + } + ] + }, + { + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry nb/dark/320x844", + "attachment": "p7-career-editor-nb-dark-320-structured-editor-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/015-p7-career-editor-nb-dark-320-structured-editor-audit.json", + "sha256": "1bee6c219aeb867c82760b0ec088371356442918588c73665e6f98392b9a061f", + "bytes": 39989, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "nb", + "theme": "dark", + "width": 320, + "height": 844 + }, + "state": "structured-editor", + "qualifications": [ + "Automated Chromium evidence only; no human screen reader or physical touch/software keyboard", + "No actual browser zoom, production font/photo, PDF, model/provider or production acceptance" + ] + }, + "geometry": { + "width": 320, + "height": 844, + "rootOverflow": 0, + "overflowElements": [], + "visibleFields": [ + { + "name": "Fullt navn", + "left": 55, + "right": 265, + "width": 210 + }, + { + "name": "Profesjonell overskrift", + "left": 55, + "right": 265, + "width": 210 + }, + { + "name": "Kontakt-e-post", + "left": 55, + "right": 265, + "width": 210 + }, + { + "name": "Telefon", + "left": 55, + "right": 265, + "width": 210 + }, + { + "name": "Sted", + "left": 55, + "right": 265, + "width": 210 + }, + { + "name": "Nettsted", + "left": 55, + "right": 265, + "width": 210 + }, + { + "name": "LinkedIn", + "left": 55, + "right": 265, + "width": 210 + }, + { + "name": "GitHub", + "left": 55, + "right": 265, + "width": 210 + }, + { + "name": "Etikett", + "left": 55, + "right": 265, + "width": 210 + }, + { + "name": "URL", + "left": 55, + "right": 265, + "width": 210 + }, + { + "name": "Sammendrags-punkter", + "left": 55, + "right": 265, + "width": 210 + }, + { + "name": "Kjernekompetanse", + "left": 55, + "right": 265, + "width": 210 + }, + { + "name": "Interesser", + "left": 55, + "right": 265, + "width": 210 + }, + { + "name": "Priser og utmerkelser", + "left": 55, + "right": 265, + "width": 210 + }, + { + "name": "Publikasjoner", + "left": 55, + "right": 265, + "width": 210 + }, + { + "name": "Organisasjoner", + "left": 55, + "right": 265, + "width": 210 + }, + { + "name": "Referanser", + "left": 55, + "right": 265, + "width": 210 + }, + { + "name": "Språk", + "left": 72, + "right": 248, + "width": 176 + }, + { + "name": "Nivå", + "left": 72, + "right": 248, + "width": 176 + }, + { + "name": "Notater", + "left": 72, + "right": 248, + "width": 176 + }, + { + "name": "Stillingstittel", + "left": 72, + "right": 248, + "width": 176 + }, + { + "name": "Selskap", + "left": 72, + "right": 248, + "width": 176 + }, + { + "name": "Sted", + "left": 72, + "right": 248, + "width": 176 + }, + { + "name": "Start", + "left": 72, + "right": 146, + "width": 74 + }, + { + "name": "Slutt", + "left": 174, + "right": 248, + "width": 74 + }, + { + "name": "Jobbpunkter", + "left": 72, + "right": 248, + "width": 176 + }, + { + "name": "Ferdigheter for jobben", + "left": 72, + "right": 248, + "width": 176 + }, + { + "name": "Kvalifikasjon", + "left": 72, + "right": 248, + "width": 176 + }, + { + "name": "Institusjon", + "left": 72, + "right": 248, + "width": 176 + }, + { + "name": "Sted", + "left": 72, + "right": 248, + "width": 176 + }, + { + "name": "Start", + "left": 72, + "right": 146, + "width": 74 + }, + { + "name": "Slutt", + "left": 174, + "right": 248, + "width": 74 + }, + { + "name": "Detaljer om utdanning", + "left": 72, + "right": 248, + "width": 176 + }, + { + "name": "Seksjonstittel", + "left": 72, + "right": 248, + "width": 176 + }, + { + "name": "Seksjonsinnhold", + "left": 72, + "right": 248, + "width": 176 + } + ] + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 37, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 37 + } + ] + }, + { + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry en/light/360x800", + "attachment": "p7-career-editor-en-light-360-structured-editor-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/017-p7-career-editor-en-light-360-structured-editor-audit.json", + "sha256": "f7c1584155885e0f152a74998d21020049d6245196578c6fdb76e4486630f5fb", + "bytes": 39701, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "light", + "width": 360, + "height": 800 + }, + "state": "structured-editor", + "qualifications": [ + "Automated Chromium evidence only; no human screen reader or physical touch/software keyboard", + "No actual browser zoom, production font/photo, PDF, model/provider or production acceptance" + ] + }, + "geometry": { + "width": 360, + "height": 800, + "rootOverflow": 0, + "overflowElements": [], + "visibleFields": [ + { + "name": "Full name", + "left": 55, + "right": 305, + "width": 250 + }, + { + "name": "Professional headline", + "left": 55, + "right": 305, + "width": 250 + }, + { + "name": "Contact email", + "left": 55, + "right": 305, + "width": 250 + }, + { + "name": "Phone", + "left": 55, + "right": 305, + "width": 250 + }, + { + "name": "Location", + "left": 55, + "right": 305, + "width": 250 + }, + { + "name": "Website", + "left": 55, + "right": 305, + "width": 250 + }, + { + "name": "LinkedIn", + "left": 55, + "right": 305, + "width": 250 + }, + { + "name": "GitHub", + "left": 55, + "right": 305, + "width": 250 + }, + { + "name": "Label", + "left": 55, + "right": 305, + "width": 250 + }, + { + "name": "URL", + "left": 55, + "right": 305, + "width": 250 + }, + { + "name": "Professional summary", + "left": 55, + "right": 305, + "width": 250 + }, + { + "name": "Skills", + "left": 55, + "right": 305, + "width": 250 + }, + { + "name": "Interests", + "left": 55, + "right": 305, + "width": 250 + }, + { + "name": "Awards", + "left": 55, + "right": 305, + "width": 250 + }, + { + "name": "Publications", + "left": 55, + "right": 305, + "width": 250 + }, + { + "name": "Organisations", + "left": 55, + "right": 305, + "width": 250 + }, + { + "name": "References", + "left": 55, + "right": 305, + "width": 250 + }, + { + "name": "Language", + "left": 72, + "right": 288, + "width": 216 + }, + { + "name": "Level", + "left": 72, + "right": 288, + "width": 216 + }, + { + "name": "Notes", + "left": 72, + "right": 288, + "width": 216 + }, + { + "name": "Job title", + "left": 72, + "right": 288, + "width": 216 + }, + { + "name": "Company", + "left": 72, + "right": 288, + "width": 216 + }, + { + "name": "Location", + "left": 72, + "right": 288, + "width": 216 + }, + { + "name": "Start", + "left": 72, + "right": 166, + "width": 94 + }, + { + "name": "End", + "left": 194, + "right": 288, + "width": 94 + }, + { + "name": "Job bullets", + "left": 72, + "right": 288, + "width": 216 + }, + { + "name": "Job skills", + "left": 72, + "right": 288, + "width": 216 + }, + { + "name": "Qualification", + "left": 72, + "right": 288, + "width": 216 + }, + { + "name": "Institution", + "left": 72, + "right": 288, + "width": 216 + }, + { + "name": "Location", + "left": 72, + "right": 288, + "width": 216 + }, + { + "name": "Start", + "left": 72, + "right": 166, + "width": 94 + }, + { + "name": "End", + "left": 194, + "right": 288, + "width": 94 + }, + { + "name": "Education details", + "left": 72, + "right": 288, + "width": 216 + }, + { + "name": "Section title", + "left": 72, + "right": 288, + "width": 216 + }, + { + "name": "Section items", + "left": 72, + "right": 288, + "width": 216 + } + ] + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 37, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 37 + } + ] + }, + { + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry nb/light/390x844", + "attachment": "p7-career-editor-nb-light-390-structured-editor-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/019-p7-career-editor-nb-light-390-structured-editor-audit.json", + "sha256": "9b21d0f00f659eeb6995e930ce82275fb8030302138e4085bf1e8985f2b2ceff", + "bytes": 39957, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "nb", + "theme": "light", + "width": 390, + "height": 844 + }, + "state": "structured-editor", + "qualifications": [ + "Automated Chromium evidence only; no human screen reader or physical touch/software keyboard", + "No actual browser zoom, production font/photo, PDF, model/provider or production acceptance" + ] + }, + "geometry": { + "width": 390, + "height": 844, + "rootOverflow": 0, + "overflowElements": [], + "visibleFields": [ + { + "name": "Fullt navn", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Profesjonell overskrift", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Kontakt-e-post", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Telefon", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Sted", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Nettsted", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "LinkedIn", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "GitHub", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Etikett", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "URL", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Sammendrags-punkter", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Kjernekompetanse", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Interesser", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Priser og utmerkelser", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Publikasjoner", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Organisasjoner", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Referanser", + "left": 55, + "right": 335, + "width": 280 + }, + { + "name": "Språk", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Nivå", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Notater", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Stillingstittel", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Selskap", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Sted", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Start", + "left": 72, + "right": 181, + "width": 109 + }, + { + "name": "Slutt", + "left": 209, + "right": 318, + "width": 109 + }, + { + "name": "Jobbpunkter", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Ferdigheter for jobben", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Kvalifikasjon", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Institusjon", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Sted", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Start", + "left": 72, + "right": 181, + "width": 109 + }, + { + "name": "Slutt", + "left": 209, + "right": 318, + "width": 109 + }, + { + "name": "Detaljer om utdanning", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Seksjonstittel", + "left": 72, + "right": 318, + "width": 246 + }, + { + "name": "Seksjonsinnhold", + "left": 72, + "right": 318, + "width": 246 + } + ] + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 37, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 37 + } + ] + }, + { + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry en/dark/768x1024", + "attachment": "p7-career-editor-en-dark-768-structured-editor-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/021-p7-career-editor-en-dark-768-structured-editor-audit.json", + "sha256": "d9967df322c191bb5e4deff8ddd6416b4d34fa216c6304d9d59e432785db4f75", + "bytes": 38997, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "dark", + "width": 768, + "height": 1024 + }, + "state": "structured-editor", + "qualifications": [ + "Automated Chromium evidence only; no human screen reader or physical touch/software keyboard", + "No actual browser zoom, production font/photo, PDF, model/provider or production acceptance" + ] + }, + "geometry": { + "width": 768, + "height": 1024, + "rootOverflow": 0, + "overflowElements": [], + "visibleFields": [ + { + "name": "Full name", + "left": 75, + "right": 693, + "width": 618 + }, + { + "name": "Professional headline", + "left": 75, + "right": 693, + "width": 618 + }, + { + "name": "Contact email", + "left": 75, + "right": 693, + "width": 618 + }, + { + "name": "Phone", + "left": 75, + "right": 693, + "width": 618 + }, + { + "name": "Location", + "left": 75, + "right": 693, + "width": 618 + }, + { + "name": "Website", + "left": 75, + "right": 693, + "width": 618 + }, + { + "name": "LinkedIn", + "left": 75, + "right": 693, + "width": 618 + }, + { + "name": "GitHub", + "left": 75, + "right": 693, + "width": 618 + }, + { + "name": "Label", + "left": 75, + "right": 183.953125, + "width": 108.953125 + }, + { + "name": "URL", + "left": 211.953125, + "right": 649, + "width": 437.046875 + }, + { + "name": "Professional summary", + "left": 75, + "right": 693, + "width": 618 + }, + { + "name": "Skills", + "left": 75, + "right": 693, + "width": 618 + }, + { + "name": "Interests", + "left": 75, + "right": 693, + "width": 618 + }, + { + "name": "Awards", + "left": 75, + "right": 693, + "width": 618 + }, + { + "name": "Publications", + "left": 75, + "right": 693, + "width": 618 + }, + { + "name": "Organisations", + "left": 75, + "right": 693, + "width": 618 + }, + { + "name": "References", + "left": 75, + "right": 693, + "width": 618 + }, + { + "name": "Language", + "left": 96, + "right": 672, + "width": 576 + }, + { + "name": "Level", + "left": 96, + "right": 672, + "width": 576 + }, + { + "name": "Notes", + "left": 96, + "right": 672, + "width": 576 + }, + { + "name": "Job title", + "left": 96, + "right": 672, + "width": 576 + }, + { + "name": "Company", + "left": 96, + "right": 672, + "width": 576 + }, + { + "name": "Location", + "left": 96, + "right": 672, + "width": 576 + }, + { + "name": "Start", + "left": 96, + "right": 370, + "width": 274 + }, + { + "name": "End", + "left": 398, + "right": 672, + "width": 274 + }, + { + "name": "Job bullets", + "left": 96, + "right": 672, + "width": 576 + }, + { + "name": "Job skills", + "left": 96, + "right": 672, + "width": 576 + }, + { + "name": "Qualification", + "left": 96, + "right": 672, + "width": 576 + }, + { + "name": "Institution", + "left": 96, + "right": 672, + "width": 576 + }, + { + "name": "Location", + "left": 96, + "right": 672, + "width": 576 + }, + { + "name": "Start", + "left": 96, + "right": 370, + "width": 274 + }, + { + "name": "End", + "left": 398, + "right": 672, + "width": 274 + }, + { + "name": "Education details", + "left": 96, + "right": 672, + "width": 576 + }, + { + "name": "Section title", + "left": 96, + "right": 672, + "width": 576 + }, + { + "name": "Section items", + "left": 96, + "right": 672, + "width": 576 + } + ] + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 36, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 36 + } + ] + }, + { + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry nb/dark/1024x768", + "attachment": "p7-career-editor-nb-dark-1024-structured-editor-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/023-p7-career-editor-nb-dark-1024-structured-editor-audit.json", + "sha256": "bbc7b793c9a5db119a7fd602e96ffe6adc88a524856e41afb1fe6594cb89796d", + "bytes": 39398, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "nb", + "theme": "dark", + "width": 1024, + "height": 768 + }, + "state": "structured-editor", + "qualifications": [ + "Automated Chromium evidence only; no human screen reader or physical touch/software keyboard", + "No actual browser zoom, production font/photo, PDF, model/provider or production acceptance" + ] + }, + "geometry": { + "width": 1024, + "height": 768, + "rootOverflow": 0, + "overflowElements": [], + "visibleFields": [ + { + "name": "Fullt navn", + "left": 329, + "right": 623, + "width": 294 + }, + { + "name": "Profesjonell overskrift", + "left": 655, + "right": 949, + "width": 294 + }, + { + "name": "Kontakt-e-post", + "left": 329, + "right": 623, + "width": 294 + }, + { + "name": "Telefon", + "left": 655, + "right": 949, + "width": 294 + }, + { + "name": "Sted", + "left": 329, + "right": 623, + "width": 294 + }, + { + "name": "Nettsted", + "left": 655, + "right": 949, + "width": 294 + }, + { + "name": "LinkedIn", + "left": 329, + "right": 949, + "width": 620 + }, + { + "name": "GitHub", + "left": 329, + "right": 949, + "width": 620 + }, + { + "name": "Etikett", + "left": 329, + "right": 438.078125, + "width": 109.078125 + }, + { + "name": "URL", + "left": 466.078125, + "right": 905, + "width": 438.921875 + }, + { + "name": "Sammendrags-punkter", + "left": 329, + "right": 623, + "width": 294 + }, + { + "name": "Kjernekompetanse", + "left": 655, + "right": 949, + "width": 294 + }, + { + "name": "Interesser", + "left": 329, + "right": 623, + "width": 294 + }, + { + "name": "Priser og utmerkelser", + "left": 329, + "right": 623, + "width": 294 + }, + { + "name": "Publikasjoner", + "left": 655, + "right": 949, + "width": 294 + }, + { + "name": "Organisasjoner", + "left": 329, + "right": 623, + "width": 294 + }, + { + "name": "Referanser", + "left": 655, + "right": 949, + "width": 294 + }, + { + "name": "Språk", + "left": 350, + "right": 500, + "width": 150 + }, + { + "name": "Nivå", + "left": 528, + "right": 678, + "width": 150 + }, + { + "name": "Notater", + "left": 706, + "right": 856, + "width": 150 + }, + { + "name": "Stillingstittel", + "left": 350, + "right": 625, + "width": 275 + }, + { + "name": "Selskap", + "left": 653, + "right": 928, + "width": 275 + }, + { + "name": "Sted", + "left": 350, + "right": 625, + "width": 275 + }, + { + "name": "Start", + "left": 653, + "right": 776.5, + "width": 123.5 + }, + { + "name": "Slutt", + "left": 804.5, + "right": 928, + "width": 123.5 + }, + { + "name": "Jobbpunkter", + "left": 350, + "right": 928, + "width": 578 + }, + { + "name": "Ferdigheter for jobben", + "left": 350, + "right": 928, + "width": 578 + }, + { + "name": "Kvalifikasjon", + "left": 350, + "right": 625, + "width": 275 + }, + { + "name": "Institusjon", + "left": 653, + "right": 928, + "width": 275 + }, + { + "name": "Sted", + "left": 350, + "right": 625, + "width": 275 + }, + { + "name": "Start", + "left": 653, + "right": 776.5, + "width": 123.5 + }, + { + "name": "Slutt", + "left": 804.5, + "right": 928, + "width": 123.5 + }, + { + "name": "Detaljer om utdanning", + "left": 350, + "right": 928, + "width": 578 + }, + { + "name": "Seksjonstittel", + "left": 350, + "right": 856, + "width": 506 + }, + { + "name": "Seksjonsinnhold", + "left": 350, + "right": 928, + "width": 578 + } + ] + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 36, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 36 + } + ] + }, + { + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry en/light/1280x320", + "attachment": "p7-career-editor-en-light-1280-structured-editor-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/025-p7-career-editor-en-light-1280-structured-editor-audit.json", + "sha256": "cdb9529ef99936bad238b04fbf446863eea16c8b350f1675b5c86c85e3adc6ac", + "bytes": 39214, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "light", + "width": 1280, + "height": 320 + }, + "state": "structured-editor", + "qualifications": [ + "Automated Chromium evidence only; no human screen reader or physical touch/software keyboard", + "No actual browser zoom, production font/photo, PDF, model/provider or production acceptance" + ] + }, + "geometry": { + "width": 1280, + "height": 320, + "rootOverflow": 0, + "overflowElements": [], + "visibleFields": [ + { + "name": "Full name", + "left": 329, + "right": 751, + "width": 422 + }, + { + "name": "Professional headline", + "left": 783, + "right": 1205, + "width": 422 + }, + { + "name": "Contact email", + "left": 329, + "right": 751, + "width": 422 + }, + { + "name": "Phone", + "left": 783, + "right": 1205, + "width": 422 + }, + { + "name": "Location", + "left": 329, + "right": 751, + "width": 422 + }, + { + "name": "Website", + "left": 783, + "right": 1205, + "width": 422 + }, + { + "name": "LinkedIn", + "left": 329, + "right": 1205, + "width": 876 + }, + { + "name": "GitHub", + "left": 329, + "right": 1205, + "width": 876 + }, + { + "name": "Label", + "left": 329, + "right": 450.1875, + "width": 121.1875 + }, + { + "name": "URL", + "left": 478.1875, + "right": 1161, + "width": 682.8125 + }, + { + "name": "Professional summary", + "left": 329, + "right": 751, + "width": 422 + }, + { + "name": "Skills", + "left": 783, + "right": 1205, + "width": 422 + }, + { + "name": "Interests", + "left": 329, + "right": 751, + "width": 422 + }, + { + "name": "Awards", + "left": 329, + "right": 751, + "width": 422 + }, + { + "name": "Publications", + "left": 783, + "right": 1205, + "width": 422 + }, + { + "name": "Organisations", + "left": 329, + "right": 751, + "width": 422 + }, + { + "name": "References", + "left": 783, + "right": 1205, + "width": 422 + }, + { + "name": "Language", + "left": 350, + "right": 584.328125, + "width": 234.328125 + }, + { + "name": "Level", + "left": 612.328125, + "right": 846.671875, + "width": 234.34375 + }, + { + "name": "Notes", + "left": 874.671875, + "right": 1109.015625, + "width": 234.34375 + }, + { + "name": "Job title", + "left": 350, + "right": 753, + "width": 403 + }, + { + "name": "Company", + "left": 781, + "right": 1184, + "width": 403 + }, + { + "name": "Location", + "left": 350, + "right": 753, + "width": 403 + }, + { + "name": "Start", + "left": 781, + "right": 968.5, + "width": 187.5 + }, + { + "name": "End", + "left": 996.5, + "right": 1184, + "width": 187.5 + }, + { + "name": "Job bullets", + "left": 350, + "right": 1184, + "width": 834 + }, + { + "name": "Job skills", + "left": 350, + "right": 1184, + "width": 834 + }, + { + "name": "Qualification", + "left": 350, + "right": 753, + "width": 403 + }, + { + "name": "Institution", + "left": 781, + "right": 1184, + "width": 403 + }, + { + "name": "Location", + "left": 350, + "right": 753, + "width": 403 + }, + { + "name": "Start", + "left": 781, + "right": 968.5, + "width": 187.5 + }, + { + "name": "End", + "left": 996.5, + "right": 1184, + "width": 187.5 + }, + { + "name": "Education details", + "left": 350, + "right": 1184, + "width": 834 + }, + { + "name": "Section title", + "left": 350, + "right": 1109.015625, + "width": 759.015625 + }, + { + "name": "Section items", + "left": 350, + "right": 1184, + "width": 834 + } + ] + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 36, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 36 + } + ] + }, + { + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry nb/light/1440x900", + "attachment": "p7-career-editor-nb-light-1440-structured-editor-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/027-p7-career-editor-nb-light-1440-structured-editor-audit.json", + "sha256": "1e64abec3de45c0ada46a1bb7a1ac9a1b4a85d22ca9291bd37e9efa34d8454c9", + "bytes": 39470, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "nb", + "theme": "light", + "width": 1440, + "height": 900 + }, + "state": "structured-editor", + "qualifications": [ + "Automated Chromium evidence only; no human screen reader or physical touch/software keyboard", + "No actual browser zoom, production font/photo, PDF, model/provider or production acceptance" + ] + }, + "geometry": { + "width": 1440, + "height": 900, + "rootOverflow": 0, + "overflowElements": [], + "visibleFields": [ + { + "name": "Fullt navn", + "left": 337, + "right": 831, + "width": 494 + }, + { + "name": "Profesjonell overskrift", + "left": 863, + "right": 1357, + "width": 494 + }, + { + "name": "Kontakt-e-post", + "left": 337, + "right": 831, + "width": 494 + }, + { + "name": "Telefon", + "left": 863, + "right": 1357, + "width": 494 + }, + { + "name": "Sted", + "left": 337, + "right": 831, + "width": 494 + }, + { + "name": "Nettsted", + "left": 863, + "right": 1357, + "width": 494 + }, + { + "name": "LinkedIn", + "left": 337, + "right": 1357, + "width": 1020 + }, + { + "name": "GitHub", + "left": 337, + "right": 1357, + "width": 1020 + }, + { + "name": "Etikett", + "left": 337, + "right": 462.765625, + "width": 125.765625 + }, + { + "name": "URL", + "left": 490.765625, + "right": 1313, + "width": 822.234375 + }, + { + "name": "Sammendrags-punkter", + "left": 337, + "right": 831, + "width": 494 + }, + { + "name": "Kjernekompetanse", + "left": 863, + "right": 1357, + "width": 494 + }, + { + "name": "Interesser", + "left": 337, + "right": 831, + "width": 494 + }, + { + "name": "Priser og utmerkelser", + "left": 337, + "right": 831, + "width": 494 + }, + { + "name": "Publikasjoner", + "left": 863, + "right": 1357, + "width": 494 + }, + { + "name": "Organisasjoner", + "left": 337, + "right": 831, + "width": 494 + }, + { + "name": "Referanser", + "left": 863, + "right": 1357, + "width": 494 + }, + { + "name": "Språk", + "left": 358, + "right": 641.328125, + "width": 283.328125 + }, + { + "name": "Nivå", + "left": 669.328125, + "right": 952.65625, + "width": 283.328125 + }, + { + "name": "Notater", + "left": 980.65625, + "right": 1264, + "width": 283.34375 + }, + { + "name": "Stillingstittel", + "left": 358, + "right": 833, + "width": 475 + }, + { + "name": "Selskap", + "left": 861, + "right": 1336, + "width": 475 + }, + { + "name": "Sted", + "left": 358, + "right": 833, + "width": 475 + }, + { + "name": "Start", + "left": 861, + "right": 1084.5, + "width": 223.5 + }, + { + "name": "Slutt", + "left": 1112.5, + "right": 1336, + "width": 223.5 + }, + { + "name": "Jobbpunkter", + "left": 358, + "right": 1336, + "width": 978 + }, + { + "name": "Ferdigheter for jobben", + "left": 358, + "right": 1336, + "width": 978 + }, + { + "name": "Kvalifikasjon", + "left": 358, + "right": 833, + "width": 475 + }, + { + "name": "Institusjon", + "left": 861, + "right": 1336, + "width": 475 + }, + { + "name": "Sted", + "left": 358, + "right": 833, + "width": 475 + }, + { + "name": "Start", + "left": 861, + "right": 1084.5, + "width": 223.5 + }, + { + "name": "Slutt", + "left": 1112.5, + "right": 1336, + "width": 223.5 + }, + { + "name": "Detaljer om utdanning", + "left": 358, + "right": 1336, + "width": 978 + }, + { + "name": "Seksjonstittel", + "left": 358, + "right": 1264, + "width": 906 + }, + { + "name": "Seksjonsinnhold", + "left": 358, + "right": 1336, + "width": 978 + } + ] + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 36, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 36 + } + ] + }, + { + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry en/dark/1920x1080", + "attachment": "p7-career-editor-en-dark-1920-structured-editor-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/029-p7-career-editor-en-dark-1920-structured-editor-audit.json", + "sha256": "9b980b7f6f0fd8ffe12d418325231a5169ea7d71972c14b76f0a138344532e0a", + "bytes": 39189, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "dark", + "width": 1920, + "height": 1080 + }, + "state": "structured-editor", + "qualifications": [ + "Automated Chromium evidence only; no human screen reader or physical touch/software keyboard", + "No actual browser zoom, production font/photo, PDF, model/provider or production acceptance" + ] + }, + "geometry": { + "width": 1920, + "height": 1080, + "rootOverflow": 0, + "overflowElements": [], + "visibleFields": [ + { + "name": "Full name", + "left": 478, + "right": 1071, + "width": 593 + }, + { + "name": "Professional headline", + "left": 1103, + "right": 1696, + "width": 593 + }, + { + "name": "Contact email", + "left": 478, + "right": 1071, + "width": 593 + }, + { + "name": "Phone", + "left": 1103, + "right": 1696, + "width": 593 + }, + { + "name": "Location", + "left": 478, + "right": 1071, + "width": 593 + }, + { + "name": "Website", + "left": 1103, + "right": 1696, + "width": 593 + }, + { + "name": "LinkedIn", + "left": 478, + "right": 1696, + "width": 1218 + }, + { + "name": "GitHub", + "left": 478, + "right": 1696, + "width": 1218 + }, + { + "name": "Label", + "left": 478, + "right": 608.546875, + "width": 130.546875 + }, + { + "name": "URL", + "left": 636.546875, + "right": 1652, + "width": 1015.453125 + }, + { + "name": "Professional summary", + "left": 478, + "right": 1071, + "width": 593 + }, + { + "name": "Skills", + "left": 1103, + "right": 1696, + "width": 593 + }, + { + "name": "Interests", + "left": 478, + "right": 1071, + "width": 593 + }, + { + "name": "Awards", + "left": 478, + "right": 1071, + "width": 593 + }, + { + "name": "Publications", + "left": 1103, + "right": 1696, + "width": 593 + }, + { + "name": "Organisations", + "left": 478, + "right": 1071, + "width": 593 + }, + { + "name": "References", + "left": 1103, + "right": 1696, + "width": 593 + }, + { + "name": "Language", + "left": 499, + "right": 847.328125, + "width": 348.328125 + }, + { + "name": "Level", + "left": 875.328125, + "right": 1223.671875, + "width": 348.34375 + }, + { + "name": "Notes", + "left": 1251.671875, + "right": 1600, + "width": 348.328125 + }, + { + "name": "Job title", + "left": 499, + "right": 1073, + "width": 574 + }, + { + "name": "Company", + "left": 1101, + "right": 1675, + "width": 574 + }, + { + "name": "Location", + "left": 499, + "right": 1073, + "width": 574 + }, + { + "name": "Start", + "left": 1101, + "right": 1374, + "width": 273 + }, + { + "name": "End", + "left": 1402, + "right": 1675, + "width": 273 + }, + { + "name": "Job bullets", + "left": 499, + "right": 1675, + "width": 1176 + }, + { + "name": "Job skills", + "left": 499, + "right": 1675, + "width": 1176 + }, + { + "name": "Qualification", + "left": 499, + "right": 1073, + "width": 574 + }, + { + "name": "Institution", + "left": 1101, + "right": 1675, + "width": 574 + }, + { + "name": "Location", + "left": 499, + "right": 1073, + "width": 574 + }, + { + "name": "Start", + "left": 1101, + "right": 1374, + "width": 273 + }, + { + "name": "End", + "left": 1402, + "right": 1675, + "width": 273 + }, + { + "name": "Education details", + "left": 499, + "right": 1675, + "width": 1176 + }, + { + "name": "Section title", + "left": 499, + "right": 1600.015625, + "width": 1101.015625 + }, + { + "name": "Section items", + "left": 499, + "right": 1675, + "width": 1176 + } + ] + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 36, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 36 + } + ] + } + ], + "qualification": "Finite overlapping regression lane; full vectors/attachments retained unchanged in raw report and extracted JSON. No count addition beyond actual new editor11." + }, + "career-source-ids": { + "command": { + "name": "career-source-ids", + "command": [ + "rtk", + "proxy", + "node", + "node_modules/@playwright/test/cli.js", + "test", + "e2e/phase7-career-source-ids.spec.ts", + "--retries=0", + "--reporter=list,json", + "--output=E:\\Storage\\Projects\\Active\\Job tracker\\.artifacts\\phase7\\current\\ui\\career-source-ids-results" + ], + "startedUtc": "2026-10-12T11:14:58.203327+00:00", + "finishedUtc": "2026-10-12T11:15:10.584388+00:00", + "exitCode": 0, + "stats": { + "startTime": "2026-10-12T11:14:58.782Z", + "duration": 11766.523000000001, + "expected": 2, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + } + }, + "commandRaw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-source-ids-command.json", + "sha256": "1504bc1f574aab8b3a2c2599098b95df120b0fdee78f8cedea8752dafced42ad", + "bytes": 674, + "hashPolicy": "Exact measured raw bytes" + }, + "reportRaw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-source-ids.json", + "sha256": "fefd50362c7053b707ba1ade4569bb7d5ee638be4ebfa6529285f402b2841e25", + "bytes": 404902, + "hashPolicy": "Exact measured raw bytes" + }, + "logRaw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-source-ids.log", + "sha256": "27b9cbc1946e9a78f3e37fe4fce88c92374d4c10fc5b976935b3ecc49a60f375", + "bytes": 926, + "hashPolicy": "Exact measured raw bytes" + }, + "stats": { + "startTime": "2026-10-12T11:14:58.782Z", + "duration": 11766.523000000001, + "expected": 2, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "cases": [ + { + "title": "[P7-03 PRES-C01 C03 C06 C07 C10 W05 W06] unrelated canonical UI save preserves four source IDs, existing CV overrides, sibling and frozen package", + "file": "phase7-career-source-ids.spec.ts", + "line": 69, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 4064 + }, + { + "title": "[P7-03 PRES-C01 C03 E05 E09] real HTTP bounds canonical last-writer saves and structured-history recovery without claiming stale-write protection", + "file": "phase7-career-source-ids.spec.ts", + "line": 185, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 865 + } + ], + "reportErrors": [], + "configuration": { + "version": "1.62.1", + "workers": 1, + "projects": [ + { + "name": "chromium", + "retries": 0 + } + ] + }, + "auditSummaries": [], + "qualification": "Finite overlapping regression lane; full vectors/attachments retained unchanged in raw report and extracted JSON. No count addition beyond actual new editor11." + }, + "career": { + "command": { + "name": "career", + "command": [ + "rtk", + "proxy", + "node", + "node_modules/@playwright/test/cli.js", + "test", + "e2e/phase7-career-overview.spec.ts", + "--retries=0", + "--reporter=list,json", + "--output=E:\\Storage\\Projects\\Active\\Job tracker\\.artifacts\\phase7\\current\\ui\\career-results" + ], + "startedUtc": "2026-10-12T11:15:10.593438+00:00", + "finishedUtc": "2026-10-12T11:16:08.055945+00:00", + "exitCode": 0, + "stats": { + "startTime": "2026-10-12T11:15:11.135Z", + "duration": 56873.35, + "expected": 14, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + } + }, + "commandRaw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-command.json", + "sha256": "f0dd15650b1b2c75519b94db538a87718d0f525eb37b27957f6cc363233d63a2", + "bytes": 641, + "hashPolicy": "Exact measured raw bytes" + }, + "reportRaw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "logRaw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.log", + "sha256": "a382ac664650d707bd6afbf67975be2adb699b7fc091fa1c5b26dfeb212b5a61", + "bytes": 3267, + "hashPolicy": "Exact measured raw bytes" + }, + "stats": { + "startTime": "2026-10-12T11:15:11.135Z", + "duration": 56873.35, + "expected": 14, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "cases": [ + { + "title": "[P7-02 PRES-C04 E09] real SQLite evidence list preserves owner boundaries and existing validation", + "file": "phase7-career-overview.spec.ts", + "line": 106, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 925 + }, + { + "title": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/dark 320px overview and factual evidence preserve canonical source and recent CV links", + "file": "phase7-career-overview.spec.ts", + "line": 139, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 4287 + }, + { + "title": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/light 360px overview and factual evidence preserve canonical source and recent CV links", + "file": "phase7-career-overview.spec.ts", + "line": 139, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 4087 + }, + { + "title": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/light 390px overview and factual evidence preserve canonical source and recent CV links", + "file": "phase7-career-overview.spec.ts", + "line": 139, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 3785 + }, + { + "title": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/dark 768px overview and factual evidence preserve canonical source and recent CV links", + "file": "phase7-career-overview.spec.ts", + "line": 139, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 4073 + }, + { + "title": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/dark 1024px overview and factual evidence preserve canonical source and recent CV links", + "file": "phase7-career-overview.spec.ts", + "line": 139, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 4120 + }, + { + "title": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/light 1280px overview and factual evidence preserve canonical source and recent CV links", + "file": "phase7-career-overview.spec.ts", + "line": 139, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 4382 + }, + { + "title": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/light 1440px overview and factual evidence preserve canonical source and recent CV links", + "file": "phase7-career-overview.spec.ts", + "line": 139, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 4505 + }, + { + "title": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/dark 1920px overview and factual evidence preserve canonical source and recent CV links", + "file": "phase7-career-overview.spec.ts", + "line": 139, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 4411 + }, + { + "title": "[P7-02 PRES-C02 E09] unavailable /career/profile stays unknown and retries its reads without writes or false first-run guidance", + "file": "phase7-career-overview.spec.ts", + "line": 191, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 2257 + }, + { + "title": "[P7-02 PRES-C02 E09] unavailable /profile-cv/runs stays unknown and retries its reads without writes or false first-run guidance", + "file": "phase7-career-overview.spec.ts", + "line": 191, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 2217 + }, + { + "title": "[P7-02 PRES-C02 E09] unavailable /cv/variants stays unknown and retries its reads without writes or false first-run guidance", + "file": "phase7-career-overview.spec.ts", + "line": 191, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 2233 + }, + { + "title": "[P7-02 PRES-C04 E09] evidence pending/failure/read retry and failed save preserve drafts across section changes, cancellation and actual deletion", + "file": "phase7-career-overview.spec.ts", + "line": 229, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 6594 + }, + { + "title": "[P7-02 PRES-C01 C02] existing raw source copy and history entry remain read-only", + "file": "phase7-career-overview.spec.ts", + "line": 331, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 2144 + } + ], + "reportErrors": [], + "configuration": { + "version": "1.62.1", + "workers": 1, + "projects": [ + { + "name": "chromium", + "retries": 0 + } + ] + }, + "auditSummaries": [ + { + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/dark 320px overview and factual evidence preserve canonical source and recent CV links", + "attachment": "p7-career-nb-dark-320-populated-overview-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/002-p7-career-nb-dark-320-populated-overview-audit.json", + "sha256": "06b9894b40df5b25aadfe47d380ffe29af49c9decc5c9b81a012049f2bd56736", + "bytes": 6792, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "nb", + "theme": "dark", + "width": 320, + "height": 844 + }, + "state": "populated-overview", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 320, + "height": 844, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 2, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 2 + } + ] + }, + { + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/dark 320px overview and factual evidence preserve canonical source and recent CV links", + "attachment": "p7-career-nb-dark-320-long-evidence-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/004-p7-career-nb-dark-320-long-evidence-audit.json", + "sha256": "a2288f6072ead891375093fa002407fce5c056845ea1d5ff99eb4d4c681368af", + "bytes": 11676, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "nb", + "theme": "dark", + "width": 320, + "height": 844 + }, + "state": "long-evidence", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 320, + "height": 844, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 8, + "byRule": [ + { + "kind": "incomplete", + "id": "aria-hidden-focus", + "nodes": 1 + }, + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 7 + } + ] + }, + { + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/light 360px overview and factual evidence preserve canonical source and recent CV links", + "attachment": "p7-career-en-light-360-populated-overview-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/006-p7-career-en-light-360-populated-overview-audit.json", + "sha256": "4967c67ec92d240fa20f82b2bc41c34fcb2e55d5b511e033f45f6407981a06b1", + "bytes": 6679, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "light", + "width": 360, + "height": 800 + }, + "state": "populated-overview", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 360, + "height": 800, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 2, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 2 + } + ] + }, + { + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/light 360px overview and factual evidence preserve canonical source and recent CV links", + "attachment": "p7-career-en-light-360-long-evidence-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/008-p7-career-en-light-360-long-evidence-audit.json", + "sha256": "7ecb060300192a0c5b9827b24ebab835fbdd5648215cf9eaa9aea4bc0b37fb4d", + "bytes": 11585, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "light", + "width": 360, + "height": 800 + }, + "state": "long-evidence", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 360, + "height": 800, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 8, + "byRule": [ + { + "kind": "incomplete", + "id": "aria-hidden-focus", + "nodes": 1 + }, + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 7 + } + ] + }, + { + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/light 390px overview and factual evidence preserve canonical source and recent CV links", + "attachment": "p7-career-nb-light-390-populated-overview-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/010-p7-career-nb-light-390-populated-overview-audit.json", + "sha256": "c2c8a7cdb3177360635095b74bcd6cf5e881448133b357f38da9b8b8100461c5", + "bytes": 6796, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "nb", + "theme": "light", + "width": 390, + "height": 844 + }, + "state": "populated-overview", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 390, + "height": 844, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 2, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 2 + } + ] + }, + { + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/light 390px overview and factual evidence preserve canonical source and recent CV links", + "attachment": "p7-career-nb-light-390-long-evidence-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/012-p7-career-nb-light-390-long-evidence-audit.json", + "sha256": "d73b176c5a2750dd55ea1ddbe49ac868c6c38ac07b9924af78c11b096bb1ea6d", + "bytes": 11677, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "nb", + "theme": "light", + "width": 390, + "height": 844 + }, + "state": "long-evidence", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 390, + "height": 844, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 8, + "byRule": [ + { + "kind": "incomplete", + "id": "aria-hidden-focus", + "nodes": 1 + }, + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 7 + } + ] + }, + { + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/dark 768px overview and factual evidence preserve canonical source and recent CV links", + "attachment": "p7-career-en-dark-768-populated-overview-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/014-p7-career-en-dark-768-populated-overview-audit.json", + "sha256": "79e22aff21539affadbdfeb0a37132d4624bae7bc6550eaceccd4f4b42b60b0e", + "bytes": 5998, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "dark", + "width": 768, + "height": 1024 + }, + "state": "populated-overview", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 768, + "height": 1024, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 1, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 1 + } + ] + }, + { + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/dark 768px overview and factual evidence preserve canonical source and recent CV links", + "attachment": "p7-career-en-dark-768-long-evidence-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/016-p7-career-en-dark-768-long-evidence-audit.json", + "sha256": "89d50b7618ebb51a50935bbbfc564f70b252b930e8974eea64ab72ff04a77df3", + "bytes": 10419, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "dark", + "width": 768, + "height": 1024 + }, + "state": "long-evidence", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 768, + "height": 1024, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 7, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 7 + } + ] + }, + { + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/dark 1024px overview and factual evidence preserve canonical source and recent CV links", + "attachment": "p7-career-nb-dark-1024-populated-overview-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/018-p7-career-nb-dark-1024-populated-overview-audit.json", + "sha256": "9416274400aef9ef072254ba01914c44daa7324f876cd7b07273a3c62e485003", + "bytes": 6194, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "nb", + "theme": "dark", + "width": 1024, + "height": 768 + }, + "state": "populated-overview", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 1024, + "height": 768, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 1, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 1 + } + ] + }, + { + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/dark 1024px overview and factual evidence preserve canonical source and recent CV links", + "attachment": "p7-career-nb-dark-1024-long-evidence-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/020-p7-career-nb-dark-1024-long-evidence-audit.json", + "sha256": "ab06eb0e4f2ed956cd36c9328f2dc64d096e623d9ec076204207137fb99e12fa", + "bytes": 10595, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "nb", + "theme": "dark", + "width": 1024, + "height": 768 + }, + "state": "long-evidence", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 1024, + "height": 768, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 7, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 7 + } + ] + }, + { + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/light 1280px overview and factual evidence preserve canonical source and recent CV links", + "attachment": "p7-career-en-light-1280-populated-overview-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/022-p7-career-en-light-1280-populated-overview-audit.json", + "sha256": "1147566317d407fa4f55a29daebd710a06b5e2ed6919d694706ded2f7d4f9add", + "bytes": 6086, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "light", + "width": 1280, + "height": 320 + }, + "state": "populated-overview", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 1280, + "height": 320, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 1, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 1 + } + ] + }, + { + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/light 1280px overview and factual evidence preserve canonical source and recent CV links", + "attachment": "p7-career-en-light-1280-long-evidence-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/024-p7-career-en-light-1280-long-evidence-audit.json", + "sha256": "09f2a02a6783ff589b05c4221cf3fdb73ed096ad649bdeb9514797224f9420ef", + "bytes": 10509, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "light", + "width": 1280, + "height": 320 + }, + "state": "long-evidence", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 1280, + "height": 320, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 7, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 7 + } + ] + }, + { + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/light 1440px overview and factual evidence preserve canonical source and recent CV links", + "attachment": "p7-career-nb-light-1440-populated-overview-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/026-p7-career-nb-light-1440-populated-overview-audit.json", + "sha256": "b17107c4aa02114c5f96d80b4e195a207b17cce2462cf047226de37c5baf81d6", + "bytes": 6195, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "nb", + "theme": "light", + "width": 1440, + "height": 900 + }, + "state": "populated-overview", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 1440, + "height": 900, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 1, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 1 + } + ] + }, + { + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/light 1440px overview and factual evidence preserve canonical source and recent CV links", + "attachment": "p7-career-nb-light-1440-long-evidence-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/028-p7-career-nb-light-1440-long-evidence-audit.json", + "sha256": "140bdf86a0e3d8d95f4b409da4474b1d27942ea8899c11ee19a2e1601be94415", + "bytes": 15841, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "nb", + "theme": "light", + "width": 1440, + "height": 900 + }, + "state": "long-evidence", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 1440, + "height": 900, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 7, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 7 + } + ] + }, + { + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/dark 1920px overview and factual evidence preserve canonical source and recent CV links", + "attachment": "p7-career-en-dark-1920-populated-overview-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/030-p7-career-en-dark-1920-populated-overview-audit.json", + "sha256": "2a5f1935c4e8ddbd47be73964cb490dc32f3087d7230f7386ba6a7d469045d17", + "bytes": 6040, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "dark", + "width": 1920, + "height": 1080 + }, + "state": "populated-overview", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 1920, + "height": 1080, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 1, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 1 + } + ] + }, + { + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/dark 1920px overview and factual evidence preserve canonical source and recent CV links", + "attachment": "p7-career-en-dark-1920-long-evidence-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/032-p7-career-en-dark-1920-long-evidence-audit.json", + "sha256": "ff66cdef6a1c1427213380396fe09f603bdcdb5478cef1df1dd9dde33bb055e9", + "bytes": 10463, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "dark", + "width": 1920, + "height": 1080 + }, + "state": "long-evidence", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 1920, + "height": 1080, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 7, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 7 + } + ] + }, + { + "test": "[P7-02 PRES-C02 E09] unavailable /career/profile stays unknown and retries its reads without writes or false first-run guidance", + "attachment": "p7-career-en-dark-390-unavailable-profile-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/034-p7-career-en-dark-390-unavailable-profile-audit.json", + "sha256": "416a3fdf25bfe9631a29819d3060060a27811f3fbfb365ca0e6f43697508f663", + "bytes": 5945, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "dark", + "width": 390, + "height": 844 + }, + "state": "unavailable-profile", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 390, + "height": 844, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 2, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 2 + } + ] + }, + { + "test": "[P7-02 PRES-C02 E09] unavailable /profile-cv/runs stays unknown and retries its reads without writes or false first-run guidance", + "attachment": "p7-career-en-dark-390-unavailable-runs-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/036-p7-career-en-dark-390-unavailable-runs-audit.json", + "sha256": "3395ba3449e5cb433bcce98ca25b44da3b82274b72f752130471522eb0f1c4e2", + "bytes": 6109, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "dark", + "width": 390, + "height": 844 + }, + "state": "unavailable-runs", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 390, + "height": 844, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 2, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 2 + } + ] + }, + { + "test": "[P7-02 PRES-C02 E09] unavailable /cv/variants stays unknown and retries its reads without writes or false first-run guidance", + "attachment": "p7-career-en-dark-390-unavailable-variants-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/038-p7-career-en-dark-390-unavailable-variants-audit.json", + "sha256": "bd70a06a950d5a9727cdcc47f38c6523848ff3b20c1c81feb898069920a7235f", + "bytes": 6107, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "dark", + "width": 390, + "height": 844 + }, + "state": "unavailable-variants", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 390, + "height": 844, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 2, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 2 + } + ] + }, + { + "test": "[P7-02 PRES-C04 E09] evidence pending/failure/read retry and failed save preserve drafts across section changes, cancellation and actual deletion", + "attachment": "p7-career-en-light-390-pending-evidence-read-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/040-p7-career-en-light-390-pending-evidence-read-audit.json", + "sha256": "1cf61579d7e4b068a6637706d5c9c10ceee13b4d098768bc4cc6115b289b4b02", + "bytes": 9069, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "light", + "width": 390, + "height": 844 + }, + "state": "pending-evidence-read", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 390, + "height": 844, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 7, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 7 + } + ] + }, + { + "test": "[P7-02 PRES-C04 E09] evidence pending/failure/read retry and failed save preserve drafts across section changes, cancellation and actual deletion", + "attachment": "p7-career-en-light-390-failed-save-retained-draft-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/042-p7-career-en-light-390-failed-save-retained-draft-audit.json", + "sha256": "3c7cdfe93e72fecd2bd2e127bad501f151c44abbe5e005113f93b7270ea01c64", + "bytes": 10008, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "light", + "width": 390, + "height": 844 + }, + "state": "failed-save-retained-draft", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 390, + "height": 844, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 8, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 8 + } + ] + }, + { + "test": "[P7-02 PRES-C04 E09] evidence pending/failure/read retry and failed save preserve drafts across section changes, cancellation and actual deletion", + "attachment": "p7-career-en-light-390-failed-delete-retained-row-audit", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/044-p7-career-en-light-390-failed-delete-retained-row-audit.json", + "sha256": "ac1472ace969c0ff3d8c3890fb77df067a0eda0c151fb8b7a5947e5f3c5bd75d", + "bytes": 10190, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "context": { + "sample": { + "language": "en", + "theme": "light", + "width": 390, + "height": 844 + }, + "state": "failed-delete-retained-row", + "limits": [ + "No human screen reader or physical touch/software keyboard", + "No actual browser zoom or production font/photo qualification", + "Controlled faults are explicit; no model/provider invocation" + ] + }, + "geometry": { + "width": 390, + "height": 844, + "rootOverflow": 0 + }, + "engine": null, + "toolOptions": null, + "violationNodes": 0, + "incompleteNodes": 8, + "byRule": [ + { + "kind": "incomplete", + "id": "color-contrast", + "nodes": 8 + } + ] + } + ], + "qualification": "Finite overlapping regression lane; full vectors/attachments retained unchanged in raw report and extracted JSON. No count addition beyond actual new editor11." + }, + "career-preservation": { + "command": { + "name": "career-preservation", + "command": [ + "rtk", + "proxy", + "node", + "node_modules/@playwright/test/cli.js", + "test", + "e2e/redesign-preservation.spec.ts", + "--grep", + "mobile CV override|legacy workspace preserves frozen", + "--retries=0", + "--reporter=list,json", + "--output=E:\\Storage\\Projects\\Active\\Job tracker\\.artifacts\\phase7\\current\\ui\\career-preservation-results" + ], + "startedUtc": "2026-10-12T11:16:08.068050+00:00", + "finishedUtc": "2026-10-12T11:16:22.811226+00:00", + "exitCode": 0, + "stats": { + "startTime": "2026-10-12T11:16:08.576Z", + "duration": 14198.398, + "expected": 2, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + } + }, + "commandRaw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-preservation-command.json", + "sha256": "39d5935e7dc15133b6841053465000ac24e9d61536041deb0bd82042245cc7bc", + "bytes": 742, + "hashPolicy": "Exact measured raw bytes" + }, + "reportRaw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-preservation.json", + "sha256": "60fe8b85a1b74f92f6d08392d20c2f26d389992f7de3bc8e62cde119adfa8081", + "bytes": 150527, + "hashPolicy": "Exact measured raw bytes" + }, + "logRaw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-preservation.log", + "sha256": "dece08dd3dec03d1fb6dc0b4be939ce876269719347b7cf86bb2413c51cd1a91", + "bytes": 866, + "hashPolicy": "Exact measured raw bytes" + }, + "stats": { + "startTime": "2026-10-12T11:16:08.576Z", + "duration": 14198.398, + "expected": 2, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "cases": [ + { + "title": "[PRES-C01 PRES-C06 PRES-C07 PRES-C10] mobile CV override persists without changing the canonical profile or sibling CV", + "file": "redesign-preservation.spec.ts", + "line": 43, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 3660 + }, + { + "title": "[PRES-W01 PRES-W05 PRES-W06 PRES-W07 PRES-W08] legacy workspace preserves frozen documents after current sources change", + "file": "redesign-preservation.spec.ts", + "line": 73, + "expectedStatus": "passed", + "project": "chromium", + "resultStatuses": [ + "passed" + ], + "retries": [ + 0 + ], + "errors": [ + [] + ], + "durationMs": 3541 + } + ], + "reportErrors": [], + "configuration": { + "version": "1.62.1", + "workers": 1, + "projects": [ + { + "name": "chromium", + "retries": 0 + } + ] + }, + "auditSummaries": [], + "qualification": "Finite overlapping regression lane; full vectors/attachments retained unchanged in raw report and extracted JSON. No count addition beyond actual new editor11." + } + }, + "visuals": [ + { + "lane": "career-editor", + "test": "[P7-03 PRES-C01 C02 E08] structured and raw drafts survive English to Bokmål without canonical refetch or write", + "name": "p7-career-editor-nb-light-1440-locale-retained-raw-draft", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/003-p7-career-editor-nb-light-1440-locale-retained-raw-draft.png", + "sha256": "925e36da5065edf311806a3f5c509c378ee9992b16b4dccc17bba40dd966d625", + "bytes": 121972, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "Actually viewed by parent for final13-image receipt; finite scope only" + }, + { + "lane": "career-editor", + "test": "[P7-03 PRES-C01 C02 E08] held save locks edits and duplicate writes; failed save retains its snapshot for explicit identical-body retry", + "name": "p7-career-editor-en-light-390-held-save", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/006-p7-career-editor-en-light-390-held-save.png", + "sha256": "2a29a5cc760ea8bbd3b7b4b7a7c717c949f8362f458d2bbfa841f11278aeba53", + "bytes": 220599, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "Actually viewed by parent for final13-image receipt; finite scope only" + }, + { + "lane": "career-editor", + "test": "[P7-03 PRES-C01 C02 E08] held save locks edits and duplicate writes; failed save retains its snapshot for explicit identical-body retry", + "name": "p7-career-editor-en-light-390-held-save-raw-import", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/008-p7-career-editor-en-light-390-held-save-raw-import.png", + "sha256": "47255355301994af45380734dc727a4607203a6c1e6cfa1bed7c9f9c4befa29f", + "bytes": 82264, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "Actually viewed by parent for final13-image receipt; finite scope only" + }, + { + "lane": "career-editor", + "test": "[P7-03 PRES-C01 C02 E08] held save locks edits and duplicate writes; failed save retains its snapshot for explicit identical-body retry", + "name": "p7-career-editor-en-light-390-failed-save-retained-draft", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/010-p7-career-editor-en-light-390-failed-save-retained-draft.png", + "sha256": "95504b5367bdb37b06751371823ad15ae4ed0c0cb674e2520b913f6904798bed", + "bytes": 231855, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "Actually viewed by parent for final13-image receipt; finite scope only" + }, + { + "lane": "career-editor", + "test": "[P7-03 PRES-C01 C02 E08] actual validation400 retains draft and source; corrected explicit save persists once", + "name": "p7-career-editor-nb-dark-390-actual-validation400-retained-draft", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/013-p7-career-editor-nb-dark-390-actual-validation400-retained-draft.png", + "sha256": "8670224884756d9395ce42c1d823c0fe4088747e55da5ead2185624e214fe265", + "bytes": 228565, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "Actually viewed by parent for final13-image receipt; finite scope only" + }, + { + "lane": "career-editor", + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry nb/dark/320x844", + "name": "p7-career-editor-nb-dark-320-structured-editor", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/016-p7-career-editor-nb-dark-320-structured-editor.png", + "sha256": "827df127af44ef2ba0c40cf4df49a3fb1ef9e289c7d02bc165c976a68c4e7ef6", + "bytes": 215085, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "Actually viewed by parent for final13-image receipt; finite scope only" + }, + { + "lane": "career-editor", + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry en/light/360x800", + "name": "p7-career-editor-en-light-360-structured-editor", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/018-p7-career-editor-en-light-360-structured-editor.png", + "sha256": "d21e0e5b461765d68af8302f8fe88b573aeb7feff13dc8dba2e90787ff6b389c", + "bytes": 225072, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "Actually viewed by parent for final13-image receipt; finite scope only" + }, + { + "lane": "career-editor", + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry nb/light/390x844", + "name": "p7-career-editor-nb-light-390-structured-editor", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/020-p7-career-editor-nb-light-390-structured-editor.png", + "sha256": "41c89f8f30f775931757612b3e99a7de4b9c8f27571292f09eb1d370b2edcdeb", + "bytes": 228278, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "Actually viewed by parent for final13-image receipt; finite scope only" + }, + { + "lane": "career-editor", + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry en/dark/768x1024", + "name": "p7-career-editor-en-dark-768-structured-editor", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/022-p7-career-editor-en-dark-768-structured-editor.png", + "sha256": "a67010306e33329ccf730f484aa276759ee4ee744bb8686d436750620f13af26", + "bytes": 255964, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "Actually viewed by parent for final13-image receipt; finite scope only" + }, + { + "lane": "career-editor", + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry nb/dark/1024x768", + "name": "p7-career-editor-nb-dark-1024-structured-editor", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/024-p7-career-editor-nb-dark-1024-structured-editor.png", + "sha256": "a07dd51c5539af697b14bddafc294b132ad2895aa658be3d96473c4b75c3a20f", + "bytes": 260065, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "Actually viewed by parent for final13-image receipt; finite scope only" + }, + { + "lane": "career-editor", + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry en/light/1280x320", + "name": "p7-career-editor-en-light-1280-structured-editor", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/026-p7-career-editor-en-light-1280-structured-editor.png", + "sha256": "d721ca58d8d9e6ad337049e2e5127f4f18f69e3f98f876c7a5852dd2a5049236", + "bytes": 254685, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "Actually viewed by parent for final13-image receipt; finite scope only" + }, + { + "lane": "career-editor", + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry nb/light/1440x900", + "name": "p7-career-editor-nb-light-1440-structured-editor", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/028-p7-career-editor-nb-light-1440-structured-editor.png", + "sha256": "5bd50302507c454b271940d3c2b3d251403c2d81597106aa0d291458978a2b86", + "bytes": 276145, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "Actually viewed by parent for final13-image receipt; finite scope only" + }, + { + "lane": "career-editor", + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry en/dark/1920x1080", + "name": "p7-career-editor-en-dark-1920-structured-editor", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/030-p7-career-editor-en-dark-1920-structured-editor.png", + "sha256": "1322478133a66f072744c7b816ada0bb445a599a76972bb15a24603a544a1964", + "bytes": 281794, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-editor.json", + "sha256": "700f0f8870435d4a385373c5027cf1ab2323bf1c26105f5fe55d9b6d16f3ccfd", + "bytes": 4564438, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "Actually viewed by parent for final13-image receipt; finite scope only" + }, + { + "lane": "career-source-ids", + "test": "[P7-03 PRES-C01 C03 C06 C07 C10 W05 W06] unrelated canonical UI save preserves four source IDs, existing CV overrides, sibling and frozen package", + "name": "native-career-source-id-editor", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-source-ids/002-native-career-source-id-editor.png", + "sha256": "8b05a83fba9bec19a8da6cd3f82a4e498f6213c03a426072fd1a807029c5fbd5", + "bytes": 201253, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-source-ids.json", + "sha256": "fefd50362c7053b707ba1ade4569bb7d5ee638be4ebfa6529285f402b2841e25", + "bytes": 404902, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/dark 320px overview and factual evidence preserve canonical source and recent CV links", + "name": "p7-career-nb-dark-320-populated-overview", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/003-p7-career-nb-dark-320-populated-overview.png", + "sha256": "a5e2a497ad77f8a1e0b6437c59b8e1b7247c19c84534203de59476f5de76dcfe", + "bytes": 85586, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/dark 320px overview and factual evidence preserve canonical source and recent CV links", + "name": "p7-career-nb-dark-320-long-evidence", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/005-p7-career-nb-dark-320-long-evidence.png", + "sha256": "bd9f56b40d881e6c1733cd54d0115927b29be340bd55b4cb3434231d517cd61b", + "bytes": 79268, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/light 360px overview and factual evidence preserve canonical source and recent CV links", + "name": "p7-career-en-light-360-populated-overview", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/007-p7-career-en-light-360-populated-overview.png", + "sha256": "78a15394efe0b58fea2494f70b939a379845661c96b6eebedb5a42dc8e64bd3b", + "bytes": 83980, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/light 360px overview and factual evidence preserve canonical source and recent CV links", + "name": "p7-career-en-light-360-long-evidence", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/009-p7-career-en-light-360-long-evidence.png", + "sha256": "203ded6fe42434459875d165a3ff42f5405a962e9972a4b44f11189167a647ca", + "bytes": 69976, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/light 390px overview and factual evidence preserve canonical source and recent CV links", + "name": "p7-career-nb-light-390-populated-overview", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/011-p7-career-nb-light-390-populated-overview.png", + "sha256": "4f82ab83b185fa48d3538a55a9b10c3c6223799c3c984801d969547bf076fe44", + "bytes": 85950, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/light 390px overview and factual evidence preserve canonical source and recent CV links", + "name": "p7-career-nb-light-390-long-evidence", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/013-p7-career-nb-light-390-long-evidence.png", + "sha256": "cbcbccbfaa042e3e5100d04bd154e8ca23d0ba6e6ff95d5578db36193ed433d8", + "bytes": 70584, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/dark 768px overview and factual evidence preserve canonical source and recent CV links", + "name": "p7-career-en-dark-768-populated-overview", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/015-p7-career-en-dark-768-populated-overview.png", + "sha256": "03e5d7bc1ff0aaf39d962311b768fc4eccf2521365e64f6fcb6cbea816db0272", + "bytes": 94090, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/dark 768px overview and factual evidence preserve canonical source and recent CV links", + "name": "p7-career-en-dark-768-long-evidence", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/017-p7-career-en-dark-768-long-evidence.png", + "sha256": "65417e33920f9b068817467086f432e0af952c5c3e6f7369216e41c9faa101d2", + "bytes": 83520, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/dark 1024px overview and factual evidence preserve canonical source and recent CV links", + "name": "p7-career-nb-dark-1024-populated-overview", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/019-p7-career-nb-dark-1024-populated-overview.png", + "sha256": "cb24d25efa36f82f35e977ff712b71cdaa0a51cc443ec9024c160c91eeddf076", + "bytes": 119337, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/dark 1024px overview and factual evidence preserve canonical source and recent CV links", + "name": "p7-career-nb-dark-1024-long-evidence", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/021-p7-career-nb-dark-1024-long-evidence.png", + "sha256": "aad9445b73a3b9ae50bd0fede197cb1bf3eb21659674e54c8af36921236ae0ae", + "bytes": 110598, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/light 1280px overview and factual evidence preserve canonical source and recent CV links", + "name": "p7-career-en-light-1280-populated-overview", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/023-p7-career-en-light-1280-populated-overview.png", + "sha256": "309c88a3c7552f7c94e72b343f70d7c9c3aeaa8eb00f209ea425783b7ed133d9", + "bytes": 102454, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/light 1280px overview and factual evidence preserve canonical source and recent CV links", + "name": "p7-career-en-light-1280-long-evidence", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/025-p7-career-en-light-1280-long-evidence.png", + "sha256": "ece0a990576e3efd9d38235863c309c71e82bb211f83b18593223d88b9970c15", + "bytes": 95996, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/light 1440px overview and factual evidence preserve canonical source and recent CV links", + "name": "p7-career-nb-light-1440-populated-overview", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/027-p7-career-nb-light-1440-populated-overview.png", + "sha256": "1f956860c78a148735943232c84a79a911fa61c744611ab5b70be876e01ca3ca", + "bytes": 116219, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] nb/light 1440px overview and factual evidence preserve canonical source and recent CV links", + "name": "p7-career-nb-light-1440-long-evidence", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/029-p7-career-nb-light-1440-long-evidence.png", + "sha256": "04caa483538045200e1f2e3299c50c578329c31f1c13485dabb286b2c6615caa", + "bytes": 246987, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/dark 1920px overview and factual evidence preserve canonical source and recent CV links", + "name": "p7-career-en-dark-1920-populated-overview", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/031-p7-career-en-dark-1920-populated-overview.png", + "sha256": "20102e413578e1356cb142dec729708fa663125d1053ed8f5b558da92582357f", + "bytes": 120994, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C01 C02 C04 C05 E08 E09] en/dark 1920px overview and factual evidence preserve canonical source and recent CV links", + "name": "p7-career-en-dark-1920-long-evidence", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/033-p7-career-en-dark-1920-long-evidence.png", + "sha256": "39634c7db0ce3e0fcfb8093fc0e847c400303a402e452884aa6908581aa472ae", + "bytes": 114428, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C02 E09] unavailable /career/profile stays unknown and retries its reads without writes or false first-run guidance", + "name": "p7-career-en-dark-390-unavailable-profile", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/035-p7-career-en-dark-390-unavailable-profile.png", + "sha256": "6ecbb6649f057a102474611b4ecdc24ff64059296d350ae74692346fb451a0cf", + "bytes": 73179, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C02 E09] unavailable /profile-cv/runs stays unknown and retries its reads without writes or false first-run guidance", + "name": "p7-career-en-dark-390-unavailable-runs", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/037-p7-career-en-dark-390-unavailable-runs.png", + "sha256": "7ecdc9566b816fdf4eb2dbc51f602f32e84f3b6e53d398f6ab19f9900a55770b", + "bytes": 73572, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C02 E09] unavailable /cv/variants stays unknown and retries its reads without writes or false first-run guidance", + "name": "p7-career-en-dark-390-unavailable-variants", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/039-p7-career-en-dark-390-unavailable-variants.png", + "sha256": "8c77ff1f4b95e77fdbc9e2ca8e1f1cf3d331b5ec2e026d21aba68821238f8eb9", + "bytes": 74948, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C04 E09] evidence pending/failure/read retry and failed save preserve drafts across section changes, cancellation and actual deletion", + "name": "p7-career-en-light-390-pending-evidence-read", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/041-p7-career-en-light-390-pending-evidence-read.png", + "sha256": "a1c3e56d179197d1dd68c78069abd34f64c61527cf368f09124678a69d3c23f1", + "bytes": 46260, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C04 E09] evidence pending/failure/read retry and failed save preserve drafts across section changes, cancellation and actual deletion", + "name": "p7-career-en-light-390-failed-save-retained-draft", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/043-p7-career-en-light-390-failed-save-retained-draft.png", + "sha256": "9c2e095ebc44aeb595fbace39bc0f83994bad3548ed06910255ef7d1ed806153", + "bytes": 50068, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career", + "test": "[P7-02 PRES-C04 E09] evidence pending/failure/read retry and failed save preserve drafts across section changes, cancellation and actual deletion", + "name": "p7-career-en-light-390-failed-delete-retained-row", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career/045-p7-career-en-light-390-failed-delete-retained-row.png", + "sha256": "e622150cc8ac5e8b3638bf04d409747ecb64fb01255e362789fe19b5803e12e1", + "bytes": 52574, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career.json", + "sha256": "8579d222f707db71758f90b15f3e4a06d78969f3ea1f5f57d8cb87560d2c0fc0", + "bytes": 3018591, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + }, + { + "lane": "career-preservation", + "test": "[PRES-W01 PRES-W05 PRES-W06 PRES-W07 PRES-W08] legacy workspace preserves frozen documents after current sources change", + "name": "native-frozen-package", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-preservation/001-native-frozen-package.png", + "sha256": "77ae45ed53404de5565bdd911345ce3ce07f9656e2ab32ccd7bfedfa27f96025", + "bytes": 108870, + "hashPolicy": "Exact saved raw bytes" + }, + "originalEmbeddedReport": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/career-preservation.json", + "sha256": "60fe8b85a1b74f92f6d08392d20c2f26d389992f7de3bc8e62cde119adfa8081", + "bytes": 150527, + "hashPolicy": "Exact measured raw bytes" + }, + "manualReview": "PENDING_PARENT_EXACT_IMAGE_RECEIPT" + } + ], + "accessibility": { + "byLane": { + "career-editor": { + "scans": 13, + "violationNodes": 0, + "incompleteNodes": 377 + }, + "career-source-ids": { + "scans": 0, + "violationNodes": 0, + "incompleteNodes": 0 + }, + "career": { + "scans": 22, + "violationNodes": 0, + "incompleteNodes": 99 + }, + "career-preservation": { + "scans": 0, + "violationNodes": 0, + "incompleteNodes": 0 + } + }, + "ruleOccurrences": [ + { + "lane": "career-editor", + "kind": "incomplete", + "rule": "color-contrast", + "nodes": 376 + }, + { + "lane": "career-editor", + "kind": "incomplete", + "rule": "aria-hidden-focus", + "nodes": 1 + }, + { + "lane": "career", + "kind": "incomplete", + "rule": "color-contrast", + "nodes": 96 + }, + { + "lane": "career", + "kind": "incomplete", + "rule": "aria-hidden-focus", + "nodes": 3 + } + ], + "checkContexts": [ + { + "lane": "career-editor", + "kind": "incomplete", + "rule": "color-contrast", + "id": "color-contrast", + "message": "Element's background color could not be determined because it is overlapped by another element", + "occurrences": 362, + "representativeContexts": [ + { + "attachment": "p7-career-editor-nb-light-1440-locale-retained-raw-draft-audit", + "target": [ + ".MuiButtonGroup-firstButton" + ], + "checkData": { + "contrastRatio": 0, + "fontSize": "9.8pt (13px)", + "fontWeight": "bold", + "messageKey": "bgOverlap", + "expectedContrastRatio": "4.5:1" + }, + "relatedNodes": [] + }, + { + "attachment": "p7-career-editor-nb-light-1440-locale-retained-raw-draft-audit", + "target": [ + ".MuiButton-containedSizeSmall" + ], + "checkData": { + "contrastRatio": 0, + "fontSize": "9.8pt (13px)", + "fontWeight": "bold", + "messageKey": "bgOverlap", + "expectedContrastRatio": "4.5:1" + }, + "relatedNodes": [] + } + ] + }, + { + "lane": "career-editor", + "kind": "incomplete", + "rule": "color-contrast", + "id": "color-contrast", + "message": "Element content is too short to determine if it is actual text content", + "occurrences": 13, + "representativeContexts": [ + { + "attachment": "p7-career-editor-nb-light-1440-locale-retained-raw-draft-audit", + "target": [ + ".MuiBadge-badge" + ], + "checkData": { + "contrastRatio": 0, + "fontSize": "9.0pt (12px)", + "fontWeight": "normal", + "messageKey": "shortTextContent", + "expectedContrastRatio": "4.5:1" + }, + "relatedNodes": [] + }, + { + "attachment": "p7-career-editor-en-light-390-held-save-audit", + "target": [ + ".MuiBadge-badge" + ], + "checkData": { + "contrastRatio": 0, + "fontSize": "9.0pt (12px)", + "fontWeight": "normal", + "messageKey": "shortTextContent", + "expectedContrastRatio": "4.5:1" + }, + "relatedNodes": [] + } + ] + }, + { + "lane": "career-editor", + "kind": "incomplete", + "rule": "aria-hidden-focus", + "id": "focusable-modal-open", + "message": "Check that focusable elements are not tabbable in the current state", + "occurrences": 1, + "representativeContexts": [ + { + "attachment": "p7-career-editor-en-light-390-held-save-raw-import-audit", + "target": [ + "#menu-" + ], + "checkData": null, + "relatedNodes": [ + { + "html": "
  • ", + "target": [ + "li[data-value=\"import\"]" + ] + } + ] + } + ] + }, + { + "lane": "career-editor", + "kind": "incomplete", + "rule": "color-contrast", + "id": "color-contrast", + "message": "Element's background color could not be determined because it partially overlaps other elements", + "occurrences": 1, + "representativeContexts": [ + { + "attachment": "p7-career-editor-nb-dark-390-actual-validation400-retained-draft-audit", + "target": [ + ".MuiAlert-filledError > .MuiAlert-message.css-127h8j3" + ], + "checkData": { + "contrastRatio": 0, + "fontSize": "10.5pt (14px)", + "fontWeight": "normal", + "messageKey": "elmPartiallyObscuring", + "expectedContrastRatio": "4.5:1" + }, + "relatedNodes": [] + } + ] + }, + { + "lane": "career", + "kind": "incomplete", + "rule": "color-contrast", + "id": "color-contrast", + "message": "Element content is too short to determine if it is actual text content", + "occurrences": 22, + "representativeContexts": [ + { + "attachment": "p7-career-nb-dark-320-populated-overview-audit", + "target": [ + ".MuiBadge-badge" + ], + "checkData": { + "contrastRatio": 0, + "fontSize": "9.0pt (12px)", + "fontWeight": "normal", + "messageKey": "shortTextContent", + "expectedContrastRatio": "4.5:1" + }, + "relatedNodes": [] + }, + { + "attachment": "p7-career-nb-dark-320-long-evidence-audit", + "target": [ + ".MuiBadge-badge" + ], + "checkData": { + "contrastRatio": 0, + "fontSize": "9.0pt (12px)", + "fontWeight": "normal", + "messageKey": "shortTextContent", + "expectedContrastRatio": "4.5:1" + }, + "relatedNodes": [] + } + ] + }, + { + "lane": "career", + "kind": "incomplete", + "rule": "color-contrast", + "id": "color-contrast", + "message": "Element's background color could not be determined because it is overlapped by another element", + "occurrences": 74, + "representativeContexts": [ + { + "attachment": "p7-career-nb-dark-320-populated-overview-audit", + "target": [ + ".MuiSelect-select" + ], + "checkData": { + "contrastRatio": 0, + "fontSize": "10.5pt (14px)", + "fontWeight": "normal", + "messageKey": "bgOverlap", + "expectedContrastRatio": "4.5:1" + }, + "relatedNodes": [] + }, + { + "attachment": "p7-career-nb-dark-320-long-evidence-audit", + "target": [ + ".css-1f6076n > .MuiSelect-select.MuiSelect-outlined.css-1ehla7j" + ], + "checkData": { + "contrastRatio": 0, + "fontSize": "10.5pt (14px)", + "fontWeight": "normal", + "messageKey": "bgOverlap", + "expectedContrastRatio": "4.5:1" + }, + "relatedNodes": [] + } + ] + }, + { + "lane": "career", + "kind": "incomplete", + "rule": "aria-hidden-focus", + "id": "focusable-modal-open", + "message": "Check that focusable elements are not tabbable in the current state", + "occurrences": 3, + "representativeContexts": [ + { + "attachment": "p7-career-nb-dark-320-long-evidence-audit", + "target": [ + "#menu-" + ], + "checkData": null, + "relatedNodes": [ + { + "html": "
  • ", + "target": [ + "li[data-value=\"evidence\"]" + ] + } + ] + }, + { + "attachment": "p7-career-en-light-360-long-evidence-audit", + "target": [ + "#menu-" + ], + "checkData": null, + "relatedNodes": [ + { + "html": "
  • ", + "target": [ + "li[data-value=\"evidence\"]" + ] + } + ] + } + ] + } + ], + "triage": "Editor13all-enabled scans retain0violations/377incompletes:362background overlap,13short-text invisible badges,1partially obscured dark validation alert and1hidden MUI import-selection portal focus. M11 contextualcontrast/forcedcolors/motion and M09 reader/hiddenportalkeyboard qualification remain open; portal check asks whether hiddenfocusable element is currently tabbable, no new source cause established. Separate Career22regression scans retain0violations/99incompletes(74overlap22badge3hiddenportal). SourceID/preservation0scans; no combined conformance or like-for-like earlier comparison." + }, + "historicalCapsules": [ + { + "path": ".artifacts/phase7/p7-03/editor/baseline/native-first/baseline-results.json", + "sha256": "2f369a739c9241b0aa6e823a52fb454e9b35e8506ccecdc3cc664edc8afe3104", + "bytes": 766463, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/baseline/native-narrow/diagnostic-results.json", + "sha256": "7ea08bda9bc1f64b4e10ebdbe3aadbf329703c84d7e9d639a93b93cea526c9d5", + "bytes": 96396, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/attempt1-20261012T104838Z/attempt-results.json", + "sha256": "4caafc3749b0d20f4aa3f6f92311c0745a024e2e83fa9e8bee051bf25af328b6", + "bytes": 723957, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/attempt2-20261012T105446Z/attempt-results.json", + "sha256": "03f504f04b0d03a2636918ffe1b5e0af67b462a994f19a74cf0f0b0255f8dfc9", + "bytes": 242474, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/attempt3-20261012T110336Z/attempt-results.json", + "sha256": "663023740b3386959e5593eb4f062caf7053882c1f5a15811f5b05abd160e820", + "bytes": 239292, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/review-red-20261012T105914Z/review-results.json", + "sha256": "1b38715672c673aa65afa72b1396f3d66c8747931e1186d3965cad4170594b24", + "bytes": 657081, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/raw-held-diagnostic-20261012T110509Z/diagnostic-results.json", + "sha256": "fbad9c2ca693d849af9dc4deb2423b5050b72b3354f7872e3b6e99cf5e869a85", + "bytes": 100853, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/raw-coverage-attempt-20261012T111053Z/coverage-results.json", + "sha256": "6ad1c3059da8cf02aee9edd532e799d45ca57c0d2c85edb47aac59c037190153", + "bytes": 689579, + "hashPolicy": "Exact saved raw bytes" + }, + { + "path": ".artifacts/phase7/p7-03/editor/raw-expanded-red-20261012T111149Z/coverage-results.json", + "sha256": "4e5f0cc94bae87ea4941212e34c2520e690d49946529863566021e7b0e8c1eab", + "bytes": 47469, + "hashPolicy": "Exact saved raw bytes" + } + ], + "countDisposition": { + "freshAffected": "54/4,0failed/pending/todo", + "newEditorCases": 8, + "newUnitSuite": 1, + "newOrdinaryNativeCases": 11, + "frontend626/91": "DERIVED_ONLY,latest full573/89 inherited", + "ordinaryBrowser227": "DERIVED_ONLY;29 focused cases overlap existing packs", + "backend1034": "DERIVED_ONLY;latest full1033/sidecar49 inherited", + "rendering": "Original16/36+settings8/24 unchanged inherited; no output owner change" + }, + "preservation": { + "groups": 57, + "partial": 56, + "deferred": 1, + "routes": 32 + }, + "limitations": [ + "All manual reader/device/zoom/provider/output qualifications remain open", + "No new density control outside Jobs, no public density claim", + "Original DwxCC export overwritten before archive; exact historical source/commands/report retained, no reconstruction", + "Actual stale200/last-writer characterization remains; no concurrency repair", + "Import/history second presentation boundary PENDING", + "Main27657f31131cd95d42f0e1290853ec9c9b3959a4 unchanged;productionNO-GO;P5-13 deferred;Phase8 separate" + ], + "parentVisualReview": { + "receiptSource": "Parent actual view_image receipt2026-10-12 for final11:16:54 run", + "status": "ACTUAL13_OF13_EDITOR_PNGS_VIEWED", + "images": [ + { + "test": "[P7-03 PRES-C01 C02 E08] structured and raw drafts survive English to Bokmål without canonical refetch or write", + "name": "p7-career-editor-nb-light-1440-locale-retained-raw-draft", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/003-p7-career-editor-nb-light-1440-locale-retained-raw-draft.png", + "sha256": "925e36da5065edf311806a3f5c509c378ee9992b16b4dccc17bba40dd966d625", + "bytes": 121972, + "hashPolicy": "Exact saved raw bytes" + } + }, + { + "test": "[P7-03 PRES-C01 C02 E08] held save locks edits and duplicate writes; failed save retains its snapshot for explicit identical-body retry", + "name": "p7-career-editor-en-light-390-held-save", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/006-p7-career-editor-en-light-390-held-save.png", + "sha256": "2a29a5cc760ea8bbd3b7b4b7a7c717c949f8362f458d2bbfa841f11278aeba53", + "bytes": 220599, + "hashPolicy": "Exact saved raw bytes" + } + }, + { + "test": "[P7-03 PRES-C01 C02 E08] held save locks edits and duplicate writes; failed save retains its snapshot for explicit identical-body retry", + "name": "p7-career-editor-en-light-390-held-save-raw-import", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/008-p7-career-editor-en-light-390-held-save-raw-import.png", + "sha256": "47255355301994af45380734dc727a4607203a6c1e6cfa1bed7c9f9c4befa29f", + "bytes": 82264, + "hashPolicy": "Exact saved raw bytes" + } + }, + { + "test": "[P7-03 PRES-C01 C02 E08] held save locks edits and duplicate writes; failed save retains its snapshot for explicit identical-body retry", + "name": "p7-career-editor-en-light-390-failed-save-retained-draft", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/010-p7-career-editor-en-light-390-failed-save-retained-draft.png", + "sha256": "95504b5367bdb37b06751371823ad15ae4ed0c0cb674e2520b913f6904798bed", + "bytes": 231855, + "hashPolicy": "Exact saved raw bytes" + } + }, + { + "test": "[P7-03 PRES-C01 C02 E08] actual validation400 retains draft and source; corrected explicit save persists once", + "name": "p7-career-editor-nb-dark-390-actual-validation400-retained-draft", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/013-p7-career-editor-nb-dark-390-actual-validation400-retained-draft.png", + "sha256": "8670224884756d9395ce42c1d823c0fe4088747e55da5ead2185624e214fe265", + "bytes": 228565, + "hashPolicy": "Exact saved raw bytes" + } + }, + { + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry nb/dark/320x844", + "name": "p7-career-editor-nb-dark-320-structured-editor", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/016-p7-career-editor-nb-dark-320-structured-editor.png", + "sha256": "827df127af44ef2ba0c40cf4df49a3fb1ef9e289c7d02bc165c976a68c4e7ef6", + "bytes": 215085, + "hashPolicy": "Exact saved raw bytes" + } + }, + { + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry en/light/360x800", + "name": "p7-career-editor-en-light-360-structured-editor", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/018-p7-career-editor-en-light-360-structured-editor.png", + "sha256": "d21e0e5b461765d68af8302f8fe88b573aeb7feff13dc8dba2e90787ff6b389c", + "bytes": 225072, + "hashPolicy": "Exact saved raw bytes" + } + }, + { + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry nb/light/390x844", + "name": "p7-career-editor-nb-light-390-structured-editor", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/020-p7-career-editor-nb-light-390-structured-editor.png", + "sha256": "41c89f8f30f775931757612b3e99a7de4b9c8f27571292f09eb1d370b2edcdeb", + "bytes": 228278, + "hashPolicy": "Exact saved raw bytes" + } + }, + { + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry en/dark/768x1024", + "name": "p7-career-editor-en-dark-768-structured-editor", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/022-p7-career-editor-en-dark-768-structured-editor.png", + "sha256": "a67010306e33329ccf730f484aa276759ee4ee744bb8686d436750620f13af26", + "bytes": 255964, + "hashPolicy": "Exact saved raw bytes" + } + }, + { + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry nb/dark/1024x768", + "name": "p7-career-editor-nb-dark-1024-structured-editor", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/024-p7-career-editor-nb-dark-1024-structured-editor.png", + "sha256": "a07dd51c5539af697b14bddafc294b132ad2895aa658be3d96473c4b75c3a20f", + "bytes": 260065, + "hashPolicy": "Exact saved raw bytes" + } + }, + { + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry en/light/1280x320", + "name": "p7-career-editor-en-light-1280-structured-editor", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/026-p7-career-editor-en-light-1280-structured-editor.png", + "sha256": "d721ca58d8d9e6ad337049e2e5127f4f18f69e3f98f876c7a5852dd2a5049236", + "bytes": 254685, + "hashPolicy": "Exact saved raw bytes" + } + }, + { + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry nb/light/1440x900", + "name": "p7-career-editor-nb-light-1440-structured-editor", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/028-p7-career-editor-nb-light-1440-structured-editor.png", + "sha256": "5bd50302507c454b271940d3c2b3d251403c2d81597106aa0d291458978a2b86", + "bytes": 276145, + "hashPolicy": "Exact saved raw bytes" + } + }, + { + "test": "[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry en/dark/1920x1080", + "name": "p7-career-editor-en-dark-1920-structured-editor", + "raw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/embedded/career-editor/030-p7-career-editor-en-dark-1920-structured-editor.png", + "sha256": "1322478133a66f072744c7b816ada0bb445a599a76972bb15a24603a544a1964", + "bytes": 281794, + "hashPolicy": "Exact saved raw bytes" + } + } + ], + "observations": "Expanded raw held390 capture visibly contains disabled textarea/readable helper and expected nonempty import inventory. Locale1440 retains exact dirty raw draft. Finite matrix fits with clear hierarchy; held/failure/400 states show localised headings/draft locks. Deep-scroll/full-page stickyheader, visible skip-link and toast overlay retain capture-context/focus qualifications. Long image renderer resizing is not full-resolution human device qualification.", + "limitations": "No human screen reader, physical touch/software keyboard, browser zoom, density matrix, real provider/font/photo or production qualification. Raw-import legacy presentation remains nextslice.", + "receiptRaw": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/manual-review.json", + "sha256": "f565d0b5e39b0d267622fb15495f5ce751b1307424f8d6be42e2f9e70254681a", + "bytes": 7805, + "hashPolicy": "Exact saved raw bytes" + } + }, + "staticGate": { + "status": "PASS", + "checkedUtc": "2026-10-12T11:30:04.864682+00:00", + "portableEvidence": { + "path": "docs/redesign/phase-7/p7-03/evidence/editor-static-checks.json", + "sha256": "18cb0a46e035d6af96b1489509aab0f5979db2a81b635df164bb9759a33b23c5", + "bytes": 3166, + "hashPolicy": "UTF-8 text CRLF normalized to LF" + }, + "immutableRecord": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/static/20261012T113001Z/editor-static-checks.json", + "sha256": "18cb0a46e035d6af96b1489509aab0f5979db2a81b635df164bb9759a33b23c5", + "bytes": 3166, + "hashPolicy": "Exact saved raw bytes" + }, + "commands": [ + { + "name": "secret-scan", + "command": [ + "rtk", + "proxy", + "C:\\Users\\Connor\\AppData\\Local\\Programs\\Python\\Python312\\python.exe", + "-X", + "utf8", + "scripts/supply-chain.py", + "scan-secrets" + ], + "startedUtc": "2026-10-12T11:30:01.781304+00:00", + "finishedUtc": "2026-10-12T11:30:04.235080+00:00", + "exitCode": 0, + "log": ".artifacts/phase7/current/static/20261012T113001Z/secret-scan.log", + "logSha256Raw": "c5a88d5ebdc042adba125c1eaacbe44f9f4a5c19898c0f195573c00d511aa28d", + "retainedLog": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/static/20261012T113001Z/secret-scan.log", + "sha256": "c5a88d5ebdc042adba125c1eaacbe44f9f4a5c19898c0f195573c00d511aa28d", + "bytes": 153, + "hashPolicy": "Exact saved raw bytes" + } + }, + { + "name": "working-whitespace", + "command": [ + "rtk", + "proxy", + "git", + "diff", + "--check" + ], + "startedUtc": "2026-10-12T11:30:04.235080+00:00", + "finishedUtc": "2026-10-12T11:30:04.323058+00:00", + "exitCode": 0, + "log": ".artifacts/phase7/current/static/20261012T113001Z/working-whitespace.log", + "logSha256Raw": "d2993bc68ad9a63f711c8f5473155e2ba00fdcd461220cc3849185f2f9ad93e6", + "retainedLog": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/static/20261012T113001Z/working-whitespace.log", + "sha256": "d2993bc68ad9a63f711c8f5473155e2ba00fdcd461220cc3849185f2f9ad93e6", + "bytes": 78, + "hashPolicy": "Exact saved raw bytes" + } + }, + { + "name": "staged-whitespace", + "command": [ + "rtk", + "proxy", + "git", + "diff", + "--cached", + "--check" + ], + "startedUtc": "2026-10-12T11:30:04.323058+00:00", + "finishedUtc": "2026-10-12T11:30:04.415537+00:00", + "exitCode": 0, + "log": ".artifacts/phase7/current/static/20261012T113001Z/staged-whitespace.log", + "logSha256Raw": "d2993bc68ad9a63f711c8f5473155e2ba00fdcd461220cc3849185f2f9ad93e6", + "retainedLog": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/static/20261012T113001Z/staged-whitespace.log", + "sha256": "d2993bc68ad9a63f711c8f5473155e2ba00fdcd461220cc3849185f2f9ad93e6", + "bytes": 78, + "hashPolicy": "Exact saved raw bytes" + } + }, + { + "name": "phase7-whitespace", + "command": [ + "rtk", + "proxy", + "git", + "diff", + "--check", + "b5319981ad3d1bd635daff861453d23c0de5320b" + ], + "startedUtc": "2026-10-12T11:30:04.416038+00:00", + "finishedUtc": "2026-10-12T11:30:04.543148+00:00", + "exitCode": 0, + "log": ".artifacts/phase7/current/static/20261012T113001Z/phase7-whitespace.log", + "logSha256Raw": "d2993bc68ad9a63f711c8f5473155e2ba00fdcd461220cc3849185f2f9ad93e6", + "retainedLog": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/static/20261012T113001Z/phase7-whitespace.log", + "sha256": "d2993bc68ad9a63f711c8f5473155e2ba00fdcd461220cc3849185f2f9ad93e6", + "bytes": 78, + "hashPolicy": "Exact saved raw bytes" + } + } + ], + "documentation": { + "files": 10, + "relativeLinks": 384, + "errors": [] + }, + "preservation": { + "groups": 57, + "statuses": { + "PARTIAL": 56, + "PASS": 0, + "FAIL": 0, + "DEFERRED": 1 + }, + "originalRoutesPreserved": true, + "currentConcreteRoutes": 32 + }, + "production": { + "main": "27657f31131cd95d42f0e1290853ec9c9b3959a4", + "originMain": "27657f31131cd95d42f0e1290853ec9c9b3959a4", + "status": "NO-GO", + "qualification": "Local fetched refs; direct push observation recorded separately." + }, + "qualification": "Actual staged observation; no new runtime/manual/production acceptance. Normal commit/push remains pending." + }, + "pushReceipt": { + "status": "PENDING_ACTUAL_NORMAL_COMMIT_PUSH" + }, + "rawRetention": { + "root": ".artifacts/phase7/p7-03/editor/final-expanded", + "pathRelocation": { + "originalPrefix": ".artifacts/phase7/p7-03/editor/final/", + "retainedPrefix": ".artifacts/phase7/p7-03/editor/final-expanded/", + "originalMetadata": { + "path": ".artifacts/phase7/p7-03/editor/final-expanded/pre-relocation-portable.json", + "sha256": "636106750e0e7c86c458ac6c670a80777cab7069e0c0e1ec563da0f9d654ab3f", + "bytes": 238447, + "hashPolicy": "Exact saved raw bytes" + }, + "qualification": "Only metadata reference paths moved. Every measured report/log/trace/image/source/export byte unchanged. Earlier0UBD12-state whole capsule is separately archived as attempt3 with consistent rebased references and original metadata bytes." + } + }, + "nativeOracleQualification": "Final editor11 rerun after test-only disclosure/scroll/viewport ratio0.5/nonempty both-area field inventory guards. App source/build/unit unchanged. Latest browserTSC11:16:54–58 covers finalnativeoracle; other18 actualregressions remain applicable on sameW4export.", + "wholeP703": "IN_PROGRESS;separateimport/history presentation pending" +} diff --git a/docs/redesign/phase-7/p7-03/evidence/editor-static-checks.json b/docs/redesign/phase-7/p7-03/evidence/editor-static-checks.json new file mode 100644 index 0000000..d0ee9db --- /dev/null +++ b/docs/redesign/phase-7/p7-03/evidence/editor-static-checks.json @@ -0,0 +1,104 @@ +{ + "schemaVersion": 1, + "checkpoint": "p7-03", + "status": "PASS", + "checkedUtc": "2026-10-12T11:30:04.864682+00:00", + "commands": [ + { + "name": "secret-scan", + "command": [ + "rtk", + "proxy", + "C:\\Users\\Connor\\AppData\\Local\\Programs\\Python\\Python312\\python.exe", + "-X", + "utf8", + "scripts/supply-chain.py", + "scan-secrets" + ], + "startedUtc": "2026-10-12T11:30:01.781304+00:00", + "finishedUtc": "2026-10-12T11:30:04.235080+00:00", + "exitCode": 0, + "log": ".artifacts/phase7/current/static/20261012T113001Z/secret-scan.log", + "logSha256Raw": "c5a88d5ebdc042adba125c1eaacbe44f9f4a5c19898c0f195573c00d511aa28d" + }, + { + "name": "working-whitespace", + "command": [ + "rtk", + "proxy", + "git", + "diff", + "--check" + ], + "startedUtc": "2026-10-12T11:30:04.235080+00:00", + "finishedUtc": "2026-10-12T11:30:04.323058+00:00", + "exitCode": 0, + "log": ".artifacts/phase7/current/static/20261012T113001Z/working-whitespace.log", + "logSha256Raw": "d2993bc68ad9a63f711c8f5473155e2ba00fdcd461220cc3849185f2f9ad93e6" + }, + { + "name": "staged-whitespace", + "command": [ + "rtk", + "proxy", + "git", + "diff", + "--cached", + "--check" + ], + "startedUtc": "2026-10-12T11:30:04.323058+00:00", + "finishedUtc": "2026-10-12T11:30:04.415537+00:00", + "exitCode": 0, + "log": ".artifacts/phase7/current/static/20261012T113001Z/staged-whitespace.log", + "logSha256Raw": "d2993bc68ad9a63f711c8f5473155e2ba00fdcd461220cc3849185f2f9ad93e6" + }, + { + "name": "phase7-whitespace", + "command": [ + "rtk", + "proxy", + "git", + "diff", + "--check", + "b5319981ad3d1bd635daff861453d23c0de5320b" + ], + "startedUtc": "2026-10-12T11:30:04.416038+00:00", + "finishedUtc": "2026-10-12T11:30:04.543148+00:00", + "exitCode": 0, + "log": ".artifacts/phase7/current/static/20261012T113001Z/phase7-whitespace.log", + "logSha256Raw": "d2993bc68ad9a63f711c8f5473155e2ba00fdcd461220cc3849185f2f9ad93e6" + } + ], + "untrackedSecretScan": { + "files": 0, + "findings": 0 + }, + "documentation": { + "files": 10, + "relativeLinks": 384, + "errors": [] + }, + "preservation": { + "groups": 57, + "statuses": { + "PARTIAL": 56, + "PASS": 0, + "FAIL": 0, + "DEFERRED": 1 + }, + "originalRoutesPreserved": true, + "currentConcreteRoutes": 32 + }, + "production": { + "main": "27657f31131cd95d42f0e1290853ec9c9b3959a4", + "originMain": "27657f31131cd95d42f0e1290853ec9c9b3959a4", + "status": "NO-GO", + "qualification": "Local fetched refs; direct push observation recorded separately." + }, + "hashPolicy": "Portable JSON UTF8 LF; raw log hashes measure exact saved bytes.", + "limits": [ + "Pattern scanner skips binary and files over2MiB; not historical Git/production secrets.", + "Local links check target existence, not URL/heading anchors.", + "Static evidence is not runtime/manual/device/provider/production acceptance." + ] +} diff --git a/docs/redesign/phase-7/p7-03/evidence/entry-baseline.json b/docs/redesign/phase-7/p7-03/evidence/entry-baseline.json index 5bd3c3e..5bd77c9 100644 --- a/docs/redesign/phase-7/p7-03/evidence/entry-baseline.json +++ b/docs/redesign/phase-7/p7-03/evidence/entry-baseline.json @@ -105,5 +105,148 @@ "Structured editor presentation", "Import review/history presentation" ], - "manualQualifications": "M01–M12 remain unverified; M09/M11 contextual/reader, physical/device/zoom/provider/output and production gates carry; M13/P5-13 deferred, Phase8 separate." + "manualQualifications": "M01–M12 remain unverified; M09/M11 contextual/reader, physical/device/zoom/provider/output and production gates carry; M13/P5-13 deferred, Phase8 separate.", + "structuredEditorEntry": { + "commit": "704637ab375c32d14aa46f9d4ef0f210136de4d9", + "pushReceipt": { + "observedUtc": "2026-10-12T06:34:48.620963+00:00", + "branch": "codex/ui-redesign-phase4", + "sourceRepairCommit": "3047b6c4a87c43de6f397e4a3d109be9ce3ddeca", + "hygieneCommit": "704637ab375c32d14aa46f9d4ef0f210136de4d9", + "head": "704637ab375c32d14aa46f9d4ef0f210136de4d9", + "originDevelopment": "704637ab375c32d14aa46f9d4ef0f210136de4d9", + "liveDevelopment": "704637ab375c32d14aa46f9d4ef0f210136de4d9", + "main": "27657f31131cd95d42f0e1290853ec9c9b3959a4", + "originMain": "27657f31131cd95d42f0e1290853ec9c9b3959a4", + "liveMain": "27657f31131cd95d42f0e1290853ec9c9b3959a4", + "workingTreePorcelain": "", + "push": "normal; both new commits; no force/main push" + }, + "repairManifestSnapshot": { + "path": ".artifacts/phase7/p7-03/editor/baseline/entry-source-id-results.json", + "sha256": "fdde360d26f9394ee5d265ba9ac68ec65405a6946c010d5b7b004c9a380ca595", + "bytes": 102346, + "hashPolicy": "Exact saved raw bytes" + }, + "sourceBaseline": { + "path": ".artifacts/phase7/p7-03/editor/baseline/identity.json", + "sha256": "9ee021b5d7fb36c7ad4985fe81106f98a55c09f2b569d4cb735c5410d829ef96", + "bytes": 3702, + "hashPolicy": "Exact saved raw bytes" + }, + "latestFullFrontend": "573/89 inherited", + "derivedOnly": { + "frontend": "618/90", + "browser": 216, + "backend": 1034 + }, + "freshPriorSlice": "Source-ID affected46/3,native2/preservation2,types/lint/build/corrected hygiene; no new editor execution", + "catalogBoundary": "Committed704637a catalog frozen from Git object; current expected bilingual test catalog differs, while native RED uses old prebuilt bzQi labels/H3.", + "status": "EDITOR_IMPLEMENTED_SCOPE_CONDITIONAL_GO;FINAL_STAGED_HYGIENE_PASS;NORMAL_PUSH_PENDING;IMPORT_HISTORY_PENDING", + "firstEditorRed": { + "path": ".artifacts/phase7/p7-03/editor/baseline/native-first/baseline-results.json", + "sha256": "2f369a739c9241b0aa6e823a52fb454e9b35e8506ccecdc3cc664edc8afe3104", + "bytes": 766463, + "hashPolicy": "Exact saved raw bytes", + "native": { + "passed": 0, + "failed": 11, + "skipped": 0, + "flaky": 0, + "retries": 0 + }, + "affectedUnit": { + "passed": 38, + "failed": 8, + "total": 46, + "suites": 3, + "pending": 0 + }, + "axe": { + "scans": 12, + "violationNodes": 0, + "incompleteNodes": 408, + "backgroundOverlapChecks": 396, + "shortTextChecks": 12 + }, + "qualification": "Unchanged prebuilt bzQi editor/704637a old catalog versus newly materialized expected test catalog; full vectors and sources retained in immutable baseline. Only320 NB dark image inspected by parent; overflow owner diagnostic and final acceptance pending." + }, + "narrowDiagnostic": { + "path": ".artifacts/phase7/p7-03/editor/baseline/native-narrow/diagnostic-results.json", + "sha256": "7ea08bda9bc1f64b4e10ebdbe3aadbf329703c84d7e9d639a93b93cea526c9d5", + "bytes": 96396, + "hashPolicy": "Exact saved raw bytes", + "native": { + "passed": 0, + "failed": 1, + "skipped": 0, + "flaky": 0, + "retries": 0 + }, + "overlap": "Same320 NB dark case from original11; no added case count", + "geometry": { + "rootOverflow": 30, + "overflowElements": 20, + "maximumOuterRight": 349.6875, + "maximumVisibleFieldRight": 314.6875 + }, + "axe": { + "scans": 1, + "violationNodes": 0, + "incompleteNodes": 37 + }, + "qualification": "Native DOM diagnostic only; no source cause/repair or individual PNG inspection inferred" + }, + "candidateUnitGreen": { + "path": ".artifacts/phase7/p7-03/editor/candidate-20261012T104643Z/candidate-results.json", + "sha256": "fc802b0e2804598ca8d229f71066222b2906f1c9b4828802ede45c87f8ccbe96", + "bytes": 17344, + "hashPolicy": "Exact saved raw bytes", + "unit": { + "passed": 54, + "failed": 0, + "pending": 0, + "suites": 4 + }, + "appTypecheck": "PASS10:46:21-10:46:32UTC", + "status": "CANDIDATE_ONLY; final native/build/visual/static/push pending", + "derivedFrontend": "626/91 only; no full execution" + }, + "candidateNativeAttempt2": { + "path": ".artifacts/phase7/p7-03/editor/attempt2-20261012T105446Z/attempt-results.json", + "sha256": "03f504f04b0d03a2636918ffe1b5e0af67b462a994f19a74cf0f0b0255f8dfc9", + "bytes": 242474, + "hashPolicy": "Exact saved raw bytes", + "runtime": "29finite native PASS; overlapping editor11/sourceID2/Career14/preservation2", + "status": "ACCEPTANCE_WITHHELD;helper contrast and generic-error locale repair pending", + "editorAxe": { + "scans": 12, + "violationNodes": 7, + "incompleteNodes": 374 + }, + "visualReview": "Only NB320/EN360/EN1920 images actually reviewed; other9 not claimed", + "derivedOnly": { + "frontend": "626/91", + "browser": 227 + } + }, + "latestEditorResult": { + "path": "docs/redesign/phase-7/p7-03/evidence/editor-results.json", + "sha256": "b1075e97a9cd705552b82b94782a7411d21d8700a5239a5c8d50bc84a193cef4", + "bytes": 255840, + "hashPolicy": "UTF-8 text CRLF normalized to LF", + "unit": "54/4 fresh PASS", + "native": "editor11/source-ID2/Career14/preservation2 PASS;29 finite overlapping ordinary cases", + "buildId": "W4fUO7_GUC0Qh5FuL3qVL", + "visual": "All13 final PNGs actually reviewed;human/device/zoom/provider qualification pending", + "axe": "Editor13 scans0violation nodes/377 incompletes;Career22 scans0/99 separately;source-ID/preservation0axe attachments", + "derivedOnly": { + "frontend": "626/91", + "browser": 227, + "backend": 1034 + }, + "qualification": "Earlier entry/baseline/candidate observations remain historical. No new whole-suite/backend/manual/production acceptance;all57 statuses and32 routes unchanged.", + "staticGate": "PASS2026-10-12T11:30:04UTC;four commands0,10docs384links0errors,57groups32routes retained;main unchanged" + } + } } diff --git a/docs/redesign/phase-7/p7-03/evidence/source-id-results.json b/docs/redesign/phase-7/p7-03/evidence/source-id-results.json index 74216e2..393eb14 100644 --- a/docs/redesign/phase-7/p7-03/evidence/source-id-results.json +++ b/docs/redesign/phase-7/p7-03/evidence/source-id-results.json @@ -3,7 +3,7 @@ "checkpoint": "P7-03", "slice": "Separate source-ID and nullable-metadata prerequisite repair", "collectedUtc": "2026-10-12T06:16:28.371706+00:00", - "acceptance": "GO for bounded runtime compatibility repair; corrected staged hygiene PASS, normal hygiene successor and push pending", + "acceptance": "GO for bounded forward compatibility repair; corrected hygiene PASS, normal two-commit push directly verified", "entryCommit": "8b4d5c21125e800199d3ecc2d9c059a80ac5125d", "entrySnapshot": { "path": ".artifacts/phase7/p7-03/source-id-repair/final/entry-career-results.json", @@ -50,10 +50,11 @@ "hashPolicy": "Exact measured raw bytes" }, "canonicalLf": { - "path": "job-tracker-ui/src/profile-page.test.tsx", + "path": ".artifacts/phase7/p7-03/source-id-repair/final/tests/job-tracker-ui/src/profile-page.test.tsx", "sha256": "ac1421ecf0fb4723fa974e4e1f0899d0eb0aa53d3225eb428b11c086d6f22950", "bytes": 30021, - "hashPolicy": "UTF-8 text with CRLF normalized to LF" + "hashPolicy": "UTF-8 text with CRLF normalized to LF", + "originalSourcePath": "job-tracker-ui/src/profile-page.test.tsx" } }, { @@ -65,10 +66,11 @@ "hashPolicy": "Exact measured raw bytes" }, "canonicalLf": { - "path": "job-tracker-ui/e2e/phase7-career-source-ids.spec.ts", + "path": ".artifacts/phase7/p7-03/source-id-repair/final/tests/job-tracker-ui/e2e/phase7-career-source-ids.spec.ts", "sha256": "92bc8f1b4c82210207071c56940813dfece3136832ba09ebd1e6c3471d8d7945", "bytes": 20601, - "hashPolicy": "UTF-8 text with CRLF normalized to LF" + "hashPolicy": "UTF-8 text with CRLF normalized to LF", + "originalSourcePath": "job-tracker-ui/e2e/phase7-career-source-ids.spec.ts" } } ], @@ -2042,8 +2044,30 @@ "M01–M12 human/device/zoom/contextual requirements carry; P5-13/C11 deferred, Phase8 separate, main unchanged/production NO-GO." ], "pushReceipt": { - "status": "LOCAL_REPAIR_COMMITTED_UNPUSHED_PENDING_HYGIENE_SUCCESSOR", - "repairCommit": "3047b6c4a87c43de6f397e4a3d109be9ce3ddeca" + "status": "PUSHED_AND_DIRECTLY_VERIFIED", + "repairCommit": "3047b6c4a87c43de6f397e4a3d109be9ce3ddeca", + "hygieneCommit": "704637ab375c32d14aa46f9d4ef0f210136de4d9", + "record": { + "observedUtc": "2026-10-12T06:34:48.620963+00:00", + "branch": "codex/ui-redesign-phase4", + "sourceRepairCommit": "3047b6c4a87c43de6f397e4a3d109be9ce3ddeca", + "hygieneCommit": "704637ab375c32d14aa46f9d4ef0f210136de4d9", + "head": "704637ab375c32d14aa46f9d4ef0f210136de4d9", + "originDevelopment": "704637ab375c32d14aa46f9d4ef0f210136de4d9", + "liveDevelopment": "704637ab375c32d14aa46f9d4ef0f210136de4d9", + "main": "27657f31131cd95d42f0e1290853ec9c9b3959a4", + "originMain": "27657f31131cd95d42f0e1290853ec9c9b3959a4", + "liveMain": "27657f31131cd95d42f0e1290853ec9c9b3959a4", + "workingTreePorcelain": "", + "push": "normal; both new commits; no force/main push" + }, + "raw": { + "path": ".artifacts/phase7/p7-03/source-id-repair/push-receipt.json", + "sha256": "fa8ae1e5170110070e4ca02507517628fce8b5aed1512a6ef44e1d76275a15dd", + "bytes": 687, + "hashPolicy": "Exact saved raw bytes" + }, + "qualification": "Actual normal chronological two-commit push; no rewrite/force/main push. Measured runtime/test source3047 and the one-LF hygiene relation remain historical and unchanged." }, "readbackPayloads": [ { @@ -2286,9 +2310,9 @@ "qualification": "Earlier static observation PASS06:21:53; subsequent final staged check failed and the root committed without handling it. Current repository hygiene is separately pending correction recheck in repositoryHygiene; prior measured static/runtime records remain unchanged." }, "repositoryHygiene": { - "status": "CORRECTED_FULL_STAGED_GATE_PASS_PENDING_SUCCESSOR_AND_PUSH", + "status": "CORRECTED_SUCCESSOR_COMMITTED_AND_NORMAL_PUSH_VERIFIED", "repairCommit": "3047b6c4a87c43de6f397e4a3d109be9ce3ddeca", - "pushStatus": "UNPUSHED", + "pushStatus": "PUSHED_AND_DIRECTLY_VERIFIED", "reportedOriginalStagedCheckExitCode": 1, "historicalCommittedCheck": { "record": { @@ -2498,7 +2522,8 @@ "Static evidence is not runtime/manual/device/provider/production acceptance." ] }, - "qualification": "Fresh actual staged correction gate PASS; original failure/local3047/as-run snapshots remain immutable. Normal hygiene successor commit and subsequent normal two-commit push pending." - } + "qualification": "Fresh actual staged correction gate PASS; subsequent normal hygiene successor704637a and two-commit push directly verified. Original failure/local3047/as-run snapshots remain immutable." + }, + "hygieneCommit": "704637ab375c32d14aa46f9d4ef0f210136de4d9" } } diff --git a/docs/roadmap/todo.md b/docs/roadmap/todo.md index 927c025..7231d25 100644 --- a/docs/roadmap/todo.md +++ b/docs/roadmap/todo.md @@ -85,7 +85,7 @@ Follow the approved [Phase 7 handoff](../redesign/phase-6/p6-05/PHASE7_HANDOFF.m - [x] P7-00 fresh scope inventory and unchanged-source fixture baseline; finite static checks pass. Commit and remote receipt in the Phase 7 ledger. - [x] P7-01 public authentication and separate account/security presentation (implemented scope CONDITIONAL GO; account pushedad7b419/direct receipt19:16:15UTC): public sub-slice CONDITIONAL GO, pushed `8ad720d`, direct remote=HEAD verified2026-10-11 18:50:24UTC, main unchanged; affected61/native22/isolated SMTP2/helper6/auth subset87 pass. [Checkpoint record](../redesign/phase-7/p7-01/README.md) retains manual/provider/production gates. Fresh account full573/89, native6/public22/auth-boundaries10 and types/lint/build pass; all eight final post-copy PNGs actually inspected and source/context evidence frozen. Account85 and public31 current axe incompletes remain qualified; final staged finite hygiene passed; normal account pushad7b419 directly verified2026-10-11 19:16:15UTC with localHEAD=origin=live equality and clean worktree at observation, main unchanged. - [x] P7-02 [onboarding guidance and Career overview/evidence](../redesign/phase-7/p7-02/README.md): entryad7b419 pushed/verified; onboarding implemented-scope CONDITIONAL GO32/13/4+types/lint/build/13 actual PNG inspections/hygiene, pushedd21501aa/direct receipt23:55:12UTC. Separate actual SQLite evidence-list repair91 guards/HTTP1/Release passed and pushed01281f52/direct receipt00:06:47UTC; unfinished Career work preserved/main unchanged. Career affected46/3/native14/fresh preservation2/types/lint/build and22 actual PNG inspections pass; implemented P7-02 CONDITIONAL GO, final Career hygiene PASS (four commands0,9docs347links0errors) and normal push8b4d5c2 directly verified05:51:04UTC, localHEAD=origin=live/clean worktree/main unchanged. Career0/99 axe incompletes/manual gates retained; fullfrontend610/backend1,034 are derived only, latest fresh full573/89 unchanged. -- [ ] P7-03 Career structured editor and import/history: P7-02 pushed8b4d5c2; bounded source-ID/null-metadata repair46/3+native2/preservation2/types/lint/build and readback review pass; local3047b6c4 unpushed after staged EOF whitespace failure, corrected full staged gate PASS (four commands0,10docs374links0errors), normal hygiene successor/two-commit push pending. No logic/assertion change; frozen runtime preserved. Old orphan recovery/concurrency remains open; prove dirty-locale/held-PUT pending-write ownership/recovery before structured/import presentation. Full618/90/browser216 derived only. +- [ ] P7-03 Career structured editor and import/history: prerequisite repair3047/hygiene704637a normally pushed/directly verified06:34:48UTC, original staged EOF failure retained. Structured-editor implemented scope CONDITIONAL GO: affected54/4, native editor11/source-ID2/Career14/preservation2, types/lint/build PASS; all13 final PNGs inspected,13 editor scans0/377 and separate Career22 scans0/99 retained. Dirty-locale/no-refetch, structured/raw held-save locks, retry/validation/readback and finite reflow proven. Final staged hygiene/normal push PENDING; separate import/history presentation and whole checkpoint remain unfinished. Old orphan recovery/concurrency/manual/provider/production gates stay open. Full626/91/browser227/backend1,034 derived only; latest full573/89 inherited,57/32 unchanged/main NO-GO. - [ ] P7-04 CV library and public entry. - [ ] P7-05 Discovery, Companies, Offers and Reminders. - [ ] P7-06 remaining Application forms and global correspondence. diff --git a/job-tracker-ui/e2e/phase7-career-editor.spec.ts b/job-tracker-ui/e2e/phase7-career-editor.spec.ts new file mode 100644 index 0000000..93950e9 --- /dev/null +++ b/job-tracker-ui/e2e/phase7-career-editor.spec.ts @@ -0,0 +1,407 @@ +import { expect, test as base, type APIRequestContext, type APIResponse, type Page, type TestInfo } from '@playwright/test'; +import AxeBuilder from '@axe-core/playwright'; +import { translations } from '../src/i18n/translations'; +import type { StructuredCvProfile } from '../src/profileCv'; + +const apiUrl = 'http://localhost:5302/api'; +const password = 'E2ePassword123!'; +type Owner = { id: string; headers: Record }; +type Sample = { language: 'en' | 'nb'; theme: 'light' | 'dark'; width: number; height: number }; +type CareerReadback = { profile: StructuredCvProfile; completeness: unknown; cvText: string | null }; + +async function json(response: APIResponse, status = 200): Promise { + expect(response.status(), `${response.url()} must return ${status}`).toBe(status); + return response.json(); +} + +async function login(api: APIRequestContext, email: string): Promise { + expect((await api.post(`${apiUrl}/auth/login`, { data: { email, password } })).status()).toBe(200); + const me = await json<{ id: string; sessionContext: string }>(await api.get(`${apiUrl}/auth/me`)); + const csrf = (await api.storageState()).cookies.find(cookie => cookie.name === 'XSRF-TOKEN'); + expect(csrf).toBeDefined(); + return { id: me.id, headers: { 'X-CSRF-TOKEN': csrf!.value, 'X-Session-Context': me.sessionContext } }; +} + +const test = base.extend<{ owner: Owner }>({ + owner: async ({ page, context, playwright }, provide) => { + const admin = await playwright.request.newContext(); + try { + const adminOwner = await login(admin, 'e2e@example.test'); + const email = `p7-career-editor-${Date.now()}-${Math.random().toString(36).slice(2)}@example.test`; + expect((await admin.post(`${apiUrl}/users`, { headers: adminOwner.headers, data: { email, password, roles: [] } })).status()).toBe(200); + const owner = await login(page.request, email); + await context.route('**/*', route => { + const url = new URL(route.request().url()); + return ['localhost', '127.0.0.1'].includes(url.hostname) || ['data:', 'blob:', 'about:'].includes(url.protocol) + ? route.continue() : route.abort(); + }); + await provide(owner); + } finally { await admin.dispose(); } + }, +}); + +async function seed(page: Page, owner: Owner) { + const profile = { + version: '1', + metadata: { fields: { 'contact.fullName': { confidence: null, sourcePage: null, method: 'manual', + sourceSnippet: 'A long owner-reviewed source note about recorded work and qualifications, retained without adding a new claim.', reviewState: 'reviewed' } } }, + contact: { fullName: 'Åse Nordlys — owner-reviewed professional identity with an intentionally long recorded name', + headline: 'Experienced software engineer with recorded delivery, collaboration and professional responsibility across Norwegian organisations', + email: 'owner-reviewed-professional-contact@example.test', phone: '+47 900 00 001', location: 'Trondheim, Trøndelag, Norge — remote and hybrid work', + website: 'https://example.test/portfolio/recorded-professional-work', linkedIn: 'https://www.linkedin.com/in/reviewed-professional-identity', + gitHub: 'https://github.com/reviewed-professional-identity', links: [{ label: 'Detailed portfolio of recorded work and owner-reviewed outcomes', + url: 'https://example.test/recorded-work/long-reviewed-professional-source-reference' }] }, + summary: ['Owner-reviewed professional summary with specific recorded delivery and collaboration.', 'Another factual summary line, kept separate.'], + jobs: [{ id: 'editor-job-source', title: 'Senior software engineer with responsibility for recorded platform delivery and professional collaboration', + company: 'Nordlys programvare og dokumenterte tjenester AS', location: 'Trondheim and remote collaboration across Norway', + start: 'Jan 2020', end: 'Dec 2022', bullets: ['Recorded delivery with owner-reviewed implementation details.', 'Recorded collaboration and operational responsibility.'], skills: ['C#', 'React', 'Norsk'] }], + education: [{ id: 'editor-education-source', qualification: 'Computer science and software engineering with a recorded specialisation in reliable services', + qualificationLevel: 'Bachelor', institution: 'Recorded university department for computer science and software engineering', + location: 'Trondheim, Norge', start: 'Aug 2016', end: 'Jun 2019', details: ['Recorded qualification and reviewed project work.'] }], + projects: [{ id: 'editor-project-source', name: 'Recorded professional project', role: 'Developer', start: '2023-01', end: '2023-12', + bullets: ['Recorded project evidence.'], skills: ['React'] }], + certifications: [{ id: 'editor-certification-source', name: 'Recorded certification', issuer: 'Fixture Academy', date: 'Jun 2022', details: ['Reviewed certification detail.'] }], + skills: ['C#', 'React', 'SQL', 'Norsk'], interests: ['Recorded community participation'], + languages: [{ name: 'Norwegian Sign Language — recorded professional communication experience', level: 'Professional working proficiency with reviewed workplace communication', + notes: 'An owner-reviewed language note retained with the source and kept separate from CV-specific presentation.' }], + awards: ['Recorded award'], publications: ['Recorded publication'], organisations: ['Recorded organisation'], references: ['Available by owner agreement'], + otherSections: [{ title: 'Owner-reviewed custom career information with a deliberately long descriptive section title', + items: ['Recorded custom fact with relevant professional context.', 'Another recorded custom fact, preserved during unrelated contact editing.'] }], + }; + const raw = 'Exact original career source — æøå\nRecorded work and qualifications.\n'; + await json(await page.request.put(`${apiUrl}/career/profile`, { headers: owner.headers, data: { profile, cvText: raw } })); + return { canonical: await json(await page.request.get(`${apiUrl}/career/profile`)), + history: await json(await page.request.get(`${apiUrl}/career/profile/versions`)) }; +} + +async function enter(page: Page, owner: Owner, sample: Sample) { + expect((await page.request.put(`${apiUrl}/auth/preferences/language`, { headers: owner.headers, + data: { language: sample.language === 'nb' ? 'nb-NO' : 'en' } })).status()).toBe(204); + await page.addInitScript(({ language, theme }) => { + localStorage.setItem('uiLanguage', language); + localStorage.setItem('jobtracker.themeMode', theme); + }, sample); + await page.setViewportSize({ width: sample.width, height: sample.height }); + await page.emulateMedia({ reducedMotion: 'reduce' }); + await page.goto('/career?section=profile&source=phase7-editor#preserved'); + await expect(page.locator('html')).toHaveAttribute('lang', sample.language === 'nb' ? 'nb-NO' : 'en'); + await expect(page.locator('html')).toHaveAttribute('data-color-scheme', sample.theme); + await expect(page.getByLabel(translations[sample.language].profileCvContactPhone, { exact: true })).toHaveValue('+47 900 00 001'); +} + +async function navigateSection(page: Page, language: Sample['language'], section: 'profile' | 'import') { + const t = translations[language]; + const label = section === 'profile' ? t.careerWorkspaceProfileTab : t.careerWorkspaceImportTab; + const selector = page.getByRole('combobox', { name: t.careerWorkspaceNavigation, exact: true }); + if (await selector.isVisible()) { + await selector.click(); + await page.getByRole('option', { name: label, exact: true }).click(); + } else await page.getByRole('tab', { name: label, exact: true }).click(); + const url = new URL(page.url()); + expect(url.searchParams.get('section')).toBe(section); + expect(url.searchParams.get('source')).toBe('phase7-editor'); + expect(url.hash).toBe('#preserved'); +} + +function escaped(value: string) { return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } + +async function openRaw(page: Page, language: Sample['language']) { + const field = page.getByLabel(translations[language].profileCvTextLabel, { exact: true }); + const disclosure = page.getByRole('button', { name: new RegExp(escaped(translations[language].profileCvRawPanelTitle)) }); + if (await disclosure.getAttribute('aria-expanded') !== 'true') await disclosure.click(); + await expect(disclosure).toHaveAttribute('aria-expanded', 'true'); + await expect(field).toBeVisible(); + await field.scrollIntoViewIfNeeded(); + await expect(field).toBeInViewport({ ratio: 0.5 }); + await expect(disclosure).toHaveAttribute('aria-expanded', 'true'); + return field; +} + +async function settle(page: Page) { + await page.evaluate(async () => { await document.fonts.ready; await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(() => resolve()))); }); +} + +async function capture(page: Page, info: TestInfo, sample: Sample, state: string) { + await settle(page); + const geometry = await page.evaluate(() => ({ width: innerWidth, height: innerHeight, + rootOverflow: Math.max(0, document.documentElement.scrollWidth - document.documentElement.clientWidth), + overflowElements: [...document.querySelectorAll('body *')] + .filter(element => element.getClientRects().length > 0 && getComputedStyle(element).visibility !== 'hidden' && !element.closest('[hidden],[aria-hidden="true"]')) + .map(element => { + const rect = element.getBoundingClientRect(); + const style = getComputedStyle(element); + return { tag: element.tagName.toLowerCase(), id: element.id || null, class: element.getAttribute('class'), + text: (element.textContent ?? '').replace(/\s+/g, ' ').trim().slice(0, 120), left: rect.left, right: rect.right, width: rect.width, + minWidth: style.minWidth, display: style.display, clientWidth: element.clientWidth, scrollWidth: element.scrollWidth }; + }) + .filter(element => element.width > 0 && (element.right > innerWidth + 1 || element.left < -1)) + .slice(0, 20), + visibleFields: [...document.querySelectorAll('#career-profile-editor input, #career-profile-editor textarea, #career-cv-import input, #career-cv-import textarea')] + .filter(element => element.getClientRects().length > 0 && getComputedStyle(element).visibility !== 'hidden' && element.getAttribute('aria-hidden') !== 'true') + .map(element => { const rect = element.getBoundingClientRect(); return { name: element.getAttribute('aria-label') || (element as HTMLInputElement).labels?.[0]?.textContent, + left: rect.left, right: rect.right, width: rect.width }; }), + })); + const axe = await new AxeBuilder({ page }).options({ rules: { 'target-size': { enabled: true } } }).analyze(); + const name = `p7-career-editor-${sample.language}-${sample.theme}-${sample.width}-${state}`; + await info.attach(`${name}-audit`, { body: JSON.stringify({ sample, state, geometry, ariaSnapshot: await page.getByRole('main').ariaSnapshot(), + axe: { scope: 'All enabled rules plus target-size; complete findings retained', violations: axe.violations, incomplete: axe.incomplete, + passes: axe.passes.map(rule => ({ id: rule.id, nodes: rule.nodes.length })) }, + qualifications: ['Automated Chromium evidence only; no human screen reader or physical touch/software keyboard', + 'No actual browser zoom, production font/photo, PDF, model/provider or production acceptance'], + }), contentType: 'application/json' }); + await info.attach(name, { body: await page.screenshot({ fullPage: true, animations: 'disabled' }), contentType: 'image/png' }); + expect(geometry.rootOverflow).toBe(0); + expect(geometry.visibleFields.length).toBeGreaterThan(0); + if (state === 'held-save-raw-import') expect(geometry.visibleFields.some(field => field.name === translations[sample.language].profileCvTextLabel)).toBe(true); + expect(geometry.visibleFields.every(field => field.left >= 0 && field.right <= geometry.width && field.width > 0)).toBe(true); + expect(axe.violations).toEqual([]); + return axe; +} + +test('[P7-03 PRES-C01 C02 E08] structured and raw drafts survive English to Bokmål without canonical refetch or write', async ({ page, owner }, info) => { + test.setTimeout(90_000); + const before = await seed(page, owner); + const sample: Sample = { language: 'en', theme: 'light', width: 1440, height: 900 }; + let profileReads = 0; + const readCompletions: Promise[] = []; + await page.route('**/api/career/profile', async route => { + if (route.request().method() !== 'GET') return route.continue(); + profileReads++; + const completed = (async () => { const response = await route.fetch(); await route.fulfill({ response }); })(); + readCompletions.push(completed); + await completed; + }); + const canonicalWrites: unknown[] = []; + page.on('request', request => { if (request.url() === `${apiUrl}/career/profile` && request.method() === 'PUT') canonicalWrites.push(request.postDataJSON()); }); + await enter(page, owner, sample); + const draftPhone = '+47 900 00 099'; + const draftRaw = 'Unsaved owner-reviewed raw draft — æøå\nThis text is not persisted yet.\n'; + await page.getByLabel(translations.en.profileCvContactPhone, { exact: true }).fill(draftPhone); + await navigateSection(page, 'en', 'import'); + await (await openRaw(page, 'en')).fill(draftRaw); + await navigateSection(page, 'en', 'profile'); + await expect(page.getByLabel(translations.en.profileCvContactPhone, { exact: true })).toHaveValue(draftPhone); + const readsBeforeLocale = profileReads; + const preferenceSaved = page.waitForResponse(response => response.url() === `${apiUrl}/auth/preferences/language` && response.request().method() === 'PUT'); + await page.locator('header').getByRole('button', { name: 'Norsk', exact: true }).click(); + expect((await preferenceSaved).status()).toBe(204); + await expect(page.locator('html')).toHaveAttribute('lang', 'nb-NO'); + await expect(page.getByLabel(translations.nb.profileCvContactPhone, { exact: true })).toBeVisible(); + await settle(page); + await Promise.all(readCompletions); + await settle(page); + const observedPhone = await page.getByLabel(translations.nb.profileCvContactPhone, { exact: true }).inputValue(); + await navigateSection(page, 'nb', 'import'); + const observedRaw = await (await openRaw(page, 'nb')).inputValue(); + const after = await json(await page.request.get(`${apiUrl}/career/profile`)); + const historyAfter = await json(await page.request.get(`${apiUrl}/career/profile/versions`)); + await info.attach('native-career-editor-locale-drafts', { body: JSON.stringify({ readsBeforeLocale, readsAfterLocale: profileReads, + expected: { phone: draftPhone, raw: draftRaw }, observed: { phone: observedPhone, raw: observedRaw }, canonicalWrites, before, after, historyAfter, + qualification: 'Preference PUT204 is real; canonical GETs are proxied to actual HTTP for completion tracking. No source response is fabricated.' }), contentType: 'application/json' }); + await capture(page, info, { ...sample, language: 'nb' }, 'locale-retained-raw-draft'); + expect(readsBeforeLocale).toBeGreaterThan(0); + expect(profileReads).toBe(readsBeforeLocale); + expect(observedPhone).toBe(draftPhone); + expect(observedRaw).toBe(draftRaw); + expect(canonicalWrites).toEqual([]); + expect(after).toEqual(before.canonical); + expect(historyAfter).toEqual(before.history); +}); + +test('[P7-03 PRES-C01 C02 E08] held save locks edits and duplicate writes; failed save retains its snapshot for explicit identical-body retry', async ({ page, owner }, info) => { + test.setTimeout(120_000); + const before = await seed(page, owner); + const sample: Sample = { language: 'en', theme: 'light', width: 390, height: 844 }; + const t = translations.en; + const payloads: unknown[] = []; + let release!: () => void; + const held = new Promise(resolve => { release = resolve; }); + await page.route('**/api/career/profile', async route => { + if (route.request().method() !== 'PUT') return route.continue(); + payloads.push(route.request().postDataJSON()); + if (payloads.length === 1) { + await held; + return route.fulfill({ status: 500, contentType: 'application/json', body: JSON.stringify({ message: 'Controlled career save unavailable' }) }); + } + return route.continue(); + }); + await enter(page, owner, sample); + const draftPhone = '+47 900 00 088'; + const draftSummary = 'Owner-reviewed pending summary.'; + const draftRaw = 'Pending owner raw source — æøå\nRetain this exact draft after failure.\n'; + await page.getByLabel(t.profileCvContactPhone, { exact: true }).fill(draftPhone); + const summary = page.getByLabel(t.profileCvStructuredSummary, { exact: true }); + await summary.fill(draftSummary); + await navigateSection(page, 'en', 'import'); + await (await openRaw(page, 'en')).fill(draftRaw); + await navigateSection(page, 'en', 'profile'); + await summary.evaluate((element: HTMLTextAreaElement) => element.setSelectionRange(0, 5)); + const save = page.getByRole('button', { name: new RegExp(`^(?:${escaped(t.profileSaveChanges)}|${escaped(t.saving)})$`) }); + const firstResponse = page.waitForResponse(response => response.url() === `${apiUrl}/career/profile` && response.request().method() === 'PUT'); + let pending!: { fields: Array<{ name: string | null; disabled: boolean }>; actions: Array<{ name: string; disabled: boolean }>; + rawDisabled: boolean; saveDisabled: boolean; savingLabelCount: number; writeCount: number; summaryAfterAttempt: string }; + try { + await save.focus(); + await page.keyboard.press('Enter'); + await expect.poll(() => payloads.length).toBe(1); + await settle(page); + const editor = page.locator('#career-profile-editor'); + const actionNames = [t.profileCvAddLink, t.profileCvStructuredAddLanguage, t.profileCvStructuredAddJob, t.profileCvStructuredAddEducation, + t.profileCvStructuredAddOtherSection, t.profileCvStructuredRemove, t.profileCvDeleteCustomLink.replace('{index}', '1'), + t.careerProfileRemoveJob.replace('{index}', '1'), t.careerProfileRemoveEducation.replace('{index}', '1'), + t.careerProfileRemoveLanguage.replace('{index}', '1'), t.careerProfileRemoveOtherSection.replace('{index}', '1'), + t.richTextBold, t.richTextItalic, t.richTextUnderline, t.richTextLink]; + const fields = await editor.locator('input:not([type="file"]),textarea:not([aria-hidden="true"])').evaluateAll(elements => elements + .filter(element => element.getClientRects().length > 0 && getComputedStyle(element).visibility !== 'hidden') + .map(element => ({ name: element.getAttribute('aria-label') || (element as HTMLInputElement).labels?.[0]?.textContent || null, + disabled: (element as HTMLInputElement).disabled }))); + const actions = (await editor.getByRole('button').evaluateAll(elements => elements.map(element => ({ + name: element.getAttribute('aria-label') || (element.textContent ?? '').replace(/\s+/g, ' ').trim(), disabled: (element as HTMLButtonElement).disabled, + })))).filter(action => actionNames.includes(action.name)); + const rawDisabled = await page.getByLabel(t.profileCvTextLabel, { exact: true }).isDisabled(); + const saveDisabled = await save.isDisabled(); + const savingLabelCount = await page.getByRole('button', { name: t.saving, exact: true }).count(); + // A native disabled button ignores click(); an enabled formatting button would mutate + // the held snapshot's draft. These attempts remain local to this disposable owner. + await save.evaluate((element: HTMLButtonElement) => element.click()); + await editor.getByRole('button', { name: t.richTextBold, exact: true }).first().evaluate((element: HTMLButtonElement) => element.click()); + await settle(page); + pending = { fields, actions, rawDisabled, saveDisabled, savingLabelCount, writeCount: payloads.length, summaryAfterAttempt: await summary.inputValue() }; + await info.attach('native-career-editor-pending-lock', { body: JSON.stringify({ pending, heldBody: payloads[0] }), contentType: 'application/json' }); + await capture(page, info, sample, 'held-save'); + await navigateSection(page, 'en', 'import'); + await expect(await openRaw(page, 'en')).toBeDisabled(); + try { await capture(page, info, sample, 'held-save-raw-import'); } + finally { await navigateSection(page, 'en', 'profile'); } + } finally { release(); } + expect((await firstResponse).status()).toBe(500); + await expect(page.getByRole('button', { name: t.profileSaveChanges, exact: true })).toBeEnabled(); + const failedPhone = await page.getByLabel(t.profileCvContactPhone, { exact: true }).inputValue(); + const failedSummary = await summary.inputValue(); + const failedRaw = await page.getByLabel(t.profileCvTextLabel, { exact: true }).inputValue(); + const failureAlerts = await page.getByRole('main').getByRole('alert').allTextContents(); + const afterFailure = await json(await page.request.get(`${apiUrl}/career/profile`)); + const historyAfterFailure = await json(await page.request.get(`${apiUrl}/career/profile/versions`)); + await capture(page, info, sample, 'failed-save-retained-draft'); + const retryResponse = page.waitForResponse(response => response.url() === `${apiUrl}/career/profile` && response.request().method() === 'PUT'); + await page.getByRole('button', { name: t.profileSaveChanges, exact: true }).focus(); + await page.keyboard.press('Enter'); + expect((await retryResponse).status()).toBe(200); + const afterRetry = await json(await page.request.get(`${apiUrl}/career/profile`)); + const historyAfterRetry = await json(await page.request.get(`${apiUrl}/career/profile/versions`)); + await info.attach('native-career-editor-save-retry', { body: JSON.stringify({ pending: pending!, payloads, failedDraft: { phone: failedPhone, summary: failedSummary, raw: failedRaw }, + failureAlerts, before, afterFailure, historyAfterFailure, afterRetry, historyAfterRetry, + qualification: 'First500 is controlled transport failure; retry200 and canonical/history readbacks use actual SQLite HTTP. No canonical stale-write protection is claimed.' }), contentType: 'application/json' }); + expect(pending!.fields.length).toBeGreaterThan(20); + expect(pending!.fields.every(field => field.disabled)).toBe(true); + expect(pending!.actions.length).toBeGreaterThanOrEqual(26); + expect(pending!.actions.every(action => action.disabled)).toBe(true); + expect(pending!.rawDisabled).toBe(true); + expect(pending!.saveDisabled).toBe(true); + expect(pending!.savingLabelCount).toBe(1); + expect(pending!.writeCount).toBe(1); + expect(pending!.summaryAfterAttempt).toBe(draftSummary); + expect(failedPhone).toBe(draftPhone); + expect(failedSummary).toBe(draftSummary); + expect(failedRaw).toBe(draftRaw); + expect(failureAlerts.some(alert => alert.includes(t.profileUpdateFailed) && alert.includes('Controlled career save unavailable'))).toBe(true); + expect(afterFailure).toEqual(before.canonical); + expect(historyAfterFailure).toEqual(before.history); + expect(payloads).toHaveLength(2); + expect(payloads[1]).toEqual(payloads[0]); + expect(afterRetry.profile.contact.phone).toBe(draftPhone); + expect(afterRetry.profile.summary).toEqual([draftSummary]); + expect(afterRetry.cvText).toBe(draftRaw); + expect(historyAfterRetry).toHaveLength(before.history.length + 1); + await page.reload(); + await expect(page.getByLabel(t.profileCvContactPhone, { exact: true })).toHaveValue(draftPhone); + await expect(page.getByLabel(t.profileCvStructuredSummary, { exact: true })).toHaveValue(draftSummary); +}); + +test('[P7-03 PRES-C01 C02 E08] actual validation400 retains draft and source; corrected explicit save persists once', async ({ page, owner }, info) => { + test.setTimeout(90_000); + const before = await seed(page, owner); + const sample: Sample = { language: 'nb', theme: 'dark', width: 390, height: 844 }; + const t = translations.nb; + const payloads: unknown[] = []; + page.on('request', request => { if (request.url() === `${apiUrl}/career/profile` && request.method() === 'PUT') payloads.push(request.postDataJSON()); }); + await enter(page, owner, sample); + const website = page.getByLabel(t.profileCvContactWebsite, { exact: true }); + const prefix = 'https://example.test/'; + const overLimit = prefix + 'a'.repeat(501 - prefix.length); + await website.fill(overLimit); + const rejectedResponse = page.waitForResponse(response => response.url() === `${apiUrl}/career/profile` && response.request().method() === 'PUT'); + await page.getByRole('button', { name: t.profileSaveChanges, exact: true }).focus(); + await page.keyboard.press('Enter'); + const rejected = await rejectedResponse; + const rejectedBody = await rejected.text(); + expect(rejected.status()).toBe(400); + await expect(page.getByRole('button', { name: t.profileSaveChanges, exact: true })).toBeEnabled(); + const retainedWebsite = await website.inputValue(); + const failureAlerts = await page.getByRole('main').getByRole('alert').allTextContents(); + const afterFailure = await json(await page.request.get(`${apiUrl}/career/profile`)); + const historyAfterFailure = await json(await page.request.get(`${apiUrl}/career/profile/versions`)); + await capture(page, info, sample, 'actual-validation400-retained-draft'); + const corrected = 'https://example.test/recorded-work/corrected-reviewed-reference'; + await website.fill(corrected); + const acceptedResponse = page.waitForResponse(response => response.url() === `${apiUrl}/career/profile` && response.request().method() === 'PUT'); + await page.getByRole('button', { name: t.profileSaveChanges, exact: true }).focus(); + await page.keyboard.press('Enter'); + expect((await acceptedResponse).status()).toBe(200); + const afterSave = await json(await page.request.get(`${apiUrl}/career/profile`)); + const historyAfterSave = await json(await page.request.get(`${apiUrl}/career/profile/versions`)); + await info.attach('native-career-editor-real-validation', { body: JSON.stringify({ rejectedStatus: rejected.status(), rejectedBody, + requestedLength: overLimit.length, retainedWebsite, failureAlerts, payloads, before, afterFailure, historyAfterFailure, afterSave, historyAfterSave, + qualification: 'The501-character website is rejected by the actual existing500-character short-field limit before persistence. No transport fault substitutes for this validation response.' }), contentType: 'application/json' }); + expect(rejectedBody).toContain('A contact field exceeds the allowed length.'); + expect(retainedWebsite).toBe(overLimit); + expect(failureAlerts.some(alert => alert.includes(t.profileUpdateFailed) && alert.includes('A contact field exceeds the allowed length.'))).toBe(true); + expect(afterFailure).toEqual(before.canonical); + expect(historyAfterFailure).toEqual(before.history); + expect(payloads).toHaveLength(2); + expect(afterSave.profile.contact.website).toBe(corrected); + expect(afterSave.cvText).toBe(before.canonical.cvText); + expect(historyAfterSave).toHaveLength(before.history.length + 1); + await page.reload(); + await expect(page.getByLabel(t.profileCvContactWebsite, { exact: true })).toHaveValue(corrected); +}); + +const matrix: Sample[] = [ + { language: 'nb', theme: 'dark', width: 320, height: 844 }, + { language: 'en', theme: 'light', width: 360, height: 800 }, + { language: 'nb', theme: 'light', width: 390, height: 844 }, + { language: 'en', theme: 'dark', width: 768, height: 1024 }, + { language: 'nb', theme: 'dark', width: 1024, height: 768 }, + { language: 'en', theme: 'light', width: 1280, height: 320 }, + { language: 'nb', theme: 'light', width: 1440, height: 900 }, + { language: 'en', theme: 'dark', width: 1920, height: 1080 }, +]; + +for (const sample of matrix) { + test(`[P7-03 PRES-C01 C02 E08] structured editor headings, contextual actions and geometry ${sample.language}/${sample.theme}/${sample.width}x${sample.height}`, async ({ page, owner }, info) => { + test.setTimeout(90_000); + const before = await seed(page, owner); + await enter(page, owner, sample); + const t = translations[sample.language]; + const writes: string[] = []; + page.on('request', request => { if (request.url().startsWith(apiUrl) && !['GET', 'HEAD', 'OPTIONS'].includes(request.method())) writes.push(request.method() + ' ' + request.url()); }); + // Capture the existing rendered baseline even when a new semantic requirement + // fails in RED. This retains actual geometry, axe results and pixels for review. + const axe = await capture(page, info, sample, 'structured-editor'); + await expect(page.getByRole('heading', { level: 1 })).toHaveCount(1); + await expect(page.getByRole('heading', { level: 2, name: t.profileCvStructuredEditor, exact: true })).toBeVisible(); + for (const label of [t.careerProfileContactSection, t.profileCvStructuredLanguages, t.profileCvStructuredJobs, t.profileCvStructuredEducation, t.profileCvStructuredOtherSections]) { + await expect(page.getByRole('heading', { level: 3, name: label, exact: true })).toBeVisible(); + } + for (const label of [t.careerProfileRemoveLanguage, t.careerProfileRemoveJob, t.careerProfileRemoveEducation, t.careerProfileRemoveOtherSection]) { + const remove = page.getByRole('button', { name: label.replace('{index}', '1'), exact: true }); + await expect(remove).toHaveCount(1); + await remove.focus(); + await expect(remove).toBeFocused(); + } + expect(axe.violations).toEqual([]); + expect(await json(await page.request.get(`${apiUrl}/career/profile`))).toEqual(before.canonical); + expect(await json(await page.request.get(`${apiUrl}/career/profile/versions`))).toEqual(before.history); + expect(writes).toEqual([]); + }); +} diff --git a/job-tracker-ui/src/career-editor.test.tsx b/job-tracker-ui/src/career-editor.test.tsx new file mode 100644 index 0000000..9e04795 --- /dev/null +++ b/job-tracker-ui/src/career-editor.test.tsx @@ -0,0 +1,285 @@ +import React from "react"; +import "@testing-library/jest-dom"; +import { act, fireEvent, render, screen, waitFor, within } from "@testing-library/react"; +import { api } from "./api"; +import { I18nProvider } from "./i18n/I18nProvider"; +import { translations } from "./i18n/translations"; +import { emptyStructuredCv, StructuredCvProfile } from "./profileCv"; +import { ToastProvider } from "./toast"; +import CareerProfilePage from "./views/CareerProfilePage"; + +jest.mock("./api", () => ({ + getApiErrorMessage: jest.requireActual("./api").getApiErrorMessage, + api: { get: jest.fn(), post: jest.fn(), put: jest.fn(), patch: jest.fn(), delete: jest.fn() }, +})); +jest.mock("./components/CropImageDialog", () => () => null); + +const mockedApi = api as jest.Mocked; +const en = translations.en; +const nb = translations.nb; +const rawText = "Original stored source\nNo silent import acceptance"; +let profile: StructuredCvProfile; +let provider: "local" | "external"; + +function deferred() { + let resolve!: (value: T) => void; + let reject!: (reason: unknown) => void; + const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); + return { promise, resolve, reject }; +} + +function sourceResponse() { + return { data: { profile, cvText: rawText, completeness: { percent: 72, missing: [], sections: [] } } }; +} + +function renderPage() { + return render(); +} + +async function ready() { + await waitFor(() => expect(screen.getByLabelText(en.profileCvContactFullName)).toHaveValue("Recorded owner")); + await waitFor(() => expect(screen.getByRole("button", { name: en.profileSaveChanges })).toBeEnabled()); +} + +async function changeLocale() { + await act(async () => window.dispatchEvent(new StorageEvent("storage", { key: "uiLanguage", newValue: "nb" }))); +} + +function readCount(url: string) { + return mockedApi.get.mock.calls.filter(([requested]) => requested === url).length; +} + +function editor() { + const element = document.getElementById("career-profile-editor"); + expect(element).not.toBeNull(); + return within(element!); +} + +beforeEach(() => { + jest.resetAllMocks(); + window.localStorage.clear(); + window.history.replaceState({}, "", "/career?section=profile&retained=1#editor"); + provider = "local"; + profile = { + ...emptyStructuredCv(), + metadata: { profileVersion: 4, fields: {} }, + contact: { + fullName: "Recorded owner", headline: "Backend engineer", email: "career@example.test", + phone: "+47 12345678", location: "Oslo", website: "https://example.test", + linkedIn: "https://example.test/linkedin", gitHub: "https://example.test/github", + links: [{ label: "Portfolio", url: "https://example.test/portfolio" }], + }, + summary: ["Recorded summary"], skills: ["C#", "SQL"], interests: ["Walking"], + awards: ["Recorded award"], publications: ["Recorded publication"], + organisations: ["Recorded organisation"], references: ["Recorded reference"], + jobs: [{ id: "opaque-job-key", title: "Recorded role", company: "Recorded company", location: "Oslo", start: "2020", end: "Current", isCurrent: true, bullets: ["Recorded outcome"], skills: ["C#"] }], + education: [{ id: "opaque-education-key", qualification: "Recorded degree", qualificationLevel: "Master", institution: "Recorded school", location: "Oslo", start: "2016", end: "2019", details: ["Recorded distinction"] }], + certifications: [{ id: "opaque-certification-key", name: "Recorded certification", issuer: "Recorded issuer", date: "2024", details: ["Recorded credential detail"] }], + projects: [{ id: "opaque-project-key", name: "Recorded project", role: "Owner", start: "2023", end: "2024", bullets: ["Recorded project outcome"], skills: ["SQL"] }], + languages: [{ name: "English", level: "Professional", notes: "Recorded language note" }], + otherSections: [{ title: "Volunteering", items: ["Recorded community work"] }], + sections: [{ name: "Original source", content: "No silent import acceptance", wordCount: 5 }], + }; + mockedApi.get.mockImplementation((url: string) => { + if (url === "/career/profile") return Promise.resolve(sourceResponse() as any); + if (url === "/auth/me") return Promise.resolve({ data: { id: "editor-owner", provider, email: "account@example.test", displayName: "Recorded owner" } } as any); + if (url === "/career/profile/versions") return Promise.resolve({ data: [ + { version: 4, source: "manual", createdAtUtc: "2026-10-12T01:00:00Z", isCurrent: true }, + { version: 3, source: "manual", createdAtUtc: "2026-10-11T01:00:00Z", isCurrent: false }, + ] } as any); + if (url === "/profile-cv/runs") return Promise.resolve({ data: [] } as any); + return Promise.resolve({ data: {} } as any); + }); + mockedApi.put.mockResolvedValue({ data: {} } as any); + mockedApi.post.mockResolvedValue({ data: {} } as any); +}); + +test("a locale update retains dirty structured and raw drafts without reading their source again", async () => { + renderPage(); + await ready(); + fireEvent.change(screen.getByLabelText(en.profileCvContactFullName), { target: { value: "Unsaved canonical owner" } }); + fireEvent.click(screen.getByRole("tab", { name: en.careerWorkspaceImportTab })); + fireEvent.click(screen.getByRole("button", { name: new RegExp(en.profileCvRawPanelTitle) })); + fireEvent.change(screen.getByLabelText(en.profileCvTextLabel), { target: { value: "Unsaved raw source" } }); + fireEvent.click(screen.getByRole("tab", { name: en.careerWorkspaceProfileTab })); + const before = [readCount("/career/profile"), readCount("/auth/me"), readCount("/career/profile/versions"), readCount("/profile-cv/runs")]; + + await changeLocale(); + expect(screen.getByLabelText(nb.profileCvContactFullName)).toHaveValue("Unsaved canonical owner"); + expect([readCount("/career/profile"), readCount("/auth/me"), readCount("/career/profile/versions"), readCount("/profile-cv/runs")]).toEqual(before); + fireEvent.click(screen.getByRole("tab", { name: nb.careerWorkspaceImportTab })); + fireEvent.click(screen.getByRole("button", { name: new RegExp(nb.profileCvRawPanelTitle) })); + expect(screen.getByLabelText(nb.profileCvTextLabel)).toHaveValue("Unsaved raw source"); + expect(window.location.search).toContain("retained=1"); + expect(window.location.hash).toBe("#editor"); + expect(mockedApi.put).not.toHaveBeenCalled(); + expect(mockedApi.post).not.toHaveBeenCalled(); +}); + +test("a pending initial read keeps one request and reports its failure in the latest locale without language writes", async () => { + const pending = deferred(); + const read = mockedApi.get.getMockImplementation()!; + mockedApi.get.mockImplementation((url: string) => url === "/career/profile" ? pending.promise : read(url)); + renderPage(); + expect(screen.getByRole("button", { name: en.profileSaveChanges })).toBeDisabled(); + expect(screen.queryByRole("button", { name: en.saving })).not.toBeInTheDocument(); + await changeLocale(); + await act(async () => { pending.reject({ isAxiosError: true, message: "Request failed with status code 500", response: { status: 500, data: {} } }); }); + + expect(readCount("/career/profile")).toBe(1); + expect(readCount("/auth/me")).toBe(1); + const failure = await editor().findByRole("alert"); + expect(failure).toHaveTextContent(nb.profileLoadFailed); + expect(failure).not.toHaveTextContent("Request failed with status code 500"); + expect(screen.queryByRole("button", { name: nb.saving })).not.toBeInTheDocument(); + await act(async () => window.dispatchEvent(new StorageEvent("storage", { key: "uiLanguage", newValue: "en" }))); + expect(editor().getByRole("alert")).toHaveTextContent(en.profileLoadFailed); + expect(editor().getByRole("alert")).not.toHaveTextContent(nb.profileLoadFailed); + expect(readCount("/career/profile")).toBe(1); + expect(mockedApi.put).not.toHaveBeenCalled(); + expect(mockedApi.post).not.toHaveBeenCalled(); +}); + +test("a held Save locks every editor mutation, raw input and history restore until its snapshot settles", async () => { + const pending = deferred(); + mockedApi.put.mockReturnValue(pending.promise); + renderPage(); + await ready(); + fireEvent.change(screen.getByLabelText(en.profileCvContactFullName), { target: { value: "Snapshot owner" } }); + fireEvent.click(screen.getByRole("button", { name: /Version history/ })); + fireEvent.click(screen.getByRole("button", { name: en.profileSaveChanges })); + try { + expect(mockedApi.put).toHaveBeenCalledTimes(1); + const snapshot = mockedApi.put.mock.calls[0][1] as { profile: StructuredCvProfile; cvText: string }; + expect(snapshot.profile.contact.fullName).toBe("Snapshot owner"); + expect(snapshot.cvText).toBe(rawText); + expect(screen.getAllByRole("textbox").filter((field) => !(field as HTMLInputElement).disabled).map((field) => field.getAttribute("aria-label") || field.id)).toEqual([]); + for (const name of [en.profileCvAddLink, en.profileCvStructuredAddLanguage, en.profileCvStructuredAddJob, en.profileCvStructuredAddEducation, en.profileCvStructuredAddOtherSection, en.profileCvVersionRestore]) { + expect(screen.getByRole("button", { name })).toBeDisabled(); + } + for (const button of screen.getAllByRole("button", { name: /^(Remove|Delete custom link|Bold|Italic|Underline|Link$)/ })) expect(button).toBeDisabled(); + expect(screen.getByRole("button", { name: en.saving })).toBeDisabled(); + fireEvent.click(screen.getByRole("tab", { name: en.careerWorkspaceImportTab })); + fireEvent.click(screen.getByRole("button", { name: new RegExp(en.profileCvRawPanelTitle) })); + expect(screen.getByLabelText(en.profileCvTextLabel)).toBeDisabled(); + expect(mockedApi.post).not.toHaveBeenCalled(); + } finally { + await act(async () => { pending.resolve({ data: {} }); await pending.promise; }); + } + fireEvent.click(screen.getByRole("tab", { name: en.careerWorkspaceProfileTab })); + expect(screen.getByLabelText(en.profileCvContactFullName)).toHaveValue("Snapshot owner"); + expect(screen.getByLabelText(en.profileCvContactFullName)).toBeEnabled(); + expect(screen.getByRole("button", { name: en.profileSaveChanges })).toBeEnabled(); + expect(mockedApi.put).toHaveBeenCalledTimes(1); +}); + +test("two Save activations before React commits pending state send only one canonical PUT", async () => { + const pending = deferred(); + mockedApi.put.mockReturnValue(pending.promise); + renderPage(); + await ready(); + const save = screen.getByRole("button", { name: en.profileSaveChanges }); + try { + act(() => { + save.dispatchEvent(new MouseEvent("click", { bubbles: true })); + save.dispatchEvent(new MouseEvent("click", { bubbles: true })); + }); + expect(mockedApi.put).toHaveBeenCalledTimes(1); + expect(mockedApi.post).not.toHaveBeenCalled(); + } finally { + await act(async () => { pending.resolve({ data: {} }); await pending.promise; }); + } +}); + +test("a failed Save retains a scoped localized error and draft for retry through the same Save button", async () => { + localStorage.setItem("uiLanguage", "nb"); + mockedApi.put.mockRejectedValueOnce({ isAxiosError: true, message: "Request failed with status code 500", response: { status: 500, data: {} } }); + renderPage(); + await waitFor(() => expect(screen.getByLabelText(nb.profileCvContactFullName)).toHaveValue("Recorded owner")); + fireEvent.change(screen.getByLabelText(nb.profileCvContactFullName), { target: { value: "Beholdt utkast" } }); + fireEvent.click(screen.getByRole("button", { name: nb.profileSaveChanges })); + + const failure = await editor().findByRole("alert"); + expect(failure).toHaveTextContent(nb.profileUpdateFailed); + expect(failure).not.toHaveTextContent("Request failed with status code 500"); + expect(screen.getByLabelText(nb.profileCvContactFullName)).toHaveValue("Beholdt utkast"); + expect(screen.getByText(nb.assetsUnsavedChanges)).toBeInTheDocument(); + await act(async () => window.dispatchEvent(new StorageEvent("storage", { key: "uiLanguage", newValue: "en" }))); + expect(editor().getByRole("alert")).toHaveTextContent(en.profileUpdateFailed); + expect(editor().getByRole("alert")).not.toHaveTextContent(nb.profileUpdateFailed); + await changeLocale(); + const reads = mockedApi.get.mock.calls.length; + const save = screen.getByRole("button", { name: nb.profileSaveChanges }); + expect(save).toBeEnabled(); + expect(mockedApi.put).toHaveBeenCalledTimes(1); + fireEvent.click(save); + await waitFor(() => expect(mockedApi.put).toHaveBeenCalledTimes(2)); + expect(mockedApi.put.mock.calls[1]).toEqual(mockedApi.put.mock.calls[0]); + await waitFor(() => expect(editor().queryByRole("alert")).not.toBeInTheDocument()); + expect(screen.getByLabelText(nb.profileCvContactFullName)).toHaveValue("Beholdt utkast"); + expect(screen.queryByText(nb.assetsUnsavedChanges)).not.toBeInTheDocument(); + expect(mockedApi.get).toHaveBeenCalledTimes(reads); + expect(mockedApi.post).not.toHaveBeenCalled(); +}); + +test("the editor exposes named H2/H3 groups and contextual repeated-item remove controls", async () => { + renderPage(); + await ready(); + expect(screen.getByRole("heading", { name: en.profileCvStructuredEditor, level: 2 })).toBeInTheDocument(); + expect(screen.getByRole("region", { name: en.profileCvStructuredEditor })).toBeInTheDocument(); + for (const name of [en.careerProfileContactSection, en.profileCvStructuredLanguages, en.profileCvStructuredJobs, en.profileCvStructuredEducation, en.profileCvStructuredOtherSections]) { + expect(screen.getByRole("heading", { name, level: 3 })).toBeInTheDocument(); + expect(screen.getByRole("region", { name })).toBeInTheDocument(); + } + for (const name of [en.careerProfileRemoveJob, en.careerProfileRemoveEducation, en.careerProfileRemoveLanguage, en.careerProfileRemoveOtherSection]) { + expect(screen.getByRole("button", { name: name.replace("{index}", "1") })).toBeEnabled(); + } + expect(screen.getByRole("button", { name: en.profileCvDeleteCustomLink.replace("{index}", "1") })).toBeEnabled(); + expect(mockedApi.put).not.toHaveBeenCalled(); + expect(mockedApi.post).not.toHaveBeenCalled(); +}); + +test("manual edits preserve long-tail data, custom links, opaque IDs and modeled fields without editor controls", async () => { + renderPage(); + await ready(); + fireEvent.change(screen.getByLabelText(en.profileCvStructuredAwards), { target: { value: "Recorded award\nManual award" } }); + fireEvent.change(screen.getByLabelText(en.profileCvLinkLabel), { target: { value: "Edited portfolio" } }); + fireEvent.change(screen.getByLabelText(en.profileCvJobTitle), { target: { value: "Edited role" } }); + fireEvent.click(screen.getByRole("tab", { name: en.careerWorkspaceImportTab })); + fireEvent.click(screen.getByRole("button", { name: new RegExp(en.profileCvRawPanelTitle) })); + fireEvent.change(screen.getByLabelText(en.profileCvTextLabel), { target: { value: "Manually retained source\nNo extraction requested" } }); + fireEvent.click(screen.getByRole("tab", { name: en.careerWorkspaceProfileTab })); + fireEvent.click(screen.getByRole("button", { name: en.profileSaveChanges })); + await waitFor(() => expect(mockedApi.put).toHaveBeenCalledTimes(1)); + const saved = mockedApi.put.mock.calls[0][1] as { profile: StructuredCvProfile; cvText: string }; + expect(saved).toEqual({ profile: { + ...profile, + awards: ["Recorded award", "Manual award"], + contact: { ...profile.contact, links: [{ label: "Edited portfolio", url: "https://example.test/portfolio" }] }, + jobs: [{ ...profile.jobs[0], title: "Edited role" }], + }, cvText: "Manually retained source\nNo extraction requested" }); + expect(mockedApi.post).not.toHaveBeenCalled(); + expect(mockedApi.patch).not.toHaveBeenCalled(); + expect(mockedApi.delete).not.toHaveBeenCalled(); +}); + +test("a read-only provider cannot edit canonical fields or trigger canonical writes", async () => { + provider = "external"; + renderPage(); + await waitFor(() => expect(screen.getByLabelText(en.profileCvContactFullName)).toHaveValue("Recorded owner")); + fireEvent.click(screen.getByRole("button", { name: /Version history/ })); + expect(screen.getAllByRole("textbox").filter((field) => !(field as HTMLInputElement).disabled)).toEqual([]); + for (const name of [en.profileSaveChanges, en.profileCvVersionRestore, en.profileCvAddLink, en.profileCvStructuredAddLanguage, en.profileCvStructuredAddJob, en.profileCvStructuredAddEducation, en.profileCvStructuredAddOtherSection]) { + const control = screen.getByRole("button", { name }); + expect(control).toBeDisabled(); + control.click(); + } + for (const button of screen.getAllByRole("button", { name: /^(Remove|Delete custom link|Bold|Italic|Underline|Link$)/ })) expect(button).toBeDisabled(); + fireEvent.click(screen.getByRole("tab", { name: en.careerWorkspaceImportTab })); + fireEvent.click(screen.getByRole("button", { name: new RegExp(en.profileCvRawPanelTitle) })); + expect(screen.getByLabelText(en.profileCvTextLabel)).toBeDisabled(); + expect(mockedApi.put).not.toHaveBeenCalled(); + expect(mockedApi.post).not.toHaveBeenCalled(); + expect(mockedApi.patch).not.toHaveBeenCalled(); + expect(mockedApi.delete).not.toHaveBeenCalled(); +}); diff --git a/job-tracker-ui/src/career-workspace-page.test.tsx b/job-tracker-ui/src/career-workspace-page.test.tsx index 1cad68b..568dd58 100644 --- a/job-tracker-ui/src/career-workspace-page.test.tsx +++ b/job-tracker-ui/src/career-workspace-page.test.tsx @@ -212,22 +212,16 @@ test("the parent exposes failed import-read retry without canonical saves or his expect(mockedApi.put).not.toHaveBeenCalled(); }); -test("overview retry cannot overwrite a dirty canonical draft after a failed source refresh", async () => { +test("changing language in overview cannot refetch or overwrite a dirty canonical draft", async () => { renderCareer(); await screen.findByText("70%"); fireEvent.click(screen.getByRole("tab", { name: translations.en.careerWorkspaceProfileTab })); fireEvent.change(screen.getByLabelText("Full name"), { target: { value: "Unsaved canonical name" } }); fireEvent.click(screen.getByRole("tab", { name: translations.en.careerWorkspaceOverviewTab })); - const originalGet = mockedApi.get.getMockImplementation()!; - mockedApi.get.mockImplementation((url: string) => url === "/career/profile" - ? Promise.reject(new Error("Source refresh unavailable")) : originalGet(url)); + const reads = mockedApi.get.mock.calls.length; act(() => window.dispatchEvent(new StorageEvent("storage", { key: "uiLanguage", newValue: "nb" }))); const region = await screen.findByRole("region", { name: translations.nb.careerOverviewProfileStatus }); - expect(await within(region).findByRole("alert")).toHaveTextContent(translations.nb.careerOverviewRetryDraftHint); - const reads = mockedApi.get.mock.calls.length; - const retry = within(region).getByRole("button", { name: translations.nb.retry }); - expect(retry).toBeDisabled(); - fireEvent.click(retry); + expect(within(region).queryByRole("alert")).not.toBeInTheDocument(); expect(mockedApi.get).toHaveBeenCalledTimes(reads); fireEvent.click(screen.getByRole("tab", { name: translations.nb.careerWorkspaceProfileTab })); expect(screen.getByLabelText("Fullt navn")).toHaveValue("Unsaved canonical name"); diff --git a/job-tracker-ui/src/i18n/translations.ts b/job-tracker-ui/src/i18n/translations.ts index 191bd3a..b99af8e 100644 --- a/job-tracker-ui/src/i18n/translations.ts +++ b/job-tracker-ui/src/i18n/translations.ts @@ -1285,9 +1285,14 @@ export const translations = { profileCvLinkLabel: "Label", profileCvLinkUrl: "URL", profileCvDeleteCustomLink: "Delete custom link {index}", + careerProfileContactSection: "Contact information", + careerProfileRemoveJob: "Remove work experience {index}", + careerProfileRemoveEducation: "Remove education {index}", + careerProfileRemoveLanguage: "Remove language {index}", + careerProfileRemoveOtherSection: "Remove custom section {index}", profileCvTextLabel: "Profile CV / master resume text", profileCvTextHelp: "Keep this updated and specific. Include recent roles, tools, achievements, measurable outcomes, and the work you want to be hired for next. If extraction misses something, edit it here manually.", - profileCvStructuredDefaultHint: "Your career information stays front and center. Open the original import only when you need to check or clean up what was read from your file.", + profileCvStructuredDefaultHint: "Career information is the main view. Open the original import to check what was read from your file.", profileCvRawPanelTitle: "Original import", profileCvRawPanelHelp: "Usually messy, but useful for checking what was actually read from the uploaded file.", profileCvPreferredUploads: "Supported uploads: PDF, DOCX, TXT, MD, PNG, JPG, JPEG, WEBP.", @@ -1300,7 +1305,7 @@ export const translations = { profileCvStructureParseFailed: "Couldn't read sections from your CV.", profileCvStructureEmpty: "No sections read yet.", profileCvStructuredEditor: "Career information", - profileCvStructuredEditorHelp: "Your career facts. The CV Builder uses this information to create documents — edit it here and every CV stays up to date.", + profileCvStructuredEditorHelp: "Changes here update inherited information in live and published CVs. CV-specific edits and frozen submission packages stay separate.", profileCvExtractionHistory: "Extraction history", profileCvExtractionHistoryHelp: "See which parser run produced the current structured profile and reprocess from the stored source artifact when needed.", profileCvExtractionHistoryEmpty: "No extraction runs yet.", @@ -3875,9 +3880,14 @@ export const translations = { profileCvLinkLabel: "Etikett", profileCvLinkUrl: "URL", profileCvDeleteCustomLink: "Slett egendefinert lenke {index}", + careerProfileContactSection: "Kontaktinformasjon", + careerProfileRemoveJob: "Fjern arbeidserfaring {index}", + careerProfileRemoveEducation: "Fjern utdanning {index}", + careerProfileRemoveLanguage: "Fjern språk {index}", + careerProfileRemoveOtherSection: "Fjern egendefinert seksjon {index}", profileCvTextLabel: "Profil-CV / hovedtekst for CV", profileCvTextHelp: "Hold denne oppdatert og konkret. Ta med nylige roller, verktøy, prestasjoner, målbare resultater og arbeidet du vil bli ansatt for neste gang. Hvis tekstuttrekket mangler noe, kan du redigere manuelt her.", - profileCvStructuredDefaultHint: "Den strukturerte CV-en er hovedvisningen. Åpne originaluttrekket bare når du vil kontrollere eller rydde opp i parserresultatet.", + profileCvStructuredDefaultHint: "Karriereprofilen er hovedvisningen. Åpne originalimporten når du vil kontrollere det som ble lest fra filen din.", profileCvRawPanelTitle: "Originalt uttrekk", profileCvRawPanelHelp: "Som regel rotete, men nyttig når du vil se nøyaktig hva parseren hentet ut fra den opplastede filen.", profileCvPreferredUploads: "Støttede opplastinger: PDF, DOCX, TXT, MD, PNG, JPG, JPEG, WEBP.", @@ -3889,8 +3899,8 @@ export const translations = { profileCvStructureParsed: "CV-strukturen er analysert.", profileCvStructureParseFailed: "Kunne ikke analysere CV-strukturen.", profileCvStructureEmpty: "Ingen analyserte seksjoner ennå.", - profileCvStructuredEditor: "Strukturert CV-redigering", - profileCvStructuredEditorHelp: "Rediger gjenbrukbare CV-data direkte slik at generatorer og matching kan jobbe fra stabile felt i stedet for bare råtekst.", + profileCvStructuredEditor: "Karriereinformasjon", + profileCvStructuredEditorHelp: "CV-er som bruker profilen, inkludert publiserte CV-er, får oppdatert innhold. Tilpasninger i hver CV og fryste innsendingspakker holdes separate.", profileCvExtractionHistory: "Ekstraksjonshistorikk", profileCvExtractionHistoryHelp: "Se hvilken parserkjøring som produserte den nåværende strukturerte profilen, og kjør på nytt fra det lagrede kildeartefaktet ved behov.", profileCvExtractionHistoryEmpty: "Ingen ekstraksjonskjøringer ennå.", diff --git a/job-tracker-ui/src/profile-page.test.tsx b/job-tracker-ui/src/profile-page.test.tsx index da85192..0a042de 100644 --- a/job-tracker-ui/src/profile-page.test.tsx +++ b/job-tracker-ui/src/profile-page.test.tsx @@ -206,7 +206,7 @@ test('Career Profile section headings describe the visible hierarchy without cha renderPage(); await waitFor(() => expect(screen.getByLabelText(/full name/i)).toHaveValue('Demo User')); expect(screen.getByRole('heading', { name: 'Career profile', level: 2 })).toBeInTheDocument(); - expect(screen.getByRole('heading', { name: 'Career information', level: 3 })).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: 'Career information', level: 2 })).toBeInTheDocument(); expect(screen.getByLabelText(/full name/i)).toHaveValue('Demo User'); let previous = 1; for (const heading of screen.getAllByRole('heading')) { @@ -504,7 +504,7 @@ test('profile page shows durable CV operation state and retries a failed run', a test('profile page keeps raw extraction collapsed until expanded', async () => { renderPage('import'); - expect(await screen.findByText(/your career information stays front and center/i)).toBeInTheDocument(); + expect(await screen.findByText(/Career information is the main view/i)).toBeInTheDocument(); const originalExtractionToggle = screen.getByRole('button', { name: /original import/i }); expect(originalExtractionToggle).toHaveAttribute('aria-expanded', 'false'); diff --git a/job-tracker-ui/src/views/CareerProfilePage.tsx b/job-tracker-ui/src/views/CareerProfilePage.tsx index 0fe7a8d..8f47101 100644 --- a/job-tracker-ui/src/views/CareerProfilePage.tsx +++ b/job-tracker-ui/src/views/CareerProfilePage.tsx @@ -27,6 +27,7 @@ import { useToast } from "../toast"; import { useI18n } from "../i18n/I18nProvider"; import { useAccountPlan } from "../accountPlan"; import ProFeatureNotice from "../components/ProFeatureNotice"; +import { PageSection } from "../layout/PageLayout"; import type { UserOperation } from "../types"; import { emptyStructuredCv, @@ -147,11 +148,16 @@ export default function CareerProfilePage() { const careerOnly = true; const { toast } = useToast(); const { language, t } = useI18n(); + const translationRef = useRef(t); + useEffect(() => { translationRef.current = t; }, [t]); const cvInputRef = useRef(null); const avatarInputRef = useRef(null); const [me, setMe] = useState(null); const [loading, setLoading] = useState(true); const [loadError, setLoadError] = useState(null); + const [saving, setSaving] = useState(false); + const [saveError, setSaveError] = useState(null); + const profileMutationPending = useRef(false); const [uploadingCv, setUploadingCv] = useState(false); const [improvingCv, setImprovingCv] = useState(false); const [rebuildingCv, setRebuildingCv] = useState(false); @@ -192,6 +198,8 @@ export default function CareerProfilePage() { }, []); const restoreVersion = useCallback(async (version: number) => { + if (profileMutationPending.current || me?.provider !== "local" || loading) return; + profileMutationPending.current = true; setLoading(true); try { const r = await api.post(`/career/profile/versions/${version}/restore`); @@ -203,9 +211,10 @@ export default function CareerProfilePage() { } catch (e: any) { toast(String(e?.response?.data || e?.message || t("profileUpdateFailed")), "error"); } finally { + profileMutationPending.current = false; setLoading(false); } - }, [loadVersions, t, toast]); + }, [loadVersions, loading, me?.provider, t, toast]); const [extractionRuns, setExtractionRuns] = useState([]); const [runsLoading, setRunsLoading] = useState(true); const [runsLoadError, setRunsLoadError] = useState(null); @@ -269,13 +278,13 @@ export default function CareerProfilePage() { setProfileDirty(false); setHeadline(profile.contact.headline ?? ""); setLoadError(null); - } catch (error: any) { + } catch (error) { setMe(null); - setLoadError(String(error?.response?.data || error?.message || t("profileLoadFailed"))); + setLoadError(getApiErrorMessage(error, "")); } finally { setLoading(false); } - }, [t]); + }, []); useEffect(() => { void loadProfile(); @@ -328,6 +337,8 @@ export default function CareerProfilePage() { const initials = useMemo(() => initialsFrom([me?.displayName, me?.firstName, me?.lastName, me?.userName, me?.email]), [me]); const isLocal = me?.provider === "local"; + const editorDisabled = !isLocal || loading || saving; + const loadErrorMessage = loadError === null ? null : loadError || t("profileLoadFailed"); const fullName = [me?.firstName, me?.lastName].filter(Boolean).join(" "); const cvWordCount = profileCvText.trim() ? profileCvText.trim().split(/\s+/).length : 0; @@ -345,8 +356,8 @@ export default function CareerProfilePage() { const pendingCvRun = extractionRuns.find((run) => run.status === "pending_review"); const extractionProgress = activeCvRun?.operation?.progressPercent; return ( - - + + {t("careerWorkspaceNavigation")} void restoreVersion(version)} showSummary={false} /> : null} @@ -438,10 +449,10 @@ export default function CareerProfilePage() { }} /> : null} - {loadError ? ( - void loadProfile()}>{t("retry")}}> + {loadErrorMessage ? ( + { if (!profileDirty && !saving) void loadProfile(); }}>{t("retry")}}> {t("profileLoadFailed")} - {loadError} + {loadError ? {loadError} : null} ) : null} @@ -452,9 +463,9 @@ export default function CareerProfilePage() { {t("careerProfileImportBody")} }> {t("careerProfileImportReady")} : null} - {!canUseAi ? {t("profileProImportBody")} : null} + {!canUseAi ? {t("profileProImportBody")} : null} : null} {workspaceSection === "profile" ? @@ -643,7 +654,7 @@ export default function CareerProfilePage() { helperText={t("profileCvTextHelp")} multiline minRows={12} - disabled={!isLocal} + disabled={editorDisabled} fullWidth /> @@ -783,7 +794,7 @@ export default function CareerProfilePage() { diff --git a/job-tracker-ui/src/views/career/CareerProfileSections.tsx b/job-tracker-ui/src/views/career/CareerProfileSections.tsx index aec0795..a4d0c41 100644 --- a/job-tracker-ui/src/views/career/CareerProfileSections.tsx +++ b/job-tracker-ui/src/views/career/CareerProfileSections.tsx @@ -5,6 +5,7 @@ import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline"; import RichTextField from "../../components/RichTextField"; import { useI18n } from "../../i18n/I18nProvider"; +import { PageSection } from "../../layout/PageLayout"; import { joinLines, splitLines, @@ -62,190 +63,182 @@ export function PersonalInformationSection({ value, onChange, getMetadata, + disabled, }: { value: StructuredCvContact; onChange: (next: StructuredCvContact) => void; getMetadata: MetadataLookup; + disabled: boolean; }) { const { t } = useI18n(); const set = (patch: Partial) => onChange({ ...value, ...patch }); return ( - + + - set({ fullName: e.target.value || undefined })} fullWidth /> + set({ fullName: e.target.value || undefined })} fullWidth /> - set({ headline: e.target.value || undefined })} fullWidth /> + set({ headline: e.target.value || undefined })} fullWidth /> - set({ email: e.target.value || undefined })} fullWidth /> + set({ email: e.target.value || undefined })} fullWidth /> - set({ phone: e.target.value || undefined })} fullWidth /> + set({ phone: e.target.value || undefined })} fullWidth /> - set({ location: e.target.value || undefined })} fullWidth /> + set({ location: e.target.value || undefined })} fullWidth /> - set({ website: e.target.value || undefined })} fullWidth /> - set({ linkedIn: e.target.value || undefined })} fullWidth sx={{ gridColumn: { xs: "1 / -1", md: "1 / -1" } }} /> - set({ gitHub: e.target.value || undefined })} fullWidth sx={{ gridColumn: { xs: "1 / -1", md: "1 / -1" } }} /> + set({ website: e.target.value || undefined })} fullWidth /> + set({ linkedIn: e.target.value || undefined })} fullWidth sx={{ gridColumn: { xs: "1 / -1", md: "1 / -1" } }} /> + set({ gitHub: e.target.value || undefined })} fullWidth sx={{ gridColumn: { xs: "1 / -1", md: "1 / -1" } }} /> - {t("profileCvOtherLinks")} - {(value.links ?? []).map((link, index) => set({ links: (value.links ?? []).map((item, itemIndex) => itemIndex === index ? { ...item, label: event.target.value || undefined } : item) })} sx={{ flex: "0 1 180px" }} /> set({ links: (value.links ?? []).map((item, itemIndex) => itemIndex === index ? { ...item, url: event.target.value || undefined } : item) })} fullWidth /> set({ links: (value.links ?? []).filter((_, itemIndex) => itemIndex !== index) })}>)} + {t("profileCvOtherLinks")} + {(value.links ?? []).map((link, index) => set({ links: (value.links ?? []).map((item, itemIndex) => itemIndex === index ? { ...item, label: event.target.value || undefined } : item) })} sx={{ flex: { xs: "0 1 auto", sm: "0 1 180px" } }} /> set({ links: (value.links ?? []).map((item, itemIndex) => itemIndex === index ? { ...item, url: event.target.value || undefined } : item) })} fullWidth /> set({ links: (value.links ?? []).filter((_, itemIndex) => itemIndex !== index) })}>)} + ); } // Shared free-text list editor (one item per line) for Summary / Skills / Interests. -function LinesField({ label, value, onChange, metadata, minRows }: { label: string; value: string[]; onChange: (next: string[]) => void; metadata?: StructuredCvFieldMetadata; minRows: number }) { +function LinesField({ label, value, onChange, metadata, minRows, disabled }: { label: string; value: string[]; onChange: (next: string[]) => void; metadata?: StructuredCvFieldMetadata; minRows: number; disabled: boolean }) { const { t } = useI18n(); return ( - onChange(splitLines(e.target.value))} helperText={t("profileCvStructuredListHelp")} multiline minRows={minRows} fullWidth /> + onChange(splitLines(e.target.value))} helperText={t("profileCvStructuredListHelp")} multiline minRows={minRows} fullWidth /> ); } -export function ProfessionalSummarySection({ value, onChange, getMetadata }: { value: string[]; onChange: (next: string[]) => void; getMetadata: MetadataLookup }) { +export function ProfessionalSummarySection({ value, onChange, getMetadata, disabled }: { value: string[]; onChange: (next: string[]) => void; getMetadata: MetadataLookup; disabled: boolean }) { const { t } = useI18n(); return ( - onChange(splitLines(text))} minRows={5} /> + onChange(splitLines(text))} minRows={5} /> ); } -export function SkillsSection({ value, onChange, getMetadata }: { value: string[]; onChange: (next: string[]) => void; getMetadata: MetadataLookup }) { +export function SkillsSection({ value, onChange, getMetadata, disabled }: { value: string[]; onChange: (next: string[]) => void; getMetadata: MetadataLookup; disabled: boolean }) { const { t } = useI18n(); - return ; + return ; } -export function InterestsSection({ value, onChange, getMetadata }: { value: string[]; onChange: (next: string[]) => void; getMetadata: MetadataLookup }) { +export function InterestsSection({ value, onChange, getMetadata, disabled }: { value: string[]; onChange: (next: string[]) => void; getMetadata: MetadataLookup; disabled: boolean }) { const { t } = useI18n(); - return ; + return ; } -export function LongTailSections({ values, onChange }: { values: Record<"awards" | "publications" | "organisations" | "references", string[]>; onChange: (key: keyof typeof values, next: string[]) => void }) { +export function LongTailSections({ values, onChange, disabled }: { values: Record<"awards" | "publications" | "organisations" | "references", string[]>; onChange: (key: keyof typeof values, next: string[]) => void; disabled: boolean }) { const { t } = useI18n(); const labels = { awards: t("profileCvStructuredAwards"), publications: t("profileCvStructuredPublications"), organisations: t("profileCvStructuredOrganisations"), references: t("profileCvStructuredReferences") }; - return {(Object.keys(values) as (keyof typeof values)[]).map((key) => onChange(key, next)} minRows={3} />)}; + return {(Object.keys(values) as (keyof typeof values)[]).map((key) => onChange(key, next)} minRows={3} disabled={disabled} />)}; } -export function LanguagesSection({ value, onChange, getMetadata }: { value: StructuredCvLanguage[]; onChange: (next: StructuredCvLanguage[]) => void; getMetadata: MetadataLookup }) { +export function LanguagesSection({ value, onChange, getMetadata, disabled }: { value: StructuredCvLanguage[]; onChange: (next: StructuredCvLanguage[]) => void; getMetadata: MetadataLookup; disabled: boolean }) { const { t } = useI18n(); const update = (index: number, patch: Partial) => onChange(value.map((entry, i) => (i === index ? { ...entry, ...patch } : entry))); return ( - - - {t("profileCvStructuredLanguages")} - - + onChange([...value, { name: "", level: "", notes: "" }])}>{t("profileCvStructuredAddLanguage")}}> + {value.length === 0 ? {t("profileCvStructuredEmpty")} : null} {value.map((language, index) => ( - - - update(index, { name: e.target.value || undefined })} fullWidth /> - update(index, { level: e.target.value || undefined })} fullWidth /> - update(index, { notes: e.target.value || undefined })} fullWidth /> - + + + update(index, { name: e.target.value || undefined })} fullWidth /> + update(index, { level: e.target.value || undefined })} fullWidth /> + update(index, { notes: e.target.value || undefined })} fullWidth /> + ))} - + ); } -export function WorkExperienceSection({ value, onChange }: { value: StructuredCvJob[]; onChange: (next: StructuredCvJob[]) => void }) { +export function WorkExperienceSection({ value, onChange, disabled }: { value: StructuredCvJob[]; onChange: (next: StructuredCvJob[]) => void; disabled: boolean }) { const { t } = useI18n(); const update = (index: number, patch: Partial) => onChange(value.map((entry, i) => (i === index ? { ...entry, ...patch } : entry))); return ( - - - {t("profileCvStructuredJobs")} - - + onChange([...value, { title: "", company: "", location: "", start: "", end: "", isCurrent: false, bullets: [], skills: [] }])}>{t("profileCvStructuredAddJob")}}> + {value.length === 0 ? {t("profileCvStructuredEmpty")} : null} {value.map((job, index) => ( - - - update(index, { title: e.target.value || undefined })} fullWidth /> - update(index, { company: e.target.value || undefined })} fullWidth /> - update(index, { location: e.target.value || undefined })} fullWidth /> - - update(index, { start: e.target.value || undefined })} fullWidth /> - update(index, { end: e.target.value || undefined, isCurrent: /present|current/i.test(e.target.value) || job.isCurrent })} fullWidth /> + + + update(index, { title: e.target.value || undefined })} fullWidth /> + update(index, { company: e.target.value || undefined })} fullWidth /> + update(index, { location: e.target.value || undefined })} fullWidth /> + + update(index, { start: e.target.value || undefined })} fullWidth /> + update(index, { end: e.target.value || undefined, isCurrent: /present|current/i.test(e.target.value) || job.isCurrent })} fullWidth /> - update(index, { bullets: splitLines(text) })} minRows={5} /> - update(index, { skills: splitLines(e.target.value) })} helperText={t("profileCvStructuredListHelp")} multiline minRows={3} fullWidth sx={{ gridColumn: { xs: "1 / -1", md: "1 / -1" } }} /> + update(index, { bullets: splitLines(text) })} minRows={5} /> + update(index, { skills: splitLines(e.target.value) })} helperText={t("profileCvStructuredListHelp")} multiline minRows={3} fullWidth sx={{ gridColumn: { xs: "1 / -1", md: "1 / -1" } }} /> - + ))} - + ); } -export function EducationSection({ value, onChange }: { value: StructuredCvEducation[]; onChange: (next: StructuredCvEducation[]) => void }) { +export function EducationSection({ value, onChange, disabled }: { value: StructuredCvEducation[]; onChange: (next: StructuredCvEducation[]) => void; disabled: boolean }) { const { t } = useI18n(); const update = (index: number, patch: Partial) => onChange(value.map((entry, i) => (i === index ? { ...entry, ...patch } : entry))); return ( - - - {t("profileCvStructuredEducation")} - - + onChange([...value, { qualification: "", institution: "", location: "", start: "", end: "", details: [] }])}>{t("profileCvStructuredAddEducation")}}> + {value.length === 0 ? {t("profileCvStructuredEmpty")} : null} {value.map((education, index) => ( - - - update(index, { qualification: e.target.value || undefined })} fullWidth /> - update(index, { institution: e.target.value || undefined })} fullWidth /> - update(index, { location: e.target.value || undefined })} fullWidth /> - - update(index, { start: e.target.value || undefined })} fullWidth /> - update(index, { end: e.target.value || undefined })} fullWidth /> + + + update(index, { qualification: e.target.value || undefined })} fullWidth /> + update(index, { institution: e.target.value || undefined })} fullWidth /> + update(index, { location: e.target.value || undefined })} fullWidth /> + + update(index, { start: e.target.value || undefined })} fullWidth /> + update(index, { end: e.target.value || undefined })} fullWidth /> - update(index, { details: splitLines(text) })} minRows={4} /> + update(index, { details: splitLines(text) })} minRows={4} /> - + ))} - + ); } -export function OtherSectionsSection({ value, onChange }: { value: StructuredCvOtherSection[]; onChange: (next: StructuredCvOtherSection[]) => void }) { +export function OtherSectionsSection({ value, onChange, disabled }: { value: StructuredCvOtherSection[]; onChange: (next: StructuredCvOtherSection[]) => void; disabled: boolean }) { const { t } = useI18n(); const update = (index: number, patch: Partial) => onChange(value.map((entry, i) => (i === index ? { ...entry, ...patch } : entry))); return ( - - - {t("profileCvStructuredOtherSections")} - - + onChange([...value, { title: "", items: [] }])}>{t("profileCvStructuredAddOtherSection")}}> + {value.length === 0 ? {t("profileCvStructuredEmpty")} : null} {value.map((section, index) => ( - - - update(index, { title: e.target.value || undefined })} fullWidth /> - - update(index, { items: splitLines(text) })} minRows={4} /> + + + update(index, { title: e.target.value || undefined })} fullWidth /> + + update(index, { items: splitLines(text) })} minRows={4} /> ))} - + ); }