atlas-iac/services/hermes/contracts/hux/permission.schema.json
jenkins 6964a9d8c8 hermes(hux): close Wave A review findings in autonomy and the HTTP pipeline
F1 policy writes and allow grants are human-surface only; F2 worker trust is
confined to the hook allowlist and unexpected exceptions become audited 500
error records; F4 external side effects release only for the same run and
argument hash; F6 the gate honours budget exhaustion; F8 only the gateway
can vouch for an empty process registry and failed receipts can be
superseded; F11/F12 receipt revision and unshipped card routes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNPhwu2bsaRNg3DETSAZoM
2026-08-24 00:48:20 -03:00

454 lines
11 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://hermes.bstein.dev/contracts/hux/v1/permission.schema.json",
"title": "HUX autonomy, grants, approvals, cancellation",
"description": "Policy engine records (HUX-05). A policy fixes the autonomy level and explicit capability grants for a scope; approvals are queued items answered with the existing gateway choices (once|session|always|deny); a cancellation receipt proves what a stop actually did.",
"$defs": {
"capability": {
"type": "string",
"enum": [
"read_files",
"write_files",
"shell",
"network",
"web_search",
"send_message",
"memory_write",
"artifact_write",
"spend_tokens",
"delegate",
"deploy",
"external_side_effect"
]
},
"decision": {
"type": "string",
"enum": [
"allow",
"ask",
"deny"
]
},
"policy": {
"type": "object",
"additionalProperties": false,
"required": [
"schema",
"id",
"owner",
"scope",
"autonomy",
"grants",
"budgets",
"provenance",
"updated_at",
"revision"
],
"properties": {
"schema": {
"const": "hux.policy.v1"
},
"id": {
"$ref": "common.schema.json#/$defs/id"
},
"owner": {
"$ref": "common.schema.json#/$defs/user_ref"
},
"scope": {
"type": "object",
"additionalProperties": false,
"required": [
"level"
],
"properties": {
"level": {
"type": "string",
"enum": [
"global",
"project",
"conversation"
]
},
"scope_id": {
"$ref": "common.schema.json#/$defs/id"
}
}
},
"autonomy": {
"type": "string",
"enum": [
"ask_first",
"safe",
"autonomous"
]
},
"grants": {
"type": "array",
"maxItems": 64,
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"capability",
"decision"
],
"properties": {
"capability": {
"$ref": "#/$defs/capability"
},
"decision": {
"$ref": "#/$defs/decision"
},
"expires_at": {
"$ref": "common.schema.json#/$defs/timestamp"
},
"granted_by": {
"$ref": "common.schema.json#/$defs/actor"
}
}
}
},
"budgets": {
"type": "object",
"additionalProperties": false,
"properties": {
"tokens_per_run": {
"type": "integer",
"minimum": 0
},
"tool_calls_per_run": {
"type": "integer",
"minimum": 0
},
"wall_clock_seconds": {
"type": "integer",
"minimum": 0
},
"delegations_per_run": {
"type": "integer",
"minimum": 0
},
"spend_units": {
"type": "integer",
"minimum": 0
},
"subagents_per_run": {
"type": "integer",
"minimum": 0
},
"scope": {
"type": "object",
"additionalProperties": false,
"properties": {
"conversations": {
"type": "array",
"maxItems": 64,
"items": {
"$ref": "common.schema.json#/$defs/id"
}
},
"paths": {
"type": "array",
"maxItems": 64,
"items": {
"type": "string",
"maxLength": 300
}
}
}
}
}
},
"provenance": {
"$ref": "common.schema.json#/$defs/provenance"
},
"updated_at": {
"$ref": "common.schema.json#/$defs/timestamp"
},
"revision": {
"$ref": "common.schema.json#/$defs/revision"
}
}
},
"approval": {
"type": "object",
"additionalProperties": false,
"required": [
"schema",
"id",
"run_id",
"conversation_id",
"capability",
"request",
"status",
"requested_at",
"expires_at"
],
"properties": {
"schema": {
"const": "hux.approval.v1"
},
"id": {
"$ref": "common.schema.json#/$defs/id"
},
"run_id": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"conversation_id": {
"$ref": "common.schema.json#/$defs/id"
},
"capability": {
"$ref": "#/$defs/capability"
},
"request": {
"type": "object",
"additionalProperties": false,
"required": [
"summary",
"risk",
"external"
],
"properties": {
"summary": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"detail": {
"type": "string",
"maxLength": 4000
},
"risk": {
"type": "string",
"enum": [
"low",
"medium",
"high"
]
},
"evidence": {
"type": "array",
"maxItems": 16,
"items": {
"$ref": "common.schema.json#/$defs/evidence_ref"
}
},
"external": {
"type": "boolean",
"description": "True when the action leaves the tenant (message, network call, deploy). External side effects always need an approval record regardless of autonomy level."
}
}
},
"status": {
"type": "string",
"enum": [
"pending",
"approved",
"denied",
"expired",
"cancelled"
]
},
"decision": {
"type": "object",
"additionalProperties": false,
"required": [
"choice",
"by",
"at"
],
"properties": {
"choice": {
"type": "string",
"enum": [
"once",
"session",
"always",
"deny"
]
},
"by": {
"$ref": "common.schema.json#/$defs/actor"
},
"at": {
"$ref": "common.schema.json#/$defs/timestamp"
}
}
},
"requested_at": {
"$ref": "common.schema.json#/$defs/timestamp"
},
"expires_at": {
"$ref": "common.schema.json#/$defs/timestamp"
},
"idempotency_key": {
"$ref": "common.schema.json#/$defs/idempotency_key"
}
}
},
"cancellation_receipt": {
"type": "object",
"additionalProperties": false,
"required": [
"schema",
"id",
"run_id",
"requested_by",
"requested_at",
"outcome",
"side_effects"
],
"properties": {
"schema": {
"const": "hux.cancel_receipt.v1"
},
"id": {
"$ref": "common.schema.json#/$defs/id"
},
"run_id": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"requested_by": {
"$ref": "common.schema.json#/$defs/actor"
},
"requested_at": {
"$ref": "common.schema.json#/$defs/timestamp"
},
"acknowledged_at": {
"$ref": "common.schema.json#/$defs/timestamp"
},
"completed_at": {
"$ref": "common.schema.json#/$defs/timestamp"
},
"outcome": {
"type": "string",
"enum": [
"cancelled",
"already_complete",
"failed_to_cancel"
]
},
"side_effects": {
"type": "array",
"maxItems": 64,
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"description",
"reverted"
],
"properties": {
"description": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"reverted": {
"type": "boolean"
},
"evidence": {
"$ref": "common.schema.json#/$defs/evidence_ref"
}
}
}
},
"conversation_id": {
"$ref": "common.schema.json#/$defs/id"
},
"revision": {
"type": "integer",
"minimum": 1,
"description": "Store revision; bumps when a failed_to_cancel receipt is superseded by a later stop."
}
}
},
"budget_state": {
"type": "object",
"additionalProperties": false,
"required": [
"schema",
"run_id",
"spent",
"limits",
"exhausted"
],
"properties": {
"schema": {
"const": "hux.budget_state.v1"
},
"run_id": {
"type": "string",
"maxLength": 120
},
"spent": {
"type": "object",
"additionalProperties": false,
"properties": {
"tokens": {
"type": "integer",
"minimum": 0
},
"tool_calls": {
"type": "integer",
"minimum": 0
},
"wall_clock_seconds": {
"type": "integer",
"minimum": 0
},
"delegations": {
"type": "integer",
"minimum": 0
},
"spend_units": {
"type": "integer",
"minimum": 0
},
"subagents": {
"type": "integer",
"minimum": 0
}
}
},
"limits": {
"$ref": "#/$defs/policy/properties/budgets"
},
"exhausted": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"enum": [
"tokens_per_run",
"tool_calls_per_run",
"wall_clock_seconds",
"delegations_per_run",
"spend_units",
"subagents_per_run"
]
}
}
}
}
},
"oneOf": [
{
"$ref": "#/$defs/policy"
},
{
"$ref": "#/$defs/approval"
},
{
"$ref": "#/$defs/cancellation_receipt"
},
{
"$ref": "#/$defs/budget_state"
}
]
}