{ ManifestAction = std.enum.TagOrString, StepHook = { action | ManifestAction, params | { _ | String } | default = {}, delay | Number | default = 0, }, ManifestEntry = { file | String | optional, action | ManifestAction | default = 'apply, skip_if_exists | Bool | default = false, delay | Number | default = 0, params | { _ | String } | default = {}, pre | Array StepHook | default = [], post | Array StepHook | default = [], }, _ManifestPlanSafe = std.contract.custom (fun label value => let base = value | { init | Array ManifestEntry | default = [], update | Array ManifestEntry | default = [], delete | Array ManifestEntry | default = [], restart | Array ManifestEntry | default = [], } in let protected = ["namespace", "pvc"] in let is_destructive = fun a => a == 'delete || a == "delete" || a == 'recreate || a == "recreate" in let violations = fun op steps => steps |> std.array.filter (fun e => std.record.has_field "file" e && std.array.elem e.file protected && is_destructive e.action ) |> std.array.map (fun e => "%{op}:%{e.file}") in let all_violations = violations "update" base.update @ violations "delete" base.delete @ violations "restart" base.restart in if std.array.length all_violations > 0 then let msg = std.string.join ", " all_violations in 'Error { message = "ManifestPlan: protected resources cannot use delete/recreate — [%{msg}]" } else 'Ok base ), ManifestPlan = _ManifestPlanSafe, }