REL-WF-005 — Reconcile a cleared run without adding a grid column
| Field | Value |
|---|---|
| Status | Open; user-observed, source risk verified, controlled reproduction pending |
| Architecture state | Deployed behavior |
| Severity | High |
| Affected surface | Workflow detail Runs grid after Clear existing tasks or Clear only failed tasks |
| Components | sparqd/oqullus, sparqd/workflow-backend, Airflow |
| Associated issue | Not opened |
Where the problem appears
Start with a DAG that shows two runs, select the first run, clear it, and watch the run grid while auto-refresh is enabled.
Concrete observed case
A user observed two runs becoming three visible grid columns after the first run was cleared. A clear is not a new-run operation: it resets task instances inside the selected Airflow DAG run. The expected canonical run count therefore remains two unless a schedule or separate manual trigger creates another run.
Source inspection found two defects that can make clear reconciliation unreliable:
- each run column is keyed by mutable
start_date, not immutabledag_run_id; clearing and rerunning can reset timing fields, and absent or repeated start dates also produce duplicate React keys; - the change fingerprint includes run/task IDs and states but omits run and task timing, try number, map index, and other fields changed by a clear. A response with the same summarized states can therefore be discarded as unchanged.
These defects are sufficient to require correction, but available evidence does not prove which one caused the reported third column. The canonical network response and DOM column identities were not captured during the original event.
Expected condition
Key and reconcile every column by dag_run_id. After clear, keep the same
column selected, show that it is being cleared/rerun, update try and timing data,
and display a new column only for a genuinely new dag_run_id. Detect and flag
duplicate IDs at the boundary rather than rendering them.
Cause and evidence
- Oqullus
Runs/index.tsxrenders run columns withkey={run.start_date}while navigation and selection correctly usedag_run_id. - Its diff fingerprint excludes
start_date,end_date, task timestamps,try_number, andmap_index. - Clear calls the Airflow clear-run or clear-task-instances endpoint, then enables five-second refresh. It does not intentionally trigger a new run.
- The direct run-list path has no normalization step that asserts uniqueness by
dag_run_idor records before/after run identities. - Airflow's stable API describes clear as clearing a DAG run and returns the affected run or task instances; trigger is a separate operation.
Why it matters
An apparent extra run corrupts operational interpretation: users may infer an unexpected schedule or duplicate execution, while stale try and timing data can hide what the clear actually reran. This affects incident response, audit, and compute-cost decisions.
Existing controls and workarounds
Before and after clear, compare unique dag_run_id values in the dagRuns
network response rather than counting rendered bars. Reload the page if the DOM
count disagrees. Confirm that no scheduled or manual trigger occurred before
classifying a genuine third run as a grid defect.
Alternatives considered
- Recommended: normalize responses into a map keyed by
dag_run_id, retain response order separately, and render withkey={run.dag_run_id}. - Replace the custom reconciliation with a query cache keyed by workflow and filter contract, invalidated after mutations, while retaining immutable run identity.
- Force a full remount after clear — may hide the symptom but loses selection and does not correct identity or stale-field detection.
Component involvement
- sparqd/oqullus owns immutable rendering identity, complete comparison, selection, and visible clear progress.
sparqd/workflow-backendshould return the canonical managed run list and mutation outcome.- Airflow provides
dag_run_id, task-instance try data, and audit events.
Reproduction and verification
Follow WF-S019.
Resolution conditions
Close when a deterministic test changes clear-related state and timing without
changing dag_run_id, proves the DOM retains exactly one column per canonical
run, and deployed evidence distinguishes a true new run from a rendering
artifact.
Validation and blockers
Oqullus owns the confirmed client defects. Workflow-backend and Airflow owners must validate the canonical response. A disposable workflow and authenticated session are required for non-destructive deployed reproduction.