---
status: reconciled-partial
coverage_depth: deep-for-independent-durable-and-browser-seams
last_walked: 2026-05-29
last_reconciled: 2026-07-21
specs:
  - apps/oshun/web/e2e/nisaba-notebooks-index.spec.ts
  - apps/oshun/web/e2e/nisaba-notebook-new.spec.ts
  - apps/oshun/web/e2e/nisaba-annotation-bff.spec.ts
  - apps/oshun/web/e2e/nisaba-notebook-bff.spec.ts
  - apps/oshun/web/e2e/nisaba-split-view.spec.ts
  - apps/oshun/web/e2e/nisaba-reading-compare-annotate.spec.ts
  - apps/oshun/web/e2e/nisaba-notebook-capture-cite.spec.ts
  - apps/oshun/web/e2e/nisaba-analytics.spec.ts
  - apps/oshun/web/e2e/nisaba-metis-study-prompts.spec.ts
  - apps/oshun/web/e2e/studio-study-a11y.spec.ts
  - apps/oshun/web/e2e/studio-study-alignment-maps.spec.ts
  - apps/oshun/web/e2e/studio-study-epistemic-types.spec.ts
  - apps/oshun/web/e2e/studio-study-walking-skeleton.spec.ts
source: WALKTHROUGH/journeys/nisaba-notebook-capture-and-cite.md
---

# Journey result: Nisaba notebook capture and cite — two durable lanes, disconnected clients

- **Walked**: 2026-05-29 at `9455bc53ad`. The retained result named an ephemeral
  `/tmp/claude-oshun-lt-2-walkthrough/walk.mjs` script and recorded three
  rendered routes, one notebook create request, zero page errors, and zero
  persistent failures. It preserved no script, trace, account, notebook id,
  annotation, item read-back, citation payload, or downloaded artifact.
- **Reconciled**: 2026-07-21 against the notebook index and create form, live
  Nisaba reading workspace, browser note and citation builders, fixture notebook
  detail and export block, authenticated BFF routes, ordered durable store,
  production wiring, erasure/export integration, the now-interactive Studio
  study workspace, its session-verifying proxy, Yemaya study service,
  Nisaba-owned Postgres adapter, publication gate, study-trail export, four
  Studio browser suites, three BFF durability suites, and all nine legacy
  Playwright files. This was source review, not a fresh application, BFF,
  study-service, Postgres, object-store, or product-browser run.
- **Verdict**: **partial / deep for the independent shipped seams** — owner-
  scoped notebooks and annotations have real HTTP contracts, write-before-ack
  durable snapshots, restart restoration, deletion fences, and data export.
  Annotation-to-notebook association also materializes a real notebook item.
  Studio now delivers a second durable, anchor-cited path with Nisaba-native
  notebook/card identities and a study-trail export. The legacy browser still
  does not join its create label, local study-note composer, stored-notebook
  links, citation generator, and fixture export page to that path or to one
  canonical citation lifecycle.
- **Current authority**:
  [`WALKTHROUGH/journeys/nisaba-notebook-capture-and-cite.md`](../journeys/nisaba-notebook-capture-and-cite.md)
  follows the split between the legacy BFF snapshot, the Studio study service's
  Nisaba Postgres records, browser-local study notes, client-derived citations,
  and the authored notebook specimen.

## Result at a glance

