Agent: - lifecycle: run tracking, middleware hardening, langgraph setup - tests: agent lifecycle + langgraph setup coverage Backend: - async_job_runner: resilience hardening, tests - agent_conversations: run lifecycle integration - translate: scheduler + orchestrator SQL adjustments - schemas/services: agent_lifecycle model extensions Frontend: - TaskDrawer: UX improvements - TaskLogPanel/Viewer: safety hardening, i18n (en/ru) - FilterBar: report filters contract + tests - Reports page: layout adjustments Specs: - 036-agent-test-stabilization: runs contract, modules, events - 037-superset-baseline-engine: catalog schema, testing API, modules - 038-dashboard-scenario-model: scenario schema, capture profile, modules - 039-dashboard-scenario-ui: screen models, release verification UX, modules - dashboard-verification-usecases: new cross-cutting spec
8.7 KiB
#region SupersetBaselineEngine.DataModel [C:5] [TYPE ADR] [SEMANTICS data-model,superset,baseline,filter,comparison] @BRIEF Canonical query, filter, value, baseline, fingerprint, and comparison entities for feature 037. @RELATION DEPENDS_ON -> [SupersetBaselineEngine.Research]
DashboardQueryModel
- schema_version, environment_id, dashboard_id/title/slug;
- charts: ChartQueryModel[];
- datasets: DatasetQueryModel[];
- native_filters: NativeFilterModel[];
- capabilities: chart_data, dataset_query, xlsx_export;
- warnings: structured source/resource/code/detail;
- query_model_fingerprint.
ChartQueryModel includes chart id/uuid/title/viz_type, dataset id, metric/result descriptors, group-bys, saved query inputs, applicable_filter_ids, excluded_filter_ids, and execution capability. DatasetQueryModel includes id/uuid/name, columns with semantic types, metrics, and access state.
NormalizedFilterContext
{
"schema_version": 1,
"filters": [
{
"filter_id": "NATIVE_FILTER-date",
"dataset_id": 77,
"column": "business_date",
"operator": "TEMPORAL_RANGE",
"value": {"from": "2026-05-29", "to": "2026-05-29", "inclusive": true},
"target_chart_ids": [128]
}
],
"filters_hash": "sha256"
}
Canonical order is dataset_id, column, operator, canonical value, filter_id. Duplicate semantic filters are rejected unless their scopes are disjoint.
SupersetQueryRequest
Contains environment_id, dashboard_id, chart_id or dataset_id, result_key, and NormalizedFilterContext. It cannot contain SQL, raw endpoint, raw query_context, or arbitrary expression fields.
NormalizedValue
| Field | Meaning |
|---|---|
| kind | null, boolean, integer, decimal, string, date, datetime, percent, table |
| raw | Redacted bounded source value |
| canonical | JSON-safe canonical value; decimal is string |
| display | Optional Superset display value |
| format | Optional format metadata |
| source | environment/dashboard/chart/dataset/result/query hash |
| warnings | normalization warnings |
Table canonical value contains ordered columns and rows. Each cell is a scalar NormalizedValue payload without recursive source duplication.
BaselineEntry
Release-pinned expected value. Stored in dashboard_tests/{dashboard_key}/baselines.yaml in the git repository alongside the dashboard.
Required fields:
| Field | Rule |
|---|---|
| schema_version | const: 1 |
| baseline_id | UUID, stable across releases |
| release_version | Semver string, required (e.g. "v1.2.0") |
| release_commit_hash | 40-char git SHA, required |
| dashboard_id | Superset dashboard integer id |
| chart_id | or dataset_id, one required |
| result_key | Metric/result identifier |
| label | Human-readable display name |
| normalized_filters | NormalizedFilterContext with filters_hash |
| expected | NormalizedValue — the approved expected value |
| source_response_hash | SHA-256 of the Superset API response body at the time expected was captured |
| captured_at | ISO-8601 timestamp of capture |
| comparison_policy | ComparisonPolicy |
| status | approved, superseded, retired |
| provenance | Capture metadata: environment, actor, agent_run_id |
| immutability | ImmutabilityBlock or null |
| created_at, updated_at | Timestamps |
ImmutabilityBlock
| Field | Type | Rule |
|---|---|---|
| enabled | boolean | True for closed-period entries |
| period | string | Period identifier, e.g. "2026-05" |
| frozen_at | ISO-8601 | When the period was closed |
| policy | enum | alert, block_publish, require_investigation |
When immutability.enabled=true: any change in source_response_hash at verification time MUST raise immutability_violation, not stale_baseline. Automated expected-value updates are forbidden. New values require explicit analyst override with reason.
Baseline inheritance rule
When creating release v1.(N+1).0 from v1.N.0:
- For each metric entry in v1.N.0: if the chart's
content_hashin DashboardQueryModel has NOT changed → inheritexpected,source_response_hash,captured_at. - If chart
content_hashHAS changed → mark entry asneeds_reextraction; analyst or system re-extracts from PREPROD. - New charts (not in v1.N.0) → create new entries with fresh extraction from PREPROD.
- Removed charts → entries retained with status
retired.
ComparisonPolicy
Discriminated union:
- exact;
- absolute_tolerance(amount decimal string);
- relative_tolerance(ratio decimal string, zero_absolute_fallback optional);
- range(min/max and inclusive flags);
- row_set(keys, order_sensitive, allow_extra_rows, per_column policies).
Policy/value type compatibility is validated when loading catalog and before comparison.
ComparisonResult
Contains status, actual, expected, policy, diff, stale_dimensions, warnings, source_error, baseline_id, release_version, and evidence refs.
Status enum: pass, fail, inconclusive, missing_baseline, stale_baseline, stale_visual_baseline, immutability_violation, permission_denied, source_error.
immutability_violation is CRITICAL severity — it means source_response_hash changed for a closed-period entry, indicating retroactive data modification. It blocks release publication and triggers investigation.
VisualBaseline
Same release-pinned structure as metric BaselineEntry with kind=visual. Fields: baseline_id, release_version, release_commit_hash, dashboard_id, normalized_filters, tab_identifier, region_of_interest (optional), expected_image_sha256, tolerance_policy (VisualComparisonPolicy), source_response_hash, captured_at, immutability (optional), status, provenance.
VisualComparisonPolicy
Discriminated union: exact (digest match) or perceptual (ssim_min, pixel_diff_threshold). Visual baselines cannot use metric policies and vice versa; cross-kind comparison is rejected at catalog load.
StructureDiff
Structural comparison of DashboardQueryModel between two releases. Computed deterministically without metric execution.
| Field | Meaning |
|---|---|
| release_from | Version string of baseline release |
| release_to | Version string of target release |
| query_model_hash_from | SHA-256 of source DashboardQueryModel |
| query_model_hash_to | SHA-256 of target DashboardQueryModel |
| changes | Array of StructureChange |
StructureChange
| Field | Meaning |
|---|---|
| target | JSON pointer in DashboardQueryModel (e.g. charts[128].columns, filters[contractor].scope) |
| kind | Classifier: filter_scope_narrowed, filter_scope_widened, filter_operator_changed, filter_default_changed, filter_removed, column_order_changed, column_added, column_removed, chart_added, chart_removed, viz_type_changed, group_by_changed, time_grain_changed |
| severity | critical, warning, info |
| before, after | Values before and after the change |
| affected_artifacts | Array of affected artifact kinds: xlsx_export, screenshot_evidence, metric_assertion |
| rationale | Human-readable explanation |
Severity classification:
- critical: filter scope narrowed/lost, filter operator changed, chart removed, filter removed — affects data correctness
- warning: column reorder, group_by changed, viz_type changed, time_grain changed — affects downstream artifacts
- info: chart added, column added, filter scope widened — additive changes
StructureDiff is used at: DEV pre-deploy check, PREPROD post-deploy verification, release approval gate.
VerificationRun
Links an AgentRun (036) to a DashboardRelease. Records what was verified and the outcome.
| Field | Meaning |
|---|---|
| id | UUID |
| release_id | FK to DashboardRelease, nullable (nil for pre-release PREPROD checks) |
| repository_id | FK to GitRepository |
| agent_run_id | FK to AgentRun (036) |
| trigger | manual, deploy_to_preprod, release_create, release_approve, release_publish, post_publish, scheduled, etl_completed |
| environment_id | Target Superset environment |
| categories_run | Array: metric, visual, structure, xlsx, content_integrity |
| categories_passed | Subset of categories_run that passed |
| categories_failed | Subset that failed |
| overall_status | pass, warn, fail, blocked |
| summary | Human-readable summary text |
| baseline_version | Release version of the baseline used |
| baseline_commit | Git commit of baseline.yaml used |
| structure_diff | StructureDiff or null |
| metric_results | Array of ComparisonResult |
| created_at, created_by | Timestamps |
Catalog File
Path: dashboard_tests/{dashboard_key}/baselines.yaml
schema_version: 1
dashboard:
id: 42
slug: fi-0080
entries: []
Entries sort by chart/dataset identity, result_key, filters_hash, baseline_id. Writer uses atomic temp-file replace inside the resolved repository and only through a consumed 036 gate.
#endregion SupersetBaselineEngine.DataModel