docs(phase-16): draft anonId privacy-note copy; note deferred Postgres integration harness
This commit is contained in:
@@ -152,6 +152,7 @@ A small set of items that are real but don't fit a phase yet. Surface them when
|
||||
- **Identity / accounts.** Currently no user concept. Needed before web upload (2.4); also a precondition for favourites, listening history, per-user playlists. Decide the shape before any of those lands. `[speculative]` until Daniel signals interest.
|
||||
- **`ITrackService` interface.** Audit-suggested. Low value today (one consumer pair); higher value when the test surface expands beyond FileDatabase.
|
||||
- **Test coverage outside FileDatabase.** Tests today cover the FileDatabase subsystem comprehensively and nothing else. As features in Phases 1–4 land, test scope should expand — at minimum `WavOffsetService`, `AudioProcessor`, `TrackService` (both sides), and the streaming player services. Not a phase of its own; an attached cost to feature work.
|
||||
- *Real-Postgres integration harness (deferred per Daniel — big lift).* The Phase 16 distinct-listener aggregation LINQ (`EventRepository.CountDistinctListenersAsync` / `...ForTrackAsync` / `...ForReleaseAsync`) is currently exercised only against the EF in-memory provider, which does not validate real Npgsql SQL translation — the distinct-count queries want translation verification against an actual Postgres instance. More broadly, an integration-test harness against a real Postgres is the deferred prerequisite for trusting any non-trivial LINQ across the EF surface. **Explicitly deferred by Daniel (big lift); a note for now, not committed work — no timeline.**
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
# Phase 16 — Privacy-Note Copy (DRAFT — awaiting Daniel sign-off)
|
||||
|
||||
Status: **DRAFT — NOT FINAL. Awaiting Daniel's sign-off on (a) wording and (b) placement.** Author:
|
||||
product-designer. Date: 2026-06-19. Surface: **public site only** (`DeepDrftPublic` /
|
||||
`DeepDrftPublic.Client`). **No code, no shipped copy** — this is a copy draft for review.
|
||||
|
||||
This note drafts the short privacy line that `phase-16-play-share-tracking.md` **§3 (Option A,
|
||||
RESOLVED D5)** explicitly calls for: *"a short privacy-note line rather than a cookie wall."* It
|
||||
explains, in plain language, the anonymous first-party `anonId` token minted in wave 16.3.
|
||||
|
||||
## What the copy has to be honest about (from the spec §3)
|
||||
|
||||
The line must be accurate to the actual mechanism — no more, no less:
|
||||
|
||||
- A **random, first-party** token kept in this browser (`localStorage`), minted on first visit.
|
||||
- **No accounts, no personal data, no names, no email** — there is no identity model behind it.
|
||||
- **No cross-site tracking, no fingerprinting** — it never leaves as anything but an opaque token, and
|
||||
a third-party embed cannot read it (storage is partitioned).
|
||||
- **Listener-clearable** at any time (clear site data) — and clearing it simply mints a new one.
|
||||
- Used **only** to estimate *how many* listeners a track or release reached, in aggregate — never
|
||||
*who*. We label the number "listeners," not "people," because it over-counts by design (phone +
|
||||
laptop = two).
|
||||
|
||||
Voice target: the DeepDrft collective wrote this. Smart, plain, a little dry. No "we value your
|
||||
privacy," no "your trust matters to us," no marketing reassurance theatre. State the mechanism and
|
||||
stop. The honesty *is* the reassurance.
|
||||
|
||||
---
|
||||
|
||||
## Copy variants (pick one, or splice)
|
||||
|
||||
### Variant 1 — "the plain mechanism" (recommended)
|
||||
|
||||
> We keep a random tag in your browser so we can count how many people a track reaches — not who they
|
||||
> are. No account, no name, nothing personal, nothing shared with anyone else. Clear your browser data
|
||||
> and the tag's gone.
|
||||
|
||||
**Why this one:** it leads with the mechanism ("a random tag in your browser"), names the exact limit
|
||||
("how many people... not who they are"), and closes on the listener's control. Reads like a person
|
||||
explaining a thing, not a policy. Shortest honest version that covers all five facts.
|
||||
|
||||
### Variant 2 — "the counter framing" (matches the 90s-hit-counter vibe)
|
||||
|
||||
> The play counter works off a random tag stored in your browser — enough to tell that a listen is a
|
||||
> distinct one, never enough to tell who you are. No login, no personal data, no tracking across other
|
||||
> sites. It's yours to clear whenever you like.
|
||||
|
||||
**Why this one:** ties the note directly to the Plays card it explains ("the play counter works
|
||||
off..."), which reads well if the line lives near the home stats. Slightly longer; "distinct one"
|
||||
nods honestly at the approximate-count nature.
|
||||
|
||||
### Variant 3 — "the one-liner" (footer-scale)
|
||||
|
||||
> We count listens with a random, anonymous tag in your browser — how many, never who. No accounts, no
|
||||
> cross-site tracking. Clear it any time.
|
||||
|
||||
**Why this one:** tightest. Fits a single footer line or a caption. Drops the explanatory rhythm of
|
||||
1 and 2 for density — best where space is the constraint and a fuller line would look heavy.
|
||||
|
||||
### Variant 4 — "the editorial aside" (for the /about page treatment)
|
||||
|
||||
> A note on the numbers: the play and listener counts you see run on a random tag we keep in your
|
||||
> browser — no account, no name, nothing that says who you are, nothing handed to anyone else. It tells
|
||||
> us a track reached *some number of* listeners, not which ones. Clear your site data and you're a
|
||||
> fresh tag; we'd never know the difference.
|
||||
|
||||
**Why this one:** written to sit inside the About page's editorial prose voice (the "Liner Notes"
|
||||
register), longer and more conversational. Only appropriate if the line lives on `/about`; too much
|
||||
for a footer.
|
||||
|
||||
---
|
||||
|
||||
## Placement options (also Daniel's call)
|
||||
|
||||
### A. Footer line (site-wide)
|
||||
|
||||
- **Pro:** always reachable, conventional home for a privacy note, set-and-forget, decouples the line
|
||||
from any one feature so it survives card/layout changes.
|
||||
- **Con:** low-salience — nobody reads footers; satisfies the "we disclosed it" bar more than the
|
||||
"listener actually understands" bar. A full sentence can look heavy in a footer; favours Variant 3.
|
||||
|
||||
### B. A line on the `/about` page
|
||||
|
||||
- **Pro:** `/about` is already the collective's voice explaining itself (the "presentation and proof of
|
||||
effort" page); a privacy aside fits its register and reaches the curious reader who'd actually care.
|
||||
Variant 4 was written for exactly this slot.
|
||||
- **Con:** lowest reach — only the fraction who open `/about` see it. Weak as the *sole* disclosure;
|
||||
better as the *expanded* version with a shorter pointer elsewhere.
|
||||
|
||||
### C. A small note near the home stats card
|
||||
|
||||
- **Pro:** highest contextual relevance — it sits right where the listener-count it explains is
|
||||
rendered, so the disclosure lands at the moment the number does. This is the most *honest* placement:
|
||||
you see the count and the "here's how we got it" in the same glance. Variant 2 is tuned for it.
|
||||
- **Con:** real estate is tight by the odometer cards; risks visual clutter on the hero. May need to be
|
||||
a small caption / info-affordance (a quiet "?" or "how we count" toggle) rather than always-on prose.
|
||||
And the card is the wave-16.5 capstone — this placement only exists once the card goes live, which
|
||||
couples the note's ship to the last wave.
|
||||
|
||||
### Recommendation
|
||||
|
||||
**Primary: A (footer line), using Variant 1 or 3 — ship it with the substrate, independent of the
|
||||
capstone card.** A footer line is the lowest-coupling, always-available disclosure and does not wait on
|
||||
the 16.5 card. Because the `anonId` token is minted in **wave 16.3** (already landed on dev), the
|
||||
disclosure arguably *should* exist before the capstone, and the footer is the only placement that
|
||||
doesn't depend on the card being live.
|
||||
|
||||
**Pair it with C (a quiet "how we count" affordance by the home stats) when the capstone card lands in
|
||||
16.5**, using Variant 2 — so the explanation also appears exactly where the number does. B (`/about`)
|
||||
is a nice-to-have third surface for the curious reader (Variant 4), not load-bearing.
|
||||
|
||||
This gives a tiered disclosure: an always-present footer line (legal/ethical floor), a contextual note
|
||||
at the point of display (honesty high-water mark), and an editorial expansion for the reader who wants
|
||||
it — without a cookie wall anywhere, per the spec.
|
||||
|
||||
**One sequencing flag for Daniel:** the token already ships (16.3 landed); the disclosure does not yet
|
||||
exist. If the footer line is the chosen floor, it can land independently of the 16.5 card and arguably
|
||||
should not trail it. Not urgent (first-party, no cross-site tracking, clearable — the lightest-touch
|
||||
case under GDPR/ePrivacy per spec §3), but worth a deliberate call rather than letting it ride to the
|
||||
capstone by default.
|
||||
|
||||
---
|
||||
|
||||
## What this note is NOT
|
||||
|
||||
- Not a privacy policy. If a full policy page is ever wanted, that is a separate, larger artifact — this
|
||||
line is the privacy-light disclosure the spec asked for, not a legal document.
|
||||
- Not a consent mechanism. Per spec §3 (D5), a random first-party id used for first-party aggregate
|
||||
counts is the lightest-touch case and is **deliberately not** behind a banner or wall. This note
|
||||
*informs*; it does not *gate*.
|
||||
- Not final. **Every variant above is a draft pending Daniel's wording sign-off and placement pick.**
|
||||
Reference in New Issue
Block a user