@dogfood-lab/schemas
v1.9.0
Published
JSON schemas for the testing-os contract spine — record, finding, pattern, recommendation, doctrine, policy, scenario, submission.
Maintainers
Readme
@dogfood-lab/schemas
JSON schemas for the testing-os contract spine — record, finding, pattern, recommendation, doctrine, policy, scenario, submission.
Part of the testing-os monorepo — the operating system for testing in the AI era.
This package ships the 8 canonical JSON Schemas (2020-12 dialect) that the testing-os contract spine validates against. Every record, finding, pattern, recommendation, doctrine artifact, policy file, scenario definition, and submission envelope produced by the rest of the monorepo conforms to one of these schemas. Consumer packages (@dogfood-lab/verify, @dogfood-lab/findings, @dogfood-lab/report) load the schemas via the ./json/* subpath export and compile them with ajv.
Install
npm install @dogfood-lab/schemasThe 8 Schemas
| Schema file | Purpose |
|---|---|
| dogfood-record.schema.json | Persisted test/audit record produced by dogfood runs |
| dogfood-record-submission.schema.json | Envelope shape repository_dispatch payloads must match |
| dogfood-finding.schema.json | Evidence-bound finding contract — anchored to source line + severity + status |
| dogfood-pattern.schema.json | Reusable pattern derived from findings (synthesis layer) |
| dogfood-recommendation.schema.json | Recommendation derived from patterns |
| dogfood-doctrine.schema.json | Doctrine artifact synthesized from patterns + recommendations |
| policy.schema.json | Per-repo policy YAML shape (gate accumulation, severity thresholds) |
| scenario.schema.json | Scenario definition shape (what gets tested + how) |
Usage — TypeScript surface
The package exports validatePayload and the compiled validators. validatePayload(name, payload) takes the schema name first (one of record, recordSubmission, finding, pattern, recommendation, doctrine, policy, scenario — all camelCase, NOT the file basename) and the payload second. The return shape is { valid: boolean, errors: ValidationError[] } — each error carries path, message, keyword (the Ajv rule that fired, e.g. required / pattern / enum), and optional params.
import { validatePayload } from '@dogfood-lab/schemas';
const result = validatePayload('recordSubmission', submission);
if (!result.valid) {
console.error('schema mismatch:', result.errors);
process.exit(1);
}compileSchema(name) returns the raw Ajv ValidateFunction for advanced cases (custom error formatting, direct validate.errors inspection). Sibling packages (@dogfood-lab/verify, @dogfood-lab/findings, @dogfood-lab/ingest, @dogfood-lab/report) all delegate to validatePayload — collapsing N Ajv instances to one per schema per process via the module-scope validatorCache.
Usage — Raw JSON schemas
The raw schema files are available via the ./json/* subpath export. Use createRequire to load them at runtime:
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
const recordSchema = require('@dogfood-lab/schemas/json/dogfood-record.schema.json');
const findingSchema = require('@dogfood-lab/schemas/json/dogfood-finding.schema.json');Or with import attributes (Node 22+):
import recordSchema from '@dogfood-lab/schemas/json/dogfood-record.schema.json' with { type: 'json' };Compatibility
| | Constraint |
|---|---|
| JSON Schema dialect | 2020-12 |
| Node | ≥ 22 |
| $id form | https://github.com/dogfood-lab/testing-os/packages/schemas/src/json/<name>.schema.json |
$id is a contract field. Changes that consumers should treat as contract changes bump the monorepo's lockstep version.
Schema versioning
Payloads that carry a schema_version are gated by MAJOR range, not exact match. The accepted ranges live in one place — SUPPORTED_SCHEMA_VERSIONS (src/schema-versions.ts), which @dogfood-lab/verify imports to drive the gate and to stamp the persisted record's schema_version:
| Field | Meaning |
|---|---|
| current | the version this build emits for the contract |
| minMajor | lowest MAJOR accepted (inclusive) |
| maxMajor | highest MAJOR accepted (inclusive) |
The gate compares the payload's MAJOR against [minMajor, maxMajor]:
- MAJOR inside the range (any patch/minor) → accepted.
- MAJOR above
maxMajor→ rejectedCONTRACT_SCHEMA_TOO_NEW— the payload was emitted against a newer contract than this build understands. Operator action: upgrade testing-os. - MAJOR below
minMajor→ rejectedCONTRACT_SCHEMA_TOO_OLD— the payload predates the supported contract. Operator action: re-emit against the current contract.
The contracts that carry schema_version are record, recordSubmission, finding, pattern, recommendation, doctrine, and the agentOutput swarm envelope. policy and scenario deliberately carry no schema_version and are exempt from the gate — the gate only fires on payloads that declare one. See the error code reference for how the CONTRACT_SCHEMA_TOO_* rejections surface to a consumer.
Docs
📖 Full handbook: https://dogfood-lab.github.io/testing-os/handbook/
License
MIT © 2026 mcp-tool-shop
