WI-011 · Platform & Contracts · provider-adapter-boundary
done P0 high risk Owner: Paul 100% · 5/5 tasks complete
| Code | WI-011 |
|---|---|
| Phase | Platform & Contracts |
| Order | 11 of 93 |
| Story points | 13 |
| Primary surface | Vision provider gateway library (provider-neutral boundary) |
| Retires | — |
| Depends on | Freeze scan I/O contract schemas + versioning |
| Blocks | Observability core (operation envelope, OTel trace tree + attributes/events, durable provider-attempt records, P3/P4/P5/P7 trace linkage, redaction, sampling, dashboards), Provider scan test harness (Mark-testable): fire a real photo at a provider, see normalized result + cost, Provider adapters + live tests (OpenAI + 2nd cloud + local stub), Sprint 4: Vision Contract POC - scan types, watchlists, overlays, appraisal routing, Vision scan service contract and provider adapter scaffold |
One canonical result regardless of provider (OpenAI/Gemini/Claude/local) via strict structured output, so providers are swappable behind a single boundary (§18).
Spec (docs/specs/P2)
Build (core)
Test
Freeze (§31)
Gap-resolution expansion (D26, 2026-06-20)
The gateway returns a ProviderAttempt (canonical-shaped draft, not a trusted result); scan-definition registry + provider/model registry + capability model + prompt compiler + schema compiler (with compatibility report) + image-prep (reversible coord map) + provenance/telemetry + error taxonomy exist; deterministic tests pass. Per spec §28/§29 (core rows). Resolve §31 reconciliations before freeze.
First real paid API spend: live multi-provider vision (OpenAI/Gemini/Claude). Bounded by P8 budgets.
done Sprint: P&C Wave 2: Core Contracts
Edit status / sprint on the ★ Live Board → — changes are logged live with who / when / why.
No human tasks linked.
ci:floor runs all 3 packages + quarantine, PASS.trovesnap.keylessCi flag) so parallel branches don’t collide on a central list — directly serves D37.../../platform (no workspace root yet) — small follow-up to wire @trovesnap/*.None recorded yet.
None recorded yet.
None recorded yet.
packages/scan-providers/src/attempt.mjs — ProviderAttempt boundary (P2 §3/§20)packages/scan-providers/src/routing.mjs — deterministic route selection (P2 §14/§15)packages/scan-providers/test/attempt.test.mjs — + routing.test.mjs (13 tests)packages/platform/scripts/ci-floor.mjs — auto-discover keyless packages (keylessCi flag)packages/scan-providers/src/registry.mjs — provider/model + capability registry → routing candidatespackages/scan-providers/src/scan-definition.mjs — versioned scan-definition registry (P2 §6)packages/scan-providers/src/prompt-compiler.mjs — hashed prompt package + overlay guardrails (P2 §9)packages/scan-providers/src/schema-compiler.mjs — P1→provider projection + compatibility report (P2 §10; no silent weakening)packages/scan-providers/src/image-prep.mjs — reversible pixel→0–1000 coord map (P2 §11)packages/scan-providers/src/gateway.mjs — executeAttempt → ProviderAttempt; P8 budget hook (D35); injected adapterBuilt in worktree branch wi-011-p2-core (D37, parallel with Codex WI-014). First increment: the ProviderAttempt boundary (returns a canonical draft, not a trusted result — P3 decides; P2 §3) + deterministic route selection (smallest qualified-per-scan-version within privacy/capability/budget; P2 §15.2). Uses @trovesnap/platform for the att_ id.
ci:floor runs all 3 packages + quarantine, PASS.trovesnap.keylessCi flag) so parallel branches don’t collide on a central list — directly serves D37.../../platform (no workspace root yet) — small follow-up to wire @trovesnap/*.WI-011 core boundary is feature-complete: registry (→ routing candidates), scan-definition registry (P2 §6), prompt compiler (hashed package + overlay guardrails, §9), schema compiler (P1→provider projection + compatibility report; required-unsupported ⇒ ineligible, no silent weakening, §10), image-prep (reversible coord map, §11), and the gateway executeAttempt (orchestrates one attempt with an injected adapter + the P8 budget hook per D35; returns a ProviderAttempt draft, never trusted).
Merged worktree-wi-011-p2-core → main (no conflicts; ran parallel with Codex WI-014). P2 core boundary done. Adapters + live tests (WI-058) and the harness (WI-056) follow.