src/lightspeed@cluster@durable_backend.erl

-module(lightspeed@cluster@durable_backend).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/lightspeed/cluster/durable_backend.gleam").
-export([expanded_backends/0, default_slo_budgets/0, valid/1, backend_matrix_certified/0, run_pressure_matrix/0, takeover_fencing_recovery_certified/0, evaluate_slo_budget/2, budget_failures/1, backend_class_label/1, pressure_label/1, artifact_signature/1, backend_signature/1, observation_signature/1, budget_result_signature/1, matrix_signature/0, name/1, artifact/1]).
-export_type([backend_class/0, pressure_profile/0, certification_artifact/0, backend_contract/0, observation/0, slo_budget/0, budget_result/0]).

-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.

?MODULEDOC(" Durable backend conformance contracts for M49.\n").

-type backend_class() :: sql_quorum |
    kv_consensus |
    log_replicated |
    object_manifest.

-type pressure_profile() :: nominal |
    dependency_degraded |
    dependency_partitioned.

-type certification_artifact() :: {certification_artifact,
        binary(),
        binary(),
        binary()}.

-type backend_contract() :: {backend_contract,
        binary(),
        backend_class(),
        binary(),
        boolean(),
        boolean(),
        integer(),
        integer(),
        list(pressure_profile()),
        certification_artifact()}.

-type observation() :: {observation,
        binary(),
        pressure_profile(),
        integer(),
        integer(),
        integer(),
        integer(),
        boolean()}.

-type slo_budget() :: {slo_budget,
        pressure_profile(),
        integer(),
        integer(),
        integer()}.

-type budget_result() :: {budget_result,
        binary(),
        pressure_profile(),
        boolean(),
        binary()}.

-file("src/lightspeed/cluster/durable_backend.gleam", 80).
?DOC(" Expanded M49 backend matrix.\n").
-spec expanded_backends() -> list(backend_contract()).
expanded_backends() ->
    [{backend_contract,
            <<"postgres_wal_quorum"/utf8>>,
            sql_quorum,
            <<"postgres://cluster/wal"/utf8>>,
            true,
            true,
            70,
            1,
            [nominal, dependency_degraded, dependency_partitioned],
            {certification_artifact,
                <<"docs/backend_failover_tuning_and_certification.md#postgres-wal-quorum"/utf8>>,
                <<"docs/reports/durable_backend_fixture_latest.md#postgres_wal_quorum"/utf8>>,
                <<"ops/certification/postgres_wal_quorum.md"/utf8>>}},
        {backend_contract,
            <<"foundationdb_consensus"/utf8>>,
            kv_consensus,
            <<"foundationdb://cluster/default"/utf8>>,
            true,
            true,
            68,
            1,
            [nominal, dependency_degraded, dependency_partitioned],
            {certification_artifact,
                <<"docs/backend_failover_tuning_and_certification.md#foundationdb-consensus"/utf8>>,
                <<"docs/reports/durable_backend_fixture_latest.md#foundationdb_consensus"/utf8>>,
                <<"ops/certification/foundationdb_consensus.md"/utf8>>}},
        {backend_contract,
            <<"etcd_lease_journal"/utf8>>,
            log_replicated,
            <<"etcd://cluster/leases"/utf8>>,
            true,
            true,
            72,
            2,
            [nominal, dependency_degraded, dependency_partitioned],
            {certification_artifact,
                <<"docs/backend_failover_tuning_and_certification.md#etcd-lease-journal"/utf8>>,
                <<"docs/reports/durable_backend_fixture_latest.md#etcd_lease_journal"/utf8>>,
                <<"ops/certification/etcd_lease_journal.md"/utf8>>}},
        {backend_contract,
            <<"object_manifest_journal"/utf8>>,
            object_manifest,
            <<"s3://durable/manifests"/utf8>>,
            true,
            true,
            82,
            2,
            [nominal, dependency_degraded, dependency_partitioned],
            {certification_artifact,
                <<"docs/backend_failover_tuning_and_certification.md#object-manifest-journal"/utf8>>,
                <<"docs/reports/durable_backend_fixture_latest.md#object_manifest_journal"/utf8>>,
                <<"ops/certification/object_manifest_journal.md"/utf8>>}}].

-file("src/lightspeed/cluster/durable_backend.gleam", 162).
?DOC(" Deterministic M49 pressure budgets.\n").
-spec default_slo_budgets() -> list(slo_budget()).
default_slo_budgets() ->
    [{slo_budget, nominal, 55, 95, 1},
        {slo_budget, dependency_degraded, 70, 112, 2},
        {slo_budget, dependency_partitioned, 88, 130, 2}].

