src/lightspeed@ops@ga_harness.erl

-module(lightspeed@ops@ga_harness).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/lightspeed/ops/ga_harness.gleam").
-export([run_scenario/1, run_matrix/0, scenario_label/1, pass_fail_label/1, signature/1, deterministic/1, scenario/1, outcomes/1, failed_scenarios/1, nondeterministic_failures/1, report_signature/1]).
-export_type([scenario/0, scenario_outcome/0, report/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(" GA parity harness for 1.0.0 release readiness and reproducibility.\n").

-type scenario() :: policy_freeze |
    quality_gate |
    performance_gate |
    channel_gate |
    generator_gate |
    migration_gate.

-type scenario_outcome() :: {scenario_outcome,
        scenario(),
        boolean(),
        boolean(),
        binary()}.

-type report() :: {report, list(scenario_outcome()), integer(), integer()}.

-file("src/lightspeed/ops/ga_harness.gleam", 245).
-spec count_nondeterministic(list(scenario_outcome())) -> integer().
count_nondeterministic(Outcomes) ->
    case Outcomes of
        [] ->
            0;

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

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

-file("src/lightspeed/ops/ga_harness.gleam", 234).
-spec count_failed(list(scenario_outcome())) -> integer().
count_failed(Outcomes) ->
    case Outcomes of
        [] ->
            0;

        [Outcome | Rest] ->
            case erlang:element(3, Outcome) of
                true ->
                    count_failed(Rest);

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

-file("src/lightspeed/ops/ga_harness.gleam", 211).
-spec evaluate_migration_gate() -> {boolean(), binary()}.
evaluate_migration_gate() ->
    First = lightspeed@ops@migration_harness:run_matrix(),
    Second = lightspeed@ops@migration_harness:run_matrix(),
    First_signature = lightspeed@ops@migration_harness:report_signature(First),
    Second_signature = lightspeed@ops@migration_harness:report_signature(Second),
    Passed = (lightspeed@ops@migration_harness:failed_scenarios(First) =:= 0)
    andalso (First_signature =:= Second_signature),
    {Passed, First_signature}.

-file("src/lightspeed/ops/ga_harness.gleam", 199).
-spec evaluate_generator_gate() -> {boolean(), binary()}.
evaluate_generator_gate() ->
    First = lightspeed@ops@generator_harness:run_matrix(),
    Second = lightspeed@ops@generator_harness:run_matrix(),
    First_signature = lightspeed@ops@generator_harness:report_signature(First),
    Second_signature = lightspeed@ops@generator_harness:report_signature(Second),
    Passed = (lightspeed@ops@generator_harness:failed_scenarios(First) =:= 0)
    andalso (First_signature =:= Second_signature),
    {Passed, First_signature}.

-file("src/lightspeed/ops/ga_harness.gleam", 189).
-spec evaluate_channel_gate() -> {boolean(), binary()}.
evaluate_channel_gate() ->
    First = lightspeed@ops@channel_harness:run_default(),
    Second = lightspeed@ops@channel_harness:run_default(),
    First_signature = lightspeed@ops@channel_harness:report_signature(First),
    Second_signature = lightspeed@ops@channel_harness:report_signature(Second),
    Passed = First_signature =:= Second_signature,
    {Passed, First_signature}.

-file("src/lightspeed/ops/ga_harness.gleam", 177).
-spec evaluate_performance_gate() -> {boolean(), binary()}.
evaluate_performance_gate() ->
    Report = lightspeed@ops@performance_harness:run_suite(),
    Budget = lightspeed@ops@performance_harness:evaluate_budget(
        Report,
        lightspeed@ops@performance_harness:default_budget()
    ),
    Passed = lightspeed@ops@performance_harness:budget_failures(Budget) =:= 0,
    {Passed, lightspeed@ops@performance_harness:report_signature(Report)}.

-file("src/lightspeed/ops/ga_harness.gleam", 168).
-spec evaluate_quality_gate() -> {boolean(), binary()}.
evaluate_quality_gate() ->
    Report = lightspeed@ops@quality_harness:run_matrix(),
    Passed = (lightspeed@ops@quality_harness:failed_scenarios(Report) =:= 0)
    andalso (lightspeed@ops@quality_harness:nondeterministic_failures(Report)
    =:= 0),
    {Passed, lightspeed@ops@quality_harness:report_signature(Report)}.

-file("src/lightspeed/ops/ga_harness.gleam", 223).
-spec has_milestone(list(lightspeed@release@policy:matrix_entry()), binary()) -> boolean().
has_milestone(Entries, Milestone) ->
    case Entries of
        [] ->
            false;

        [Entry | Rest] ->
            case erlang:element(2, Entry) =:= Milestone of
                true ->
                    true;

                false ->
                    has_milestone(Rest, Milestone)
            end
    end.

-file("src/lightspeed/ops/ga_harness.gleam", 152).
-spec evaluate_policy_freeze() -> {boolean(), binary()}.
evaluate_policy_freeze() ->
    Release_policy = lightspeed@release@policy:ga_1_0_0(),
    Matrix = lightspeed@release@policy:matrix(Release_policy),
    Passed = ((((((lightspeed@release@policy:valid(Release_policy) andalso has_milestone(
        Matrix,
        <<"M13"/utf8>>
    ))
    andalso has_milestone(Matrix, <<"M14"/utf8>>))
    andalso has_milestone(Matrix, <<"M15"/utf8>>))
    andalso has_milestone(Matrix, <<"M16"/utf8>>))
    andalso has_milestone(Matrix, <<"M17"/utf8>>))
    andalso has_milestone(Matrix, <<"M18"/utf8>>))
    andalso has_milestone(Matrix, <<"M19"/utf8>>),
    {Passed, lightspeed@release@policy:policy_signature(Release_policy)}.

-file("src/lightspeed/ops/ga_harness.gleam", 141).
-spec evaluate(scenario()) -> {boolean(), binary()}.
evaluate(Scenario) ->
    case Scenario of
        policy_freeze ->
            evaluate_policy_freeze();

        quality_gate ->
            evaluate_quality_gate();

        performance_gate ->
            evaluate_performance_gate();

        channel_gate ->
            evaluate_channel_gate();

        generator_gate ->
            evaluate_generator_gate();

        migration_gate ->
            evaluate_migration_gate()
    end.

-file("src/lightspeed/ops/ga_harness.gleam", 60).
?DOC(" Run one scenario twice and require stable signature parity.\n").
-spec run_scenario(scenario()) -> scenario_outcome().
run_scenario(Scenario) ->
    {First_passed, First_signature} = evaluate(Scenario),
    {Second_passed, Second_signature} = evaluate(Scenario),
    Deterministic = (First_passed =:= Second_passed) andalso (First_signature
    =:= Second_signature),
    Passed = (First_passed andalso Second_passed) andalso Deterministic,
    {scenario_outcome, Scenario, Passed, Deterministic, First_signature}.

-file("src/lightspeed/ops/ga_harness.gleam", 41).
?DOC(" Run all M20 GA readiness scenarios.\n").
-spec run_matrix() -> report().
run_matrix() ->
    Scenarios = [policy_freeze,
        quality_gate,
        performance_gate,
        channel_gate,
        generator_gate,
        migration_gate],
    Outcomes = gleam@list:map(Scenarios, fun run_scenario/1),
    {report, Outcomes, count_failed(Outcomes), count_nondeterministic(Outcomes)}.

-file("src/lightspeed/ops/ga_harness.gleam", 76).
?DOC(" Scenario label.\n").
-spec scenario_label(scenario()) -> binary().
scenario_label(Scenario) ->
    case Scenario of
        policy_freeze ->
            <<"policy_freeze"/utf8>>;

        quality_gate ->
            <<"quality_gate"/utf8>>;

        performance_gate ->
            <<"performance_gate"/utf8>>;

        channel_gate ->
            <<"channel_gate"/utf8>>;

        generator_gate ->
            <<"generator_gate"/utf8>>;

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

-file("src/lightspeed/ops/ga_harness.gleam", 88).
?DOC(" Stable pass/fail label.\n").
-spec pass_fail_label(scenario_outcome()) -> binary().
pass_fail_label(Outcome) ->
    case erlang:element(3, Outcome) of
        true ->
            <<"pass"/utf8>>;

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

-file("src/lightspeed/ops/ga_harness.gleam", 96).
?DOC(" Scenario signature.\n").
-spec signature(scenario_outcome()) -> binary().
signature(Outcome) ->
    erlang:element(5, Outcome).

-file("src/lightspeed/ops/ga_harness.gleam", 101).
?DOC(" Determinism accessor.\n").
-spec deterministic(scenario_outcome()) -> boolean().
deterministic(Outcome) ->
    erlang:element(4, Outcome).

-file("src/lightspeed/ops/ga_harness.gleam", 106).
?DOC(" Scenario accessor.\n").
-spec scenario(scenario_outcome()) -> scenario().
scenario(Outcome) ->
    erlang:element(2, Outcome).

-file("src/lightspeed/ops/ga_harness.gleam", 111).
?DOC(" Outcomes accessor.\n").
-spec outcomes(report()) -> list(scenario_outcome()).
outcomes(Report) ->
    erlang:element(2, Report).

-file("src/lightspeed/ops/ga_harness.gleam", 116).
?DOC(" Failed scenario count.\n").
-spec failed_scenarios(report()) -> integer().
failed_scenarios(Report) ->
    erlang:element(3, Report).

-file("src/lightspeed/ops/ga_harness.gleam", 121).
?DOC(" Nondeterministic scenario count.\n").
-spec nondeterministic_failures(report()) -> integer().
nondeterministic_failures(Report) ->
    erlang:element(4, Report).

-file("src/lightspeed/ops/ga_harness.gleam", 263).
-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/ops/ga_harness.gleam", 256).
-spec bool_label(boolean()) -> binary().
bool_label(Value) ->
    case Value of
        true ->
            <<"true"/utf8>>;

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

-file("src/lightspeed/ops/ga_harness.gleam", 126).
?DOC(" Stable report signature for M20 fixtures and release checklist evidence.\n").
-spec report_signature(report()) -> binary().
report_signature(Report) ->
    Entries = gleam@list:map(
        erlang:element(2, Report),
        fun(Outcome) ->
            <<<<<<<<<<<<(scenario_label(erlang:element(2, Outcome)))/binary,
                                    "="/utf8>>/binary,
                                (pass_fail_label(Outcome))/binary>>/binary,
                            ":deterministic="/utf8>>/binary,
                        (bool_label(erlang:element(4, Outcome)))/binary>>/binary,
                    ":"/utf8>>/binary,
                (erlang:element(5, Outcome))/binary>>
        end
    ),
    join_with(<<";"/utf8>>, Entries).