Adds RequestIX.use_case_inline so callers can define ad-hoc extraction
schemas in the request itself, bypassing the backend registry. The
pipeline builds a fresh (Request, Response) Pydantic class pair per
call via ix.use_cases.inline.build_use_case_classes; structural errors
(dup field, bad identifier, choices-on-non-str, empty fields) raise
IX_001_001 to match the registry-miss path. Inline wins when both
use_case and use_case_inline are set. Existing REST callers see no
behavioural change.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
First pipeline step. Validates the request (IX_000_002 on empty context),
normalises every Context.files entry to a FileRef, downloads them in
parallel via asyncio.gather, byte-sniffs MIMEs (IX_000_005 for
unsupported), loads the use-case pair from REGISTRY (IX_001_001 on
miss), and builds the flat pages + page_metadata list on
response_ix.context.
Fetcher / ingestor / MIME detector / tmp_dir / fetch_config all inject
via the constructor so unit tests stay hermetic — production wires the
real ix.ingestion defaults via the app factory.
7 unit tests in tests/unit/test_setup_step.py cover validate errors,
happy path (fetcher + ingestor invoked correctly, context populated,
use_case_name echoed), FileRef headers pass through, unsupported MIME
-> IX_000_005, unknown use case -> IX_001_001, text-only request, and
the _InternalContext type assertion.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>