| Interaction                 | Proof · limit                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Historical route walk       | **Proof:** `/nisaba`, `/nisaba/notebooks`, and `/nisaba/notebook/new` rendered, and the create form reached `POST /v1/nisaba/notebooks`. **Limit:** route reachability and a request attempt did not prove owner read-back, item capture, durable commit, citation provenance, or that the opened detail represented the created id.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| Studio study workspace      | **Proof:** `/studio/study` now mounts a real project → rights → ingest → anchor → notebook/card → study-trail-export client behind a session-verifying web proxy. Four available capability entries point to the live workspace, Nisaba index, and Library; ten craft lenses are explicitly manual-only, and automated analysis is unavailable. **Limit:** this is a separate study-service/Nisaba-Postgres authority, not hydration of the legacy BFF notebook pages, local notes, or six-format citation builder.                                                                                                                                                                                                                                                                                                                             |
| Studio notebook and card    | **Proof:** the service rejects unknown anchors, mints `nbk_`/`crd_` identities in Nisaba-owned code, stores current revisions in `nisaba_study`, gates audience widening by cited-work rights, restores across an app restart, and includes notebooks in a rights-filtered study-trail export. **Limit:** the UI always cites its first anchor; notebook creation and project-ref update span two databases without a transaction; card insert and notebook supersession are also separate statements; the card route does not authorize the target notebook.                                                                                                                                                                                                                                                                                   |
| Notebook creation           | **Proof:** the mobile browser case submits title, visibility, and optional text with bearer and CSRF headers, receives a generated notebook id, and reads the row back from the real BFF. **Limit:** the field labelled **First passage (optional)** is converted to `summary`; the form sends no `linkedPassageId` and creates no passage item. Its **Open it** link targets the fixture detail route.                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| Notebook index              | **Proof:** seven cases distinguish a real row, an honest live empty state, mobile/standalone containment, anonymous gating, and service-worker document replay. **Limit:** an authenticated BFF refusal silently substitutes three review fixtures. The cards link to `/nisaba/notebook?id=...`, not the BFF-provided `/workspace/notebook/:id` launch path.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| Durable member state        | **Proof:** production requires a snapshot sink, hydrates `nisaba-study-workspaces` before traffic, awaits each candidate snapshot before exposing the mutation, rolls back failed writes, restores notebook/annotation relationships, and returns `503` when required persistence is unavailable. **Limit:** it is one ordered snapshot for all subjects, not row-level notebook storage, and the named web API cases do not restart Postgres.                                                                                                                                                                                                                                                                                                                                                                                                  |
| Annotation capture          | **Proof:** the live workspace submits selection offsets/excerpt, note, color, visibility, tags, notebook ids, and evidence ids. The BFF validates referenced ids, creates or updates the owner record, and automatically synchronizes its annotation item into every associated notebook before durable acknowledgment. **Limit:** named browser cases seed an annotation through HTTP and then update/archive it; none drives real text selection through browser creation and reads the resulting notebook item back.                                                                                                                                                                                                                                                                                                                         |
| Dedicated item API          | **Proof:** `POST /v1/nisaba/notebooks/:id/items` resolves `passage`, `annotation`, `grounded-evidence-view`, and `compare` refs; the passage case proves a launchable item, duplicate idempotency, and no mutation for an unknown ref. **Limit:** the current reading component never calls this route for passage, evidence, or compare capture.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| Workspace study note        | **Proof:** the notes inspector captures context, title, body, and tags, keeps up to 24 notes under `oshun.nisaba.study-notes`, and has browser and analytics evidence. **Limit:** **Save note** writes only localStorage. The visible **Saved to ...** status and **Durable notes stay attached ...** copy do not represent a BFF notebook or annotation mutation.                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| Citation workspace          | **Proof:** the browser builds and can copy/download Citation, BibTeX, RIS, CSL-JSON, Markdown, and JSON for current artifacts; tests exercise live passage/source reads, format changes, copy status, links, and enabled download controls. **Limit:** output is synthesized from current title, meta, summary, route, selected passage, and access time. It has no canonical citation id, edition pin, DOI authority, immutable locator, source hash, or signed manifest.                                                                                                                                                                                                                                                                                                                                                                      |
| Notebook detail and exports | **Proof:** `/nisaba/notebook` renders a rich no-index specimen, and browser probes validate its fixture-derived Markdown, BibTeX, minimal PDF, and print actions. **Limit:** the page accepts no id, calls `getNisabaNotebook()` with no subject or notebook argument, and always returns the Renata K. fixture. **Cite this** and **Resolve** remain inert.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| Data lifecycle              | **Proof:** customer export includes notebook and annotation records; account deletion erases the exact subject, preserves neighbors, persists a restart-safe fence, and rejects stale recreation with `409`. **Limit:** browser-local study notes and fixture exports are outside that server lifecycle, and no joined named browser case requests export or erasure after capture.                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| Studio lifecycle            | **Proof:** source deletion runs a durable saga, removes media and derived export objects, tombstones study records, and opens review tasks for affected Nisaba notebooks instead of rewriting them. An owner may also hard-delete an archived project only after its source list is empty. **Limit:** project deletion tombstones the project without cascading source or Nisaba records. The Oshun account export/deletion registry covers legacy BFF notebooks/annotations, not `nisaba_study.notebook` or `study_card`; the adapter exposes no author-scoped list/delete contract, so Studio records have no demonstrated DSAR erasure path.                                                                                                                                                                                                 |
| Named automation            | **Proof:** the nine legacy Playwright files contain 50 cases, while four Studio study browser files add nine real-stack cases. Six launch-surface component cases, 15 adapter cases, 11 publication cases, and at least 29 environment-gated walking-skeleton cases were present at this reconciliation. The service suite covers grant correction, renewal, revocation, quarantine review, allowed actions, layered resolution, non-mutating change simulation, and ordered rights-audit history through the generated client. **Limit:** its newest question/source-management cases are adjacent service evidence, and the browser still only creates the initial grant; the evidence spans two notebook stores, two clients, localStorage, fixtures, and generated metadata rather than one cross-client capture-to-canonical-citation run. |

## Evidence map

The map reads from one selected client surface into two shipped durability
lanes. Solid edges stay inside an authority. Dashed edges show where a client
crosses into a different store or substitutes derived/specimen output; those
boundaries are why the whole page is still partial.

```mermaid
flowchart TB
    S[Client surface] --> A[Legacy reading and annotation UI]
    S --> D[Studio study UI]
    A --> B[BFF owner record and synchronized item]
    B --> C[Awaited nisaba-study-workspaces snapshot]
    D --> E[Session proxy and study service]
    E --> F[Validated project anchor]
    F --> G[Nisaba adapter mints notebook and card refs]
    G --> H[Nisaba Postgres current revisions]
    H --> I[Rights-filtered study-trail export]
    C -. legacy links ignore stored id .-> J[Renata K. fixture and exports]
    C -. browser-only note .-> K[LocalStorage study note]
    C -. metadata-derived output .-> L[Six citation formats]
    H -. separate authority and no legacy hydration .-> C
```

