---
path: /nisaba/plan
surface: customer
domain: nisaba
auth: signed-in
source: apps/oshun/web/src/app/nisaba/plan/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; content
  re-verified 2026-06-03 against current source'
---

# Nisaba · the study plan

## Purpose

A seven-week study arc with a prerequisite chain — what rests on what — paced by
weeks. The fixture is "On the ruling part" — week 4 of 7, 18 of 31 readings.

## Entry points

- **Nisaba sub-nav** — verify a "plan" entry on [`nisaba.md`](./nisaba.md)
- **Notebook** — link from [`nisaba-notebook.md`](./nisaba-notebook.md)
- **Direct URL / bookmark** — yes

## Layout regions

`page.tsx` is a thin server component: `await getNisabaPlan()` →
`<NisabaPlan data={data} />`.

Inside `NisabaPlan` (`nisaba.tsx`, line 2048):

- **Web shell top** — `LCustomerNav active="library"`
- **Header strip** — eyebrow row "Nisaba · study plan" / "'On the ruling part' ·
  7 weeks" / "week 4 of 7 · 18 of 31 readings"; `LDisplay` (size 72) headline
  "The arc, paced by weeks."
- **Progress row** (`gridTemplateColumns: '1fr auto'`):
  - **Progress label + bar** — 6 px ruler with accent fill at `(3.4 / 7) * 100`%
    and a 14 px accent dot positioned at the current marker
  - **Week labels** — `w. 1 … w. 7` with `w. 4 · today` highlighted in accent
- **Weekly arc body** (verify exact layout further in `nisaba.tsx`) — one card
  per week, listing readings, prerequisites, and links to the reading desk

## States

- [ ] **Loaded** — `getNisabaPlan()` resolves before render
- [ ] **Current week** — highlighted "w. <n> · today"; progress bar fills to
      `(<fraction>/7) * 100`%
- [ ] **Reading completed** — verify per-reading completion indicator
- [ ] **Prerequisite locked** — verify lock state for prerequisites that haven't
      been satisfied
- [ ] **Plan paused / abandoned** — verify whether the surface handles a paused
      state
- [ ] **Reduced motion** — composes static Lilith primitives

## Interactions

### Header

- [ ] **`LDisplay`** — non-interactive headline

### Progress row

- [ ] **Progress bar** — non-interactive
- [ ] **Week label** (`w. 1` … `w. 7`) — verify whether labels link to that
      week's section anchor

### Weekly arc body

- [ ] **Week card** — opens the week's reading list (verify scroll-spy or route
      push)
- [ ] **Reading row** — opens the passage in the reading desk (`/nisaba/...`)
- [ ] **Mark complete** — verify whether the plan supports checking off readings
      in V1
- [ ] **Prerequisite hint** — verify hover/focus tooltip on locked items

## Data & contracts

- **Reads**: `getNisabaPlan()` from `@/lib/lilith-data/nisaba-depth` — returns
  `NisabaPlanData` (verify shape: weeks, readings, prerequisites, current
  progress)
- **Writes**: verify whether the plan supports a "mark complete" write path
- **Realtime**: _None._
- **Caching**: server fetch
- **Auth/role check**: shell middleware

## Cross-references

- Sibling Nisaba routes:
  - [`nisaba.md`](./nisaba.md), [`nisaba-compare.md`](./nisaba-compare.md),
    [`nisaba-daily.md`](./nisaba-daily.md),
    [`nisaba-graph.md`](./nisaba-graph.md),
    [`nisaba-lexicon.md`](./nisaba-lexicon.md),
    [`nisaba-manuscript.md`](./nisaba-manuscript.md),
    [`nisaba-notebook.md`](./nisaba-notebook.md),
    [`nisaba-scholar.md`](./nisaba-scholar.md)
- Component sources:
  - `apps/oshun/web/src/components/lilith/nisaba.tsx` (`NisabaPlan` line 2048)
- Feature spec: [`V1/features.md#nisaba`](../../../V1/features.md#nisaba)

## Open questions / known gaps

- [ ] Confirm whether reading completion is wired to a BFF write path
- [ ] Document the prerequisite-locked behavior (visual only? prevents
      navigation?)
- [ ] Confirm whether the plan should integrate with Metis course progression or
      remain Nisaba-internal
- [ ] Document how week labels behave on mobile (they sit in a horizontal row;
      narrow viewports may overflow)
