///|
/// Release governance helpers keep the engineering evidence reviewable.
pub(all) struct GateItem {
code : String
title : String
passed : Bool
severity : Severity
evidence : String
remediation : String
} derive(Eq, @debug.Debug)
///|
pub(all) struct ReleaseGate {
project : String
version : String
items : Array[GateItem]
passed : Bool
score : Int
} derive(Eq, @debug.Debug)
///|
pub(all) struct ReleaseInput {
keymap : Keymap
analysis : Analysis
validation : ValidationReport
profile : ProfileReport?
benchmark : Array[BenchmarkResult]
diff : KeymapDiff?
} derive(Eq, @debug.Debug)
///|
fn gate_item(
code : String,
title : String,
passed : Bool,
severity : Severity,
evidence : String,
remediation : String,
) -> GateItem {
{ code, title, passed, severity, evidence, remediation }
}
///|
fn benchmark_passed(results : Array[BenchmarkResult]) -> Bool {
for result in results {
if result.mismatches > 0 {
return false
}
}
true
}
///|
fn gate_score(items : Array[GateItem]) -> Int {
if items.length() == 0 {
return 100
}
let mut passed = 0
for item in items {
if item.passed {
passed += 1
}
}
passed * 100 / items.length()
}
///|
/// Evaluate the evidence that matters before publishing a new keymap policy.
pub fn release_gate(
project : String,
version : String,
input : ReleaseInput,
) -> ReleaseGate {
let items : Array[GateItem] = []
items.push(
gate_item(
"RG001",
"structural validation",
input.validation.valid,
Error,
input.validation.error_count.to_string() + " structural errors",
"fix invalid records, contexts, or reserved markers",
),
)
items.push(
gate_item(
"RG002",
"conflict analysis",
input.analysis.ok(),
Error,
input.analysis.error_count.to_string() + " error findings",
"resolve exact conflicts and reserved shortcuts",
),
)
let profile_ok = match input.profile {
Some(profile) => profile.passed
None => true
}
items.push(
gate_item(
"RG003",
"policy profile",
profile_ok,
Warning,
if profile_ok {
"profile passed"
} else {
"profile gate failed"
},
"adjust declarations or select a documented profile",
),
)
let bench_ok = benchmark_passed(input.benchmark)
items.push(
gate_item(
"RG004",
"dispatcher regression",
bench_ok,
Error,
input.benchmark.length().to_string() + " benchmark fixtures",
"update the dispatcher or expected fixture deliberately",
),
)
let diff_ok = match input.diff {
None => true
Some(diff) => behavioral_changes(diff).length() == 0
}
items.push(
gate_item(
"RG005",
"migration review",
diff_ok,
Warning,
if diff_ok {
"no unreviewed behavior changes"
} else {
"behavioral changes present"
},
"review migration_plan output before release",
),
)
let passed = items
.filter(item => !item.passed && item.severity == Error)
.length() ==
0
{ project, version, items, passed, score: gate_score(items) }
}
///|
fn gate_kind_name(severity : Severity) -> String {
match severity {
Error => "blocking"
Warning => "advisory"
Info => "informational"
}
}
///|
pub fn release_gate_to_json(gate : ReleaseGate) -> String {
let rows : Array[String] = []
for item in gate.items {
rows.push(
"{\"code\":" +
json_string(item.code) +
",\"title\":" +
json_string(item.title) +
",\"passed\":" +
(if item.passed { "true" } else { "false" }) +
",\"severity\":" +
json_string(gate_kind_name(item.severity)) +
",\"evidence\":" +
json_string(item.evidence) +
",\"remediation\":" +
json_string(item.remediation) +
"}",
)
}
"{\"project\":" +
json_string(gate.project) +
",\"version\":" +
json_string(gate.version) +
",\"passed\":" +
(if gate.passed { "true" } else { "false" }) +
",\"score\":" +
gate.score.to_string() +
",\"items\":[" +
rows.join(",") +
"]}"
}
///|
pub fn release_gate_to_markdown(gate : ReleaseGate) -> String {
let lines : Array[String] = [
"## Release gate: " + gate.project + " " + gate.version,
"",
"Result: **" +
(if gate.passed { "PASS" } else { "FAIL" }) +
"** (score " +
gate.score.to_string() +
"/100)",
"",
"| Code | Check | Result | Severity | Evidence |",
"| --- | --- | --- | --- | --- |",
]
for item in gate.items {
lines.push(
"| `" +
item.code +
"` | " +
item.title +
" | " +
(if item.passed { "pass" } else { "fail" }) +
" | " +
gate_kind_name(item.severity) +
" | " +
item.evidence +
" |",
)
}
lines.push("")
lines.push("### Remediation")
for item in gate.items {
if !item.passed {
lines.push("- `" + item.code + "`: " + item.remediation)
}
}
lines.join("\n")
}
///|
/// Create a complete release input from a keymap and an optional baseline.
pub fn release_input(
keymap : Keymap,
profile? : PolicyProfile? = None,
baseline? : Keymap? = None,
) -> ReleaseInput {
let analysis = analyze(keymap)
let validation = validate_keymap(keymap)
let profile_report = match profile {
Some(policy) =>
Some(audit_with_profile(keymap_to_dsl(keymap), keymap.name, policy))
None => None
}
let diff = match baseline {
Some(previous) => Some(diff_keymaps(previous, keymap))
None => None
}
{ keymap, analysis, validation, profile: profile_report, benchmark: [], diff }
}