## Proven observations

### The historical pass proved route repair, not the named lifecycle

- The old walk correctly recorded that the notebooks index and new-notebook
  routes no longer returned `404`, and that the create form could reach a real
  endpoint. Those were useful launch checks.
- Its generic `pass` collapsed several different outcomes: a rendered list, an
  attempted write, a passage annotation, a captured notebook item, a citation,
  and a stored-notebook export. The preserved evidence reaches only the first
  two.
- “0 persistent failures” described the walker's visible route session. It was
  not a BFF restart result, a snapshot check, a second-account isolation test,
  or an export verification.
- The route now has far stronger repository evidence than the old result knew
  about, but that evidence also makes the missing browser joins more precise.

### The Studio study route has become a second real capture authority

- `/studio/study` still leads with the manual-first capability inventory, but it
  now mounts `StudyWorkspaceApp` below it. Study projects/source ingest and
  playback/annotation link to that live section; Nisaba notebooks and Library
  remain real destinations. Ten craft lenses expose honest manual-annotation
  vocabularies without analyzers; only automated lens analysis is marked **Not
  yet available** without a control.
- The client drives project creation, work registration, deny-before-rights
  ingest, playback, manual segments and anchors, observations, a Nisaba
  notebook, study cards, study-trail export, and source deletion. It holds only
  the HttpOnly Oshun session cookie.
- `/api/study/[...path]` verifies that session through the BFF refresh exchange,
  mints a five-minute study token, and proxies GET/POST/DELETE to the configured
  service. Missing service URL/signing secret returns `503`; missing or refused
  session returns `401` instead of a fixture success.
- Four Studio Playwright suites contain nine cases over the real-stack harness:
  four accessibility and keyboard-driven journeys, one alignment-map journey,
  one epistemic-type journey, and three walking-skeleton cases including export,
  deletion, expiry, and accessibility. They are substantive product evidence,
  not the six launch-surface component cases.

### Studio authors Nisaba-native records, with two important write boundaries

- The notebook form requires an existing anchor, but it always selects
  `trail.anchors[0]`, appends `[^1]` to the narrative, and sends one `^1`
  citation. The browser offers no anchor picker, marker editor, multi-citation
  composer, publication control, or link into the resulting stored record.
- The study route validates the project tenant and every cited anchor before it
  calls the adapter. Nisaba-owned code mints opaque `nbk_` notebook and `crd_`
  card refs; the `nisaba_study` schema stores every revision and enforces one
  current revision. Card append supersedes the notebook to list the card.
- Publication widening is a separate, shipped service route. It verifies project
  tenant, notebook project and tenant, author-or-project-owner status, and
  collaboration/publication rights for every cited work; narrowing is allowed
  and both outcomes are audited. The current Studio UI does not expose that
  route.
- Notebook creation writes the Nisaba database before adding the ref to the
  Yemaya project. Card append writes the card before superseding the notebook.
  The first sequence spans databases and the second spans tables; neither is
  wrapped in a transaction or compensating rollback, so a later write failure
  can leave an orphan notebook or card. A notebook supersession likewise marks
  the former revision before inserting the next one without a surrounding
  transaction.
- More seriously, the card endpoint validates each supplied anchor against the
  request's `projectId`, but it does not verify that the target notebook belongs
  to that project, tenant, or actor. The adapter fetches by opaque ref and then
  supersedes that notebook. Knowledge of another ref is therefore enough to
  cross the intended authorization boundary; no named test exercises that case.
- Production wires the adapter only when `NISABA_DATABASE_URL` is present; an
  absent adapter makes notebook routes return `503`. A completed study export
  reads Nisaba notebooks into the rights-filtered document, records an export
  reference, stores the JSON in the object store, and returns a five-minute
  presigned URL. It is an authoritative study-service bundle, not a formatted
  scholarly citation.
- Source deletion deliberately does not mutate a Nisaba notebook that cites the
  deleted work. The durable saga captures affected refs while anchors still
  exist, tombstones Yemaya records and removes object/export bytes, then opens
  affected-decision review tasks for the notebooks.
- Account deletion is a different boundary. The BFF export/erasure registry
  includes its legacy notebook and annotation partitions, but no integration
  enumerates or deletes `nisaba_study.notebook` or `study_card` rows by author.
  The new Studio records therefore have no demonstrated customer export or
  account-erasure path.

### Notebook creation and notebook opening use different meanings of “passage”

- `/nisaba/notebook/new` is a real client form. It requires a two-character
  title, offers a keyboard-operable private/unlisted/public radio group,
  attaches bearer and CSRF headers, and reports explicit HTTP or offline
  failure.
