A scanner finding is not permission to write.
Change envelope
{
"resource":"variant/123",
"field":"sku",
"before":"RHS00025-SC1",
"proposed":"RHS00025-BIG",
"reason":"distinct size variants share SKU",
"dependencies":["fulfilment","feed","returns"],
"approval_state":"pending"
}
Workflow
- capture resource version and public evidence
- generate exact diff
- list affected products and downstream systems
- obtain merchant approval
- apply with idempotency key
- verify Shopify record and public page
- retain restore payload
Theme fixes use duplicate themes and theme IDs, not blind text replacement. SKU changes require export and downstream mapping review. The Rhode shared-SKU case is not safe for automatic correction because the public scan cannot know the merchant’s fulfilment design.
Restore
Restore only when the current value still matches the applied value; otherwise a later merchant edit could be overwritten. Conflicts require human review.
Resource-specific backups
A backup must match the write surface. Product and variant changes retain the relevant Admin API object, version or update timestamp, metafield type, market context, and downstream identifiers. Theme changes retain the theme ID, asset key, checksum, and complete prior asset content. App configuration retains the app-owned object and schema version.
Do not call a screenshot or copied text a backup. It may explain the change, but it cannot restore the exact resource.
Approval payload
The merchant reviews a stable payload containing the current value, proposed value, evidence, affected resources, risk, validation steps, and rollback plan. The approval record stores a digest of that payload. If any field changes after approval, the digest changes and approval returns to pending.
{
"change_id": "chg_01J...",
"shop_id": "shop_42",
"resource_version": "2026-07-27T18:41:12Z",
"payload_digest": "sha256:...",
"approved_by": "merchant_user_7",
"approved_at": "2026-07-27T19:03:00Z"
}
Idempotent execution
Every execution uses a unique idempotency key bound to the shop, change, and approved payload. Replaying a network request must not create a second metafield, duplicate a block, or overwrite a new version. The worker checks the resource version immediately before writing and stops on mismatch.
For theme work, use a duplicate unpublished theme where possible. Render fixtures for product states such as in stock, sold out, multi-variant, subscription, and market-specific currency. Publishing a theme remains a separate merchant-controlled action.
Restore protocol
- Read the current resource.
- Confirm it still equals the value applied by this change.
- Apply the retained prior value with a restore idempotency key.
- Verify the Shopify object.
- Verify the public storefront independently.
- Record the restore result and any remaining cache or feed lag.
If step two fails, report a restore conflict with a three-way comparison: original value, applied value, and current value. Never overwrite the current value automatically.
Required failure tests
Test a network timeout after a successful write, duplicate queue delivery, stale resource version, revoked token, partial multi-resource change, public cache delay, and merchant edit between apply and restore. A safe system must leave an inspectable terminal state for each case.
This protocol supports the Fix stage. Verification remains a separate stage so the same agent that proposed a write is not allowed to declare success from its own mutation response.
Community discussion
Add to the article
Ask a technical question, share a storefront result, or challenge a conclusion with evidence.