Compile-time Elixir macro DSL, two-tier caching layer, and execution runner for
TypeSafe Jev (SystemOneSDK) semantic contracts.
JevDSL compiles %SystemOneSDK.Prepared{} contracts at build time (defnoul,
defchoice, defscore, defjev, defalias), caches rehydrated Jason.Fragment
wire payloads in :persistent_term in O(1), provides deterministic SHA-256
content-addressed L1/L2 caching (JevDSL.Cache), and generates evaluate/3,
evaluate!/3, evaluate_many/3, available?/2, cache_key/2, contract/1,
prepared/1, and __export_cue__/0 directly on your contract module.
Both atoms and strings are supported interchangeably for contract keys, question
keys, stab-clause option keys, and answer lookups (fetch_answer/2, choice?/2,
probability/2).
Quick Start
defmodule MyApp.TriageContracts do
use JevDSL,
otp_app: :my_app,
cache: JevDSL.Cache.ETS
defnoul :is_spam do
"Does this message contain unsolicited promotional spam?"
end
defchoice :sentiment,
ask: "Classify the overall tone of the message." do
positive -> "Constructive, appreciative, or favorable tone."
neutral -> "Factual or informational without strong emotion."
negative -> "Critical, frustrated, or dissatisfied tone."
end
defscore :completeness,
ask: "Rate how complete the submission is." do
incomplete -> "Missing required identity or contact fields."
partial -> "Core fields are present but optional context is missing."
complete -> "All identity, contact, and biographical fields are populated."
end
defjev :ticket_triage do
noul :requires_escalation do
"Does this issue require immediate engineering escalation?"
end
choice :priority,
ask: "Select the appropriate response priority." do
urgent -> "Production outage or security incident."
normal -> "Standard bug report or feature question."
end
score :clarity,
ask: "Rate the clarity of the reproduction steps." do
vague -> "No steps or environment details provided."
clear -> "Includes clear steps and expected vs actual behavior."
end
end
endEvaluating Contracts
# Single evaluation (automatically cached by state + contract fingerprint)
{:ok, response} = MyApp.TriageContracts.evaluate(:sentiment, %{text: "Great work!"})
# Concurrent batch evaluation (resolves L1/L2 cache hits first, batches only misses)
results = MyApp.TriageContracts.evaluate_many(:is_spam, [%{body: "a"}, %{body: "b"}])
# Deterministic unit tests via 1-arity `:eval_fn` (or `:cache_only` / `SystemOneSDK.Test`)
{:ok, mocked} =
MyApp.TriageContracts.evaluate(:is_spam, %{body: "a"},
eval_fn: fn _state -> {:ok, %{answers: %{is_spam: %{noul: 0.05}}}} end
)
Summary
Functions
Returns true if a ChoiceAnswer (or choice value) selected expected_option,
comparing atoms and strings equivalently.
Aliases a secondary or legacy contract name (atom or string) to a canonical contract name.
Defines a single-question Choice contract (SystemOneSDK.Question.Choice) using key -> "description" stab clauses.
Preserves the exact declaration order of options and compiles option keys as atoms.
Defines a multi-question contract combining choice, noul, and/or score sub-questions.
Defines a single-question Noul (boolean probability) contract (SystemOneSDK.Question.Noul).
Defines a single-question ordered Score contract (SystemOneSDK.Question.Score, 2..10 rubric levels)
using label -> "description" stab clauses.
Exports compiled Jev contracts into a CUE schema document.
Fetches an answer from a %SystemOneSDK.SystemOneResponse{} (or map with :answers),
matching key whether passed as an atom or a string.
Fetches an answer by atom or string key, raising KeyError if not present.
Rehydrates and caches the Jason.Fragment wire encoder on a compile-time %SystemOneSDK.Prepared{} struct.
Fetches the probability for option_key (atom or string) from a ChoiceAnswer or probability map.
Functions
@spec choice?( SystemOneSDK.ChoiceAnswer.t() | map() | atom() | String.t(), atom() | String.t() ) :: boolean()
Returns true if a ChoiceAnswer (or choice value) selected expected_option,
comparing atoms and strings equivalently.
Examples
iex> ans = %SystemOneSDK.ChoiceAnswer{choice: "positive", confidence: 0.9, probabilities: %{"positive" => 0.9}}
iex> JevDSL.choice?(ans, :positive)
true
iex> JevDSL.choice?(ans, "positive")
true
iex> JevDSL.choice?(ans, :negative)
false
Aliases a secondary or legacy contract name (atom or string) to a canonical contract name.
Defines a single-question Choice contract (SystemOneSDK.Question.Choice) using key -> "description" stab clauses.
Preserves the exact declaration order of options and compiles option keys as atoms.
Defines a multi-question contract combining choice, noul, and/or score sub-questions.
Defines a single-question Noul (boolean probability) contract (SystemOneSDK.Question.Noul).
Supports a string block, ask: "..." option, or true -> "..." / false -> "..." stab clauses.
Defines a single-question ordered Score contract (SystemOneSDK.Question.Score, 2..10 rubric levels)
using label -> "description" stab clauses.
@spec export_cue(%{optional(atom() | String.t()) => JevDSL.Contract.t() | map()}) :: String.t()
Exports compiled Jev contracts into a CUE schema document.
@spec fetch_answer(SystemOneSDK.SystemOneResponse.t() | map(), atom() | String.t()) :: {:ok, term()} | :error
Fetches an answer from a %SystemOneSDK.SystemOneResponse{} (or map with :answers),
matching key whether passed as an atom or a string.
Examples
iex> resp = %{answers: %{tone: %{choice: "positive"}}}
iex> JevDSL.fetch_answer(resp, :tone)
{:ok, %{choice: "positive"}}
iex> JevDSL.fetch_answer(resp, "tone")
{:ok, %{choice: "positive"}}
iex> JevDSL.fetch_answer(resp, :missing)
:error
@spec fetch_answer!(SystemOneSDK.SystemOneResponse.t() | map(), atom() | String.t()) :: term()
Fetches an answer by atom or string key, raising KeyError if not present.
@spec hydrate_prepared(SystemOneSDK.Prepared.t()) :: SystemOneSDK.Prepared.t()
Rehydrates and caches the Jason.Fragment wire encoder on a compile-time %SystemOneSDK.Prepared{} struct.
@spec probability(SystemOneSDK.ChoiceAnswer.t() | map(), atom() | String.t()) :: {:ok, number()} | :error
Fetches the probability for option_key (atom or string) from a ChoiceAnswer or probability map.
Examples
iex> ans = %SystemOneSDK.ChoiceAnswer{choice: "positive", confidence: 0.9, probabilities: %{"positive" => 0.9, "neutral" => 0.1}}
iex> JevDSL.probability(ans, :positive)
{:ok, 0.9}
iex> JevDSL.probability(ans, "neutral")
{:ok, 0.1}