V1 Web PWA · Walk result

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

A dated evidence record for V1 Web PWA: observed behavior, current source reconciliation, automation evidence, and explicit proof limits.

verdict: partial· 2026-05-29
8sections14 minread1table

On this page
  • 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 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.

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 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#

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?