///|
/// Explainable policy metadata keeps CI failures actionable for humans.
pub struct PolicyRule {
id : String
title : String
rationale : String
severity : String
} derive(Debug, Eq)
///|
pub fn PolicyRule::new(
id : String,
title : String,
rationale : String,
severity : String,
) -> PolicyRule {
{ id, title, rationale, severity }
}
///|
pub fn PolicyRule::to_markdown(self : PolicyRule) -> String {
"| `" +
self.id +
"` | " +
self.title +
" | " +
self.severity +
" | " +
self.rationale +
" |"
}
///|
pub fn PolicyRule::to_json(self : PolicyRule) -> String {
"{\"id\":\"" +
json_escape(self.id) +
"\",\"title\":\"" +
json_escape(self.title) +
"\",\"rationale\":\"" +
json_escape(self.rationale) +
"\",\"severity\":\"" +
json_escape(self.severity) +
"\"}"
}
///|
pub struct PolicyCatalog {
name : String
rules : Array[PolicyRule]
} derive(Debug, Eq)
///|
pub fn PolicyCatalog::brandbook() -> PolicyCatalog {
{
name: "brandbook quality policy",
rules: [
PolicyRule::new(
"schema.required", "Required sections", "A guide must be importable without guessing missing structure.",
"error",
),
PolicyRule::new(
"color.hex", "Valid colors", "Color values must be portable across CSS and design tools.",
"error",
),
PolicyRule::new(
"type.rhythm", "Readable rhythm", "Line height and size bounds protect long-form readability.",
"error",
),
PolicyRule::new(
"a11y.contrast", "Contrast guidance", "Text combinations need an explicit accessibility review.",
"warning",
),
PolicyRule::new(
"asset.path", "Safe asset paths", "Generated references must not escape the asset root.",
"error",
),
PolicyRule::new(
"component.contract", "Component contracts", "States and token references make guidance implementable.",
"warning",
),
PolicyRule::new(
"export.stable", "Stable exports", "Consumers need deterministic machine-readable artifacts.",
"error",
),
],
}
}
///|
pub fn PolicyCatalog::len(self : PolicyCatalog) -> Int {
self.rules.length()
}
///|
pub fn PolicyCatalog::rule(self : PolicyCatalog, id : String) -> PolicyRule? {
for rule in self.rules {
if rule.id == id {
return Some(rule)
}
}
None
}
///|
pub fn PolicyCatalog::rule_ids(self : PolicyCatalog) -> Array[String] {
self.rules.map(fn(rule) { rule.id })
}
///|
pub fn PolicyCatalog::contains(self : PolicyCatalog, id : String) -> Bool {
self.rule(id) is Some(_)
}
///|
pub fn PolicyCatalog::errors(self : PolicyCatalog) -> Array[PolicyRule] {
self.rules.filter(fn(rule) { rule.severity == "error" })
}
///|
pub fn PolicyCatalog::warnings(self : PolicyCatalog) -> Array[PolicyRule] {
self.rules.filter(fn(rule) { rule.severity == "warning" })
}
///|
pub fn PolicyCatalog::critical_ids(self : PolicyCatalog) -> Array[String] {
self.errors().map(fn(rule) { rule.id })
}
///|
pub fn PolicyCatalog::is_complete(self : PolicyCatalog) -> Bool {
self.contains("schema.required") &&
self.contains("a11y.contrast") &&
self.contains("export.stable")
}
///|
pub fn PolicyCatalog::summary(self : PolicyCatalog) -> String {
let counts = self.severity_counts()
self.len().to_string() +
" rules: " +
counts[0].to_string() +
" errors, " +
counts[1].to_string() +
" warnings, " +
counts[2].to_string() +
" notes"
}
///|
pub fn PolicyCatalog::rule_for_path(
self : PolicyCatalog,
path : String,
) -> PolicyRule? {
let normalized = normalize_identifier(path)
for rule in self.rules {
let rule_id = normalize_identifier(rule.id)
if normalized == rule_id || normalized.contains(rule_id) {
return Some(rule)
}
}
None
}
///|
pub fn PolicyCatalog::checklist(self : PolicyCatalog) -> Array[String] {
self.rules.map(fn(rule) { "[ ] " + rule.title })
}
///|
pub fn PolicyCatalog::filter_severity(
self : PolicyCatalog,
severity : String,
) -> Array[PolicyRule] {
self.rules.filter(fn(rule) { rule.severity == severity })
}
///|
pub fn PolicyCatalog::titles(self : PolicyCatalog) -> Array[String] {
self.rules.map(fn(rule) { rule.title })
}
///|
pub fn PolicyCatalog::rationales(self : PolicyCatalog) -> Array[String] {
self.rules.map(fn(rule) { rule.rationale })
}
///|
pub fn PolicyCatalog::markdown_checklist(self : PolicyCatalog) -> String {
"## Policy checklist\n\n" + self.checklist().join("\n")
}
///|
pub fn PolicyCatalog::json_rule_ids(self : PolicyCatalog) -> String {
"[" +
self.rule_ids().map(fn(id) { "\"" + json_escape(id) + "\"" }).join(",") +
"]"
}
///|
pub fn PolicyCatalog::has_errors(self : PolicyCatalog) -> Bool {
self.errors().length() > 0
}
///|
pub fn PolicyCatalog::has_warnings(self : PolicyCatalog) -> Bool {
self.warnings().length() > 0
}
///|
pub fn PolicyCatalog::error_count(self : PolicyCatalog) -> Int {
self.errors().length()
}
///|
pub fn PolicyCatalog::warning_count(self : PolicyCatalog) -> Int {
self.warnings().length()
}
///|
pub fn PolicyCatalog::note_count(self : PolicyCatalog) -> Int {
self.filter_severity("info").length()
}
///|
pub fn PolicyCatalog::first_error(self : PolicyCatalog) -> PolicyRule? {
match self.errors() {
[first, ..] => Some(first)
_ => None
}
}
///|
pub fn PolicyCatalog::last_rule(self : PolicyCatalog) -> PolicyRule? {
if self.rules.length() == 0 {
None
} else {
Some(self.rules[self.rules.length() - 1])
}
}
///|
pub fn PolicyCatalog::all_ids_non_empty(self : PolicyCatalog) -> Bool {
self.rules.all(fn(rule) { rule.id.trim().to_owned() != "" })
}
///|
pub fn PolicyCatalog::all_rationales_non_empty(self : PolicyCatalog) -> Bool {
self.rules.all(fn(rule) { rule.rationale.trim().to_owned() != "" })
}
///|
pub fn PolicyCatalog::ready(self : PolicyCatalog) -> Bool {
self.is_complete() &&
self.all_ids_non_empty() &&
self.all_rationales_non_empty()
}
///|
pub fn PolicyCatalog::status(self : PolicyCatalog) -> String {
if self.ready() {
"ready"
} else {
"incomplete"
}
}
///|
pub fn PolicyCatalog::status_line(self : PolicyCatalog) -> String {
self.name + ": " + self.status() + " (" + self.summary() + ")"
}
///|
pub fn PolicyCatalog::search(
self : PolicyCatalog,
text : String,
) -> Array[PolicyRule] {
let query = normalize_identifier(text)
self.rules.filter(fn(rule) {
normalize_identifier(rule.id).contains(query) ||
normalize_identifier(rule.title).contains(query) ||
normalize_identifier(rule.rationale).contains(query)
})
}
///|
pub fn PolicyCatalog::search_ids(
self : PolicyCatalog,
text : String,
) -> Array[String] {
self.search(text).map(fn(rule) { rule.id })
}
///|
pub fn PolicyCatalog::severity_labels(self : PolicyCatalog) -> Array[String] {
self.rules.map(fn(rule) { rule.severity })
}
///|
pub fn PolicyCatalog::unique_severities(self : PolicyCatalog) -> Array[String] {
let result : Array[String] = []
for severity in self.severity_labels() {
if !result.contains(severity) {
result.push(severity)
}
}
result
}
///|
pub fn PolicyCatalog::rule_titles_markdown(self : PolicyCatalog) -> String {
self.titles().map(fn(title) { "- " + title }).join("\n")
}
///|
pub fn PolicyCatalog::rationales_markdown(self : PolicyCatalog) -> String {
self.rationales().map(fn(value) { "- " + value }).join("\n")
}
///|
pub fn PolicyCatalog::compact_json(self : PolicyCatalog) -> String {
"{\"count\":" +
self.len().to_string() +
",\"status\":\"" +
self.status() +
"\",\"errors\":" +
self.error_count().to_string() +
"}"
}
///|
pub fn PolicyCatalog::severity_counts(self : PolicyCatalog) -> Array[Int] {
[
self.rules.filter(fn(rule) { rule.severity == "error" }).length(),
self.rules.filter(fn(rule) { rule.severity == "warning" }).length(),
self.rules.filter(fn(rule) { rule.severity == "info" }).length(),
]
}
///|
pub fn PolicyCatalog::to_markdown(self : PolicyCatalog) -> String {
let lines : Array[String] = [
"# " + self.name,
"",
"| Rule | Title | Severity | Rationale |",
"| --- | --- | --- | --- |",
]
for rule in self.rules {
lines.push(rule.to_markdown())
}
lines.join("\n")
}
///|
pub fn PolicyCatalog::to_json(self : PolicyCatalog) -> String {
"{\"name\":\"" +
json_escape(self.name) +
"\",\"rules\":[" +
self.rules.map(fn(rule) { rule.to_json() }).join(",") +
"]}"
}
///|
pub fn policy_catalog() -> PolicyCatalog {
PolicyCatalog::brandbook()
}
///|
pub fn policy_markdown() -> String {
policy_catalog().to_markdown()
}
///|
pub fn policy_json() -> String {
policy_catalog().to_json()
}
///|
pub fn PolicyCatalog::has_rule_with_title(
self : PolicyCatalog,
title : String,
) -> Bool {
self.rules.any(fn(rule) { rule.title == title })
}
///|
pub fn PolicyCatalog::ids_markdown(self : PolicyCatalog) -> String {
self.rule_ids().map(fn(id) { "- `" + id + "`" }).join("\n")
}
///|
pub fn PolicyCatalog::severity_summary(self : PolicyCatalog) -> String {
self
.unique_severities()
.map(fn(value) {
value + "=" + self.filter_severity(value).length().to_string()
})
.join(", ")
}
///|
pub fn PolicyCatalog::coverage_score(self : PolicyCatalog) -> Int {
if self.is_complete() {
100
} else {
60
}
}
///|
pub fn PolicyCatalog::coverage_label(self : PolicyCatalog) -> String {
self.coverage_score().to_string() + "/100"
}
///|
pub fn PolicyCatalog::ready_summary(self : PolicyCatalog) -> String {
self.status_line() + "; coverage " + self.coverage_label()
}
///|
pub fn PolicyCatalog::rule_count_for(
self : PolicyCatalog,
severity : String,
) -> Int {
self.filter_severity(severity).length()
}
///|
pub fn PolicyCatalog::has_required_sections(self : PolicyCatalog) -> Bool {
self.contains("schema.required") && self.contains("export.stable")
}
///|
pub fn PolicyCatalog::ready_for_ci(self : PolicyCatalog) -> Bool {
self.ready() && self.has_required_sections()
}
///|
pub fn PolicyCatalog::ci_message(self : PolicyCatalog) -> String {
if self.ready_for_ci() {
"policy checks ready"
} else {
"policy catalog needs review"
}
}
///|
pub fn PolicyCatalog::rule_ids_csv(self : PolicyCatalog) -> String {
self.rule_ids().join(",")
}
///|
pub fn PolicyCatalog::rule_titles_csv(self : PolicyCatalog) -> String {
self.titles().join(",")
}
///|
pub fn PolicyCatalog::is_empty(self : PolicyCatalog) -> Bool {
self.rules.length() == 0
}
///|
pub fn PolicyCatalog::name_text(self : PolicyCatalog) -> String {
self.name
}
///|
pub fn PolicyCatalog::rule_at(self : PolicyCatalog, index : Int) -> PolicyRule? {
if index < 0 || index >= self.rules.length() {
None
} else {
Some(self.rules[index])
}
}
///|
pub fn PolicyCatalog::first_rule(self : PolicyCatalog) -> PolicyRule? {
self.rule_at(0)
}