{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://echo.cc/schemas/envelope-v1.json",
  "title": "echo.cc v1 producer contract",
  "description": "Canonical records produced by echo.cc. Omit unset optional fields. Structural validation only: use ecc validate for byte limits, controls, trace IDs, source/member equality, path rules, and expiry relationships. JSON parsing must reject duplicate keys.",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "specversion": {
      "const": "1.0"
    },
    "id": {
      "$ref": "#/$defs/ulid"
    },
    "source": {
      "$ref": "#/$defs/member"
    },
    "type": {
      "enum": [
        "cc.echo.message.v1",
        "cc.echo.presence.v1",
        "cc.echo.ack.v1",
        "cc.echo.hold.v1",
        "cc.echo.sealed.v1"
      ]
    },
    "time": {
      "$ref": "#/$defs/timestamp"
    },
    "datacontenttype": {
      "const": "application/json"
    },
    "net": {
      "$ref": "#/$defs/token"
    },
    "expiresat": {
      "$ref": "#/$defs/timestamp"
    },
    "traceparent": {
      "type": "string",
      "pattern": "^00-[0-9a-f]{32}-[0-9a-f]{16}-[0-9a-f]{2}$"
    },
    "tracestate": {
      "type": "string",
      "maxLength": 512
    },
    "data": {
      "type": "object"
    },
    "certid": {
      "$ref": "#/$defs/ulid"
    },
    "signature": {
      "type": "string",
      "pattern": "^[0-9a-f]{128}$"
    }
  },
  "required": [
    "specversion",
    "id",
    "source",
    "type",
    "time",
    "datacontenttype",
    "net",
    "expiresat",
    "data"
  ],
  "$defs": {
    "token": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]{0,62}$"
    },
    "member": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]{0,62}\\.[a-z0-9][a-z0-9-]{0,62}\\.[a-z0-9][a-z0-9-]{0,62}$"
    },
    "ulid": {
      "type": "string",
      "pattern": "^[0-7][0-9A-HJKMNP-TV-Z]{25}$"
    },
    "timestamp": {
      "type": "string",
      "format": "date-time"
    },
    "message": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "to": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/member"
          },
          "uniqueItems": true
        },
        "topic": {
          "$ref": "#/$defs/token"
        },
        "summary": {
          "type": "string",
          "minLength": 1,
          "maxLength": 160
        },
        "body": {
          "type": "string",
          "description": "At most 65536 UTF-8 bytes; control-character restrictions are checked by ecc validate."
        },
        "replyto": {
          "$ref": "#/$defs/ulid"
        },
        "thread": {
          "$ref": "#/$defs/ulid"
        },
        "hops": {
          "type": "integer",
          "minimum": 0,
          "maximum": 64
        }
      },
      "required": [
        "summary"
      ],
      "oneOf": [
        {
          "required": [
            "to"
          ],
          "properties": {
            "to": {
              "minItems": 1
            }
          },
          "not": {
            "required": [
              "topic"
            ]
          }
        },
        {
          "required": [
            "topic"
          ],
          "not": {
            "required": [
              "to"
            ]
          }
        }
      ],
      "dependentRequired": {
        "replyto": [
          "thread"
        ]
      },
      "allOf": [
        {
          "if": {
            "required": [
              "hops"
            ],
            "properties": {
              "hops": {
                "minimum": 1
              }
            }
          },
          "then": {
            "required": [
              "thread"
            ]
          }
        }
      ]
    },
    "presence": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "member": {
          "$ref": "#/$defs/member"
        },
        "version": {
          "type": "string"
        },
        "pid": {
          "type": "integer"
        },
        "cwd": {
          "type": "string"
        },
        "repo": {
          "type": "string"
        },
        "branch": {
          "type": "string"
        },
        "state": {
          "enum": [
            "starting",
            "working",
            "idle",
            "needs-input",
            "ended"
          ]
        },
        "title": {
          "type": "string",
          "maxLength": 160
        },
        "tier": {
          "type": "integer",
          "minimum": 0,
          "maximum": 3
        },
        "subscribe": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/token"
          }
        },
        "caps": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "wakes": {
          "type": "integer"
        },
        "started": {
          "$ref": "#/$defs/timestamp"
        }
      },
      "required": [
        "member",
        "state",
        "tier",
        "started"
      ]
    },
    "hold": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "id": {
          "$ref": "#/$defs/ulid"
        },
        "member": {
          "$ref": "#/$defs/member"
        },
        "paths": {
          "type": "array",
          "items": {
            "type": "string",
            "minLength": 1
          },
          "minItems": 1
        },
        "mode": {
          "enum": [
            "exclusive",
            "shared"
          ]
        },
        "note": {
          "type": "string"
        },
        "created": {
          "$ref": "#/$defs/timestamp"
        },
        "expires": {
          "$ref": "#/$defs/timestamp"
        }
      },
      "required": [
        "id",
        "member",
        "paths",
        "mode",
        "created",
        "expires"
      ]
    },
    "ack": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "message": {
          "$ref": "#/$defs/ulid"
        }
      },
      "required": [
        "message"
      ]
    },
    "sealed": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "recipient": {
          "$ref": "#/$defs/member"
        },
        "certid": {
          "$ref": "#/$defs/ulid"
        },
        "ciphertext": {
          "type": "string",
          "minLength": 64,
          "maxLength": 262144
        }
      },
      "required": [
        "recipient",
        "certid",
        "ciphertext"
      ]
    }
  },
  "dependentRequired": {
    "tracestate": [
      "traceparent"
    ]
  },
  "allOf": [
    {
      "if": {
        "properties": {
          "type": {
            "const": "cc.echo.message.v1"
          }
        }
      },
      "then": {
        "properties": {
          "data": {
            "$ref": "#/$defs/message"
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "type": {
            "const": "cc.echo.presence.v1"
          }
        }
      },
      "then": {
        "properties": {
          "data": {
            "$ref": "#/$defs/presence"
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "type": {
            "const": "cc.echo.ack.v1"
          }
        }
      },
      "then": {
        "properties": {
          "data": {
            "$ref": "#/$defs/ack"
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "type": {
            "const": "cc.echo.hold.v1"
          }
        }
      },
      "then": {
        "properties": {
          "data": {
            "$ref": "#/$defs/hold"
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "type": {
            "const": "cc.echo.sealed.v1"
          }
        }
      },
      "then": {
        "properties": {
          "data": {
            "$ref": "#/$defs/sealed"
          }
        }
      }
    }
  ]
}
