The read tier now also fetches each row raw and fails if a typed row lost a
key, which is what catches a field the models drop.
The write tier creates a purchase order, location, webhook and recurring
invoice from bare `Default` models, since those are exactly what broke
against a real server, and exercises the uploads and the client extras. The
password tier merges two throwaway clients and purges the survivor.
Writes stay behind the existing guard: `IN_SMOKE_WRITE_HOST` must equal the
host in `IN_BASE_URL`, so a write only ever reaches a server that was named
explicitly. It prints PASS/FAIL per check and never the contents of a
record. `smoke.yml` runs it on demand only (`workflow_dispatch`), with the
write tier gated on the `write_host` input naming the instance.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>