- The optional field is labelled **First passage**, but `buildNotebookSummary`
  simply trims that text and sends it as `summary`. The payload contains title,
  summary, visibility, and empty tags. It does not contain `linkedPassageId`,
  selection offsets, a source id, or an item body.
- The created response is real and the focused E2E reads title, summary, and
  visibility back through `GET /v1/nisaba/notebooks`. The success panel then
  offers `/nisaba/notebook?id=<created id>`.
- The index repeats that destination for every live or fallback row. In
  contrast, the BFF serializes a notebook's launch target as
  `/workspace/notebook/<id>`, which the Nisaba domain workspace can use to
  select a notebook summary while keeping the reading frame mounted.
- `/nisaba/notebook` receives neither `searchParams` nor an authenticated
  subject. It calls a zero-argument `getNisabaNotebook()`, and that function
  returns `getNisabaNotebookFixture()`. The query id is therefore decorative.
- The index's real empty branch is honest, but its failure branch is not
  distinguishable in the rendered copy. When `bffGet` returns null, the page
  shows **On the citadel**, **The night watch**, and **Quiet hour** as three
  held notebooks with current-relative edit dates.

### Legacy BFF notebook and annotation writes are ordered and durable

- `NisabaConsumerStateStore` retains member-authored notebooks, annotations,
  saved passage ids, and study reminders in one `NisabaStudyWorkspaceSnapshot`.
  Shared corpus passages, manuscripts, compare views, and grounded evidence are
  deliberately recomputed rather than copied into the member snapshot.
- Production calls `requireDurableNisabaStudyWorkspaces()` before startup. When
  the admin snapshot database is configured, startup loads
  `nisaba-study-workspaces` and binds the save sink before accepting traffic.
- Notebook create/update/item capture and annotation create/update clone the
  current record, apply a candidate mutation, await `sink.save`, and only then
  publish the candidate to the visible in-memory record. A failed snapshot
  becomes `nisaba_study_workspace_persistence_unavailable`, and the route sends
  `503` without exposing the candidate.
- Mutations share a global ordered tail and a subject tail. Tests prove rollback
  after one failed snapshot, recovery on the next write, and deterministic
  create/delete race outcomes. They do not provide an HTTP revision precondition
  for two editing clients; the server serializes arrival order.
- The restart test proves that annotation notes and generated notebook items
  survive snapshot restore. The real-Postgres test is environment-gated and
  exercises saved-passage/reminder partitions while retaining a notebook; it is
  not a deployed browser journey for notebook capture.

### Annotation association is now a real notebook-item write

- The reading workspace captures a real DOM selection, supplies its excerpt and
  offsets, and defaults the annotation form to the selected notebook id. Create
  and update mutations go through the shared BFF hooks.
- The route requires authentication plus `domain:*` or `domain:nisaba`,
  validates the passage, notebook ids, evidence-view ids, selection, note,
  color, and visibility, and binds the write to `authContext.userId`.
- `synchronizeAnnotationNotebookItems` removes an older copy of that annotation
  item, rebuilds it from the current note and passage, inserts it for each
  notebook id still associated with the annotation, sorts the items, and bumps
  the notebook update time. The durable test reads that relationship after a
  simulated restart.
- This corrects the earlier journey claim that `notebookIds` was merely a loose
  association. It is a materialized notebook item today.
- Archive is a status update, not deletion. Because synchronization keys on
  `notebookIds`, not active status, archiving an annotation leaves its notebook
  item present unless the association is separately removed.
- The four-case annotation API spec does not attach a notebook id. The broader
  browser specs seed associated annotations through HTTP and exercise live
  update/archive UI. No named test selects passage text, clicks the browser
  create control, observes `Highlight saved`, and then performs a notebook
  detail read-back for that same annotation item.

### The dedicated item route is broader than the current browser capture UI

- `POST /v1/nisaba/notebooks/:notebookId/items` accepts exactly four kinds:
  passage, annotation, grounded-evidence-view, and compare. It resolves the ref
  against the caller's seeded/shared view of the Nisaba record and fails closed
  if the notebook or referenced resource is missing.
- The passage API case proves a deterministic item id, nonempty title, source-
  derived summary, launch path, revision bump, and idempotent duplicate replay.
  The unknown-ref case proves revision and item count stay unchanged.
- The new-notebook form never calls this route. Neither the selection handler
  nor citation/source controls call it for passage, evidence, or compare. Only
  annotation association reaches a notebook item automatically through the
  annotation mutation.
- The index reports `passageCount` from items whose kind is exactly `passage`.
  An annotation captured into a notebook increments `annotationCount`, not the
  visible passage count on that index card.

### The workspace note composer is local continuity with durable-sounding copy

- `handleSaveNote` builds a `NisabaStudyNote` with the selected notebook id and
  title, passage anchor, source label, context frame, body, tags, and
  timestamps. It prepends the record to localStorage and caps the array at 24.
- The corresponding draft store, collections, study plans, and density mode are
  also browser-side continuity. The split-view test explicitly reads the
  `oshun.nisaba.study-notes` key after the save.
