{"schemaVersion":"1.0","canonicalUrl":"https://www.iamgeorgekelly.com/field-guide/product-feed-portability-experiment","markdownUrl":"https://www.iamgeorgekelly.com/field-guide/product-feed-portability-experiment/index.md","editorialNote":"AI-assisted research and drafting. Provider-specific claims link to primary sources. Frameworks are editorial proposals; worked examples are illustrative and are not employer performance results.","publication":{"name":"iamgeorgekelly","url":"https://www.iamgeorgekelly.com"},"citation":"George Kelly. Can you copy a product feed unchanged? A 12-case test iamgeorgekelly. Updated 2026-09-22. https://www.iamgeorgekelly.com/field-guide/product-feed-portability-experiment","slug":"product-feed-portability-experiment","title":"Can you copy a product feed unchanged? A 12-case test","description":"Inspect twelve synthetic product records or check your own JSON locally. Review explicit mappings, unresolved fields, and supplied evidence; download reproducible results.","answer":"In this controlled local test, explicit mapping cleared four representation problems. Six evidence or identity problems remained held. The result describes twelve deliberately authored records under a small review profile; it does not measure vendor acceptance, model accuracy, or typical merchant error rates.","category":"Product data","status":"published","published":"2026-09-13","updated":"2026-09-22","author":"George Kelly","sections":[{"id":"what-we-tested","title":"What the experiment actually tests","paragraphs":["On September 13, 2026, we executed a deterministic local comparison of two methods against the same twelve synthetic records: copy the record unchanged, or apply a small explicit transformation. There were two valid controls and ten deliberately selected edge cases.","The target is a canonical-field editorial review subset informed by OpenAI’s Stable native discovery format. It is not a simulation of its ingestion service. In particular, native providers may accept aliases that this local canonical-field profile reports for mapping. OpenAI’s separately confirmed Google-compatible upload path is outside the experiment.","All URLs, products, sellers, and page-price evidence are fictional. No external page was fetched, no product was uploaded, and no model was called. The same author designed the cases and checks; this is a reproducible worked experiment, not independent validation."],"sources":["openai"]},{"id":"observed-results","title":"Observed results: four repairs, six holds","paragraphs":["The original September 13 experiment and the shared-core rerun at 2026-09-22T01:51:11.141Z produced the same case observations and counts below. The unchanged method cleared the two controls and held all ten edge cases. Mapping cleared those controls plus four edge cases; six records still needed review. The fixture bytes are unchanged.","Clear means no issue was found in the named local checks. It does not mean upload-ready, factually correct in the world, approved by a provider, or visible in shopping results. We report counts because this constructed set is not a sample from a real catalog."],"table":{"headers":["Method","Records","No issue in these checks","Needs review"],"rows":[["copy","12","2","10"],["mapped","12","6","6"]]},"download":{"url":"/downloads/product-feed-portability-results.json","label":"Download the complete observed results (JSON)"}},{"id":"explore-cases","title":"Explore the saved cases or check your record","paragraphs":["Choose a fixture to inspect the original record, explicit changes, and resulting issues from the recorded run. Below it, paste your own product JSON to execute the same deterministic review rules in your browser and download the result.","The custom check accepts one JSON object plus optional supplied evidence, up to 64 KiB combined. Choose an unchanged review or explicit mapping. Input stays in your browser; there is no model call, provider upload, live-source lookup, or saved input. Supplied page-price and measurement-basis evidence is not independently verified."],"feedCaseExplorer":true},{"id":"case-register","title":"The complete case register","paragraphs":["The first two rows are controls. F01–F10 are the ten failure cases. The mapped decisions were written into the fixture file before execution; the observed result is recorded separately."],"table":{"headers":["Case","Unchanged","After mapping","What the case establishes"],"rows":[["C01 · Native nonvariant control","No issue in these checks","No issue in these checks","The selected local checks find no issue."],["C02 · Native variant control","No issue in these checks","No issue in these checks","The selected local checks find no issue in the declared variant."],["F01 · Destination field names","Needs review","No issue in these checks","Map source keys to the selected native representation."],["F02 · Preorder spelling","Needs review","No issue in these checks","Translate the explicit Google stock value to native pre_order."],["F03 · Variant representation","Needs review","No issue in these checks","Preserve the parent and selected options while constructing native grouping fields."],["F04 · Mixed explicit product units","Needs review","No issue in these checks","Convert two evidenced product axes to one unit."],["F05 · Missing seller identity","Needs review","Needs review","A required seller identity cannot be derived from the product brand."],["F06 · Numeric item identifier","Needs review","Needs review","The local profile refuses numeric IDs because prior string information may be lost."],["F07 · Parent reused as item ID","Needs review","Needs review","The parent and selected item must remain distinct."],["F08 · Conflicting selected color","Needs review","Needs review","A mapping must not silently choose between contradictory selected colors."],["F09 · Price disagrees with page","Needs review","Needs review","The supplied fictional page evidence disagrees with the offer price."],["F10 · Package dimensions relabeled","Needs review","Needs review","Package measurements do not establish the item dimensions."]]},"download":{"url":"/downloads/product-feed-portability-cases.json","label":"Download the frozen cases and protocol (JSON)"}},{"id":"why-four-clear","title":"Why four cases can be transformed","paragraphs":["F01 renames explicitly identified fields. F02 translates the known preorder spelling. F03 constructs a declared parent-and-option representation. F04 converts two supplied product dimensions to centimeters: 30 inches becomes 76.2 centimeters, while 50.8 centimeters remains unchanged.","These repairs use information already present in the record. They do not choose a seller, recover a lost leading zero, establish which color is correct, or substitute package measurements for product measurements. Numeric conversions in the runner are bounded demonstration arithmetic, not a general measurement library."],"sources":["openai","google-group","google-dimensions"]},{"id":"why-six-hold","title":"Why six cases still need evidence","paragraphs":["The held records lack a seller, contain a numeric item identifier, reuse a parent as the selected item, contradict their selected color, disagree with supplied page-price evidence, or label package dimensions as product dimensions. Returning to the authoritative source is part of the work.","The page-price and measurement-basis checks are additional editorial checks. They illustrate why satisfying field syntax alone cannot establish offer truth. The supplied evidence may itself be wrong; live-source verification remains outside this run."],"sources":["google-price","google-dimensions"],"links":[{"slug":"product-data-ownership","label":"Assign ownership to unresolved facts","reason":"A missing or conflicting fact needs a source decision before a mapping rule."}]},{"id":"reproduce","title":"Reproduce the recorded comparison","paragraphs":["Download the runner below, the shared review core in the next section, and the frozen fixture JSON into the same folder. With Node.js 22 or later, run: node product-feed-portability.mjs --fixtures product-feed-portability-cases.json. It writes a JSON report to standard output and makes no network requests.","The report records a run timestamp, rule version, and SHA-256 hashes of the fixture bytes, runner, and shared review core. A rerun has a different timestamp; identical source files should reproduce the same case observations and counts. The browser and downloaded runner use the same mapping and review functions.","Changing the cases creates a different experiment. Preserve the original denominator and edition, document the new conditions, and report new results separately."],"download":{"url":"/downloads/product-feed-portability.mjs","label":"Download the local runner (.mjs; requires the core below)"}},{"id":"check-your-own-record-locally","title":"Check your own record from a local file","paragraphs":["Save a single product object as product.json, then download the shared core below beside the runner. Run: node product-feed-portability.mjs --record product.json. The unchanged review is the default. The original JSON file is not modified.","To apply the explicit transformations with optional evidence, run: node product-feed-portability.mjs --record product.json --evidence evidence.json --method mapped. The evidence file should be an object such as {\"pagePrice\":\"18.00 USD\",\"dimensionBasis\":\"product\"}. Omit --evidence evidence.json when no evidence is supplied.","The combined record and evidence limit is 64 KiB. Arrays, scalars, excessive nesting, and invalid JSON are rejected. The report includes the input, supplied evidence, resulting record, applied changes, field issues, rule version, and limits.","These are the same small canonical-field and positive-USD checks used in the experiment. A result with no issue does not establish provider acceptance or that the product facts are true."],"download":{"url":"/downloads/product-feed-review.mjs","label":"Download the shared browser-safe review core (.mjs)"}},{"id":"limits-and-next-test","title":"What remains untested","paragraphs":["The local review does not cover the full destination schema, merchant eligibility, network accessibility, live imagery, GTIN assignment, real stock, checkout, every currency, or cross-row catalog consistency. Its monetary checks deliberately use positive USD amounts with two decimal places.","To estimate operational performance, use a separately selected real catalog sample, authorized source evidence, predeclared criteria, and a reviewer who did not author the transformations. To compare AI models, run and retain actual model outputs under a specified protocol. Neither measurement has been performed here.","Use these cases as a starting regression set for a mapping project. The useful result is knowing which decisions still need evidence, not maximizing a pass count."],"links":[{"slug":"product-data-conflict-casebook","label":"Test agreement after record checks pass","reason":"Run the same synthetic records through both portability and freshness checks."}]}],"sources":[{"id":"openai","title":"OpenAI: Stable product file-upload specification","url":"https://developers.openai.com/commerce/specs/file-upload/products","note":"Native discovery fields and the distinct Google-compatible path. This edition is a selected comparison, not the complete upload contract.","checked":"2026-09-13"},{"id":"google-group","title":"Google Merchant Center: Item group ID","url":"https://support.google.com/merchants/answer/6324507?hl=en","note":"Variant groups, identifying attributes, and matching landing-page values.","checked":"2026-09-13"},{"id":"google-price","title":"Google Merchant Center: Price","url":"https://support.google.com/merchants/answer/6324371?hl=en","note":"Amount and currency, plus agreement with landing page and checkout.","checked":"2026-09-13"},{"id":"google-dimensions","title":"Google Merchant Center: Product dimensions and weight","url":"https://support.google.com/merchants/answer/11018531?hl=en","note":"Product measures, accepted units, and agreement between repeated measurements. Packaging has a different meaning.","checked":"2026-09-13"}],"related":["product-data-conflict-casebook","product-feed-field-reference","product-identifiers-sku-gtin-variants","product-variant-acceptance-test"]}