V1 Web PWA · Coverage matrix

Coverage

The route/coverage matrix for the V1 Web PWA walkthrough.

coverage matrix
15sections62 minread5tables

On this page

What's covered by the walkthrough, what's stub, what's deferred. Reflects the state on the day this file was last updated — for live status, query routes.csv.

At a glance#

Bucket Count Walkthrough status
Total page.tsx files in apps/oshun/web/src/app/ 701
In V1 scope 692 690 walked · 2 drafted
Out of V1 (V2/V3/V6/V7 prefixes) 9 9 walked (100%)

2026-06-03 reconciliation pass. An adversarial doc-vs-code audit across all 684 per-view files found the studio surface had drifted hard: every studio doc claimed ShellLayout active="explore" (all 483 pages use active="studio"), and ~470 studio domain-bridge/core docs described an obsolete flow-card/FLOW_POLICY/fixture template. The real components are live admin-scoped BFF "Lane" consoles (GET /v1/admin/<domain>/<slug> catalog + POST .../<verb>). All studio bodies were re-derived from current source; customer/operator/shell/journeys docs were reconciled (wired Lilith room buttons, real BFF reads, proxy.ts not middleware.ts, no operator-role gate, /system/* is anon, scene unlock server action, etc.); the 8 previously-drafted routes were runtime-probed (Playwright, prod build + mock BFF — 12/12 render HTTP 200 with the right <h1>, 0 page errors) and promoted to walked. CSV is now 684 walked / 0 drafted. See results/walkthrough-runtime-probe-2026-06-03.md.

2026-06-04 comprehensive sweep. A full executable Playwright probe of all 684 routes (real per-worker signed-in session, prod build + mock BFF) plus a fan-out adversarial doc-vs-code audit of every per-view file + journeys/ + shell/. Runtime: 650/684 render cleanly first pass; the 34 non-passing were 5 real React #418 hydration mismatches (/domains/nyx/{events,moon,solar}, /domains/tara/{analytics,collections}) — fixed in app source and re-verified (/domains re-probe 55/55, 0 page errors) — plus 32 AAA-gated /studio/isis/* routes correctly hard-blocking under a contemplative session (§24.11, working as designed; content verified by the isis doc audit). Doc audit fixed a bounded set of real drift: 2 fully-stale Tara TTS docs rewritten, 52 route-map off-by-one counts, 4 welcome/test-* auth misclassifications, 3 isis selector errors, and ~20 smaller endpoint/count/path/terminology corrections across customer, studio, operator, journeys, and shell. Probe tool: scripts/walkthrough-probe-all.mjs. See results/walkthrough-comprehensive-sweep-2026-06-04.md.

2026-07-16 Docs Center reconciliation. The live app had reached 701 page.tsx routes while routes.csv still held 692. Nine routes were absent from the matrix; seven also lacked per-view pages. All nine rows are now present, the seven missing pages are authored, and the two existing pages (/lilith-studio/release, /tenant/invite) are indexed. A generator unit test now compares every tracked page.tsx to each Next.js walkthrough matrix exactly, so this under-enumeration class fails before rendering.

There is no longer an "unconfirmed-v1" bucket. The 157 Bellona / Hathor / Neith studio routes that were previously unconfirmed were confirmed in-v1 on 2026-05-29 by the product owner (see the studio sub-area note below).

The 2026-06-02 coverage-gap sweep closed 8 routes that recent feature work had added without a CSV row or per-view file (the count grew 676 → 684): 4 in-v1 (/nyx/sky-almanac + /studio/generation/{curated-cards,music,nyx-3d}) and 4 out-of-v1 future-version surfaces (/v6 + /egbe-studio for the V6 Egbe domain, /mawu-studio/{accessibility,localization} for the V7 Mawu domain). After the sweep the three sets are identical again: 684 app routes = 684 CSV rows = 684 per-view files.

Surface breakdown (V1 scope)#

Surface Routes Folder Status
customer 187 customer/ 186 walked · 1 drafted
studio 490 studio/ 490 walked (100%)
operator 13 operator/ 12 walked · 1 drafted
workspace 2 workspace/ 2 walked (100%)

In-v1 totals only (692). The 9 out-of-v1 routes break down as 6 customer (/v2×4, /v3/landing, /v6) and 3 studio (/egbe-studio, /mawu-studio/accessibility, /mawu-studio/localization) — see the Out-of-V1 section below. Counting all scopes the surface totals are: customer 193, studio 493, operator 13, workspace 2 = 701.

Customer domain breakdown#

Counts below are the live domain tallies from routes.csv for surface == customer (187 in-v1 + 6 out-of-v1 = 193 total customer routes). They match the per-view files one-to-one. The folder column is where the per-view files live; the CSV domain column is the grouping key.

Domain (CSV) Routes Folder Notes
arete 25 customer/04-arete/ /arete/* (incl. habits, habits/new, offerings, weekly) + /domains/arete/*
veritas 25 customer/05-veritas/ /veritas/* (incl. dynamic source profiles) + /domains/veritas/*
nyx 25 customer/06-nyx/ /nyx (incl. events, observation, tonight, sky-almanac) + /domains/nyx/*
lilith 13 customer/10-lilith/ /lilith, /personas, /lilith-studio/* (incl. release, scene/new, tara)
nisaba 11 customer/07-nisaba/ /nisaba/* (incl. notebooks, notebook/new)
discovery 11 customer/02-home-discovery/ /explore, /search, /library* (incl. collections, collections/new), /activity, /messages, /switcher, /events*
tara 10 customer/03-tara/ /tara, /tara/sit/[id] + /domains/tara/*
metis 11 customer/08-metis/ /metis/* plus /integrity/[verdictId]/appeal
account 10 customer/09-account/ /profile*, /billing*, and /settings
onboarding-public 10 customer/00-public/, 01-onboarding/ /landing, /welcome*, /onboarding, /auth/verify-email
legal 8 customer/00-public/ /legal/*
atelier 8 customer/11-atelier/ /atelier/* (incl. new, camera-obscura)
system 7 customer/13-system/ /system/*, /status, /aaa-upgrade
scene 3 customer/12-scene/ /scene/*
device-shell 2 customer/02-home-discovery/ /mobile, /tablet
home 1 customer/02-home-discovery/ / — the main entry
sophia 1 customer/14-sophia/ /sophia — grounded-only answer surface
shell-routing 3 customer/02-home-discovery/ /assistant, /notifications, and /d/[domain]/[[...path]]
domains-other 1 customer/02-home-discovery/ /domains/[domainId] catch-all
library 1 customer/02-home-discovery/ /share/[token] recipient-side collection resolution
onboarding-tenant 1 customer/01-onboarding/ /tenant/invite signed-in tenant-invitation acceptance
v2-knowledge 3 customer/00-public/ /v2/glossary, /v2/roadmap, /v2/wikiout-of-v1
v2-shell 1 customer/00-public/ /v2out-of-v1
v3-marketing 1 customer/00-public/ /v3/landingout-of-v1
v6-steward 1 customer/00-public/ /v6 — Egbe Steward web app (V6 arc) — out-of-v1

Account data-rights real-infra route journey (2026-06-25): /profile/data now exercises all three read lanes against authenticated dev BFF routes: /v1/data-rights/consent is a real customerConsentStateStore projection instead of a domain-stub fixture, while exports/deletions continue to use the canonical stores. profile-data-readback.spec.ts covers consent transition reflection, empty export/deletion state, seeded completed export and scheduled deletion snapshots, anonymous redirect gating, the 50-row export cap, download aria labeling, mobile 44 px controls/no horizontal overflow, and the shared axe gate.

Account persona voice real-infra route journey (2026-06-25): /profile/persona now consumes the real registry-derived /v1/persona/voice contract instead of the stale fixture shape. The BFF projects voice-profile metadata (providerId, engineId, voiceProfileId, locales, watermark/disclosure requirements) and explicitly returns previewUrl: null until preview media is a real registry asset. profile-persona-readback.spec.ts covers no-consent empty state, real voice-consent grant, real persona selection → active voice readback, metadata/card rendering, anonymous redirect gating, Data Rights handoff, mobile 44 px controls/no horizontal overflow, and the shared axe gate.

Account notifications real-projection route journey (2026-06-30): /profile/notifications now reads an authenticated /v1/profile/notifications projection from the customer profile store, notification-preferences store, and Telegram link store instead of the old guarded fixture. profile-notifications-index.spec.ts plants the real access token for the server-rendered BFF read, asserts the live summary and profile email, flips notifications.pushEnabled through real PATCH /v1/preferences and verifies the Push channel disables on reload, covers invalid-bearer fail-closed empty copy, and retains footer, mobile, standalone-PWA, telemetry, anonymous-gate, and real-service-worker offline replay coverage. BFF coverage in notifications-preferences-route.test.ts proves auth gating and store-backed projection.

Account settings direct-route profile projection (2026-06-30): /settings now renders domain statistics and connected-service rows from the authenticated profile projection instead of component-local demo arrays. /v1/profile projects calendar services from calendarOAuthConnectionStore and notification channels from channelBindingsStore, while the settings rail routes service actions into /profile?path=calendar / /profile?path=notifications and domain management into /domains/<id>?origin=profile. profile-settings-flows.spec.ts seeds a verified channel through the real BFF channel-binding round trip, asserts the projected connected state, and drives the service/domain management navigations from direct /settings.

Account Telegram live linked-state polling (2026-06-30): /profile/telegram now keeps the not-linked card live after the user opens the Telegram deep link. The client state panel polls the authenticated /v1/telegram/link BFF read while the page remains open and repaints to the linked card as soon as the real /telegram/webhook /start link-<nonce> path completes the nonce. profile-telegram-bridge.spec.ts verifies the browser stays on the same /profile/telegram URL, the card moves from data-profile-telegram-live-status="watching" to "linked", and no generic fallback token or reload is needed.

Account memory BFF retry state (2026-06-30): /profile/memory now distinguishes an empty Iris review from an unavailable BFF read. A transient review/consent failure keeps cached rows visible, renders data-profile-memory-bff-status with a Retry Iris read action, and retries against the live /v1/iris/adapter/review BFF path. The focused memory-edit-pause-forget.spec.ts failure-mode leg proves cached-row preservation, visible retry copy, and alert dismissal after the real BFF retry succeeds.

Studio sub-area breakdown#

Sub-area Routes Notes
aja 98 Studio bridge for Aja (embodied instr.)
isis 88 Governed generation control plane
yemaya 79 Rendering substrate bridge
concordia-workbench 12 Cross-domain editorial workbench
bellona 82 In V1 (confirmed 2026-05-29; not yet in features.md)
hathor 74 In V1 (confirmed 2026-05-29; not yet in features.md)
neith 1 In V1 (confirmed 2026-05-29; not yet in features.md)
tara 2
generation 6 living-scene, generation-gallery, asset-preview-pipeline, + curated-cards, music, nyx-3d (last 3 added 2026-06-02)
egbe (V6) 1 /egbe-studioout-of-v1 V6 creator suite (added 2026-06-02)
mawu (V7) 2 /mawu-studio/{accessibility,localization}out-of-v1 V7 (added 2026-06-02)
(other studio sub-areas) ~27 One route each: design-language, color-system, typography, navigation-commands, etc.

Routes under bellona, hathor, neith were confirmed in-v1 by the product owner on 2026-05-29 and flipped from unconfirmed-v1in-v1 in routes.csv. The corresponding domains do not yet appear in V1/features.md's "Customer-facing domains", "Platform substrates", or "Cross-domain support" lists — that spec should be updated to name Bellona (engine bridges / build pipeline), Hathor (narrative / world / lore), and Neith (inverse modeling) so the feature map matches the confirmed route scope.

Out-of-V1 (documented for completeness)#

Path prefix Routes Folder Status
/v2* 4 customer/00-public/v2*.md 4 drafted (100%)
/v3* 1 customer/00-public/v3-landing.md 1 drafted (100%)
/v4* 0 (no routes under apps/oshun/web/src/app/v4/) n/a
/v6 (V6) 1 customer/00-public/v6.md 1 drafted (100%)
/egbe-studio (V6) 1 studio/future/egbe-studio.md 1 drafted (100%)
/mawu-studio/* (V7) 2 studio/future/mawu-studio-*.md 2 drafted (100%)

Routes under /v2 and /v3 are real, anon-readable surfaces that ship with V1 builds even though they are out of the V1 feature map. They are drafted in customer/00-public/ with v1_scope: out-of-v1 declared in each frontmatter, so the V1 audit scope remains explicit while the walkthrough surface stays exhaustive.

The V6/V7 future-version surfaces (added in the 2026-06-02 sweep) follow the same v1_scope: out-of-v1 convention but are signed-in (not in PUBLIC_PATHS, unlike anon /v2/v3). /v6 is the customer-facing Egbe Steward web app (companion to the V6 mobile Steward App). /egbe-studio is the V6 Egbe creator suite and /mawu-studio/* are the V7 Mawu studio surfaces; both are ShellLayout active="studio" surfaces filed under a new studio/future/ folder (they live at top-level routes, not under /studio/*, so they are classified surface: studio by their shell role rather than their URL prefix). The Egbe domain (V6) and Mawu domain (V7) specs live at V6/ and V7/.

If apps/oshun/web/src/app/v4/, /v5/, or further version prefixes ever gain routes, add them with the same v1_scope: out-of-v1 flag — customer surfaces in customer/00-public/, studio surfaces in studio/future/.

Method#

routes.csv was generated from find apps/oshun/web/src/app -name page.tsx filtered and classified by:

  • route — derived from the file path
  • v1_scopeout-of-v1 if the route is a future-version surface; otherwise in-v1. Future-version surfaces are identified by a /vN URL prefix (/v2, /v3, /v6, …) or by belonging to a post-V1 domain even when the URL is unprefixed — /egbe-studio (V6 Egbe domain) and /mawu-studio/* (V7 Mawu domain) are out-of-v1 despite not starting with /vN. (Bellona / Hathor / Neith studio sub-areas were initially unconfirmed-v1 because they weren't in V1/features.md; the product owner confirmed them in-v1 on 2026-05-29, so the unconfirmed-v1 value is now retired and unused.)
  • surfacestudio / operator / workspace / customer, by URL prefix where one applies, else by the route's ShellLayout active= role (so the top-level /egbe-studio and /mawu-studio/* are surface: studio because they render ShellLayout active="studio").
  • domain — best-effort match against domain names and route grouping

If the classification is wrong, edit the CSV directly. The script that produced it (/tmp/classify-routes.py from the inventory step) is non-authoritative — the CSV is the truth.

Status legend (for status column)#

  • stub — no walkthrough file written yet
  • drafted — content written from code reading; not verified live
  • walked — verified live against the running app on a known commit
  • stale — code under Source: changed since Last walked

What's done so far#

Scaffold + shell (session 1, 2026-05-24):

  • shell/01-app-shell.md through shell/06-keyboard-a11y.md (6 docs)
  • One example per surface: customer/02-home-discovery/home.md, customer/03-tara/tara.md, studio/studio-overview.md, operator/operator-overview.md
  • One example journey: journeys/install-as-pwa.md

Customer surface sweep (session 2, 2026-05-24): all 147 customer routes drafted (5 parallel agents). Coverage per folder:

  • customer/00-public/ — 16 files (landing, welcome×7, legal×8)
  • customer/01-onboarding/ — 1 file (/onboarding)
  • customer/02-home-discovery/ — 12 files (home + explore + search + library + activity + messages + switcher + events + mobile + tablet + d-domain-path + domains-domainId)
  • customer/03-tara/ — 9 files (tara + 8 /domains/tara/*)
  • customer/04-arete/ — 21 files (9 polished + 12 namespace alternates)
  • customer/05-veritas/ — 23 files (9 polished + 14 namespace alternates)
  • customer/06-nyx/ — 21 files (1 hub + 20 /domains/nyx/*)
  • customer/07-nisaba/ — 9 files
  • customer/08-metis/ — 5 files
  • customer/09-account/ — 4 files (profile + memory + safety + billing/crypto)
  • customer/10-lilith/ — 9 files (lilith showcase + lilith-studio×8)
  • customer/11-atelier/ — 6 files
  • customer/12-scene/ — 3 files (scene + embed + report)
  • customer/13-system/ — 7 files (system×5 + status + aaa-upgrade)

Studio surface sweep (session 3, 2026-05-24): all 325 remaining studio in-v1 routes drafted (7 parallel agents). Coverage per folder:

  • studio/domain-bridges/aja/ — 98 files
  • studio/domain-bridges/isis/ — 88 files (16 AAA-gated per AAA_ONLY_STUDIO_ROUTES)
  • studio/domain-bridges/yemaya/ — 79 files (38 first-half + 40 second-half; 1 genuinely-deep surface at remote-actor-home-capture, 1566 LOC / 93 panels)
  • studio/domain-bridges/tara/ — 2 files (tts-voice-consent + tts-voice-contract)
  • studio/collaboration/concordia-workbench/ — 12 files (root + 11 case sub-surfaces; all share one workspace component dispatched via initialSurface prop)
  • studio/collaboration/ — 6 files (presence, comments, realtime, reviews, notifications, activity-change-feeds)
  • studio/design/ — 6 files (design-language, color-system, typography, spacing-layout, component-primitives, complex-interactions)
  • studio/governance/ — 10 files (rbac, audit, retention, launch readiness, tenant isolation, security hardening, authentication, a11y governance, experimentation, i18n)
  • studio/operations/ — 10 files (observability, perf budgets, backup, background jobs, resilience, quality, adoption, metrics, api-gateway-bff, sdk docs)
  • studio/authoring/ — 11 files (authoring, compose, navigation, search, ingestion, multi-project, workspace switching, project obsidian, session/device, webhooks, cross-domain entity model)
  • studio/generation/ — 3 files (generation, generation-gallery, asset-preview-pipeline)

Operator surface sweep (session 4, 2026-05-24): 5 remaining operator routes drafted (orchestrator wrote inline; small enough to skip agents).

  • operator/operator-admin.md/operator/admin (admin inbox: incidents, citation drift, tenant requests, support routing)
  • operator/operator-admin-isis-provenance.md/operator/admin/isis/provenance (hash-chain ledger inspector + generated-artifact provenance)
  • operator/operator-metis.md/operator/metis (institutional dashboard: lesson review queue, OneRoster sync, tutor telemetry, Themis flags)
  • operator/operator-studio.md/operator/studio (editorial review queue and approval workspace)
  • operator/operator-tenant.md/operator/tenant (tenant console: members, plans, sittings, last seen)

Workspace surface sweep (session 5, 2026-05-24): 2 remaining workspace routes drafted (orchestrator wrote inline).

  • workspace/workspace-catchall.md/(workspace)/workspace/[[...path]] (MultiPanelWorkspace — tabs / panels / side panel / search / content export / Iris mobile handoff; ~800+ LOC component)
  • workspace/app-surface-catchall.md/app/[surface]/[[...path]] (server-redirect alias; maps home|explore|activity|library|profile|search→explore to canonical shell routes; everything else → notFound())

Unconfirmed-v1 studio sweep (session 6, 2026-05-24): all 157 unconfirmed-v1 routes drafted (4 parallel agents).

  • studio/domain-bridges/bellona/ — 82 files (41 + 41 alphabetical split). Bellona has its own polycentric backbone: StudioBellonaBridgeProtocolAndSessionsWorkspace (~4000 LOC), StudioBellonaBlenderBridgeCommandsWorkspace, StudioBellonaBuildJobAuthoringWorkspace, etc.; no Hathor-Economy-Modeling embed.
  • studio/domain-bridges/hathor/ — 74 files (37 + 37). StudioHathorEconomyModelingWorkspace (~2756 LOC) is mounted natively at /studio/hathor/economy-modeling and embedded across ~265 confirmed-V1 studio routes.
  • studio/domain-bridges/neith/ — 1 file (/studio/neith/inverse-modeling). StudioNeithInverseModelingWorkspace has actual computed logic (RGBA reference-image feature extraction, terrain/vegetation/urban/noise parameter estimation, confidence scoring, export-manifest generation, plus real-BFF fit-quality evaluation).

Full coverage: 701 / 701 (100%) — every page.tsx in apps/oshun/web/src/app has a drafted walkthrough, including the 9 out-of-V1 surfaces (V2 / V3 closed out by the 2026-05-26 audit sweep; the V6 / V7 future surfaces closed out by the 2026-06-02 sweep) and /tara/sit/[id] (closed out by the 2026-05-27 audit sweep). The count was 676 through 2026-05-29; the 2026-06-02 sweep added 8 routes recent feature work had introduced (see "At a glance" and the session-9 entry below).

Coverage-gap audit sweep (session 8, 2026-05-29): a route-inventory diff (find apps/oshun/web/src/app -name page.tsx vs routes.csv vs per-view path: frontmatter) surfaced 32 real V1 routes that had no CSV row and no per-view file — they had been missed by the original sweeps. All 32 were authored from the live code (6 parallel agents), added to routes.csv, and verified to exist with substantive pages. After this sweep the three sets are identical: 676 app routes = 676 CSV rows = 676 per-view files, zero gaps in either direction. The 32 closed routes:

  • arete (4): /arete/habits, /arete/habits/new, /arete/offerings, /arete/weekly (last is a 308 redirect to /arete/review)
  • metis (5): /metis/courses/new, /metis/ingest, /metis/lessons, /metis/session, /metis/upload (last is a query-preserving 308 redirect to /metis/byom)
  • nyx (3): /nyx/events, /nyx/observation, /nyx/tonight
  • nisaba (2): /nisaba/notebooks, /nisaba/notebook/new
  • account (5): /billing, /profile/data, /profile/notifications, /profile/persona, /profile/telegram
  • atelier (2): /atelier/new, /atelier/camera-obscura
  • lilith (2): /lilith-studio/scene/new, /lilith-studio/tara
  • veritas (1): /veritas/evidence
  • sophia (1): /sophia — new customer/14-sophia/ folder (first customer-facing Sophia surface)
  • discovery (3): /events, /library/collections, /library/collections/new
  • operator (4): /operator/audit, /operator/incidents, /operator/sso, /operator/tenants

Coverage-gap audit sweep (session 9, 2026-06-02): the same route-inventory diff (find apps/oshun/web/src/app -name page.tsx vs routes.csv source column vs per-view source: frontmatter) surfaced 8 routes that recent feature work had added with no CSV row and no per-view file. All 8 were authored from the live component code, added to routes.csv, and the three sets re-verified identical (684 = 684 = 684, zero gaps either direction). The 8 closed routes:

  • nyx (1, in-v1): /nyx/sky-almanac — power-user depth page; SSR fetch of /v1/nyx/sky-almanac (computed by @oshun/domain-nyx), honest unavailable state with no fabricated astronomy → customer/06-nyx/nyx-sky-almanac.md
  • studio/generation (3, in-v1): /studio/generation/curated-cards (§24.6 six curated cards), /studio/generation/music (§24.6/§24.8 music), /studio/generation/nyx-3d (§24.6/§24.8 3D sky briefing) — all fail-closed 503 until a provider is configured → studio/generation/studio-generation-{curated-cards,music,nyx-3d}.md
  • V6 (2, out-of-v1): /v6 (Egbe Steward web app → customer/00-public/v6.md) and /egbe-studio (Egbe creator suite → studio/future/egbe-studio.md)
  • V7 (2, out-of-v1): /mawu-studio/accessibility, /mawu-studio/localization (Mawu studio → studio/future/mawu-studio-*.md)

This added the studio/future/ folder (out-of-v1 studio surfaces filed by shell role, since they live at top-level routes rather than under /studio/*), the v6-steward, egbe, and mawu domain keys, and a generation studio sub-area row. The V6 (egbe) and V7 (mawu) domains should be added to V1/features.md only if/when they are pulled into V1 scope; today they are explicitly out-of-v1.

Journeys sweep (session 7, 2026-05-24): 23 cross-view journeys drafted (4 parallel agents) + journey index. Total 24 journey files. See ../journeys/README.md for the bucket map. Buckets covered:

  • First-time + PWA infrastructure (5): first-time-anonymous-visitor, first-tara-sit, install-as-pwa, offline-first-time-use, pwa-update-flow
  • Customer domain entries (6): tara-daily-ritual, arete-create-habit, veritas-evidence-trail, nyx-tonight-observation, nisaba-scholarly-read, metis-lesson-completion
  • Cross-domain bridges (4): tara-to-nisaba-handoff, nyx-to-tara-bridge, veritas-to-nisaba-deeper, arete-streak-recovery
  • Lilith policy (1): crisis-aware-tone-policy
  • Operator + studio + cross-surface (6): editorial-review-approval, incident-triage, citation-drift-resolution, tenant-onboard, user-flag-to-review (blocked), sophia-grounded-answer
  • Workspace shell (1): multi-device-workspace-handoff (added to README bucket map in the 2026-05-26 audit sweep — file existed but was not indexed)
  • journeys/README.md — bucket map + cross-cutting findings + add-a-journey guide

Profile safety route journey (2026-06-25): /profile/safety is now walkthrough-documented as a real BFF-backed safety record surface. The profile-safety-crisis-recovery spec signs in a unique member, verifies the live no-frame empty state, activates a crisis frame through the real operator BFF route, waits for Redis-worker durable projection, then drives the browser readback, stillness, re-entry, check-ins, resource visibility, anonymous gate, and axe pass without mocking /v1/safety/crisis-frames/mine. The 2026-06-30 timeline addendum renders the full live BFF frames[] projection as an expandable cross-surface crisis-frame timeline covering assistant, Iris, Lilith video, Psyche, and Tara markers. The 2026-06-30 resource addendum verifies the surfaced us-988 link target and lilith_safety_resource_opened telemetry from the same live safety record.

Phase 2 architectural decisions (2026-05-24):

  • P2.1studio shell tab added; 488 studio routes flipped from active="explore"active="studio". Studio now has its own first-class sidebar entry, shortcut 6.
  • P2.2 — 11 admin bypass routes (8 Isis sub-routes + 2 cross-product + 1 voice-abuse) canonicalized: wrapped in AdminShell with session check; 3 new workspaces (isis, messaging, tenant-console) added to OSHUN_ADMIN_WORKSPACE_MODEL.
  • P2.3 — Namespace direction resolved as intentional consumer-vs-power-user split (see cross-cutting finding #1 below). Spec updates: V1/features.md per-domain "Surfaces" callouts + V1/ARCHITECTURE.md Customer Web section now name both namespaces with their audiences. No redirects, no route deletions.
  • P2.4 — Customer-side session-to-role wiring shipped (pure helper at lib/customer-role.ts + server reader at lib/server/customer-session.ts); /lilith-studio page now gates on studio:editorial scope and renders a denial UI for non-editorial visitors.

Remaining qualitative work:

  • Walking — 699 of 701 files are status: walked. The two pages authored from code during the 2026-07-16 reconciliation are still drafted: /operator/autonomy and /veritas/source/[sourceId]. Their per-view files name the exact runtime, mobile, accessibility, and failure-state checks still required before promotion.
  • V1-scope decisions — RESOLVED 2026-05-29. Bellona / Hathor / Neith were confirmed in-v1 by the product owner and flipped from unconfirmed-v1in-v1. Follow-up: add these three domains to V1/features.md so the feature map names them (the walkthroughs already document the surfaces).
  • Walkability blocked journeys — first-tara-sit (step 4, TaraRoom ghost button) and user-flag-to-review (step 1, no customer flag affordance exists) can't currently be walked end-to-end. These are load-bearing for V1 UAT.
  • P2.3 follow-up: per-view walkthrough files that framed /<domain>/* and /domains/<domain>/* as "polished vs internal" (vs the now-canonical "consumer hub vs power-user deep tools" framing) can be re-read against the new spec when each domain is walked live.

Customer sweep — cross-cutting findings#

Surfaced by the parallel agents during the customer sweep. These are issues in the underlying code that surfaced through the walkthrough, not walkthrough quality issues; recorded here so the next walker has them in mind.

  1. Two parallel UI namespaces per domain — RESOLVED as intentional audience split (P2 Decision 3, 2026-05-24). /<domain>/* is the consumer hub + depth (Lilith-design-system rooms, presentational, first-read customers). /domains/<domain>/* is the power-user deep tools layer (heavier client workspaces, scholars, customer-mode operators, editorial / curation roles). Both are V1; not deprecation candidates for each other. Metis and Nisaba do not yet ship a /domains/* namespace — their deep tools mount inside the consumer hub. The canonical contract is in V1/features.md and V1/ARCHITECTURE.md (Customer Web section). Per-view files that previously framed one as polished and the other as "internal" or "pre-V1" should be re-read against this split; that backlog is tracked but not blocking.
  2. Ghost buttons — placeholder state now honest at the primitive level (P3, 2026-05-25). The polished depth surfaces (Arete approve/skip, Veritas read-once/re-open, Atelier bake/mix/cast, etc.) still ship action-shaped UI without onClick handlers — wiring each surface requires new BFF endpoints and state stores that are out of scope for one session. As an interim fix, LBtn in apps/oshun/web/src/design-system/lilith/primitives.tsx now detects placeholder state (no onClick, no href) and renders the button with aria-disabled="true", data-placeholder="true", cursor: not-allowed, reduced opacity, and a "No handler wired — placeholder" tooltip. Screen readers announce the disabled state; sighted users see the dimmed treatment. Future codemods can locate the remaining unwired buttons via the data-placeholder attribute. Wiring a call site automatically removes the placeholder treatment as soon as onClick or href is passed.
  3. Anon-readable test/QA harnesses — GATED (P3, 2026-05-25). The four /welcome/test-{achievements,assistant,routines,wearable} harnesses already carried robots: noindex metadata, but were still rendered to any signed-in user in production. Each layout now wraps its children with TestHarnessGate (apps/oshun/web/src/components/welcome/TestHarnessGate.tsx), which calls notFound() when NODE_ENV === 'production' unless an operator explicitly sets OSHUN_ENABLE_TEST_HARNESSES=true. In non-prod builds the gate renders a visible amber "internal use only — SIMULATED_*" banner above the harness content. Layout metadata also adds noarchive + nosnippet on top of the existing noindex/nofollow. 4 tests at TestHarnessGate.test.tsx cover the dev-build pass-through, the production deny-by-default, the explicit override, and the non-literal-true reject case (any value other than 'true' is rejected).
  4. Hard-coded literals in production paths — TIGHTENED (P3, 2026-05-25).
    • /explore and /search no longer carry a literal Bearer dev.… token. The header is built via resolveBffAuthToken() in apps/oshun/web/src/lib/bff-auth.ts, which prefers the real session token (set by AuthProvider) and falls back to the dev token only when process.env.NODE_ENV !== 'production'. Production builds either send the real token or omit Authorization entirely (the BFF then rejects the request) — there is no production code path that emits the dev token.
    • /domains/veritas/topics/[topicId] previously routed any unknown topicId to renewable-energy silently. getTopicKey() now returns null for unknown topicIds and VeritasTopicHubWorkspace renders a dedicated VeritasTopicNotFoundPanel (lists the known hubs: renewable-energy, quantum-computing) instead of substituting content. Hub landing (/domains/veritas/topics, no topicId) still defaults to renewable-energy — that is the intentional curated landing view. 3 tests at VeritasTopicHubWorkspace.test.tsx cover the unknown-id not-found path, the Back-button callback, and the no-topicId hub landing.
  5. Scene password leak — FULLY RESOLVED (P1.3 + P3, 2026-05-25). P1.3 replaced the GET-with-password URL pattern with a POST server action that stored the password in an HttpOnly path-scoped cookie. P3 closes the remaining gap: the action now exchanges the password for a short-lived BFF-issued unlock token via POST /v1/living-scenes/public/<shortCode>/unlock-token. The cookie stores the token, not the password; the scene page sends the token via Authorization: Bearer … on revalidation; the BFF verifies the HMAC-signed, shortCode-scoped, 4h-TTL token without re-reading the password. Token sign / verify lives in apps/oshun/bff/src/living-scenes/scene-unlock-token.ts with 7 unit tests, the route is exercised by the existing living-scenes route suite (one new integration case covering wrong-password rejection, token mint, token revalidation, and cross-scene token rejection). The embed endpoint still calls fetchPublicLivingScene without an unlock token — password-protected scenes deliberately surface a retired tile in embed.
  6. LCustomerNav active inconsistency — RESOLVED (P3, 2026-05-25). The original concern (Veritas hub mounted active="explore" while depth views mounted active="library") is gone: the Veritas hub (/veritas/page.tsx) no longer uses LCustomerNav at all — it renders VeritasRoom directly. The remaining LCustomerNav usages in the Veritas family (/veritas/mobile, components/lilith/veritas.tsx) both declare active="library", so the active state is now consistent across the surface. A grep across the codebase shows the only LCustomerNav active="explore" consumers are the V2 shell surfaces (V2ShellSurface, V2KnowledgeSurface), which is correct — V2 is the knowledge/explore-anchored shell.
  7. Two observation-log routes — RESOLVED via H1 disambiguation + cross-link (P3, 2026-05-25). /domains/nyx/observation-log is the canonical recording / management surface (six tabs incl. New Entry, Equipment, Conditions) and now reads Observation Log · session list. /domains/nyx/observation-log-deep is the read-side analytics complement (five view modes incl. calendar, map, equipment-grouped) and now reads Observation Log · analytic views. Both subtitles cross-link to the other so the IA split is visible from either entry point. No route merger needed — the surfaces have distinct purposes.
  8. Lilith Studio role gating — RESOLVED at the route level (P3, 2026-05-25). /lilith-studio and the seven authoring sub-routes (scenes, avatar-costume, personas, music, asana, provenance, concerts) are now gated through apps/oshun/web/src/app/lilith-studio/layout.tsx, which reads the customer session, calls deriveCustomerRoleFromScopes / hasLilithStudioAccess, and substitutes LilithStudioAccessDenied for the authoring shell when access is missing. Prior to this fix only the root page was gated; the seven sub-routes mounted their editors to any signed-in customer. data-v1-editorial-role remains as a visual attribute for UI styling but no longer carries the access decision. The BFF is still the authoritative enforcement boundary on the data path; this layout closes the client-visible leak.
  9. Coach BFF endpoint shipped — framework selector now honoured (P3 follow-up, 2026-05-25). /domains/arete/coach no longer composes responses inline. The keyword router + template registry moved to apps/oshun/bff/src/arete/coach-responses.ts and is exposed via POST /v1/arete/coach/responses. The framework selector (CBT / ACT / Stoic / Reflective / general) is now a real input parameter — the composer returns framework-specific responses for the same prompt (CBT separates situation/thought/feeling; Stoic invokes the dichotomy of control; ACT pivots on values; etc.). The customer maps its CoachMode to the BFF framework, with reflection → reflective and the conversation-scoping modes (goals, habits, motivation) falling back to general. A local-fallback template preserves the coach's response if the BFF call drops, so the customer never sees a blank reply. The Sophia-grounded retrieval-augmented composer is the next swap behind the same POST /v1/arete/coach/responses contract.
  10. Nyx /domains/nyx/renderer and /domains/nyx/widgets — GATED AS OPERATOR PREVIEWS (P3, 2026-05-25). Both routes render substantive interactive components (NyxSkyRenderer ~1809 LOC, NyxDashboardWidgets ~1262 LOC) but have zero inbound links from any customer surface — they are orphan specimen pages. Each route now has a layout.tsx wrapping its children with OperatorPreviewSurfaceGate (calls notFound() in production unless OSHUN_ENABLE_OPERATOR_PREVIEWS=true; in non-prod renders a teal "preview surface — no customer entrypoint" banner). Layout metadata adds noindex + nofollow + noarchive + nosnippet. 4 tests at OperatorPreviewSurfaceGate.test.tsx cover the dev-build pass-through, production deny-by-default, explicit override, and non-literal-true reject. The walkthrough split into primitives vs surfaces is no longer necessary; the gate marks these explicitly out-of-customer-scope at the route level.

Studio sweep — cross-cutting findings#

Surfaced by the 7 parallel agents during the studio sweep. Same caveat: these are code-state findings, not walkthrough quality issues. Several are load-bearing for release planning.

  1. StudioHathorEconomyModelingWorkspace backbone — IA contract codified via lane card (P3, 2026-05-25). 192 sibling wrapper components plus 44 Hathor wrappers previously each mounted the canonical ~2,756-LOC Economy Modeling workspace under a route-specific H1, so a single page render instantiated the same workspace 4–7 times with independent client state. All 236 sibling embeds now mount a thin StudioHathorEconomyModelingLaneCard (capability summary + link to /studio/hathor/economy-modeling). The canonical workspace renders only at its own page, ending the duplicate-mount pattern. Route-specific concerns (subject identity, LoRA epoch sliders, mesh topology, retention TTL, voice picker, asset marketplace UI, character variants, CRDT replicas) remain to be authored per-wrapper as separate work; the lane card unblocks that authoring by removing the misleading "the workspace is already wired here" appearance.

  2. Composite routes Hathor instances — collapsed by lane card (P3, 2026-05-25). The transitive composition that mounted ~15+ Hathor instances on /studio/isis/workflows (via workflowsworkflow- registryoutput-registry → 5 lanes...) no longer compounds — each layer now mounts the lane card, so a single workspace ever renders the canonical Economy Modeling surface. Bundle size and hydration cost drop accordingly; duplicate a11y controls on the canonical surface are no longer mirrored across the page.

  3. AAA gate leaks via embedding — PLUGGED (P3, 2026-05-25). The route-level middleware in libs/isis/entitlements/src/studio-boundary.ts gates direct navigation to AAA-only routes, but cannot see inside a non-AAA hub that embeds the same AAA workspace component as a lane. <AaaGate routeSegment="…"> wraps each leak site and applies the same tier check that the middleware applies to the dedicated route. After this sweep:

    • Four sites already wrapped pre-existing gpu-worker embeds: StudioIsisJobEnvelopeWorkspace, StudioIsisWorkflowRegistryWorkspace, StudioIsisWebWorkspace, StudioIsisOutputRegistryWorkspace.
    • StudioIsisAiVideoWorkspace now wraps both animatediff-lightning and rife-interpolation (the remaining unprotected embeds found via a directed scan of AAA_ONLY_STUDIO_ROUTES workspace components against their non-AAA-route embed sites).
    • Test infrastructure: src/__tests__/setup.tsx now mocks server-only, next/headers, @/lib/server/studio-entitlement (defaulting tests to aaa-creator tier), and the @/components/studio/AaaGate component (passes children through synchronously). The earlier import failures blocked all 5 sites' tests from running; they now pass.
    • Embeds within AAA-only parent components (e.g., StudioIsisComfyuiNodesWorkspace embedding Florence2, StudioIsisComfyuiSdkWorkspace embedding ComfyuiNodes) are deliberately not wrapped — the parent route is already gated, so the child cannot be reached without AAA tier.
    • comfyui-integration (mentioned in the original finding) does not currently import any AAA-only workspace component; the prior lane-card sweep already replaced its inline embed with a navigation link.
  4. Aja workspace pattern lattice — duplicate mounts resolved (P3, 2026-05-25). 60+ Aja workspaces still follow one of three patterns: (A) thin h1 + Hathor; (B) capability grid + Hathor; (C) composite with 4–5 embedded sibling Aja workspaces. The duplicate-mount consequence (4–7 Hathor renders per page with independent state) is resolved by finding #1 — Hathor is no longer rendered transitively. The lattice itself remains as IA structure; collapsing patterns A/B/C into one canonical shape is a separate authoring concern.

  5. Mixed casing on studio identifiers — RESOLVED (P3, 2026-05-25). Three patterns had drifted from the rest of the studio PascalCase convention (initialisms get only the first letter capitalized). All three are now normalized across components, route maps, test files, page imports, and walkthrough docs:

    • CRDTSyncCrdtSync (Yemaya; one workspace + one route map + tests; route segment crdt-sync unchanged)
    • AIContentGenerationAiContentGeneration (Yemaya; one workspace
      • one route map + tests; route segment ai-content-generation unchanged)
    • TypeScriptSdkTypescriptSdk (Aja, Bellona, Hathor; three workspaces + three route maps + tests; route segment typescript-sdk unchanged) DaVinciIntegration is preserved — "Da Vinci" is a two-word proper noun and its current PascalCase mapping matches the da-vinci-integration route segment.
  6. One genuinely deep Yemaya surface. /studio/yemaya/remote-actor-home-capture is 1566 LOC / 93 panel components integrating @yemaya/remote-film-capture. The exception that proves the rule.

  7. Self-links in related-workspace panels — RESOLVED (P3, 2026-05-25). The finding was filed as "breadcrumb cycles" but the underlying defect was in the per-page related-workspaces panel: 122 studio pages (/studio/aja/*, /studio/isis/*, /studio/yemaya/*, /studio/bellona/*, /studio/hathor/*) each listed their own route as the first quickAction Link, creating a no-op "open the page you're on" action. Reciprocal links to sibling workspaces (e.g., Avatar Library → Avatar Integration → Avatar Library) are intentional and remain. The actual breadcrumbs (Studio / Aja / X) were already correct.

  8. Aja API Endpoints lane-mount duplication — RESOLVED (P3, 2026-05-25). The 1399-LOC StudioAjaApiEndpointsWorkspace (35 workflows, force-failure toggles, contract diagnostics) was embedded as a full-workspace lane in four aggregator hubs (/studio/aja/docs, /studio/aja/motion-integration, /studio/aja/motion-pipeline-sdk, /studio/aja/motion-pipeline-sdk-python) — each embed mounted independent client state, so toggling a workflow in one embed did not affect the others, and operators saw the same controls in multiple places. All four embeds now mount a thin <StudioAjaApiEndpointsLaneCard /> (capability summary + link to the canonical surface). The original finding referenced /studio/aja/cli but cli no longer embeds API Endpoints today — cli mounts only the CLI command surface and SDK lanes. The canonical workspace surface remains at /studio/aja/api-endpoints.

  9. active="explore" wrong for every studio route — RESOLVED (P3, 2026-05-25). The original concern was that every studio page.tsx mounted ShellLayout active="explore", leaving Studio without its own dedicated nav state. A repo-wide grep confirms this is no longer true: all 480 studio page.tsx files now declare active="studio", zero declare active="explore". The studio shell-route is a first-class member of WebShellRoute and the customer sidebar (with shortcut key 6); the original lane-card sweep flipped every studio route to active="studio". No code change needed; finding marked resolved as already-fixed.

  10. /studio/compose and /studio/generation/living-scene — NOINDEX-TAGGED (P3, 2026-05-25). Both routes are intentionally reachable without a session (per PUBLIC_PATHS in proxy.ts): /studio/compose ships built-in fixtures with no user-state writes; /studio/generation/living-scene exposes only approved templates and enforces tier + tenant policy via headers. They are not marketing surfaces, though — the canonical funnel for search indexing is /welcome and the per-domain landing pages. Both routes now export robots: { index: false, follow: false, noarchive: true, nosnippet: true, googleBot: { index: false, follow: false } } in their metadata so a crawler that discovers them via an inbound link does not index them. 2 tests at src/__tests__/anon-studio-route-metadata.test.ts assert the literal noindex block is present in each route's source (source-text assertion, since both pages have client-side imports that vitest's resolver cannot follow without the Next.js build).

  11. Concordia workbench uses one workspace for 12 routes dispatched via an initialSurface prop. Walkthrough files link back to the parent rather than duplicating the shared Interactions surface.

  12. Studio workspace persistence — V1 foundation shipped (P3, 2026-05-25). Adds a typed useStudioWorkspacePersistence hook at apps/oshun/web/src/lib/studio-workspace-persistence.ts that mirrors useState<T> but persists across reloads via localStorage, with a versioned key (oshun.studio-workspace.<workspaceId>.v<n>), a debounced save (250ms default), an isValid type-guard for crash-safe hydration, and a schemaVersion bump that discards incompatible persisted shapes.

    Canonical wiring lives on StudioHathorEconomyModelingWorkspace for the workspace's density + viewportMode shell state — operator choices now survive page reloads. 6 hook tests cover defaults, persistence, hydration, invalid-state fallback, schema-version bumping, and debounce coalescing.

    The localStorage backend is intentional V1 scope. The BFF endpoint pair has now shipped (P3 follow-up, 2026-05-25):

    • GET /v1/studio/workspaces/:workspaceId/state returns the caller's persisted state for a given workspace (404 when none stored).
    • POST /v1/studio/workspaces/:workspaceId/state upserts state for the caller. Payload: { schemaVersion: integer >= 1, stateJson: string } (opaque JSON; client owns the shape). 32 KiB cap; workspaceId must match /^[a-z][a-z0-9-]+$/.
    • studioWorkspaceStateStore in apps/oshun/bff/src/studio/ workspace-state-store.ts keys per (userId, workspaceId) so two operators on the same browser cannot read each other's drafts.
    • 8 route tests cover auth, GET/POST roundtrip, cross-user isolation, invalid payload, invalid workspaceId, oversized state, and upsert.
    • Hook swap shipped (P3 follow-up, 2026-05-25): useStudioWorkspacePersistence is now local-first + BFF-authoritative- on-newer. Hydration: localStorage envelope { state, updatedAtIso } first (sync, no flash), then async BFF GET — adopts the BFF copy iff its updatedAtIso is strictly newer. Saves: debounced dual-write to localStorage + POST to the BFF. Legacy raw-state localStorage entries (the V1 shape) are still accepted; they're treated as epoch-0 so the next save or BFF load supersedes them. BFF errors, 401s, and 404s are swallowed silently so the hook degrades to localStorage-only when offline / signed out / no remote state yet. The call signature [T, Dispatch<SetStateAction<T>>] is unchanged — every existing caller (currently StudioHathorEconomyModelingWorkspace) keeps working without modification. 11 hook tests: 7 cover the localStorage path (bffSyncEnabled: false), 4 cover the BFF path (BFF-newer adopt, BFF-older keep-local, BFF-404 keep-local, POST-on-change).

    Other studio workspaces opt in by adopting the hook with their own workspaceId + defaultState + isValid guard. Larger / more complex state (saved filters, draft text, multi-tab cursor positions) can use the same hook with a richer T.

  13. Studio page-boundary telemetry — FOUNDATION SHIPPED (P3, 2026-05-25). Adds three new event types to OshunEventPayloadMap in libs/oshun/analytics/src/types.ts: studio_workspace_mounted, studio_workspace_unmounted, studio_workspace_interaction. The reusable helper at apps/oshun/web/src/analytics/studioWorkspaceMountTelemetry.ts exposes emitStudioWorkspaceMount, emitStudioWorkspaceUnmount, emitStudioWorkspaceInteraction, each typed against the new payload entries.

    Canonical wiring lives on the two highest-traffic studio surfaces: StudioHathorEconomyModelingWorkspace (the canonical Hathor lane-card target) and StudioAjaApiEndpointsWorkspace (the canonical Aja API contract surface). Both fire _mounted on mount and _unmounted on unmount with a durationMs payload.

    Per-workspace opt-in is the extension pattern — future studio routes call emitStudioWorkspaceMount({ workspaceId, surface }) from their own mount effect. The data-* attributes remain as Playwright test hooks; this is the additive analytics signal.

    The stdout-info shim stays as a dev-time signal. The BFF ingest sink has now shipped (P3 follow-up, 2026-05-25):

    • POST /v1/studio/telemetry/workspace-events accepts batches of up to 100 events. Payload: { events: StudioWorkspaceTelemetryEvent[] }. Validation: known kinds only, well-formed ISO occurredAt, workspaceId pattern, surface pattern, durationMs only on _unmounted, action only on _interaction. The whole batch fails on the first invalid event (client should never silently drop signals).
    • studioWorkspaceTelemetrySink keeps an in-memory buffer (10k-event capacity, oldest-dropped overflow). Each accepted event is stamped with the authenticated userId and a server-side receivedAtIso.
    • The customer-web studioWorkspaceMountTelemetry.ts helper now has a second bffSink alongside the existing stdout sink. Events queue client-side and flush every 2s, on pagehide, or when the queue hits 25 entries. Network failures are swallowed silently so a hiccup never breaks a render path.
    • 9 BFF route tests (auth, valid batch persist, empty batch ok, oversize batch 413, unknown kind, durationMs-on-mounted reject, missing-action reject, userId stamping) + 1 web-side batch-flush test (verifies fetch is called with the queued events when the 2s window elapses).
    • Forwarder hook shipped (P3 follow-up, 2026-05-25): studioWorkspaceTelemetrySink.setForwarder(fn) installs a pluggable callback that's invoked once per accepted batch with the records that were just appended. Production wires it to an OpenTelemetry collector or warehouse pipeline; the default is null (no-op) so the sink stays useful as a standalone in-memory buffer in dev/test. The sink swallows both synchronous throws and async rejections from the forwarder so a misconfigured collector can never break ingest — records are buffered regardless. 3 additional route tests cover forwarder-invocation, sync-error-swallow, and async-rejection- swallow; the OpenTelemetry SDK wiring itself is deployment work (env var + SDK init + collector URL), kept out of application code.

Unconfirmed-v1 sweep — cross-cutting findings#

Surfaced by the 4 parallel agents during the Bellona / Hathor / Neith sweep. Each finding has direct V1-decision-making implications.

  1. StudioHathorEconomyModelingWorkspace — DECISION: wrappers are breadcrumb / IA only (P3, 2026-05-25). The canonical ~2,756-LOC component lives at /studio/hathor/economy-modeling (apps/oshun/web/src/app/studio/hathor/economy-modeling/page.tsx). 236 sibling components across Hathor / Aja / Bellona / Isis / Yemaya that previously embedded the full workspace now mount a thin StudioHathorEconomyModelingLaneCard (link to the canonical surface). The IA contract is now explicit: each wrapper is a breadcrumb / navigation surface, not a re-render of the same workspace with independent state. Wrappers may still author route-specific concerns (NPC memory, safety, scenarios, screenplays, validation, SDK, etc.) as first-class panels — that authoring is unblocked by the lane card removing the misleading "Economy Modeling is already wired here" appearance.

  2. Bellona is structurally different from Aja/Isis/Yemaya. It does NOT embed StudioHathorEconomyModelingWorkspace. Instead it has its own polycentric backbone: Studio BellonaBridgeProtocolAndSessionsWorkspace (~4,000 LOC, embedded by adapters/bridge-core/event-handlers/event-publisher), plus bespoke per-engine bridges (StudioBellonaBlenderBridgeCommandsWorkspace, StudioBellonaGodotBridgeCommandsWorkspace), build-pipeline workspaces (StudioBellonaBuildJobAuthoringWorkspace, StudioBellonaBuildQueueTrackingWorkspace, StudioBellonaContentAddressableBuildCacheWorkspace), and heavy first-class workspaces for CliSurfaces, Client, CrossDomainAssetIngestion, EngineSynchronization, ExportPipeline, FormatRegistry, DaVinciIntegration, gameplay-runtime sub-systems, and a TypeScript SDK lane embedded inside Client.

  3. Bellona has three structural patterns:

    • Breadcrumbed aggregator — imports a route-map module
    • No-breadcrumb single workspace — inline _ROUTE_MAP
    • Meta-aggregator (/studio/bellona/interchange, /studio/bellona/metahuman) embedding sibling lane workspaces
  4. Hathor has triple-to-sevenfold nesting in aggregators: pre-production (3 lanes), simulation (4 lanes), simulation-worker (2 lanes), sophia-integration (3 lanes), theory (4 lanes), validation (4 lanes), workbench (7 lanes), world-api (2 lanes). Almost every lane component itself embeds Economy Modeling, so a single workbench page render mounts Economy Modeling 4–7 times with independent client state.

  5. Four bespoke Hathor workspaces — SAVED-VIEW + WIZARD HALVES COMPLETE (P3, 2026-05-26). The four bespoke Hathor authoring workspaces (quest-authoring, story-graph-authoring, timeline-modeling, world-configuration, ~15,250 LOC combined) DO NOT embed Economy Modeling; they carry bespoke client state for wizard / realtime / saved-view actions. The realtime half still needs a WebSocket / SSE story — a substantial follow-up. The saved-view half is done across all four surfaces (see below) and the wizard half BFF endpoint pairs are now live for all four:

    • GET/POST /v1/studio/hathor/quest-authoring/records + DELETE …/:questId — full QuestAuthoringRecord contract validation, 9 route tests.
    • GET/POST /v1/studio/hathor/story-graph-authoring/records + DELETE …/:graphId — full StoryGraphAuthoringRecord contract validation, 9 route tests.
    • GET/POST /v1/studio/hathor/timeline-modeling/records + DELETE …/:timelineId — TimelineRecord plus nested validation of timeline[] (chronology entries with ISO timestamps), diagnostics (chronologyConflicts/causalityGaps/publicationRiskScore), and relatedEntities[] (entityType + state enums); arrays capped at 200. 10 route tests.
    • GET/POST /v1/studio/hathor/world-configuration/records + DELETE …/:recordId — WorldConfigurationRecord keyed by recordId so one user can hold multiple records sharing a worldId across the three scopes (cosmology/geography/society). 11 route tests.
    • All four stores key per (userId, recordId) so two operators on the same browser cannot read each other's drafts. 39 BFF route tests in total across the four endpoint pairs.
    • Wizard consumer swaps complete across all four workspaces (P3, 2026-05-26): each workspace now mounts → GET its records endpoint (falls back to its INITIAL_*_RECORDS seed on empty / 401 / offline / network failure so a fresh or signed-out operator still sees a populated workspace) and wizard create/edit submits fire a best-effort POST with keepalive: true (silent on failure; local state stays the source of truth for the session). The timeline-modeling edit branch was refactored to compute editedRecord outside the setRecords callback so both local state and the BFF POST see the same final value, including prepended timeline[] history entries and clamped diagnostics.publicationRiskScore. The quest-authoring edit branch had a parallel refactor for finalRecord to include the existing streamState/streamLagMs/reconnectCount24h. Stream-state mutations (live/paused/reconnecting + lag ticks) intentionally stay client-only since they tick on runtime telemetry rather than operator intent. 74 workspace tests pass across the four surfaces.

    The saved-view half across all four surfaces: each uses useStudioWorkspacePersistence with its own shell-state shape + isValid type-guard, persisting operator preferences (density, viewport mode, viewport-sync, command-strip visibility, policy-error visualisation where applicable, high-contrast where applicable) local-first via localStorage with BFF-authoritative-on-newer sync via /v1/studio/workspaces/{hathor-quest-authoring,hathor-story-graph-authoring,hathor-timeline-modeling,hathor-world-configuration}/state. Operator role + permission tier stay session-scoped (they come from the auth context once the BFF wiring lands). 74 tests pass across the four workspaces (18+18+18+20). Several callback-form setX(prev => ...) usages converted to direct-value form along the way; for timeline-modeling, two telemetry side-effects moved out of the setter callback into the click handler body.

    Data Retention & Lifecycle Controls real-infra route journey (2026-06-30): /studio/data-retention-lifecycle-controls now has focused Playwright coverage against the real dev BFF for the Studio governance lifecycle classifier: admin catalog load, seeded retain/archive/purge/hold classification, edited unknown-class safe-retain issue, legal-hold precedence, client-only malformed JSON rejection with no evaluate POST, live BFF invalid-payload details, network-unreachable classify failure, catalog loading/error, native pending submit disablement, non-admin fail-closed state, anonymous redirect, flat quick-action affordances, automated 44px checks, and the shared axe gate. This verifies another V1 Studio governance lane-console surface; the broader V1 walkthrough/E2E task remains open.

    Concordia Workbench real-infra route journey (2026-06-30): /studio/concordia-workbench now has focused Playwright coverage for the live Agreement Frontier lane against the real dev BFF plus the seeded Concordia workbench shell. The spec verifies admin catalog load, default Pareto compute, edited duplicate-option and missing-utility BFF 400 details, client-only malformed JSON rejection with no compute POST, network-unreachable compute failure, catalog loading/error, native pending submit disablement, non-admin fail-closed state, route-map and quick-action affordances, all 11 seeded surface renderers, viewer privacy projection, case switching, audit recording, direct /cases/:caseId/frontier subroute selection, anonymous redirect-before-render, and the existing shared-axe accessibility smoke. The case bundle remains seeded in-memory until the production Concordia adapter lands, so adapter-offline and future production adapter behavior remain open.

    Isis Video Production Workflows real-infra route journey (2026-06-30): /studio/isis/video-production-workflows now has focused Playwright coverage against the real dev BFF for the @isis/workflows workflow schema validator: production hard-block for signed-in direct navigation without the lane bypass, localhost E2E lane navigation, admin catalog load, required-field rendering, default valid workflow header, edited missing-section and bad-schema_version schema errors, client-only malformed JSON rejection with no validate POST, live BFF invalid_workflow detail, network-unreachable validate failure, catalog loading/error, native pending submit disablement, non-admin fail-closed state, anonymous redirect, route-map / quick-action affordances, automated 44px checks, and the shared axe gate. This verifies another Isis lane-console surface; the broader V1 walkthrough/E2E task remains open.

    Isis Model Registry real-infra route journey (2026-07-01): /studio/isis/model-registry now has focused Playwright coverage against the real dev BFF for the managed-model browser: Studio-boundary hard-block, localhost E2E lane navigation, seeded default safe catalog, search / asset-type / commercial-use / NSFW filter re-queries, cursor pagination through the live BFF, catalog loading/empty/error/malformed states, non-admin fail-closed state, anonymous redirect, route-map / quick-action affordances, automated 44px filter/toggle/load-more/link checks, and the shared axe gate. This verifies another Isis model-governance surface; the broader V1 walkthrough/E2E task remains open.

    Isis Budget Management real-infra route journey (2026-07-01): /studio/isis/budget-management now has focused Playwright coverage against the real dev BFF for the @isis/runpod-surface cost-quota evaluator: Studio-boundary hard-block, localhost E2E lane navigation, live seeded tenant verdicts (ok, alert, kill-switch-armed, over-cap), status-count rollup, status-filter narrowing with local persistence, loading/service- failure / malformed / filtered-empty / network-failure states, route-map / quick-action affordances, automated 44px select/link checks, non-admin fail-closed state, anonymous redirect, and the shared axe gate. This verifies another Isis GPU spend-governance surface; the broader V1 walkthrough/E2E task remains open.

    Isis Cost Tracking real-infra route journey (2026-07-01): /studio/isis/cost-tracking now has focused Playwright coverage against the real dev BFF for the @isis/token-budget LLM cost ledger: Studio-boundary hard-block, localhost E2E lane navigation, live pricing/rollup catalog load, valid claude-3.5-sonnet usage recording with exact $0.0180 cost, duplicate-record and unknown-model rejection, client token-count validation, native pending submit disablement, loading/service- failure / malformed-catalog / malformed-record / network-failure states, route-map / quick-action affordances, automated 44px form/link checks, non-admin fail-closed state, anonymous redirect, and the shared axe gate. This verifies another Isis LLM spend-governance surface; the broader V1 walkthrough/E2E task remains open.

    Isis Resource Recommendations real-infra route journey (2026-07-01): /studio/isis/resource-recommendations now has focused Playwright coverage against the real dev BFF for the @isis/resource-recommendations fallback selector: Studio-boundary hard-block, localhost E2E lane navigation, live fallback chain/reason catalog load, seeded recommendation rendering, valid downgrade recommendation write/readback, cheapest-model no-downgrade recommendation, duplicate-id and off-chain-model rejection, client validation, native pending submit disablement, loading/service-failure / malformed-catalog / malformed-record / network-failure states, route-map / quick-action affordances, automated 44px form/link checks, non-admin fail-closed state, anonymous redirect, and the shared axe gate. This verifies another Isis LLM spend-reduction surface; the broader V1 walkthrough/E2E task remains open.

    Isis Creator Monetization real-infra route journey (2026-07-01): /studio/isis/creator-monetization now has focused Playwright coverage against the real dev BFF for the @isis/3d-marketplace-ops collaborator payout-split planner: Studio-boundary hard-block, localhost E2E lane navigation, live role/status catalog load, valid 100% split write/readback, manual-review marketplace-terms warning, blocked under-allocation warning, live BFF invalid_payload rejection for unknown roles, client malformed / non-array JSON validation, native pending submit disablement, loading/service-failure / malformed-catalog / malformed-plan / network-failure states, route-map / quick-action affordances, automated 44px textarea/button/link checks, non-admin fail-closed state, anonymous redirect, and the shared axe gate. This verifies another Isis marketplace revenue-governance surface; the broader V1 walkthrough/E2E task remains open.

    Isis RIFE Interpolation real-infra route journey (2026-07-01): /studio/isis/rife-interpolation now has focused Playwright coverage against the real dev BFF for the @isis/video-enhancement RIFE frame-interpolation planner: Studio-boundary hard-block, localhost E2E lane navigation, live source/target fps catalog load, exact 24→48 and 24→120 plan write/readback, unsupported 30→48 plan failure, live BFF invalid_payload rejection for too few source frames, client frame-count validation, native pending submit disablement, loading/service-failure / malformed-catalog / malformed-plan / network-failure states, route-map / quick-action affordances, automated 44px select/input/button/link checks, non-admin fail-closed state, anonymous redirect, and the shared axe gate. This verifies another Isis generated-video planning surface; the broader V1 walkthrough/E2E task remains open.

    Isis Job Submission real-infra route journey (2026-07-01): /studio/isis/job-submission now has focused Playwright coverage against the real dev BFF for the @isis/job-envelope submission builder: Studio-boundary hard-block, localhost E2E lane navigation, real generation-type / priority catalog load, valid music-generation envelope build, pending submit disablement, client-only malformed JSON rejection, live BFF invalid_payload and strict enum validation issue rendering, catalog loading/error/malformed states, non-admin fail-closed state, anonymous redirect, route-map / quick-action affordances, automated 44px form/link checks, and the shared axe gate. This verifies another Isis job-governance surface; the broader V1 walkthrough/E2E task remains open.

    Isis Job Envelope real-infra route journey (2026-07-01): /studio/isis/job-envelope now has focused Playwright coverage against the real dev BFF for the @isis/job-envelope field-normalization/coercion lane: Studio-boundary hard-block, localhost E2E lane navigation, live field/vocabulary catalog load, alias-heavy normalize POST, unresolved-token rendering without fabricated canonical values, loading/service-failure / malformed-catalog / malformed-normalization / network-failure states, embedded job-pipeline lane shells, AAA embed-gate, route-map / quick-action affordances, automated 44px form/link checks, non-admin fail-closed state, anonymous redirect, and the shared axe gate. This verifies the coercion layer between job submission and job queue operations; the broader V1 walkthrough/E2E task remains open.

    Isis Job Management real-infra route journey (2026-07-01): /studio/isis/job-management now has focused Playwright coverage against the real dev BFF for the generation job queue: Studio-boundary hard-block, localhost E2E lane navigation, live queue seeding through /v1/generation/jobs, status / kind / job-id filters, selected job request/error detail, process-queue POST with { max: 25 }, fail-closed provider_not_configured rendering, failed-job retry back to queued, loading/empty/error/malformed states, non-admin fail-closed state, anonymous redirect, route-map / quick-action affordances, automated 44px filter/button/row/link checks, and the shared axe gate. This verifies the Isis job-queue operations surface that follows envelope validation; the broader V1 walkthrough/E2E task remains open.

    Workbench World Editor real-infra route journey (2026-06-25): /studio/hathor/workbench-world-editor now has focused Playwright coverage against the real dev BFF for the CGI scene validator: admin catalog load, issue-type / coordinate enum rendering, seeded missing-location verdict, clean export-ready verdict, BFF schema-validation detail, client-side malformed JSON rejection with no validate POST, native pending submit disablement, non-admin fail-closed state, route-map / quick-action affordances, mobile 44px controls, and the shared axe gate. This verifies one Hathor §34 surface; the broader 74-surface Hathor task remains open.

    Workbench Worlds real-infra route journey (2026-06-29): /studio/hathor/workbench-worlds now has focused Playwright coverage against the real dev BFF for the @hathor/domain-models region geography scorer: admin catalog load, seeded temperate-forest analysis, edited volcanic-wasteland analysis, client-only malformed JSON rejection with no analyze POST, live BFF terrain validation detail, catalog loading/error, native pending submit disablement, non-admin fail-closed state, anonymous redirect, route-map / quick-action affordances, automated 44px checks, and the shared axe gate. This verifies another Hathor workbench surface; the broader 74-surface Hathor task remains open.

    Workbench Timeline real-infra route journey (2026-06-29): /studio/hathor/workbench-timeline now has focused Playwright coverage against the real dev BFF for the @hathor/timeline scene-order packet validator: admin catalog load, seeded blocking story-order plus causal dependency verdict, edited clean export-ready packet, warning-only uncovered world-state tag, client-only malformed/primitive JSON rejection with no validate POST, live BFF empty-scenes validation detail, catalog loading/error, native pending submit disablement, non-admin fail-closed state, anonymous redirect, route-map / quick-action affordances, automated 44px checks, and the shared axe gate. This verifies another Hathor workbench surface; the broader 74-surface Hathor task remains open.

    Economy Simulation real-infra route journey (2026-06-29): /studio/hathor/economy-simulation now has focused Playwright coverage against the real dev BFF for the @hathor/domain-models market-pricing model: admin catalog load, seeded luxury/rare elastic pricing, edited land/common scarce pricing, zero-ratio maximum-scarcity pricing, client-only numeric rejection with no price POST, live BFF unknown-category validation detail, catalog loading/error, native pending submit disablement, non-admin fail-closed state, anonymous redirect, route-map / quick-action affordances, automated 44px checks, and the shared axe gate. This verifies another Hathor economy surface; the broader 74-surface Hathor task remains open.

    Lore Validation Timeline real-infra route journey (2026-06-29): /studio/hathor/lore-validation-timeline now has focused Playwright coverage against the real dev BFF for the @hathor/validation TimelineValidator: admin catalog load, seeded TIMELINE_ORDER_VIOLATION, opt-in TIMELINE_GAP_DETECTED, client-only malformed/empty/threshold validation rejection with no validate POST, live BFF invalid_event detail, catalog loading/error, native pending submit disablement, non-admin fail-closed state, anonymous redirect, route-map / quick-action affordances, automated 44px checks, and the shared axe gate. This verifies another Hathor lane-console surface; the broader 74-surface Hathor task remains open.

    Lore Validation Causality real-infra route journey (2026-06-29): /studio/hathor/lore-validation-causality now has focused Playwright coverage against the real dev BFF for the @hathor/validation CausalityValidator: admin catalog load, seeded CAUSALITY_CYCLE_DETECTED, opt-in CAUSALITY_ORPHAN_EFFECT / CAUSALITY_DANGLING_CAUSE, client-only malformed/empty validation rejection with no validate POST, live BFF invalid_event detail, catalog loading/error, native pending submit disablement, non-admin fail-closed state, anonymous redirect, route-map / quick-action affordances, automated 44px checks, and the shared axe gate. This verifies another Hathor lane-console surface; the broader 74-surface Hathor task remains open.

    Lore Validation Taxonomy real-infra route journey (2026-06-29): /studio/hathor/lore-validation-taxonomy now has focused Playwright coverage against the real dev BFF for the @hathor/validation TaxonomyValidator: admin catalog load, seeded TAXONOMY_CYCLE_DETECTED, edited TAXONOMY_INVALID_TYPE, clean age → epoch hierarchy, TAXONOMY_HIERARCHY_VIOLATION warning, client-only malformed/empty validation rejection with no validate POST, live BFF invalid_era detail, catalog loading/error, native pending submit disablement, non-admin fail-closed state, anonymous redirect, route-map / quick-action affordances, automated 44px checks, and the shared axe gate. This verifies another Hathor lane-console surface; the broader 74-surface Hathor task remains open.

    Lore Validation Contradictions real-infra route journey (2026-06-29): /studio/hathor/lore-validation-contradictions now has focused Playwright coverage against the real dev BFF for the @hathor/validation contradiction detector: admin catalog load, seeded CONTRADICTION_TEMPORAL, edited clean-event payload, client-only malformed/empty validation rejection with no detect POST, live BFF invalid_event detail, catalog loading/error, native pending submit disablement, non-admin fail-closed state, anonymous redirect, route-map / quick-action affordances, automated 44px checks, and the shared axe gate. This verifies another Hathor lane-console surface; the broader 74-surface Hathor task remains open.

    Hathor Validation aggregator real-infra route journey (2026-06-29): /studio/hathor/validation now has focused Playwright coverage against the real dev BFFs for every embedded validation lane: Unified Validation Dashboard, Timeline, Causality, and Taxonomy. The route-level spec verifies all embedded catalog GETs, seeded and clean unified-dashboard suite POSTs, seeded embedded Timeline/Causality/Taxonomy POSTs, dashboard client-only malformed/non-array/empty zero-POST validation, dashboard catalog-failure isolation while sibling lanes remain ready, non-admin fail-closed state across every embedded lane, anonymous redirect, route-map / quick-action affordances including the Contradictions link, automated 44px checks, and the shared axe gate. This verifies the Hathor validation hub surface; the broader 74-surface Hathor task remains open.

    Unified Validation Dashboard real-infra route journey (2026-06-29): /studio/hathor/unified-validation-dashboard now has focused standalone Playwright coverage against the real dev BFF for the combined @hathor/validation suite: admin catalog load, seeded inconsistent Timeline/Causality verdicts, edited clean overall verdict, client-only malformed/non-array/empty validation rejection with no validate POST, live BFF invalid_event detail, catalog loading/error, native pending submit disablement, non-admin fail-closed state, anonymous redirect, route-map / quick-action affordances, automated 44px checks, and the shared axe gate. This verifies the dashboard as its own V1 Studio route in addition to the embedded validation hub coverage; the broader 74-surface Hathor task remains open.

  6. Neith has genuine domain logic. StudioNeithInverseModelingWorkspace now mounts the V1 reference-inversion lane backed by neith-inverse-modeling.ts: decoded RGBA payload validation, feature extraction (mean, contrast, edgeEnergy, entropy, warmBias), terrain/vegetation/urban/noise parameter estimates, confidence scoring, and export-manifest output. The same route also keeps the admin-scoped live BFF fit-quality evaluator for residual/RMSE/MAE/R² verification.

  7. Bridge-command routes near-identical — TEMPLATED (P3, 2026-05-25). The four bridge-command lanes (blender-, godot-, unity-, unreal-bridge-commands) previously each inlined a near-identical 24-line route-map constant and a 30-line cross-link panel that differed only by engine name. They now mount a single shared BridgeCommandsPageScaffold from apps/oshun/web/src/components/studio/bridgeCommands/bridgeCommandsTemplate.tsx that takes { engine, Workspace } and renders the canonical 6-entry route map plus the cross-link panel (with the current engine filtered out, so no self-link). Adding a fifth engine is now a 2-line entry in BRIDGE_COMMAND_ENGINES plus a thin page.tsx. 9-test contract suite at bridgeCommandsTemplate.test.tsx asserts: 4 engines with matching slug/route pairs, every route map is exactly 6 entries rooted at the canonical path, and every page renders sibling cross-links but never a self-link.

  8. visionOS Features and Meta Quest Features — TEMPLATED (P3, 2026-05-25). The two XR-features lanes (visionos-features, meta-quest-features) shared an identical 5-entry route map (feature → artifact → rollout) inlined in each page. They now mount a single shared XrFeaturesPageScaffold from apps/oshun/web/src/components/studio/xrFeatures/xrFeaturesTemplate.tsx that takes { platform, Workspace } and renders the canonical route map plus the cross-link panel (sibling platform + XR Platform Support + Shared XR Capabilities + Virtual Production ICVFX, with the current platform filtered out so no page self-links). Adding a third XR platform is a 2-line entry in XR_FEATURE_PLATFORMS plus a thin page.tsx. 5-test contract suite at xrFeaturesTemplate.test.tsx asserts the platform set, per-platform 5-entry route map shape, and sibling-cross-link/no-self-link guarantees.

  9. Pervasive copy-paste artefacts in Bellona — RESOLVED (P3, 2026-05-25). The 10 short-name lanes (audio, bridge-core, database, davinci, event-handlers, event-publisher, gameplay-systems, godot, houdini, client) previously each shipped a route map of five fictional /lane/<entity>/[id] nested URLs that have no corresponding page.tsx in the app router. Each lane now declares an explicit alias relationship via the role field on its route map:

    • 8 lanes are alias surfaces (route map: 1 alias + 1 canonical-target [+ optional related-peer for godot and houdini]).
    • gameplay-systems is a hub-alias (route map: 1 hub-alias + 5 canonical-target lanes for the gameplay-runtime cluster).
    • Page-level: every lane renders a Studio / Bellona / <Canonical> / <Lane> (alias) breadcrumb and an IA-contract panel showing the alias → canonical link with role badges.
    • 21-test contract suite at StudioBellonaAliasContracts.test.ts asserts: each alias declares the correct self-path, every canonical target is a real flat /studio/bellona/ path, no fictional nested URLs appear, and the alias-lane set is unique. Replaces the 10 stale per-lane route-map tests that asserted the now-deleted nested URLs.
  10. Breadcrumb IA inconsistency in Hathor — RESOLVED (P3, 2026-05-25). The four simulation routes (simulation, simulation-worker, simulation-physics, simulation-state-persistence) now share a single declarative IA contract via the role field on their route-map entries:

    • /studio/hathor/simulation is the aggregator for the cluster. Its route map lists every sibling lane via the real flat /studio/hathor/<lane> path (no more fictional /simulation/worker/[id] nested URLs); the page renders an aggregator breadcrumb and quick-action links to all six sibling lanes.
    • The other three routes mark themselves as self, point back at /studio/hathor/simulation as parent-aggregator, and list the other lanes as peer-lane entries. Each page now shows a consistent Studio / Hathor / Simulation / <lane> breadcrumb (previously simulation-physics and simulation-state-persistence had none).
    • The 16-test contract suite asserts cluster invariants (aggregator singularity, parent-points-back, no fictional nested URLs) so drift triggers a CI fail. If a fifth simulation lane is added, the canonical sibling set lives in StudioHathorSimulationClusterIa.test.ts:EXPECTED_SIBLINGS.
  11. Hathor world-configuration → Bellona cross-domain link — STRUCTURED (P3, 2026-05-25). The world-configuration page previously rendered a single quick-action linking to Bellona C++ SDK with no in-domain Hathor peers (anomalous because every other Hathor world-* lane cross-links to in-domain peers like world-api, world-version-branching, geography-modeling). The IA contract is now explicit via three labelled panels:

    • Related Hathor world lanes — 6 in-domain peers (world-api, world-version-branching, geography-modeling, location-modeling, culture-modeling, faction-modeling).
    • Downstream engine integration — cross-domain Bellona consumers (/studio/bellona/cpp-sdk and /studio/bellona/lore-to-engine-compilation), each link is suffixed (downstream consumer) so it doesn't read as a peer. Preserves the original C++ SDK link instead of dropping it (world configuration data really does compile via the C++ SDK).
    • Back to Studio — index back-link in its own panel.
    • 2 tests at StudioHathorWorldConfigurationPage.test.tsx assert: the in-domain panel has the 6 expected Hathor lanes in order; cross-domain links are confined to the labelled downstream panel and never bleed into the in-domain panel.

Audit sweep (2026-05-26)#

Comprehensive completeness audit. Goal: ensure every page.tsx in apps/oshun/web/src/app/ has a drafted walkthrough and every walkthrough file passes its own conventions. Findings + fixes:

  1. 5 out-of-V1 stub rows drafted. /v2, /v2/wiki, /v2/glossary, /v2/roadmap, /v3/landing had status=stub in routes.csv and no walkthrough file. Drafted in customer/00-public/ with v1_scope: out-of-v1 in frontmatter; CSV rows updated to status=drafted and domain reclassified from unclassified to v2-shell / v2-knowledge / v3-marketing.
  2. 1 invalid YAML frontmatter. studio/domain-bridges/isis/studio-isis-video-generation.md carried an unquoted backtick-colon sequence in its auth: value (note: \video-generation` is not in …`) that broke YAML parsing. Quoted the value.
  3. 2 broken relative .md links. journeys/nisaba-scholarly-read.md linked ./nisaba.md (file lives at ../customer/07-nisaba/nisaba.md); studio/governance/studio-accessibility-governance.md linked ../operations/studio-experimentation-feature-flags.md (file lives in the same governance/ folder). Both fixed.
  4. 1 unlisted journey. journeys/multi-device-workspace-handoff.md existed since 2026-05-24 but was never added to journeys/README.md's bucket map. Added under a new "Workspace shell (1)" bucket. Journey-file count is now 24 (23 journeys + index), matching the file listing on disk.
  5. Final integrity check (all clean): 643 CSV rows / 643 per-view files / 0 YAML errors / 0 missing source files on disk / 0 status mismatches with CSV / 0 missing required sections / 0 broken relative .md links across 3,814 links.

Audit sweep (2026-05-27)#

Second comprehensive completeness audit. Goal: exhaustive flow + global-chrome coverage to match the 100% per-view coverage achieved in the 2026-05-26 sweep. Findings + fixes:

  1. 1 page.tsx file with no walkthrough. /tara/sit/[id] was added to the app router by f96ca1dd85 feat(shared): wire tara begin sitting to /tara/sit/[id] player after the 2026-05-26 sweep closed. Drafted in customer/03-tara/tara-sit-id.md (302 lines) covering the TaraSitPlayer client component (timer / drift detection / completion threshold / reflection capture / cross-domain step-out). Routes.csv row added; customer count 147 → 148, V1 count 481 → 482.

  2. 24 missing journey files. The 23-journey sweep from 2026-05-24 covered the per-domain entries + first-time/PWA infra + cross-domain bridges + the Lilith policy + operator/studio + workspace shell. The 2026-05-27 audit identified 24 additional end-to-end flows that were either explicitly named in V1/features.md / V1/ARCHITECTURE.md or implied by per-view files without a journey to land on. Drafted (file → bucket):

    • First-time + PWA infrastructure: onboarding-ten-steps
    • Customer-domain follow-ons: arete-living-offering-create, weekly-review-arete, veritas-retraction-cascade-customer-view, metis-byom-ingest-to-course
    • Discovery, messages, library: messages-center-deliver-and-unsubscribe, messages-quiet-hours-and-channel-binding, library-save-collection-share, search-explore-deep-read-library-save, nyx-event-calendar-sync-reminder, nisaba-notebook-capture-and-cite
    • Account, billing, identity: account-deletion-and-dsar, memory-edit-pause-forget, sign-up-and-pay-crypto, aaa-upgrade-entitlement-bounce
    • Scene + atelier authoring: scene-keep-and-share, public-scene-abuse-report, scene-public-viewer-anonymous, atelier-image-to-library, lilith-studio-tara-scene-publish
    • Agentic pipelines: agentic-pipeline-customer-invocation (single template walking any of the six Cross-Domain Autonomous Pipelines)
    • Assistant, operator, tenant — extended: assistant-handoff-context-carry, tenant-bulk-member-invite-scim, tenant-audit-log-investigation

    Total journey files: 48 (47 journeys + 1 README), up from 24. All new journeys are grounded in real BFF routes, components, and contract types; each documents missing endpoints as Open questions rather than fabricating. (Subsequent second-pass audit added 5 more, bringing the journey total to 52 journeys + 1 README = 53 files — see the second-pass section below.)

  3. 8 missing shell-chrome files. The 6-file shell/ folder from 2026-05-24 covered app-shell / routing / PWA / auth / notifications / a11y. The audit identified 8 additional cross-cutting concerns referenced from per-view files or present in shell-level code without a documenting walkthrough. Drafted:

    • shell/07-trust-safety.md — flag button, crisis cascade, /profile/safety audit log, recovery substrate
    • shell/08-telemetry-analytics.mdOshunEventPayloadMap taxonomy, transports (stdoutSink / BFF / observability triad), cookie-consent gating, forbidden patterns
    • shell/09-i18n-locale-time.md — 8-locale matrix, useLocaleStore, hard-coded <html lang> drift, DST/timezone formatting, hreflang, RTL
    • shell/10-feature-flags-experimentation.md — flag registry, kill switches vs experiments, RuntimeConfigProvider, exposure telemetry
    • shell/11-design-system-tokens.md — Lilith L tokens, font stacks, primitives (LBtn/LChip/LDots/…), shells (LWebShell/LCustomerNav), cream-paper/dark-paper themes, forced-colors fallback
    • shell/12-overlays-and-panels.md — command palette, universal search, assistant dock + panel, What's New, quick-actions, widget sidebar, dialog/modal/sheet, focus management, z-index stacking
    • shell/13-domain-launch-runtime.md — domain switcher, startup gate, transition, degradation, outage banner, error boundary, active-execution status bar, launch-failure telemetry
    • shell/14-performance-web-vitals.md — critical-route budgets, nisabaViewPerformanceBudgets, lighthouse config, web vitals (LCP / INP / CLS / TTFB / FCP), CI gating, bundle budgets, escape hatches

    Total shell files: 14, up from 6.

  4. Final integrity check (all clean): 644 CSV rows / 644 per-view files / 0 YAML errors / 0 missing source files on disk / 0 status mismatches with CSV / 0 missing required sections / 0 broken relative .md links across 3,427 actual links (the 3 "broken" hits in the link-validator are template examples inside 00-conventions.md's per-view file template code block, not literal cross-references). 47 journey files / 14 shell files (counts later updated to 52 + 1 README and same 14 shell — see second-pass section). Every journey

    • shell file's internal .md links resolve.

Audit sweep (2026-05-27, second pass)#

Cross-referenced V1/features.md and V1/ARCHITECTURE.md against the 47 existing journeys to find any multi-step user flow / lifecycle / cross-domain handoff named in the spec but not landed in a journey file. 5 genuine gaps identified; 5 new journey files drafted and indexed:

  • telegram-bot-assistant-delivery.md — bound Telegram user sends text / voice note → BFF webhook (apps/oshun/bff/src/telegram/webhook.ts, routes/telegram.ts) → Sophia-grounded composer (libs/oshun/messaging-channels/src/telegram/sophia-grounder.ts) → reply with disclosure footer + optional TTS audio. Delivery-side counterpart to messages-quiet-hours-and-channel-binding.md. Five concrete TBDs flagged: voice STT is stubbed (webhook.ts:67-71), TTS-back not wired, no per-user account binding lookup, no outbound delivery to api.telegram.org, no crisis scan on voice transcripts.
  • themis-assessment-appeal.md — Themis academic-integrity verdict → student opens appeal → tenant teacher reviews in /operator/metis → override / upheld → student notified → audit chain captured. Anchored on libs/metis/integrations/src/themis-canonical-wiring.ts (adjudicateAcademicIntegrity, openAcademicIntegrityAppeal, resolveAppealCase, captureAcademicIntegrityAuditRecord) and the libs/contracts/src/metis/index.ts Themis verdict schemas. Customer-facing appeal BFF surface is TBD — flagged in Open questions; no themis or appeal handlers exist under apps/oshun/bff/src/.
  • persona-voice-avatar-approval-workflow.md — creator proposes new persona in /lilith-studio/personas → Lilith quality eval → voice-quality + avatar reviewer checks → operator-studio publish gate → deployed to session-selection picker → eventual deprecation / supersession. Grounded on SaraswatiPersonaDossierEditor.tsx, AvatarCostumeAuthoring.tsx, libs/oshun/persona-registry/src/lifecycle.ts (canonical event set with requiredActors + PersonaLifecycleRollbackPlan invariants), and the POST /v1/admin/personas/:personaId/publish route family verified against admin-persona-governance-route.test.ts. Multiple TBDs flagged (rehearsal runner BFF, customer session-selection picker, retirement-recovery flow, audit dedup).
  • psyche-tutor-live-session-to-graded-record.md/metis/tutor → Psyche real-time envelope → transcript auto-persists → Iris memory bridge (apps/oshun/bff/src/routes/assistant-metis-handoff.ts) → adaptive-loop mastery update (libs/metis/tutoring/src/loop/adaptive-loop.ts 8-step, 600 ms P95) → optional /operator/metis review lane → optional Nisaba scholarly handoff. Distinct from metis-lesson-completion.md (quiz / assessment path). Live-voice toggle, transcript persistence endpoint (tutor-session-memories declared in metis/api-client/src/adapter.ts:243 but absent from BFF routes), Psyche transport (WebRTC / WS / SSE), and operator tutor-session review lane are all TBD.
  • tenant-sso-config-saml-oidc-claim-mapping.md — tenant admin uploads SAML metadata XML / OIDC discovery URL → maps external claims onto tenant role templates → sets MFA / IP allowlist / device-posture policy → test sign-in → enable. Setup-side of tenant-bulk-member-invite-scim.md Step 5 (consumption-side). Found in libs/oshun/tenant-console/src/identity/ (sso.tsSsoConnection, SsoClaimMapping, processSsoLogin, five typed error codes, four claim transforms; federation-and-auth-policy.tsTenantAuthPolicy, evaluateAuthChallenge, ipMatchesCidr IPv4-only). The configuration UI lives in apps/oshun/tenant-admin/src/app/identity/page.tsx, not /operator/tenant — discrepancy flagged. Full BFF write surface (/v1/admin/tenants/:id/sso/*) is TBD.

Journey README bucket map updated to add the 5 new entries under their respective buckets: telegram-bot-assistant-delivery → Discovery (7 total); psyche-tutor-live-session-to-graded-record → Customer-domain follow-ons (5 total); tenant-sso-config-saml-oidc-claim-mapping → Assistant/operator/tenant extended (4 total); themis-assessment-appeal + persona-voice-avatar-approval-workflow → Operator + studio + cross-surface (8 total).

Final integrity check (all clean): 644 CSV rows / 644 per-view files / 0 YAML errors / 0 missing source files / 0 status mismatches with CSV / 0 broken relative .md links (excluding the 3 known template examples in 00-conventions.md documented above). 52 journey files + 1 README = 53 files in journeys/. 14 shell files in shell/. Coverage matrix is exhaustive for V1 PWA flows / journeys / global chrome documented in the V1 spec.

Maintenance#

  • When a new route lands, append a row to routes.csv (stub) and create the corresponding file in the right folder.
  • When a route is removed, mark its CSV row status=removed and move the file under archive/ (don't delete — old PRs may still reference it).
  • When Source: code changes, set status of that file's CSV row to stale.
  • A future enhancement: a CI check that diff-compares the CSV against find apps/oshun/web/src/app -name page.tsx and fails on drift, plus the YAML / link integrity checks the 2026-05-26 audit ran by hand.