{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://litlfred.github.io/bootstrap/0.1.0/schemas/requirement-set.schema.json",
  "$comment": "Generated by the bootstrap toolset (https://github.com/litlfred/bootstrap-tools, scripts/gen-bootstrap-schemas.ts) from its Zod source — do not edit; change the Zod.",
  "title": "Requirement Set",
  "description": "A requirements document: a set of requirement statements (by `req:` reference, each with its own decision) at one stage of its life — draft, proposed, approved, planned, in-progress, delivered, accepted, or rejected, cancelled, superseded — with its work plan and the sign-offs that moved it there. A sign-off is a recorded decision: who (kind, id, actor), when, about what, the outcome (approve, amend, reject, defer, cancel), the stage it moves the set to, why, and a link to where it was made. `approved` and `accepted` need a human sign-off; from `planned` on, the set names its work plan; `cancelled` needs a reason. The set's stage and each member's own status are independent.",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "pattern": "^reqset:[a-z0-9][a-z0-9-]*$"
    },
    "title": {
      "type": "string",
      "minLength": 1
    },
    "methodology": {
      "type": "string",
      "minLength": 1
    },
    "issue": {
      "type": "string",
      "pattern": "^https:\\/\\/\\S+$"
    },
    "stage": {
      "type": "string",
      "enum": [
        "draft",
        "proposed",
        "approved",
        "planned",
        "in-progress",
        "delivered",
        "accepted",
        "rejected",
        "cancelled",
        "superseded"
      ]
    },
    "members": {
      "minItems": 1,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "ref": {
            "type": "string",
            "pattern": "^req:[a-z0-9][a-z0-9-]*(#[A-Za-z0-9][A-Za-z0-9_.-]*(\\/[A-Za-z0-9][A-Za-z0-9_.-]*)?)?$"
          },
          "decision": {
            "type": "string",
            "enum": [
              "approved",
              "amended",
              "rejected",
              "deferred"
            ]
          }
        },
        "required": [
          "ref"
        ]
      }
    },
    "workPlan": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      }
    },
    "signOffs": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "script",
              "agent",
              "human"
            ]
          },
          "id": {
            "type": "string",
            "minLength": 1
          },
          "actor": {
            "type": "string",
            "minLength": 1
          },
          "at": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:\\d{2}))?$"
          },
          "scope": {
            "type": "string",
            "pattern": "^(reqset:[a-z0-9][a-z0-9-]*|req:[a-z0-9][a-z0-9-]*(#[A-Za-z0-9][A-Za-z0-9_.-]*)?)$"
          },
          "outcome": {
            "type": "string",
            "enum": [
              "approve",
              "amend",
              "reject",
              "defer",
              "cancel"
            ]
          },
          "stage": {
            "type": "string",
            "enum": [
              "draft",
              "proposed",
              "approved",
              "planned",
              "in-progress",
              "delivered",
              "accepted",
              "rejected",
              "cancelled",
              "superseded"
            ]
          },
          "reason": {
            "type": "string",
            "minLength": 1
          },
          "evidence": {
            "type": "string",
            "pattern": "^https:\\/\\/\\S+$"
          }
        },
        "required": [
          "kind",
          "id",
          "at",
          "scope",
          "outcome",
          "evidence"
        ]
      }
    },
    "document": {
      "type": "string",
      "minLength": 1
    },
    "supersededBy": {
      "type": "string",
      "pattern": "^reqset:[a-z0-9][a-z0-9-]*$"
    }
  },
  "required": [
    "id",
    "title",
    "methodology",
    "stage",
    "members"
  ],
  "allOf": [
    {
      "if": {
        "properties": {
          "stage": {
            "const": "superseded"
          }
        },
        "required": [
          "stage"
        ]
      },
      "then": {
        "required": [
          "supersededBy"
        ]
      }
    },
    {
      "if": {
        "properties": {
          "stage": {
            "enum": [
              "planned",
              "in-progress",
              "delivered",
              "accepted"
            ]
          }
        },
        "required": [
          "stage"
        ]
      },
      "then": {
        "required": [
          "workPlan"
        ],
        "properties": {
          "workPlan": {
            "minItems": 1
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "stage": {
            "const": "approved"
          }
        },
        "required": [
          "stage"
        ]
      },
      "then": {
        "required": [
          "signOffs"
        ],
        "properties": {
          "signOffs": {
            "contains": {
              "type": "object",
              "properties": {
                "stage": {
                  "const": "approved"
                },
                "outcome": {
                  "enum": [
                    "approve",
                    "amend"
                  ]
                },
                "kind": {
                  "const": "human"
                }
              },
              "required": [
                "stage",
                "outcome",
                "kind"
              ]
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "stage": {
            "const": "accepted"
          }
        },
        "required": [
          "stage"
        ]
      },
      "then": {
        "required": [
          "signOffs"
        ],
        "properties": {
          "signOffs": {
            "contains": {
              "type": "object",
              "properties": {
                "stage": {
                  "const": "accepted"
                },
                "outcome": {
                  "enum": [
                    "approve"
                  ]
                },
                "kind": {
                  "const": "human"
                }
              },
              "required": [
                "stage",
                "outcome",
                "kind"
              ]
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "stage": {
            "const": "rejected"
          }
        },
        "required": [
          "stage"
        ]
      },
      "then": {
        "required": [
          "signOffs"
        ],
        "properties": {
          "signOffs": {
            "contains": {
              "type": "object",
              "properties": {
                "stage": {
                  "const": "rejected"
                },
                "outcome": {
                  "enum": [
                    "reject"
                  ]
                }
              },
              "required": [
                "stage",
                "outcome"
              ]
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "stage": {
            "const": "cancelled"
          }
        },
        "required": [
          "stage"
        ]
      },
      "then": {
        "required": [
          "signOffs"
        ],
        "properties": {
          "signOffs": {
            "contains": {
              "type": "object",
              "properties": {
                "stage": {
                  "const": "cancelled"
                },
                "outcome": {
                  "enum": [
                    "cancel"
                  ]
                }
              },
              "required": [
                "stage",
                "outcome",
                "reason"
              ]
            }
          }
        }
      }
    }
  ]
}
