commit 8d0e7300bb65431cbe9306a07d1853f17317822a parent 0ce0a87f49fd2777c5ae6cbca7bbdb6c5d32f342 Author: triesap <tyson@radroots.org> Date: Thu, 24 Sep 2026 15:58:29 +0000 C004: add strict hyf_ops_v2 operation schemas, examples and manifests (D45 CB01-CB04) Diffstat:
47 files changed, 2547 insertions(+), 0 deletions(-)
diff --git a/schemas/hyf_ops_v2/buyer_request_interpret.request.schema.json b/schemas/hyf_ops_v2/buyer_request_interpret.request.schema.json @@ -0,0 +1,252 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "hyf_ops_v2/buyer_request_interpret.request.schema.json", + "title": "hyf_ops_v2 buyer_request.interpret strict request (ADR-0025 D45 CB01-CB04)", + "$comment": "Corrected versioned operation contract. Buyer operations never require a fabricated farm identity; context farm_id is forbidden and the trusted buyer principal is context.actor_id.", + "type": "object", + "properties": { + "version": { + "type": "integer", + "const": 1 + }, + "request_id": { + "type": "string", + "minLength": 1 + }, + "trace_id": { + "type": "string", + "minLength": 1 + }, + "capability": { + "type": "string", + "const": "buyer_request.interpret" + }, + "context": { + "$ref": "#/$defs/buyer_context" + }, + "input": { + "$ref": "#/$defs/buyer_interpret_input" + } + }, + "required": ["version", "request_id", "capability", "context", "input"], + "additionalProperties": false, + "$defs": { + "versions": { + "type": "object", + "properties": { + "schema": {"type": "string", "const": "hyf_ops_v2"}, + "taxonomy": {"type": "string", "minLength": 1}, + "normalization": {"type": "string", "minLength": 1}, + "review_policy": {"type": "string", "minLength": 1}, + "ranking_policy": {"type": "string", "minLength": 1}, + "question_bundle": {"type": "string", "minLength": 1}, + "model": {"type": "string", "minLength": 1} + }, + "required": [ + "schema", + "taxonomy", + "normalization", + "review_policy", + "ranking_policy", + "question_bundle", + "model" + ], + "additionalProperties": false + }, + "buyer_context": { + "type": "object", + "properties": { + "consumer": {"type": "string", "minLength": 1}, + "execution_mode_preference": { + "type": "string", + "enum": ["deterministic", "assisted"] + }, + "deadline_ms": {"type": "integer", "minimum": 1}, + "evaluation_time": {"type": "string", "minLength": 1}, + "timezone": {"type": "string", "minLength": 1}, + "locale": {"type": "string", "minLength": 1}, + "versions": {"$ref": "#/$defs/versions"}, + "return_provenance": {"type": "boolean"}, + "actor_id": {"type": "string", "minLength": 1} + }, + "required": ["evaluation_time", "versions", "actor_id"], + "additionalProperties": false + }, + "interpretation_source_buyer": { + "type": "object", + "properties": { + "source_id": {"type": "string", "minLength": 1}, + "revision": {"type": "string", "minLength": 1}, + "text": {"type": "string", "minLength": 1}, + "source_time": {"type": "string", "minLength": 1}, + "timezone": {"type": "string", "minLength": 1}, + "locale": {"type": "string", "minLength": 1}, + "actor_id": {"type": "string", "minLength": 1}, + "ingestion_time": {"type": "string", "minLength": 1} + }, + "required": [ + "source_id", + "revision", + "text", + "source_time", + "actor_id" + ], + "additionalProperties": false + }, + "reported_quantity": { + "type": "object", + "properties": { + "state": {"type": "string", "enum": ["known", "unknown"]}, + "value": { + "type": ["string", "null"], + "pattern": "^-?(0|[1-9][0-9]*)(\\.[0-9]{1,9})?$" + }, + "unit": {"type": ["string", "null"], "minLength": 1}, + "qualifier": {"type": "string", "enum": ["exact", "approximate"]} + }, + "required": ["state", "qualifier"], + "additionalProperties": false, + "allOf": [ + { + "if": { + "properties": {"state": {"const": "unknown"}}, + "required": ["state"] + }, + "then": { + "properties": {"value": {"type": "null"}, "unit": {"type": "null"}} + } + }, + { + "if": { + "properties": {"state": {"const": "known"}}, + "required": ["state"] + }, + "then": { + "properties": { + "value": { + "type": "string", + "pattern": "^-?(0|[1-9][0-9]*)(\\.[0-9]{1,9})?$" + }, + "unit": {"type": "string", "minLength": 1} + }, + "required": ["value", "unit"] + } + } + ] + }, + "taxonomy_bundle": { + "type": "object", + "properties": { + "version": {"type": "string", "minLength": 1}, + "provenance": {"type": "string", "enum": ["synthetic", "host_supplied"]}, + "products": { + "type": "array", + "items": { + "type": "object", + "properties": { + "catalogue_id": {"type": "string", "minLength": 1}, + "terms": { + "type": "array", + "minItems": 1, + "items": {"type": "string", "minLength": 1} + } + }, + "required": ["catalogue_id", "terms"], + "additionalProperties": false + } + } + }, + "required": ["version", "provenance", "products"], + "additionalProperties": false + }, + "normalization_bundle": { + "type": "object", + "properties": { + "version": {"type": "string", "minLength": 1}, + "provenance": {"type": "string", "enum": ["synthetic", "host_supplied"]}, + "units": { + "type": "array", + "items": { + "type": "object", + "properties": { + "unit": {"type": "string", "minLength": 1}, + "dimension": { + "type": "string", + "enum": ["mass", "volume", "count", "unknown"] + } + }, + "required": ["unit", "dimension"], + "additionalProperties": false + } + }, + "conversions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "from_unit": {"type": "string", "minLength": 1}, + "to_unit": {"type": "string", "minLength": 1}, + "numerator": {"type": "string", "pattern": "^[1-9][0-9]*$"}, + "denominator": {"type": "string", "pattern": "^10*$"} + }, + "required": ["from_unit", "to_unit", "numerator", "denominator"], + "additionalProperties": false + } + }, + "packs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "product_id": {"type": "string", "minLength": 1}, + "pack_unit": {"type": "string", "minLength": 1}, + "inner_unit": {"type": "string", "minLength": 1}, + "value": { + "type": "string", + "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]{1,9})?$", + "allOf": [ + {"not": {"const": "0"}}, + {"not": {"pattern": "^0(\\.0+)?$"}} + ] + } + }, + "required": ["product_id", "pack_unit", "inner_unit", "value"], + "additionalProperties": false + } + } + }, + "required": ["version", "provenance", "units", "conversions", "packs"], + "additionalProperties": false + }, + "references": { + "type": "object", + "properties": { + "taxonomy": {"$ref": "#/$defs/taxonomy_bundle"}, + "normalization": {"$ref": "#/$defs/normalization_bundle"} + }, + "required": ["taxonomy", "normalization"], + "additionalProperties": false + }, + "clarification": { + "type": "object", + "properties": { + "source_id": {"type": "string", "minLength": 1}, + "revision": {"type": "string", "minLength": 1}, + "target_field": {"type": "string", "minLength": 1}, + "text": {"type": "string", "minLength": 1} + }, + "required": ["source_id", "revision", "target_field", "text"], + "additionalProperties": false + }, + "buyer_interpret_input": { + "type": "object", + "properties": { + "source": {"$ref": "#/$defs/interpretation_source_buyer"}, + "references": {"$ref": "#/$defs/references"}, + "clarification": {"$ref": "#/$defs/clarification"} + }, + "required": ["source", "references"], + "additionalProperties": false + } + } +} diff --git a/schemas/hyf_ops_v2/buyer_request_interpret.response.schema.json b/schemas/hyf_ops_v2/buyer_request_interpret.response.schema.json @@ -0,0 +1,205 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "hyf_ops_v2/buyer_request_interpret.response.schema.json", + "title": "hyf_ops_v2 buyer_request.interpret strict response (ADR-0025 D45 CB02-CB04)", + "$comment": "Typed demand lines with the D23 reported decimal-string projection; inference is never treated as confirmation.", + "type": "object", + "properties": { + "version": { + "type": "integer", + "const": 1 + }, + "request_id": { + "type": "string", + "minLength": 1 + }, + "trace_id": { + "type": "string" + }, + "ok": { + "type": "boolean" + }, + "output": { + "$ref": "#/$defs/interpret_output" + }, + "error": { + "$ref": "#/$defs/wire_error" + }, + "meta": { + "type": "object", + "additionalProperties": true + } + }, + "required": ["version", "request_id", "ok"], + "additionalProperties": false, + "$defs": { + "wire_error": { + "type": "object", + "properties": { + "code": {"type": "string", "minLength": 1}, + "message": {"type": "string"} + }, + "required": ["code", "message"], + "additionalProperties": false + }, + "evidence_span": { + "type": "object", + "properties": { + "source_id": {"type": "string", "minLength": 1}, + "revision": {"type": "string", "minLength": 1}, + "start": {"type": "integer", "minimum": 0}, + "end": {"type": "integer", "minimum": 0}, + "method": {"type": "string", "minLength": 1} + }, + "required": ["source_id", "revision", "start", "end", "method"], + "additionalProperties": false + }, + "reported_quantity": { + "type": "object", + "properties": { + "state": {"type": "string", "enum": ["known", "unknown"]}, + "value": { + "type": ["string", "null"], + "pattern": "^-?(0|[1-9][0-9]*)(\\.[0-9]{1,9})?$" + }, + "unit": {"type": ["string", "null"], "minLength": 1}, + "qualifier": {"type": "string", "enum": ["exact", "approximate"]} + }, + "required": ["state", "qualifier"], + "additionalProperties": false, + "allOf": [ + { + "if": { + "properties": {"state": {"const": "unknown"}}, + "required": ["state"] + }, + "then": { + "properties": {"value": {"type": "null"}, "unit": {"type": "null"}} + } + }, + { + "if": { + "properties": {"state": {"const": "known"}}, + "required": ["state"] + }, + "then": { + "properties": { + "value": { + "type": "string", + "pattern": "^-?(0|[1-9][0-9]*)(\\.[0-9]{1,9})?$" + }, + "unit": {"type": "string", "minLength": 1} + }, + "required": ["value", "unit"] + } + } + ] + }, + "product_ref": { + "type": "object", + "properties": { + "phrase": {"type": "string", "minLength": 1}, + "catalogue_id": {"type": ["string", "null"], "minLength": 1}, + "resolution": {"type": "string", "enum": ["resolved", "unresolved"]} + }, + "required": ["phrase", "catalogue_id", "resolution"], + "additionalProperties": false + }, + "demand_line": { + "type": "object", + "properties": { + "line_id": {"type": "string", "minLength": 1}, + "product": {"$ref": "#/$defs/product_ref"}, + "quantity": {"$ref": "#/$defs/reported_quantity"}, + "conditions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": [ + "fulfillment", + "window", + "grade", + "price", + "attribute", + "substitution" + ] + }, + "strength": { + "type": "string", + "enum": ["mandatory", "preferred", "excluded", "permitted"] + }, + "value": {"type": ["string", "null"]}, + "evidence": { + "type": "array", + "items": {"$ref": "#/$defs/evidence_span"} + } + }, + "required": ["kind", "strength", "evidence"], + "additionalProperties": false + } + }, + "evidence": { + "type": "array", + "items": {"$ref": "#/$defs/evidence_span"} + }, + "review_required": {"type": "boolean"} + }, + "required": [ + "line_id", + "product", + "quantity", + "conditions", + "evidence", + "review_required" + ], + "additionalProperties": false + }, + "review": { + "type": "object", + "properties": { + "required": {"type": "boolean"}, + "clarifications": { + "type": "array", + "items": { + "type": "object", + "properties": { + "field": {"type": "string", "minLength": 1}, + "reason": {"type": "string", "minLength": 1} + }, + "required": ["field", "reason"], + "additionalProperties": false + } + } + }, + "required": ["required", "clarifications"], + "additionalProperties": false + }, + "execution": { + "type": "object", + "properties": { + "status": {"type": "string", "enum": ["complete", "degraded", "failed"]}, + "provider_calls": {"type": "integer", "minimum": 0}, + "model": {"type": ["string", "null"]}, + "question_bundle": {"type": ["string", "null"]} + }, + "required": ["status", "provider_calls", "model", "question_bundle"], + "additionalProperties": false + }, + "interpret_output": { + "type": "object", + "properties": { + "demand_lines": { + "type": "array", + "items": {"$ref": "#/$defs/demand_line"} + }, + "review": {"$ref": "#/$defs/review"}, + "execution": {"$ref": "#/$defs/execution"} + }, + "required": ["demand_lines", "review", "execution"], + "additionalProperties": false + } + } +} diff --git a/schemas/hyf_ops_v2/buyer_request_match.request.schema.json b/schemas/hyf_ops_v2/buyer_request_match.request.schema.json @@ -0,0 +1,390 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "hyf_ops_v2/buyer_request_match.request.schema.json", + "title": "hyf_ops_v2 buyer_request.match strict request (ADR-0025 D45 CB01-CB04)", + "$comment": "Corrected versioned operation contract. Consumes the typed reviewed need, authorized snapshots and coverage; no flattened product_phrase/unreserved_value/scale shortcut.", + "type": "object", + "properties": { + "version": { + "type": "integer", + "const": 1 + }, + "request_id": { + "type": "string", + "minLength": 1 + }, + "trace_id": { + "type": "string", + "minLength": 1 + }, + "capability": { + "type": "string", + "const": "buyer_request.match" + }, + "context": { + "$ref": "#/$defs/buyer_context" + }, + "input": { + "$ref": "#/$defs/match_input" + } + }, + "required": ["version", "request_id", "capability", "context", "input"], + "additionalProperties": false, + "$defs": { + "versions": { + "type": "object", + "properties": { + "schema": {"type": "string", "const": "hyf_ops_v2"}, + "taxonomy": {"type": "string", "minLength": 1}, + "normalization": {"type": "string", "minLength": 1}, + "review_policy": {"type": "string", "minLength": 1}, + "ranking_policy": {"type": "string", "minLength": 1}, + "question_bundle": {"type": "string", "minLength": 1}, + "model": {"type": "string", "minLength": 1} + }, + "required": [ + "schema", + "taxonomy", + "normalization", + "review_policy", + "ranking_policy", + "question_bundle", + "model" + ], + "additionalProperties": false + }, + "buyer_context": { + "type": "object", + "properties": { + "consumer": {"type": "string", "minLength": 1}, + "execution_mode_preference": { + "type": "string", + "enum": ["deterministic", "assisted"] + }, + "deadline_ms": {"type": "integer", "minimum": 1}, + "evaluation_time": {"type": "string", "minLength": 1}, + "timezone": {"type": "string", "minLength": 1}, + "locale": {"type": "string", "minLength": 1}, + "versions": {"$ref": "#/$defs/versions"}, + "return_provenance": {"type": "boolean"}, + "actor_id": {"type": "string", "minLength": 1} + }, + "required": ["evaluation_time", "versions", "actor_id"], + "additionalProperties": false + }, + "evidence_span": { + "type": "object", + "properties": { + "source_id": {"type": "string", "minLength": 1}, + "revision": {"type": "string", "minLength": 1}, + "start": {"type": "integer", "minimum": 0}, + "end": {"type": "integer", "minimum": 0}, + "method": {"type": "string", "minLength": 1} + }, + "required": ["source_id", "revision", "start", "end", "method"], + "additionalProperties": false + }, + "reported_quantity": { + "type": "object", + "properties": { + "state": {"type": "string", "enum": ["known", "unknown"]}, + "value": { + "type": ["string", "null"], + "pattern": "^-?(0|[1-9][0-9]*)(\\.[0-9]{1,9})?$" + }, + "unit": {"type": ["string", "null"], "minLength": 1}, + "qualifier": {"type": "string", "enum": ["exact", "approximate"]} + }, + "required": ["state", "qualifier"], + "additionalProperties": false, + "allOf": [ + { + "if": { + "properties": {"state": {"const": "unknown"}}, + "required": ["state"] + }, + "then": { + "properties": {"value": {"type": "null"}, "unit": {"type": "null"}} + } + }, + { + "if": { + "properties": {"state": {"const": "known"}}, + "required": ["state"] + }, + "then": { + "properties": { + "value": { + "type": "string", + "pattern": "^-?(0|[1-9][0-9]*)(\\.[0-9]{1,9})?$" + }, + "unit": {"type": "string", "minLength": 1} + }, + "required": ["value", "unit"] + } + } + ] + }, + "product_ref": { + "type": "object", + "properties": { + "phrase": {"type": "string", "minLength": 1}, + "catalogue_id": {"type": ["string", "null"], "minLength": 1}, + "resolution": {"type": "string", "enum": ["resolved", "unresolved"]} + }, + "required": ["phrase", "catalogue_id", "resolution"], + "additionalProperties": false + }, + "taxonomy_bundle": { + "type": "object", + "properties": { + "version": {"type": "string", "minLength": 1}, + "provenance": {"type": "string", "enum": ["synthetic", "host_supplied"]}, + "products": { + "type": "array", + "items": { + "type": "object", + "properties": { + "catalogue_id": {"type": "string", "minLength": 1}, + "terms": { + "type": "array", + "minItems": 1, + "items": {"type": "string", "minLength": 1} + } + }, + "required": ["catalogue_id", "terms"], + "additionalProperties": false + } + } + }, + "required": ["version", "provenance", "products"], + "additionalProperties": false + }, + "normalization_bundle": { + "type": "object", + "properties": { + "version": {"type": "string", "minLength": 1}, + "provenance": {"type": "string", "enum": ["synthetic", "host_supplied"]}, + "units": { + "type": "array", + "items": { + "type": "object", + "properties": { + "unit": {"type": "string", "minLength": 1}, + "dimension": { + "type": "string", + "enum": ["mass", "volume", "count", "unknown"] + } + }, + "required": ["unit", "dimension"], + "additionalProperties": false + } + }, + "conversions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "from_unit": {"type": "string", "minLength": 1}, + "to_unit": {"type": "string", "minLength": 1}, + "numerator": {"type": "string", "pattern": "^[1-9][0-9]*$"}, + "denominator": {"type": "string", "pattern": "^10*$"} + }, + "required": ["from_unit", "to_unit", "numerator", "denominator"], + "additionalProperties": false + } + }, + "packs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "product_id": {"type": "string", "minLength": 1}, + "pack_unit": {"type": "string", "minLength": 1}, + "inner_unit": {"type": "string", "minLength": 1}, + "value": { + "type": "string", + "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]{1,9})?$", + "allOf": [ + {"not": {"const": "0"}}, + {"not": {"pattern": "^0(\\.0+)?$"}} + ] + } + }, + "required": ["product_id", "pack_unit", "inner_unit", "value"], + "additionalProperties": false + } + } + }, + "required": ["version", "provenance", "units", "conversions", "packs"], + "additionalProperties": false + }, + "references": { + "type": "object", + "properties": { + "taxonomy": {"$ref": "#/$defs/taxonomy_bundle"}, + "normalization": {"$ref": "#/$defs/normalization_bundle"} + }, + "required": ["taxonomy", "normalization"], + "additionalProperties": false + }, + "demand_line": { + "type": "object", + "properties": { + "line_id": {"type": "string", "minLength": 1}, + "product": {"$ref": "#/$defs/product_ref"}, + "quantity": {"$ref": "#/$defs/reported_quantity"}, + "conditions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": [ + "fulfillment", + "window", + "grade", + "price", + "attribute", + "substitution" + ] + }, + "strength": { + "type": "string", + "enum": ["mandatory", "preferred", "excluded", "permitted"] + }, + "value": {"type": ["string", "null"]}, + "evidence": { + "type": "array", + "items": {"$ref": "#/$defs/evidence_span"} + } + }, + "required": ["kind", "strength", "evidence"], + "additionalProperties": false + } + }, + "evidence": { + "type": "array", + "items": {"$ref": "#/$defs/evidence_span"} + }, + "review_required": {"type": "boolean"} + }, + "required": [ + "line_id", + "product", + "quantity", + "conditions", + "evidence", + "review_required" + ], + "additionalProperties": false + }, + "need": { + "type": "object", + "properties": { + "need_id": {"type": "string", "minLength": 1}, + "revision": {"type": "string", "minLength": 1}, + "actor_id": {"type": "string", "minLength": 1}, + "demand_lines": { + "type": "array", + "items": {"$ref": "#/$defs/demand_line"} + }, + "partial_fulfillment": { + "type": "string", + "enum": ["allowed", "disallowed", "unstated"] + } + }, + "required": [ + "need_id", + "revision", + "actor_id", + "demand_lines", + "partial_fulfillment" + ], + "additionalProperties": false + }, + "snapshot": { + "type": "object", + "properties": { + "lot_id": {"type": "string", "minLength": 1}, + "revision": {"type": "string", "minLength": 1}, + "supplier_id": {"type": "string", "minLength": 1}, + "product": {"$ref": "#/$defs/product_ref"}, + "unreserved_quantity": {"$ref": "#/$defs/reported_quantity"}, + "attributes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": {"type": "string", "minLength": 1}, + "verified": {"type": "boolean"} + }, + "required": ["name", "verified"], + "additionalProperties": false + } + }, + "fulfillment": { + "type": "object", + "properties": { + "method": { + "type": "string", + "enum": ["pickup", "delivery", "unspecified"] + }, + "area": {"type": ["string", "null"]}, + "window": {"type": ["string", "null"]} + }, + "required": ["method", "area", "window"], + "additionalProperties": false + }, + "price": { + "type": "object", + "properties": { + "state": {"type": "string", "enum": ["known", "unknown"]}, + "amount": { + "type": ["string", "null"], + "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]{1,9})?$" + }, + "currency": {"type": ["string", "null"], "minLength": 3}, + "basis": {"type": ["string", "null"], "minLength": 1} + }, + "required": ["state", "amount", "currency", "basis"], + "additionalProperties": false + } + }, + "required": [ + "lot_id", + "revision", + "supplier_id", + "product", + "unreserved_quantity" + ], + "additionalProperties": false + }, + "coverage": { + "type": "object", + "properties": { + "scope": {"type": "string", "enum": ["supplied_only"]}, + "truncated": {"type": "boolean"}, + "evaluated": {"type": "integer", "minimum": 0}, + "excluded": {"type": "integer", "minimum": 0} + }, + "required": ["scope", "truncated"], + "additionalProperties": false + }, + "match_input": { + "type": "object", + "properties": { + "need": {"$ref": "#/$defs/need"}, + "snapshots": { + "type": "array", + "items": {"$ref": "#/$defs/snapshot"} + }, + "coverage": {"$ref": "#/$defs/coverage"}, + "references": {"$ref": "#/$defs/references"} + }, + "required": ["need", "snapshots", "coverage", "references"], + "additionalProperties": false + } + } +} diff --git a/schemas/hyf_ops_v2/buyer_request_match.response.schema.json b/schemas/hyf_ops_v2/buyer_request_match.response.schema.json @@ -0,0 +1,232 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "hyf_ops_v2/buyer_request.match.response.schema.json", + "title": "hyf_ops_v2 buyer_request.match strict response (ADR-0025 D45 CB02-CB04)", + "$comment": "Assessments and bounded single-supplier plans are suggestions, never reservations. Allocated quantities use the D23 reported projection and carry the lot revision.", + "type": "object", + "properties": { + "version": { + "type": "integer", + "const": 1 + }, + "request_id": { + "type": "string", + "minLength": 1 + }, + "trace_id": { + "type": "string" + }, + "ok": { + "type": "boolean" + }, + "output": { + "$ref": "#/$defs/match_output" + }, + "error": { + "$ref": "#/$defs/wire_error" + }, + "meta": { + "type": "object", + "additionalProperties": true + } + }, + "required": ["version", "request_id", "ok"], + "additionalProperties": false, + "$defs": { + "wire_error": { + "type": "object", + "properties": { + "code": {"type": "string", "minLength": 1}, + "message": {"type": "string"} + }, + "required": ["code", "message"], + "additionalProperties": false + }, + "evidence_span": { + "type": "object", + "properties": { + "source_id": {"type": "string", "minLength": 1}, + "revision": {"type": "string", "minLength": 1}, + "start": {"type": "integer", "minimum": 0}, + "end": {"type": "integer", "minimum": 0}, + "method": {"type": "string", "minLength": 1} + }, + "required": ["source_id", "revision", "start", "end", "method"], + "additionalProperties": false + }, + "reported_quantity": { + "type": "object", + "properties": { + "state": {"type": "string", "enum": ["known", "unknown"]}, + "value": { + "type": ["string", "null"], + "pattern": "^-?(0|[1-9][0-9]*)(\\.[0-9]{1,9})?$" + }, + "unit": {"type": ["string", "null"], "minLength": 1}, + "qualifier": {"type": "string", "enum": ["exact", "approximate"]} + }, + "required": ["state", "qualifier"], + "additionalProperties": false, + "allOf": [ + { + "if": { + "properties": {"state": {"const": "unknown"}}, + "required": ["state"] + }, + "then": { + "properties": {"value": {"type": "null"}, "unit": {"type": "null"}} + } + }, + { + "if": { + "properties": {"state": {"const": "known"}}, + "required": ["state"] + }, + "then": { + "properties": { + "value": { + "type": "string", + "pattern": "^-?(0|[1-9][0-9]*)(\\.[0-9]{1,9})?$" + }, + "unit": {"type": "string", "minLength": 1} + }, + "required": ["value", "unit"] + } + } + ] + }, + "check": { + "type": "object", + "properties": { + "kind": {"type": "string", "minLength": 1}, + "result": {"type": "string", "enum": ["pass", "fail", "unknown"]}, + "reason": {"type": "string", "minLength": 1}, + "evidence": { + "type": "array", + "items": {"$ref": "#/$defs/evidence_span"} + } + }, + "required": ["kind", "result", "reason"], + "additionalProperties": false + }, + "assessment": { + "type": "object", + "properties": { + "candidate_id": {"type": "string", "minLength": 1}, + "eligibility": { + "type": "string", + "enum": ["eligible", "conditional", "ineligible"] + }, + "checks": { + "type": "array", + "items": {"$ref": "#/$defs/check"} + } + }, + "required": ["candidate_id", "eligibility", "checks"], + "additionalProperties": false + }, + "allocation": { + "type": "object", + "properties": { + "lot_id": {"type": "string", "minLength": 1}, + "revision": {"type": "string", "minLength": 1}, + "line_id": {"type": "string", "minLength": 1}, + "quantity": {"$ref": "#/$defs/reported_quantity"} + }, + "required": ["lot_id", "revision", "line_id", "quantity"], + "additionalProperties": false + }, + "plan": { + "type": "object", + "properties": { + "plan_id": {"type": "string", "minLength": 1}, + "supplier_id": {"type": "string", "minLength": 1}, + "allocations": { + "type": "array", + "items": {"$ref": "#/$defs/allocation"} + }, + "coverage": { + "type": "object", + "properties": { + "lines_covered": { + "type": "array", + "items": {"type": "string", "minLength": 1} + }, + "uncovered": { + "type": "array", + "items": {"type": "string", "minLength": 1} + }, + "partial": {"type": "boolean"} + }, + "required": ["lines_covered", "uncovered", "partial"], + "additionalProperties": false + }, + "unresolved": { + "type": "array", + "items": { + "type": "object", + "properties": { + "kind": {"type": "string", "minLength": 1}, + "reason": {"type": "string", "minLength": 1} + }, + "required": ["kind", "reason"], + "additionalProperties": false + } + }, + "preference": { + "type": "object", + "properties": { + "policy": {"type": "string", "minLength": 1}, + "score": {"type": "integer"} + }, + "required": ["policy", "score"], + "additionalProperties": false + } + }, + "required": ["plan_id", "supplier_id", "allocations", "coverage"], + "additionalProperties": false + }, + "limitations": { + "type": "object", + "properties": { + "scope": {"type": "string", "enum": ["supplied_only"]}, + "truncated": {"type": "boolean"}, + "supported_mode": {"type": "string", "minLength": 1}, + "unsupported": { + "type": "array", + "items": {"type": "string", "minLength": 1} + } + }, + "required": ["scope", "truncated", "supported_mode", "unsupported"], + "additionalProperties": false + }, + "execution": { + "type": "object", + "properties": { + "status": {"type": "string", "enum": ["complete", "degraded", "failed"]}, + "provider_calls": {"type": "integer", "minimum": 0}, + "model": {"type": ["string", "null"]}, + "question_bundle": {"type": ["string", "null"]} + }, + "required": ["status", "provider_calls", "model", "question_bundle"], + "additionalProperties": false + }, + "match_output": { + "type": "object", + "properties": { + "assessments": { + "type": "array", + "items": {"$ref": "#/$defs/assessment"} + }, + "plans": { + "type": "array", + "items": {"$ref": "#/$defs/plan"} + }, + "limitations": {"$ref": "#/$defs/limitations"}, + "execution": {"$ref": "#/$defs/execution"} + }, + "required": ["assessments", "plans", "limitations", "execution"], + "additionalProperties": false + } + } +} diff --git a/schemas/hyf_ops_v2/domain_manifest.json b/schemas/hyf_ops_v2/domain_manifest.json @@ -0,0 +1,29 @@ +{ + "schema_version": 1, + "program": "hyf_http_v1", + "revision": "hyf_ops_v2", + "note": "Schema-to-domain mapping for the corrected three operations. Every v2 business object maps to an existing approved domain type or an explicitly named future owner; no new business capability is introduced by C004.", + "mappings": [ + {"schema_path": "context", "domain": "hyf_core.operation_context.OperationContext", "owner": "C004", "status": "parsed_strictly"}, + {"schema_path": "context.versions", "domain": "hyf_core.operation_context.OperationVersions", "owner": "C004", "status": "closed_seven_axes"}, + {"schema_path": "input.source", "domain": "hyf_application.context.InterpretationSource", "owner": "C008/C009", "status": "schema_bound"}, + {"schema_path": "input.references.taxonomy", "domain": "hyf_core.normalization.candidates.Candidate discovery terms", "owner": "C008/C009/C023", "status": "schema_bound"}, + {"schema_path": "input.references.normalization.units", "domain": "hyf_core.domain.units.unit_dimension", "owner": "C008/C009/C023", "status": "schema_bound"}, + {"schema_path": "input.references.normalization.conversions", "domain": "hyf_core.domain.units.ConversionRule / conversion_rule", "owner": "C008/C009/C023", "status": "schema_bound"}, + {"schema_path": "input.references.normalization.packs", "domain": "hyf_core.domain.pack.PackRule / pack_rule", "owner": "C008/C009/C023", "status": "schema_bound"}, + {"schema_path": "input.prior_records", "domain": "hyf_core.domain.source.Revision (immutable id/revision)", "owner": "C008/C009", "status": "schema_bound"}, + {"schema_path": "input.clarification", "domain": "hyf_core.domain.clarification.ClarificationEvidence", "owner": "C008/C009/C023", "status": "schema_bound"}, + {"schema_path": "input.need", "domain": "hyf_core.domain.demand.DemandLine", "owner": "C008/C009/C023", "status": "schema_bound"}, + {"schema_path": "input.need.actor_id", "domain": "hyf_core.domain.source.ActorId", "owner": "C023", "status": "schema_bound"}, + {"schema_path": "input.snapshots", "domain": "hyf_core.domain.snapshot.SupplySnapshot", "owner": "C008/C009/C023", "status": "schema_bound"}, + {"schema_path": "input.coverage", "domain": "hyf_core.domain.coverage.Coverage", "owner": "C008/C009/C023", "status": "schema_bound"}, + {"schema_path": "*.quantity.value", "domain": "hyf_core.domain.quantity.Quantity value/scale (D23 decimal-string grammar)", "owner": "C004/C009", "status": "schema_bound"}, + {"schema_path": "*.evidence", "domain": "hyf_core.domain.evidence.EvidenceRef (UTF-8 byte span, source_id + revision)", "owner": "C008/C009/C023", "status": "schema_bound"}, + {"schema_path": "output.claims/proposed_changes", "domain": "hyf_application.farm_review_output", "owner": "C008/C009/C030", "status": "schema_bound"}, + {"schema_path": "output.demand_lines", "domain": "hyf_application.buyer_needs", "owner": "C008/C009/C030", "status": "schema_bound"}, + {"schema_path": "output.assessments/plans/limitations", "domain": "hyf_application.match_checks / match_plan / match_index", "owner": "C008/C009/C038", "status": "schema_bound"}, + {"schema_path": "output.execution", "domain": "hyf_core.domain.execution.execution_state", "owner": "C008/C009", "status": "schema_bound"} + ], + "authority_integration": "docs/spec/hyf_v1_jev/specs/AUTHORITY_INTEGRATION.md: HYF is read-only; supplied records are host-authorized preconditions, HYF validates consistency but performs no writes and claims no authentication.", + "unavailability": "C004 parses the corrected context and then refuses dispatch with capability_unavailable until C042-C046 activate the operations." +} diff --git a/schemas/hyf_ops_v2/examples/corpus.json b/schemas/hyf_ops_v2/examples/corpus.json @@ -0,0 +1,44 @@ +{ + "schema_version": 1, + "program": "hyf_http_v1", + "revision": "hyf_ops_v2", + "note": "Reference-validation corpus for C004. schema_valid records the JSON Schema outcome; semantic names a labelled obligation that JSON Schema cannot express and that is exercised separately (semantic-cases.json). Targets: '<operation>.<request|response>' uses that operation schema; 'def:<name>' validates against that $defs entry of the farm request schema.", + "entries": [ + {"file": "examples/valid/farm_update_interpret.request.json", "target": "farm_update.interpret.request", "schema_valid": true}, + {"file": "examples/valid/farm_update_interpret.response.json", "target": "farm_update.interpret.response", "schema_valid": true}, + {"file": "examples/valid/buyer_request_interpret.request.json", "target": "buyer_request.interpret.request", "schema_valid": true}, + {"file": "examples/valid/buyer_request_interpret.response.json", "target": "buyer_request.interpret.response", "schema_valid": true}, + {"file": "examples/valid/buyer_request_match.request.json", "target": "buyer_request.match.request", "schema_valid": true}, + {"file": "examples/valid/buyer_request_match.response.json", "target": "buyer_request.match.response", "schema_valid": true}, + {"file": "examples/valid/quantity.integer_string.json", "target": "def:reported_quantity", "schema_valid": true}, + {"file": "examples/valid/quantity.known_zero.json", "target": "def:reported_quantity", "schema_valid": true}, + {"file": "examples/valid/quantity.negative_signed.json", "target": "def:reported_quantity", "schema_valid": true}, + {"file": "examples/valid/quantity.nine_fractional_digits.json", "target": "def:reported_quantity", "schema_valid": true}, + {"file": "examples/valid/quantity.unknown.json", "target": "def:reported_quantity", "schema_valid": true}, + {"file": "examples/valid/taxonomy.unicode.json", "target": "def:taxonomy_bundle", "schema_valid": true}, + {"file": "examples/valid/normalization.full.json", "target": "def:normalization_bundle", "schema_valid": true}, + {"file": "examples/invalid/quantity.ten_fractional_digits.json", "target": "def:reported_quantity", "schema_valid": false}, + {"file": "examples/invalid/quantity.leading_zero.json", "target": "def:reported_quantity", "schema_valid": false}, + {"file": "examples/invalid/quantity.exponent.json", "target": "def:reported_quantity", "schema_valid": false}, + {"file": "examples/invalid/quantity.leading_plus.json", "target": "def:reported_quantity", "schema_valid": false}, + {"file": "examples/invalid/quantity.unknown_with_value.json", "target": "def:reported_quantity", "schema_valid": false}, + {"file": "examples/invalid/quantity.known_without_value.json", "target": "def:reported_quantity", "schema_valid": false}, + {"file": "examples/invalid/quantity.number_not_string.json", "target": "def:reported_quantity", "schema_valid": false}, + {"file": "examples/invalid/quantity.bad_qualifier.json", "target": "def:reported_quantity", "schema_valid": false}, + {"file": "examples/invalid/quantity.unknown_field.json", "target": "def:reported_quantity", "schema_valid": false}, + {"file": "examples/invalid/quantity.negative_zero.json", "target": "def:reported_quantity", "schema_valid": true, "semantic": "negative_zero"}, + {"file": "examples/invalid/quantity.negative_zero_scaled.json", "target": "def:reported_quantity", "schema_valid": true, "semantic": "negative_zero"}, + {"file": "examples/invalid/taxonomy.empty_terms.json", "target": "def:taxonomy_bundle", "schema_valid": false}, + {"file": "examples/invalid/normalization.bad_denominator.json", "target": "def:normalization_bundle", "schema_valid": false}, + {"file": "examples/invalid/normalization.pack_zero.json", "target": "def:normalization_bundle", "schema_valid": false}, + {"file": "examples/invalid/farm_update_interpret.request.unknown_field.json", "target": "farm_update.interpret.request", "schema_valid": false}, + {"file": "examples/invalid/farm_update_interpret.request.missing_actor.json", "target": "farm_update.interpret.request", "schema_valid": false}, + {"file": "examples/invalid/farm_update_interpret.request.present_null_timezone.json", "target": "farm_update.interpret.request", "schema_valid": false}, + {"file": "examples/invalid/farm_update_interpret.response.unknown_field.json", "target": "farm_update.interpret.response", "schema_valid": false}, + {"file": "examples/invalid/farm_update_interpret.response.negative_zero_quantity.json", "target": "farm_update.interpret.response", "schema_valid": true, "semantic": "negative_zero"}, + {"file": "examples/invalid/buyer_request_interpret.request.farm_id_forbidden.json", "target": "buyer_request.interpret.request", "schema_valid": false}, + {"file": "examples/invalid/buyer_request_match.request.missing_references.json", "target": "buyer_request.match.request", "schema_valid": false}, + {"file": "examples/invalid/buyer_request_match.request.need_actor_missing.json", "target": "buyer_request.match.request", "schema_valid": false}, + {"file": "examples/invalid/buyer_request_match.request.unknown_selector.json", "target": "buyer_request.match.request", "schema_valid": false} + ] +} diff --git a/schemas/hyf_ops_v2/examples/invalid/buyer_request_interpret.request.farm_id_forbidden.json b/schemas/hyf_ops_v2/examples/invalid/buyer_request_interpret.request.farm_id_forbidden.json @@ -0,0 +1,32 @@ +{ + "version": 1, + "request_id": "buyer-interpret-bad-farm", + "capability": "buyer_request.interpret", + "context": { + "evaluation_time": "2026-09-24T09:00:00-07:00", + "versions": { + "schema": "hyf_ops_v2", + "taxonomy": "hyf_ops_v2.taxonomy.v1", + "normalization": "hyf_ops_v2.normalization.v1", + "review_policy": "hyf_ops_v2.review_policy.v1", + "ranking_policy": "hyf_ops_v2.ranking_policy.v1", + "question_bundle": "hyf_ops_v2.question_bundle.v1", + "model": "jev-1.13.0" + }, + "actor_id": "buyer-7", + "farm_id": "farm-1" + }, + "input": { + "source": { + "source_id": "src-buyer-1", + "revision": "rev-3", + "text": "25 lb of Roma tomatoes", + "source_time": "2026-09-24T08:45:00-07:00", + "actor_id": "buyer-7" + }, + "references": { + "taxonomy": {"version": "hyf_ops_v2.taxonomy.v1", "provenance": "host_supplied", "products": []}, + "normalization": {"version": "hyf_ops_v2.normalization.v1", "provenance": "host_supplied", "units": [], "conversions": [], "packs": []} + } + } +} diff --git a/schemas/hyf_ops_v2/examples/invalid/buyer_request_match.request.missing_references.json b/schemas/hyf_ops_v2/examples/invalid/buyer_request_match.request.missing_references.json @@ -0,0 +1,29 @@ +{ + "version": 1, + "request_id": "match-bad-missing-refs", + "capability": "buyer_request.match", + "context": { + "evaluation_time": "2026-09-24T09:05:00-07:00", + "versions": { + "schema": "hyf_ops_v2", + "taxonomy": "hyf_ops_v2.taxonomy.v1", + "normalization": "hyf_ops_v2.normalization.v1", + "review_policy": "hyf_ops_v2.review_policy.v1", + "ranking_policy": "hyf_ops_v2.ranking_policy.v1", + "question_bundle": "hyf_ops_v2.question_bundle.v1", + "model": "jev-1.13.0" + }, + "actor_id": "buyer-7" + }, + "input": { + "need": { + "need_id": "need-1", + "revision": "rev-4", + "actor_id": "buyer-7", + "demand_lines": [], + "partial_fulfillment": "unstated" + }, + "snapshots": [], + "coverage": {"scope": "supplied_only", "truncated": false} + } +} diff --git a/schemas/hyf_ops_v2/examples/invalid/buyer_request_match.request.need_actor_missing.json b/schemas/hyf_ops_v2/examples/invalid/buyer_request_match.request.need_actor_missing.json @@ -0,0 +1,32 @@ +{ + "version": 1, + "request_id": "match-bad-need-actor", + "capability": "buyer_request.match", + "context": { + "evaluation_time": "2026-09-24T09:05:00-07:00", + "versions": { + "schema": "hyf_ops_v2", + "taxonomy": "hyf_ops_v2.taxonomy.v1", + "normalization": "hyf_ops_v2.normalization.v1", + "review_policy": "hyf_ops_v2.review_policy.v1", + "ranking_policy": "hyf_ops_v2.ranking_policy.v1", + "question_bundle": "hyf_ops_v2.question_bundle.v1", + "model": "jev-1.13.0" + }, + "actor_id": "buyer-7" + }, + "input": { + "need": { + "need_id": "need-1", + "revision": "rev-4", + "demand_lines": [], + "partial_fulfillment": "unstated" + }, + "snapshots": [], + "coverage": {"scope": "supplied_only", "truncated": false}, + "references": { + "taxonomy": {"version": "hyf_ops_v2.taxonomy.v1", "provenance": "host_supplied", "products": []}, + "normalization": {"version": "hyf_ops_v2.normalization.v1", "provenance": "host_supplied", "units": [], "conversions": [], "packs": []} + } + } +} diff --git a/schemas/hyf_ops_v2/examples/invalid/buyer_request_match.request.unknown_selector.json b/schemas/hyf_ops_v2/examples/invalid/buyer_request_match.request.unknown_selector.json @@ -0,0 +1,33 @@ +{ + "version": 1, + "request_id": "match-bad-selector", + "capability": "buyer_request.match", + "context": { + "evaluation_time": "2026-09-24T09:05:00-07:00", + "versions": { + "schema": "hyf_ops_v3", + "taxonomy": "hyf_ops_v2.taxonomy.v1", + "normalization": "hyf_ops_v2.normalization.v1", + "review_policy": "hyf_ops_v2.review_policy.v1", + "ranking_policy": "hyf_ops_v2.ranking_policy.v1", + "question_bundle": "hyf_ops_v2.question_bundle.v1", + "model": "jev-1.13.0" + }, + "actor_id": "buyer-7" + }, + "input": { + "need": { + "need_id": "need-1", + "revision": "rev-4", + "actor_id": "buyer-7", + "demand_lines": [], + "partial_fulfillment": "unstated" + }, + "snapshots": [], + "coverage": {"scope": "supplied_only", "truncated": false}, + "references": { + "taxonomy": {"version": "hyf_ops_v2.taxonomy.v1", "provenance": "host_supplied", "products": []}, + "normalization": {"version": "hyf_ops_v2.normalization.v1", "provenance": "host_supplied", "units": [], "conversions": [], "packs": []} + } + } +} diff --git a/schemas/hyf_ops_v2/examples/invalid/farm_update_interpret.request.missing_actor.json b/schemas/hyf_ops_v2/examples/invalid/farm_update_interpret.request.missing_actor.json @@ -0,0 +1,32 @@ +{ + "version": 1, + "request_id": "farm-interpret-bad-actor", + "capability": "farm_update.interpret", + "context": { + "evaluation_time": "2026-09-24T09:00:00-07:00", + "versions": { + "schema": "hyf_ops_v2", + "taxonomy": "hyf_ops_v2.taxonomy.v1", + "normalization": "hyf_ops_v2.normalization.v1", + "review_policy": "hyf_ops_v2.review_policy.v1", + "ranking_policy": "hyf_ops_v2.ranking_policy.v1", + "question_bundle": "hyf_ops_v2.question_bundle.v1", + "model": "jev-1.13.0" + }, + "farm_id": "farm-1" + }, + "input": { + "source": { + "source_id": "src-farm-1", + "revision": "rev-7", + "text": "80 lb of Roma tomatoes", + "source_time": "2026-09-24T08:30:00-07:00", + "actor_id": "farm-1", + "farm_id": "farm-1" + }, + "references": { + "taxonomy": {"version": "hyf_ops_v2.taxonomy.v1", "provenance": "host_supplied", "products": []}, + "normalization": {"version": "hyf_ops_v2.normalization.v1", "provenance": "host_supplied", "units": [], "conversions": [], "packs": []} + } + } +} diff --git a/schemas/hyf_ops_v2/examples/invalid/farm_update_interpret.request.present_null_timezone.json b/schemas/hyf_ops_v2/examples/invalid/farm_update_interpret.request.present_null_timezone.json @@ -0,0 +1,34 @@ +{ + "version": 1, + "request_id": "farm-interpret-bad-null-zone", + "capability": "farm_update.interpret", + "context": { + "evaluation_time": "2026-09-24T09:00:00-07:00", + "timezone": null, + "versions": { + "schema": "hyf_ops_v2", + "taxonomy": "hyf_ops_v2.taxonomy.v1", + "normalization": "hyf_ops_v2.normalization.v1", + "review_policy": "hyf_ops_v2.review_policy.v1", + "ranking_policy": "hyf_ops_v2.ranking_policy.v1", + "question_bundle": "hyf_ops_v2.question_bundle.v1", + "model": "jev-1.13.0" + }, + "actor_id": "farm-1", + "farm_id": "farm-1" + }, + "input": { + "source": { + "source_id": "src-farm-1", + "revision": "rev-7", + "text": "80 lb of Roma tomatoes", + "source_time": "2026-09-24T08:30:00-07:00", + "actor_id": "farm-1", + "farm_id": "farm-1" + }, + "references": { + "taxonomy": {"version": "hyf_ops_v2.taxonomy.v1", "provenance": "host_supplied", "products": []}, + "normalization": {"version": "hyf_ops_v2.normalization.v1", "provenance": "host_supplied", "units": [], "conversions": [], "packs": []} + } + } +} diff --git a/schemas/hyf_ops_v2/examples/invalid/farm_update_interpret.request.unknown_field.json b/schemas/hyf_ops_v2/examples/invalid/farm_update_interpret.request.unknown_field.json @@ -0,0 +1,34 @@ +{ + "version": 1, + "request_id": "farm-interpret-bad-unknown", + "capability": "farm_update.interpret", + "context": { + "evaluation_time": "2026-09-24T09:00:00-07:00", + "versions": { + "schema": "hyf_ops_v2", + "taxonomy": "hyf_ops_v2.taxonomy.v1", + "normalization": "hyf_ops_v2.normalization.v1", + "review_policy": "hyf_ops_v2.review_policy.v1", + "ranking_policy": "hyf_ops_v2.ranking_policy.v1", + "question_bundle": "hyf_ops_v2.question_bundle.v1", + "model": "jev-1.13.0" + }, + "actor_id": "farm-1", + "farm_id": "farm-1" + }, + "input": { + "source": { + "source_id": "src-farm-1", + "revision": "rev-7", + "text": "80 lb of Roma tomatoes", + "source_time": "2026-09-24T08:30:00-07:00", + "actor_id": "farm-1", + "farm_id": "farm-1" + }, + "references": { + "taxonomy": {"version": "hyf_ops_v2.taxonomy.v1", "provenance": "host_supplied", "products": []}, + "normalization": {"version": "hyf_ops_v2.normalization.v1", "provenance": "host_supplied", "units": [], "conversions": [], "packs": []} + } + }, + "extra": true +} diff --git a/schemas/hyf_ops_v2/examples/invalid/farm_update_interpret.response.negative_zero_quantity.json b/schemas/hyf_ops_v2/examples/invalid/farm_update_interpret.response.negative_zero_quantity.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "request_id": "farm-interpret-req-1", + "ok": true, + "output": { + "claims": [ + { + "claim_id": "claim-1", + "product": {"phrase": "Roma tomatoes", "catalogue_id": "tomato.roma", "resolution": "resolved"}, + "status": "offered", + "quantity": {"state": "known", "value": "-0", "unit": "lb", "qualifier": "exact"}, + "evidence": [], + "review_required": false + } + ], + "proposed_changes": [], + "review": {"required": false, "clarifications": []}, + "execution": {"status": "complete", "provider_calls": 0, "model": null, "question_bundle": null} + } +} diff --git a/schemas/hyf_ops_v2/examples/invalid/farm_update_interpret.response.unknown_field.json b/schemas/hyf_ops_v2/examples/invalid/farm_update_interpret.response.unknown_field.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "request_id": "farm-interpret-req-1", + "ok": true, + "extra": true, + "output": { + "claims": [], + "proposed_changes": [], + "review": {"required": false, "clarifications": []}, + "execution": {"status": "complete", "provider_calls": 0, "model": null, "question_bundle": null} + } +} diff --git a/schemas/hyf_ops_v2/examples/invalid/normalization.bad_denominator.json b/schemas/hyf_ops_v2/examples/invalid/normalization.bad_denominator.json @@ -0,0 +1,12 @@ +{ + "version": "hyf_ops_v2.normalization.v1", + "provenance": "host_supplied", + "units": [ + {"unit": "lb", "dimension": "mass"}, + {"unit": "kg", "dimension": "mass"} + ], + "conversions": [ + {"from_unit": "lb", "to_unit": "kg", "numerator": "45359237", "denominator": "12"} + ], + "packs": [] +} diff --git a/schemas/hyf_ops_v2/examples/invalid/normalization.pack_zero.json b/schemas/hyf_ops_v2/examples/invalid/normalization.pack_zero.json @@ -0,0 +1,11 @@ +{ + "version": "hyf_ops_v2.normalization.v1", + "provenance": "host_supplied", + "units": [ + {"unit": "crate", "dimension": "count"} + ], + "conversions": [], + "packs": [ + {"product_id": "egg.chicken", "pack_unit": "crate", "inner_unit": "crate", "value": "0"} + ] +} diff --git a/schemas/hyf_ops_v2/examples/invalid/quantity.bad_qualifier.json b/schemas/hyf_ops_v2/examples/invalid/quantity.bad_qualifier.json @@ -0,0 +1 @@ +{"state": "known", "value": "1", "unit": "kg", "qualifier": "roughly"} diff --git a/schemas/hyf_ops_v2/examples/invalid/quantity.exponent.json b/schemas/hyf_ops_v2/examples/invalid/quantity.exponent.json @@ -0,0 +1 @@ +{"state": "known", "value": "8e2", "unit": "kg", "qualifier": "exact"} diff --git a/schemas/hyf_ops_v2/examples/invalid/quantity.known_without_value.json b/schemas/hyf_ops_v2/examples/invalid/quantity.known_without_value.json @@ -0,0 +1 @@ +{"state": "known", "value": null, "unit": null, "qualifier": "exact"} diff --git a/schemas/hyf_ops_v2/examples/invalid/quantity.leading_plus.json b/schemas/hyf_ops_v2/examples/invalid/quantity.leading_plus.json @@ -0,0 +1 @@ +{"state": "known", "value": "+8", "unit": "kg", "qualifier": "exact"} diff --git a/schemas/hyf_ops_v2/examples/invalid/quantity.leading_zero.json b/schemas/hyf_ops_v2/examples/invalid/quantity.leading_zero.json @@ -0,0 +1 @@ +{"state": "known", "value": "080", "unit": "kg", "qualifier": "exact"} diff --git a/schemas/hyf_ops_v2/examples/invalid/quantity.negative_zero.json b/schemas/hyf_ops_v2/examples/invalid/quantity.negative_zero.json @@ -0,0 +1 @@ +{"state": "known", "value": "-0", "unit": "kg", "qualifier": "exact"} diff --git a/schemas/hyf_ops_v2/examples/invalid/quantity.negative_zero_scaled.json b/schemas/hyf_ops_v2/examples/invalid/quantity.negative_zero_scaled.json @@ -0,0 +1 @@ +{"state": "known", "value": "-0.00", "unit": "kg", "qualifier": "exact"} diff --git a/schemas/hyf_ops_v2/examples/invalid/quantity.number_not_string.json b/schemas/hyf_ops_v2/examples/invalid/quantity.number_not_string.json @@ -0,0 +1 @@ +{"state": "known", "value": 80, "unit": "kg", "qualifier": "exact"} diff --git a/schemas/hyf_ops_v2/examples/invalid/quantity.ten_fractional_digits.json b/schemas/hyf_ops_v2/examples/invalid/quantity.ten_fractional_digits.json @@ -0,0 +1 @@ +{"state": "known", "value": "1.1234567890", "unit": "kg", "qualifier": "exact"} diff --git a/schemas/hyf_ops_v2/examples/invalid/quantity.unknown_field.json b/schemas/hyf_ops_v2/examples/invalid/quantity.unknown_field.json @@ -0,0 +1 @@ +{"state": "known", "value": "1", "unit": "kg", "qualifier": "exact", "precision": 2} diff --git a/schemas/hyf_ops_v2/examples/invalid/quantity.unknown_with_value.json b/schemas/hyf_ops_v2/examples/invalid/quantity.unknown_with_value.json @@ -0,0 +1 @@ +{"state": "unknown", "value": "5", "unit": "kg", "qualifier": "exact"} diff --git a/schemas/hyf_ops_v2/examples/invalid/taxonomy.empty_terms.json b/schemas/hyf_ops_v2/examples/invalid/taxonomy.empty_terms.json @@ -0,0 +1,7 @@ +{ + "version": "hyf_ops_v2.taxonomy.v1", + "provenance": "host_supplied", + "products": [ + {"catalogue_id": "tomato.roma", "terms": []} + ] +} diff --git a/schemas/hyf_ops_v2/examples/valid/buyer_request_interpret.request.json b/schemas/hyf_ops_v2/examples/valid/buyer_request_interpret.request.json @@ -0,0 +1,63 @@ +{ + "version": 1, + "request_id": "buyer-interpret-req-1", + "capability": "buyer_request.interpret", + "context": { + "consumer": "radroots-cli", + "execution_mode_preference": "deterministic", + "deadline_ms": 2500, + "evaluation_time": "2026-09-24T09:00:00-07:00", + "timezone": "America/Vancouver", + "locale": "en-CA", + "versions": { + "schema": "hyf_ops_v2", + "taxonomy": "hyf_ops_v2.taxonomy.v1", + "normalization": "hyf_ops_v2.normalization.v1", + "review_policy": "hyf_ops_v2.review_policy.v1", + "ranking_policy": "hyf_ops_v2.ranking_policy.v1", + "question_bundle": "hyf_ops_v2.question_bundle.v1", + "model": "jev-1.13.0" + }, + "return_provenance": false, + "actor_id": "buyer-7" + }, + "input": { + "source": { + "source_id": "src-buyer-1", + "revision": "rev-3", + "text": "Looking for 25 lb of Roma tomatoes, pickup near Vancouver this weekend.", + "source_time": "2026-09-24T08:45:00-07:00", + "timezone": "America/Vancouver", + "locale": "en-CA", + "actor_id": "buyer-7", + "ingestion_time": "2026-09-24T08:46:00-07:00" + }, + "references": { + "taxonomy": { + "version": "hyf_ops_v2.taxonomy.v1", + "provenance": "host_supplied", + "products": [ + {"catalogue_id": "tomato.roma", "terms": ["Roma tomatoes", "roma tomato", "tomates"]} + ] + }, + "normalization": { + "version": "hyf_ops_v2.normalization.v1", + "provenance": "host_supplied", + "units": [ + {"unit": "lb", "dimension": "mass"}, + {"unit": "kg", "dimension": "mass"} + ], + "conversions": [ + {"from_unit": "lb", "to_unit": "kg", "numerator": "45359237", "denominator": "100000000"} + ], + "packs": [] + } + }, + "clarification": { + "source_id": "src-clar-2", + "revision": "rev-1", + "target_field": "conditions.window", + "text": "weekend includes Friday evening" + } + } +} diff --git a/schemas/hyf_ops_v2/examples/valid/buyer_request_interpret.response.json b/schemas/hyf_ops_v2/examples/valid/buyer_request_interpret.response.json @@ -0,0 +1,38 @@ +{ + "version": 1, + "request_id": "buyer-interpret-req-1", + "ok": true, + "output": { + "demand_lines": [ + { + "line_id": "line-1", + "product": {"phrase": "Roma tomatoes", "catalogue_id": "tomato.roma", "resolution": "resolved"}, + "quantity": {"state": "known", "value": "25", "unit": "lb", "qualifier": "exact"}, + "conditions": [ + { + "kind": "fulfillment", + "strength": "mandatory", + "value": "pickup", + "evidence": [ + {"source_id": "src-buyer-1", "revision": "rev-3", "start": 55, "end": 61, "method": "span"} + ] + }, + { + "kind": "window", + "strength": "preferred", + "value": "2026-09-26/2026-09-27", + "evidence": [ + {"source_id": "src-buyer-1", "revision": "rev-3", "start": 62, "end": 71, "method": "span"} + ] + } + ], + "evidence": [ + {"source_id": "src-buyer-1", "revision": "rev-3", "start": 12, "end": 39, "method": "span"} + ], + "review_required": false + } + ], + "review": {"required": false, "clarifications": []}, + "execution": {"status": "complete", "provider_calls": 0, "model": null, "question_bundle": null} + } +} diff --git a/schemas/hyf_ops_v2/examples/valid/buyer_request_match.request.json b/schemas/hyf_ops_v2/examples/valid/buyer_request_match.request.json @@ -0,0 +1,94 @@ +{ + "version": 1, + "request_id": "buyer-match-req-1", + "capability": "buyer_request.match", + "context": { + "consumer": "radroots-cli", + "execution_mode_preference": "deterministic", + "deadline_ms": 2500, + "evaluation_time": "2026-09-24T09:05:00-07:00", + "timezone": "America/Vancouver", + "locale": "en-CA", + "versions": { + "schema": "hyf_ops_v2", + "taxonomy": "hyf_ops_v2.taxonomy.v1", + "normalization": "hyf_ops_v2.normalization.v1", + "review_policy": "hyf_ops_v2.review_policy.v1", + "ranking_policy": "hyf_ops_v2.ranking_policy.v1", + "question_bundle": "hyf_ops_v2.question_bundle.v1", + "model": "jev-1.13.0" + }, + "return_provenance": true, + "actor_id": "buyer-7" + }, + "input": { + "need": { + "need_id": "need-1", + "revision": "rev-4", + "actor_id": "buyer-7", + "demand_lines": [ + { + "line_id": "line-1", + "product": {"phrase": "Roma tomatoes", "catalogue_id": "tomato.roma", "resolution": "resolved"}, + "quantity": {"state": "known", "value": "25", "unit": "lb", "qualifier": "exact"}, + "conditions": [ + { + "kind": "fulfillment", + "strength": "mandatory", + "value": "pickup", + "evidence": [ + {"source_id": "src-buyer-1", "revision": "rev-3", "start": 55, "end": 61, "method": "span"} + ] + } + ], + "evidence": [ + {"source_id": "src-buyer-1", "revision": "rev-3", "start": 12, "end": 39, "method": "span"} + ], + "review_required": false + } + ], + "partial_fulfillment": "unstated" + }, + "snapshots": [ + { + "lot_id": "lot-1", + "revision": "rev-9", + "supplier_id": "farm-1", + "product": {"phrase": "Roma tomatoes", "catalogue_id": "tomato.roma", "resolution": "resolved"}, + "unreserved_quantity": {"state": "known", "value": "120", "unit": "lb", "qualifier": "exact"}, + "attributes": [{"name": "grade-A", "verified": true}], + "fulfillment": {"method": "pickup", "area": "Vancouver", "window": "2026-09-26/2026-09-27"}, + "price": {"state": "known", "amount": "2.50", "currency": "CAD", "basis": "per_lb"} + }, + { + "lot_id": "lot-2", + "revision": "rev-4", + "supplier_id": "farm-2", + "product": {"phrase": "Roma tomatoes", "catalogue_id": null, "resolution": "unresolved"}, + "unreserved_quantity": {"state": "unknown", "value": null, "unit": null, "qualifier": "exact"} + } + ], + "coverage": {"scope": "supplied_only", "truncated": false, "evaluated": 2, "excluded": 0}, + "references": { + "taxonomy": { + "version": "hyf_ops_v2.taxonomy.v1", + "provenance": "host_supplied", + "products": [ + {"catalogue_id": "tomato.roma", "terms": ["Roma tomatoes", "roma tomato"]} + ] + }, + "normalization": { + "version": "hyf_ops_v2.normalization.v1", + "provenance": "host_supplied", + "units": [ + {"unit": "lb", "dimension": "mass"}, + {"unit": "kg", "dimension": "mass"} + ], + "conversions": [ + {"from_unit": "lb", "to_unit": "kg", "numerator": "45359237", "denominator": "100000000"} + ], + "packs": [] + } + } + } +} diff --git a/schemas/hyf_ops_v2/examples/valid/buyer_request_match.response.json b/schemas/hyf_ops_v2/examples/valid/buyer_request_match.response.json @@ -0,0 +1,49 @@ +{ + "version": 1, + "request_id": "buyer-match-req-1", + "ok": true, + "output": { + "assessments": [ + { + "candidate_id": "lot-1", + "eligibility": "eligible", + "checks": [ + {"kind": "product", "result": "pass", "reason": "product_match", "evidence": []}, + {"kind": "availability", "result": "pass", "reason": "availability_known", "evidence": []}, + {"kind": "quantity", "result": "pass", "reason": "quantity_sufficient", "evidence": []} + ] + }, + { + "candidate_id": "lot-2", + "eligibility": "conditional", + "checks": [ + {"kind": "product", "result": "unknown", "reason": "product_unresolved", "evidence": []}, + {"kind": "availability", "result": "unknown", "reason": "stock_unknown", "evidence": []} + ] + } + ], + "plans": [ + { + "plan_id": "plan-1", + "supplier_id": "farm-1", + "allocations": [ + { + "lot_id": "lot-1", + "revision": "rev-9", + "line_id": "line-1", + "quantity": {"state": "known", "value": "25", "unit": "lb", "qualifier": "exact"} + } + ], + "coverage": {"lines_covered": ["line-1"], "uncovered": [], "partial": false}, + "unresolved": [] + } + ], + "limitations": { + "scope": "supplied_only", + "truncated": false, + "supported_mode": "single_supplier_compatible_lots", + "unsupported": ["multi_supplier"] + }, + "execution": {"status": "complete", "provider_calls": 0, "model": null, "question_bundle": null} + } +} diff --git a/schemas/hyf_ops_v2/examples/valid/farm_update_interpret.request.json b/schemas/hyf_ops_v2/examples/valid/farm_update_interpret.request.json @@ -0,0 +1,74 @@ +{ + "version": 1, + "request_id": "farm-interpret-req-1", + "trace_id": "farm-interpret-trace-1", + "capability": "farm_update.interpret", + "context": { + "consumer": "radroots-cli", + "execution_mode_preference": "deterministic", + "deadline_ms": 2500, + "evaluation_time": "2026-09-24T09:00:00-07:00", + "timezone": "America/Vancouver", + "locale": "en-CA", + "versions": { + "schema": "hyf_ops_v2", + "taxonomy": "hyf_ops_v2.taxonomy.v1", + "normalization": "hyf_ops_v2.normalization.v1", + "review_policy": "hyf_ops_v2.review_policy.v1", + "ranking_policy": "hyf_ops_v2.ranking_policy.v1", + "question_bundle": "hyf_ops_v2.question_bundle.v1", + "model": "jev-1.13.0" + }, + "return_provenance": true, + "actor_id": "farm-1", + "farm_id": "farm-1" + }, + "input": { + "source": { + "source_id": "src-farm-1", + "revision": "rev-7", + "text": "Got about 80 lb of Roma tomatoes and two crates of eggs today.", + "source_time": "2026-09-24T08:30:00-07:00", + "timezone": "America/Vancouver", + "locale": "en-CA", + "actor_id": "farm-1", + "farm_id": "farm-1", + "ingestion_time": "2026-09-24T08:31:00-07:00" + }, + "references": { + "taxonomy": { + "version": "hyf_ops_v2.taxonomy.v1", + "provenance": "host_supplied", + "products": [ + {"catalogue_id": "tomato.roma", "terms": ["Roma tomatoes", "roma tomato"]}, + {"catalogue_id": "egg.chicken", "terms": ["eggs"]} + ] + }, + "normalization": { + "version": "hyf_ops_v2.normalization.v1", + "provenance": "host_supplied", + "units": [ + {"unit": "lb", "dimension": "mass"}, + {"unit": "kg", "dimension": "mass"}, + {"unit": "crate", "dimension": "count"}, + {"unit": "egg", "dimension": "count"} + ], + "conversions": [ + {"from_unit": "lb", "to_unit": "kg", "numerator": "45359237", "denominator": "100000000"} + ], + "packs": [ + {"product_id": "egg.chicken", "pack_unit": "crate", "inner_unit": "egg", "value": "12"} + ] + } + }, + "prior_records": [ + {"record_id": "record-100", "revision": "rev-2", "role": "authorized_listing"} + ], + "clarification": { + "source_id": "src-clar-1", + "revision": "rev-1", + "target_field": "quantity", + "text": "about 80 lb means at least 75 and at most 85 lb" + } + } +} diff --git a/schemas/hyf_ops_v2/examples/valid/farm_update_interpret.response.json b/schemas/hyf_ops_v2/examples/valid/farm_update_interpret.response.json @@ -0,0 +1,40 @@ +{ + "version": 1, + "request_id": "farm-interpret-req-1", + "trace_id": "farm-interpret-trace-1", + "ok": true, + "output": { + "claims": [ + { + "claim_id": "claim-1", + "product": {"phrase": "Roma tomatoes", "catalogue_id": "tomato.roma", "resolution": "resolved"}, + "status": "offered", + "quantity": {"state": "known", "value": "80.00", "unit": "lb", "qualifier": "approximate"}, + "evidence": [ + {"source_id": "src-farm-1", "revision": "rev-7", "start": 11, "end": 21, "method": "span"} + ], + "review_required": true + } + ], + "proposed_changes": [ + { + "target": {"kind": "listing", "id": "listing-1"}, + "operation": "remaining", + "expected_revision": "rev-2", + "evidence": [ + {"source_id": "src-farm-1", "revision": "rev-7", "start": 11, "end": 21, "method": "span"} + ] + } + ], + "review": { + "required": true, + "clarifications": [{"field": "quantity", "reason": "approximation_requested"}] + }, + "execution": { + "status": "complete", + "provider_calls": 0, + "model": null, + "question_bundle": null + } + } +} diff --git a/schemas/hyf_ops_v2/examples/valid/normalization.full.json b/schemas/hyf_ops_v2/examples/valid/normalization.full.json @@ -0,0 +1,18 @@ +{ + "version": "hyf_ops_v2.normalization.v1", + "provenance": "host_supplied", + "units": [ + {"unit": "lb", "dimension": "mass"}, + {"unit": "kg", "dimension": "mass"}, + {"unit": "l", "dimension": "volume"}, + {"unit": "crate", "dimension": "count"}, + {"unit": "mystery", "dimension": "unknown"} + ], + "conversions": [ + {"from_unit": "lb", "to_unit": "kg", "numerator": "45359237", "denominator": "100000000"} + ], + "packs": [ + {"product_id": "egg.chicken", "pack_unit": "crate", "inner_unit": "egg", "value": "12"}, + {"product_id": "egg.chicken", "pack_unit": "crate", "inner_unit": "egg", "value": "12.5"} + ] +} diff --git a/schemas/hyf_ops_v2/examples/valid/quantity.integer_string.json b/schemas/hyf_ops_v2/examples/valid/quantity.integer_string.json @@ -0,0 +1 @@ +{"state": "known", "value": "8000", "unit": "kg", "qualifier": "exact"} diff --git a/schemas/hyf_ops_v2/examples/valid/quantity.known_zero.json b/schemas/hyf_ops_v2/examples/valid/quantity.known_zero.json @@ -0,0 +1 @@ +{"state": "known", "value": "0", "unit": "kg", "qualifier": "exact"} diff --git a/schemas/hyf_ops_v2/examples/valid/quantity.negative_signed.json b/schemas/hyf_ops_v2/examples/valid/quantity.negative_signed.json @@ -0,0 +1 @@ +{"state": "known", "value": "-5.5", "unit": "kg", "qualifier": "exact"} diff --git a/schemas/hyf_ops_v2/examples/valid/quantity.nine_fractional_digits.json b/schemas/hyf_ops_v2/examples/valid/quantity.nine_fractional_digits.json @@ -0,0 +1 @@ +{"state": "known", "value": "80.123456789", "unit": "lb", "qualifier": "approximate"} diff --git a/schemas/hyf_ops_v2/examples/valid/quantity.unknown.json b/schemas/hyf_ops_v2/examples/valid/quantity.unknown.json @@ -0,0 +1 @@ +{"state": "unknown", "value": null, "unit": null, "qualifier": "exact"} diff --git a/schemas/hyf_ops_v2/examples/valid/taxonomy.unicode.json b/schemas/hyf_ops_v2/examples/valid/taxonomy.unicode.json @@ -0,0 +1,7 @@ +{ + "version": "hyf_ops_v2.taxonomy.v1", + "provenance": "synthetic", + "products": [ + {"catalogue_id": "tomato.roma", "terms": ["Roma tomatoes", "roma tomato", "tomates Roma", "トマト"]} + ] +} diff --git a/schemas/hyf_ops_v2/farm_update_interpret.request.schema.json b/schemas/hyf_ops_v2/farm_update_interpret.request.schema.json @@ -0,0 +1,405 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "hyf_ops_v2/farm_update_interpret.request.schema.json", + "title": "hyf_ops_v2 farm_update.interpret strict request (ADR-0025 D45 CB01-CB04)", + "$comment": "Corrected versioned operation contract. Selected by context.versions.schema=hyf_ops_v2. Strict closed objects; duplicate keys are rejected by the semantic layer, not by JSON Schema. Envelope version stays 1.", + "type": "object", + "properties": { + "version": { + "type": "integer", + "const": 1 + }, + "request_id": { + "type": "string", + "minLength": 1 + }, + "trace_id": { + "type": "string", + "minLength": 1 + }, + "capability": { + "type": "string", + "const": "farm_update.interpret" + }, + "context": { + "$ref": "#/$defs/farm_context" + }, + "input": { + "$ref": "#/$defs/farm_input" + } + }, + "required": ["version", "request_id", "capability", "context", "input"], + "additionalProperties": false, + "$defs": { + "versions": { + "type": "object", + "properties": { + "schema": { + "type": "string", + "const": "hyf_ops_v2" + }, + "taxonomy": { + "type": "string", + "minLength": 1 + }, + "normalization": { + "type": "string", + "minLength": 1 + }, + "review_policy": { + "type": "string", + "minLength": 1 + }, + "ranking_policy": { + "type": "string", + "minLength": 1 + }, + "question_bundle": { + "type": "string", + "minLength": 1 + }, + "model": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "schema", + "taxonomy", + "normalization", + "review_policy", + "ranking_policy", + "question_bundle", + "model" + ], + "additionalProperties": false + }, + "farm_context": { + "type": "object", + "properties": { + "consumer": { + "type": "string", + "minLength": 1 + }, + "execution_mode_preference": { + "type": "string", + "enum": ["deterministic", "assisted"] + }, + "deadline_ms": { + "type": "integer", + "minimum": 1 + }, + "evaluation_time": { + "type": "string", + "minLength": 1 + }, + "timezone": { + "type": "string", + "minLength": 1 + }, + "locale": { + "type": "string", + "minLength": 1 + }, + "versions": { + "$ref": "#/$defs/versions" + }, + "return_provenance": { + "type": "boolean" + }, + "actor_id": { + "type": "string", + "minLength": 1 + }, + "farm_id": { + "type": "string", + "minLength": 1 + } + }, + "required": ["evaluation_time", "versions", "actor_id", "farm_id"], + "additionalProperties": false + }, + "interpretation_source_farm": { + "type": "object", + "properties": { + "source_id": { + "type": "string", + "minLength": 1 + }, + "revision": { + "type": "string", + "minLength": 1 + }, + "text": { + "type": "string", + "minLength": 1 + }, + "source_time": { + "type": "string", + "minLength": 1 + }, + "timezone": { + "type": "string", + "minLength": 1 + }, + "locale": { + "type": "string", + "minLength": 1 + }, + "actor_id": { + "type": "string", + "minLength": 1 + }, + "farm_id": { + "type": "string", + "minLength": 1 + }, + "ingestion_time": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "source_id", + "revision", + "text", + "source_time", + "actor_id", + "farm_id" + ], + "additionalProperties": false + }, + "evidence_span": { + "type": "object", + "properties": { + "source_id": { + "type": "string", + "minLength": 1 + }, + "revision": { + "type": "string", + "minLength": 1 + }, + "start": { + "type": "integer", + "minimum": 0 + }, + "end": { + "type": "integer", + "minimum": 0 + }, + "method": { + "type": "string", + "minLength": 1 + } + }, + "required": ["source_id", "revision", "start", "end", "method"], + "additionalProperties": false + }, + "reported_quantity": { + "type": "object", + "properties": { + "state": { + "type": "string", + "enum": ["known", "unknown"] + }, + "value": { + "type": ["string", "null"], + "pattern": "^-?(0|[1-9][0-9]*)(\\.[0-9]{1,9})?$" + }, + "unit": { + "type": ["string", "null"], + "minLength": 1 + }, + "qualifier": { + "type": "string", + "enum": ["exact", "approximate"] + } + }, + "required": ["state", "qualifier"], + "additionalProperties": false, + "allOf": [ + { + "if": { + "properties": {"state": {"const": "unknown"}}, + "required": ["state"] + }, + "then": { + "properties": {"value": {"type": "null"}, "unit": {"type": "null"}} + } + }, + { + "if": { + "properties": {"state": {"const": "known"}}, + "required": ["state"] + }, + "then": { + "properties": { + "value": { + "type": "string", + "pattern": "^-?(0|[1-9][0-9]*)(\\.[0-9]{1,9})?$" + }, + "unit": {"type": "string", "minLength": 1} + }, + "required": ["value", "unit"] + } + } + ] + }, + "taxonomy_bundle": { + "type": "object", + "properties": { + "version": { + "type": "string", + "minLength": 1 + }, + "provenance": { + "type": "string", + "enum": ["synthetic", "host_supplied"] + }, + "products": { + "type": "array", + "items": { + "type": "object", + "properties": { + "catalogue_id": { + "type": "string", + "minLength": 1 + }, + "terms": { + "type": "array", + "minItems": 1, + "items": {"type": "string", "minLength": 1} + } + }, + "required": ["catalogue_id", "terms"], + "additionalProperties": false + } + } + }, + "required": ["version", "provenance", "products"], + "additionalProperties": false + }, + "normalization_bundle": { + "type": "object", + "properties": { + "version": { + "type": "string", + "minLength": 1 + }, + "provenance": { + "type": "string", + "enum": ["synthetic", "host_supplied"] + }, + "units": { + "type": "array", + "items": { + "type": "object", + "properties": { + "unit": {"type": "string", "minLength": 1}, + "dimension": { + "type": "string", + "enum": ["mass", "volume", "count", "unknown"] + } + }, + "required": ["unit", "dimension"], + "additionalProperties": false + } + }, + "conversions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "from_unit": {"type": "string", "minLength": 1}, + "to_unit": {"type": "string", "minLength": 1}, + "numerator": {"type": "string", "pattern": "^[1-9][0-9]*$"}, + "denominator": {"type": "string", "pattern": "^10*$"} + }, + "required": ["from_unit", "to_unit", "numerator", "denominator"], + "additionalProperties": false + } + }, + "packs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "product_id": {"type": "string", "minLength": 1}, + "pack_unit": {"type": "string", "minLength": 1}, + "inner_unit": {"type": "string", "minLength": 1}, + "value": { + "type": "string", + "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]{1,9})?$", + "allOf": [ + {"not": {"const": "0"}}, + {"not": {"pattern": "^0(\\.0+)?$"}} + ] + } + }, + "required": ["product_id", "pack_unit", "inner_unit", "value"], + "additionalProperties": false + } + } + }, + "required": ["version", "provenance", "units", "conversions", "packs"], + "additionalProperties": false + }, + "references": { + "type": "object", + "properties": { + "taxonomy": { + "$ref": "#/$defs/taxonomy_bundle" + }, + "normalization": { + "$ref": "#/$defs/normalization_bundle" + } + }, + "required": ["taxonomy", "normalization"], + "additionalProperties": false + }, + "prior_records": { + "type": "array", + "items": { + "type": "object", + "properties": { + "record_id": {"type": "string", "minLength": 1}, + "revision": {"type": "string", "minLength": 1}, + "role": {"type": "string", "minLength": 1} + }, + "required": ["record_id", "revision", "role"], + "additionalProperties": false + } + }, + "clarification": { + "type": "object", + "properties": { + "source_id": {"type": "string", "minLength": 1}, + "revision": {"type": "string", "minLength": 1}, + "target_field": {"type": "string", "minLength": 1}, + "text": {"type": "string", "minLength": 1} + }, + "required": ["source_id", "revision", "target_field", "text"], + "additionalProperties": false + }, + "farm_input": { + "type": "object", + "properties": { + "source": { + "$ref": "#/$defs/interpretation_source_farm" + }, + "references": { + "$ref": "#/$defs/references" + }, + "prior_records": { + "$ref": "#/$defs/prior_records" + }, + "clarification": { + "$ref": "#/$defs/clarification" + } + }, + "required": ["source", "references"], + "additionalProperties": false + } + } +} diff --git a/schemas/hyf_ops_v2/farm_update_interpret.response.schema.json b/schemas/hyf_ops_v2/farm_update_interpret.response.schema.json @@ -0,0 +1,208 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "hyf_ops_v2/farm_update_interpret.response.schema.json", + "title": "hyf_ops_v2 farm_update.interpret strict response (ADR-0025 D45 CB02-CB04)", + "$comment": "Proposals only, never inventory mutation. quantity uses the D23 reported decimal-string projection. Envelope version stays 1.", + "type": "object", + "properties": { + "version": { + "type": "integer", + "const": 1 + }, + "request_id": { + "type": "string", + "minLength": 1 + }, + "trace_id": { + "type": "string" + }, + "ok": { + "type": "boolean" + }, + "output": { + "$ref": "#/$defs/farm_output" + }, + "error": { + "$ref": "#/$defs/wire_error" + }, + "meta": { + "type": "object", + "additionalProperties": true + } + }, + "required": ["version", "request_id", "ok"], + "additionalProperties": false, + "$defs": { + "wire_error": { + "type": "object", + "properties": { + "code": {"type": "string", "minLength": 1}, + "message": {"type": "string"} + }, + "required": ["code", "message"], + "additionalProperties": false + }, + "evidence_span": { + "type": "object", + "properties": { + "source_id": {"type": "string", "minLength": 1}, + "revision": {"type": "string", "minLength": 1}, + "start": {"type": "integer", "minimum": 0}, + "end": {"type": "integer", "minimum": 0}, + "method": {"type": "string", "minLength": 1} + }, + "required": ["source_id", "revision", "start", "end", "method"], + "additionalProperties": false + }, + "reported_quantity": { + "type": "object", + "properties": { + "state": {"type": "string", "enum": ["known", "unknown"]}, + "value": { + "type": ["string", "null"], + "pattern": "^-?(0|[1-9][0-9]*)(\\.[0-9]{1,9})?$" + }, + "unit": {"type": ["string", "null"], "minLength": 1}, + "qualifier": {"type": "string", "enum": ["exact", "approximate"]} + }, + "required": ["state", "qualifier"], + "additionalProperties": false, + "allOf": [ + { + "if": { + "properties": {"state": {"const": "unknown"}}, + "required": ["state"] + }, + "then": { + "properties": {"value": {"type": "null"}, "unit": {"type": "null"}} + } + }, + { + "if": { + "properties": {"state": {"const": "known"}}, + "required": ["state"] + }, + "then": { + "properties": { + "value": { + "type": "string", + "pattern": "^-?(0|[1-9][0-9]*)(\\.[0-9]{1,9})?$" + }, + "unit": {"type": "string", "minLength": 1} + }, + "required": ["value", "unit"] + } + } + ] + }, + "product_ref": { + "type": "object", + "properties": { + "phrase": {"type": "string", "minLength": 1}, + "catalogue_id": {"type": ["string", "null"], "minLength": 1}, + "resolution": {"type": "string", "enum": ["resolved", "unresolved"]} + }, + "required": ["phrase", "catalogue_id", "resolution"], + "additionalProperties": false + }, + "claim": { + "type": "object", + "properties": { + "claim_id": {"type": "string", "minLength": 1}, + "product": {"$ref": "#/$defs/product_ref"}, + "status": { + "type": "string", + "enum": ["offered", "forecast", "unavailable", "correction", "unclear"] + }, + "quantity": {"$ref": "#/$defs/reported_quantity"}, + "evidence": { + "type": "array", + "items": {"$ref": "#/$defs/evidence_span"} + }, + "review_required": {"type": "boolean"} + }, + "required": ["claim_id", "product", "status", "evidence", "review_required"], + "additionalProperties": false + }, + "proposed_change": { + "type": "object", + "properties": { + "target": { + "type": "object", + "properties": { + "kind": {"type": "string", "enum": ["listing", "product", "farm"]}, + "id": {"type": ["string", "null"], "minLength": 1} + }, + "required": ["kind", "id"], + "additionalProperties": false + }, + "operation": { + "type": "string", + "enum": [ + "addition", + "remaining", + "replacement", + "withdrawal", + "correction", + "unresolved" + ] + }, + "expected_revision": {"type": ["string", "null"], "minLength": 1}, + "evidence": { + "type": "array", + "items": {"$ref": "#/$defs/evidence_span"} + } + }, + "required": ["target", "operation", "evidence"], + "additionalProperties": false + }, + "review": { + "type": "object", + "properties": { + "required": {"type": "boolean"}, + "clarifications": { + "type": "array", + "items": { + "type": "object", + "properties": { + "field": {"type": "string", "minLength": 1}, + "reason": {"type": "string", "minLength": 1} + }, + "required": ["field", "reason"], + "additionalProperties": false + } + } + }, + "required": ["required", "clarifications"], + "additionalProperties": false + }, + "execution": { + "type": "object", + "properties": { + "status": {"type": "string", "enum": ["complete", "degraded", "failed"]}, + "provider_calls": {"type": "integer", "minimum": 0}, + "model": {"type": ["string", "null"]}, + "question_bundle": {"type": ["string", "null"]} + }, + "required": ["status", "provider_calls", "model", "question_bundle"], + "additionalProperties": false + }, + "farm_output": { + "type": "object", + "properties": { + "claims": { + "type": "array", + "items": {"$ref": "#/$defs/claim"} + }, + "proposed_changes": { + "type": "array", + "items": {"$ref": "#/$defs/proposed_change"} + }, + "review": {"$ref": "#/$defs/review"}, + "execution": {"$ref": "#/$defs/execution"} + }, + "required": ["claims", "proposed_changes", "review", "execution"], + "additionalProperties": false + } + } +} diff --git a/schemas/hyf_ops_v2/manifest.json b/schemas/hyf_ops_v2/manifest.json @@ -0,0 +1,40 @@ +{ + "schema_version": 1, + "program": "hyf_http_v1", + "revision": "hyf_ops_v2", + "selector": { + "field": "context.versions.schema", + "value": "hyf_ops_v2" + }, + "envelope_version": 1, + "activation": { + "state": "pre_activation", + "guard_error_code": "capability_unavailable", + "owner": "C042-C046", + "note": "Before activation a recognized hyf_ops_v2 request is parsed and then refused with capability_unavailable; it never reaches the legacy shortcut handlers even when their enable flag is set. C004 does not advertise v2 readiness." + }, + "operations": { + "farm_update.interpret": { + "request_schema": "farm_update_interpret.request.schema.json", + "response_schema": "farm_update_interpret.response.schema.json" + }, + "buyer_request.interpret": { + "request_schema": "buyer_request_interpret.request.schema.json", + "response_schema": "buyer_request_interpret.response.schema.json" + }, + "buyer_request.match": { + "request_schema": "buyer_request_match.request.schema.json", + "response_schema": "buyer_request_match.response.schema.json" + } + }, + "error_families": { + "invalid_request": "malformed JSON/schema/type/selector/version/reference/scope inconsistency", + "unsupported_capability": "unknown capability", + "capability_disabled": "disabled legacy operation", + "capability_unavailable": "recognized hyf_ops_v2 request before activation", + "internal_error": "unexpected internal failure (sanitized)" + }, + "semantic_cases": "semantic-cases.json", + "version_manifest": "version_manifest.json", + "domain_manifest": "domain_manifest.json" +} diff --git a/schemas/hyf_ops_v2/semantic-cases.json b/schemas/hyf_ops_v2/semantic-cases.json @@ -0,0 +1,30 @@ +{ + "schema_version": 1, + "program": "hyf_http_v1", + "revision": "hyf_ops_v2", + "note": "Semantic obligations that JSON Schema alone cannot express. Each case is labelled with the enforcing owner and the C004 control that exercises it. No case is claimed enforced by a regex or by the reference validator; C008/C009/C023 own the full typed/semantic enforcement.", + "cases": [ + {"id": "duplicate_key_identity", "path": "input.source.revision", "expect": "reject", "wire": "invalid_request", "owner": "C004", "enforced_by": "strict duplicate-key detection in hyf_core.operation_context and Mojo control test"}, + {"id": "escaped_duplicate_key_identity", "path": "context.actor_id vs context.\\u0061ctor_id", "expect": "reject", "wire": "invalid_request", "owner": "C004", "enforced_by": "decoded key identity in duplicate detection"}, + {"id": "taxonomy_version_mismatch", "path": "context.versions.taxonomy != input.references.taxonomy.version", "expect": "reject", "wire": "invalid_request", "owner": "C023", "enforced_by": "C004 labelled semantic script; C023 typed consistency"}, + {"id": "normalization_version_mismatch", "path": "context.versions.normalization != input.references.normalization.version", "expect": "reject", "wire": "invalid_request", "owner": "C023", "enforced_by": "C004 labelled semantic script; C023 typed consistency"}, + {"id": "source_actor_mismatch", "path": "input.source.actor_id != context.actor_id", "expect": "reject", "wire": "invalid_request", "owner": "C023", "enforced_by": "C004 labelled semantic script; C023 typed consistency"}, + {"id": "match_need_actor_mismatch", "path": "input.need.actor_id != context.actor_id", "expect": "reject", "wire": "invalid_request", "owner": "C023", "enforced_by": "C004 labelled semantic script; C023 typed consistency"}, + {"id": "farm_source_farm_mismatch", "path": "input.source.farm_id != context.farm_id", "expect": "reject", "wire": "invalid_request", "owner": "C023", "enforced_by": "C004 labelled semantic script; C023 typed consistency"}, + {"id": "unknown_quantity_with_value", "path": "quantity.state=unknown with non-null value", "expect": "reject", "wire": "invalid_request", "owner": "C004", "enforced_by": "schema if/then; C009 typed mapping"}, + {"id": "known_quantity_without_value", "path": "quantity.state=known without value/unit", "expect": "reject", "wire": "invalid_request", "owner": "C004", "enforced_by": "schema if/then; C009 typed mapping"}, + {"id": "negative_zero", "path": "quantity.value='-0' or '-0.00'", "expect": "reject", "wire": "invalid_request", "owner": "C004", "enforced_by": "D23 grammar; labelled semantic script + C009 parse"}, + {"id": "fractional_width_10", "path": "quantity.value with 10 fractional digits", "expect": "reject", "wire": "invalid_request", "owner": "C004", "enforced_by": "schema pattern; C009 int64/scale bound"}, + {"id": "ambiguous_leading_zero", "path": "quantity.value='080'", "expect": "reject", "wire": "invalid_request", "owner": "C004", "enforced_by": "schema pattern"}, + {"id": "exponent_spelling", "path": "quantity.value='8e2'", "expect": "reject", "wire": "invalid_request", "owner": "C004", "enforced_by": "schema pattern"}, + {"id": "leading_plus", "path": "quantity.value='+8'", "expect": "reject", "wire": "invalid_request", "owner": "C004", "enforced_by": "schema pattern"}, + {"id": "int64_coefficient_overflow", "path": "quantity coefficient beyond int64 after removing the point", "expect": "reject", "wire": "invalid_request", "owner": "C004", "enforced_by": "C009 checked int64 decode; labelled semantic script"}, + {"id": "span_end_before_start", "path": "evidence span end < start", "expect": "reject", "wire": "invalid_request", "owner": "C008/C009", "enforced_by": "hyf_core.domain.evidence.span_evidence; C004 labelled semantic script"}, + {"id": "span_revision_mismatch", "path": "evidence span revision differs from its source revision", "expect": "reject", "wire": "invalid_request", "owner": "C023", "enforced_by": "validate_span_against_revision; C004 labelled semantic script"}, + {"id": "type_coercion_number_for_string", "path": "quantity.value as JSON number instead of string", "expect": "reject", "wire": "invalid_request", "owner": "C004", "enforced_by": "schema type; C009 typed decode (no coercion)"}, + {"id": "present_null_optional_scalar", "path": "context.timezone=null", "expect": "reject", "wire": "invalid_request", "owner": "C004", "enforced_by": "schema type string; parser rejects present null"}, + {"id": "missing_selector", "path": "context.versions absent", "expect": "reject", "wire": "invalid_request", "owner": "C004", "enforced_by": "operation-context parse requires versions"}, + {"id": "unknown_selector", "path": "context.versions.schema is not hyf_ops_v2", "expect": "reject", "wire": "invalid_request", "owner": "C004", "enforced_by": "selector detection falls back to the legacy parser, which rejects versions"}, + {"id": "deterministic_path_reports_model_non_use", "path": "context.versions.model present with deterministic execution", "expect": "accepted_no_call", "wire": "capability_unavailable (pre-activation)", "owner": "C042-C046", "enforced_by": "C004 unavailability guard issues zero provider calls"} + ] +} diff --git a/schemas/hyf_ops_v2/version_manifest.json b/schemas/hyf_ops_v2/version_manifest.json @@ -0,0 +1,25 @@ +{ + "schema_version": 1, + "program": "hyf_http_v1", + "revision": "hyf_ops_v2", + "authority": "ADR-0025 D45 CB01-CB05 over ADR-0010 D21 (selector hyf_ops_v2) and ADR-0011 D23 (reported quantity grammar)", + "note": "Mechanical C004 version manifest. These are the current checked-in identifiers for the seven closed context.versions axes. review_policy/ranking_policy/question_bundle identifier semantics are bound by C008/C009/C023 against the checked-in implementations; C004 records the contract-revision identifiers so the strict schemas, examples and parser are self-consistent. model is the configured pinned assisted model default.", + "versions": { + "schema": "hyf_ops_v2", + "taxonomy": "hyf_ops_v2.taxonomy.v1", + "normalization": "hyf_ops_v2.normalization.v1", + "review_policy": "hyf_ops_v2.review_policy.v1", + "ranking_policy": "hyf_ops_v2.ranking_policy.v1", + "question_bundle": "hyf_ops_v2.question_bundle.v1", + "model": "jev-1.13.0" + }, + "version_sources": { + "schema": "ADR-0010 D21 new contract selector (immutable)", + "taxonomy": "C004 contract revision identifier; validated against the supplied input.references.taxonomy.version", + "normalization": "C004 contract revision identifier; validated against the supplied input.references.normalization.version", + "review_policy": "C008/C009/C023 bind the checked-in review-policy implementation version", + "ranking_policy": "C008/C009/C023 bind the checked-in ranking-policy implementation version", + "question_bundle": "C008/C009 bind the checked-in minimized question-bundle version", + "model": "hyf_runtime.config HyfTypesafeProviderRuntimeConfig default model" + } +}