---
path: /studio/hathor/journal-and-codex
surface: studio
domain: hathor
auth: signed-in + studio entitlement
source: apps/oshun/web/src/app/studio/hathor/journal-and-codex/page.tsx
status: walked
last_walked:
  '2026-07-03 focused real-dev-infra Playwright route walk — anonymous redirect,
  Hathor-admin catalog load, browser bearer propagation, exact default /
  empty-discovery / duplicate-flag codex unlock results 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-journal-and-codex.spec.ts and
  WALKTHROUGH/results/v1-real-infra-run-2026-06-22.md#278-2026-07-03-studio-hathor-journal-and-codex-real-bff-coverage'
---

# Studio Hathor · Journal and Codex

## Purpose

The load-bearing surface is an admin lane console — the **Live Codex Unlock
Resolver** — that runs the real codex-unlock resolver over a set of codex
entries and player progress to compute which entries unlock, completion
percentage, and the next unlock. The operator submits a JSON codex payload and
the lane returns the resolved unlock state. The resolver is wrapped in a
retained dense expert-mode shell (controls grid, observability, etc.).

## Entry points

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

## Layout regions

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

- **Workspace** `<StudioHathorJournalAndCodexWorkspace />`:
  - `WorkspaceHeading` `<h1>` — "Hathor Journal and Codex Workspace" + an intro
    `<p>` describing journal/codex/citation governance
  - **Live Codex Unlock Resolver** lane (`data-jcx-lane`) —
    `<h2 data-jcx-heading>`; the real admin lane console (loading / unauthorized
    / error / form / result)
  - A retained "Expert Controls" shell beneath the lane (density / breakpoint
    selects under `data-hathor-journal-and-codex-controls-grid` and further
    expert panels) — scaffolding around the lane, not the load-bearing surface
- **Route Map panel** `data-hathor-journal-and-codex-route-map` — `<h2>` "Route
  Map" listing the 5 `STUDIO_HATHOR_JOURNAL_AND_CODEX_ROUTE_MAP` entries
  (entries / codex / citations / governance child paths) with
  `data-hathor-jcx-route-count` and per-entry `data-route-path`
- **Quick-action lane** `data-hathor-jcx-quick-actions` — two `Link.quickAction`
  anchors: Story Graph Authoring, Back to Studio workspace index

## States

- [x] **Loading** — `data-jcx-loading` "Loading codex unlock resolver…";
      Playwright holds the catalog request before releasing it to a 503
- [x] **Unauthorized (admin-scope 401/403)** — `data-jcx-unauthorized`, verified
      with a non-admin browser bearer forwarded to the real BFF
- [x] **Error** — `data-jcx-error`, verified for 503 catalog and malformed
      catalog bodies
- [x] **Ready (form)** — when `outcome.status === 'ready'`: `data-jcx-form`
      exposes `data-jcx-form-state="idle"` and `aria-busy="false"` with the
      default codex payload
- [x] **Pending** — `data-jcx-form-state="pending"`, disabled textarea/button,
      `aria-busy="true"`, and button text "Resolving…" while the POST is held
- [x] **Result** — `data-jcx-result` with `data-jcx-headline`,
      `data-jcx-completion`, `data-jcx-next`, and `data-jcx-entries` (per-entry
      `data-jcx-entry-row` carrying `data-jcx-entry-state` /
      `data-jcx-entry-missing`), verified for default, empty-discovery, and
      duplicate-flag payloads against the real BFF
- [x] **Validation error** — `data-jcx-resolve-error` for invalid JSON,
      non-object JSON, BFF invalid-payload detail, malformed 200 result, and
      transport failure

## Interactions

### Live Codex Unlock Resolver lane

- [x] **Codex entries payload** — `<textarea data-jcx-payload>` (aria-label
      "codex entries json"), disabled during pending submit, 44px minimum
      target, and mobile no-overflow verified
- [x] **Submit** — `<button data-jcx-submit>` "Resolve unlocks" → POST
      `JCX_RESOLVE_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_JOURNAL_AND_CODEX_ROUTE_MAP` (5 entries) by
      `data-hathor-jcx-route-count` and per-entry `data-route-path`

### Quick-action lane

- [x] **"Open Hathor Story Graph Authoring workspace"** →
      `/studio/hathor/story-graph-authoring`
- [x] **"Back to Studio workspace index"** → `/studio`

## Data & contracts

- **Reads**: `GET /v1/admin/hathor/journal-and-codex` (`JCX_ENDPOINT`) — the
  codex resolver catalog
- **Writes**: `POST /v1/admin/hathor/journal-and-codex/resolve`
  (`JCX_RESOLVE_ENDPOINT`) with the codex entries payload
- **Realtime**: none for the resolver 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-journal-and-codex.spec.ts` forwards browser
  resolver 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-story-graph-authoring.md`](./studio-hathor-story-graph-authoring.md),
  [`./studio-hathor-narrative-export.md`](./studio-hathor-narrative-export.md)
- Component sources:
  - `apps/oshun/web/src/components/studio/StudioHathorJournalAndCodexWorkspace.tsx`
  - `apps/oshun/web/src/components/studio/StudioHathorJournalAndCodexRouteMap.ts`
- Real-infra Playwright:
  `apps/oshun/web/e2e/studio-hathor-journal-and-codex.spec.ts`

## Open questions / known gaps

- [ ] The workspace still ships a large dense expert-mode shell (density /
      breakpoint controls, expert panels) around the real resolver lane. Confirm
      whether that shell is intended for V1 or is migration debris from the
      older list-detail-wizard template; the load-bearing surface is the
      resolver 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.
