- Walked: 2026-05-29 at
bf12b0f7d8c291499e1df1ec75d4bd21acf3f6b1. The retained walker was an ephemeral/tmpscript. It rendered/library,/library/collections, and/library/collections/new, then observed a collection-create POST. - Reconciled: 2026-07-18 against the current journey, all four Library routes, the saved-item and collection sources, the sharing engine/BFF, the recipient route, and six focused browser specs. This was source review, not a fresh application run.
- Verdict: partial — the dated route/create slice passed and later browser suites substantially deepened save, collection editing, share-policy, and recipient-denial evidence. The complete journey still spans two disconnected collection models, keeps dashboard collection composition on one device, and resolves shared permission without rendering the sender's collection contents.
- Current authority:
WALKTHROUGH/journeys/library-save-collection-share.mdand itspartialcoverage-registry row.
Result at a glance#
| Evidence plane | Current implementation | Strongest surviving proof | Authority limit |
|---|---|---|---|
| Saved items | Domain saves converge on webLibraryStore; signed-in snapshots use /v1/library/saved-items, with optimistic local cache and guest migration |
Real-BFF save/read-back, unsave, same-user clean-device hydrate, LWW sync, tombstones, isolation, cap paywall, and several direct producers | Not every producer or entitlement/resume permutation is exercised; Nyx event save still owns a separate local action store |
| Server collection catalog | /library/collections/new posts label + opaque item ids to the member-scoped /v1/library/collections; /library/collections lists those rows |
Live-BFF accepted, pending, validation, offline, focus, owner-isolation, and mobile form coverage | Create/list is a separate plane from the dashboard editor; the success/list links point to /library?collectionId=…, which the root page does not read |
| Dashboard collection composition | /library/collection/:id edits label, description, follow-up, membership, and archive state in oshun.library.collections.v1 |
Create-from-filter, edit, membership toggle, archive, corrupt fallback, unknown deep link, and v0→v1 migration | Browser-local only; labels, membership, and archive state do not follow the member to another device |
| Share policy | CollectionShareControls writes private, named-user, link, and public-profile policy through /v1/library/collections/:id/* |
Token issue/revoke, invite/referral attribution, permission tiers, owner checks, and policy read-back over the BFF | The policy store is process memory, and policy creation does not prove that a corresponding server collection payload exists |
| Recipient route | /share/:token asks the BFF to resolve a collection id and requested permission |
Valid grant, wrong/revoked token, insufficient tier, and same-id local-shadow rejection | Current tests use signed-in recipients; the page shows id/tier/via only, not sender labels, items, provenance, or embed cards |
Evidence map#
The current UI crosses three persistence planes. The dashed branch is the key disconnect a green create response cannot reveal.
flowchart LR
A[Domain Save] --> B[Saved-items BFF]
B --> C[Library hydrate]
C --> D[Dashboard collection editor]
D --> E[Local collection payload]
D --> F[Share-policy BFF]
F --> G[Share token]
G --> H[Recipient permission view]
I[Server collection form] --> J[Server collection catalog]
J -. collectionId query ignored .-> C
H -. contents not delivered .-> E
Proven observations#
The dated slice is reproducible as a historical claim#
- Both abbreviated commits in the old record resolve in repository history: the
walk at
bf12b0f7d8c291499e1df1ec75d4bd21acf3f6b1and the earlier route repair at8ad5d6a4dfac400ef925ef95df2d6bf155c57158. - All three dated routes remain in the current 701-route inventory. The new
collection form still POSTs
{ label, itemIds }to/v1/library/collections, exposes pending/error/accepted states, preserves fields after server/offline failure, and moves focus to its accepted status. - The member-scoped BFF collection route rejects anonymous callers, validates a
two-character label, records the owner, returns
202, and lists only the caller's rows plus legacy unowned migration rows. Its backing tier can be PostgreSQL, a protected development snapshot, or test memory. - The original “0 page errors, 0 persistent failures” remains a dated walker
observation. The missing
/tmpwalker means its exact selectors, environment, and raw report cannot be independently inspected now.
Saved-item continuity is substantially deeper today#
webLibraryStorekeeps an offline cache but hydrates signed-in members from the saved-items BFF. Focused browser evidence covers direct Nisaba passage save, guest→sign-in migration, clean-device hydration, resume navigation, saved-queue transitions, and unsave row removal.- Companion real-HTTP suites cover same-user cross-device propagation, LWW conflict accounting, tombstone deletion, per-user isolation, and the 25-save free-tier cap. Search, Explore, Veritas, Sophia, Atelier, Tara, Nyx search results, and Metis producers have targeted evidence elsewhere in the current journey registry.
- This evidence is appropriately stronger than “the page rendered.” It proves server read-back for named producers and states; it does not prove every saveable surface or every canonical resume destination.
Collection composition and sharing are not one persisted object#
- The Dashboard collection manager builds
/library/collection/:idlinks and persists its own versioned label, description, follow-up, membership, and archive model underoshun.library.collections.v1. - The separate server catalog links a created row to
/library?collectionId=<id>, whileapp/library/page.tsxonly parsesdomainandkind. That link opens the generic Library rather than selecting the server-created collection. The form spec currently asserts the href, not a successful open-and-edit continuation. CollectionShareControlscan attach a valid BFF policy to a Dashboard collection id, but the sharing route governs authorization only. It does not fetch or deliver the Dashboard's local collection record.- The recipient route deliberately avoids the recipient's same-id local shadow. Its granted state displays the server-resolved collection id, tier, and resolution channel; this is a correct isolation repair, not content sharing.
Share authorization fails closed within its tested scope#
- Tokens are generated from 32 random bytes, returned once, and stored as a SHA-256 hash. The engine validates view/comment/copy ordering, expiry, revocation, owner-only mutation, named-user grants, and public-profile policy.
- Browser/BFF specs cover issue→resolve→revoke, wrong-token denial, insufficient permission, invite/referral attribution, private state, named-user copy, and public-profile comment policy read-back.
- The current
LibrarySharePolicyStoreis an in-processMap. A BFF restart or a different instance loses its policies unless a durable adapter replaces this binding; “real BFF” must not be read as production durability.
Boundaries and gaps#
- The dated pass belongs to a route/create slice, not the current journey. Rendering three pages and observing one POST never proved domain save, collection editing, link authorization, recipient isolation, or read-back.
- A server collection row is not the Dashboard collection. The create/list route, local editor, and share policy currently agree only on an opaque id; they do not share one authoritative collection payload.
- The “Open it” continuation is broken by contract. Both the catalog and
accepted form emit
?collectionId=, but/libraryignores that parameter. - A permission card is not shared content. The recipient does not receive the sender's label, member items, ordering, provenance, grounding, synthetic indicators, or embeddable card.
- A process-local policy is not durable authorization. Restart and multi-instance behavior remain outside the present sharing proof.
- Anonymous link access is not proven. The resolution BFF route requires an auth context, and current browser evidence signs in the recipient.
- Collection composition is not cross-device. Saved items sync; Dashboard collection metadata and membership remain localStorage-only.
- Several journey branches remain open. Nyx event-save convergence, filter-URL write-back, offline resume, gated-item resume, collection delete, public-profile collection rendering, and provenance-preserving embed cards are not closed by this result.
- Source reconciliation is not execution. None of the cited web/BFF suites was rerun for this documentation audit.
Re-run evidence#
Run the live BFF and production-like web app at the same immutable commit, then execute the focused specs one at a time with one worker:
bash
pnpm --dir apps/oshun/web exec playwright test -c playwright.config.ts e2e/library-collections-new.spec.ts --project=chromium --workers=1
pnpm --dir apps/oshun/web exec playwright test -c playwright.config.ts e2e/library-save-collection-share.spec.ts --project=chromium --workers=1
pnpm --dir apps/oshun/web exec playwright test -c playwright.config.ts e2e/library-collection-management.spec.ts --project=chromium --workers=1
pnpm --dir apps/oshun/web exec playwright test -c playwright.config.ts e2e/collection-share.spec.ts --project=chromium --workers=1
pnpm --dir apps/oshun/web exec playwright test -c playwright.config.ts e2e/library-shared-resolution.spec.ts --project=chromium --workers=1
pnpm --dir apps/oshun/web exec playwright test -c playwright.config.ts e2e/library-shared-web-view.spec.ts --project=chromium --workers=1
Retain the web/BFF commit, backing-store tier, environment manifest, Playwright artifacts, and member identities. Add an explicit create→open→edit→second-device read-back assertion before upgrading this result beyond partial.
Source trail#
- Current journey contract
- Current coverage registry
- Server collection list
- Server collection form
- Library root route
- Dashboard collection manager
- Saved-item store
- Collection share controls
- Shared-token route
- Collection catalog BFF routes
- Sharing BFF routes
- Share-policy store
Cross-references#
- Library route evidence
- Collection deep-link evidence
- New collection route evidence
- Shared-token route evidence
- Search→deep read→save journey
- External collection contract
- V1 completeness audit
Open questions#
- Which collection model becomes canonical: the BFF catalog, the Dashboard local payload, or a merged server contract with migration from both?
- Should server-created collection links use
/library/collection/:id, and what server read must hydrate that route before editing is enabled? - When will share policies move from the in-process map to the same durable, owner-scoped collection boundary?
- What payload should an authorized recipient receive, and how will it preserve ordering, provenance, grounding, synthetic indicators, and entitlement gates?
- Is anonymous link-with-key access intended? If so, what limited auth/rate/ revocation boundary replaces the current signed-in precondition?
- Which test will prove one continuous domain-save→collection-create→share→ recipient-content flow with clean sender and recipient browser contexts?