src/lightspeed@ops@transport_matrix_harness.erl

-module(lightspeed@ops@transport_matrix_harness).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/lightspeed/ops/transport_matrix_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(" Deterministic M24 transport matrix and progressive enhancement harness.\n").

-type scenario() :: compatibility_across_profiles |
    reconnect_and_ordering_invariant |
    transport_fault_invariant.

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

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

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

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

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 574).
-spec first_failure_reason(list(binary())) -> binary().
first_failure_reason(Frames) ->
    case Frames of
        [] ->
            <<"none"/utf8>>;

        [Frame | Rest] ->
            case lightspeed@protocol:decode(Frame) of
                {ok, {failure, _, Reason}} ->
                    Reason;

                _ ->
                    first_failure_reason(Rest)
            end
    end.

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 585).
-spec append(list(binary()), list(binary())) -> list(binary()).
append(Left, Right) ->
    case Left of
        [] ->
            Right;

        [Entry | Rest] ->
            [Entry | append(Rest, Right)]
    end.

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 551).
-spec drain_receive(lightspeed@transport@matrix:receive_result()) -> {lightspeed@transport@matrix:adapter_state(),
    list(binary())}.
drain_receive(Result) ->
    Polled = lightspeed@transport@matrix:poll(erlang:element(2, Result)),
    {erlang:element(2, Polled),
        append(erlang:element(3, Result), erlang:element(3, Polled))}.

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 539).
-spec drain_connect(lightspeed@transport@matrix:connect_result()) -> {ok,
        {lightspeed@transport@matrix:adapter_state(), list(binary())}} |
    {error, binary()}.
drain_connect(Result) ->
    case Result of
        {rejected, Error} ->
            {error, lightspeed@transport@contract:error_to_string(Error)};

        {connected, State, Outbound_frames} ->
            Polled = lightspeed@transport@matrix:poll(State),
            {ok,
                {erlang:element(2, Polled),
                    append(Outbound_frames, erlang:element(3, Polled))}}
    end.

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 512).
-spec connect_with_policies(
    lightspeed@transport@matrix:profile(),
    boolean(),
    integer(),
    lightspeed@transport@matrix:security_policy(),
    lightspeed@transport@matrix:timeout_policy()
) -> {ok, {lightspeed@transport@matrix:adapter_state(), list(binary())}} |
    {error, binary()}.
connect_with_policies(
    Profile,
    Prefer_fallback,
    Now_ms,
    Security_policy,
    Timeout_policy
) ->
    Result = lightspeed@transport@matrix:connect_with_policies(
        lightspeed@agent@session:start(
            <<"m24-connect"/utf8>>,
            <<"proc-a"/utf8>>,
            rehydrate,
            0,
            100
        ),
        {connect_request,
            <<"/counter"/utf8>>,
            <<"csrf"/utf8>>,
            <<"https://example.test"/utf8>>,
            Now_ms,
            Prefer_fallback},
        Profile,
        lightspeed@transport@contract:allow_all(<<"proc-a"/utf8>>),
        lightspeed@transport@contract:allow_protection(),
        Security_policy,
        Timeout_policy
    ),
    drain_connect(Result).

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 498).
-spec connect_default(
    lightspeed@transport@matrix:profile(),
    boolean(),
    integer()
) -> {ok, {lightspeed@transport@matrix:adapter_state(), list(binary())}} |
    {error, binary()}.
