From a88310481fbfa7701478043e8bf192ee45c7c28e Mon Sep 17 00:00:00 2001 From: cesnimda Date: Tue, 3 Nov 2026 15:24:55 +0100 Subject: [PATCH] fix(ai): discard proposals when section context changes --- .../ui-modernisation/AI_CONTEXT_VALIDATION.md | 13 +++++++++++ docs/ui-modernisation/UI-08.md | 14 +++++++++++ .../evidence/ai-context/CHECKS.json | 20 ++++++++++++++++ .../evidence/ai-context/SOURCE_MANIFEST.json | 23 +++++++++++++++++++ .../ai-context/a3-ai-context-green.json | 1 + .../a3-ai-context-parent-tests.json | 1 + .../ai-context/a3-ai-context-red.json | 1 + .../ai-context/a3-ai-settings-baseline.json | 1 + .../src/ai-section-assistant.test.tsx | 10 ++++++-- .../src/components/cv/AiSectionAssistant.tsx | 2 +- 10 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 docs/ui-modernisation/AI_CONTEXT_VALIDATION.md create mode 100644 docs/ui-modernisation/UI-08.md create mode 100644 docs/ui-modernisation/evidence/ai-context/CHECKS.json create mode 100644 docs/ui-modernisation/evidence/ai-context/SOURCE_MANIFEST.json create mode 100644 docs/ui-modernisation/evidence/ai-context/a3-ai-context-green.json create mode 100644 docs/ui-modernisation/evidence/ai-context/a3-ai-context-parent-tests.json create mode 100644 docs/ui-modernisation/evidence/ai-context/a3-ai-context-red.json create mode 100644 docs/ui-modernisation/evidence/ai-context/a3-ai-settings-baseline.json diff --git a/docs/ui-modernisation/AI_CONTEXT_VALIDATION.md b/docs/ui-modernisation/AI_CONTEXT_VALIDATION.md new file mode 100644 index 00000000..442517d2 --- /dev/null +++ b/docs/ui-modernisation/AI_CONTEXT_VALIDATION.md @@ -0,0 +1,13 @@ +# A3-IM08 bounded stale-proposal repair + +3 November2026. IM08 is authorised and remains IN PROGRESS. This subpackage fixes a reproduced section-assistant defect without changing any model/provider/API/schema or acceptance writer. + +The shared assistant sends source text, targetId, document/output language, context and sectionName when generating a proposal. Its existing invalidation effect omitted the last two inputs. CvBuilderEditor entry callers include edited entry title/subtitle in context, so a user could change facts while a request was pending, then see and apply the previous suggestion; a displayed review also survived those changes. Four controlled regressions reproduced both pending/visible cases for context and section name before the fix. + +Added context and sectionName to the same invalidation effect. Existing requestId guards reject late success/failure/finally work and clear the old proposal. Generation remains explicit, Apply still requires server token acceptance, and parent source flush/revision/epoch guards remain unchanged. No silent content write or automatic regeneration. A translated section label may conservatively discard a prompt-bound proposal; it never changes document/output language to match UI language. + +Checks PASSED:23 section-assistant cases plus59 parent studio cases,82 disjoint cases/2 suites; typecheck, scoped zero-warning lint and production build. Independent static review found no actionable issue and did not repeat tests. Initial58-case Settings/AI baseline overlaps the section cases and is not added. Parent suite emitted existing direct-focus act warnings at cv-builder-deep-link.test.tsx475/782; all59 cases passed, but this is not a warning-free test run. Fixture-only callbacks/tokens, no live model or semantic AI-quality claim. + +NOT RUN for this one-line dependency repair:backend rerun, new browser sweep, physical PDF, native device, live models/providers, final integrated security/release. Existing rendered document layouts are unchanged; controlled React regressions exercise the affected async behavior directly. Other IM08 Settings/automation presentation and final scope qualification remain open; no Gate F acceptance is requested for this subpackage alone. + +Native baseline/red/green/parent reports and source manifest are in evidence/ai-context. Red run:4 failed,4 passed,15 intentionally excluded by test-name filter. Final complete section suite23 passed,zero failed/pending; parent59 passed. Rollback reverts the effect-dependency change; no database/data rollback. diff --git a/docs/ui-modernisation/UI-08.md b/docs/ui-modernisation/UI-08.md new file mode 100644 index 00000000..616745af --- /dev/null +++ b/docs/ui-modernisation/UI-08.md @@ -0,0 +1,14 @@ +# A3-IM08 Contextual AI and Settings automation + +3 November2026. Owner explicitly approved **"Approve calendar/documents/mail and A3-IM08"**. Isolated codex/a3-ui-08 starts at accepted UI07 fba80ef346bc021e675024638dacf9ccef7243db. Acceptance receipt e5a979386d6377138e7ea7fd44958adb22838886 is published and independently remotely verified. No live model activation; application automation controls are distinct from the paused, untouched backlog orchestrator. + +- [x] Inspect SettingsView, rules/notification owners, AI privacy/usage and contextual section-assistant callers. +- [x] Initial selected baseline:58 cases/5 suites passed, not blanket AI quality or full roadmap acceptance. +- [ ] Contextual assistance: preserve manual editing, source/document-language separation, explicit review/apply, stale-input discard, quota/consent/failure/retry/close. Investigate context and section-name changes while a proposal is pending or under review. +- [ ] Settings automation: expose current supported controls and explain effects/timing/disable behavior under Settings; preserve existing rules drafts and notification/AI preference writers. Inspect actual worker/data contracts before promising independent per-rule switches not represented in current six numeric thresholds. No fake controls, worker activation or policy/infrastructure change. +- [ ] Scoped EN/NB, responsive/focus/accessibility presentation; types/lint/build, controlled browser and applicable local backend tests; independent review. +- [ ] Publish validated checkpoints and exact evidence; update durable handoff. Next Gate F before IM09 account/session/connections/admin/processing views. + +Current source findings:rules expose only six integer day thresholds1–365, not independent enable flags; email-follow-up notifications and AI/privacy preferences have actual existing boolean controls. Do not represent thresholds as disable switches or imply a general worker-control API. Contextual assistant invalidation currently covers source text, target ID, language and entitlement; generation also consumes context and sectionName, which need compatibility review. + +No schema/dependency/migration planned for presentation and bounded stale-proposal fix. Existing canonical Career Profile, CV/letter history/settings, RD21, per-owner data, quota/consent and server review/apply stay authoritative. Rollback reverts this UI increment; no database rollback. Full integrated AI/security/native/provider/release qualifications remain separate. diff --git a/docs/ui-modernisation/evidence/ai-context/CHECKS.json b/docs/ui-modernisation/evidence/ai-context/CHECKS.json new file mode 100644 index 00000000..585c3de0 --- /dev/null +++ b/docs/ui-modernisation/evidence/ai-context/CHECKS.json @@ -0,0 +1,20 @@ +{ + "frontendPassed": 82, + "suites": 2, + "failed": 0, + "pending": 0, + "typecheckExit": 0, + "scopedLintExit": 0, + "buildExit": 0, + "independentReview": "No actionable static findings; tests not repeated", + "warnings": [ + "Parent direct-focus tests emit act warnings;59 passed" + ], + "notRun": [ + "backend rerun", + "new browser matrix", + "physical PDF", + "live models/providers", + "final integrated security/release" + ] +} diff --git a/docs/ui-modernisation/evidence/ai-context/SOURCE_MANIFEST.json b/docs/ui-modernisation/evidence/ai-context/SOURCE_MANIFEST.json new file mode 100644 index 00000000..49797658 --- /dev/null +++ b/docs/ui-modernisation/evidence/ai-context/SOURCE_MANIFEST.json @@ -0,0 +1,23 @@ +{ + "base": "e5a979386d6377138e7ea7fd44958adb22838886", + "recordedAtUtc": "2026-11-03T14:24:45.724564+00:00", + "policy": "LF-normalised text SHA256", + "sources": { + "job-tracker-ui/src/components/cv/AiSectionAssistant.tsx": "40475ae87da5a1966bdd52a5107b4c54e34a28a4be31687dc5471217105c4d7a", + "job-tracker-ui/src/ai-section-assistant.test.tsx": "bcf642a670c5b2741ba8dd46fbf1b1f231c4801b4f1c8bebec6eab6dabd31396", + "job-tracker-ui/src/views/CvBuilderEditor.tsx": "49537d71b577df7c564609c2cfcd239afe066fe4b4c550677544886a205e0e0b", + "job-tracker-ui/src/cv-builder-deep-link.test.tsx": "8d5ae8d6a07991856dd2b21bde332ad91762c46f7534c2154719cf8a41d81dd2", + "job-tracker-ui/src/cvBuilder.ts": "c021bafeabbc8ad3526d1b10b90ad8f7f0958ded8ed26eac8c1d28b53098b64d", + "job-tracker-ui/package.json": "3745394e406cefa40d30a87e840bccb359be147bac6ffba736e2ae90898a8626", + "job-tracker-ui/package-lock.json": "bf31e90d7af03e8af059db2aaf893925b9e8881a30a1688034ed88ef45d4fcab", + "docs/ui-modernisation/UI-08.md": "a9077d5bdce58e8f23d818564cbdb6853392444b29ff19063562f621732c2361", + "docs/ui-modernisation/AI_CONTEXT_VALIDATION.md": "f934cdf1f43b3c50026ce692e1fce8e0a754ba6373ca5039b9414308998f5adf" + }, + "evidence": { + "a3-ai-context-green.json": "0a587c3a3cd5235b4e36b805805fc9d5eb6be89ef87ff40516c3ad818939cfc4", + "a3-ai-context-parent-tests.json": "c6ca2b8ffd4f2150a19fa3ce94c4c35cd72ea08833cf28b671218930a2c2e3d8", + "a3-ai-context-red.json": "8536fc3228bb8fa7cb7735f7e470998ca8bfaa003ed6c91a9d0b54f7e27c0e71", + "a3-ai-settings-baseline.json": "47ad0bc2aaff394e233fd7a69a33fe17b13443318635af8c806a09d69854f3a4", + "CHECKS.json": "76564d88813d9fc8b798916db2391038d57b4d9d87b5f802d82fb068202c7279" + } +} diff --git a/docs/ui-modernisation/evidence/ai-context/a3-ai-context-green.json b/docs/ui-modernisation/evidence/ai-context/a3-ai-context-green.json new file mode 100644 index 00000000..f8be12a7 --- /dev/null +++ b/docs/ui-modernisation/evidence/ai-context/a3-ai-context-green.json @@ -0,0 +1 @@ +{"numFailedTestSuites":0,"numFailedTests":0,"numPassedTestSuites":1,"numPassedTests":23,"numPendingTestSuites":0,"numPendingTests":0,"numRuntimeErrorTestSuites":0,"numTodoTests":0,"numTotalTestSuites":1,"numTotalTests":23,"openHandles":[],"snapshot":{"added":0,"didUpdate":false,"failure":false,"filesAdded":0,"filesRemoved":0,"filesRemovedList":[],"filesUnmatched":0,"filesUpdated":0,"matched":0,"total":0,"unchecked":0,"uncheckedKeysByFile":[],"unmatched":0,"updated":0},"startTime":1793715500100,"success":true,"testResults":[{"assertionResults":[{"ancestorTitles":[],"duration":593,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"direct Improve writing action retains explicit review","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715506248,"status":"passed","title":"direct Improve writing action retains explicit review"},{"ancestorTitles":[],"duration":144,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"direct Suggest content action retains explicit review","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715506842,"status":"passed","title":"direct Suggest content action retains explicit review"},{"ancestorTitles":[],"duration":111,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"direct Grammar check action retains explicit review","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715506986,"status":"passed","title":"direct Grammar check action retains explicit review"},{"ancestorTitles":[],"duration":154,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"direct Shorter action retains explicit review","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715507098,"status":"passed","title":"direct Shorter action retains explicit review"},{"ancestorTitles":[],"duration":160,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"empty source requests career facts without making an AI request","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"startAt":1793715507252,"status":"passed","title":"empty source requests career facts without making an AI request"},{"ancestorTitles":[],"duration":502,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"section AI uses the CV document language and requires explicit server acceptance","invocations":1,"location":null,"numPassingAsserts":6,"retryReasons":[],"startAt":1793715507412,"status":"passed","title":"section AI uses the CV document language and requires explicit server acceptance"},{"ancestorTitles":[],"duration":99,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"section AI controls render in Bokmål without changing the document language","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715507914,"status":"passed","title":"section AI controls render in Bokmål without changing the document language"},{"ancestorTitles":[],"duration":205,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-C11] Reject removes the suggestion without accepting content","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715508013,"status":"passed","title":"[PRES-C11] Reject removes the suggestion without accepting content"},{"ancestorTitles":[],"duration":306,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-C11] Close removes the suggestion without accepting content","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715508218,"status":"passed","title":"[PRES-C11] Close removes the suggestion without accepting content"},{"ancestorTitles":[],"duration":230,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-C11] accepts the user's edited suggestion with the original proposal token","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715508524,"status":"passed","title":"[PRES-C11] accepts the user's edited suggestion with the original proposal token"},{"ancestorTitles":[],"duration":200,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-C11] a failed suggestion can be retried without accepting content","invocations":1,"location":null,"numPassingAsserts":5,"retryReasons":[],"startAt":1793715508754,"status":"passed","title":"[PRES-C11] a failed suggestion can be retried without accepting content"},{"ancestorTitles":[],"duration":293,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"closing and reopening ignores an old request even after a newer suggestion completes","invocations":1,"location":null,"numPassingAsserts":6,"retryReasons":[],"startAt":1793715508954,"status":"passed","title":"closing and reopening ignores an old request even after a newer suggestion completes"},{"ancestorTitles":[],"duration":110,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a changed text invalidates a pending suggestion","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715509247,"status":"passed","title":"a changed text invalidates a pending suggestion"},{"ancestorTitles":[],"duration":110,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a changed target invalidates a pending suggestion","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715509357,"status":"passed","title":"a changed target invalidates a pending suggestion"},{"ancestorTitles":[],"duration":122,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a changed document language invalidates a pending suggestion","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715509467,"status":"passed","title":"a changed document language invalidates a pending suggestion"},{"ancestorTitles":[],"duration":103,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a changed context invalidates a pending suggestion","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715509589,"status":"passed","title":"a changed context invalidates a pending suggestion"},{"ancestorTitles":[],"duration":109,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a changed section name invalidates a pending suggestion","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715509692,"status":"passed","title":"a changed section name invalidates a pending suggestion"},{"ancestorTitles":[],"duration":166,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"changed text removes an existing review before it can be accepted","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715509801,"status":"passed","title":"changed text removes an existing review before it can be accepted"},{"ancestorTitles":[],"duration":148,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"changed context removes an existing review before it can be accepted","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715509967,"status":"passed","title":"changed context removes an existing review before it can be accepted"},{"ancestorTitles":[],"duration":160,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"changed section name removes an existing review before it can be accepted","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715510115,"status":"passed","title":"changed section name removes an existing review before it can be accepted"},{"ancestorTitles":[],"duration":342,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"regeneration replaces the proposal and its token before acceptance","invocations":1,"location":null,"numPassingAsserts":5,"retryReasons":[],"startAt":1793715510275,"status":"passed","title":"regeneration replaces the proposal and its token before acceptance"},{"ancestorTitles":[],"duration":321,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"Reject invalidates a pending regeneration and clears the previous review","invocations":1,"location":null,"numPassingAsserts":6,"retryReasons":[],"startAt":1793715510618,"status":"passed","title":"Reject invalidates a pending regeneration and clears the previous review"},{"ancestorTitles":[],"duration":433,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"failed server acceptance keeps the edited review and allows retry without duplicate submits","invocations":1,"location":null,"numPassingAsserts":10,"retryReasons":[],"startAt":1793715510939,"status":"passed","title":"failed server acceptance keeps the edited review and allows retry without duplicate submits"}],"endTime":1793715511374,"message":"","name":"C:\\Users\\Connor\\.codex\\worktrees\\direct-roadmap-integration\\Job tracker\\job-tracker-ui\\src\\ai-section-assistant.test.tsx","startTime":1793715501726,"status":"passed","summary":""}],"wasInterrupted":false} diff --git a/docs/ui-modernisation/evidence/ai-context/a3-ai-context-parent-tests.json b/docs/ui-modernisation/evidence/ai-context/a3-ai-context-parent-tests.json new file mode 100644 index 00000000..c0c39c72 --- /dev/null +++ b/docs/ui-modernisation/evidence/ai-context/a3-ai-context-parent-tests.json @@ -0,0 +1 @@ +{"numFailedTestSuites":0,"numFailedTests":0,"numPassedTestSuites":1,"numPassedTests":59,"numPendingTestSuites":0,"numPendingTests":0,"numRuntimeErrorTestSuites":0,"numTodoTests":0,"numTotalTestSuites":1,"numTotalTests":59,"openHandles":[],"snapshot":{"added":0,"didUpdate":false,"failure":false,"filesAdded":0,"filesRemoved":0,"filesRemovedList":[],"filesUnmatched":0,"filesUpdated":0,"matched":0,"total":0,"unchecked":0,"uncheckedKeysByFile":[],"unmatched":0,"updated":0},"startTime":1793715649930,"success":true,"testResults":[{"assertionResults":[{"ancestorTitles":[],"duration":2998,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"Strict Mode groups a typing burst into one undo step and preserves redo through autosave","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715655000,"status":"passed","title":"Strict Mode groups a typing burst into one undo step and preserves redo through autosave"},{"ancestorTitles":[],"duration":2051,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a pause between typing bursts leaves a separate undo step","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"startAt":1793715657999,"status":"passed","title":"a pause between typing bursts leaves a separate undo step"},{"ancestorTitles":[],"duration":440,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"tablet width keeps both editing and preview available in the stacked document flow","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715660050,"status":"passed","title":"tablet width keeps both editing and preview available in the stacked document flow"},{"ancestorTitles":[],"duration":2174,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"document shortcuts undo and redo renaming, preserve native input undo and discard branched redo","invocations":1,"location":null,"numPassingAsserts":5,"retryReasons":[],"startAt":1793715660491,"status":"passed","title":"document shortcuts undo and redo renaming, preserve native input undo and discard branched redo"},{"ancestorTitles":[],"duration":1706,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a revision conflict disables document history without silently writing an undo","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715662665,"status":"passed","title":"a revision conflict disables document history without silently writing an undo"},{"ancestorTitles":[],"duration":2217,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"switching documents hides the previous draft while loading and starts fresh history","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715664371,"status":"passed","title":"switching documents hides the previous draft while loading and starts fresh history"},{"ancestorTitles":[],"duration":1134,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"explicit blank editing excludes master content and includes a profile section only after an Add action","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715666589,"status":"passed","title":"explicit blank editing excludes master content and includes a profile section only after an Add action"},{"ancestorTitles":[],"duration":895,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a blank CV can deliberately add an additional Career Profile section","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"startAt":1793715667723,"status":"passed","title":"a blank CV can deliberately add an additional Career Profile section"},{"ancestorTitles":[],"duration":2609,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a historical restore response from the previous document cannot change the newly opened CV","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715668618,"status":"passed","title":"a historical restore response from the previous document cannot change the newly opened CV"},{"ancestorTitles":[],"duration":711,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"content sections follow the editing-region heading without mutating CV settings","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715671228,"status":"passed","title":"content sections follow the editing-region heading without mutating CV settings"},{"ancestorTitles":[],"duration":921,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"settings history explains current Career Profile resolution without writing data","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"startAt":1793715671939,"status":"passed","title":"settings history explains current Career Profile resolution without writing data"},{"ancestorTitles":[],"duration":2875,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"PDF export locks immediately, rejects a newer unsaved draft, and keeps that draft recoverable","invocations":1,"location":null,"numPassingAsserts":5,"retryReasons":[],"startAt":1793715672860,"status":"passed","title":"PDF export locks immediately, rejects a newer unsaved draft, and keeps that draft recoverable"},{"ancestorTitles":[],"duration":1974,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"edits during a held PDF response prevent an older document download","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715675735,"status":"passed","title":"edits during a held PDF response prevent an older document download"},{"ancestorTitles":[],"duration":1537,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"moving a section to the first position announces its actual order and focuses its row","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"startAt":1793715677709,"status":"passed","title":"moving a section to the first position announces its actual order and focuses its row"},{"ancestorTitles":[],"duration":6309,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"section navigation opens and focuses omitted/custom sections without changing their data","invocations":1,"location":null,"numPassingAsserts":9,"retryReasons":[],"startAt":1793715679246,"status":"passed","title":"section navigation opens and focuses omitted/custom sections without changing their data"},{"ancestorTitles":[],"duration":1689,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"keyboard move controls retain focus and persist the same section order shown by navigation","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715685555,"status":"passed","title":"keyboard move controls retain focus and persist the same section order shown by navigation"},{"ancestorTitles":[],"duration":1718,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"secondary duplicate action saves the current draft before creating the copy","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715687245,"status":"passed","title":"secondary duplicate action saves the current draft before creating the copy"},{"ancestorTitles":[],"duration":878,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"pane navigation focuses the existing preview without changing the pending draft","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715688964,"status":"passed","title":"pane navigation focuses the existing preview without changing the pending draft"},{"ancestorTitles":[],"duration":481,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"deep link loads the exact variant named in the route","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"startAt":1793715689842,"status":"passed","title":"deep link loads the exact variant named in the route"},{"ancestorTitles":[],"duration":25,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a variant that does not exist shows a safe error instead of an empty editor","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"startAt":1793715690323,"status":"passed","title":"a variant that does not exist shows a safe error instead of an empty editor"},{"ancestorTitles":[],"duration":47,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"another user's variant is refused by the server and never rendered","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715690348,"status":"passed","title":"another user's variant is refused by the server and never rendered"},{"ancestorTitles":[],"duration":54,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a denied CV read has localized permission context without a write or retry","invocations":1,"location":null,"numPassingAsserts":5,"retryReasons":[],"startAt":1793715690395,"status":"passed","title":"a denied CV read has localized permission context without a write or retry"},{"ancestorTitles":[],"duration":254,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a temporary CV opening failure retries reads and restores focus to the editor without saving","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715690449,"status":"passed","title":"a temporary CV opening failure retries reads and restores focus to the editor without saving"},{"ancestorTitles":[],"duration":1342,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"Bokmål history localizes known sources while preserving unknown metadata and versions","invocations":1,"location":null,"numPassingAsserts":8,"retryReasons":[],"startAt":1793715690703,"status":"passed","title":"Bokmål history localizes known sources while preserving unknown metadata and versions"},{"ancestorTitles":[],"duration":982,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"invalid names are explained and are not silently autosaved","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715692045,"status":"passed","title":"invalid names are explained and are not silently autosaved"},{"ancestorTitles":[],"duration":1665,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"failed autosave is visible and can be retried with the latest data","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715693028,"status":"passed","title":"failed autosave is visible and can be retried with the latest data"},{"ancestorTitles":[],"duration":1820,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"session undo and redo restore content edits before autosave","invocations":1,"location":null,"numPassingAsserts":6,"retryReasons":[],"startAt":1793715694694,"status":"passed","title":"session undo and redo restore content edits before autosave"},{"ancestorTitles":[],"duration":1603,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"queued saves use acknowledged server versions without replacing newer local editing state","invocations":1,"location":null,"numPassingAsserts":5,"retryReasons":[],"startAt":1793715696514,"status":"passed","title":"queued saves use acknowledged server versions without replacing newer local editing state"},{"ancestorTitles":[],"duration":3564,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"revision conflict retains the draft and blocks later autosaves until explicit reload","invocations":1,"location":null,"numPassingAsserts":10,"retryReasons":[],"startAt":1793715698117,"status":"passed","title":"revision conflict retains the draft and blocks later autosaves until explicit reload"},{"ancestorTitles":[],"duration":2844,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"edits made while a confirmed reload is in flight remain recoverable","invocations":1,"location":null,"numPassingAsserts":5,"retryReasons":[],"startAt":1793715701681,"status":"passed","title":"edits made while a confirmed reload is in flight remain recoverable"},{"ancestorTitles":[],"duration":2807,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"restoring history uses the current version and never replaces edits made during the request","invocations":1,"location":null,"numPassingAsserts":6,"retryReasons":[],"startAt":1793715704525,"status":"passed","title":"restoring history uses the current version and never replaces edits made during the request"},{"ancestorTitles":[],"duration":1598,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"Content is the primary studio panel and all advanced tabs retain their controls","invocations":1,"location":null,"numPassingAsserts":14,"retryReasons":[],"startAt":1793715707333,"status":"passed","title":"Content is the primary studio panel and all advanced tabs retain their controls"},{"ancestorTitles":[],"duration":2258,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"choosing a template restores its own structure instead of inheriting the previous template layout","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715708931,"status":"passed","title":"choosing a template restores its own structure instead of inheriting the previous template layout"},{"ancestorTitles":[],"duration":1493,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"editor sections, design controls and document settings render in Bokmål","invocations":1,"location":null,"numPassingAsserts":7,"retryReasons":[],"startAt":1793715711189,"status":"passed","title":"editor sections, design controls and document settings render in Bokmål"},{"ancestorTitles":[],"duration":1593,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"internal navigation warns and can be cancelled before discarding a pending edit","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715712682,"status":"passed","title":"internal navigation warns and can be cancelled before discarding a pending edit"},{"ancestorTitles":[],"duration":10297,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"custom entries can be added, edited, reordered and deleted with confirmation","invocations":1,"location":null,"numPassingAsserts":16,"retryReasons":[],"startAt":1793715714276,"status":"passed","title":"custom entries can be added, edited, reordered and deleted with confirmation"},{"ancestorTitles":[],"duration":4207,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P5-10 PRES-C01 C07] source-backed entry edits identify their scope and save only this CV","invocations":1,"location":null,"numPassingAsserts":8,"retryReasons":[],"startAt":1793715724574,"status":"passed","title":"[P5-10 PRES-C01 C07] source-backed entry edits identify their scope and save only this CV"},{"ancestorTitles":[],"duration":6000,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P5-10 PRES-C07 C10] resetting one entry field preserves omission, sibling override and order and supports undo","invocations":1,"location":null,"numPassingAsserts":12,"retryReasons":[],"startAt":1793715728781,"status":"passed","title":"[P5-10 PRES-C07 C10] resetting one entry field preserves omission, sibling override and order and supports undo"},{"ancestorTitles":[],"duration":3730,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P5-10 PRES-C07 C10 E08] omitted entries remain editable and retain their draft after a failed save","invocations":1,"location":null,"numPassingAsserts":6,"retryReasons":[],"startAt":1793715734782,"status":"passed","title":"[P5-10 PRES-C07 C10 E08] omitted entries remain editable and retain their draft after a failed save"},{"ancestorTitles":[],"duration":2168,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P5-10 PRES-C01 C07] section content reset inherits source without changing omission or presentation","invocations":1,"location":null,"numPassingAsserts":6,"retryReasons":[],"startAt":1793715738512,"status":"passed","title":"[P5-10 PRES-C01 C07] section content reset inherits source without changing omission or presentation"},{"ancestorTitles":[],"duration":5626,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"profile-backed sections expand, reorder, hide and persist variant-only overrides","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715740680,"status":"passed","title":"profile-backed sections expand, reorder, hide and persist variant-only overrides"},{"ancestorTitles":[],"duration":1803,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"focusing a preview retry control keeps its pointer target stationary","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"startAt":1793715746306,"status":"passed","title":"focusing a preview retry control keeps its pointer target stationary"},{"ancestorTitles":[],"duration":1772,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"preview failure is visible and retryable without leaving the editor","invocations":1,"location":null,"numPassingAsserts":6,"retryReasons":[],"startAt":1793715748109,"status":"passed","title":"preview failure is visible and retryable without leaving the editor"},{"ancestorTitles":[],"duration":847,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P5-11 PRES-C06 E08] automatic fit attaches when the asynchronously loaded preview pane appears","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"startAt":1793715749881,"status":"passed","title":"[P5-11 PRES-C06 E08] automatic fit attaches when the asynchronously loaded preview pane appears"},{"ancestorTitles":[],"duration":1248,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P5-11 PRES-C06 C12] page count is announced only after the renderer has settled","invocations":1,"location":null,"numPassingAsserts":7,"retryReasons":[],"startAt":1793715750728,"status":"passed","title":"[P5-11 PRES-C06 C12] page count is announced only after the renderer has settled"},{"ancestorTitles":[],"duration":2645,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P5-11 PRES-C06 E09] overlapping preview successes and failures cannot replace the newest document","invocations":1,"location":null,"numPassingAsserts":11,"retryReasons":[],"startAt":1793715751976,"status":"passed","title":"[P5-11 PRES-C06 E09] overlapping preview successes and failures cannot replace the newest document"},{"ancestorTitles":[],"duration":1137,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P5-11 PRES-C06 C10 E08] returning from preview focuses the existing editor without changing the pending draft","invocations":1,"location":null,"numPassingAsserts":7,"retryReasons":[],"startAt":1793715754621,"status":"passed","title":"[P5-11 PRES-C06 C10 E08] returning from preview focuses the existing editor without changing the pending draft"},{"ancestorTitles":[],"duration":2148,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-C11 PRES-C07] whole-document AI Apply changes only an explicitly accepted CV override","invocations":1,"location":null,"numPassingAsserts":12,"retryReasons":[],"startAt":1793715755758,"status":"passed","title":"[PRES-C11 PRES-C07] whole-document AI Apply changes only an explicitly accepted CV override"},{"ancestorTitles":[],"duration":1684,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-C11 PRES-C07] whole-document AI Reject changes only an explicitly accepted CV override","invocations":1,"location":null,"numPassingAsserts":11,"retryReasons":[],"startAt":1793715757906,"status":"passed","title":"[PRES-C11 PRES-C07] whole-document AI Reject changes only an explicitly accepted CV override"},{"ancestorTitles":[],"duration":1935,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-C11] unsafe whole-document response (invalid JSON) cannot be applied","invocations":1,"location":null,"numPassingAsserts":7,"retryReasons":[],"startAt":1793715759590,"status":"passed","title":"[PRES-C11] unsafe whole-document response (invalid JSON) cannot be applied"},{"ancestorTitles":[],"duration":1765,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-C11] unsafe whole-document response (missing original ID) cannot be applied","invocations":1,"location":null,"numPassingAsserts":7,"retryReasons":[],"startAt":1793715761525,"status":"passed","title":"[PRES-C11] unsafe whole-document response (missing original ID) cannot be applied"},{"ancestorTitles":[],"duration":1617,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-C11] unsafe whole-document response (duplicate original ID) cannot be applied","invocations":1,"location":null,"numPassingAsserts":7,"retryReasons":[],"startAt":1793715763290,"status":"passed","title":"[PRES-C11] unsafe whole-document response (duplicate original ID) cannot be applied"},{"ancestorTitles":[],"duration":5508,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"bound document generation saves the pending draft, reviews server Original, and accepted AI remains undoable","invocations":1,"location":null,"numPassingAsserts":11,"retryReasons":[],"startAt":1793715764907,"status":"passed","title":"bound document generation saves the pending draft, reviews server Original, and accepted AI remains undoable"},{"ancestorTitles":[],"duration":3011,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a newer draft is flushed before stale proposal acceptance fails without rebasing or changing content","invocations":1,"location":null,"numPassingAsserts":13,"retryReasons":[],"startAt":1793715770415,"status":"passed","title":"a newer draft is flushed before stale proposal acceptance fails without rebasing or changing content"},{"ancestorTitles":[],"duration":3692,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"late document proposals cannot return after tab unmount or a source undo","invocations":1,"location":null,"numPassingAsserts":6,"retryReasons":[],"startAt":1793715773427,"status":"passed","title":"late document proposals cannot return after tab unmount or a source undo"},{"ancestorTitles":[],"duration":3488,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"bound section:skills assistant sends explicit scope and edited wording to server acceptance","invocations":1,"location":null,"numPassingAsserts":5,"retryReasons":[],"startAt":1793715777120,"status":"passed","title":"bound section:skills assistant sends explicit scope and edited wording to server acceptance"},{"ancestorTitles":[],"duration":3806,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"bound custom:sample assistant sends explicit scope and edited wording to server acceptance","invocations":1,"location":null,"numPassingAsserts":5,"retryReasons":[],"startAt":1793715780608,"status":"passed","title":"bound custom:sample assistant sends explicit scope and edited wording to server acceptance"},{"ancestorTitles":[],"duration":3582,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"bound entry:experience:job-1 assistant sends explicit scope and edited wording to server acceptance","invocations":1,"location":null,"numPassingAsserts":5,"retryReasons":[],"startAt":1793715784414,"status":"passed","title":"bound entry:experience:job-1 assistant sends explicit scope and edited wording to server acceptance"},{"ancestorTitles":[],"duration":2608,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"user edits made during server acceptance are retained instead of overwritten by its late saved response","invocations":1,"location":null,"numPassingAsserts":9,"retryReasons":[],"startAt":1793715787996,"status":"passed","title":"user edits made during server acceptance are retained instead of overwritten by its late saved response"}],"endTime":1793715790607,"message":"","name":"C:\\Users\\Connor\\.codex\\worktrees\\direct-roadmap-integration\\Job tracker\\job-tracker-ui\\src\\cv-builder-deep-link.test.tsx","startTime":1793715651303,"status":"passed","summary":""}],"wasInterrupted":false} diff --git a/docs/ui-modernisation/evidence/ai-context/a3-ai-context-red.json b/docs/ui-modernisation/evidence/ai-context/a3-ai-context-red.json new file mode 100644 index 00000000..4350735a --- /dev/null +++ b/docs/ui-modernisation/evidence/ai-context/a3-ai-context-red.json @@ -0,0 +1 @@ +{"numFailedTestSuites":1,"numFailedTests":4,"numPassedTestSuites":0,"numPassedTests":4,"numPendingTestSuites":0,"numPendingTests":15,"numRuntimeErrorTestSuites":0,"numTodoTests":0,"numTotalTestSuites":1,"numTotalTests":23,"openHandles":[],"snapshot":{"added":0,"didUpdate":false,"failure":false,"filesAdded":0,"filesRemoved":0,"filesRemovedList":[],"filesUnmatched":0,"filesUpdated":0,"matched":0,"total":0,"unchecked":0,"uncheckedKeysByFile":[],"unmatched":0,"updated":0},"startTime":1793715476674,"success":false,"testResults":[{"assertionResults":[{"ancestorTitles":[],"duration":null,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"direct Improve writing action retains explicit review","invocations":1,"location":null,"numPassingAsserts":0,"retryReasons":[],"startAt":1793715482157,"status":"pending","title":"direct Improve writing action retains explicit review"},{"ancestorTitles":[],"duration":null,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"direct Suggest content action retains explicit review","invocations":1,"location":null,"numPassingAsserts":0,"retryReasons":[],"startAt":1793715482157,"status":"pending","title":"direct Suggest content action retains explicit review"},{"ancestorTitles":[],"duration":null,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"direct Grammar check action retains explicit review","invocations":1,"location":null,"numPassingAsserts":0,"retryReasons":[],"startAt":1793715482157,"status":"pending","title":"direct Grammar check action retains explicit review"},{"ancestorTitles":[],"duration":null,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"direct Shorter action retains explicit review","invocations":1,"location":null,"numPassingAsserts":0,"retryReasons":[],"startAt":1793715482157,"status":"pending","title":"direct Shorter action retains explicit review"},{"ancestorTitles":[],"duration":null,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"empty source requests career facts without making an AI request","invocations":1,"location":null,"numPassingAsserts":0,"retryReasons":[],"startAt":1793715482157,"status":"pending","title":"empty source requests career facts without making an AI request"},{"ancestorTitles":[],"duration":null,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"section AI uses the CV document language and requires explicit server acceptance","invocations":1,"location":null,"numPassingAsserts":0,"retryReasons":[],"startAt":1793715482157,"status":"pending","title":"section AI uses the CV document language and requires explicit server acceptance"},{"ancestorTitles":[],"duration":null,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"section AI controls render in Bokmål without changing the document language","invocations":1,"location":null,"numPassingAsserts":0,"retryReasons":[],"startAt":1793715482157,"status":"pending","title":"section AI controls render in Bokmål without changing the document language"},{"ancestorTitles":[],"duration":null,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-C11] Reject removes the suggestion without accepting content","invocations":1,"location":null,"numPassingAsserts":0,"retryReasons":[],"startAt":1793715482157,"status":"pending","title":"[PRES-C11] Reject removes the suggestion without accepting content"},{"ancestorTitles":[],"duration":null,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-C11] Close removes the suggestion without accepting content","invocations":1,"location":null,"numPassingAsserts":0,"retryReasons":[],"startAt":1793715482157,"status":"pending","title":"[PRES-C11] Close removes the suggestion without accepting content"},{"ancestorTitles":[],"duration":null,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-C11] accepts the user's edited suggestion with the original proposal token","invocations":1,"location":null,"numPassingAsserts":0,"retryReasons":[],"startAt":1793715482157,"status":"pending","title":"[PRES-C11] accepts the user's edited suggestion with the original proposal token"},{"ancestorTitles":[],"duration":null,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-C11] a failed suggestion can be retried without accepting content","invocations":1,"location":null,"numPassingAsserts":0,"retryReasons":[],"startAt":1793715482157,"status":"pending","title":"[PRES-C11] a failed suggestion can be retried without accepting content"},{"ancestorTitles":[],"duration":null,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"closing and reopening ignores an old request even after a newer suggestion completes","invocations":1,"location":null,"numPassingAsserts":0,"retryReasons":[],"startAt":1793715482157,"status":"pending","title":"closing and reopening ignores an old request even after a newer suggestion completes"},{"ancestorTitles":[],"duration":295,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a changed text invalidates a pending suggestion","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715482157,"status":"passed","title":"a changed text invalidates a pending suggestion"},{"ancestorTitles":[],"duration":107,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a changed target invalidates a pending suggestion","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715482452,"status":"passed","title":"a changed target invalidates a pending suggestion"},{"ancestorTitles":[],"duration":101,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a changed document language invalidates a pending suggestion","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715482559,"status":"passed","title":"a changed document language invalidates a pending suggestion"},{"ancestorTitles":[],"duration":153,"failing":false,"failureDetails":[{"matcherResult":{"pass":true,"message":"expect(element).not.toBeInTheDocument()\n\nexpected document not to contain element, found instead"}}],"failureMessages":["Error: expect(element).not.toBeInTheDocument()\n\nexpected document not to contain element, found instead\n at toBeInTheDocument (C:\\Users\\Connor\\.codex\\worktrees\\direct-roadmap-integration\\Job tracker\\job-tracker-ui\\src\\ai-section-assistant.test.tsx:188:69)"],"fullName":"a changed context invalidates a pending suggestion","invocations":1,"location":null,"numPassingAsserts":0,"retryReasons":[],"startAt":1793715482661,"status":"failed","title":"a changed context invalidates a pending suggestion"},{"ancestorTitles":[],"duration":119,"failing":false,"failureDetails":[{"matcherResult":{"pass":true,"message":"expect(element).not.toBeInTheDocument()\n\nexpected document not to contain element, found instead"}}],"failureMessages":["Error: expect(element).not.toBeInTheDocument()\n\nexpected document not to contain element, found instead\n at toBeInTheDocument (C:\\Users\\Connor\\.codex\\worktrees\\direct-roadmap-integration\\Job tracker\\job-tracker-ui\\src\\ai-section-assistant.test.tsx:188:69)"],"fullName":"a changed section name invalidates a pending suggestion","invocations":1,"location":null,"numPassingAsserts":0,"retryReasons":[],"startAt":1793715482827,"status":"failed","title":"a changed section name invalidates a pending suggestion"},{"ancestorTitles":[],"duration":187,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"changed text removes an existing review before it can be accepted","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715482946,"status":"passed","title":"changed text removes an existing review before it can be accepted"},{"ancestorTitles":[],"duration":140,"failing":false,"failureDetails":[{"matcherResult":{"pass":true,"message":"expect(element).not.toBeInTheDocument()\n\nexpected document not to contain element, found instead"}}],"failureMessages":["Error: expect(element).not.toBeInTheDocument()\n\nexpected document not to contain element, found instead\n at toBeInTheDocument (C:\\Users\\Connor\\.codex\\worktrees\\direct-roadmap-integration\\Job tracker\\job-tracker-ui\\src\\ai-section-assistant.test.tsx:203:62)"],"fullName":"changed context removes an existing review before it can be accepted","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"startAt":1793715483133,"status":"failed","title":"changed context removes an existing review before it can be accepted"},{"ancestorTitles":[],"duration":125,"failing":false,"failureDetails":[{"matcherResult":{"pass":true,"message":"expect(element).not.toBeInTheDocument()\n\nexpected document not to contain element, found instead"}}],"failureMessages":["Error: expect(element).not.toBeInTheDocument()\n\nexpected document not to contain element, found instead\n at toBeInTheDocument (C:\\Users\\Connor\\.codex\\worktrees\\direct-roadmap-integration\\Job tracker\\job-tracker-ui\\src\\ai-section-assistant.test.tsx:203:62)"],"fullName":"changed section name removes an existing review before it can be accepted","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"startAt":1793715483273,"status":"failed","title":"changed section name removes an existing review before it can be accepted"},{"ancestorTitles":[],"duration":null,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"regeneration replaces the proposal and its token before acceptance","invocations":1,"location":null,"numPassingAsserts":0,"retryReasons":[],"startAt":1793715483399,"status":"pending","title":"regeneration replaces the proposal and its token before acceptance"},{"ancestorTitles":[],"duration":null,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"Reject invalidates a pending regeneration and clears the previous review","invocations":1,"location":null,"numPassingAsserts":0,"retryReasons":[],"startAt":1793715483399,"status":"pending","title":"Reject invalidates a pending regeneration and clears the previous review"},{"ancestorTitles":[],"duration":null,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"failed server acceptance keeps the edited review and allows retry without duplicate submits","invocations":1,"location":null,"numPassingAsserts":0,"retryReasons":[],"startAt":1793715483399,"status":"pending","title":"failed server acceptance keeps the edited review and allows retry without duplicate submits"}],"endTime":1793715483421,"message":" ● a changed context invalidates a pending suggestion\n\n expect(element).not.toBeInTheDocument()\n\n expected document not to contain element, found instead\n\n 186 | rerenderAssistant(updates);\n 187 | await act(async () => { request.resolve(proposal(\"Stale source suggestion\")); });\n > 188 | expect(screen.queryByDisplayValue(\"Stale source suggestion\")).not.toBeInTheDocument();\n | ^\n 189 | expect(screen.queryByRole(\"button\", { name: \"Apply\" })).not.toBeInTheDocument();\n 190 | expect(onAccept).not.toHaveBeenCalled();\n 191 | });\n\n at toBeInTheDocument (src/ai-section-assistant.test.tsx:188:69)\n\n ● a changed section name invalidates a pending suggestion\n\n expect(element).not.toBeInTheDocument()\n\n expected document not to contain element, found instead\n\n 186 | rerenderAssistant(updates);\n 187 | await act(async () => { request.resolve(proposal(\"Stale source suggestion\")); });\n > 188 | expect(screen.queryByDisplayValue(\"Stale source suggestion\")).not.toBeInTheDocument();\n | ^\n 189 | expect(screen.queryByRole(\"button\", { name: \"Apply\" })).not.toBeInTheDocument();\n 190 | expect(onAccept).not.toHaveBeenCalled();\n 191 | });\n\n at toBeInTheDocument (src/ai-section-assistant.test.tsx:188:69)\n\n ● changed context removes an existing review before it can be accepted\n\n expect(element).not.toBeInTheDocument()\n\n expected document not to contain element, found instead\n\n 201 | expect(await screen.findByDisplayValue(\"Proposed wording\")).toBeInTheDocument();\n 202 | rerenderAssistant(updates);\n > 203 | expect(screen.queryByDisplayValue(\"Proposed wording\")).not.toBeInTheDocument();\n | ^\n 204 | expect(screen.queryByRole(\"button\", { name: \"Apply\" })).not.toBeInTheDocument();\n 205 | expect(onAccept).not.toHaveBeenCalled();\n 206 | });\n\n at toBeInTheDocument (src/ai-section-assistant.test.tsx:203:62)\n\n ● changed section name removes an existing review before it can be accepted\n\n expect(element).not.toBeInTheDocument()\n\n expected document not to contain element, found instead\n\n 201 | expect(await screen.findByDisplayValue(\"Proposed wording\")).toBeInTheDocument();\n 202 | rerenderAssistant(updates);\n > 203 | expect(screen.queryByDisplayValue(\"Proposed wording\")).not.toBeInTheDocument();\n | ^\n 204 | expect(screen.queryByRole(\"button\", { name: \"Apply\" })).not.toBeInTheDocument();\n 205 | expect(onAccept).not.toHaveBeenCalled();\n 206 | });\n\n at toBeInTheDocument (src/ai-section-assistant.test.tsx:203:62)\n","name":"C:\\Users\\Connor\\.codex\\worktrees\\direct-roadmap-integration\\Job tracker\\job-tracker-ui\\src\\ai-section-assistant.test.tsx","startTime":1793715478116,"status":"failed","summary":""}],"wasInterrupted":false} diff --git a/docs/ui-modernisation/evidence/ai-context/a3-ai-settings-baseline.json b/docs/ui-modernisation/evidence/ai-context/a3-ai-settings-baseline.json new file mode 100644 index 00000000..897bbe2d --- /dev/null +++ b/docs/ui-modernisation/evidence/ai-context/a3-ai-settings-baseline.json @@ -0,0 +1 @@ +{"numFailedTestSuites":0,"numFailedTests":0,"numPassedTestSuites":5,"numPassedTests":58,"numPendingTestSuites":0,"numPendingTests":0,"numRuntimeErrorTestSuites":0,"numTodoTests":0,"numTotalTestSuites":5,"numTotalTests":58,"openHandles":[],"snapshot":{"added":0,"didUpdate":false,"failure":false,"filesAdded":0,"filesRemoved":0,"filesRemovedList":[],"filesUnmatched":0,"filesUpdated":0,"matched":0,"total":0,"unchecked":0,"uncheckedKeysByFile":[],"unmatched":0,"updated":0},"startTime":1793715317482,"success":true,"testResults":[{"assertionResults":[{"ancestorTitles":[],"duration":1000,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"each selected Settings section has a named panel linked to its tab and remains selectable on phones","invocations":1,"location":null,"numPassingAsserts":13,"retryReasons":[],"startAt":1793715323660,"status":"passed","title":"each selected Settings section has a named panel linked to its tab and remains selectable on phones"},{"ancestorTitles":[],"duration":634,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"settings view has no accent picker and uses one follow-up section, one notification section","invocations":1,"location":null,"numPassingAsserts":9,"retryReasons":[],"startAt":1793715324661,"status":"passed","title":"settings view has no accent picker and uses one follow-up section, one notification section"},{"ancestorTitles":[],"duration":261,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"AI privacy settings are server-backed and external processing is local-only by default","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715325295,"status":"passed","title":"AI privacy settings are server-backed and external processing is local-only by default"},{"ancestorTitles":[],"duration":4624,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-S03] failed notification save preserves the draft for an explicit retry","invocations":1,"location":null,"numPassingAsserts":6,"retryReasons":[],"startAt":1793715325556,"status":"passed","title":"[PRES-S03] failed notification save preserves the draft for an explicit retry"},{"ancestorTitles":[],"duration":594,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-S03 PRES-W11] saving one follow-up rule preserves the other scenarios","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"startAt":1793715330180,"status":"passed","title":"[PRES-S03 PRES-W11] saving one follow-up rule preserves the other scenarios"},{"ancestorTitles":[],"duration":382,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-S03 PRES-J05] table and theme preferences keep their independent callbacks","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715330774,"status":"passed","title":"[PRES-S03 PRES-J05] table and theme preferences keep their independent callbacks"},{"ancestorTitles":[],"duration":762,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-S03 W11] the Settings session retains independent pending Rules fields across tab unmounts","invocations":1,"location":null,"numPassingAsserts":6,"retryReasons":[],"startAt":1793715331156,"status":"passed","title":"[PRES-S03 W11] the Settings session retains independent pending Rules fields across tab unmounts"},{"ancestorTitles":[],"duration":983,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-S03] failed Rules save remains actionable after tab return and explicit retry clears dirty state","invocations":1,"location":null,"numPassingAsserts":8,"retryReasons":[],"startAt":1793715331918,"status":"passed","title":"[PRES-S03] failed Rules save remains actionable after tab return and explicit retry clears dirty state"},{"ancestorTitles":[],"duration":1058,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-S03] invalid and empty Rules input and associated validation survive internal navigation","invocations":1,"location":null,"numPassingAsserts":7,"retryReasons":[],"startAt":1793715332901,"status":"passed","title":"[PRES-S03] invalid and empty Rules input and associated validation survive internal navigation"},{"ancestorTitles":[],"duration":781,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-S03] explicit discard resets only the Rules draft to its saved baseline without writing","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715333959,"status":"passed","title":"[PRES-S03] explicit discard resets only the Rules draft to its saved baseline without writing"},{"ancestorTitles":[],"duration":982,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-S03] later edits stay dirty when an earlier Rules save completes after a tab switch","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715334740,"status":"passed","title":"[PRES-S03] later edits stay dirty when an earlier Rules save completes after a tab switch"},{"ancestorTitles":[],"duration":614,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-S03 E09] leaving the Settings session disposes its draft and pending responses","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715335722,"status":"passed","title":"[PRES-S03 E09] leaving the Settings session disposes its draft and pending responses"},{"ancestorTitles":[],"duration":718,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-S03] switching locale while Rules is hidden does not reload or overwrite its pending draft","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715336336,"status":"passed","title":"[PRES-S03] switching locale while Rules is hidden does not reload or overwrite its pending draft"},{"ancestorTitles":[],"duration":576,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-S03] Rules draft updates do not refetch an unrelated notification preference","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"startAt":1793715337055,"status":"passed","title":"[PRES-S03] Rules draft updates do not refetch an unrelated notification preference"},{"ancestorTitles":[],"duration":426,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P7-09 preferences] initial notification failure offers a single GET Retry and recovers its vanished focused action","invocations":1,"location":null,"numPassingAsserts":8,"retryReasons":[],"startAt":1793715337631,"status":"passed","title":"[P7-09 preferences] initial notification failure offers a single GET Retry and recovers its vanished focused action"},{"ancestorTitles":[],"duration":907,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P7-09 preferences] notification drafts survive internal sections and locale changes without a GET or save","invocations":1,"location":null,"numPassingAsserts":7,"retryReasons":[],"startAt":1793715338057,"status":"passed","title":"[P7-09 preferences] notification drafts survive internal sections and locale changes without a GET or save"},{"ancestorTitles":[],"duration":932,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P7-09 preferences] one held notification save acknowledges its snapshot and preserves later edits across sections","invocations":1,"location":null,"numPassingAsserts":8,"retryReasons":[],"startAt":1793715338964,"status":"passed","title":"[P7-09 preferences] one held notification save acknowledges its snapshot and preserves later edits across sections"},{"ancestorTitles":[],"duration":811,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P7-09 preferences] failed notification save keeps its current-locale draft and retries only the original Save","invocations":1,"location":null,"numPassingAsserts":8,"retryReasons":[],"startAt":1793715339896,"status":"passed","title":"[P7-09 preferences] failed notification save keeps its current-locale draft and retries only the original Save"},{"ancestorTitles":[],"duration":675,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P7-09 preferences] discarding a notification draft leaves the independent Rules draft untouched","invocations":1,"location":null,"numPassingAsserts":6,"retryReasons":[],"startAt":1793715340707,"status":"passed","title":"[P7-09 preferences] discarding a notification draft leaves the independent Rules draft untouched"},{"ancestorTitles":[],"duration":689,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P7-09 preferences] a disposed notification save cannot publish into surviving providers or a new Settings session","invocations":1,"location":null,"numPassingAsserts":7,"retryReasons":[],"startAt":1793715341382,"status":"passed","title":"[P7-09 preferences] a disposed notification save cannot publish into surviving providers or a new Settings session"},{"ancestorTitles":[],"duration":500,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P7-09 preferences] Rules load failure follows locale without reloading and Retry retains the six-field contract","invocations":1,"location":null,"numPassingAsserts":11,"retryReasons":[],"startAt":1793715342072,"status":"passed","title":"[P7-09 preferences] Rules load failure follows locale without reloading and Retry retains the six-field contract"}],"endTime":1793715342574,"message":"","name":"C:\\Users\\Connor\\.codex\\worktrees\\direct-roadmap-integration\\Job tracker\\job-tracker-ui\\src\\settings-view.test.tsx","startTime":1793715318994,"status":"passed","summary":""},{"assertionResults":[{"ancestorTitles":[],"duration":193,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"direct Improve writing action retains explicit review","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715344037,"status":"passed","title":"direct Improve writing action retains explicit review"},{"ancestorTitles":[],"duration":107,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"direct Suggest content action retains explicit review","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715344230,"status":"passed","title":"direct Suggest content action retains explicit review"},{"ancestorTitles":[],"duration":108,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"direct Grammar check action retains explicit review","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715344337,"status":"passed","title":"direct Grammar check action retains explicit review"},{"ancestorTitles":[],"duration":77,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"direct Shorter action retains explicit review","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715344445,"status":"passed","title":"direct Shorter action retains explicit review"},{"ancestorTitles":[],"duration":49,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"empty source requests career facts without making an AI request","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"startAt":1793715344522,"status":"passed","title":"empty source requests career facts without making an AI request"},{"ancestorTitles":[],"duration":234,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"section AI uses the CV document language and requires explicit server acceptance","invocations":1,"location":null,"numPassingAsserts":6,"retryReasons":[],"startAt":1793715344571,"status":"passed","title":"section AI uses the CV document language and requires explicit server acceptance"},{"ancestorTitles":[],"duration":51,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"section AI controls render in Bokmål without changing the document language","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715344806,"status":"passed","title":"section AI controls render in Bokmål without changing the document language"},{"ancestorTitles":[],"duration":153,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-C11] Reject removes the suggestion without accepting content","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715344857,"status":"passed","title":"[PRES-C11] Reject removes the suggestion without accepting content"},{"ancestorTitles":[],"duration":176,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-C11] Close removes the suggestion without accepting content","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715345010,"status":"passed","title":"[PRES-C11] Close removes the suggestion without accepting content"},{"ancestorTitles":[],"duration":217,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-C11] accepts the user's edited suggestion with the original proposal token","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715345186,"status":"passed","title":"[PRES-C11] accepts the user's edited suggestion with the original proposal token"},{"ancestorTitles":[],"duration":182,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[PRES-C11] a failed suggestion can be retried without accepting content","invocations":1,"location":null,"numPassingAsserts":5,"retryReasons":[],"startAt":1793715345403,"status":"passed","title":"[PRES-C11] a failed suggestion can be retried without accepting content"},{"ancestorTitles":[],"duration":231,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"closing and reopening ignores an old request even after a newer suggestion completes","invocations":1,"location":null,"numPassingAsserts":6,"retryReasons":[],"startAt":1793715345585,"status":"passed","title":"closing and reopening ignores an old request even after a newer suggestion completes"},{"ancestorTitles":[],"duration":94,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a changed text invalidates a pending suggestion","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715345816,"status":"passed","title":"a changed text invalidates a pending suggestion"},{"ancestorTitles":[],"duration":94,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a changed target invalidates a pending suggestion","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715345910,"status":"passed","title":"a changed target invalidates a pending suggestion"},{"ancestorTitles":[],"duration":104,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a changed document language invalidates a pending suggestion","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793715346004,"status":"passed","title":"a changed document language invalidates a pending suggestion"},{"ancestorTitles":[],"duration":138,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"source changes remove an existing review before it can be accepted","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715346108,"status":"passed","title":"source changes remove an existing review before it can be accepted"},{"ancestorTitles":[],"duration":254,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"regeneration replaces the proposal and its token before acceptance","invocations":1,"location":null,"numPassingAsserts":5,"retryReasons":[],"startAt":1793715346246,"status":"passed","title":"regeneration replaces the proposal and its token before acceptance"},{"ancestorTitles":[],"duration":156,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"Reject invalidates a pending regeneration and clears the previous review","invocations":1,"location":null,"numPassingAsserts":6,"retryReasons":[],"startAt":1793715346500,"status":"passed","title":"Reject invalidates a pending regeneration and clears the previous review"},{"ancestorTitles":[],"duration":305,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"failed server acceptance keeps the edited review and allows retry without duplicate submits","invocations":1,"location":null,"numPassingAsserts":10,"retryReasons":[],"startAt":1793715346656,"status":"passed","title":"failed server acceptance keeps the edited review and allows retry without duplicate submits"}],"endTime":1793715346963,"message":"","name":"C:\\Users\\Connor\\.codex\\worktrees\\direct-roadmap-integration\\Job tracker\\job-tracker-ui\\src\\ai-section-assistant.test.tsx","startTime":1793715342593,"status":"passed","summary":""},{"assertionResults":[{"ancestorTitles":[],"duration":128,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"keeps its heading and named loading state, then retries only a failed usage GET","invocations":1,"location":null,"numPassingAsserts":7,"retryReasons":[],"startAt":1793715348497,"status":"passed","title":"keeps its heading and named loading state, then retries only a failed usage GET"},{"ancestorTitles":[],"duration":76,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"billing failure remains visible beside usage and its Retry only reads billing","invocations":1,"location":null,"numPassingAsserts":6,"retryReasons":[],"startAt":1793715348626,"status":"passed","title":"billing failure remains visible beside usage and its Retry only reads billing"},{"ancestorTitles":[],"duration":44,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"locale changes format numbers and byte decimals without reloading; zero storage limit stays finite","invocations":1,"location":null,"numPassingAsserts":5,"retryReasons":[],"startAt":1793715348703,"status":"passed","title":"locale changes format numbers and byte decimals without reloading; zero storage limit stays finite"},{"ancestorTitles":[],"duration":41,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"one billing POST ignores a late failure after unmount","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"startAt":1793715348747,"status":"passed","title":"one billing POST ignores a late failure after unmount"},{"ancestorTitles":[],"duration":48,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"one billing POST ignores a late failure after session","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"startAt":1793715348788,"status":"passed","title":"one billing POST ignores a late failure after session"},{"ancestorTitles":[],"duration":60,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"late billing success after unmount never consumes the redirect URL","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"startAt":1793715348836,"status":"passed","title":"late billing success after unmount never consumes the redirect URL"},{"ancestorTitles":[],"duration":44,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"late billing success after session never consumes the redirect URL","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"startAt":1793715348896,"status":"passed","title":"late billing success after session never consumes the redirect URL"},{"ancestorTitles":[],"duration":101,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a failed billing POST offers the existing explicit action without automatic replay","invocations":1,"location":null,"numPassingAsserts":6,"retryReasons":[],"startAt":1793715348941,"status":"passed","title":"a failed billing POST offers the existing explicit action without automatic replay"},{"ancestorTitles":[],"duration":35,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"shows monthly AI call and token limits","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715349042,"status":"passed","title":"shows monthly AI call and token limits"},{"ancestorTitles":[],"duration":26,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"does not offer a false upgrade action when billing is not configured","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"startAt":1793715349077,"status":"passed","title":"does not offer a false upgrade action when billing is not configured"}],"endTime":1793715349104,"message":"","name":"C:\\Users\\Connor\\.codex\\worktrees\\direct-roadmap-integration\\Job tracker\\job-tracker-ui\\src\\ai-usage-card.test.tsx","startTime":1793715346978,"status":"passed","summary":""},{"assertionResults":[{"ancestorTitles":[],"duration":899,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P7-09 lifetime] an accepted import continues once across Notifications and Rules while a real Settings unmount stops queued writes","invocations":1,"location":null,"numPassingAsserts":17,"retryReasons":[],"startAt":1793715350570,"status":"passed","title":"[P7-09 lifetime] an accepted import continues once across Notifications and Rules while a real Settings unmount stops queued writes"},{"ancestorTitles":[],"duration":1073,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P7-09 lifetime] the General privacy owner keeps its draft and read across internal tabs while Backup remains lazy and disposable","invocations":1,"location":null,"numPassingAsserts":21,"retryReasons":[],"startAt":1793715351469,"status":"passed","title":"[P7-09 lifetime] the General privacy owner keeps its draft and read across internal tabs while Backup remains lazy and disposable"}],"endTime":1793715352543,"message":"","name":"C:\\Users\\Connor\\.codex\\worktrees\\direct-roadmap-integration\\Job tracker\\job-tracker-ui\\src\\settings-import-lifetime.test.tsx","startTime":1793715349114,"status":"passed","summary":""},{"assertionResults":[{"ancestorTitles":[],"duration":108,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P7-09 privacy] failed initial read has a read-only Retry and no perpetual loading","invocations":1,"location":null,"numPassingAsserts":5,"retryReasons":[],"startAt":1793715353790,"status":"passed","title":"[P7-09 privacy] failed initial read has a read-only Retry and no perpetual loading"},{"ancestorTitles":[],"duration":130,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P7-09 privacy] submitted acknowledgement preserves a newer edit and serializes Save","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715353898,"status":"passed","title":"[P7-09 privacy] submitted acknowledgement preserves a newer edit and serializes Save"},{"ancestorTitles":[],"duration":115,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P7-09 privacy] a failed save retains the draft and never replays through read recovery","invocations":1,"location":null,"numPassingAsserts":7,"retryReasons":[],"startAt":1793715354028,"status":"passed","title":"[P7-09 privacy] a failed save retains the draft and never replays through read recovery"},{"ancestorTitles":[],"duration":57,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P7-09 privacy] unmount ignores an old save acknowledgement and success notification","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"startAt":1793715354144,"status":"passed","title":"[P7-09 privacy] unmount ignores an old save acknowledgement and success notification"},{"ancestorTitles":[],"duration":111,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P7-09 privacy] pending save uses the current language without refetching the draft","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"startAt":1793715354201,"status":"passed","title":"[P7-09 privacy] pending save uses the current language without refetching the draft"},{"ancestorTitles":[],"duration":58,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P7-09 privacy] local-only capability permits revoking a historical external consent","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793715354312,"status":"passed","title":"[P7-09 privacy] local-only capability permits revoking a historical external consent"}],"endTime":1793715354370,"message":"","name":"C:\\Users\\Connor\\.codex\\worktrees\\direct-roadmap-integration\\Job tracker\\job-tracker-ui\\src\\ai-privacy-settings.test.tsx","startTime":1793715352555,"status":"passed","summary":""}],"wasInterrupted":false} diff --git a/job-tracker-ui/src/ai-section-assistant.test.tsx b/job-tracker-ui/src/ai-section-assistant.test.tsx index 53772922..0a8640b9 100644 --- a/job-tracker-ui/src/ai-section-assistant.test.tsx +++ b/job-tracker-ui/src/ai-section-assistant.test.tsx @@ -176,6 +176,8 @@ test.each([ ["text", { text: "Changed career facts" }], ["target", { targetId: "experience:job-2" }], ["document language", { documentLanguage: "en" }], + ["context", { context: "Different recorded job requirements" }], + ["section name", { sectionName: "Different section purpose" }], ] as const)("a changed %s invalidates a pending suggestion", async (_source, updates) => { const request = deferred(); const { onAccept, rerenderAssistant } = renderAssistant({ onGenerate: jest.fn().mockReturnValue(request.promise) }); @@ -188,12 +190,16 @@ test.each([ expect(onAccept).not.toHaveBeenCalled(); }); -test("source changes remove an existing review before it can be accepted", async () => { +test.each([ + ["text", { text: "Changed career facts" }], + ["context", { context: "Different recorded job requirements" }], + ["section name", { sectionName: "Different section purpose" }], +] as const)("changed %s removes an existing review before it can be accepted", async (_source, updates) => { const { onAccept, rerenderAssistant } = renderAssistant(); fireEvent.click(screen.getByRole("button", { name: "AI suggestions" })); fireEvent.click(screen.getByRole("button", { name: "Suggest" })); expect(await screen.findByDisplayValue("Proposed wording")).toBeInTheDocument(); - rerenderAssistant({ text: "Changed career facts" }); + rerenderAssistant(updates); expect(screen.queryByDisplayValue("Proposed wording")).not.toBeInTheDocument(); expect(screen.queryByRole("button", { name: "Apply" })).not.toBeInTheDocument(); expect(onAccept).not.toHaveBeenCalled(); diff --git a/job-tracker-ui/src/components/cv/AiSectionAssistant.tsx b/job-tracker-ui/src/components/cv/AiSectionAssistant.tsx index 5cc5a3ed..f8b1371d 100644 --- a/job-tracker-ui/src/components/cv/AiSectionAssistant.tsx +++ b/job-tracker-ui/src/components/cv/AiSectionAssistant.tsx @@ -42,7 +42,7 @@ export default function AiSectionAssistant({ sectionName, text, context, documen setBusy(false); setApplying(false); return () => { requestId.current += 1; }; - }, [text, targetId, normalizedLanguage, targetLanguage, canUseAi]); + }, [text, targetId, context, sectionName, normalizedLanguage, targetLanguage, canUseAi]); const discard = () => { requestId.current += 1;