Skip to content

Commit 0138a78

Browse files
feat(skills): edit SKILL frontmatter schema, add CI validation, and documentation (#625)
## Description Added foundational skill infrastructure to support semantic invocation and optional frontmatter properties. This is a prerequisite for migrating existing scripts to the Agent Skills pattern. Changes span the frontmatter schema, a new CI validation script with Pester tests, prompt-builder guidance for semantic skill invocation, documentation updates, and PR validation pipeline integration. > Note: Some additional changes were done to `prompt-builder.instructions.md` based on optimization recommended by the `/analyse-prompt` command to improve clarity and structure of the semantic invocation documentation. - feat(skills): Added `user-invokable`, `disable-model-invocation`, and `argument-hint` optional properties to `skill-frontmatter.schema.json` with `maxLength` constraints on `name` (64), `description` (1024), and `argument-hint` (256) - feat(skills): Created `Validate-SkillStructure.ps1` (464 lines) with SKILL.md presence checks, frontmatter field validation, name-directory consistency, unrecognized subdirectory warnings, changed-files-only mode via Git merge-base, CI annotations, and JSON results export - feat(skills): Created `Validate-SkillStructure.Tests.ps1` (876 lines) with full Pester coverage across `Get-SkillFrontmatter`, `Test-SkillDirectory`, `Get-ChangedSkillDirectories`, and `Write-SkillValidationResults` including edge cases for git failures, path normalization, and CI annotation emission - feat(skills): Added "Skill Invocation from Callers" subsection to `prompt-builder.instructions.md` documenting semantic description matching as the primary invocation pattern with before/after examples, progressive disclosure levels, and updated optional field documentation - docs(skills): Updated `docs/contributing/skills.md` with Optional Fields section, Invocation Control Matrix table, frontmatter example with optional fields, Semantic Skill Loading section with progressive disclosure levels, caller invocation patterns, and external references to agentskills.io and VS Code docs - ci(skills): Created `skill-validation.yml` reusable workflow with `soft-fail` and `changed-files-only` inputs, pinned action SHAs, and artifact upload for `skill-validation-results` - ci(skills): Integrated `skill-validation` job into `pr-validation.yml` with `changed-files-only: true` - chore: Added `validate:skills` npm script to `package.json` and appended it to `lint:all`; updated `CONTRIBUTING.md`, `scripts/README.md`, `scripts/linting/README.md`, `docs/architecture/workflows.md`, `docs/contributing/ai-artifacts-common.md`, `.github/workflows/README.md`, and `.github/PULL_REQUEST_TEMPLATE.md` to document the new validation step - chore: Added `agentskills` and `invokable` to `.cspell.json` dictionary ## Related Issue(s) Closes #623 ## Type of Change Select all that apply: **Code & Documentation:** - [ ] Bug fix (non-breaking change fixing an issue) - [x] New feature (non-breaking change adding functionality) - [ ] Breaking change (fix or feature causing existing functionality to change) - [x] Documentation update **Infrastructure & Configuration:** - [x] GitHub Actions workflow - [ ] Linting configuration (markdown, PowerShell, etc.) - [ ] Security configuration - [ ] DevContainer configuration - [ ] Dependency update **AI Artifacts:** - [x] Reviewed contribution with `prompt-builder` agent and addressed all feedback - [x] Copilot instructions (`.github/instructions/*.instructions.md`) - [ ] Copilot prompt (`.github/prompts/*.prompt.md`) - [ ] Copilot agent (`.github/agents/*.agent.md`) - [ ] Copilot skill (`.github/skills/*/SKILL.md`) > **Note for AI Artifact Contributors**: > > - **Agents**: Research, indexing/referencing other project (using standard VS Code GitHub Copilot/MCP tools), planning, and general implementation agents likely already exist. Review `.github/agents/` before creating new ones. > - **Skills**: Must include both bash and PowerShell scripts. See [Skills](../docs/contributing/skills.md). > - **Model Versions**: Only contributions targeting the **latest Anthropic and OpenAI models** will be accepted. Older model versions (e.g., GPT-3.5, Claude 3) will be rejected. > - See [Agents Not Accepted](../docs/contributing/custom-agents.md#agents-not-accepted) and [Model Version Requirements](../docs/contributing/ai-artifacts-common.md#model-version-requirements). **Other:** - [x] Script/automation (`.ps1`, `.sh`, `.py`) - [ ] Other (please describe): ## Sample Prompts (for AI Artifact Contributions) <!-- Not applicable — this PR updates prompt-builder instructions rather than creating a new standalone AI artifact --> ## Testing - Ran `/analyze-prompt` - Ran `Validate-SkillStructure.Tests.ps1` with Pester to verify all tests pass, including edge cases for git failures, path normalization, and CI annotation emission. - Ran `npm run validate:skills` to ensure the validation script executes without errors in a real-world scenario (based on currently one existing skill). ## Checklist ### Required Checks - [x] Documentation is updated (if applicable) - [x] Files follow existing naming conventions - [ ] Changes are backwards compatible (if applicable) - [x] Tests added for new functionality (if applicable) ### AI Artifact Contributions <!-- If contributing an agent, prompt, instruction, or skill, complete these checks --> - [x] Used `/prompt-analyze` to review contribution - [x] Addressed all feedback from `prompt-builder` review - [x] Verified contribution follows common standards and type-specific requirements ### Required Automated Checks The following validation commands must pass before merging: - [x] Markdown linting: `npm run lint:md` - [x] Spell checking: `npm run spell-check` - [x] Frontmatter validation: `npm run lint:frontmatter` - [x] Skill structure validation: `npm run validate:skills` - [x] Link validation: `npm run lint:md-links` - [x] PowerShell analysis: `npm run lint:ps` ## Security Considerations - [x] This PR does not contain any sensitive or NDA information - [ ] Any new dependencies have been reviewed for security issues - [ ] Security-related scripts follow the principle of least privilege ## Additional Notes All four deliverables from issue #623 are addressed in this PR: 1. **Skill Frontmatter Schema Updates** — Added three optional properties with type constraints and length limits 2. **Prompt-Builder Instructions Updates** — Added semantic invocation guidance with before/after examples and progressive disclosure documentation 3. **CI Validation for Skill Structure** — Created `Validate-SkillStructure.ps1` with comprehensive Pester test coverage in `Validate-SkillStructure.Tests.ps1` 4. **Documentation Updates** — Updated `docs/contributing/skills.md` with optional fields, invocation control matrix, semantic skill loading, and external specification references 🛠️ - Generated by Copilot --------- Co-authored-by: Bill Berry <WilliamBerryiii@users.noreply.github.com> Co-authored-by: Bill Berry <wberry@microsoft.com>
1 parent de8d86c commit 0138a78

16 files changed

Lines changed: 2065 additions & 31 deletions

.cspell.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,15 @@
5959
"general-technical"
6060
],
6161
"words": [
62+
"agentskills",
6263
"autobuild",
6364
"behaviour",
6465
"Browsable",
6566
"Chronograf",
6667
"edgeai",
6768
"GHCP",
6869
"GHSA",
70+
"invokable",
6971
"Kapacitor",
7072
"kata",
7173
"katas",

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ The following validation commands must pass before merging:
9595
- [ ] Markdown linting: `npm run lint:md`
9696
- [ ] Spell checking: `npm run spell-check`
9797
- [ ] Frontmatter validation: `npm run lint:frontmatter`
98+
- [ ] Skill structure validation: `npm run validate:skills`
9899
- [ ] Link validation: `npm run lint:md-links`
99100
- [ ] PowerShell analysis: `npm run lint:ps`
100101

.github/instructions/prompt-builder.instructions.md

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,10 @@ Purpose: Self-contained packages that bundle documentation with executable scrip
248248

249249
Characteristics:
250250

251-
* Bundled with bash and PowerShell scripts in the same directory.
251+
* Optionally bundled with bash and PowerShell scripts in a `scripts/` subdirectory.
252252
* Provides step-by-step instructions for task execution.
253253
* Includes prerequisites, parameters, and troubleshooting sections.
254+
* Skills without scripts are valid documentation-driven knowledge packages.
254255

255256
Skill directory structure:
256257

@@ -268,6 +269,32 @@ Skill directory structure:
268269
└── README.md # Usage examples (recommended)
269270
```
270271

272+
#### Optional Directories
273+
274+
##### scripts/
275+
276+
Contains executable code that agents run to perform tasks:
277+
278+
* Scripts are self-contained or clearly document dependencies.
279+
* Include helpful error messages and handle edge cases gracefully.
280+
* Provide parallel implementations for bash and PowerShell when targeting cross-platform use.
281+
282+
##### references/
283+
284+
Contains additional documentation that agents read when needed:
285+
286+
* *REFERENCE.md* for detailed technical reference material.
287+
* Domain-specific files such as `finance.md` or `legal.md`.
288+
* Keep individual reference files focused; agents load these on demand.
289+
290+
##### assets/
291+
292+
Contains static resources:
293+
294+
* Templates for documents or configuration files.
295+
* Images such as diagrams or examples.
296+
* Data files such as lookup tables or schemas.
297+
271298
### Skill Content Structure
272299

273300
Skill files include these sections in order:
@@ -281,7 +308,7 @@ Skill files include these sections in order:
281308
7. Troubleshooting: Common issues and solutions.
282309
8. Attribution: Attribution in `description:` frontmatter and standard footer.
283310

284-
### Progressive Disclosure
311+
#### Progressive Disclosure
285312

286313
Structure skills for efficient context usage:
287314

@@ -291,7 +318,7 @@ Structure skills for efficient context usage:
291318

292319
Keep the main *SKILL.md* focused. Move detailed reference material to separate files.
293320

294-
### File References
321+
#### File References
295322

296323
When referencing other files in the skill, use relative paths from the skill root:
297324

@@ -304,10 +331,35 @@ scripts/extract.py
304331

305332
Keep file references one level deep from *SKILL.md*. Avoid deeply nested reference chains.
306333

334+
#### Skill Invocation from Callers
335+
336+
When prompts, agents, or instructions need a skill's capability, describe the task intent rather than referencing script paths directly. Copilot matches the task description against each skill's `description` frontmatter and loads the skill on-demand via progressive disclosure.
337+
338+
Avoid hardcoded script paths, platform detection logic, or extension fallback code in caller files. Skills handle these concerns internally through their SKILL.md instructions and scripts.
339+
340+
For explicit invocation, reference the slash command `/skill-name` in usage documentation.
341+
342+
Semantic invocation pattern:
343+
344+
```markdown
345+
<!-- Direct script reference (avoid) -->
346+
Run `./scripts/dev-tools/pr-ref-gen.sh --base-branch origin/main` to generate the PR reference.
347+
348+
<!-- Semantic skill invocation (preferred) -->
349+
Generate the PR reference XML file comparing the current branch against origin/main.
350+
```
351+
352+
When a caller describes a task that semantically matches a skill's `description`, Copilot follows this loading sequence:
353+
354+
1. Level 1 (Discovery): Matches the task description against skill frontmatter `name` and `description` fields (~100 tokens per skill).
355+
2. Level 2 (Instructions): Loads the full SKILL.md body into context with script usage instructions (<5000 tokens recommended).
356+
3. Level 3 (Resources): Accesses scripts, examples, and references in the skill directory on-demand during execution.
357+
307358
Validation guidelines:
308359

309360
* Frontmatter follows the Frontmatter Requirements section, including `name` and `description` fields.
310361
* Provide parallel script implementations for bash and PowerShell when targeting cross-platform use.
362+
* Skills without scripts are valid; omit Parameters Reference and Script Reference sections in that case.
311363
* Document prerequisites for each supported platform.
312364
* Keep *SKILL.md* focused; move detailed reference material to `references/`.
313365
* Additional sections can be added between Parameters Reference and Troubleshooting as needed.
@@ -328,7 +380,7 @@ Skill files also include a standard attribution footer as the last line of body
328380

329381
## Frontmatter Requirements
330382

331-
This section defines frontmatter field requirements for prompt engineering artifacts.
383+
Frontmatter field requirements for prompt engineering artifacts follow.
332384

333385
Maturity is tracked in `collections/*.collection.yml` item metadata, not in frontmatter. Do not include a `maturity` field in artifact frontmatter. Set maturity on the artifact's matching collection item entry; when omitted, maturity defaults to `stable`.
334386

@@ -352,7 +404,7 @@ Optional fields available by file type:
352404

353405
* `tools:` - Tool restrictions for agents and subagents. When omitted, all tools are accessible. When specified, list only tools available in the current VS Code context.
354406
* `handoffs:` - Agent handoff declarations. Each entry includes `label` (display text, supports emoji), `agent` (target agent name), and optionally `prompt` (slash command to invoke) and `send` (boolean, auto-send the prompt when `true`).
355-
* `user-invocable:` - Boolean. Set to `false` to hide the agent from the user and prevent direct invocation. Defaults to `true` when omitted. Use for subagents that should not appear in the agent picker.
407+
* `user-invocable:` - Boolean. Set to `false` to hide the artifact from the user and prevent direct invocation. Defaults to `true` when omitted. Use for subagents that should not appear in the agent picker or background-only skills that should not appear in the slash command menu.
356408
* `disable-model-invocation:` - Boolean. Set to `true` to prevent Copilot from automatically invoking the agent. Use for agents that run subagents, agents that cause side effects (git operations, backlog management, deployments), or agents that should only run when explicitly requested. Defaults to `false` when omitted.
357409
* `agent:` - Agent delegation for prompt files.
358410
* `argument-hint:` - Hint text for prompt picker display.

.github/workflows/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ Compose multiple reusable workflows for comprehensive validation and security sc
6969
| `table-format.yml` | markdown-table-formatter | Verify table formatting (check-only) | `soft-fail` (false) | table-format-results |
7070
| `ps-script-analyzer.yml` | PSScriptAnalyzer | PowerShell static analysis | `soft-fail` (false), `changed-files-only` (true) | psscriptanalyzer-results |
7171
| `frontmatter-validation.yml` | Custom PS script | YAML frontmatter validation | `soft-fail` (false), `changed-files-only` (true), `skip-footer-validation` (false), `warnings-as-errors` (true) | frontmatter-validation-results |
72+
| `skill-validation.yml` | Custom PS script | Skill directory structure validation | `soft-fail` (false), `changed-files-only` (true) | skill-validation-results |
7273
| `link-lang-check.yml` | Custom PS script | Detect language-specific URLs | `soft-fail` (false) | link-lang-check-results |
7374
| `markdown-link-check.yml` | markdown-link-check | Validate links (internal/external) | `soft-fail` (true) | markdown-link-check-results |
7475

.github/workflows/pr-validation.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,16 @@ jobs:
9797
with:
9898
soft-fail: false
9999

100+
skill-validation:
101+
name: Skill Validation
102+
uses: ./.github/workflows/skill-validation.yml
103+
permissions:
104+
contents: read
105+
with:
106+
soft-fail: false
107+
changed-files-only: true
108+
base-branch: ${{ github.event.pull_request.base.sha || format('origin/{0}', github.base_ref) }}
109+
100110
link-lang-check:
101111
name: Link Language Check
102112
uses: ./.github/workflows/link-lang-check.yml
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Skill Validation
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
soft-fail:
7+
description: 'Whether to continue on validation failures'
8+
required: false
9+
type: boolean
10+
default: false
11+
changed-files-only:
12+
description: 'Only validate skills with changed files'
13+
required: false
14+
type: boolean
15+
default: true
16+
base-branch:
17+
description: 'Base branch or SHA for change detection (defaults to origin/main)'
18+
required: false
19+
type: string
20+
default: ''
21+
22+
permissions:
23+
contents: read
24+
25+
jobs:
26+
validate:
27+
name: Validate Skill Structure
28+
runs-on: ubuntu-latest
29+
permissions:
30+
contents: read
31+
steps:
32+
- name: Checkout code
33+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2
34+
with:
35+
persist-credentials: false
36+
fetch-depth: 0
37+
38+
- name: Run skill validation
39+
shell: pwsh
40+
run: |
41+
$params = @{}
42+
if ('${{ inputs.changed-files-only }}' -eq 'true') {
43+
$params['ChangedFilesOnly'] = $true
44+
$baseBranch = '${{ inputs.base-branch }}'
45+
if (-not [string]::IsNullOrEmpty($baseBranch)) {
46+
$params['BaseBranch'] = $baseBranch
47+
}
48+
}
49+
& './scripts/linting/Validate-SkillStructure.ps1' -WarningsAsErrors @params
50+
continue-on-error: ${{ inputs.soft-fail }}
51+
52+
- name: Upload validation results
53+
if: always()
54+
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v4.4.3
55+
with:
56+
name: skill-validation-results
57+
path: logs/skill-validation-results.json
58+
retention-days: 30
59+
if-no-files-found: ignore

CONTRIBUTING.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ npm run lint:md # Run markdownlint
4343
npm run lint:ps # Run PowerShell analyzer
4444
npm run lint:yaml # Run YAML linter
4545
npm run lint:frontmatter # Validate markdown frontmatter
46+
npm run validate:skills # Validate skill directory structure
4647
npm run lint:md-links # Check markdown links
4748
npm run spell-check # Run cspell
4849
npm run format:tables # Format markdown tables
@@ -61,21 +62,31 @@ We strongly recommend using the provided DevContainer, which comes pre-configure
6162
- [Required Tools](#required-tools)
6263
- [Validation Commands](#validation-commands)
6364
- [Development Environment](#development-environment)
65+
- [Table of Contents](#table-of-contents)
6466
- [Code of Conduct](#code-of-conduct)
6567
- [I Have a Question](#i-have-a-question)
6668
- [I Want To Contribute](#i-want-to-contribute)
6769
- [Reporting Bugs](#reporting-bugs)
70+
- [Before Submitting a Bug Report](#before-submitting-a-bug-report)
71+
- [How Do I Submit a Good Bug Report?](#how-do-i-submit-a-good-bug-report)
6872
- [Suggesting Enhancements](#suggesting-enhancements)
73+
- [Before Submitting an Enhancement](#before-submitting-an-enhancement)
74+
- [How Do I Submit a Good Enhancement Suggestion?](#how-do-i-submit-a-good-enhancement-suggestion)
6975
- [Your First Code Contribution](#your-first-code-contribution)
7076
- [Improving The Documentation](#improving-the-documentation)
7177
- [AI Artifact Contributions](#ai-artifact-contributions)
78+
- [Getting Started with AI Artifacts](#getting-started-with-ai-artifacts)
79+
- [Artifact Types](#artifact-types)
80+
- [Essential Resources](#essential-resources)
81+
- [Quick Reference](#quick-reference)
7282
- [Pull Request Inactivity Policy](#pull-request-inactivity-policy)
7383
- [Active Pull Requests](#active-pull-requests)
7484
- [Draft Pull Requests](#draft-pull-requests)
7585
- [Exemptions](#exemptions)
7686
- [Style Guides](#style-guides)
7787
- [Local Development Setup](#local-development-setup)
7888
- [Coding Conventions](#coding-conventions)
89+
- [Copyright and License Headers](#copyright-and-license-headers)
7990
- [Testing Requirements](#testing-requirements)
8091
- [When Tests Are Required](#when-tests-are-required)
8192
- [Test Conventions](#test-conventions)
@@ -175,7 +186,7 @@ When contributing code to the project, please consider the following guidance:
175186
- Assign an issue to yourself before beginning any effort, and update the issue status accordingly.
176187
- If an issue for your contribution does not exist, [please file an issue](https://github.com/microsoft/hve-core/issues/new) first to engage with the project maintainers for guidance.
177188
- Commits should reference related issues for traceability (e.g., "Fixes #123" or "Relates to #456").
178-
- When creating a PR, use [GitHub's closing keywords](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) in the description to automatically link and close related issues.
189+
- When creating a PR, use [GitHub's closing keywords](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue) in the description to automatically link and close related issues.
179190
- All code PRs destined for the `main` branch will be reviewed by pre-determined reviewer groups that are automatically added to each PR.
180191

181192
This project also includes a Dev Container for development work, and using that dev container is preferred, to ensure you are using the same toolchains and tool versions as other contributors. You can read more about the Dev Container in its [ReadMe](./.devcontainer/README.md).

docs/architecture/workflows.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ Individual validation workflows called by orchestration workflows:
6666
| `ps-script-analyzer.yml` | PowerShell static analysis | `npm run lint:ps` |
6767
| `table-format.yml` | Markdown table formatting | `npm run format:tables` |
6868
| `pester-tests.yml` | PowerShell unit tests | `npm run test:ps` |
69+
| `skill-validation.yml` | Skill structure validation | `npm run validate:skills` |
6970
| `dependency-pinning-scan.yml` | GitHub Actions pinning | N/A (PowerShell direct) |
7071
| `sha-staleness-check.yml` | SHA reference freshness | N/A (PowerShell direct) |
7172
| `codeql-analysis.yml` | CodeQL security scanning | N/A (GitHub native) |
@@ -112,6 +113,7 @@ flowchart LR
112113
| yaml-lint | `yaml-lint.yml` | YAML syntax |
113114
| pester-tests | `pester-tests.yml` | PowerShell unit tests |
114115
| frontmatter-validation | `frontmatter-validation.yml` | AI artifact metadata |
116+
| skill-validation | `skill-validation.yml` | Skill directory structure |
115117
| link-lang-check | `link-lang-check.yml` | Link accessibility |
116118
| markdown-link-check | `markdown-link-check.yml` | Broken links |
117119
| dependency-pinning-check | `dependency-pinning-scan.yml` | Action SHA pinning |
@@ -235,6 +237,7 @@ Workflows invoke validation through npm scripts defined in `package.json`:
235237
| `lint:ps` | `Invoke-PSScriptAnalyzer.ps1` | ps-script-analyzer.yml |
236238
| `format:tables` | `markdown-table-formatter` | table-format.yml |
237239
| `test:ps` | `Invoke-Pester` | pester-tests.yml |
240+
| `validate:skills` | `Validate-SkillStructure.ps1` | skill-validation.yml |
238241

239242
## Related Documentation
240243

docs/contributing/ai-artifacts-common.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,9 @@ npm run lint:md-links
651651

652652
# PowerShell analysis (if applicable)
653653
npm run lint:ps
654+
655+
# Validate skill structure (if applicable)
656+
npm run validate:skills
654657
```
655658

656659
### Quality Gates

0 commit comments

Comments
 (0)