---
status: reconciled-partial
coverage_depth: deep-for-separated-hub-catalog-player-reciprocal-and-recommendation-seams
last_walked: 2026-05-29
last_reconciled: 2026-07-21
specs:
  - apps/oshun/web/e2e/nyx-event-pages.spec.ts
source: WALKTHROUGH/journeys/nyx-to-tara-bridge.md
---

# Journey result: Nyx → Tara — curated navigation, no shared handoff record

- **Walked**: 2026-05-29 at `3678298cd3`. The retained result cited an ephemeral
  `/tmp/claude-oshun-lt-2-walkthrough/walk.mjs`, reported one Tara link on
  `/nyx`, and treated a 200 from `/v1/cross-domain/recommendations` as bridge
  evidence. It retained no DOM, href, source event id, resolver output, Tara
  practice id, analytics record, session receipt, completion record, return
  target, member identity, or service trace.
- **Reconciled**: 2026-07-21 against the live and unavailable `/nyx` mappers,
  all fixed event models, the Nyx → Tara relationship resolver and card, shell
  route hydration, Tara player and reciprocal suggestion builders, local
  theme-continuity storage, auth cleanup, the BFF recommendation route, focused
  unit suites, and the named Playwright file. This is repository evidence, not a
  production analytics sink, real audio stream, personalized policy evaluation,
  cross-device session, or service-level trace.
- **Verdict**: **partial / deep for the separated shipped seams** — every fixed
  rich Nyx event receives one deterministic Tara card; the real link opens the
  intended Tara timer player; completion exposes a generic reciprocal Nyx
  suggestion and a 12-hour browser-local theme snapshot. The `/nyx` hub's
  conditional Tara slot is not populated, the event id stops at the source
  link's DOM attributes, the telemetry markers have no emitter, audio is wired
  to the wrong shape/path, and no owner-scoped handoff or completion record
  joins Nyx to Tara.
- **Current authority**:
  [`WALKTHROUGH/journeys/nyx-to-tara-bridge.md`](../journeys/nyx-to-tara-bridge.md)
  now walks the implemented fixed-catalog path and names the hub, API,
  telemetry, media, identity, and persistence boundaries explicitly.

## Result at a glance

| Interaction               | Proof · limit                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Historical walk           | **Proof:** a prior browser walk reported a visible Tara link and a successful recommendation response. **Limit:** its temporary script and artifacts are gone, so neither claim retains inspectable identity or network evidence.                                                                                                                                                                                                                         |
| `/nyx` hub                | **Proof:** `NyxRoom` contains a conditional **Ground with Tara** link when `data.taraGroundingCue` exists. **Limit:** neither `mapNyxTonightToNyxData` nor `nyxUnavailable` supplies that optional field, so both live and unavailable hub states omit the link.                                                                                                                                                                                          |
| Fixed event relationship  | **Proof:** every record returned by `listNyxEventPageModels` receives exactly one relationship from a static resolver. Event type plus authored `highlightFrame` and `audience` select awe, lunar, meteor, seasonal, or cosmic-perspective copy and a Tara path. **Limit:** `audience` describes the content; no member, preference, lineage, crisis, history, time, or location enters the resolver.                                                     |
| Event-detail card         | **Proof:** the card renders reason, relationship, mode, ritual moment, subtype, title, summary, and a real `/domains/tara?origin=...&stack=nyx&path=...` link. It exposes source event, practice, and relationship ids as DOM attributes. **Limit:** the href itself contains only shell origin, domain stack, and practice path; Tara receives no event id or event envelope.                                                                            |
| Tara destination          | **Proof:** the hydrated path launches `SessionPlayer`; a Nyx-final stack labels the Play control `surface=nyx_event_handoff`, and the timer, seek, pause, transcript, completion, and reflection UI are functional local state. **Limit:** the surface label is derived only from `stack.at(-1) === 'nyx'`; it does not validate the source event or a server-issued handoff.                                                                             |
| Tara audio                | **Proof:** the player remains usable when media fails and explicitly reports timer mode. **Limit:** its hidden audio source uses `/api/v1/sessions/<id>/audio`, while the Next rewrite proxies `/v1/*`; the BFF endpoint returns a JSON metadata envelope whose `tracks.primary.url` is the actual media locator. The audited element neither reaches that route nor resolves the track URL.                                                              |
| Completion                | **Proof:** reaching `totalSec` or seeking to it renders the completion surface, appends `taraSessionState=complete` to browser history, and writes a theme snapshot. **Limit:** no Tara session completion POST, Nyx observation, Iris memory, shared trace, or durable receipt occurs. The URL flag can reopen completion without proving elapsed practice.                                                                                              |
| Reciprocal Nyx suggestion | **Proof:** the completed player builds a Tara → Nyx relationship from the generic launched session and routes to `/nightly-highlights` or `/sky-map` with a `ref`. **Limit:** `march-equinox` and every other originating event id are absent; the destination cannot return to the exact event.                                                                                                                                                          |
| Theme continuity          | **Proof:** `oshun.tara.theme-continuity.v1` stores session taxonomy and expires reads after 12 hours. **Limit:** the key is browser global, is not cleared by normal auth cleanup, and is consumed by Home recommendation ordering—not as a Nyx/Tara handoff record.                                                                                                                                                                                      |
| Telemetry contract        | **Proof:** the Nyx link exposes `nyx_event_tara_recommendation_opened`; the Tara Play control switches among `tara_sit_started`, paused, and resumed attributes and labels the inferred surface. **Limit:** the audited controls only mutate UI/navigation; no delegated handler or direct analytics call consumes those attributes.                                                                                                                      |
| BFF recommendations       | **Proof:** the authenticated route can rank and return member-scoped source candidates, partial-failure metadata, cache headers, attribution, and server-side served telemetry. **Limit:** its target union is only Nisaba or Metis. Its Nyx builders produce Nyx → Nisaba and Nyx → Metis items, and no Nyx event-detail or Tara player component calls the route.                                                                                       |
| Named automation          | **Proof:** `nyx-event-pages.spec.ts` contains 15 browser cases. One case crosses `march-equinox` → Tara timer → generic Nyx return; another checks five relationship buckets, while component/domain tests pin the builders and attributes. **Limit:** the browser case accelerates completion with repeated 15-second seek dispatches, asserts DOM telemetry rather than delivery, and does not inspect a server completion receipt because none exists. |

