{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openeik.org/schemas/0.3/envelope/answer.schema.json",
  "$comment": "OpenEik 0.2: folded by tools/fold-schemas.mjs from the proposal envelope, which 0.2 makes a rule (decision D5). Written by hand from the text, not generated.",
  "title": "Command answer",
  "description": "What a command processor answers a batch (Part V, 9), with what Part XVII adds: the mode, the operation and the target it met, and every refusal with its code, a JSON pointer into the command, a message for people and a fix where one is known. A processor may add members of its own (the reference processor's joins and the like): a reader ignores what it does not know.",
  "type": "object",
  "required": [
    "ok",
    "dryRun",
    "mode",
    "results"
  ],
  "properties": {
    "ok": {
      "description": "Whether the batch was accepted: every command and the whole model checked.",
      "type": "boolean"
    },
    "dryRun": {
      "description": "Whether nothing was committed to the target: true for the modes dryRun and propose.",
      "type": "boolean"
    },
    "mode": {
      "enum": [
        "apply",
        "dryRun",
        "propose"
      ]
    },
    "operation": {
      "description": "The operation of an envelope (Part XVII, 3): its id; the digest of the envelope; whether the processor records operations, so that one sent again is applied once; and repeated, true where this answer is the recorded one, given again.",
      "type": "object",
      "required": [
        "id",
        "kept"
      ],
      "properties": {
        "id": {
          "type": "string"
        },
        "digest": {
          "type": "string",
          "pattern": "^[0-9a-f]{64}$"
        },
        "kept": {
          "type": "boolean"
        },
        "repeated": {
          "const": true
        }
      },
      "x-eik-closed": true
    },
    "target": {
      "description": "The target an envelope names and what the processor met (Part XVII, 5): its ref and base, the version the commands were applied to or tried on (null where the processor keeps none), whether the two were compared, and whether the ref had moved since the base.",
      "type": "object",
      "required": [
        "ref",
        "base",
        "version",
        "compared"
      ],
      "properties": {
        "ref": {
          "type": "string"
        },
        "base": {
          "$ref": "#/$defs/version"
        },
        "version": {
          "$ref": "#/$defs/version"
        },
        "compared": {
          "type": "boolean"
        },
        "moved": {
          "type": "boolean"
        }
      },
      "x-eik-closed": true
    },
    "sequence": {
      "description": "The host's change sequence after the batch (Part V, 9).",
      "type": [
        "integer",
        "string"
      ]
    },
    "affected": {
      "description": "The ids of every record the batch changed, those changed as a consequence included (Part V, 9).",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "verify": {
      "description": "How to check the result: a filter that selects exactly the affected elements (Part VII, 4), and the views and snapshots to look at (Part V, 9).",
      "type": "object"
    },
    "warnings": {
      "description": "What the writer should know that did not refuse the batch.",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "failed": {
      "description": "Of a refused batch, how many commands were refused.",
      "type": "integer",
      "minimum": 0
    },
    "results": {
      "description": "Each command's answer, in order (Part V, 9). A refused command's has its refusals. A refused batch that is not a dry run answers up to the first refused command (Part V, 7.1); a dry run answers for every command (Part V, 7.3).",
      "type": "array",
      "items": {
        "$ref": "#/$defs/result"
      }
    },
    "errors": {
      "description": "Of a refused batch, in words, what no command caused: the errors the model had before the batch.",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "refusals": {
      "description": "The refusals that are no one command's: the envelope's (Part XVII, 2 to 8), and the errors the model had before the batch, each with the validator's code.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/refusal"
      }
    },
    "proposal": {
      "description": "Of an accepted batch in the mode propose, the proposal made: a proposal file of Part VI, 8.7, which the application keeps in its folder, or what a host gives for its own proposal (its id and where it is).",
      "type": "object"
    }
  },
  "$defs": {
    "version": {
      "anyOf": [
        {
          "type": "string",
          "pattern": "^([0-9a-f]{40}|[0-9a-f]{64})$"
        },
        {
          "type": "null"
        }
      ]
    },
    "result": {
      "type": "object",
      "required": [
        "index",
        "ok",
        "kind"
      ],
      "properties": {
        "index": {
          "type": "integer",
          "minimum": 0
        },
        "ok": {
          "type": "boolean"
        },
        "kind": {
          "type": "string"
        },
        "commandId": {
          "type": "string"
        },
        "error": {
          "description": "The refusal in words, naming the command: \"Command <index> (<kind> <id>): ...\" (Part V, 6).",
          "type": "string"
        },
        "refusals": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/$defs/refusal"
          }
        },
        "result": {
          "description": "Of an accepted command, the record written, or for a delete {deleted, removedDependents?} (Part V, 9)."
        }
      }
    },
    "refusal": {
      "description": "One refusal (Part XVII, 10.2).",
      "type": "object",
      "required": [
        "code",
        "rule",
        "pointer",
        "message"
      ],
      "properties": {
        "code": {
          "description": "A code of Part XVII, 10.4, or of the validator's (Part XVII, 10.5); a processor's own under its prefix (<prefix>:<code>).",
          "type": "string",
          "pattern": "^([a-z][a-z0-9]*(-[a-z0-9]+)*:)?[a-z][a-z0-9]*(-[a-z0-9]+)*$"
        },
        "rule": {
          "description": "The rule it comes from: a Part's number and the section and rule, as V.3.1 or II.6.1.5.",
          "type": "string",
          "minLength": 1
        },
        "pointer": {
          "description": "A JSON pointer (RFC 6901) into the command, of a command's refusal, or into the envelope, of the envelope's: the member that is wrong; \"\" for the whole.",
          "type": "string",
          "pattern": "^(/[^/]*)*$"
        },
        "message": {
          "description": "What is wrong, for people, in the terms of the domain (Part V, 6).",
          "type": "string",
          "minLength": 1
        },
        "fix": {
          "$ref": "#/$defs/fix"
        },
        "data": {
          "description": "Values for a program beside the message: a conflict's expected and current revisions, the records that use what a delete would remove.",
          "type": "object"
        },
        "record": {
          "description": "Where in the model the refusal is: a record by its list and id, and a JSON pointer in it.",
          "type": "object",
          "required": [
            "list",
            "id",
            "pointer"
          ],
          "properties": {
            "list": {
              "type": "string"
            },
            "id": {
              "type": "string"
            },
            "pointer": {
              "type": "string",
              "pattern": "^(/[^/]*)*$"
            }
          },
          "x-eik-closed": true
        }
      },
      "x-eik-closed": true
    },
    "fix": {
      "description": "What would make the command pass, where it is known (Part XVII, 10.3): a JSON Patch (RFC 6902) of the command, a command to send in its place, or the records to read again and make the command from. It changes nothing by itself, and it never writes a precondition the writer did not read.",
      "oneOf": [
        {
          "type": "object",
          "required": [
            "patch"
          ],
          "properties": {
            "patch": {
              "type": "array",
              "minItems": 1,
              "items": {
                "type": "object",
                "required": [
                  "op",
                  "path"
                ],
                "properties": {
                  "op": {
                    "enum": [
                      "add",
                      "remove",
                      "replace",
                      "move",
                      "copy",
                      "test"
                    ]
                  },
                  "path": {
                    "type": "string",
                    "pattern": "^(/[^/]*)*$"
                  },
                  "from": {
                    "type": "string",
                    "pattern": "^(/[^/]*)*$"
                  },
                  "value": {}
                }
              }
            }
          },
          "additionalProperties": false
        },
        {
          "type": "object",
          "required": [
            "command"
          ],
          "properties": {
            "command": {
              "type": "object",
              "required": [
                "kind"
              ]
            }
          },
          "additionalProperties": false
        },
        {
          "type": "object",
          "required": [
            "read"
          ],
          "properties": {
            "read": {
              "type": "array",
              "minItems": 1,
              "items": {
                "type": "object",
                "required": [
                  "list",
                  "id"
                ],
                "properties": {
                  "list": {
                    "type": "string"
                  },
                  "id": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "additionalProperties": false
        }
      ]
    }
  }
}
