provisioning/schemas/lib/build_spec.ncl

72 lines
2.5 KiB
Text
Raw Normal View History

# schemas/lib/build_spec.ncl — BuildSpec contract (ADR-039)
#
# Schema for .build-spec.ncl files at the root of each built repo.
# buildkit-launcher validates against this schema at parse time and exits
# non-zero on failure (constraint: build-spec-schema-versioned).
#
# Three-tier sizing resolution (launcher, not schema):
# 1. Explicit declaration here (highest priority)
# 2. P95 historical from orchestrator SurrealDB × 1.2
# 3. Language-default fallback (lowest priority)
#
# Usage:
# let bs = import "schemas/lib/build_spec.ncl" in
# { .. } | bs.BuildSpec
let positive_number_ =
std.contract.custom (
fun label =>
fun value =>
if value > 0 then
'Ok value
else
'Error {
message = "Expected a positive number, got '%{std.to_string value}'.\nAll resource fields must be > 0"
}
)
in
let bounded_cpu_ =
std.contract.custom (
fun label =>
fun value =>
if value > 0 && value <= 256 then
'Ok value
else
'Error {
message = "Invalid cpu value '%{std.to_string value}'.\nValid range: (0, 256]"
}
)
in
let bounded_time_budget_ =
std.contract.custom (
fun label =>
fun value =>
if value > 0 && value <= 1440 then
'Ok value
else
'Error {
message = "Invalid time_budget_min '%{std.to_string value}'.\nValid range: (0, 1440] — max 24 hours"
}
)
in
let _BuildSpec = {
schema_version | Number | doc "Schema version — buildkit-launcher rejects files with unknown versions" | default = 1,
cpu | bounded_cpu_ | doc "Virtual CPUs to request for the ephemeral runner VM",
memory_gb | positive_number_ | doc "RAM in GiB for the runner VM",
disk_gb | positive_number_ | doc "Ephemeral disk in GiB; no persistent storage — all state is destroyed with the VM",
time_budget_min | bounded_time_budget_ | doc "Hard wall-clock limit in minutes; VM is killed on expiry",
cache_keys | Array String | doc "sccache / BuildKit cache key namespaces to warm for this repo" | default = [],
oom_retry | Bool | doc "When true, launcher retries once at next size tier on OOM kill; bounded to 1 retry (constraint: oom-retry-bounded)" | default = true,
} in
{
BuildSpec = _BuildSpec,
PositiveNumber = positive_number_,
BoundedCpu = bounded_cpu_,
make_build_spec | not_exported = fun data => data | _BuildSpec,
}