Schema reference
Generated from the live contract module — always in sync with the editor and skill.
Overview
A SpecPad project lives in docs/specpad/ inside your git repository and
consists of up to five JSON files:
| File | Purpose |
|---|---|
[name].proj.json |
Project index — names the system and lists the SRS/VTP documents that belong to it. |
[name].srs.json |
Software Requirements Specification — ordered requirements and section headings. |
[name].vtp.json |
Verification Test Plan — ordered tests, each linking to the requirements it verifies. |
[name].releases.json (sidecar) |
Release manifest — one entry per git tag, with snapshot paths for change-tracking. |
[name].job.json (sidecar) |
Current-job marker — the active ticket or issue number attributed to in-flight spec changes. |
Snapshot files are cached under docs/specpad/.specpad/; that sub-folder is
regenerable from git history and is never the source of truth. Each release entry carries
a snapshot path (or null if not yet cached) pointing to the
corresponding raw document copy.
Schema versioning
Every file carries a schemaVersion field. Version "1.0" maps to
the pinned editor build at /v01/. When a new schema version ships, its
editor build is deployed at a new path (e.g. /v02/) and the old path remains
live forever — so existing documents always open in an editor that understands them.
What is and isn't stored
Git owns history. The files contain no modifiedBy,
modifiedDate, author, or change-list fields — git commits carry that context.
Nothing derived is stored. Test counts, pass/fail roll-ups, and change diffs
are computed on read from the raw JSON; storing them would create a drift hazard.
Field reference
Field descriptions are authoritative — they are read directly from the JSON Schema definitions at build time. A missing description is a build error.
project
| Field | Type | Required | Description |
|---|---|---|---|
schemaVersion |
const "1.0" |
required | Contract version of this file; "1.0" documents open in the pinned editor build at /v01/. |
type |
const "project" |
required | Document discriminator; selects the schema this file is validated against. |
name |
string |
required | Short system name; also the filename stem ([name].proj.json). |
title |
string |
required | Human-readable project title shown in the editor. |
description |
string |
optional | Optional free-text summary of the system under specification. |
documents |
array of objects |
required | The SRS and VTP files that make up this project. |
documents[].type |
"srs" | "vtp" |
required | Which kind of document this entry points at: "srs" or "vtp". |
documents[].path |
string |
required | Path of the document file, relative to the project index. |
documents[].title |
string |
required | Display title for the document. |
srs
| Field | Type | Required | Description |
|---|---|---|---|
schemaVersion |
const "1.0" |
required | Contract version of this file; "1.0" documents open in the pinned editor build at /v01/. |
type |
const "srs" |
required | Document discriminator; selects the schema this file is validated against. |
name |
string |
required | Short system name; also the filename stem ([name].srs.json). |
title |
string |
required | Human-readable document title. |
items |
array of objects |
required | Ordered list of requirements and section headings. |
items[].id |
string |
required | Stable machine identifier, generated once and never changed; all cross-references target it. |
items[].code |
string |
optional | Human-facing label (e.g. "DOC-1"); freely renameable because references never use it. |
items[].text |
string |
required | The requirement statement. |
items[].heading |
boolean |
optional | True when this item is a section heading rather than a requirement/test. |
items[].level |
integer |
optional | Indent depth for hierarchy; absent means 0. Headings form dotted section codes. |
items[].tags |
array of string |
optional | Free-form labels for filtering and grouping. |
items[].hazards |
array of string |
optional | Reserved hazard labels (legacy v1 field; the editor no longer surfaces it). |
vtp
| Field | Type | Required | Description |
|---|---|---|---|
schemaVersion |
const "1.0" |
required | Contract version of this file; "1.0" documents open in the pinned editor build at /v01/. |
type |
const "vtp" |
required | Document discriminator; selects the schema this file is validated against. |
name |
string |
required | Short system name; also the filename stem ([name].vtp.json). |
title |
string |
required | Human-readable document title. |
items |
array of objects |
required | Ordered list of tests and section headings. |
items[].id |
string |
required | Stable machine identifier, generated once and never changed; all cross-references target it. |
items[].code |
string |
optional | Human-facing label (e.g. "DOC-1"); freely renameable because references never use it. |
items[].text |
string |
required | The test procedure: what to do to verify the linked requirements. |
items[].heading |
boolean |
optional | True when this item is a section heading rather than a requirement/test. |
items[].level |
integer |
optional | Indent depth for hierarchy; absent means 0. Headings form dotted section codes. |
items[].verifies |
array of string |
optional | Ids of the SRS requirements this test verifies — ids, never codes, so renames cannot break traceability. |
items[].expected |
string |
optional | The expected result that defines a pass. |
items[].result |
"" | "not_tested" | "passed" | "failed" |
optional | Latest recorded outcome: "", "not_tested", "passed", or "failed". Roll-ups are computed on read, never stored. |
items[].notes |
string |
optional | Evidence and context for the recorded result (e.g. which automated test covers it). |
items[].tags |
array of string |
optional | Free-form labels for filtering and grouping. |
releases
| Field | Type | Required | Description |
|---|---|---|---|
schemaVersion |
const "1.0" |
required | Contract version of this file; "1.0" documents open in the pinned editor build at /v01/. |
type |
const "releases" |
required | Document discriminator; selects the schema this file is validated against. |
name |
string |
required | Project name this manifest belongs to. |
tagPattern |
string |
required | Git tag glob (e.g. "v*") that marks releases of the spec. |
baseline |
string | null |
required | Version whose snapshot the editor diffs the working copy against (the current redline base). |
releases |
array of objects |
required | One entry per matching git tag, oldest first. |
releases[].version |
string |
required | The release tag name. |
releases[].ref |
string |
required | Commit hash the tag points at. |
releases[].date |
string |
required | Commit date (ISO). |
releases[].author |
object |
required | Author of the tagged commit (release-granularity attribution). |
releases[].author.name |
string |
required | Author display name from git. |
releases[].author.email |
string |
required | Author email from git. |
releases[].snapshot |
string | null |
required | Path of the cached snapshot under docs/specpad/, or null if not yet cached. |
job
| Field | Type | Required | Description |
|---|---|---|---|
schemaVersion |
const "1.0" |
required | Contract version of this file; "1.0" documents open in the pinned editor build at /v01/. |
type |
const "job" |
required | Document discriminator; selects the schema this file is validated against. |
job |
string |
required | The active work item (a ticket key or issue number) that current changes are attributed to. |
title |
string |
optional | Optional human-readable summary of the job. |
Governance rules
JSON Schema validates structure only (required fields, types, enums). These policy rules
run in both the skill and the editor from one shared module
(src/shared/governance.ts) — they cannot drift.
traceability — Every requirement is verified
Every non-heading SRS requirement must be referenced by at least one VTP test.
referential-integrity — References resolve
Every VTP `verifies` entry must resolve to an existing SRS item id.
missing-expected — Tests declare an expected result
Every non-heading VTP test must have a non-empty `expected` value.
Annotated example
A real requirement from SpecPad's own SRS (DOC-1) and its verifying test
(TEST-1), showing how the key fields relate.
{
"id": "r_a101",
"code": "DOC-1",
"text": "The system shall store project documentation as JSON files under docs/specpad/: one project index, one SRS, and one VTP.",
"tags": ["schema"]
}
{
"id": "t_c001",
"code": "TEST-1",
"text": "Confirm docs/specpad/ holds the three core files and each parses as JSON.",
"verifies": ["r_a101"],
"expected": "All three files exist and parse without error.",
"result": "passed",
"notes": "dogfood.test.ts"
}
-
idr_a101/t_c001— stable machine identifiers generated once and never changed. Renamingcode(the human label) never touchesid. -
codeDOC-1/TEST-1— freely renameable display labels. The editor shows them; the skill increments them; traceability links ignore them entirely. -
verifies["r_a101"]— the test links to the requirement byid, never bycode, so renamingDOC-1toARCH-1cannot break the link. -
expected"All three files exist…"— a non-empty expected result is required on every non-heading test (governance rulemissing-expected).
Install & use the skill
The SpecPad Claude Code skill lets you create and maintain SRS/VTP documents directly from your AI assistant, with full validation and governance checks.
-
Download
specpad-skill.zipand unzip it into~/.claude/skills/so that~/.claude/skills/specpad/SKILL.mdexists. -
In any repo, tell Claude Code: "set up specpad" — it scaffolds
docs/specpad/with a project index, an empty SRS, and an empty VTP. -
Use natural language to manage your spec. Trigger phrases:
write a specformalize requirementsadd a requirementwrite tests forcheck traceability
- Before finishing any task the skill validates structure and runs all three governance rules — so the JSON files on disk are always editor-ready.
- Open the same files in the hosted visual editor at specpad.com/v01/ to review, edit, and record test results through a full UI. Git is the shared history layer; both halves read and write the same JSON.