src/lightspeed@ops@chaos_harness.erl

-module(lightspeed@ops@chaos_harness).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/lightspeed/ops/chaos_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, snapshot_signature/0, snapshot_report_markdown/0]).
-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 chaos, fuzz, and SLO-autopilot harness for M30.\n").

-type scenario() :: protocol_fuzz_corpus_regression |
    runtime_fuzz_corpus_regression |
    transport_chaos_fault_injection |
    runtime_chaos_fault_injection |
    storage_chaos_fault_injection |
    slo_autopilot_audit_gate.

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

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

-file("src/lightspeed/ops/chaos_harness.gleam", 760).
-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/chaos_harness.gleam", 749).
-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/chaos_harness.gleam", 804).
-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/chaos_harness.gleam", 793).
-spec contains_substring(list(binary()), binary()) -> boolean().
contains_substring(Values, Target) ->
    case Values of
        [] ->
            false;

        [Value | Rest] ->
            case gleam_stdlib:contains_string(Value, Target) of
                true ->
                    true;

                false ->
                    contains_substring(Rest, Target)
            end
    end.

-file("src/lightspeed/ops/chaos_harness.gleam", 735).
-spec count_decision(list(lightspeed@ops@slo_autopilot:audit_entry()), binary()) -> integer().
count_decision(Entries, Label) ->
    case Entries of
        [] ->
            0;

        [Entry | Rest] ->
            case lightspeed@ops@slo_autopilot:decision_label(
                erlang:element(4, Entry)
            )
            =:= Label of
                true ->
                    1 + count_decision(Rest, Label);

                false ->
                    count_decision(Rest, Label)
            end
    end.

-file("src/lightspeed/ops/chaos_harness.gleam", 445).
-spec evaluate_slo_autopilot_audit_gate() -> {boolean(), binary()}.
evaluate_slo_autopilot_audit_gate() ->
    Runtime = lightspeed@ops@slo_autopilot:new(
        lightspeed@ops@slo_autopilot:default_thresholds()
    ),
    Warning_sample = lightspeed@ops@slo_autopilot:sample(
        <<"edge"/utf8>>,
        <<"availability"/utf8>>,
        1200,
        900,
        <<"tenant-a"/utf8>>
    ),
    {Runtime@1, Warning_status} = lightspeed@ops@slo_autopilot:evaluate(
        Runtime,
        Warning_sample,
        <<"autopilot"/utf8>>,
        10
    ),
    Critical_sample = lightspeed@ops@slo_autopilot:sample(
        <<"edge"/utf8>>,
        <<"availability"/utf8>>,
        2600,
        1800,
        <<"tenant-a"/utf8>>
    ),
    {Runtime@2, Critical_status} = lightspeed@ops@slo_autopilot:evaluate(
        Runtime@1,
        Critical_sample,
        <<"autopilot"/utf8>>,
        20
    ),
    Healthy_sample = lightspeed@ops@slo_autopilot:sample(
        <<"edge"/utf8>>,
        <<"availability"/utf8>>,
        200,
        100,
        <<""/utf8>>
    ),
    {Runtime@3, Healthy_status} = lightspeed@ops@slo_autopilot:evaluate(
        Runtime@2,
        Healthy_sample,
        <<"autopilot"/utf8>>,
        30
    ),
    Audits = lightspeed@ops@slo_autopilot:audit_entries(Runtime@3),
    Metrics = gleam@list:map(
        Audits,
        fun(Entry) ->
            lightspeed@ops@telemetry:metric_line(
                lightspeed@ops@slo_autopilot:audit_metric(Entry)
            )
        end
    ),
    Applied = count_decision(Audits, <<"applied"/utf8>>),
    Rolled_back = count_decision(Audits, <<"rolled_back"/utf8>>),
    Active = gleam@list:map(
        lightspeed@ops@slo_autopilot:active_controls(Runtime@3),
        fun lightspeed@ops@slo_autopilot:control_label/1
    ),
    Passed = (((((((lightspeed@ops@slo_autopilot:valid(Runtime@3) andalso (lightspeed@ops@slo_autopilot:status_label(
        Warning_status
    )
    =:= <<"warning"/utf8>>))
    andalso (lightspeed@ops@slo_autopilot:status_label(Critical_status) =:= <<"critical"/utf8>>))
    andalso (lightspeed@ops@slo_autopilot:status_label(Healthy_status) =:= <<"healthy"/utf8>>))
    andalso (Active =:= []))
    andalso (Applied >= 3))
    andalso (Rolled_back >= 3))
    andalso contains_substring(
        Metrics,
        <<"counter lightspeed.slo.autopilot_control_total"/utf8>>
    ))
    andalso contains_substring(Metrics, <<"decision=rolled_back"/utf8>>),
    {Passed,
        <<<<<<<<<<<<<<<<<<<<<<<<<<"statuses="/utf8,
                                                            (lightspeed@ops@slo_autopilot:status_label(
                                                                Warning_status
                                                            ))/binary>>/binary,
                                                        ","/utf8>>/binary,
                                                    (lightspeed@ops@slo_autopilot:status_label(
                                                        Critical_status
                                                    ))/binary>>/binary,
                                                ","/utf8>>/binary,
                                            (lightspeed@ops@slo_autopilot:status_label(
                                                Healthy_status
                                            ))/binary>>/binary,
                                        "|active="/utf8>>/binary,
                                    (join_with(<<","/utf8>>, Active))/binary>>/binary,
                                "|applied="/utf8>>/binary,
                            (erlang:integer_to_binary(Applied))/binary>>/binary,
                        "|rolled_back="/utf8>>/binary,
                    (erlang:integer_to_binary(Rolled_back))/binary>>/binary,
                "|runtime="/utf8>>/binary,
            (lightspeed@ops@slo_autopilot:signature(Runtime@3))/binary>>}.

