Feature tests
A feature test drives the real app in a real browser. The harness records the evidence during the run; the test itself can only drive the app:- The video is a screen recording of the app under test.
- The data snapshots are read from the app’s database, before and after the flow.
- The service calls are captured at the service boundary as the app makes them.
- Each acceptance check runs as a real assertion against the page. A failed assertion fails the entry, and with it the build.
Access rules are derived from the code
Access entries are derived from the code and cross-checked at build time:- Access in an app is expressed through two structured mechanisms: procedure guards (public, authentication required, or required scopes) and each procedure’s declared access pattern (rows scoped to the caller, to their org, shared across the app, and so on).
- Each endpoint’s declared contract is cross-checked against those guards at build time. A contract claiming authentication or scopes the procedure doesn’t enforce fails the build, and vice versa.
- From the contract, the build derives the scenarios the entry’s test must cover (the anonymous caller denied, the wrong scope denied, the owner’s call works and another user’s doesn’t, each business rule rejects) and fails until every one exists. The scenarios run as real requests against the running backend.
Concerns are computed from access patterns
Because access is enforced through those structured mechanisms rather than ad-hoc checks scattered through handlers, every endpoint’s effective access pattern is machine-readable. The build reads the verified contract and computes review flags from it: any endpoint that lets a signed-in user read or modify rows beyond their own gets a warning that the permissive access should be verified. The plain-language “who can do this” descriptions are generated the same way. Neither the flags nor the descriptions can be omitted or reworded, by the agent or by anyone else. See Access verification.Calculation tests must use the real implementation
Build-time gates check every calculation test at two levels: it must import real app code, and every assertion must be computed from an imported call’s result. A restated formula, an assertion on local arithmetic, a same-value conditional, or a dynamic load of app code all fail the build. At runtime, the calls a test makes into the app’s implementation are recorded (function, arguments, returned value) and shown in the PRD view, grouped by the check that made them, and a test whose checks never call the implementation fails. See Verifying calculations.Tests never call live services
Every service call an app makes (an LLM request, a Slack message, a warehouse query) crosses one statically typed boundary, and PRD tests stub that boundary completely. This makes mutations safely testable: the flow that sends the email really runs, and the PRD records exactly what would have been sent, but nothing leaves the machine. See Services and workflows.The PRD stays in sync
- Every endpoint is in the matrix. A build-time validation fails if any API endpoint is missing from the access-control section, so an endpoint can’t be left out of verification.
- Every entry has a test. The build fails on an entry with no test file, and the test’s title must equal the entry id.
- Failing tests fail the build. The suite runs in every build. The agent making a change gets the failure immediately and fixes it as part of the change, which is why entries are usually green by the time you review them.
- Results go stale with the code. When a build changes the app, affected results show as stale in the PRD view until the tests re-run, so a green entry always refers to the code you’re looking at.

