46 lines
1.9 KiB
Plaintext
Raw Permalink Normal View History

2026-03-13 00:21:04 +00:00
let profile_type = [| 'Development, 'Staging, 'Production, 'CI, 'Test, 'Custom |] in
let seal_type = {
hash | String, # sha256 of nickel export <profile.ncl> (drift detection)
snapshot_hash | String | default = "", # sha256 of values_snapshot JSON (rollback integrity)
applied_at | String, # ISO 8601 datetime
applied_by | String, # actor: developer | agent | ci
note | String | default = "",
related_adr | String | default = "", # adr-NNN
related_pr | String | default = "", # PR number or URL
related_bug | String | default = "", # backlog item id or issue ref
} in
let config_state_type = {
id | String, # cfg-<timestamp>-<actor>
profile | profile_type,
seal | seal_type,
values_snapshot | String, # JSON-encoded values at seal time (String to avoid Nickel/JSON syntax clash)
supersedes | String | default = "", # cfg-id this replaces (rollback chain)
} in
# Per-profile variant constraints — what is allowed to differ between profiles
let profile_invariants_type = {
# Fields that MUST have different values in Production vs Development
must_differ | Array String | default = [],
# Fields that MUST be identical across all profiles (shared contract)
must_match | Array String | default = [],
# Fields forbidden in Production (e.g. debug flags)
forbidden_in_production | Array String | default = [],
} in
let config_manifest_type = {
project | String,
profiles | Array profile_type,
invariants | profile_invariants_type | default = { must_differ = [], must_match = [], forbidden_in_production = [] },
active | { _: String }, # profile → cfg-NNN (current active seal id)
} in
{
Profile = profile_type,
Seal = seal_type,
ConfigState = config_state_type,
ProfileInvariants = profile_invariants_type,
ConfigManifest = config_manifest_type,
}