-module(lightspeed@ops@contention_harness). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/lightspeed/ops/contention_harness.gleam"). -export([budget_failures/1, default_budget/0, evaluate_budget/2, run_scenario/1, run_matrix/0, budget_version_label/0, scenario_label/1, pass_fail_label/1, signature/1, deterministic/1, invariants_met/1, scenario/1, profile_metrics/1, outcomes/1, budget_results/1, failed_scenarios/1, nondeterministic_failures/1, invariant_failures/1, failed_budgets/1, metrics_signature/1, report_signature/1, snapshot_signature/0, snapshot_report_markdown/0]). -export_type([scenario/0, metrics/0, scenario_outcome/0, budget/0, budget_result/0, report/0, claim/0, claim_accumulator/0, renewal_sample/0, renewal_accumulator/0, continuity_entry/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 durable-store contention profiling harness for M37.\n"). -type scenario() :: ownership_fencing_contention | lease_renewal_contention | takeover_queue_retry_pressure | checkpoint_replay_windows. -type metrics() :: {metrics, integer(), integer(), integer(), integer(), integer(), integer(), integer(), integer(), integer(), integer(), integer()}. -type scenario_outcome() :: {scenario_outcome, scenario(), boolean(), boolean(), boolean(), binary(), metrics()}. -type budget() :: {budget, scenario(), integer(), integer(), integer(), integer(), integer()}. -type budget_result() :: {budget_result, scenario(), boolean(), binary()}. -type report() :: {report, list(scenario_outcome()), list(budget_result()), integer(), integer(), integer(), integer()}. -type claim() :: {claim, binary(), integer(), binary(), integer(), integer()}. -type claim_accumulator() :: {claim_accumulator, lightspeed@cluster@durable_session:durable_session(), integer(), integer(), integer(), integer(), integer(), integer()}. -type renewal_sample() :: {renewal_sample, integer(), integer()}. -type renewal_accumulator() :: {renewal_accumulator, lightspeed@cluster@durable_session:durable_session(), integer(), integer(), integer(), integer(), integer(), list(integer())}. -type continuity_entry() :: {continuity_entry, boolean(), binary(), lightspeed@cluster@durable_session:continuity_report(), boolean()}. -file("src/lightspeed/ops/contention_harness.gleam", 176). ?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(3, Result) of true -> budget_failures(Rest); false -> 1 + budget_failures(Rest) end end. -file("src/lightspeed/ops/contention_harness.gleam", 1116). -spec count_invariant_failures(list(scenario_outcome())) -> integer(). count_invariant_failures(Outcomes) -> case Outcomes of [] -> 0; [Outcome | Rest] -> case erlang:element(5, Outcome) of true -> count_invariant_failures(Rest); false -> 1 + count_invariant_failures(Rest) end end. -file("src/lightspeed/ops/contention_harness.gleam", 1105). -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/contention_harness.gleam", 1094). -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/contention_harness.gleam", 130). ?DOC(" Default deterministic M37 contention budgets.\n"). -spec default_budget() -> list(budget()). default_budget() -> [{budget, ownership_fencing_contention, 50, 1, 50, 8, 8}, {budget, lease_renewal_contention, 10, 1, 50, 4, 16}, {budget, takeover_queue_retry_pressure, 50, 1, 40, 6, 6}, {budget, checkpoint_replay_windows, 50, 1, 30, 4, 4}]. -file("src/lightspeed/ops/contention_harness.gleam", 1159). -spec bool_label(boolean()) -> binary(). bool_label(Value) -> case Value of true -> <<"true"/utf8>>; false -> <<"false"/utf8>> end. -file("src/lightspeed/ops/contention_harness.gleam", 1152). -spec max_int(integer(), integer()) -> integer(). max_int(Left, Right) -> case Left >= Right of true -> Left; false -> Right end. -file("src/lightspeed/ops/contention_harness.gleam", 1025). -spec evaluate_budget_outcome(scenario_outcome(), budget()) -> budget_result(). evaluate_budget_outcome(Outcome, Budget) -> Lease_within = erlang:element(7, erlang:element(7, Outcome)) =< erlang:element( 3, Budget ), Checkpoint_within = erlang:element(11, erlang:element(7, Outcome)) =< erlang:element( 4, Budget ), Replay_within = erlang:element(12, erlang:element(7, Outcome)) =< erlang:element( 5, Budget ), Queue_peak = max_int( erlang:element(8, erlang:element(7, Outcome)), erlang:element(9, erlang:element(7, Outcome)) ), Queue_within = Queue_peak =< erlang:element(6, Budget), Retry_within = erlang:element(10, erlang:element(7, Outcome)) =< erlang:element( 7, Budget ), Passed = (((((erlang:element(3, Outcome) andalso erlang:element(5, Outcome)) andalso Lease_within) andalso Checkpoint_within) andalso Replay_within) andalso Queue_within) andalso Retry_within, Reason = case Passed of true -> <<"within_budget"/utf8>>; false -> <<<<<<<<<<<<<<<<<<<<<<<<<<"lease="/utf8, (bool_label( Lease_within ))/binary>>/binary, ":checkpoint="/utf8>>/binary, (bool_label( Checkpoint_within ))/binary>>/binary, ":replay="/utf8>>/binary, (bool_label(Replay_within))/binary>>/binary, ":queue="/utf8>>/binary, (bool_label(Queue_within))/binary>>/binary, ":retry="/utf8>>/binary, (bool_label(Retry_within))/binary>>/binary, ":scenario_passed="/utf8>>/binary, (bool_label(erlang:element(3, Outcome)))/binary>>/binary, ":invariants="/utf8>>/binary, (bool_label(erlang:element(5, Outcome)))/binary>> end, {budget_result, erlang:element(2, Budget), Passed, Reason}. -file("src/lightspeed/ops/contention_harness.gleam", 1073). -spec find_outcome(list(scenario_outcome()), scenario()) -> gleam@option:option(scenario_outcome()). find_outcome(Outcomes, Scenario) -> case Outcomes of [] -> none; [Outcome | Rest] -> case erlang:element(2, Outcome) =:= Scenario of true -> {some, Outcome}; false -> find_outcome(Rest, Scenario) end end. -file("src/lightspeed/ops/contention_harness.gleam", 1002). -spec evaluate_budget_loop( list(scenario_outcome()), list(budget()), list(budget_result()) ) -> list(budget_result()). evaluate_budget_loop(Outcomes, Budgets, Acc_rev) -> case Budgets of [] -> lists:reverse(Acc_rev); [Budget | Rest] -> Result = case find_outcome(Outcomes, erlang:element(2, Budget)) of none -> {budget_result, erlang:element(2, Budget), false, <<"missing_scenario"/utf8>>}; {some, Outcome} -> evaluate_budget_outcome(Outcome, Budget) end, evaluate_budget_loop(Outcomes, Rest, [Result | Acc_rev]) end. -file("src/lightspeed/ops/contention_harness.gleam", 168). ?DOC(" Evaluate one outcome list against one budget profile.\n"). -spec evaluate_budget(list(scenario_outcome()), list(budget())) -> list(budget_result()). evaluate_budget(Outcomes, Budgets) -> evaluate_budget_loop(Outcomes, Budgets, []). -file("src/lightspeed/ops/contention_harness.gleam", 1166). -spec join_with(binary(), list(binary())) -> binary(). join_with(Separator, Values) -> case Values of [] -> <<""/utf8>>; [Value] -> Value; [Value@1 | Rest] -> <<<>/binary, (join_with(Separator, Rest))/binary>> end. -file("src/lightspeed/ops/contention_harness.gleam", 1145). -spec max_loop(integer(), list(integer())) -> integer(). max_loop(Current_max, Values) -> case Values of [] -> Current_max; [Value | Rest] -> max_loop(max_int(Current_max, Value), Rest) end. -file("src/lightspeed/ops/contention_harness.gleam", 1138). -spec max_or_zero(list(integer())) -> integer(). max_or_zero(Values) -> case Values of [] -> 0; [Value | Rest] -> max_loop(Value, Rest) end. -file("src/lightspeed/ops/contention_harness.gleam", 1087). -spec continuity_entries_all_met(list(continuity_entry())) -> boolean(). continuity_entries_all_met(Entries) -> case Entries of [] -> true; [Entry | Rest] -> erlang:element(2, Entry) andalso continuity_entries_all_met(Rest) end. -file("src/lightspeed/ops/contention_harness.gleam", 951). -spec evaluate_checkpoint_backend( lightspeed@cluster@durable_session:persistence_backend(), integer() ) -> continuity_entry(). evaluate_checkpoint_backend(Backend, Index) -> Session_id = <<"m37-window-"/utf8, (erlang:integer_to_binary(Index + 1))/binary>>, Crashed = begin _pipe = lightspeed@cluster@durable_session:start( Session_id, <<"node-a"/utf8>>, <<"/window"/utf8>>, Backend, rehydrate, 0, 35, 1 ), _pipe@1 = lightspeed@cluster@durable_session:append_counter_delta( _pipe, 1, 3 ), _pipe@2 = lightspeed@cluster@durable_session:append_counter_delta( _pipe@1, 1, 5 ), _pipe@3 = lightspeed@cluster@durable_session:append_counter_delta( _pipe@2, 1, 7 ), _pipe@4 = lightspeed@cluster@durable_session:append_counter_delta( _pipe@3, 1, 9 ), _pipe@5 = lightspeed@cluster@durable_session:crash( _pipe@4, <<"boom"/utf8>> ), lightspeed@cluster@durable_session:restart(_pipe@5, 500) end, Takeover = lightspeed@cluster@durable_session:request_takeover( Crashed, <<"node-b"/utf8>>, 2, lightspeed@cluster@durable_session:expected_token( Session_id, <<"node-b"/utf8>>, 2 ), 510 ), {Recovered, Takeover_successful} = case Takeover of {ok, Updated} -> {Updated, true}; {error, _} -> {Crashed, false} end, Reconnected = lightspeed@cluster@durable_session:reconnect( Recovered, rehydrate, <<"/window"/utf8>>, 524 ), Continuity = lightspeed@cluster@durable_session:continuity_report( Reconnected, 500, 524 ), {continuity_entry, erlang:element(4, Continuity), lightspeed@cluster@durable_session:backend_label(Backend), Continuity, Takeover_successful}. -file("src/lightspeed/ops/contention_harness.gleam", 936). -spec evaluate_checkpoint_entries( list(lightspeed@cluster@durable_session:persistence_backend()), integer(), list(continuity_entry()) ) -> list(continuity_entry()). evaluate_checkpoint_entries(Backends, Index, Acc_rev) -> case Backends of [] -> Acc_rev; [Backend | Rest] -> evaluate_checkpoint_entries( Rest, Index + 1, [evaluate_checkpoint_backend(Backend, Index) | Acc_rev] ) end. -file("src/lightspeed/ops/contention_harness.gleam", 746). -spec evaluate_checkpoint_replay_windows() -> {boolean(), boolean(), metrics(), binary()}. evaluate_checkpoint_replay_windows() -> Entries = begin _pipe = evaluate_checkpoint_entries( lightspeed@cluster@durable_session:supported_backends(), 0, [] ), lists:reverse(_pipe) end, Met_all = continuity_entries_all_met(Entries), Takeover_successes = begin _pipe@1 = Entries, _pipe@2 = gleam@list:filter( _pipe@1, fun(Entry) -> erlang:element(5, Entry) end ), erlang:length(_pipe@2) end, Signatures = begin _pipe@3 = Entries, gleam@list:map( _pipe@3, fun(Entry@1) -> <<<<(erlang:element(3, Entry@1))/binary, ":"/utf8>>/binary, (lightspeed@cluster@durable_session:continuity_signature( erlang:element(4, Entry@1) ))/binary>> end ) end, Checkpoint_window_events = begin _pipe@4 = Entries, _pipe@5 = gleam@list:map( _pipe@4, fun(Entry@2) -> erlang:element(3, erlang:element(4, Entry@2)) end ), max_or_zero(_pipe@5) end, Replay_window_ms = begin _pipe@6 = Entries, _pipe@7 = gleam@list:map( _pipe@6, fun(Entry@3) -> erlang:element(2, erlang:element(4, Entry@3)) end ), max_or_zero(_pipe@7) end, Invariants_met = Met_all andalso (erlang:length(Entries) =:= 3), Profile = {metrics, 0, 0, 0, 0, Takeover_successes, 0, 0, 0, 0, Checkpoint_window_events, Replay_window_ms}, Passed = Invariants_met andalso (Checkpoint_window_events =< 1), {Passed, Invariants_met, Profile, <<<<<<<<<<"entries="/utf8, (join_with(<<";"/utf8>>, Signatures))/binary>>/binary, "|checkpoint_window="/utf8>>/binary, (erlang:integer_to_binary(Checkpoint_window_events))/binary>>/binary, "|replay_window_ms="/utf8>>/binary, (erlang:integer_to_binary(Replay_window_ms))/binary>>}. -file("src/lightspeed/ops/contention_harness.gleam", 828). -spec apply_claim(claim_accumulator(), claim()) -> claim_accumulator(). apply_claim(Accumulator, Claim) -> Queue_peak = max_int( erlang:element(8, Accumulator), erlang:element(5, Claim) ), case lightspeed@cluster@durable_session:request_takeover( erlang:element(2, Accumulator), erlang:element(2, Claim), erlang:element(3, Claim), erlang:element(4, Claim), erlang:element(6, Claim) ) of {ok, Updated} -> {claim_accumulator, Updated, erlang:element(3, Accumulator), erlang:element(4, Accumulator), erlang:element(5, Accumulator), erlang:element(6, Accumulator) + 1, erlang:element(7, Accumulator), Queue_peak}; {error, {split_brain, _, _, _}} -> {claim_accumulator, erlang:element(2, Accumulator), erlang:element(3, Accumulator) + 1, erlang:element(4, Accumulator), erlang:element(5, Accumulator), erlang:element(6, Accumulator), erlang:element(7, Accumulator) + 1, Queue_peak}; {error, {stale_owner, _, _}} -> {claim_accumulator, erlang:element(2, Accumulator), erlang:element(3, Accumulator), erlang:element(4, Accumulator) + 1, erlang:element(5, Accumulator), erlang:element(6, Accumulator), erlang:element(7, Accumulator) + 1, Queue_peak}; {error, {invalid_token, _, _}} -> {claim_accumulator, erlang:element(2, Accumulator), erlang:element(3, Accumulator), erlang:element(4, Accumulator), erlang:element(5, Accumulator) + 1, erlang:element(6, Accumulator), erlang:element(7, Accumulator) + 1, Queue_peak} end. -file("src/lightspeed/ops/contention_harness.gleam", 818). -spec run_claims_loop(claim_accumulator(), list(claim())) -> claim_accumulator(). run_claims_loop(Accumulator, Claims) -> case Claims of [] -> Accumulator; [Claim | Rest] -> run_claims_loop(apply_claim(Accumulator, Claim), Rest) end. -file("src/lightspeed/ops/contention_harness.gleam", 800). -spec run_claims( lightspeed@cluster@durable_session:durable_session(), list(claim()) ) -> claim_accumulator(). run_claims(Session, Claims) -> run_claims_loop({claim_accumulator, Session, 0, 0, 0, 0, 0, 0}, Claims). -file("src/lightspeed/ops/contention_harness.gleam", 613). -spec evaluate_takeover_queue_retry_pressure() -> {boolean(), boolean(), metrics(), binary()}. evaluate_takeover_queue_retry_pressure() -> Session_id = <<"m37-queue"/utf8>>, Base = begin _pipe = lightspeed@cluster@durable_session:start( Session_id, <<"node-a"/utf8>>, <<"/queue"/utf8>>, {snapshot_journal, <<"snapshot"/utf8>>, <<"journal"/utf8>>, 2}, rehydrate, 0, 45, 1 ), _pipe@1 = lightspeed@cluster@durable_session:append_counter_delta( _pipe, 5, 4 ), _pipe@2 = lightspeed@cluster@durable_session:crash( _pipe@1, <<"boom"/utf8>> ), lightspeed@cluster@durable_session:restart(_pipe@2, 200) end, Claims = [{claim, <<"node-b"/utf8>>, 2, lightspeed@cluster@durable_session:expected_token( Session_id, <<"node-b"/utf8>>, 2 ), 5, 210}, {claim, <<"node-c"/utf8>>, 2, lightspeed@cluster@durable_session:expected_token( Session_id, <<"node-c"/utf8>>, 2 ), 5, 211}, {claim, <<"node-a"/utf8>>, 1, lightspeed@cluster@durable_session:expected_token( Session_id, <<"node-a"/utf8>>, 1 ), 4, 212}, {claim, <<"node-d"/utf8>>, 3, <<"bad-token"/utf8>>, 3, 213}, {claim, <<"node-c"/utf8>>, 3, lightspeed@cluster@durable_session:expected_token( Session_id, <<"node-c"/utf8>>, 3 ), 3, 214}, {claim, <<"node-b"/utf8>>, 3, lightspeed@cluster@durable_session:expected_token( Session_id, <<"node-b"/utf8>>, 3 ), 2, 215}, {claim, <<"node-d"/utf8>>, 4, lightspeed@cluster@durable_session:expected_token( Session_id, <<"node-d"/utf8>>, 4 ), 1, 216}], Contested = run_claims(Base, Claims), Reconnected = lightspeed@cluster@durable_session:reconnect( erlang:element(2, Contested), rehydrate, <<"/queue"/utf8>>, 236 ), Continuity = lightspeed@cluster@durable_session:continuity_report( Reconnected, 200, 236 ), Fence = lightspeed@cluster@durable_session:fence(Reconnected), Snapshot = lightspeed@cluster@durable_session:snapshot(Reconnected), Ownership_conflicts = (erlang:element(3, Contested) + erlang:element( 4, Contested )) + erlang:element(5, Contested), Invariants_met = ((((((erlang:element(3, Contested) =:= 2) andalso (erlang:element( 4, Contested ) =:= 1)) andalso (erlang:element(5, Contested) =:= 1)) andalso (erlang:element(6, Contested) =:= 3)) andalso (erlang:element(2, Fence) =:= <<"node-d"/utf8>>)) andalso (erlang:element(3, Fence) =:= 4)) andalso (erlang:element(4, Snapshot) =:= 5), Profile = {metrics, Ownership_conflicts, erlang:element(3, Contested), erlang:element(4, Contested), erlang:element(5, Contested), erlang:element(6, Contested), 0, 0, erlang:element(8, Contested), erlang:element(7, Contested), erlang:element(3, Continuity), erlang:element(2, Continuity)}, Passed = (Invariants_met andalso erlang:element(4, Continuity)) andalso lightspeed@cluster@durable_session:valid( Reconnected ), {Passed, Invariants_met, Profile, <<<<<<<<<<<<<<<<<<<<<<<<<<"fence="/utf8, (lightspeed@cluster@durable_session:fence_signature( Fence ))/binary>>/binary, "|split_brain="/utf8>>/binary, (erlang:integer_to_binary( erlang:element( 3, Contested ) ))/binary>>/binary, "|stale_owner="/utf8>>/binary, (erlang:integer_to_binary( erlang:element(4, Contested) ))/binary>>/binary, "|invalid_token="/utf8>>/binary, (erlang:integer_to_binary( erlang:element(5, Contested) ))/binary>>/binary, "|queue_peak="/utf8>>/binary, (erlang:integer_to_binary( erlang:element(8, Contested) ))/binary>>/binary, "|retries="/utf8>>/binary, (erlang:integer_to_binary(erlang:element(7, Contested)))/binary>>/binary, "|continuity="/utf8>>/binary, (lightspeed@cluster@durable_session:continuity_signature(Continuity))/binary>>}. -file("src/lightspeed/ops/contention_harness.gleam", 1134). -spec p95_or_zero(list(integer())) -> integer(). p95_or_zero(Values) -> max_or_zero(Values). -file("src/lightspeed/ops/contention_harness.gleam", 1127). -spec retries_from_queue_depth(integer()) -> integer(). retries_from_queue_depth(Queue_depth) -> case Queue_depth =< 1 of true -> 0; false -> Queue_depth - 1 end. -file("src/lightspeed/ops/contention_harness.gleam", 895). -spec apply_lease_renewal_sample( binary(), binary(), renewal_sample(), renewal_accumulator() ) -> renewal_accumulator(). apply_lease_renewal_sample(Session_id, Owner, Sample, Accumulator) -> Epoch = erlang:element(3, Accumulator) + 1, Now_ms = erlang:element(4, Accumulator) + erlang:element(2, Sample), Queue_retry = retries_from_queue_depth(erlang:element(3, Sample)), Queue_peak = max_int( erlang:element(7, Accumulator), erlang:element(3, Sample) ), Token = lightspeed@cluster@durable_session:expected_token( Session_id, Owner, Epoch ), case lightspeed@cluster@durable_session:request_takeover( erlang:element(2, Accumulator), Owner, Epoch, Token, Now_ms ) of {ok, Updated} -> {renewal_accumulator, Updated, Epoch, Now_ms, erlang:element(5, Accumulator) + 1, erlang:element(6, Accumulator) + Queue_retry, Queue_peak, [erlang:element(2, Sample) | erlang:element(8, Accumulator)]}; {error, _} -> {renewal_accumulator, erlang:element(2, Accumulator), erlang:element(3, Accumulator), erlang:element(4, Accumulator), erlang:element(5, Accumulator), (erlang:element(6, Accumulator) + Queue_retry) + 1, Queue_peak, erlang:element(8, Accumulator)} end. -file("src/lightspeed/ops/contention_harness.gleam", 877). -spec run_lease_renewals( binary(), binary(), list(renewal_sample()), renewal_accumulator() ) -> renewal_accumulator(). run_lease_renewals(Session_id, Owner, Samples, Accumulator) -> case Samples of [] -> Accumulator; [Sample | Rest] -> run_lease_renewals( Session_id, Owner, Rest, apply_lease_renewal_sample( Session_id, Owner, Sample, Accumulator ) ) end. -file("src/lightspeed/ops/contention_harness.gleam", 532). -spec evaluate_lease_renewal_contention() -> {boolean(), boolean(), metrics(), binary()}. evaluate_lease_renewal_contention() -> Session_id = <<"m37-lease"/utf8>>, Owner = <<"node-a"/utf8>>, Base = lightspeed@cluster@durable_session:start( Session_id, Owner, <<"/todos"/utf8>>, {journal_only, <<"lease_journal"/utf8>>}, resume, 0, 40, 1 ), Samples = [{renewal_sample, 4, 1}, {renewal_sample, 6, 2}, {renewal_sample, 7, 2}, {renewal_sample, 5, 3}, {renewal_sample, 8, 2}, {renewal_sample, 6, 1}, {renewal_sample, 4, 2}, {renewal_sample, 7, 1}], Renewal = run_lease_renewals( Session_id, Owner, Samples, {renewal_accumulator, Base, 1, 0, 0, 0, 0, []} ), Fence = lightspeed@cluster@durable_session:fence(erlang:element(2, Renewal)), Windows = lists:reverse(erlang:element(8, Renewal)), Lease_p95 = p95_or_zero(Windows), Sample_count = erlang:length(Samples), Invariants_met = ((erlang:element(5, Renewal) =:= Sample_count) andalso (erlang:element( 2, Fence ) =:= Owner)) andalso (erlang:element(3, Fence) =:= (1 + Sample_count)), Profile = {metrics, 0, 0, 0, 0, erlang:element(5, Renewal), Lease_p95, erlang:element(7, Renewal), erlang:element(7, Renewal), erlang:element(6, Renewal), 0, 0}, Passed = Invariants_met andalso lightspeed@cluster@durable_session:valid( erlang:element(2, Renewal) ), {Passed, Invariants_met, Profile, <<<<<<<<<<<<<<<<<<"fence="/utf8, (lightspeed@cluster@durable_session:fence_signature( Fence ))/binary>>/binary, "|lease_p95_ms="/utf8>>/binary, (erlang:integer_to_binary(Lease_p95))/binary>>/binary, "|lease_queue_peak="/utf8>>/binary, (erlang:integer_to_binary( erlang:element(7, Renewal) ))/binary>>/binary, "|retries="/utf8>>/binary, (erlang:integer_to_binary(erlang:element(6, Renewal)))/binary>>/binary, "|windows="/utf8>>/binary, (join_with( <<","/utf8>>, gleam@list:map(Windows, fun erlang:integer_to_binary/1) ))/binary>>}. -file("src/lightspeed/ops/contention_harness.gleam", 422). -spec evaluate_ownership_fencing_contention() -> {boolean(), boolean(), metrics(), binary()}. evaluate_ownership_fencing_contention() -> Session_id = <<"m37-fence"/utf8>>, Base = lightspeed@cluster@durable_session:start( Session_id, <<"node-a"/utf8>>, <<"/counter"/utf8>>, {snapshot_journal, <<"snapshot"/utf8>>, <<"journal"/utf8>>, 2}, rehydrate, 0, 40, 1 ), Claims = [{claim, <<"node-b"/utf8>>, 2, lightspeed@cluster@durable_session:expected_token( Session_id, <<"node-b"/utf8>>, 2 ), 4, 10}, {claim, <<"node-c"/utf8>>, 2, lightspeed@cluster@durable_session:expected_token( Session_id, <<"node-c"/utf8>>, 2 ), 3, 11}, {claim, <<"node-a"/utf8>>, 1, lightspeed@cluster@durable_session:expected_token( Session_id, <<"node-a"/utf8>>, 1 ), 3, 12}, {claim, <<"node-d"/utf8>>, 3, <<"invalid-token"/utf8>>, 2, 13}, {claim, <<"node-b"/utf8>>, 3, lightspeed@cluster@durable_session:expected_token( Session_id, <<"node-b"/utf8>>, 3 ), 2, 14}, {claim, <<"node-c"/utf8>>, 3, lightspeed@cluster@durable_session:expected_token( Session_id, <<"node-c"/utf8>>, 3 ), 1, 15}], Result = run_claims(Base, Claims), Fence = lightspeed@cluster@durable_session:fence(erlang:element(2, Result)), Ownership_conflicts = (erlang:element(3, Result) + erlang:element(4, Result)) + erlang:element(5, Result), Invariants_met = (((((erlang:element(3, Result) =:= 2) andalso (erlang:element( 4, Result ) =:= 1)) andalso (erlang:element(5, Result) =:= 1)) andalso (erlang:element(6, Result) =:= 2)) andalso (erlang:element(2, Fence) =:= <<"node-b"/utf8>>)) andalso (erlang:element(3, Fence) =:= 3), Profile = {metrics, Ownership_conflicts, erlang:element(3, Result), erlang:element(4, Result), erlang:element(5, Result), erlang:element(6, Result), 0, 0, erlang:element(8, Result), erlang:element(7, Result), 0, 0}, Passed = Invariants_met andalso lightspeed@cluster@durable_session:valid( erlang:element(2, Result) ), {Passed, Invariants_met, Profile, <<<<<<<<<<<<<<<<<<<<<<"fence="/utf8, (lightspeed@cluster@durable_session:fence_signature( Fence ))/binary>>/binary, "|split_brain="/utf8>>/binary, (erlang:integer_to_binary( erlang:element(3, Result) ))/binary>>/binary, "|stale_owner="/utf8>>/binary, (erlang:integer_to_binary( erlang:element(4, Result) ))/binary>>/binary, "|invalid_token="/utf8>>/binary, (erlang:integer_to_binary(erlang:element(5, Result)))/binary>>/binary, "|queue_peak="/utf8>>/binary, (erlang:integer_to_binary(erlang:element(8, Result)))/binary>>/binary, "|retries="/utf8>>/binary, (erlang:integer_to_binary(erlang:element(7, Result)))/binary>>}. -file("src/lightspeed/ops/contention_harness.gleam", 413). -spec evaluate(scenario()) -> {boolean(), boolean(), metrics(), binary()}. evaluate(Scenario) -> case Scenario of ownership_fencing_contention -> evaluate_ownership_fencing_contention(); lease_renewal_contention -> evaluate_lease_renewal_contention(); takeover_queue_retry_pressure -> evaluate_takeover_queue_retry_pressure(); checkpoint_replay_windows -> evaluate_checkpoint_replay_windows() end. -file("src/lightspeed/ops/contention_harness.gleam", 101). ?DOC(" Run one M37 scenario twice and require deterministic parity.\n"). -spec run_scenario(scenario()) -> scenario_outcome(). run_scenario(Scenario) -> {First_passed, First_invariants, First_metrics, First_signature} = evaluate( Scenario ), {Second_passed, Second_invariants, Second_metrics, Second_signature} = evaluate( Scenario ), Deterministic = (((First_passed =:= Second_passed) andalso (First_invariants =:= Second_invariants)) andalso (First_signature =:= Second_signature)) andalso (First_metrics =:= Second_metrics), Passed = (First_passed andalso Second_passed) andalso Deterministic, Invariants_met = First_invariants andalso Second_invariants, {scenario_outcome, Scenario, Passed, Deterministic, Invariants_met, First_signature, First_metrics}. -file("src/lightspeed/ops/contention_harness.gleam", 79). ?DOC(" Run all M37 scenarios and evaluate default contention budgets.\n"). -spec run_matrix() -> report(). run_matrix() -> Outcomes = begin _pipe = [ownership_fencing_contention, lease_renewal_contention, takeover_queue_retry_pressure, checkpoint_replay_windows], gleam@list:map(_pipe, fun run_scenario/1) end, Budget_results = evaluate_budget(Outcomes, default_budget()), {report, Outcomes, Budget_results, count_failed(Outcomes), count_nondeterministic(Outcomes), count_invariant_failures(Outcomes), budget_failures(Budget_results)}. -file("src/lightspeed/ops/contention_harness.gleam", 125). ?DOC(" M37 budget profile version label.\n"). -spec budget_version_label() -> binary(). budget_version_label() -> <<"m37.budget.v"/utf8, (erlang:integer_to_binary(1))/binary>>. -file("src/lightspeed/ops/contention_harness.gleam", 188). ?DOC(" Scenario label.\n"). -spec scenario_label(scenario()) -> binary(). scenario_label(Scenario) -> case Scenario of ownership_fencing_contention -> <<"ownership_fencing_contention"/utf8>>; lease_renewal_contention -> <<"lease_renewal_contention"/utf8>>; takeover_queue_retry_pressure -> <<"takeover_queue_retry_pressure"/utf8>>; checkpoint_replay_windows -> <<"checkpoint_replay_windows"/utf8>> end. -file("src/lightspeed/ops/contention_harness.gleam", 198). ?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/contention_harness.gleam", 206). ?DOC(" Scenario signature accessor.\n"). -spec signature(scenario_outcome()) -> binary(). signature(Outcome) -> erlang:element(6, Outcome). -file("src/lightspeed/ops/contention_harness.gleam", 211). ?DOC(" Scenario determinism accessor.\n"). -spec deterministic(scenario_outcome()) -> boolean(). deterministic(Outcome) -> erlang:element(4, Outcome). -file("src/lightspeed/ops/contention_harness.gleam", 216). ?DOC(" Scenario invariant accessor.\n"). -spec invariants_met(scenario_outcome()) -> boolean(). invariants_met(Outcome) -> erlang:element(5, Outcome). -file("src/lightspeed/ops/contention_harness.gleam", 221). ?DOC(" Scenario accessor.\n"). -spec scenario(scenario_outcome()) -> scenario(). scenario(Outcome) -> erlang:element(2, Outcome). -file("src/lightspeed/ops/contention_harness.gleam", 226). ?DOC(" Scenario profile accessor.\n"). -spec profile_metrics(scenario_outcome()) -> metrics(). profile_metrics(Outcome) -> erlang:element(7, Outcome). -file("src/lightspeed/ops/contention_harness.gleam", 231). ?DOC(" Report outcomes accessor.\n"). -spec outcomes(report()) -> list(scenario_outcome()). outcomes(Report) -> erlang:element(2, Report). -file("src/lightspeed/ops/contention_harness.gleam", 236). ?DOC(" Report budget-results accessor.\n"). -spec budget_results(report()) -> list(budget_result()). budget_results(Report) -> erlang:element(3, Report). -file("src/lightspeed/ops/contention_harness.gleam", 241). ?DOC(" Failed scenario count.\n"). -spec failed_scenarios(report()) -> integer(). failed_scenarios(Report) -> erlang:element(4, Report). -file("src/lightspeed/ops/contention_harness.gleam", 246). ?DOC(" Nondeterministic scenario count.\n"). -spec nondeterministic_failures(report()) -> integer(). nondeterministic_failures(Report) -> erlang:element(5, Report). -file("src/lightspeed/ops/contention_harness.gleam", 251). ?DOC(" Invariant failure count.\n"). -spec invariant_failures(report()) -> integer(). invariant_failures(Report) -> erlang:element(6, Report). -file("src/lightspeed/ops/contention_harness.gleam", 256). ?DOC(" Failed budget count.\n"). -spec failed_budgets(report()) -> integer(). failed_budgets(Report) -> erlang:element(7, Report). -file("src/lightspeed/ops/contention_harness.gleam", 261). ?DOC(" Stable metrics signature.\n"). -spec metrics_signature(metrics()) -> binary(). metrics_signature(Metrics) -> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"conflicts="/utf8, (erlang:integer_to_binary( erlang:element( 2, Metrics ) ))/binary>>/binary, ":split="/utf8>>/binary, (erlang:integer_to_binary( erlang:element( 3, Metrics ) ))/binary>>/binary, ":stale="/utf8>>/binary, (erlang:integer_to_binary( erlang:element( 4, Metrics ) ))/binary>>/binary, ":invalid="/utf8>>/binary, (erlang:integer_to_binary( erlang:element( 5, Metrics ) ))/binary>>/binary, ":takeovers="/utf8>>/binary, (erlang:integer_to_binary( erlang:element( 6, Metrics ) ))/binary>>/binary, ":lease_p95_ms="/utf8>>/binary, (erlang:integer_to_binary( erlang:element(7, Metrics) ))/binary>>/binary, ":lease_queue_peak="/utf8>>/binary, (erlang:integer_to_binary( erlang:element(8, Metrics) ))/binary>>/binary, ":takeover_queue_peak="/utf8>>/binary, (erlang:integer_to_binary( erlang:element(9, Metrics) ))/binary>>/binary, ":retries="/utf8>>/binary, (erlang:integer_to_binary(erlang:element(10, Metrics)))/binary>>/binary, ":checkpoint_window="/utf8>>/binary, (erlang:integer_to_binary(erlang:element(11, Metrics)))/binary>>/binary, ":replay_window_ms="/utf8>>/binary, (erlang:integer_to_binary(erlang:element(12, Metrics)))/binary>>. -file("src/lightspeed/ops/contention_harness.gleam", 287). ?DOC(" Stable report signature.\n"). -spec report_signature(report()) -> binary(). report_signature(Report) -> Outcome_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, ":invariants="/utf8>>/binary, (bool_label(erlang:element(5, Outcome)))/binary>>/binary, ":profile="/utf8>>/binary, (metrics_signature(erlang:element(7, Outcome)))/binary>>/binary, ":"/utf8>>/binary, (erlang:element(6, Outcome))/binary>> end ), Budget_entries = gleam@list:map( erlang:element(3, Report), fun(Result) -> <<<<<<<<(scenario_label(erlang:element(2, Result)))/binary, "="/utf8>>/binary, (bool_label(erlang:element(3, Result)))/binary>>/binary, ":"/utf8>>/binary, (erlang:element(4, Result))/binary>> end ), <<<<<<"outcomes="/utf8, (join_with(<<";"/utf8>>, Outcome_entries))/binary>>/binary, "|budgets="/utf8>>/binary, (join_with(<<";"/utf8>>, Budget_entries))/binary>>. -file("src/lightspeed/ops/contention_harness.gleam", 318). ?DOC(" Deterministic snapshot signature for M37 drift gates.\n"). -spec snapshot_signature() -> binary(). snapshot_signature() -> <<<<<<"m37.snapshot.v"/utf8, (erlang:integer_to_binary(1))/binary>>/binary, "|"/utf8>>/binary, (report_signature(run_matrix()))/binary>>. -file("src/lightspeed/ops/contention_harness.gleam", 326). ?DOC(" Deterministic markdown report for M37 fixture scripts.\n"). -spec snapshot_report_markdown() -> binary(). snapshot_report_markdown() -> Report = run_matrix(), Failed = failed_scenarios(Report), Nondeterministic = nondeterministic_failures(Report), Failed_invariants = invariant_failures(Report), Failed_budget_checks = failed_budgets(Report), Status = case (((Failed =:= 0) andalso (Nondeterministic =:= 0)) andalso (Failed_invariants =:= 0)) andalso (Failed_budget_checks =:= 0) of true -> <<"OK"/utf8>>; false -> <<"FAIL"/utf8>> end, <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"# Contention Fixture Report\n\n"/utf8, "snapshot_version: "/utf8>>/binary, (erlang:integer_to_binary( 1 ))/binary>>/binary, "\n"/utf8>>/binary, "budget_version: "/utf8>>/binary, (budget_version_label( ))/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"/utf8>>/binary, "invariant_failures: "/utf8>>/binary, (erlang:integer_to_binary( Failed_invariants ))/binary>>/binary, "\n"/utf8>>/binary, "failed_budgets: "/utf8>>/binary, (erlang:integer_to_binary( Failed_budget_checks ))/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>>.