---
path: /nisaba/notebook
surface: customer
domain: nisaba
auth: signed-in
source: apps/oshun/web/src/app/nisaba/notebook/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; 2026-06-29 Playwright re-walk
  added Veritas retraction-notice disclosure + per-citation drill-down coverage;
  2026-06-29 addendum linked the affected citation to the Nisaba compare
  edition-diff surface; 2026-07-03 Playwright pass verified notebook export Blob
  payloads for Markdown, BibTeX, and PDF plus print and robots meta'
---

# Nisaba · the notebook

## Purpose

Long-form study in a private notebook. Outline, pinned passages, footnotes, and
a threaded suggestion from Lilith. The fixture is Renata K.'s "On the ruling
part" — 14 entries, 6 weeks, private, last edit 11 min ago.

## Entry points

- **Nisaba sub-nav** — `LSubNav` entry "Notebook" on [`nisaba.md`](./nisaba.md)
- **Daily passage** — verify the "Carry it to the notebook" affordance from
  [`nisaba-daily.md`](./nisaba-daily.md)
- **Scholar mode** — verify cross-link from
  [`nisaba-scholar.md`](./nisaba-scholar.md) marginalia
- **Direct URL / bookmark** — yes
- **`robots`** — `index: false, follow: false` per `metadata.robots` (private
  surface)

## Layout regions

`page.tsx` is a thin server component: `await getNisabaNotebook()` →
`<NisabaNotebook data={data} />`.
`metadata.robots = { index: false, follow: false }`.

Inside `NisabaNotebook` (`nisaba.tsx`):

- **Web shell top** — `LCustomerNav active="library"`
- **Header strip** — eyebrow row "Nisaba · notebook · Renata K." / "'On the
  ruling part' · 14 entries · 6 weeks" / "private · last edit, 11 min ago";
  `LDisplay` headline "'On the ruling part.'"; italic copy "A working study of
  ἡγεμονικόν as it appears across Aurelius and Epictetus, with cross-tradition
  glances. Notebook · provisional · keep editing."
- **Three-column body** (`gridTemplateColumns: '220px 1fr 280px'`):
  - **Left — Outline** — `data.outline.map(([n, t, here])` rows; the `here`
    entry is accent-coloured with a 2 px accent left border and italic treatment
  - **Centre — Reading column** — long-form notes with pinned passages and
    footnotes (verify exact layout further in `nisaba.tsx`)
  - **Right — Cross-references / Lilith thread** — verify the threaded
    suggestion from Lilith and pinned-passage rail
  - **Right — Veritas retraction notice** —
    `data-nisaba-notebook-retraction-notice` appears when
    `data.retractionNotice` exists; native disclosure opens citation rows,
    original quote, corrected-source link, edition-diff link, and placeholder
    keep-with-marker action

## States

- [x] **Loaded** — `getNisabaNotebook()` resolves before render; Playwright
      opens `/nisaba/notebook` and verifies the "On the ruling part" notebook
      content before driving the export rail
- [ ] **Outline active entry** — `here === true` highlights the current section
- [x] **Pinned passage present** — Playwright verifies the rendered
      `Aurelius IV.viii.7` pinned passage before export
- [x] **Footnote present** — Playwright verifies the rendered
      `Aurelius IV.viii.1` footnote copy before export
- [x] **Lilith suggestion** — Playwright verifies the threaded assistant
      suggestion text ("Lilith · suggestion · 2 days ago"); a separate
      accept/dismiss/drop interaction remains unchecked below
- [x] **Private indicator** — eyebrow row says "private"; Playwright verifies
      `private · last edit, 11 min ago`
- [x] **Veritas retraction notice** — optional `data.retractionNotice` renders a
      notebook-level cascade notice with cascade id, severity, affected-count,
      and hidden citation rows until the disclosure opens
- [x] **Robots noindex** — `metadata.robots = { index: false, follow: false }`;
      Playwright verifies the emitted `meta[name="robots"]` contains
      `noindex,nofollow`
- [ ] **Edit mode** — verify whether the notebook supports editing in V1 or is
      read-only specimen

## Interactions

### Header

- [x] **Author byline (Renata K.)** — non-interactive specimen label verified by
      Playwright before export
- [x] **Privacy chip** — non-interactive eyebrow verified by Playwright before
      export

### Outline rail

- [ ] **Outline row** — navigates to its section anchor; current row highlighted

### Reading column

- [ ] **Pinned passage row** — opens the passage in the reading desk
- [ ] **Footnote callout** — opens the footnote inline or to its source
- [ ] **Edit affordances** — verify whether inline editing controls exist
- [ ] **Save indicator** — verify auto-save status

### Veritas retraction notice

