- Walked: 2026-05-29 against
bf12b0f7d8c291499e1df1ec75d4bd21acf3f6b1. The retained/tmpwalker is ephemeral, so this is a dated smoke record rather than a reproducible run artifact. The client-bundle fix later landed inadae8117ddb084fd6dbf9c26b0a31e4f86da2148; the historical/v1/memorystub landed in03d45f0ad7a276369d9536f8f15e7ba0c627d945. - Reconciled: 2026-07-18 against the current profile component, browser reducers, Iris BFF route and durable adapter, startup wiring, and both named Playwright specs. This was source review, not a fresh application run.
- Verdict: partial / deep for the server-backed core — the current suites deeply cover Iris hydration, server-authoritative pause, blocked and resumed writes, single-record deletion, and an export receipt. Editing, conflict resolution, the audit projection, and the seven-day full-clear request remain browser-local; the destructive challenge is not server-issued.
- Current authority:
WALKTHROUGH/journeys/memory-edit-pause-forget.mdpreserves those authority boundaries step by step.
Result at a glance#
| Interaction | Proof · limit |
|---|---|
| Iris hydrate/review | Authority / proof: GET /v1/iris/adapter/review?role=settings&pageSize=100 supplies server records; browser state and oshun-profile-memory-controls-v1 cache the projection. Real-BFF cases cover hydrate, empty, unavailable/retry, consent, filters, detail, and tenant scope. Limit: an unavailable read may leave cached rows visible; detail and filtering do not perform a fresh authoritative read. |
| Edit/conflict | Authority / proof: local reducers create revisions; tests cover edit, audit projection, telemetry redaction, and two-tab keep-remote/overwrite. Limit: no BFF edit, durable revision precondition, or cross-device compare-and-swap. |
| Pause/resume | Authority / proof: signed-in controls call PATCH /v1/iris/adapter/pause?role=settings; durable Iris persists the opt-out. Tests prove continuity off, 409 iris_memory_paused, two contexts, resume, and a later write. Limit: the second context proves read-back after reload, not real-time push to open devices. |
| Single-fact delete | Authority / proof: a synced row sends settings role, hard mode, reason, and confirmed=true; durable Iris tombstones the id. Tests prove the real delete, local mirror, and next-review absence. Limit: the phrase is static, and the route defaults missing confirmed to true instead of validating server-issued step-up. |
| Full clear | Authority / proof: request/cancel mutate browser state, localStorage, and telemetry; tests cover the challenge, seven-day banner, and cancellation. Limit: no BFF request, durable account-wide schedule, executor, or completion receipt. |
| Export | Authority / proof: POST /v1/iris/adapter/export?role=settings returns receipt metadata; the browser separately composes the bundle. Tests cover id/count/checksum plus the local artifact and audit chain. Limit: the receipt does not make the downloaded artifact a server-owned DSAR export. |
Evidence map#
Solid edges show the customer-facing sequence exercised across the named specs. Dashed edges name the production authority the current surface does not yet provide. Only pause/resume and deletion in this sequence mutate durable Iris authority; edit/conflict and full clear remain local projections.
Proven observations#
Hydration clearly separates current Iris state from a cached projection#
ProfileMemoryControlsstarts from an honestly empty production state, then requests Iris review, consent, and pause data. A successful non-empty review maps server records into the control projection; the component does not ship fabricated customer memories as initial facts.- The browser persists its projection under the exact key
oshun-profile-memory-controls-v1. When review is unavailable, retained cached rows remain readable beside an explicit unavailable state and retry. When Iris returns no records, the rendered outcome still depends on the local projection and pause response rather than proving that every cached row was authoritatively erased. - Category and scope chips, fact detail, provenance, recall history, downstream counts, and the local audit-chain link operate on the hydrated browser model. They are useful inspection affordances, but selecting a row does not issue a second server read.
Edit and conflict resolution are deliberately browser-local#
handleEditSubmitcompares the editor's expected revision against browser state, calls the local edit reducer, writes the next projection to localStorage, and emits redacted browser telemetry. It does not send a BFF edit request even when the selected row originated in Iris.- The edit reducer supersedes the displayed item and creates a child revision
with
editedFromItemId. The resulting audit chain describes operations in this browser model; it is not a durable server ledger for the Iris record. - The component listens for the same storage key's
storageevent. Two tabs on one origin can therefore expose a stale-draft conflict and choose the remote localStorage revision or layer another local revision on it. Two devices do not share that CAS boundary.
Pause and single-record deletion reach durable Iris authority#
- Signed-in pause toggles call the Iris adapter and commit the returned state only after success. The offline case fails closed: the UI does not pretend a pause was accepted when the mutation failed.
- The real-BFF suite proves the behavioral gate, not just the toggle. Continuity
reports memory
off; a live remember attempt returns409 iris_memory_paused; the blocked sentence is absent from review; resume persistspaused: false; and a later remember call creates a visible row. - Two isolated browser contexts with the same BFF identity read the same account-scoped pause after navigation/reload. That is durable read-back, not a claim of socket-driven synchronization between already-mounted pages.
- Deleting a synced fact sends hard mode, a reason, and
confirmed=trueto the management route. The durable Iris adapter tombstones the id, and a later review hides it. Only after a successful response does the component mirror the deletion into its local reducer.
Full clear and export combine unlike authorities in one surface#
- Typing
FORGET EVERYTHINGplusiris-step-upcan create or cancel a seven-day grace object in browser state. The library tests the state machine, and the profile spec tests its banner and telemetry, but there is no matching Iris BFF full-clear route or scheduled worker consuming that record. - For synced state, export first posts to the Iris adapter and displays a
non-secret receipt with id, count, and checksum metadata. The downloadable
“signed” bundle is then assembled from the browser control projection by
exportIrisUserMemoryBundle; the server does not return that artifact's bytes through this flow. profile-memory-controls.spec.tscontains four local/stub-driven cases.memory-edit-pause-forget.spec.tscontains sixteen cases spanning anonymous gating, failure/retry, local conflicts, real Iris hydrate/export/delete, pause/read-back, two contexts, and the blocked-write boundary.
Boundaries and gaps#
- Cached rows are not a fresh Iris read. Unavailable and retry states must stay visible whenever the page is showing retained browser data.
- A local revision is not a server edit. The UI cannot promise that its revised content changed the durable Iris fact.
- A same-origin conflict is not cross-device compare-and-swap. The storage event model coordinates tabs sharing one browser origin, not independent devices or BFF writers.
- A static phrase is not server-issued step-up.
iris-step-upnever reaches the route as a credential, andconfirmedcurrently defaults to true when absent at the server boundary. - A local grace record is not a deletion schedule. Nothing on this page registers, executes, or proves an account-wide full-memory clear.
- A tombstone mirror is not a second deletion. The server tombstone is authoritative for a synced id; the local reducer updates the projection only after that mutation succeeds.
- An export receipt is not the downloaded bundle. Server metadata and the browser-composed artifact have distinct provenance and assurance levels.
- A memory export is not a DSAR lifecycle. The separate data-rights journey owns request, status, cancellation, and delivery claims.
- Historical
/v1/memorysmoke is not current Iris proof. The present flow uses/v1/iris/adapter/*; the 2026-05-29 walker cannot substantiate later route behavior. - Source reconciliation is not execution. Neither cited application suite was rerun for this documentation audit.
Re-run evidence#
Run the two focused suites sequentially against one production-like web/BFF pair and one immutable commit:
pnpm --dir apps/oshun/web exec playwright test -c playwright.config.ts e2e/profile-memory-controls.spec.ts --project=chromium --workers=1
pnpm --dir apps/oshun/web exec playwright test -c playwright.config.ts e2e/memory-edit-pause-forget.spec.ts --project=chromium --workers=1
Retain the commit, browser and BFF reports, backing-store tier, seeded identity, and before/after Iris snapshots. A stronger follow-up should also retain a restart result, two real-device traces, the server-issued step-up exchange, and a durable full-clear request through execution and receipt.
Source trail#
- Current journey contract
- Current coverage registry
- Profile memory controls
- Profile memory state bridge
- Browser control reducers
- Iris adapter route
- Iris adapter and durable store
- Durable Iris startup wiring
- Local control spec
- Real-BFF memory spec
Cross-references#
- Profile memory view evidence
- Account deletion and DSAR journey
- Account deletion and DSAR result
- Assistant handoff result
- Crisis-aware tone-policy result
- Current Docs Center coverage audit
Open questions#
- Which server edit contract will accept revision preconditions and return a durable conflict that independent devices can resolve safely?
- Which authentication flow will issue, expire, bind, and consume a genuine step-up credential for destructive memory operations?
- Where will full-clear request, cancellation, grace expiry, execution, and completion receipt live as one durable account-scoped lifecycle?
- Should an authoritative empty Iris review clear cached rows, quarantine them, or preserve them under an explicitly historical/offline label?
- Will export return a server-owned artifact with durable retention and access controls, or remain separate from the account DSAR workflow?
- When will “forget all mentions” across authorized actors gain a real UI, policy contract, and multi-record server operation?