- No note-save branch calls the notebook, item, or annotation endpoint. It does
  not update the BFF revision, materialize a notebook item, enter the customer
  export bundle, or cross devices through the account.
- The interface nevertheless says **Saved to <notebook>** and **Durable notes
  stay attached to <notebook>**. “Attached” here means the local record carries
  the notebook id; “Durable” is not supported by the persistence authority.
- Analytics evidence is useful but orthogonal: the event reports ids, counts,
  mode, and origin while omitting note text. It does not turn the local note
  into server state.

### Citation output is functional browser serialization, not canonical scholarship

- `buildNisabaCitationExportArtifacts` collects current route artifacts and can
  append browser-local collection and study-plan artifacts. It de-duplicates by
  id and produces six formats per artifact.
- The plain citation, BibTeX, RIS, and CSL-JSON all identify the author as Oshun
  Nisaba and use the browser's access date. Markdown and JSON retain title,
  metadata, summary, route, and selected passage context. Copy and Blob-download
  controls are real.
- The citation-trail panel derives a primary source step, optional manuscript
  witness, and up to three contextual concept steps from the current passage and
  a BFF-provided source-lineage view. Its own source comment says the BFF does
  not ship canonical citation-trail data.
- A “fully traced” panel state is computed from the grounded-view status; it is
  not a DOI resolution, edition lock, immutable locator, content digest, or
  signed provenance statement.
- The named citation cases prove live passage hydration, four format
  transitions, JSON parsing, source-panel drill-down, copy status, link copy,
  and enabled download controls. They do not compare the output with a canonical
  citation service or reopen it after an edition change.

### The rich notebook exporter operates entirely on authored specimen data

- The detail page always displays **Renata K.**, **On the ruling part**, **14
  entries**, **last edit, 11 min ago**, a fixed word count, citation density,
  activity, a Lilith suggestion, and privacy copy. Most of those values are
  component literals; outline, pins, tags, recent activity, and retraction copy
  come from the fixture function.
- **Cite this** and **Resolve** are `LBtn` controls without `href` or `onClick`.
  The retraction **Keep with marker** control is likewise presented as a pending
  write rather than a completed mutation.
- The export block is real. It builds fixture-derived Markdown with footnotes,
  one BibTeX `@misc` per pin, a small single-page PDF string, and a print call.
  The six-case browser spec captures Blob filename, MIME type, and content for
  all three downloads and observes the print request.
- `robots: { index: false, follow: false }` correctly emits `noindex,nofollow`.
  It does not authenticate the viewer, authorize the fixture as their notebook,
  or prevent a leaked URL from being requested.
- The server's customer export is more authoritative than this page: its
  `notebook` partition includes the caller's real notebook and annotation
  records. The specimen exporter never reads that partition or the selected
  notebook id.

### The named automation is deep but deliberately distributed

- The nine named Playwright files contain **50 cases**: seven for the index, two
  for creation, four for annotation HTTP, five for notebook HTTP, 18 for the
  split workspace, five for reading/compare/annotation, six for capture/cite
  exports, one for analytics, and two for Nisaba-to-Metis study handoff.
- Four Studio study Playwright files add **nine cases**: four accessibility and
  keyboard-driven journeys, one alignment-map journey, one epistemic-type
  journey, and three walking-skeleton cases. The walking skeleton authors a
  notebook and card, downloads a study-trail export containing the notebook,
  survives an app restart, deletes source derivatives, and checks rights expiry
  against real Postgres, MinIO, ffmpeg, and a separate Nisaba database when the
  harness is up.
- The launch inventory adds six component cases. The adapter has nine
  conformance plus six focused cases, the publication gate has 11, and the
  service walking skeleton had at least 29 environment-gated cases at this
  reconciliation; those counts overlap capabilities rather than representing
  additional browser journeys.
- Six of those service cases drive the generated client's rights lifecycle:
  correction/renewal/revocation, quarantined-grant approval, current allowed
  actions, an action-specific layered resolution with appeal context, a
  non-mutating revoke simulation, and chain-ordered rights-audit history. The
  Studio browser still calls only `grantRights`; it exposes no control for those
  subsequent review and decision operations.
- The twenty-seventh service case drives an adjacent question-first lifecycle:
  ask, rescope, investigate, reject an evidence-free answer, abandon, list, and
  replay history. `StudyWorkspaceApp` calls none of those question methods, so
  that case is not notebook-capture coverage.
- Two later cases read source detail/deletion impact and resolve source-identity
  candidates. They likewise deepen the shared service, not the notebook/citation
  browser path. The source gate therefore pins the relevant behaviors and only a
  lower bound for this actively growing global suite.
- Many cases use the real BFF and unique authenticated subjects. The index also
  proves real service-worker document replay and phone containment; the create
  form proves CSRF and text-safe telemetry; the citation/export probe inspects
  generated bytes.
- `state-durability.test.ts` adds 13 unit cases for write-before-ack snapshots,
  restart restoration, failure rollback, category erasure, fences, and races.
  `nisaba-durability.test.ts` adds two HTTP failure cases. The one Postgres case
  is skipped without a database URL.
