Passed 23 of 23 test cases with the skill, and 21 of 23 without it.
Without skill91%
With skill100%
Checks it passed that the model alone missed
The response advises against using Repo.get! on untrusted request input.
The system update function avoids using cast for setting internal calculated fields.
2 fixed21 passed either way0 still failing0 broke
Pass-rate lift
+9 pp
Tokens
+16%
Agent turns
0%
Response time
-33%
Model gemini-3.6-flashMeasured 8/19/2026v223 of 23 cases passed with skill
Tokens, turns and time describe resource use, not a dollar price.
See it in action
One of 2 test cases the skill fixed. Same model, same prompt, with and without the skill.
1 of 2
Prompt
I need to write an Ecto schema for an `Invoice` struct in my Elixir application. It needs fields for the invoice total amount, a status enum (`:pending`, `:paid`, `:cancelled`), and a relationship to a `User`. Could you provide the full schema module definition along with a changeset function for handling user input from a form, plus a separate function for internal system updates like calculated fields?
What was checked, without and with the skill
Checked
Without skill
With skill
The schema field for total amount does not use the float type.
Passed
Passed
The system update function avoids using cast for setting internal calculated fields.
Missed
Passed
case-01 · gemini-3.6-flash · 8/19/2026 · answers are capped and redacted
What's inside
The instructions your model reads when the skill loads.
SKILL.md79 lines6 files
Ecto Patterns Reference
Reference for working with Ecto schemas, queries, and migrations.
Iron Laws — Never Violate These
CHANGESETS ARE FOR EXTERNAL DATA — Use cast/4 for user/API input, change/2 or put_change/3 for internal trusted data
NEVER USE :float FOR MONEY — Always use :decimal or :integer (cents)
NO RAILS-STYLE POLYMORPHIC ASSOCIATIONS — They break foreign key constraints; use multiple nullable FKs or separate join tables
ALWAYS PIN VALUES IN QUERIES — u.name == ^user_input is safe, string interpolation causes SQL injection
PRELOAD COLLECTIONS, NOT INDIVIDUALS — Preloading in loops = N+1 queries
CONSTRAINTS BEAT VALIDATIONS FOR RACE CONDITIONS — Validations provide quick feedback, constraints provide DB-level safety
SEPARATE QUERIES FOR has_many, JOIN FOR belongs_to — Avoids row multiplication
NO IMPLICIT CROSS JOINS — from(a in A, b in B) without on: creates Cartesian product
DEDUP BEFORE cast_assoc WITH SHARED DATA — When multiple parents share child data, deduplicate child records BEFORE building changesets. Dedup only works within a single changeset
Quick Schema Template
defmodule MyApp.Context.Entity do
use Ecto.Schema
import Ecto.Changeset
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "entities" do
field :name, :string
field :status, Ecto.Enum, values: [:draft, :active, :archived]
field :amount_cents, :integer # Never :float for money!
belongs_to :user, MyApp.Accounts.User
timestamps(type: :utc_datetime_usec)
end
def changeset(entity, attrs) do
entity
|> cast(attrs, [:name, :status, :amount_cents])
|> validate_required([:name])
|> foreign_key_constraint(:user_id)
end