---
path: /domains/arete/plan-review
surface: customer
domain: arete
auth: signed-in
source: apps/oshun/web/src/app/domains/arete/plan-review/page.tsx
status: walked
last_walked:
  '2026-05-29 automated runtime walk (Playwright headless) — render, /v1 data
  (2xx), console/page-errors, expected content, screenshot verified; live
  screen-reader, touch, offline, and telemetry-delivery checks pending a manual
  AT pass. Evidence: WALKTHROUGH/results/runtime-sweep-2026-05-29.md'
---

# Arete Plan Review Workspace

## Purpose

Internal `/domains/arete/*` plan-review workspace. A heavy multi-region view
tying together goals, routines, friction logs, reflection prompts, decision
tracking, progress signals, pattern dimensions, continuity cards, Tara
suggestions, accountability flows, and an artifact action panel. Backed by
`@oshun/domain-arete` canonical builders and policies; uses localStorage for
artifact persistence.

## Entry points

- **Direct URL / bookmark** — yes (signed-in): `/domains/arete/plan-review`
- **Arete shell route** — yes: `/domains/arete?origin=home&path=%2Fplan-review`
  hydrates the internal workspace for a pro-entitled account; `/domains/arete`
  also exposes the `Plan & Review` nav item
- **Back navigation** — dedicated page passes `onBack={() => router.back()}`;
  shell route passes `goHome`, returning in-place to the Arete shell home

## Layout regions

`page.tsx` is a `'use client'` page using `useRouter()`. Renders
`<AretePlanReviewWorkspace onBack={() => router.back()} />`. Component at
`apps/oshun/web/src/components/domains/arete/AretePlanReviewWorkspace.tsx`.

The workspace is large (~2940 lines) and assembles many sub-regions. From state
declarations in the main component:

- **Review window**: `weekly` / `quarterly` (`ReviewWindow`)
- **Selected goal**: one of `goals` (fixture array of `GoalWorkspaceModel`)
- **Selected routine**: one of `routines` (fixture array of
  `RoutineWorkspaceModel`)
- **Selected reflection prompt**: one of `reflectionPrompts`
  (`ReviewReflectionPrompt`)
- **Reflection draft**: free-form string with `reflectionDraft` /
  `reflectionCapturedAt` / `shareReflectionConsent` / `exportReflectionConsent`
- **Decision statuses**: `Record<decisionId, AreteReviewDecisionStatus>` for
  each review's decisions (initialised from the canonical reviews)
- **Completed anchors**: `Set<routineId>` tracking which routine anchor steps
  have been ticked

Computed regions surfaced in the layout (per source):

- **Coaching shell**: `buildAreteCoachingSummaryShellModel({ summary: ... })`
- **Routine evaluations**: per-routine `evaluateAreteRoutineCompletion` results
- **Decision counts**: `{ accepted, deferred, discarded }`
- **Tara suggestions**: `buildAretePlanReviewTaraSuggestions`
- **Assistant accountability flows**: `buildAreteAssistantAccountabilityFlows`
- **Progress map signals**: `buildProgressMapSignals`
- **Pattern dimensions**: `buildPatternDimensions`
- **Continuity cards**: 3 cards (Next practice / Weekly review thread /
  Reflection thread)
- **Artifact action gates**: per-action gates from
  `resolveAreteArtifactActionGate` for save / share / export, gated on privacy
  level and consent flags
- **Artifact governance summary**: human-readable strings of each gate's
  status + reason

## States

- [ ] **Loading** — N/A: client component with sync canonical builders; saved-at
      hydrated via `useEffect` against `readSavedAreteArtifact`
- [x] **Window toggled (weekly ↔ quarterly)** — re-derives `activeReview`,
      coaching shell, decision counts, Tara suggestions, accountability flows,
      progress map signals, pattern dimensions
- [x] **Reflection draft contains text** —
      `reviewContainsPrivateReflection === true` flips artifact action gates to
      require explicit share/export consent
- [x] **Reflection consent off** — `effectiveCannotShareExport`: when
      `reviewContainsPrivateReflection && !shareReflectionConsent`, the share
      gate's privacy level becomes `'private'` and is disallowed
- [x] **Decision status changes** — `decisionStatuses[id]` mutated by decision
      UI (not enumerated in the top-of-function block — see below); re-derives
      `decisionCounts`
- [x] **Anchor step completed** — `completedAnchors.has(routineId)` toggles the
      routine's anchor step in the evaluation
- [x] **Artifact saved** — `setArtifactSavedAt` updates after
      `handleSaveArtifact`
- [x] **Artifact exported (gated)** — `handleExportArtifact` is short-circuited
      via `if (!artifactActionGates.export.allowed) return;`
- [ ] **Error (recoverable)** — relies on app-level error boundary
- [ ] **Offline** — purely client; identical offline (saved artifacts in
      localStorage)
- [x] **Gated** — privacy gates govern share/export of reflection text; shell
      hydration also requires a real pro entitlement from the BFF
- [ ] **Standalone PWA** — no shell chrome around the page

## Interactions

### Top-level controls (verified in component head)

- [x] **Back button** — `onBack` callback wired to `router.back()` or shell
      `goHome`
