Generated documentation fails when a model is allowed to invent the facts a maintainer must defend. The useful split is operational rather than stylistic, so reviewers should fix it before any drafting starts. A model may draft page structure, section transitions, and code examples that stay labeled as unexecuted proposals.
A human must own versions, limits, security boundaries, and any availability statement a reader might rely on. Teams that skip that split ship pages that read smoothly and still misstate what the product currently offers. This workflow keeps the generated draft useful without treating raw model output as a source of record.
Why generated setup pages drift
A setup page mixes local procedure with product claims, and those two kinds of sentences age differently. Local commands can be checked against a repository at a known commit, while quotas and server offers change outside that commit. If the model writes both kinds in one pass, reviewers tend to edit tone and miss an unsupported number. The failure is measurable as a count of unowned claims rather than as awkward or unfinished prose.
Public write-ups of generated personal sites show the same ownership gap under a different page format. A page can look finished while its factual layer was never assigned to a named person. Documentation teams should treat that pattern as a review defect, not as a reason to ban drafting tools. The remedy is a register that decides ownership before any generated paragraph is accepted into the branch.
What the model may draft
Reviewers should use the table below as a merge gate rather than as a prose style guide. A sentence moves to the model only when a false statement would be caught by a local test or an explicit proposal label. Everything else stays with a named human owner until a primary source is attached to the row.
| Claim type | Model may draft | Human must own | Gate before merge |
|---|---|---|---|
| Heading outline and section order | Yes | Reviews the outline | No product facts inside headings |
| Explanation of code already in the repo | Yes, if cited to a path | Confirms path and commit | Link the file and revision |
| Commands marked as unexecuted proposals | Yes, with a proposal label | Decides whether to run them | Do not present them as measured results |
| Version pins, API names, and default flags | No | Yes | Quote the repo or upstream docs |
| Quotas, duration, hardware, and price | No | Yes | Attach a current primary source or omit |
| Security boundaries and data handling | No | Yes | Name the control and the owner |
| Rankings and permanence language | No | Yes | Refuse unsupported comparisons |
Quotas, durations, hardware notes, and model menus stay in the human-owned lane even when a vendor brief sounds specific. A reviewer copies those sentences only from a primary page retrieved on the publication day, and stores that URL on the row. If that page is silent, the generated draft must not invent a number to make the setup section feel complete. The same block applies to rankings, permanence language, and any claim that becomes false if the offer changes tomorrow.
Worked classification
Consider these three sentences that often land together in a generated setup guide for a hosted tool. The first sentence lists local files the reader will edit, and it can be drafted if the paths exist at the frozen commit. The second sentence says a free server option exists, and it stays human-owned until the current documentation URL is stored on the row. The third sentence names a token quantity, and it is blocked until a primary source states that quantity on the day of publication.
That third block is deliberate, because an outreach brief is not a primary source and can go stale before review finishes. The same rule covers hardware shapes, time limits, model identifiers, and any ranking against other tools. If the source is missing on publication day, the page ships without the sentence instead of shipping a guessed figure.
Numbered workflow
Follow the six steps in order, and do not ask a model for prose until the register rows exist.
- Freeze the source set by recording the repository commit, the document path, and every product page a human will cite.
- Extract candidate sentences so each claim occupies one line and can receive an owner stamp before generation.
- Classify each line as model_draft, human_own, or blocked, and attach a source to every current human-owned fact.
- Draft only open lanes by requesting headings, transitions, and proposal-labeled examples, then paste frozen human lines back unchanged.
- Diff the draft against the register, and fail the page when a blocked claim appears or a human line was paraphrased.
- Require approval from a person who can defend the product facts, and keep model output marked as a draft until that approval.
The sequence stays intentionally strict because generation is cheap and a later public correction is expensive. A reviewer who cannot explain a human-owned row should send the page back before any model sentence is expanded. Shared notes from that rejection belong in the register, not in a chat transcript that the next draft can quietly drop.
Register checker
The script below is a local review proposal, and it is not a record of an executed benchmark. It reads a JSON register and a markdown draft, then exits non-zero when unowned product language sits outside stamped lines. Adapt the forbidden token list to your own unsupported claims rather than treating the sample list as a product specification. Store the checker under tools so the same command can run in review and on a shared server workspace.
#!/usr/bin/env python3
"""Proposal: flag unowned product claims in a generated doc draft."""
import json
import sys
import re
FORBIDDEN = re.compile(
r"\b(quota|tokens?|gpu|sla|permanent|unlimited|benchmark)\b",
re.I,
)
def load(path):
with open(path, encoding="utf-8") as handle:
return json.load(handle)
def main(register_path, draft_path):
register = load(register_path)
draft = open(draft_path, encoding="utf-8").read()
owned = [
row["text"]
for row in register["claims"]
if row["lane"] == "human_own"
]
errors = []
for row in register["claims"]:
if row["lane"] == "human_own" and row["text"] not in draft:
errors.append("missing owned line: %s" % row["id"])
if row["lane"] == "blocked" and row["text"] in draft:
errors.append("blocked line present: %s" % row["id"])
residue = draft
for text in owned:
residue = residue.replace(text, "")
for match in FORBIDDEN.finditer(residue):
errors.append("unowned term in draft residue: %s" % match.group(0))
if errors:
print("\n".join(errors))
return 1
print("register check passed")
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1], sys.argv[2]))
A matching register should stay small enough that a reviewer can read every owned sentence during the same pass. Each row names the lane, the exact sentence a human will defend, and the source that justified the stamp. Replace the placeholder commit and URL before the checker is allowed to pass in a real review.
{
"commit": "REPLACE_WITH_REVIEWED_SHA",
"claims": [
{
"id": "avail-1",
"lane": "human_own",
"text": "Operator-stated options are free model access and a free server option.",
"source": "REPLACE_WITH_CURRENT_PRODUCT_DOC_URL"
},
{
"id": "quota-1",
"lane": "blocked",
"text": "The free tier includes a fixed token quantity.",
"source": null
}
]
}
Run the checker from the repository root after the draft exists, and treat a non-zero exit as a merge block. A zero exit only means the scanned strings matched the register, not that the claims are true. Link checks, example execution, and legal review remain separate gates that this script does not pretend to cover.
mkdir -p tools docs
python3 tools/doc_ownership_check.py docs/register.json docs/setup.md
An unexecuted expectation is a non-zero exit when the draft residue contains the word quota outside a human-owned line. A clean draft that repeats only stamped lines, and avoids the forbidden list elsewhere, is expected to print the pass line. Those expectations were not executed for this article, so a team should run them on a fixture before trusting the gate.
Where a free drafting pass fits
Disclosure: This article was prepared as part of MonkeyCode's product outreach. MonkeyCode enters this method only as the drafting workspace those two operator-supplied options are meant to cover. A free model access option and a free server option are the two availability claims the operator supplied for this workflow. Neither option is a quota, a hardware profile, a duration, or permission to skip the ownership stamp.
A free model is enough for the drafting step because that step is forbidden from creating product facts. A free server is enough when reviewers need one workspace that holds the register, the draft, and the checker. Readers should confirm both options in the current project documentation before a setup page repeats them. If a repository is the source of truth for licensing, cite that repository instead of restating license terms from memory.
Limitations
This checker is a string gate, so a paraphrase of a blocked claim can still pass after forbidden words are removed. It does not execute examples, verify links, or prove that a cited page still matches the register from yesterday. Teams should not treat a passing run as compliance certification, a security review, or a substitute for reading. Authors who cannot name a human owner for an availability claim should omit that claim instead of drafting around it.
Who should skip this approach
Skip the workflow when the page is a personal log that states no product facts a stranger might rely on. In that case the register adds ceremony without reducing the risk of an unsupported public statement. Skip it when legal or security copy must come from counsel, because a documentation lane is the wrong owner. Also skip it when the only goal is to maximize mentions of a tool, because the page must stay useful without those mentions.
If the ownership split is the constraint you actually have, rehearse the six steps on one setup page before expanding the register. Keep the product mention to the single sentence a human can still defend after every model sentence is removed. That remaining sentence should point readers to current project documentation rather than freeze a quota, a duration, or a hardware claim.
Top comments (0)