Nonfiction profile schema (nf-1)
Every nonfiction profile uses this schema: the same ten sections, the same rule fields, the same meanings. The writing agent uses it to know what to do. The reviewer uses it to know what to check. Both read the same rules the same way.
The schema is Voice Forge's own. It combines ideas from several research traditions (listed under each section and in Sources). No scholar proposed this exact list, and there is no single agreed schema for all nonfiction.
The exact file layout is in profile-format.md. vf.py validate checks it.
Reading a rule
Writers and reviewers both read this section. It is the contract.
A rule looks like this:
- R14 Introduce the paragraph's central claim before its numbers.
- strength: preferred
- kind: tendency
- applies: analytical body paragraphs in papers and reports
- except: paragraphs that describe data sets or methods
- check: In each applicable paragraph, find the central claim and the first number. PASS if the claim comes first.
- evidence: 20261005-1142, 20261007-0930, 20261009-1015
- status: approved 2026-10-09
The ID's letter tells its home: R for a profile rule, N for a "never" rule, B for a rule in base.md. The rule's category is the section it sits in.
| Field | Meaning |
|---|---|
| first line | The instruction: one action an agent can take. |
strength |
How binding it is (table below). |
kind |
How compliance is judged (table below). |
applies |
The texts, parts or situations the rule covers. all prose (or todo el texto) if it has no limit. |
except |
Cases the rule does not cover. none (or ninguna) if there are none. |
check |
What a reviewer looks at, and what counts as PASS. Observable, not a feeling. |
auto |
Optional. A mechanical check measure.py check can run. See Mechanical checks. |
evidence |
Round IDs, analysis:<id>, stated YYYY-MM-DD or adopted YYYY-MM-DD (analysis:<id>). |
status |
approved YYYY-MM-DD: the day the user said yes to the exact words. |
from |
Optional. The lesson it came from, such as L003. |
transfer |
Optional. How the rule behaves in another language: any, adapt, en-only or es-only. See Language scope. |
Strength
| Strength | Writer | Reviewer: severity of a violation |
|---|---|---|
mandatory |
Always do it where it applies. | high |
prohibited |
Never do it where it applies. | high |
preferred |
Do it unless the task or a clear reason says otherwise. | medium |
optional |
Allowed and typical; use it when it fits. | low; absence is never a violation |
Kind
| Kind | What it is | How the reviewer judges it |
|---|---|---|
constraint |
A yes or no condition true of every instance. | One clear breach is a VIOLATION. |
tendency |
A habit measured over the whole text, such as sentence length. | Judge the text as a whole. One long sentence is not a violation of "keep sentences short". |
preference |
A matter of judgment, such as tone. | VIOLATION only with a clear, quotable reason. Otherwise UNCERTAIN. |
A measurement describes a habit. It is not a hard limit. "Your sentences average 18 words" becomes a tendency, never "every sentence under 18 words".
Scope, exceptions and the task
Apply a rule only where applies covers the text and no except case holds. Some rules do not fit a task at all: argument rules do not apply to a two line scheduling email. Then the rule is NOT APPLICABLE for that task. That is a decision about the task, not about the profile.
When rules conflict, follow the rule order in SKILL.md section 4. Within a profile, mandatory and prohibited beat preferred, and preferred beats optional.
Do not invent requirements. If no rule covers something, it is free.
Support
vf.py export derives a support label from the evidence. Nobody types it.
| Support | Evidence |
|---|---|
trained |
3 or more rounds on 2 or more topics, or 2 rounds on 2 topics plus an analysis. One analysis is enough; more analyses never replace rounds |
stated |
The user stated the rule (stated ...) |
adopted |
The user adopted a suggestion (adopted ...) |
thin |
Less than the above; allowed because the user approved it, but test it in training |
transferred |
Copied from a profile in another language (transferred from ...); not yet confirmed here |
confirmed |
Transferred, then confirmed by a training round in this profile |
Section status
Each of sections 2 to 10 has a status line:
established: the section has one or more approved rules.unknown: no rules yet, because there is not enough evidence or training. This is the normal start.not_applicable: the section does not fit the profile's purpose. Give the reason. Never use it just because nothing was collected yet.
A profile is complete in structure even when most sections are unknown.
The ten sections
Each section lists what it covers, what code can measure, and what needs judgment. The lesson category slug is in brackets.
1. Identity and context [identity]
The brief. Agents read it to pick the profile and to judge conventions.
- Language and register (Biber and Conrad: register is language shaped by its situation of use).
- Genre and document types, purpose and readers (Swales: a genre is defined by its communicative purpose and its community of readers).
- Field, venues and conventions the user follows.
- Scope: when to use this profile and when not.
2. Document architecture [architecture]
How a whole document is organized.
- Overall structure, and the usual sequence of sections and moves.
- Introductions and conclusions.
- Moves such as framing a problem, defining terms, explaining, synthesizing.
- How structure changes by genre within the profile.
- Formatting that organizes the text: headings, lists, boxes, tables and captions. (Banned formatting goes to section 10.)
Source: Swales's move analysis (a move is a stretch of text that does one job, such as "establish a gap"). Judgment: the agent labels moves. Code cannot.
3. Argumentation and reasoning [argument]
How claims are made and supported.
- Where the central claim appears and how it develops.
- Premises, evidence, warrants and conclusions.
- Objections, counterarguments, rebuttals and qualifications.
- Preferred patterns of explanation and reasoning.
Source: Toulmin's model (claim, data, warrant, backing, qualifier, rebuttal) and later work on argument schemes. Judgment only.
4. Paragraphs [paragraphs]
How a paragraph is built.
- Length and its variation. Code measures words and sentences per paragraph.
- Topic sentences and where the main claim sits.
- How ideas progress inside the paragraph: explanation, evidence, example, comparison.
- Where support goes, how paragraphs end, and how one leads to the next.
Source: there is no single standard model of the paragraph. This section applies discourse relations and thematic progression (section 5) at paragraph scale. Mostly judgment, plus length measures.
5. Discourse and coherence [discourse]
How ideas connect.
- Relations: elaboration, contrast, concession, justification, cause and effect.
- Transitions between sentences, paragraphs and sections.
- Thematic progression: how each sentence picks up what came before.
- Which information is central and which supports it.
Source: Rhetorical Structure Theory (Mann and Thompson: texts hold together through relations between a central part, the nucleus, and a supporting part, the satellite) and Daneš's thematic progression. Judgment, with connector counts as a hint.
6. Sentences and rhythm [sentences]
How sentences are built.
- Sentence length, its spread and variation. Code measures these.
- Syntactic complexity: coordination, subordination, dense noun phrases.
- Recurring constructions, such as parallelism, when the evidence shows them.
- Rhythm and deliberate variation.
Source: Biber and Conrad's corpus methods; Biber, Gray and Poonpon on phrasal versus clausal complexity in academic writing. Length is measured; constructions need judgment.
7. Vocabulary and register [vocabulary]
Which words the user picks.
- Preferred and avoided words and phrases.
- Technical terms and how they are introduced.
- Lexical diversity and repetition. Code gives a moving average type token ratio (MATTR: the share of different words in each 50 word window).
- Abstraction and sophistication; changes by audience.
Source: Biber and Conrad (lexical features of registers); Covington and McFall (MATTR).
8. Voice and metadiscourse [voice]
How the author shows up and treats the reader.
- Tone and position toward the topic.
- Stance: hedges ("may", «quizás»), boosters ("clearly"), attitude, self mention ("I", "we").
- Engagement: direct address, questions, directives, appeals to shared knowledge.
- Talk about the text itself ("This section shows...").
Source: Hyland's metadiscourse and his model of stance and engagement. Code counts hedges, boosters, first person and questions per 1,000 words as hints; the meaning needs judgment.
9. Evidence and sources [evidence]
How numbers, data and other people's work appear.
- How numbers are introduced and interpreted.
- How empirical evidence is woven in.
- Citation patterns: integral ("Smith (2020) shows") or non integral ("(Smith 2020)"), reporting verbs, quotations.
- How uncertainty and limits are stated.
Source: Swales (integral and non integral citation); Hyland on citation across disciplines. Judgment.
10. Anti-patterns and constraints [constraints]
What the user rejects outright.
- Rejected words, phrases and constructions.
- Unwanted rhetorical habits.
- Banned punctuation or formatting.
- Other restrictions the user approved.
Source: the user's own statements, plus the slop rules. Most rules here are prohibited constraints, often with an auto check.
Mechanical checks
The optional auto field lets measure.py check test a rule by code. One check per rule:
| auto | Passes when |
|---|---|
no-dashes |
No em or en dash, and no spaced hyphen, is used as punctuation |
angle-quotes |
Spanish text uses «» for first level quotes, never English quotes |
no-phrase "a" "b" |
None of the phrases appears (case is ignored). Quote each phrase with "", “” or «» |
no-paragraph-start "a" «b» |
No paragraph starts with any of the phrases (case is ignored) |
no-regex PATTERN |
The pattern (a Python regular expression) never matches the writer's own words; quoted text is skipped |
max-sentence-words N |
Every sentence has N words or fewer |
max-paragraph-words N |
Every paragraph has N words or fewer |
max-paragraph-sentences N |
Every paragraph has N sentences or fewer |
mean-sentence-words A-B |
The average sentence length is between A and B |
share-sentences-over N P |
At most P percent of sentences have more than N words |
Code cannot see scope or exceptions. When applies is narrower than all prose, except is not none, or the rule is not a constraint, a mechanical VIOLATION is a lead for the reviewer, not a verdict.
Language scope and derived profiles
Most of a writer's habits travel across languages: how they build an argument or a paragraph. Some do not: a Spanish phrase, «» quotes, tú or usted. The optional transfer field records which is which.
| Value | Meaning |
|---|---|
any |
Works in every language as it is (after translation) |
adapt |
The idea travels, but wording, examples or numbers must change |
en-only, es-only |
Belongs to one language |
Two uses:
- In
base.md: a rule markedes-onlyapplies to every Spanish profile and is skipped in English ones. Use it for language habits true in all the user's writing, such as «» in Spanish. - When deriving a profile in another language (derive.md):
anyandadaptrules are copied and adapted; language-only rules stay behind. When a rule has no label, derive uses the section's default: architecture, argument, paragraphs, discourse and evidence areany; sentences, vocabulary, voice and constraints areadapt.
A derived profile has derived_from: <source>@<version> and stage: provisional in its front matter. It is a starting point: its rules are transferred until training confirms them. vf.py make-official ends the provisional stage. Profiles without stage are official.
Profile types
The front matter's type says which schema applies:
nonfiction: this schema.vf.py validateenforces it.fiction: not defined yet. Validation checks only the rule fields.unclassified: a profile whose scope is not decided. Validation checks only the rule fields and asks the user to classify it.
Sources
- Biber, D. and Conrad, S. (2009). Register, Genre, and Style. Cambridge University Press.
- Biber, D., Gray, B. and Poonpon, K. (2011). Should we use characteristics of conversation to measure grammatical complexity in L2 writing development? TESOL Quarterly 45(1).
- Covington, M. and McFall, J. (2010). Cutting the Gordian knot: the moving average type token ratio (MATTR). Journal of Quantitative Linguistics 17(2).
- Daneš, F. (1974). Functional sentence perspective and the organization of the text. In Papers on Functional Sentence Perspective. Academia.
- Hyland, K. (2005). Metadiscourse: Exploring Interaction in Writing. Continuum.
- Hyland, K. (2005). Stance and engagement: a model of interaction in academic discourse. Discourse Studies 7(2).
- Mann, W. and Thompson, S. (1988). Rhetorical Structure Theory: toward a functional theory of text organization. Text 8(3).
- Swales, J. (1990). Genre Analysis: English in Academic and Research Settings. Cambridge University Press.
- Toulmin, S. (1958). The Uses of Argument. Cambridge University Press.
- Walton, D., Reed, C. and Macagno, F. (2008). Argumentation Schemes. Cambridge University Press.