## Evidence map

Solid arrows are implemented navigation or local state transitions. Dashed
arrows are dormant render branches, identity loss, or unrelated authorities. The
central lane is the only working Nyx → Tara path.

```mermaid
flowchart TB
    B[Nyx to Tara bridge] --> H[Nyx hub<br/>live or unavailable mapper]
    B --> E[Fixed Nyx event detail]
    B --> X[BFF cross-domain recommendations]
    H -. taraGroundingCue never supplied .-> G[Dormant Ground with Tara slot]
    E --> R[Static relationship resolver<br/>content fields only]
    R --> C[Tara recommendation card<br/>event id stays in DOM]
    C --> P[Tara timer player<br/>origin · stack · practice path]
    P --> L[Local completion<br/>URL flag + 12-hour theme snapshot]
    L --> N[Generic Nyx suggestion<br/>nightly highlights or sky map]
    C -. no emitted analytics .-> A[Analytics receipt]
    P -. no event or session envelope .-> D[Durable cross-domain record]
    N -. no originating event id .-> E
    X --> M[Nisaba or Metis targets only]
```

## Proven observations

### The retained hub pass no longer matches the data path

- `NyxRoom` still contains the exact conditional block that can render **Ground
  with Tara**, but its input type makes `taraGroundingCue` optional. The live
  `mapNyxTonightToNyxData` mapper copies the ephemeris fields and adds only the
  Nisaba canon link. `nyxUnavailable` does the same for the empty state. A
  repository-wide source search finds no producer for the optional Tara field.
- This makes the branch dormant in both normal `/nyx` outcomes. The older
  result's statement that the hub "ships" the link is not supported by current
  source or mapper tests. The working customer bridge moved to the fixed rich
  event surface under `/events/<fixed-id>` and
  `/domains/nyx?...path=/events/...`.
- The hub is fed by `/v1/nyx/tonight`, while the event-detail bridge is built
  from `NYX_WEB_EVENT_RECORDS`. Their adjacency in Nyx does not make a missing
  hub cue evidence for the fixed catalog path.

### Every fixed event receives one authored classification, not a member recommendation

- `buildNyxTaraRecommendations` always returns a one-element array for a valid
  fixed event. Six event ids have explicit `highlightFrame` and `audience`
  configurations; remaining event types fall through authored awe, symbolic,
  seasonal, observer, or educational rules. The domain resolver then defaults
  any unmatched input to `nightly_awe`.
