-module(lightspeed@tooling@ai_workflow).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/lightspeed/tooling/ai_workflow.gleam").
-export([scaffold_plan/2, refactor_plan/2, template_plan/2, kind_label/1, boundary_label/1, guardrail_label/1, plan_signature/1, evidence_label/1, evaluate/1, passed/1, quality_score/1, policy_score/1, violations/1, evidence/1, signature/1, track_label/1, required_evidence/1, satisfies_track_requirements/3]).
-export_type([workflow_kind/0, review_boundary/0, plan/0, guardrail/0, artifact/0, evidence/0, evaluation/0, verification_track/0, candidate/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(" AI-native workflow contracts and guardrails for M44.\n").
-type workflow_kind() :: scaffold_generation |
refactor_generation |
template_refinement.
-type review_boundary() :: {review_boundary,
binary(),
boolean(),
binary(),
binary()}.
-type plan() :: {plan,
binary(),
workflow_kind(),
binary(),
list(binary()),
list(review_boundary())}.
-type guardrail() :: tests_required |
rfc_adr_required |
deterministic_evidence_required |
human_review_required_for_refactor |
forbidden_token_ban.
-type artifact() :: {artifact, binary(), binary()}.
-type evidence() :: {evidence, binary(), binary()}.
-type evaluation() :: {evaluation,
plan(),
boolean(),
integer(),
integer(),
list(binary()),
list(evidence()),
binary()}.
-type verification_track() :: generator_track | template_track.
-type candidate() :: {candidate, list(artifact()), list(evidence()), binary()}.
-file("src/lightspeed/tooling/ai_workflow.gleam", 682).
-spec normalize_label(binary()) -> binary().
normalize_label(Value) ->
_pipe = Value,
_pipe@1 = string:lowercase(_pipe),
_pipe@2 = gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"_"/utf8>>),
_pipe@3 = gleam@string:replace(_pipe@2, <<"-"/utf8>>, <<"_"/utf8>>),
_pipe@4 = gleam@string:replace(_pipe@3, <<"."/utf8>>, <<"_"/utf8>>),
gleam@string:replace(_pipe@4, <<" "/utf8>>, <<"_"/utf8>>).
-file("src/lightspeed/tooling/ai_workflow.gleam", 84).
?DOC(" Build one scaffolding-focused AI plan.\n").
-spec scaffold_plan(binary(), binary()) -> plan().
scaffold_plan(App_name, Resource) ->
{plan,
<<"ai_scaffold_"/utf8, (normalize_label(Resource))/binary>>,
scaffold_generation,
<<<<<<<<"Generate live scaffold for "/utf8, App_name/binary>>/binary,
" resource "/utf8>>/binary,
Resource/binary>>/binary,
" with policy-compliant defaults."/utf8>>,
[<<"gen.live"/utf8>>, App_name, Resource],
[{review_boundary,
<<"prompt_review"/utf8>>,
true,
<<"application_owner"/utf8>>,
<<"confirm product scope and tenancy constraints"/utf8>>},
{review_boundary,
<<"policy_review"/utf8>>,
true,
<<"reviewer"/utf8>>,
<<"verify generated scaffold satisfies governance contracts"/utf8>>}]}.
-file("src/lightspeed/tooling/ai_workflow.gleam", 112).
?DOC(" Build one refactor-focused AI plan.\n").
-spec refactor_plan(binary(), binary()) -> plan().
refactor_plan(Module_path, Change_summary) ->
{plan,
<<"ai_refactor_"/utf8, (normalize_label(Module_path))/binary>>,
refactor_generation,
<<<<<<"Refactor "/utf8, Module_path/binary>>/binary,
" while preserving behavior and adding required tests: "/utf8>>/binary,
Change_summary/binary>>,
[],
[{review_boundary,
<<"human_review"/utf8>>,
true,
<<"senior_reviewer"/utf8>>,
<<"review semantic risk and regression surface"/utf8>>},
{review_boundary,
<<"policy_review"/utf8>>,
true,
<<"reviewer"/utf8>>,
<<"verify RFC/ADR/test obligations and deterministic evidence"/utf8>>}]}.
-file("src/lightspeed/tooling/ai_workflow.gleam", 139).
?DOC(" Build one template-refinement AI plan.\n").
-spec template_plan(binary(), binary()) -> plan().
template_plan(Component_name, Change_summary) ->
{plan,
<<"ai_template_"/utf8, (normalize_label(Component_name))/binary>>,
template_refinement,
<<<<<<"Refine template ergonomics for "/utf8, Component_name/binary>>/binary,
" with backward-compatible hints and test updates: "/utf8>>/binary,
Change_summary/binary>>,
[],
[{review_boundary,
<<"human_review"/utf8>>,
true,
<<"template_owner"/utf8>>,
<<"validate rendering semantics and migration guidance"/utf8>>},
{review_boundary,
<<"policy_review"/utf8>>,
true,
<<"reviewer"/utf8>>,
<<"enforce deterministic workflow and governance compliance"/utf8>>}]}.
-file("src/lightspeed/tooling/ai_workflow.gleam", 166).
?DOC(" Workflow kind label.\n").
-spec kind_label(workflow_kind()) -> binary().
kind_label(Kind) ->
case Kind of
scaffold_generation ->
<<"scaffold_generation"/utf8>>;
refactor_generation ->
<<"refactor_generation"/utf8>>;
template_refinement ->
<<"template_refinement"/utf8>>
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 717).
-spec bool_label(boolean()) -> binary().
bool_label(Value) ->
case Value of
true ->
<<"true"/utf8>>;
false ->
<<"false"/utf8>>
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 175).
?DOC(" Review boundary label.\n").
-spec boundary_label(review_boundary()) -> binary().
boundary_label(Boundary) ->
<<<<<<<<(erlang:element(2, Boundary))/binary, ":required="/utf8>>/binary,
(bool_label(erlang:element(3, Boundary)))/binary>>/binary,
":owner="/utf8>>/binary,
(erlang:element(4, Boundary))/binary>>.
-file("src/lightspeed/tooling/ai_workflow.gleam", 184).
?DOC(" Guardrail label.\n").
-spec guardrail_label(guardrail()) -> binary().
guardrail_label(Guardrail) ->
case Guardrail of
tests_required ->
<<"tests_required"/utf8>>;
rfc_adr_required ->
<<"rfc_adr_required"/utf8>>;
deterministic_evidence_required ->
<<"deterministic_evidence_required"/utf8>>;
human_review_required_for_refactor ->
<<"human_review_required_for_refactor"/utf8>>;
forbidden_token_ban ->
<<"forbidden_token_ban"/utf8>>
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 691).
-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/tooling/ai_workflow.gleam", 195).
?DOC(" Stable plan signature.\n").
-spec plan_signature(plan()) -> binary().
plan_signature(Plan) ->
<<<<<<<<<<<<<<<<<<"id="/utf8, (erlang:element(2, Plan))/binary>>/binary,
"|kind="/utf8>>/binary,
(kind_label(erlang:element(3, Plan)))/binary>>/binary,
"|prompt="/utf8>>/binary,
(erlang:element(4, Plan))/binary>>/binary,
"|command_args="/utf8>>/binary,
(join_with(<<","/utf8>>, erlang:element(5, Plan)))/binary>>/binary,
"|boundaries="/utf8>>/binary,
(join_with(
<<";"/utf8>>,
gleam@list:map(erlang:element(6, Plan), fun boundary_label/1)
))/binary>>.
-file("src/lightspeed/tooling/ai_workflow.gleam", 334).
?DOC(" Stable evidence entry label.\n").
-spec evidence_label(evidence()) -> binary().
evidence_label(Entry) ->
<<<<(erlang:element(2, Entry))/binary, "="/utf8>>/binary,
(erlang:element(3, Entry))/binary>>.
-file("src/lightspeed/tooling/ai_workflow.gleam", 518).
-spec evaluation_signature(
plan(),
boolean(),
integer(),
integer(),
list(binary()),
list(evidence())
) -> binary().
evaluation_signature(
Plan,
Passed,
Quality_score,
Policy_score,
Violations,
Evidence
) ->
<<<<<<<<<<<<<<<<<<<<(plan_signature(Plan))/binary, "|passed="/utf8>>/binary,
(bool_label(Passed))/binary>>/binary,
"|quality="/utf8>>/binary,
(erlang:integer_to_binary(Quality_score))/binary>>/binary,
"|policy="/utf8>>/binary,
(erlang:integer_to_binary(Policy_score))/binary>>/binary,
"|violations="/utf8>>/binary,
(join_with(<<","/utf8>>, Violations))/binary>>/binary,
"|evidence="/utf8>>/binary,
(join_with(<<";"/utf8>>, gleam@list:map(Evidence, fun evidence_label/1)))/binary>>.
-file("src/lightspeed/tooling/ai_workflow.gleam", 706).
-spec clamp(integer(), integer(), integer()) -> integer().
clamp(Value, Min, Max) ->
case Value < Min of
true ->
Min;
false ->
case Value > Max of
true ->
Max;
false ->
Value
end
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 699).
-spec min_int(integer(), integer()) -> integer().
min_int(Left, Right) ->
case Left =< Right of
true ->
Left;
false ->
Right
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 556).
-spec score_quality(integer(), integer(), integer()) -> integer().
score_quality(Artifact_count, Evidence_count, Violation_count) ->
Base = 60,
Artifact_bonus = min_int(25, Artifact_count * 3),
Evidence_bonus = min_int(15, Evidence_count * 3),
Penalty = Violation_count * 20,
clamp(((Base + Artifact_bonus) + Evidence_bonus) - Penalty, 0, 100).
-file("src/lightspeed/tooling/ai_workflow.gleam", 549).
-spec score_policy(integer(), integer()) -> integer().
score_policy(Passed_guardrails, Total_guardrails) ->
case Total_guardrails =< 0 of
true ->
0;
false ->
case Total_guardrails of
0 -> 0;
Gleam@denominator -> Passed_guardrails * 100 div Gleam@denominator
end
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 628).
-spec content_contains_any(binary(), list(binary())) -> boolean().
content_contains_any(Content, Tokens) ->
case Tokens of
[] ->
false;
[Token | Rest] ->
case gleam_stdlib:contains_string(Content, Token) of
true ->
true;
false ->
content_contains_any(Content, Rest)
end
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 614).
-spec has_forbidden_token_with_list(list(artifact()), list(binary())) -> boolean().
has_forbidden_token_with_list(Artifacts, Forbidden_tokens) ->
case Artifacts of
[] ->
false;
[Artifact | Rest] ->
case content_contains_any(
erlang:element(3, Artifact),
Forbidden_tokens
) of
true ->
true;
false ->
has_forbidden_token_with_list(Rest, Forbidden_tokens)
end
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 606).
-spec has_forbidden_token(list(artifact())) -> boolean().
has_forbidden_token(Artifacts) ->
has_forbidden_token_with_list(
Artifacts,
[<<"unsafe-inline-script"/utf8>>,
<<"eval("/utf8>>,
<<"shell_exec("/utf8>>]
).
-file("src/lightspeed/tooling/ai_workflow.gleam", 595).
-spec has_human_review_boundary(list(review_boundary())) -> boolean().
has_human_review_boundary(Boundaries) ->
case Boundaries of
[] ->
false;
[Boundary | Rest] ->
case (erlang:element(2, Boundary) =:= <<"human_review"/utf8>>)
andalso erlang:element(3, Boundary) of
true ->
true;
false ->
has_human_review_boundary(Rest)
end
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 639).
-spec evidence_contains(list(evidence()), binary()) -> boolean().
evidence_contains(Evidence, Label) ->
case Evidence of
[] ->
false;
[Entry | Rest] ->
case erlang:element(2, Entry) =:= Label of
true ->
true;
false ->
evidence_contains(Rest, Label)
end
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 584).
-spec has_artifact_path(list(artifact()), binary()) -> boolean().
has_artifact_path(Artifacts, Path) ->
case Artifacts of
[] ->
false;
[Artifact | Rest] ->
case erlang:element(2, Artifact) =:= Path of
true ->
true;
false ->
has_artifact_path(Rest, Path)
end
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 579).
-spec has_governance_artifacts(list(artifact())) -> boolean().
has_governance_artifacts(Artifacts) ->
has_artifact_path(Artifacts, <<"rfcs/0000-template.md"/utf8>>) andalso has_artifact_path(
Artifacts,
<<"adrs/0000-template.md"/utf8>>
).
-file("src/lightspeed/tooling/ai_workflow.gleam", 568).
-spec has_test_artifact(list(artifact())) -> boolean().
has_test_artifact(Artifacts) ->
case Artifacts of
[] ->
false;
[Artifact | Rest] ->
case gleam_stdlib:string_starts_with(
erlang:element(2, Artifact),
<<"test/"/utf8>>
) of
true ->
true;
false ->
has_test_artifact(Rest)
end
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 473).
-spec guardrail_violation(plan(), candidate(), guardrail()) -> gleam@option:option(binary()).
guardrail_violation(Plan, Candidate, Guardrail) ->
case Guardrail of
tests_required ->
case has_test_artifact(erlang:element(2, Candidate)) of
true ->
none;
false ->
{some, <<"missing_test_artifacts"/utf8>>}
end;
rfc_adr_required ->
case has_governance_artifacts(erlang:element(2, Candidate)) of
true ->
none;
false ->
{some, <<"missing_governance_artifacts"/utf8>>}
end;
deterministic_evidence_required ->
case (erlang:element(4, Candidate) /= <<""/utf8>>) andalso evidence_contains(
erlang:element(3, Candidate),
<<"deterministic_signature"/utf8>>
) of
true ->
none;
false ->
{some, <<"missing_deterministic_evidence"/utf8>>}
end;
human_review_required_for_refactor ->
case erlang:element(3, Plan) of
refactor_generation ->
case has_human_review_boundary(erlang:element(6, Plan)) of
true ->
none;
false ->
{some, <<"missing_human_review_boundary"/utf8>>}
end;
template_refinement ->
case has_human_review_boundary(erlang:element(6, Plan)) of
true ->
none;
false ->
{some, <<"missing_human_review_boundary"/utf8>>}
end;
scaffold_generation ->
none
end;
forbidden_token_ban ->
case has_forbidden_token(erlang:element(2, Candidate)) of
true ->
{some, <<"forbidden_tokens_present"/utf8>>};
false ->
none
end
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 439).
-spec evaluate_guardrails(
plan(),
candidate(),
list(guardrail()),
list(binary()),
integer(),
integer()
) -> {list(binary()), integer(), integer()}.
evaluate_guardrails(
Plan,
Candidate,
Guardrails,
Violations_rev,
Passed_guardrails,
Total_guardrails
) ->
case Guardrails of
[] ->
{lists:reverse(Violations_rev), Passed_guardrails, Total_guardrails};
[Guardrail | Rest] ->
case guardrail_violation(Plan, Candidate, Guardrail) of
none ->
evaluate_guardrails(
Plan,
Candidate,
Rest,
Violations_rev,
Passed_guardrails + 1,
Total_guardrails
);
{some, Violation} ->
evaluate_guardrails(
Plan,
Candidate,
Rest,
[Violation | Violations_rev],
Passed_guardrails,
Total_guardrails
)
end
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 539).
-spec default_guardrails() -> list(guardrail()).
default_guardrails() ->
[tests_required,
rfc_adr_required,
deterministic_evidence_required,
human_review_required_for_refactor,
forbidden_token_ban].
-file("src/lightspeed/tooling/ai_workflow.gleam", 677).
-spec extract_template_target(binary()) -> binary().
extract_template_target(Plan_id) ->
_pipe = gleam@string:replace(Plan_id, <<"ai_template_"/utf8>>, <<""/utf8>>),
gleam@string:replace(_pipe, <<"_"/utf8>>, <<"/"/utf8>>).
-file("src/lightspeed/tooling/ai_workflow.gleam", 405).
-spec template_candidate(plan()) -> candidate().
template_candidate(Plan) ->
Component_target = extract_template_target(erlang:element(2, Plan)),
Deterministic = <<"template_signature:"/utf8, Component_target/binary>>,
Artifacts = [{artifact,
<<<<"src/lightspeed/component/"/utf8, Component_target/binary>>/binary,
".gleam"/utf8>>,
<<"pub fn template_marker() -> String {\n \"ai_template\"\n}\n"/utf8>>},
{artifact,
<<<<"test/lightspeed/"/utf8,
(normalize_label(Component_target))/binary>>/binary,
"_template_test.gleam"/utf8>>,
<<"pub fn template_regression_test() -> Bool {\n True\n}\n"/utf8>>},
{artifact,
<<"rfcs/0000-template.md"/utf8>>,
<<"# RFC placeholder\n"/utf8>>},
{artifact,
<<"adrs/0000-template.md"/utf8>>,
<<"# ADR placeholder\n"/utf8>>}],
Evidence = [{evidence, <<"deterministic_signature"/utf8>>, Deterministic},
{evidence, <<"template_workflow_signature"/utf8>>, Deterministic},
{evidence,
<<"template_guardrail_profile"/utf8>>,
<<"aliases+defaults+hints"/utf8>>},
{evidence, <<"template_migration_contract"/utf8>>, <<"enforced"/utf8>>}],
{candidate, Artifacts, Evidence, Deterministic}.
-file("src/lightspeed/tooling/ai_workflow.gleam", 672).
-spec extract_refactor_target(binary()) -> binary().
extract_refactor_target(Plan_id) ->
_pipe = gleam@string:replace(Plan_id, <<"ai_refactor_"/utf8>>, <<""/utf8>>),
gleam@string:replace(_pipe, <<"_"/utf8>>, <<"/"/utf8>>).
-file("src/lightspeed/tooling/ai_workflow.gleam", 375).
-spec refactor_candidate(plan()) -> candidate().
refactor_candidate(Plan) ->
Module_target = extract_refactor_target(erlang:element(2, Plan)),
Deterministic = <<"refactor_signature:"/utf8, Module_target/binary>>,
Artifacts = [{artifact,
<<<<"src/lightspeed/"/utf8, Module_target/binary>>/binary,
".gleam"/utf8>>,
<<"pub fn refactor_marker() -> String {\n \"ai_refactor\"\n}\n"/utf8>>},
{artifact,
<<<<"test/lightspeed/"/utf8,
(normalize_label(Module_target))/binary>>/binary,
"_test.gleam"/utf8>>,
<<"pub fn refactor_regression_test() -> Bool {\n True\n}\n"/utf8>>},
{artifact,
<<"rfcs/0000-template.md"/utf8>>,
<<"# RFC placeholder\n"/utf8>>},
{artifact,
<<"adrs/0000-template.md"/utf8>>,
<<"# ADR placeholder\n"/utf8>>}],
Evidence = [{evidence, <<"deterministic_signature"/utf8>>, Deterministic},
{evidence, <<"human_review_boundary"/utf8>>, <<"required"/utf8>>},
{evidence,
<<"policy_profile"/utf8>>,
<<"tests+rfc+adr+determinism"/utf8>>}],
{candidate, Artifacts, Evidence, Deterministic}.
-file("src/lightspeed/tooling/ai_workflow.gleam", 658).
-spec project_artifacts(
list(lightspeed@tooling@generator:file()),
list(artifact())
) -> list(artifact()).
project_artifacts(Files, Artifacts_rev) ->
case Files of
[] ->
lists:reverse(Artifacts_rev);
[File | Rest] ->
project_artifacts(
Rest,
[{artifact, erlang:element(2, File), erlang:element(3, File)} |
Artifacts_rev]
)
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 346).
-spec scaffold_candidate(plan()) -> {ok, candidate()} | {error, binary()}.
scaffold_candidate(Plan) ->
case lightspeed@tooling@generator:parse(erlang:element(5, Plan)) of
{error, Error} ->
{error,
<<"parse_error:"/utf8,
(lightspeed@tooling@generator:parse_error_label(Error))/binary>>};
{ok, Command} ->
Project = lightspeed@tooling@generator:scaffold(Command),
Artifacts = project_artifacts(
lightspeed@tooling@generator:files(Project),
[]
),
Deterministic = lightspeed@tooling@generator:fixture_signature(
Project
),
Evidence = [{evidence,
<<"generator_fixture_signature"/utf8>>,
Deterministic},
{evidence,
<<"generator_snapshot_signature"/utf8>>,
lightspeed@tooling@generator:snapshot_signature()},
{evidence,
<<"generator_contract"/utf8>>,
bool_label(
lightspeed@tooling@generator:production_contract(
Project
)
)},
{evidence, <<"deterministic_signature"/utf8>>, Deterministic}],
{ok, {candidate, Artifacts, Evidence, Deterministic}}
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 338).
-spec generate_candidate(plan()) -> {ok, candidate()} | {error, binary()}.
generate_candidate(Plan) ->
case erlang:element(3, Plan) of
scaffold_generation ->
scaffold_candidate(Plan);
refactor_generation ->
{ok, refactor_candidate(Plan)};
template_refinement ->
{ok, template_candidate(Plan)}
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 209).
?DOC(" Evaluate one AI workflow plan against deterministic guardrails.\n").
-spec evaluate(plan()) -> evaluation().
evaluate(Plan) ->
case generate_candidate(Plan) of
{error, Reason} ->
{evaluation,
Plan,
false,
0,
0,
[Reason],
[],
evaluation_signature(Plan, false, 0, 0, [Reason], [])};
{ok, Candidate} ->
Guardrails = default_guardrails(),
{Violations, Passed_guardrails, Total_guardrails} = evaluate_guardrails(
Plan,
Candidate,
Guardrails,
[],
0,
erlang:length(Guardrails)
),
Policy = score_policy(Passed_guardrails, Total_guardrails),
Quality = score_quality(
erlang:length(erlang:element(2, Candidate)),
erlang:length(erlang:element(3, Candidate)),
erlang:length(Violations)
),
Passed = ((Violations =:= []) andalso (Policy >= 80)) andalso (Quality
>= 80),
{evaluation,
Plan,
Passed,
Quality,
Policy,
Violations,
erlang:element(3, Candidate),
evaluation_signature(
Plan,
Passed,
Quality,
Policy,
Violations,
erlang:element(3, Candidate)
)}
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 263).
?DOC(" Evaluation pass/fail accessor.\n").
-spec passed(evaluation()) -> boolean().
passed(Evaluation) ->
erlang:element(3, Evaluation).
-file("src/lightspeed/tooling/ai_workflow.gleam", 268).
?DOC(" Evaluation quality score accessor.\n").
-spec quality_score(evaluation()) -> integer().
quality_score(Evaluation) ->
erlang:element(4, Evaluation).
-file("src/lightspeed/tooling/ai_workflow.gleam", 273).
?DOC(" Evaluation policy score accessor.\n").
-spec policy_score(evaluation()) -> integer().
policy_score(Evaluation) ->
erlang:element(5, Evaluation).
-file("src/lightspeed/tooling/ai_workflow.gleam", 278).
?DOC(" Evaluation violations accessor.\n").
-spec violations(evaluation()) -> list(binary()).
violations(Evaluation) ->
erlang:element(6, Evaluation).
-file("src/lightspeed/tooling/ai_workflow.gleam", 283).
?DOC(" Evaluation evidence accessor.\n").
-spec evidence(evaluation()) -> list(evidence()).
evidence(Evaluation) ->
erlang:element(7, Evaluation).
-file("src/lightspeed/tooling/ai_workflow.gleam", 288).
?DOC(" Evaluation signature accessor.\n").
-spec signature(evaluation()) -> binary().
signature(Evaluation) ->
erlang:element(8, Evaluation).
-file("src/lightspeed/tooling/ai_workflow.gleam", 293).
?DOC(" Verification track label.\n").
-spec track_label(verification_track()) -> binary().
track_label(Track) ->
case Track of
generator_track ->
<<"generator_track"/utf8>>;
template_track ->
<<"template_track"/utf8>>
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 301).
?DOC(" Required evidence labels for one verification track.\n").
-spec required_evidence(verification_track()) -> list(binary()).
required_evidence(Track) ->
case Track of
generator_track ->
[<<"generator_fixture_signature"/utf8>>,
<<"generator_snapshot_signature"/utf8>>,
<<"generator_contract"/utf8>>];
template_track ->
[<<"template_workflow_signature"/utf8>>,
<<"template_guardrail_profile"/utf8>>,
<<"template_migration_contract"/utf8>>]
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 650).
-spec has_all_evidence(list(evidence()), list(binary())) -> boolean().
has_all_evidence(Evidence, Labels) ->
case Labels of
[] ->
true;
[Label | Rest] ->
evidence_contains(Evidence, Label) andalso has_all_evidence(
Evidence,
Rest
)
end.
-file("src/lightspeed/tooling/ai_workflow.gleam", 317).
?DOC(" True when one evaluation satisfies required evidence and external signature.\n").
-spec satisfies_track_requirements(evaluation(), verification_track(), binary()) -> boolean().
satisfies_track_requirements(Evaluation, Track, External_signature) ->
Requirements = required_evidence(Track),
Has_required = has_all_evidence(erlang:element(7, Evaluation), Requirements),
External_ok = case Track of
generator_track ->
gleam_stdlib:string_starts_with(
External_signature,
<<"m25.snapshot.v"/utf8>>
);
template_track ->
gleam_stdlib:string_starts_with(
External_signature,
<<"m39.snapshot.v"/utf8>>
)
end,
Has_required andalso External_ok.