-file("src/lightspeed/cluster/durable_backend.gleam", 333).
-spec artifact_valid(certification_artifact()) -> boolean().
artifact_valid(Artifact) ->
    (gleam_stdlib:string_starts_with(
        erlang:element(2, Artifact),
        <<"docs/"/utf8>>
    )
    andalso gleam_stdlib:string_starts_with(
        erlang:element(3, Artifact),
        <<"docs/reports/"/utf8>>
    ))
    andalso gleam_stdlib:string_starts_with(
        erlang:element(4, Artifact),
        <<"ops/"/utf8>>
    ).

-file("src/lightspeed/cluster/durable_backend.gleam", 186).
?DOC(" Validate one backend contract.\n").
-spec valid(backend_contract()) -> boolean().
valid(Backend) ->
    (((((((erlang:element(2, Backend) /= <<""/utf8>>) andalso (erlang:element(
        4,
        Backend
    )
    /= <<""/utf8>>))
    andalso erlang:element(5, Backend))
    andalso erlang:element(6, Backend))
    andalso (erlang:element(7, Backend) > 0))
    andalso (erlang:element(8, Backend) >= 0))
    andalso (erlang:element(9, Backend) /= []))
    andalso artifact_valid(erlang:element(10, Backend)).

-file("src/lightspeed/cluster/durable_backend.gleam", 360).
-spec contains_string(list(binary()), binary()) -> boolean().
contains_string(Values, Expected) ->
    case Values of
        [] ->
            false;

        [Value | Rest] ->
            (Value =:= Expected) orelse contains_string(Rest, Expected)
    end.

-file("src/lightspeed/cluster/durable_backend.gleam", 346).
-spec unique_backend_names(list(backend_contract()), list(binary())) -> boolean().
unique_backend_names(Backends, Seen) ->
    case Backends of
        [] ->
            true;

        [Backend | Rest] ->
            case contains_string(Seen, erlang:element(2, Backend)) of
                true ->
                    false;

                false ->
                    unique_backend_names(
                        Rest,
                        [erlang:element(2, Backend) | Seen]
                    )
            end
    end.

-file("src/lightspeed/cluster/durable_backend.gleam", 339).
-spec all_backends_valid(list(backend_contract())) -> boolean().
all_backends_valid(Backends) ->
    case Backends of
        [] ->
            true;

        [Backend | Rest] ->
            valid(Backend) andalso all_backends_valid(Rest)
    end.

-file("src/lightspeed/cluster/durable_backend.gleam", 198).
?DOC(" Deterministic M49 backend-matrix certification invariant.\n").
-spec backend_matrix_certified() -> boolean().
backend_matrix_certified() ->
    Backends = expanded_backends(),
    ((erlang:length(Backends) =:= 4) andalso all_backends_valid(Backends))
    andalso unique_backend_names(Backends, []).

-file("src/lightspeed/cluster/durable_backend.gleam", 454).
-spec all_observations_fencing(list(observation())) -> boolean().
all_observations_fencing(Observations) ->
    case Observations of
        [] ->
            true;

        [Observation | Rest] ->
            (erlang:element(6, Observation) >= 1) andalso all_observations_fencing(
                Rest
            )
    end.

-file("src/lightspeed/cluster/durable_backend.gleam", 446).
-spec all_observations_continuity(list(observation())) -> boolean().
all_observations_continuity(Observations) ->
    case Observations of
        [] ->
            true;

        [Observation | Rest] ->
            erlang:element(8, Observation) andalso all_observations_continuity(
                Rest
            )
    end.

-file("src/lightspeed/cluster/durable_backend.gleam", 383).
-spec prepend_reversed(list(observation()), list(observation())) -> list(observation()).
prepend_reversed(Values, Target) ->
    case Values of
        [] ->
            Target;

        [Value | Rest] ->
            prepend_reversed(Rest, [Value | Target])
    end.

-file("src/lightspeed/cluster/durable_backend.gleam", 438).
-spec pressure_adjustment(pressure_profile()) -> {integer(),
    integer(),
    integer(),
    integer()}.
pressure_adjustment(Pressure) ->
    case Pressure of
        nominal ->
            {0, 0, 0, 0};

        dependency_degraded ->
            {10, 16, 1, 0};

        dependency_partitioned ->
            {22, 28, 2, 1}
    end.