connect_default(Profile, Prefer_fallback, Now_ms) ->
    connect_with_policies(
        Profile,
        Prefer_fallback,
        Now_ms,
        lightspeed@transport@matrix:default_security_policy(),
        lightspeed@transport@matrix:default_timeout_policy()
    ).

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 388).
-spec run_transport_fault_script(
    lightspeed@transport@matrix:profile(),
    boolean()
) -> {boolean(), binary()}.
run_transport_fault_script(Profile, Prefer_fallback) ->
    Insecure_reason = case lightspeed@transport@matrix:connect(
        lightspeed@agent@session:start(
            <<"m24-fault-insecure"/utf8>>,
            <<"proc-a"/utf8>>,
            rehydrate,
            0,
            100
        ),
        {connect_request,
            <<"/counter"/utf8>>,
            <<"csrf"/utf8>>,
            <<"http://example.test"/utf8>>,
            0,
            Prefer_fallback},
        Profile,
        lightspeed@transport@contract:allow_all(<<"proc-a"/utf8>>)
    ) of
        {rejected, Error} ->
            lightspeed@transport@contract:error_to_string(Error);

        {connected, _, _} ->
            <<"unexpected_ok"/utf8>>
    end,
    Bad_frame_reason = case connect_default(Profile, Prefer_fallback, 0) of
        {error, Reason} ->
            <<"connect_error:"/utf8, Reason/binary>>;

        {ok, {Connected, _}} ->
            Result = lightspeed@transport@matrix:'receive'(
                Connected,
                <<"event|1|save|abc\\"/utf8>>,
                1,
                1
            ),
            {_, Frames} = drain_receive(Result),
            first_failure_reason(Frames)
    end,
    Payload_reason = case connect_with_policies(
        Profile,
        Prefer_fallback,
        0,
        {security_policy, true, true, 8},
        lightspeed@transport@matrix:default_timeout_policy()
    ) of
        {error, Reason@1} ->
            <<"connect_error:"/utf8, Reason@1/binary>>;

        {ok, {Connected@1, _}} ->
            Huge_payload = lightspeed@protocol:encode(
                {event,
                    <<"huge"/utf8>>,
                    <<"increment"/utf8>>,
                    <<"{\"k\":\"long\"}"/utf8>>}
            ),
            Result@1 = lightspeed@transport@matrix:'receive'(
                Connected@1,
                Huge_payload,
                1,
                1
            ),
            {_, Frames@1} = drain_receive(Result@1),
            first_failure_reason(Frames@1)
    end,
    Timeout_reason = case connect_with_policies(
        Profile,
        Prefer_fallback,
        0,
        lightspeed@transport@matrix:default_security_policy(),
        {timeout_policy, 5, 50}
    ) of
        {error, Reason@2} ->
            <<"connect_error:"/utf8, Reason@2/binary>>;

        {ok, {Connected@2, _}} ->
            Result@2 = lightspeed@transport@matrix:'receive'(
                Connected@2,
                lightspeed@protocol:encode(
                    {event, <<"hb"/utf8>>, <<"heartbeat"/utf8>>, <<"{}"/utf8>>}
                ),
                10,
                1
            ),
            {_, Frames@2} = drain_receive(Result@2),
            first_failure_reason(Frames@2)
    end,
    Passed = (((Insecure_reason =:= <<"protection_rejected:insecure_origin"/utf8>>)
    andalso (Bad_frame_reason =:= <<"protocol_decode_failed:invalid_escape_sequence"/utf8>>))
    andalso (Payload_reason =:= <<"unsupported_client_frame:payload_too_large"/utf8>>))
    andalso (Timeout_reason =:= <<"invalid_adapter_state:heartbeat_timeout"/utf8>>),
    {Passed,
        <<<<<<<<<<<<<<"insecure="/utf8, Insecure_reason/binary>>/binary,
                                ",bad_frame="/utf8>>/binary,
                            Bad_frame_reason/binary>>/binary,
                        ",payload="/utf8>>/binary,
                    Payload_reason/binary>>/binary,
                ",timeout="/utf8>>/binary,
            Timeout_reason/binary>>}.

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 201).
-spec evaluate_transport_fault_invariant() -> {boolean(), binary()}.
evaluate_transport_fault_invariant() ->
    {Ws_passed, Ws_signature} = run_transport_fault_script(
        web_socket_only,
        false
    ),
    {Sse_passed, Sse_signature} = run_transport_fault_script(
        web_socket_with_server_sent_events_fallback,
        true
    ),
    {Lp_passed, Lp_signature} = run_transport_fault_script(
        web_socket_with_long_polling_fallback,
        true
    ),
    Signatures_match = (Ws_signature =:= Sse_signature) andalso (Sse_signature
    =:= Lp_signature),
    Passed = ((Ws_passed andalso Sse_passed) andalso Lp_passed) andalso Signatures_match,
    {Passed,
        <<<<<<<<<<<<<<"ws="/utf8, Ws_signature/binary>>/binary, "|sse="/utf8>>/binary,
                            Sse_signature/binary>>/binary,
                        "|lp="/utf8>>/binary,
                    Lp_signature/binary>>/binary,
                "|signatures_match="/utf8>>/binary,
            (bool_label(Signatures_match))/binary>>}.

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 614).
-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/transport_matrix_harness.gleam", 563).
-spec frame_label(binary()) -> binary().
frame_label(Frame) ->
    case lightspeed@protocol:decode(Frame) of
        {ok, {hello, _, _}} ->
            <<"hello"/utf8>>;

        {ok, {event, _, _, _}} ->
            <<"event"/utf8>>;

        {ok, {diff, _, _}} ->
            <<"diff"/utf8>>;

        {ok, {ack, _}} ->
            <<"ack"/utf8>>;

        {ok, {failure, _, _}} ->
            <<"failure"/utf8>>;

        {error, _} ->
            <<"invalid"/utf8>>
    end.

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 558).
-spec frame_labels(list(binary())) -> binary().
frame_labels(Frames) ->
    Labels = begin
        _pipe = Frames,
        gleam@list:map(_pipe, fun frame_label/1)
    end,
    join_with(<<","/utf8>>, Labels).

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 287).
-spec run_reconnect_and_ordering_script(
    lightspeed@transport@matrix:profile(),
    boolean()
) -> {boolean(), binary()}.
run_reconnect_and_ordering_script(Profile, Prefer_fallback) ->
    case connect_default(Profile, Prefer_fallback, 0) of
        {error, Reason} ->
            {false, <<"connect_error="/utf8, Reason/binary>>};

        {ok, {Connected, _}} ->
            Ack_result = lightspeed@transport@matrix:'receive'(
                Connected,
                lightspeed@protocol:encode({ack, <<"1"/utf8>>}),
                1,
                1
            ),
            {After_ack, _} = drain_receive(Ack_result),
            Reconnect_result = lightspeed@transport@matrix:reconnect(
                After_ack,
                {connect_request,
                    <<"/counter"/utf8>>,
                    <<"csrf"/utf8>>,
                    <<"https://example.test"/utf8>>,
                    3,
                    Prefer_fallback},
                lightspeed@transport@contract:allow_all(<<"proc-a"/utf8>>)
            ),
            case drain_connect(Reconnect_result) of
                {error, Reason@1} ->
                    {false, <<"reconnect_error="/utf8, Reason@1/binary>>};

                {ok, {After_reconnect, Reconnect_frames}} ->
                    Reconnect_labels = frame_labels(Reconnect_frames),
                    Increment_result = lightspeed@transport@matrix:'receive'(
                        After_reconnect,
                        lightspeed@protocol:encode(
                            {event,
                                <<"inc-2"/utf8>>,
                                <<"increment"/utf8>>,
                                <<"{}"/utf8>>}
                        ),
                        4,
                        2
                    ),
                    {After_increment, Increment_frames} = drain_receive(
                        Increment_result
                    ),
                    Increment_labels = frame_labels(Increment_frames),
                    Duplicate_result = lightspeed@transport@matrix:'receive'(
                        After_increment,
                        lightspeed@protocol:encode(
                            {event,
                                <<"dup"/utf8>>,
                                <<"decrement"/utf8>>,
                                <<"{}"/utf8>>}
                        ),
                        5,
                        2
                    ),
                    {After_duplicate, Duplicate_frames} = drain_receive(
                        Duplicate_result
                    ),
                    Duplicate_reason = first_failure_reason(Duplicate_frames),
                    Final_increment = lightspeed@transport@matrix:'receive'(
                        After_duplicate,
                        lightspeed@protocol:encode(
                            {event,
                                <<"inc-3"/utf8>>,
                                <<"increment"/utf8>>,
                                <<"{}"/utf8>>}
                        ),
                        6,
                        3
                    ),
                    {After_final, Final_frames} = drain_receive(Final_increment),
                    Final_labels = frame_labels(Final_frames),
                    Counter = lightspeed@agent@session:counter(
                        lightspeed@transport@matrix:session_state(After_final)
                    ),
                    Passed = ((((Reconnect_labels =:= <<"hello,diff"/utf8>>)
                    andalso (Increment_labels =:= <<"diff"/utf8>>))
                    andalso (Duplicate_reason =:= <<"invalid_adapter_state:event_order_violation:last=2:incoming=2"/utf8>>))
                    andalso (Final_labels =:= <<"diff"/utf8>>))
                    andalso (Counter =:= 2),
                    {Passed,
                        <<<<<<<<<<<<<<<<<<"reconnect="/utf8,
                                                            Reconnect_labels/binary>>/binary,
                                                        ",increment="/utf8>>/binary,
                                                    Increment_labels/binary>>/binary,
                                                ",duplicate_reason="/utf8>>/binary,
                                            Duplicate_reason/binary>>/binary,
                                        ",final="/utf8>>/binary,
                                    Final_labels/binary>>/binary,
                                ",counter="/utf8>>/binary,
                            (erlang:integer_to_binary(Counter))/binary>>}
            end
    end.

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 171).
-spec evaluate_reconnect_and_ordering_invariant() -> {boolean(), binary()}.
evaluate_reconnect_and_ordering_invariant() ->
    {Ws_passed, Ws_signature} = run_reconnect_and_ordering_script(
        web_socket_only,
        false
    ),
    {Sse_passed, Sse_signature} = run_reconnect_and_ordering_script(
        web_socket_with_server_sent_events_fallback,
        true
    ),
    {Lp_passed, Lp_signature} = run_reconnect_and_ordering_script(
        web_socket_with_long_polling_fallback,
        true
    ),
    Signatures_match = (Ws_signature =:= Sse_signature) andalso (Sse_signature
    =:= Lp_signature),
    Passed = ((Ws_passed andalso Sse_passed) andalso Lp_passed) andalso Signatures_match,
    {Passed,
        <<<<<<<<<<<<<<"ws="/utf8, Ws_signature/binary>>/binary, "|sse="/utf8>>/binary,
                            Sse_signature/binary>>/binary,
                        "|lp="/utf8>>/binary,
                    Lp_signature/binary>>/binary,
                "|signatures_match="/utf8>>/binary,
            (bool_label(Signatures_match))/binary>>}.

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 492).
-spec verify_m10_regression_guard() -> boolean().
verify_m10_regression_guard() ->
    Report = lightspeed@ops@quality_harness:run_matrix(),
    (lightspeed@ops@quality_harness:failed_scenarios(Report) =:= 0) andalso (lightspeed@ops@quality_harness:nondeterministic_failures(
        Report
    )
    =:= 0).

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 228).
-spec run_compatibility_script(lightspeed@transport@matrix:profile(), boolean()) -> {boolean(),
    binary()}.
