Sync
catalog_sync pulls Shopify products, variants, and cost_per_item into the products table with Tier A cost confidence. performance_sync ingests Shopify orders + Google Ads spend into performance_daily per (date, variant_id).
// catalog specialist
Sync, classify, decide, execute — every product moves through one lifecycle state, gated by ALLOWED_TRANSITIONS, with a reversible decision row attached. Margin-aware. Tier-gated. Append-only.
product : "Brushed Linen Throw — Sand"
variant : 'SKU-LIN-228-SND-L'
from_state : ACTIVE
to_state : ON_DISCOUNT
action : DISCOUNT_TEST
delta : −15% (€89 → €76)
window : 14d, auto-revert
reason : OPTIMIZE_CYCLE_FAILED (2 cycles)
margin tier = A (verified)
p75 winner floor = 2.4x ROAS
current ROAS = 1.6x (28d)
evidence : [perf#9123, cycle#771, judge=0.88]
applied_at : 2026-05-25T08:02:14Z
applied_by : catalog_agent.discount_executor
status : APPLIED (live)
reversal : PRICE_RESTORE on day 14// what it does
catalog_sync pulls Shopify products, variants, and cost_per_item into the products table with Tier A cost confidence. performance_sync ingests Shopify orders + Google Ads spend into performance_daily per (date, variant_id).
self_calibrator derives store-specific thresholds — winner ROAS floor = max(2.0, p75 of your distribution). classifier assigns WINNER / MID / LOSER / INSUFFICIENT_DATA every cycle, never the same number twice.
decision_engine emits an Action enum per SKU — KEEP, SCALE_WINNER, OPTIMIZE_LOSER, DISCOUNT_TEST, DRAFT, VAULT, REVIVE_SEASONAL, FLAG_ORPHAN. Every action validated against ALLOWED_TRANSITIONS before write.
action_executor mutates Shopify (draft / publish / edit). discount_executor changes prices. copy_rewriter rewrites titles + descriptions via LLM, gated by trademark filter and uniqueness check.
// lifecycle state machine
Fresh import, awaiting first decision.
Live on storefront, gathering signal.
Selling within range — keep cycle.
Copy or pricing under iteration.
Discount window open, time-bounded.
Unpublished, removed from catalog.
Held for next relevant window.
Permanently removed, recoverable on request.
AUDIT → PUBLISHED, DRAFTED, FLAG
PUBLISHED → ACTIVE, DRAFTED, OPTIMIZING
ACTIVE → OPTIMIZING, ON_DISCOUNT,
DRAFTED, ARCHIVED
OPTIMIZING → ACTIVE, ON_DISCOUNT, DRAFTED
ON_DISCOUNT → ACTIVE, DRAFTED, ARCHIVED
DRAFTED → PUBLISHED, SEASONAL_VAULT,
ARCHIVED
SEASONAL_VAULT → PUBLISHED (window only),
ARCHIVED
ARCHIVED → DRAFTED (operator-only)
validate(from, to) → bool
invalid → review row, not mutation// action enum
| Action | What it does | Valid from | Trigger |
|---|---|---|---|
| KEEP | Continue selling at current price. | PUBLISHED, ACTIVE | Within ROAS band |
| SCALE_WINNER | Flagged for budget lift on paid side. | ACTIVE | ROAS > p75 winner floor |
| OPTIMIZE_LOSER | Copy + image regenerate cycle. | ACTIVE, ON_DISCOUNT | ROAS < floor, 14d window |
| DISCOUNT_TEST | Time-bounded price test, margin gated. | OPTIMIZING | OPTIMIZE_CYCLE_FAILED |
| DRAFT | Unpublish from storefront. | ON_DISCOUNT, ACTIVE | SALES_ZERO_N_DAYS |
| VAULT | Park as seasonal candidate. | DRAFTED | Seasonal pattern detected |
| REVIVE_SEASONAL | Republish ahead of season window. | SEASONAL_VAULT | Calendar trigger + signal |
| FLAG_ORPHAN | Missing cost data — operator review. | AUDIT | Tier C cost confidence |
// cost confidence
// data source
Shopify cost_per_item field, confirmed per variant.
// what is allowed
All actions enabled — price changes, scale, archive, publish.
// data source
Inferred from supplier match or category-typical margin.
// what is allowed
Soft actions only — KEEP, OPTIMIZE, FLAG_ORPHAN. No discount writes.
// data source
Missing or unverifiable cost — orphan SKU.
// what is allowed
Read-only. Operator review required before any catalog write.
Why this matters. Most catalog tools assume your cost data is right. Magistry assumes it isn't — every SKU is scored, every write is gated, and a Tier-C product never gets a discount on its own. Your margin policy is enforced in the type system.
// what operators say
“We pruned 1,200 dead SKUs in the first week — every move a row we could see and reverse. The thing that finally got buy-in from finance was the tier gate. Magistry simply refused to discount the orphan products. That was the conversation that ended the spreadsheet era for us.”
// catalog specialist
Connect a read-only Shopify token and the Catalog Specialist will draft its first audit cycle inside an hour — every SKU classified, every action explained, zero mutations until you flip the switch.
Dry-run by default · Append-only logs · One-click rollback