52 lines
1.5 KiB
Plaintext
52 lines
1.5 KiB
Plaintext
|
|
let _adr_id_format = std.contract.custom (
|
||
|
|
fun label =>
|
||
|
|
fun value =>
|
||
|
|
if std.string.is_match "^adr-[0-9]{3}$" value then
|
||
|
|
'Ok value
|
||
|
|
else
|
||
|
|
'Error {
|
||
|
|
message = "ADR id must match 'adr-NNN' format (e.g. 'adr-001'), got: '%{value}'"
|
||
|
|
}
|
||
|
|
) in
|
||
|
|
|
||
|
|
let _non_empty_constraints = std.contract.custom (
|
||
|
|
fun label =>
|
||
|
|
fun value =>
|
||
|
|
if std.array.length value == 0 then
|
||
|
|
'Error {
|
||
|
|
message = "constraints must not be empty — an ADR with no constraints is passive documentation, not an active constraint"
|
||
|
|
}
|
||
|
|
else
|
||
|
|
'Ok value
|
||
|
|
) in
|
||
|
|
|
||
|
|
let _non_empty_negative = std.contract.custom (
|
||
|
|
fun label =>
|
||
|
|
fun value =>
|
||
|
|
if std.array.length value.negative == 0 then
|
||
|
|
'Error {
|
||
|
|
message = "consequences.negative must not be empty on id='%{value.id}' — an ADR with no negative consequences is incomplete"
|
||
|
|
}
|
||
|
|
else
|
||
|
|
'Ok value
|
||
|
|
) in
|
||
|
|
|
||
|
|
let _requires_justification = std.contract.custom (
|
||
|
|
fun label =>
|
||
|
|
fun value =>
|
||
|
|
if value.ontology_check.verdict == 'RequiresJustification
|
||
|
|
&& !(std.record.has_field "invariant_justification" value) then
|
||
|
|
'Error {
|
||
|
|
message = "ADR '%{value.id}': ontology_check.verdict = 'RequiresJustification but invariant_justification field is missing"
|
||
|
|
}
|
||
|
|
else
|
||
|
|
'Ok value
|
||
|
|
) in
|
||
|
|
|
||
|
|
{
|
||
|
|
AdrIdFormat = _adr_id_format,
|
||
|
|
NonEmptyConstraints = _non_empty_constraints,
|
||
|
|
NonEmptyNegativeConsequences = _non_empty_negative,
|
||
|
|
RequiresJustificationWhenRisky = _requires_justification,
|
||
|
|
}
|