Skip to content

Kover Scenario DSL & Mirror Mode

kover specs/kover/scenario-dsl.kmd

Define a captura de entradas do usuário, a serialização em uma DSL de cenários reproduzíveis, e o modo espelho (executar a operação em um programa e replicá-la automaticamente em um segundo programa similar). A DSL e o espelho são a mesma máquina vista em tempos diferentes: capturar input → serializar → reexecutar (ao vivo = espelho; de arquivo = cenário). Define o schema de input record, a injeção em tiers (T1 protocolo / T2 OS-input), a tolerância de sincronização, e o reuso como caso de regressão. Implementa kover-RFC-001 §6.

When this spec applies

Primary triggers

All triggers

Specification body

Spec — Kover Scenario DSL & Mirror Mode (v0.1)

Core insight: the reproducible-scenario DSL and mirror mode are one machine viewed at two times — capture input → serialise → re-execute. Live re-execution into a second program = mirror; later re-execution from a file = reproducible scenario. This spec fixes the input record schema, the serialisation, the tiered injection, and the regression reuse. Rules R*, tests T*.

Scope

The L3 record/replay engine and mirror mode. Consumes capture (capture.kmd) and the connector (protocol.kmd); is consumed by the cockpit (KOVER-008) and regression-tests.kmd.

R1 — Input record schema

R1.1 — A captured input is a typed record: { seq, ts, kind, target, payload } where:

  • seq — monotonic ordinal within the scenario.
  • ts — RFC3339 UTC ms (relative offsets derived for replay timing).
  • kind ∈ { pointer, key, text, scroll, nav, wait, assert }.
  • target — a semantic selector when available (DOM selector / a11y node / OUIA data-ouia-component-id per specs/testing/ouia-test-hooks.kmd when the target is a KDS-built UI / IPC target), falling back to a geometric one ({x,y} in a named viewport). The selector tier drives the injection tier (R3).
  • payload — kind-specific (button/coords; keycode/modifiers; string; delta; url; duration; assertion expr).

R1.2 — Captured timing is preserved as inter-event offsets so replay can run at recorded speed, fixed speed, or as-fast-as-possible.

R2 — DSL serialisation (reuse, don't greenfield)

R2.1 — The scenario file SHOULD extend the existing infra/observe/probe Chromium scenario format rather than invent a new language, so a Kover scenario and a probe scenario share tooling. If a distinct surface is needed it is a KMD profile, never an ad-hoc format.

R2.2 — A scenario file is: { meta, viewport(s), targets[], steps[] } where steps[] is an ordered list of R1 records plus control nodes (branch, repeat, wait-for). It is human-readable and diffable.

R2.3 — Regression reuse (the loop-closer): a recorded scenario MUST be directly consumable as a regression-tests.kmd case (behavioural or golden). Reproducing a bug once yields a permanent test. (Maps RFC-001 A2.)

R2.4 — Harness layer. Beyond a single linear scenario, the DSL is harness-capable via three additive constructs: a setup/teardown lifecycle (launch/seed/reset the target(s) + env), a matrix (run the same steps across N targets × configs — the A/B is the 2-target case), and reusable fixtures. Composed with the headless runner (kover-RFC-001 §7.4) these turn a scenario into an executable test harness: the DSL authors the harness; the runner + connector (launch/command, protocol.kmd) + capture + budgets execute it. Reuse infra/observe/probe's runner and stack-RFC-005 Layer-3 where they fit — do not fork a third runner.

R3 — Tiered injection

R3.1 — Replay injects each step via the highest available tier for its target:

TierMechanismWhen
T1 protocol-drivensemantic injection via a control protocol — CDP (Kruze CEF + Chrome), IPC (protocol.kmd, Koder apps), Koder Eye (Android gesture+tree)target is a semantic selector and the program exposes a control protocol
T2 OS-input fan-outsynthesise OS input events (X11/Wayland/Win32/macOS a11y) by coordinateno control protocol; geometric target only

R3.2 — The engine MUST record which tier executed each step and surface it (a T2-replayed scenario is labelled approximateheadless-self-check honesty). A scenario MUST NOT silently downgrade T1→T2 without recording it.

R3.3 — T1 is the supported, deterministic path (RFC-001 phase 1). T2 ships labelled best-effort.

R3.4 — Synthetic input injection SHOULD reuse the koder_test_input primitive (stack-RFC-005), not a bespoke synthesiser; semantic selectors SHOULD resolve via OUIA hooks (specs/testing/ouia-test-hooks.kmd) when the target is a KDS-built UI. The headless runner (kover-RFC-001 §7.4) consumes the same DSL unattended — one format across cockpit, mirror, and harness.

R4 — Mirror mode (live A/B)

R4.1 — Mirror runs two targets (primary + secondary "similar program") from one input stream: the operator drives the primary; each captured input (R1) is also injected into the secondary via R3.

R4.2 — Sync tolerance: mirror MUST NOT assume lockstep. Each step carries a settle policy (wait-for selector/idle/timeout) so the secondary can lag and re-converge. A step whose secondary injection fails is recorded (not fatal) and flagged in the diff.

R4.3 — Mirror produces, per run: the shared scenario (R2), a capture per target (capture.kmd), a trace per target, and a diff (R5).

R4.4 — Canonical case: primary = Kruze (CEF/CDP), secondary = Chrome (CDP). Both T1, so the A/B is deterministic — this is the RFC-001 phase-1 seed.

R5 — Diff

R5.1 — The diff aligns the two runs by seq/scenario step and reports, per step: wall-time delta, key trace-phase deltas (paint/layout/script/network for web targets), and resource deltas (protocol.kmd R5). It is the primary artifact handed to Kortex (capture.kmd R2 diff).

Test cases

#CheckSeverity
T1A recorded scenario replays deterministically into a single CDP target and reproduces the captured navigation.hard
T2The same scenario file is accepted by the regression-tests.kmd runner as a case (R2.3).hard
T3Mirror drives Kruze + Chrome from one input stream; each step is injected into both via T1/CDP.hard
T4Every replayed step records its injection tier; a T2 step is labelled approximate (R3.2).hard
T5A secondary-injection failure in mirror is recorded and flagged in the diff, not fatal (R4.2).hard
T6The diff aligns by step and surfaces a per-step wall-time + trace-phase delta (R5.1).hard
T7Replay honours recorded timing, fixed-speed, and as-fast modes (R1.2).soft

Non-goals

  • The injection backends themselves (CDP client, IPC client, OS-input synthesiser) — implementation, tracked by KOVER-006/007.
  • Capture storagecapture.kmd.
  • Cross-program semantic equivalence of selectors (when primary and secondary have different DOMs/UI) — best-effort mapping; out of v0.1.

Open questions

  1. Selector mapping when primary and secondary are not the same app (e.g. Kruze vs Chrome render the same URL but expose different chrome): the web content DOM is shared (same page), so content selectors map; browser chrome actions need a per-target alias table. Scope the alias table at KOVER-007.
  2. Whether wait-for predicates should reuse the probe assertion grammar verbatim (R2.1 alignment) — likely yes; confirm at KOVER-006.

References