-file("src/lightspeed/ops/chaos_harness.gleam", 699).
-spec takeover_result_label(
    {ok, lightspeed@cluster@durable_session:durable_session()} |
        {error, lightspeed@cluster@durable_session:ownership_error()}
) -> binary().
takeover_result_label(Result) ->
    case Result of
        {ok, _} ->
            <<"ok"/utf8>>;

        {error, Error} ->
            lightspeed@cluster@durable_session:ownership_error_label(Error)
    end.

-file("src/lightspeed/ops/chaos_harness.gleam", 364).
-spec evaluate_storage_chaos_fault_injection() -> {boolean(), binary()}.
evaluate_storage_chaos_fault_injection() ->
    Base = begin
        _pipe = lightspeed@cluster@durable_session:start(
            <<"storage-1"/utf8>>,
            <<"node-a"/utf8>>,
            <<"/counter"/utf8>>,
            {snapshot_journal, <<"snap"/utf8>>, <<"journal"/utf8>>, 2},
            rehydrate,
            0,
            25,
            0
        ),
        _pipe@1 = lightspeed@cluster@durable_session:append_counter_delta(
            _pipe,
            1,
            3
        ),
        _pipe@2 = lightspeed@cluster@durable_session:append_counter_delta(
            _pipe@1,
            1,
            4
        ),
        _pipe@3 = lightspeed@cluster@durable_session:crash(
            _pipe@2,
            <<"boom"/utf8>>
        ),
        lightspeed@cluster@durable_session:restart(_pipe@3, 8)
    end,
    Invalid = begin
        _pipe@4 = lightspeed@cluster@durable_session:request_takeover(
            Base,
            <<"node-b"/utf8>>,
            2,
            <<"wrong-token"/utf8>>,
            10
        ),
        takeover_result_label(_pipe@4)
    end,
    Takeover = case lightspeed@cluster@durable_session:request_takeover(
        Base,
        <<"node-b"/utf8>>,
        2,
        lightspeed@cluster@durable_session:expected_token(
            <<"storage-1"/utf8>>,
            <<"node-b"/utf8>>,
            2
        ),
        12
    ) of
        {ok, Updated} ->
            Updated;

        {error, _} ->
            Base
    end,
    Stale = begin
        _pipe@5 = lightspeed@cluster@durable_session:request_takeover(
            Takeover,
            <<"node-a"/utf8>>,
            1,
            lightspeed@cluster@durable_session:expected_token(
                <<"storage-1"/utf8>>,
                <<"node-a"/utf8>>,
                1
            ),
            13
        ),
        takeover_result_label(_pipe@5)
    end,
    Split = begin
        _pipe@6 = lightspeed@cluster@durable_session:request_takeover(
            Takeover,
            <<"node-c"/utf8>>,
            2,
            lightspeed@cluster@durable_session:expected_token(
                <<"storage-1"/utf8>>,
                <<"node-c"/utf8>>,
                2
            ),
            14
        ),
        takeover_result_label(_pipe@6)
    end,
    Continuity = begin
        _pipe@7 = lightspeed@cluster@durable_session:continuity_report(
            Takeover,
            100,
            140
        ),
        lightspeed@cluster@durable_session:continuity_signature(_pipe@7)
    end,
    Passed = (((Invalid =:= <<"invalid_token:node-b:2"/utf8>>) andalso (Stale
    =:= <<"stale_owner:2:1"/utf8>>))
    andalso (Split =:= <<"split_brain:node-b:node-c:2"/utf8>>))
    andalso gleam_stdlib:contains_string(Continuity, <<"met=false"/utf8>>),
    {Passed,
        <<<<<<<<<<<<<<"invalid="/utf8, Invalid/binary>>/binary, "|stale="/utf8>>/binary,
                            Stale/binary>>/binary,
                        "|split="/utf8>>/binary,
                    Split/binary>>/binary,
                "|continuity="/utf8>>/binary,
            Continuity/binary>>}.

