{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "urn:orbiplex:schema:service-offer-common:v1",
  "title": "Service Offer Common Content v1",
  "x-dia-workflow": "project",
  "x-dia-status": "accepted",
  "x-dia-basis": [
    "doc/project/30-stories/story-006-voluntary-swarm-exchange.md",
    "doc/project/30-stories/story-006-buyer-node-components.md",
    "doc/project/40-proposals/021-service-offers-orders-and-procurement-bridge.md",
    "doc/project/50-requirements/requirements-012-service-offers-orders.md"
  ],
  "description": "Shared unsigned standing-offer content. The signed service-offer.v1 additionally requires a provider signature; a task-pack draft explicitly forbids that signature.",
  "type": "object",
  "additionalProperties": true,
  "required": [
    "schema/v",
    "offer/id",
    "created-at",
    "published-at",
    "expires-at",
    "sequence/no",
    "provider/node-id",
    "provider/participant-id",
    "service/type",
    "service/description",
    "pricing/amount",
    "pricing/currency",
    "pricing/unit",
    "pricing/unit-kind",
    "delivery/max-duration-sec",
    "queue/auto-accept",
    "queue/max-depth",
    "hybrid"
  ],
  "properties": {
    "schema/v": {
      "const": 1,
      "description": "Schema version."
    },
    "offer/id": {
      "type": "string",
      "minLength": 1,
      "pattern": "^offer:[A-Za-z0-9][A-Za-z0-9:-]*$",
      "description": "Stable identifier of this standing service offer."
    },
    "offer/status": {
      "type": "string",
      "enum": [
        "active",
        "withdrawn"
      ],
      "default": "active",
      "description": "Provider-attested lifecycle marker. Missing means `active`; a superseding `withdrawn` snapshot keeps the offer auditable while removing it from active-only catalog views."
    },
    "created-at": {
      "type": "string",
      "format": "date-time",
      "description": "Timestamp when the offer record became auditable."
    },
    "published-at": {
      "type": "string",
      "format": "date-time",
      "description": "Timestamp when the offer was last published to the exchange-visible channel."
    },
    "expires-at": {
      "type": "string",
      "format": "date-time",
      "description": "Timestamp after which the offer should be treated as stale."
    },
    "sequence/no": {
      "type": "integer",
      "minimum": 0,
      "description": "Monotonic per-offer sequence number. Higher values supersede lower ones for the same standing offer identity."
    },
    "provider/node-id": {
      "type": "string",
      "minLength": 1,
      "description": "Serving node hosting this offer."
    },
    "provider/participant-id": {
      "type": "string",
      "minLength": 1,
      "description": "Provider-side accountable subject publishing this offer."
    },
    "service/type": {
      "type": "string",
      "minLength": 1,
      "description": "Marketplace-visible service category such as `text/redaction`, `research/topical`, or `image/generation`."
    },
    "service/description": {
      "type": "string",
      "minLength": 1,
      "description": "Human-readable summary of the offered service."
    },
    "pricing/amount": {
      "type": "integer",
      "minimum": 0,
      "description": "Price in minor units for one billable unit of service. When `pricing/currency = ORC`, the value uses ORC minor units with fixed scale `2`."
    },
    "pricing/currency": {
      "type": "string",
      "minLength": 2,
      "maxLength": 16,
      "description": "Settlement unit or currency symbol, with `ORC` as the current hard-MVP marketplace unit."
    },
    "pricing/unit": {
      "type": "string",
      "minLength": 1,
      "description": "Human-readable billable unit label, for example `1 summary item`, `1800 input characters`, or `1 illustration`."
    },
    "pricing/unit-kind": {
      "type": "string",
      "enum": [
        "per-item",
        "per-character-block",
        "per-request",
        "per-task",
        "flat"
      ],
      "description": "Host-computable pricing kind. The host computes total price and hold from explicit order units multiplied by `pricing/amount`; `pricing/unit` remains descriptive only."
    },
    "delivery/max-duration-sec": {
      "type": "integer",
      "minimum": 1,
      "description": "Maximum provider-side promised duration for one accepted order under this standing offer."
    },
    "queue/auto-accept": {
      "type": "boolean",
      "description": "Whether the provider declares automatic acceptance up to the published queue posture."
    },
    "queue/max-depth": {
      "type": "integer",
      "minimum": 0,
      "description": "Maximum queue depth at which the provider still considers the service admissible."
    },
    "queue/current-depth": {
      "type": "integer",
      "minimum": 0,
      "description": "Current queue depth when the offer was published or refreshed."
    },
    "constraints/input": {
      "type": "object",
      "additionalProperties": true,
      "description": "Optional input-side bounded constraints declared by the provider."
    },
    "constraints/output": {
      "type": "object",
      "additionalProperties": true,
      "description": "Optional output-side bounded constraints declared by the provider."
    },
    "hybrid": {
      "type": "boolean",
      "description": "Whether this service involves human intervention beyond pure automated model execution."
    },
    "model-first": {
      "type": "boolean",
      "description": "Whether model-backed processing is intended to happen before human intervention when `hybrid` is true."
    },
    "confirmation/mode": {
      "type": "string",
      "enum": [
        "arbiter-confirmed",
        "self-confirmed",
        "manual-review-only"
      ],
      "description": "Provider-declared preferred confirmation mode intended to map directly into procurement contract confirmation semantics."
    },
    "corpus/topics": {
      "type": "array",
      "minItems": 1,
      "maxItems": 64,
      "uniqueItems": true,
      "items": {
        "$ref": "#/$defs/corpus_topic_term"
      },
      "description": "Corpus provider topic scopes pinned to `corpus/taxonomy-digest`. Runtime admission MUST reject any topic not present in the trusted taxonomy material."
    },
    "corpus/taxonomy-digest": {
      "$ref": "#/$defs/sha256_digest",
      "description": "Digest of the trusted topic taxonomy used to interpret `corpus/topics`."
    },
    "corpus/taxonomy-issuer": {
      "type": "string",
      "pattern": "^(nym|participant|organization):did:key:z[1-9A-HJ-NP-Za-km-z]+$",
      "description": "Accountable issuer of the taxonomy material. This is a governance/provenance identifier, not a provider identity."
    },
    "corpus/model-class": {
      "type": "string",
      "enum": [
        "local-llm",
        "remote-llm",
        "human-curated",
        "hybrid-llm-curated"
      ],
      "description": "Provider-declared reasoning backend class for Corpus procurement routing."
    },
    "corpus/reasoning": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "max-steps": {
          "type": "integer",
          "minimum": 1,
          "maximum": 128
        },
        "languages": {
          "type": "array",
          "minItems": 1,
          "maxItems": 16,
          "uniqueItems": true,
          "items": {
            "type": "string",
            "minLength": 2,
            "maxLength": 16
          }
        }
      },
      "description": "Optional Corpus-specific bounded reasoning posture. It does not replace base service offer pricing or delivery promises."
    },
    "policy_annotations": {
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "inference/posture": {
          "$ref": "inference-execution-posture.v1.schema.json",
          "description": "Optional characteristic covered by the offer signature. Its assertion owner is provider/participant-id, subject/ref and scope/ref equal offer/id, and generation equals sequence/no. It declares execution posture, not observed execution or authority."
        },
        "operator-task/profile": {
          "$ref": "operator-task-common.v1.schema.json#/$defs/offerTaskProfile"
        }
      },
      "description": "Optional marketplace-local or federation-local annotations that do not redefine the core standing-offer semantics."
    }
  },
  "allOf": [
    {
      "if": {
        "properties": {
          "hybrid": {
            "const": false
          }
        },
        "required": [
          "hybrid"
        ]
      },
      "then": {
        "properties": {
          "model-first": {
            "const": false
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "service/type": {
            "const": "corpus.provider"
          }
        },
        "required": [
          "service/type"
        ]
      },
      "then": {
        "required": [
          "corpus/topics",
          "corpus/taxonomy-digest",
          "corpus/taxonomy-issuer",
          "corpus/model-class"
        ]
      }
    }
  ],
  "$defs": {
    "sha256_digest": {
      "type": "string",
      "pattern": "^sha256:[A-Za-z0-9_-]{16,128}$"
    },
    "corpus_topic_term": {
      "type": "string",
      "minLength": 1,
      "maxLength": 256,
      "pattern": "^[A-Za-z0-9][A-Za-z0-9:._+/-]*$"
    },
    "signature": {
      "type": "object",
      "additionalProperties": true,
      "required": [
        "alg",
        "value"
      ],
      "properties": {
        "alg": {
          "type": "string",
          "enum": [
            "ed25519"
          ],
          "description": "Signature algorithm used by the provider-side accountable subject."
        },
        "value": {
          "type": "string",
          "minLength": 1,
          "description": "Serialized signature value."
        }
      }
    }
  }
}
