LegitimeterPrivacyTermsSupport

DRAFT - NOT LEGAL ADVICE

Legitimeter Privacy Policy (draft for counsel review)

Drafted 2026-10-01 by agent DjSYhkPZ for CFo0ETXT (P5). Every data statement below is grounded in the code at the cited file:line, as read on 2026-10-01; where code and this text disagree, the code governs and this draft is wrong. {{OWNER}} = a fact only the owner can supply; {{COUNSEL}} = a legal judgment for the attorney (see ATTORNEY_BRIEF.md). Regime sources: docs/STRATEGY_GAPS.md section 3.


1. Who we are

Legitimeter is operated by Holoschema LLC, a Texas limited liability company (Texas SOS file #6000019436), {{OWNER: postal address}}, contact support@legitimeter.com (web: https://legitimeter.com/support). EU representative (GDPR Art 27) and UK representative: {{OWNER/COUNSEL: appoint before EU/UK entry}}.

2. The short version

3. What we collect, exactly

3.1 Usage counts (analytics)

FieldWhat it isSource
install_id128-bit random number, not derived from any key or identity; resettable to a new, unlinked oneanalytics.mjs:8, :31, :56
daycalendar date (YYYY-MM-DD)analytics.mjs:32
countsinteger counts of named events from a fixed list only: install, first_value, opt_in, register, plan_view, checkout_start, paid, active, chip_shown, label_feedback, report_problem, crash, error, mark, undo, donation, uninstall_surveyanalytics.mjs:11-16, :35-38

No other key is accepted (analytics.mjs:29). When switched off, nothing is stored and zero requests are made (analytics.mjs:9-10).

**In-product notice (verbatim, USAGE_NOTICE_COPY, packages/adapter-chromium/src/ui.mjs:170, commit 9b8e272; INTERIM DRAFT approved by A0 ruling 2026-10-01 16:48):**

Legitimeter counts which features are used, with a random install ID. No names, accounts or browsing history. You can switch this off anytime in Settings.

Button: "Allow usage counts" (shown in every region; Settings lets you switch counting off again). This policy must match that constant word for word. Any wording change is made in that one place, and test/usage_notice.test.mjs guards it.

How it behaves (G11):

Earlier default-ON behaviour (user ruling v271, counting after the notice outside opt-in regions) was retired on 2026-10-20: usage counting is now opt-in on every browser and in every region. {{COUNSEL}} Confirm that the notice plus the "Allow usage counts" button is valid opt-in consent in every region (ATTORNEY_BRIEF Q3).

The server computes cohort retention (D1/D7/D30) from these counts (packages/server/src/usage.mjs:5, :177-180).

3.2 Contributions (opt-in only)

If you turn on contribution, your device sends a judgment about a public account, never the account name itself:

FieldWhat it isSource
epocha period label such as 2026-W39core/src/privacy_gate.mjs:21, :29-34
entity_keya keyed hash (HMAC-SHA256) of platform + handle under a rotating epoch key; the raw handle is refusedprivacy_gate.mjs:36-39, :84
contributor_ida keyed hash of a device secret + epoch, so contributions are unlinkable across epochsprivacy_gate.mjs:41-44
axesnumeric scores and confidences in [0,1] for named signal axesprivacy_gate.mjs:46-61

Only these four keys are allowed (privacy_gate.mjs:19, :78-88).

The contribution record path also carries timing: observed_at (when your browser received the item) leaves the device only floored to a 15-minute UTC bucket, and full precision stays on the device; an unparseable time is refused (core/src/contribution.mjs:59, :65, :93; PV1 c2629694, commit e5533c2). authored_at is the public post's own time. content_hash is an unsalted hash of public content: someone holding the same public item could learn that some contributor received it in a given quarter-hour, but no identity is attached (wording aligned with docs/CHROMEWEBSTORE.md 'Disclosed costs'). Marks carry a month period (YYYY-MM).

Served results: aggregated entity results are served only once at least DEFAULT_K = 5 contributors agree (with a banded cold-start minimum of 2 distinct contributors), so a single user's contribution is never served alone (privacy_gate.mjs:16-18).

3.3 Account (optional; needed only for paid tiers)

FieldWhat it isSource
public_keyEd25519 public key (64 hex); the private key never leaves your deviceidentity.mjs:8-9, :25-34
account_idSHA-256 of the public keyidentity.mjs:8, :37-44
nonce, signaturesingle-use proof of key possessionidentity.mjs:10, :31-32; server nonces expire (server/src/auth_challenge.mjs:33-49)

No email, name, phone or password is collected by the account system. Payment details, when live, are collected by the payment provider, not by us (server/src/payments.mjs:10-12; see MERCHANT_OF_RECORD.md).

Referral codes are derived only from account_id; no personal data is involved (server/src/referral.mjs:10-12).

3.4 Problem reports (only when you send one)

Keys: operation, category (fixed list), message (length-capped; refused if it contains a URL or handle), diagnostics = analytics_enabled, browser_family, ext_version, policy_name, error_counts (core/src/problem_report.mjs:47-54, :57-80). You see the exact body before sending.

3.5 Peer-to-peer list sharing (if enabled)

The relay keeps peer announcements in memory only, with hard caps and a 10-minute expiry (server/src/p2p_server.mjs:12, :26). {{COUNSEL}} whether this makes us an intermediary under the DSA / UK OSA (STRATEGY_GAPS L-DSA).

3.5a Trust-list updates (automatic, no personal data)

About once a day (24 hours plus a random delay of up to 1 hour), the extension downloads a public, signed list of content-credential (C2PA) trust anchors from our own release server. The request is identical for every user: it names only the list (c2pa_trust) or a chunk's SHA-256 hash, sends no cookies, headers, body or referrer, and carries no account id, page address, browsing data or verdict (adapter-chromium/src/trust_sync.mjs REQUEST_INIT, requestUrl). A list is used only after its release signature and every chunk hash verify; otherwise the built-in list is kept. It can be turned off in Options. Status: built but not yet switched on; no release host is configured (DECISIONS.md, 2026-10-02 trust-list sync rulings). Hosting logs for this request are covered by 3.7.

3.6 What stays on your device only

Verdicts, entity history, exact timestamps, raw handles, page content, private signing keys, and your labels/preferences.

3.7 Server logs and IP addresses

The server code does not record client IP addresses (the only address check is a loopback guard on the local operator dashboard, server/src/dashboard.mjs:104). Our service is hosted on Cloudflare (edge network, static pages and request routing) and Hetzner (the API server). Our API server keeps no access log. Cloudflare processes your IP address to route and protect requests and may keep it in short-lived operational logs; we keep no copy of those logs for longer than 30 days. {{OWNER: confirm the 30-day figure and the Hetzner region}}

4. People we label (non-users)

Legitimeter shows probabilistic signals about public accounts. Under GDPR this is processing of those people's personal data even though they are not our users. Our basis is {{COUNSEL: legitimate interest (Art 6(1)(f)) + LIA}}. Because we cannot give each labeled person notice directly, we rely on {{COUNSEL: Art 14(5)(b)}} and publish 'How Legitimeter decides' (LABELING_POLICY_DRAFT.md). Any labeled person may object or request correction through the dispute path (TERMS_OF_SERVICE_DRAFT.md section 'Disputes'; owned by peer fvcXO9t8). Labels never produce legal or similarly significant effects by themselves; each user decides what to do ({{COUNSEL}} GDPR Art 22 position). Country of origin is display-only and never changes a verdict (adapter-chromium/src/channel_quality.mjs:4, decision D11).

5. Why we process data (purposes and bases)

DataPurposeEU/UK basis {{COUNSEL}}US (CCPA/TDPSA) category
Usage countsfix bugs, measure retentionconsent (EU/UK, pending G11); legitimate interest elsewhereinternet/usage activity; not sold or shared for targeted advertising
Contributionsimprove shared authenticity intelligenceconsent (opt-in)inferences about public accounts
Accountentitlement, quota, payment linkagecontractidentifiers (pseudonymous)
Problem reportssupportconsent (user-initiated)usage activity
Waitlist (email, product, time joined, optional account link)launch notificationconsent by submitting the form [OWNER/COUNSEL TO CONFIRM]; retention [OWNER DECISION PENDING]identifiers (email)

We do not sell personal data, and we do not 'share' it for cross-context behavioral advertising (CCPA/CPRA). We do not process sensitive data. We do not knowingly collect data from children under 13 (16 in the EU) (COPPA).

6. Retention

{{OWNER/COUNSEL}} per store once deployed. Code-level facts: nonces expire (auth_challenge.mjs:33-49); P2P announcements expire after 10 minutes (p2p_server.mjs:26); contributions are keyed per epoch (privacy_gate.mjs:41-44); referral credits are time-bounded windows (referral.mjs:7-8, :23-24).

7. Your rights

We do not collect a name or email for your account. If you join a waitlist, we store the email address you enter, the product name and the time you joined. You prove a request by signing it with your device key (account holders) or by giving your install_id (Options page).

What "Delete all" keeps (source of truth: docs/DATA_INVENTORY.md section 4, commit ac92729; the server keep-set is PAID_KEEP_FIELDS at server/src/accounts.mjs:41, applied at :205-217, and pinned by packages/server/test/data_rights_ops.test.mjs:38,93 (cf60ec8)):

To remove a waitlist entry, email [OD-2 CONTACT EMAIL] from the address you used and we will delete it. Your IP address is kept only in memory, in hashed form, to limit abuse, and is never written to storage.

We respond within 45 days (CCPA/TDPSA) or 1 month (GDPR).

8. Transfers and processors

The API server is hosted by Hetzner Online GmbH in {{OWNER: Hetzner region (Germany, Finland or US)}}, behind Cloudflare, Inc. (edge network and static pages). EU/UK transfers to the US: {{COUNSEL: DPF/SCCs}}. Processors: hosting Hetzner Online GmbH and Cloudflare, Inc.; payments Paddle.com Market Limited, which acts as Merchant of Record and is an independent controller for payment and tax data. No advertising SDKs and no third-party analytics are embedded; analytics go only to our own endpoint (analytics.mjs:46-50).

9. Security

Signed requests (Ed25519), single-use nonces, credential-less requests, keyed hashing of handles, and k-anonymity thresholds on served results (citations above).

10. Changes and contact

Material changes are announced in the extension before they take effect. Contact: {{OWNER}}.


Pre-publication checklist (for owner and agents, not part of the public policy)

  1. G11: EU/UK opt-in analytics (owner ruling, then agent).
  2. 'Delete all' exists in server/src/accounts.mjs, and its retention is set out in DATA_INVENTORY section 4 (ac92729). Device side: pinned by packages/adapter-chromium/test/data_rights.test.mjs:122 ('delete all, paid plan: keeps only the entitlement keys and says so'), which checks the keepIfPaid keys in REGISTRY (src/data_rights.mjs:49). Server side: pinned by packages/server/test/data_rights_ops.test.mjs:38,93 (cf60ec8). After a paid delete-all, the stored keys equal PAID_KEEP_FIELDS exactly and a signed entitlement call still returns paid:true. A free delete-all erases everything, verified by read-back. A cross-account export or delete returns 401 (Kf7mIPiv, 2026-10-01 19:24).
  3. Host and log retention confirmed after deployment (f742bcab).
  4. Counsel answers on Art 6/14/22, DPF/SCCs and DSA (ATTORNEY_BRIEF.md).
  5. Re-verify every file:line above against the release commit.

DRAFT - NOT LEGAL ADVICE