{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://bot0.ai/schemas/poa/1.3/authority.schema.json",
  "title": "Agentic Power of Action — Authority (RFC 9396 authorization-detail type https://bot0.ai/poa/authority)",
  "description": "One bounded authority inside a Power-of-Action Grant: for one act of work, what effect it produces, whom it may face, which systems it may go through, which team members may exercise it, what it may rely on, its money limits, whether it needs a go-ahead, and when its result becomes official. A Grant authorizes work, not an agent; each act carries its own authority. Authority binds to effects within work, never to tools: the same tool can realize radically different acts.",
  "type": "object",
  "additionalProperties": false,
  "required": ["act_id", "effect", "kind", "label", "targets", "grounding", "limits", "resources", "actors", "go_ahead", "commit", "narrowed"],
  "properties": {
    "act_id": { "type": "string", "pattern": "^[a-z0-9_.-]+\\.[a-z0-9_-]+$", "description": "The act as the person named it: a catalogue act (shop.buy) or a discovered one (provider.operation, e.g. amazon.place_order)." },
    "effect": { "$ref": "#/$defs/effect" },
    "kind": { "$ref": "#/$defs/kind" },
    "label": { "type": "string", "maxLength": 80 },
    "targets": { "type": "array", "items": { "$ref": "#/$defs/target" }, "maxItems": 2, "description": "Whom the act may face. Empty for acts that face no one." },
    "resources": { "type": "array", "items": { "$ref": "#/$defs/resource_scope" }, "description": "Discovered systems this act may be exercised through. Empty when no inventory was connected." },
    "actors": { "type": "array", "items": { "type": "string" }, "description": "Subjects (RFC 8693 act.sub) of the work-system members that hold this act. Empty when one agent does the work." },
    "grounding": {
      "type": "object", "additionalProperties": false,
      "required": ["allowed_sources", "prohibited_sources", "freshness"],
      "properties": {
        "allowed_sources": { "type": "array", "items": { "type": "string" } },
        "prohibited_sources": { "type": "array", "items": { "type": "string" } },
        "freshness": { "type": "string", "description": "ISO-8601 duration; PT0S means read the live state right before acting." }
      }
    },
    "limits": {
      "oneOf": [
        { "type": "null" },
        {
          "type": "object", "additionalProperties": false,
          "required": ["currency", "transaction_amount_lte", "monthly_total_lte", "categories_in"],
          "properties": {
            "currency": { "const": "USD" },
            "transaction_amount_lte": { "type": ["number", "null"], "minimum": 0 },
            "monthly_total_lte": { "type": ["number", "null"], "minimum": 0 },
            "categories_in": { "type": ["array", "null"], "items": { "type": "string" } }
          }
        }
      ]
    },
    "go_ahead": { "enum": ["standing", "each_time", "none"] },
    "commit": { "$ref": "#/$defs/commit_mode" },
    "officiality": { "enum": ["not_official", "unresolved"], "description": "B-397 (10-20): an act becomes official when it commits an authoritative business state, not because it writes data or communicates. Present only when the kind is not none and the act is NOT official: not_official — the work system declared the write operational or staging; unresolved — nobody declared whether it commits, so it asks every time and never stands. Absent = official exactly when kind is not none, as before." },
    "approver": { "type": "string", "maxLength": 120, "description": "B-215 (10-07): the person on the work who says yes to an Ask-first act. Absent = the principal." },
    "checked_by": { "type": "string", "description": "B-215 (10-07): the agent (sub) whose attested check makes this act official; never the act's only actor." },
    "narrowed": { "type": "array", "items": { "enum": ["targets", "grounding", "limits"] }, "uniqueItems": true }
  },
  "$defs": {
    "effect": {
      "description": "1.2: a catalogue effect, or an extension effect named by an https URI (spec §5, effect registry). An extension carries its own kind; a verifier that does not know it treats it as not delegated unless the Grant has an authority for it.",
      "anyOf": [
        {"enum": ["read", "search", "compare", "organize", "draft", "propose", "prepare", "hold", "create",
               "send_message", "post", "invite", "schedule", "book", "amend_booking", "purchase", "subscribe",
               "return", "pay", "transfer", "send_money", "dispute", "unsubscribe", "update_record", "submit",
               "approve", "control_device", "cancel", "delete", "share", "unlock", "execute", "delegate"] },
        { "type": "string", "pattern": "^https://[^\\s]+$" }
      ]
    },
    "kind": { "enum": ["none", "sent", "purchased", "transferred", "submitted", "changed", "deleted", "shared"] },
    "commit_mode": { "enum": ["automatic", "user_approval", "prohibited"] },
    "target": {
      "type": "object", "additionalProperties": false,
      "required": ["type", "scope", "ids"],
      "properties": {
        "type": { "enum": ["person", "merchant"] },
        "scope": { "enum": ["known", "named", "any"] },
        "ids": { "type": "array", "items": { "type": "string" } }
      }
    },
    "resource_scope": {
      "type": "object", "additionalProperties": false,
      "required": ["provider", "label", "category", "account", "effects"],
      "properties": {
        "provider": { "type": "string" },
        "label": { "type": "string" },
        "category": { "enum": ["COMMUNICATION", "KNOWLEDGE", "WORK_SYSTEMS", "COMMERCE", "MONEY", "COMPUTER", "AGENTS"] },
        "account": { "type": ["string", "null"] },
        "effects": { "type": "array", "items": { "$ref": "#/$defs/effect" } },
        "place": { "enum": ["sandbox", "shared_computer", "accounts"], "description": "Where a change through this system lands. A shared computer's logins are usable by every agent on it." },
        "reach": { "enum": ["all", "app_scoped"], "description": "How far the connector reaches: everything, or only what the app created or opened." },
        "via": { "type": ["string", "null"], "description": "What the connector goes through, e.g. a bridge." },
        "locations": { "type": "array", "items": { "type": "string" }, "maxItems": 20, "description": "Optional (10-01): where inside the app it may work — folders, channels or projects by name. Absent = the whole app." }
      }
    }
  }
}