-file("src/lightspeed/ops/chaos_harness.gleam", 771).
-spec count_label(list(binary()), binary()) -> integer().
count_label(Labels, Target) ->
    case Labels of
        [] ->
            0;

        [Value | Rest] ->
            case Value =:= Target of
                true ->
                    1 + count_label(Rest, Target);

                false ->
                    count_label(Rest, Target)
            end
    end.

-file("src/lightspeed/ops/chaos_harness.gleam", 782).
-spec contains(list(binary()), binary()) -> boolean().
contains(Values, Target) ->
    case Values of
        [] ->
            false;

        [Value | Rest] ->
            case Value =:= Target of
                true ->
                    true;

                false ->
                    contains(Rest, Target)
            end
    end.

-file("src/lightspeed/ops/chaos_harness.gleam", 716).
-spec replay_loop(
    lightspeed@agent@session:session(),
    binary(),
    list(lightspeed@agent@session:inbox_event())
) -> lightspeed@agent@session:session().
replay_loop(Runtime, Owner, Events) ->
    case Events of
        [] ->
            Runtime;

        [Event | Rest] ->
            replay_loop(
                lightspeed@agent@session:handle(
                    Runtime,
                    {inbox_message, Owner, Event}
                ),
                Owner,
                Rest
            )
    end.

-file("src/lightspeed/ops/chaos_harness.gleam", 708).
-spec replay_events(list(lightspeed@agent@session:inbox_event())) -> lightspeed@agent@session:session().
replay_events(Events) ->
    replay_loop(
        lightspeed@agent@session:start(
            <<"chaos-runtime"/utf8>>,
            <<"proc-a"/utf8>>,
            rehydrate,
            0,
            50
        ),
        <<"proc-a"/utf8>>,
        Events
    ).