-file("src/lightspeed/cluster/durable_backend.gleam", 429).
-spec class_baseline(backend_class()) -> {integer(),
    integer(),
    integer(),
    integer()}.
class_baseline(Class) ->
    case Class of
        sql_quorum ->
            {24, 58, 2, 0};

        kv_consensus ->
            {20, 52, 2, 0};

        log_replicated ->
            {23, 56, 2, 1};

        object_manifest ->
            {28, 64, 1, 1}
    end.

-file("src/lightspeed/cluster/durable_backend.gleam", 401).
-spec simulate_failover(backend_contract(), pressure_profile()) -> observation().
simulate_failover(Backend, Pressure) ->
    {Base_takeover, Base_recovery, Base_fence_rejections, Base_data_loss} = class_baseline(
        erlang:element(3, Backend)
    ),
    {Takeover_delta, Recovery_delta, Fence_delta, Data_loss_delta} = pressure_adjustment(
        Pressure
    ),
    Takeover_ms = Base_takeover + Takeover_delta,
    Recovery_ms = Base_recovery + Recovery_delta,
    Fence_rejections = Base_fence_rejections + Fence_delta,
    Data_loss_events = Base_data_loss + Data_loss_delta,
    Continuity_met = ((Takeover_ms =< erlang:element(7, Backend)) andalso (Recovery_ms
    =< (erlang:element(7, Backend) + 48)))
    andalso (Data_loss_events =< erlang:element(8, Backend)),
    {observation,
        erlang:element(2, Backend),
        Pressure,
        Takeover_ms,
        Recovery_ms,
        Fence_rejections,
        Data_loss_events,
        Continuity_met}.

-file("src/lightspeed/cluster/durable_backend.gleam", 393).
-spec run_pressure_matrix_one_backend(backend_contract()) -> list(observation()).
run_pressure_matrix_one_backend(Backend) ->
    gleam@list:map(
        erlang:element(9, Backend),
        fun(Pressure) -> simulate_failover(Backend, Pressure) end
    ).

-file("src/lightspeed/cluster/durable_backend.gleam", 367).
-spec run_pressure_matrix_backends(
    list(backend_contract()),
    list(observation())
) -> list(observation()).
run_pressure_matrix_backends(Backends, Observations_rev) ->
    case Backends of
        [] ->
            lists:reverse(Observations_rev);

        [Backend | Rest] ->
            Backend_observations = run_pressure_matrix_one_backend(Backend),
            run_pressure_matrix_backends(
                Rest,
                prepend_reversed(Backend_observations, Observations_rev)
            )
    end.

-file("src/lightspeed/cluster/durable_backend.gleam", 215).
?DOC(" Run deterministic pressure matrix across all expanded backends.\n").
-spec run_pressure_matrix() -> list(observation()).
run_pressure_matrix() ->
    run_pressure_matrix_backends(expanded_backends(), []).

-file("src/lightspeed/cluster/durable_backend.gleam", 207).
?DOC(" Deterministic takeover/fencing/recovery semantics certification.\n").
-spec takeover_fencing_recovery_certified() -> boolean().
takeover_fencing_recovery_certified() ->
    Observations = run_pressure_matrix(),
    all_observations_continuity(Observations) andalso all_observations_fencing(
        Observations
    ).

-file("src/lightspeed/cluster/durable_backend.gleam", 532).
-spec bool_label(boolean()) -> binary().
bool_label(Value) ->
    case Value of
        true ->
            <<"true"/utf8>>;

        false ->
            <<"false"/utf8>>
    end.

-file("src/lightspeed/cluster/durable_backend.gleam", 518).
-spec budget_for_pressure(pressure_profile(), list(slo_budget())) -> {ok,
        slo_budget()} |
    {error, binary()}.
budget_for_pressure(Pressure, Budgets) ->
    case Budgets of
        [] ->
            {error, <<"missing_pressure_budget"/utf8>>};

        [Budget | Rest] ->
            case erlang:element(2, Budget) =:= Pressure of
                true ->
                    {ok, Budget};

                false ->
                    budget_for_pressure(Pressure, Rest)
            end
    end.

