@dscodotco/compliance-gates
v0.1.1
Published
Config-driven legal-compliance gates for e-commerce/subscription sites: ADA/a11y (Biome preset), ARL auto-renewal, CCPA, CAN-SPAM, Prop 65, and research-use-only disclosures. Runs in CI + pre-commit.
Downloads
324
Readme
@dscodotco/compliance-gates
Config-driven legal-compliance gates for e-commerce / subscription sites — the "easy lawsuit" surface, enforced in CI and pre-commit so it can't silently regress.
Not legal advice. These gates enforce that a required disclosure, link, warning, or control is present where the law expects it. They cannot judge whether the wording is legally sufficient — that's a job for counsel. Their value is stopping the common regression: the required element quietly disappearing from a page.
Two halves
ADA / accessibility (a Biome preset).
@dscodotco/compliance-gates/biometurns on Biome's fulla11yrule group at error. Extend it from yourbiome.json:{ "extends": ["@dscodotco/compliance-gates/biome"] }This makes WCAG-adjacent issues (missing alt text, unlabeled controls, keyboard handlers, ARIA misuse) fail
biome check.Content gates (a CLI).
compliance-checkscans your source for the disclosures/links/warnings the other laws require, driven by acompliance.config.ts:import { arlAutoRenew, ccpaPrivacyChoices, prop65, canSpamFooter, ruoNotice, accessibilityStatement, noPreCheckedConsent } from "@dscodotco/compliance-gates"; export const config = { checks: [ ccpaPrivacyChoices(["surfaces/**/footer*.tsx", "surfaces/**/layout*.tsx"]), accessibilityStatement(["surfaces/**"]), arlAutoRenew(["surfaces/**/checkout/**", "surfaces/**/subscribe*.tsx"]), prop65(["surfaces/**/products/**", "surfaces/**/product-*.tsx"]), canSpamFooter(["modules/comms/**/templates*.ts"]), ruoNotice(["surfaces/storefront/**"]), noPreCheckedConsent(["surfaces/**"]), ], };Then run
compliance-check(exit 1 on any violation).
Covered categories
| Check | Law | What it asserts |
|---|---|---|
| arlAutoRenew | CA ARL §17600 / ROSCA / FTC Click-to-Cancel | A subscription/auto-renew UI also discloses the auto-renewal terms |
| ccpaPrivacyChoices | CCPA/CPRA §1798.135 | A "Your Privacy Choices" / "Do Not Sell or Share" control exists |
| prop65 | CA Prop 65 §25249.6 | A product / add-to-cart UI carries a Prop 65 warning |
| canSpamFooter | CAN-SPAM §7704 | A marketing email template carries an unsubscribe link + postal address |
| ruoNotice | FDA RUO labeling / FTC | The research-use-only notice is present |
| accessibilityStatement | ADA / CA Unruh | A public accessibility statement exists |
| noPreCheckedConsent | ROSCA / FTC negative-option | No pre-checked consent inputs (dark pattern) |
| (Biome preset) | ADA Title III / CA Unruh | a11y rules at error |
Check kinds (engine)
- required-somewhere — at least one file in
globscontains one ofanyOf. - conditional — any file matching a
triggermust also contain one ofrequire. - forbidden — no file may contain any of
forbidden.
A required-somewhere or conditional check whose globs match zero files fails ("gate scoped to nothing"): a gate pointed at a path that doesn't exist — or whose target file was deleted — must never read as green.
Matching is case-insensitive substring (grep-grade). Zero runtime dependencies.
Wiring
- Add
"compliance": "compliance-check"topackage.jsonscripts. - Run it in CI and in a pre-commit hook (alongside
biome check).
Status
Alpha (0.x). Built for the RUO Pro platform; being generalized for open source.
