{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://oags.dev/schema/oags-v0.2.schema.json",
  "title": "OAGS v0.2 scene payload",
  "description": "Open Agent Graph Standard v0.2. Additive superset of v0.1: every v0.1 scene is a valid v0.2 scene and vice-versa (additionalProperties stays true; closed enums scope/polarity are NOT widened). v0.2 names the optional verdict/bitemporal/temperature/federation fields that building JsonTube v2 required. See CORE.md v0.2 deltas.",
  "type": "object",
  "required": [
    "oags",
    "graph_id",
    "entry",
    "blocks",
    "edges",
    "declared_losses"
  ],
  "additionalProperties": true,
  "properties": {
    "oags": {
      "type": "string",
      "description": "version, e.g. 0.1; self-identifies the payload"
    },
    "graph_id": {
      "type": "string",
      "description": "opaque stable id of the whole graph; MUST NOT be dereferenced by consumers"
    },
    "site": {
      "type": "string"
    },
    "schema": {
      "type": [
        "string",
        "null"
      ],
      "description": "URL to the OAGS schema/profile; a web surface MUST publish non-null"
    },
    "conforms_to": {
      "type": [
        "string",
        "array"
      ]
    },
    "as_of": {
      "type": "string",
      "description": "timestamp of the graph state this slice reflects (distinct from served_at)"
    },
    "graph_version": {
      "type": "string"
    },
    "entry": {
      "type": "object",
      "required": [
        "block_id",
        "depth"
      ],
      "additionalProperties": true,
      "properties": {
        "block_id": {
          "type": "string"
        },
        "depth": {
          "type": "integer",
          "minimum": 0
        },
        "selector_profile": {
          "type": "string",
          "description": "v0.2 \u00a719: registered values include agent_home, graph_bfs (open \u2014 unknown profiles preserved)"
        }
      }
    },
    "blocks": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "block_id"
        ],
        "additionalProperties": true,
        "properties": {
          "block_id": {
            "type": "string",
            "pattern": "^[^@].*"
          },
          "block_class": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "attachment": {
            "$ref": "#/$defs/attachment"
          },
          "x_status": {
            "type": "string",
            "description": "v0.2 \u00a717: advisory projection status (visible_unverified|verified|contested|quarantined); never stored"
          },
          "x_temperature": {
            "type": "number",
            "description": "v0.2 \u00a717.1: advisory; MUST carry x_temperature_components in a temperature-ordered view"
          },
          "x_temperature_components": {
            "type": "object",
            "additionalProperties": true
          }
        }
      }
    },
    "edges": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "from",
          "to"
        ],
        "additionalProperties": true,
        "properties": {
          "from": {
            "type": "string"
          },
          "to": {
            "type": "string"
          },
          "op": {
            "type": "string"
          },
          "lens": {
            "type": "string"
          },
          "polarity": {
            "enum": [
              "+",
              "-",
              "0"
            ]
          },
          "id": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "attachment": {
            "$ref": "#/$defs/attachment"
          },
          "issuer_did": {
            "type": "string",
            "description": "v0.2 \u00a716: DID of the verdict issuer; trust attaches here, not to subject"
          },
          "agent_did": {
            "type": "string"
          },
          "sig": {
            "type": "object",
            "additionalProperties": true,
            "description": "v0.2 \u00a716: per-edge JWS over the canon edge (same profile as top-level sig)"
          },
          "valid_from": {
            "type": "string",
            "format": "date-time",
            "description": "v0.2 \u00a716.1: world-time start"
          },
          "valid_to": {
            "type": [
              "string",
              "null"
            ],
            "description": "v0.2 \u00a716.1: world-time end; null = still valid"
          },
          "supersedes": {
            "type": "string",
            "description": "v0.2 \u00a716.1: prior edge id/cid this edge retracts (insert-only)"
          },
          "beta_class": {
            "enum": [
              "chatter",
              "working",
              "scar",
              "support"
            ],
            "description": "v0.2 \u00a717.1: decay half-life class"
          },
          "cid": {
            "type": "string",
            "description": "v0.2 \u00a720: content-addressed id (hash of canon-JCS minus sig)"
          }
        }
      }
    },
    "lenses": {
      "type": "object",
      "description": "lens_id -> human gloss; the id is the machine token, the gloss is NOT machine-actionable",
      "additionalProperties": {
        "type": "string"
      }
    },
    "provenance": {
      "type": "object",
      "additionalProperties": true,
      "description": "flat PROV-O mini-subset, or {claim, document} split for off-origin travel"
    },
    "declared_losses": {
      "type": "array",
      "description": "the confession surface; [] = signable completeness claim within entry.depth",
      "items": {
        "type": "object",
        "required": [
          "scope"
        ],
        "additionalProperties": true,
        "properties": {
          "scope": {
            "enum": [
              "depth_limited",
              "truncated",
              "hidden_edges",
              "omitted_nodes",
              "sampled"
            ],
            "description": "CLOSED enum: what shape of thing is missing"
          },
          "reason": {
            "type": "string",
            "description": "OPEN enum; base policy/rights/rate_limit/timeout/stale/expiry/redacted_by_policy/compact_profile/encoding, or x_*; required only when scope does not self-explain. Unknown reason MUST be surfaced, not dropped."
          },
          "where": {
            "type": "string",
            "description": "a block_id/edge id, or a reserved region: @graph @schema @blocks @edges"
          },
          "count": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 0
              },
              {
                "const": "unknown"
              }
            ]
          },
          "recoverable": {
            "enum": [
              true,
              false,
              "unknown"
            ],
            "description": "true=follow expand_via, false=gone-do-not-retry, unknown; absent != false"
          },
          "expand_via": {
            "anyOf": [
              {
                "type": "object",
                "additionalProperties": true,
                "properties": {
                  "rel": {
                    "type": "string"
                  },
                  "from": {
                    "type": "string"
                  },
                  "depth": {
                    "type": "integer"
                  }
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "note": {
            "type": "string",
            "description": "human gloss; agents MUST NOT derive behavior from it"
          }
        }
      }
    },
    "negative_space": {
      "type": "array",
      "description": "absence by design; structured objects only (no bare strings); [] is NOT a completeness claim",
      "items": {
        "type": "object",
        "required": [
          "kind",
          "claim"
        ],
        "additionalProperties": true,
        "properties": {
          "kind": {
            "type": "string",
            "description": "e.g. by_design | asserted_complete"
          },
          "claim": {
            "type": "string"
          },
          "where": {
            "type": "string"
          },
          "machine_readable": {
            "type": "boolean"
          }
        }
      }
    },
    "expand": {
      "anyOf": [
        {
          "type": "string",
          "description": "RFC 6570 URI template; reserved vars from,depth,view,loss,cursor,limit"
        },
        {
          "type": "object",
          "required": [
            "template"
          ],
          "additionalProperties": true,
          "properties": {
            "template": {
              "type": "string"
            },
            "params": {
              "type": "array"
            },
            "rels": {
              "type": "object"
            }
          }
        }
      ]
    },
    "canon": {
      "anyOf": [
        {
          "type": "string",
          "description": "profile id, e.g. jcs-v1 (default)"
        },
        {
          "type": "object",
          "required": [
            "alg"
          ],
          "additionalProperties": true,
          "properties": {
            "alg": {
              "type": "string"
            },
            "scope": {
              "type": "string"
            },
            "sig_excluded": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        }
      ]
    },
    "sig": {
      "type": "object",
      "additionalProperties": true,
      "description": "detached/embedded JWS (RFC 7515) over the canon form; proves the claim was MADE, not that it is true"
    },
    "warnings": {
      "type": "array",
      "description": "conformance/build-state notes; NEVER put build-state in declared_losses",
      "items": {
        "type": "object",
        "additionalProperties": true
      }
    },
    "@context": {
      "type": [
        "string",
        "object",
        "array"
      ]
    },
    "x_trust_root": {
      "type": [
        "string",
        "array"
      ],
      "description": "v0.2 \u00a718: the issuer-DID trust_root the scene's status was computed for (echoed when a default was used)"
    }
  },
  "$defs": {
    "attachment": {
      "type": "object",
      "description": "reserved opaque latent/embedding payload ref; shape tightens in v0.2",
      "additionalProperties": true,
      "properties": {
        "model": {
          "type": "string"
        },
        "projection": {
          "type": "string"
        },
        "dims": {
          "type": "integer"
        },
        "codec": {
          "type": "string"
        },
        "version": {
          "type": "string"
        }
      }
    }
  },
  "allOf": [
    {
      "description": "if sig is present, canon MUST be present",
      "if": {
        "required": [
          "sig"
        ]
      },
      "then": {
        "required": [
          "canon"
        ]
      }
    }
  ]
}