-file("src/lightspeed/ops/chaos_harness.gleam", 326).
-spec evaluate_runtime_chaos_fault_injection() -> {boolean(), binary()}.
evaluate_runtime_chaos_fault_injection() ->
    Events = [{connect, <<"/counter"/utf8>>, <<"csrf"/utf8>>, 0},
        increment,
        {crash, <<"fault"/utf8>>},
        increment,
        {restart, 5},
        {reconnect, <<"/counter"/utf8>>, 8},
        {heartbeat, 9},
        {tick, 200},
        decrement],
    Final = replay_events(Events),
    Telemetry_labels = gleam@list:map(
        lightspeed@agent@session:telemetry(Final),
        fun lightspeed@agent@session:telemetry_label/1
    ),
    Lifecycle = lightspeed@agent@typestate:lifecycle_to_string(
        lightspeed@agent@session:lifecycle(Final)
    ),
    Counter = lightspeed@agent@session:counter(Final),
    Passed = ((((((Lifecycle =:= <<"draining"/utf8>>) andalso (Counter =:= 1))
    andalso contains(Telemetry_labels, <<"session_crashed"/utf8>>))
    andalso contains(Telemetry_labels, <<"session_restarted"/utf8>>))
    andalso contains(Telemetry_labels, <<"session_rehydrated"/utf8>>))
    andalso contains(Telemetry_labels, <<"heartbeat_timed_out"/utf8>>))
    andalso (count_label(Telemetry_labels, <<"event_ignored"/utf8>>) >= 2),
    {Passed,
        <<<<<<<<<<"lifecycle="/utf8, Lifecycle/binary>>/binary,
                        "|counter="/utf8>>/binary,
                    (erlang:integer_to_binary(Counter))/binary>>/binary,
                "|telemetry="/utf8>>/binary,
            (join_with(<<","/utf8>>, Telemetry_labels))/binary>>}.

-file("src/lightspeed/ops/chaos_harness.gleam", 659).
-spec connect_result_label(lightspeed@transport@matrix:connect_result()) -> binary().
connect_result_label(Result) ->
    case Result of
        {connected, _, _} ->
            <<"connected"/utf8>>;

        {rejected, Error} ->
            <<"rejected:"/utf8,
                (lightspeed@transport@contract:error_to_string(Error))/binary>>
    end.

-file("src/lightspeed/ops/chaos_harness.gleam", 688).
-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/chaos_harness.gleam", 613).
-spec frame_tag(lightspeed@protocol:frame()) -> binary().
frame_tag(Frame) ->
    case Frame of
        {hello, _, _} ->
            <<"hello"/utf8>>;

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

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

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

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

-file("src/lightspeed/ops/chaos_harness.gleam", 675).
-spec frame_labels(list(binary())) -> binary().
frame_labels(Frames) ->
    join_with(
        <<","/utf8>>,
        gleam@list:map(
            Frames,
            fun(Frame) -> case lightspeed@protocol:decode(Frame) of
                    {ok, Decoded} ->
                        frame_tag(Decoded);

                    {error, Error} ->
                        <<"decode_error:"/utf8,
                            (lightspeed@protocol:decode_error_to_string(Error))/binary>>
                end end
        )
    ).

-file("src/lightspeed/ops/chaos_harness.gleam", 623).
-spec connect_with_policy(integer(), binary(), integer(), integer(), integer()) -> {ok,
        lightspeed@transport@matrix:adapter_state()} |
    {error, binary()}.
connect_with_policy(
    Now_ms,
    Origin,
    Max_payload_bytes,
    Heartbeat_timeout_ms,
    Reconnect_grace_ms
) ->
    case lightspeed@transport@matrix:connect_with_policies(
        lightspeed@agent@session:start(
            <<"chaos-transport"/utf8>>,
            <<"proc-a"/utf8>>,
            rehydrate,
            Now_ms,
            100
        ),
        {connect_request,
            <<"/counter"/utf8>>,
            <<"csrf"/utf8>>,
            Origin,
            Now_ms,
            false},
        web_socket_only,
        lightspeed@transport@contract:allow_all(<<"proc-a"/utf8>>),
        lightspeed@transport@contract:allow_protection(),
        {security_policy, true, true, Max_payload_bytes},
        {timeout_policy, Heartbeat_timeout_ms, Reconnect_grace_ms}
    ) of
        {connected, State, _} ->
            {ok, State};

        {rejected, Error} ->
            {error, lightspeed@transport@contract:error_to_string(Error)}
    end.