- No one case joins: legacy browser text selection → BFF annotation and awaited
  snapshot → synchronized item → Studio `nbk_` record → stored-notebook UI →
  edition-pinned formatted citation → export → account erasure across both
  stores. The Studio journey is real, but it is a separate client and contract.

## Boundaries and gaps

- **A seed-passage label is not a captured passage item.** The create form maps
  that text to notebook summary and sends no source reference.
- **A durable notebook is not the page opened by `?id=`.** The BFF record is
  real; `/nisaba/notebook` ignores the id and renders a fixture.
- **A Studio notebook is not the legacy BFF notebook.** It has a Nisaba-native
  ref and durable `nisaba_study` revisions, but neither legacy notebook page
  hydrates it and the Studio client does not open a notebook detail view.
- **A service rights lifecycle is not a browser review console.** The generated
  client and integration suite exercise correction, renewal, revocation,
  quarantine review, allowed actions, layered resolution, simulation, and audit
  history, but the current Studio client only creates the initial grant.
- **Ordered writes are not one transaction.** Nisaba notebook persistence
  precedes the Yemaya project-ref write across databases; card insert precedes
  notebook supersession, and revision marking precedes revision insert, without
  a transaction or compensating rollback if the later statement refuses.
- **An opaque notebook ref is not authorization.** The Studio card route checks
  the supplied anchor's project but not the target notebook's project, tenant,
  or author before it supersedes that notebook.
- **Legacy account erasure is not Studio notebook erasure.** The BFF deletion
  fence covers its snapshot records, while the separate `nisaba_study` tables
  have no wired author-scoped export/delete contract.
- **A fixture fallback is not an honest live-data state.** The index substitutes
  three authored notebooks without a degraded or review-data marker.
- **A browser-local note is not a durable notebook note.** LocalStorage is the
  only note-write authority despite the UI's durable wording.
- **An automatic annotation item is not a browser-proven capture lifecycle.**
  The store synchronizes it, but the named browser cases do not drive selection
  creation and item read-back as one path.
- **An archive is not removal from the notebook.** Archived annotations retain
  their notebook item while `notebookIds` remains attached.
- **A serialized arrival order is not optimistic concurrency control.** The API
  returns revisions but accepts no expected revision or `If-Match` condition.
- **A generated citation format is not a canonical edition pin.** Browser
  metadata and access time do not establish immutable scholarly authority.
- **A derived source trail is not a signed provenance manifest.** Grounding
  status selects presentation confidence without hashing the cited edition.
- **An exportable fixture is not an export of the selected stored notebook.**
  Markdown, BibTeX, PDF, and print all serialize authored Renata K. data.
- **`noindex,nofollow` is not access control.** It is crawler guidance only.
- **A service-worker replay is not a fresh server read.** The offline index case
  deliberately replays the cached authenticated document.
- **Server erasure is not browser-note erasure.** The deletion runner fences
  durable notebooks and annotations; the local note key is a separate client
  lifecycle.
- **Fifty-six web cases are not one joined capture-to-canonical-export
  journey.** The set deeply proves two service authorities plus independent API,
  localStorage, fixture, and browser-serialization seams.

## Re-run evidence

The 2026-07-20 work reconciled source and Docs Center evidence after the Studio
study stack landed upstream. It did not execute the 13 application Playwright
files, the real-stack service suite, or the three legacy BFF durability suites.
A fresh product run should retain durable artifacts rather than another
ephemeral walker:

```bash
pnpm --dir apps/oshun/web exec playwright test -c playwright.config.ts e2e/nisaba-notebooks-index.spec.ts e2e/nisaba-notebook-new.spec.ts e2e/nisaba-annotation-bff.spec.ts e2e/nisaba-notebook-bff.spec.ts e2e/nisaba-split-view.spec.ts e2e/nisaba-reading-compare-annotate.spec.ts e2e/nisaba-notebook-capture-cite.spec.ts e2e/nisaba-analytics.spec.ts e2e/nisaba-metis-study-prompts.spec.ts --project=chromium --workers=1
pnpm --dir apps/oshun/web exec playwright test -c playwright.config.ts e2e/studio-study-a11y.spec.ts e2e/studio-study-alignment-maps.spec.ts e2e/studio-study-epistemic-types.spec.ts e2e/studio-study-walking-skeleton.spec.ts --project=chromium --workers=1
pnpm --dir apps/oshun/web exec vitest run src/app/studio/study/__tests__/study-page.spec.tsx
pnpm --dir libs/nisaba/study-adapter exec vitest run src/adapter.spec.ts src/conformance.spec.ts
pnpm --dir libs/yemaya/study-workspace exec vitest run src/notebook-publication.spec.ts
STUDY_PG_REQUIRED=1 pnpm --dir apps/yemaya/svc-study-workspace exec vitest run src/__tests__/walking-skeleton.integration.spec.ts
pnpm --dir apps/oshun/bff exec vitest run src/nisaba/state-durability.test.ts src/routes/nisaba-durability.test.ts
OSHUN_ADMIN_DATABASE_URL=... pnpm --dir apps/oshun/bff exec vitest run src/nisaba/state-durability.integration.test.ts
```