- [x] **Notebook-level notice disclosure** — native `<details>` summary opens an
      inline citation list and exposes
      `data-nisaba-notebook-retraction-cascade`,
      `data-nisaba-notebook-retraction-severity`, and affected-count attrs
- [x] **Citation row** — `data-nisaba-notebook-retraction-citation-row`
      preserves the original quote with struck-through treatment and names the
      affected notebook section / footnote
- [x] **Open corrected source** —
      `data-nisaba-notebook-retraction-action="open-corrected-source"` links to
      `/veritas/source/statnett-operator-data?origin=notebook-retraction`, and
      Playwright follows it to the Veritas source profile
- [x] **Open edition diff** —
      `data-nisaba-notebook-retraction-action="open-edition-diff"` links to
      `/nisaba/compare?origin=veritas-retraction&cascade=cascade-ai-governance-survey-retraction&citation=notebook-citation-ai-governance-adoption-claim`,
      where the passage edition-update notice renders the original vs. corrected
      citation diff
- [x] **Keep with marker** —
      `data-nisaba-notebook-retraction-action="keep-with-marker"` is visible but
      marked `aria-disabled="true"` / `data-placeholder="true"` until the
      persistence write exists

### Lilith thread

- [ ] **Suggestion card** — verify whether the user can accept / dismiss the
      suggestion
- [ ] **Cite the suggestion** — verify whether dropping the suggestion into the
      notebook is wired

### Export rail

- [x] **Markdown export** — Playwright clicks
      `data-nisaba-notebook-export="markdown"`, captures the generated Blob, and
      verifies filename, MIME type, heading, pinned-passages section, and
      numbered footnotes
- [x] **BibTeX export** — Playwright clicks
      `data-nisaba-notebook-export="bibtex"`, captures the generated Blob, and
      verifies filename, MIME type, `@misc{...}` content, and the notebook
      source attribution
- [x] **PDF export** — Playwright clicks `data-nisaba-notebook-export="pdf"`,
      captures the generated Blob, and verifies filename, MIME type, `%PDF-1.4`,
      notebook title, and pinned-passage content
- [x] **Print specimen** — Playwright stubs `window.print`, clicks
      `data-nisaba-notebook-export="print"`, and verifies the print request plus
      live export status

## Data & contracts

- **Reads**: `getNisabaNotebook()` from `@/lib/lilith-data/nisaba-depth` —
  returns `NisabaNotebookData` (`outline: [n, t, here][]`, pinned passages,
  tags, recent activity, and optional `retractionNotice`)
- **Writes**: verify edit / save endpoints (the eyebrow says "last edit, 11 min
  ago" but the rendering treats the notebook as a display specimen); the
  retraction notice's keep-with-marker action is intentionally a placeholder
  until the acknowledgement write exists
- **Realtime**: _None observed._
- **Caching**: server fetch
- **Auth/role check**: shell middleware
- **Privacy**: `metadata.robots = { index: false, follow: false }` keeps the
  notebook out of search engines

## E2E coverage

- `apps/oshun/web/e2e/veritas-retraction-cascade.spec.ts` — step 5 opens
  `/nisaba/notebook`, verifies the Veritas retraction notice disclosure, opens
  the citation row, asserts the original quote and placeholder keep-with-marker
  action, then follows the corrected-source link to the Veritas source profile
- `apps/oshun/web/e2e/veritas-nisaba-bridge.spec.ts` — step 8 starts at the
  retracted Veritas claim confidence band, opens this notebook marker, follows
  the affected citation's edition-diff link to `/nisaba/compare`, and verifies
  the cascade-specific edition-update notice and corrected-source handoff
- `apps/oshun/web/e2e/nisaba-notebook-capture-cite.spec.ts` — opens
  `/nisaba/notebook`, verifies the private notebook specimen text, checks
  `noindex,nofollow`, and captures the real browser Blob payloads for Markdown,
  BibTeX, and PDF exports before verifying print dispatch

## 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-plan.md`](./nisaba-plan.md),
    [`nisaba-scholar.md`](./nisaba-scholar.md)
- Component sources:
  - `apps/oshun/web/src/components/lilith/nisaba.tsx` (`NisabaNotebook`)
- Feature spec: [`V1/features.md#nisaba`](../../../V1/features.md#nisaba)

## Open questions / known gaps

- [ ] Confirm whether the notebook supports actual editing in V1 (the source
      reads as a display composition; the metadata claims
      `last edit, 11 min     ago`)
- [ ] Document the auto-save contract and the BFF endpoint when writes are wired
- [ ] Confirm the Lilith suggestion source — assistant runtime, curated threads,
      or both
- [ ] Verify that `robots: index: false, follow: false` is sufficient for the
      "private" promise (no shareable URL token in the route)