-file("src/lightspeed/ops/chaos_harness.gleam", 666).
-spec connect_attempt_label(
    {ok, lightspeed@transport@matrix:adapter_state()} | {error, binary()}
) -> binary().
connect_attempt_label(Result) ->
    case Result of
        {ok, _} ->
            <<"connected"/utf8>>;

        {error, Reason} ->
            <<"rejected:"/utf8, Reason/binary>>
    end.

-file("src/lightspeed/ops/chaos_harness.gleam", 227).
-spec evaluate_transport_chaos_fault_injection() -> {boolean(), binary()}.
evaluate_transport_chaos_fault_injection() ->
    Insecure = connect_with_policy(0, <<"http://evil.test"/utf8>>, 64, 5, 10),
    Insecure_label = connect_attempt_label(Insecure),
    case connect_with_policy(0, <<"https://example.test"/utf8>>, 32, 2, 10) of
        {error, Reason} ->
            {false, <<"connect_error:"/utf8, Reason/binary>>};

        {ok, State} ->
            Oversized = lightspeed@transport@matrix:'receive'(
                State,
                lightspeed@protocol:encode(
                    {event,
                        <<"evt-1"/utf8>>,
                        <<"increment"/utf8>>,
                        <<"{\"blob\":\"1234567890123456789012345678901234567890\"}"/utf8>>}
                ),
                1,
                1
            ),
            Oversized_reason = first_failure_reason(
                erlang:element(3, Oversized)
            ),
            Accepted = lightspeed@transport@matrix:'receive'(
                erlang:element(2, Oversized),
                lightspeed@protocol:encode(
                    {event,
                        <<"evt-2"/utf8>>,
                        <<"increment"/utf8>>,
                        <<"{}"/utf8>>}
                ),
                2,
                1
            ),
            Accepted_labels = frame_labels(erlang:element(3, Accepted)),
            Order_violation = lightspeed@transport@matrix:'receive'(
                erlang:element(2, Accepted),
                lightspeed@protocol:encode(
                    {event,
                        <<"evt-3"/utf8>>,
                        <<"decrement"/utf8>>,
                        <<"{}"/utf8>>}
                ),
                3,
                1
            ),
            Order_reason = first_failure_reason(
                erlang:element(3, Order_violation)
            ),
            Timeout = lightspeed@transport@matrix:'receive'(
                erlang:element(2, Order_violation),
                lightspeed@protocol:encode({ack, <<"stale"/utf8>>}),
                8,
                2
            ),
            Timeout_reason = first_failure_reason(erlang:element(3, Timeout)),
            Reconnect_label = begin
                _pipe = lightspeed@transport@matrix:reconnect(
                    erlang:element(2, Timeout),
                    {connect_request,
                        <<"/counter"/utf8>>,
                        <<"csrf"/utf8>>,
                        <<"https://example.test"/utf8>>,
                        30,
                        false},
                    lightspeed@transport@contract:allow_all(<<"proc-a"/utf8>>)
                ),
                connect_result_label(_pipe)
            end,
            Passed = (((((Insecure_label =:= <<"rejected:protection_rejected:insecure_origin"/utf8>>)
            andalso (Oversized_reason =:= <<"unsupported_client_frame:payload_too_large"/utf8>>))
            andalso (Accepted_labels =:= <<"diff"/utf8>>))
            andalso (Order_reason =:= <<"invalid_adapter_state:event_order_violation:last=1:incoming=1"/utf8>>))
            andalso (Timeout_reason =:= <<"invalid_adapter_state:heartbeat_timeout"/utf8>>))
            andalso (Reconnect_label =:= <<"rejected:invalid_adapter_state:reconnect_grace_exceeded"/utf8>>),
            {Passed,
                <<<<<<<<<<<<<<<<<<<<<<"insecure="/utf8, Insecure_label/binary>>/binary,
                                                        "|oversized="/utf8>>/binary,
                                                    Oversized_reason/binary>>/binary,
                                                "|accepted="/utf8>>/binary,
                                            Accepted_labels/binary>>/binary,
                                        "|order="/utf8>>/binary,
                                    Order_reason/binary>>/binary,
                                "|timeout="/utf8>>/binary,
                            Timeout_reason/binary>>/binary,
                        "|reconnect="/utf8>>/binary,
                    Reconnect_label/binary>>}
    end.

