Writing a dataset
A dataset is the pinned cases in evals/cases.yaml, the inputs under evals/fixtures/, and the expected files under evals/goldens/. The examples from skillgate examples install are the same shape. Read one folder next to this page, or open Examples.
File layout
The folder name, the name in SKILL.md, and skill in evals/cases.yaml are the same string.
json-response/
SKILL.md
scripts/agent_entry.py
evals/
cases.yaml
fixtures/
orders.json
empty-orders.json
goldens/
flatten-orders.json
edge-empty.json
history/Copy this pack
Copy these four files into skills/json-response/. This is the empty-input case from that example. The pack on disk adds two more cases. Then run skillgate ingest skills/json-response.
SKILL.md
---
name: json-response
description: Reshape a JSON API response. Flatten nested fields to id, status, and total, and drop empty values. Use when the user has a JSON response.
---
# JSON response
Flatten each object under `data` to `id`, `status`, and `total`. An empty `data` array becomes `[]`.evals/fixtures/empty-orders.json
{
"data": []
}evals/goldens/edge-empty.json
[]evals/cases.yaml
schema: 1
skill: json-response
cases:
- id: edge-empty
status: pinned
prompt: Flatten the JSON API response in empty-orders.json. Save output/orders.json.
should_trigger: true
input:
files:
- src: evals/fixtures/empty-orders.json
dest: empty-orders.json
golden:
output_path: output/orders.json
path: evals/goldens/edge-empty.json
kind: json
contains:
- "[]"status: pinned is what runs. dest is the name the agent sees.golden.output_path is the file the agent must write. golden.path is the expected file in the pack. kind is text, json, or bytes. contains lists substrings that must appear. should_trigger: false is an unrelated prompt: leave input.files empty and set golden: null.
What each example tests
json-response: flatten two orders; an empty list becomes[]; a pytest prompt should not trigger.readme-writer: a README frombrief.txt; a missing license rendersnot specified.log-summarizer: two timeouts and one warning; a quiet log isErrors: 0.sql-writer: id and total for open orders; asking forcustomer_emailwhen the schema does not have that column.receipt-extractor: merchant, date, and total18.40from a fictional receipt; a receipt with no total staysnull.
json-response-sabotaged copies the JSON cases. Its instructions ignore JSON and write a snack list, so a live check fails the trigger cases. The unrelated case can still pass.
How to write a case
Start with 3 to 6 pinned cases. Each example ships three: one main behavior, one edge, and one unrelated prompt.
- One behavior per case.
flatten-orderschecks the flat list.edge-emptychecks[]. - Realistic inputs. Keep the file small enough to finish from.
harbor-receipt.txtis a fictional shop receipt. - Clear expected outcomes. Put the full file in
evals/goldens/and the required lines incontains. - An edge case. Empty, missing, or zero.
log-summarizeruses a log with no errors. - One case that fails when the skill is wrong. Set
should_trigger: falseon a prompt from a different job. To see a whole pack fail, checkjson-response-sabotaged.skillgate check skills/json-response-sabotaged --expect-failexits 0 only when that run is red. - No answer leakage. The receipt prompt says to extract the total. It does not contain
18.40. The README edge prompt says not to invent a license. It does not containnot specified. - Small files, no personal data. Each example file is under 4 KB. Use fictional names. The receipt merchant is Harbor Paper Co.
Check it locally
skillgate ingest skills/json-response
skillgate case list skills/json-response
skillgate check skills/json-response
skillgate check skills/json-response --case flatten-orders
skillgate check skills/json-response-sabotaged
skillgate check skills/json-response-sabotaged --expect-failskillgate ingest prints OK json-response when SKILL.md loads. skillgate case list prints each id, pinned, and the prompt. skillgate check exits 0 when the live run is green, 1 when it is red, and 2 when no agent is available, you are not signed in, or no decision model is selected. Sign in with skillgate login, then pick a decision model. Without those, the check exits 2. That is not a pass.
skillgate ui- Click Skills. The page title is Skill Repository.
- Click Examples, then Install.
- Open
json-response. Click Evaluate this skill. - Click Run. The label is
Run 3 caseswhen three checks are loaded. Until you sign in or add a key, the line above the button isNext: sign in or add a key in Settings, then press Run. - For the red path, open
json-response-sabotagedand press Run. The JSON checks fail. The unrelated check can pass.
Common mistakes
- The name does not match the folder. Use one slug for the folder,
nameinSKILL.md, andskillincases.yaml. skillgate case listshows the case andskillgate checkskips it. Setstatus: pinned.- The fixture is missing.
srcis relative to the skill folder, for exampleevals/fixtures/orders.json. - A
.mdbrief never shows up as an input. Case inputs use a data suffix.readme-writerstores the brief asbrief.txt. Expected READMEs stay underevals/goldens/. - The golden is not found.
golden.pathpoints atevals/goldens/<file>.output_pathis where the agent writes, usuallyoutput/<file>. - The prompt already contains the answer. Move that sentence into the golden and
contains. Inreceipt-extractorcaseextract-total,18.40is in the fixture and the golden, not in the prompt. - Every case is the happy path. Add the edge and the
should_trigger: falsecase. - The pack is huge, or it contains a real email or phone number. Shrink the fixture and use a fictional value, the way
harbor-receipt.txtdoes. skillgate examples installprintsLeft N existing file(s) in place.and your edit is still there. That command never replaces a file that already exists. Delete the file you want replaced, or install into an empty folder with--dest.