318 lines
18 KiB
YAML
318 lines
18 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: Scenario Execution Engine API
|
|
version: 0.1.0
|
|
description: Start and manage execution of dashboard test scenario runs (044).
|
|
paths:
|
|
/api/scenario-runs:
|
|
post:
|
|
operationId: scenarioRun.start
|
|
summary: Start a scenario run pinned to an immutable revision
|
|
security: [{ bearerAuth: [] }]
|
|
parameters:
|
|
- { name: Idempotency-Key, in: header, required: true, schema: { type: string } }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [scenario_id, revision_id, environment_id]
|
|
properties:
|
|
scenario_id: { type: string }
|
|
revision_id: { type: string }
|
|
environment_id: { type: string }
|
|
params: { type: object, description: "Launch values; server validates against 038 ParameterDefinition and persists immutable ParameterBinding[]" }
|
|
requested_target_reference: { type: object, description: "User-selected release/target; server verifies it matches the captured TargetSnapshot" }
|
|
baseline_set: { type: string }
|
|
execution_toggles: { type: object, description: "Optional evidence only (diagnostic screenshots, verbose logs, optional VLM). Mandatory steps cannot be disabled." }
|
|
responses:
|
|
"201": { description: ScenarioRun created (queued or pending_approval), content: { application/json: { schema: { $ref: "#/components/schemas/ScenarioRun" } } } }
|
|
"403": { description: Permission denied; PROD approval creates pending_approval run rather than returning 403 }
|
|
"409": { description: Stale revision or IDEMPOTENCY_KEY_REUSED with a different canonical request }
|
|
/api/scenarios/{scenario_id}/runs:
|
|
get:
|
|
operationId: scenarioRun.history
|
|
summary: Scenario run history (for 045 RunHistoryList)
|
|
security: [{ bearerAuth: [] }]
|
|
parameters: [{ name: scenario_id, in: path, required: true, schema: { type: string } }]
|
|
responses:
|
|
"200":
|
|
description: Run history
|
|
content:
|
|
application/json:
|
|
schema: { type: array, items: { $ref: "#/components/schemas/ScenarioRun" } }
|
|
/api/scenario-runs/{run_id}/result:
|
|
get:
|
|
operationId: scenarioRun.result
|
|
summary: Final result with aggregation + provenance
|
|
security: [{ bearerAuth: [] }]
|
|
parameters: [{ name: run_id, in: path, required: true, schema: { type: string } }]
|
|
responses: { "200": { description: ScenarioExecutionResult, content: { application/json: { schema: { $ref: "#/components/schemas/ScenarioExecutionResult" } } } } }
|
|
/api/scenario-runs/compare:
|
|
get:
|
|
operationId: scenarioRun.compare
|
|
summary: Compare two runs (per-step deltas, revision-diff warning)
|
|
security: [{ bearerAuth: [] }]
|
|
parameters:
|
|
- { name: a, in: query, required: true, schema: { type: string } }
|
|
- { name: b, in: query, required: true, schema: { type: string } }
|
|
responses: { "200": { description: RunComparison, content: { application/json: { schema: { $ref: "#/components/schemas/RunComparison" } } } } }
|
|
/api/scenario-runs/{run_id}/steps/{logical_step_id}/retry:
|
|
post:
|
|
operationId: scenarioRun.retryStep
|
|
summary: Retry a failed step + invalidated downstream closure
|
|
security: [{ bearerAuth: [] }]
|
|
parameters:
|
|
- { name: run_id, in: path, required: true, schema: { type: string } }
|
|
- { name: logical_step_id, in: path, required: true, schema: { type: string } }
|
|
responses:
|
|
"200": { description: Retried; downstream closure re-run }
|
|
"409": { description: Run advanced beyond step; closure re-run rejected }
|
|
/api/scenario-runs/{run_id}:
|
|
get:
|
|
operationId: scenarioRun.detail
|
|
summary: Get a run by id (recoverable)
|
|
security: [{ bearerAuth: [] }]
|
|
parameters: [{ name: run_id, in: path, required: true, schema: { type: string } }]
|
|
responses: { "200": { description: Run detail, content: { application/json: { schema: { $ref: "#/components/schemas/ScenarioRun" } } } } }
|
|
/api/scenario-runs/{run_id}/events:
|
|
get:
|
|
operationId: scenarioRun.events
|
|
summary: SSE stream of step events (replayable via Last-Event-ID)
|
|
security: [{ bearerAuth: [] }]
|
|
parameters:
|
|
- { name: run_id, in: path, required: true, schema: { type: string } }
|
|
- { name: Last-Event-ID, in: header, schema: { type: integer }, description: "sequence to replay from" }
|
|
responses:
|
|
"200":
|
|
content: { text/event-stream: { schema: { $ref: "#/components/schemas/ScenarioRunEvent" } } }
|
|
/api/scenario-runs/{run_id}/cancel:
|
|
post:
|
|
operationId: scenarioRun.cancel
|
|
summary: Cancel a run (bounded drain)
|
|
security: [{ bearerAuth: [] }]
|
|
parameters: [{ name: run_id, in: path, required: true, schema: { type: string } }]
|
|
responses: { "200": { description: Cancelled } }
|
|
/api/scenario-runs/{run_id}/resume:
|
|
post:
|
|
operationId: scenarioRun.resume
|
|
summary: Resume a paused run from resume token
|
|
security: [{ bearerAuth: [] }]
|
|
parameters: [{ name: run_id, in: path, required: true, schema: { type: string } }]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [resume_token, resume_reason]
|
|
properties:
|
|
resume_token: { type: string }
|
|
resume_reason: { type: string, enum: [worker_recovered, infrastructure_pause_resolved] }
|
|
responses: { "200": { description: Infrastructure pause resumed }, "409": { description: Cannot resume HumanCheckpoint or stale token } }
|
|
/api/scenario-runs/{run_id}/human/decision:
|
|
post:
|
|
operationId: scenarioRun.humanDecision
|
|
summary: Resolve a HumanCheckpoint (observation disposition)
|
|
security: [{ bearerAuth: [] }]
|
|
parameters: [{ name: run_id, in: path, required: true, schema: { type: string } }]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [checkpoint_id, decision_version, disposition]
|
|
properties:
|
|
checkpoint_id: { type: string }
|
|
decision_version: { type: integer }
|
|
disposition: { type: string, enum: [confirm, false_positive, pass, fail, inconclusive] }
|
|
comment: { type: string }
|
|
responses: { "200": { description: Checkpoint consumed; step outcome recorded; runner resumed internally }, "409": { description: Checkpoint already decided, expired, or version conflict } }
|
|
components:
|
|
securitySchemes:
|
|
bearerAuth: { type: http, scheme: bearer }
|
|
schemas:
|
|
ScenarioRun:
|
|
type: object
|
|
properties:
|
|
id: { type: string }
|
|
scenario_id: { type: string }
|
|
scenario_revision_id: { type: string }
|
|
environment_id: { type: string }
|
|
status: { type: string, enum: [pending_approval, queued, running, waiting_human, blocked, cancel_requested, cancelled, passed, failed, inconclusive] }
|
|
parameter_bindings: { type: array, items: { $ref: "#/components/schemas/ParameterBinding" } }
|
|
target_snapshot: { $ref: "#/components/schemas/TargetSnapshot" }
|
|
execution_principal_fingerprint: { type: string }
|
|
analytics_context_key: { type: string, description: "Server-derived immutable analytics grouping key" }
|
|
verification_program_hash: { type: string }
|
|
action_registry_version: { type: string }
|
|
step_runs: { type: array, items: { $ref: "#/components/schemas/ScenarioStepRun" } }
|
|
ScenarioStepRun:
|
|
type: object
|
|
properties:
|
|
id: { type: string }
|
|
logical_step_id: { type: string }
|
|
step_position: { type: integer }
|
|
attempt: { type: integer }
|
|
status: { type: string }
|
|
outputs: { type: object }
|
|
artifact_refs: { type: array, items: { type: string } }
|
|
error_code: { type: string, nullable: true }
|
|
step_outcome: { $ref: "#/components/schemas/StepOutcome" }
|
|
agent_evaluations: { type: array, items: { $ref: "#/components/schemas/AgentEvaluationSummary" } }
|
|
ParameterBinding:
|
|
type: object
|
|
required: [parameter_name, resolved_value, source, resolved_at]
|
|
properties:
|
|
parameter_name: { type: string }
|
|
resolved_value: {}
|
|
source: { type: string, enum: [launch_input, default, schedule, trigger] }
|
|
resolved_at: { type: string, format: date-time }
|
|
TargetSnapshot:
|
|
type: object
|
|
required: [environment_id, dashboard_fingerprint, dataset_lineage_fingerprint, captured_at]
|
|
properties:
|
|
environment_id: { type: string }
|
|
dashboard_release_id: { type: [string, "null"] }
|
|
dashboard_fingerprint: { type: string }
|
|
dataset_lineage_fingerprint: { type: string }
|
|
captured_at: { type: string, format: date-time }
|
|
ScenarioExecutionResult:
|
|
type: object
|
|
required: [run_id, status, step_counts, provenance, failures]
|
|
properties:
|
|
run_id: { type: string }
|
|
status: { type: string }
|
|
step_counts: { type: object, additionalProperties: { type: integer } }
|
|
failures: { type: array, items: { type: object } }
|
|
provenance: { type: object }
|
|
analytics_context_key: { type: string }
|
|
step_outcomes: { type: array, items: { $ref: "#/components/schemas/StepOutcome" } }
|
|
agent_evaluation_summary: { type: object }
|
|
StepOutcome:
|
|
type: object
|
|
required: [status, reason_codes, deterministic_evidence_refs]
|
|
properties:
|
|
status: { type: string, enum: [passed, failed, inconclusive, blocked, waiting_human] }
|
|
reason_codes: { type: array, items: { type: string } }
|
|
deterministic_evidence_refs: { type: array, items: { type: string } }
|
|
agent_evaluation_ids: { type: array, items: { type: string } }
|
|
decision_policy_id: { type: [string, "null"] }
|
|
decision_policy_version: { type: [string, "null"] }
|
|
AgentEvaluationSummary:
|
|
type: object
|
|
required: [evaluation_id, logical_step_id, verdict, confidence, model_id, prompt_template_version]
|
|
properties:
|
|
evaluation_id: { type: string }
|
|
logical_step_id: { type: string }
|
|
verdict: { type: string, enum: [pass, fail, inconclusive] }
|
|
confidence: { type: number, minimum: 0, maximum: 1 }
|
|
model_id: { type: string }
|
|
prompt_template_version: { type: string }
|
|
reason_codes: { type: array, items: { type: string } }
|
|
evidence_refs: { type: array, items: { type: string } }
|
|
AgentEvaluation:
|
|
allOf:
|
|
- $ref: "#/components/schemas/AgentEvaluationSummary"
|
|
- type: object
|
|
required: [scenario_run_id, attempt, provider_id, model_version, prompt_template_id, input_manifest_hash, findings, raw_response_artifact_ref, started_at, finished_at]
|
|
properties:
|
|
scenario_run_id: { type: string }
|
|
attempt: { type: integer, minimum: 1 }
|
|
provider_id: { type: string }
|
|
model_version: { type: string }
|
|
prompt_template_id: { type: string }
|
|
input_manifest_hash: { type: string }
|
|
findings: { type: array, items: { type: object } }
|
|
raw_response_artifact_ref: { type: string }
|
|
started_at: { type: string, format: date-time }
|
|
finished_at: { type: string, format: date-time }
|
|
DecisionPolicy:
|
|
type: object
|
|
required: [policy_id, version, deterministic_hard_failure, high_confidence_failure, low_confidence, disagreement, missing_evidence]
|
|
properties:
|
|
policy_id: { type: string }
|
|
version: { type: string }
|
|
deterministic_hard_failure: { type: string, enum: [failed] }
|
|
high_confidence_failure: { type: string, enum: [failed, inconclusive] }
|
|
low_confidence: { type: string, enum: [inconclusive] }
|
|
disagreement: { type: string, enum: [waiting_human, inconclusive] }
|
|
missing_evidence: { type: string, enum: [blocked, inconclusive] }
|
|
RunComparison:
|
|
type: object
|
|
required: [run_a, run_b, step_deltas, compatibility]
|
|
properties:
|
|
run_a: { type: string }
|
|
run_b: { type: string }
|
|
compatibility: { type: object }
|
|
step_deltas: { type: array, items: { type: object } }
|
|
ScenarioRunEvent:
|
|
oneOf:
|
|
- { $ref: "#/components/schemas/RunStartedEvent" }
|
|
- { $ref: "#/components/schemas/ApprovalRequiredEvent" }
|
|
- { $ref: "#/components/schemas/RunQueuedEvent" }
|
|
- { $ref: "#/components/schemas/StepStartedEvent" }
|
|
- { $ref: "#/components/schemas/StepProgressEvent" }
|
|
- { $ref: "#/components/schemas/EvidenceCreatedEvent" }
|
|
- { $ref: "#/components/schemas/AgentEvaluationStartedEvent" }
|
|
- { $ref: "#/components/schemas/AgentEvaluationCompletedEvent" }
|
|
- { $ref: "#/components/schemas/StepCompletedEvent" }
|
|
- { $ref: "#/components/schemas/CheckpointCreatedEvent" }
|
|
- { $ref: "#/components/schemas/RunCompletedEvent" }
|
|
- { $ref: "#/components/schemas/RunFailedEvent" }
|
|
- { $ref: "#/components/schemas/RunCancelledEvent" }
|
|
RunStartedEvent:
|
|
type: object
|
|
required: [id, sequence, event_type, run_id, occurred_at]
|
|
properties: { id: { type: string }, sequence: { type: integer }, event_type: { const: run_started }, run_id: { type: string }, occurred_at: { type: string, format: date-time }, payload: { type: object } }
|
|
ApprovalRequiredEvent:
|
|
type: object
|
|
required: [id, sequence, event_type, run_id, occurred_at]
|
|
properties: { id: { type: string }, sequence: { type: integer }, event_type: { const: approval_required }, run_id: { type: string }, occurred_at: { type: string, format: date-time }, payload: { type: object, required: [approval_gate_id] } }
|
|
RunQueuedEvent:
|
|
type: object
|
|
required: [id, sequence, event_type, run_id, occurred_at]
|
|
properties: { id: { type: string }, sequence: { type: integer }, event_type: { const: run_queued }, run_id: { type: string }, occurred_at: { type: string, format: date-time }, payload: { type: object } }
|
|
StepStartedEvent:
|
|
type: object
|
|
required: [id, sequence, event_type, run_id, logical_step_id, occurred_at]
|
|
properties: { id: { type: string }, sequence: { type: integer }, event_type: { const: step_started }, run_id: { type: string }, logical_step_id: { type: string }, occurred_at: { type: string, format: date-time }, payload: { type: object } }
|
|
StepProgressEvent:
|
|
type: object
|
|
required: [id, sequence, event_type, run_id, logical_step_id, occurred_at]
|
|
properties: { id: { type: string }, sequence: { type: integer }, event_type: { const: step_progress }, run_id: { type: string }, logical_step_id: { type: string }, occurred_at: { type: string, format: date-time }, payload: { type: object, required: [progress] } }
|
|
EvidenceCreatedEvent:
|
|
type: object
|
|
required: [id, sequence, event_type, run_id, logical_step_id, occurred_at]
|
|
properties: { id: { type: string }, sequence: { type: integer }, event_type: { const: evidence_created }, run_id: { type: string }, logical_step_id: { type: string }, occurred_at: { type: string, format: date-time }, payload: { type: object, required: [evidence_ref] } }
|
|
AgentEvaluationStartedEvent:
|
|
type: object
|
|
required: [id, sequence, event_type, run_id, logical_step_id, occurred_at]
|
|
properties: { id: { type: string }, sequence: { type: integer }, event_type: { const: agent_evaluation_started }, run_id: { type: string }, logical_step_id: { type: string }, occurred_at: { type: string, format: date-time }, payload: { type: object } }
|
|
AgentEvaluationCompletedEvent:
|
|
type: object
|
|
required: [id, sequence, event_type, run_id, logical_step_id, occurred_at]
|
|
properties: { id: { type: string }, sequence: { type: integer }, event_type: { const: agent_evaluation_completed }, run_id: { type: string }, logical_step_id: { type: string }, occurred_at: { type: string, format: date-time }, payload: { $ref: "#/components/schemas/AgentEvaluationSummary" } }
|
|
StepCompletedEvent:
|
|
type: object
|
|
required: [id, sequence, event_type, run_id, logical_step_id, occurred_at]
|
|
properties: { id: { type: string }, sequence: { type: integer }, event_type: { const: step_completed }, run_id: { type: string }, logical_step_id: { type: string }, occurred_at: { type: string, format: date-time }, payload: { type: object } }
|
|
CheckpointCreatedEvent:
|
|
type: object
|
|
required: [id, sequence, event_type, run_id, occurred_at]
|
|
properties: { id: { type: string }, sequence: { type: integer }, event_type: { const: checkpoint_created }, run_id: { type: string }, occurred_at: { type: string, format: date-time }, payload: { type: object } }
|
|
RunCompletedEvent:
|
|
type: object
|
|
required: [id, sequence, event_type, run_id, occurred_at]
|
|
properties: { id: { type: string }, sequence: { type: integer }, event_type: { const: run_completed }, run_id: { type: string }, occurred_at: { type: string, format: date-time }, payload: { type: object } }
|
|
RunFailedEvent:
|
|
type: object
|
|
required: [id, sequence, event_type, run_id, occurred_at]
|
|
properties: { id: { type: string }, sequence: { type: integer }, event_type: { const: run_failed }, run_id: { type: string }, occurred_at: { type: string, format: date-time }, payload: { type: object } }
|
|
RunCancelledEvent:
|
|
type: object
|
|
required: [id, sequence, event_type, run_id, occurred_at]
|
|
properties: { id: { type: string }, sequence: { type: integer }, event_type: { const: run_cancelled }, run_id: { type: string }, occurred_at: { type: string, format: date-time }, payload: { type: object } }
|