-file("src/lightspeed/ops/chaos_harness.gleam", 524).
-spec runtime_corpus() -> list({binary(), binary()}).
runtime_corpus() ->
    Valid_replace = lightspeed@diff:encode_stream(
        [{replace, <<"#app"/utf8>>, <<"<p>ok</p>"/utf8>>}]
    ),
    Valid_upsert = lightspeed@diff:encode_stream(
        [{upsert_keyed, <<"#items"/utf8>>, <<"a"/utf8>>, <<"<li>a</li>"/utf8>>}]
    ),
    [{Valid_replace, <<"ok_ops:1:replace"/utf8>>},
        {Valid_upsert, <<"ok_ops:1:upsert_keyed"/utf8>>},
        {<<""/utf8>>, <<"error:empty_payload"/utf8>>},
        {<<"ps|a|0|0"/utf8>>, <<"error:invalid_integer:a"/utf8>>},
        {<<"ps|2|0|0"/utf8>>, <<"error:unsupported_version:2"/utf8>>},
        {<<"ps|1|0|1|r,0,1"/utf8>>, <<"error:missing_dictionary_entry:0"/utf8>>},
        {<<"ps|1|3|#app|fp|slot|1|u,0,1,1,2"/utf8>>,
            <<"error:bad_field_count:dynamic_slots:2:1"/utf8>>},
        {<<"ps|1|1|#app|1|z,0"/utf8>>, <<"error:malformed_operation:z,0"/utf8>>}].

-file("src/lightspeed/ops/chaos_harness.gleam", 602).
-spec runtime_case_label(binary()) -> binary().
runtime_case_label(Payload) ->
    case lightspeed@diff:decode_stream(Payload) of
        {ok, Patches} ->
            <<<<<<"ok_ops:"/utf8,
                        (erlang:integer_to_binary(erlang:length(Patches)))/binary>>/binary,
                    ":"/utf8>>/binary,
                (join_with(
                    <<","/utf8>>,
                    gleam@list:map(Patches, fun lightspeed@diff:operation/1)
                ))/binary>>;

        {error, Error} ->
            <<"error:"/utf8,
                (lightspeed@diff:decode_error_to_string(Error))/binary>>
    end.

-file("src/lightspeed/ops/chaos_harness.gleam", 571).
-spec evaluate_runtime_cases(
    list({binary(), binary()}),
    integer(),
    integer(),
    list(binary())
) -> {integer(), list(binary())}.
evaluate_runtime_cases(Cases, Index, Mismatches, Outcomes_rev) ->
    case Cases of
        [] ->
            {Mismatches, lists:reverse(Outcomes_rev)};

        [Entry | Rest] ->
            {Payload, Expected} = Entry,
            Actual = runtime_case_label(Payload),
            Next_mismatches = case Actual =:= Expected of
                true ->
                    Mismatches;

                false ->
                    Mismatches + 1
            end,
            evaluate_runtime_cases(
                Rest,
                Index + 1,
                Next_mismatches,
                [<<<<(erlang:integer_to_binary(Index))/binary, ":"/utf8>>/binary,
                        Actual/binary>> |
                    Outcomes_rev]
            )
    end.

-file("src/lightspeed/ops/chaos_harness.gleam", 213).
-spec evaluate_runtime_fuzz_corpus_regression() -> {boolean(), binary()}.
evaluate_runtime_fuzz_corpus_regression() ->
    {Mismatches, Outcomes} = evaluate_runtime_cases(runtime_corpus(), 1, 0, []),
    Passed = Mismatches =:= 0,
    {Passed,
        <<<<<<"mismatches="/utf8,
                    (erlang:integer_to_binary(Mismatches))/binary>>/binary,
                "|cases="/utf8>>/binary,
            (join_with(<<","/utf8>>, Outcomes))/binary>>}.

