# How to Validate AI Artifacts with JSON Schema Enforcement in HVE Core

> Learn how to validate AI artifacts using JSON schema enforcement in HVE Core's automated PowerShell pipeline. Ensure data integrity and prevent build failures with strict validation.

- Repository: [Microsoft/hve-core](https://github.com/microsoft/hve-core)
- Tags: how-to-guide
- Published: 2026-03-09

---

**HVE Core validates AI artifacts by extracting YAML front-matter from Markdown files and enforcing strict JSON Schema definitions through an automated PowerShell-based pipeline that fails CI builds on validation errors.**

The `microsoft/hve-core` repository treats every AI artifact—including instructions, prompts, agents, skills, and documentation—as structured data that must conform to predefined contracts. By implementing JSON Schema enforcement at the front-matter level, the project ensures metadata consistency, prevents malformed configurations from reaching production, and enables automated linting through both local development workflows and CI/CD pipelines.

## Architecture of the JSON Schema Validation System

The validation architecture in HVE Core consists of six integrated components that process Markdown files from extraction to error reporting.

| Component | Role | Source Location |
|-----------|------|-----------------|
| **Front-matter parser** | Extracts YAML blocks from files and converts them into PowerShell hashtables | `Get-Frontmatter` in `scripts/linting/Validate-MarkdownFrontmatter.ps1` |
| **Schema selector** | Maps file paths to appropriate JSON Schema files using glob patterns | `Get-SchemaForFile` in `scripts/linting/Validate-MarkdownFrontmatter.ps1` |
| **JSON Schema definitions** | Define required fields, types, enums, and pattern constraints | `*.schema.json` files in `scripts/linting/schemas/` |
| **Validator engine** | Recursively validates hashtable values against schema constraints | `Test-JsonSchemaValidation` in `scripts/linting/Validate-MarkdownFrontmatter.ps1` |
| **Result object** | Returns structured validation status with errors and warnings | `SchemaValidationResult` class |
| **CI integration** | Orchestrates validation with npm scripts and fail-fast behavior | `npm run lint:frontmatter` in [`package.json`](https://github.com/microsoft/hve-core/blob/main/package.json) |

The **schema mapping** logic resides in [`scripts/linting/schemas/schema-mapping.json`](https://github.com/microsoft/hve-core/blob/main/scripts/linting/schemas/schema-mapping.json), which contains an ordered list of glob patterns and their corresponding schema files. When processing a file, the script iterates through mappings and selects the first matching pattern, falling back to [`base-frontmatter.schema.json`](https://github.com/microsoft/hve-core/blob/main/base-frontmatter.schema.json) if no specific rule applies.

```json
{
  "mappings": [
    {
      "pattern": "docs/**/*.md",
      "scope": "docs",
      "schema": "docs-frontmatter.schema.json"
    },
    {
      "pattern": ".github/**/*.instructions.md",
      "schema": "instruction-frontmatter.schema.json"
    }
  ],
  "defaultSchema": "base-frontmatter.schema.json"
}

```

## Step-by-Step Validation Flow

The validation process follows a strict six-stage pipeline that transforms raw Markdown into validated structured data.

1. **File Collection** – The script receives a list of Markdown files, defaulting to `git ls-files *.md` when no specific paths are provided.

2. **Front-matter Extraction** – The `Get-Frontmatter` helper parses YAML blocks from each file and constructs PowerShell hashtables.

3. **Schema Selection** – `Get-SchemaForFile` queries [`schema-mapping.json`](https://github.com/microsoft/hve-core/blob/main/schema-mapping.json) to determine the appropriate `*.schema.json` file based on the file path.

4. **Schema Loading** – The validator loads the JSON Schema either from disk via `-SchemaPath` or from an in-memory object via `-SchemaContent`.

5. **Constraint Validation** – `Test-JsonSchemaValidation` recursively checks the hashtable against the schema, validating required fields, data types, `enum` values, `pattern` regular expressions, `minLength` constraints, and array item types. The implementation deliberately ignores complex keywords like `$ref`, `allOf`, and `anyOf` to maintain "soft" validation compatibility.

6. **Result Reporting** – Errors populate a `System.Collections.Generic.List[string]` within the `SchemaValidationResult` object. When the CI pipeline runs with `-WarningsAsErrors`, any validation error fails the build immediately.

## Running Validation Locally and in CI

You can execute the JSON Schema validation through npm scripts for CI integration or invoke the PowerShell module directly for targeted testing.

### Validate All Files via npm

Run the complete front-matter validation suite from the repository root:

```bash
npm run lint:frontmatter

```

This command executes `Validate-MarkdownFrontmatter.ps1` with `-EnableSchemaValidation` and `-WarningsAsErrors` flags enabled, ensuring the build fails on any schema violation. The script definition is located in [`package.json`](https://github.com/microsoft/hve-core/blob/main/package.json).

### Validate a Single File via PowerShell

For debugging or pre-commit checks, import the validation module and test individual files:

```powershell
Import-Module ./scripts/linting/Validate-MarkdownFrontmatter.ps1

$frontmatter = @{ title = 'My Doc'; description = 'A description' }
$schemaPath = './scripts/linting/schemas/docs-frontmatter.schema.json'

$result = Test-JsonSchemaValidation -Frontmatter $frontmatter -SchemaPath $schemaPath

if (-not $result.IsValid) {
    $result.Errors | ForEach-Object { Write-Error $_ }
}

```

This demonstrates direct usage of `Test-JsonSchemaValidation` without the wrapper script, useful for unit testing specific front-matter structures against custom schemas.

## Extending Validation for New Artifact Types

Adding support for new AI artifact types requires creating a schema definition and registering it in the mapping configuration.

### 1. Create the Schema Definition

Add a new `*.schema.json` file to `scripts/linting/schemas/`. For example, a policy file schema might look like:

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Policy File Frontmatter",
  "type": "object",
  "required": ["title", "owner"],
  "properties": {
    "title": { "type": "string", "minLength": 1 },
    "owner": { "type": "string", "minLength": 1 },
    "severity": { "type": "string", "enum": ["low", "medium", "high"] }
  },
  "additionalProperties": false
}

```

### 2. Register the Pattern Mapping

Append an entry to [`scripts/linting/schemas/schema-mapping.json`](https://github.com/microsoft/hve-core/blob/main/scripts/linting/schemas/schema-mapping.json):

```json
{
  "pattern": "policies/**/*.md",
  "schema": "policy-frontmatter.schema.json",
  "description": "Policy documentation files"
}

```

Once registered, any Markdown file under `policies/` automatically validates against your new schema when `npm run lint:frontmatter` executes.

## Summary

- **HVE Core** validates AI artifacts by enforcing JSON Schema constraints against YAML front-matter in Markdown files.
- The validation pipeline uses `Validate-MarkdownFrontmatter.ps1` to extract front-matter, select schemas via [`schema-mapping.json`](https://github.com/microsoft/hve-core/blob/main/schema-mapping.json), and report errors through `SchemaValidationResult` objects.
- **Local validation** runs via `npm run lint:frontmatter`, while CI pipelines use the same command with `-WarningsAsErrors` to prevent invalid artifacts from merging.
- **Extending the system** involves adding new `*.schema.json` files to `scripts/linting/schemas/` and registering glob patterns in [`schema-mapping.json`](https://github.com/microsoft/hve-core/blob/main/schema-mapping.json).
- The validator supports core JSON Schema keywords including `required`, `type`, `enum`, `pattern`, and `minLength`, but ignores complex composition keywords like `$ref` and `allOf` for simplified "soft" validation.

## Frequently Asked Questions

### How does HVE Core determine which JSON Schema to use for a specific file?

The `Get-SchemaForFile` function in `scripts/linting/Validate-MarkdownFrontmatter.ps1` reads [`scripts/linting/schemas/schema-mapping.json`](https://github.com/microsoft/hve-core/blob/main/scripts/linting/schemas/schema-mapping.json) and matches the file path against an ordered list of glob patterns. It selects the schema associated with the first matching pattern, or falls back to [`base-frontmatter.schema.json`](https://github.com/microsoft/hve-core/blob/main/base-frontmatter.schema.json) if no patterns match.

### What JSON Schema keywords are supported by the validator?

According to the implementation in `Test-JsonSchemaValidation`, the system validates `required` fields, `type` constraints, `enum` values, `pattern` regular expressions, `minLength` for strings, and array item types. It deliberately ignores advanced keywords like `$ref`, `allOf`, and `anyOf` to maintain compatibility and simplify the validation logic.

### Can I validate AI artifacts without running the full npm lint script?

Yes. You can import `Validate-MarkdownFrontmatter.ps1` as a PowerShell module and call `Test-JsonSchemaValidation` directly with a hashtable of front-matter data and a path to any schema file. This approach is useful for unit testing or validating single files during development without scanning the entire repository.

### How do I make the CI pipeline fail on validation warnings?

The `npm run lint:frontmatter` script invokes the PowerShell validator with `-WarningsAsErrors` enabled. This flag ensures that both validation errors and warnings trigger a non-zero exit code, causing the CI/CD pipeline to fail and block the merge of invalid AI artifacts.