spec(SD-0002 §7): delivery plan — SLICE-5..8, spine-first sequencing, rollout via pipeline, risks

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-11 12:42:37 -07:00
parent 50574fe68b
commit 07abd48b50
@@ -1100,7 +1100,107 @@ merchants having imported real data (which INV-10/12 protect).
## 7. Delivery Plan
*(not yet authored)*
Slice numbering continues app-wide from SD-0001 (SLICE-1…4), like the
invariants: this design owns **SLICE-5…8**.
### 7.1 Approach / strategy
**Spine first, infra second, compatibility last.** The codec + diff engine is
the design's novel heart and its riskiest logic — it lands first, with the
full preview/confirm UX, so the consent model (INV-11) is real from day one.
Export lands second and immediately locks the round-trip property (INV-12)
while the data model is still images-light — cheaper to fix losslessness bugs
before the image pipeline complicates identity. Images land third (the
infra-heaviest slice: first GCS bucket, first background work). The Shopify
dialect lands last: by then it is a pure mapping at a stable, well-tested
boundary (INV-17), not a moving target. SLICE-8 can run in parallel with
SLICE-7 if sessions overlap — it touches only the dialect adapter and docs.
Execution convention per the standard: each slice is its own coding session —
just-in-time implementation plan → execute → verify → ship through the §9
pipeline → merge + version bump — in dependency order. The design pass
happens once, here; if executing a slice proves this spec wrong, amend the
spec, then replan.
### 7.2 Slicing plan
#### SLICE-5 — Import spine (canonical, no images) → completes PUC-1, PUC-2, PUC-3 (+3a), PUC-4, PUC-5 (+5a), PUC-8, and PUC-11's sample download
- **Depends on:** — (SD-0001 shipped surfaces only)
- **Ships:** `products` domain + §6.3 tables (images table present;
fetch phase stubbed to no-op); canonical parser, validation, diff engine,
draft/confirm/run endpoints (§6.4); Products page, upload, preview with
drill-in, run detail (no images section), import history; sample CSV.
- **Definition of done:** BUC-1/1a/2 acceptance criteria met for the
canonical path; INV-10/11/13/14/15/18 enforced + unit/integration suites
green; E2E green: `e2e_import_preview_confirm`,
`e2e_import_errors_actionable`, `e2e_import_file_rejected`,
`e2e_import_cancel_no_trace`; TEL-1/2 emitting (§9); DOC-1 updated.
#### SLICE-6 — Export & the round-trip lock → completes PUC-9, PUC-10
- **Depends on:** SLICE-5
- **Ships:** canonical serializer (one codec, two directions), streamed
export endpoint + status filter UI, `nothing_to_apply` no-op preview
behavior, the INV-12 property test over text-field catalogs.
- **Definition of done:** BUC-3/4 acceptance criteria met; INV-12 property
test green in CI; E2E green: `e2e_export_download`, `e2e_roundtrip_noop`;
TEL-3 emitting; DOC-1 updated.
#### SLICE-7 — Images pipeline end-to-end → completes PUC-7
- **Depends on:** SLICE-6 (export must exist so hosted-URL round-trip is
testable the day hosted URLs exist)
- **Ships:** `platform/objectstore` (local + GCS adapters) and
`platform/images`; **the per-environment media bucket — provisioned via
the flotilla `provision-bucket` gesture when this slice reaches PPE
(§6.3.1, handbook §8.5)**; fetch task with SSRF guard, bounds, and
restart recovery; image-serving endpoint; hosted-URL resolution in diff
and export (INV-12 extended over images); run-detail images section,
Products-page notice band; INV-16 in force.
- **Definition of done:** PUC-7 acceptance met; INV-12 property test
extended over image URLs; integration: fetch-resume after kill, SSRF
fixtures; E2E green: `e2e_image_outcomes` (fixture image host); TEL-4/5 +
ALR-3 live; DOC-1 updated (bucket gesture documented in the operator
guide).
#### SLICE-8 — Shopify dialect + public format docs → completes PUC-6, PUC-11
- **Depends on:** SLICE-5 (codec boundary); parallelizable with SLICE-7
- **Ships:** header-set dialect detection, the Shopify→canonical mapping
with its exhaustive fixture table (§6.5.1), preview's "mapped" banner +
not-imported warnings; the **column reference** public doc + final sample
CSV (DOC-2/3 — the §7.3 launch gate for the migration path).
- **Definition of done:** BUC-1 acceptance met for an unmodified real
Shopify export fixture; E2E green: `e2e_import_shopify_dialect`; DOC-2/3
published; traceability matrix (§12) audited complete.
### 7.3 Rollout / launch plan
Via the mandatory pipeline (handbook §9), per slice: localhost + E2E → PPE
(`https://ecomm-ppe.wiggleverse.org`) + E2E → prod. **Prod does not exist
yet** (SD-0001's prod stand-up under `market.wiggleverse.org` is the cursor's
next stop): any slice completing before it lands ships to a green PPE and
rides the prod stand-up when it arrives — the PPE gate is never skipped
either way. Infra provisioned on demand at the stage that needs it
(§8.5-handbook): the media bucket at SLICE-7's PPE arrival (and again at its
prod arrival), operator-run. Prod is a single in-place slot (no blue/green
yet, per SD-0001). Rollback per slice = redeploy prior version (additive
migrations keep it safe, §6.10). **Non-code launch gates:** DOC-2/3 (column
reference + sample) published before SLICE-8 exposes the migration path;
§9.3 monitoring live with its slice; support path = tracker, pre-v1 (§10.2).
### 7.4 Risks & mitigations
| Risk | Likelihood / impact | Mitigation |
| --- | --- | --- |
| Diff-engine edge cases (blank-vs-absent, option matching, no-option variants) breed subtle catalog corruption | M / H | Property tests + per-rule fixtures (§6.8); INV-11 preview faithfulness makes any miss visible before it applies; INV-10 caps the blast radius (nothing deletes) |
| 5k-row validate+diff misses the < 10 s target on the shared VM | M / M | Measure at SLICE-5 with a 5k fixture; the cap is config, can drop without spec change (INV-18); async seam already named |
| Shopify export format drifts or has regional variants | M / M | Detection by exact header set fails *honestly* to `unknown_dialect` (never misparses); mapping is fixture-pinned; unknown columns warn rather than fail |
| Image fetch is an attack surface (SSRF, decompression bombs) | M / H | §6.6 guard (public IPs only, no cross-guard redirects, size/time/type bounds, Pillow decode caps) + integration fixtures |
| Deploy cadence kills in-process fetch tasks mid-run | M / L | Restart recovery is designed-in (§6.9) and integration-tested; per-image idempotency |
| Bucket provisioning gesture stalls SLICE-7 at PPE (operator availability) | L / L | Gesture named in the slice DoD; flotilla command handed to operator at session start, not discovery at deploy time |
| Scope creep toward in-app editing ("just one edit form") | L / M | §1.7 boundary + INV-10; editing is a future epic, not a slice |
## 8. Success Metrics & Measurement