SLICE-7 follow-ups: draft-blob→objectstore + image-fetch hardening #31

Closed
opened 2026-06-12 08:23:32 +00:00 by ben.stull · 1 comment
Owner

SLICE-7 (images pipeline, SD-0002) shipped to PPE at v0.7.0. These hardening
follow-ups were deliberately deferred and are non-blocking; grouping them so they
stay visible to triage (memory holds only the next slice).

1. Draft upload blob → objectstore (close the §6.3.1 seam). Import draft blobs
remain BYTEA on import_draft (the §7.2 SLICE-7 ships list was images-only). The
designed end-state (§6.3.1) stores them at import-drafts/{draft_id}/upload.csv
in the media bucket with the 1-day GCS lifecycle rule (the provision-bucket
script already sets that rule). Move the blob to platform/objectstore, store the
key on the draft, read it back at confirm.

2. Multi-worker image-fetch claim. repo.claim_image_for_fetch is a
presence/idempotency check adequate for the single-uvicorn-worker, in-process
model (recovery runs at startup over prior-process runs; a fresh confirm always
targets a new run — no two phases hit the same run concurrently). It is NOT a
cross-process lock. If the fetch phase ever goes multi-worker or onto a queue
(§6.9), implement a real claim: a pending → fetching status transition with
RETURNING, or SELECT … FOR UPDATE SKIP LOCKED.

3. original rendition served as application/octet-stream. The serving
route (main.py) hard-codes octet-stream for the original rendition though the
bytes were stored with their true content-type. Not on any current surface (export

  • UI use detail), but a browser hitting the original URL gets a download. Store
    the original's content-type (e.g. a column or a sidecar) and serve it.

4. Deploy-time guard on ECOMM_IMAGE_FETCH_ALLOW_PRIVATE. The SSRF
allow-private escape hatch is test-only (set in e2e/serve.sh, never in the
deployed overlay). Add a deploy/startup assertion that it is unset in PPE/prod so
a misconfigured overlay can't silently disable the SSRF guard.

Source: SLICE-7 final code review (session 0034). Items 2–4 are review minors;
item 1 is the deferred §6.3.1 design seam.

SLICE-7 (images pipeline, SD-0002) shipped to PPE at v0.7.0. These hardening follow-ups were deliberately deferred and are non-blocking; grouping them so they stay visible to triage (memory holds only the next slice). **1. Draft upload blob → objectstore (close the §6.3.1 seam).** Import draft blobs remain BYTEA on `import_draft` (the §7.2 SLICE-7 ships list was images-only). The designed end-state (§6.3.1) stores them at `import-drafts/{draft_id}/upload.csv` in the media bucket with the 1-day GCS lifecycle rule (the `provision-bucket` script already sets that rule). Move the blob to `platform/objectstore`, store the key on the draft, read it back at confirm. **2. Multi-worker image-fetch claim.** `repo.claim_image_for_fetch` is a presence/idempotency check adequate for the single-uvicorn-worker, in-process model (recovery runs at startup over prior-process runs; a fresh confirm always targets a new run — no two phases hit the same run concurrently). It is NOT a cross-process lock. If the fetch phase ever goes multi-worker or onto a queue (§6.9), implement a real claim: a `pending → fetching` status transition with `RETURNING`, or `SELECT … FOR UPDATE SKIP LOCKED`. **3. `original` rendition served as `application/octet-stream`.** The serving route (`main.py`) hard-codes octet-stream for the `original` rendition though the bytes were stored with their true content-type. Not on any current surface (export + UI use `detail`), but a browser hitting the original URL gets a download. Store the original's content-type (e.g. a column or a sidecar) and serve it. **4. Deploy-time guard on `ECOMM_IMAGE_FETCH_ALLOW_PRIVATE`.** The SSRF allow-private escape hatch is test-only (set in `e2e/serve.sh`, never in the deployed overlay). Add a deploy/startup assertion that it is unset in PPE/prod so a misconfigured overlay can't silently disable the SSRF guard. Source: SLICE-7 final code review (session 0034). Items 2–4 are review minors; item 1 is the deferred §6.3.1 design seam.
ben.stull added the type/taskpriority/P3 labels 2026-06-12 08:23:32 +00:00
Author
Owner

Closing as part of the pivot from a generic multi-tenant Shopify-alternative storefront to the commitment-commerce + cross-maker verified referral network direction (see ecomm-content/rfcs/network_strategy.md; session 0036).

SLICE-7 follow-ups on the storefront image-import path. The objectstore/images infra survives, but these import-specific follow-ups are superseded; will re-file against the network catalog-image needs if they recur.

Nothing is lost — code stays in git history and the issue can be reopened if it resurfaces under the network architecture.

Closing as part of the pivot from a generic multi-tenant Shopify-alternative storefront to the commitment-commerce + cross-maker verified referral **network** direction (see `ecomm-content/rfcs/network_strategy.md`; session 0036). SLICE-7 follow-ups on the storefront image-import path. The objectstore/images infra survives, but these import-specific follow-ups are superseded; will re-file against the network catalog-image needs if they recur. Nothing is lost — code stays in git history and the issue can be reopened if it resurfaces under the network architecture.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: wiggleverse/wiggleverse-ecomm#31