TestingDecision Tree
Decision Tree
When you ship a change, ask these questions in order. The first "yes" tells you which gate(s) to write or extend. You can stop at the first match or continue if your change touches multiple layers — gates compound.
Did your change touch the OpenAPI spec or any of its generated artifacts?
Yes →
openapi-validationalready runs; if your edit introduces a new MCP-exposed operation, the gate enforcestool_name+min_tier+x-matter-lifecycle.primaryfor it. Runbun run gates --gate=openapi-validationlocally.openapi-mcp-driftrunsgenerate-mcp-tools.tsagainst the new spec. If your edit changes the catalog, regenerate viabun run --filter matter-mcp-server generate-toolsand commit. Don't manually editapps/mcp/src/tools/generated.ts.
Did your change add or rename a route in apps/app?
Yes →
card-action-targetsalready runs. Any newnavigate.totarget in an exemplar CardSpec must resolve. If you added a new route, no action needed. If you renamed one, update any exemplar that referenced the old path.route-manifest-propertyruns against the framework's own matcher; nothing to do unless you changedroute-manifest.tsitself.
Did your change add a new typed Matter resource ID prefix (abc_...)?
Yes →
- Add the prefix to
packages/components/src/cards/resource-urls.tsRESOURCE_URL_BUILDERS. Map it to its canonical dashboard URL.card-action-targetswill then resolveopen_resourceactions for that prefix.
Did your change touch the brand tokens (TS or CSS)?
Yes →
brand-tokens-driftasserts TS-CSS parity for the signature colors. If you added a new canonical color, extend thechecksarray in the gate. If you changed an existing color value in TS, update tokens.css to match (or vice versa).
Did your change touch the Prisma schema?
Yes →
- Run
bun run migratelocally.prisma-schema-driftasserts the schema is canonically formatted. - For schema-to-client drift, the standard
bun run migrateworkflow regenerates the client; no extra gate yet.
Did your change add or modify an AI emission (CardSpec, MCP tool output, document draft)?
Yes →
agent-output-schemaasserts every exemplar parses againstCardZ. If your change modifiesCardZ, every exemplar must still validate; update them in lockstep.- For new AI capabilities, add a case to
__evals__/<your-flow>-cases.jsonand write aneval-mode gate (template atpackages/testing/templates/eval.template.ts).
Did your change touch the assistant's voice (marketing copy, brand README, docs index pages)?
Yes →
voice-judgeruns in shadow mode againstpackages/brand/README.md+CLAUDE.md. Add your surface to theSURFACESarray in the gate if it's load-bearing voice copy.- Set
ANTHROPIC_API_KEYlocally to activate the judge.
Did your change introduce a new third-party dependency?
Yes →
dependency-auditwrapsbun auditand runs on every PR. No action needed unless a finding appears — then either upgrade the dep, swap it, or add an allowlist entry tied to a tracking issue + expiration.
Did your change touch the dispatcher's resolveResourceUrl or any pure parsing / matching function?
Yes →
dispatcher-fuzzandroute-manifest-propertycover those two specifically. For new pure functions, write a property gate usingpackages/testing/templates/property.template.ts. Property gates catch invariant violations example-based tests don't reach.
Did your change add or change a security-sensitive surface (auth, secrets, key handling)?
Yes →
secret-scanalready runs on every commit and PR. If your change adds a new key prefix Matter mints, extend the patterns inpackages/testing/src/gates/secret-scan.gate.ts.- Consider writing a
mode: "static"+category: "security"gate that asserts your specific invariant (e.g. "nosk_live_*ever flows through this code path").
Nothing above matched my change
That's a signal in itself. If your change touches a surface no gate covers, ask:
- Could a small static check have caught the most likely regression class? (Often yes — emit a Finding when condition X is violated.)
- Could a property test assert an invariant over your function's input domain?
- Is there an "X must stay in sync with Y" relationship a drift gate would catch?
Write the gate. Templates at packages/testing/templates/. The framework's interface is complete — new gates just need a *.gate.ts file anywhere.