//// Durable backend conformance contracts for M49.
import gleam/int
import gleam/list
import gleam/string
/// Durable backend class.
pub type BackendClass {
SqlQuorum
KvConsensus
LogReplicated
ObjectManifest
}
/// External dependency pressure profile.
pub type PressureProfile {
Nominal
DependencyDegraded
DependencyPartitioned
}
/// Backend certification artifacts.
pub type CertificationArtifact {
CertificationArtifact(
tuning_guide: String,
certification_report: String,
evidence_manifest: String,
)
}
/// One durable backend contract.
pub type BackendContract {
BackendContract(
name: String,
class: BackendClass,
durable_store: String,
takeover_requires_fencing: Bool,
recovery_requires_replay: Bool,
continuity_slo_ms: Int,
max_data_loss_events: Int,
supported_pressures: List(PressureProfile),
artifact: CertificationArtifact,
)
}
/// One failover observation under dependency pressure.
pub type Observation {
Observation(
backend: String,
pressure: PressureProfile,
takeover_ms: Int,
recovery_ms: Int,
fence_rejections: Int,
data_loss_events: Int,
continuity_met: Bool,
)
}
/// SLO budget by pressure profile.
pub type SloBudget {
SloBudget(
pressure: PressureProfile,
max_takeover_ms: Int,
max_recovery_ms: Int,
max_data_loss_events: Int,
)
}
/// Budget-check result.
pub type BudgetResult {
BudgetResult(
backend: String,
pressure: PressureProfile,
passed: Bool,
reason: String,
)
}
/// Expanded M49 backend matrix.
pub fn expanded_backends() -> List(BackendContract) {
[
BackendContract(
name: "postgres_wal_quorum",
class: SqlQuorum,
durable_store: "postgres://cluster/wal",
takeover_requires_fencing: True,
recovery_requires_replay: True,
continuity_slo_ms: 70,
max_data_loss_events: 1,
supported_pressures: [
Nominal,
DependencyDegraded,
DependencyPartitioned,
],
artifact: CertificationArtifact(
tuning_guide: "docs/backend_failover_tuning_and_certification.md#postgres-wal-quorum",
certification_report: "docs/reports/durable_backend_fixture_latest.md#postgres_wal_quorum",
evidence_manifest: "ops/certification/postgres_wal_quorum.md",
),
),
BackendContract(
name: "foundationdb_consensus",
class: KvConsensus,
durable_store: "foundationdb://cluster/default",
takeover_requires_fencing: True,
recovery_requires_replay: True,
continuity_slo_ms: 68,
max_data_loss_events: 1,
supported_pressures: [
Nominal,
DependencyDegraded,
DependencyPartitioned,
],
artifact: CertificationArtifact(
tuning_guide: "docs/backend_failover_tuning_and_certification.md#foundationdb-consensus",
certification_report: "docs/reports/durable_backend_fixture_latest.md#foundationdb_consensus",
evidence_manifest: "ops/certification/foundationdb_consensus.md",
),
),
BackendContract(
name: "etcd_lease_journal",
class: LogReplicated,
durable_store: "etcd://cluster/leases",
takeover_requires_fencing: True,
recovery_requires_replay: True,
continuity_slo_ms: 72,
max_data_loss_events: 2,
supported_pressures: [
Nominal,
DependencyDegraded,
DependencyPartitioned,
],
artifact: CertificationArtifact(
tuning_guide: "docs/backend_failover_tuning_and_certification.md#etcd-lease-journal",
certification_report: "docs/reports/durable_backend_fixture_latest.md#etcd_lease_journal",
evidence_manifest: "ops/certification/etcd_lease_journal.md",
),
),
BackendContract(
name: "object_manifest_journal",
class: ObjectManifest,
durable_store: "s3://durable/manifests",
takeover_requires_fencing: True,
recovery_requires_replay: True,
continuity_slo_ms: 82,
max_data_loss_events: 2,
supported_pressures: [
Nominal,
DependencyDegraded,
DependencyPartitioned,
],
artifact: CertificationArtifact(
tuning_guide: "docs/backend_failover_tuning_and_certification.md#object-manifest-journal",
certification_report: "docs/reports/durable_backend_fixture_latest.md#object_manifest_journal",
evidence_manifest: "ops/certification/object_manifest_journal.md",
),
),
]
}
/// Deterministic M49 pressure budgets.
pub fn default_slo_budgets() -> List(SloBudget) {
[
SloBudget(
pressure: Nominal,
max_takeover_ms: 55,
max_recovery_ms: 95,
max_data_loss_events: 1,
),
SloBudget(
pressure: DependencyDegraded,
max_takeover_ms: 70,
max_recovery_ms: 112,
max_data_loss_events: 2,
),
SloBudget(
pressure: DependencyPartitioned,
max_takeover_ms: 88,
max_recovery_ms: 130,
max_data_loss_events: 2,
),
]
}
/// Validate one backend contract.
pub fn valid(backend: BackendContract) -> Bool {
backend.name != ""
&& backend.durable_store != ""
&& backend.takeover_requires_fencing
&& backend.recovery_requires_replay
&& backend.continuity_slo_ms > 0
&& backend.max_data_loss_events >= 0
&& backend.supported_pressures != []
&& artifact_valid(backend.artifact)
}
/// Deterministic M49 backend-matrix certification invariant.
pub fn backend_matrix_certified() -> Bool {
let backends = expanded_backends()
list.length(backends) == 4
&& all_backends_valid(backends)
&& unique_backend_names(backends, [])
}
/// Deterministic takeover/fencing/recovery semantics certification.
pub fn takeover_fencing_recovery_certified() -> Bool {
let observations = run_pressure_matrix()
all_observations_continuity(observations)
&& all_observations_fencing(observations)
}
/// Run deterministic pressure matrix across all expanded backends.
pub fn run_pressure_matrix() -> List(Observation) {
run_pressure_matrix_backends(expanded_backends(), [])
}
/// Evaluate one pressure-matrix run against one SLO budget profile.
pub fn evaluate_slo_budget(
observations: List(Observation),
budgets: List(SloBudget),
) -> List(BudgetResult) {
evaluate_budget_loop(observations, budgets, [])
}
/// Count failing budget checks.
pub fn budget_failures(results: List(BudgetResult)) -> Int {
case results {
[] -> 0
[result, ..rest] ->
case result.passed {
True -> budget_failures(rest)
False -> 1 + budget_failures(rest)
}
}
}
/// Stable backend-class label.
pub fn backend_class_label(class: BackendClass) -> String {
case class {
SqlQuorum -> "sql_quorum"
KvConsensus -> "kv_consensus"
LogReplicated -> "log_replicated"
ObjectManifest -> "object_manifest"
}
}
/// Stable pressure label.
pub fn pressure_label(pressure: PressureProfile) -> String {
case pressure {
Nominal -> "nominal"
DependencyDegraded -> "dependency_degraded"
DependencyPartitioned -> "dependency_partitioned"
}
}
/// Stable artifact signature.
pub fn artifact_signature(artifact: CertificationArtifact) -> String {
"tuning="
<> artifact.tuning_guide
<> "|certification="
<> artifact.certification_report
<> "|evidence="
<> artifact.evidence_manifest
}
/// Stable backend signature.
pub fn backend_signature(backend: BackendContract) -> String {
"backend="
<> backend.name
<> "|class="
<> backend_class_label(backend.class)
<> "|store="
<> backend.durable_store
<> "|fencing="
<> bool_label(backend.takeover_requires_fencing)
<> "|replay="
<> bool_label(backend.recovery_requires_replay)
<> "|slo_ms="
<> int.to_string(backend.continuity_slo_ms)
<> "|max_data_loss="
<> int.to_string(backend.max_data_loss_events)
<> "|pressures="
<> join_with(",", list.map(backend.supported_pressures, pressure_label))
<> "|artifact="
<> artifact_signature(backend.artifact)
}
/// Stable pressure observation signature.
pub fn observation_signature(observation: Observation) -> String {
observation.backend
<> ":pressure="
<> pressure_label(observation.pressure)
<> ":takeover_ms="
<> int.to_string(observation.takeover_ms)
<> ":recovery_ms="
<> int.to_string(observation.recovery_ms)
<> ":fence_rejections="
<> int.to_string(observation.fence_rejections)
<> ":data_loss_events="
<> int.to_string(observation.data_loss_events)
<> ":continuity_met="
<> bool_label(observation.continuity_met)
}
/// Stable budget-result signature.
pub fn budget_result_signature(result: BudgetResult) -> String {
result.backend
<> ":pressure="
<> pressure_label(result.pressure)
<> ":passed="
<> bool_label(result.passed)
<> ":reason="
<> result.reason
}
/// Stable matrix signature across expanded backends.
pub fn matrix_signature() -> String {
join_with(";", list.map(expanded_backends(), backend_signature))
}
/// Backend name accessor.
pub fn name(backend: BackendContract) -> String {
backend.name
}
/// Backend artifact accessor.
pub fn artifact(backend: BackendContract) -> CertificationArtifact {
backend.artifact
}
fn artifact_valid(artifact: CertificationArtifact) -> Bool {
string.starts_with(artifact.tuning_guide, "docs/")
&& string.starts_with(artifact.certification_report, "docs/reports/")
&& string.starts_with(artifact.evidence_manifest, "ops/")
}
fn all_backends_valid(backends: List(BackendContract)) -> Bool {
case backends {
[] -> True
[backend, ..rest] -> valid(backend) && all_backends_valid(rest)
}
}
fn unique_backend_names(
backends: List(BackendContract),
seen: List(String),
) -> Bool {
case backends {
[] -> True
[backend, ..rest] ->
case contains_string(seen, backend.name) {
True -> False
False -> unique_backend_names(rest, [backend.name, ..seen])
}
}
}
fn contains_string(values: List(String), expected: String) -> Bool {
case values {
[] -> False
[value, ..rest] -> value == expected || contains_string(rest, expected)
}
}
fn run_pressure_matrix_backends(
backends: List(BackendContract),
observations_rev: List(Observation),
) -> List(Observation) {
case backends {
[] -> list.reverse(observations_rev)
[backend, ..rest] -> {
let backend_observations = run_pressure_matrix_one_backend(backend)
run_pressure_matrix_backends(
rest,
prepend_reversed(backend_observations, observations_rev),
)
}
}
}
fn prepend_reversed(
values: List(Observation),
target: List(Observation),
) -> List(Observation) {
case values {
[] -> target
[value, ..rest] -> prepend_reversed(rest, [value, ..target])
}
}
fn run_pressure_matrix_one_backend(
backend: BackendContract,
) -> List(Observation) {
list.map(backend.supported_pressures, fn(pressure) {
simulate_failover(backend, pressure)
})
}
fn simulate_failover(
backend: BackendContract,
pressure: PressureProfile,
) -> Observation {
let #(base_takeover, base_recovery, base_fence_rejections, base_data_loss) =
class_baseline(backend.class)
let #(takeover_delta, recovery_delta, fence_delta, data_loss_delta) =
pressure_adjustment(pressure)
let takeover_ms = base_takeover + takeover_delta
let recovery_ms = base_recovery + recovery_delta
let fence_rejections = base_fence_rejections + fence_delta
let data_loss_events = base_data_loss + data_loss_delta
let continuity_met =
takeover_ms <= backend.continuity_slo_ms
&& recovery_ms <= backend.continuity_slo_ms + 48
&& data_loss_events <= backend.max_data_loss_events
Observation(
backend: backend.name,
pressure: pressure,
takeover_ms: takeover_ms,
recovery_ms: recovery_ms,
fence_rejections: fence_rejections,
data_loss_events: data_loss_events,
continuity_met: continuity_met,
)
}
fn class_baseline(class: BackendClass) -> #(Int, Int, Int, Int) {
case class {
SqlQuorum -> #(24, 58, 2, 0)
KvConsensus -> #(20, 52, 2, 0)
LogReplicated -> #(23, 56, 2, 1)
ObjectManifest -> #(28, 64, 1, 1)
}
}
fn pressure_adjustment(pressure: PressureProfile) -> #(Int, Int, Int, Int) {
case pressure {
Nominal -> #(0, 0, 0, 0)
DependencyDegraded -> #(10, 16, 1, 0)
DependencyPartitioned -> #(22, 28, 2, 1)
}
}
fn all_observations_continuity(observations: List(Observation)) -> Bool {
case observations {
[] -> True
[observation, ..rest] ->
observation.continuity_met && all_observations_continuity(rest)
}
}
fn all_observations_fencing(observations: List(Observation)) -> Bool {
case observations {
[] -> True
[observation, ..rest] ->
observation.fence_rejections >= 1 && all_observations_fencing(rest)
}
}
fn evaluate_budget_loop(
observations: List(Observation),
budgets: List(SloBudget),
results_rev: List(BudgetResult),
) -> List(BudgetResult) {
case observations {
[] -> list.reverse(results_rev)
[observation, ..rest] -> {
let result = evaluate_one_budget(observation, budgets)
evaluate_budget_loop(rest, budgets, [result, ..results_rev])
}
}
}
fn evaluate_one_budget(
observation: Observation,
budgets: List(SloBudget),
) -> BudgetResult {
case budget_for_pressure(observation.pressure, budgets) {
Error(reason) ->
BudgetResult(
backend: observation.backend,
pressure: observation.pressure,
passed: False,
reason: reason,
)
Ok(budget) -> {
let takeover_ok = observation.takeover_ms <= budget.max_takeover_ms
let recovery_ok = observation.recovery_ms <= budget.max_recovery_ms
let loss_ok = observation.data_loss_events <= budget.max_data_loss_events
let continuity_ok = observation.continuity_met
let passed = takeover_ok && recovery_ok && loss_ok && continuity_ok
let reason = case passed {
True -> "within_budget"
False ->
"budget_exceeded:"
<> "takeover="
<> bool_label(takeover_ok)
<> ":recovery="
<> bool_label(recovery_ok)
<> ":data_loss="
<> bool_label(loss_ok)
<> ":continuity="
<> bool_label(continuity_ok)
}
BudgetResult(
backend: observation.backend,
pressure: observation.pressure,
passed: passed,
reason: reason,
)
}
}
}
fn budget_for_pressure(
pressure: PressureProfile,
budgets: List(SloBudget),
) -> Result(SloBudget, String) {
case budgets {
[] -> Error("missing_pressure_budget")
[budget, ..rest] ->
case budget.pressure == pressure {
True -> Ok(budget)
False -> budget_for_pressure(pressure, rest)
}
}
}
fn bool_label(value: Bool) -> String {
case value {
True -> "true"
False -> "false"
}
}
fn join_with(separator: String, values: List(String)) -> String {
case values {
[] -> ""
[value] -> value
[value, ..rest] -> value <> separator <> join_with(separator, rest)
}
}