{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://heartcortex.ai/schemas/1.0/rule.schema.json",
  "title": "rule",
  "type": "object",
  "required": [
    "id",
    "enabled"
  ],
  "properties": {
    "id": {
      "type": "string",
      "x-heart-privacy": "public"
    },
    "enabled": {
      "type": "boolean",
      "x-heart-privacy": "public",
      "description": "The owner's on/off switch. A rule runs only if this is true and status is adopted."
    },
    "origin": {
      "enum": [
        "owner",
        "vendor",
        "learned"
      ],
      "x-heart-privacy": "internal"
    },
    "description": {
      "type": "string",
      "x-heart-privacy": "internal"
    },
    "when": {
      "description": "What starts it: a check on a signal (it fires each time a new sample makes the check hold), or an event that happens count times within windowSec. Received messages never match.",
      "oneOf": [
        {
          "$ref": "common.schema.json#/$defs/check"
        },
        {
          "type": "object",
          "required": [
            "event"
          ],
          "additionalProperties": false,
          "properties": {
            "event": {
              "type": "string",
              "pattern": "^[a-z0-9]+(\\.[a-z0-9_-]+)+$"
            },
            "component": {
              "type": "string"
            },
            "count": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "windowSec": {
              "type": "integer",
              "minimum": 1,
              "maximum": 604800,
              "default": 3600
            }
          }
        }
      ],
      "x-heart-privacy": "internal"
    },
    "then": {
      "description": "What it does: run a capability, raise an alert, or both. A learned Playbook also carries expect and undoIf, and every run is a Trial.",
      "type": "object",
      "additionalProperties": false,
      "minProperties": 1,
      "properties": {
        "capability": {
          "type": "string"
        },
        "arguments": {
          "type": "object"
        },
        "raise": {
          "type": "object",
          "required": [
            "code",
            "severity"
          ],
          "additionalProperties": false,
          "properties": {
            "code": {
              "type": "string",
              "pattern": "^[a-z0-9]+(\\.[a-z0-9-]+)+$",
              "description": "The alert's fault code (Part 3, Section 5), such as connectivity.dependency-unreachable, or a profile or reverse-DNS product code. The same pattern as an Arrhythmia's code."
            },
            "severity": {
              "$ref": "common.schema.json#/$defs/severity"
            },
            "summary": {
              "type": "string",
              "maxLength": 500
            }
          }
        },
        "expect": {
          "type": "array",
          "minItems": 1,
          "maxItems": 8,
          "items": {
            "$ref": "common.schema.json#/$defs/check"
          }
        },
        "undoIf": {
          "$ref": "proposal.schema.json#/properties/undoIf"
        }
      },
      "dependentRequired": {
        "arguments": [
          "capability"
        ],
        "expect": [
          "capability",
          "undoIf"
        ],
        "undoIf": [
          "capability",
          "expect"
        ]
      },
      "x-heart-privacy": "internal"
    },
    "ext": {
      "$ref": "common.schema.json#/$defs/ext",
      "x-heart-privacy": "private"
    },
    "status": {
      "description": "proposed: waiting for a person to adopt it; every Playbook starts here, including vendor and learned ones. adopted: a human with heart.admin adopted it with proof of presence (PUT /heart/v1/tending/rules/{id}). suspended: the system or a person paused it; only a person can adopt it again.",
      "enum": [
        "proposed",
        "adopted",
        "suspended"
      ],
      "default": "proposed",
      "x-heart-privacy": "internal"
    },
    "envelope": {
      "$ref": "common.schema.json#/$defs/changeEnvelope",
      "x-heart-privacy": "internal",
      "description": "For a learned Playbook: how far its fix may go. It narrows the allowlist entry's envelope; both apply."
    },
    "evidence": {
      "description": "For a learned Playbook: the Trials it came from.",
      "type": "object",
      "required": [
        "trials"
      ],
      "properties": {
        "trials": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "common.schema.json#/$defs/uuid"
          }
        },
        "kept": {
          "type": "integer",
          "minimum": 0
        },
        "undone": {
          "type": "integer",
          "minimum": 0
        },
        "undoneInARow": {
          "type": "integer",
          "minimum": 0
        }
      },
      "x-heart-privacy": "internal"
    },
    "reviewBy": {
      "description": "For an adopted learned Playbook: after this time it is suspended until a person renews it. Adopting sets it to one year later unless given.",
      "$ref": "common.schema.json#/$defs/timestamp",
      "x-heart-privacy": "internal"
    },
    "adoptedBy": {
      "description": "The human who adopted it.",
      "type": "string",
      "x-heart-privacy": "private"
    },
    "adoptedAt": {
      "$ref": "common.schema.json#/$defs/timestamp",
      "x-heart-privacy": "internal"
    },
    "adoptedPhysical": {
      "description": "True if the person adopted it knowing its capability is physical. A rule never runs a physical capability without this.",
      "type": "boolean",
      "x-heart-privacy": "internal"
    },
    "actionId": {
      "description": "Request only (PUT /heart/v1/tending/rules/{id}), never stored or returned: the Action ID the client chose (API Standard 6.3).",
      "$ref": "common.schema.json#/$defs/actionId"
    },
    "presence": {
      "description": "Request only, never stored or returned: proof of presence for the digest of the Action named by actionId, so a person adopts the Playbook in one call (API Standard 6.3).",
      "$ref": "common.schema.json#/$defs/presence"
    }
  },
  "allOf": [
    {
      "if": {
        "properties": {
          "origin": {
            "const": "learned"
          }
        },
        "required": [
          "origin"
        ]
      },
      "then": {
        "required": [
          "evidence",
          "status"
        ],
        "properties": {
          "then": {
            "required": [
              "capability",
              "expect",
              "undoIf"
            ]
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "status": {
            "const": "adopted"
          }
        },
        "required": [
          "status"
        ]
      },
      "then": {
        "required": [
          "adoptedAt"
        ]
      }
    },
    {
      "if": {
        "properties": {
          "origin": {
            "const": "learned"
          },
          "status": {
            "const": "adopted"
          }
        },
        "required": [
          "origin",
          "status"
        ]
      },
      "then": {
        "required": [
          "reviewBy"
        ]
      }
    },
    {
      "if": {
        "properties": {
          "origin": {
            "enum": [
              "learned",
              "vendor"
            ]
          }
        },
        "required": [
          "origin"
        ]
      },
      "then": {
        "required": [
          "status"
        ]
      }
    }
  ],
  "description": "A Playbook: a Tending rule a person adopted (Core Standard, Section 4.3). It runs only if enabled is true and status is adopted.",
  "additionalProperties": false,
  "dependentRequired": {
    "presence": [
      "actionId"
    ]
  }
}
