---
path: /studio/hathor/chronicle-parser
surface: studio
domain: hathor
auth: signed-in + studio entitlement
source: apps/oshun/web/src/app/studio/hathor/chronicle-parser/page.tsx
status: walked
last_walked: |
  2026-07-03 standalone real-BFF route addendum: the dedicated Playwright spec now covers anonymous redirect, admin direct navigation, live chronicle-parser catalog GET, AuthProvider Hathor-admin bearer propagation, exact two-age Chronicle parse statistics through the real BFF and @hathor/pre-production, client-only empty-source rejection, BFF detail surfacing, parse transport failure, catalog loading/503/malformed states, non-admin fail-closed state, pending submit disablement, route-map and quick-action affordances, mobile 44px controls, direct BFF auth/schema gates, and shared axe.
  Evidence: WALKTHROUGH/results/v1-real-infra-run-2026-06-22.md §269; apps/oshun/web/e2e/studio-hathor-chronicle-parser.spec.ts.
  2026-05-29 automated runtime walk evidence: WALKTHROUGH/results/runtime-sweep-2026-05-29.md; body re-derived 2026-06-03 from current source (lane-console architecture).
---

# Studio Hathor · Chronicle Parser

## Purpose

Admin lane console for the real `@hathor/pre-production` `parseChronicle`
lore-document parser. Paste a Chronicle source (title-page key/value block,
`=== ERA ===` headings, typed `BATTLE: … - place - date` event headings,
`@SPEAKER` + dialogue, narration, `{{document: …}}` references), pick extraction
options, and read back the structured element-type histogram plus chronicle
statistics (era / event counts, the unique speaker and location sets, dialogue /
narration word counts). Admin-scoped and fail-closed.

## Entry points

- **Quick-action link from `/studio/hathor/lore-compiler`** — "Open Hathor
  Chronicle Parser workspace"; that page also shows a breadcrumb Studio › Hathor
  Chronicle Parser › Lore Compiler
- **Aggregator embed**: `StudioHathorLoreCompilerWorkspace` mounts
  `<StudioHathorChronicleParserWorkspace />` inline as its "Chronicle Parser
  Lane"
- **Direct URL / bookmark** — yes; `alternates.canonical` set
- **Studio overview** — see
  [`../../studio-overview.md`](../../studio-overview.md)

## Layout regions

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

- **Workspace** `<section data-hathor-chronicle-parser-workspace>` — owns:
  - `<h1>` (WorkspaceHeading) "Hathor Chronicle Parser Workspace"
  - Summary `<p data-hathor-chronicle-parser-summary>`
  - The catalog summary (`data-hathor-cp-catalog`) and parse form lane
    (catalog-gated): `data-hathor-cp-parse-form`
- **Route Map panel** (`data-hathor-chronicle-parser-route-map`): `<h2>` "Route
  Map" + 5 entries from `STUDIO_HATHOR_CHRONICLE_PARSER_ROUTE_MAP`, each tagged
  with `data-hathor-chronicle-parser-route-map-entry` and `data-route-path`
- **Quick-action lane** (`data-hathor-chronicle-parser-quick-actions`): two
  `Link.quickAction` anchors — Cinematography Planning
  (`data-hathor-chronicle-parser-quick-action="cinematography-planning"`), Back
  to Studio workspace index
  (`data-hathor-chronicle-parser-quick-action="studio-index"`)

## States

- [x] **Loading** — `<p data-hathor-cp-loading>` "Loading chronicle parser…"
      while the GET catalog request is in flight
- [x] **Unauthorized** — `data-hathor-cp-unauthorized` "Access restricted." on
      401/403 (admin Hathor scope required); fail-closed
- [x] **Error** — `data-hathor-cp-error` "Could not load the chronicle parser."
      on non-OK GET or malformed catalog
- [x] **Ready (form)** — `data-hathor-cp-parse-form` renders once the catalog
      (`elementTypes`, `statFields`) loads, with visible
      `data-hathor-cp-catalog`
- [x] **Pending submit** — `data-hathor-cp-submit-state="pending"`; source,
      toggles, and submit are disabled with `aria-busy="true"` until the BFF
      response returns
- [x] **Result** — `data-hathor-cp-result` after a 200 parse; client validation
      / non-200 / transport failures surface through
      `data-hathor-cp-parse-error`

