{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "urn:orbiplex:schema:sensorium-directive-result:v1",
  "title": "Sensorium Directive Result v1",
  "description": "Response envelope returned by sensorium-core to the consumer that submitted a sensorium-directive.v1. Always carries outcome/id (audit record reference) and observation/ids (empty when the directive produced no world-fact observations).",
  "type": "object",
  "additionalProperties": true,
  "x-dia-workflow": "project",
  "x-dia-status": "draft",
  "x-dia-basis": [
    "doc/project/40-proposals/045-sensorium-local-enaction-stratum.md"
  ],
  "required": [
    "schema",
    "schema/v",
    "directive/id",
    "status",
    "outcome/id",
    "observation/ids"
  ],
  "properties": {
    "schema": {
      "type": "string",
      "const": "sensorium-directive-result.v1",
      "description": "Schema tag for the v1 Sensorium contract."
    },
    "schema/v": {
      "const": 1,
      "description": "Schema version."
    },
    "directive/id": {
      "type": "string",
      "description": "Echo of the directive/id from the originating sensorium-directive.v1."
    },
    "correlation/id": {
      "type": "string",
      "description": "Optional echo of the correlation/id from the directive, when present, so callers can confirm the response belongs to the expected workflow/thread without fetching the outcome record."
    },
    "status": {
      "type": "string",
      "enum": [
        "admitted",
        "completed",
        "failed",
        "timed_out",
        "rejected"
      ],
      "description": "Final status for sync mode; initial status for async mode (typically admitted). rejected indicates the directive was refused at admission (policy, allowlist, or schema validation); in that case outcome/id is present and observation/ids is empty."
    },
    "result": {
      "description": "Typed per action_id. Shape defined by the allowlist entry's result_schema. Absent or null for rejected responses and admitted/async responses.",
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": true
        },
        {
          "type": "null"
        }
      ]
    },
    "outcome/id": {
      "type": "string",
      "description": "Identifier of the sensorium-directive-outcome.v1 audit record. Always present. Outcome records are audit-only and are NOT published to the local Agora bus; they are reachable only through host-owned audit capabilities."
    },
    "observation/ids": {
      "type": "array",
      "description": "List of linked sensorium-observation.v1 ids. Empty list means the directive produced no world-fact observations or has not completed yet in async mode. The outcome record is authoritative for the full list.",
      "items": {
        "type": "string"
      },
      "uniqueItems": true
    },
    "artifacts": {
      "type": "array",
      "description": "References to artifacts produced by the directive (e.g. stdout, stderr, generated files) using the minimal artifact-lane contract from proposal 045.",
      "items": {
        "$ref": "#/$defs/artifactRef"
      }
    },
    "diagnostics": {
      "type": "array",
      "description": "Optional diagnostic entries from the connector (warnings, soft errors). Not a replacement for the outcome record; these are hints to the caller.",
      "items": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "level": {
            "type": "string",
            "enum": [
              "info",
              "warn",
              "error"
            ]
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "$defs": {
    "artifactRef": {
      "type": "object",
      "additionalProperties": true,
      "required": [
        "artifact/id",
        "role"
      ],
      "description": "Minimal artifact-lane reference. The artifact itself is stored outside this envelope and is addressed by a content or host-owned blob reference.",
      "properties": {
        "artifact/id": {
          "type": "string",
          "pattern": "^(sha256:[A-Za-z0-9_-]+|memarium-blob:[A-Za-z0-9._:/-]+)$",
          "description": "Content-addressed or host-owned artifact identifier. v1 accepts sha256:<base64url-or-hex> and memarium-blob:<opaque-id> forms."
        },
        "role": {
          "type": "string",
          "enum": [
            "stdout",
            "stderr",
            "produced-file",
            "raw-capture"
          ],
          "description": "Role of the artifact in the Sensorium exchange."
        },
        "media_type": {
          "type": "string",
          "description": "Optional media type of the referenced artifact."
        },
        "size_bytes": {
          "type": "integer",
          "minimum": 0,
          "description": "Optional artifact size in bytes."
        }
      }
    }
  },
  "allOf": [
    {
      "if": {
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "enum": [
              "rejected",
              "admitted"
            ]
          }
        }
      },
      "then": {
        "properties": {
          "result": {
            "type": "null"
          }
        }
      }
    }
  ]
}
