Move the legacy Dawn storefront (business logic in client JS + Script Editor) to Horizon's thin, blocks-native presentation — with cart, pricing, and checkout logic re-homed to server-side Shopify Functions and the Tool Runner, driveable by an agent under an AP2 mandate.
Immovable clock. Shopify Script Editor is removed as of 2026-06-30. Any reorder/hide-payment, shipping, or line-item-discount Script still live means that checkout logic has silently stopped. Pillar 1 (checkout-touching) and Pillar 8 (all Scripts → Functions) are the urgent thread — do these before the broader theme rebuild.
Point of Difference
GraphQL + GA4 Signals — one seismic move, not two chores
Enterprises are forced through two migrations they treat as unrelated: REST → GraphQL (2026 sunset) and GA4 Consent Mode v2 signals (four signals — ad_storage, analytics_storage, ad_user_data, ad_personalization — mandatory in the EEA). The seismic recognition: they are the same migration to one thing — a consent-gated, agent-addressable data plane.
Neither migration delivers the agent-ready plane alone; the value is the fusion.
Move
Delivers
Missing alone
REST → GraphQL
Typed, bulk, server-resolved data — machine-addressable, no REST rot
Reach without permission — the agent can query but not know what it may do
GA4 Consent Mode v2
Consent as a first-class signal on every event
Permission without reach — data still un-queryable at scale
Fused
Every datum machine-addressable AND consent-qualified — exactly what autonomous AI workflows need
—
The fusion is only safe on the trust foundation this stack already carries:
Foundation
What it guarantees for AI workflows
Orthogonal Trust
Consent ⊥ access — the axes compose without coupling; the agent carries zero trust
Hexagonal Trust
GraphQL plane behind ports; every consumer (agent, GA4, ESB, CDP, storefront) crosses one consent-enforcing port
Loop Engineering
The agent's query loop re-checks consent every iteration, fail-closed — trust re-earned per loop, never inherited
Enterprise unlock: AI workflows that are powerful (reach all the data) and safe (consent lineage for GDPR Art. 28 / CPRA, re-verified per loop) — most stacks force that trade-off; the fused plane removes it. It coexists with your ESB / CDP — the GraphQL loop feeds Adobe AEP and the ESB, it doesn't replace them.
Compliance & Permissions
Enforcement is a benefit — revenue, trust, reputation
Compliance and permissions are not a cost center or a checkbox. Enforced at the data plane — fail-closed, per-loop — they protect revenue, compound trust, and defend reputation. Lead with the benefit; the mechanism is only how it is guaranteed.
Read the benefit first (column 1); the capability and enforcement are the proof.
Benefit
Capability
Enforcement
Ad ROAS preserved
Consent Mode v2 signals keep measurement + remarketing legal — lost consent = lost signal = wasted spend
4 signals required, fail-closed before analytics fire
Promotions run legally
Omnibus 30-day prior-lowest price — discount in the EU without fines or "fake sale" penalties
price-history ledger, read-gated
Market access retained
Data rights (opt-out, export, delete) — the price of selling in the EU / California at all
wired to live endpoints, fail-closed
Safe delegation → new revenue
Scoped, revocable per-tenant tokens + capability permissions — sell to teams and agencies without exposure
PII-free audit trail — provable governance is what enterprise procurement requires before it can buy
audit by construction
The reframe: permissions enforcement converts compliance from risk and cost into revenue enablement and a trust asset. The governance is the reason the data is safe to open — which is the core offer: accessibility, made safe by construction.
1 · Why Horizon fits the Orthogonal Stack
Horizon is blocks-first: a blocks/ directory, nested blocks via {% content_for 'blocks' %}, per-component {% stylesheet %}/{% javascript %}, no framework runtime. That posture — thin presentation, logic pushed out — is the native Shopify endpoint for the stack, not a fight against it.
Each row is Dawn coupling absorbed by one orthogonal layer.
Dawn coupling (what breaks)
Orthogonal layer that absorbs it
Business rules in section <script> / Script Editor
Data plane → server-resolved (cart-transform / draft order)
Product data hardcoded in Liquid
Source of truth → hydrate from Xano PIM via GraphQL
Auth & gating in theme JS
Identity → JWE claim, derived server-side, never in Liquid
Brand look re-built per surface
Look → Design Sync theme.css keys Horizon + all surfaces
2 · Agentic Cart Functions — Guideline
Two audiences hit the same cart: a human on the Horizon storefront and an agent acting under a mandate. The rule is that both cross the same server-side boundary — no logic path exists only in the browser.
2.1 · Script → Function replacement map
Legacy Script (removed 2026-06-30)
Shopify Function
Runs at
Reorder / hide payment methods
payment_customization
checkout
Reorder / hide / rename shipping
delivery_customization
checkout
Line-item / order discount
product_discount / order_discount
cart + checkout
Bundle / merge / expand lines
cart_transform
cart
Block invalid carts
cart_checkout_validation
cart + checkout
Functions are Wasm, run server-side on Shopify's infra, and are deterministic + input-bounded — which is exactly why an agent can be allowed to trigger them: the merchant's rules hold regardless of who or what filled the cart.
The agent never asserts price, discount, or identity. It calls a tool; the tool decrypts the JWE claim, checks caps at the data plane, and submits a cart. Merchant Functions then apply pricing, payment, and shipping rules on the server — the same rules a human would hit. The AP2 mandate is the user's scoped, revocable authorization for the agent to transact, re-checked on each loop (fail-closed).
2.3 · Rules
No money math in the browser. Price, tax, discount, and shipping totals are server-resolved (Function or draft order). Liquid renders the resolved number; it never computes it.
One cart boundary for human and agent. The Tool Runner's add_to_cart/checkout tools hit the same Cart/Checkout as the storefront — never a private, unguarded path.
Agent authority = mandate, not session. Authorization comes from the decrypted AP2 mandate + caps, re-verified every tool call. A prior grant is never inherited across the loop.
Deterministic rules live in Functions. Anything that must hold for every cart (discounts, payment/shipping gating, bundle logic) is a Wasm Function — not worker code, not theme JS.
Orchestration lives in the Tool Runner. Multi-step, stateful, or cross-system logic (PIM lookup, consent, settlement rail choice) is a worker tool — not a Function (Functions are input-bounded and side-effect-free).
Catalog from PIM, not Liquid. PDP/collection hydrate from Xano via GraphQL; no product data hardcoded in templates.
Consent gates the cart, not just analytics. The AP2 mandate + Consent Mode v2 signals must be present before an agent transacts; absent consent = fail-closed.
Present as Horizon blocks. Cart, upsell, and PDP UI are theme blocks with per-component CSS/JS — thin presentation over the server-resolved state, themed by Design Sync tokens.
3 · Migration Checklist
Work top-to-bottom. Groups A–B are the hard-dated urgent thread; C–F are the Q3 spine.
A · Step-0 Audit Do first
Inventory Script Editor scripts
Every payment / shipping / discount Script → one checklist row in group B.
Grep theme for inline <script> business logic
Cart math, gating, price recompute, eligibility rules living in section/asset JS.
Find REST calls & hardcoded catalog data
Mark each for GraphQL + PIM hydration (group E).
List per-locale theme forks
Route to edge-translate instead of forked templates.
B · Scripts → Functions 2026-06-30
Payment Script → payment_customization
Reorder / hide / rename methods, moved server-side.