Skip to content
Back to skills

Elixir Iron Review

ASecurity

Review a diff or the working tree against the Emisar Iron Laws (IL-1…IL-20) — the mechanical Credo checks plus the judgment checks a static analyzer can't do. Use when reviewing portal/ Elixir before a PR, after a refactor, or to double-check context/query/changeset/LiveView changes. Reports law · file:line · fix.

  • 391 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
devopsrustbashawsgitsecurity

Works with

  • mcp

Security analysis

A100/100

Scanned November 7, 2026

npx -y skills add AndrewDryga/emisar --skill elixir-iron-review --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Elixir Iron Review?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Elixir Iron Review
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/andrewdryga-elixir-iron-review/badge)](https://www.skillsdirectory.com/skills/andrewdryga-elixir-iron-review)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: elixir-iron-review
description: Review a diff or the working tree against the Emisar Iron Laws (IL-1…IL-20) — the mechanical Credo checks plus the judgment checks a static analyzer can't do. Use when reviewing portal/ Elixir before a PR, after a refactor, or to double-check context/query/changeset/LiveView changes. Reports law · file:line · fix.
effort: medium
argument-hint: "[path or git ref, default = working tree]  [--fix]"
allowed-tools: Read, Grep, Glob, Bash, Write, Edit
---

# Iron Law review

Check `portal/` Elixir against the Iron Laws in `portal/AGENTS.md`. The custom
Credo checks (`Emisar.Checks.*`) cover the mechanical subset; this skill
**adds the judgment laws** — including IL-15 and IL-16, whose safety depends on
where a value came from, which a static check deliberately can't decide. Default scope: the working
tree (`git diff` + untracked). A path or git ref narrows it.

Read-only by default. A fix request or `--fix` authorizes repairs within its scope.
Gather evidence for judgment findings before changing behavior; ask only for a
material decision or missing authority.

## Step 1 — mechanical checks (Credo)

Use existing gate/Credo evidence when it covers the unchanged reviewed tree;
otherwise run focused Credo on changed Elixir files. Report findings during a
review; repair them only when fixes are authorized. The final Portal gate still
includes full Credo. Details: portal/.agent/kb/rules/elixir-layered-contexts.md
section Enforcement.

## Step 2 — judgment checks (read the changed bodies)

For each changed context / query / changeset / authorizer / LiveView / MCP /
controller file, read it and check:

- **IL-3** — every *public* context fn takes `%Subject{}` as the last required
  arg and calls `ensure_has_permissions/2` **before** any DB call. (Internal §1.4
  helpers are exempt — confirm they're truly internal and unexposed.)
- **IL-4** — `Authorizer.for_subject(query, subject)` sits immediately before
  every `Repo.fetch`/`list`/`fetch_and_update` in a context.
- **IL-5** — public reads/writes return tagged tuples; no bare struct/`nil`.
- **IL-9** — authorizers expose `build(Schema, :verb)` accessors, clause all
  roles, and the new authorizer's context is listed in `auth/permissions.ex`'s
  `@authorizer_contexts`.
- **IL-10** — Subject-gated context reads route preloads through Query `preloads/0`.
  An internal, no-Subject, already-authorized path holding a struct may use
  `Repo.preload/2` for its parent association (post-commit email helpers or the
  runner-register billing check). Confirm that distinction before reporting a finding.
- **IL-13** — recurrent jobs derive work from durable rows, keep each tick
  idempotent, and stay safe if a previous tick partially completed.
- **IL-14** — `String.to_atom/1` only on code literals / bounded sets; **never** on
  request params, runner output, or MCP/LLM input (atom-table DoS). Trace the arg to
  its source before clearing it.
- **IL-16** — `raw/1` only on app-generated / known-safe HTML (server-rendered QR
  SVG, sanitized markdown); **never** on runner output, runbook, or pack text
  (stored XSS). Confirm the source.
- **IL-15** — every LiveView `handle_event` / MCP action / controller action that
  mutates passes the subject into a context call (no trusting mount/connect).
- **IL-17** — long-lived processes are under a supervisor (no bare `start_link`).
- **IL-18** — LiveView: no unconditional `Repo`/context read in `mount`
  (`assign_async` or `connected?` + cache); `stream/3` for lists that can grow;
  `connected?(socket)` guard before `subscribe`; no `assign_new` for per-mount
  values.
- **IL-11** — no shim/flag/deprecated-kept/corrective-migration-on-unshipped.
- **IL-20** — a done local change has green `./run gate portal --changed`
  output; a pushed or release-ready change has green `./run gate portal` output.

## Step 3 — report

One block per finding, ordered by law number, then severity:

```
IL-4 · BLOCKER · lib/emisar/widgets.ex:42
  list_widgets/2 calls Repo.list without Authorizer.for_subject above it — cross-account leak.
  Fix: pipe `|> Authorizer.for_subject(subject)` before `|> Repo.list(...)`.
```

Lead with a one-line verdict (`N blockers, M suggestions`). If clean, say so in
one line — don't pad. Findings that need a human call (is this list large enough
to need a stream?) are SUGGESTIONS with the question stated, not BLOCKERS.

## Fix scope

Trace return contracts and data provenance before repairing a finding. Moving an
inline query into its Query module can preserve behavior; replacing Repo.get with
Repo.fetch changes the return shape, and changing a money field may require a
production migration. Follow the actual caller and applied-migration contracts.
For authorized security fixes, establish intended scope and test the denial path;
do not require another confirmation merely because the finding involves judgment.
Run focused checks after repair and the canonical final gate on the finished tree.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.