{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://starlingshq.com/spec/schema.json",
  "title": "Starlings Subject Spec",
  "version": "0.2.0",
  "$defs": {
    "SubjectKind": {
      "type": "string",
      "enum": [
        "project",
        "lead",
        "partner",
        "event"
      ],
      "description": "One of the subject kinds."
    },
    "DoorKind": {
      "type": "string",
      "enum": [
        "subject",
        "person",
        "agent",
        "thread",
        "document",
        "event",
        "task",
        "issue"
      ],
      "description": "What a door names."
    },
    "Door": {
      "type": "string",
      "pattern": "^(?:subject:(?:project|lead|partner|event):.+|(?:person|agent|thread|document|event|task|issue):.+)$",
      "description": "The stable address of a thing: `<kind>:<id>`, or `subject:<subject kind>:<id>` for a subject."
    },
    "DecisionSource": {
      "type": "string",
      "enum": [
        "message",
        "meeting",
        "manual",
        "agent"
      ],
      "description": "Where the decision was made: a message, a meeting, by hand, or by an agent acting for a person."
    },
    "Decision": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Stable id of the decision."
        },
        "subject_kind": {
          "$ref": "#/$defs/SubjectKind"
        },
        "subject_id": {
          "type": "string",
          "description": "Id of the subject the decision belongs to."
        },
        "body": {
          "type": "string",
          "maxLength": 2000,
          "description": "What was chosen, in one to a few sentences."
        },
        "source": {
          "$ref": "#/$defs/DecisionSource"
        },
        "source_ref": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "The message id, the meeting id, or the agent, by `source`. Null for `manual`."
        },
        "goal_id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "The goal the decision serves, if any."
        },
        "decided_by_name": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Display name of the person who decided."
        },
        "decided_by_email": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Address of the person who decided."
        },
        "decided_at": {
          "type": "string",
          "description": "When it was decided, as an ISO 8601 timestamp."
        }
      },
      "required": [
        "id",
        "subject_kind",
        "subject_id",
        "body",
        "source",
        "source_ref",
        "goal_id",
        "decided_by_name",
        "decided_by_email",
        "decided_at"
      ],
      "additionalProperties": false,
      "description": "A settled choice on one subject."
    },
    "Subject": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Stable id of the subject, unique within its kind."
        },
        "kind": {
          "$ref": "#/$defs/SubjectKind"
        },
        "title": {
          "type": "string",
          "description": "The name people use for it."
        },
        "subtitle": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "One line of context: a client, a stage, a date. Null when there is none."
        },
        "last_activity_at": {
          "description": "When something last happened on the subject, as an ISO 8601 timestamp. Null or absent when unknown.",
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ]
        }
      },
      "required": [
        "id",
        "kind",
        "title",
        "subtitle"
      ],
      "additionalProperties": false,
      "description": "One thing a company works on: a project, a lead, a partner or an event."
    },
    "TaskStatus": {
      "type": "string",
      "enum": [
        "pending",
        "in_progress",
        "review",
        "blocked",
        "completed",
        "cancelled",
        "proposed",
        "declined"
      ],
      "description": "Where the task stands. `proposed`: suggested by an agent, not yet accepted by a person. `declined`: turned down by a person."
    },
    "Task": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Stable id of the task."
        },
        "title": {
          "type": "string",
          "description": "What must be done, in a few words."
        },
        "notes": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Longer detail. Null when there is none."
        },
        "status": {
          "$ref": "#/$defs/TaskStatus"
        },
        "subject_kind": {
          "anyOf": [
            {
              "$ref": "#/$defs/SubjectKind"
            },
            {
              "type": "null"
            }
          ],
          "description": "The kind of subject the task belongs to. Null, with `subject_id`, for a task that belongs to no subject."
        },
        "subject_id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Id of the subject the task belongs to. Null exactly when `subject_kind` is null."
        },
        "assignee_name": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Display name of the person who owns the task. Null when nobody does."
        },
        "assignee_email": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Address of the person who owns the task. Null when nobody does."
        },
        "due_date": {
          "anyOf": [
            {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            },
            {
              "type": "null"
            }
          ],
          "description": "The day it is due, as YYYY-MM-DD. Null when it has no date."
        },
        "goal_id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "The goal the task serves, if any."
        },
        "updated_at": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "When the task last changed, as an ISO 8601 timestamp. Null when unknown."
        }
      },
      "required": [
        "id",
        "title",
        "notes",
        "status",
        "subject_kind",
        "subject_id",
        "assignee_name",
        "assignee_email",
        "due_date",
        "goal_id",
        "updated_at"
      ],
      "additionalProperties": false,
      "description": "Work someone must do, usually on one subject."
    }
  }
}