- The web test explicitly asserts that every fixed event has a Tara
  recommendation. There is no shipped "no relationship" branch for a valid fixed
  record, no score or abstention threshold, and no runtime service call.
- Resolver inputs include event title and object names, but its decision logic
  does not read them. The decisive fields are `ritualMoment`, highlight frame,
  event type, source kind, and the content-level audience enum. The output is a
  descriptor from `NYX_TARA_RELATIONSHIPS`, including generic copy and one of
  the fixed practice paths.
- `audience: 'general' | 'student' | 'observer' | 'mixed'` is authored metadata
  for the event model. No authenticated subject id, member profile, selected
  tradition, preference, prior practice, accessibility need, or distress input
  is available. Authentication gets the user into the shell; it does not make
  this resolver personalized or crisis aware.

### The real link carries a practice choice but drops event identity

- The event card retains excellent inspectable source metadata:
  `data-telemetry-event-id`, `data-telemetry-practice-id`, relationship kind,
  reason, display mode, ritual moment, and subtype. The March equinox case maps
  to `tara-morning-opening` and a seasonal-opening relationship.
- `buildHydratedWebDomainRoutePath` encodes only the destination path plus
  `origin` and `stack`. The March equinox href is therefore
  `/domains/tara?origin=explore&stack=nyx&path=%2Fmeditate%2Fritual%2Ftara-morning-opening`.
  Neither `eventId=march-equinox` nor a handoff id crosses the anchor.
- `TaraSurface` parses the path, converts the final segment into a generic
  session id, labels ritual paths **Guided ritual**, and creates companion
  prompts from that generic Tara session. It does not read the source anchor's
  DOM attributes after navigation. The `nyx_event_handoff` player surface is
  inferred solely from the last stack entry.
- Browser history preserves the broad shell context and later the
  `taraSessionState=complete` flag. Those are useful navigation affordances, but
  they neither assert that the correct event created the launch nor bind a
  completion to that event.

### The player is a timer experience; its current audio source cannot consume the BFF contract

- The timer advances once per second, supports seek controls, and completes when
  elapsed time reaches the generated duration. The E2E helper dispatches the
  15-second forward control repeatedly until completion, so it proves player
  state and the completion surface without waiting for a full practice.
- The hidden `<audio>` element points to
  `/api/v1/sessions/<sessionId>/audio?quality=...`. `next.config.mjs` only
  rewrites `/v1/:path*`, not `/api/v1/:path*`. Even at the correct BFF path,
  `session-audio.ts` returns `TaraSessionAudioMeta` JSON containing
  `tracks.primary.url`; it is not the media stream itself. The player never
  fetches that envelope or assigns the nested URL to the element.
- Error handling is honest enough to keep the timer usable and say **Audio
  failed to load. Using timer mode.** The bridge automation does not wait for
  audio readiness, inspect an audio response, or prove playback bytes. Its
  successful completion must be read as timer-mode UI proof.

### Completion and the reciprocal suggestion are local and generic

- Completion writes `taraSessionState=complete` with `history.replaceState` and
  calls `persistRecentTaraThemeContinuity` once. That snapshot contains the
  generic Tara session id/title, inferred ritual moment, taxonomy, instructor,
  and capture time. Reads expire it after 12 hours.
- No completion handler calls `/v1/sessions`, `/v1/nyx/observations`, an Iris
  route, or a cross-domain store. Reopening a URL containing
  `taraSessionState=complete` sets the completion screen directly; it is a
  browser route state, not evidence that a timer elapsed on this or another
  device.
- `buildTaraNyxPerspectiveSuggestion` independently infers a relationship from
  the generic Tara session. For the morning ritual it produces
  `/domains/nyx?origin=explore&stack=tara&path=%2Fnightly-highlights&ref=...`.
  It has no input field for the Nyx source event and therefore cannot return to
  `/events/march-equinox`.
- The theme-continuity snapshot influences Home's cross-domain ordering and
  explanatory callouts. Its browser-global storage key is absent from
  `clearLocalAuthState`, which resets auth/profile/preferences/privacy/data-
  rights/billing stores and requests a service-worker cache purge. A second
  account on the same browser can therefore read the first account's recent
  session theme during the 12-hour window.

### Telemetry is described in the DOM but never delivered from these controls

