4.1 KiB
#region ScenarioAutomation.DataModel [C:4] [TYPE ADR] [SEMANTICS data-model,scenario,automation,schedule,trigger,policy] @BRIEF Schedule, trigger-rule, notification, and automation-policy models for 046. @RELATION DEPENDS_ON -> [ScenarioAutomation.Research] @RATIONALE Automation binds a scenario+revision to schedules/triggers with explicit policies; reuses 037 trigger semantics rather than a parallel scheduler. @REJECTED Reimplementing scheduler; writing scenario results into 037 baseline/verification.
ScenarioSchedule
Fields: id, scenario_id, revision_policy (current|pinned), revision_id (required when pinned), environment_id, cron_expr, timezone, missed_execution_policy, enabled, policy_id, created_by, created_at. Reuses existing APScheduler.
Schedule/trigger creation and every current-policy dispatch preflight require automation_eligible=true and an activated 042 current revision. A newly saved candidate is never silently adopted by a current schedule; it becomes eligible only through 042 atomic activation. A revision containing any 044 human step is manual_run_only; the service rejects the rule/dispatch with AUTOMATION_INELIGIBLE_HUMAN_STEP, rather than skipping the step or emitting a false PASS.
Scheduler semantics (#22)
Explicit APScheduler configuration: timezone (per schedule, IANA), DST policy (cron still fires on wall-clock), misfire_grace_time (default 300s), and max_instances (1 — no overlapping instances of the same schedule). coalesce is derived, never independently configured: skip ignores missed occurrences, run_latest sets coalesce=true, and queue_all sets coalesce=false. Scheduler restart applies that derived policy.
ScenarioTriggerRule
Fields: id, scenario_id, environment_id, trigger (deploy_to_preprod | release_created | etl_completed | api), revision_policy, revision_id (required when pinned), enabled, policy_id. Mapped onto the 037 trigger framework (release_create/scheduled hooks).
NotificationEvent
Fields: id, type (completed|failed|blocked|scenario_stale|repeated_flaky_failure), scenario_id, run_id?, severity, payload, emitted_at, investigation_signal_id?, investigation_queue_item_id?. Channel delivery is infrastructure-owned; qualifying attention events emit the canonical 036 InvestigationSignal; 047 creates/updates the Queue item from it rather than auto-starting agent work. human_action_required is not an automation event because human-step revisions are manual-run-only.
AutomationPolicy
Fields: id, name, enabled, workload_class, max_concurrent_per_env, dedup_window_seconds, overlap_rule (block|warn), retention_days, prod_gate_required (bool), on_repeated_failure (alert|disable). Applies to schedule/trigger runs through the global 044 ExecutionCapacityManager; it cannot reserve capacity owned by another workload class.
An agent may create, modify, pause or resume schedules/trigger rules under delegated policy and may investigate a repeated failure after an analyst opens its queue item. Scheduler dispatch, eligibility checks, deduplication, capacity, retention and trigger provenance stay deterministic. A policy-gated automation mutation is represented by an inline ActionApprovalGate, never a modal.
Retention tiers (#23)
Layered retention independent of the analytics minimum history window: run metadata 180d, triage/audit 365d (or policy), step metrics 90d, heavy artifacts 30d, screenshots 30d, raw VLM 7d. The analytics minimum history window (047) is guaranteed even when aggressive run retention prunes.
RunBinding
A triggered run pins scenario_id + revision_id + immutable Verification Program/content hash + environment_id + target snapshot + execution principal + server-owned trigger source (from 044). Concurrency bucket (for capacity) may be environment+workload class; dedup identity is canonical_execution_request_hash, or for an event trigger (source_type, source_event_id, scenario_id). External API triggers require an Idempotency-Key; same key/hash returns the same run, while a changed canonical request returns 409. Automation cannot supply or rewrite runtime SQL/DSL/program content.
#endregion ScenarioAutomation.DataModel