-file("src/lightspeed/cluster/durable_backend.gleam", 476).
-spec evaluate_one_budget(observation(), list(slo_budget())) -> budget_result().
evaluate_one_budget(Observation, Budgets) ->
    case budget_for_pressure(erlang:element(3, Observation), Budgets) of
        {error, Reason} ->
            {budget_result,
                erlang:element(2, Observation),
                erlang:element(3, Observation),
                false,
                Reason};

        {ok, Budget} ->
            Takeover_ok = erlang:element(4, Observation) =< erlang:element(
                3,
                Budget
            ),
            Recovery_ok = erlang:element(5, Observation) =< erlang:element(
                4,
                Budget
            ),
            Loss_ok = erlang:element(7, Observation) =< erlang:element(
                5,
                Budget
            ),
            Continuity_ok = erlang:element(8, Observation),
            Passed = ((Takeover_ok andalso Recovery_ok) andalso Loss_ok) andalso Continuity_ok,
            Reason@1 = case Passed of
                true ->
                    <<"within_budget"/utf8>>;

                false ->
                    <<<<<<<<<<<<<<<<"budget_exceeded:"/utf8, "takeover="/utf8>>/binary,
                                                (bool_label(Takeover_ok))/binary>>/binary,
                                            ":recovery="/utf8>>/binary,
                                        (bool_label(Recovery_ok))/binary>>/binary,
                                    ":data_loss="/utf8>>/binary,
                                (bool_label(Loss_ok))/binary>>/binary,
                            ":continuity="/utf8>>/binary,
                        (bool_label(Continuity_ok))/binary>>
            end,
            {budget_result,
                erlang:element(2, Observation),
                erlang:element(3, Observation),
                Passed,
                Reason@1}
    end.

-file("src/lightspeed/cluster/durable_backend.gleam", 462).
-spec evaluate_budget_loop(
    list(observation()),
    list(slo_budget()),
    list(budget_result())
) -> list(budget_result()).
evaluate_budget_loop(Observations, Budgets, Results_rev) ->
    case Observations of
        [] ->
            lists:reverse(Results_rev);

        [Observation | Rest] ->
            Result = evaluate_one_budget(Observation, Budgets),
            evaluate_budget_loop(Rest, Budgets, [Result | Results_rev])
    end.

-file("src/lightspeed/cluster/durable_backend.gleam", 220).
?DOC(" Evaluate one pressure-matrix run against one SLO budget profile.\n").
-spec evaluate_slo_budget(list(observation()), list(slo_budget())) -> list(budget_result()).
evaluate_slo_budget(Observations, Budgets) ->
    evaluate_budget_loop(Observations, Budgets, []).

-file("src/lightspeed/cluster/durable_backend.gleam", 228).
?DOC(" Count failing budget checks.\n").
-spec budget_failures(list(budget_result())) -> integer().
budget_failures(Results) ->
    case Results of
        [] ->
            0;

        [Result | Rest] ->
            case erlang:element(4, Result) of
                true ->
                    budget_failures(Rest);

                false ->
                    1 + budget_failures(Rest)
            end
    end.

-file("src/lightspeed/cluster/durable_backend.gleam", 240).
?DOC(" Stable backend-class label.\n").
-spec backend_class_label(backend_class()) -> binary().
backend_class_label(Class) ->
    case Class of
        sql_quorum ->
            <<"sql_quorum"/utf8>>;

        kv_consensus ->
            <<"kv_consensus"/utf8>>;

        log_replicated ->
            <<"log_replicated"/utf8>>;

        object_manifest ->
            <<"object_manifest"/utf8>>
    end.

-file("src/lightspeed/cluster/durable_backend.gleam", 250).
?DOC(" Stable pressure label.\n").
-spec pressure_label(pressure_profile()) -> binary().
pressure_label(Pressure) ->
    case Pressure of
        nominal ->
            <<"nominal"/utf8>>;

        dependency_degraded ->
            <<"dependency_degraded"/utf8>>;

        dependency_partitioned ->
            <<"dependency_partitioned"/utf8>>
    end.

-file("src/lightspeed/cluster/durable_backend.gleam", 259).
?DOC(" Stable artifact signature.\n").
-spec artifact_signature(certification_artifact()) -> binary().
artifact_signature(Artifact) ->
    <<<<<<<<<<"tuning="/utf8, (erlang:element(2, Artifact))/binary>>/binary,
                    "|certification="/utf8>>/binary,
                (erlang:element(3, Artifact))/binary>>/binary,
            "|evidence="/utf8>>/binary,
        (erlang:element(4, Artifact))/binary>>.

-file("src/lightspeed/cluster/durable_backend.gleam", 539).
-spec join_with(binary(), list(binary())) -> binary().
join_with(Separator, Values) ->
    case Values of
        [] ->
            <<""/utf8>>;

        [Value] ->
            Value;

        [Value@1 | Rest] ->
            <<<<Value@1/binary, Separator/binary>>/binary,
                (join_with(Separator, Rest))/binary>>
    end.

