{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://docs.demiton.io/registers/email_issue/v1.json",
  "title": "email_issue contract v1",
  "type": "object",
  "required": [
    "clock",
    "emails",
    "kind",
    "message_id",
    "project",
    "raisers",
    "received_at",
    "sender",
    "subject"
  ],
  "properties": {
    "kind": {
      "type": "string",
      "description": "What kind of issue it is, chosen by the person in the panel. Documents the vocabulary for the panel and the validators; the write path refuses an unknown value (email_issue_kinds.validate_kind), because the fact gate checks presence and type only and enforces no enum anywhere.",
      "enum": [
        "extra_work",
        "delay",
        "defect",
        "dispute",
        "over_budget",
        "compliance",
        "other"
      ],
      "x-demiton-requiredness": "required"
    },
    "clock": {
      "type": "object",
      "description": "The notice clock computed in code at raise time. Code, never the model, and P9 arms a window from `applies` alone.",
      "properties": {
        "days": {
          "type": "integer",
          "description": "The period in days, as the contract states it.",
          "x-demiton-requiredness": "optional"
        },
        "clause": {
          "type": "string",
          "description": "The contract clause the period comes from.",
          "x-demiton-requiredness": "optional"
        },
        "applies": {
          "type": "boolean",
          "description": "True only when the kind can start a clock, the sender is on the principal's side, and contract_terms states the period.",
          "x-demiton-requiredness": "required"
        },
        "deadline": {
          "type": "string",
          "description": "The date the notice is due, counted from received_at.",
          "x-demiton-requiredness": "optional",
          "format": "date",
          "x-demiton-type": "date"
        }
      },
      "x-demiton-requiredness": "required"
    },
    "chosen": {
      "type": "object",
      "description": "What the person actually picked, which is what the rest of the payload reflects.",
      "properties": {
        "job": {
          "type": "string",
          "description": "The job as raised, by name.",
          "x-demiton-requiredness": "optional"
        },
        "kind": {
          "type": "string",
          "description": "The kind as raised.",
          "x-demiton-requiredness": "optional"
        }
      },
      "x-demiton-requiredness": "optional"
    },
    "emails": {
      "type": "array",
      "description": "Every email stored as this issue's evidence, the raised one first.",
      "items": {
        "type": "object",
        "properties": {
          "blob": {
            "type": "string",
            "description": "The org-uploads key of the stored .eml (org_<id>/evidence/email_issue/<sha256>.eml).",
            "x-demiton-requiredness": "required"
          },
          "subject": {
            "type": "string",
            "description": "That email's subject line.",
            "x-demiton-requiredness": "required"
          },
          "received_at": {
            "type": "string",
            "description": "That email's Date header, ISO 8601.",
            "x-demiton-requiredness": "required",
            "format": "date-time",
            "x-demiton-type": "datetime"
          }
        }
      },
      "x-demiton-requiredness": "required"
    },
    "sender": {
      "type": "string",
      "description": "The From address of the raised email.",
      "x-demiton-requiredness": "required"
    },
    "guessed": {
      "type": "object",
      "description": "What the panel pre-selected, kept so the guess's accuracy can be measured again from production rows.",
      "properties": {
        "job": {
          "type": "string",
          "description": "The guessed job, by name.",
          "x-demiton-requiredness": "optional"
        },
        "kind": {
          "type": "string",
          "description": "The guessed kind, or null when nothing was guessed.",
          "x-demiton-requiredness": "optional"
        }
      },
      "x-demiton-requiredness": "optional"
    },
    "project": {
      "type": "string",
      "description": "The job this issue was raised against, by name. The fact also carries the project as its coordinate, which is what the window engine reads.",
      "x-demiton-requiredness": "required"
    },
    "raisers": {
      "type": "array",
      "description": "The Demiton user ids who raised this issue; more than one when two people raised the same message.",
      "items": {
        "type": "integer"
      },
      "x-demiton-requiredness": "required"
    },
    "subject": {
      "type": "string",
      "description": "The subject line of the raised email.",
      "x-demiton-requiredness": "required"
    },
    "currency": {
      "type": "string",
      "description": "ISO 4217 code of `estimate`. Present exactly when `estimate` is.",
      "x-demiton-requiredness": "optional"
    },
    "estimate": {
      "type": "number",
      "description": "the raiser's estimate of what this costs the job if nobody acts, in `currency`. Never `amount`: that key is in the claim-window verdict's exposure keys and would reach the Baseline.",
      "x-demiton-requiredness": "optional"
    },
    "message_id": {
      "type": "string",
      "description": "The raised email's internetMessageId. With the org, the kind and the project it is the dedupe key.",
      "x-demiton-requiredness": "required"
    },
    "estimate_at": {
      "type": "string",
      "description": "when the estimate was raised, UTC. The pilot window filters on this.",
      "x-demiton-requiredness": "optional",
      "format": "date-time",
      "x-demiton-type": "datetime"
    },
    "estimate_by": {
      "type": "integer",
      "description": "the Demiton user id whose estimate this is: the first raiser's.",
      "x-demiton-requiredness": "optional"
    },
    "received_at": {
      "type": "string",
      "description": "The raised email's own Date header, ISO 8601. The fact's occurred_at and every window deadline are counted from this, never from the day someone noticed.",
      "x-demiton-requiredness": "required",
      "format": "date-time",
      "x-demiton-type": "datetime"
    },
    "sender_domain": {
      "type": "string",
      "description": "The sender's domain, as used to match the job.",
      "x-demiton-requiredness": "optional"
    }
  },
  "x-demiton-register-type": "email_issue",
  "x-demiton-contract-version": "1.1.0",
  "x-demiton-store": "tenant",
  "x-demiton-axes": [
    {
      "axis": "project",
      "requirement": "required",
      "role": "subject"
    }
  ],
  "x-demiton-measures": [],
  "x-demiton-provenance": {
    "standards": []
  },
  "description": "The Email issue register contract, version 1. JSON Schema (draft 2020-12); x-demiton-* keywords carry Demiton's own meaning and standard validators ignore them.",
  "x-demiton-contract-url": "https://docs.demiton.io/registers/email_issue/",
  "x-demiton-register-catalog": "https://docs.demiton.io/concepts/register-catalog"
}