Gate Your CI
Turn SkillEvaluator into a merge gate for your skill repository. Tier 1 needs no model API key; full scanner-backed checks can still contact vulnerability services. Adopt the CLI in any CI system and add model-backed checks separately.
For the prebuilt runtime and one-file consumer setup, see GitHub Actions. The recipe below installs tools explicitly; its PR-comment step is separate from the reusable publisher’s hosted-feedback setup.
Exit codes
skillevaluator validate communicates pass/fail through its exit code, so a plain run: step is already a gate — no output parsing required.
Tier 1 checks always gate the exit code. Tier 2 deduplication findings gate when dedup runs unless you pass --no-block-on-dedup; the recommended keyless gate below selects --tiers 1 to exclude Tier 2 and Tier 3. Tier 3 live-evaluation results are advisory inside validate unless you pass --block-on-agent-eval. Reports record the effective choice for each tier. Without an explicit scope, validate runs all three tiers for skills, including Tier 3 autopilot.
The recommended gate
Each flag earns its place:
--externalpins the public-publication profile explicitly instead of relying on the environment, so the gate behaves identically on every runner. The active profile name is stamped into the HTML report andBENCHMARK.md(and printed in the run banner with--verbose), so a run always records which gate was applied.--tiers 1runs static checks without the provider-backed Tier 2 and Tier 3 stages. Use--tiers 1,2once you add a provider secret, or omit the option to include Tier 3 after configuring its runtime.--no-dedupalone skips only Tier 2 and still runs Tier 3.-r json,markdown,sarifwrites machine-readable JSON, a Markdown PR comment, and a SARIF file for GitHub Code Scanning.-o reportscollects everything in one directory for artifact upload.--min-score 70is the default quality bar, written out explicitly so raising it later is a visible one-line diff.
GitHub Actions recipe
A complete workflow: install with uv, add the external Semgrep, SkillSpector, and Gitleaks scanners for a complete security result, validate, upload the reports, and post the Markdown report on the pull request.
The security extra installs Bandit and pip-audit. Semgrep and SkillSpector
stay in separate uv tool environments, while Gitleaks is installed from its
official releases. Report
filenames embed a sortable timestamp (skillevaluator-output-<timestamp>.md),
which is why a lexicographic sort finds the newest one. The if: always()
conditions keep reports flowing even when validation fails — which is exactly
when you want them.
The same shape ports to any CI system: install, run validate, gate on the exit code, archive reports/.
Validating collections
Point validate at a folder of skills and it validates each one:
Two flags control how a multi-skill run behaves:
-c overrides --fail-fast if both are passed. For a merge gate, prefer -c: contributors get the complete picture in one run instead of a fix-push-repeat loop.
Adopt progressively
You do not have to turn on the strictest gate on day one. A path that works well:
Start advisory
Run the gate but never fail the build. Contributors see reports and get used to the findings before anything blocks a merge.
Gate on Tier 1
Remove the || true. Exit code 1 now blocks merges on schema, security, PII, license, code-integrity, Unicode, and quality failures — all still keyless. (The lint check also runs, but its findings are advisory warnings and never fail validation.)
Raise the quality bar
Bump --min-score above the default 70 once your collection consistently clears it. The score and grade in each report tell you where the collection stands before you move the line.
Add LLM-backed checks
Add a provider key as a masked CI secret, set SKILL_EVAL_LLM_PROVIDER, then add --llm (and --llm-verify to suppress false positives) and select --tiers 1,2 so Tier 2 overlap checks run too. Once dedup runs, its findings gate alongside Tier 1 by default; add --no-block-on-dedup if you want evidence without enforcing it yet. See Providers & Credentials for provider setup.
Add an advisory Tier 3 job
Run live agent evaluation as a separate job with skillevaluator tier3 ./my-skill, or remove --tiers 1,2 from validate to run all three tiers. Both workflows reuse existing evaluation sources and generate one starter case when none exists. Attached Tier 3 is advisory by default; add --block-on-agent-eval when the team is ready for its findings or invalid source evidence to fail the merge gate. Standalone Tier 3 exits non-zero when the run itself fails to complete. Expose agent credentials as CI secrets in the job environment — the env: block of the workflow step — because SkillEvaluator reads operator credentials from the host environment only. With the nv_build provider and --env-mode docker, a single NVIDIA_API_KEY secret covers the evaluator and all three agents. See Tier 3: Live Evaluation.
Keep provider and agent keys as masked CI secrets in the job environment — never in the repo or in evals/config.yml. SkillEvaluator enforces this: a harbor.runtime_env entry that names or ${VAR}-references an operator-owned credential (such as OPENAI_API_KEY or NVIDIA_API_KEY) fails the Tier 3 run with a hard error.
Custom policy in CI
If the default external profile is too loose or too strict for your repository, commit a policy overlay next to your skills and pin it in the gate. Severity decisions then get reviewed like code:
The policy overlays the external profile, and the resulting profile name is stamped into the HTML report and BENCHMARK.md (and printed in the run banner with --verbose) — so a run always tells you which gate produced it. Full overlay syntax is on the Tier 1: Validation page.
Parse the JSON
When the exit code is not enough — dashboards, custom thresholds, badge generation — read reports/skillevaluator-output-<timestamp>.json. The fields CI cares about sit at the top level:
overall_status and overall_passed describe the configured command gate. They
can be green when an advisory tier did not run, so do not use them as a
publication signal. Require publication_status == "pass" (or
publication.eligible == true) before publishing a benchmark.
A step that enforces a stricter score than the built-in gate:
jq -e exits non-zero when the expression is false, so the step fails the job on its own. For Tier 3 payloads and the full results-on-disk layout, see Reports & Results.
Troubleshooting
The run exits 2 instead of 1
Exit code 2 is a configuration error — a bad flag or an unreadable target path. Fix the pipeline; the skill was never judged. (Passing --llm without a configured provider does not exit 2: the LLM-backed scanner is marked incomplete and the run fails with 1.)
overall_status is 'incomplete'
A required scanner is missing or returned no evidence. Check the report for
the named scanner: Semgrep, SkillSpector, and Gitleaks are all separate
executables, and the security extra alone does not install them. The
scanners fail closed: validate exits non-zero and the report stays
non-green until every required scanner is installed and returns valid
evidence. See the workflow above or
Installation: System tools.
The report artifact is empty
Make sure the artifact path matches your -o directory and that the upload step carries if: always() — otherwise a failed gate skips the upload, and you lose the report exactly when you need it.