purview-buildsdk-skill-tests
Author agent skills in a repository that uses Purview.BuildSdk, and validate them with Purview.Skills.Testing or the SDK's pack-time ValidatePurviewSkills target. Use when adding or renaming a skill,
SKILL.mdskills/purview-buildsdk-skill-tests/SKILL.md
GitHubAuthoring and validating agent skills
For installing skills a package ships, use purview-buildsdk-skill-installation.
Where skills live
At the repository root, in skills/<name>/SKILL.md. Always.
The skills CLI only discovers skills at a root skills/ folder, and it reaches a repository by
The skills CLI only discovers skills at a root skills/ folder, and it reaches a repository by
cloning it, so nothing else is visible to it. Nothing is packed into a NuGet package — a package
carries .NET artifacts, and skills are delivered by the CLI from git.
skills/
my-skill/
SKILL.md required
references/ loaded on demand
scripts/ executable, run on demand
assets/ templates and static resources
Link to a skill by its authored path, ./skills/<name>/SKILL.md. A link into .agents/skills/
points at a gitignored file that does not exist in a fresh clone.
SKILL.md format
---
name: my-skill
description: What it does, and when to use it. Include the words a task would contain.
license: MIT
metadata:
package: My.Package
---
# My skill
Instructions.
| Field | Required | Constraint |
|---|---|---|
name |
yes | 1–64 chars, lowercase a-z0-9 and single hyphens, no leading, trailing or consecutive hyphen, must equal the folder name |
description |
yes | 1–1024 chars, non-empty |
license |
no | A licence name, or the name of a bundled licence file |
compatibility |
no | ≤500 chars, only when the skill has real environment requirements |
metadata |
no | A map of string to string. Anything not defined above belongs here |
allowed-tools |
no | Space-separated pre-approved tools. Experimental |
There are no other top-level fields. category, roles and tags are common inventions and a
strict client rejects them; put them under metadata.
The full specification is at https://agentskills.io/specification. references/authoring.md covers description writing, naming for a shared namespace, and progressive disclosure.
Progressive disclosure
An agent loads a skill in three stages: the name and description at startup, the whole
SKILL.md body once the skill activates, and references/, scripts/ or assets/ only when the
task reaches them.
So: keep SKILL.md under 500 lines, and move detail into references/. The body is a cost paid
on every activation; a reference file is paid only when it is needed.
Keep file references one level deep from SKILL.md, and relative to the skill root. A path that
climbs out of the skill folder is broken everywhere except the authoring repository, because only
the skill's own folder is installed.
Validating
In tests — Purview.Skills.Testing
[InheritsTests]
public sealed class SkillTests : PurviewSkillTests;
[InheritsTests] is load-bearing. TUnit does not walk base types during discovery, so without
it the class compiles, the run is green and nothing is validated. TUnit reports TUnit0030; treat
it as an error.
| Rule id | What it checks |
|---|---|
skills-discovery |
The folder, when present, holds at least one skill |
skill-structure |
Every folder has a SKILL.md whose frontmatter parses |
skill-name |
Spec-legal, unique, and equal to the folder name |
skill-description |
Present, non-empty, within 1024 characters |
skill-optional-fields |
Only spec-defined fields, each within its limit |
skill-bundled-resources |
Every linked file exists, inside the skill folder |
skill-body-size |
SKILL.md stays under the recommended 500 lines |
A repository with no skills/ folder passes every rule — authoring skills is optional. An
empty folder fails skills-discovery, because every other rule is vacuous against an empty
catalogue.
Overrides: RepositoryRoot (default: the SDK's repository-root marker walk),
SkillsFolderName (default skills), and SkipRule(string).
The evaluator takes a SkillCatalogue, so a rule can be exercised against a fixture folder rather
than a real repository — the same three-layer shape this repository uses throughout: a reader, an
evaluator over an in-memory model, and a thin test base class.
At pack time — ValidatePurviewSkills
It runs BeforeTargets="Pack", so a malformed skill fails in the repository that owns it rather
than reaching the CLI, which would silently skip it.
dotnet msbuild <project> -t:ValidatePurviewSkills
Failures are reported as PRSKL0005, one per problem. Every authored skill is checked.
The two checks overlap deliberately: the pack-time one runs without a test host, the test one covers more of the specification.
What is deliberately not checked
Prose quality, and whether an agent actually obeys the skill. A build can only check that a skill is well formed. Treat a green run as "installable", not "good".