Skip to content

Trust

Built to be defensible.
Documented to be auditable.

Server-stamped customer agreements. Append-only financial and assent ledgers. Policy versioning with a pre-commit drift gate. GPC-honored consent. A documented review posture — not a legal certification.

ImmutableAppend-only at the database level
VersionedEvery policy carries a pinned-version permalink
SignedOutbound webhooks HMAC-SHA256
AuditableOne row per money, agreement, and admin event

21+ age gate

A 21+ affirmation, on the door and on every order.

Visitors must affirm they are 21 years of age or older and acknowledge the research-use-only nature of USPP products before they can browse or check out. The affirmation carries the 503A/503B statutory position and the operator-locked "will not administer, ingest, inject…" warning.

Acknowledgement persists in local storage with a 30-day TTL and is re-stamped onto every order at checkout (age_ack, age_ack_version) — so the record on each order is the version active when that researcher actually agreed.

A failure-to-affirm routes to a dedicated /restricted-access page that is intentionally bare: no analytics, no shared chrome, locked operator-dictated text.

What gets captured per order

  • 21+ affirmation version active at checkout
  • Local-storage TTL: 30 days
  • Statutory positioning: 503A / 503B
  • Fallback page: /restricted-access (locked copy)

Privacy Choices opt-out

A standalone CCPA / CPRA opt-out at /privacy-choices.

Three toggles — do not sell or share, limit targeted advertising, limit sensitive personal information — plus a GPC pill that reflects the current signal.

Preferences sit in two tables: privacy_preferences keyed by anonymous anon_id for un-logged-in visitors, and privacy_preferences_customer keyed by customer_id for signed-in researchers. A migration on account creation carries anonymous preferences across, idempotently.

Every toggle change writes one append-only row to privacy_audit_log — field, previous value, new value, source (user / GPC / agent request / migration), consent version, truncated user agent. The audit log carries no IP address (data minimization).

Audit row shape

  • Field changed
  • Previous value → new value
  • Source: user, GPC, agent request, migration
  • Consent version at the moment
  • Truncated user agent
  • No IP captured

order_assent row, per order

  • RUO, age, shipping, combined-legal acknowledgement versions
  • Snapshots: Terms of Sale, Terms of Use, Privacy Policy, RUO disclaimer
  • Age-gate version, consent-banner version, banner mode (gdpr / ccpa / none)
  • SHA-256 hash of the exact checkbox text shown at submission
  • Customer IP (XFF leftmost via Vercel, req.ip fallback)
  • Truncated user agent
  • assented_at timestamp

Order-time agreement capture

Every order writes one immutable assent row, server-stamped.

At order create, the server stamps the exact policy version active at submission, the customer IP, the user agent, and a SHA-256 hash of every checkbox label the researcher just acknowledged. The row lands in order_assent, which is append-only at the database level.

Corrections never overwrite. A financial_postings_immutable-class trigger raises an exception on UPDATE or DELETE; new rows point back via reverses_id when an event has to be re-stated.

The base orders table additionally carries the RUO acknowledgement text (ruo_ack_text) and version (ruo_ack_version) directly on the order row as a fallback evidence layer, plus an append-only order_status_log capturing every from/to status transition with actor and reason.

The customer IP capture is the chargeback-evidence layer: any later dispute can verify the exact wording the researcher saw and the network they submitted from.

Policy versioning

One registry, canonical text exports, pinned-version permalinks, pre-commit drift gate.

policy-versions.json is the single source of truth: every policy slug carries a current version, source type (canonical text export, versioned HTML, or static HTML), and a version history.

Canonical text exports live in lib/policy-text.jsRUO_AFFIRMATION_TEXT, AGE_AFFIRMATION_TEXT, AGE_GATE_TEXT, and others — so every surface that displays them reads from one place.

Versioned legal HTML lives under legal-content/<slug>/<YYYY-MM-DD-vN>.html as immutable historical artifacts. Pinned URLs (/legal/:slug/:version) serve any historical version on demand — so a researcher (or their counsel) can read the exact terms they agreed to at order time.

A pre-commit hook (tools/policy-check.js, installed per worktree via tools/install-hooks.sh) hashes the current-version files. Any edit to a policy surface that forgets to bump policy-versions.json blocks the commit.

The drift gate at commit time

  • Hashes every current-version policy file
  • Compares to policy-versions.json
  • Mismatch → commit blocks
  • Operator must bump the version, then commit
  • Historical versions stay immutable and pinned

