P9 · Platform Foundations
- Gate: P9 · Items: WI-068 (floor) + WI-069 (API/DTO) · Owner: Paul · Status: draft
- Depends on: P1–P8 (it's the shared floor they're consumed through) · Unblocks: every app/mobile/MCP surface that calls the P-gate domain functions; the P&C exit criterion (D31)
- Origin: spec gap analysis (5-round Claude+Codex, D26 approved 2026-06-20) — closes G1, G5, G15, G16, C23; carries C17's quarantine registry.
Why this gate exists: the eight P-gates are excellent internal contracts, but they have no shared floor and no enforcement against the existing MVP code that bypasses them. P9 is that floor + the guard.
1. Purpose
Define the shared platform conventions every P-gate and surface consumes before app/mobile/MCP build against them: one app/edge API contract, one ID/idempotency/correlation convention, a cross-version compatibility registry, a keyless CI floor, and the legacy-route quarantine registry that blocks P&C exit on any contract bypass.
2. Scope
2.1 App/edge API envelope + DTO boundary (G1, C23)
- One typed envelope for app/mobile/server invocations over the P-gate domain functions.
- Strict DTO separation: public / buyer-private / seller-private / internal.
- No app route returns base-table rows where a projection is required — it consumes P6 public-safe views/RPCs (P6 §29, §8.x).
- Invocation style = server/edge gateway (D33). Web/mobile/MCP call a trusted gateway (Next.js routes / Cloudflare Workers), not Supabase directly. The gateway is where the P9 envelope, the P8 budget handshake, P7 actor resolution, and P6 projections live; tenant/actor identity is server-resolved; the service-role key is never a browser/mobile/MCP client credential. Secrets (D34): per-tenant credential material in Supabase private/encrypted (service-role-only); app-level keys in Cloudflare secrets/env.
2.2 ID / idempotency / correlation convention (G16)
- Defines
operation_id, request_id, correlation_id, causation_id, and the idempotency key scope / format / replay behavior.
- P5 (source/promotion idempotency), P7 (tool idempotency), and P8 (trace linkage) all consume the same convention rather than inventing their own.
2.3 Cross-version compatibility registry (G5)
- Records the supported combinations across the independent version dimensions: P1 scan/result schemas + taxonomy/watchlist, P2 provider/schema/prompt, P3 validation, P4 ranking policy, P8 budget/observability policy.
- P1/P4 already retain exact versions but there is no cross-product matrix; this is it. P3 contract-identity validation can consult it ("is this combination supported?").
2.4 Keyless CI floor (G15)
- A no-secrets deterministic CI target that runs before any live provider or Supabase credential is needed — the TroveSnap equivalent of a structural floor.
- Must include: P1 schema/fixtures; P5 direct-write-prevention + idempotency; P6 RLS / public-leakage structural tests (where expressible without live auth); P7 mock-mode + current-tool compatibility. Green keyless CI is required from day one.
2.5 Legacy-route quarantine registry (C17 / D32)
- Encodes the D32 classification (wrap / retire / allow-with-guard) for every existing path (
/api/appraise, troveSnapApi writes, uploadEstateSalePhoto, MCP server, connectors, harness, /api/out, using(true) RLS).
- A CI guard fails the P&C exit (D31) if any production path still bypasses a P-contract.
3. Acceptance
- One typed app/edge API + the four DTO tiers; no base-table leakage; consumes P6 projections; implements the G12 decision; service-role server-only.
- The ID/idempotency/correlation convention is published and consumed by P5/P7/P8.
- The version-compatibility registry exists and is queryable by P3.
- The keyless CI floor runs the listed suites with no secrets and is green.
- The quarantine registry encodes D32 + the CI guard blocks P&C exit on a detected bypass.
4. Work-item split
- WI-068 (floor) — ID/idempotency/correlation convention + keyless CI floor + legacy-quarantine registry. Lands first (before/alongside WI-010), so everything sits on it and CI is green from the start.
- WI-069 (API/DTO) — the app/edge API envelope + DTO boundary. Lands after the G12 decision + P6 WI-015 (public-safe views).