You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Converge Newsletter, Calendar, and Mailing Export presentation
Status: blocked pending final verification — immutable user-authorized checkpoint 65fb9a8392ed76cc55e74a9b783e352914169411 with PM identity amendment approved; final quiescent preflight/full gate and fresh Designer, Tester, and PM gates remain pending; local, unpushed, and unshipped
Tags: enhancement, portal, frontend, testing, design, P1
Parent: #162, Wave A slice 5
Depends on: satisfied for implementation — accepted local commits #218 0c89588df809b2e84af02e796d1910a25eea0165, #219 9d204d208820e3d842a3d3fc83493c230bcadaa5, #220 d334020ca5a582d31a81b371988169cab4e7f6b2, and #221 8c3b110c8aa138d95385a89fe3328749bdf47250; checkpoint 65fb9a8 is based on that exact chain
Blocks: the #162 final integrated design-system audit for these three surfaces
Next owner: Software Engineer — only after the documented host process, port, resource, and retained 30-second network-quiescence prerequisites are demonstrably satisfied, execute the approved final protocol exactly
Resume condition: the host is demonstrably free of other-worktree Playwright/Chromium activity, required ports are free, resource checks pass, and the retained 30-second network observation is empty; then use immutable checkpoint 65fb9a8392ed76cc55e74a9b783e352914169411 without source or evidence drift
Product outcome
Make Newsletter, Calendar, and Mailing Exports read as one chronological planning and recovery workflow without changing their domain contracts.
Newsletter is an earliest-first publication plan with stable grouping and a clear next item.
Calendar remains an intentional desktop month/week calendar and becomes a true one-column date agenda on mobile.
Newsletter overlays and source outages remain explicit without hiding successful Calendar or Newsletter data.
Mailing Export cards name the existing safe next action precisely: wait/check status, retry, fix authorization before retrying, repair another named prerequisite, or download the completed private ZIP.
This is a presentation and evidence slice over the existing TypeScript frontend. It must preserve the accepted #108 Mailing Export product and #134 Europe/Berlin operator-day contract. It does not authorize provider execution, an API/data expansion, or a redesign of unrelated surfaces.
Frozen baseline and dependency reconciliation
The PM inventory was performed read-only at clean baseline 78e91223203aa54376a318fd1a3214ce0242e0c3.
That baseline already contains and this slice must preserve:
Reconcile and close one Europe/Berlin business date #134's closed canonical Europe/Berlin operator-day behavior: Calendar starts/returns to the injected todayIsoDate(), Newsletter derives its default range from that day, and an absent Mailing run uses that day as its run key.
#218 is not disjoint. It owns shared page-header, section, action-row, form, semantic-status, honest-state, responsive, and evidence convergence in:
frontend/src/styles.css
frontend/src/surfaces/planning.js
frontend/src/surfaces/finance/mailing.js
frontend/test/planning-surface.test.mjs
frontend/test/finance-surface.test.mjs
canonical capability/browser paths and synthetic screenshots
Therefore #222 implementation starts after #218's accepted exact commit. If another accepted branch is integrated first, reconstruct from the reviewed containing SHA, repeat the pre-edit criterion inventory, retain only still-unmet gaps, and send the reconstructed fingerprint through Designer, Tester, and PM. Do not resolve overlap by reverting, absorbing, or silently restyling dependency-owned behavior.
One canonical frontend, routes, shell, focus/history, tokens, and shared state presentation
Already compliant / dependency-owned
#180/#161 are in the baseline; frontend/src/styles.css contains the accepted token, focus, theme, density, and overlay vocabulary. #218 now owns primitive convergence.
Consume #218's accepted primitives. Do not alter shell IA, routing, account/team scope, or reintroduce route-local primitive duplication.
One Europe/Berlin operator day
Already compliant; preserve exactly
planning.js receives todayIsoDate; Calendar cursor/Today, Newsletter default bounds, and mailing.js absent-run key use it. work-model, Planning, Finance, and canonical browser tests cover the boundary. #134 is closed.
No new date resolver, timezone rule, backend timestamp change, or date library. Keep all current #134 tests green.
Newsletter chronological plan
Substantially compliant with one concrete determinism/evidence gap
planning.js groups by month or ISO week and sorts by publicationDate; rows use semantic <time>, human booking labels, status text, filters, alerts, native dialog, validation/conflict retention, and safe campaign links. Unit and browser suites cover grouping, mutation, conflict, empty/failure, mobile overflow, themes, and Axe. Current tests do not prove out-of-order same-date input produces a stable operator order or that the earliest actionable slot remains first across grouping/filter changes.
Define one earliest-first presentation order independent of API order: publication date, then stable human campaign label, then stable record identity only as a non-visible tie-breaker. Preserve grouping, filters, mutation contracts, booking labels, statuses, links, and #134 bounds. Add behavior evidence for shuffled records and filter/group changes.
Newsletter refresh failure after useful data
Concrete honest-state gap
load() replaces the schedule with Newsletter schedule unavailable and says to reopen; there is no in-surface Retry control. Existing tests prove initial failure and recovery via changing a filter, not preservation of a previously useful schedule.
On a later GET failure, keep the last confirmed schedule visible as stale/read-only context, identify Newsletter as unavailable, and provide one connected Retry newsletter schedule control that repeats the current query. On initial failure show no synthetic rows. Do not retain failed mutation as success; dialog values/conflict behavior remain unchanged.
Desktop Calendar month/week planning
Already compliant; preserve
planning.js renders deterministic Monday–Sunday month/week grids, ISO weeks, filters, layer toggles, holidays, activities, overlays, alerts, semantic dates, create/edit/conflict, and Today navigation. Unit, calendar-seams, canonical capability, and design suites cover these contracts.
At <=820px, late CSS renders each week as seven 112px columns with overflow-x:auto; the UI instructs operators to swipe horizontally. planning-surfaces-design.spec.js is titled “one-column agenda” but explicitly asserts the horizontal strip.
At 390×844, render the selected period as one chronological vertical agenda of date rows. Each meaningful day exposes its date, activity/holiday/newsletter items, and state in reading order; empty days may be compact but dates and controls remain reachable. No horizontal day strip, hidden off-screen action, or page-level overflow. Desktop remains a grid.
Newsletter overlay success
Already compliant; preserve
Calendar independently requests /overlays, renders linked Newsletter items, allows the layer to be toggled, and canonical real-server evidence covers calendar.overlays-alerts.
Preserve real overlay links, toggle behavior, chronology, and safe labels. Do not duplicate Newsletter records or create a second source.
Overlay unavailable while Calendar succeeds
Partially compliant with a concrete recovery/ownership gap
Promise.allSettled keeps Calendar items when the overlay request fails and appends terse text to the shared status. The layer remains checked, no source-owned unavailable block or retry action appears, and existing browser behavior does not prove recovery without reloading the whole route.
Keep Calendar activities/holidays usable, mark only Newsletter dates unavailable adjacent to the layer/calendar decision, never imply zero overlays, and provide one Retry newsletter dates action that retries the existing overlay request/range. Recovery removes the warning and restores overlays without duplicating Calendar records.
Full Calendar refresh failure
Concrete honest-state gap
The catch path clears items, holidays, and overlays, replaces the grid, and says Reopen Calendar to retry, although calendar.failure describes preserved successful data. Existing browser recovery uses Today/reload rather than an explicit recovery control.
Initial failure shows no invented records. A later failure preserves the last confirmed calendar as stale/read-only context, names Calendar as unavailable, retains the selected period/filter/layers, and offers one connected Retry calendar action. Recovery updates once without duplicate records or mutations.
Mailing Export durable behavior and privacy
Already compliant; preserve exactly
mailing.js, Finance tests, canonical real-server capability evidence, and accepted #108 behavior cover no-config, empty, pending, failed, completed, history pagination, deterministic run keys, one logical run, sanitized errors, Artifact linkage, and authenticated short-lived download.
No provider/service/API/persistence/configuration/security change. No provider call during implementation/review. Preserve no-secret/no-contact/no-storage-identity output and all #108 tests.
Mailing next-action explanation
Already present but not precise enough
actionCopy distinguishes wait, retry, fix-authorization, fix-storage, fix-task-link, and download. It also prints raw lower-case states/error codes and every non-completed run exposes the same Advance / retry button, obscuring whether the operator should wait, retry, or repair authorization first.
Render human state labels and one unambiguous next-action heading/instruction. Map the existing server nextAction to precise visible controls without changing which existing endpoint is invoked or its durable run key. Remove the combined Advance / retry label.
Wait / Retry / Fix authorization / Download language
Concrete gap
Pending runs say to wait but still show Advance / retry; failed authorization/storage/task-link states share the same button; completed uses Download ZIP while explanatory copy alone mentions privacy/expiry.
Required labels/meaning: Check status for wait (same durable run; no claim of a new export), Retry export for retry, Retry after authorization is fixed for fix-authorization, equivalent named repair-first labels for storage/task-link states, and Download private ZIP for download. Completed cards expose no start/advance action. Copy states that the download is authenticated and expires in five minutes; it never implies the browser has already downloaded or that provider work succeeded before authoritative completion.
Mailing history chronology and honest pagination
Already compliant; preserve
sortedRuns() orders newest request first with stable ID tie-break; pagination retains loaded history on later-page failure and offers retry.
Keep ordering, loaded records, continuation, and error behavior. Presentation may consume #218 primitives only.
Durable capability and source/SAM evidence
Machinery already compliant; candidate evidence gap
frontend-capabilities.json already defines all Newsletter, Calendar, and Mailing Export states. canonical-capability-behavior.spec.js emits real-server evidence; build/SAM parity machinery exists. Intercepted legacy/design specs are useful regression/visual fixtures but are not core behavior proof.
Reuse existing IDs; do not change #159 schema or add style-only capability IDs. Extend behavior assertions so the existing states prove current mobile agenda, partial/unavailable recovery, and exact mailing next-action semantics. Prove changed source, backend/dist, and SAM assets are identical.
Implement only the concrete presentation/recovery gaps: deterministic Newsletter chronology, retained useful data with explicit retry, desktop Calendar/mobile agenda, overlay-specific unavailable recovery, and precise Mailing Export next-action language.
Add focused production-module tests, one dedicated real-server Converge Newsletter, Calendar, and Mailing Export presentation #222 browser journey, updates to existing regressions whose old mobile/action assumptions are intentionally replaced, and existing durable capability/source-SAM evidence.
Complete Designer → independent Tester → PM acceptance on one frozen fingerprint before commit.
A newly required production or test path needs a PM amendment before editing. Do not edit backend/e2e/frontend-capabilities.json, capability reporter/schema machinery, backend routes/services/models, infrastructure, provider adapters, or configuration. Existing intercepted specs remain regression/visual checks only; the dedicated and canonical real-server journeys are the behavior authority.
Acceptance criteria
Newsletter chronology and recovery
Newsletter records render earliest publication first regardless of API order, grouped by the selected month/week with a stable same-date tie-break; filter/group changes preserve that chronology.
Semantic <time datetime> values, human campaign/booking labels, statuses, alert language, public campaign links, Add/Edit dialog, validation/conflict value retention, and Reconcile and close one Europe/Berlin business date #134 date bounds remain unchanged.
Initial Newsletter failure invents no records. A refresh failure after success preserves the last confirmed schedule as visibly stale/read-only context, identifies the unavailable source, retains current filters, and exposes one connected Retry newsletter schedule control.
Retry repeats the current query once, removes the stale/unavailable state on success, and neither duplicates rows nor performs a mutation.
Calendar desktop, mobile agenda, and source honesty
At 1440×900, Calendar retains the intentional seven-column month/week grid, Monday–Sunday/ISO-week semantics, activity filter, layer controls, holiday/activity/Newsletter distinctions, alert dismissal, and create/edit dialog.
At 390×844, the selected month/week is a one-column chronological agenda—not a horizontally scrolling seven-day strip. Dates, relevant items, status, and links follow DOM reading order; there is no hidden horizontal day content or page overflow.
The first meaningful current/next agenda date and its first item or honest empty decision are visible in the initial viewport after the page heading and compact controls. All controls and linked/actionable agenda items are at least 44×44 CSS pixels.
Overlay failure preserves successful Calendar activities/holidays, clearly labels only Newsletter dates unavailable, never presents zero as authoritative, and provides Retry newsletter dates for the same range.
Initial Calendar failure invents no records. A later Calendar refresh failure retains the last confirmed period as visibly stale/read-only context with selected view/filter/layers and a connected Retry calendar action.
Successful retries replace state once, remove the associated warning, restore overlays/calendar data without duplicates, and preserve Today/previous/next/week/month behavior under the Reconcile and close one Europe/Berlin business date #134 Berlin day.
Existing Calendar/Newsletter mutation, validation, conflict, dialog, route, focus, and history contracts remain unchanged.
Mailing Export next-action language
The existing server status and nextAction remain authoritative; no browser-only lifecycle or guessed provider success is introduced.
Human state labels and action instructions never expose raw enum/reason-code/storage/provider/credential identity as routine operator copy.
wait shows that the same durable run is still pending and labels its existing safe action Check status; it never claims a new export was requested.
retry labels the existing action Retry export and retains the same durable run key.
fix-authorization says authorization must be repaired through the approved external mechanism and labels the existing action Retry after authorization is fixed. Storage and Task-link repairs receive equally precise repair-first labels; no portal control claims to repair credentials, storage, or Task configuration itself.
download appears only for an authoritative completed run with an Artifact and is labeled Download private ZIP; nearby copy states that the authenticated link expires in five minutes. The UI claims preparation/success only after the existing download API succeeds.
Completed cards have no start/check/retry control; empty cards retain Start daily export; no-config remains non-actionable; later-page failures retain loaded history and precise retry.
At 1440×900 each surface has one dominant heading, adjacent description, content-width action hierarchy, and its first chronological decision visible without duplicated status/card chrome.
At 390×844 filters/actions/forms wrap in DOM order, dialogs remain within the viewport, controls meet 44×44, and there is no clipping, overlap, inaccessible off-canvas content, or page-level horizontal scrolling.
One owned page-heading contract, correctly nested period/date/history headings, semantic list/article/time/status/alert/dialog structure, native labels, and meaningful accessible names are retained.
Loading/progress uses role=status; blocking unavailable/mutation failure is announced; partial failure keeps successful content and names only the failed source. Status and next action are not conveyed by color alone.
Automated scans report zero critical/serious WCAG A/AA findings for every captured changed state.
Behavior, privacy, and parity
The engineer freezes HEAD plus binary diff, status, and candidate-content fingerprints before review; Designer, Tester, and PM use the same fingerprint.
A real local TypeScript server journey creates only synthetic records through normal authenticated APIs and exercises Newsletter chronology/recovery, Calendar desktop/mobile/overlay/full-failure recovery, and all Mailing next-action states without request interception for core behavior.
Deterministic local fault/provider-simulator controls may produce unavailable/run states, but there are no external provider calls, fixed sleeps, test-order dependencies, broad 404 swallowing, source-string assertions, incidental copy/whitespace pins, screenshot assertions, or screenshot goldens.
The normal full Playwright run emits passing evidence for every existing Newsletter, Calendar, and Mailing Export capability state and role; responsive-only assertions complement rather than replace durable state evidence.
Source, backend/dist, and packaged SAM frontend assets are identical for every changed asset; the normal source/SAM parity run accounts for all existing capability evidence and screenshots.
Fixtures, logs, screenshots, and comments contain only synthetic public-safe data: no provider execution, contact/audience data, production/private records, credentials, signed URLs, storage identity, private links, or operational artifacts.
Test scenarios
Shuffled Newsletter chronology
Given shuffled synthetic slots spanning month/week boundaries, including same-date records
When Newsletter loads and the operator switches grouping and filters
Then each visible group and row remains earliest-first with the documented stable tie-break, semantic dates and status stay correct, and the first actionable slot is not displaced by response order
Newsletter refresh outage and recovery
Given a confirmed visible schedule and current filters
When the next list request fails through the deterministic local fault seam
Then the prior schedule remains visibly stale/read-only, Newsletter alone is named unavailable, no false empty state appears, and Retry newsletter schedule repeats the same query once
When the fault clears
Then fresh rows replace the stale state once without duplication
Desktop Calendar and mobile agenda
Given synthetic activities, holidays, alerts, and linked Newsletter overlays across several dates
When Calendar opens at 1440×900 and then 390×844
Then desktop uses the existing month/week grid while mobile uses one chronological agenda in DOM order, the first meaningful date/item is visible, and there is no horizontal day strip or page overflow
Independent overlay outage
Given Calendar data succeeds and Newsletter overlays fail
When the period settles
Then activities and holidays remain usable, the overlay layer says Newsletter dates are unavailable rather than empty, and Retry newsletter dates restores links for the same range without re-creating Calendar records
Calendar refresh outage
Given a successful populated period and selected view/filter/layers
When a later Calendar request fails
Then the last confirmed period remains visibly stale and read-only with an announced Retry calendar action
When retry succeeds
Then the current period refreshes once, retained controls remain selected, and no record or mutation is duplicated
Exact Mailing next actions
Given synthetic no-config, empty, waiting, retryable failure, authorization failure, storage failure, Task-link failure, and completed runs returned by the normal local server/provider simulator
When the operator scans each card and invokes the available safe action
Then visible labels distinguish Start, Check status, Retry export, repair-first retries, and Download private ZIP; each existing action uses the same durable run key/endpoint, completed has no run action, and no secret/provider/storage identity appears
Source/SAM identity
Given the frozen accepted source candidate and a clean SAM build
When the same routes and existing durable states run from source and packaged targets
Then behavior evidence agrees, changed assets are byte-identical, and every expected source/SAM record is accounted for
Synthetic screenshot inventory
Capture exactly these 12 untracked native-size PNGs under .tmp/screenshots/issue-222/; delete stale extras before review:
Use the normal local server, deterministic local faults/provider simulator, and synthetic public-safe records. Tester and Designer inspect every image at native resolution for chronology, first-decision visibility, grid-versus-agenda behavior, state/action ownership, exact safe language, focus cues, target sizing, theme/contrast, overflow, clipping, overlap, and private-data leakage. Screenshots are visual evidence only: do not commit or publicly attach them, and do not use them as behavior/parity proof.
Required verification
Engineer may use focused commands while iterating. Independent Tester runs the complete relevant workflow on one frozen candidate and records commands, exit codes, observed counts, behavior titles, capability-state accounting, artifact/evidence paths, and every intentional skip:
node --test frontend/test/planning-surface.test.mjs frontend/test/finance-surface.test.mjs
npm run test:frontend:unit
npm run test:frontend:coverage
npm --prefix backend test
npm --prefix backend run typecheck
npm --prefix backend run build
node backend/scripts/verify-frontend-artifact.mjs --source frontend --artifact backend/dist
npm --prefix backend run test:e2e -- e2e/issue-222-planning-presentation.spec.js e2e/canonical-capability-behavior.spec.js e2e/planning-surfaces-design.spec.js e2e/calendar-seams.spec.js e2e/newsletter-production-portal.spec.js --retries=0
npm --prefix backend run test:e2e
npm --prefix backend run test:e2e:frontend-parity
make sam-validate
make sam-build
node backend/scripts/verify-frontend-artifact.mjs --source frontend --artifact .aws-sam/build/BackendFunction
make ci
git diff --check
The dedicated #222 spec must be part of the normal full Playwright run. Existing canonical capability evidence remains authoritative for durable state IDs. Intercepted Calendar/Newsletter regression/design specs do not substitute for the real-server journey.
User-authorized immutable checkpoint 65fb9a8392ed76cc55e74a9b783e352914169411 recorded; this is not DESIGN PASS, TESTER PASS, final PM acceptance, merge, push, or shipment
PM protocol identity amendment approved with all quiescence, evidence chronology, one-preflight/one-full-run, stop, and no-rerun constraints preserved
Software Engineer completes the exact final quiescent Phase 0, one authorized affected-journey preflight, and—only after a qualifying preflight/inter-phase quiescence—one unfiltered zero-retry full gate on the unchanged checkpoint
Fresh Designer review posts DESIGN PASS on the same immutable identity and final evidence chronology
Fresh independent Tester verification posts TESTER PASS on the same immutable identity and final evidence chronology
PM performs final user-perspective review and posts ACCEPTED on the same immutable identity
Final commit gate is satisfied only after fresh acceptance; the existing checkpoint needs no restatement commit if bytes remain exact, while any fix requires a new disposition/refreeze
Orchestrator merges locally in the recorded safe order and pushes main
On-Call verifies normal CI/CD, deployment, source/SAM identity, and smoke evidence before shipped/closure is claimed
No HUMAN gate is required for this local, synthetic, provider-free presentation slice. #108's separate real-provider HUMAN gates remain untouched and do not block local #222 implementation/review after #218.
Converge Newsletter, Calendar, and Mailing Export presentation
Status: blocked pending final verification — immutable user-authorized checkpoint 65fb9a8392ed76cc55e74a9b783e352914169411 with PM identity amendment approved; final quiescent preflight/full gate and fresh Designer, Tester, and PM gates remain pending; local, unpushed, and unshipped
Tags:
enhancement,portal,frontend,testing,design,P1Parent: #162, Wave A slice 5
Depends on: satisfied for implementation — accepted local commits #218 0c89588df809b2e84af02e796d1910a25eea0165, #219 9d204d208820e3d842a3d3fc83493c230bcadaa5, #220 d334020ca5a582d31a81b371988169cab4e7f6b2, and #221 8c3b110c8aa138d95385a89fe3328749bdf47250; checkpoint 65fb9a8 is based on that exact chain
Blocks: the #162 final integrated design-system audit for these three surfaces
Next owner: Software Engineer — only after the documented host process, port, resource, and retained 30-second network-quiescence prerequisites are demonstrably satisfied, execute the approved final protocol exactly
Resume condition: the host is demonstrably free of other-worktree Playwright/Chromium activity, required ports are free, resource checks pass, and the retained 30-second network observation is empty; then use immutable checkpoint 65fb9a8392ed76cc55e74a9b783e352914169411 without source or evidence drift
Product outcome
Make Newsletter, Calendar, and Mailing Exports read as one chronological planning and recovery workflow without changing their domain contracts.
This is a presentation and evidence slice over the existing TypeScript frontend. It must preserve the accepted #108 Mailing Export product and #134 Europe/Berlin operator-day contract. It does not authorize provider execution, an API/data expansion, or a redesign of unrelated surfaces.
Frozen baseline and dependency reconciliation
The PM inventory was performed read-only at clean baseline
78e91223203aa54376a318fd1a3214ce0242e0c3.That baseline already contains and this slice must preserve:
Europe/Berlinoperator-day behavior: Calendar starts/returns to the injectedtodayIsoDate(), Newsletter derives its default range from that day, and an absent Mailing run uses that day as its run key.#218 is not disjoint. It owns shared page-header, section, action-row, form, semantic-status, honest-state, responsive, and evidence convergence in:
frontend/src/styles.cssfrontend/src/surfaces/planning.jsfrontend/src/surfaces/finance/mailing.jsfrontend/test/planning-surface.test.mjsfrontend/test/finance-surface.test.mjsTherefore #222 implementation starts after #218's accepted exact commit. If another accepted branch is integrated first, reconstruct from the reviewed containing SHA, repeat the pre-edit criterion inventory, retain only still-unmet gaps, and send the reconstructed fingerprint through Designer, Tester, and PM. Do not resolve overlap by reverting, absorbing, or silently restyling dependency-owned behavior.
Criterion-to-current-source inventory at
78e9122frontend/src/styles.csscontains the accepted token, focus, theme, density, and overlay vocabulary. #218 now owns primitive convergence.planning.jsreceivestodayIsoDate; Calendar cursor/Today, Newsletter default bounds, andmailing.jsabsent-run key use it.work-model, Planning, Finance, and canonical browser tests cover the boundary. #134 is closed.planning.jsgroups by month or ISO week and sorts bypublicationDate; rows use semantic<time>, human booking labels, status text, filters, alerts, native dialog, validation/conflict retention, and safe campaign links. Unit and browser suites cover grouping, mutation, conflict, empty/failure, mobile overflow, themes, and Axe. Current tests do not prove out-of-order same-date input produces a stable operator order or that the earliest actionable slot remains first across grouping/filter changes.load()replaces the schedule withNewsletter schedule unavailableand says to reopen; there is no in-surface Retry control. Existing tests prove initial failure and recovery via changing a filter, not preservation of a previously useful schedule.Retry newsletter schedulecontrol that repeats the current query. On initial failure show no synthetic rows. Do not retain failed mutation as success; dialog values/conflict behavior remain unchanged.planning.jsrenders deterministic Monday–Sunday month/week grids, ISO weeks, filters, layer toggles, holidays, activities, overlays, alerts, semantic dates, create/edit/conflict, and Today navigation. Unit,calendar-seams, canonical capability, and design suites cover these contracts.<=820px, late CSS renders each week as seven112pxcolumns withoverflow-x:auto; the UI instructs operators to swipe horizontally.planning-surfaces-design.spec.jsis titled “one-column agenda” but explicitly asserts the horizontal strip./overlays, renders linked Newsletter items, allows the layer to be toggled, and canonical real-server evidence coverscalendar.overlays-alerts.Promise.allSettledkeeps Calendar items when the overlay request fails and appends terse text to the shared status. The layer remains checked, no source-owned unavailable block or retry action appears, and existing browser behavior does not prove recovery without reloading the whole route.Retry newsletter datesaction that retries the existing overlay request/range. Recovery removes the warning and restores overlays without duplicating Calendar records.items,holidays, andoverlays, replaces the grid, and saysReopen Calendar to retry, althoughcalendar.failuredescribes preserved successful data. Existing browser recovery uses Today/reload rather than an explicit recovery control.Retry calendaraction. Recovery updates once without duplicate records or mutations.mailing.js, Finance tests, canonical real-server capability evidence, and accepted #108 behavior cover no-config, empty, pending, failed, completed, history pagination, deterministic run keys, one logical run, sanitized errors, Artifact linkage, and authenticated short-lived download.actionCopydistinguisheswait,retry,fix-authorization,fix-storage,fix-task-link, anddownload. It also prints raw lower-case states/error codes and every non-completed run exposes the sameAdvance / retrybutton, obscuring whether the operator should wait, retry, or repair authorization first.nextActionto precise visible controls without changing which existing endpoint is invoked or its durable run key. Remove the combinedAdvance / retrylabel.Advance / retry; failed authorization/storage/task-link states share the same button; completed usesDownload ZIPwhile explanatory copy alone mentions privacy/expiry.Check statusforwait(same durable run; no claim of a new export),Retry exportforretry,Retry after authorization is fixedforfix-authorization, equivalent named repair-first labels for storage/task-link states, andDownload private ZIPfordownload. Completed cards expose no start/advance action. Copy states that the download is authenticated and expires in five minutes; it never implies the browser has already downloaded or that provider work succeeded before authoritative completion.sortedRuns()orders newest request first with stable ID tie-break; pagination retains loaded history on later-page failure and offers retry.frontend-capabilities.jsonalready defines all Newsletter, Calendar, and Mailing Export states.canonical-capability-behavior.spec.jsemits real-server evidence; build/SAM parity machinery exists. Intercepted legacy/design specs are useful regression/visual fixtures but are not core behavior proof.backend/dist, and SAM assets are identical.Scope
Bounded write set
Production files:
frontend/src/surfaces/planning.jsfrontend/src/surfaces/finance/mailing.jsfrontend/src/styles.cssFocused tests/evidence:
frontend/test/planning-surface.test.mjsfrontend/test/finance-surface.test.mjsbackend/e2e/issue-222-planning-presentation.spec.js(new)backend/e2e/canonical-capability-behavior.spec.jsbackend/e2e/planning-surfaces-design.spec.jsbackend/e2e/calendar-seams.spec.jsbackend/e2e/newsletter-production-portal.spec.jsA newly required production or test path needs a PM amendment before editing. Do not edit
backend/e2e/frontend-capabilities.json, capability reporter/schema machinery, backend routes/services/models, infrastructure, provider adapters, or configuration. Existing intercepted specs remain regression/visual checks only; the dedicated and canonical real-server journeys are the behavior authority.Acceptance criteria
Newsletter chronology and recovery
<time datetime>values, human campaign/booking labels, statuses, alert language, public campaign links, Add/Edit dialog, validation/conflict value retention, and Reconcile and close one Europe/Berlin business date #134 date bounds remain unchanged.Retry newsletter schedulecontrol.Calendar desktop, mobile agenda, and source honesty
Retry newsletter datesfor the same range.Retry calendaraction.Mailing Export next-action language
statusandnextActionremain authoritative; no browser-only lifecycle or guessed provider success is introduced.waitshows that the same durable run is still pending and labels its existing safe actionCheck status; it never claims a new export was requested.retrylabels the existing actionRetry exportand retains the same durable run key.fix-authorizationsays authorization must be repaired through the approved external mechanism and labels the existing actionRetry after authorization is fixed. Storage and Task-link repairs receive equally precise repair-first labels; no portal control claims to repair credentials, storage, or Task configuration itself.downloadappears only for an authoritative completed run with an Artifact and is labeledDownload private ZIP; nearby copy states that the authenticated link expires in five minutes. The UI claims preparation/success only after the existing download API succeeds.Start daily export; no-config remains non-actionable; later-page failures retain loaded history and precise retry.Responsive, visual, and accessibility
role=status; blocking unavailable/mutation failure is announced; partial failure keeps successful content and names only the failed source. Status and next action are not conveyed by color alone.Behavior, privacy, and parity
backend/dist, and packaged SAM frontend assets are identical for every changed asset; the normal source/SAM parity run accounts for all existing capability evidence and screenshots.Test scenarios
Shuffled Newsletter chronology
Given shuffled synthetic slots spanning month/week boundaries, including same-date records
When Newsletter loads and the operator switches grouping and filters
Then each visible group and row remains earliest-first with the documented stable tie-break, semantic dates and status stay correct, and the first actionable slot is not displaced by response order
Newsletter refresh outage and recovery
Given a confirmed visible schedule and current filters
When the next list request fails through the deterministic local fault seam
Then the prior schedule remains visibly stale/read-only, Newsletter alone is named unavailable, no false empty state appears, and
Retry newsletter schedulerepeats the same query onceWhen the fault clears
Then fresh rows replace the stale state once without duplication
Desktop Calendar and mobile agenda
Given synthetic activities, holidays, alerts, and linked Newsletter overlays across several dates
When Calendar opens at 1440×900 and then 390×844
Then desktop uses the existing month/week grid while mobile uses one chronological agenda in DOM order, the first meaningful date/item is visible, and there is no horizontal day strip or page overflow
Independent overlay outage
Given Calendar data succeeds and Newsletter overlays fail
When the period settles
Then activities and holidays remain usable, the overlay layer says Newsletter dates are unavailable rather than empty, and
Retry newsletter datesrestores links for the same range without re-creating Calendar recordsCalendar refresh outage
Given a successful populated period and selected view/filter/layers
When a later Calendar request fails
Then the last confirmed period remains visibly stale and read-only with an announced
Retry calendaractionWhen retry succeeds
Then the current period refreshes once, retained controls remain selected, and no record or mutation is duplicated
Exact Mailing next actions
Given synthetic no-config, empty, waiting, retryable failure, authorization failure, storage failure, Task-link failure, and completed runs returned by the normal local server/provider simulator
When the operator scans each card and invokes the available safe action
Then visible labels distinguish Start, Check status, Retry export, repair-first retries, and Download private ZIP; each existing action uses the same durable run key/endpoint, completed has no run action, and no secret/provider/storage identity appears
Source/SAM identity
Given the frozen accepted source candidate and a clean SAM build
When the same routes and existing durable states run from source and packaged targets
Then behavior evidence agrees, changed assets are byte-identical, and every expected source/SAM record is accounted for
Synthetic screenshot inventory
Capture exactly these 12 untracked native-size PNGs under
.tmp/screenshots/issue-222/; delete stale extras before review:01-newsletter-chronological-ready-desktop-1440x900.png02-newsletter-chronological-ready-mobile-390x844.png03-newsletter-retained-unavailable-desktop-1440x900.png04-newsletter-retained-unavailable-mobile-390x844.png05-calendar-overlay-ready-desktop-1440x900.png06-calendar-overlay-ready-agenda-mobile-390x844.png07-calendar-overlay-unavailable-desktop-1440x900.png08-calendar-overlay-unavailable-agenda-mobile-390x844.png09-mailing-wait-retry-fix-auth-desktop-1440x900.png10-mailing-wait-retry-fix-auth-mobile-390x844.png11-mailing-completed-download-desktop-1440x900.png12-mailing-completed-download-mobile-390x844.pngUse the normal local server, deterministic local faults/provider simulator, and synthetic public-safe records. Tester and Designer inspect every image at native resolution for chronology, first-decision visibility, grid-versus-agenda behavior, state/action ownership, exact safe language, focus cues, target sizing, theme/contrast, overflow, clipping, overlap, and private-data leakage. Screenshots are visual evidence only: do not commit or publicly attach them, and do not use them as behavior/parity proof.
Required verification
Engineer may use focused commands while iterating. Independent Tester runs the complete relevant workflow on one frozen candidate and records commands, exit codes, observed counts, behavior titles, capability-state accounting, artifact/evidence paths, and every intentional skip:
node --test frontend/test/planning-surface.test.mjs frontend/test/finance-surface.test.mjs npm run test:frontend:unit npm run test:frontend:coverage npm --prefix backend test npm --prefix backend run typecheck npm --prefix backend run build node backend/scripts/verify-frontend-artifact.mjs --source frontend --artifact backend/dist npm --prefix backend run test:e2e -- e2e/issue-222-planning-presentation.spec.js e2e/canonical-capability-behavior.spec.js e2e/planning-surfaces-design.spec.js e2e/calendar-seams.spec.js e2e/newsletter-production-portal.spec.js --retries=0 npm --prefix backend run test:e2e npm --prefix backend run test:e2e:frontend-parity make sam-validate make sam-build node backend/scripts/verify-frontend-artifact.mjs --source frontend --artifact .aws-sam/build/BackendFunction make ci git diff --checkThe dedicated #222 spec must be part of the normal full Playwright run. Existing canonical capability evidence remains authoritative for durable state IDs. Intercepted Calendar/Newsletter regression/design specs do not substitute for the real-server journey.
Lifecycle gates
No HUMAN gate is required for this local, synthetic, provider-free presentation slice. #108's separate real-provider HUMAN gates remain untouched and do not block local #222 implementation/review after #218.
Out of scope