{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://www.valyzen.ai/ucp/negotiation/schema.json",
  "title": "ai.valyzen.shopping.negotiation",
  "description": "Messages of the Valyzen negotiation capability: a buyer agent opens an arbitrated session over one SKU, makes moves, and receives a signed receipt. Money is integer minor units plus an ISO 4217 code; fractions are decimal strings.",
  "$defs": {
    "Money": {
      "type": "object",
      "required": ["amount_minor", "currency"],
      "additionalProperties": false,
      "properties": {
        "amount_minor": { "type": "integer", "minimum": 0 },
        "currency": { "type": "string", "pattern": "^[A-Z]{3}$" }
      }
    },
    "Inclusion": {
      "type": "object",
      "required": ["kind", "value"],
      "additionalProperties": false,
      "properties": {
        "kind": { "type": "string", "minLength": 1, "maxLength": 64 },
        "value": { "type": "string", "maxLength": 512 }
      }
    },
    "Terms": {
      "type": "object",
      "required": ["price"],
      "additionalProperties": false,
      "properties": {
        "price": { "$ref": "#/$defs/Money" },
        "inclusions": { "type": "array", "items": { "$ref": "#/$defs/Inclusion" } },
        "expiry": { "type": "string" }
      }
    },
    "Declared": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "max_rounds": { "type": "integer", "minimum": 1, "maximum": 100, "default": 5 },
        "currency": { "type": "string", "pattern": "^[A-Z]{3}$" },
        "inclusions": { "type": "array", "items": { "type": "string" }, "maxItems": 32 },
        "utilities": {
          "type": "object",
          "additionalProperties": { "type": "string", "pattern": "^(0(\\.[0-9]+)?|1(\\.0+)?)$" }
        },
        "non_price_preferences": { "type": "array", "items": { "type": "string" }, "maxItems": 32 }
      }
    },
    "OpenSessionRequest": {
      "type": "object",
      "required": ["sku", "buyer"],
      "additionalProperties": false,
      "properties": {
        "sku": { "type": "string", "minLength": 1, "maxLength": 256 },
        "buyer": {
          "type": "object",
          "required": ["agent_id"],
          "additionalProperties": false,
          "properties": {
            "agent_id": { "type": "string", "minLength": 1, "maxLength": 128 },
            "declared": { "$ref": "#/$defs/Declared" },
            "commitment": {
              "type": "string",
              "pattern": "^sha256:[0-9a-f]{64}$",
              "description": "sha256 over the canonical bytes of the buyer's private set. Optional: without it the gateway commits to an explicit empty set and the receipt says so."
            }
          }
        },
        "fairness_profile": { "type": "string", "default": "default/v0.1" },
        "description": { "type": "string", "maxLength": 1024 }
      }
    },
    "Move": {
      "description": "A buyer move in shorthand. The gateway mints the envelope and labels the round.",
      "oneOf": [
        {
          "type": "object",
          "required": ["type", "price_minor"],
          "additionalProperties": false,
          "properties": {
            "type": { "const": "offer" },
            "price_minor": { "type": "integer", "minimum": 0 },
            "inclusions": { "type": "array", "items": { "type": "string" }, "maxItems": 32 },
            "justification": { "type": "string", "maxLength": 2048 },
            "message_id": { "type": "string", "description": "Idempotency key; a repeat returns the same view." }
          }
        },
        {
          "type": "object",
          "required": ["type"],
          "additionalProperties": false,
          "properties": { "type": { "const": "accept" }, "message_id": { "type": "string" } }
        },
        {
          "type": "object",
          "required": ["type"],
          "additionalProperties": false,
          "properties": {
            "type": { "const": "reject" },
            "reason": { "type": "string", "maxLength": 512 },
            "message_id": { "type": "string" }
          }
        },
        {
          "type": "object",
          "required": ["type", "private"],
          "additionalProperties": false,
          "properties": {
            "type": { "const": "reveal" },
            "private": { "type": "object", "description": "The private set matching the commitment; accepted only after the session ends." }
          }
        }
      ]
    },
    "Verdict": {
      "type": "object",
      "properties": {
        "round": { "type": "integer" },
        "verdict": { "enum": ["fair", "unfair_to_buyer", "unfair_to_merchant", "unscoreable"] },
        "fairness_score": { "type": ["string", "null"] },
        "price_minor": { "type": "integer" },
        "outcome": { "enum": ["pending", "rejected", "accepted", "unenforced"] }
      }
    },
    "SessionView": {
      "type": "object",
      "required": ["session_id", "mode", "sku", "state", "round", "max_rounds", "your_turn", "corrective", "events"],
      "properties": {
        "session_id": { "type": "string" },
        "mode": { "enum": ["test", "live"] },
        "sku": { "type": "string" },
        "state": { "enum": ["open", "accepted", "negotiating", "corrective", "agreed", "closed"] },
        "round": { "type": "integer" },
        "max_rounds": { "type": "integer" },
        "your_turn": { "type": "boolean" },
        "corrective": { "type": "boolean", "description": "The buyer's last offer was refused; one corrective offer is allowed." },
        "offer_on_table": {
          "type": ["object", "null"],
          "properties": {
            "proposer": { "enum": ["buyer", "merchant"] },
            "terms": { "$ref": "#/$defs/Terms" }
          }
        },
        "last_verdict": { "anyOf": [{ "$ref": "#/$defs/Verdict" }, { "type": "null" }] },
        "close": {
          "type": ["object", "null"],
          "properties": { "reason": { "type": "string" }, "detail": { "type": ["string", "null"] } }
        },
        "events": {
          "type": "array",
          "description": "Every OANP envelope produced by this call: the buyer's, the arbiter's evaluations and rejections, the merchant's reply, and the agreement or close.",
          "items": { "type": "object" }
        },
        "receipt": { "type": ["string", "null"], "description": "URL of the signed receipt once the session has ended." },
        "session_token": { "type": "string", "description": "Returned once, on open: the bearer for this session's later calls." }
      }
    },
    "Receipt": {
      "type": "object",
      "required": ["session_id", "state", "arbiter", "chain", "jwks", "signature"],
      "properties": {
        "oanp_version": { "type": "string" },
        "session_id": { "type": "string" },
        "state": { "enum": ["agreed", "closed", "open", "accepted", "negotiating", "corrective"] },
        "enforcement": { "enum": ["arbitrated", "bilateral"] },
        "arbiter": {
          "type": "object",
          "required": ["agent_id", "relationship"],
          "properties": { "agent_id": { "type": "string" }, "relationship": { "enum": ["independent", "affiliated"] } }
        },
        "verdicts": { "type": "array", "items": { "$ref": "#/$defs/Verdict" } },
        "final_terms": { "anyOf": [{ "$ref": "#/$defs/Terms" }, { "type": "null" }] },
        "invariants": { "type": "object" },
        "chain": {
          "type": "object",
          "required": ["head", "length"],
          "properties": {
            "head": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" },
            "length": { "type": "integer" },
            "retention_days": { "type": "integer" }
          }
        },
        "artifact": {
          "type": ["object", "null"],
          "description": "Detached JWS (EdDSA, b64 false, crit [b64], kid) over the RFC 8785 bytes of signed_payload.",
          "properties": { "protected": { "type": "string" }, "signature": { "type": "string" } }
        },
        "signed_payload": {
          "type": ["object", "null"],
          "properties": { "final_terms": { "$ref": "#/$defs/Terms" }, "session": { "type": "object" } }
        },
        "jwks": { "type": "object", "properties": { "keys": { "type": "array", "items": { "type": "object" } } } },
        "signature": {
          "type": "object",
          "properties": { "status": { "enum": ["valid", "invalid", "unverifiable", "unsigned"] }, "reason": { "type": "string" } }
        },
        "mode": { "enum": ["test", "live"] },
        "hosted": { "type": "object" }
      }
    }
  },
  "properties": {
    "open": { "$ref": "#/$defs/OpenSessionRequest" },
    "move": { "$ref": "#/$defs/Move" },
    "view": { "$ref": "#/$defs/SessionView" },
    "receipt": { "$ref": "#/$defs/Receipt" }
  }
}
