# CMD-02 command-dispatch reproduction

This fixture compares two synchronous call graphs for the same two order
commands. One graph injects typed handlers. The other uses Laravel's real
`Dispatcher`, an explicit command map, and ordered pipes. Both graphs call the
same domain object and SQLite repository.

The fixture is synthetic. Its order rules are not Brian's production rules,
and its results are not production measurements. It answers a narrower
question: which behavior changes or becomes hidden when a typed call is
replaced by synchronous dispatch?

## Run it

Docker is the only host dependency:

```bash
./run.sh
```

The runner builds from pinned PHP and Composer image digests, installs the
locked Laravel dependencies, and writes every command, complete output, exit
code, duration, request, response, trace, outcome record, and before-and-after
database row under `results/`.

## What must survive

The positive matrix executes cancellation, address change, domain refusal,
repository failure, and post-handler failure through both call graphs. The
retained traces expose handler selection and wrapper order rather than relying
on an HTTP status alone.

Five source mutations must make focused tests fail:

- removing a command mapping;
- removing the transaction pipe;
- removing the outcome pipe;
- moving outcome recording inside a post-handler failure; and
- bypassing the typed direct wrapper for one handler.

The source analyzer inventories controller edges, command mappings, pipe
order, dispatcher calls, transactions, outcome recording, nested dispatch,
and command-specific middleware. Four independent defect fixtures prove that
it rejects controller bypasses, nested dispatch, and a cross-cutting pipe that
depends on one command type.

`compare.php` checks the retained evidence as a separate final step. It
rejects behavioral drift, missing rollback, a missing-map failure at the wrong
boundary, false success caused by pipe order, and a direct-wrapper bypass that
the positive suite did not detect.

## What it cannot prove

The in-memory outcome recorder exists to expose wrapper order. It is not a
durable audit log. SQLite, one PHP process, and synchronous HTTP requests do
not model queues, retries, concurrent workers, or distributed failures. The
fixture measures no performance and cannot establish that a command bus is
faster, simpler, or universally preferable. Those remain application-specific
decisions.
