
verify
The one definition of what each gate runs. Use to run a gate stage, to add or change a check, or to read why a step exists.
- Installs
- 536
- Last 24h
- +22
- Trending rank
- #5452
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/timschoch/skilly --skill verify- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads verify automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Verify
references/verify.json holds the default steps. Sync keeps them current in every Consumer. .skilly/verify.json holds only what the repo changes. Hooks and CI call a stage of the merged config, so the local gate and the pipeline cannot drift into disagreeing about what green means.
Usage
node .agents/skills/verify/scripts/verify.mjs <stage> # run the stage
node .agents/skills/verify/scripts/verify.mjs <stage> --steps # resolved steps as JSON, runs nothing
node .agents/skills/verify/scripts/verify.mjs --config # merged config as JSON, runs nothing
Works from anywhere in the Consumer. Exit 0 passed, 2 config or usage error, anything else is the failing step's code.
Config
Shape of both files:
{
"budgetTicket": "https://github.com/owner/repo/issues/1",
"stages": {
"commit": { "budgetSeconds": 10, "steps": [{ "name": "lint-staged", "run": "npx lint-staged", "why": "the reason this step exists" }] },
"push": { "extends": "commit", "budgetSeconds": 120, "steps": [] },
"ci": { "extends": "push", "budgetSeconds": 600, "steps": [] },
"nightly": { "tier": "product", "budgetSeconds": 1800, "steps": [{ "name": "e2e", "run": "npm run e2e", "target": "e2e" }] }
}
}
extends is cumulative: push runs every commit step first. A stage skips an inherited step only where the config names it:
| Field | On | Effect |
|---|---|---|
"replaces": "unit (changed)" | a step | drops the named step when this step runs. unit holds the changed tests, so each test runs one time |
"without": ["unit", "e2e smoke"] | a stage | drops the named inherited steps |
Stages
| Stage | Runs | Called by |
|---|---|---|
commit | nothing by default | pre-commit calls lint-staged directly |
push | branch name, naming, typecheck, unit (changed) | the pre-push hook |
ci | push, lint, full unit, build, audit, e2e smoke | CI on a PR; on the release PR where a PR runs pr |
pr | ci without full unit and e2e smoke | CI on a PR of a product repo with a release PR and a nightly |
nightly | full unit, e2e full, deps drift, security scan | the nightly workflow, product tier |
pr needs its net: each merge to main meets the full suites on the release PR and in the nightly. The ci.yml template of setup-repo picks pr only where both exist.
Changed tests
unit (changed) runs scripts/run-changed-tests.mjs: the test command with --changed <base>, or the full suite when the diff holds a fullSuiteTriggers path. Vitest follows imports only, and no test imports a lockfile or a migration.
{ "fullSuiteTriggers": ["drizzle/"] }
| Trigger | Matches |
|---|---|
drizzle/ | each file in that folder, from the git root |
package.json | that file name at any depth |
vitest.config.* | * is any characters inside one path segment |
src/schema.sql | that path |
The list in .skilly/verify.json appends to the defaults; "-package.json" drops one.
A budget warns and never fails. A gate that fails on slowness teaches you to bypass the gate, and the bypass outlives the slowness. budgetTicket says where a stage that outgrew its budget gets split.
Override
.skilly/verify.json merges over the defaults (scripts/merge-config.mjs). Steps match by name, per stage:
| Repo file | Effect |
|---|---|
{ "name": "lint", "run": "pnpm lint" } | changes the default lint step, keeps its other fields |
"-lint" | drops the default lint step |
{ "name": "docs", "run": "…" } | adds a step after the defaults |
"budgetSeconds": 60 on a stage | replaces the default |
An override of unit must run the full suite each time, because unit replaces unit (changed). An override that runs the suite only on a condition must set "replaces": null.
The file is optional. Check the result with --config or <stage> --steps.
Tier
tier in .skilly/config.json, default sandbox, order sandbox < tool < product. A step's tier is the minimum a repo needs to run it; below that the step is skipped. A stage's tier is that rule for the whole stage: below it nothing runs and the exit is 0. Tier sets the size of the net, not the standard.
Target
A step's target is a path relative to the repo root; missing, the step is skipped. That is how one stage list fits repos that do not all have an e2e/ or a Dockerfile.
Audit
The audit step (scripts/audit.mjs) fails on every high or critical advisory. It runs yarn audit (yarn 1) when yarn.lock exists, else npm audit. An advisory with no patched version goes on the step's accept list in .skilly/verify.json:
{ "stages": { "ci": { "steps": [{ "name": "audit", "accept": [{ "id": "GHSA-vfj7-8cjw-p6xm", "why": "braces, no fix, dev only" }] }] } } }
An entry needs an id and a why; without both it accepts nothing. It fails the step once GitHub lists a patched version for the range the audit matched, or once the audit no longer finds the advisory. Remove it then. The step never edits the file, so the local gate and CI give the same answer.
Hook scripts
The gates and guards ship here, so each Sync PR updates them. /setup-repo (setup-project bundle) wires them; never copy one into the repo.
| Script | Run by | Blocks |
|---|---|---|
| check-commit-msg.mjs | commit-msg | a commit header that is not Conventional Commits |
| check-push-branch.mjs | pre-push | a direct push to the trunk |
| check-branch-name.mjs | the branch name step | a branch not named <type>/<description> |
| block-destructive-git.sh | Claude Code PreToolUse | reset --hard, clean -f, branch -D, bare push --force |
| block-invalid-branch-push.sh | Claude Code PreToolUse | an agent push from a bad branch name, even without installed git hooks |
| block-unverified-push.sh | Claude Code PreToolUse | an agent push that skips the push stage |
Adding a check
One step, never a line in a hook or a workflow. A check for this repo only goes in .skilly/verify.json. A check every Consumer needs goes in the hub's bundles/workflow/skills/verify/references/verify.json. Give it a why: it prints the moment the step goes red, when the reader is least likely to go looking for it.
FAQ
What does the verify skill do?
The one definition of what each gate runs. Use to run a gate stage, to add or change a check, or to read why a step exists.
How do I install verify?
Run npx skills add https://github.com/timschoch/skilly --skill verify in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/verify/ (personal) or .claude/skills/verify/ (project).
Which AI agents can use verify?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is verify safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains verify?
It is published by timschoch in timschoch/skilly. It has 536 recorded installs.
More from timschoch/skilly
git-shortcuts
timschoch/skilly
Translates shorthand git/GitHub workflow commands into the correct sequence of actions. ALWAYS trigger when the user's message contains a "--" prefixed shorthand like: "--c", "--p", "--cp", "--pr", "--prm", "--cppr", "--cpprm", "--ff", "--release", "--pub", "--close" — with or without a trailing "?". The "--" prefix is required — do NOT trigger on bare letters like "c" or "pr" appearing in normal sentences. NEVER invoke this skill autonomously — it MUST always be user-invoked via an explicit "--" shorthand in their message.
cleanup-merged-branches
timschoch/skilly
Delete remote branches whose PR was merged. Read-only dry-run, then confirm, then delete.
step-by-step
timschoch/skilly
Walk the user through a manual procedure step by step, with every value spelled out and every link clickable.
plan-critics
timschoch/skilly
Critiques an implementation plan — or a wayfinder map/ticket — from multiple angles (security, simplicity, edge cases, scope creep, codebase conflicts, tech-specific best practices) via parallel critic subagents. Trigger: user says "kritisiere den plan", "plan check", "plan-kritik", "blinde flecken", "/plan-critics" — also invoke when a planning agent wants to validate its own plan before presenting it, or a wayfinder session wants a resolution checked before closing a ticket. Must be called at top-level (not inside a subagent) — it uses the Task tool.
qa
timschoch/skilly
Interactive QA session where user reports bugs or issues conversationally, and the agent files GitHub issues. Explores the codebase in the background for context and domain language. Use when user wants to report bugs, do QA, file issues conversationally, or mentions "QA session".
1-3-1
timschoch/skilly
Frame a problem or decision as 1-3-1: one problem, three distinct solutions, one recommendation. Use when the user brings a non-trivial decision or fork and wants options weighed before a pick ("what should I do about X", "help me decide", "weigh the tradeoffs"), or names "1-3-1" or "do a 131". Skip questions with one right answer, just answer those.
Popular other skills
hyperframes-cli
heygen-com/hyperframes
The HyperFrames CLI by job - scaffold, check, look at frames, edit the timeline, preview, render locally or in the cloud, publish, project history - plus reading its JSON and recovering from build or render failures.
triage
mattpocock/skills
Move issues and external PRs through a state machine of triage roles, categorise, verify, grill if needed, and write agent-ready briefs.
ask-matt
mattpocock/skills
Ask which skill or flow fits your situation. A router over the skills in this repo.
to-questionnaire
mattpocock/skills
Turn a decision you can't fully answer into a questionnaire for someone else to fill in.
loop-me
mattpocock/skills
Grill me about specs for the workflows I want to build, within this workspace.