financial_postings columns

  • kind: sale, refund, tax_collected, tax_refunded, shipping_collected, discount, adjustment
  • rail: bankful, venmo, solana, btcpay, zelle, manual
  • jurisdiction: US-TX or US-OTHER (from shipping address)
  • idempotency_key: UNIQUE — safe for live hook + daily backstop
  • reverses_id: reversal-chain pointer
  • Indexes: period-by-kind, jurisdiction-by-period, rail-by-period, order-level

Immutable financial postings

One row per money event. One reversal chain. One export path.

financial_postings is the canonical money ledger. Every sale, refund, tax collection or refund, shipping collection, discount, and manual adjustment writes exactly one row. Append-only at the database level: UPDATE and DELETE raise an exception. Corrections must point back via reverses_id.

A unique idempotency_key lets the live posting hook (fires on paid + refund) and the daily backstop cron (catches anything missed) both run safely against the same event.

lib/finance-export.js produces a QuickBooks IIF export with configurable account mapping (TRNS / SPL / ENDTRNS blocks) plus a CSV path for per-period journal import.

Audit logs

Ten append-only tables. One per concern.

Every operationally meaningful action writes to an append-only audit table. None of these tables permit UPDATE or DELETE through application code; some are protected by a database trigger.

Table What it records
order_assent Customer agreement capture at order time: versions, snapshots, checkbox-hash, IP, UA, timestamp.
order_status_log Every from-status → to-status transition with actor, reason, timestamp.
financial_postings Every money event with reversal chain, idempotency key, jurisdiction, rail.
customer_audit_log CRM mutations (note delete, tag delete, task delete) and authentication events.
customer_tier_audit Per-researcher pricing-tier changes with admin email and reason.
privacy_audit_log Every privacy-preference change with source (user / GPC / agent / migration).
stock_ledger Every inventory movement: receive, allocate, return, reconcile, adjust.
webhook_outbox Every outbound webhook attempt with status, attempt count, error.
rate_limit_hits IP + bucket + timestamp for rate-limit enforcement.
coa_files COA upload metadata.

Research-Use-Only copy controls

A documented review skill, canonical text exports, locked compliance surfaces.

USPP positions as a chemical supplier to researchers — not a pharmacy, supplement vendor, wellness brand, or therapeutic provider. The project carries a dedicated SEO Regulated Claims Guard skill at .claude/skills/seo-regulated-claims-guard/ with three files: a procedure (SKILL.md), a rule posture (RUO_COPY_RULES.md), and 37 numbered regex rules with category, rationale, and suggested rephrasing (HIGH_RISK_PHRASES.md).

Required vocabulary includes "researcher" (never customer / user / patient), "chemical supplier" (never vendor), "released" or "analytically released" (never approved / verified for use / certified), "lot" (preferred over batch), and "RUO" present at least once per product or policy page.

Hard bans cover therapeutic verbs, human-use guidance, outcome claims, superlatives, supplement framing, comparative-drug claims, and bodybuilding lexicon.

Honest scope. The skill is a documented review process, not a build-time enforcement. The codebase contains two operator-marked review traces (an explicit row-19 exemption comment in the landing and bundle pages) but does not contain an automated log proving every existing storefront string has been scanned. Site-wide application of the guard against every researcher-facing surface remains an operator follow-up.

Surfaces under explicit version control

  • RUO affirmation at checkout (RUO_AFFIRMATION_TEXT)
  • Age-gate text + 21+ affirmation (AGE_GATE_TEXT, AGE_AFFIRMATION_TEXT)
  • Shipping affirmation, combined-legal statement, consent-banner copy
  • Every versioned legal HTML body under legal-content/<slug>/
  • Pre-commit hook blocks edits that forget the version bump

Security & reliability

Six controls that anchor the perimeter.

Need to verify a specific control?

Every claim above maps to a documented code path. Email the team if you want to walk through a specific safeguard for compliance review or audit.

  1. 21+ age gate & statutory posture
  2. Jurisdictional consent (GDPR / CCPA / GPC)
  3. Privacy Choices opt-out
  4. Order-time agreement capture
  5. Policy versioning & drift gate
  6. Immutable financial postings
  7. Audit logs
  8. Research-Use-Only copy controls
  9. Security & reliability
  10. Honest framing
Talk to the team →