home.mdarete-coaching.mdarete-review.mdarete.mdJourney flow#
Generated from the authored steps below — click a node to jump to that section.
Sunday's push or in-app reminder arrives, the user opens /arete/review, walks
the four acts (look back / acknowledge / pivot / commit), checks the week's KPI
tiles and journal lines, sees the continuity card, and commits a plan for the
next week. Tests the cadence reminder, the four-act composition, the KPI/journal
sidebar, and Lilith's recovery/streak tone policy.
Personas#
- Sunday-reminder user — receives the configured Sunday-evening push per
V1/features.md("Sunday evening default; skipping is itself logged but never penalized") - Skipped-last-week user — closed late or missed; this Sunday's review must not shame the skip per the no-shame floor
- Multi-quiet-day user — has had quiet days; the review's
kept,partial,rest, andquietmetrics must remain descriptive, never punitive - Tenant-bound institutional user — institutional review cadence may differ; the Sunday default is configurable per tenant
- Power-user reviewer — prefers the deeper internal surface at
/domains/arete/plan-review
Pre-conditions#
- Signed-in session; middleware permits
/arete,/arete/review,/arete/coaching getAreteReview()returnsAreteReviewData({ weekLabel, acts, kpi, days }); BFF mapping comment marks/arete/reviews/:weekId- Notification permission previously granted (push delivery walked in
install-as-pwa.md§13) - Lilith
coachpersona on Arete withreflectivetone band perV1/features.md#persona-taxonomy-tone-band-catalog-and-crisis-recovery-journey - No crisis frame active (crisis policy supersedes)
Steps#
1. Sunday push or in-app reminder fires#
- Account-visible reminder category:
/profile/notificationsrendersarete-weekly-reviewwithCadence · weekly, backed by the real Arete domain reminder preference;profile-notifications-indexpatches/v1/notifications/preferences/domains/areteand proves the weekly-review category turns off without turning general reminders off. - In-app fallback banner:
/aretereads the same real Arete reminder preference through/v1/arete/room, renders the Sunday-eveningarete-weekly-reviewbanner when the in-app modality is enabled, and removes it after the Arete reminder preference is disabled. - OS push delivery per cadence config (default: Sunday evening), if granted
- Reminder copy: humane copy ("a quiet moment, the week kept"); never "you missed your review" / "you broke your streak"
- Push target:
/arete/review; tap → service workernotificationclicklistener focuses the existing tab or cold-launches (seeinstall-as-pwa.md§13) - In-app target: banner CTA opens
/arete/review - Telemetry:
arete_review_reminder_shownemits after the BFF-backed banner mounts on/arete
2. Arrive on /arete/review#
page.tsx is a thin server component: await getAreteReview() →
<AreteReview>, inside LWebShell with LCustomerNav active="today".
- Page server-blocks on
getAreteReview()(noloading.tsx) - Masthead reads "Arete · sunday review" /
data.weekLabel/ "four acts · twenty minutes", display title "Sunday. Look back, gently.", lede about Celebrate · Notice · Choose · Invite - Verify:
customer/04-arete/arete-review.mdlayout regions
3. Walk Act I — Celebrate (look back)#
Four acts stack vertically on the left (1.4fr). Each act renders a header row
(eyebrow / title / LCode duration), a mixed-emphasis body, and a two-column
grid of list items.
- Act I header eyebrow reads "act I · what held" (accent if
a.accent) - Body composes
a.bodyParts— mixed text withemphasized(accent italic) andchip(highlight bg) inline spans - List items in rounded outlined cards; copy must not shame — celebrate
names what went well per
V1/features.md
4. Act II — Acknowledge / Notice#
- Act II header: "act II · what slipped"; body names patterns without
inviting shame per the no-shame floor (same rule as
arete-streak-recovery.md§4) - List items are named patterns (e.g., "Wednesday dip", "evening practice slipped")
5. Act III — Choose / Pivot#
- Act III header: "act III · one change"; body asks the user to choose what
to commit to next week per
V1/features.md - List items are candidate commitments; per-view file flags no per-act completion state today (user cannot mark Choose individually)
6. Act IV — Invite / Commit#
- Act IV header: "act IV · into the week"; body invites release per
V1/features.md - List items are release / commitment statements
7. KPIs + journal lines (right column)#
- "The week, kept" renders all four
data.kpimetrics in one flexible row; each tuple[k, v, c]renders big serif numeral coloured byc(accent/ink/ muted viakpiColorhelper) - "Mood thread" SVG (aria-hidden) draws a smooth quadratic curve across
mon–sun; caption renders
data.moodCaptionso the named weekly pattern can adapt with the review data - "What you wrote" lists
data.days[i] = [day, txt]with date code + italic text; no per-entry link to the journal route
8. Continuity card and next-week plan#
Per V1/features.md
("continuity card, next-practice recommendations, plan adjustments saved with
user approval"), the review output composes into a continuity card.
- Footer note: "The review is yours; Lilith never alters a sentence. She might suggest a phrase in the margin."
- Click the margin-suggestion reveal; a data-backed phrase appears beside
the footer note,
aria-expandedflips to true, and the rendered review body remains unchanged - Click "Save as private letter" (
AreteReviewClosebutton); client POSTs/v1/arete/review/closewith{ weekLabel, action: 'saved-private' }and rendersdata-arete-review-close-state="kept-private" - Click "Close the week" (
AreteReviewClosebutton); client POSTs/v1/arete/review/closewith{ weekLabel, action: 'closed' }and rendersdata-arete-review-close-state="week-closed". The same persisted closure now feeds/aretethrough/v1/arete/roomas a continuity card; richer plan adjustments remain subject to user approval per feature spec - Telemetry: after the real BFF close/save response succeeds,
AreteReviewCloseemitsarete_weekly_review_closedwithsurface: 'arete_review',sourcePath: '/arete/review',weekLabel,action,state, andclosureId
9. Return to /arete and verify continuity#
- Navigate back to
/arete; continuity card reads back the latestweek-closed/kept-privatereview closure from/v1/arete/room - Home rail
HomeAretePracticeSectionreflects adjustments percustomer/04-arete/arete.mddata contract (BFF mapping notes/arete coaching.latest-suggestion,/arete evening-prompt.today) - Lilith's letter at
/arete/coachingmay surface follow-up patterns named during the review (lagged — seearete-create-habit.md§10 for the coaching cadence)
Post-conditions#
- Four acts rendered with mixed-emphasis bodies and list cards
- KPI tiles, mood SVG, day-by-day journal lines rendered without shaming language
- If "Close the week" pressed: closure persists to
/v1/arete/review/closedand reads back on/arete; richer next-week plan adjustments remain an explicit product gap - If either terminal footer action succeeds: the browser emits
arete_weekly_review_closedwith the exact persisted closure action/state - A shown in-app reminder emits
arete_review_reminder_shown; the product requirement to log a skipped review without penalizing it remains open
Failure modes#
- "Save as private letter" / "Close the week" are wired —
AreteReviewClosereplaced the inert footer buttons; both actions POST/v1/arete/review/closeand render BFF-backed status (kept-private/week-closed) - No per-act completion state — user cannot mark Celebrate / Notice / Choose / Invite individually
- No journal input on the review page —
data.daysis read-only; "Save as private letter" persists the review closure, not editable journal text - Mood-thread caption hardcoded — fixed 2026-06-24:
AreteReviewData.moodCaptionfeeds the visible caption, with component coverage proving a custom caption replaces the default fixture text - Margin-suggestion affordance missing — fixed 2026-06-24:
AreteReviewMarginSuggestionrevealsdata.marginSuggestionwitharia-expanded/aria-controlsand does not mutate the review body - Sunday push not granted — if push declined, the in-app banner is the only entry; user may miss the reminder
- Crisis frame active — recovery / weekly-review prompts suspended;
safety surface takes priority per
crisis-aware-tone-policy.md - Shaming copy regression — any prose using "you broke your streak" or
"you missed your review" violates the no-shame floor (same rule as
arete-streak-recovery.md)
E2E coverage#
Spec:
apps/oshun/web/e2e/arete-weekly-review.spec.ts
— as of 2026-06-25, the four-act specimen is asserted through stable
data-arete-review-* anchors for page counts, masthead, every act/body/list
cell, every KPI tile/value/color, the mood chart/caption, all seven journal
rows, and the footer action region.
Spec:
apps/oshun/web/e2e/arete-review-reminder.spec.ts
— step 1's locally-verifiable reminder entry is now driven end-to-end: the test
patches the real Arete notification preference into in-app fallback mode, loads
/arete, asserts the BFF-backed Sunday-evening reminder card, proves humane
copy/no-shame wording, captures arete_review_reminder_shown, clicks through to
/arete/review, then disables the Arete reminder preference and proves the
banner disappears.
Spec (wave-7, close interaction):
apps/oshun/web/e2e/arete-review-close.spec.ts
— step 8 is now driven end-to-end: the AreteReviewClose island replaced the
inert <LBtn>s, so "Close the week" POSTs /v1/arete/review/close and renders
a week-closed confirmation, and "Save as private letter" POSTs the same
route to render kept-private. Both terminal actions now assert the
arete_weekly_review_closed analytics event after the real BFF response. The
four-act review body above it stays render-only; only the close/save row is
wired.
| Step | Test name | Status |
|---|---|---|
| 2 | page loads with masthead week-label, four-act lede, and Lilith tone identity | covered via page/masthead/count anchors |
| 3 | Act I — Celebrate: eyebrow, title, mixed-emphasis body, list cards | covered via act/body/list anchors |
| 4 | Act II — Notice: eyebrow, pattern body, list items | covered via act/body/list anchors |
| 5 | Act III — Choose: eyebrow, body, list items | covered via act/body/list anchors |
| 6 | Act IV — Invite: eyebrow, body, list items | covered via act/body/list anchors |
| 7 | KPI tiles render all four labels and numeric values | covered via per-KPI value/color anchors |
| 7 | Mood-thread SVG aria-hidden; data-backed mood caption present | covered via mood chart/caption anchors |
| 7 | Journal day lines render all seven days with italic entry text | covered via per-row day/text anchors |
| 8 | Footer note present; Save-as-letter and Close-the-week buttons present | covered via footer/action anchors |
| 8 | Margin suggestion reveal toggles a data-backed phrase without body mutation | covered |
| 8 | Close the week → POST /v1/arete/review/close → week-closed confirmation | covered (arete-review-close.spec.ts) |
| 8 | Save as private letter → POST /v1/arete/review/close → kept-private | covered (arete-review-close.spec.ts) |
| 8 | Close/save telemetry emits arete_weekly_review_closed after BFF success |
covered (arete-review-close.spec.ts) |
| 9 | Return to /arete and verify weekly-review continuity card |
covered (arete-review-close.spec.ts via /v1/arete/room read-back) |
| — | No-shame floor: shaming phrases absent from rendered page | covered |
| 1 | Account notification index exposes the Arete weekly-review reminder category | covered (profile-notifications-index: real Arete preference PATCH + reload) |
| 1 | In-app reminder fallback on /arete |
covered (arete-review-reminder.spec.ts: real preference PATCH + telemetry) |
| 1 | Sunday OS push delivery | not covered — push delivery requires OS notification infra |
| 9 | Home rail / coaching follow-up plan adjustments | not covered — richer review-derived plan adjustment payload is not modeled yet |
Coverage depth: partial — see coverage.md.
/arete/review is a server-rendered specimen (getAreteReviewFixture) for the
four-act body. The specimen layer is now row/cell-level: the browser test checks
route counts, masthead text, every act's identity/title/duration/body-part kind,
every list item, every KPI value/color, the mood chart/caption, all seven
journal rows, and the footer action region through stable anchors rather than
broad page text. The close interaction is wired separately: the
AreteReviewClose island replaced the inert buttons, so "Close the week" and
"Save as private letter" POST /v1/arete/review/close, render week-closed /
kept-private, emit arete_weekly_review_closed with the persisted
action/state/week label/closure id, and return to /arete to assert the
persisted closure through /v1/arete/room (arete-review-close.spec.ts). The
same /v1/arete/room response now also carries the member's
weeklyReviewReminder snapshot from the real notification preference store, and
arete-review-reminder.spec.ts proves the in-app fallback card, no-shame copy,
arete_review_reminder_shown, /arete/review CTA, and preference-off removal.
The four-act content still has no per-act interaction, but the journey is no
longer shallow — its render specimen, terminal close action, close telemetry,
reminder entry, and Arete-hub read-back are all covered, and the mood-thread
caption is a review-data contract instead of JSX literal copy. The footer
margin-suggestion promise is also wired as a data-backed reveal interaction.
Uncovered: step 1's actual Sunday OS push scheduler/delivery (the account
notification index and /arete in-app fallback are covered, but OS notification
delivery remains separate infra); the four-act body's per-act completion state
(no per-act onClick); review-derived Home rail / coaching follow-up plan
adjustments. The margin suggestion, close/save action, reminder impression,
close telemetry, and /arete continuity read-back are now covered end-to-end.
Note — the
/arete/reviewroute is not inert. The same route also mountsAreteReviewDraftRun(apps/oshun/web/src/components/lilith/arete.tsx), a fully wired agent surface that POSTs the real/v1/agentic/runslifecycle (request → approve →queued/ discard →cancelled) against the live BFF. That surface is a different feature from the four-act weekly review and is covered byagentic-pipeline-runnow-arete.spec.ts(the agentic-pipeline-customer-invocation journey). So "no write path is wired on/arete/review" would be wrong. The four-act review's close/save footer is also wired throughAreteReviewClose; remaining gaps are the static act body and richer plan-adjustment read-back.
Per-view files touched by this journey#
customer/04-arete/arete-review.md— four acts, KPI sidebar, footer action rowcustomer/04-arete/arete.md— return point with continuity cardcustomer/04-arete/arete-coaching.md— Lilith's letter where review-named patterns lag-surfacecustomer/02-home-discovery/home.md—HomeAretePracticeSectionreflects review-derived plan adjustments
Cross-references#
- Feature spec:
V1/features.md§ Weekly Review and Reflection - Lilith tone policy (streak / recovery): see
arete-streak-recovery.mdfor the full no-shame-floor walk; the samecoachpersona +reflectiveband applies perV1/features.md#persona-taxonomy-tone-band-catalog-and-crisis-recovery-journey - Related journeys:
arete-streak-recovery.md,crisis-aware-tone-policy.md,install-as-pwa.md— Sunday push walks the same notification path - Component source:
apps/oshun/web/src/components/lilith/arete.tsx(AreteReview) - Close BFF routes:
apps/oshun/bff/src/routes/domain-stubs.ts(POST /v1/arete/review/close,GET /v1/arete/review/closed) - Data:
apps/oshun/web/src/lib/lilith-data/arete-depth.ts(getAreteReviewFixture) - Internal alternate:
/domains/arete/plan-reviewpercustomer/04-arete/domains-arete-plan-review.md
Open questions / known gaps#
- Add
/aretecontinuity-card read-back coverage after/v1/arete/review/close; the closure persists via/v1/arete/review/closedand the hub continuity card now reads it through/v1/arete/room - Confirm the cadence config surface — where does the user set Sunday vs
another day per the feature spec's "configurable" promise? The account
notification index now shows the weekly-review reminder category and the
/profile?path=notificationshandoff, but no day-of-week selector is modeled yet. - Document the plan-adjustment approval flow —
V1/features.mdrequires "plan adjustments saved with user approval"; where is the per-adjustment Approve / Defer affordance? - Wire the margin-suggestion affordance, or remove the claim — fixed by
AreteReviewMarginSuggestion - Confirm the continuity card on
/aretereads from the same BFF review-closure store as/v1/arete/review/closed— namespace drift risk per thearete-create-habit.mdfinding - Document the per-tenant cadence override path for institutional reviewers