Platform laws
These rules apply to every repository in the A11Y platform: the detector, the regression API, the dashboard, the extension, identity-and-billing, the Reporter, and the resolver. They exist because several products share one identity service, one detector database and one Cognito pool, so a change that looks local to one repo can take down another product.
This page is the canonical copy. Each repo's CLAUDE.md and .claude/rules/ point here instead of repeating the text. To change a law, open a PR against this page; the CTO approves it.
How a law is checked:
- CI:
scripts/check_platform_laws.shin the repo greps for the forbidden pattern. It starts in warn mode and switches to fail mode at the end of the realignment. - Contract: the repo's contract test suite fails when a response field is removed or renamed.
- Review: no reliable automatic check; reviewers and CODEOWNERS enforce it.
| Law | Rule | Why | Check |
|---|---|---|---|
| L1 | Only the identity-billing Worker reads or writes the identity-and-billing database. Everything else calls its API. | Today the detector, the regression API and the Worker all write users and subscriptions directly, each with its own idea of the schema. One access point means one set of rules. | CI: identity-and-billing or MONGO_USERS_FIXED_DB outside the allowed paths |
| L2 | Plan numbers (credits, caps, prices) live only in the I&B plans / addons collections. | The resolver's plan numbers are duplicated in three places, and they drift. | Review; CI once the collections exist |
| L3 | Nothing writes to snap_shots after process_order creates the document. Order state lives in test_orders. | A snapshot is the configuration of a test; mixing order state into it is what makes it impossible to reuse or cache safely. | CI: update_one / update_many on snap_shots outside process_order and the migration scripts |
| L4 | Regression may write only these fields of detector collections: test_orders.qa_status, test_orders.manual_review_time, and the source-id unsets. Temporary, until the detector exposes an API for them. | Regression reaching into detector collections is the main source of schema coupling between the two services. | Review |
| L5 | The detector detects and deduplicates. No report wording, colour suggestions, translations or exports. | Report generation belongs to the Reporter service; keeping it in two places produced two different reports for the same findings. | Review |
| L6 | The resolver never calls the Reporter. | The resolver ships to clients with a pinned detector; a runtime dependency on the Reporter would couple two release schedules. | Review |
| L7 | No Cognito pool ID, client ID or domain hardcoded in app code. Use /auth-config / AUTH_ISSUERS. Until the identity layer lands, don't add new occurrences. | Hardcoded IDs are what make a per-stage pool, a per-app client or a login-provider switch a multi-repo change. | CI: occurrences counted against a baseline that can only go down |
| L8 | LLM detection caching only through LLMDetectionStore. Until that store lands, only through LLMVisionManager with its cache-hit checks. | A cache keyed wrongly silently reuses results from another page or order, which shows up as missing findings. | Review |
| L9 | Schema changes only through idempotent dry-run scripts plus ensure_indexes. | Hand-run console changes are not repeatable across dev, qa and prod, and are how the stages drifted apart. | Review |
| L10 | Expand → migrate → contract. No breaking change to a field, endpoint or collection that something still reads. | Clients deploy on different schedules, and the Chrome Web Store version lags the code. | Contract |
| L11 | Dashboard-impacting and extension-impacting deploys never happen on the same day. | They share the detector API and the Cognito client; one bad day must not take both down. | Review; the deploy calendar |
| L12 | Never print or commit secrets, cookies or .env values. | A committed key has already had to be rotated. | Review; secret scanning |
| L13 | identity-billing is product-agnostic: no product slug in its code (the one marked compat default excepted). Products, plans, add-ons and initial settings are data. | It is the company-wide service for users, subscriptions and plans; code that assumes one product blocks every other product. | CI in identity-and-billing |
Terms
- Dashboard-impacting: the regression API, the regression authorizer, and the dashboard build or its Cognito client.
- Extension-impacting: the detector API, the detector authorizer, and the extension build or its Cognito client.
- identity-billing Worker: the Cloudflare Worker in the
identity-and-billingrepo, deployed asidentity-billing(prod) andidentity-billing-nonprod(dev and qa).
