///|
pub(all) enum ScenarioTarget {
Native
Js
Wasm
WasmGc
} derive(Debug, Eq)
///|
pub fn ScenarioTarget::name(self : ScenarioTarget) -> String {
match self {
Native => "native"
Js => "js"
Wasm => "wasm"
WasmGc => "wasm-gc"
}
}
///|
pub fn scenario_target(value : String) -> ScenarioTarget? {
match ascii_lower(trim_ascii(value)) {
"native" => Some(Native)
"js" => Some(Js)
"wasm" => Some(Wasm)
"wasm-gc" => Some(WasmGc)
_ => None
}
}
///|
pub fn all_scenario_targets() -> Array[ScenarioTarget] {
[Native, Js, Wasm, WasmGc]
}
///|
pub(all) enum ExpectedStatus {
Success
Failure
} derive(Debug, Eq)
///|
pub fn ExpectedStatus::name(self : ExpectedStatus) -> String {
match self {
Success => "success"
Failure => "failure"
}
}
///|
pub fn expected_status(value : String) -> ExpectedStatus? {
match ascii_lower(trim_ascii(value)) {
"success" => Some(Success)
"pass" => Some(Success)
"failure" => Some(Failure)
"fail" => Some(Failure)
_ => None
}
}
///|
pub(all) enum ObservationStatus {
Passed
Failed
Skipped
} derive(Debug, Eq)
///|
pub fn ObservationStatus::name(self : ObservationStatus) -> String {
match self {
Passed => "passed"
Failed => "failed"
Skipped => "skipped"
}
}
///|
pub(all) enum IssueSeverity {
Notice
Warning
Error
} derive(Debug, Eq)
///|
pub fn IssueSeverity::name(self : IssueSeverity) -> String {
match self {
Notice => "notice"
Warning => "warning"
Error => "error"
}
}
///|
pub(all) struct ScenarioSpec {
id : String
title : String
command : String
targets : Array[ScenarioTarget]
expected : ExpectedStatus
expected_output : String
timeout_ms : Int
required : Bool
tags : Array[String]
} derive(Debug, Eq)
///|
pub fn ScenarioSpec::target_names(self : ScenarioSpec) -> String {
join_target_names(self.targets)
}
///|
pub fn ScenarioSpec::has_target(
self : ScenarioSpec,
target : ScenarioTarget,
) -> Bool {
contains_target(self.targets, target)
}
///|
pub fn ScenarioSpec::has_tag(self : ScenarioSpec, tag : String) -> Bool {
contains_string(self.tags, tag)
}
///|
pub(all) struct ScenarioObservation {
id : String
target : ScenarioTarget
status : ObservationStatus
stdout : String
stderr : String
duration_ms : Int
evidence_digest : String
} derive(Debug, Eq)
///|
pub fn ScenarioObservation::is_passed(self : ScenarioObservation) -> Bool {
self.status == Passed
}
///|
pub(all) struct ScenarioIssue {
code : String
severity : IssueSeverity
scenario_id : String
target : String
message : String
hint : String
} derive(Debug, Eq)
///|
pub(all) struct ScenarioManifest {
name : String
version : String
specs : Array[ScenarioSpec]
issues : Array[ScenarioIssue]
} derive(Debug, Eq)
///|
pub(all) struct ParsedScenario {
spec : ScenarioSpec?
issues : Array[ScenarioIssue]
} derive(Debug, Eq)
///|
pub(all) struct TargetCoverage {
target : ScenarioTarget
required_cases : Int
observed_cases : Int
passed_cases : Int
complete : Bool
} derive(Debug, Eq)
///|
pub(all) struct ScenarioMatrix {
name : String
version : String
specs : Array[ScenarioSpec]
observations : Array[ScenarioObservation]
coverage : Array[TargetCoverage]
issues : Array[ScenarioIssue]
required_count : Int
completed_count : Int
passed_count : Int
failed_count : Int
skipped_count : Int
} derive(Debug, Eq)
///|
pub fn ScenarioMatrix::passes(self : ScenarioMatrix) -> Bool {
self.issues_have_no_errors() &&
self.failed_count == 0 &&
self.completed_count == self.required_count
}
///|
pub fn ScenarioMatrix::issues_have_no_errors(self : ScenarioMatrix) -> Bool {
let mut index = 0
while index < self.issues.length() {
if self.issues[index].severity == Error {
return false
}
index += 1
}
true
}
///|
pub fn ScenarioMatrix::coverage_for(
self : ScenarioMatrix,
target : ScenarioTarget,
) -> TargetCoverage? {
let mut index = 0
while index < self.coverage.length() {
if self.coverage[index].target == target {
return Some(self.coverage[index])
}
index += 1
}
None
}
///|
pub(all) struct ScenarioDiff {
added_ids : Array[String]
removed_ids : Array[String]
regressed_ids : Array[String]
recovered_ids : Array[String]
unchanged_count : Int
} derive(Debug, Eq)
///|
pub fn ScenarioDiff::has_regressions(self : ScenarioDiff) -> Bool {
self.regressed_ids.length() > 0
}
///|
pub(all) struct TargetProfile {
target : ScenarioTarget
label : String
supports_files : Bool
supports_network : Bool
supports_process : Bool
notes : String
} derive(Debug, Eq)
///|
pub(all) struct ScenarioQuery {
tag : String
target : ScenarioTarget?
status : ObservationStatus?
required_only : Bool
} derive(Debug, Eq)
///|
pub(all) struct ScenarioStats {
scenario_count : Int
target_case_count : Int
required_case_count : Int
observed_case_count : Int
passed_case_count : Int
failed_case_count : Int
missing_case_count : Int
} derive(Debug, Eq)
///|
pub(all) struct MatrixPolicy {
required_targets : Array[ScenarioTarget]
max_timeout_ms : Int
require_evidence : Bool
require_output_for_success : Bool
allow_failure_scenarios : Bool
} derive(Debug, Eq)
///|
pub(all) struct RunPlanStep {
index : Int
scenario_id : String
target : ScenarioTarget
command : String
expected : ExpectedStatus
timeout_ms : Int
required : Bool
} derive(Debug, Eq)
///|
pub(all) struct ObservationParseResult {
observations : Array[ScenarioObservation]
issues : Array[ScenarioIssue]
} derive(Debug, Eq)
///|
pub(all) struct ParsedObservation {
observation : ScenarioObservation?
issues : Array[ScenarioIssue]
} derive(Debug, Eq)
///|
pub(all) enum ScheduleLane {
Portable
HostBound
Restricted
} derive(Debug, Eq)
///|
pub fn ScheduleLane::name(self : ScheduleLane) -> String {
match self {
Portable => "portable"
HostBound => "host-bound"
Restricted => "restricted"
}
}
///|
pub(all) struct ScheduleStep {
index : Int
case_id : String
target : ScenarioTarget
lane : ScheduleLane
command : String
estimated_ms : Int
} derive(Debug, Eq)
///|
pub(all) struct ScheduleBatch {
index : Int
target : ScenarioTarget
lane : ScheduleLane
steps : Array[ScheduleStep]
parallel_safe : Bool
} derive(Debug, Eq)
///|
pub(all) struct ReplayEnvelope {
case_id : String
target : ScenarioTarget
command : String
expected : ExpectedStatus
stdout : String
stderr : String
duration_ms : Int
evidence_digest : String
replay_key : String
} derive(Debug, Eq)
///|
pub(all) struct ContractInvariant {
code : String
description : String
passes : Bool
detail : String
} derive(Debug, Eq)
///|
pub(all) struct ReproductionContract {
matrix_name : String
matrix_version : String
matrix_digest : String
policy_digest : String
invariants : Array[ContractInvariant]
replay_count : Int
schedule_batch_count : Int
passes : Bool
} derive(Debug, Eq)
///|
pub(all) enum ScenarioRiskLevel {
Low
Medium
High
} derive(Debug, Eq)
///|
pub fn ScenarioRiskLevel::name(self : ScenarioRiskLevel) -> String {
match self {
Low => "low"
Medium => "medium"
High => "high"
}
}
///|
pub(all) struct ScenarioRiskFinding {
scenario_id : String
target : ScenarioTarget
level : ScenarioRiskLevel
code : String
message : String
hint : String
} derive(Debug, Eq)
///|
pub(all) struct ScenarioRiskReport {
findings : Array[ScenarioRiskFinding]
low_count : Int
medium_count : Int
high_count : Int
passes : Bool
} derive(Debug, Eq)
///|
pub(all) struct MatrixSnapshot {
label : String
digest : String
required_count : Int
passed_count : Int
failed_count : Int
skipped_count : Int
ready : Bool
} derive(Debug, Eq)
///|
pub(all) struct MatrixTimeline {
snapshots : Array[MatrixSnapshot]
improved : Int
regressed : Int
stable : Int
} derive(Debug, Eq)
///|
pub(all) struct ScenarioMetrics {
scenario_count : Int
target_case_count : Int
observed_case_count : Int
covered_target_count : Int
required_target_count : Int
passed_count : Int
failed_count : Int
skipped_count : Int
total_duration_ms : Int
min_duration_ms : Int
max_duration_ms : Int
coverage_percent : Int
pass_percent : Int
balance_score : Int
} derive(Debug, Eq)
///|
fn scenario_issue(
code : String,
severity : IssueSeverity,
scenario_id : String,
target : String,
message : String,
hint : String,
) -> ScenarioIssue {
ScenarioIssue::{ code, severity, scenario_id, target, message, hint }
}
///|
fn contains_target(
items : Array[ScenarioTarget],
value : ScenarioTarget,
) -> Bool {
let mut index = 0
while index < items.length() {
if items[index] == value {
return true
}
index += 1
}
false
}
///|
fn contains_string(items : Array[String], value : String) -> Bool {
let mut index = 0
while index < items.length() {
if items[index] == value {
return true
}
index += 1
}
false
}
///|
fn join_target_names(items : Array[ScenarioTarget]) -> String {
let mut out = ""
let mut index = 0
while index < items.length() {
if index > 0 {
out = out + ","
}
out = out + items[index].name()
index += 1
}
out
}
///|
fn join_strings(items : Array[String], separator : String) -> String {
let mut out = ""
let mut index = 0
while index < items.length() {
if index > 0 {
out = out + separator
}
out = out + items[index]
index += 1
}
out
}