- [x] **Window selector (weekly / quarterly)** — `setReviewWindow(...)`
- [x] **Goal selector** — `setSelectedGoalId(...)` driven by the goals grid
- [x] **Routine selector** — `setSelectedRoutineId(...)` driven by the routines
      panel
- [x] **Reflection prompt selector** — `setSelectedPromptId(...)` from a prompt
      list
- [x] **Reflection draft textarea** — `setReflectionDraft(...)`
- [x] **Capture reflection** — sets `reflectionCapturedAt` to a timestamp
- [x] **Share / Export consent toggles** — `setShareReflectionConsent`,
      `setExportReflectionConsent`
- [x] **Decision status buttons** — accept / defer / discard per decision
      (`setDecisionStatuses(...)`)
- [x] **Anchor step toggle** — `setCompletedAnchors(...)` per routine
- [x] **Artifact panel**: Save / Share / Export buttons, each gated by
      `artifactActionGates[action]`

### Computed surfaces (presentational)

- [x] **Coaching shell summary cards** — title + summary per card
- [x] **Continuity cards** (3) — Next practice / Weekly review thread /
      Reflection thread
- [x] **Tara suggestions** — `taraSuggestions` array of
      `AretePlanReviewTaraSuggestion`
- [x] **Assistant accountability flows** — `assistantFlows` array of
      `AreteAssistantAccountabilityFlow`
- [x] **Progress map signals** — `progressMapSignals` (per-region scores)
- [x] **Pattern dimensions** — `patternDimensions` (per-dimension insights)
- [x] **Governance summary** — three lines per save / share / export gate status

## Data & contracts

- **Reads**: imports from `@oshun/domain-arete`:
  `buildAreteAssistantAccountabilityFlows`, `buildAretePlanReviewExport`,
  `buildAreteCoachingSummaryShellModel`, `buildCanonicalAreteCoachingSummary`,
  `buildCanonicalAreteGoal`, `buildCanonicalAreteReview`,
  `buildCanonicalAreteRoutine`, `buildAretePlanReviewTaraSuggestions`,
  `evaluateAreteRoutineCompletion`, `getAreteArtifactPolicy`,
  `resolveAreteArtifactActionGate`. Types: `AreteCanonicalCoachingSummary`,
  `AreteCanonicalGoal`, `AreteCanonicalReview`, `AreteCanonicalRoutine`,
  `AreteAssistantAccountabilityFlow`, `AreteArtifactAction`,
  `AreteArtifactActionGate`, `AreteNextPracticeRecommendationModel`,
  `AretePlanReviewTaraSuggestion`, `AreteReviewDecisionStatus`. In-file fixtures
  `goals`, `routines`, `reflectionPrompts`, `reviews`, `coachingSummaries`.
- **Writes**: `saveAreteArtifact` (localStorage); export triggers
  `triggerAreteArtifactDownload`; no BFF write
- **Realtime**: none
- **Caching**: client bundle + localStorage for saved artifacts
- **Auth/role check**: app-level middleware

## Cross-references

- Domain hub: [`arete.md`](./arete.md)
- Polished counterparts: [`arete-plan.md`](./arete-plan.md),
  [`arete-review.md`](./arete-review.md)
- Sibling internal alternates:
  - [`domains-arete-journal.md`](./domains-arete-journal.md)
  - [`domains-arete-progress.md`](./domains-arete-progress.md)
  - [`domains-arete-goals.md`](./domains-arete-goals.md)
- Cross-domain: Tara suggestions are computed in-domain (Arete) but feed into a
  Tara handoff via `buildAretePlanReviewTaraSuggestions`
- Component source:
  `apps/oshun/web/src/components/domains/arete/AretePlanReviewWorkspace.tsx`
- Library: `libs/domain-arete/*` (`@oshun/domain-arete`)
- Artifact support:
  `apps/oshun/web/src/components/domains/arete/areteArtifactSupport.ts`,
  `AreteArtifactActionPanel.tsx`

## E2E coverage

Covered by `apps/oshun/web/e2e/arete-plan-review-workspace.spec.ts`.

The spec runs the dedicated route and the shell route against real dev infra.
For shell hydration it upgrades the seeded account through the real admin
bulk-entitlements BFF pipeline, then verifies:

- Dedicated route render and all primary workspace regions
- Goal, routine, reflection prompt, reflection draft, capture, anchor, and
  decision interactions
- Private-reflection share/export gates blocked before consent and enabled after
  consent
- Artifact save state, localStorage persistence, reload, and shell re-entry
- Gated export download and export-prepared state
- Weekly/quarterly window switching plus shell back navigation
- Tara ritual handoff into the Tara session player
- Next-practice, accountability, and recovery assistant-open events
- Recovery guidance recalculation when decisions and anchors are cleared or
  restored

## Open questions / known gaps

- [ ] Recoverable error boundary, explicit offline mode, and standalone PWA
      display remain unautomated for this route
- [ ] Saved artifacts live in localStorage only; no server persistence is
      covered or expected for V1
- [ ] Telemetry delivery, live screen-reader behavior, and touch-device
      ergonomics still need the broader runtime/manual pass
- [ ] This route is the unified internal plan-review workspace; polished
      `/arete/plan` and `/arete/review` remain split surfaces with their own
      walkthroughs