-file("src/lightspeed/ops/chaos_harness.gleam", 509).
-spec protocol_corpus() -> list({binary(), binary()}).
protocol_corpus() ->
    [{<<"hello|lightspeed|1"/utf8>>, <<"ok:hello"/utf8>>},
        {<<"hello|lightspeed|2"/utf8>>, <<"error:unsupported_version:2"/utf8>>},
        {<<"hello|other|1"/utf8>>, <<"error:unsupported_protocol:other"/utf8>>},
        {<<"event|r1|increment|{}"/utf8>>, <<"ok:event"/utf8>>},
        {<<"diff|r1|<p>x</p>"/utf8>>, <<"ok:diff"/utf8>>},
        {<<"ack|r1"/utf8>>, <<"ok:ack"/utf8>>},
        {<<"failure|r1|boom"/utf8>>, <<"ok:failure"/utf8>>},
        {<<"event|r1|increment|bad\\"/utf8>>,
            <<"error:invalid_escape_sequence"/utf8>>},
        {<<"ack"/utf8>>, <<"error:bad_field_count:ack:2:1"/utf8>>},
        {<<"noop|x"/utf8>>, <<"error:unknown_frame_tag:noop"/utf8>>}].

-file("src/lightspeed/ops/chaos_harness.gleam", 595).
-spec protocol_case_label(binary()) -> binary().
protocol_case_label(Payload) ->
    case lightspeed@protocol:decode(Payload) of
        {ok, Frame} ->
            <<"ok:"/utf8, (frame_tag(Frame))/binary>>;

        {error, Error} ->
            <<"error:"/utf8,
                (lightspeed@protocol:decode_error_to_string(Error))/binary>>
    end.

-file("src/lightspeed/ops/chaos_harness.gleam", 547).
-spec evaluate_protocol_cases(
    list({binary(), binary()}),
    integer(),
    integer(),
    list(binary())
) -> {integer(), list(binary())}.
evaluate_protocol_cases(Cases, Index, Mismatches, Outcomes_rev) ->
    case Cases of
        [] ->
            {Mismatches, lists:reverse(Outcomes_rev)};

        [Entry | Rest] ->
            {Payload, Expected} = Entry,
            Actual = protocol_case_label(Payload),
            Next_mismatches = case Actual =:= Expected of
                true ->
                    Mismatches;

                false ->
                    Mismatches + 1
            end,
            evaluate_protocol_cases(
                Rest,
                Index + 1,
                Next_mismatches,
                [<<<<(erlang:integer_to_binary(Index))/binary, ":"/utf8>>/binary,
                        Actual/binary>> |
                    Outcomes_rev]
            )
    end.

-file("src/lightspeed/ops/chaos_harness.gleam", 199).
-spec evaluate_protocol_fuzz_corpus_regression() -> {boolean(), binary()}.
evaluate_protocol_fuzz_corpus_regression() ->
    {Mismatches, Outcomes} = evaluate_protocol_cases(
        protocol_corpus(),
        1,
        0,
        []
    ),
    Passed = Mismatches =:= 0,
    {Passed,
        <<<<<<"mismatches="/utf8,
                    (erlang:integer_to_binary(Mismatches))/binary>>/binary,
                "|cases="/utf8>>/binary,
            (join_with(<<","/utf8>>, Outcomes))/binary>>}.

-file("src/lightspeed/ops/chaos_harness.gleam", 188).
-spec evaluate(scenario()) -> {boolean(), binary()}.
evaluate(Scenario) ->
    case Scenario of
        protocol_fuzz_corpus_regression ->
            evaluate_protocol_fuzz_corpus_regression();

        runtime_fuzz_corpus_regression ->
            evaluate_runtime_fuzz_corpus_regression();

        transport_chaos_fault_injection ->
            evaluate_transport_chaos_fault_injection();

        runtime_chaos_fault_injection ->
            evaluate_runtime_chaos_fault_injection();

        storage_chaos_fault_injection ->
            evaluate_storage_chaos_fault_injection();

        slo_autopilot_audit_gate ->
            evaluate_slo_autopilot_audit_gate()
    end.