## Interactions

### Workspace body (parse form lane)

- [x] **Chronicle source** — `<textarea data-hathor-cp-source>` (aria-label
      "chronicle source"), seeded with a default chronicle
- [x] **Normalize speakers** —
      `<input data-hathor-cp-normalize type="checkbox">` inside
      `data-hathor-cp-normalize-control`
- [x] **Include annotations** —
      `<input data-hathor-cp-annotations type="checkbox">` inside
      `data-hathor-cp-annotations-control`
- [x] **Parse chronicle** — `<button data-hathor-cp-parse-submit type="submit">`
      → POST `/v1/admin/hathor/chronicle-parser/parse` with
      `{ source, options: { normalizeSpeakers, includeAnnotations } }`
- [x] **Result fields** — `data-hathor-cp-element-count`, `-era-count`,
      `-event-count`, `-speakers`, `-locations`, `-word-count` (with
      dialogue/narration), `-doc-refs`, optional `-title-page`, and a
      `data-hathor-cp-histogram` list of `data-hathor-cp-histogram-row` per
      element type

### Route Map panel

- [x] **5 route entries** (non-interactive `<article>` rows) — verify match with
      `STUDIO_HATHOR_CHRONICLE_PARSER_ROUTE_MAP`

### Quick-action lane

- [x] **"Open Hathor Cinematography Planning workspace"** (link →
      `/studio/hathor/cinematography-planning`)
- [x] **"Back to Studio workspace index"** (link → `/studio`)

## Data & contracts

- **Reads**: GET `/v1/admin/hathor/chronicle-parser` (catalog of element types
  - stat fields) on mount
- **Writes**: POST `/v1/admin/hathor/chronicle-parser/parse`
- **Realtime**: none
- **Caching**: client `fetch` on mount, `cache: 'no-store'`;
  `buildBffAuthHeaders`
- **Auth/role check**: admin-scoped fail-closed (401/403 → Access restricted);
  route is behind the signed-in + studio proxy gate

## Cross-references

- Parent: [`../../studio-overview.md`](../../studio-overview.md)
- Shell:
  [`../../../shell/04-auth-session.md`](../../../shell/04-auth-session.md)
- Sibling routes:
  [`./studio-hathor-lore-compiler.md`](./studio-hathor-lore-compiler.md)
  (aggregator that embeds this workspace),
  [`./studio-hathor-cinematography-planning.md`](./studio-hathor-cinematography-planning.md)
- Component sources:
  - `apps/oshun/web/src/components/studio/StudioHathorChronicleParserWorkspace.tsx`
  - `apps/oshun/web/src/components/studio/StudioHathorChronicleParserRouteMap.ts`

## E2E coverage

- [`apps/oshun/web/e2e/studio-hathor-chronicle-parser.spec.ts`](../../../../apps/oshun/web/e2e/studio-hathor-chronicle-parser.spec.ts)
  covers the standalone route against the real dev BFF: anonymous redirect,
  admin direct navigation, catalog GET with browser bearer forwarding, exact
  two-age Chronicle parse statistics from `@hathor/pre-production`, client-only
  empty-source rejection, BFF detail surfacing, parse transport failure, catalog
  loading/503/malformed states, non-admin fail-closed state, pending submit
  lockout, route-map and quick-action affordances, 44px checks for controls and
  quick-action links, mobile no-overflow, direct BFF 401/403/400/200 contract
  gates, document-reference parsing, and the shared axe gate.

## Open questions / known gaps

- [x] Hathor is confirmed in V1 per `WALKTHROUGH/matrix/routes.csv` and
      `WALKTHROUGH/matrix/coverage.md` (product-owner confirmation recorded
      2026-05-29 for Bellona / Hathor / Neith).
- [ ] Confirm whether the dedicated `/studio/hathor/*` admin lane consoles ship
      in V1 or are internal-only operator tooling.
- [ ] Route Map advertises `sources/`, `events/`, `actors/`, and `governance/`
      sub-routes that have no `page.tsx` yet — confirm whether they are planned
      drill-downs or aspirational IA.
- [ ] Manual screen-reader pass remains for the live browser surface; automated
      axe and touch-target coverage now pass for the standalone route.
