Skip to content

Schema reference

Every field the catalog validates, read directly from schemas/*.schema.json. This page is generated, so it cannot drift from what tools/validate.py actually enforces.

The contract is frozen. Before changing any schema, read the change-class policy in ADR 0019: annotation edits are a normal PR, a new optional property is a minor bump, and anything else needs an ADR, a major bump, and a migration.

Shared base schema for all taxonomy entry types

  • Published at: https://product-on-purpose.github.io/writing-style-catalog/schemas/v1/entry.universal.schema.json
  • Freeze status: frozen (ADR 0019)
FieldTypeRequiredNotes
anti_patternsarray of object (min 2, max 4)yesADR 0009 pedagogical bar (required since 2026-06-22, the F2 tighten-to-required step after the 60-entry backfill). 2 to 4 misuse/why pairs; consumed by Gate 2. Makes explicit what is implicit in when_not_to_use and confusable_with.
avoid_witharray of stringyesList of entry IDs that conflict or produce poor results
axisenum: voice, tone, style, formatyesThe taxonomy axis this entry belongs to. Four peer axes, applied in this precedence order during composition: voice, tone, style, format. Voice and Tone are the most confusable pair (voice is stable across contexts; tone varies per piece) but they are separate axes with separate schemas. See ADR 0018.
confusable_witharray of stringyesEntry IDs that are commonly confused with this one
deprecated_in_favor_ofstringnoIf deprecated, the entry ID that replaces this one
descriptionstringyesFull prose description, 100-500 words
examples_indexarray of stringnoRelative paths to example files
failure_modesarray of object (min 2, max 3)yesADR 0009 pedagogical bar (required since 2026-06-22, the F2 tighten-to-required step after the 60-entry backfill). 2 to 3 mode/mitigation pairs. The field the C1 restraint check renders against: a sample is judged a caricature if it triggers the entry’s own declared failure modes.
idstringyesSlug identifier, unique within axis
llm_instruction_phrasingstringyesReady-to-use instruction paragraph for an LLM
namestringyesHuman-readable display name
one_linerstringyes1-2 sentence standalone description
pairs_well_witharray of string (min 1)yesList of entry IDs that compose well with this entry
review_statusenum: draft, reviewed, stable, reference-quality, deprecatedyesLifecycle state of this entry. draft = initial content; reviewed = editorially checked; stable = in active use; reference-quality = exemplary; deprecated = superseded.
tagsarray of stringyesSearchable tags
tellsarray of string (min 5, max 7)yesADR 0009 pedagogical bar (required since 2026-06-22, the F2 tighten-to-required step after the 60-entry backfill). 5 to 7 spottable phrases, syntactic moves, or structural markers by which a reader identifies this entry’s application in the wild. Largely reformats the per-axis fields (language_patterns, markers, structural_conventions). Substance (non-empty strings) is enforced by Gate 2 in tools/validate.py.
when_not_to_usearray of string (min 1)yesSituations where this entry is inappropriate
when_to_usearray of string (min 1)yesSituations where this entry is appropriate

Schema for the YAML frontmatter of example files in the examples/ directory

  • Published at: https://product-on-purpose.github.io/writing-style-catalog/schemas/v1/example.schema.json
  • Freeze status: frozen (ADR 0019)
FieldTypeRequiredNotes
audiencestringnoIntended audience for the example content
author_typeenum: human, llm, hybridyesWho produced the example content. human = written by a person; llm = fully AI-generated; hybrid = AI-generated and then edited by a human.
axisenum: voice, tone, style, formatyes
edited_bystringnoHuman editor name (applicable when author_type is hybrid)
entry_idstringyesSlug of the taxonomy entry this example demonstrates
format_idstringnoFormat entry ID if this example demonstrates a format combination
generated_atstringnoISO 8601 date when the example was generated
llm_modelstringnoModel identifier (required when author_type is llm or hybrid)
llm_prompt_filestringnoRelative path to the prompt file used to generate this example
review_statusenum: draft, reviewed, stable, reference-qualityyes
style_idstringnoStyle entry ID if this example demonstrates a style combination
tone_idstringnoTone entry ID if this example demonstrates a tone combination
topic_labelstringyesHuman-readable topic name
topic_slugstringyesSlug of the anchor topic (e.g., async-standups)
voice_idstringnoVoice entry ID if this example demonstrates a voice combination
word_countintegernoWord count of the example body

Schema for the YAML frontmatter of diff-pair files in examples/diff-pairs/. A diff-pair contrasts two taxonomy entries on the same axis applied to the same topic, with every other axis held constant.

  • Published at: https://product-on-purpose.github.io/writing-style-catalog/schemas/experimental/diff-pair.schema.json
  • Freeze status: not frozen - may take a breaking change without a major version bump
FieldTypeRequiredNotes
author_typeenum: human, llm, hybridnoWho produced the diff-pair body. human = written by a person; llm = fully AI-generated; hybrid = AI-generated and then edited by a human.
axis_variedenum: voice, tone, style, formatyesThe axis whose value differs between entry_a and entry_b. All other axes are held constant.
diff_pair_idstringyesSlug uniquely identifying this diff pair. Convention: -<entry_a>-vs-<entry_b>-<topic_slug>.
entry_astringyesSlug of the first taxonomy entry being contrasted.
entry_bstringyesSlug of the second taxonomy entry being contrasted.
generated_atstringnoISO 8601 date when the diff-pair was generated.
generatorstringnoPath to the script or process that produced this file, if applicable.
llm_modelstringnoModel identifier (relevant when author_type is llm or hybrid).
notesstringnoOptional curator notes about why this pair was chosen or what it teaches.
review_statusenum: draft, reviewed, stable, reference-qualityyes
topic_labelstringyesHuman-readable topic name.
topic_slugstringyesSlug of the anchor topic the pair is rendered on (e.g., async-standups).

Schema for format entries (axis 4 of 4). Format is the structural container or output type: headings, field ordering, section templates.

  • Published at: https://product-on-purpose.github.io/writing-style-catalog/schemas/v1/format.schema.json
  • Freeze status: frozen (ADR 0019)
  • Composes: entry.universal.schema.json
FieldTypeRequiredNotes
axisno
canonical_templatestringnoThe structural template (e.g., Context/Decision/Consequences for ADR)
digital_or_printenum: digital, print, both, neithernoPrimary medium for this format
domainenum: professional, public, personal, ceremonial, contemplativeyesSphere of life the writing happens in (ADR 0010). Required (F2 phase 3, tightened 2026-06-19 after the 60 were backfilled). The enum mirrors tools/taxonomy.py FORMAT_DOMAINS; the family-belongs-to-domain rule is enforced by validate.py.
familyenum: deliberation, instruction, progress, brief, appraisal, messaging, outreach, response, broadcast, copy, position, accountability, correspondence, essay, tribute, devotion, journalyesStructural/functional kind of writing, scoped to its domain (ADR 0010). Flat enum (mirrors tools/taxonomy.py); membership within the domain is checked by validate.py. Required (F2 phase 3).
subfamilystringnoOptional third level, required once a family reaches 12 members (ADR 0010). Membership is checked by validate.py where the family enumerates subfamilies.
typical_lengthobjectnoTypical word-count range for this format
typical_tonesarray of stringnoTone IDs that frequently use this format
typical_voicesarray of stringnoVoice IDs that frequently use this format

Schema for style entries (axis 3 of 4). Style is the kind or mode of writing (rhetorical, narrative, or genre category): how ideas are sequenced and structured.

  • Published at: https://product-on-purpose.github.io/writing-style-catalog/schemas/v1/style.schema.json
  • Freeze status: frozen (ADR 0019)
  • Composes: entry.universal.schema.json
FieldTypeRequiredNotes
axisno
classical_modestringnoClassical rhetorical mode if applicable (narration, description, exposition, argumentation)
evidence_typesarray of stringnoTypes of evidence or support this style typically uses
framestringnoThe rhetorical or narrative frame (e.g., argument, narrative, expository)
reader_contractstringnoWhat the reader can expect from a piece written in this style
structural_conventionsarray of string (min 1)yesThe typical structure rules for this style

Schema for tone entries (axis 2 of 4). Tone captures situational register, how the writing feels in a given context, and varies from one piece to the next. Voice, its most confusable neighbour, captures persistent identity and is stable across contexts. They are separate axes with separate schemas. See ADR 0018.

  • Published at: https://product-on-purpose.github.io/writing-style-catalog/schemas/v1/tone.schema.json
  • Freeze status: frozen (ADR 0019)
  • Composes: entry.universal.schema.json
FieldTypeRequiredNotes
axisno
markersarray of string (min 3)yesObservable textual markers that signal this tone
nn_g_profileenum: funny, neutral, seriousnoNielsen-Norman Group tone profile classification
spectrumstringnoWhich emotional or rhetorical spectrum this tone lives on (e.g., warmth, confidence, formality)
spectrum_positionnumbernoPosition on the spectrum (0 = one extreme, 1 = the other extreme)

Schema for voice entries (axis 1 of 4). Voice is the persistent identity of who is speaking, stable across contexts. Contrast tone, which varies per piece.

  • Published at: https://product-on-purpose.github.io/writing-style-catalog/schemas/v1/voice.schema.json
  • Freeze status: frozen (ADR 0019)
  • Composes: entry.universal.schema.json
FieldTypeRequiredNotes
axisno
default_povenum: first-person, second-person, third-person, variablenoDefault grammatical person
dictionstringnoVocabulary register: formal, casual, technical, vernacular, etc.
familyenum: expert, care, principal, witness, dissidentyesVoice family, grounded by communicative function (ADR 0010 sections 2 and 2a). No domain: a voice travels across spheres. Enum mirrors tools/taxonomy.py VOICE_FAMILIES. Required (F2 phase 3, tightened 2026-06-19).
language_patternsarray of string (min 3)yesObservable language patterns: sentence structures, word choices, rhythms
sentence_stylestringnoCharacteristic sentence construction
subfamilystringnoOptional third level, required once a family reaches 12 members (ADR 0010). For example care -> pastoral. Membership is checked by validate.py where the family enumerates subfamilies.
typical_tonesarray of stringnoTone IDs that frequently pair with this voice