Add three new pages completing the control-room web UI: - Agent activity: polls /agent-activity every 5s, filterable by type/agent - Knowledge search: FTS over /knowledge/search with snippet + entity links - Audit trail: browseable audit log with actor/action/entity filters Enhanced live events page with correlation-id clustering (Groups toggle). Added fetchAgentActivity/searchKnowledge/fetchAudit to the API client. 11 nav items now cover all planned control-room views.
3279 lines
81 KiB
YAML
3279 lines
81 KiB
YAML
openapi: 3.0.3
|
|
info:
|
|
title: Oikos API
|
|
version: 1.0.0
|
|
contact:
|
|
name: dtoro
|
|
license:
|
|
name: Private
|
|
url: https://example.invalid/private
|
|
description: 'Control-plane API for the Oikos homelab OS. This file is the **source of
|
|
|
|
truth** (contract-first): Go server stubs are generated with oapi-codegen,
|
|
|
|
clients (homelab CLI, future UIs) from the same spec.
|
|
|
|
|
|
Conventions (plan R3-3):
|
|
|
|
- Errors are RFC 9457 `application/problem+json`.
|
|
|
|
- Lists use `{items, next_cursor}` with cursor pagination (default limit 50, max 200).
|
|
|
|
- Unsafe POSTs accept `Idempotency-Key` (24h replay window).
|
|
|
|
- Mutable resources carry `version`; GET returns `ETag`, PATCH requires `If-Match` (412 on mismatch).
|
|
|
|
- Timestamps are RFC 3339 UTC.
|
|
|
|
- Entities are addressable by UUID or slug (`host:hubris`).
|
|
|
|
|
|
The MCP interface (streamable HTTP, official Go SDK) is mounted at `/mcp`
|
|
|
|
on the same binary and is out of scope for this document; its tools wrap
|
|
|
|
the same service layer as these endpoints.
|
|
|
|
'
|
|
servers:
|
|
- url: /api/v1
|
|
tags:
|
|
- name: entities
|
|
description: Inventory graph — entities and relationships
|
|
- name: clients
|
|
description: Client enrollment, context distribution, secrets
|
|
- name: ontology
|
|
description: Entity types, relationship types, lifecycles
|
|
- name: signals
|
|
description: Signals and checks (observe)
|
|
- name: executions
|
|
description: Executions, classifications, approvals (decide/act)
|
|
- name: learning
|
|
description: Patterns and skills (learn)
|
|
- name: policy
|
|
description: Risk classes, approval rules, autonomy
|
|
- name: knowledge
|
|
description: Knowledge graph search
|
|
- name: observability
|
|
description: Metrics, trends, audit, events, health
|
|
- name: system
|
|
description: Export, health
|
|
security:
|
|
- bearerAuth: []
|
|
paths:
|
|
/entities:
|
|
get:
|
|
tags:
|
|
- entities
|
|
operationId: listEntities
|
|
summary: List entities
|
|
x-required-scope: viewer
|
|
parameters:
|
|
- name: type
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Filter by entity type (includes descendants)
|
|
- name: state
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: domain
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: layer
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: q
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Substring match on slug/name
|
|
- $ref: '#/components/parameters/Cursor'
|
|
- $ref: '#/components/parameters/Limit'
|
|
responses:
|
|
'200':
|
|
description: Entity list
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Entity'
|
|
next_cursor:
|
|
type: string
|
|
nullable: true
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
post:
|
|
tags:
|
|
- entities
|
|
operationId: createEntity
|
|
summary: Create an entity
|
|
x-required-scope: operator
|
|
parameters:
|
|
- $ref: '#/components/parameters/IdempotencyKey'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/EntityCreate'
|
|
responses:
|
|
'201':
|
|
description: Created
|
|
headers:
|
|
ETag:
|
|
$ref: '#/components/headers/ETag'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Entity'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/entities/{id}:
|
|
parameters:
|
|
- $ref: '#/components/parameters/EntityId'
|
|
get:
|
|
tags:
|
|
- entities
|
|
operationId: getEntity
|
|
summary: Get entity by UUID or slug
|
|
x-required-scope: viewer
|
|
responses:
|
|
'200':
|
|
description: Entity detail
|
|
headers:
|
|
ETag:
|
|
$ref: '#/components/headers/ETag'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Entity'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
patch:
|
|
tags:
|
|
- entities
|
|
operationId: patchEntity
|
|
summary: Update attributes or transition lifecycle state
|
|
description: 'Lifecycle transitions are validated against the type''s lifecycle_def;
|
|
|
|
illegal transitions return 409 (invalid-transition). Policy-gated
|
|
|
|
actions may return 403 (approval-required).
|
|
|
|
'
|
|
x-required-scope: operator
|
|
parameters:
|
|
- $ref: '#/components/parameters/IfMatch'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/EntityPatch'
|
|
responses:
|
|
'200':
|
|
description: Updated entity
|
|
headers:
|
|
ETag:
|
|
$ref: '#/components/headers/ETag'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Entity'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/entities/{id}/relations:
|
|
parameters:
|
|
- $ref: '#/components/parameters/EntityId'
|
|
get:
|
|
tags:
|
|
- entities
|
|
operationId: getEntityRelations
|
|
summary: Direct relationships of an entity (both directions)
|
|
x-required-scope: viewer
|
|
parameters:
|
|
- name: rel_type
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: direction
|
|
in: query
|
|
schema:
|
|
type: string
|
|
enum:
|
|
- out
|
|
- in
|
|
- both
|
|
default: both
|
|
responses:
|
|
'200':
|
|
description: Relationships
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Relationship'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/relationships:
|
|
post:
|
|
tags:
|
|
- entities
|
|
operationId: createRelationship
|
|
summary: Create a relationship edge
|
|
description: Endpoint types validated against relationship_types (hierarchy-aware); cardinality
|
|
enforced.
|
|
x-required-scope: operator
|
|
parameters:
|
|
- $ref: '#/components/parameters/IdempotencyKey'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/RelationshipCreate'
|
|
responses:
|
|
'201':
|
|
description: Created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Relationship'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
delete:
|
|
tags:
|
|
- entities
|
|
operationId: endRelationship
|
|
summary: End a relationship (sets valid_to; the edge is kept for history)
|
|
x-required-scope: operator
|
|
parameters:
|
|
- name: source
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: target
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: rel_type
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'204':
|
|
description: Relationship ended
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/graph:
|
|
get:
|
|
tags:
|
|
- entities
|
|
operationId: getGraph
|
|
summary: Subgraph for visualization (nodes + edges)
|
|
x-required-scope: viewer
|
|
parameters:
|
|
- name: root
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Start entity (UUID or slug); omit for whole graph (capped)
|
|
- name: depth
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
default: 2
|
|
maximum: 5
|
|
- name: rel_type
|
|
in: query
|
|
schema:
|
|
type: array
|
|
items:
|
|
type: string
|
|
style: form
|
|
explode: true
|
|
- name: include
|
|
in: query
|
|
schema:
|
|
type: array
|
|
items:
|
|
type: string
|
|
enum:
|
|
- status
|
|
style: form
|
|
explode: true
|
|
description: include=status joins entity_status and populates GraphView.health
|
|
responses:
|
|
'200':
|
|
description: Graph view
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/GraphView'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/entities/{id}/blast-radius:
|
|
parameters:
|
|
- $ref: '#/components/parameters/EntityId'
|
|
get:
|
|
tags:
|
|
- entities
|
|
operationId: getBlastRadius
|
|
summary: Entities affected if this entity fails
|
|
x-required-scope: viewer
|
|
parameters:
|
|
- name: depth
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
default: 3
|
|
maximum: 5
|
|
responses:
|
|
'200':
|
|
description: Affected entities with graph distance
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
type: object
|
|
required:
|
|
- entity
|
|
- depth
|
|
properties:
|
|
entity:
|
|
$ref: '#/components/schemas/Entity'
|
|
depth:
|
|
type: integer
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/clients/enroll:
|
|
post:
|
|
tags:
|
|
- clients
|
|
operationId: enrollClient
|
|
summary: Enroll a new client — issue age key, create Infisical identity
|
|
description: >
|
|
Validates mesh IP, generates an age keypair, creates an Infisical
|
|
machine identity, and transitions the entity to provisioning.
|
|
Caller must already have an entity in planned or provisioning state.
|
|
x-required-scope: agent
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/EnrollRequest'
|
|
responses:
|
|
'200':
|
|
description: Enrollment response with keys and identity
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/EnrollResponse'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/clients/{slug}/context:
|
|
parameters:
|
|
- $ref: '#/components/parameters/EntitySlug'
|
|
get:
|
|
tags:
|
|
- clients
|
|
operationId: getClientContext
|
|
summary: Get agent context delta since a timestamp
|
|
description: >
|
|
Returns which agent files, tools, and SOPS config changed since the
|
|
given timestamp. Thin clients poll this instead of git pull.
|
|
x-required-scope: agent
|
|
parameters:
|
|
- name: since
|
|
in: query
|
|
schema:
|
|
type: string
|
|
format: date-time
|
|
description: Return only changes since this timestamp (RFC 3339)
|
|
responses:
|
|
'200':
|
|
description: Context delta
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ClientContext'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/clients/{slug}/secrets:
|
|
parameters:
|
|
- $ref: '#/components/parameters/EntitySlug'
|
|
get:
|
|
tags:
|
|
- clients
|
|
operationId: getClientSecrets
|
|
summary: List secrets accessible to this client
|
|
description: Infisical-secured secrets scoped to the client's machine identity
|
|
x-required-scope: agent
|
|
responses:
|
|
'200':
|
|
description: Secret keys accessible to this client
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ClientSecrets'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/entities/provision:
|
|
post:
|
|
tags:
|
|
- entities
|
|
operationId: provisionEntity
|
|
summary: Provision a compute entity (LXC, VM, container) on a host
|
|
description: >
|
|
Creates the entity in planned state, validates constraints (VMID, IP,
|
|
capacity, template), classifies the action against policy, and
|
|
transitions to provisioning on operator approval.
|
|
x-required-scope: operator
|
|
parameters:
|
|
- $ref: '#/components/parameters/IdempotencyKey'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ProvisionRequest'
|
|
responses:
|
|
'201':
|
|
description: Entity created, provisioning queued
|
|
headers:
|
|
ETag:
|
|
$ref: '#/components/headers/ETag'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ProvisionResponse'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/entities/{slug}/provision/status:
|
|
parameters:
|
|
- $ref: '#/components/parameters/EntitySlug'
|
|
get:
|
|
tags:
|
|
- entities
|
|
operationId: getProvisionStatus
|
|
summary: Poll provisioning progress for a compute entity
|
|
x-required-scope: viewer
|
|
responses:
|
|
'200':
|
|
description: Provisioning steps with status
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ProvisionStatus'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
|
|
/ontology:
|
|
get:
|
|
tags:
|
|
- ontology
|
|
operationId: getOntology
|
|
summary: Full ontology — entity types, relationship types, lifecycles
|
|
x-required-scope: viewer
|
|
responses:
|
|
'200':
|
|
description: Ontology
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- entity_types
|
|
- relationship_types
|
|
- lifecycles
|
|
properties:
|
|
entity_types:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/EntityType'
|
|
relationship_types:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/RelationshipType'
|
|
lifecycles:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/LifecycleDef'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/ontology/entity-types:
|
|
post:
|
|
tags:
|
|
- ontology
|
|
operationId: createEntityType
|
|
summary: Extend the ontology with a new entity type
|
|
description: Policy-gated as config_mutation (creates a meta-approval when required).
|
|
x-required-scope: operator
|
|
parameters:
|
|
- $ref: '#/components/parameters/IdempotencyKey'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/EntityTypeCreate'
|
|
responses:
|
|
'201':
|
|
description: Created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/EntityType'
|
|
'202':
|
|
$ref: '#/components/responses/PendingApproval'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/ontology/entity-types/{name}:
|
|
parameters:
|
|
- name: name
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
patch:
|
|
tags:
|
|
- ontology
|
|
operationId: patchEntityType
|
|
summary: Update or deprecate an entity type
|
|
description: Hard delete is not supported while instances exist — deprecate instead (plan D3).
|
|
x-required-scope: operator
|
|
parameters:
|
|
- $ref: '#/components/parameters/IfMatch'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/EntityTypePatch'
|
|
responses:
|
|
'200':
|
|
description: Updated
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/EntityType'
|
|
'202':
|
|
$ref: '#/components/responses/PendingApproval'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/signals:
|
|
get:
|
|
tags:
|
|
- signals
|
|
operationId: listSignals
|
|
summary: List signals
|
|
x-required-scope: viewer
|
|
parameters:
|
|
- name: state
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: severity
|
|
in: query
|
|
schema:
|
|
type: string
|
|
enum:
|
|
- info
|
|
- warning
|
|
- critical
|
|
- name: entity_id
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: kind
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- $ref: '#/components/parameters/Cursor'
|
|
- $ref: '#/components/parameters/Limit'
|
|
responses:
|
|
'200':
|
|
description: Signals
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Signal'
|
|
next_cursor:
|
|
type: string
|
|
nullable: true
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/signals/{id}/ack:
|
|
parameters:
|
|
- $ref: '#/components/parameters/EntityId'
|
|
post:
|
|
tags:
|
|
- signals
|
|
operationId: ackSignal
|
|
summary: Acknowledge a signal
|
|
x-required-scope: operator
|
|
responses:
|
|
'200':
|
|
$ref: '#/components/responses/SignalUpdated'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/signals/{id}/resolve:
|
|
parameters:
|
|
- $ref: '#/components/parameters/EntityId'
|
|
post:
|
|
tags:
|
|
- signals
|
|
operationId: resolveSignal
|
|
summary: Resolve a signal manually
|
|
x-required-scope: operator
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
note:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
$ref: '#/components/responses/SignalUpdated'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/signals/{id}/mute:
|
|
parameters:
|
|
- $ref: '#/components/parameters/EntityId'
|
|
post:
|
|
tags:
|
|
- signals
|
|
operationId: muteSignal
|
|
summary: Mute a signal for a TTL
|
|
x-required-scope: operator
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- mute_until
|
|
properties:
|
|
mute_until:
|
|
type: string
|
|
format: date-time
|
|
note:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
$ref: '#/components/responses/SignalUpdated'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/checks:
|
|
get:
|
|
tags:
|
|
- signals
|
|
operationId: listChecks
|
|
summary: List check definitions
|
|
x-required-scope: viewer
|
|
parameters:
|
|
- name: kind
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: target
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: enabled
|
|
in: query
|
|
schema:
|
|
type: boolean
|
|
- $ref: '#/components/parameters/Cursor'
|
|
- $ref: '#/components/parameters/Limit'
|
|
responses:
|
|
'200':
|
|
description: Checks
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Check'
|
|
next_cursor:
|
|
type: string
|
|
nullable: true
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
post:
|
|
tags:
|
|
- signals
|
|
operationId: createCheck
|
|
summary: Create a check (checks-as-data, plan R3-7)
|
|
x-required-scope: operator
|
|
parameters:
|
|
- $ref: '#/components/parameters/IdempotencyKey'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CheckCreate'
|
|
responses:
|
|
'201':
|
|
description: Created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Check'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/checks/{id}:
|
|
parameters:
|
|
- $ref: '#/components/parameters/EntityId'
|
|
patch:
|
|
tags:
|
|
- signals
|
|
operationId: patchCheck
|
|
summary: Update or disable a check
|
|
x-required-scope: operator
|
|
parameters:
|
|
- $ref: '#/components/parameters/IfMatch'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CheckPatch'
|
|
responses:
|
|
'200':
|
|
description: Updated
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Check'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/executions:
|
|
get:
|
|
tags:
|
|
- executions
|
|
operationId: listExecutions
|
|
summary: List executions
|
|
x-required-scope: viewer
|
|
parameters:
|
|
- name: status
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: target
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: action
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: correlation_id
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- $ref: '#/components/parameters/Cursor'
|
|
- $ref: '#/components/parameters/Limit'
|
|
responses:
|
|
'200':
|
|
description: Executions
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Execution'
|
|
next_cursor:
|
|
type: string
|
|
nullable: true
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
post:
|
|
tags:
|
|
- executions
|
|
operationId: requestExecution
|
|
summary: Request an execution (classify → approval check → enqueue)
|
|
description: 'The handler classifies the (entity, action), checks policy/autonomy,
|
|
|
|
and either enqueues the execution (auto-approved) or creates an
|
|
|
|
approval request and returns the execution in `proposed` state.
|
|
|
|
Also exposed to the agent role — this is the ONLY way agents act.
|
|
|
|
'
|
|
x-required-scope: agent
|
|
parameters:
|
|
- $ref: '#/components/parameters/IdempotencyKey'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ExecutionRequest'
|
|
responses:
|
|
'201':
|
|
description: Execution created (may be pending approval)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Execution'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/executions/{id}:
|
|
parameters:
|
|
- $ref: '#/components/parameters/EntityId'
|
|
get:
|
|
tags:
|
|
- executions
|
|
operationId: getExecution
|
|
summary: Execution status + result
|
|
x-required-scope: viewer
|
|
responses:
|
|
'200':
|
|
description: Execution
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Execution'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/executions/{id}/cancel:
|
|
parameters:
|
|
- $ref: '#/components/parameters/EntityId'
|
|
post:
|
|
tags:
|
|
- executions
|
|
operationId: cancelExecution
|
|
summary: Cancel a proposed/executing execution
|
|
x-required-scope: operator
|
|
responses:
|
|
'200':
|
|
description: Cancelled
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Execution'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/classifications:
|
|
get:
|
|
tags:
|
|
- executions
|
|
operationId: listClassifications
|
|
summary: Classifier decisions (the autonomous-decision audit trail)
|
|
x-required-scope: viewer
|
|
parameters:
|
|
- name: signal_id
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: entity_id
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: route
|
|
in: query
|
|
schema:
|
|
type: string
|
|
enum:
|
|
- auto-act
|
|
- escalate
|
|
- hold
|
|
- $ref: '#/components/parameters/Cursor'
|
|
- $ref: '#/components/parameters/Limit'
|
|
responses:
|
|
'200':
|
|
description: Classifications
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Classification'
|
|
next_cursor:
|
|
type: string
|
|
nullable: true
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/approvals:
|
|
get:
|
|
tags:
|
|
- executions
|
|
operationId: listApprovals
|
|
summary: List approvals
|
|
x-required-scope: viewer
|
|
parameters:
|
|
- name: status
|
|
in: query
|
|
schema:
|
|
type: string
|
|
enum:
|
|
- pending
|
|
- approved
|
|
- denied
|
|
- expired
|
|
- revoked
|
|
- name: kind
|
|
in: query
|
|
schema:
|
|
type: string
|
|
enum:
|
|
- execution
|
|
- policy-change
|
|
- pattern-activation
|
|
- $ref: '#/components/parameters/Cursor'
|
|
- $ref: '#/components/parameters/Limit'
|
|
responses:
|
|
'200':
|
|
description: Approvals
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Approval'
|
|
next_cursor:
|
|
type: string
|
|
nullable: true
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/approvals/{id}/decision:
|
|
parameters:
|
|
- $ref: '#/components/parameters/EntityId'
|
|
post:
|
|
tags:
|
|
- executions
|
|
operationId: decideApproval
|
|
summary: Approve or deny (single-use token verified server-side)
|
|
x-required-scope: operator
|
|
parameters:
|
|
- $ref: '#/components/parameters/IdempotencyKey'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- decision
|
|
properties:
|
|
decision:
|
|
type: string
|
|
enum:
|
|
- approve
|
|
- deny
|
|
- revoke
|
|
note:
|
|
type: string
|
|
token:
|
|
type: string
|
|
description: HMAC approval token (single-use, verified server-side)
|
|
responses:
|
|
'200':
|
|
description: Decision recorded
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Approval'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/patterns:
|
|
get:
|
|
tags:
|
|
- learning
|
|
operationId: listPatterns
|
|
summary: List patterns
|
|
x-required-scope: viewer
|
|
parameters:
|
|
- name: entity_type
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: action
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: status
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- $ref: '#/components/parameters/Cursor'
|
|
- $ref: '#/components/parameters/Limit'
|
|
responses:
|
|
'200':
|
|
description: Patterns
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Pattern'
|
|
next_cursor:
|
|
type: string
|
|
nullable: true
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/patterns/{id}:
|
|
parameters:
|
|
- $ref: '#/components/parameters/EntityId'
|
|
patch:
|
|
tags:
|
|
- learning
|
|
operationId: patchPattern
|
|
summary: Transition a pattern (activate / invalidate / deprecate)
|
|
description: Operator safety valve (plan SG7). Activation is policy-gated config_mutation (S4).
|
|
x-required-scope: operator
|
|
parameters:
|
|
- $ref: '#/components/parameters/IfMatch'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
status:
|
|
type: string
|
|
enum:
|
|
- validated
|
|
- active
|
|
- deprecated
|
|
- invalidated
|
|
quarantined:
|
|
type: boolean
|
|
note:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Updated
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Pattern'
|
|
'202':
|
|
$ref: '#/components/responses/PendingApproval'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/skills:
|
|
get:
|
|
tags:
|
|
- learning
|
|
operationId: listSkills
|
|
summary: List skills (latest version per skill)
|
|
x-required-scope: viewer
|
|
parameters:
|
|
- name: applies_to
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: action
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: status
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- $ref: '#/components/parameters/Cursor'
|
|
- $ref: '#/components/parameters/Limit'
|
|
responses:
|
|
'200':
|
|
description: Skills
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Skill'
|
|
next_cursor:
|
|
type: string
|
|
nullable: true
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/skills/{id}:
|
|
parameters:
|
|
- $ref: '#/components/parameters/EntityId'
|
|
patch:
|
|
tags:
|
|
- learning
|
|
operationId: patchSkill
|
|
summary: Transition a skill or pin a version
|
|
x-required-scope: operator
|
|
parameters:
|
|
- $ref: '#/components/parameters/IfMatch'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
status:
|
|
type: string
|
|
enum:
|
|
- tested
|
|
- active
|
|
- deprecated
|
|
pinned_version:
|
|
type: integer
|
|
note:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Updated
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Skill'
|
|
'202':
|
|
$ref: '#/components/responses/PendingApproval'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/skills/{id}/versions:
|
|
parameters:
|
|
- $ref: '#/components/parameters/EntityId'
|
|
get:
|
|
tags:
|
|
- learning
|
|
operationId: listSkillVersions
|
|
summary: Version history of a skill
|
|
x-required-scope: viewer
|
|
responses:
|
|
'200':
|
|
description: Versions
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Skill'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/policy/risk-classes:
|
|
get:
|
|
tags:
|
|
- policy
|
|
operationId: listRiskClasses
|
|
summary: List risk classes
|
|
x-required-scope: viewer
|
|
responses:
|
|
'200':
|
|
description: Risk classes
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/RiskClass'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/policy/approval-rules:
|
|
get:
|
|
tags:
|
|
- policy
|
|
operationId: listApprovalRules
|
|
summary: List approval rules
|
|
x-required-scope: viewer
|
|
responses:
|
|
'200':
|
|
description: Rules
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ApprovalRule'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
post:
|
|
tags:
|
|
- policy
|
|
operationId: createApprovalRule
|
|
summary: Propose a new approval rule (dual-control)
|
|
description: Creates a policy-change approval; the rule applies only after operator approval (plan
|
|
S3).
|
|
x-required-scope: operator
|
|
parameters:
|
|
- $ref: '#/components/parameters/IdempotencyKey'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ApprovalRuleCreate'
|
|
responses:
|
|
'202':
|
|
$ref: '#/components/responses/PendingApproval'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/policy/approval-rules/{id}:
|
|
parameters:
|
|
- $ref: '#/components/parameters/EntityId'
|
|
patch:
|
|
tags:
|
|
- policy
|
|
operationId: patchApprovalRule
|
|
summary: Propose a rule change (dual-control)
|
|
x-required-scope: operator
|
|
parameters:
|
|
- $ref: '#/components/parameters/IfMatch'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ApprovalRuleCreate'
|
|
responses:
|
|
'202':
|
|
$ref: '#/components/responses/PendingApproval'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/policy/autonomy:
|
|
get:
|
|
tags:
|
|
- policy
|
|
operationId: getAutonomySettings
|
|
summary: Autonomy settings (kill-switch, never-auto-act list)
|
|
x-required-scope: viewer
|
|
responses:
|
|
'200':
|
|
description: Settings
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/AutonomySetting'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
patch:
|
|
tags:
|
|
- policy
|
|
operationId: patchAutonomySettings
|
|
summary: Propose autonomy changes (dual-control; kill-switch OFF is immediate)
|
|
description: 'Raising autonomy is dual-controlled (202 + approval). Lowering it —
|
|
|
|
setting `global.auto_act: "off"` or adding a never_auto_act key —
|
|
|
|
applies immediately (200): the kill-switch must never wait for an approval.
|
|
|
|
'
|
|
x-required-scope: operator
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Applied (restriction)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/AutonomySetting'
|
|
'202':
|
|
$ref: '#/components/responses/PendingApproval'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/knowledge/search:
|
|
get:
|
|
tags:
|
|
- knowledge
|
|
operationId: searchKnowledge
|
|
summary: Full-text search over knowledge entities (documents, runbooks)
|
|
x-required-scope: viewer
|
|
parameters:
|
|
- name: q
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- $ref: '#/components/parameters/Limit'
|
|
responses:
|
|
'200':
|
|
description: Hits
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/KnowledgeHit'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/knowledge/{entity_id}:
|
|
parameters:
|
|
- name: entity_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
get:
|
|
tags:
|
|
- knowledge
|
|
operationId: getEntityKnowledge
|
|
summary: All documents/runbooks linked to an entity
|
|
x-required-scope: viewer
|
|
responses:
|
|
'200':
|
|
description: Linked knowledge
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/KnowledgeHit'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/metrics:
|
|
get:
|
|
tags:
|
|
- observability
|
|
operationId: queryMetrics
|
|
summary: Query time-series metrics
|
|
x-required-scope: viewer
|
|
parameters:
|
|
- name: entity_id
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: metric
|
|
in: query
|
|
schema:
|
|
type: array
|
|
items:
|
|
type: string
|
|
style: form
|
|
explode: true
|
|
- name: rollup
|
|
in: query
|
|
schema:
|
|
type: string
|
|
enum:
|
|
- raw
|
|
- 1h
|
|
- 1d
|
|
- auto
|
|
default: auto
|
|
- $ref: '#/components/parameters/FromTime'
|
|
- $ref: '#/components/parameters/ToTime'
|
|
responses:
|
|
'200':
|
|
description: Metric series
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/MetricSeries'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/trends/{entity_id}:
|
|
parameters:
|
|
- name: entity_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
get:
|
|
tags:
|
|
- observability
|
|
operationId: getTrends
|
|
summary: Trend analysis for all metrics on an entity
|
|
x-required-scope: viewer
|
|
parameters:
|
|
- $ref: '#/components/parameters/FromTime'
|
|
- $ref: '#/components/parameters/ToTime'
|
|
responses:
|
|
'200':
|
|
description: Trends
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Trend'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/audit:
|
|
get:
|
|
tags:
|
|
- observability
|
|
operationId: queryAudit
|
|
summary: Audit log
|
|
x-required-scope: operator
|
|
parameters:
|
|
- name: actor_type
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: actor_id
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: entity_id
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: action
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: correlation_id
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- $ref: '#/components/parameters/FromTime'
|
|
- $ref: '#/components/parameters/ToTime'
|
|
- $ref: '#/components/parameters/Cursor'
|
|
- $ref: '#/components/parameters/Limit'
|
|
responses:
|
|
'200':
|
|
description: Audit entries (ts DESC)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/AuditEntry'
|
|
next_cursor:
|
|
type: string
|
|
nullable: true
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/events:
|
|
get:
|
|
tags:
|
|
- observability
|
|
operationId: queryEvents
|
|
summary: Historical events
|
|
x-required-scope: viewer
|
|
parameters:
|
|
- name: type
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: entity_id
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: severity
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: correlation_id
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- $ref: '#/components/parameters/FromTime'
|
|
- $ref: '#/components/parameters/ToTime'
|
|
- $ref: '#/components/parameters/Cursor'
|
|
- $ref: '#/components/parameters/Limit'
|
|
responses:
|
|
'200':
|
|
description: Events (ts DESC)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Event'
|
|
next_cursor:
|
|
type: string
|
|
nullable: true
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/events/stream:
|
|
get:
|
|
tags:
|
|
- observability
|
|
operationId: streamEvents
|
|
summary: Live event stream (SSE)
|
|
description: 'Server-Sent Events. Each event''s `id` is the event row id (resume
|
|
|
|
with `Last-Event-ID`), `event` is the event type, `data` is the JSON
|
|
|
|
Event object. Heartbeat comments every 15s. Best-effort delivery —
|
|
|
|
bounded per-subscriber buffer, drop-oldest (plan P6); use GET /events
|
|
|
|
to backfill.
|
|
|
|
'
|
|
x-required-scope: viewer
|
|
parameters:
|
|
- name: type
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Filter by event type prefix
|
|
- name: Last-Event-ID
|
|
in: header
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: SSE stream
|
|
content:
|
|
text/event-stream:
|
|
schema:
|
|
type: string
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/agent-activity:
|
|
get:
|
|
tags:
|
|
- observability
|
|
operationId: queryAgentActivity
|
|
summary: Agent behavior log
|
|
x-required-scope: viewer
|
|
parameters:
|
|
- name: agent_id
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: activity_type
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- name: entity_id
|
|
in: query
|
|
schema:
|
|
type: string
|
|
- $ref: '#/components/parameters/FromTime'
|
|
- $ref: '#/components/parameters/ToTime'
|
|
- $ref: '#/components/parameters/Cursor'
|
|
- $ref: '#/components/parameters/Limit'
|
|
responses:
|
|
'200':
|
|
description: Activity entries
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/AgentActivity'
|
|
next_cursor:
|
|
type: string
|
|
nullable: true
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/health:
|
|
get:
|
|
tags:
|
|
- observability
|
|
operationId: getFleetHealth
|
|
summary: Fleet health summary with trend indicators
|
|
x-required-scope: viewer
|
|
responses:
|
|
'200':
|
|
description: Health summary
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/HealthSummary'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/dashboard/summary:
|
|
get:
|
|
tags:
|
|
- observability
|
|
operationId: getDashboardSummary
|
|
summary: One-round-trip overview for the control room home page
|
|
x-required-scope: viewer
|
|
responses:
|
|
'200':
|
|
description: Dashboard summary
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/DashboardSummary'
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
/export:
|
|
get:
|
|
tags:
|
|
- system
|
|
operationId: exportSeeds
|
|
summary: Regenerate seed YAMLs from current DB state (DR / version control)
|
|
x-required-scope: operator
|
|
responses:
|
|
'200':
|
|
description: Seed bundle
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- ontology
|
|
- inventory
|
|
- policy
|
|
properties:
|
|
ontology:
|
|
type: string
|
|
description: YAML document
|
|
inventory:
|
|
type: string
|
|
description: YAML document
|
|
policy:
|
|
type: string
|
|
description: YAML document
|
|
default:
|
|
$ref: '#/components/responses/Problem'
|
|
components:
|
|
securitySchemes:
|
|
bearerAuth:
|
|
type: http
|
|
scheme: bearer
|
|
description: 'Operator/viewer: Authentik OIDC JWT (validated in-API — Caddy
|
|
|
|
forward-auth is defense-in-depth, not the source of truth).
|
|
|
|
Agent: static bearer token from Infisical (scope `agent`).
|
|
|
|
'
|
|
parameters:
|
|
EntityId:
|
|
name: id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: UUID or slug (e.g. `host:hubris`)
|
|
Cursor:
|
|
name: cursor
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Opaque cursor from a previous response's next_cursor
|
|
Limit:
|
|
name: limit
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
default: 50
|
|
maximum: 200
|
|
minimum: 1
|
|
FromTime:
|
|
name: from
|
|
in: query
|
|
schema:
|
|
type: string
|
|
format: date-time
|
|
ToTime:
|
|
name: to
|
|
in: query
|
|
schema:
|
|
type: string
|
|
format: date-time
|
|
IfMatch:
|
|
name: If-Match
|
|
in: header
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: ETag from a prior GET; 412 on version mismatch
|
|
IdempotencyKey:
|
|
name: Idempotency-Key
|
|
in: header
|
|
schema:
|
|
type: string
|
|
maxLength: 128
|
|
description: Client-generated key; replays within 24h return the original response
|
|
EntitySlug:
|
|
name: slug
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: Entity slug (e.g. `ws:mac-mini`, `lxc:caddy`)
|
|
headers:
|
|
ETag:
|
|
schema:
|
|
type: string
|
|
description: Resource version for If-Match
|
|
responses:
|
|
Problem:
|
|
description: Error (RFC 9457)
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: '#/components/schemas/Problem'
|
|
PendingApproval:
|
|
description: Change staged; a meta-approval was created (dual-control)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Approval'
|
|
SignalUpdated:
|
|
description: Updated signal
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Signal'
|
|
schemas:
|
|
Problem:
|
|
type: object
|
|
required:
|
|
- title
|
|
- status
|
|
properties:
|
|
type:
|
|
type: string
|
|
format: uri
|
|
default: about:blank
|
|
title:
|
|
type: string
|
|
status:
|
|
type: integer
|
|
detail:
|
|
type: string
|
|
instance:
|
|
type: string
|
|
errors:
|
|
type: array
|
|
description: Field-level validation errors (422)
|
|
items:
|
|
type: object
|
|
required:
|
|
- field
|
|
- reason
|
|
properties:
|
|
field:
|
|
type: string
|
|
reason:
|
|
type: string
|
|
Entity:
|
|
type: object
|
|
required:
|
|
- id
|
|
- slug
|
|
- type
|
|
- name
|
|
- version
|
|
- created_at
|
|
- updated_at
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
slug:
|
|
type: string
|
|
example: host:hubris
|
|
type:
|
|
type: string
|
|
name:
|
|
type: string
|
|
state:
|
|
type: string
|
|
nullable: true
|
|
attributes:
|
|
type: object
|
|
maintenance_until:
|
|
type: string
|
|
format: date-time
|
|
nullable: true
|
|
version:
|
|
type: integer
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
updated_at:
|
|
type: string
|
|
format: date-time
|
|
EntityCreate:
|
|
type: object
|
|
required:
|
|
- slug
|
|
- type
|
|
- name
|
|
properties:
|
|
slug:
|
|
type: string
|
|
type:
|
|
type: string
|
|
description: Must be a non-abstract entity type
|
|
name:
|
|
type: string
|
|
state:
|
|
type: string
|
|
description: Defaults to the lifecycle's default_state
|
|
attributes:
|
|
type: object
|
|
description: Validated against the type's attribute_schema
|
|
EntityPatch:
|
|
type: object
|
|
description: At least one of the fields must be present.
|
|
properties:
|
|
name:
|
|
type: string
|
|
state:
|
|
type: string
|
|
description: Target lifecycle state (transition validated)
|
|
attributes:
|
|
type: object
|
|
description: Merged; validated against attribute_schema
|
|
maintenance_until:
|
|
type: string
|
|
format: date-time
|
|
nullable: true
|
|
Relationship:
|
|
type: object
|
|
required:
|
|
- source
|
|
- target
|
|
- type
|
|
- valid_from
|
|
properties:
|
|
source:
|
|
type: string
|
|
description: Slug of source entity
|
|
target:
|
|
type: string
|
|
description: Slug of target entity
|
|
type:
|
|
type: string
|
|
attributes:
|
|
type: object
|
|
nullable: true
|
|
valid_from:
|
|
type: string
|
|
format: date-time
|
|
valid_to:
|
|
type: string
|
|
format: date-time
|
|
nullable: true
|
|
RelationshipCreate:
|
|
type: object
|
|
required:
|
|
- source
|
|
- target
|
|
- type
|
|
properties:
|
|
source:
|
|
type: string
|
|
description: UUID or slug
|
|
target:
|
|
type: string
|
|
description: UUID or slug
|
|
type:
|
|
type: string
|
|
attributes:
|
|
type: object
|
|
GraphView:
|
|
type: object
|
|
required:
|
|
- nodes
|
|
- edges
|
|
properties:
|
|
nodes:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Entity'
|
|
edges:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Relationship'
|
|
truncated:
|
|
type: boolean
|
|
description: True if node cap was hit
|
|
health:
|
|
type: object
|
|
description: entity id -> health, present when include=status was requested
|
|
additionalProperties:
|
|
type: string
|
|
enum:
|
|
- healthy
|
|
- degraded
|
|
- down
|
|
- unknown
|
|
EntityType:
|
|
type: object
|
|
required:
|
|
- name
|
|
- domain
|
|
- layer
|
|
- is_abstract
|
|
- status
|
|
properties:
|
|
name:
|
|
type: string
|
|
parent_type:
|
|
type: string
|
|
nullable: true
|
|
is_abstract:
|
|
type: boolean
|
|
domain:
|
|
type: string
|
|
layer:
|
|
type: string
|
|
enum:
|
|
- meta
|
|
- infrastructure
|
|
- governance
|
|
- cognition
|
|
description:
|
|
type: string
|
|
lifecycle_id:
|
|
type: string
|
|
nullable: true
|
|
attribute_schema:
|
|
type: object
|
|
description: JSON Schema
|
|
nullable: true
|
|
schema_version:
|
|
type: integer
|
|
status:
|
|
type: string
|
|
enum:
|
|
- active
|
|
- deprecated
|
|
version:
|
|
type: integer
|
|
EntityTypeCreate:
|
|
type: object
|
|
required:
|
|
- name
|
|
- domain
|
|
- layer
|
|
properties:
|
|
name:
|
|
type: string
|
|
parent_type:
|
|
type: string
|
|
is_abstract:
|
|
type: boolean
|
|
default: false
|
|
domain:
|
|
type: string
|
|
layer:
|
|
type: string
|
|
enum:
|
|
- infrastructure
|
|
- governance
|
|
- cognition
|
|
description:
|
|
type: string
|
|
lifecycle_id:
|
|
type: string
|
|
attribute_schema:
|
|
type: object
|
|
EntityTypePatch:
|
|
type: object
|
|
properties:
|
|
description:
|
|
type: string
|
|
attribute_schema:
|
|
type: object
|
|
status:
|
|
type: string
|
|
enum:
|
|
- active
|
|
- deprecated
|
|
RelationshipType:
|
|
type: object
|
|
required:
|
|
- name
|
|
- source_type
|
|
- target_type
|
|
- cardinality
|
|
properties:
|
|
name:
|
|
type: string
|
|
inverse:
|
|
type: string
|
|
nullable: true
|
|
source_type:
|
|
type: string
|
|
description: May be abstract
|
|
target_type:
|
|
type: string
|
|
description: May be abstract
|
|
cardinality:
|
|
type: string
|
|
enum:
|
|
- one-to-one
|
|
- one-to-many
|
|
- many-to-one
|
|
- many-to-many
|
|
description:
|
|
type: string
|
|
LifecycleDef:
|
|
type: object
|
|
required:
|
|
- id
|
|
- states
|
|
- default_state
|
|
- transitions
|
|
properties:
|
|
id:
|
|
type: string
|
|
states:
|
|
type: array
|
|
items:
|
|
type: string
|
|
default_state:
|
|
type: string
|
|
terminal_states:
|
|
type: array
|
|
items:
|
|
type: string
|
|
transitions:
|
|
type: object
|
|
description: '{from: {to: {requires: [named-check, ...]}}}'
|
|
Signal:
|
|
type: object
|
|
required:
|
|
- id
|
|
- slug
|
|
- kind
|
|
- severity
|
|
- state
|
|
- occurrence_count
|
|
- first_seen_at
|
|
- last_seen_at
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
slug:
|
|
type: string
|
|
kind:
|
|
type: string
|
|
example: service-down
|
|
severity:
|
|
type: string
|
|
enum:
|
|
- info
|
|
- warning
|
|
- critical
|
|
state:
|
|
type: string
|
|
enum:
|
|
- raised
|
|
- acknowledged
|
|
- acting
|
|
- muted
|
|
- resolved
|
|
- failed
|
|
target:
|
|
type: string
|
|
description: Slug of the entity this concerns
|
|
nullable: true
|
|
check_id:
|
|
type: string
|
|
nullable: true
|
|
evidence:
|
|
type: string
|
|
nullable: true
|
|
likely_cause:
|
|
type: string
|
|
nullable: true
|
|
occurrence_count:
|
|
type: integer
|
|
flap_count:
|
|
type: integer
|
|
hold_down_until:
|
|
type: string
|
|
format: date-time
|
|
nullable: true
|
|
mute_until:
|
|
type: string
|
|
format: date-time
|
|
nullable: true
|
|
first_seen_at:
|
|
type: string
|
|
format: date-time
|
|
last_seen_at:
|
|
type: string
|
|
format: date-time
|
|
Check:
|
|
type: object
|
|
required:
|
|
- id
|
|
- slug
|
|
- kind
|
|
- interval_s
|
|
- timeout_s
|
|
- enabled
|
|
- version
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
slug:
|
|
type: string
|
|
kind:
|
|
type: string
|
|
enum:
|
|
- http
|
|
- tcp
|
|
- disk
|
|
- cert-expiry
|
|
- drift
|
|
- ssh-script
|
|
target:
|
|
type: string
|
|
description: Entity slug (instance-scoped)
|
|
nullable: true
|
|
target_type:
|
|
type: string
|
|
description: Entity type (type-scoped)
|
|
nullable: true
|
|
config:
|
|
type: object
|
|
description: Validated per-kind
|
|
interval_s:
|
|
type: integer
|
|
timeout_s:
|
|
type: integer
|
|
zone:
|
|
type: string
|
|
nullable: true
|
|
enabled:
|
|
type: boolean
|
|
version:
|
|
type: integer
|
|
CheckCreate:
|
|
type: object
|
|
required:
|
|
- slug
|
|
- kind
|
|
properties:
|
|
slug:
|
|
type: string
|
|
kind:
|
|
type: string
|
|
enum:
|
|
- http
|
|
- tcp
|
|
- disk
|
|
- cert-expiry
|
|
- drift
|
|
- ssh-script
|
|
target:
|
|
type: string
|
|
target_type:
|
|
type: string
|
|
config:
|
|
type: object
|
|
interval_s:
|
|
type: integer
|
|
default: 600
|
|
timeout_s:
|
|
type: integer
|
|
default: 10
|
|
zone:
|
|
type: string
|
|
enabled:
|
|
type: boolean
|
|
default: true
|
|
CheckPatch:
|
|
type: object
|
|
properties:
|
|
config:
|
|
type: object
|
|
interval_s:
|
|
type: integer
|
|
timeout_s:
|
|
type: integer
|
|
enabled:
|
|
type: boolean
|
|
Execution:
|
|
type: object
|
|
required:
|
|
- id
|
|
- slug
|
|
- action
|
|
- risk_class
|
|
- status
|
|
- correlation_id
|
|
- created_at
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
slug:
|
|
type: string
|
|
target:
|
|
type: string
|
|
nullable: true
|
|
action:
|
|
type: string
|
|
risk_class:
|
|
type: string
|
|
status:
|
|
type: string
|
|
enum:
|
|
- proposed
|
|
- approved
|
|
- auto_approved
|
|
- denied
|
|
- expired
|
|
- executing
|
|
- verifying
|
|
- verified
|
|
- failed
|
|
- timed_out
|
|
- cancelled
|
|
- rolled_back
|
|
- rollback_failed
|
|
classification_id:
|
|
type: string
|
|
nullable: true
|
|
signal_id:
|
|
type: string
|
|
nullable: true
|
|
approval_id:
|
|
type: string
|
|
nullable: true
|
|
agent_id:
|
|
type: string
|
|
nullable: true
|
|
skill_id:
|
|
type: string
|
|
nullable: true
|
|
skill_version:
|
|
type: integer
|
|
nullable: true
|
|
params:
|
|
type: object
|
|
description: Skill params (validated against params_schema)
|
|
result:
|
|
type: object
|
|
nullable: true
|
|
duration_ms:
|
|
type: integer
|
|
nullable: true
|
|
verified:
|
|
type: boolean
|
|
correlation_id:
|
|
type: string
|
|
started_at:
|
|
type: string
|
|
format: date-time
|
|
nullable: true
|
|
completed_at:
|
|
type: string
|
|
format: date-time
|
|
nullable: true
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
ExecutionRequest:
|
|
type: object
|
|
required:
|
|
- target
|
|
- action
|
|
properties:
|
|
target:
|
|
type: string
|
|
description: Entity UUID or slug
|
|
action:
|
|
type: string
|
|
example: restart
|
|
params:
|
|
type: object
|
|
signal_id:
|
|
type: string
|
|
description: Signal that motivated this (optional)
|
|
reason:
|
|
type: string
|
|
Classification:
|
|
type: object
|
|
required:
|
|
- id
|
|
- action
|
|
- risk_class
|
|
- route
|
|
- reasoning
|
|
- correlation_id
|
|
- created_at
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
signal_id:
|
|
type: string
|
|
nullable: true
|
|
target:
|
|
type: string
|
|
nullable: true
|
|
action:
|
|
type: string
|
|
recommended_action:
|
|
type: object
|
|
nullable: true
|
|
risk_class:
|
|
type: string
|
|
route:
|
|
type: string
|
|
enum:
|
|
- auto-act
|
|
- escalate
|
|
- hold
|
|
blast_radius:
|
|
type: array
|
|
items:
|
|
type: string
|
|
pattern_confidence:
|
|
type: number
|
|
nullable: true
|
|
skill_id:
|
|
type: string
|
|
nullable: true
|
|
autonomy_check:
|
|
type: string
|
|
reasoning:
|
|
type: object
|
|
correlation_id:
|
|
type: string
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
Approval:
|
|
type: object
|
|
required:
|
|
- id
|
|
- slug
|
|
- action
|
|
- risk_class
|
|
- kind
|
|
- status
|
|
- expires_at
|
|
- created_at
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
slug:
|
|
type: string
|
|
subject:
|
|
type: string
|
|
description: Entity slug the approval concerns
|
|
nullable: true
|
|
action:
|
|
type: string
|
|
risk_class:
|
|
type: string
|
|
kind:
|
|
type: string
|
|
enum:
|
|
- execution
|
|
- policy-change
|
|
- pattern-activation
|
|
payload:
|
|
type: object
|
|
description: e.g. proposed policy diff
|
|
nullable: true
|
|
status:
|
|
type: string
|
|
enum:
|
|
- pending
|
|
- approved
|
|
- denied
|
|
- expired
|
|
- revoked
|
|
expires_at:
|
|
type: string
|
|
format: date-time
|
|
decided_at:
|
|
type: string
|
|
format: date-time
|
|
nullable: true
|
|
decided_by:
|
|
type: string
|
|
nullable: true
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
Pattern:
|
|
type: object
|
|
required:
|
|
- id
|
|
- slug
|
|
- applies_type
|
|
- action
|
|
- pattern
|
|
- confidence
|
|
- evidence_count
|
|
- status
|
|
- version
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
slug:
|
|
type: string
|
|
applies_type:
|
|
type: string
|
|
action:
|
|
type: string
|
|
pattern:
|
|
type: string
|
|
confidence:
|
|
type: number
|
|
description: Wilson lower bound, capped by evidence_count/5
|
|
evidence_count:
|
|
type: integer
|
|
success_count:
|
|
type: integer
|
|
failure_count:
|
|
type: integer
|
|
status:
|
|
type: string
|
|
enum:
|
|
- hypothesized
|
|
- validated
|
|
- active
|
|
- deprecated
|
|
- invalidated
|
|
quarantined:
|
|
type: boolean
|
|
version:
|
|
type: integer
|
|
last_validated_at:
|
|
type: string
|
|
format: date-time
|
|
nullable: true
|
|
Skill:
|
|
type: object
|
|
required:
|
|
- id
|
|
- slug
|
|
- name
|
|
- version
|
|
- action
|
|
- status
|
|
- procedure
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
slug:
|
|
type: string
|
|
name:
|
|
type: string
|
|
version:
|
|
type: integer
|
|
action:
|
|
type: string
|
|
applies_type:
|
|
type: string
|
|
nullable: true
|
|
procedure:
|
|
type: object
|
|
description: Structured steps/verify/rollback/params (plan R3-9)
|
|
required:
|
|
- steps
|
|
- verify
|
|
properties:
|
|
params_schema:
|
|
type: object
|
|
steps:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/SkillStep'
|
|
verify:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/SkillStep'
|
|
rollback:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/SkillStep'
|
|
expected_duration_s:
|
|
type: integer
|
|
known_failure_modes:
|
|
type: array
|
|
items:
|
|
type: string
|
|
pattern_ids:
|
|
type: array
|
|
items:
|
|
type: string
|
|
status:
|
|
type: string
|
|
enum:
|
|
- drafted
|
|
- tested
|
|
- active
|
|
- refined
|
|
- failed
|
|
- deprecated
|
|
success_rate:
|
|
type: number
|
|
nullable: true
|
|
changed_by:
|
|
type: string
|
|
nullable: true
|
|
change_reason:
|
|
type: string
|
|
nullable: true
|
|
last_used_at:
|
|
type: string
|
|
format: date-time
|
|
nullable: true
|
|
SkillStep:
|
|
type: object
|
|
required:
|
|
- runner
|
|
- command
|
|
properties:
|
|
name:
|
|
type: string
|
|
runner:
|
|
type: string
|
|
enum:
|
|
- ssh
|
|
- http
|
|
- internal
|
|
target:
|
|
type: string
|
|
description: Go template over params
|
|
command:
|
|
type: string
|
|
description: Go template over params
|
|
timeout_s:
|
|
type: integer
|
|
default: 60
|
|
expect:
|
|
type: object
|
|
properties:
|
|
exit_code:
|
|
type: integer
|
|
stdout_contains:
|
|
type: string
|
|
retry:
|
|
type: object
|
|
properties:
|
|
attempts:
|
|
type: integer
|
|
delay_s:
|
|
type: integer
|
|
RiskClass:
|
|
type: object
|
|
required:
|
|
- name
|
|
- approval_required
|
|
- autonomy_allowed
|
|
properties:
|
|
name:
|
|
type: string
|
|
description:
|
|
type: string
|
|
approval_required:
|
|
type: string
|
|
enum:
|
|
- none
|
|
- operator
|
|
- operator_confirmed
|
|
autonomy_allowed:
|
|
type: boolean
|
|
ApprovalRule:
|
|
type: object
|
|
required:
|
|
- id
|
|
- action
|
|
- risk_class
|
|
- autonomy_level
|
|
- version
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
entity_type:
|
|
type: string
|
|
description: May be abstract (inherits down)
|
|
nullable: true
|
|
action:
|
|
type: string
|
|
risk_class:
|
|
type: string
|
|
autonomy_level:
|
|
type: string
|
|
enum:
|
|
- auto
|
|
- escalate
|
|
- never
|
|
scope_entity:
|
|
type: string
|
|
description: Entity slug for per-entity overrides
|
|
nullable: true
|
|
version:
|
|
type: integer
|
|
ApprovalRuleCreate:
|
|
type: object
|
|
required:
|
|
- action
|
|
- risk_class
|
|
- autonomy_level
|
|
properties:
|
|
entity_type:
|
|
type: string
|
|
action:
|
|
type: string
|
|
risk_class:
|
|
type: string
|
|
autonomy_level:
|
|
type: string
|
|
enum:
|
|
- auto
|
|
- escalate
|
|
- never
|
|
scope_entity:
|
|
type: string
|
|
AutonomySetting:
|
|
type: object
|
|
required:
|
|
- key
|
|
- value
|
|
- version
|
|
properties:
|
|
key:
|
|
type: string
|
|
example: global.auto_act
|
|
value:
|
|
type: string
|
|
version:
|
|
type: integer
|
|
updated_at:
|
|
type: string
|
|
format: date-time
|
|
KnowledgeHit:
|
|
type: object
|
|
required:
|
|
- id
|
|
- slug
|
|
- type
|
|
- title
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
slug:
|
|
type: string
|
|
type:
|
|
type: string
|
|
enum:
|
|
- document
|
|
- runbook
|
|
- investigation
|
|
title:
|
|
type: string
|
|
source_path:
|
|
type: string
|
|
nullable: true
|
|
snippet:
|
|
type: string
|
|
description: Highlighted match context
|
|
nullable: true
|
|
linked_entities:
|
|
type: array
|
|
items:
|
|
type: string
|
|
rank:
|
|
type: number
|
|
nullable: true
|
|
MetricSeries:
|
|
type: object
|
|
required:
|
|
- entity_id
|
|
- metric
|
|
- rollup
|
|
- samples
|
|
properties:
|
|
entity_id:
|
|
type: string
|
|
metric:
|
|
type: string
|
|
rollup:
|
|
type: string
|
|
enum:
|
|
- raw
|
|
- 1h
|
|
- 1d
|
|
samples:
|
|
type: array
|
|
items:
|
|
type: object
|
|
required:
|
|
- ts
|
|
properties:
|
|
ts:
|
|
type: string
|
|
format: date-time
|
|
value:
|
|
type: number
|
|
description: Raw sample value
|
|
nullable: true
|
|
avg:
|
|
type: number
|
|
nullable: true
|
|
min:
|
|
type: number
|
|
nullable: true
|
|
max:
|
|
type: number
|
|
nullable: true
|
|
count:
|
|
type: integer
|
|
nullable: true
|
|
trend:
|
|
$ref: '#/components/schemas/Trend'
|
|
Trend:
|
|
type: object
|
|
required:
|
|
- metric
|
|
- direction
|
|
properties:
|
|
metric:
|
|
type: string
|
|
direction:
|
|
type: string
|
|
enum:
|
|
- improving
|
|
- degrading
|
|
- stable
|
|
- unknown
|
|
slope:
|
|
type: number
|
|
description: Linear fit per day
|
|
nullable: true
|
|
anomaly:
|
|
type: boolean
|
|
forecast:
|
|
type: number
|
|
description: Simple linear projection, 7d out
|
|
nullable: true
|
|
AuditEntry:
|
|
type: object
|
|
required:
|
|
- id
|
|
- ts
|
|
- actor_type
|
|
- action
|
|
properties:
|
|
id:
|
|
type: integer
|
|
ts:
|
|
type: string
|
|
format: date-time
|
|
actor_type:
|
|
type: string
|
|
enum:
|
|
- agent
|
|
- operator
|
|
- system
|
|
- scheduler
|
|
actor_id:
|
|
type: string
|
|
nullable: true
|
|
action:
|
|
type: string
|
|
entity_id:
|
|
type: string
|
|
nullable: true
|
|
method:
|
|
type: string
|
|
nullable: true
|
|
path:
|
|
type: string
|
|
nullable: true
|
|
status_code:
|
|
type: integer
|
|
nullable: true
|
|
detail:
|
|
type: object
|
|
source_ip:
|
|
type: string
|
|
nullable: true
|
|
correlation_id:
|
|
type: string
|
|
nullable: true
|
|
Event:
|
|
type: object
|
|
required:
|
|
- id
|
|
- ts
|
|
- type
|
|
- severity
|
|
- source
|
|
properties:
|
|
id:
|
|
type: integer
|
|
ts:
|
|
type: string
|
|
format: date-time
|
|
type:
|
|
type: string
|
|
example: signal.raised
|
|
entity_id:
|
|
type: string
|
|
nullable: true
|
|
severity:
|
|
type: string
|
|
enum:
|
|
- info
|
|
- warning
|
|
- critical
|
|
source:
|
|
type: string
|
|
data:
|
|
type: object
|
|
correlation_id:
|
|
type: string
|
|
nullable: true
|
|
AgentActivity:
|
|
type: object
|
|
required:
|
|
- id
|
|
- ts
|
|
- agent_id
|
|
- activity_type
|
|
properties:
|
|
id:
|
|
type: integer
|
|
ts:
|
|
type: string
|
|
format: date-time
|
|
agent_id:
|
|
type: string
|
|
session_id:
|
|
type: string
|
|
nullable: true
|
|
activity_type:
|
|
type: string
|
|
enum:
|
|
- tool_call
|
|
- reasoning
|
|
- decision
|
|
- mcp_query
|
|
- escalation
|
|
tool_name:
|
|
type: string
|
|
nullable: true
|
|
entity_id:
|
|
type: string
|
|
nullable: true
|
|
input_summary:
|
|
type: string
|
|
nullable: true
|
|
output_summary:
|
|
type: string
|
|
nullable: true
|
|
duration_ms:
|
|
type: integer
|
|
nullable: true
|
|
token_count:
|
|
type: integer
|
|
nullable: true
|
|
success:
|
|
type: boolean
|
|
nullable: true
|
|
correlation_id:
|
|
type: string
|
|
nullable: true
|
|
HealthSummary:
|
|
type: object
|
|
required:
|
|
- summary
|
|
- entities
|
|
properties:
|
|
summary:
|
|
type: object
|
|
required:
|
|
- healthy
|
|
- degraded
|
|
- down
|
|
- unknown
|
|
properties:
|
|
healthy:
|
|
type: integer
|
|
degraded:
|
|
type: integer
|
|
down:
|
|
type: integer
|
|
unknown:
|
|
type: integer
|
|
entities:
|
|
type: array
|
|
items:
|
|
type: object
|
|
required:
|
|
- slug
|
|
- type
|
|
- health
|
|
properties:
|
|
slug:
|
|
type: string
|
|
type:
|
|
type: string
|
|
health:
|
|
type: string
|
|
enum:
|
|
- healthy
|
|
- degraded
|
|
- down
|
|
- unknown
|
|
trend:
|
|
type: string
|
|
enum:
|
|
- improving
|
|
- degrading
|
|
- stable
|
|
- unknown
|
|
nullable: true
|
|
last_check_at:
|
|
type: string
|
|
format: date-time
|
|
nullable: true
|
|
DashboardSummary:
|
|
type: object
|
|
required:
|
|
- entities_by_type
|
|
- entities_by_state
|
|
- health
|
|
- signals_by_severity
|
|
- approvals_pending
|
|
- executions_by_state
|
|
- event_rate
|
|
properties:
|
|
entities_by_type:
|
|
type: object
|
|
description: entity counts keyed by type
|
|
additionalProperties:
|
|
type: integer
|
|
entities_by_state:
|
|
type: object
|
|
description: entity counts keyed by state
|
|
additionalProperties:
|
|
type: integer
|
|
health:
|
|
type: object
|
|
required:
|
|
- healthy
|
|
- degraded
|
|
- down
|
|
- unknown
|
|
properties:
|
|
healthy:
|
|
type: integer
|
|
degraded:
|
|
type: integer
|
|
down:
|
|
type: integer
|
|
unknown:
|
|
type: integer
|
|
signals_by_severity:
|
|
type: object
|
|
description: open (non-resolved) signal counts keyed by severity
|
|
additionalProperties:
|
|
type: integer
|
|
approvals_pending:
|
|
type: integer
|
|
executions_by_state:
|
|
type: object
|
|
description: execution counts keyed by state, last 24h
|
|
additionalProperties:
|
|
type: integer
|
|
event_rate:
|
|
type: array
|
|
description: event counts bucketed by 5-minute interval, most recent last
|
|
items:
|
|
type: object
|
|
required:
|
|
- bucket
|
|
- count
|
|
properties:
|
|
bucket:
|
|
type: string
|
|
format: date-time
|
|
count:
|
|
type: integer
|
|
EnrollRequest:
|
|
type: object
|
|
required:
|
|
- slug
|
|
properties:
|
|
slug:
|
|
type: string
|
|
description: Entity slug (e.g. ws:new-laptop)
|
|
hostname:
|
|
type: string
|
|
description: Actual hostname of the enrolling machine
|
|
mesh_ip:
|
|
type: string
|
|
description: Source mesh IP for identity validation
|
|
EnrollResponse:
|
|
type: object
|
|
required:
|
|
- age_public_key
|
|
- age_private_key
|
|
- infisical_client_id
|
|
- infisical_client_secret
|
|
properties:
|
|
age_public_key:
|
|
type: string
|
|
description: age1... public key for SOPS recipients
|
|
age_private_key:
|
|
type: string
|
|
description: AGE-SECRET-KEY-... for local decryption
|
|
infisical_client_id:
|
|
type: string
|
|
description: Infisical UniversalAuth client ID
|
|
infisical_client_secret:
|
|
type: string
|
|
description: Infisical UniversalAuth client secret
|
|
machine_identity_token:
|
|
type: string
|
|
description: Infisical machine identity access token
|
|
ClientContext:
|
|
type: object
|
|
required:
|
|
- version
|
|
properties:
|
|
version:
|
|
type: integer
|
|
description: Monotonic context version number
|
|
agent_files_changed:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Paths of agent instruction files that changed
|
|
sops_config_changed:
|
|
type: boolean
|
|
description: True if .sops.yaml recipients changed
|
|
tools_changed:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Paths of tools/*.setup.sh that changed
|
|
since:
|
|
type: string
|
|
format: date-time
|
|
description: Timestamp for the next poll request
|
|
ClientSecrets:
|
|
type: object
|
|
required:
|
|
- keys
|
|
properties:
|
|
keys:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Infisical secret keys accessible to this client
|
|
ProvisionRequest:
|
|
type: object
|
|
required:
|
|
- slug
|
|
- type
|
|
- name
|
|
- host
|
|
properties:
|
|
slug:
|
|
type: string
|
|
description: e.g. lxc:jellyfin
|
|
type:
|
|
type: string
|
|
description: Must be lxc, vm, or docker-container
|
|
name:
|
|
type: string
|
|
description: Human-readable name
|
|
host:
|
|
type: string
|
|
description: Slug of the Proxmox host (e.g. host:hubris)
|
|
attributes:
|
|
type: object
|
|
description: VMID, cores, ram_mb, disk_gb, ip, template, mounts, services
|
|
ProvisionResponse:
|
|
type: object
|
|
required:
|
|
- entity
|
|
- execution_id
|
|
properties:
|
|
entity:
|
|
$ref: '#/components/schemas/Entity'
|
|
execution_id:
|
|
type: string
|
|
format: uuid
|
|
description: Execution ID to track provisioning progress
|
|
ProvisionStatus:
|
|
type: object
|
|
required:
|
|
- slug
|
|
- state
|
|
- steps
|
|
properties:
|
|
slug:
|
|
type: string
|
|
state:
|
|
type: string
|
|
description: Current entity state
|
|
steps:
|
|
type: array
|
|
items:
|
|
type: object
|
|
required:
|
|
- step
|
|
- status
|
|
properties:
|
|
step:
|
|
type: string
|
|
status:
|
|
type: string
|
|
enum:
|
|
- pending
|
|
- running
|
|
- ok
|
|
- failed
|
|
- skipped
|
|
error_message:
|
|
type: string
|
|
nullable: true
|
|
started_at:
|
|
type: string
|
|
format: date-time
|
|
nullable: true
|
|
finished_at:
|
|
type: string
|
|
format: date-time
|
|
nullable: true
|
|
error:
|
|
type: string
|
|
nullable: true
|
|
description: Overall error if provisioning failed
|