-file("src/lightspeed/cluster/durable_backend.gleam", 269).
?DOC(" Stable backend signature.\n").
-spec backend_signature(backend_contract()) -> binary().
backend_signature(Backend) ->
    <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"backend="/utf8,
                                                                        (erlang:element(
                                                                            2,
                                                                            Backend
                                                                        ))/binary>>/binary,
                                                                    "|class="/utf8>>/binary,
                                                                (backend_class_label(
                                                                    erlang:element(
                                                                        3,
                                                                        Backend
                                                                    )
                                                                ))/binary>>/binary,
                                                            "|store="/utf8>>/binary,
                                                        (erlang:element(
                                                            4,
                                                            Backend
                                                        ))/binary>>/binary,
                                                    "|fencing="/utf8>>/binary,
                                                (bool_label(
                                                    erlang:element(5, Backend)
                                                ))/binary>>/binary,
                                            "|replay="/utf8>>/binary,
                                        (bool_label(erlang:element(6, Backend)))/binary>>/binary,
                                    "|slo_ms="/utf8>>/binary,
                                (erlang:integer_to_binary(
                                    erlang:element(7, Backend)
                                ))/binary>>/binary,
                            "|max_data_loss="/utf8>>/binary,
                        (erlang:integer_to_binary(erlang:element(8, Backend)))/binary>>/binary,
                    "|pressures="/utf8>>/binary,
                (join_with(
                    <<","/utf8>>,
                    gleam@list:map(
                        erlang:element(9, Backend),
                        fun pressure_label/1
                    )
                ))/binary>>/binary,
            "|artifact="/utf8>>/binary,
        (artifact_signature(erlang:element(10, Backend)))/binary>>.

-file("src/lightspeed/cluster/durable_backend.gleam", 291).
?DOC(" Stable pressure observation signature.\n").
-spec observation_signature(observation()) -> binary().
observation_signature(Observation) ->
    <<<<<<<<<<<<<<<<<<<<<<<<(erlang:element(2, Observation))/binary,
                                                    ":pressure="/utf8>>/binary,
                                                (pressure_label(
                                                    erlang:element(
                                                        3,
                                                        Observation
                                                    )
                                                ))/binary>>/binary,
                                            ":takeover_ms="/utf8>>/binary,
                                        (erlang:integer_to_binary(
                                            erlang:element(4, Observation)
                                        ))/binary>>/binary,
                                    ":recovery_ms="/utf8>>/binary,
                                (erlang:integer_to_binary(
                                    erlang:element(5, Observation)
                                ))/binary>>/binary,
                            ":fence_rejections="/utf8>>/binary,
                        (erlang:integer_to_binary(
                            erlang:element(6, Observation)
                        ))/binary>>/binary,
                    ":data_loss_events="/utf8>>/binary,
                (erlang:integer_to_binary(erlang:element(7, Observation)))/binary>>/binary,
            ":continuity_met="/utf8>>/binary,
        (bool_label(erlang:element(8, Observation)))/binary>>.

-file("src/lightspeed/cluster/durable_backend.gleam", 308).
?DOC(" Stable budget-result signature.\n").
-spec budget_result_signature(budget_result()) -> binary().
budget_result_signature(Result) ->
    <<<<<<<<<<<<(erlang:element(2, Result))/binary, ":pressure="/utf8>>/binary,
                        (pressure_label(erlang:element(3, Result)))/binary>>/binary,
                    ":passed="/utf8>>/binary,
                (bool_label(erlang:element(4, Result)))/binary>>/binary,
            ":reason="/utf8>>/binary,
        (erlang:element(5, Result))/binary>>.

-file("src/lightspeed/cluster/durable_backend.gleam", 319).
?DOC(" Stable matrix signature across expanded backends.\n").
-spec matrix_signature() -> binary().
matrix_signature() ->
    join_with(
        <<";"/utf8>>,
        gleam@list:map(expanded_backends(), fun backend_signature/1)
    ).

-file("src/lightspeed/cluster/durable_backend.gleam", 324).
?DOC(" Backend name accessor.\n").
-spec name(backend_contract()) -> binary().
name(Backend) ->
    erlang:element(2, Backend).

-file("src/lightspeed/cluster/durable_backend.gleam", 329).
?DOC(" Backend artifact accessor.\n").
-spec artifact(backend_contract()) -> certification_artifact().
artifact(Backend) ->
    erlang:element(10, Backend).