///|
pub fn build_reproduction_contract(
matrix : ScenarioMatrix,
policy : MatrixPolicy,
) -> ReproductionContract {
let replay = build_replay_envelopes(matrix)
let schedule = build_schedule(matrix)
let invariants : Array[ContractInvariant] = []
invariants.push(ContractInvariant::{
code: "matrix-passes",
description: "all required scenario cases have matching observations",
passes: matrix.passes(),
detail: scenario_matrix_summary(matrix),
})
invariants.push(ContractInvariant::{
code: "target-coverage",
description: "every selected target has required coverage",
passes: matrix.required_targets_complete(),
detail: coverage_detail(matrix.coverage),
})
invariants.push(ContractInvariant::{
code: "replay-keys-unique",
description: "every observed case has one stable replay key",
passes: replay_envelopes_are_unique(replay),
detail: "replays=" + replay.length().to_string(),
})
invariants.push(ContractInvariant::{
code: "schedule-deterministic",
description: "target batches and steps have stable ordering",
passes: schedule_is_deterministic(schedule),
detail: "batches=" + schedule.length().to_string(),
})
invariants.push(ContractInvariant::{
code: "policy-output",
description: "selected matrix policy has no blocking issues",
passes: apply_policy(matrix, policy).passes(),
detail: policy_summary(policy),
})
invariants.push(ContractInvariant::{
code: "evidence-digest",
description: "matrix and replay evidence have deterministic digests",
passes: digest_is_well_formed(digest_for_matrix(matrix)) &&
digest_is_well_formed(replay_envelopes_digest(replay)),
detail: "matrix=" + digest_for_matrix(matrix),
})
let mut passes = true
let mut index = 0
while index < invariants.length() {
if !invariants[index].passes {
passes = false
}
index += 1
}
ReproductionContract::{
matrix_name: matrix.name,
matrix_version: matrix.version,
matrix_digest: digest_for_matrix(matrix),
policy_digest: scenario_evidence_digest(policy_summary(policy), ""),
invariants,
replay_count: replay.length(),
schedule_batch_count: schedule.length(),
passes,
}
}
///|
pub fn ReproductionContract::is_ready(self : ReproductionContract) -> Bool {
self.passes
}
///|
pub fn ReproductionContract::summary(self : ReproductionContract) -> String {
"contract=" +
bool_text(self.passes) +
", matrix=" +
self.matrix_name +
", version=" +
self.matrix_version +
", invariants=" +
self.invariants.length().to_string() +
", replays=" +
self.replay_count.to_string() +
", batches=" +
self.schedule_batch_count.to_string()
}
///|
pub fn ReproductionContract::to_markdown(self : ReproductionContract) -> String {
let mut out = "# Reproduction Contract\n\n"
out = out + "- Matrix: `" + self.matrix_name + "`\n"
out = out + "- Version: `" + self.matrix_version + "`\n"
out = out + "- Ready: " + bool_text(self.passes) + "\n"
out = out + "- Matrix digest: `" + self.matrix_digest + "`\n"
out = out + "- Policy digest: `" + self.policy_digest + "`\n"
out = out + "- Replay envelopes: " + self.replay_count.to_string() + "\n"
out = out +
"- Schedule batches: " +
self.schedule_batch_count.to_string() +
"\n\n"
out = out +
"| Code | Passes | Invariant | Detail |\n| --- | --- | --- | --- |\n"
let mut index = 0
while index < self.invariants.length() {
let invariant = self.invariants[index]
out = out + "| `" + invariant.code + "` | " + bool_text(invariant.passes)
out = out +
" | " +
invariant.description +
" | " +
invariant.detail +
" |\n"
index += 1
}
out
}
///|
pub fn ReproductionContract::to_json(self : ReproductionContract) -> String {
let mut out = "{\"matrix\":\"" + json_escape(self.matrix_name) + "\","
out = out + "\"version\":\"" + json_escape(self.matrix_version) + "\","
out = out + "\"passes\":" + bool_text(self.passes) + ","
out = out + "\"matrix_digest\":\"" + self.matrix_digest + "\","
out = out + "\"policy_digest\":\"" + self.policy_digest + "\","
out = out + "\"replays\":" + self.replay_count.to_string() + ","
out = out + "\"batches\":" + self.schedule_batch_count.to_string() + ","
out = out + "\"invariants\":["
let mut index = 0
while index < self.invariants.length() {
if index > 0 {
out = out + ","
}
let invariant = self.invariants[index]
out = out + "{\"code\":\"" + invariant.code + "\","
out = out + "\"passes\":" + bool_text(invariant.passes) + ","
out = out + "\"detail\":\"" + json_escape(invariant.detail) + "\"}"
index += 1
}
out + "]}"
}
///|
pub fn contract_invariant(
contract : ReproductionContract,
code : String,
) -> ContractInvariant? {
let mut index = 0
while index < contract.invariants.length() {
if contract.invariants[index].code == code {
return Some(contract.invariants[index])
}
index += 1
}
None
}
///|
fn coverage_detail(coverage : Array[TargetCoverage]) -> String {
let parts : Array[String] = []
let mut index = 0
while index < coverage.length() {
let item = coverage[index]
parts.push(
item.target.name() +
"=" +
item.passed_cases.to_string() +
"/" +
item.required_cases.to_string(),
)
index += 1
}
join_strings(parts, ",")
}