Privacy Policy and Data Inventory
Version 2026-09-08.1
Effective September 8, 2026 · Technical inventory verified September 4, 2026
Publisher and privacy-request channel
PlaySolitaire.io is published by MB „NM Media“. A contact form at /contact delivers messages to the operator's mailbox once the deployment's SMTP transport and destination settings are configured; the release gate requires this notice and that configuration to stay consistent, and live delivery is confirmed during release acceptance. The form is a general contact channel. No verified privacy-request channel with a tracked response workflow is currently configured: an operator and counsel must establish and verify that workflow and the required public wording before this notice can advertise that privacy requests may be submitted. The complete controller identity/address, jurisdiction-specific legal bases, rights wording and response deadlines also remain unverified.
Current data practices
The entries below disclose the fields, purpose, provider, activation condition, retention, deletion path and transfer status observed in the current application.
On-device game and preference data
Saved games
Active- Technology / records
localStorage · solitaire:game:v1 · playsolitaire:game:draw2:v1 · playsolitaire:game:freecell:v1 · playsolitaire:game:spider:v1 · playsolitaire:game:daily:v1 · playsolitaire:game:turn3:v1 · playsolitaire:game:turn3-legacy:v1 · playsolitaire:game:spider2:v1 · playsolitaire:game:spider4:v1 · playsolitaire:game:golf:v1 · playsolitaire:game:yukon:v1 · playsolitaire:game:russian:v1 · playsolitaire:game:alaska:v1 · playsolitaire:game:pyramid:v1 · playsolitaire:game:tripeaks:v1 · playsolitaire:game:scorpion:v1 · playsolitaire:game:wasp:v1 · playsolitaire:game:fortythieves:v1 · playsolitaire:game:crescent:v1 · playsolitaire:game:canfield:v1 · playsolitaire:game:eightoff:v1 · playsolitaire:save-envelope:v2:* · playsolitaire:save-quarantine:v2:* · playsolitaire:save-exit:v1:* · sessionStorage: playsolitaire:save-exit-owner:v1- Provider
- Your browser (first-party storage)
- When it activates
- Each non-demo game writes a rollback-compatible raw record plus a validated versioned sidecar. When a dirty page is hidden or closed, it first stages one local page-exit snapshot before the same checked dual writer runs. A later load resumes that snapshot only through its exact predecessor checkpoint, or uses the existing cross-tab conflict recovery if another tab advanced first. Unsupported or damaged records are marked in local quarantine, writes to that game slot stop, and automatic recovery restores a compatible copy or removes an unusable pair before reloading.
- Fields
- game variant and rules mode
- deal seed or FreeCell deal number
- card positions, stock, waste, foundations and other variant-specific piles
- move count, status, start time and final time when won
- full undo history, with a quota fallback that keeps the latest 20 entries or removes the history while retaining the current board
- daily date key or onboarding metadata when applicable
- save format version, rules version, monotonic revision and update time
- pseudonymous deal and attempt identifiers derived from the game slot, seed, rules and start time
- a bounded pending-replacement journal containing predecessor lifecycle summaries (variant/mode, finite first-action category, status, move/final totals and pseudonymous identifiers), plus a crash-completion marker while the rollback copy catches up
- one temporary page-exit snapshot per document for the game slot, its creation time, a session-scoped opaque document owner identifier, an opaque random per-stage journal generation identifier, its expected revision and non-cryptographic hashes of the predecessor records; if storage quota rejects the full snapshot, undo history is reduced to the latest 20 entries or removed while the current board is retained
- quarantine reason, detection time, record size and a non-cryptographic diagnostic hash (the damaged record remains in its original key until recovery)
- Purpose
- Resume the current game
- Undo moves
- Restore the requested variant and deal
- Preserve the latest move when a page exits while another tab holds the save lock
- Validate migrations and preserve rollback compatibility
- Prevent damaged, newer or conflicting cross-tab records from overwriting a known-good compatible copy
- Retention
- Compatible save pairs remain until replaced by another save for that game or until you clear site data. The document owner identifier remains for the tab/session. Each page-exit snapshot is removed after that state is durably accepted or its conflict is resolved; an invalid or abandoned snapshot can remain until a later load cleans it up or until you clear site data. Automatic recovery normally clears a quarantine marker immediately; if browser storage rejects that update, the marker remains until a retry succeeds or you clear site data.
- Deletion / control
- Automatic recovery keeps a valid compatible copy when one exists; otherwise it removes the unusable slot and starts fresh. If browser storage rejects the repair, use Try again or clear site data in your browser.
- Transfer
- After account creation or sign-in, a validated board copy can be sent automatically to the first-party account API from a durably fenced import while the guest copy is still authoritative. A valid exact-predecessor page-exit snapshot may supply that board copy, but full undo history, onboarding state, the journal identifier and record, predecessor hashes, and quarantine metadata remain in the browser. The account namespace activates only after the final receipt and local activation state are durable, and a guest namespace already linked to another account is not sent again. (verified in source code)
- Verification
-
- All legacy keys, versioned sidecars, central dual writes, quarantine blocks and automatic recovery were traced. (verified in source code)
- Legal-review status
- The bounded account-transfer behavior is verified in code and the factual disclosure is owner-accepted for launch. This technical inventory is not legal advice or a claim of counsel approval.
Settings and interface preferences
Active- Technology / records
localStorage · solitaire:settings:v3 · solitaire:customThemeVars:v1 · sd-hint-1tap-seen · playsolitaire:hintDebug · solitaire:whatsNew:v1- Provider
- Your browser (first-party storage)
- When it activates
- The main settings and theme cache are written when settings change, and the one-tap flag is written when its instructional hint is acknowledged. The hint-debug flag is only read when someone manually places the value 1 in browser storage. The what’s-new marker is written when the updates page is visited or its menu indicator is shown or expires.
- Fields
- theme and custom palette values
- card and text size
- sound, motion, contrast and control preferences
- Klondike draw/winnable-deal settings and FreeCell settings
- whether the one-tap hint was already shown
- whether manually requested hint decisions should be logged to the browser console
- which product-update announcement was last acknowledged and on which days its indicator appeared
- Purpose
- Restore the interface you selected
- Avoid repeating an introductory hint
- Enable local hint diagnostics when manually requested
- Retention
- The main settings record and theme cache remain until replaced or reset. The one-tap-seen and manually supplied hint-debug flags remain until individually removed or all site data is cleared; the in-game reset does not delete those auxiliary flags.
- Deletion / control
- The in-game reset restores the main settings and theme cache to defaults but does not delete the one-tap-seen or hint-debug flags. Clear site data in your browser to remove every record listed here.
- Transfer
- After account creation or sign-in, the documented gameplay and accessibility preference subset, including card size, can be uploaded automatically to the account API from the durably fenced guest import before the account browser namespace activates. The guest namespace remains authoritative until the final durable receipt and local activation state are stored. A guest namespace already linked to another account is not sent again. Consent, experiments, PWA state, hint state and shuffle history remain device-only. In the current bounded implementation, after a setting is successfully committed, a separate consent-gated GA4 event may report its name and a finite category; custom colours report only an edited-slot category. (verified in source code)
- Verification
-
- Settings, pre-paint restoration, and hint acknowledgement writes were traced. (verified in source code)
- Legal-review status
- The purpose statement is code-verified; the legal classification of each preference is pending counsel review.
Local progress and statistics
Active- Technology / records
localStorage · IndexedDB database: playsolitaire-progress · playsolitaire:stats:v1 · playsolitaire:daily:v1 · playsolitaire:daily:challenge:v1 · playsolitaire:recentlyPlayed:v1 · solitaire:timer:v1 and variant-scoped timer keys · sessionStorage: playsolitaire:timer-exit:v1:* · localStorage capability probe: playsolitaire:daily:probe- Provider
- Your browser (first-party storage)
- When it activates
- On the first meaningful action, the legacy localStorage statistics and daily records are frozen as an immutable historical baseline in IndexedDB and a unique methodology-v2 start event is appended. One terminal event may then be appended for that attempt. Challenge links, clocks and recent games continue to use their listed localStorage records. When a game page exits, the clock writes one tab-scoped checkpoint for that save slot so same-tab navigation cannot add time spent on another page. The daily gate writes and removes its probe before using localStorage so it can detect whether durable local progress is available.
- Fields
- per-variant games played, wins, streaks, best time and fewest moves
- historical localStorage aggregate snapshots, retained as a baseline and no longer mutated by methodology v2
- pseudonymous attempt, deal and event identifiers derived from the game slot, rules, deal and start time
- append-only start and terminal events with variant/mode, first-action category, outcome, move count and elapsed-time summary
- daily date, streak, completion, time and moves
- incoming daily challenge date, challenger target time and challenger move count
- recent game identifiers and timestamps (maximum eight)
- played-time snapshot keyed to the current game start
- tab-scoped exit checkpoint containing the active browser namespace, game-save slot, attempt identifier, start identifier and elapsed time
- temporary value used only to test whether localStorage can be written
- Purpose
- Show local records and daily progress
- Restore the played-time clock
- Show recently played games
- Test localStorage availability before writing durable daily progress
- Retention
- The historical baseline and append-only progress events remain until you clear this site’s browser data; methodology-v2 events are not overwritten or calendar-expired. Other progress records remain until overwritten by newer records or site data is cleared. Each tab-scoped timer-exit checkpoint is overwritten by a later exit from the same game slot and disappears when that tab session ends. The daily storage-capability probe is written and synchronously removed during its check.
- Deletion / control
- Clear site data in your browser.
- Transfer
- After account creation or sign-in, the first-party account API can automatically receive a cumulative lifetime/daily projection of the verified local event ledger, up to eight recent game keys, and the elapsed-time value stored with each synchronized current or saved game. This durably fenced import may transfer before the account browser namespace activates; the guest copy remains authoritative until the final receipt and local activation state are stored. New automatic handoffs leave raw progress events in the guest browser namespace and retain only the bounded cumulative projection. A guest namespace already linked to another account is not sent again. Ongoing synchronization likewise retains only the latest cumulative rollup, event count and hash-chain checkpoint per browser namespace. A frozen legacy import that was already staged by an older release may retain up to 10,000 validated immutable raw progress events until the account is deleted. Daily challenge links and the browser timer records themselves remain device-only. Consent-gated analytics are disclosed under GA4. (verified in source code)
- Verification
-
- Each local record shape and writer was traced. (verified in source code)
- Legal-review status
- The technical separation between local records and analytics is verified; legal-basis wording is pending counsel review.
Optional account synchronization queue
Active- Technology / records
IndexedDB database: playsolitaire-account-sync · stores: meta, queue, receipts, imports and snapshots · localStorage sentinel: playsolitaire:guest-import-fence:v1 · per-account localStorage namespace: playsolitaire:account-space:v1:* · sessionStorage: playsolitaire:account:modal-return:v1 (ten-minute exact-page OAuth popup return intent) · per-account progress stores in IndexedDB database: playsolitaire-progress- Provider
- Your browser (first-party storage)
- When it activates
- This database is opened only by the optional account client. During the private account handoff after account creation or sign-in, the client automatically prepares existing guest progress while the guest namespace remains selected. Every non-account route holds a shared browser lock before hydration because it can mount a settings or game-state writer; preparation requires the exclusive lock. A game tab releases its shared lock after activating its isolated account namespace. The optional identity timeout cannot release hydration before the shared lock is held and the guest-write fence has been checked. If preparation returns a retry before any transfer sentinel exists, a confirmed login may return to ordinary local play; cloud synchronization waits for a later successful preparation, and the destination rechecks the durable fence before guest writers hydrate. Before the first import request, the client writes and verifies a synchronous device sentinel, then atomically stores the complete frozen draft and a versioned guest-write fence. In production, a new fence also requires the active controlling service worker to answer guest-state protocol version 1 with no unsafe older client. A successfully read absent sentinel lets ordinary account-free startup continue without opening this database. A present, malformed or unreadable sentinel must be reconciled against the IndexedDB fence and otherwise fails closed. Once fenced, a non-account route cannot hydrate guest writers: it must resume the exact import or redirect to the private account handoff and remain stopped. The frozen import can be transferred before activation. A successful final receipt, revision snapshot and imported fingerprints are stored before the account binding activates atomically with fence removal; the sentinel is reconciled only after that commit. A blocked or incoherent browser-storage read, unavailable lock, active guest-writing tab, service-worker mismatch, offline state or retryable failure leaves guest records untouched. If another account already claimed that guest namespace, it is not uploaded again and the signed-in account opens in its clean, isolated namespace. An exact successful server stage receipt can repair a neutral unavailable local ownership marker for the rightful authenticated account; ordinary local claims cannot.
- Fields
- random guest namespace and operation identifiers
- one random browser-state namespace identifier per signed-in account
- signed-in account identifier and pending, active or legacy deferred device-binding state
- bounded unsent or sealed synchronization commands without undo or onboarding history
- versioned guest-write fence and matching synchronous crash sentinel, server import identifier, highest acknowledged import-item sequence and finalize-attempt time
- account, settings, profile and per-game revision checkpoints
- a bounded per-game timer authority record while a validated cloud board replaces the prior local board
- validated account snapshot cache plus stable synchronization, guest-import and account-deletion receipts
- one same-tab, exact-page OAuth error return intent containing only the internal return path and bounded popup/error kinds
- retry count, next-attempt time, transient bounded Retry-After delay, and local creation or acknowledgement time
- Purpose
- Save gameplay locally before a network request
- Prevent guest writers after an import freeze
- Resume an interrupted import after its highest acknowledged item without rebuilding it
- Retry an ambiguous request with the same idempotency key
- Return an OAuth failure to the exact game and reopen the relevant account popup without changing that URL
- Keep guest and per-account games, progress, settings and recent-game records isolated
- Prevent one signed-in account from receiving another account’s queued data
- Remember which account already claimed a guest namespace on this browser
- Retention
- The queue is bounded to 128 records per account and streams larger progress histories only after each prior batch is acknowledged. A frozen import keeps its fence, synchronous sentinel, exact manifest, highest acknowledged item and finalize-attempt marker until activation removes the fence and draft atomically, then reconciles the sentinel. Accepted synchronization commands leave the queue after a matching receipt is stored. The timer authority journal is one replaceable record per game slot and is cleared when that slot advances to another local game. The OAuth popup return intent is consumed once on the exact page, expires after ten minutes, and also disappears when the tab/session ends. Guest records and each account namespace remain separate until this site’s browser data is cleared.
- Deletion / control
- Clear this site’s browser data. Deleting the server account removes only that account’s local binding, import draft, fence and ownership marker, then reconciles the sentinel from any remaining fence; unrelated guest saves remain on the device.
- Transfer
- The frozen guest-import manifest and items can be sent to the same-origin account API after the durable write fence is stored but before the browser binding becomes active. The guest namespace remains authoritative during that transfer. After activation, only sealed synchronization commands are sent. The synchronous fence sentinel remains on the device; the fence, acknowledged-item cursor, finalize-attempt marker, queue metadata and retry timing remain in IndexedDB. (verified in source code)
- Verification
-
- The durable import fence/cursor, account namespace boundary, service-worker protocol gate, idempotent retry and receipt-gated activation were traced. (verified in source code)
- Legal-review status
- The factual queue and transfer disclosure is owner-accepted for launch. This technical inventory is not legal advice or a claim of counsel approval.
PWA install offer state
Active- Technology / records
localStorage · playsolitaire:pwaInstallOffer:v2 · beforeinstallprompt and appinstalled browser events- Provider
- Your browser (first-party storage)
- When it activates
- After EXP-3 settled on the install-chip treatment, the contextual offer is the shared product behavior on eligible free Klondike and Turn 3 pages. A valid browser install-prompt event is intercepted only after the prompt-state record can be written and read back; storage denial, failed readback, malformed events, installed display modes and excluded pages retain browser-default behavior. The state is updated for the bounded win-count fallback, first offer eligibility, explicit dismissal and a dismissed native prompt outcome. Daily games and other variants do not show the offer.
- Fields
- record version and product-state creation timestamp
- install-offer snooze-until timestamp after explicit or native dismissal
- at most two distinct pseudonymous credited-attempt identifiers when lifetime Klondike statistics cannot be read
- first offer-eligible timestamp used to avoid reporting the eligibility stage twice
- Purpose
- Offer installation only after two credited Klondike wins
- Honor the 14-day dismissal period without falling back to native promotion
- Keep eligibility and dismissal behavior stable across page loads and tabs
- Avoid duplicate install-offer eligibility reporting across page loads
- Retention
- The product record remains until you clear site data. An explicit or native dismissal suppresses the offer for 14 days. The record stores at most two fallback attempt identifiers and one first-eligible timestamp; later writes merge these bounded fields rather than growing an activity history.
- Deletion / control
- Clear this site’s browser data.
- Transfer
- The creation, snooze and eligibility timestamps and fallback attempt identifiers remain on-device. After analytics consent, separate bounded GA4 events can send the Klondike mode, install-offer stage and finite prompt outcome without an experiment arm; the local timestamps and attempt identifiers are never sent. (verified in source code)
- Verification
-
- Eligibility, fail-open prompt interception, EXP-3 state migration, two-win fallback, cross-tab convergence and snooze are registered to one browser-state writer. (verified in source code)
- Legal-review status
- The local/consent-gated technical separation is code-verified; product-state necessity, proportionality and analytics-consent wording remain pending counsel review.
First-game continuity record
Active- Technology / records
localStorage · playsolitaire:firstGame:v2 · sessionStorage: playsolitaire:firstGame:pagehide:v1 · localStorage capability probe: playsolitaire:firstGame:probe · sessionStorage capability probe: playsolitaire:firstGame:sessionProbe · first-party cookie: ps_first_game (fallback only)- Provider
- Your browser and the PlaySolitaire origin for the fallback cookie
- When it activates
- The storage probes run before first-game assignment to test localStorage and sessionStorage availability. The continuity record is then created for first-game assignment, a short-lived session marker is written on pagehide when sessionStorage works, and the fallback cookie is used only when the localStorage probe fails.
- Fields
- random assignment identifier
- variant and draw mode
- golden-deal flag, optional seed, pool index and pool version
- reserved/started/won/abandoned status
- first-seen, start, end and return timestamps
- analytics-sent flags
- move and played-time summaries in localStorage only (omitted from the fallback cookie)
- pagehide refresh marker containing the assignment identifier and pending-session end time in sessionStorage
- temporary values used only to test whether localStorage and sessionStorage can be written
- Purpose
- Keep the first-game assignment and lifecycle idempotent across refreshes
- Distinguish an immediate refresh from an abandoned session
- Avoid duplicate first-session analytics
- Test storage availability and decide whether the fallback cookie is required
- Retention
- The localStorage record has no calendar expiry. The sessionStorage refresh marker is cleared after a matching refresh or when the tab/session ends. Each storage-capability probe is written and synchronously removed during its check. The fallback cookie has a maximum age of 365 days. These records also disappear when you clear the relevant browser data.
- Deletion / control
- Clear this site’s local storage, session storage and cookies.
- Transfer
- The ps_first_game fallback cookie is sent in the Cookie header on same-site requests and therefore traverses Bunny CDN and the Hostinger origin as disclosed under site delivery. The localStorage record and sessionStorage refresh marker remain on-device. (verified in source code)
- Verification
-
- Record fields, sessionStorage refresh marker, cookie compaction and registry-fixed Secure/Lax 365-day maximum age were traced. (verified in source code)
- Legal-review status
- Whether the fallback cookie qualifies as strictly necessary in each jurisdiction is pending counsel review.
Analytics consent and opt-out choices
Active- Technology / records
localStorage: ps:consent:v1 · localStorage: ps:optout:v1 · sessionStorage: ps:analytics-denied:session:v1 · first-party cookie: ps_analytics_denied · BroadcastChannel: playsolitaire:privacy:v1- Provider
- Your browser and the PlaySolitaire origin
- When it activates
- Read on every page. Written when you accept, reject, or use the analytics opt-out control.
- Fields
- analytics allowed/denied
- decision timestamp
- whether a non-GDPR geo result supplied an implied acceptance
- opt-out/denial flags
- Purpose
- Enforce your analytics choice
- Make rejection win across tabs and page reloads
- Retention
- The localStorage choice lasts until changed or cleared. The denial cookie has a maximum age of 365 days. The session flag ends with the browser tab/session.
- Deletion / control
- Change the choice through Cookie settings or the analytics opt-out page, or clear site data. Withdrawing consent also clears GA and Hotjar cookies that are visible to the site.
- Transfer
- The ps_analytics_denied cookie is sent in the Cookie header on same-site requests and therefore traverses Bunny CDN and the Hostinger origin as disclosed under site delivery. The consent script calls the first-party /api/geo endpoint without browser credentials when no choice exists. (verified in source code)
- Verification
-
- The denial-dominant state machine, registry-fixed cookie value/retention/security, storage and cross-tab paths were tested. (verified in source code)
- Legal-review status
- Regional consent requirements and any lawful basis for non-consented operational processing are pending counsel review.
Transient analytics-decision event queues
Active- Technology / records
in-memory JavaScript eventQueue · in-memory JavaScript pwaEventQueue- Provider
- Your browser memory before an analytics decision; Google only after the state resolves to granted
- When it activates
- An attempted GA4 or PWA event is held in memory when the analytics decision is still unknown or the consented Google tag has not finished loading.
- Fields
- queued event name
- queued event parameters from the gameplay, settings, first-game, CTA, sharing, video and PWA fields disclosed under Google Analytics
- temporary PWA session-tracked flag
- Purpose
- Wait for the privacy decision before sending
- Preserve event order while the consented Google tag loads
- Prevent duplicate PWA session reporting
- Retention
- Memory only until the decision/navigation ends: denial clears both queues immediately; grant flushes queued events to GA4 and removes them from the arrays; a page unload discards remaining memory.
- Deletion / control
- Reject or withdraw analytics to clear the queues immediately, or leave/reload the page to discard page memory.
- Transfer
- No queued event is transferred while the decision remains unknown. If the decision becomes granted, queued fields are sent to Google under the GA4 entry; denial discards them without that transfer. (verified in source code)
- Verification
-
- Unknown, denied, granted, flush and page-lifetime queue paths were traced. (verified in source code)
- Legal-review status
- The pre-decision memory behavior is code-verified; any legal classification of transient in-memory processing remains pending counsel review.
Temporary content-to-game attribution
Active- Technology / records
sessionStorage: playsolitaire:content-origin:v1 · Web Crypto getRandomValues- Provider
- Your browser (first-party session storage)
- When it activates
- Written only after analytics consent is currently granted and you use a trusted, unmodified, same-tab play link whose source, destination and analytics labels exactly match the English content registry on the production site. Staging, automated browsers, unknown consent, downloads, new-tab links and links with a query or fragment never create the record.
- Fields
- record version v (fixed at 1)
- content_origin_id (the bounded source content identifier)
- origin_cta_id (the bounded source link identifier)
- content_origin_locale
- target_game (the canonical intended playable-content identifier)
- origin_click_id (ps_o_ plus 16 lowercase hexadecimal characters generated with Web Crypto)
- clicked_at_ms (the local click time in milliseconds)
- Purpose
- Attribute one consented game start to the exact guide or research play link that led to it
- Reconcile the generic click, dedicated content click and resulting game start without storing a browsing history
- Retention
- The record has a strict 30-minute lifetime. A later eligible click replaces it. A valid game_start consumes and removes it before analytics dispatch. Expired, future-dated, malformed, incompatible, denied-consent and non-production records are ignored and removed; sessionStorage also ends with the tab/session.
- Deletion / control
- Start the linked game, reject or withdraw analytics, wait 30 minutes, close the tab/session, or clear this site’s session data. Each of those paths removes or invalidates the record.
- Transfer
- The sessionStorage record itself remains on-device. When a valid record is consumed with analytics still granted, its bounded identifiers are copied into the consent-gated GA4 click and game_start fields disclosed below; clicked_at_ms is never sent. (verified in source code)
- Verification
-
- The exact CTA match, consent/production/trusted-navigation gates, cryptographic click identifier, 30-minute replacement/consumption rules and fail-closed game_start enrichment were traced and tested. (verified in source code)
- Legal-review status
- The bounded technical behavior and consent gate are code-verified; purpose, proportionality and any jurisdiction-specific classification remain pending counsel review.
Legacy compatibility records
Active- Technology / records
localStorage · solitaire:settings:v2 · solitaire:settings:v1 · playsolitaire:firstGame:v1 · solitaire:stats:v2 · solitaire:stats:v1 · solitaire:results:v1 · solitaire:recordedWins:v1 · solitaire:installPrompt:v1 · playsolitaire:consecutiveLosses:v1 · playsolitaire:ab:stats:v1 · playsolitaire:ab:pwaInstall:v1 · playsolitaire:pwaInstallPrompt:v1 · playsolitaire:ab:postWinOverlay:v1 · playsolitaire:ab:gameShell:v1 · playsolitaire:ab:gameShell:v2 · playsolitaire:ab:gameShell:v3 · playsolitaire:ab:gameShell:v4- Provider
- Your browser (first-party storage)
- When it activates
- Older settings/statistics/first-game keys are read only when migrating settings or deciding whether a visitor has prior play history. The settled PWA install experiment arm is never read and the current install-offer module attempts to remove it during initialization. The settled post-win overlay and game-shell v1, v2, v3 and v4 records have no current reader or writer. The registered older install-prompt and consecutive-loss keys also have no current reader or writer.
- Fields
- older settings
- older statistics/results/win markers
- first-game-used flag
- legacy install-prompt and consecutive-loss records if an older release wrote them
- settled personal-best experiment arm (stats or control) if a 2026-07 release assigned one
- settled PWA install experiment arm (install or control) and v1 prompt state until migration cleanup succeeds
- settled post-win overlay arm (clear or shade) if an August or September 2026 release assigned one
- settled game-shell v1, v2, v3 or v4 assignment data, including its version, arm, timestamps, cohort or exclusion reason when an earlier release wrote those fields
- Purpose
- Preserve rollback compatibility
- Avoid treating an existing player as a first-time player
- Disclose registered legacy keys even when the current release has no reader or writer for them
- Retention
- The settled PWA install assignment and v1 prompt state are removed best-effort after the prompt state migrates to the separate v2 product key. Inert post-win overlay assignment records remain until browser data is cleared. Inert game-shell assignment records and other existing values do too.
- Deletion / control
- Clear site data in your browser.
- Transfer
- The compatibility reads do not upload the legacy record contents. (verified in source code)
- Verification
-
- Only migration and prior-play reads remain for these keys. (verified in source code)
- The older install-prompt, consecutive-loss, settled personal-best and post-win overlay experiment keys remain registered without current writers; the retired PWA experiment key has a removal-only owner, and game-shell v1/v2/v3/v4 remain registered without current readers or writers. (verified in source code)
- Legal-review status
- Retention proportionality for legacy values is pending counsel/product review.
Share sheet and clipboard actions
Active only after your interaction- Technology / records
Web Share API (navigator.share) · Clipboard API (navigator.clipboard.writeText) · legacy document.execCommand copy fallback- Provider
- Your browser for clipboard operations; the application or person you choose in the operating-system share sheet for native sharing
- When it activates
- Only after you press a share or copy control. Touch-device result sharing can open the native share sheet; desktop result sharing and deal/guide citation controls copy to the clipboard.
- Fields
- result or challenge text, including applicable game/variant, time, moves, streak or daily result
- PlaySolitaire page, challenge or numbered-deal URL
- FreeCell deal number embedded in a copied URL
- guide/citation text selected by the copy control
- Purpose
- Let you share a result or challenge through a destination you choose
- Copy a deal URL, result, guide snippet or citation for reuse
- Retention
- PlaySolitaire does not retain a separate copy of the shared or copied payload. Clipboard history and a chosen share target may retain it under browser, operating-system or destination controls.
- Deletion / control
- Replace or clear your clipboard using browser/operating-system controls. For native sharing, use the chosen destination’s controls; PlaySolitaire cannot delete a payload after you send it there.
- Transfer
- Clipboard-only actions remain within browser/operating-system clipboard handling. Native sharing transfers the displayed payload only to the application or person you select; PlaySolitaire does not choose or receive that destination. (vendor or contract verification pending)
- Verification
-
- Every native-share and clipboard payload construction path was traced. (verified in source code)
- Clipboard history and selected native-share destination retention depend on the browser, operating system and destination. (vendor or contract verification pending)
- Any required legal wording for user-directed native sharing remains pending counsel review. (counsel review pending)
- Legal-review status
- The code-level user interaction and payload fields are verified; legal characterization of a user-selected destination remains pending counsel review.
Offline and performance caches
Active- Technology / records
Cache Storage · playsolitaire-precache-<service-worker-content-hash> · playsolitaire-runtime-<service-worker-content-hash>- Provider
- Your browser (service worker)
- When it activates
- Created when the service worker installs and as same-origin pages or static assets are requested. Before a production guest import can freeze browser state, the active controlling worker must answer the version-1 guest-state protocol and there must be no waiting replacement worker.
- Fields
- site HTML
- offline page
- card images, fonts, icons and other static assets
- request URL/path needed as the cache key
- fixed guest-state protocol version and an ephemeral request identifier used only for the page/worker readiness exchange
- Purpose
- Provide offline recovery
- Make repeat navigation and static assets faster
- Prevent a guest import from starting under an older or overlapping service-worker protocol generation
- Retention
- Old PlaySolitaire cache versions are deleted when a new service worker activates. The current caches remain until replaced, evicted by the browser, or site data is cleared.
- Deletion / control
- Clear this site’s cached data/service worker storage in your browser.
- Transfer
- Cache Storage remains on-device. API responses and local game-save payloads are not cached by this service worker. (verified in source code)
- Verification
-
- Cache prefixes, allowlist, API bypass, old-version deletion and the guest-state protocol response were traced. (verified in source code)
- Legal-review status
- Any jurisdiction-specific storage disclosure classification is pending counsel review.
Optional account and synchronization
Optional PlaySolitaire account
Active- Technology / records
Better Auth 1.6.25 · dedicated managed PostgreSQL over TLS · secure HttpOnly first-party session cookie · Google OAuth when selected- Provider
- NM Media-operated application runtime and dedicated managed database; Google only when you select Google
- When it activates
- The service activates only if you choose to create an account or sign in. Email account creation asks for a nickname with the credentials. Google account creation verifies the Google identity first, creates a signed-in account with a non-public provisional nickname and a nickname-completion flag, and then asks you to choose the public nickname; synchronization and Daily publication remain unavailable until that choice is saved. During the private account handoff, existing browser progress is then prepared automatically from a coherent snapshot protected against every non-account route that can mount a writer. A valid exact-predecessor page-exit snapshot may supply the latest board. Before transfer, the complete draft and guest-write fence are durable and the production service-worker protocol gate must pass. The fenced draft can then be uploaded while the guest copy remains authoritative. It becomes attached to the active account browser namespace only after the server returns a durable final import receipt and the client stores the revision snapshot, imported fingerprints and active binding. A failed capture or changed account session cannot activate the account namespace. A guest namespace already linked to another account is not attached again; that signed-in account instead uses its clean, isolated namespace. Later eligible changes synchronize automatically while you remain signed in on an activated browser.
- Fields
- email address, player-chosen unique nickname after setup, unique non-public provisional nickname and boolean nickname-completion state while a new Google account awaits that choice, account identifier and account creation/update times
- password hash for an email/password account or Google provider account identifier when connected; provider access, refresh and ID tokens are not retained
- session identifier, expiry, IP address and browser user agent
- current and automatically preserved saved boards without undo or onboarding history, including variant, rules, deal/attempt identifiers, move state, elapsed time and revisions
- one cumulative lifetime/daily progress rollup, event count and hash-chain checkpoint per browser namespace; ongoing start/terminal event batches are validated in transit and not retained; new automatic guest handoffs retain the projected baseline rather than raw events; a frozen legacy import already staged by an older release may retain up to 10,000 validated immutable raw progress events; up to eight recent game keys
- the documented gameplay, theme and accessibility settings subset, including card size; consent, analytics, PWA, experiment, hint and shuffle-history state remain device-only
- idempotency keys, request digests, revisions, import state and synchronization/deletion receipts
- Purpose
- Complete a new Google account with a player-chosen public nickname before synchronization or publication
- Let you use the same optional account on supported devices
- Restore valid current boards with empty undo history
- Preserve concurrent valid games without asking you to resolve a technical conflict
- Provide account export and resumable deletion controls
- Prevent abuse and replayed writes
- Retention
- Account-owned identity, including a provisional Google nickname and pending-completion state until a nickname is chosen or the account is deleted, cumulative progress, any immutable raw progress events retained from a frozen legacy import, and operation receipts remain while the account exists. New automatic guest handoffs retain the cumulative projection and leave raw events in browser storage. Sessions expire after 30 days and refresh at most daily while used. A completed deletion receipt and its non-reversible user-identifier digest are retained for 30 days so a retry can receive a stable result, then must be purged by the operations process.
- Deletion / control
- The Account popup provides Download data and Delete account. Deletion is idempotent and resumable, removes account identity, sessions, provider links and synchronized data, and returns a completion receipt. It does not delete independent guest data left in a browser; clear site data separately to remove that local copy.
- Transfer
- Account requests go to the same-origin application and dedicated managed database. A durably fenced guest import may transfer before the local account browser namespace activates, but only after any required Google nickname choice is complete; its exact retry identities and acknowledged-item cursor prevent rebuilding or resending the acknowledged prefix, and a bounded server Retry-After delay is honored. If you select Google, the browser is redirected to Google for the requested openid, email and profile scopes. The provisional nickname and completion flag remain in the first-party account database. No advertising or subscription service receives account data. (verified in source code)
- Verification
-
- Authentication boundaries, Google-first nickname completion, exact origins, secure cookie policy, disabled implicit linking, token stripping, database schema, durable sync and lifecycle routes were traced. (verified in source code)
- The dedicated production database project, point-in-time recovery, migration ledger, exact Google production client, edge-attested account client-address rules and live deletion receipt purge have not yet been verified in their provider consoles. (operator verification pending)
- Legal-review status
- Accurate disclosure plus operator and owner acceptance are the launch gate. This technical inventory is not legal advice or a claim of counsel approval, and the entry must still be verified against the production deployment.
Daily Challenge verification and standings
Active- Technology / records
localStorage: playsolitaire:daily:competition-archive:v1 · sessionStorage: playsolitaire:daily:oauth-consent:v1 (ten-minute exact-receipt Google OAuth return intent) · secure HttpOnly session cookie: __Host-ps-daily-guest · same-origin /api/daily endpoints · dedicated managed PostgreSQL over TLS- Provider
- NM Media-operated application runtime and dedicated managed database
- When it activates
- The Daily Challenge on PlaySolitaire’s supported language routes requests one server-issued attempt when you start today’s ranked deal. A guest result is replayed by the server after a win and remains private. Add your name opens simple in-game Register and Log In tabs. Email registration asks for the public nickname with the credentials; email registration or login publishes that exact guest result without leaving the game. A compact Google action is available in both tabs: Register explicitly requests Google account creation and completes the player-chosen nickname on the localized account page before returning, while Log In starts the existing-account path without a signup request. Before Google navigation, a ten-minute session intent binds the Daily date and exact receipt; a successful return consumes it once and claims only that result. Every eligible verified win completed while signed in with a completed nickname is published automatically under the account nickname, with moves, hints and frozen official-client play time when available. Each public board selects the account’s best published result for that metric. Server-side revocation clears the current published rows for that Daily date; a later new signed-in win publishes again. Account deletion removes the Daily history. Archived deals are practice and cannot enter the standings.
- Fields
- on-device rolling Daily archive for up to eight dates, including the deterministic challenge, board, action tokens, attempt token, submission identifier, receipt and private/published/revoked state
- one session-only Google OAuth return intent containing the exact Daily date and receipt reference
- a random session cookie whose value remains HttpOnly; the database stores only its one-way digest for guest continuity
- challenge/version identifiers, signed attempt-token claims, request and replay-log digests, canonical move log, verification release and timestamps
- moves, hints, stock clicks, undos, server wall duration, optional frozen official-client play time and the private result receipt; legal replay does not verify play time
- account identifier and player-chosen nickname only after nickname completion; the internal provisional Google nickname and completion flag never appear on a standings board; nickname, moves and any non-zero hint count appear publicly for an eligible signed-in or claimed result; official-client play time also appears when that result includes protocol v2 time
- publication and time-publication timestamps plus revocation timestamp
- moderation status transitions, opaque actor reference, reason and timestamp; no account identifier or guest digest
- Purpose
- Give every player on PlaySolitaire’s supported language routes the same deterministic Daily deal
- Reject altered, expired or illegal result submissions by replaying the move log
- Keep a verified guest result private until the player chooses a public nickname
- Rank published results separately by fewest moves and official-client best time, project each account’s best result for each metric, and support server-side revocation and account deletion
- Prevent abusive or replayed requests
- Retention
- The on-device archive keeps at most eight Daily dates until it is replaced or site data is cleared. A Google OAuth return intent is removed on its first return check and otherwise expires with its ten-minute validity or the browser tab/session; a later Google attempt replaces it with the newly selected exact receipt. The guest identity cookie is session-only. Full replay evidence and unpublished guest attempts, runs and receipts are retained for 30 days after expiry or verification, then removed by bounded maintenance. Rate-limit rows expire within one day and are removed opportunistically. All account-owned attempts and results, private or published, remain until account deletion. A Google account still awaiting a player-chosen nickname cannot create a Daily publication, and standings exclude any such identity. Legacy result-protocol v1 runs keep a NULL official-client play time and legacy moves-only publications keep a NULL time-publication timestamp, so they are not placed on Best Time. An exact submission retry cannot publish an older private run. A signed-in browser may request one current-day repair for its matching stored private receipt, but the server publishes it only when the immutable run was already owned by that same account; guest receipts still require the player’s explicit Add your name or Add to standings action. Removed publication records remain until account deletion so the same receipt cannot be republished as another result. Moderation events are append-only and retain an opaque run identifier, old and new status, opaque actor reference, reason and timestamp without automatic expiry; they contain no account identifier or guest digest.
- Deletion / control
- Clear this site’s data to remove the on-device archive and guest cookie. Server-side revocation clears all of an account’s public results from both boards for that Daily date; a later new signed-in win publishes again. Delete the account to remove its Daily results and publication history; unpublished guest data otherwise expires under the 30-day cleanup policy.
- Transfer
- Daily requests go only to the same-origin application and dedicated managed database. Anonymous guest rows are never public. Google accounts awaiting a player-chosen nickname are never public. An eligible signed-in or claimed result exposes the completed account nickname, moves, any non-zero hint count and official-client play time when available. Each board shows only that account’s best published result for its metric; server wall duration and the detailed replay remain private. (verified in source code)
- Verification
-
- The PlaySolitaire locale gate, device archive, guest-private result, nickname-completion gate, automatic signed-in publication, exact claim/revocation requests and two-metric public response were traced. (verified in source code)
- Guest-private and replay-evidence cleanup are bounded and account-owned publication history is preserved until account deletion. (verified in source code)
- Lawful basis, retention proportionality, public-standing wording and any jurisdiction-specific rights language remain pending counsel review. (counsel review pending)
- Legal-review status
- The technical minimisation, guest-private default, automatic signed-in publication, claim and revocation paths are code-verified. This inventory is not legal advice or a claim of counsel approval.
Site delivery and security
CDN, origin hosting and request handling
Active- Technology / records
Bunny CDN · Hostinger VPS · Caddy · Astro Node server · first-party POST /api/csp-report report-only collector · Docker journald driver with exact application tags; bounded systemd journal; legacy local syslog archives- Provider
- Bunny.net and Hostinger; NM Media-operated application runtime
- When it activates
- Every request to the site and its first-party API routes.
- Fields
- IP address and connection metadata
- requested URL, method and request headers including browser user agent and referrer when supplied
- daily-share URL query fields when a recipient opens a result link: t (elapsed seconds), m (move count), and optional s (streak length)
- response status and timing metadata
- Cookie request headers when attached by the browser, including the compact ps_first_game record, ps_analytics_denied state, and consented _ga / _ga_* identifiers
- edge-derived two-letter country code for /api/geo
- Bunny ordinary request-log fields: IP address subject to the enabled API anonymisation setting, URL/path, country, user agent, referrer and status; this setting does not prove when the original IP address is erased
- normalized Content Security Policy report fields: release/environment, policy version, document origin/path without query or fragment, effective and violated directive, disposition, response status, blocked target category/origin/path, source origin/path, and line/column numbers
- Purpose
- Deliver the site
- Route and secure requests
- Return a fail-closed regional consent verdict
- Observe required-origin violations before deciding whether the report-only Content Security Policy can be enforced
- Retention
- The 2026-09-08 administrative check confirmed ordinary Bunny logging is enabled for PlaySolitaire, Pasianssia, Patienshuset and PlaySolitaire.jp, with IP anonymisation enabled (type 0), no forwarding, no permanent log storage and no extended logging. Bunny documentation describes raw-log retention of 3 days; API anonymisation does not establish original-IP erasure or retention of separate origin-error and security records. All seven publications use the journald driver on both origins. Production journald is configured for at most 7 days, 1 GB total and 1-day files. An early rsyslog rule excludes their exact application tags from new local syslog copies. Older syslog archives can remain until weekly rotation with four archives, potentially about 35 days. The checked Caddy configuration has no access-log or file writer. Hostinger platform/network-level retention remains externally unverified.
- Deletion / control
- New normalized CSP reports and container output follow the configured journal retention instead of an unbounded Docker JSON file. On 2026-09-08 all 28 current production containers had empty Docker LogPath values, and no Docker JSON log files were found in the standard container directory on either origin. This does not establish deletion of unknown historical copies outside that directory. Older syslog copies expire through the existing weekly rotation. Original-IP erasure and separate provider-record deletion remain unverified. The general contact and signed-in self-service paths do not establish a verified operator privacy-request register or response workflow; available deletion depends on the record and applicable law.
- Transfer
- Requests pass through Bunny CDN and the Hostinger-hosted origin. This includes daily-share t, m and optional s query fields when a recipient requests a shared result URL. Exact processing locations and transfer mechanisms are pending contract and provider-console verification. (operator verification pending)
- Verification
-
- The /api/geo data minimisation and no-store response were traced. (verified in source code)
- The CSP collector accepts only bounded CSP media types, strips queries, fragments, samples, referrers and original policies, emits normalized one-line journal records, rate limits requests and returns no-store responses. (verified in source code)
- Read-only Bunny GETs confirmed ordinary logging is enabled for PlaySolitaire, Pasianssia, Patienshuset and PlaySolitaire.jp, with IP anonymisation enabled (type 0); forwarding, permanent storage and extended logging are disabled. Spanish, German and Polish publication zones separately have ordinary logging disabled and anonymisation type 1. These settings do not prove original-IP erasure or separate provider-log retention. (verified through an administrative API)
- Read-only checks found all 28 PS-family production containers using journald with exact application tags and empty Docker LogPath values. Both origins retain 7day/1G/1day journal limits and an early rsyslog exclusion for all 14 application tags. Caddy has no access-log or file writer. No Docker JSON log files were found in the standard container directory; older syslog archives remain under existing rotation. No synthetic log write or deletion of historical files was performed. (verified in the current deployment)
- Hostinger platform/network logging and retention still require provider-console or contract verification. (operator verification pending)
- Processor roles and international-transfer wording require contract and counsel review. (counsel review pending)
- Legal-review status
- Controller/processor roles, lawful basis, and transfer mechanism are not approved in this inventory and remain pending counsel review.
Analytics and error monitoring
Google Analytics 4
- Technology / records
Google tag G-L22FHX4NDQ · www.googletagmanager.com/gtag/js · www.google-analytics.com/g/collect and region1.google-analytics.com/g/collect · GA4 web stream 4800998831 · Google Analytics property 361367397 · cookies such as _ga and _ga_*- Provider
- When it activates
- Loads only when the site’s denial-dominant privacy state machine resolves to granted on the production hostname. With no saved choice, a verified edge country outside the code’s GDPR-region set creates an implied grant; a configured-region or unknown result shows the banner. Staging, automated browsers and explicit rejection remain silent. On PlaySolitaire Klondike pages, the renderer-assignment denominator is sent after consent but before either assigned renderer import. A separate finite ready or fallback outcome records the assigned and effective renderer only after a renderer is live. The web-vitals attribution module loads only for a secure-random 50% diagnostic sample whose page-lifetime performance-architecture assignment is eligible and bound to an exact deployment SHA. It produces INP, bounded action-worst Event Timing, action-coverage, LCP and TTFB measurements only where the required browser timing support exists. INP transmission excludes selected interactions that began before the consented observation boundary. Loading metrics are registered only when analytics consent was already granted at the first eligible game registration, because their buffered entries do not expose an equivalent consent timestamp. Bounded interaction and coverage updates can be sent when the page becomes hidden or exits; distinct official v6 and synthetic a3 metric-ID namespaces permit unambiguous raw-export deduplication. Rejection or withdrawal prevents later performance transmissions.
- Fields
- page URL, referrer, session and device/browser information collected by the Google tag
- network-derived approximate location and request metadata processed by Google
- Google user/session pseudonymous identifiers and consented GA cookies
- the Enhanced Measurement umbrella switch is on, but pageChangesEnabled, scrollsEnabled, outboundClicksEnabled, siteSearchEnabled, videoEngagementEnabled, fileDownloadsEnabled and formInteractionsEnabled are absent/default false; the configured q, s, search, query and keyword parameter list does not collect site-search events while siteSearchEnabled is false
- game variant, mode, suit/draw mode, deal number/seed where emitted, move count, elapsed-time summaries and outcome/reason
- corrected game_abandoned events include the fixed played_time_basis value active so active-timer calculations can be separated from historical unmarked wall-age events; first_session_duration_ms remains wall span
- game_resumed_play records one confirmed local persisted gameplay change, including Undo, per eligible initially restored progressed attempt per provider mount; attempt/deal join keys and fixed resume_version/resume_scope describe this occurrence, not every returning GA session; initially auto-completable boards, recovery and any later external adoption are excluded, as are hydration, Hint alone and timer-only changes
- methodology version plus stable pseudonymous event, attempt and deal identifiers derived from game state for BigQuery lifecycle joins and deduplication
- first-game random assignment ID, pool/experiment metadata and lifecycle timestamps/status
- two-suit Spider deal_pool, deal_difficulty, pool_version, pool_index and rollout_arm; rollout_arm remains raw-export-only and is not registered as a GA4 custom dimension
- exact custom event parameter names: abandoned, action_path, action_type, actual_game_id, already_won, asset_id, asset_type, assigned_cell, assignment_id, attempt_id, beat, board_actions, board_actions_target_other, board_interactions, board_interactions_with_action_path, cache_duration_ms, connection_duration_ms, content_attribution_version, content_id, content_locale, content_origin_id, content_origin_locale, content_type, control_location, coverage_complete, cta_id, cta_location, dataset_version, day_key, deal_difficulty, deal_id, deal_mode, deal_number, deal_pool, destination_url, device_category, dns_duration_ms, draw_mode, effective_cell, element_render_delay_ms, error_kind, event_id, experiment_cell, experiment_version, feedback_type, file_format, first_game_move_count, first_game_played_ms, first_game_status, first_session_duration_ms, freshness, game, game_variant, goal, golden_deal, has_result, ineligible_reason, input_delay_ms, interaction_latency_ms, interaction_target, interaction_type, kind, lcp_target, length, link_placement, loading_latency_ms, loaf_count, loaf_support, loaf_total_paint_ms, loaf_total_script_ms, loaf_total_style_layout_ms, loaf_total_unattributed_ms, locale, longest_script_source_owner, longest_script_subpart, max_loaf_blocking_ms, message, method, methodology_id, methodology_version, metric_id, metric_name, metric_scope, mode, move_count, navigation_type, new_best, new_level, observed_interactions, orientation, origin_click_id, origin_cta_id, outcome, page_type, played_ms, played_time_basis, pool_index, pool_version, presentation_delay_ms, previous_level, processing_duration_ms, promo_id, pwa_display_mode, pwa_is_standalone, pwa_precached, pwa_service_worker_supported, rating, reason, release_sha, render_scope, renderer_outcome, reply, request_duration_ms, research_id, resource_load_delay_ms, resource_load_duration_ms, resource_page, resume_scope, resume_version, rollout_arm, scenario_id, seconds_to_goal, service_worker_status, setting_key, setting_value, shown_count, social_platform, start_seconds, streak_length, suit_mode, surface, target_content_id, target_game, target_url, their_t, time_to_first_byte_ms, trigger, ui_source, updated_pile_bucket, variant, video_id, viewport_class, viewport_range, waiting_duration_ms, win_streak, won
- daily/share fields include day_key, freshness, has_result, already_won, beat, their_t (the friend target time in seconds), method, outcome, kind, surface, streak_length and reply
- content and navigation fields include page_type, goal, scenario_id, cta_id, cta_location, video_id, game, locale, start_seconds, social_platform, link_placement and destination_url; seconds_to_goal measures content-goal latency on content_goal_reached
- consented content-journey clicks can send content_id, content_type, content_locale, content_origin_id, origin_cta_id, content_origin_locale, target_game, target_url, origin_click_id and content_attribution_version; a compatible one-shot game_start additionally sends actual_game_id, while research interactions can send research_id, the public dataset_version, methodology_id, target_content_id, asset_id and file_format
- content_id, content_origin_id and origin_cta_id are intended for event-scoped GA4 interface dimensions; content locale, target/actual game, research ID, dataset version, click ID, target URL and attribution version remain unregistered raw-export fields
- successful in-game feedback events include only feedback_type, ui_source and game_variant; feedback text, email, page path and diagnostics are excluded
- deadlock and promotion fields include trigger, shown_count and promo_id; rows sent while the settled 2026-07 personal-best and PWA-install experiments ran can also carry ab_stats or ab_pwa_install, retained in the BigQuery export
- PWA fields include pwa_display_mode, pwa_is_standalone, pwa_service_worker_supported and pwa_precached
- the settled PWA install offer can send Klondike game_variant, free/turn3 mode and the finite accepted, dismissed, unavailable or error prompt outcome after analytics consent; product-state creation, snooze and eligibility timestamps plus fallback attempt identifiers are excluded. Historical EXP-3 rows can carry ab_pwa_install (install or control) and bounded assignment-to-install seconds, retained for the completed analysis
- historical EXP-4 rows can carry ab_game_shell (control, b or c), ab_game_shell_version (v2) and game_shell_exposure data retained for the completed analysis. Historical EXP-5 v3 and v4 rows can carry ab_game_shell (classic or bliss), their matching ab_game_shell_version, game_variant, eligibility, release_sha and game_shell_exposure data retained for the retired analyses. The settled shell no longer assigns an arm or sends those experiment fields
- historical rows collected during the retired post-win overlay v1 test can carry ab_post_win_overlay (clear or shade), ab_post_win_overlay_version, Klondike game_variant, free/turn3 mode, draw_mode, shell_mode, pseudonymous attempt_id, full release_sha and one finite cta_location. The settled result popup no longer assigns an arm or sends those experiment events or fields
- after the bounded setting-analytics cutover, successfully committed setting name and finite category are sent as setting_key and setting_value, with ui_source; custom colours report only the edited slot and customized or reset_default
- UI entry points on setting, deal-picker and feedback events use ui_source. Historical clients used source, which can contaminate collected campaign-source attribution; those old rows remain historical and are not repaired by the field rename
- historical setting_changed rows collected before the cutover, and legacy rows potentially emitted afterward by already-open or stale cached clients, may contain joined raw custom-palette colour values including picker-change events; the separate BigQuery export can retain those rows indefinitely
- the consented performance_architecture_exposure event is the assignment-time intention-to-treat denominator and is emitted before either renderer import; performance_architecture_outcome separately records only finite ready or fallback status with assigned and effective cells; performance_architecture_client_error adds only finite error or unhandledrejection kind for the exact artifact release and assigned cell
- sampled interaction_performance methodology version 3 uses a fixed 50% diagnostic cohort on eligible Klondike pages and sends the official Google web-vitals page-worst INP candidate and bounded synthetic action-worst Event Timing summaries with distinct v6 and a3 metric-ID namespaces; each includes input-delay, processing and presentation timings, full artifact release SHA, page-lifetime control or retained_scene_v1 experiment cell, finite interaction type and synchronous target category, compact/wide viewport class, and an action_path composed only from finite pointer, keyboard or click, target and deal, drag_accept, drag_reject, tap_move, card_reveal, draw, activate or unresolved buckets
- interaction_performance_coverage sends only bounded aggregate counts for observed interactions, board interactions, board interactions with an action path, board actions and board actions classified as other, plus compact/wide viewport and a boolean that is false if the 512-interaction in-memory denominator cap was reached
- action-path matching uses only a consented sampled page’s navigation-relative event timestamps, a maximum of 16 short-lived in-memory input bundles and 32 action records. Each input bundle contains only its finite pointer, keyboard or click kind, a finite target bucket, a finite Enter/Space/other keyboard bucket, transient browser-local pointer ID when supplied, bounded timestamps and optional finite action; both ledgers are cleared on denial, measurement reset and final game unregistration and are never created for unknown, denied, forced-QA, ineligible or sample-excluded pages
- when the browser provides interaction-associated Long Animation Frame attribution, the event can send bounded frame count and maximum blocking time; bounded script, style/layout, paint and unattributed totals only when frame render/style timing is internally ordered; a finite longest-script owner, duration and INP-phase category; and optional finite render-scope and updated-pile-count buckets. Raw script URL, invoker and function data are never transmitted
- sampled loading_performance methodology version 3 sends final Google web-vitals LCP or TTFB value, rating, finite metric ID, full release SHA, experiment cell, compact/wide viewport, navigation type and service-worker status. LCP adds only a finite snapshot-card, game-card, game-shell, content-image, text or other target plus its TTFB, resource-delay, resource-duration and render-delay subparts; TTFB adds bounded waiting, cache, DNS, connection and request durations
- the custom performance payloads never add DOM text, card state, selectors, raw resource or script URLs, function names, a custom page-path field, pointer coordinates or individual interaction traces
- interaction_target, viewport_class and interaction_type plus previously registered interaction timing parameters remain available for GA4 interface reporting; game_variant and methodology_version were already registered, while action_path, experiment_cell, loading attribution, metric_id, release_sha and the new diagnostic attribution fields remain raw-export-only to avoid unapproved or high-cardinality GA4 dimensions
- deck-integrity action_type and bounded diagnostic message (up to 200 characters)
- Purpose
- Measure pages and game usage
- Evaluate product experiments and content interactions
- Detect aggregate gameplay/integrity problems
- Measure sampled real-user Klondike interaction responsiveness and loading performance by page-lifetime experiment cell and artifact release, with a finite renderer-exposure denominator plus finite input/action, script, style/layout, paint, LCP-subpart and TTFB-phase attribution
- Retention
- GA4 event and user data retention in the GA interface is configured to 14 months, reset on new activity. That setting does not expire the separate BigQuery export disclosed below. Cookie lifetime is controlled by the Google tag and browser; the exact live cookie expiry still needs a browser verification.
- Deletion / control
- Reject or withdraw through Cookie settings or the opt-out page to stop later events and clear visible GA cookies. No verified monitored privacy-request channel is currently configured for requests about data already received by Google; establishing that workflow remains an operator/counsel action.
- Transfer
- Consented analytics is sent to Google. Exact processing locations, Google entity/roles and international-transfer mechanism are pending contract and counsel review. (counsel review pending)
- Verification
-
- The single consent-gated event gateway and all code-level event producers were traced. (verified in source code)
- GA4 Admin API: active web stream 4800998831 / G-L22FHX4NDQ. enhancedMeasurementSettings returns streamEnabled=true and searchQueryParameter=q,s,search,query,keyword; pageChangesEnabled, scrollsEnabled, outboundClicksEnabled, siteSearchEnabled, videoEngagementEnabled, fileDownloadsEnabled and formInteractionsEnabled are absent/default false, so configured search parameters are not currently collected as site-search events. Standard property; FOURTEEN_MONTHS event/user retention; reset-on-new-activity true; Google Signals ENABLED with consent state CONSENTED; property timezone America/Los_Angeles. (verified through an administrative API)
- Live GA cookie expiry and exact Google processing/subprocessor facts need browser and contract verification. (vendor or contract verification pending)
- The bounded setting-analytics and lifecycle-methodology cutover was activated at 2026-07-15T12:50:26Z in production release a34baa34ca6cdae2eb69e2e5d09d5c2dd2efa096. The event-scoped methodology_version custom dimension was registered in GA4; the high-cardinality lifecycle identifiers were not registered. (verified in the current deployment)
- GA4 Admin API: the existing event-scoped pool_index dimension was renamed from Golden pool index to Deal pool index; event-scoped deal_difficulty was registered; rollout_arm was intentionally left unregistered for raw BigQuery analysis only. (verified through an administrative API)
- GA4 Admin API: event-scoped ab_pwa_install remains registered for historical EXP-3 install/control rows; the settled product offer no longer emits the arm. (verified through an administrative API)
- GA4 Admin API: event-scoped ab_game_shell remains registered for historical EXP-4 and EXP-5 v3/v4 rows; the settled shell no longer emits it, while ab_game_shell_version, eligibility and release_sha remain raw-export-only historical fields. (verified through an administrative API)
- GA4 Admin API: event-scoped interaction_target, viewport_class and interaction_type dimensions plus interaction_latency_ms, input_delay_ms, processing_duration_ms, presentation_delay_ms, max_loaf_blocking_ms and the historical interaction_count metric are registered for sampled interaction reporting. Methodology v3 no longer emits interaction_count. game_variant and methodology_version were already registered; metric_id, release_sha, experiment_cell, action_path, loading attribution and LoAF/render attribution remain raw-export-only. (verified through an administrative API)
- Monitor the post-cutover stale-client tail for legacy raw palette-shaped setting_value rows after export latency has elapsed. (operator verification pending)
- Consent scope, Google Signals, legal basis and transfer mechanism require counsel review. (counsel review pending)
- Legal-review status
- The Admin API facts are operational facts only; they do not establish lawful basis or legal approval. Google Signals being enabled requires explicit counsel/product review.
GA4 BigQuery export
- Technology / records
Google Cloud BigQuery · stilldeck-analytics:analytics_361367397 (EU dataset) · daily events_* and pseudonymous_users_* tables- Provider
- Google Cloud, in the NM Media-managed stilldeck-analytics project
- When it activates
- GA4 exports collected analytics rows to BigQuery. Because source GA4 collection is gated, explicit rejection prevents new PlaySolitaire events from entering the export.
- Fields
- exported GA4 event rows and event parameters
- pseudonymous user identifiers and pseudonymous_users records
- event time, page, session, device/browser, approximate geo, traffic-source and consent metadata supplied by the GA4 export schema
- the custom game, PWA, settings, experiment, content-origin, CTA, video and diagnostic fields listed in the GA4 entry
- pseudonymous content-origin click IDs used with user_pseudo_id to reconcile generic clicks, dedicated guide/research clicks and same-session or 30-minute game starts; no raw query string or clicked_at_ms sessionStorage value is exported by the custom events
- methodology-v3 performance_architecture_exposure assignment denominators, finite ready/fallback outcomes, assigned-arm client-error counts, sampled page-worst and action-worst interaction_performance summaries, aggregate interaction_performance_coverage summaries and loading_performance summaries; metric events include distinct official v6 and synthetic a3 metric IDs, artifact release SHA and control or retained_scene_v1 page-lifetime experiment cell, official page-worst or bounded action-worst phase timings, finite synchronous input-target-action path, optional render-scope and updated-pile buckets, and page-worst interaction-associated Long Animation Frame totals plus finite script-owner/subpart categories. Loading events include LCP/TTFB values with finite loading subparts, target, navigation and service-worker buckets. The custom events add no DOM text, card state, selector, raw resource or script URL, invoker, function name, custom page-path field, pointer coordinate or individual interaction trace beyond the standard GA4 export schema disclosed above
- Purpose
- Run product and traffic analysis outside the GA interface
- Join and audit pseudonymous event lifecycles
- Reconcile consented guide/research play clicks with one compatible game start and audit malformed, duplicate, orphaned or mismatched attribution rows
- Measure exact-release intention-to-treat renderer allocation, ready/fallback outcomes, client errors and early abandonment
- Compare sampled Klondike page-worst INP, action-worst responsiveness, LCP and TTFB by exact artifact release and page-lifetime performance-architecture experiment cell
- Measure aggregate action-path and target-classification coverage without individual interaction traces
- Attribute slow interaction time to finite input/action, render scope, updated-pile, script-owner, script, style/layout, paint and unattributed categories
- Attribute slow loading time to finite LCP subparts, TTFB phases, structural target, navigation and service-worker categories
- Deduplicate repeated performance reports using scope-specific finite metric IDs
- Preserve historical measurement series
- Retention
- The EU dataset has no default table expiration, and inspected daily events and pseudonymous-user tables have no expiration time. Exported rows are therefore retained indefinitely until someone with project access manually deletes them or adds an expiry.
- Deletion / control
- There is no automatic expiry. Deletion requires an authorised operator to delete or rewrite the relevant BigQuery tables/rows. No verified monitored privacy-request channel is currently configured; establishing that workflow remains an operator/counsel action.
- Transfer
- The export is stored in a Google Cloud BigQuery dataset configured in the EU. Google Cloud roles, subprocessors and any onward-transfer mechanism remain pending contract and counsel review. (counsel review pending)
- Verification
-
- BigQuery dataset analytics_361367397 is in the EU and has no defaultTableExpirationMs; sampled events_20260712 has no expirationTime; daily events and pseudonymous_users tables are present. (verified through an administrative API)
- Google Cloud project access, deletion procedure, audit logs, DPA and subprocessor facts need an operator/contract review. (vendor or contract verification pending)
- Indefinite retention proportionality, lawful basis, rights handling and international-transfer wording require counsel approval. (counsel review pending)
- Legal-review status
- The EU dataset location is verified, but it does not itself establish a lawful basis or eliminate all international-transfer questions. Indefinite retention is an operational fact, not an approved legal conclusion.
Sentry error monitoring
Active- Technology / records
@sentry/node · Sentry browser SDK loaded from browser.sentry-cdn.com only after a client error · ingest.de.sentry.io project endpoint- Provider
- Sentry
- When it activates
- Server SDK initializes for valid production/staging deployment identities. The browser SDK is fetched only after an error or unhandled rejection; its default browser integrations then apply to later captured events on that page.
- Fields
- error message, exception type and stack trace
- page URL and default browser SDK, runtime, release and environment context
- server request method and URL path after query strings and fragments are removed
- server RequestData collection is disabled; beforeSend also removes request bodies/data, parsed cookies, every request header, query values, request environment fields and Sentry user fields before transmission
- finite assigned Klondike renderer cell (control or retained_scene_v1) only after analytics consent on eligible experiment-page browser errors; the tag is removed on consent withdrawal
- browser request IP address, user agent and connection metadata processed by the Sentry CDN and ingest endpoints
- default browser SDK breadcrumbs after initialization: navigation, console activity, fetch/XHR URLs and DOM interaction metadata
- unexpected values that an application or dependency explicitly places in an error message, stack, breadcrumb or other event field
- Purpose
- Detect, diagnose and repair application failures
- Separate staging and production errors by release/environment
- Retention
- Not defined in application code; current project retention requires Sentry-console verification.
- Deletion / control
- No verified monitored privacy-request channel is currently configured for requests about Sentry records. Establishing a working request workflow remains an operator/counsel action; deletion will also depend on record availability and applicable law.
- Transfer
- Errors go to the configured Sentry DE ingest endpoint. Storage location, subprocessors and any onward transfer remain pending vendor/contract verification. (vendor or contract verification pending)
- Verification
-
- Client/server initialization, browser defaults, release/environment separation, disabled server RequestData integration and the beforeSend request/user scrub were traced and regression-tested. (verified in source code)
- Staging/production acceptance must verify the exact Sentry release/environment identities emitted by each deployed SHA and confirm that staging events do not appear as production. (operator verification pending)
- Project retention, location and deletion settings require a Sentry-console and contract audit. (vendor or contract verification pending)
- The lawful basis for error monitoring outside the analytics-consent gate requires counsel approval. (counsel review pending)
- Legal-review status
- The server request scrub materially limits request-carried data, but error messages, stack traces and later browser breadcrumbs can still contain unexpected personal data. Lawful-basis wording is pending counsel review.
Hotjar behavior analytics
- Technology / records
Hotjar site 6689617 · static.hotjar.com/c/hotjar-6689617.js loader · script.hotjar.com vendor modules and in.hotjar.com ingest endpoints, plus further vendor-internal *.hotjar.com / *.hotjar.io and WebSocket endpoints · cookies such as _hjSession_6689617 and _hjSessionUser_6689617- Provider
- Hotjar (a Contentsquare company)
- When it activates
- Loads only when the denial-dominant privacy state machine resolves to granted on the production hostname and the visitor then provides a trusted pointer or keyboard interaction. After that interaction, the loader still waits for window load and a browser idle callback, keeping Hotjar out of startup and the first input. Staging, automated browsers and explicit rejection remain silent. Withdrawal cancels pending activation and tears down Hotjar globals, script elements and visible _hj* cookies.
- Fields
- page URL, referrer, viewport and device/browser information collected by the Hotjar script
- mouse movement, click, tap and scroll interaction coordinates used for heatmaps and session recordings
- Hotjar pseudonymous user/session identifiers and consented _hj* cookies
- network-derived approximate location and request metadata processed by Hotjar
- text typed into form fields is suppressed by Hotjar default masking; recordings capture interaction shape, not keystroke content, subject to vendor-console verification below
- Purpose
- Understand how the interface is used through aggregated heatmaps
- Review consented session recordings to find usability problems
- Retention
- Vendor-side recording and heatmap retention is controlled in the Hotjar console and requires vendor-console verification. Cookie lifetime is controlled by the Hotjar script and browser; the exact live cookie expiry still needs a browser verification.
- Deletion / control
- Reject or withdraw through Cookie settings or the opt-out page to stop later collection and clear visible _hj* cookies. No verified monitored privacy-request channel is currently configured for requests about data already received by Hotjar; establishing that workflow remains an operator/counsel action.
- Transfer
- Consented behavior data is sent to Hotjar. Exact processing locations, the Hotjar/Contentsquare entity roles and the international-transfer mechanism are pending contract and counsel review. (counsel review pending)
- Verification
-
- The consent-gated, trusted-interaction and load-plus-idle-deferred loader, pending-activation cancellation, and withdrawal teardown of Hotjar globals, scripts and cookies were traced. (verified in source code)
- Production acceptance must confirm no Hotjar request is emitted before consent or before a later trusted interaction, and that the loader appears only after both conditions on the live site. (operator verification pending)
- Hotjar console settings — retention, masking/suppression configuration, recording sampling and DPA facts — require a vendor-console and contract audit. (vendor or contract verification pending)
- Consent scope for session recordings, proportionality, lawful basis and transfer mechanism require counsel review. (counsel review pending)
- Legal-review status
- Session-recording collection is limited by consent gating and vendor default masking, but recordings can still capture unexpected on-screen content. Lawful-basis and retention wording is pending counsel review.
Contact delivery and abuse controls
SMTP contact and feedback delivery
Active only after your interaction- Technology / records
/contact form · in-game feedback form · POST /api/contact · SMTP_HOST · SMTP_PORT · SMTP_USER · SMTP_PASS · CONTACT_TO · Nodemailer- Provider
- The operator-configured SMTP mailbox provider that receives messages for the site mailbox
- When it activates
- Data leaves the browser only after you fill in the form at /contact or open the in-game feedback form and press send. The endpoint processes a request only when every required SMTP runtime entry is configured and, on deployed hosts, the edge attestation headers match. In-game feedback additionally requires the PS_FEEDBACK_ENABLED runtime gate.
- Fields
- message
- optional email address for feedback or required email address for contact
- locale
- page path
- feedback type and entry point
- game variant
- for bug reports only: game mode, draw mode, seed or deal number, status, move count, deal pool/difficulty, viewport, browser user agent and release
- mail transport metadata
- Purpose
- Deliver contact messages, bug reports and suggestions to the site mailbox
- Reply by email when an address is provided
- Reproduce and diagnose reported game problems
- Retention
- The delivered email remains in the receiving mailbox until the operator deletes it; the application server stores no copy.
- Deletion / control
- Ask for deletion in the message itself or in a reply when you provide an email address; the operator deletes the mailbox copy. Anonymous feedback cannot later be linked back to you by the application.
- Transfer
- Submitting the form sends your message from the application server to the operator-configured SMTP provider over an authenticated connection for delivery to the site mailbox. (operator verification pending)
- Verification
-
- The contact and in-game feedback forms post to /api/contact through the first-party request gateway. The endpoint validates, rate-limits and forwards messages through SMTP without storing an application copy; feedback drafts remain only in page memory. (verified in source code)
- Production release acceptance must confirm the required SMTP and destination variables are present in the protected production profile and that a monitored end-to-end submission is delivered to the configured mailbox. (operator verification pending)
- Legal-review status
- The contact reply purpose and feedback diagnostic disclosure are stated beside their forms. Provider, retention, DPA and transfer documentation must be kept current with the configured SMTP provider; formal privacy-request workflow wording remains pending counsel review.
User-initiated third-party content
External publisher, social, reference, licence and contributor links
Active only after your interaction- Technology / records
ordinary browser links to registered HTTPS destinations · non-fetching HTML and JSON-LD references to registered metadata destinations · https://pasianssia.fi/ · https://patienshuset.se/ · https://playsolitaire.jp/ · https://solitario777.com/ · https://xn--solitr777-z2a.de/ · https://solitario777.it/ · https://pasjans777.pl/ · https://creativecommons.org/licenses/by/4.0/ · https://arxiv.org/abs/1906.12314 · https://discord.com/invite/kTmkxT6rGG · https://en.wikipedia.org/wiki/Klondike_(solitaire) · https://mobilityware.helpshift.com/hc/en/12-freecell/faq/1049-are-there-deals-that-are-impossible-to-win-in-freecell/ · https://nmmedia.lt/ · https://www.garanteprivacy.it/it/i-miei-diritti · https://www.freecell.org/5-facts-about-freecell.html · https://www.tiktok.com/@playsolitaireio · https://www.linkedin.com/in/ · https://www.serrae.net/ · https://www.upwork.com/ · https://www.youtube.com/ · https://x.com/Playsolitaireio · mailto:info@playsolitaire.io · https://pasianssia.fi/ · https://patienshuset.se/ · https://playsolitaire.jp/ · https://solitario777.com/ · https://xn--solitr777-z2a.de/ · https://solitario777.it/ · https://pasjans777.pl/ · https://creativecommons.org/licenses/by/4.0/ · https://nmmedia.lt/ · https://schema.org/ · https://www.tiktok.com/@playsolitaireio · https://x.com/Playsolitaireio- Provider
- The destination you choose, including NM Media, TikTok, X, Discord, Creative Commons, Wikipedia, LinkedIn, Upwork or a credited contributor site
- When it activates
- Registered publisher, social-profile, reference, licence and schema URLs can appear as inert HTML or JSON-LD metadata, which does not itself contact the named destination in the browser. A browser navigation opens only after you activate the corresponding link.
- Fields
- publisher, social-profile, schema, reference and licence URLs embedded in page metadata without an automatic browser request
- destination URL selected by you
- IP address and browser/request headers, including a referrer when the browser supplies one, after HTTPS navigation
- Purpose
- Declare publisher, social-profile, schema, licence and reference relationships without automatically loading those destinations
- Open official social profiles, publisher information, source references, licence terms or contributor profiles
- Retention
- PlaySolitaire retains only a consented GA4 social-link click event as disclosed under Google Analytics; it does not retain a separate operational record of ordinary outbound navigation. Any destination request is controlled and retained by the selected browser and destination under their own terms.
- Deletion / control
- Use the selected destination controls. PlaySolitaire cannot delete a request held by a destination you chose.
- Transfer
- Metadata references remain values in the delivered page and do not themselves make a browser request. Only your activation navigates to a registered HTTPS destination, which then receives normal request metadata. (vendor or contract verification pending)
- Verification
-
- Every shipped external navigation and metadata destination is parsed from built output and matched to its typed registry. (verified in source code)
- Destination logging, retention, account linking and deletion behavior are controlled by each selected destination. (vendor or contract verification pending)
- Any jurisdiction-specific notice or lawful-basis wording for user-directed external navigation remains pending counsel review. (counsel review pending)
- Legal-review status
- The interaction gate and destination set are code-verified; destination processing and legal characterization are not presented as counsel-approved.
YouTube privacy-enhanced player
Active only after your interaction- Technology / records
youtube-nocookie.com embed · YouTube watch and channel links · non-fetching JSON-LD references to YouTube embeds, watch pages and i.ytimg.com thumbnails- Provider
- Google / YouTube
- When it activates
- Structured data can name a launched video, channel, privacy-enhanced embed URL and thumbnail without making a browser request. No player iframe loads on page render. A preconnect can occur on pointer hover or touch intent, and the privacy-enhanced iframe loads only when you press play or choose a video chapter. Following a YouTube link is also your action.
- Fields
- video, channel and thumbnail identifiers present in structured metadata without an automatic browser request
- IP address and browser/request metadata after interaction
- video identifier and playback request
- cookies or browser storage that Google/YouTube may set after interaction
- Purpose
- Describe the launched tutorial in structured metadata without automatically loading YouTube
- Play the tutorial video you requested
- Open the requested video/channel on YouTube
- Retention
- Controlled by Google/YouTube after interaction; exact cookie and account/activity retention is not defined in this repository and requires vendor verification.
- Deletion / control
- Use browser controls and any Google/YouTube account controls that apply. No verified monitored privacy-request channel is currently configured for requests relating to PlaySolitaire-controlled records.
- Transfer
- Structured metadata values do not themselves request YouTube. Interaction sends later preconnect, playback or navigation requests directly from your browser to Google/YouTube. Processing locations and transfer mechanisms are pending vendor and counsel review. (vendor or contract verification pending)
- Verification
-
- Facade, preconnect trigger and click-to-create iframe were traced. (verified in source code)
- Cookies/storage, retention, processing location and account-linking behavior require a current vendor/browser audit. (vendor or contract verification pending)
- Role, lawful basis and international-transfer wording require counsel review. (counsel review pending)
- Legal-review status
- “Privacy-enhanced” is the configured YouTube mode, not a claim that Google receives no data after interaction.
Analytics choice and withdrawal
Google Analytics loads only when the site’s current privacy state resolves to granted. An explicit
rejection or opt-out wins over an earlier acceptance or a regional result. With no saved choice,
a verified country outside the regional set currently configured in /api/geo creates
an implied grant; a configured-region or unknown result shows the banner. The legal accuracy and
legal basis of that regional behavior remain pending counsel review. You can reopen
at any time, or use the analytics opt-out page. Withdrawal denies later GA
collection, clears queued GA/PWA events and visible GA or Hotjar cookies, and saves the
current game before any necessary reload.
Local data and browser controls
Clearing cookies alone does not remove localStorage, IndexedDB or Cache Storage. Use your browser’s “site data” control to remove the separate guest and per-account save namespaces, settings, local statistics, the account synchronization queue, privacy choices, service-worker caches and first-party cookies together. Account deletion removes the server copy but deliberately does not erase independent guest data in this browser.
Requests and applicable rights
The account page provides self-service download, nickname and email changes, and resumable account deletion for the signed-in account. Those controls do not replace any statutory request process that may apply.
No verified monitored channel for access, correction, deletion, restriction, objection, portability or other privacy requests is currently configured. The contact form delivers general messages to the operator's mailbox when its SMTP transport and destination are configured, but it is not a verified privacy-request workflow with tracked response deadlines. Establishing that workflow and response process is an open operator/counsel item, not a service this notice claims is available today. Some on-device data can only be controlled through your browser because we do not receive the complete local record. Exact statutory rights, exemptions and response deadlines are pending counsel verification and are not expanded or limited by this technical notice.
Advertising, accounts and sale of data
The current application offers optional accounts as described in the inventory above. It has no active advertising, subscription or data-sale integration. Those separate features remain behind their own launch gates and require another notice update before activation.
Open verification and counsel items
These items remain explicit instead of being filled with assumptions:
- Operator / counsel: Configure and verify a monitored privacy-request channel, publish it in this notice, define the response workflow, and only then advertise that requests can be submitted. The /contact form is a general contact channel and is not presented as that verified workflow.
- Counsel / owner: Confirm the full controller identity, registered address, jurisdiction-specific lawful bases, rights wording and response deadlines.
- Operator / counsel: Verify current DPAs, provider roles, processing locations, international-transfer mechanisms and retention/deletion controls for Bunny, Hostinger, Google/YouTube and Sentry.
- Operator: Maintain the publication-specific Bunny settings and the verified Docker journald/rsyslog/Caddy configuration. Recheck the complete path when configuration changes; distinguish legacy archives from new output. Obtain missing original-IP, separate provider-log and Hostinger platform/network retention evidence, and keep Sentry release/environment identity plus project retention under its separate acceptance checks.
- Product / counsel: Review Google Signals and the indefinite GA4 BigQuery export, both currently enabled, before treating the present analytics configuration and retention as legally approved.
- Release gate: Complete the pending operator, provider-console and live deletion/export checks, then record owner acceptance of this factual disclosure before the account launch reaches production. Update this inventory and policy again before activating another vendor, ads or subscriptions.
- Release gate / Batch 8: Keep each conditional integration absent in production until production inventory facts, notice rendering, and live acceptance support activation. Staging enforces its own host-local protected profile and is not presented here as production evidence.
Changes
A material data-practice change must update the typed inventory, its regression tests, this notice version and effective date before release. Historical Git versions provide the change record.