3.7 KiB
Correspondence read and manual-note recovery
Baseline b9bb3c44; implementation/test/verifier c751b427 on codex/a3-ui-10.
Changes and preservation
- Superseded message reads cannot replace the current application or its error/loading state. Previous messages clear when the application changes; obsolete callbacks cannot start a previous-job read. The existing job/unmount lifecycle and request counter guard these boundaries.
- Manual note submission locks its captured form and rejects duplicate clicks. Rejected writes retain the draft and permit a deliberate retry. Old-job/unmounted completions cannot clear a newer draft, show an unrelated failure or trigger another read.
- A committed note followed by failed refresh clears the submitted draft and presents the existing read-retry notice. It does not report a failed write or invite another POST.
- Read errors translate at render time without another request or lost draft. Pending note rejection uses the current UI language. Existing Gmail connection/import/linking permissions and the manual note payload remain unchanged.
- Disabled character-count helper text remains readable; the first real-browser pending-state scan measured 4.46:1 before this correction. The input remains disabled. No accessibility rule was suppressed.
Verification
PASSED: 27 frontend cases across correspondence recovery and the existing Gmail import suite: 14 recovery cases plus 13 existing cases. Earlier 18/22/25/26-case runs overlap this final run. Red receipts retain three initial read-boundary failures, three manual-note failures and one unnecessary locale-read failure. An initial TypeScript failure from unsupported test-only exact selectors was corrected before the final successful build.
PASSED: production static build/TypeScript and scoped ESLint. No backend, dependency, schema or migration changed.
PASSED: eight controlled real-application journeys at 390/1440 widths × EN/NB × light/dark. Forty accessibility captures cover read error, rejected write, pending write, committed-write/read error and recovery. Sixteen intercepted write attempts comprise eight deliberate fixture500 rejections and eight fixture commitments. Each journey checks live language switching without extra reads, retained drafts, keyboard read retry, pending duplicate exclusion and read-only recovery after commitment. Zero page errors/unavailable API reads; external Google Fonts requests were blocked. The single pilot overlaps the final eight configurations. Incomplete-fixture and failed-contrast receipts are retained separately, not counted as passes.
Desktop light and mobile Bokmål dark captures were visually inspected. Existing nested correspondence surfaces remain a visual follow-up; these states do not establish whole-route parity with A3.
Evidence: evidence/correspondence-recovery/. CORRESPONDENCE_RECOVERY_SOURCE_MANIFEST.json binds LF-normalised source/text evidence and raw images/export files. It is content provenance, not a release image or full integrated acceptance.
Remaining work and rollback
Manual pasted-email recording still needs the equivalent pending-write, stale completion and committed-refresh qualification. Gmail candidate/link/refresh mutation races, cross-job unsaved-draft navigation policy and wider mail workflows retain their own open review. Provider-shaped API responses here are synthetic; no real mail is fetched or sent. Human/native-device, assistive-technology, integrated security/recovery, final A3 and release gates remain open.
Rollback: revert c751b427, rebuild and rerun affected correspondence checks. No stored data changes are made by the patch itself. A real in-flight POST may have committed even if the UI is unmounted; no automatic write retry or server idempotency claim is introduced.