prompts/skills/clojure-guardrails/SKILL.md
Reference for Guardrails library with Malli in Clojure. Use when working with `>defn`, `>defn-`, `>def`, `>fdef` macros, gspec syntax, or function validation. Triggers on guardrails imports, `com.fulcrologic.guardrails.malli`, function specs with `=>` operator, or questions about runtime validation in Clojure.
npx skillsauth add ramblurr/nix-devenv clojure-guardrailsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Check if guardrails is in use:
grep -r "guardrails.enabled" deps.edn shadow-cljs.edn 2>/dev/null
deps.edn:
{:deps {com.fulcrologic/guardrails {:mvn/version "1.2.16"}
metosin/malli {:mvn/version "0.20.0"}}
:aliases {:dev {:jvm-opts ["-Dguardrails.enabled=true"]}}}
See https://clojars.org/com.fulcrologic/guardrails for the latest version.
guardrails.edn (sibling to deps.edn):
{:throw? true}
This causes guardrails violations to throw exceptions instead of just logging. We want this in nearly all cases — silent validation failures defeat the purpose.
Enable at runtime: -Dguardrails.enabled=true
(require '[com.fulcrologic.guardrails.malli.core :refer [>defn >defn- >def >fdef | ? =>]])
| Macro | Purpose |
|-------|---------|
| >defn | Define function with inline spec |
| >defn- | Private function with spec |
| >def | Register malli schema |
| >fdef | Declare spec without body |
| ? | Nilable shorthand [:maybe schema] |
| \| | "Such that" constraints |
| => | Separates args from return |
[arg-specs* (| arg-preds+)? => ret-spec (| ret-preds+)?]
Basic:
(>defn add [a b]
[:int :int => :int]
(+ a b))
With constraints:
(>defn ranged-rand [start end]
[:int :int | #(< start end)
=> :int | #(>= % start) #(< % end)]
(+ start (long (rand (- end start)))))
Nilable:
(>defn find-user [id]
[:int => (? :map)]
(get users id))
Multi-arity:
(>defn greet
([name]
[:string => :string]
(str "Hello, " name))
([greeting name]
[:string :string => :string]
(str greeting ", " name)))
Variadic:
(>defn sum [x & more]
[:int [:* :int] => :int]
(apply + x more))
Map schemas:
(>defn process-user [user]
[[:map [:name :string] [:age :int]] => :string]
(str (:name user) " is " (:age user)))
This is an optional feature.
(require '[com.fulcrologic.guardrails.malli.registry :as gr.reg])
;; Register schemas
(>def :user/name :string)
(>def :user/age :int)
(>def :user/record [:map :user/name :user/age])
;; Use in functions
(>defn get-user [id]
[:int => (? :user/record)]
(lookup id))
These specs validate nothing meaningful and defeat the purpose of guardrails.
;; BAD - :any accepts everything, this is just ceremony
(>defn process [data]
[:any => :any]
...)
;; BAD - :map only confirms it's a map, catches no real bugs
(>defn process-user [user]
[:map => :string]
...)
;; GOOD - spec the keys you actually care about
;; Maps are open by default, so you only need to declare the slice
;; your function uses. Extra keys pass through fine.
(>defn process-user [user]
[[:map [:name :string] [:age :int]] => :string]
(str (:name user) " is " (:age user)))
If you don't know the shape yet, figure it out before writing the spec. A guardrails spec that validates nothing is worse than no spec — it creates a false sense of safety.
See gspec-syntax.md for complete syntax documentation.
testing
Use this OCP when executing or preparing to execute commands that change a live or important system, service reloads/restarts, package changes, deployments, migrations, firewall/network/access changes, credential rotation, NixOS switch/test/boot/deploy, or incident mitigation. It guides safe operations with a persisted ledger for scope, preflight, baseline, rollback, validation, and evidence.
development
Create new agent skills with proper structure, progressive disclosure, and bundled resources. Use when user wants to create, write, or build a new skill.
documentation
Naming conventions for workflow documents in prompts/. Use when creating plans, PRDs, research reports, idea capture or other workflow documents. Triggers on (1) creating new planning documents, (2) naming PRDs or research reports, (3) questions about document organization in prompts/.
testing
Grilling session that challenges your plan against the existing domain model, sharpens terminology, and updates documentation (CONTEXT.md, ADRs) inline as decisions crystallise. Use when user wants to stress-test a plan against their project's language and documented decisions.