Skip to main content
This page describes how the harness handles the service boundary and workflow execution. For reading the captured calls as a reviewer, see What gets captured. Apps do much of their important work through services: LLM calls, Slack messages, warehouse queries, emails. This work is normally the hardest to test, because a test can’t safely send a real message. The PRD harness is designed so these flows run, and get verified, anyway.

A single stubbed service boundary

Every service call an app makes crosses a single boundary defined by the services framework, where each service declares its tools with typed request and response shapes. PRD tests stub that boundary completely: the app’s code runs unmodified right up to the moment a call would leave the machine, and the harness answers instead. This gives three guarantees:
  • Nothing real is ever called. There is no path around the boundary, so no test can message a Slack channel, spend LLM tokens, or write to a warehouse. This is structural, not best-effort HTTP mocking.
  • Mutations are safely testable. Because the send can’t actually happen, the flow that sends can actually run. The PRD records what would have been sent, verbatim.
  • Stubs are faithful. Default stub responses are generated from each tool’s declared output schema, so the app receives realistically shaped data without per-test setup. When the story needs specific content, the test overrides it.
When one service is called several times with different inputs, such as generating a distinct summary per user, $byParams matches responses to the call’s parameters declaratively:

Asserting what was sent, and what wasn’t

Captured calls are assertable in the test, with plain-language labels that land in the timeline:
The positive assertion has a blind spot: it matches any captured call, so it can’t catch a violating extra call. For scoped behavior (per-user, per-tenant, per-setting), tests pair it with a matcher-negative that checks every captured call:
This mirrors the seeding rule for visibility boundaries: the test asserts that the in-scope data produced a call, and that the out-of-scope marker appears in none of them. Together the pair verifies scoping through the entire pipeline, not just on the screen. App-level configuration follows the same pattern. prd/fixtures/app-settings.json declares the configured world once (the Slack channel is set) and every test runs against it. The one test whose point is missing configuration overrides it with prd.appSettings({ slackChannelId: "" }) and asserts the call doesn’t fire.

Workflows execute in the test

A feature backed by a workflow (trigger, pipeline, persisted result, display) is not verified by inspecting the workflow’s definition. A test that reads the definition only proves the definition says what you meant, not that running it does what you meant. Instead, when the app submits a workflow job, the harness intercepts the submission and executes the job in-process with the real workflow engine: real SQL steps against the test database, real imports and persists, and every service step routed through the same stubs. Execution is synchronous, and a failing workflow step fails the test with that step’s error. The hero test drives the whole chain and asserts at each link:
A workflow with both a manual trigger and a schedule is two stories, because they’re different journeys: the user-triggered run, scoped to the caller (with the matcher-negative proving other users’ data stayed out), and the scheduled run, which the test executes exactly as the scheduler would with prd.runWorkflow. In the scheduled story, all users are processed, each seeded owner gets one properly scoped service call, and each user finds their own result without having triggered anything. prd.runWorkflow also means nothing has to be added to the product to make something testable: the harness can trigger anything the system can, so the app never grows an admin “run for everyone” button just so a test can reach the scheduled path.