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
454 lines
11 KiB
JSON
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"
|
|
}
|
|
]
|
|
}
|