Skip to main content

// catalog specialist

Run the lifecycle of every SKU.

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.

Shopify Admin GraphQL 8 lifecycle states Dry-run + Live phases
decision_log · catalog
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
next: classify cycle 09:00append-only

// what it does

Four phases. One loop. Every cycle.

The Catalog Specialist runs end-to-end every day — never a one-time sync. Each phase writes its evidence into the audit plane before the next phase is allowed to start.
01

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_syncperformance_syncTier A
02

Classify

self_calibrator derives thresholds from your store's own performance distribution — winner floor at p75, loser floor at p25, no hardcoded ROAS rules. classifier assigns WINNER / MID / LOSER / INSUFFICIENT_DATA / SEASONAL every cycle.

self_calibratorclassifierp75 / p25
03

Decide

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.

decision_engineALLOWED_TRANSITIONSAction enum
04

Execute

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.

action_executordiscount_executorcopy_rewriter

// the real product

The catalog, graded and stateful.

A real screenshot of the dashboard — demo store data. Every SKU carries its lifecycle state, grade, and margin in one view.
app.magistry.io/dashboard/catalog
The Magistry catalog view — products listed with lifecycle state, performance grade, price, and margin per SKU

// product deep view

Every SKU has a full dossier.

Click into any product and you get the whole history — not a row in a table, but the evidence the agent decides on.

180-day timeseries

Revenue, spend, ROAS, and orders per day — the same window the classifier reads.

Variants heatmap

Per-variant performance at a glance — the size that carries the product and the color that drags it.

Decision history

Every lifecycle move, price change, and copy rewrite the agent made on this SKU — with its evidence.

Copy versions

Each generated title and description is versioned, so you can compare what shipped and roll back.

// lifecycle state machine

Eight states. One state per SKU. Always.

Every product variant lives in exactly one lifecycle state. Transitions are validated against the ALLOWED_TRANSITIONS map before any catalog write — invalid moves become operator-review rows, not Shopify mutations.
01

AUDIT

Fresh import, awaiting first decision.

02

PUBLISHED

Live on storefront, gathering signal.

03

ACTIVE

Selling within range — keep cycle.

04

OPTIMIZING

Copy or pricing under iteration.

05

ON_DISCOUNT

Discount window open, time-bounded.

06

DRAFTED

Unpublished, removed from catalog.

07

SEASONAL_VAULT

Parked off-season — auto-revived ~6 weeks before its peak.

08

ARCHIVED

Permanently removed, recoverable on request.

ALLOWED_TRANSITIONS
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

The full move set.

decision_engine emits one of these per SKU per cycle. Each action carries its own trigger, its own valid from-states, and its own pre-stored reversal op.
ActionWhat it doesValid fromTrigger
KEEPContinue selling at current price.PUBLISHED, ACTIVEWithin ROAS band
SCALE_WINNERFlagged for budget lift on paid side.ACTIVEROAS > p75 winner floor
OPTIMIZE_LOSERCopy + image regenerate cycle.ACTIVE, ON_DISCOUNTROAS < floor, 14d window
DISCOUNT_TESTTime-bounded price test, margin gated.OPTIMIZINGOPTIMIZE_CYCLE_FAILED
DRAFTUnpublish from storefront.ON_DISCOUNT, ACTIVESALES_ZERO_N_DAYS
VAULTPark as seasonal candidate.DRAFTEDSeasonal pattern detected
REVIVE_SEASONALRepublish ahead of season window.SEASONAL_VAULT~6 weeks before seasonal peak
FLAG_ORPHANMissing cost data — operator review.AUDITTier C cost confidence

// cost confidence

Tier-gated writes. No guesswork.

Magistry will not move money or change prices on a SKU whose margin it cannot prove. Every variant gets one of three cost confidence tiers — and the tier decides what the agent is allowed to do.

Tier A

// data source

Shopify cost_per_item field, confirmed per variant.

// what is allowed

All actions enabled — price changes, scale, archive, publish.

Tier B

// data source

Supplier cost discovered via reverse-image match against supplier sites.

// what is allowed

Performance-based actions only — KEEP, OPTIMIZE, FLAG_ORPHAN. No price or discount writes.

Tier C

// data source

Missing or unverifiable cost — orphan SKU.

// what is allowed

State-based actions only — publish/draft moves. No performance or price decisions without operator review.

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.

// built to be trusted

Built to be trusted, not just to act.

Dead SKUs get archived and every move is a row you can see and reverse. The cost-confidence tier gate refuses to discount orphan-cost products, so price moves stay bounded to SKUs with a known landed cost — the kind of guardrail that gets finance comfortable with autonomy.

// catalog specialist

See your catalog the way Magistry sees it.

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