Retain the commit and environment, authenticated subject and adjacent subject,
create payload and response revision, snapshot store and commit result, selected
passage offsets, annotation id, synchronized notebook item, restart read-back,
index provenance state, exact page opened from the notebook link, citation
format bytes, Studio project/anchor/`nbk_`/`crd_` refs, both database commit
results, study-pack object and signature status, exported notebook id and bytes,
customer-export row, erasure receipt/fence, and the final state in both server
and browser storage.

## Source trail

- [`apps/oshun/web/src/app/nisaba/notebooks/page.tsx`](../../apps/oshun/web/src/app/nisaba/notebooks/page.tsx)
  — live list normalization, real empty state, fixture fallback, and id-bearing
  links to the specimen detail.
- [`apps/oshun/web/src/app/nisaba/notebook/new/NisabaNewNotebookForm.tsx`](../../apps/oshun/web/src/app/nisaba/notebook/new/NisabaNewNotebookForm.tsx)
  — browser create payload, CSRF/bearer headers, summary mapping, and success
  destination.
- [`apps/oshun/web/src/components/domains/NisabaSurface.tsx`](../../apps/oshun/web/src/components/domains/NisabaSurface.tsx)
  — live reading workspace, annotation mutations, local notes, citation/source
  derivation, and notebook-summary hydration.
- [`apps/oshun/web/src/components/studio/StudioStudyWorkspace.tsx`](../../apps/oshun/web/src/components/studio/StudioStudyWorkspace.tsx),
  [`apps/oshun/web/src/components/studio/StudyWorkspaceApp.tsx`](../../apps/oshun/web/src/components/studio/StudyWorkspaceApp.tsx),
  [`apps/oshun/web/src/app/studio/study/page.tsx`](../../apps/oshun/web/src/app/studio/study/page.tsx),
  [`apps/oshun/web/src/app/api/study/[...path]/route.ts`](../../apps/oshun/web/src/app/api/study/[...path]/route.ts),
  and
  [`apps/oshun/web/src/app/studio/study/__tests__/study-page.spec.tsx`](../../apps/oshun/web/src/app/studio/study/__tests__/study-page.spec.tsx)
  — truthful three-state capability inventory, live study client,
  session-verifying proxy, canonical route, and six launch-surface component
  cases.
- [`apps/yemaya/svc-study-workspace/src/routes/study-routes.ts`](../../apps/yemaya/svc-study-workspace/src/routes/study-routes.ts),
  [`apps/yemaya/svc-study-workspace/src/index.ts`](../../apps/yemaya/svc-study-workspace/src/index.ts),
  and
  [`apps/yemaya/svc-study-workspace/src/__tests__/walking-skeleton.integration.spec.ts`](../../apps/yemaya/svc-study-workspace/src/__tests__/walking-skeleton.integration.spec.ts)
  — notebook/card routes, production dependency wiring, study-trail export,
  restart evidence, and the current card-authorization boundary.
- [`libs/nisaba/study-adapter/src/adapter.ts`](../../libs/nisaba/study-adapter/src/adapter.ts),
  [`libs/nisaba/study-adapter/src/notebook-store.ts`](../../libs/nisaba/study-adapter/src/notebook-store.ts),
  and
  [`libs/yemaya/study-workspace/src/use-cases/set-notebook-publication.ts`](../../libs/yemaya/study-workspace/src/use-cases/set-notebook-publication.ts)
  — Nisaba-native identity, revisioned Postgres persistence, card supersession,
  and rights-gated audience changes.
- [`libs/yemaya/study-workspace/src/use-cases/deletion-saga.ts`](../../libs/yemaya/study-workspace/src/use-cases/deletion-saga.ts)
  — durable source cleanup and affected-notebook review creation without
  rewriting Nisaba-owned records.
- [`libs/yemaya/study-workspace/src/use-cases/manage-study-project.ts`](../../libs/yemaya/study-workspace/src/use-cases/manage-study-project.ts)
  — owner-gated hard deletion for an archived project with no remaining source
  references; it tombstones the project without cascading source or Nisaba
  records.
- [`apps/oshun/web/e2e/studio-study-walking-skeleton.spec.ts`](../../apps/oshun/web/e2e/studio-study-walking-skeleton.spec.ts),
  [`apps/oshun/web/e2e/studio-study-a11y.spec.ts`](../../apps/oshun/web/e2e/studio-study-a11y.spec.ts),
  [`apps/oshun/web/e2e/studio-study-alignment-maps.spec.ts`](../../apps/oshun/web/e2e/studio-study-alignment-maps.spec.ts),
  and
  [`apps/oshun/web/e2e/studio-study-epistemic-types.spec.ts`](../../apps/oshun/web/e2e/studio-study-epistemic-types.spec.ts)
  — nine real-stack browser cases spanning the durable capture path and adjacent
  evidence, review, accessibility, expiry, and deletion behavior.
