- run.py: compose_run_context (§5: merge inbox -> seed -> fold, read-only on
the inbox) + execute_run (§8 meter, artifacts persisted on BOTH outcomes,
structured exit 3 on budget stop) + thin CLI (python -m ..run). The model
client is injected; only default_client_factory constructs the SDK client
(wired, never executed by the suite). The navigated docs dir comes from the
validated startup contract (resolves review OBS-2 on the shippable path;
run_s10.py stays byte-frozen fasit -> won't-fix there).
- test_run_entrance_loadbearing.py: inbox verdict reaches the composed
context (detach-proven: merge dropped -> red), empty/missing-inbox
controls, read-only inbox byte-proof, R-10 budget-stop binding via the NEW
entrance (detach-proven: stop persistence dropped -> red), happy path
through the CLI with the inbox signal surviving the chain, SDK-wiring test.
- test_ingest_adoption.py (K2.9): the two library guarantees the consumer
relies on, bound through the seam — empty CSV -> typed SourceError with NO
partial bundle on disk; non-SELECT SQL -> SourceError 'returned no columns'
(behavior verified empirically against pin dae0bd1a before binding).
- README: inbox section now points at the shippable entrance; run.py added
to the run layer; stale test count 265 -> 395.
386 -> 395 tests, full gate green (pytest, ruff check+format, mypy strict);
goldens unchanged; runs/s10 and run_s10.py untouched.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>