CLI: lint
vally lint [path] [options]Description
Section titled “Description”vally lint is the home for fast static checks on the assets in your Vally project — no agent execution required. It validates eval specs (eval.yaml) for configuration errors and checks any SKILL.md files in the given path against the spec graders. All checks complete in seconds.
Arguments
Section titled “Arguments”| Argument | Required | Default | Description |
|---|---|---|---|
path | No | Current directory | Root directory to scan for SKILL.md files |
Options
Section titled “Options”| Flag | Type | Default | Description |
|---|---|---|---|
--eval-spec <path> | string | — | Path to an eval spec file to validate |
--known-domains <path> | string | — | Path to a known-domains file for URL reference scanning |
--allowed-external-deps <path> | string | — | Path to an allowlist file for structural dependency scanning |
--grader-plugin <specifier> | string | — | Grader plugin to load (npm package name or local path). Prevents unknown-grader-type errors for plugin graders. |
--strict | boolean | false | Treat warnings as errors (exit 1 on any diagnostic, including dependency warnings) |
--verbose | boolean | false | Show detailed grader evidence for each check |
Exit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
0 | All checks passed (warnings may be present unless --strict) |
1 | One or more skills failed, a reference error was found, an eval spec error was found, or an error occurred |
Eval spec checks
Section titled “Eval spec checks”When --eval-spec is provided, the following checks run against the eval YAML:
Errors (block execution)
Section titled “Errors (block execution)”| Code | What it catches |
|---|---|
unknown-grader-type | Grader type not in registry. Includes fuzzy “did you mean?” suggestions. |
invalid-grader-config | Unknown config keys, missing required fields, wrong types. |
invalid-scoring-weight-key | Scoring weights reference a grader type not used in any stimulus. |
invalid-constraint-value | Negative limits, overlapping expect/reject lists. |
environment-file-not-found | Environment files[].src path doesn’t exist on disk. |
duplicate-stimulus-name | Two stimuli share the same name. |
Warnings (surface ambiguity)
Section titled “Warnings (surface ambiguity)”| Code | What it surfaces |
|---|---|
duplicate-grader-type-in-stimulus | Same grader type used twice in one stimulus (shared scoring weight key). |
rubric-without-llm-judge | rubric defined but no LLM judge grader configured. |
regression-without-baseline | type: regression set but no baseline configuration. |
graders-without-execution | Graders defined but runs: 0 or no executor. |
scoring-defaults-applied | No scoring block defined (using default: equal weights, threshold 0). |
SKILL.md checks
Section titled “SKILL.md checks”When a path is provided, vally lint discovers all SKILL.md files under it and runs three built-in graders:
| Grader | What it checks |
|---|---|
| spec-compliance | Name format (kebab-case, ≤ 64 chars), description presence and length (≤ 1024 chars), valid frontmatter |
| valid-refs | Every file path referenced in the SKILL.md exists on disk |
| orphan-files | No files in the references/ directory are unreachable from the SKILL.md |
Reference checks
Section titled “Reference checks”When --known-domains is provided, all SKILL.md, *.agent.md, and references/*.md files within discovered skill directories are scanned for URL reference issues:
| Code | What it catches |
|---|---|
EXTERNAL-DOMAIN | URL domain not in the known-domains allowlist |
HTTP-NOT-HTTPS | Insecure http:// URL (localhost and schemas.microsoft.com are exempt) |
PIPE-TO-SHELL | curl or wget piped directly to a shell interpreter |
SCRIPT-NO-SRI | External <script> tag without integrity (SRI) attribute |
Known-domains file format
Section titled “Known-domains file format”One domain per line. Lines starting with # are comments, blank lines are ignored.
- Bare domains match the host and any subdomain:
microsoft.commatcheslearn.microsoft.com - Path-scoped entries require the URL prefix to match:
github.com/dotnet/runtimematchesgithub.com/dotnet/runtime/issuesbut notgithub.com/dotnet/sdk
# Core domainsmicrosoft.comgithub.com
# Path-scopedgithub.com/dotnet/runtimeExternal dependency checks
Section titled “External dependency checks”When --allowed-external-deps is provided, each discovered skill is checked for structural external dependencies. These findings are advisory warnings — they do not fail the lint unless --strict is used.
| Code | What it catches |
|---|---|
SCRIPT-FILE | Script file (.ps1, .sh, .py, .bat, .cmd, .bash) in the skill’s scripts/ directory |
INVOKES-SCRIPT | Skill description contains an INVOKES <script> pattern |
NON-BUILTIN-TOOL-REF | #tool:xxx reference to a non-built-in tool in the skill content |
Allowlist file format
Section titled “Allowlist file format”One entry per line. Lines starting with # are comments, blank lines are ignored. Keys are case-insensitive and use the format type:skill-name:detail:
# Allow the setup script in my-skillscript:my-skill:scripts/setup.ps1
# Allow the INVOKES pattern in nullable-ref skillinvokes:nullable-ref
# Allow a specific tool referencetool-ref:my-skill:#tool:web/fetchEach warning message includes the exact (allow: ...) key to add to the allowlist file.
Examples
Section titled “Examples”Validate an eval spec
Section titled “Validate an eval spec”# Validate eval spec onlyvally lint --eval-spec eval.yaml
# Validate eval spec AND lint SKILL.md filesvally lint ./skills --eval-spec eval.yamlLint SKILL.md files
Section titled “Lint SKILL.md files”# Lint current directoryvally lint
# Lint a specific skillvally lint ./skills/my-skill
# Lint with detailed outputvally lint ./skills --verboseStrict mode for CI
Section titled “Strict mode for CI”# Fail on any warnings toovally lint . --eval-spec eval.yaml --strictReference scanning
Section titled “Reference scanning”# Check URLs against a known-domains listvally lint ./skills --known-domains known-domains.txt
# Combine with eval validationvally lint ./skills --known-domains known-domains.txt --eval-spec eval.yamlExternal dependency scanning
Section titled “External dependency scanning”# Check for external dependenciesvally lint ./skills --allowed-external-deps allowed-external-deps.txt
# Fail on dependency warnings in CIvally lint ./skills --allowed-external-deps allowed-external-deps.txt --strictOutput format
Section titled “Output format”Eval spec output
Section titled “Eval spec output”On success:
✔ eval.yaml is validWith issues:
Eval: eval.yaml✘ error [unknown-grader-type] Unknown grader type "output-contain" at stimuli[0].graders[0].type Did you mean "output-contains"?
⚠ warning [scoring-defaults-applied] No scoring configuration; using equal weights, threshold 0 at scoring
1 error(s), 1 warning(s)SKILL.md output
Section titled “SKILL.md output”Found 2 skill(s): auth-helper, code-reviewer
✔ auth-helper ✔ spec-compliance (4/4 checks passed) ✔ valid-refs (3 references, 0 broken) ✔ orphan-files (0 orphaned files)
✘ code-reviewer ✘ spec-compliance (3/4 checks passed) ✗ name-format: Name must be kebab-case ✔ valid-refs ✔ orphan-files
1/2 skills passed