arch-01 reproduction

Public source retained with the related article. Generated results, dependency directories, runtime storage, secrets, and oversized binary artifacts are intentionally excluded.

README

# ARCH-01 hexagonal-boundary experiment

This fixture supports the planned article *A Hexagon Is Not a Directory
Layout*. It runs one Laravel quote request through three source structures:

- a controller coupled to Laravel HTTP and the provider schema;
- the same dependency moved under an `Application` namespace; and
- an application-owned `ProductPrices` port with HTTP adapters outside it.

The provider changes from top-level `price_cents` to nested
`price.amount_minor`. The fixture asks where that change lands. It does not use
file counts or timings as a maintainability claim.

## Run it

Docker is the only host dependency.

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

The runner builds a digest-pinned image, starts a local PHP provider for each
case, sends one in-process Laravel HTTP request through real routing and
container resolution, and retains every command, exit, duration, request,
provider response, application response, failure, source diff, and dependency
report under `results/`.

Laravel's feature request is integration evidence, not end-to-end evidence.
The inbound request is simulated inside the framework process. The outbound
catalogue request crosses a real local HTTP process boundary.

## Expected behavior matrix

| Flow | Provider | Result |
| --- | --- | --- |
| coupled v1 | v1 | pass |
| coupled v1 | v2 | fail with missing v1 value |
| coupled v2 | v2 | pass |
| renamed v1 | v1 | pass |
| renamed v1 | v2 | fail with missing v1 value |
| renamed v2 | v2 | pass |
| hexagonal v1 adapter | v1 | pass |
| hexagonal v1 adapter | v2 | fail with typed missing v1 value |
| hexagonal v2 adapter | v2 | pass |

Every passing row returns the same application JSON for two `desk-lamp`
products. Every cross-schema failure receives the v2 provider payload but uses
the v1 mapping.

## Dependency evidence

`analyze.php` reads the committed PHP files and verifies:

- coupled controllers import Laravel HTTP and provider fields;
- renamed application services still import Laravel HTTP, call framework
  configuration, and read provider fields;
- the hexagonal application imports no Laravel type, infrastructure class,
  provider field, URL, or configuration helper;
- both HTTP adapters implement the application-owned `ProductPrices` port; and
- the v1 and v2 renamed controllers are identical after normalizing only their
  version namespace.

The runner also executes an owned direction-defect fixture. Its application
class imports an HTTP adapter, and the analyzer must reject it. The retained
v1-to-v2 diffs identify the coupled controller, renamed application service,
and hexagonal HTTP adapter as the provider-aware change sites.

## Boundary of the conclusion

The fixture proves source direction and one controlled schema-change surface.
It does not prove lower defect rates, faster delivery, easier navigation, or a
universal need for ports and adapters. A direct flow remains reasonable when
the provider mechanism is stable, the application policy is trivial, and the
proposed port would copy HTTP vocabulary instead of naming an application
conversation.

Retained files