Public identity and data minimization

Comments may be posted as a named guest, an anonymous guest, with an attributed account, or anonymously while signed in. An authenticated comment shown as Anonymous is still associated with its account internally for ownership, moderation, and abuse handling; it is anonymous only to ordinary public readers.

Account and comment identity is text-only. This site does not display or retain profile pictures, provider avatars, or user-uploaded identity images. Public responses do not expose email addresses, session IDs, network identifiers, provider tokens, moderation metadata, internal account IDs for anonymous comments, or guest-key secrets and digests.

Guest keys, local storage, and recovery

A guest edit key is a bearer capability: anyone with the complete key can control that comment. The browser creates the locator and 256-bit secret. The server stores the locator and only a SHA-256 digest of the secret, so this site cannot reconstruct a lost secret. Keep the key private and do not save it on a shared device.

Before the first POST, the browser durably stages the raw key, a create-idempotency ID, and the content ID in local browser storage. It does not duplicate the comment body there. After a confirmed or recovered submission, the browser promotes the key to the saved comment mapping. This protects ownership if a response is lost or a tab crashes. You can remove saved and pending keys from the guest-key page or clear this site's browser storage.

A separately saved full key can recover its exact pending, approved, or rejected comment without knowing the comment ID, but only while that comment and credential remain within their retention windows. Losing both the browser copy and any separately saved key is not recoverable by the operator.

Abuse controls, visitor cookie, and Turnstile

Anonymous write routes may set a random, first-party, HttpOnly __Host-visitor_id cookie for up to 30 days. It is used only as a coarse abuse-control signal, not for analytics, public identity, ownership, or advertising, and it is not available to site JavaScript.

A separate purpose-keyed limiter value is derived transiently from the network address Cloudflare supplies for the current request. The raw address and derived limiter key are not stored or logged as ordinary application data. If a longer-lived application abuse hash is needed, it is separate from ownership credentials and normally expires after 30 days.

Guest writes, reports, and key recovery may require Cloudflare Turnstile. The browser sends the challenge result for server-side verification; Turnstile is independent of the visitor cookie and never grants ownership. Cloudflare processes challenge and network/browser signals under its own service terms and privacy practices.

Moderation, deletion, and reports

Guest comments are normally pending until reviewed. Approved edits may return to review. Rejected comments may be edited and resubmitted; spam-marked comments cannot be edited, although their owner may delete them. Public prose disappears immediately on deletion, while a minimal tombstone may remain when needed to preserve a reply tree.

Reports store a structured reason and may include optional free-form details. Guest reports require Turnstile; authenticated reports are rate-limited. Report and moderation data is restricted to authorized administration. Free-form notes are minimized sooner than the structured audit record and must not be used to duplicate comment text unnecessarily.

Retention windows

Expiry is enforced when data is read, even if scheduled physical cleanup has not run yet. Inactivity windows can move after a valid owner edit, but absolute caps and hard expiries do not restart. A finite, reviewed security or privacy incident hold may apply only where explicitly stated.

  • Ordinary previous or deleted prose: 14 days. A body already protected as spam evidence may remain only through its original later deadline; deletion does not restart that deadline.
  • Completed create-idempotency protocol record: 24 hours. Revoked guest credential verifier: 14 days.
  • Never-public pending prose: 30 days of inactivity, capped at 180 days from creation.
  • Previously public prose pending re-review: 90 days of inactivity, capped at 180 days for that hidden episode.
  • Rejected hidden prose: normally 30 days from rejection without extending an existing absolute cap. Spam evidence: 30 days from the spam decision and not refreshable by the owner.
  • Resolved or dismissed report: 90 days after closure. An open report's structured workflow record remains while genuinely open, but its free-form details are minimized after 365 days unless a finite audited incident hold applies.
  • Stored application abuse identifier: normally 30 days. Moderation audit: full metadata for 90 days, then minimized, and normally deleted after 365 days.

Accounts, sessions, and linked sign-in providers

Better Auth manages account, linked-provider, session, verification, and rate-limit records in the site's database. GitHub and Google sign-in request only the configured minimal scopes. Automatic same-email linking is disabled; linking and unlinking are explicit, and at least one sign-in method must remain. Provider/account identity and tokens are not copied into comment rows.

When provider OAuth tokens must be stored for an account, Better Auth encrypts them. Sessions use secure first-party cookies, origin and CSRF checks, and the Cloudflare-provided client IP address for account-security, session, and auth rate-limit behavior. Arbitrary forwarded-IP headers are not trusted. Auth session IP data is not copied into comments, analytics, moderation logs, or ordinary application logs and follows Better Auth's session and account lifecycle.

Public account identity is limited to a validated text display name. This site does not use provider avatars. Your provider may separately process sign-in activity under its own privacy terms.

Account deletion

Account deletion requires a sufficiently recent verified session and runs as a retry-safe process. While it is pending, attributed comments fail closed to “Deleted user,” anonymous account comments remain “Anonymous,” and new account-owned mutations and links are blocked. Approved technical discussion is retained unless you separately delete the comment.

The process removes the Better Auth account and linked provider state, unlinks internal account IDs from application records, and clears display data that is no longer required. Its minimal coordination record contains no provider tokens or comment bodies; after completion its user ID is cleared and the record normally expires after 30 days. A minimal recovery-journal event is recorded first so an older restore cannot silently recreate the account.

Backups, recovery journal, and restores

Once meaningful dynamic production data exists, D1 exports are copied daily to a private backup R2 bucket in the same Cloudflare account. Daily copies are retained for up to 90 days and 12 monthly restore points are retained. Because this is a same-account secondary copy, it does not protect against every Cloudflare-account failure.

Disaster-recovery copies may physically contain data longer than it is visible in the live application, until backup rotation removes the copy. They are not ordinary admin-readable history. A restored database immediately applies logical expiry and cleanup before normal use.

A separate minimal recovery journal records comment, moderator, and account deletion intent without bodies, names, email, guest secrets, provider tokens, or session tokens. Restore promotion replays those intents so an older copy cannot silently resurrect deleted data. Missing or corrupt required journal coverage blocks promotion.

Every restore invalidates all restored Better Auth sessions and transient verification or OAuth state, requiring a new sign-in. Encrypted linked-account/provider state needed for non-deleted accounts may remain, while journaled deleted accounts are removed or unlinked before promotion.