Skip to content

feat(onboarding): add catalog-hygiene-audit skill - #136

Open
yani-c wants to merge 1 commit into
Fluid-WeCommerce:mainfrom
yani-c:feat/onboarding-catalog-hygiene-audit
Open

feat(onboarding): add catalog-hygiene-audit skill#136
yani-c wants to merge 1 commit into
Fluid-WeCommerce:mainfrom
yani-c:feat/onboarding-catalog-hygiene-audit

Conversation

@yani-c

@yani-c yani-c commented Jul 31, 2026

Copy link
Copy Markdown

What

Adds onboarding/catalog-hygiene-audit — a read-only catalog integrity sweep that
finds the defects a post-import catalog ships with, ranks them by customer-visible
impact, and applies only what the user approves, one product at a time.

Five detection rules:

Rule Severity Finds
R1 CRITICAL the same normalized SKU on 2+ distinct product ids
R2 HIGH a defective slug live on a public URL (-copy, copy-of-, ^untitled, title mismatch)
R3 MEDIUM two or more slug patterns expressing one qualifier inside a product family
R4 MEDIUM an identical image_url across distinct products (reported, never auto-fixed)
R5 CRITICAL a 0/null price on a product that is active and purchasable right now

Why

These defects are invisible in the admin list view and loud to a customer. A
product left at $0.00 is buyable at zero until someone notices; a slug like
…/products/widget-2-copy is an admin duplicate that shipped to the public URL.
A shared SKU is quieter and worse — it breaks inventory decrementing and merges
two products in every revenue report.

The skill is deliberately conservative: read-only until an explicit per-product
approval, no bulk writes, no deletions (archive is proposed instead, and
"remove" is never silently read as "delete"), and no invented prices.

Validated against a live catalog

Run end to end on a real 51-product catalog. Found 4 unpriced live products, 2
SKU collisions, 2 defective slugs, a family with 3 competing slug patterns for
one qualifier, and 2 image-reuse cases needing a merchandising judgment call —
42 products clean. One fix was taken through the approval gate and verified by
re-read.

Three findings from that run are baked into the skill:

  1. The custom_slug trap. PATCH /api/v202604/company/products/{id} with a
    slug but no custom_slug: true returns 200 with the OLD slug — the API
    regenerates from the title and silently discards yours. An agent following the
    obvious path reports a success that did not happen. This is why the skill
    mandates a re-read before claiming any fix, and why Step 5 says a 200 is not
    proof.
  2. sku at product level is usually null; the real value is
    default_variant.sku. Deduplicating on the product field finds nothing on a
    catalog full of duplicate SKUs.
  3. Archiving a $0 product does not fix its price. The variant's country row
    keeps price: "0.0" and buyable: true, so republishing reintroduces the
    defect. The skill has to report that residual rather than implying the data is
    now correct.

Rules also suppress two classes of false positive that a naive implementation
gets wrong: a trailing digit that is a model number (widget-2 for "Widget 2")
is not an admin counter, and a refurbished listing reusing its retail parent's
hero image is normal, not a merchandising gap.

How to test

python3 scripts/validate_catalog.py
python3 -m unittest discover -s scripts -p 'test_*.py'

Expect catalog validation passed: 42 skills, 6 workflows and 16 tests OK.

Note that neither validator actually inspects a new skill's body — frontmatter is
not validated, and the banned-fragment scan runs only against the 14 hardcoded
SHARED_CONTRACT_FILES. So the green check confirms the manifest entry, not the
content. The skill carries no company-specific names, product ids, SKUs, or
currencies; examples use a neutral widget-2.

Category

Filed under onboarding because its nearest neighbour is
onboarding/fluid-product-admin-import — this audits what that import produced.
It is not exclusively a post-import skill, though, so if maintainers would rather
see a new top-level catalog category (the way #96 added portal), it is a
one-line change in the manifest entry and the file path. Happy either way.

Known limitations

  • R3 and R4 are judgment calls the skill deliberately refuses to auto-fix. R4 in
    particular needs a human to distinguish a legitimate refurb reusing its parent's
    image from a differently-branded listing that needs its own photography.
  • R5 never invents a price. Where a price is genuinely unknown (member-gated
    pricing behind a login, for instance) the skill reports it as awaiting a
    decision
    and offers reversible archival as the interim fix.
  • Slug repair changes a live public URL and the old one 404s. The skill checks
    mobile widgets for references and states the blast radius on the approval card,
    but it cannot see every external inbound link.

Adds a read-only catalog integrity sweep that ranks data defects by
customer-visible impact and applies only user-approved fixes, one product
at a time.

Five rules: duplicate SKU across distinct products, defective slug shipped
live, inconsistent family naming, image reused across products, and zero or
missing price on a purchasable product.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant