{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://grip.foxora.dev/schema/1.0-draft.2/common.schema.json",
  "title": "GRIP common definitions",
  "description": "Shared envelope and value types for GRIP/1.0-draft.2 (§4.2).",
  "$defs": {
    "digest": {
      "type": "string",
      "pattern": "^sha256:[0-9a-f]{64}$",
      "description": "Lowercase hex SHA-256, prefixed. §4.2."
    },
    "keyref": {
      "type": "string",
      "format": "uri",
      "description": "HTTPS origin key reference or DID, including fragment key id.",
      "pattern": "^(https://|did:).+"
    },
    "gripVersion": { "type": "string", "const": "1.0-draft.2" },
    "timestamp": { "type": "integer", "minimum": 0, "description": "Integer seconds since epoch." },
    "crit": {
      "type": "array",
      "items": { "type": "string" },
      "minItems": 1,
      "uniqueItems": true,
      "description": "Slash-delimited extension paths a consumer MUST understand. §4.2, §4.8."
    },
    "sig": {
      "type": "string",
      "pattern": "^[A-Za-z0-9_-]+\\.\\.[A-Za-z0-9_-]+$",
      "description": "Detached JWS, compact serialization, EdDSA, RFC 7797 unencoded payload. Protected header MUST be {\"alg\":\"EdDSA\",\"kid\":<keyref>,\"b64\":false,\"crit\":[\"b64\"]}."
    },
    "budget": {
      "type": "object",
      "description": "Registered axes (§4.5). An absent axis is unmetered. Unknown axes are criticality-bearing by default.",
      "properties": {
        "usd_micro":  { "type": "integer", "minimum": 0 },
        "tokens_in":  { "type": "integer", "minimum": 0 },
        "tokens_out": { "type": "integer", "minimum": 0 },
        "ms":         { "type": "integer", "minimum": 0 }
      },
      "additionalProperties": { "type": "integer", "minimum": 0 },
      "minProperties": 1
    },
    "consequenceClass": {
      "enum": ["observe", "egress", "settle"],
      "description": "§4.4. Severity order settle > egress > observe."
    },
    "verb": {
      "type": "string",
      "pattern": "^(tool|model|agent|skill|stop)\\.[a-z][a-z0-9_]*$",
      "description": "Five registered families. §4.4."
    },
    "allowEntry": {
      "type": "object",
      "required": ["verb", "resource", "class"],
      "properties": {
        "verb": { "$ref": "#/$defs/verb" },
        "resource": {
          "type": "string",
          "minLength": 1,
          "description": "Exact string, or prefix ending in a single trailing '*'. No other wildcard forms in v1. §4.3.2 law 1."
        },
        "class": { "$ref": "#/$defs/consequenceClass" },
        "boundary": { "type": "array", "items": { "type": "string" }, "uniqueItems": true }
      },
      "additionalProperties": false
    },
    "envelope": {
      "type": "object",
      "required": ["grip", "type", "id", "iss", "iat", "sig"],
      "properties": {
        "grip": { "$ref": "#/$defs/gripVersion" },
        "type": { "enum": ["mandate", "grant", "receipt", "stop", "settlement", "context"] },
        "id":   { "$ref": "#/$defs/digest" },
        "parents": { "type": "array", "items": { "$ref": "#/$defs/digest" }, "minItems": 1 },
        "iss":  { "$ref": "#/$defs/keyref" },
        "iat":  { "$ref": "#/$defs/timestamp" },
        "exp":  { "$ref": "#/$defs/timestamp" },
        "crit": { "$ref": "#/$defs/crit" },
        "sig":  { "$ref": "#/$defs/sig" }
      }
    }
  }
}
