programming-elixir — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited programming-elixir (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Write Elixir as clear data transformations with explicit process and failure ownership. As of 2026-10: Elixir 1.20 is the current stable line (released June 2026) and Phoenix 1.8.x the current Phoenix line, with gradual compiler type inference across language constructs. Inspect the project's Elixir/Erlang requirements and locked Phoenix/Ecto versions first. Elixir 1.20 requires OTP 27+; select a documented compatible pair rather than independently upgrading runtimes.
Modules organize behavior; processes own concurrent activity and state. Supervision restores failed processes, not lost database transactions or external side effects. Validate untrusted input and represent expected failures explicitly; let unexpected defects fail where a deliberate supervision boundary can handle them.
{:ok, value}/{:error, reason} contracts consistent. Use with for dependent fallible steps, but normalize ambiguous failure shapes in their owning functions. A large else reconstructing which step failed signals unclear contracts.case for branching and pipes for linear transformations; do not force every condition into with. Keep error reasons useful to callers without leaking sensitive input.@spec and @type for documented contracts and existing analysis tools. Do not invent new set-theoretic annotation syntax: user-supplied signatures and typed structs for that system remain future work in the 1.20 release.@enforce_keys does not validate values.String.to_atom/1 can exhaust the atom table; to_existing_atom/1 still raises and does not prove an atom is allowed for this operation.Stream for deferred traversal when needed; consume it deliberately. Avoid assuming laziness removes the memory cost of a later full materialization.:one_for_one for independent children, :rest_for_one when later children depend on earlier ones. Specify restart/shutdown policy; a Task normally has temporary restart behavior.Task.async links caller and task, so task failure can terminate its caller. Use supervised async_nolink when that coupling is undesirable, and consume results, failures, and monitor messages.Task.async_stream or equivalent limits. Set concurrency according to downstream capacity, with a deliberate timeout policy. Lazy input alone does not make unbounded spawning safe.GenServer.call timeout does not cancel work already accepted by the server. Account for uncertain completion before retrying a mutation; a cast provides no processing acknowledgement.Ecto.Multi for named dependent database operations when it improves clarity. Handle the failed operation and reason; returned changes_so_far contains prior operation results, while the transaction's database writes roll back. Transactions do not make external API calls reversible.Scope struct (current_scope) from authentication into context functions. When the project uses scopes, pass the scope explicitly and filter queries by it rather than reading the user from assigns deep inside contexts.assign_async/start_async for lifecycle-managed work, with loading/error rendering. Capture needed values before starting work; avoid blocking callbacks with Task.await.Accept only known external values without creating atoms or disguising errors:
defmodule Visibility do
@spec parse(term()) :: {:ok, :public | :private} | {:error, :invalid_visibility}
def parse("public"), do: {:ok, :public}
def parse("private"), do: {:ok, :private}
def parse(_), do: {:error, :invalid_visibility}
endThe final clause returns an explicit expected failure. Internal callers can pattern-match the result without rescuing exceptions or silently selecting a default.
mix compile --warnings-as-errors, ExUnit, and existing analysis tools when authorized. Format checks alone do not prove compilation or behavior; use async tests only when their shared resources are isolated.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.