- The event link declares `nyx_event_tara_recommendation_opened`, source event,
  practice, relationship, and `from=nyx`. It remains a normal Next `Link` with
  no click handler. Repository search finds no delegated consumer for
  `[data-telemetry-event]`, `dataset.telemetry`, or an equivalent closest-node
  listener.
- The Tara Play button computes `tara_sit_started`, paused, or resumed and
  exposes origin, stack, session id, and the stack-derived surface. Its click
  handler only updates animation and `isPlaying`. Unit and E2E assertions read
  those attributes; they do not observe an analytics client, BFF call, queue,
  trace id, or sink receipt.
- This is a useful proposed event contract, but current evidence cannot support
  funnel counts, delivery guarantees, source-event attribution in Tara, or a
  claim that a server recorded the start.

### The 200 BFF endpoint is a different cross-domain product

- `/v1/cross-domain/recommendations` correctly requires authentication and
  authorized domain scopes, builds a member ranking profile, isolates cache keys
  by user and profile revision, carries partial-failure details, appends
  attribution, and emits a server-side "recommendations served" event.
- Its `CrossDomainRecommendationItem.targetDomain` type is only
  `nisaba | metis`. The Nyx source tasks call `buildNyxToNisabaRecommendation`
  and `buildNyxToMetisRecommendation`; there is no Nyx → Tara task in this
  route. A 200 response can contain ten credible results and still contain zero
  Tara destinations.
- The fixed event card imports the domain relationship resolver directly and
  never calls `useCrossDomainRecommendations`. The Tara player likewise builds
  its local companions directly. The BFF endpoint appears on mixed Home and
  cross-domain recommendation surfaces, not in the audited event bridge.

## Boundaries and gaps

- **A dormant render branch is not a shipped hub bridge.** The optional
  `taraGroundingCue` UI has no current producer.
- **A catalog classification is not member personalization.** Authored event
  metadata selects a fixed descriptor without reading a person.
- **Navigation context is not event context.** `origin` and `stack` identify
  shell history, not March equinox or any other event.
- **A practice path is not the originating event identity.** The href carries
  `tara-morning-opening` and drops `march-equinox`.
- **A DOM telemetry contract is not an emitted analytics record.** Attributes
  with good names still need an emitter and receipt.
- **Audio metadata is not an audio stream.** The player's unproxied `/api/v1`
  source cannot consume the JSON track envelope returned by the BFF.
- **Timer completion is not a durable session receipt.** The state change has no
  owner-scoped service write or cross-domain trace.
- **A completion query flag is not persisted progress.** It can restore the
  final screen without proving elapsed practice.
- **A generic Nyx suggestion is not an exact return path.** The reciprocal
  builder never receives the source event id.
- **Theme continuity is not cross-domain continuity.** The Home taxonomy hint is
  not a Nyx/Tara handoff record.
- **Browser-local continuity is not subject-partitioned state.** The 12-hour key
  survives normal logout without a member namespace.
- **A 200 recommendation envelope is not a Nyx-to-Tara recommendation.** That
  endpoint only targets Nisaba and Metis and is not called by this path.
- **Fifteen cases are not a service-level handoff receipt.** The named browser
  file includes two focused bridge cases but no emitted analytics, audio bytes,
  durable completion, account-isolation, or exact-return assertion.

## Re-run evidence

- The complete Docs Center source suite passes **54/54** cases. Its Result 45
  gate pins registry position, front matter, section order, the single evidence
  map, the 15-case named browser file, dormant hub slot, fixed relationship
  resolver, href identity loss, stack-derived telemetry surface, media contract
  mismatch, local completion, reciprocal path, auth cleanup, and BFF target
  boundary.
- Six focused unit/integration files pass **100/100** cases: 4 Nyx → Tara domain
  relationships, 16 fixed event models, 4 event-detail workspaces, 4 reciprocal
  suggestion builders, 69 Tara player cases, and 3 BFF recommendation-route
  cases. These cover the deterministic relationships, component DOM, route
  construction, timer/completion state, local persistence, and the separate API
  envelope.
- `nyx-event-pages.spec.ts` contains **15 cases** and ran serially with one
  Chromium worker. Both affected bridge cases pass **2/2** in isolation: March
  equinox card → Tara timer → reciprocal generic Nyx landing, plus all five
  relationship buckets. The full file passes **14/15**; the sole failure is an
  unrelated pre-existing assistant-explainer button contrast violation. The
  test's 15-second seek helper, DOM-only telemetry assertions, and lack of a
  service receipt remain explicit evidence limits.
