{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "grift.agents.feed-0.1.schema.json",
  "title": "grift.agents.feed 0.1",
  "description": "Real GRIFT agents for game engines: identities, plans, decisions, activity, business records and on-chain proofs, with the source of every fact. Read-only. docs/CONTRACT.md explains each field; the GRIFT Roblox SDK's src/Contract.luau is the reference validator (it also checks ordering, place references and size limits that a schema cannot express).",
  "type": "object",
  "required": ["contract", "version", "generatedAt", "provenance", "clock", "places", "agents", "businesses", "chain", "honesty"],
  "properties": {
    "contract": { "const": "grift.agents.feed" },
    "version": { "type": "string", "pattern": "^0\\.1\\.\\d+$" },
    "generatedAt": { "$ref": "#/$defs/time" },
    "provenance": { "$ref": "#/$defs/provenance" },
    "clock": { "$ref": "#/$defs/clock" },
    "places": { "type": "object", "additionalProperties": { "$ref": "#/$defs/place" }, "maxProperties": 128 },
    "agents": { "type": "array", "items": { "$ref": "#/$defs/agent" }, "maxItems": 64 },
    "businesses": { "type": "array", "items": { "$ref": "#/$defs/business" }, "maxItems": 16 },
    "chain": {
      "type": "object",
      "required": ["id", "name", "explorer"],
      "properties": {
        "id": { "type": "integer" },
        "name": { "type": "string" },
        "explorer": { "type": "string", "format": "uri" },
        "contracts": { "type": "object", "additionalProperties": { "type": ["string", "null"] } },
        "posting": { "type": ["object", "null"] }
      }
    },
    "honesty": { "type": "array", "items": { "type": "string" }, "minItems": 1 }
  },
  "$defs": {
    "time": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$" },
    "sourceId": { "type": ["string", "null"], "maxLength": 200 },
    "address": { "type": ["string", "null"], "pattern": "^0x[0-9a-fA-F]{40}$" },
    "provenance": {
      "type": "object",
      "required": ["mode", "label", "origin", "sources"],
      "properties": {
        "mode": { "enum": ["live", "cached", "recorded"] },
        "label": { "type": "string", "maxLength": 400 },
        "origin": { "type": "string", "format": "uri" },
        "gateway": { "type": ["object", "null"], "properties": { "name": { "type": "string" }, "version": { "type": "string" } } },
        "lastGoodAt": { "anyOf": [{ "$ref": "#/$defs/time" }, { "type": "null" }] },
        "recording": {
          "type": ["object", "null"],
          "required": ["capturedAt", "planDay", "note"],
          "properties": {
            "capturedAt": { "$ref": "#/$defs/time" },
            "planDay": { "type": "integer" },
            "agents": { "type": "integer" },
            "answers": { "type": ["integer", "null"] },
            "chainReads": { "type": "integer" },
            "chainReadWindow": { "type": "string" },
            "note": { "type": "string" }
          }
        },
        "sources": {
          "type": "object",
          "maxProperties": 600,
          "additionalProperties": {
            "type": "object",
            "required": ["route", "url", "status"],
            "properties": {
              "route": { "type": "string" },
              "url": { "type": "string", "format": "uri" },
              "fetchedAt": { "anyOf": [{ "$ref": "#/$defs/time" }, { "type": "null" }] },
              "sha256": { "type": ["string", "null"], "pattern": "^[0-9a-f]{64}$" },
              "status": { "enum": ["ok", "stale", "down", "recorded"] }
            }
          }
        }
      },
      "if": { "properties": { "mode": { "const": "recorded" } } },
      "then": { "required": ["recording"], "properties": { "recording": { "type": "object" } } }
    },
    "clock": {
      "type": "object",
      "required": ["dayMs", "hourMs", "planDay", "shiftMs", "validFrom", "validUntil"],
      "properties": {
        "dayMs": { "const": 1800000 },
        "hourMs": { "const": 75000 },
        "planDay": { "type": "integer" },
        "shiftMs": { "type": "number" },
        "validFrom": { "$ref": "#/$defs/time" },
        "validUntil": { "$ref": "#/$defs/time" }
      }
    },
    "place": {
      "type": "object",
      "required": ["key", "name", "kind"],
      "properties": {
        "key": { "type": "string" },
        "name": { "type": "string", "maxLength": 200 },
        "kind": { "enum": ["venue", "work", "home", "stall", "other"] },
        "business": { "type": ["string", "null"] },
        "note": { "type": ["string", "null"] },
        "sv": { "type": ["object", "null"], "properties": { "door": { "type": "array", "items": { "type": "number" }, "minItems": 2, "maxItems": 2 } } }
      }
    },
    "verification": {
      "type": "object",
      "required": ["status", "steps", "basis"],
      "properties": {
        "status": { "enum": ["verified", "failed", "unchecked"] },
        "steps": { "type": "object", "additionalProperties": { "type": ["boolean", "null"] } },
        "basis": { "enum": ["live", "recorded"] },
        "checkedAt": { "anyOf": [{ "$ref": "#/$defs/time" }, { "type": "null" }] },
        "chainReadAt": { "anyOf": [{ "$ref": "#/$defs/time" }, { "type": "null" }] },
        "note": { "type": ["string", "null"] }
      }
    },
    "erc8004": {
      "type": "object",
      "required": ["chainId", "registry", "agentId", "explorer", "verification"],
      "properties": {
        "chainId": { "type": "integer" },
        "registry": { "$ref": "#/$defs/address" },
        "agentId": { "type": "integer" },
        "owner": { "$ref": "#/$defs/address" },
        "agentWallet": { "$ref": "#/$defs/address" },
        "tokenUri": { "type": ["string", "null"] },
        "card": { "type": ["string", "null"] },
        "line": { "type": ["string", "null"] },
        "registerTx": { "type": ["string", "null"] },
        "explorer": { "type": "string", "format": "uri" },
        "verification": { "$ref": "#/$defs/verification" },
        "source": { "$ref": "#/$defs/sourceId" }
      }
    },
    "identity": {
      "type": "object",
      "properties": {
        "erc8004": { "anyOf": [{ "$ref": "#/$defs/erc8004" }, { "type": "null" }] },
        "key": { "type": ["object", "null"], "properties": { "kind": { "type": "string" }, "address": { "type": "string" }, "note": { "type": "string" } } },
        "none": { "type": ["string", "null"] },
        "why": { "type": ["string", "null"] }
      }
    },
    "record": {
      "type": "object",
      "required": ["kind"],
      "properties": {
        "kind": { "type": "string", "maxLength": 64 },
        "absent": { "type": ["boolean", "null"] },
        "why": { "type": ["string", "null"] },
        "label": { "type": ["string", "null"] },
        "epoch": { "type": ["integer", "null"] },
        "schema": { "type": ["string", "null"] },
        "chainId": { "type": ["integer", "null"] },
        "contract": { "$ref": "#/$defs/address" },
        "root": { "type": ["string", "null"], "pattern": "^0x[0-9a-fA-F]{64}$" },
        "tx": { "type": ["string", "null"], "pattern": "^0x[0-9a-fA-F]{64}$" },
        "block": { "type": ["string", "null"] },
        "data": { "type": ["object", "null"] },
        "links": { "type": ["object", "null"] },
        "verification": { "$ref": "#/$defs/verification" },
        "source": { "$ref": "#/$defs/sourceId" }
      },
      "if": { "not": { "properties": { "absent": { "const": true } }, "required": ["absent"] } },
      "then": { "required": ["contract", "root", "verification"] }
    },
    "segment": {
      "type": "object",
      "required": ["t0", "t1", "kind"],
      "properties": {
        "t0": { "type": "number" },
        "t1": { "type": "number" },
        "h0": { "type": "number" },
        "h1": { "type": "number" },
        "kind": { "enum": ["home", "walk", "at", "stroll"] },
        "place": { "type": ["string", "null"] },
        "from": { "type": ["string", "null"] },
        "toward": { "type": ["string", "null"] },
        "role": { "type": ["string", "null"] },
        "slot": { "type": ["string", "null"] },
        "decision": { "enum": ["plan", "rota", null] },
        "sv": {
          "type": ["object", "null"],
          "properties": {
            "at": { "type": "array", "items": { "type": "number" }, "minItems": 2, "maxItems": 2 },
            "path": { "type": "array", "minItems": 2, "maxItems": 4000, "items": { "type": "array", "items": { "type": "number" }, "minItems": 3, "maxItems": 3 } }
          }
        }
      }
    },
    "slot": {
      "type": "object",
      "required": ["choice", "decided"],
      "properties": {
        "choice": { "type": "string" },
        "place": { "type": ["string", "null"] },
        "why": { "type": ["string", "null"] },
        "spend": { "type": ["number", "null"] },
        "decided": { "type": "boolean" }
      }
    },
    "agent": {
      "type": "object",
      "required": ["id", "name", "kind", "identity", "records", "schedule"],
      "properties": {
        "id": { "type": "integer" },
        "name": { "type": "string", "maxLength": 200 },
        "kind": { "enum": ["native", "outside", "team", "deployed"] },
        "kindLabel": { "type": "string" },
        "district": { "type": ["string", "null"] },
        "job": { "type": ["object", "null"] },
        "crew": {},
        "selection": { "type": ["string", "null"] },
        "identity": { "$ref": "#/$defs/identity" },
        "runsOn": { "type": ["object", "null"], "properties": { "model": { "type": ["string", "null"] }, "note": { "type": "string" } } },
        "cash": { "type": ["object", "null"], "properties": { "amount": { "type": "number" }, "unit": { "type": "string" } } },
        "plan": {
          "type": ["object", "null"],
          "properties": {
            "forDay": { "type": ["integer", "null"] },
            "current": { "type": ["boolean", "null"] },
            "slots": { "type": "object", "properties": { "aft": { "$ref": "#/$defs/slot" }, "night": { "$ref": "#/$defs/slot" } } },
            "source": { "$ref": "#/$defs/sourceId" }
          }
        },
        "decision": {
          "type": ["object", "null"],
          "properties": {
            "by": { "type": ["string", "null"] },
            "byLabel": { "type": "string" },
            "note": { "type": ["string", "null"] },
            "outcome": { "type": ["string", "null"] },
            "model": { "type": ["string", "null"] },
            "costMicros": { "type": ["number", "null"] },
            "at": { "anyOf": [{ "$ref": "#/$defs/time" }, { "type": "null" }] },
            "source": { "$ref": "#/$defs/sourceId" }
          }
        },
        "memory": { "type": ["object", "null"], "properties": { "notes": { "type": "array", "items": { "type": "string" } }, "what": { "type": "string" } } },
        "records": { "type": "array", "items": { "$ref": "#/$defs/record" }, "maxItems": 32 },
        "schedule": { "type": "array", "items": { "$ref": "#/$defs/segment" }, "maxItems": 600 }
      }
    },
    "ledgerRow": {
      "type": "object",
      "properties": {
        "at": { "anyOf": [{ "$ref": "#/$defs/time" }, { "type": "null" }] },
        "actor": { "type": ["string", "null"] },
        "kind": { "type": ["string", "null"] },
        "amount": { "type": ["number", "null"] },
        "ref": { "type": ["string", "null"] },
        "line": { "type": ["string", "null"] },
        "fact": { "type": ["string", "null"] },
        "decision": { "type": "boolean" }
      }
    },
    "business": {
      "type": "object",
      "required": ["id", "name", "place", "identity", "decisions", "activity", "records"],
      "properties": {
        "id": { "type": "string" },
        "name": { "type": "string" },
        "place": { "type": "string" },
        "identity": { "$ref": "#/$defs/identity" },
        "status": { "type": ["object", "null"] },
        "decisions": { "type": "array", "items": { "$ref": "#/$defs/ledgerRow" } },
        "activity": { "type": "array", "items": { "$ref": "#/$defs/ledgerRow" }, "maxItems": 400 },
        "activitySource": { "$ref": "#/$defs/sourceId" },
        "records": { "type": "array", "items": { "$ref": "#/$defs/record" } },
        "notes": { "type": "array", "items": { "type": "string" } }
      }
    }
  }
}
