Context
apps/loopover-ui/src/lib/snapshot-replay.ts builds the "decision snapshot replay" view model (issue
#285) used by apps/loopover-ui/src/components/site/snapshot-replay.tsx's <SnapshotReplayCard> /
<SnapshotReplay> (wired into apps/loopover-ui/src/routes/app.runs.tsx). Its whole job is a privacy
boundary: buildSnapshotReplayView({ viewer, snapshot, counterfactuals }) takes a
viewer: "public" | "authenticated" and, for "public", strips reason/facts/assumptions off
every counterfactual alternative via projectCounterfactuals() (lines 195-213), replacing them with
null/[] and recording what was withheld in withheldPrivateFields. The component then renders an
explicit audience toggle (<SnapshotReplayCard authenticated publicSafe>) specifically so a reviewer
can visually confirm the public view never leaks the private detail the authenticated view shows (see
the component's own doc comment, lines 24-29).
Despite being the actual enforcement point for that privacy boundary, neither file has a test:
there is no snapshot-replay.test.ts next to the lib module and no snapshot-replay.test.tsx next to
the component (confirmed — no file matches either name anywhere under apps/loopover-ui/src, and
neither buildSnapshotReplayView nor SnapshotReplayCard/SnapshotReplay is referenced from any
*.test.ts* file in the repo). This is the kind of logic this repo otherwise tests heavily elsewhere
— e.g. apps/loopover-ui/src/lib/config-generator-yaml.test.ts,
apps/loopover-ui/src/lib/registration-workspace.test.ts — and the module's own header explicitly
calls out that it's "intentionally standalone (no imports) so it can be unit-tested directly," which
never actually happened.
Requirements
- Add
apps/loopover-ui/src/lib/snapshot-replay.test.ts covering buildSnapshotReplayView's pure
logic, in particular:
viewer: "public" strips reason/facts/assumptions from every counterfactual alternative and
sets withheldPrivateFields to ["counterfactual_detail"] when any alternative actually carried
private detail, and to [] when none did.
viewer: "authenticated" passes counterfactuals through unchanged with withheldPrivateFields: [].
- Malformed/missing
snapshot (not a record) returns the "missing" status view.
- Missing
snapshot.provenance returns the "missing" status view but still carries through
snapshotId/actionType/target/generatedAt that were present on the snapshot itself.
status is "stale" when freshness !== "fresh", evidenceComplete === false, or
evidenceGaps is non-empty (and "populated" when none of those hold) — test each trigger
independently and the "all clear" case.
readCounterfactuals filters to the matching target.repoFullName (case-insensitively, per
sameRepo) when one is present, and keeps all entries when targetRepoFullName is null.
- Unknown/invalid
confidence and freshness string values narrow to "unknown" rather than
passing through arbitrary strings.
- Add
apps/loopover-ui/src/components/site/snapshot-replay.test.tsx covering:
<SnapshotReplayCard> defaults to the "authenticated" view and switching the toggle to
"public" renders the publicSafe view's content, not the authenticated view's — assert a
private-only string (e.g. a reason) present in the authenticated fixture is absent from the
rendered DOM after toggling to public.
<SnapshotReplay view={...}> with status: "missing" renders only the notice, none of the detail
sections.
- The
withheldPrivateFields footer note only renders when the array is non-empty.
Deliverables
Test Coverage Requirements
apps/** is outside this repo's Codecov coverage.include (vitest.config.ts / codecov.yml's
ignore: ["apps/**", ...]), so this change owes no Codecov patch-coverage percentage — but that's
exactly why this gap existed undetected. Aim for genuine branch coverage of every conditional listed
in Requirements (both sides of each ? :/??/|| in buildSnapshotReplayView,
projectCounterfactuals, and resolveRegistrationWorkspaceFreshness-style staleness triggers), not
just line coverage. Run npx vitest run apps/loopover-ui/src/lib/snapshot-replay.test.ts apps/loopover-ui/src/components/site/snapshot-replay.test.tsx while iterating, and npm run ui:test
before opening the PR.
Expected Outcome
The public/authenticated privacy boundary this module exists to enforce has a real regression test
suite, so a future change to projectCounterfactuals or the component's viewer toggle that
accidentally leaked private reason/facts/assumptions text into the public view would be caught
by CI instead of only by manual review.
Links & Resources
apps/loopover-ui/src/lib/snapshot-replay.ts (the view-model module to test)
apps/loopover-ui/src/components/site/snapshot-replay.tsx (the component to test)
apps/loopover-ui/src/routes/app.runs.tsx (the real call site)
apps/loopover-ui/src/lib/registration-workspace.ts and its
registration-workspace.test.ts for this repo's existing pattern of testing a similar
payload-to-view-model + public-safe-sanitization module
Context
apps/loopover-ui/src/lib/snapshot-replay.tsbuilds the "decision snapshot replay" view model (issue#285) used by
apps/loopover-ui/src/components/site/snapshot-replay.tsx's<SnapshotReplayCard>/<SnapshotReplay>(wired intoapps/loopover-ui/src/routes/app.runs.tsx). Its whole job is a privacyboundary:
buildSnapshotReplayView({ viewer, snapshot, counterfactuals })takes aviewer: "public" | "authenticated"and, for"public", stripsreason/facts/assumptionsoffevery counterfactual alternative via
projectCounterfactuals()(lines 195-213), replacing them withnull/[]and recording what was withheld inwithheldPrivateFields. The component then renders anexplicit audience toggle (
<SnapshotReplayCard authenticated publicSafe>) specifically so a reviewercan visually confirm the public view never leaks the private detail the authenticated view shows (see
the component's own doc comment, lines 24-29).
Despite being the actual enforcement point for that privacy boundary, neither file has a test:
there is no
snapshot-replay.test.tsnext to the lib module and nosnapshot-replay.test.tsxnext tothe component (confirmed — no file matches either name anywhere under
apps/loopover-ui/src, andneither
buildSnapshotReplayViewnorSnapshotReplayCard/SnapshotReplayis referenced from any*.test.ts*file in the repo). This is the kind of logic this repo otherwise tests heavily elsewhere— e.g.
apps/loopover-ui/src/lib/config-generator-yaml.test.ts,apps/loopover-ui/src/lib/registration-workspace.test.ts— and the module's own header explicitlycalls out that it's "intentionally standalone (no imports) so it can be unit-tested directly," which
never actually happened.
Requirements
apps/loopover-ui/src/lib/snapshot-replay.test.tscoveringbuildSnapshotReplayView's purelogic, in particular:
viewer: "public"stripsreason/facts/assumptionsfrom every counterfactual alternative andsets
withheldPrivateFieldsto["counterfactual_detail"]when any alternative actually carriedprivate detail, and to
[]when none did.viewer: "authenticated"passes counterfactuals through unchanged withwithheldPrivateFields: [].snapshot(not a record) returns the"missing"status view.snapshot.provenancereturns the"missing"status view but still carries throughsnapshotId/actionType/target/generatedAtthat were present on the snapshot itself.statusis"stale"whenfreshness !== "fresh",evidenceComplete === false, orevidenceGapsis non-empty (and"populated"when none of those hold) — test each triggerindependently and the "all clear" case.
readCounterfactualsfilters to the matchingtarget.repoFullName(case-insensitively, persameRepo) when one is present, and keeps all entries whentargetRepoFullNameis null.confidenceandfreshnessstring values narrow to"unknown"rather thanpassing through arbitrary strings.
apps/loopover-ui/src/components/site/snapshot-replay.test.tsxcovering:<SnapshotReplayCard>defaults to the"authenticated"view and switching the toggle to"public"renders thepublicSafeview's content, not theauthenticatedview's — assert aprivate-only string (e.g. a
reason) present in the authenticated fixture is absent from therendered DOM after toggling to public.
<SnapshotReplay view={...}>withstatus: "missing"renders only the notice, none of the detailsections.
withheldPrivateFieldsfooter note only renders when the array is non-empty.Deliverables
apps/loopover-ui/src/lib/snapshot-replay.test.tswith the coverage listed above.apps/loopover-ui/src/components/site/snapshot-replay.test.tsxwith the coverage listed above.Test Coverage Requirements
apps/**is outside this repo's Codecovcoverage.include(vitest.config.ts/codecov.yml'signore: ["apps/**", ...]), so this change owes no Codecov patch-coverage percentage — but that'sexactly why this gap existed undetected. Aim for genuine branch coverage of every conditional listed
in Requirements (both sides of each
? :/??/||inbuildSnapshotReplayView,projectCounterfactuals, andresolveRegistrationWorkspaceFreshness-style staleness triggers), notjust line coverage. Run
npx vitest run apps/loopover-ui/src/lib/snapshot-replay.test.ts apps/loopover-ui/src/components/site/snapshot-replay.test.tsxwhile iterating, andnpm run ui:testbefore opening the PR.
Expected Outcome
The public/authenticated privacy boundary this module exists to enforce has a real regression test
suite, so a future change to
projectCounterfactualsor the component's viewer toggle thataccidentally leaked private
reason/facts/assumptionstext into the public view would be caughtby CI instead of only by manual review.
Links & Resources
apps/loopover-ui/src/lib/snapshot-replay.ts(the view-model module to test)apps/loopover-ui/src/components/site/snapshot-replay.tsx(the component to test)apps/loopover-ui/src/routes/app.runs.tsx(the real call site)apps/loopover-ui/src/lib/registration-workspace.tsand itsregistration-workspace.test.tsfor this repo's existing pattern of testing a similarpayload-to-view-model + public-safe-sanitization module