# Unadopted product evidence — native semantics This owner specifies `product_observations.validate`, `product_observations.validate-batch` and `product_observations.adapt`. They are semantic operation IDs, not an executable interface. Use native facilities to apply the complete [producer and adapter schema](product-observation.schema.json) and these rules. No Arch Studio helper, installation or reconstructed source is required. Read-only validation/adaptation performs no retrieval or canonical mutation; a requested saved report follows the [native mutation sequence](../docs/workspace-model.md#native-mutation-sequence), including actual prepared and destination access metadata. ## Validation and evidence Validate the entire closed schema, its nested branches, formats, bounds, required properties and additional-property rules. An unsupported assertion is a validation capability gap, not a successful check. Reject duplicate JSON object keys, nonfinite numbers and invalid Unicode; preserve original envelopes and exact number kinds. For schema constants, preserve exact kind: schema_version is integer1, never true or floating1.0. String minLength checks apply to trimmed length (so required field/source/locator/tag strings are nonblank), without trimming stored content; unrestricted text values can remain blank. A single result reports valid, observation_id and sha256 (the logical SHA-256 described below), with adoption_performed, retrieval_performed and specification_mutated all false. A batch is a nonempty array: validate every entry, reject the whole batch on any invalid entry or repeated observation UUID, and retain input order in results. Report the invalid index/field without dropping evidence. An envelope has schema_version1, canonical lowercase observation UUID and a real timezone-aware observed_at no more than five minutes ahead of the actual validation clock. Source kind is url/pdf/workbook/supplied. Retain actual nonempty source reference and optional lowercase 64-hex content hash or null. URL source references and nonnull image values must be absolute HTTP(S) without credentials. Do not infer current facts from access failure or a source label. Product identity retains exactly manufacturer, model, manufacturer_sku, vendor_item_id and storefront_id; missing values stay null. Configuration.selected records what was observed at the source, not a project selection; configuration.available records options. Preserve unique typed option values, original field order and duplicate field observations. The schema permits 1–10000 fields per envelope; every field carries field, kind, value, status, locator, unit, meaning, currency, price_basis and variant_match. Unknown/unavailable requires null value; inferred evidence stays inferred. Quantity and price are nonnegative finite JSON numbers or null; booleans are not numbers. Quantity needs unit/meaning for proposal eligibility; price needs evidenced uppercase three-letter currency and price_basis. Structurally allowed null or empty-string metadata can still make a value ineligible. Eligibility checks unit/meaning/price_basis for nonempty strings, not trimmed length when the schema has no minLength; preserve literal whitespace and source uncertainty rather than silently normalizing it. Text and image fields have null unrelated numeric metadata. Image value is a URL or null. Available options, family matches, unknown variant and inferred values never establish exact selected specifications. Zero is a value, not missing data. Preserve absent, null and empty string separately. ## Exact logical encoding Logical observation digests and adaptation input_sha256 are lowercase SHA-256 over compact UTF-8 JSON: sort every object's keys by Unicode scalar value, preserve array order, use comma/colon with no added spaces and no trailing LF. Encode Unicode directly; escape quote/backslash, use `\b`, `\t`, `\n`, `\f`, `\r` and lowercase `\u00xx` for other U+0000–U+001F controls. Do not escape slash, non-ASCII, U+2028 or U+2029. Reject unpaired surrogates. Booleans/null are lowercase. This is the historical logical digest grammar, distinct from a saved artifact's raw-byte hash. Parse integer tokens as exact arbitrary-precision integers and tokens with a decimal point or exponent as finite IEEE754 binary64. Preserve these kinds: true, 1 and 1.0 differ, as do -0.0 and 0.0. Integer negative zero encodes as 0. Integers use decimal digits without leading zeros. Floating values use the shortest correctly rounded coefficient that round-trips to the same binary64 value (nearest, ties to even); fixed notation for decimal exponent -4 through15, appending .0 when integral; otherwise lowercase e, explicit sign and at least two exponent digits without unnecessary .0 before e. Examples: 1e-4→0.0001, 1e-5→1e-05, 1e15→1000000000000000.0, 1e16→1e+16; -0.0 remains -0.0 and integer9007199254740993 remains exact. A representation that loses these distinctions cannot establish the digest. Canonical typed equality compares this encoding; object order is immaterial, array order and exact Unicode strings are material. ## Explicit adaptation inputs Use exactly schema_version1, observations, items and bindings under `$defs.adapter`: 1–1000 observations, 1–10000 selected items and 1–10000 bindings. Validate every observation first. Each item requires canonical item_id, integer revision>=1, nonempty exact tag, fields, provenance and decision_refs. Item IDs and exact tags are unique. Decision links are project-relative without traversal. Keep all original item identities, revisions, tags, present fields, provenance and links; this operation never reads names as permission to select an item. Each binding names observation_id, item_id, exact expected_revision and a nonempty map from source field names to target field names. Refuse unknown IDs, stale revisions, absent selected source fields and repeated identical `(observation_id,item_id,source-field,target-field)` bindings. Do not silently deduplicate or rebind. Preserve binding order, map encounter order and matching source-field order when producing audit/proposal results. Compare every nonempty observed product identity with the corresponding nonempty selected item's field by canonical typed equality. Differences produce product-identity-conflict with exact differing identity field names; every candidate from that observation/item pair becomes ineligible. Other explicitly bound pairs are assessed independently. ## Audit projection and proposals For every matching source field, retain an audit observation containing exactly item_id, target field, typed value, status, source `{reference,locator}` and observed_at. Typed values are text, price `{amount,currency,basis}`, quantity `{value,unit,meaning}`, image `{url,variant_match}`, or null. Keep all projected evidence in encounter order, including duplicate source fields. The legacy audit interface accepts only observed/unavailable. Use unavailable for identity conflict, source status unknown/unavailable/inferred, or nonexact variant; otherwise observed. In particular unknown/exact/null is **unavailable**, while its original full envelope and existing notice.status retain unknown. This explicitly corrects the old observed/null projection without changing the durable schema or adding an audit enum. Always deliver notices/conflicts alongside the reduced audit; it cannot represent all identity/configuration metadata. A candidate is eligible only when source status is observed, variant_match exact, value neither null nor empty string, no identity conflict, and quantity unit/meaning or price currency/basis is a nonempty string as applicable (use exact values; do not add trimming beyond the schema). Every ineligible bound field receives not-eligible-for-record-proposal with item_id, target field, observation_id, original status and variant_match. Do not discard the underlying envelope. Group eligible candidates by selected item/target field. Canonically unequal typed candidates produce conflicting-observations and no proposal for that field. Identical candidates can contribute one value using the **first eligible candidate in binding order, then source-field order**, while preserving all audit evidence. This is not necessarily observations-array order. If the target field is already present, preserve its value/provenance even when null or blank. An equal eligible candidate is a no-op; an unequal eligible candidate produces existing-value-requires-resolution. Ineligible evidence produces its notice, not an invented candidate conflict. Only an absent target receives a deep-copied proposed value and provenance: status supplied, original source reference, retrieved_at from observation.observed_at, and a note naming observation UUID/locator as host evidence not independently verified. Never advance revisions or manufacture approval. Return schema_version1, input_sha256, audit_observations, record_proposal.items, expected_item_revisions, conflicts, notices, requires_review true and adoption_performed/retrieval_performed/specification_mutated false. Proposal items preserve input order and all unaffected contents. Canonical adoption or revision requires the master-schedule owner, current schedule/item revisions, exact authority and its full publication guarantees. Reusable CSV saves belong to product-library. A validation result establishes schema conformity, not truth, retrieval, selection or publication. ## Exact adaptation result shapes `record_proposal` is exactly `{items: [...]}`; `expected_item_revisions` is an object mapping every selected item UUID to its unchanged integer revision. `conflicts`, `notices` and `audit_observations` are ordered arrays. Use these existing entries, with no inferred adoption flags or extra durable fields: | Entry | Exact members and meaning | |---|---| | Product identity conflict | item_id, observation_id, code `product-identity-conflict`, fields (array of differing identity field names in observed product member order). One entry per conflicting binding pair. | | Conflicting candidate values | item_id, field (target), code `conflicting-observations`, observed (all eligible typed candidate values in encounter order, including duplicate values). One per affected target; no field proposal. | | Existing unequal value | item_id, field (target), code `existing-value-requires-resolution`, recorded (original typed value), observed (single agreed eligible typed value). One per affected existing target. | | Ineligible evidence notice | item_id, field (target), observation_id, code `not-eligible-for-record-proposal`, status (original source status), variant_match (original match). One per ineligible bound field occurrence. | Identity conflicts are encountered while walking bindings; candidate-value/existing-value conflicts follow in first-encountered target-group order. Notices and audit entries retain binding/source-field encounter order. Identical candidate values do not erase duplicate audit entries or alter first eligible provenance. Batch validation returns valid true, count, ordered observations (each single validation result), and adoption_performed/retrieval_performed/specification_mutated false. Validation failure returns a precise field/index error without a successful result or partial published proposal.