-file("src/lightspeed/ops/chaos_harness.gleam", 68).
?DOC(" Run one scenario twice and require deterministic 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/chaos_harness.gleam", 48).
?DOC(" Run all M30 scenarios.\n").
-spec run_matrix() -> report().
run_matrix() ->
    Outcomes = begin
        _pipe = [protocol_fuzz_corpus_regression,
            runtime_fuzz_corpus_regression,
            transport_chaos_fault_injection,
            runtime_chaos_fault_injection,
            storage_chaos_fault_injection,
            slo_autopilot_audit_gate],
        gleam@list:map(_pipe, fun run_scenario/1)
    end,
    {report, Outcomes, count_failed(Outcomes), count_nondeterministic(Outcomes)}.

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

        runtime_fuzz_corpus_regression ->
            <<"runtime_fuzz_corpus_regression"/utf8>>;

        transport_chaos_fault_injection ->
            <<"transport_chaos_fault_injection"/utf8>>;

        runtime_chaos_fault_injection ->
            <<"runtime_chaos_fault_injection"/utf8>>;

        storage_chaos_fault_injection ->
            <<"storage_chaos_fault_injection"/utf8>>;

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

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

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

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

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

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

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

-file("src/lightspeed/ops/chaos_harness.gleam", 812).
-spec bool_label(boolean()) -> binary().
bool_label(Value) ->
    case Value of
        true ->
            <<"true"/utf8>>;

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

-file("src/lightspeed/ops/chaos_harness.gleam", 134).
?DOC(" Stable report signature.\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).

-file("src/lightspeed/ops/chaos_harness.gleam", 150).
?DOC(" Deterministic snapshot signature for fixture drift gates.\n").
-spec snapshot_signature() -> binary().
snapshot_signature() ->
    <<<<<<"m30.snapshot.v"/utf8, (erlang:integer_to_binary(1))/binary>>/binary,
            "|"/utf8>>/binary,
        (report_signature(run_matrix()))/binary>>.

-file("src/lightspeed/ops/chaos_harness.gleam", 158).
?DOC(" Deterministic markdown report for fixture scripts.\n").
-spec snapshot_report_markdown() -> binary().
snapshot_report_markdown() ->
    Report = run_matrix(),
    Failed = failed_scenarios(Report),
    Nondeterministic = nondeterministic_failures(Report),
    Status = case (Failed =:= 0) andalso (Nondeterministic =:= 0) of
        true ->
            <<"OK"/utf8>>;

        false ->
            <<"FAIL"/utf8>>
    end,
    <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"# Chaos Fixture Report\n\n"/utf8,
                                                                            "snapshot_version: "/utf8>>/binary,
                                                                        (erlang:integer_to_binary(
                                                                            1
                                                                        ))/binary>>/binary,
                                                                    "\n"/utf8>>/binary,
                                                                "status: "/utf8>>/binary,
                                                            Status/binary>>/binary,
                                                        "\n"/utf8>>/binary,
                                                    "failed_scenarios: "/utf8>>/binary,
                                                (erlang:integer_to_binary(
                                                    Failed
                                                ))/binary>>/binary,
                                            "\n"/utf8>>/binary,
                                        "nondeterministic_failures: "/utf8>>/binary,
                                    (erlang:integer_to_binary(Nondeterministic))/binary>>/binary,
                                "\n\n"/utf8>>/binary,
                            "snapshot_signature: "/utf8>>/binary,
                        (snapshot_signature())/binary>>/binary,
                    "\n\n"/utf8>>/binary,
                "report_signature: "/utf8>>/binary,
            (report_signature(Report))/binary>>/binary,
        "\n"/utf8>>.