---
path: /studio/hathor/narrative-export
surface: studio
domain: hathor
auth: signed-in + studio entitlement
source: apps/oshun/web/src/app/studio/hathor/narrative-export/page.tsx
status: walked
last_walked:
  '2026-07-03 focused real-dev-infra Playwright route walk — anonymous redirect,
  Hathor-admin segment-type catalog load, browser bearer propagation, exact
  seeded and edited stage-direction narrative export estimates through the real
  BFF, client JSON/object validation, BFF invalid-payload detail surfacing,
  malformed result/catalog fail-closed states, loading / 503 / non-admin /
  transport states, pending-submit lockout, route-map and quick-action
  contracts, mobile no-overflow / 44px targets, scoped axe, and direct BFF
  auth/schema gates. Evidence:
  apps/oshun/web/e2e/studio-hathor-narrative-export.spec.ts and
  WALKTHROUGH/results/v1-real-infra-run-2026-06-22.md#279-2026-07-03-studio-hathor-narrative-export-real-bff-coverage'
---

# Studio Hathor · Narrative Export

## Purpose

The load-bearing surface is an admin lane console — the **Live Export
Estimator** — that estimates a narrative export package: runtime, page count,
and per-type word/segment counts from the supplied narrative payload. The
operator submits a JSON export payload and the lane returns the estimate. The
estimator is wrapped in a retained dense expert-mode shell.

## Entry points

- **Quick-action link from `/studio/hathor/journal-and-codex`** and the
  **`/studio/hathor/narrative`** aggregator — "Open Hathor Narrative Export
  workspace"
- **Direct URL / bookmark** — yes; `alternates.canonical` set to
  `/studio/hathor/narrative-export`
- **Studio overview** — see
  [`../../studio-overview.md`](../../studio-overview.md)

## Layout regions

`page.tsx` renders inside `<ShellLayout active="studio">`:

- **Workspace** `<StudioHathorNarrativeExportWorkspace />`:
  - `WorkspaceHeading` `<h1>` — "Hathor Narrative Export Workspace" (with a
    `data-hathor-narrative-export-screenreader-summary` SR summary)
  - **Live Export Estimator** lane (`data-nxe-lane`) — `<h2 data-nxe-heading>`;
    the real admin lane console (loading / unauthorized / error / form / result)
  - A retained dense expert-mode shell around the lane — scaffolding, not the
    load-bearing surface
- **Route Map panel** `data-hathor-narrative-export-route-map` — `<h2>` "Route
  Map" listing the 5 `STUDIO_HATHOR_NARRATIVE_EXPORT_ROUTE_MAP` entries (exports
  / packages / destinations / governance child paths) with
  `data-hathor-nxe-route-count` and per-entry `data-route-path`
- **Quick-action lane** `data-hathor-nxe-quick-actions` — two `Link.quickAction`
  anchors: Journal and Codex, Back to Studio workspace index

## States

- [x] **Loading** — `data-nxe-loading`; Playwright holds the catalog request
      before releasing it to a 503
- [x] **Unauthorized (admin-scope 401/403)** — `data-nxe-unauthorized`, verified
      with a non-admin browser bearer forwarded to the real BFF
- [x] **Error** — `data-nxe-error`, verified for 503 catalog and malformed
      catalog bodies
- [x] **Ready (form)** — `data-nxe-form` exposes `data-nxe-form-state="idle"`
      and `aria-busy="false"` with the default export payload
- [x] **Pending** — `data-nxe-form-state="pending"`, disabled textarea/button,
      `aria-busy="true"`, and button text "Estimating…" while the POST is held
- [x] **Result** — `data-nxe-result` with `data-nxe-headline`,
      `data-nxe-runtime`, `data-nxe-pages`, and `data-nxe-types` (per-type
      `data-nxe-type-row` carrying `data-nxe-type-words` /
      `data-nxe-type-segments`), verified for seeded and edited stage-direction
      payloads against the real BFF
- [x] **Validation error** — `data-nxe-estimate-error` for invalid JSON,
      non-object JSON, BFF invalid-payload detail, malformed 200 result, and
      transport failure

## Interactions

### Live Export Estimator lane

- [x] **Export payload** — `<textarea data-nxe-payload>` (aria-label "narrative
      export json"), disabled during pending submit, 44px minimum target, and
      mobile no-overflow verified
- [x] **Submit** — `<button data-nxe-submit>` "Estimate export" → POST
      `NXE_ESTIMATE_ENDPOINT`; browser auth header and request body are captured
      while the same-origin call is forwarded to the real local BFF

### Route Map panel

- [x] **Route entries** — verified to match
      `STUDIO_HATHOR_NARRATIVE_EXPORT_ROUTE_MAP` (5 entries) by
      `data-hathor-nxe-route-count` and per-entry `data-route-path`

### Quick-action lane

- [x] **"Open Hathor Journal and Codex workspace"** →
      `/studio/hathor/journal-and-codex`
- [x] **"Back to Studio workspace index"** → `/studio`

## Data & contracts

- **Reads**: `GET /v1/admin/hathor/narrative-export` (`NXE_ENDPOINT`) — the
  export-estimator catalog
- **Writes**: `POST /v1/admin/hathor/narrative-export/estimate`
  (`NXE_ESTIMATE_ENDPOINT`) with the export payload
- **Realtime**: none for the estimator lane
- **Caching**: client `fetch` on mount, `cache: 'no-store'`,
  `buildBffAuthHeaders()`
- **Auth/role check**: admin-scoped, fail-closed on 401/403; route additionally
  gated signed-in + studio by the BFF proxy
- **Real-infra E2E**:
  `apps/oshun/web/e2e/studio-hathor-narrative-export.spec.ts` forwards browser
  estimator calls to the real local BFF and separately asserts direct BFF
  unauthenticated, non-admin, invalid-payload, and valid-result gates.

## Cross-references

- Parent: [`../../studio-overview.md`](../../studio-overview.md)
- Shell:
  [`../../../shell/04-auth-session.md`](../../../shell/04-auth-session.md)
- Sibling routes:
  [`./studio-hathor-journal-and-codex.md`](./studio-hathor-journal-and-codex.md),
  [`./studio-hathor-narrative.md`](./studio-hathor-narrative.md) (the aggregator
  that embeds this lane)
- Component sources:
  - `apps/oshun/web/src/components/studio/StudioHathorNarrativeExportWorkspace.tsx`
  - `apps/oshun/web/src/components/studio/StudioHathorNarrativeExportRouteMap.ts`
- Real-infra Playwright:
  `apps/oshun/web/e2e/studio-hathor-narrative-export.spec.ts`

## Open questions / known gaps

- [ ] The workspace still ships a large dense expert-mode shell around the real
      estimator lane. Confirm whether that shell is intended for V1 or is
      migration debris; the load-bearing surface is the estimator lane.
- [ ] Hathor is `unconfirmed-v1` per `WALKTHROUGH/matrix/routes.csv`. Confirm
      whether the dedicated `/studio/hathor/` lane consoles ship at V1 or are
      internal-only.
