-module(lightspeed@tenant@policy).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/lightspeed/tenant/policy.gleam").
-export([tenant_context/3, system_context/1, budget/3, expanded_budget/6, default_budget/0, new/2, valid/1, mitigation_label/1, evaluate/2, repository_scope/1, role_label/1, telemetry_tags/1, action_label/1, denial_metric/1, decision_kind_label/1, surface_label/1, decision_metric/1, context_label/1, outcome_label/1, budget_label/1, usage_label/1, denial_label/1, expanded_budget_label/1, expanded_usage_label/1, decision_label/1, context/1, runtime_budget/1, runtime_usage/1, denials/1, decisions/1, signature/1]).
-export_type([role/0, context/0, surface/0, mitigation/0, action/0, budget/0, usage/0, denial_telemetry/0, decision_kind/0, decision_telemetry/0, outcome/0, runtime/0, budget_class/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(" Tenant isolation and policy runtime contracts (M29/M52 expansion).\n").
-type role() :: viewer | editor | tenant_admin.
-type context() :: {tenant_context, binary(), binary(), role()} |
{system_context, binary()}.
-type surface() :: runtime_surface |
data_surface |
pipeline_surface |
policy_surface.
-type mitigation() :: throttle_events | pause_pipelines | isolate_tenant.
-type action() :: {read, binary()} |
{write, binary()} |
{delete, binary()} |
{emit_event, integer()} |
{open_session, integer()} |
{start_job, integer()} |
{start_pipeline_run, integer()} |
{replay_pipeline_run, integer()} |
{apply_mitigation, mitigation(), integer()}.
-type budget() :: {budget,
integer(),
integer(),
integer(),
integer(),
integer(),
integer()}.
-type usage() :: {usage,
integer(),
integer(),
integer(),
integer(),
integer(),
integer()}.
-type denial_telemetry() :: {denial_telemetry,
binary(),
binary(),
action(),
binary(),
usage(),
budget()}.
-type decision_kind() :: allowed_decision | denied_decision | mitigated_decision.
-type decision_telemetry() :: {decision_telemetry,
binary(),
binary(),
surface(),
action(),
decision_kind(),
binary(),
usage(),
budget()}.
-type outcome() :: {allowed, binary()} | {denied, denial_telemetry()}.
-opaque runtime() :: {runtime,
context(),
budget(),
usage(),
list(denial_telemetry()),
list(decision_telemetry())}.
-type budget_class() :: event_budget |
session_budget |
job_budget |
pipeline_run_budget |
pipeline_replay_budget |
mitigation_budget.
-file("src/lightspeed/tenant/policy.gleam", 124).
?DOC(" Build one tenant context.\n").
-spec tenant_context(binary(), binary(), role()) -> context().
tenant_context(Actor_id, Tenant_id, Role) ->
{tenant_context, Actor_id, Tenant_id, Role}.
-file("src/lightspeed/tenant/policy.gleam", 133).
?DOC(" Build one system context.\n").
-spec system_context(binary()) -> context().
system_context(Actor_id) ->
{system_context, Actor_id}.
-file("src/lightspeed/tenant/policy.gleam", 138).
?DOC(" Build one budget.\n").
-spec budget(integer(), integer(), integer()) -> budget().
budget(Max_events, Max_sessions, Max_jobs) ->
{budget, Max_events, Max_sessions, Max_jobs, Max_jobs, Max_jobs, Max_events}.
-file("src/lightspeed/tenant/policy.gleam", 150).
?DOC(" Build one expanded budget profile for runtime/data/pipeline controls.\n").
-spec expanded_budget(
integer(),
integer(),
integer(),
integer(),
integer(),
integer()
) -> budget().
expanded_budget(
Max_events,
Max_sessions,
Max_jobs,
Max_pipeline_runs,
Max_pipeline_replays,
Max_mitigations
) ->
{budget,
Max_events,
Max_sessions,
Max_jobs,
Max_pipeline_runs,
Max_pipeline_replays,
Max_mitigations}.
-file("src/lightspeed/tenant/policy.gleam", 169).
?DOC(" Default tenant budget profile.\n").
-spec default_budget() -> budget().
default_budget() ->
{budget, 8, 3, 5, 5, 3, 6}.
-file("src/lightspeed/tenant/policy.gleam", 181).
?DOC(" Build one policy runtime.\n").
-spec new(context(), budget()) -> runtime().
new(Context, Budget) ->
{runtime, Context, Budget, {usage, 0, 0, 0, 0, 0, 0}, [], []}.
-file("src/lightspeed/tenant/policy.gleam", 199).
?DOC(" Validate policy runtime invariants.\n").
-spec valid(runtime()) -> boolean().
valid(Runtime) ->
(((((((((((erlang:element(2, erlang:element(3, Runtime)) >= 0) andalso (erlang:element(
3,
erlang:element(3, Runtime)
)
>= 0))
andalso (erlang:element(4, erlang:element(3, Runtime)) >= 0))
andalso (erlang:element(5, erlang:element(3, Runtime)) >= 0))
andalso (erlang:element(6, erlang:element(3, Runtime)) >= 0))
andalso (erlang:element(7, erlang:element(3, Runtime)) >= 0))
andalso (erlang:element(2, erlang:element(4, Runtime)) >= 0))
andalso (erlang:element(3, erlang:element(4, Runtime)) >= 0))
andalso (erlang:element(4, erlang:element(4, Runtime)) >= 0))
andalso (erlang:element(5, erlang:element(4, Runtime)) >= 0))
andalso (erlang:element(6, erlang:element(4, Runtime)) >= 0))
andalso (erlang:element(7, erlang:element(4, Runtime)) >= 0).
-file("src/lightspeed/tenant/policy.gleam", 689).
-spec action_surface(action()) -> surface().
action_surface(Action) ->
case Action of
{read, _} ->
data_surface;
{write, _} ->
data_surface;
{delete, _} ->
data_surface;
{emit_event, _} ->
runtime_surface;
{open_session, _} ->
runtime_surface;
{start_job, _} ->
pipeline_surface;
{start_pipeline_run, _} ->
pipeline_surface;
{replay_pipeline_run, _} ->
pipeline_surface;
{apply_mitigation, _, _} ->
policy_surface
end.
-file("src/lightspeed/tenant/policy.gleam", 703).
-spec context_actor_tenant(context()) -> {binary(), binary()}.
context_actor_tenant(Context) ->
case Context of
{tenant_context, Actor_id, Tenant_id, _} ->
{Actor_id, Tenant_id};
{system_context, Actor_id@1} ->
{Actor_id@1, <<"system"/utf8>>}
end.
-file("src/lightspeed/tenant/policy.gleam", 667).
-spec record_decision(runtime(), action(), decision_kind(), binary()) -> runtime().
record_decision(Runtime, Action, Decision, Reason) ->
{Actor_id, Tenant_id} = context_actor_tenant(erlang:element(2, Runtime)),
Entry = {decision_telemetry,
Actor_id,
Tenant_id,
action_surface(Action),
Action,
Decision,
Reason,
erlang:element(4, Runtime),
erlang:element(3, Runtime)},
{runtime,
erlang:element(2, Runtime),
erlang:element(3, Runtime),
erlang:element(4, Runtime),
erlang:element(5, Runtime),
[Entry | erlang:element(6, Runtime)]}.
-file("src/lightspeed/tenant/policy.gleam", 626).
-spec deny(runtime(), action(), binary(), binary(), binary()) -> {runtime(),
outcome()}.
deny(Runtime, Action, Actor_id, Tenant_id, Reason) ->
Denial = {denial_telemetry,
Actor_id,
Tenant_id,
Action,
Reason,
erlang:element(4, Runtime),
erlang:element(3, Runtime)},
Runtime@1 = {runtime,
erlang:element(2, Runtime),
erlang:element(3, Runtime),
erlang:element(4, Runtime),
[Denial | erlang:element(5, Runtime)],
erlang:element(6, Runtime)},
Runtime@2 = record_decision(Runtime@1, Action, denied_decision, Reason),
{Runtime@2, {denied, Denial}}.
-file("src/lightspeed/tenant/policy.gleam", 614).
-spec deny_for_context(runtime(), action(), binary()) -> {runtime(), outcome()}.
deny_for_context(Runtime, Action, Reason) ->
case erlang:element(2, Runtime) of
{tenant_context, Actor_id, Tenant_id, _} ->
deny(Runtime, Action, Actor_id, Tenant_id, Reason);
{system_context, Actor_id@1} ->
deny(Runtime, Action, Actor_id@1, <<"system"/utf8>>, Reason)
end.
-file("src/lightspeed/tenant/policy.gleam", 406).
?DOC(" Stable mitigation label.\n").
-spec mitigation_label(mitigation()) -> binary().
mitigation_label(Mitigation) ->
case Mitigation of
throttle_events ->
<<"throttle_events"/utf8>>;
pause_pipelines ->
<<"pause_pipelines"/utf8>>;
isolate_tenant ->
<<"isolate_tenant"/utf8>>
end.
-file("src/lightspeed/tenant/policy.gleam", 657).
-spec allow_mitigated(runtime(), action(), binary()) -> {runtime(), outcome()}.
allow_mitigated(Runtime, Action, Reason) ->
Runtime@1 = record_decision(Runtime, Action, mitigated_decision, Reason),
{Runtime@1, {allowed, Reason}}.
-file("src/lightspeed/tenant/policy.gleam", 587).
-spec within_budget(usage(), budget(), budget_class()) -> boolean().
within_budget(Usage, Budget, Budget_class) ->
case Budget_class of
event_budget ->
erlang:element(2, Usage) =< erlang:element(2, Budget);
session_budget ->
erlang:element(3, Usage) =< erlang:element(3, Budget);
job_budget ->
erlang:element(4, Usage) =< erlang:element(4, Budget);
pipeline_run_budget ->
erlang:element(5, Usage) =< erlang:element(5, Budget);
pipeline_replay_budget ->
erlang:element(6, Usage) =< erlang:element(6, Budget);
mitigation_budget ->
erlang:element(7, Usage) =< erlang:element(7, Budget)
end.
-file("src/lightspeed/tenant/policy.gleam", 570).
-spec projected_usage(usage(), integer(), budget_class()) -> usage().
projected_usage(Usage, Units, Budget_class) ->
case Budget_class of
event_budget ->
{usage,
erlang:element(2, Usage) + Units,
erlang:element(3, Usage),
erlang:element(4, Usage),
erlang:element(5, Usage),
erlang:element(6, Usage),
erlang:element(7, Usage)};
session_budget ->
{usage,
erlang:element(2, Usage),
erlang:element(3, Usage) + Units,
erlang:element(4, Usage),
erlang:element(5, Usage),
erlang:element(6, Usage),
erlang:element(7, Usage)};
job_budget ->
{usage,
erlang:element(2, Usage),
erlang:element(3, Usage),
erlang:element(4, Usage) + Units,
erlang:element(5, Usage),
erlang:element(6, Usage),
erlang:element(7, Usage)};
pipeline_run_budget ->
{usage,
erlang:element(2, Usage),
erlang:element(3, Usage),
erlang:element(4, Usage),
erlang:element(5, Usage) + Units,
erlang:element(6, Usage),
erlang:element(7, Usage)};
pipeline_replay_budget ->
{usage,
erlang:element(2, Usage),
erlang:element(3, Usage),
erlang:element(4, Usage),
erlang:element(5, Usage),
erlang:element(6, Usage) + Units,
erlang:element(7, Usage)};
mitigation_budget ->
{usage,
erlang:element(2, Usage),
erlang:element(3, Usage),
erlang:element(4, Usage),
erlang:element(5, Usage),
erlang:element(6, Usage),
erlang:element(7, Usage) + Units}
end.
-file("src/lightspeed/tenant/policy.gleam", 536).
-spec apply_mitigation(runtime(), action(), mitigation(), integer()) -> {runtime(),
outcome()}.
apply_mitigation(Runtime, Action, Mitigation, Units) ->
case Units =< 0 of
true ->
deny_for_context(Runtime, Action, <<"invalid_units"/utf8>>);
false ->
case erlang:element(2, Runtime) of
{system_context, _} ->
allow_mitigated(
Runtime,
Action,
<<"system_mitigation:"/utf8,
(mitigation_label(Mitigation))/binary>>
);
{tenant_context, _, _, _} ->
Next_usage = projected_usage(
erlang:element(4, Runtime),
Units,
mitigation_budget
),
case within_budget(
Next_usage,
erlang:element(3, Runtime),
mitigation_budget
) of
true ->
_pipe = {runtime,
erlang:element(2, Runtime),
erlang:element(3, Runtime),
Next_usage,
erlang:element(5, Runtime),
erlang:element(6, Runtime)},
allow_mitigated(
_pipe,
Action,
<<"mitigation_applied:"/utf8,
(mitigation_label(Mitigation))/binary>>
);
false ->
deny_for_context(
Runtime,
Action,
<<"mitigation_quota_exceeded"/utf8>>
)
end
end
end.
-file("src/lightspeed/tenant/policy.gleam", 603).
-spec quota_reason(budget_class()) -> binary().
quota_reason(Budget_class) ->
case Budget_class of
event_budget ->
<<"event_quota_exceeded"/utf8>>;
session_budget ->
<<"session_quota_exceeded"/utf8>>;
job_budget ->
<<"job_quota_exceeded"/utf8>>;
pipeline_run_budget ->
<<"pipeline_run_quota_exceeded"/utf8>>;
pipeline_replay_budget ->
<<"pipeline_replay_quota_exceeded"/utf8>>;
mitigation_budget ->
<<"mitigation_quota_exceeded"/utf8>>
end.
-file("src/lightspeed/tenant/policy.gleam", 647).
-spec allow(runtime(), action(), binary()) -> {runtime(), outcome()}.
allow(Runtime, Action, Reason) ->
Runtime@1 = record_decision(Runtime, Action, allowed_decision, Reason),
{Runtime@1, {allowed, Reason}}.
-file("src/lightspeed/tenant/policy.gleam", 516).
-spec consume_budget(runtime(), action(), integer(), budget_class()) -> {runtime(),
outcome()}.
consume_budget(Runtime, Action, Units, Budget_class) ->
case Units =< 0 of
true ->
deny_for_context(Runtime, Action, <<"invalid_units"/utf8>>);
false ->
Next_usage = projected_usage(
erlang:element(4, Runtime),
Units,
Budget_class
),
case within_budget(
Next_usage,
erlang:element(3, Runtime),
Budget_class
) of
true ->
_pipe = {runtime,
erlang:element(2, Runtime),
erlang:element(3, Runtime),
Next_usage,
erlang:element(5, Runtime),
erlang:element(6, Runtime)},
allow(_pipe, Action, <<"within_budget"/utf8>>);
false ->
deny_for_context(
Runtime,
Action,
quota_reason(Budget_class)
)
end
end.
-file("src/lightspeed/tenant/policy.gleam", 710).
-spec can_write(role()) -> boolean().
can_write(Role) ->
case Role of
viewer ->
false;
editor ->
true;
tenant_admin ->
true
end.
-file("src/lightspeed/tenant/policy.gleam", 489).
-spec decide_tenant_action(runtime(), action(), binary(), boolean()) -> {runtime(),
outcome()}.
decide_tenant_action(Runtime, Action, Resource_tenant_id, Require_write_role) ->
case erlang:element(2, Runtime) of
{system_context, _} ->
allow(Runtime, Action, <<"system_scope"/utf8>>);
{tenant_context, Actor_id, Tenant_id, Role} ->
case Tenant_id /= Resource_tenant_id of
true ->
deny(
Runtime,
Action,
Actor_id,
Tenant_id,
<<"tenant_mismatch:"/utf8, Resource_tenant_id/binary>>
);
false ->
case Require_write_role andalso not can_write(Role) of
true ->
deny(
Runtime,
Action,
Actor_id,
Tenant_id,
<<"role_forbidden"/utf8>>
);
false ->
allow(Runtime, Action, <<"tenant_match"/utf8>>)
end
end
end.
-file("src/lightspeed/tenant/policy.gleam", 215).
?DOC(" Evaluate one policy action.\n").
-spec evaluate(runtime(), action()) -> {runtime(), outcome()}.
evaluate(Runtime, Action) ->
case Action of
{read, Resource_tenant_id} ->
decide_tenant_action(Runtime, Action, Resource_tenant_id, false);
{write, Resource_tenant_id@1} ->
decide_tenant_action(Runtime, Action, Resource_tenant_id@1, true);
{delete, Resource_tenant_id@2} ->
decide_tenant_action(Runtime, Action, Resource_tenant_id@2, true);
{emit_event, Units} ->
consume_budget(Runtime, Action, Units, event_budget);
{open_session, Units@1} ->
consume_budget(Runtime, Action, Units@1, session_budget);
{start_job, Units@2} ->
consume_budget(Runtime, Action, Units@2, job_budget);
{start_pipeline_run, Units@3} ->
consume_budget(Runtime, Action, Units@3, pipeline_run_budget);
{replay_pipeline_run, Units@4} ->
consume_budget(Runtime, Action, Units@4, pipeline_replay_budget);
{apply_mitigation, Mitigation, Units@5} ->
apply_mitigation(Runtime, Action, Mitigation, Units@5)
end.
-file("src/lightspeed/tenant/policy.gleam", 718).
-spec repository_role(role()) -> lightspeed@data@repository:role().
repository_role(Role) ->
case Role of
viewer ->
viewer;
editor ->
editor;
tenant_admin ->
tenant_admin
end.
-file("src/lightspeed/tenant/policy.gleam", 236).
?DOC(" Convert context to data repository scope.\n").
-spec repository_scope(context()) -> lightspeed@data@repository:scope().
repository_scope(Context) ->
case Context of
{tenant_context, Actor_id, Tenant_id, Role} ->
lightspeed@data@repository:tenant_scope(
Actor_id,
Tenant_id,
repository_role(Role)
);
{system_context, Actor_id@1} ->
lightspeed@data@repository:system_scope(Actor_id@1)
end.
-file("src/lightspeed/tenant/policy.gleam", 293).
?DOC(" Stable role label.\n").
-spec role_label(role()) -> binary().
role_label(Role) ->
case Role of
viewer ->
<<"viewer"/utf8>>;
editor ->
<<"editor"/utf8>>;
tenant_admin ->
<<"tenant_admin"/utf8>>
end.
-file("src/lightspeed/tenant/policy.gleam", 245).
?DOC(" Emit telemetry tags for one context.\n").
-spec telemetry_tags(context()) -> list(lightspeed@ops@telemetry:tag()).
telemetry_tags(Context) ->
case Context of
{tenant_context, Actor_id, Tenant_id, Role} ->
[{tag, <<"actor_id"/utf8>>, Actor_id},
{tag, <<"tenant_id"/utf8>>, Tenant_id},
{tag, <<"role"/utf8>>, role_label(Role)},
{tag, <<"scope"/utf8>>, <<"tenant"/utf8>>}];
{system_context, Actor_id@1} ->
[{tag, <<"actor_id"/utf8>>, Actor_id@1},
{tag, <<"tenant_id"/utf8>>, <<"system"/utf8>>},
{tag, <<"role"/utf8>>, <<"system"/utf8>>},
{tag, <<"scope"/utf8>>, <<"system"/utf8>>}]
end.
-file("src/lightspeed/tenant/policy.gleam", 311).
?DOC(" Stable action label.\n").
-spec action_label(action()) -> binary().
action_label(Action) ->
case Action of
{read, Resource_tenant_id} ->
<<"read:"/utf8, Resource_tenant_id/binary>>;
{write, Resource_tenant_id@1} ->
<<"write:"/utf8, Resource_tenant_id@1/binary>>;
{delete, Resource_tenant_id@2} ->
<<"delete:"/utf8, Resource_tenant_id@2/binary>>;
{emit_event, Units} ->
<<"emit_event:"/utf8, (erlang:integer_to_binary(Units))/binary>>;
{open_session, Units@1} ->
<<"open_session:"/utf8, (erlang:integer_to_binary(Units@1))/binary>>;
{start_job, Units@2} ->
<<"start_job:"/utf8, (erlang:integer_to_binary(Units@2))/binary>>;
{start_pipeline_run, Units@3} ->
<<"start_pipeline_run:"/utf8,
(erlang:integer_to_binary(Units@3))/binary>>;
{replay_pipeline_run, Units@4} ->
<<"replay_pipeline_run:"/utf8,
(erlang:integer_to_binary(Units@4))/binary>>;
{apply_mitigation, Mitigation, Units@5} ->
<<<<<<"apply_mitigation:"/utf8,
(mitigation_label(Mitigation))/binary>>/binary,
":"/utf8>>/binary,
(erlang:integer_to_binary(Units@5))/binary>>
end.
-file("src/lightspeed/tenant/policy.gleam", 263).
?DOC(" Convert one denial telemetry event into a counter metric.\n").
-spec denial_metric(denial_telemetry()) -> lightspeed@ops@telemetry:metric().
denial_metric(Denial) ->
{counter,
<<"lightspeed.tenant.policy_denied_total"/utf8>>,
1,
[{tag, <<"actor_id"/utf8>>, erlang:element(2, Denial)},
{tag, <<"tenant_id"/utf8>>, erlang:element(3, Denial)},
{tag, <<"action"/utf8>>, action_label(erlang:element(4, Denial))},
{tag, <<"reason"/utf8>>, erlang:element(5, Denial)}]}.
-file("src/lightspeed/tenant/policy.gleam", 415).
?DOC(" Stable decision-kind label.\n").
-spec decision_kind_label(decision_kind()) -> binary().
decision_kind_label(Decision) ->
case Decision of
allowed_decision ->
<<"allowed"/utf8>>;
denied_decision ->
<<"denied"/utf8>>;
mitigated_decision ->
<<"mitigated"/utf8>>
end.
-file("src/lightspeed/tenant/policy.gleam", 396).
?DOC(" Stable surface label.\n").
-spec surface_label(surface()) -> binary().
surface_label(Surface) ->
case Surface of
runtime_surface ->
<<"runtime"/utf8>>;
data_surface ->
<<"data"/utf8>>;
pipeline_surface ->
<<"pipeline"/utf8>>;
policy_surface ->
<<"policy"/utf8>>
end.
-file("src/lightspeed/tenant/policy.gleam", 277).
?DOC(" Convert one decision telemetry event into a counter metric.\n").
-spec decision_metric(decision_telemetry()) -> lightspeed@ops@telemetry:metric().
decision_metric(Entry) ->
{counter,
<<"lightspeed.tenant.policy_decision_total"/utf8>>,
1,
[{tag, <<"actor_id"/utf8>>, erlang:element(2, Entry)},
{tag, <<"tenant_id"/utf8>>, erlang:element(3, Entry)},
{tag, <<"surface"/utf8>>, surface_label(erlang:element(4, Entry))},
{tag, <<"action"/utf8>>, action_label(erlang:element(5, Entry))},
{tag,
<<"decision"/utf8>>,
decision_kind_label(erlang:element(6, Entry))},
{tag, <<"reason"/utf8>>, erlang:element(7, Entry)}]}.
-file("src/lightspeed/tenant/policy.gleam", 302).
?DOC(" Stable context label.\n").
-spec context_label(context()) -> binary().
context_label(Context) ->
case Context of
{tenant_context, Actor_id, Tenant_id, Role} ->
<<<<<<<<<<"tenant:"/utf8, Actor_id/binary>>/binary, ":"/utf8>>/binary,
Tenant_id/binary>>/binary,
":"/utf8>>/binary,
(role_label(Role))/binary>>;
{system_context, Actor_id@1} ->
<<"system:"/utf8, Actor_id@1/binary>>
end.
-file("src/lightspeed/tenant/policy.gleam", 330).
?DOC(" Stable outcome label.\n").
-spec outcome_label(outcome()) -> binary().
outcome_label(Outcome) ->
case Outcome of
{allowed, Reason} ->
<<"allowed:"/utf8, Reason/binary>>;
{denied, Denial} ->
<<"denied:"/utf8, (erlang:element(5, Denial))/binary>>
end.
-file("src/lightspeed/tenant/policy.gleam", 354).
?DOC(" Stable budget label.\n").
-spec budget_label(budget()) -> binary().
budget_label(Budget) ->
<<<<<<<<<<"events="/utf8,
(erlang:integer_to_binary(erlang:element(2, Budget)))/binary>>/binary,
",sessions="/utf8>>/binary,
(erlang:integer_to_binary(erlang:element(3, Budget)))/binary>>/binary,
",jobs="/utf8>>/binary,
(erlang:integer_to_binary(erlang:element(4, Budget)))/binary>>.
-file("src/lightspeed/tenant/policy.gleam", 364).
?DOC(" Stable usage label.\n").
-spec usage_label(usage()) -> binary().
usage_label(Usage) ->
<<<<<<<<<<"events="/utf8,
(erlang:integer_to_binary(erlang:element(2, Usage)))/binary>>/binary,
",sessions="/utf8>>/binary,
(erlang:integer_to_binary(erlang:element(3, Usage)))/binary>>/binary,
",jobs="/utf8>>/binary,
(erlang:integer_to_binary(erlang:element(4, Usage)))/binary>>.
-file("src/lightspeed/tenant/policy.gleam", 338).
?DOC(" Stable denial telemetry label.\n").
-spec denial_label(denial_telemetry()) -> binary().
denial_label(Denial) ->
<<<<<<<<<<<<<<<<<<<<<<"actor="/utf8, (erlang:element(2, Denial))/binary>>/binary,
"|tenant="/utf8>>/binary,
(erlang:element(3, Denial))/binary>>/binary,
"|action="/utf8>>/binary,
(action_label(erlang:element(4, Denial)))/binary>>/binary,
"|reason="/utf8>>/binary,
(erlang:element(5, Denial))/binary>>/binary,
"|usage="/utf8>>/binary,
(usage_label(erlang:element(6, Denial)))/binary>>/binary,
"|budget="/utf8>>/binary,
(budget_label(erlang:element(7, Denial)))/binary>>.
-file("src/lightspeed/tenant/policy.gleam", 374).
?DOC(" Stable expanded budget label for M52 cross-surface policy evidence.\n").
-spec expanded_budget_label(budget()) -> binary().
expanded_budget_label(Budget) ->
<<<<<<<<<<<<(budget_label(Budget))/binary, ",pipeline_runs="/utf8>>/binary,
(erlang:integer_to_binary(erlang:element(5, Budget)))/binary>>/binary,
",pipeline_replays="/utf8>>/binary,
(erlang:integer_to_binary(erlang:element(6, Budget)))/binary>>/binary,
",mitigations="/utf8>>/binary,
(erlang:integer_to_binary(erlang:element(7, Budget)))/binary>>.
-file("src/lightspeed/tenant/policy.gleam", 385).
?DOC(" Stable expanded usage label for M52 cross-surface policy evidence.\n").
-spec expanded_usage_label(usage()) -> binary().
expanded_usage_label(Usage) ->
<<<<<<<<<<<<(usage_label(Usage))/binary, ",pipeline_runs="/utf8>>/binary,
(erlang:integer_to_binary(erlang:element(5, Usage)))/binary>>/binary,
",pipeline_replays="/utf8>>/binary,
(erlang:integer_to_binary(erlang:element(6, Usage)))/binary>>/binary,
",mitigations="/utf8>>/binary,
(erlang:integer_to_binary(erlang:element(7, Usage)))/binary>>.
-file("src/lightspeed/tenant/policy.gleam", 424).
?DOC(" Stable decision-telemetry label.\n").
-spec decision_label(decision_telemetry()) -> binary().
decision_label(Entry) ->
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"actor="/utf8,
(erlang:element(
2,
Entry
))/binary>>/binary,
"|tenant="/utf8>>/binary,
(erlang:element(
3,
Entry
))/binary>>/binary,
"|surface="/utf8>>/binary,
(surface_label(
erlang:element(4, Entry)
))/binary>>/binary,
"|action="/utf8>>/binary,
(action_label(erlang:element(5, Entry)))/binary>>/binary,
"|decision="/utf8>>/binary,
(decision_kind_label(erlang:element(6, Entry)))/binary>>/binary,
"|reason="/utf8>>/binary,
(erlang:element(7, Entry))/binary>>/binary,
"|usage="/utf8>>/binary,
(expanded_usage_label(erlang:element(8, Entry)))/binary>>/binary,
"|budget="/utf8>>/binary,
(expanded_budget_label(erlang:element(9, Entry)))/binary>>.
-file("src/lightspeed/tenant/policy.gleam", 444).
?DOC(" Runtime context accessor.\n").
-spec context(runtime()) -> context().
context(Runtime) ->
erlang:element(2, Runtime).
-file("src/lightspeed/tenant/policy.gleam", 449).
?DOC(" Runtime budget accessor.\n").
-spec runtime_budget(runtime()) -> budget().
runtime_budget(Runtime) ->
erlang:element(3, Runtime).
-file("src/lightspeed/tenant/policy.gleam", 454).
?DOC(" Runtime usage accessor.\n").
-spec runtime_usage(runtime()) -> usage().
runtime_usage(Runtime) ->
erlang:element(4, Runtime).
-file("src/lightspeed/tenant/policy.gleam", 459).
?DOC(" Runtime denials in stable order.\n").
-spec denials(runtime()) -> list(denial_telemetry()).
denials(Runtime) ->
lists:reverse(erlang:element(5, Runtime)).
-file("src/lightspeed/tenant/policy.gleam", 464).
?DOC(" Runtime decisions in stable order.\n").
-spec decisions(runtime()) -> list(decision_telemetry()).
decisions(Runtime) ->
lists:reverse(erlang:element(6, Runtime)).
-file("src/lightspeed/tenant/policy.gleam", 469).
?DOC(" Stable runtime signature.\n").
-spec signature(runtime()) -> binary().
signature(Runtime) ->
<<<<<<<<<<<<<<"context="/utf8,
(context_label(erlang:element(2, Runtime)))/binary>>/binary,
"|budget="/utf8>>/binary,
(budget_label(erlang:element(3, Runtime)))/binary>>/binary,
"|usage="/utf8>>/binary,
(usage_label(erlang:element(4, Runtime)))/binary>>/binary,
"|denials="/utf8>>/binary,
(erlang:integer_to_binary(erlang:length(erlang:element(5, Runtime))))/binary>>.