Skip to content
ChangeAtlasCommerce
changeatlas-core@1.0.0

Rules

The deterministic core: every rule, its severity, and why. Severity policy is frozen with the registry version — AI never generates a blocking finding, and a rule that cannot run is NOT_EXECUTED, never guessed.

How severity is assigned
Objective failures block (structure, identity conflicts, invalid grouping, required parents). Ambiguity and destructive commands warn and go to a human. Missing evidence makes the affected rule NOT_EXECUTED and the decision UNKNOWN — severity is never invented for it.
STR-001 BLOCKStructure

Required columns present

Every column the pinned profile marks required exists in the sheet header.

Why: An importer cannot key or update records without the profile's required columns; the file cannot be evaluated further.

STR-002 BLOCKStructure

Header matches profile version

Header text matches the exporter version the profile is pinned to, byte for byte after trimming.

Why: Renamed or reordered headers silently change what each cell means.

STR-003 WARNStructure

Cell within text budget

No cell exceeds the profile's bounded cell text length.

Why: Oversized cells usually mean a pasted document or a broken row; they are also a parser resource risk.

IDN-001 BLOCKIdentity

Handle format valid

Product handles contain only lowercase letters, digits and hyphens.

Why: Shopify rewrites invalid handles on import, which breaks every reference that used the original.

IDN-002 BLOCKIdentity

Handle unique within file

No two product groups in the proposal share a handle.

Why: Two groups with one handle merge into one product on import; the later rows overwrite the earlier ones.

IDN-003 WARNIdentity

SKU unique within file

No two variants in the proposal share a SKU.

Why: Duplicate SKUs break inventory sync and SKU-keyed updates; sometimes intentional for bundles, so a human decides.

IDN-004 WARNIdentity

Re-keyed variant detected

A variant matched by row order carries a SKU that differs from the baseline.

Why: A re-key looks like a delete plus a create to SKU-keyed importers; confirm it is intended.

GRP-001 BLOCKGrouping

Product rows contiguous

All rows of one product group sit together in source order.

Why: Split groups import as two products; the second half loses its options and images.

GRP-002 BLOCKGrouping

Option values unique within product

No two variants of one product repeat the same option combination.

Why: Shopify rejects duplicate option combinations; the whole product import fails.

REF-001 WARNReferencesneeds sheet:Custom Collections

Collection reference resolves

Every collection handle a product references exists in the Custom Collections sheet or the baseline.

Why: Unresolved membership is ambiguous: it may be a typo, a collection created elsewhere, or a deletion.

REF-002 WARNReferences

Category reference resolves

Every category path a product declares exists in the file or baseline.

Why: Unknown categories are created on import, which quietly changes navigation.

REF-003 BLOCKReferences

Parent product exists for variation

A variation row's parent reference (SKU or id:) resolves to a variable product in the file or baseline.

Why: Orphaned variations are dropped or attached to the wrong parent.

REF-004 BLOCKReferences

Required parent handle present

A variant row carries the handle of its product group.

Why: A blank handle on a variant row detaches the variant; the importer either fails the row or creates a stray product.

CRD-001 BLOCKCardinality

One default variant per product

A product with no options has exactly one variant row.

Why: Multiple option-less rows are contradictory; the importer cannot pick one.

CRD-002 WARNCardinalityneeds column:Variant Barcode

Barcode unique

No two variants share a barcode.

Why: Shared barcodes break POS and marketplace feeds.

URL-001 BLOCKURLs

Handle is URL-safe

Handles produce a valid storefront path without encoding.

Why: Unsafe characters change the public URL after import and break inbound links.

URL-002 WARNURLs

Redirect target valid

Every URL redirect target is a well-formed relative path or absolute URL.

Why: A malformed target becomes a live 404 the moment the redirect is created.

URL-003 INFOURLs

SEO title length

SEO titles stay under 70 characters.

Why: Advisory only; longer titles are truncated in search results.

MED-001 WARNMedia

Image URL well-formed

Image Src values are absolute https URLs.

Why: Relative or http image URLs fail to fetch during import and the product ships without images.

MED-002 WARNMedia

Image alt text present

Every image row carries alt text.

Why: Advisory: missing alt text is an accessibility and SEO gap, not an import failure.

MED-003 INFOMedianeeds network

Image reachable

Each image URL returns 200 from an authorized environment.

Why: Requires network access; the local analysis records this check as NOT_EXECUTED rather than guessing.

CMD-001 WARNCommands

Destructive command flagged

A row carries DELETE or REPLACE in the Command column.

Why: Destructive commands are legitimate but irreversible without a backup; a human confirms each one.

CMD-002 BLOCKCommands

Command value recognized

Command values are one of NEW, MERGE, UPDATE, REPLACE, DELETE, IGNORE.

Why: An unknown command makes the importer's behavior undefined for that row.

FRM-001 WARNFormula safety

Formula-like cell

No cell starts with =, +, -, @ or a tab followed by one of those.

Why: Formula-like cells execute in spreadsheet tools and can exfiltrate data; they are also never intended catalog values.

No analysis open

Open one of the prepared sample analyses, or drop a file on the Upload screen. Everything runs in this browser against a fictional store.