Skip to content

Profile schema

This page lists each key that a profile file can hold. Speccy checks a profile against this schema when it loads the file, and speccy profile validate <file> checks one file. An unknown key is an error.

Change a profile or a check shows the common changes.

Key Type Required Meaning
key string matching ^[a-z][a-z0-9-]{0,31}$ yes The doc type. A spec doc’s frontmatter type, or a map entry in .speccy.yaml, selects the profile with this key.
name string yes The name the app shows for this doc type, such as Product Requirements Document.
version integer Speccy sets it on each save. Earlier review runs keep the version they used.
template string yes The path of the template, relative to the profile file. A doc must have each heading that ends with <!-- required -->, or with <!-- required: app --> at size app and larger (lint.required-headings).
limits object The size limits that lint checks. A key you leave out keeps its default.
links object The links a doc of this type must have.
grounding object The settings of the grounding stage.
verify object The post-build verification gate: the trace IDs it verifies, and the bounds of its repo scan.
trace object The trace IDs of this doc type.
waivers object Who approves a waiver, by the level of the check.
approvals object The approvals that a spec doc of this type needs.
divergence object The divergence stage: its readers and its build questions.
lint object The settings of the lint stage.
checks list of object yes The checks that a review runs besides lint. Each check has a slug, a level and a stage.

The size limits that lint checks. A key you leave out keeps its default.

Key Type Required Meaning
max_words integer The most words in the doc (lint.prose-limit). Default 8000.
max_section_words integer The most words in one section (lint.prose-limit). Default 900.
max_sentence_words integer The most words in one sentence (lint.sentence-length). Default 25.
max_code_block_lines integer The most lines in one code block (lint.asset-nudge). Default 40.
max_table_rows integer The most rows in one table (lint.asset-nudge). Default 15.

The links a doc of this type must have.

Key Type Required Meaning
upstream object The upstream link that a doc of this type needs (links.has-upstream).
children object A doc at size min_at or larger must link the bundles it covers (links.has-children).

The upstream link that a doc of this type needs (links.has-upstream).

Key Type Required Meaning
kinds list of one of implements, refines, references, supersedes yes The link kinds that count as an upstream link.
types list of string yes The profile keys that an upstream doc can have, such as prd.
required boolean When true, a doc with no upstream link and no standalone acknowledgement fails links.has-upstream. Default false.

A doc at size min_at or larger must link the bundles it covers (links.has-children).

Key Type Required Meaning
kinds list of one of implements, refines, references, supersedes yes The link kinds that count as a link to a covered bundle.
min integer The fewest links of those kinds that the doc needs. Default 1.
min_at one of feature, app, initiative yes The smallest doc size that the check applies to.

The settings of the grounding stage.

Key Type Required Meaning
sources object The source policy: which domains the grounding stage accepts, their tier, their freshness period, and the claim class of a section.

The source policy: which domains the grounding stage accepts, their tier, their freshness period, and the claim class of a section.

Key Type Required Meaning
allow list of string matching ^(\*\.)?[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$ When the list has a host, the grounding stage accepts sources from these hosts only.
forbid list of string matching ^(\*\.)?[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$ Hosts that Speccy never accepts and never requests.
domains list of object The tier of each host pattern. A host that matches no pattern is secondary.
freshness object Days a source of that tier stays usable. Zero is no limit.
require_primary list of string The claim classes whose sources must all be primary.
classes list of object Rules that give the claims of a section a claim class, by heading path. The most specific pattern wins.
unclassified one of allow, warn, require-classification What Speccy does with a claim in a section that matches no class rule. allow does nothing, and warn adds a note to the run. require-classification drops the claim’s sources. Default allow.
Key Type Required Meaning
pattern string matching ^(\*\.)?[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$ yes A host, such as example.com, or *.example.com for its subdomains.
tier one of primary, secondary yes The tier of a host that matches the pattern. The most specific pattern wins.

Days a source of that tier stays usable. Zero is no limit.

Key Type Required Meaning
primary integer Days a primary source stays usable.
secondary integer Days a secondary source stays usable.
Key Type Required Meaning
pattern string yes A heading path, with / between headings. A * segment matches one heading, and a trailing ** matches the rest. The match ignores case.
class string yes The claim class of a section that matches the pattern. The name unclassified is not a valid class.

The post-build verification gate: the trace IDs it verifies, and the bounds of its repo scan.

Key Type Required Meaning
prefixes list of string matching ^[A-Z]{2,6}$ The trace ID prefixes that a verification run checks. Default REQ and NFR.
exclude list of string Path globs that the repo scan passes over. A list you set replaces the default, which holds vendor/**, node_modules/**, dist/**, build/**, .git/**, **/testdata/**, **/*.min.js, **/*.lock and **/*.sum.
max_file_kb integer The largest file, in KB, that the repo scan reads. Default 512.
max_mapper_files integer The most files that the model which finds code targets sees, highest ranked first. Default 200.

The trace IDs of this doc type.

Key Type Required Meaning
prefixes list of string matching ^[A-Z]{2,6}$ The trace ID prefixes that this doc type defines. An ID with another prefix gets trace.unknown-prefix.
cover list of string matching ^[A-Z]{2,6}$ The prefixes of upstream IDs that this doc must cover. Each such ID in an implements target needs a reference or an acknowledgement (trace.coverage).

Who approves a waiver, by the level of the check.

Key Type Required Meaning
should one of any_member, non_author, maintainer, forbidden or object The waiver policy of a SHOULD check. Default non_author.
must one of any_member, non_author, maintainer, forbidden or object The waiver policy of a MUST check. Default maintainer.

The approvals that a spec doc of this type needs.

Key Type Required Meaning
required integer How many approvals the current version needs. Default 1.

The divergence stage: its readers and its build questions.

Key Type Required Meaning
readers integer How many readers answer the build questions. Default 3.
questions object How many build questions the stage writes.
themes list of string The topics that the build questions cover, such as error handling or limits.

How many build questions the stage writes.

Key Type Required Meaning
min integer The fewest build questions. Default 10. It cannot be larger than max.
max integer The most build questions. Default 20.

The settings of the lint stage.

Key Type Required Meaning
overrides map of object A level for a lint check, by slug: MUST, SHOULD, INFO, or off. The value off turns the check off.
slop_extra list of string More filler phrases for lint.slop-phrase to find, on top of its own list.
Key Type Required Meaning
slug string matching ^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$ yes The ID of the check: lower-case words with dots between them, such as sdd.data-model. It is unique in the profile.
level one of MUST, SHOULD, INFO yes The level of a finding. An open MUST finding makes the verdict Not Build Ready.
stage one of rubric, grounding, divergence, coherence yes The review stage that runs the check.
scope one of doc, section What the check reads. With doc, a waiver covers the whole doc. With section, a waiver covers one section. Default doc.
question string The question the check asks about the doc.
pass_when string What must hold for the check to pass. A finding gives it as the fix.
waiver one of any_member, non_author, maintainer, forbidden or object Who approves a waiver of this check. It replaces waivers.should or waivers.must for this check.
sizes list of one of feature, app, initiative The doc sizes this check applies to. An empty list applies at every size.