run_compatibility_script(Profile, Prefer_fallback) ->
    case connect_default(Profile, Prefer_fallback, 0) of
        {error, Reason} ->
            {false, <<"connect_error="/utf8, Reason/binary>>};

        {ok, {Connected, Connect_frames}} ->
            Connect_labels = frame_labels(Connect_frames),
            Ack_result = lightspeed@transport@matrix:'receive'(
                Connected,
                lightspeed@protocol:encode({ack, <<"1"/utf8>>}),
                1,
                1
            ),
            {After_ack, Ack_frames} = drain_receive(Ack_result),
            Ack_labels = frame_labels(Ack_frames),
            Increment_result = lightspeed@transport@matrix:'receive'(
                After_ack,
                lightspeed@protocol:encode(
                    {event,
                        <<"inc-1"/utf8>>,
                        <<"increment"/utf8>>,
                        <<"{}"/utf8>>}
                ),
                2,
                2
            ),
            {After_increment, Increment_frames} = drain_receive(
                Increment_result
            ),
            Increment_labels = frame_labels(Increment_frames),
            Counter = lightspeed@agent@session:counter(
                lightspeed@transport@matrix:session_state(After_increment)
            ),
            Push_capability = lightspeed@transport@matrix:capability_enabled(
                After_increment,
                server_push_frames
            ),
            Bidirectional = lightspeed@transport@matrix:capability_enabled(
                After_increment,
                bidirectional_channel
            ),
            Passed = ((((Connect_labels =:= <<"hello,diff"/utf8>>) andalso (Ack_labels
            =:= <<""/utf8>>))
            andalso (Increment_labels =:= <<"diff"/utf8>>))
            andalso (Counter =:= 1))
            andalso case lightspeed@transport@matrix:mode_label(After_increment) of
                <<"primary_realtime"/utf8>> ->
                    Push_capability andalso Bidirectional;

                <<"fallback_polling"/utf8>> ->
                    not Push_capability andalso not Bidirectional;

                _ ->
                    false
            end,
            {Passed,
                <<<<<<<<<<<<<<"connect="/utf8, Connect_labels/binary>>/binary,
                                        ",ack="/utf8>>/binary,
                                    Ack_labels/binary>>/binary,
                                ",increment="/utf8>>/binary,
                            Increment_labels/binary>>/binary,
                        ",counter="/utf8>>/binary,
                    (erlang:integer_to_binary(Counter))/binary>>}
    end.

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 142).
-spec evaluate_compatibility_across_profiles() -> {boolean(), binary()}.
evaluate_compatibility_across_profiles() ->
    {Ws_passed, Ws_signature} = run_compatibility_script(web_socket_only, false),
    {Sse_passed, Sse_signature} = run_compatibility_script(
        web_socket_with_server_sent_events_fallback,
        true
    ),
    {Lp_passed, Lp_signature} = run_compatibility_script(
        web_socket_with_long_polling_fallback,
        true
    ),
    Signatures_match = (Ws_signature =:= Sse_signature) andalso (Sse_signature
    =:= Lp_signature),
    Passed = (((Ws_passed andalso Sse_passed) andalso Lp_passed) andalso Signatures_match)
    andalso verify_m10_regression_guard(),
    {Passed,
        <<<<<<<<<<<<<<"ws="/utf8, Ws_signature/binary>>/binary, "|sse="/utf8>>/binary,
                            Sse_signature/binary>>/binary,
                        "|lp="/utf8>>/binary,
                    Lp_signature/binary>>/binary,
                "|signatures_match="/utf8>>/binary,
            (bool_label(Signatures_match))/binary>>}.

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 134).
-spec evaluate(scenario()) -> {boolean(), binary()}.
evaluate(Scenario) ->
    case Scenario of
        compatibility_across_profiles ->
            evaluate_compatibility_across_profiles();

        reconnect_and_ordering_invariant ->
            evaluate_reconnect_and_ordering_invariant();

        transport_fault_invariant ->
            evaluate_transport_fault_invariant()
    end.

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 55).
?DOC(" Run one scenario twice and require deterministic 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/transport_matrix_harness.gleam", 38).
?DOC(" Run all M24 scenarios.\n").
-spec run_matrix() -> report().
run_matrix() ->
    Outcomes = begin
        _pipe = [compatibility_across_profiles,
            reconnect_and_ordering_invariant,
            transport_fault_invariant],
        gleam@list:map(_pipe, fun run_scenario/1)
    end,
    {report, Outcomes, count_failed(Outcomes), count_nondeterministic(Outcomes)}.

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

        reconnect_and_ordering_invariant ->
            <<"reconnect_and_ordering_invariant"/utf8>>;

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

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 80).
?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/transport_matrix_harness.gleam", 88).
?DOC(" Scenario signature.\n").
-spec signature(scenario_outcome()) -> binary().
signature(Outcome) ->
    erlang:element(5, Outcome).

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 93).
?DOC(" Whether the scenario was deterministic.\n").
-spec deterministic(scenario_outcome()) -> boolean().
deterministic(Outcome) ->
    erlang:element(4, Outcome).

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

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

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

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

-file("src/lightspeed/ops/transport_matrix_harness.gleam", 118).
?DOC(" Stable report signature for CI fixtures.\n").
-spec report_signature(report()) -> binary().
report_signature(Report) ->
    Entries = begin
        _pipe = erlang:element(2, Report),
        gleam@list:map(
            _pipe,
            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
        )
    end,
    join_with(<<";"/utf8>>, Entries).