{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "urn:orbiplex:schema:package-capability-invocation:v1",
  "title": "Package Capability Invocation v1",
  "x-dia-status": "draft",
  "x-dia-basis": [
    "doc/project/40-proposals/093-package-scoped-private-capabilities.md"
  ],
  "description": "One append-only fact of the host invocation journal (P093 §9, R13). The `started` fact freezes the recovery context: recovery reads it, never the current overlay. Later facts name the same key `(caller, invocation/id)` and the new `event`.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema",
    "schema/v",
    "caller",
    "invocation/id",
    "request/digest",
    "capability/id",
    "activation/generation",
    "issued-at",
    "deadline",
    "protected-until",
    "recovery/context",
    "event",
    "recorded-at"
  ],
  "properties": {
    "schema": {
      "const": "package-capability-invocation.v1"
    },
    "schema/v": {
      "const": 1
    },
    "caller": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "kind",
        "ref"
      ],
      "properties": {
        "kind": {
          "enum": [
            "node",
            "component",
            "binding"
          ]
        },
        "ref": {
          "$ref": "#/$defs/ref"
        }
      }
    },
    "invocation/id": {
      "$ref": "#/$defs/invocation-id"
    },
    "request/digest": {
      "$ref": "#/$defs/digest"
    },
    "capability/id": {
      "$ref": "#/$defs/capability-id"
    },
    "activation/generation": {
      "type": "integer",
      "minimum": 1
    },
    "issued-at": {
      "$ref": "#/$defs/timestamp"
    },
    "deadline": {
      "$ref": "#/$defs/timestamp"
    },
    "protected-until": {
      "$ref": "#/$defs/timestamp"
    },
    "recovery/context": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "package/ref",
        "package/digest",
        "provider",
        "contract/digest",
        "effect/refs",
        "recovery/class"
      ],
      "properties": {
        "package/ref": {
          "$ref": "#/$defs/ref"
        },
        "package/digest": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128
        },
        "provider": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "component/id"
          ],
          "properties": {
            "component/id": {
              "$ref": "#/$defs/ref"
            },
            "flow/ref": {
              "$ref": "#/$defs/ref"
            },
            "flow/digest": {
              "$ref": "#/$defs/digest"
            }
          }
        },
        "contract/digest": {
          "$ref": "#/$defs/digest"
        },
        "effect/refs": {
          "type": "array",
          "maxItems": 32,
          "uniqueItems": true,
          "items": {
            "$ref": "#/$defs/ref"
          }
        },
        "reconciliation/operations": {
          "description": "Frozen read-only recovery operation per effect. Missing historical declarations remain unavailable; the current overlay cannot supply them retroactively.",
          "type": "object",
          "maxProperties": 32,
          "propertyNames": {"$ref": "#/$defs/ref"},
          "additionalProperties": {"$ref": "#/$defs/ref"}
        },
        "recovery/class": {
          "enum": [
            "read-only",
            "ephemeral-revertible",
            "transactional-withheld",
            "compensatable",
            "irreversible-external"
          ]
        }
      }
    },
    "event": {
      "enum": [
        "started",
        "completed",
        "aborted",
        "compensated",
        "unknown"
      ]
    },
    "result/status": {
      "enum": [
        "retained",
        "unavailable"
      ]
    },
    "output/digest": {
      "$ref": "#/$defs/digest"
    },
    "cause": {
      "enum": [
        "no-outcome",
        "output-contract-violation",
        "pending-disposal"
      ]
    },
    "recorded-at": {
      "$ref": "#/$defs/timestamp"
    }
  },
  "allOf": [
    {
      "if": {
        "properties": {
          "event": {
            "const": "completed"
          }
        },
        "required": [
          "event"
        ]
      },
      "then": {
        "required": [
          "result/status"
        ],
        "allOf": [
          {
            "not": {
              "anyOf": [
                {
                  "required": [
                    "cause"
                  ]
                }
              ]
            }
          }
        ]
      },
      "else": {
        "allOf": [
          {
            "not": {
              "anyOf": [
                {
                  "required": [
                    "result/status"
                  ]
                },
                {
                  "required": [
                    "output/digest"
                  ]
                }
              ]
            }
          }
        ]
      }
    },
    {
      "if": {
        "properties": {
          "event": {
            "const": "unknown"
          }
        },
        "required": [
          "event"
        ]
      },
      "then": {
        "required": [
          "cause"
        ]
      },
      "else": {
        "allOf": [
          {
            "not": {
              "anyOf": [
                {
                  "required": [
                    "cause"
                  ]
                }
              ]
            }
          }
        ]
      }
    }
  ],
  "$defs": {
    "capability-id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 512,
      "pattern": "^[a-z0-9][a-z0-9._-]*@(pkg|node-pkg|peer-pkg):did:key:z[1-9A-HJ-NP-Za-km-z]+/[a-z0-9][a-z0-9._-]*$",
      "description": "A package capability identifier (P093 §2); the host parses it with the one grammar."
    },
    "digest": {
      "type": "string",
      "pattern": "^sha256:[A-Za-z0-9_-]{43}$"
    },
    "invocation-id": {
      "type": "string",
      "maxLength": 128,
      "pattern": "^package-invocation:[A-Za-z0-9._-]+$"
    },
    "timestamp": {
      "type": "string",
      "minLength": 20,
      "maxLength": 40,
      "format": "date-time"
    },
    "ref": {
      "type": "string",
      "minLength": 1,
      "maxLength": 256,
      "pattern": "^[^\\s]+$"
    }
  }
}
