The core may not import a domain. A domain may not import another domain. The HTTP layer may not reach past the service layer.
These are rules we enforce with a linter, and for a while we enforced them the way everyone does: write the rule, watch it pass, move on.
Then one of them stopped working — a config refactor changed a path pattern and the rule silently matched nothing — and we did not find out for five weeks.
Fixtures that break on purpose
test/lint-fixtures/ now contains exactly one deliberate violation per rule:
test/lint-fixtures/
core-imports-domain.ts
domain-imports-domain.ts
route-skips-service.ts
The lint task runs twice. Once over the real source, where it must report nothing. Once over the fixtures, where it must report exactly one violation per file — and the task fails if any fixture comes back clean.
A rule that has stopped matching now fails the build the same day.
What this is really about
Any control you cannot observe failing is a control you are taking on faith. That applies to boundary lint, to the vector gate, to alerting, and to the backup you have never restored.
The cheap version of the fix is usually this: keep one thing around that is supposed to trip it, and check that it does.
A README per directory
The other half is documentation adjacent to the rule. Each directory carries a
README.md that states what may import what and, more usefully, which defect
the rule prevents.
“Core may not import a domain” is a constraint someone will eventually argue with. “Core may not import a domain, because the last time it did, a YouTube schema change took down the maps actor” is not.
Ada Okafor
Head of Data