feat(speckit): workflow architecture upgrades + rework 038 spec per new flow
Add prototype/openapi/validate/resume commands, wire edge-failure matrix into UX, enforce traceability + validation gates, mandate C4/C5 belief-runtime verification. Rework 038-dashboard-scenario-model artifacts: applicability, structured edge cases, 24-class UX state matrix, interactive HTML prototype, standardized OpenAPI 3.1 (7 ops), full RTM with coverage gate, 56-task backlog, and PASS validation report.
This commit is contained in:
633
specs/038-dashboard-scenario-model/contracts/openapi.yaml
Normal file
633
specs/038-dashboard-scenario-model/contracts/openapi.yaml
Normal file
@@ -0,0 +1,633 @@
|
||||
openapi: "3.1.0"
|
||||
info:
|
||||
title: Dashboard Scenario Compiler API
|
||||
version: "1.0.0"
|
||||
description: >
|
||||
OpenAPI 3.1 contract for feature 038 — deterministic ScenarioGraph compile,
|
||||
validate, resolve, draft-pack, capture, VLM, and disposition operations.
|
||||
Generated from api-ux.md, data-model.md, and contracts/modules.md.
|
||||
|
||||
servers:
|
||||
- url: /api/dashboard-testing
|
||||
description: superset-tools API gateway
|
||||
|
||||
tags:
|
||||
- name: scenario
|
||||
description: ScenarioGraph compile, validate, resolve, draft-pack
|
||||
- name: evidence
|
||||
description: Screenshot capture, VLM analysis, human disposition
|
||||
|
||||
paths:
|
||||
/scenarios/compile:
|
||||
post:
|
||||
operationId: compileDashboardScenario
|
||||
tags: [scenario]
|
||||
summary: Deterministically compile a dashboard goal into a ScenarioGraph
|
||||
description: |
|
||||
Combines bounded agent intent (objective, selected case ids) with the
|
||||
dashboard query model, checklist catalog, baseline summary, capability
|
||||
model, and parameters to produce a byte-stable DashboardTestScenario.
|
||||
Requires [scenario.compile] role.
|
||||
security:
|
||||
- BearerAuth: [scenario.compile]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/CompileRequest"
|
||||
examples:
|
||||
valid:
|
||||
$ref: "#/components/examples/CompileRequestValid"
|
||||
responses:
|
||||
"200":
|
||||
description: Deterministic scenario plus validation summary
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ScenarioResponse"
|
||||
examples:
|
||||
compiled:
|
||||
$ref: "#/components/examples/ScenarioResponseCompiled"
|
||||
"401":
|
||||
$ref: "#/components/responses/UnauthorizedError"
|
||||
"403":
|
||||
$ref: "#/components/responses/ForbiddenError"
|
||||
"422":
|
||||
$ref: "#/components/responses/ValidationError"
|
||||
"429":
|
||||
$ref: "#/components/responses/RateLimitError"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/scenarios/validate:
|
||||
post:
|
||||
operationId: validateDashboardScenario
|
||||
tags: [scenario]
|
||||
summary: Validate a candidate ScenarioGraph and return all findings
|
||||
description: |
|
||||
Pure validation of a candidate graph: schema, DAG, refs, parameters,
|
||||
baselines, tools, safety (no SQL / no raw metric truth / no path
|
||||
traversal), and checklist coverage. Returns deterministic findings.
|
||||
security:
|
||||
- BearerAuth: [scenario.compile]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ScenarioGraphInput"
|
||||
responses:
|
||||
"200":
|
||||
description: Complete validation findings
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ValidationResult"
|
||||
"401":
|
||||
$ref: "#/components/responses/UnauthorizedError"
|
||||
"422":
|
||||
$ref: "#/components/responses/ValidationError"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/scenarios/{scenarioId}/resolve:
|
||||
post:
|
||||
operationId: resolveDashboardScenario
|
||||
tags: [scenario]
|
||||
summary: Apply typed parameter/selector/manual resolutions as an immutable revision
|
||||
description: |
|
||||
Applies declared resolutions to an unresolved graph and emits a new
|
||||
immutable revision linked via parent_revision_hash. Stale base revisions
|
||||
are rejected (409) — never silently merged.
|
||||
security:
|
||||
- BearerAuth: [scenario.resolve]
|
||||
parameters:
|
||||
- name: scenarioId
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ResolveRequest"
|
||||
responses:
|
||||
"200":
|
||||
description: New immutable revision
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ScenarioResponse"
|
||||
"401":
|
||||
$ref: "#/components/responses/UnauthorizedError"
|
||||
"403":
|
||||
$ref: "#/components/responses/ForbiddenError"
|
||||
"409":
|
||||
$ref: "#/components/responses/StaleRevisionError"
|
||||
"422":
|
||||
$ref: "#/components/responses/ValidationError"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/scenarios/{scenarioId}/draft-pack:
|
||||
post:
|
||||
operationId: compileScenarioDraftPack
|
||||
tags: [scenario]
|
||||
summary: Generate a preview_only or save_eligible draft pack from versioned templates
|
||||
description: |
|
||||
Compiles a valid graph through registered versioned templates. Any
|
||||
validation error, NEEDS_SELECTOR, forbidden action, or unresolved
|
||||
required parameter makes the pack preview_only. Save-eligible packs are
|
||||
registered as 036 drafts. Idempotent per revision_hash.
|
||||
security:
|
||||
- BearerAuth: [scenario.draft]
|
||||
parameters:
|
||||
- name: scenarioId
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/DraftPackRequest"
|
||||
responses:
|
||||
"201":
|
||||
description: Draft pack registered via feature 036
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/DraftPack"
|
||||
"200":
|
||||
description: Idempotent replay — existing DraftPack for the same revision hash
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/DraftPack"
|
||||
"401":
|
||||
$ref: "#/components/responses/UnauthorizedError"
|
||||
"403":
|
||||
$ref: "#/components/responses/ForbiddenError"
|
||||
"409":
|
||||
$ref: "#/components/responses/StaleRevisionError"
|
||||
"422":
|
||||
$ref: "#/components/responses/ValidationError"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/scenarios/{scenarioId}/capture:
|
||||
post:
|
||||
operationId: captureScenarioScreenshot
|
||||
tags: [evidence]
|
||||
summary: Execute a screenshot capture step through the 036 Evidence bridge
|
||||
description: |
|
||||
Executes a validated ScreenshotCaptureSpec, registers the ScreenshotEvidence
|
||||
DraftArtifact (masked variant when mask_selectors present), and emits
|
||||
evidence_captured. Step output refs link artifact ids, not paths.
|
||||
security:
|
||||
- BearerAuth: [scenario.execute]
|
||||
parameters:
|
||||
- name: scenarioId
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/CaptureRequest"
|
||||
responses:
|
||||
"200":
|
||||
description: Captured artifact refs
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/CaptureResponse"
|
||||
"401":
|
||||
$ref: "#/components/responses/UnauthorizedError"
|
||||
"403":
|
||||
$ref: "#/components/responses/ForbiddenError"
|
||||
"422":
|
||||
$ref: "#/components/responses/ValidationError"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/scenarios/{scenarioId}/vlm:
|
||||
post:
|
||||
operationId: analyzeScenarioScreenshot
|
||||
tags: [evidence]
|
||||
summary: Submit a masked screenshot to a VLM provider and return typed findings
|
||||
description: |
|
||||
Runs a registered VLM analysis profile against a captured screenshot.
|
||||
Returns typed VlmFinding[] with model/prompt provenance; raw response is
|
||||
stored under redaction as a separate DraftArtifact. Findings are advisory
|
||||
and never alter metric baseline truth. Stale prompt templates are rejected.
|
||||
security:
|
||||
- BearerAuth: [scenario.execute]
|
||||
parameters:
|
||||
- name: scenarioId
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/VlmRequest"
|
||||
responses:
|
||||
"200":
|
||||
description: Typed VLM findings
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/VlmResponse"
|
||||
"401":
|
||||
$ref: "#/components/responses/UnauthorizedError"
|
||||
"422":
|
||||
$ref: "#/components/responses/StalePromptError"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/scenarios/{scenarioId}/disposition:
|
||||
post:
|
||||
operationId: disposeVlmFindings
|
||||
tags: [evidence]
|
||||
summary: Record a typed human disposition on VLM findings
|
||||
description: |
|
||||
Sets confirm/dismiss/inconclusive on one or more unresolved findings.
|
||||
Confirm requires a non-blank comment. Each finding is disposed exactly
|
||||
once (409 on double disposition). Graph structure never changes.
|
||||
security:
|
||||
- BearerAuth: [scenario.execute]
|
||||
parameters:
|
||||
- name: scenarioId
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/DispositionRequest"
|
||||
responses:
|
||||
"200":
|
||||
description: Updated scenario step
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/DispositionResponse"
|
||||
"401":
|
||||
$ref: "#/components/responses/UnauthorizedError"
|
||||
"409":
|
||||
$ref: "#/components/responses/DoubleDispositionError"
|
||||
"422":
|
||||
$ref: "#/components/responses/ValidationError"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
BearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: |
|
||||
superset-tools JWT. Roles encoded in `roles` claim.
|
||||
Required scopes: scenario.compile, scenario.resolve, scenario.draft,
|
||||
scenario.execute (per ADR-0005 RBAC).
|
||||
|
||||
schemas:
|
||||
ErrorEnvelope:
|
||||
type: object
|
||||
required: [error]
|
||||
properties:
|
||||
error:
|
||||
type: object
|
||||
required: [code, detail]
|
||||
properties:
|
||||
code: { type: string, example: "VALIDATION_ERROR" }
|
||||
detail: { type: string }
|
||||
fields:
|
||||
type: object
|
||||
additionalProperties: { type: string }
|
||||
description: Per-field validation errors (422 only)
|
||||
retry_after:
|
||||
type: integer
|
||||
description: Seconds until retry is allowed (429 only)
|
||||
|
||||
SuccessEnvelope:
|
||||
type: object
|
||||
required: [data]
|
||||
properties:
|
||||
data: {}
|
||||
meta:
|
||||
type: object
|
||||
properties:
|
||||
revision_hash: { type: string }
|
||||
|
||||
CompileRequest:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [agent_run_id, objective, query_model, checklist_catalog_version, baseline_version, capabilities, parameters]
|
||||
properties:
|
||||
agent_run_id: { type: string, format: uuid }
|
||||
objective:
|
||||
type: object
|
||||
required: [goal, selected_case_ids]
|
||||
properties:
|
||||
goal: { type: string, maxLength: 2000 }
|
||||
selected_case_ids: { type: array, items: { type: string } }
|
||||
rationale: { type: [string, "null"], maxLength: 4000 }
|
||||
query_model: { type: object }
|
||||
checklist_catalog_version: { const: 1 }
|
||||
baseline_version: { type: string }
|
||||
capabilities: { type: object }
|
||||
parameters: { type: object }
|
||||
|
||||
ScenarioGraphInput:
|
||||
type: object
|
||||
description: Candidate graph for validation. Forbids SQL, code bodies, raw metric truth, paths.
|
||||
additionalProperties: false
|
||||
required: [schema_version, scenario_id, dashboard_context, objective, phases, steps]
|
||||
properties:
|
||||
schema_version: { type: integer }
|
||||
scenario_id: { type: string }
|
||||
dashboard_context: { type: object }
|
||||
objective: { type: object }
|
||||
phases: { type: array, items: { type: string } }
|
||||
steps: { type: array, items: { type: object } }
|
||||
|
||||
ScenarioResponse:
|
||||
type: object
|
||||
required: [scenario, validation]
|
||||
properties:
|
||||
scenario: { type: object }
|
||||
validation: { $ref: "#/components/schemas/ValidationResult" }
|
||||
|
||||
ValidationResult:
|
||||
type: object
|
||||
required: [valid, errors, warnings, blockers, coverage, topological_order, graph_hash]
|
||||
properties:
|
||||
valid: { type: boolean }
|
||||
errors: { type: array, items: { type: object } }
|
||||
warnings: { type: array, items: { type: object } }
|
||||
blockers: { type: array, items: { type: object } }
|
||||
coverage: { type: array, items: { type: object } }
|
||||
topological_order: { type: array, items: { type: string } }
|
||||
unresolved_parameters: { type: array, items: { type: string } }
|
||||
unresolved_selectors: { type: array, items: { type: string } }
|
||||
unresolved_baselines: { type: array, items: { type: string } }
|
||||
graph_hash: { type: string }
|
||||
|
||||
ResolveRequest:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [base_revision_hash, changes]
|
||||
properties:
|
||||
base_revision_hash: { type: string, pattern: "^[a-f0-9]{64}$" }
|
||||
changes:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
required: [kind, target, value]
|
||||
properties:
|
||||
kind: { enum: [parameter, selector, manual_conversion, remove_step] }
|
||||
target: { type: string }
|
||||
value: {}
|
||||
reason: { type: [string, "null"] }
|
||||
|
||||
DraftPackRequest:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [agent_run_id, revision_hash]
|
||||
properties:
|
||||
agent_run_id: { type: string, format: uuid }
|
||||
revision_hash: { type: string, pattern: "^[a-f0-9]{64}$" }
|
||||
|
||||
DraftPack:
|
||||
type: object
|
||||
required: [scenario_revision_hash, template_version, status, manifest, artifacts, validation_summary, warnings]
|
||||
properties:
|
||||
scenario_revision_hash: { type: string }
|
||||
template_version: { type: string }
|
||||
status: { enum: [preview_only, save_eligible] }
|
||||
manifest: { type: object }
|
||||
artifacts: { type: array, items: { type: object } }
|
||||
validation_summary: { $ref: "#/components/schemas/ValidationResult" }
|
||||
warnings: { type: array, items: { type: object } }
|
||||
|
||||
CaptureRequest:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [agent_run_id, step_id, capture_spec]
|
||||
properties:
|
||||
agent_run_id: { type: string, format: uuid }
|
||||
step_id: { type: string }
|
||||
capture_spec: { $ref: "#/components/schemas/CaptureSpec" }
|
||||
|
||||
CaptureSpec:
|
||||
type: object
|
||||
required: [target, viewport, readiness, method]
|
||||
properties:
|
||||
target: { type: string, enum: [tab, viewport] }
|
||||
tab_identifier: { type: [string, "null"] }
|
||||
viewport:
|
||||
type: object
|
||||
required: [width, height]
|
||||
properties:
|
||||
width: { type: integer }
|
||||
height: { type: integer }
|
||||
readiness: { type: string, enum: [canvas_stabilized, network_idle, fixed_wait] }
|
||||
readiness_timeout_ms: { type: integer, default: 15000 }
|
||||
mask_selectors: { type: array, items: { type: string } }
|
||||
method: { type: string, enum: [cdp, full_page, region] }
|
||||
|
||||
CaptureResponse:
|
||||
type: object
|
||||
required: [artifact_refs]
|
||||
properties:
|
||||
artifact_refs:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
required: [artifact_id, kind, masked]
|
||||
properties:
|
||||
artifact_id: { type: string, format: uuid }
|
||||
kind: { type: string }
|
||||
masked: { type: boolean }
|
||||
|
||||
VlmRequest:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [agent_run_id, step_id, artifact_id, analysis]
|
||||
properties:
|
||||
agent_run_id: { type: string, format: uuid }
|
||||
step_id: { type: string }
|
||||
artifact_id: { type: string, format: uuid }
|
||||
analysis:
|
||||
type: object
|
||||
required: [profile_id, provider_id, model_id, prompt_template_id, prompt_version, prompt_template_hash]
|
||||
properties:
|
||||
profile_id: { type: string }
|
||||
provider_id: { type: string }
|
||||
model_id: { type: string }
|
||||
prompt_template_id: { type: string }
|
||||
prompt_version: { type: string }
|
||||
prompt_template_hash: { type: string, pattern: "^[a-f0-9]{64}$" }
|
||||
confidence_threshold: { type: number, minimum: 0, maximum: 1, default: 0.7 }
|
||||
|
||||
VlmResponse:
|
||||
type: object
|
||||
required: [findings]
|
||||
properties:
|
||||
findings:
|
||||
type: array
|
||||
items: { $ref: "#/components/schemas/VlmFinding" }
|
||||
|
||||
VlmFinding:
|
||||
type: object
|
||||
required: [finding_id, source_artifact_id, severity, code, confidence, description, disposition, model_provenance]
|
||||
properties:
|
||||
finding_id: { type: string }
|
||||
source_artifact_id: { type: string, format: uuid }
|
||||
severity: { type: string, enum: [info, warning, error] }
|
||||
code: { type: string }
|
||||
region:
|
||||
type: object
|
||||
properties:
|
||||
selector: { type: string }
|
||||
bounds: { type: object }
|
||||
confidence: { type: number, minimum: 0, maximum: 1 }
|
||||
description: { type: string, maxLength: 1000 }
|
||||
disposition: { type: string, enum: [unresolved, confirmed, dismissed, inconclusive] }
|
||||
disposition_comment: { type: [string, "null"], maxLength: 2000 }
|
||||
model_provenance:
|
||||
type: object
|
||||
required: [model_id, prompt_version, prompt_template_hash, analyzed_at]
|
||||
properties:
|
||||
model_id: { type: string }
|
||||
prompt_version: { type: string }
|
||||
prompt_template_hash: { type: string, pattern: "^[a-f0-9]{64}$" }
|
||||
analyzed_at: { type: string, format: date-time }
|
||||
|
||||
DispositionRequest:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [agent_run_id, step_id, dispositions]
|
||||
properties:
|
||||
agent_run_id: { type: string, format: uuid }
|
||||
step_id: { type: string }
|
||||
dispositions:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
required: [finding_id, decision]
|
||||
properties:
|
||||
finding_id: { type: string }
|
||||
decision: { enum: [confirm, dismiss, inconclusive] }
|
||||
comment: { type: [string, "null"], maxLength: 2000 }
|
||||
|
||||
DispositionResponse:
|
||||
type: object
|
||||
required: [step]
|
||||
properties:
|
||||
step: { type: object }
|
||||
|
||||
responses:
|
||||
UnauthorizedError:
|
||||
description: Missing or invalid authentication
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: "#/components/schemas/ErrorEnvelope" }
|
||||
example:
|
||||
error: { code: "UNAUTHORIZED", detail: "Authentication required" }
|
||||
ForbiddenError:
|
||||
description: Insufficient permissions
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: "#/components/schemas/ErrorEnvelope" }
|
||||
example:
|
||||
error: { code: "FORBIDDEN", detail: "Requires role: scenario.compile" }
|
||||
ValidationError:
|
||||
description: Request validation failed
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: "#/components/schemas/ErrorEnvelope" }
|
||||
example:
|
||||
error: { code: "VALIDATION_ERROR", detail: "Request validation failed", fields: { objective: "goal is required" } }
|
||||
StaleRevisionError:
|
||||
description: Base revision is stale or already resolved
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: "#/components/schemas/ErrorEnvelope" }
|
||||
example:
|
||||
error: { code: "STALE_REVISION", detail: "Base revision b2c3… no longer current. Recompile from latest." }
|
||||
StalePromptError:
|
||||
description: VLM prompt template is stale
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: "#/components/schemas/ErrorEnvelope" }
|
||||
example:
|
||||
error: { code: "STALE_PROMPT", detail: "Prompt template v1 hash mismatch. Update to current template." }
|
||||
DoubleDispositionError:
|
||||
description: Finding already disposed
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: "#/components/schemas/ErrorEnvelope" }
|
||||
example:
|
||||
error: { code: "DOUBLE_DISPOSITION", detail: "Finding f-001 already confirmed" }
|
||||
RateLimitError:
|
||||
description: Too many requests
|
||||
headers:
|
||||
Retry-After:
|
||||
schema: { type: integer }
|
||||
description: Seconds until next request is allowed
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: "#/components/schemas/ErrorEnvelope" }
|
||||
example:
|
||||
error: { code: "RATE_LIMITED", detail: "Too many requests. Retry after 30 seconds.", retry_after: 30 }
|
||||
InternalError:
|
||||
description: Unexpected server error
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: "#/components/schemas/ErrorEnvelope" }
|
||||
example:
|
||||
error: { code: "INTERNAL_ERROR", detail: "An unexpected error occurred" }
|
||||
|
||||
examples:
|
||||
CompileRequestValid:
|
||||
summary: Compile filters/metric/XLSX scenario
|
||||
value:
|
||||
agent_run_id: "550e8400-e29b-41d4-a716-446655440000"
|
||||
objective:
|
||||
goal: "Verify filters, metric, XLSX export, and baseline"
|
||||
selected_case_ids: ["B01", "C04", "C05"]
|
||||
rationale: "Release candidate covers filter and export regressions"
|
||||
query_model: { dashboard_key: "fi-0080" }
|
||||
checklist_catalog_version: 1
|
||||
baseline_version: "2026-07-01"
|
||||
capabilities: { native_filters: true, text_filter: true, table_filter: true, pagination: true, row_edit: true, bulk_edit: true, persistence_refresh: true, time_rollover: false, xlsx_export: true, cross_dashboard: false, superset_metric: true, dataset_field_read: true, screenshot: true, repository_write: true }
|
||||
parameters: { test_date: { type: "date" }, counterparty: { type: "string" } }
|
||||
ScenarioResponseCompiled:
|
||||
summary: Compiled 18-step scenario
|
||||
value:
|
||||
scenario:
|
||||
scenario_id: "fi-0080_verify-filters-metric-xlsx"
|
||||
revision_hash: "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3"
|
||||
phases: ["setup", "interact", "observe", "assert", "evidence", "report"]
|
||||
steps: [{ id: "phase-1-B01-open_dashboard", tool: "browser", action: "open_dashboard" }]
|
||||
validation:
|
||||
valid: true
|
||||
errors: []
|
||||
warnings: [{ code: "STALE_BASELINE", detail: "baseline 2026-06-15 superseded by 2026-07-01", step_id: "phase-4-C05-compare_to_baseline" }]
|
||||
blockers: []
|
||||
coverage: [{ case_id: "B01", classification: "automated" }, { case_id: "C04", classification: "automated" }, { case_id: "C05", classification: "automated" }]
|
||||
topological_order: ["phase-1-B01-open_dashboard", "phase-2-B01-apply_filters"]
|
||||
graph_hash: "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3"
|
||||
Reference in New Issue
Block a user