# Verifying Product Outcomes

This independently written lesson uses Kent C. Dodds's public testing work and official Testing Library documentation. It is not an official MEGA lesson. QueueCare and the acceptance packet below are original examples; the pseudocode is illustrative, not executed framework code.

## Learning goals

- Distinguish acceptance, review, and verification.
- Inspect a change across code, configuration, data, and operation.
- Choose quality gates that provide relevant evidence.
- Explain both what a passing check proves and what remains unknown.

## Acceptance defines the promise

Acceptance is the decision that a change meets agreed conditions. Review examines the change and its risks. Verification gathers evidence about actual behavior. These activities support each other, but none is a substitute for the others. A reviewer can approve readable code that implements the wrong cancellation policy. A browser test can pass while a migration exposes data incorrectly.

Start with the product promise. QueueCare promises that a canceled appointment will not receive a reminder that has not yet committed to dispatch. This wording exposes a boundary the team can define and test. “Reminders are reliable” does not. Decide the expected behavior at that commitment point and explain the unavoidable limit to the product owner.

Kent describes testing as an investment in confidence and favors integration tests where they provide useful confidence for their cost. He also warns against pursuing coverage as an end in itself. [Read his testing strategy article](https://kentcdodds.com/blog/write-tests). Use that reasoning to ask what important failure each check could reveal.

## Review the system diff

A code diff is one view of the change. For this lesson, a system diff means the complete set of behaviorally relevant changes: source code, dependencies, database shape, data migration, configuration, permissions, scheduled work, external service settings, monitoring, and operating instructions. This is an original review device, not a quoted Kent framework.

For QueueCare, a small worker change might also require a provider credential, a new queue, and a daily schedule. Reviewers need to know which environment each setting affects. If the schedule is installed twice, correct worker code can still send twice. If the provider account is wrong, a successful API response can be evidence of the wrong integration.

Review by following one real user action through the system. Identify the authority check, mutation, external effect, visible result, and diagnostic event. Then follow a failure along the same path. This reveals missing behavior more effectively than reading files in alphabetical order.

In his Pragmatic AI interview, Kent describes varying review depth with a change's consequences, including closer attention to migrations and important paid tooling. This is contextual practice, rather than a blanket instruction to skip review. [Read the official interview transcript](https://pragmaticai.fm/episodes/kent-c-dodds-on-mcp-and-how-product-engineering-might-outlast-coding/transcript).

Keep the review proportional to consequences. A copy change and an authorization change need different attention. For a sensitive boundary, a passing journey test is only part of the evidence; inspect the authorization decision itself and test an unauthorized action. Outcome ownership does not make implementation understanding optional where it is needed to judge risk.

## Checks should resemble use

Testing Library's guiding principles favor interacting with rendered DOM behavior in ways that resemble application use. [Read the official guiding principles](https://testing-library.com/docs/guiding-principles/). For a cancellation screen, a resident finds their appointment details, activates a named control, and reads confirmation. They do not call a component's internal setter.

The official query documentation prioritizes accessible roles and labels and distinguishes immediate queries from queries that retry for asynchronous results. [Read About Queries](https://testing-library.com/docs/queries/about/). Use that guidance to express the journey clearly, while remembering that semantic queries alone do not establish full accessibility.

Here is API-neutral pseudocode for the intended interaction:

```text
Given a confirmed booking and valid cancellation authorization
Open the resident's cancellation page
Find the button named "Cancel appointment"
Activate that button as a user
Wait for the status "Appointment canceled"
Reload the page and confirm the same final status
Scan eligible reminders with a controlled clock
Assert this booking is absent from the dispatch set
```

This check crosses interface, persistence, and reminder eligibility. It can detect a button wired to the wrong action or a status that changes only in memory. It does not prove a real email provider will behave correctly, nor does it establish every race condition. Name these limits alongside the result.

Kent's implementation-details article distinguishes checks that survive harmless refactoring from checks tied to internal structure. [Read Testing Implementation Details](https://kentcdodds.com/blog/testing-implementation-details). For QueueCare, changing the storage helper's name should not break a user journey check. Removing the button's action should.

## Worked example: an acceptance packet

Assume a candidate build changes cancellation and reminder eligibility. The following evidence is hypothetical and shows how to reason about a release decision.

```text
Candidate: revision Q42 in the staging environment
Requirement A: Authorized cancellation survives page reload.
Evidence: Browser journey B12, passed.

Requirement B: Changed authorization cannot mutate a booking.
Evidence: Service scenarios S8-S10, passed.

Requirement C: Canceled booking is excluded before dispatch.
Evidence: Controlled-clock integration I7, passed.

Requirement D: Cancellation racing with dispatch follows policy.
Evidence: Concurrency fixture I8, failed.
Observed: Worker used an earlier confirmed-state snapshot.

Decision: Hold reminder activation; repair commitment boundary.
Limit: Provider ingress and real inbox delivery not assessed here.
```

Three passes cannot average away the failed requirement. The failed race is directly relevant to the promise. The correct response is to fix the boundary or deliberately revise the promise with the product owner. Quietly deleting the check would remove evidence without changing the defect.

Now suppose the repair rechecks status while claiming a dispatch identity in the same transaction. Repeat I8 with both event orders. When cancellation wins, no dispatch may commit. When dispatch wins, the product must show that cancellation cannot recall the already committed message. Verify both resulting states, rather than assert only that a particular helper was called.

One more limitation remains: the local transaction does not make the provider effect atomic with the database. A provider timeout can leave uncertainty. That case belongs in the delivery contract and recovery policy. An acceptance packet should preserve this known boundary instead of presenting a comprehensive-sounding “all tests passed.”

## Quality gates need owners and failure actions

A useful gate has a condition, evidence source, decision owner, and response to failure. Static checks can catch invalid references. Integration checks can reveal broken collaboration. A controlled provider check can reveal credentials or payload mismatches. Production observation can reveal failures that fixtures did not represent.

Do not add gates merely to make the pipeline look rigorous. Kent's article about choosing between testing and fixing a bug emphasizes context and relative product cost. [Read Should I write a test or fix a bug?](https://kentcdodds.com/blog/should-i-write-a-test-or-fix-a-bug). Prioritize checks whose failures matter to this release and whose evidence can be trusted.

## Failure modes

- Approving a release based on the number of green checks.
- Ignoring configuration because the code diff is small.
- Asserting internal calls while the visible action is broken.
- Treating one test environment as proof of every production condition.
- Hiding a failed promise inside a broad success summary.

## Practice

Build an acceptance packet for rescheduling. Include four requirements, one code review question, one configuration check, and a deliberately failing scenario. Then decide whether the release can proceed.

Acceptance requires evidence tied to the exact candidate and environment, a statement of each check's limits, and a response to the failed scenario. Include a state check after reloading the resident page.

A strong solution blocks release when a failed scenario violates an agreed promise. It may proceed with an explicitly excluded cosmetic issue if the decision owner accepts that scope. It never relabels missing evidence as a passed check.

## Check your understanding

1. Why inspect schedules as well as worker code? Answer: Duplicate activation can create duplicate effects despite correct code.
2. Does a role-based selector prove accessibility? Answer: No. It supports meaningful interaction checks but covers only part of accessibility.
3. Can several passing checks outweigh a failed critical promise? Answer: No. Resolve that promise directly.

## Sources

- [Pragmatic AI: Kent C. Dodds interview transcript](https://pragmaticai.fm/episodes/kent-c-dodds-on-mcp-and-how-product-engineering-might-outlast-coding/transcript).
- [Kent C. Dodds: Write tests](https://kentcdodds.com/blog/write-tests).
- [Testing Library: Guiding Principles](https://testing-library.com/docs/guiding-principles/).
- [Testing Library: About Queries](https://testing-library.com/docs/queries/about/).
- [Kent C. Dodds: Testing Implementation Details](https://kentcdodds.com/blog/testing-implementation-details).
- [Kent C. Dodds: Should I write a test or fix a bug?](https://kentcdodds.com/blog/should-i-write-a-test-or-fix-a-bug).
