45 lines
1.3 KiB
Plaintext
45 lines
1.3 KiB
Plaintext
# Validation contracts for .coder/ entries.
|
|
# Applied after schema — enforce semantic invariants.
|
|
|
|
# Entry must have a non-empty title
|
|
let _non_empty_title = std.contract.custom (
|
|
fun label =>
|
|
fun value =>
|
|
if std.string.length (std.string.trim value.title) == 0 then
|
|
'Error {
|
|
message = "Entry: title must not be empty — extracted from first markdown heading or filename"
|
|
}
|
|
else
|
|
'Ok value
|
|
) in
|
|
|
|
# Entry must have a non-empty author
|
|
let _non_empty_author = std.contract.custom (
|
|
fun label =>
|
|
fun value =>
|
|
if std.string.length (std.string.trim value.author) == 0 then
|
|
'Error {
|
|
message = "Entry: author must not be empty — derived from workspace directory name"
|
|
}
|
|
else
|
|
'Ok value
|
|
) in
|
|
|
|
# Entry in Inbox category should not have relates_to (not yet triaged)
|
|
let _inbox_no_relations = std.contract.custom (
|
|
fun label =>
|
|
fun value =>
|
|
if value.category == 'Inbox && std.array.length value.relates_to > 0 then
|
|
'Error {
|
|
message = "Entry in Inbox should not have relates_to — triage first, then add relations"
|
|
}
|
|
else
|
|
'Ok value
|
|
) in
|
|
|
|
{
|
|
NonEmptyTitle = _non_empty_title,
|
|
NonEmptyAuthor = _non_empty_author,
|
|
InboxNoRelations = _inbox_no_relations,
|
|
}
|