- [`apps/oshun/web/src/lib/nisaba-offline.ts`](../../apps/oshun/web/src/lib/nisaba-offline.ts)
  and
  [`apps/oshun/web/src/lib/nisaba-citation-export.ts`](../../apps/oshun/web/src/lib/nisaba-citation-export.ts)
  — browser storage and Blob/copy helpers.
- [`apps/oshun/web/src/app/nisaba/notebook/page.tsx`](../../apps/oshun/web/src/app/nisaba/notebook/page.tsx),
  [`apps/oshun/web/src/lib/lilith-data/nisaba-depth.ts`](../../apps/oshun/web/src/lib/lilith-data/nisaba-depth.ts),
  and
  [`apps/oshun/web/src/components/lilith/NisabaNotebookExportBlock.tsx`](../../apps/oshun/web/src/components/lilith/NisabaNotebookExportBlock.tsx)
  — zero-argument fixture detail, robots metadata, and specimen exports.
- [`apps/oshun/bff/src/routes/nisaba.ts`](../../apps/oshun/bff/src/routes/nisaba.ts)
  and
  [`apps/oshun/bff/src/nisaba/state.ts`](../../apps/oshun/bff/src/nisaba/state.ts)
  — auth/scope gates, notebook/annotation/item APIs, materialized relationships,
  ordered mutation store, durability, and deletion fences.
- [`apps/oshun/bff/src/server.ts`](../../apps/oshun/bff/src/server.ts) and
  [`apps/oshun/bff/src/data-export/bundle-builder.ts`](../../apps/oshun/bff/src/data-export/bundle-builder.ts)
  — production snapshot wiring, account-deletion join, and customer export.
- [`apps/oshun/bff/src/nisaba/state-durability.test.ts`](../../apps/oshun/bff/src/nisaba/state-durability.test.ts),
  [`apps/oshun/bff/src/routes/nisaba-durability.test.ts`](../../apps/oshun/bff/src/routes/nisaba-durability.test.ts),
  and
  [`apps/oshun/bff/src/nisaba/state-durability.integration.test.ts`](../../apps/oshun/bff/src/nisaba/state-durability.integration.test.ts)
  — restart, rollback, failure, erasure, race, and environment-gated Postgres
  evidence.

## Cross-references

- [`nisaba-scholarly-read.md`](./nisaba-scholarly-read.md) — the broader split
  between the curated reading desk, live domain workspace, offline cache, and
  legacy study fixtures.
- [`citation-drift-resolution.md`](./citation-drift-resolution.md) — operator
  classification and resolution when a supporting source moves.
- [`account-deletion-and-dsar.md`](./account-deletion-and-dsar.md) — deletion
  and customer-export authorities that now include durable Nisaba records.
- [`nisaba-notebook.md`](../customer/07-nisaba/nisaba-notebook.md) and
  [`nisaba-notebook-new.md`](../customer/07-nisaba/nisaba-notebook-new.md) —
  per-view interaction inventories.

## Open questions

- [ ] Enforce project, tenant, and author/owner authorization on Studio study-
      card append before any lookup or mutation of the target notebook.
- [ ] Make the Nisaba notebook/card write and the Yemaya project/notebook-
      revision write atomic, or add idempotent compensation and orphan repair.
- [ ] Decide whether legacy BFF notebooks and Studio `nbk_` notebooks converge
      behind one reader/detail route, or label them as deliberately separate
      record families in every client.
- [ ] Let Studio authors choose cited anchors and markers, inspect the stored
      notebook/card, and invoke the shipped publication gate from the UI.
- [ ] Add author-scoped Studio notebook/card partitions to customer export and
      account erasure, with restart-safe deletion fencing across the separate
      Nisaba database.
- [ ] Route live index and create-success links to the real
      `/workspace/notebook/:id` surface, or make `/nisaba/notebook?id=` hydrate
      that exact stored record and its items.
- [ ] Rename **First passage** to **Summary** or send a resolvable
      `linkedPassageId`/item capture instead of storing free text as summary.
- [ ] Remove the silent notebook-index fixture fallback or label it explicitly
      as review data with a retryable degraded state.
- [ ] Persist workspace study notes through a durable, exportable, erasable note
      contract; until then, replace **Durable notes** and **Saved to** copy with
      accurate browser-local language.
- [ ] Add a real-browser selection → annotation create → synchronized notebook
      item → restart read-back case under one authenticated subject.
- [ ] Define archive semantics for associated annotation items and expose an
      explicit detach or delete path.
- [ ] Add expected-revision/`If-Match` conflict semantics and a reader-facing
      resolution path for concurrent notebook or annotation edits.
- [ ] Define canonical citation ids, edition/version pins, stable locators,
      content hashes, manifests, and retirement/replacement behavior before
      calling client-generated output canonical.
- [ ] Export the selected stored notebook rather than the authored fixture, and
      decide whether Chicago, APA, MLA, SBL, or CSL style rendering is in scope.
- [ ] Replace or clearly label the Renata K. specimen's last-edit, entry count,
      word count, citation density, Lilith suggestion, privacy, and retraction
      controls.
