{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://chiefos.bizgrowthai.com/schemas/spec.schema.json",
  "title": "ChiefOS Spec",
  "description": "Vendor-neutral definition of an AI Chief of Staff. Declare once; compile to any harness (Hermes, Claude Code, more); run on any model. Memory stays where the client already lives — this spec never captures or stores client data, only the operating definition.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "specVersion", "meta", "persona", "voice", "memoryPolicy",
    "priorities", "rituals", "integrations", "routing", "guardrails", "tools"
  ],
  "properties": {
    "specVersion": { "const": "1.0", "description": "Schema version this spec conforms to." },

    "meta": {
      "type": "object",
      "additionalProperties": false,
      "required": ["name", "owner", "timezone"],
      "properties": {
        "name":        { "type": "string", "description": "Short product name, e.g. \"Ellis\"." },
        "owner":       { "type": "string", "description": "Who the CoS serves / who commissioned it." },
        "timezone":    { "type": "string", "description": "IANA timezone for all rituals, e.g. America/Phoenix." },
        "harness":     { "type": "string", "description": "Current compile target (hermes, claude-code, ...). Optional — the spec is harness-agnostic." },
        "llm":         { "type": "string", "description": "Current model preference (client's own key). Optional — the spec is LLM-agnostic." },
        "version":     { "type": "string", "description": "Spec document version for change tracking." },
        "updatedAt":   { "type": "string", "format": "date", "description": "Last edited date (ISO)." }
      }
    },

    "persona": {
      "type": "object",
      "description": "The operating frame: who this agent is and who it serves. Deployment config for one CoS — not a portable identity or cross-system personality layer.",
      "additionalProperties": false,
      "required": ["name", "role", "serves", "principles"],
      "properties": {
        "name":       { "type": "string" },
        "role":       { "type": "string", "description": "One-line role, e.g. \"Chief of Staff for a fund manager\"." },
        "serves":     { "type": "string", "description": "The human/business it reports to." },
        "principles": { "type": "array", "items": { "type": "string" }, "description": "Operating principles (e.g. 'push back on rabbit holes')." }
      }
    },

    "voice": {
      "type": "object",
      "additionalProperties": false,
      "required": ["tone", "length", "rules"],
      "properties": {
        "tone":   { "type": "string", "description": "e.g. 'direct, warm, professional'." },
        "length": { "type": "string", "enum": ["terse", "brief", "moderate", "detailed"] },
        "rules":  { "type": "array", "items": { "type": "string" }, "description": "Formatting/writing rules, e.g. 'bullet lists over paragraphs', 'no emojis in email'." }
      }
    },

    "memoryPolicy": {
      "type": "object",
      "description": "WHERE durable knowledge lives. ChiefOS never provides or locks a memory store — the client's memory stays in their harness-native or chosen third-party store.",
      "additionalProperties": false,
      "required": ["store", "durable"],
      "properties": {
        "store":   { "type": "string", "enum": ["harness-native", "third-party"], "description": "Declared location only." },
        "provider": { "type": "string", "description": "Optional: named third-party store when store=third-party." },
        "durable": { "type": "array", "items": { "type": "string" }, "description": "What the CoS should treat as durable facts (business facts, people, conventions) — content seeds, not an identity layer." }
      }
    },

    "priorities": {
      "type": "object",
      "additionalProperties": false,
      "required": ["top"],
      "properties": {
        "top":       { "type": "array", "items": { "type": "string" }, "description": "Ranked priorities — what matters more than noise." },
        "definitelyNot": { "type": "array", "items": { "type": "string" }, "description": "Explicit non-priorities / rabbit holes to decline." }
      }
    },

    "rituals": {
      "type": "array",
      "description": "Recurring work the CoS runs on schedule.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": ["id", "name", "kind", "schedule", "actions"],
        "properties": {
          "id":       { "type": "string" },
          "name":     { "type": "string", "description": "e.g. 'Morning briefing'." },
          "kind":     { "type": "string", "enum": ["am-check", "pm-wrap", "daily", "weekly", "monthly", "trigger"] },
          "schedule": {
            "type": "object",
            "additionalProperties": false,
            "required": ["cron"],
            "properties": {
              "cron": { "type": "string", "description": "Cron expression in meta.timezone." },
              "tz":   { "type": "string" }
            }
          },
          "actions": { "type": "array", "items": { "type": "string" }, "description": "What it does: pull, draft, summarize, remind, post." },
          "deliverTo": { "type": "array", "items": { "type": "string" }, "description": "Channel ids / emails where output goes." }
        }
      }
    },

    "integrations": {
      "type": "array",
      "description": "Declared capabilities — never hardcoded. The compiler maps these to harness tooling.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": ["id", "name", "type", "capabilities", "auth"],
        "properties": {
          "id":           { "type": "string" },
          "name":         { "type": "string", "description": "e.g. 'Gmail'." },
          "type":         { "type": "string", "description": "e.g. 'email', 'calendar', 'crm', 'chat', 'sms', 'spreadsheet'." },
          "capabilities": { "type": "array", "items": { "type": "string" }, "description": "e.g. ['read', 'send-draft']." },
          "auth":         { "type": "string", "enum": ["oauth", "api-key", "none"] }
        }
      }
    },

    "routing": {
      "type": "object",
      "description": "Where work is reasoned about: local (self-hosted) by default for sensitive data; cloud only when explicitly safe.",
      "additionalProperties": false,
      "required": ["default", "rules"],
      "properties": {
        "default": { "type": "string", "enum": ["local", "cloud"], "description": "Self-hosted default is the regulated posture." },
        "rules": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": ["when", "route"],
            "properties": {
              "when":  { "type": "string", "description": "Pattern/condition, e.g. 'contains PHI or LP deal data'." },
              "route": { "type": "string", "enum": ["local", "cloud"] },
              "note":  { "type": "string" }
            }
          }
        },
        "logDecisions": { "type": "boolean", "description": "Audit trail of routing decisions (query hash, route, model)." }
      }
    },

    "guardrails": {
      "type": "array",
      "description": "Approval gates — what needs a human sign-off before it happens.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": ["id", "action", "requiresApproval"],
        "properties": {
          "id":              { "type": "string" },
          "action":          { "type": "string", "description": "e.g. 'send email', 'publish post', 'spend money', 'delete data'." },
          "requiresApproval": { "type": "boolean" },
          "notify":          { "type": "string", "description": "Who approves (email/chat)." }
        }
      }
    },

    "tools": {
      "type": "object",
      "additionalProperties": false,
      "required": ["allowed"],
      "properties": {
        "allowed": { "type": "array", "items": { "type": "string" }, "description": "e.g. ['web', 'file', 'cron', 'email']." },
        "denied":  { "type": "array", "items": { "type": "string" }, "description": "e.g. ['terminal', 'deployment']. Deny wins over allow." }
      }
    }
  }
}
