Step 3 - Understand the draft
Goal: know what each part of the draft means, so your adjustments in step 4 are decisions, not guesses.
Kinds are types, and each kind is a claim
A kind (service, lib, adapter, ...) fixes two things: the doc shape (which sections are required) and the rule pack (which files feed the doc). When the survey groups your repo's packages into kinds, it is making a claim: every member of this kind is the same sort of thing and deserves the same treatment.
A kind carries an intension - a definition (what this population is) and a membership test (what is and is not a member). A good kind partitions its members cleanly. A kind whose definition needs an "or" to span two populations, or whose membership names two different naming conventions, is a bundle - it has quietly swept two kinds into one. Bundles are the classic failure: one frontend kind that came to hold domain SDKs, infrastructure packages, and leftovers, all while reporting itself complete. If the draft bundled, the survey should have flagged it; if it did not, step 4 is where you split it.
The coverage: line is the honesty check
When the source opts into coverage accounting, --check prints a coverage: line that puts every source element into one of three states:
- EXTRACTED - a rule pack reaches it. It will be documented.
- EXCLUDED - a recorded decision, with a written rationale, that this is not a documentable unit.
- UNKNOWN - a surfaced gap. Nobody has decided whether it is a unit or an exclusion.
UNKNOWN is remaining work, and a non-zero UNKNOWN is not "done". This is the mechanism that stops the silent-omission failure: extraction is a whitelist, and a directory nobody decided about is never opened, never bundled, and never missed - which is exactly how real packages went undocumented while a corpus reported itself complete. Every UNKNOWN forces a decision in step 4.
Exclusions carry rationales for a reason
An exclusion is a legitimate decision - not every directory is a documentable unit. But the schema rejects a rationale-less exclusion, because an exclusion with no reason is a silent ignore wearing a config hat. A good rationale is written for a reviewer who wants to disagree with you, and it cites evidence:
coverage:
exclude:
- path: examples/**
rationale: >-
Composition sandbox, not a shipped product (examples/README.md:3).When you read an exclusion in the draft, ask: could I disagree with this from the rationale alone? If yes, it is a good exclusion. If the rationale is an apology or a restatement of the path, it needs work.
Two warnings the check can raise
- A STALE exclusion matches nothing. It is a typo, or a decision that has already rotted as the code moved. Fix it; do not leave it.
- A coverage-reconcile requirement applies when a rule pack enumerates named input files rather than globbing a tree. Enumeration is the only pack style that can silently drop a source file, so it must be paired with
coverage.reconcile: true. The check tells you when this is missing.
How the two grains trade off
The survey's report names the unit grain it chose and the alternative it rejected. The trade is real and worth understanding:
- A member grain (one unit per workspace package) is accurate on package identity but drops anything that is not a member - a non-member service directory, a manifest-less preset.
- A coarser or glob grain can surface directories the member grain drops, catching exactly what the finer grain misses, at the cost of some identity precision.
Neither is strictly better. The right choice is the one that captures the units your repo actually has, and the report's coverage delta tells you what each grain costs. This is the decision you most want to get right, because it shapes everything the campaign documents later.
Next: step 4 - Adjust.