- Final docs generation renders **3,116 files**, including **944 walkthrough
  pages**, **64 journeys**, and **2,787 reader pages**. Freshness passes
  **3,116/3,116** files; integrity reports **0** structural broken links and
  **0** dead source paths, while retaining 112 imported-content warnings. Result
  45's reader gate passes **2/2** desktop/mobile cases for partial status,
  substantive prose, all thirteen boundary statements, Mermaid containment and
  pairwise node geometry, expand-control clearance, heading anchors, journey
  navigation, console/page errors, and horizontal overflow. Full-page Chromium
  captures were also inspected at 1,440 px and 390 px widths.

## Source trail

- Dormant hub slot and producers:
  `apps/oshun/web/src/components/lilith/rooms.tsx`,
  `apps/oshun/web/src/lib/lilith-data/{types,nyx,nyx-tonight}.ts`, and
  `apps/oshun/web/src/app/nyx/page.tsx`.
- Fixed event bridge: `libs/oshun/domain-nyx/src/tara-relationship.ts`,
  `apps/oshun/web/src/components/domains/nyx/nyxEventPageModels.ts`, and
  `apps/oshun/web/src/components/domains/nyx/NyxEventDetailWorkspace.tsx`.
- Route and player: `apps/oshun/web/src/navigation/routes.ts`,
  `apps/oshun/web/src/components/domains/TaraSurface.tsx`,
  `apps/oshun/web/src/components/domains/tara/SessionPlayer.tsx`, and
  `apps/oshun/web/next.config.mjs`.
- Reciprocal and local continuity:
  `apps/oshun/web/src/components/domains/tara/taraSessionNyxSuggestions.ts`,
  `libs/oshun/domain-tara/src/nyx-relationship.ts`,
  `apps/oshun/web/src/components/home/taraThemeContinuity.ts`, and
  `apps/oshun/web/src/lib/auth-context.tsx`.
- Separate BFF authority:
  `apps/oshun/bff/src/routes/cross-domain-recommendations.ts`,
  `apps/oshun/bff/src/routes/session-audio.ts`, and
  `apps/oshun/bff/src/adapters/domain-service-adapters.ts`.
- Automation: `apps/oshun/web/e2e/nyx-event-pages.spec.ts`,
  `apps/oshun/web/e2e/support/tara.ts`, and the six focused unit/integration
  files counted above.

## Cross-references

- [`nyx-event-calendar-sync-reminder.md`](./nyx-event-calendar-sync-reminder.md)
  separates the same fixed event catalog from the dynamic ephemeris and durable
  reminder authorities.
- [`nyx-tonight-observation.md`](./nyx-tonight-observation.md) covers the real
  `/nyx` ephemeris mapper and why its ids do not automatically become fixed rich
  event pages.
- [`first-tara-sit.md`](./first-tara-sit.md) covers Tara's other player,
  reflection, and persistence paths without treating them as this bridge.
- [`tara-to-nisaba-handoff.md`](./tara-to-nisaba-handoff.md) provides a useful
  comparison: it also uses a direct relationship builder, but its destination
  coverage reaches a real grounded reading surface.
- [`assistant-handoff-context-carry.md`](./assistant-handoff-context-carry.md)
  demonstrates what an explicit persisted continuity envelope looks like.

## Open questions

- Should `/nyx` intentionally restore a live-event Tara cue, remove the dormant
  optional branch, or link into the fixed rich catalog first?
- Should the event-card href carry an immutable source event id, relationship
  version, issued-at time, and return URL in a signed or owner-scoped handoff
  envelope?
- Which service should apply preference, tradition/lineage, accessibility, and
  crisis policy, and what abstention or safe-fallback contract should it expose?
- Should Tara fetch session-audio metadata from `/v1/sessions/.../audio`, select
  the authorized track URL, and prove playable bytes plus timer fallback?
- What authenticated completion mutation should bind elapsed practice,
  originating event, member, device, and trace while preventing a URL flag from
  posing as completion proof?
- Should the reciprocal card return to the exact source event before offering a
  broader nightly-highlights path?
- Should recent theme continuity be member partitioned, removed on logout, and
  synchronized only with explicit consent?
- Will the DOM telemetry contract gain a tested analytics emitter and receipt,
  or should the attributes be labelled as instrumentation proposals?
- Should the generic recommendation endpoint support Tara targets, and if so,
  should the fixed event card consume that governed result instead of its static
  direct resolver?
