{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "urn:orbiplex:schema:inac-control:v1",
  "title": "INAC control frame",
  "description": "Control-plane frame for Inter-Node Artifact Channel offer/request/push/response exchanges. The frame is transport-neutral; concrete transports must preserve the byte identity of inline artifact bytes.",
  "type": "object",
  "required": [
    "schema",
    "operation"
  ],
  "properties": {
    "schema": {
      "const": "inac-control.v1"
    },
    "operation": {
      "type": "string",
      "enum": [
        "offer",
        "request",
        "push",
        "accept",
        "decline",
        "defer",
        "ingested",
        "already-present",
        "refused",
        "partial"
      ]
    },
    "correlation/id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 256,
      "pattern": "^[A-Za-z0-9:_./-]+$"
    },
    "idempotency/key": {
      "type": "string",
      "minLength": 1,
      "maxLength": 256,
      "pattern": "^[A-Za-z0-9:_./-]+$"
    },
    "artifact": {
      "$ref": "#/$defs/artifact"
    },
    "request": {
      "$ref": "#/$defs/request"
    },
    "transfer": {
      "$ref": "#/$defs/transfer"
    },
    "authorization": {
      "$ref": "#/$defs/authorization"
    },
    "response": {
      "$ref": "#/$defs/response"
    },
    "meta": {
      "type": "object",
      "maxProperties": 16,
      "propertyNames": {
        "minLength": 1,
        "maxLength": 64,
        "pattern": "^[A-Za-z0-9:_./-]+$"
      },
      "additionalProperties": {
        "type": "string",
        "maxLength": 512
      }
    }
  },
  "allOf": [
    {
      "if": {
        "properties": {
          "operation": {
            "const": "offer"
          }
        },
        "required": [
          "operation"
        ]
      },
      "then": {
        "required": [
          "artifact"
        ],
        "properties": {
          "artifact": {
            "oneOf": [
              {
                "required": [
                  "bytes/base64url"
                ],
                "not": {
                  "anyOf": [
                    {
                      "required": [
                        "artifact/ref"
                      ]
                    },
                    {
                      "required": [
                        "artifact/href"
                      ]
                    }
                  ]
                }
              },
              {
                "required": [
                  "artifact/ref"
                ],
                "not": {
                  "anyOf": [
                    {
                      "required": [
                        "bytes/base64url"
                      ]
                    },
                    {
                      "required": [
                        "artifact/href"
                      ]
                    }
                  ]
                }
              },
              {
                "required": [
                  "artifact/href"
                ],
                "not": {
                  "anyOf": [
                    {
                      "required": [
                        "bytes/base64url"
                      ]
                    },
                    {
                      "required": [
                        "artifact/ref"
                      ]
                    }
                  ]
                }
              }
            ]
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "operation": {
            "const": "push"
          }
        },
        "required": [
          "operation"
        ]
      },
      "then": {
        "required": [
          "artifact"
        ]
      }
    },
    {
      "if": {
        "properties": {
          "operation": {
            "const": "request"
          }
        },
        "required": [
          "operation"
        ]
      },
      "then": {
        "required": [
          "request"
        ]
      }
    },
    {
      "if": {
        "properties": {
          "operation": {
            "enum": [
              "accept",
              "decline",
              "defer",
              "ingested",
              "already-present",
              "refused",
              "partial"
            ]
          }
        },
        "required": [
          "operation"
        ]
      },
      "then": {
        "required": [
          "response"
        ]
      }
    }
  ],
  "$defs": {
    "artifact": {
      "type": "object",
      "required": [
        "schema",
        "content/type",
        "artifact/id",
        "digest",
        "size/bytes"
      ],
      "properties": {
        "schema": {
          "type": "string",
          "minLength": 1
        },
        "content/type": {
          "type": "string",
          "minLength": 1
        },
        "artifact/id": {
          "type": "string",
          "minLength": 1
        },
        "digest": {
          "type": "string",
          "pattern": "^sha256:[A-Za-z0-9_-]+$"
        },
        "size/bytes": {
          "type": "integer",
          "minimum": 0,
          "maximum": 1073741824
        },
        "bytes/base64url": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_-]+$"
        },
        "artifact/ref": {
          "type": "string",
          "minLength": 1
        },
        "artifact/href": {
          "type": "string",
          "format": "uri"
        }
      },
      "additionalProperties": false
    },
    "request": {
      "type": "object",
      "required": [
        "schema",
        "content/type"
      ],
      "properties": {
        "schema": {
          "type": "string",
          "minLength": 1
        },
        "content/type": {
          "type": "string",
          "minLength": 1
        },
        "artifact/id": {
          "type": "string",
          "minLength": 1
        },
        "digest": {
          "type": "string",
          "pattern": "^sha256:[A-Za-z0-9_-]+$"
        }
      },
      "additionalProperties": false
    },
    "transfer": {
      "type": "object",
      "properties": {
        "mode": {
          "type": "string",
          "enum": [
            "inline",
            "stream",
            "out-of-band"
          ]
        },
        "stream/id": {
          "type": "string",
          "minLength": 1
        },
        "chunk/size-bytes": {
          "type": "integer",
          "minimum": 1
        }
      },
      "additionalProperties": false
    },
    "authorization": {
      "type": "object",
      "required": [
        "mode",
        "passport"
      ],
      "properties": {
        "mode": {
          "type": "string",
          "enum": [
            "invitation-passport"
          ]
        },
        "passport": {
          "type": "object",
          "required": [
            "schema"
          ],
          "properties": {
            "schema": {
              "const": "capability-passport.v1"
            }
          },
          "additionalProperties": true
        }
      },
      "additionalProperties": false
    },
    "response": {
      "type": "object",
      "required": [
        "status"
      ],
      "properties": {
        "status": {
          "type": "string",
          "enum": [
            "accepted",
            "declined",
            "deferred",
            "ingested",
            "already-present",
            "refused",
            "partial"
          ]
        },
        "refusal/code": {
          "type": "string",
          "enum": [
            "kind-not-supported",
            "kind-conflict",
            "not-authorized",
            "invitation-unknown",
            "invitation-expired",
            "invitation-revoked",
            "invitation-scope-mismatch",
            "payload-too-large",
            "digest-mismatch",
            "malformed",
            "handler-unavailable",
            "already-present",
            "operation-not-supported",
            "policy-denied",
            "transport-unavailable",
            "rate-limited",
            "quota-exceeded"
          ]
        },
        "retryable": {
          "type": "boolean"
        },
        "retry/after-ms": {
          "type": "integer",
          "minimum": 0
        },
        "message": {
          "type": "string",
          "maxLength": 1024
        }
      },
      "additionalProperties": false
    }
  },
  "additionalProperties": false
}
