Command reference pages stay accurate when a human freezes captured help before any model writes surrounding prose. The frozen snapshot should own every flag, default, and exit phrase that a reader might copy into a shell. A model may draft sequencing advice, failure context, and cross-links that sit beside that signed snapshot. A local check should reject any draft that names a flag the captured help never printed.
Where command pages drift
Help text and narrative pages diverge whenever a writer remembers a flag that the current binary no longer prints. Readers then copy the switch, watch the process exit, and file a defect against the product rather than the page. The mismatch is local and measurable, because the token on the page is absent from the captured help text. Treating that mismatch as a matter of taste wastes time that a file comparison can settle in one pass.
Models raise the same risk because they often complete familiar command shapes from prior training patterns. A page about retries may gain --backoff even when this release only prints --max-attempts in help. That invented token looks careful during review, and it remains a false interface for anyone who copies it. The durable fix is a frozen inventory that the drafted page is not allowed to extend alone.
What humans own
Humans own the capture, the version pin, and every cell a reader might later execute unchanged. Models may own only connective explanation that does not add any new interface facts to the page. The table below is the contract for one command page, not a general policy for every document. Reviewers should treat empty human cells as blockers rather than as invitations for model completion later.
| Surface | Human must own | Model may draft |
|---|---|---|
| Flag names and short forms | Yes, from captured help | No |
| Defaults printed by help | Yes | Only as a quote from the inventory |
| Exit phrases you actually support | Yes, from tests or help | No |
| When to run the command | Supply constraints only | Yes, without new flags |
| Links already on an allow-list | Human supplies the list | Yes, from that list only |
Three inventory columns stay empty until a person fills supported-since, deprecated status, and the named owner. A model must not infer those three values from neighboring sentences inside the drafted command page. If help text omits a default, the page should say the default is unspecified in this snapshot. Guessing a missing default is an out-of-inventory fact, even when that guess looks plausible to reviewers.
Numbered workflow
1. Pin the binary and capture both streams
Record the binary version and the exact help stdout before anyone opens a documentation draft file. Store those captured files beside the page so later review can diff them without extra guesswork. Do not paste help from memory, from an older release branch, or from a model transcript. A missing capture file should block the draft, even when the command feels familiar to the author.
mkdir -p .docs/help
./mycli version > .docs/help/version.txt
./mycli retry --help > .docs/help/retry.help.txt 2> .docs/help/retry.help.err
# Linux example. On macOS, use: shasum -a 256
sha256sum .docs/help/retry.help.txt .docs/help/retry.help.err > .docs/help/retry.help.sha256
The commands above are a local pattern, not a claim about any particular shipped product binary. Replace the sample command name with the command binary that your repository actually ships today. If the useful text lands on standard error, set help_stream to stderr in the inventory header. Commit the checksum beside the help text so a later edit cannot swap the snapshot unnoticed.
2. Parse one dialect, then stop
Parse only the help dialect that your CLI actually prints, then stop for a human review. A narrow parser is safer than a universal one that guesses across argparse, clap, and custom layouts. The inventory is the artifact reviewers sign, and the markdown page stays downstream of that file. Do not ask a model to invent rows for flags that the captured help text never printed.
The fixture and parser below are a proposal for one line shape, and they remain an unexecuted example rather than a measured library. It expects an optional short flag, a long flag, a type token, a description, and an optional default in parentheses. Lines that do not match are ignored, which is a limitation you must review by eye. After parsing, a person still fills owner, support status, and any exit phrase the help text omitted.
Usage: mycli retry [options]
Options:
-n, --max-attempts int Maximum attempts before the command exits (default 3)
--timeout duration Wait limit per attempt (default 2s)
#!/usr/bin/env python3
"""Proposed parser for one help dialect. Unexecuted example, not a vendor tool."""
import json
import re
import sys
from pathlib import Path
LINE = re.compile(
r"^\s*(?:(-[A-Za-z]),\s*)?(--[a-z0-9][a-z0-9-]*)\s+(\S+)\s+(.*)$"
)
DEFAULT = re.compile(r"\s*\(default ([^)]+)\)\s*$")
def parse_line(raw: str):
match = LINE.match(raw)
if not match:
return None
short, flag, _kind, rest = match.groups()
found = DEFAULT.search(rest)
default = None
if found:
default = found.group(1)
rest = rest[: found.start()]
return {
"flag": flag,
"short": short,
"default": default,
"help_line": rest.strip(),
"supported_since": None,
"deprecated": None,
}
def parse_help(text: str) -> list:
return [row for row in (parse_line(raw) for raw in text.splitlines()) if row]
def main() -> int:
source = Path(sys.argv[1]).read_text(encoding="utf-8")
payload = {
"command": "mycli retry",
"binary_version": None,
"help_stream": "stdout",
"owner": None,
"flags": parse_help(source),
"exit_phrases": [],
}
Path(sys.argv[2]).write_text(json.dumps(payload, indent=2) + "\n", encoding="utf-8")
print(f"parsed {len(payload['flags'])} flags; human review is still required")
return 0
if __name__ == "__main__":
raise SystemExit(main())
A reviewed inventory for this sample help text would contain only --max-attempts and --timeout after parsing. The sample date in a header, if you add one, should record your capture time rather than this article's editorial date of 2026-10-13. Leave unknown cells null rather than asking a model to complete them from surrounding page context. Fill supported-since only after a person checks a release record that your team already trusts today.
3. Brief the draft inside a hard boundary
Give the model the signed inventory, an allow-list of headings, and an explicit ban on new flags. Ask for three sections only: when to run the command, how listed failures look in logs, and which approved links to mention. Tell it to quote defaults from the inventory inside backticks, using the exact phrase defaults to. Refuse any draft that adds a heading the writing brief did not name before generation started.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
MonkeyCode's free model access is enough for that bounded draft, because the inventory, not the model, carries the interface facts. MonkeyCode's free server option is a reasonable place to run the checker inside a clean worktree. Do not treat that server image as proof of the operating system your users actually run.
This method does not depend on a named model, a published quota, or a specific hardware shape. None of those product details are assumed, measured, or required before this local checker can run. If a vendor later changes availability, the inventory rule still stands on its own written terms. The same rejection rule can run in any environment that has Python 3.9 or newer and both input files.
4. Reject drafts that leave the snapshot
The checker below is a proposed local script, and this article does not report a production run. It scans long flags, short flags, and backtick defaults, then exits non-zero on any miss found. Keep the script in the repository so reviewers can run the same rule on every command page. Adjust the regular expressions only when your help dialect changes, and record that change in review.
#!/usr/bin/env python3
"""Proposed checker: fail command-page drafts that leave the help inventory."""
import json
import re
import sys
from pathlib import Path
# Long flags are matched in lowercase. Extend the class if your CLI emits capitals.
LONG_FLAG = re.compile(r"(?<![\w-])(--[a-z0-9][a-z0-9-]*)")
SHORT_FLAG = re.compile(r"(?<![\w-])(-[A-Za-z])\b")
DEFAULT = re.compile(r"defaults to `([^`]+)`", re.IGNORECASE)
def load(path: Path) -> dict:
data = json.loads(path.read_text(encoding="utf-8"))
flags = {item["flag"] for item in data["flags"]}
shorts = {item["short"] for item in data["flags"] if item.get("short")}
defaults = {
str(item["default"])
for item in data["flags"]
if item.get("default") is not None
}
return {"flags": flags, "shorts": shorts, "defaults": defaults}
def check(text: str, inv: dict) -> list:
errors = []
for match in LONG_FLAG.finditer(text):
token = match.group(1)
if token not in inv["flags"]:
errors.append(f"out-of-inventory long flag: {token}")
for match in SHORT_FLAG.finditer(text):
token = match.group(1)
if token not in inv["shorts"]:
errors.append(f"out-of-inventory short flag: {token}")
for match in DEFAULT.finditer(text):
value = match.group(1)
if value not in inv["defaults"]:
errors.append(f"out-of-inventory default: {value}")
return errors
def main() -> int:
inventory = load(Path(sys.argv[1]))
text = Path(sys.argv[2]).read_text(encoding="utf-8")
errors = check(text, inventory)
if errors:
print("\n".join(errors))
return 1
print("draft stays inside the frozen help inventory")
return 0
if __name__ == "__main__":
raise SystemExit(main())
python3 scripts/parse_help_inventory.py .docs/help/retry.help.txt .docs/help/retry.inventory.json
python3 scripts/check_command_page.py .docs/help/retry.inventory.json docs/commands/retry.md
A failing draft that mentions --backoff should print out-of-inventory long flag: --backoff and stop the merge. A passing draft may say that --max-attempts defaults to 3, because both tokens exist in the signed inventory. Keep the checker in the same pull request as the page so the rule cannot drift silently. Store one failing sample beside the script so a future edit can prove the rejection still fires.
Run `mycli retry` when a listed network error appears in the service log.
`--max-attempts` defaults to `3`.
Do not invent `--backoff` when the signed inventory has no such flag.
5. Merge prose without rewriting owned cells
Accept generated model text only inside the headings that the writing brief had explicitly allowed beforehand. Copy the flag table from the inventory with a generator, or paste it by hand from the signed file. Do not let the model rewrite the flag table, the version pin, or the named owner line. If the binary changes, recapture help, review the inventory diff, and only then request a new draft.
6. Repeat the capture for each subcommand
Treat each subcommand help file as its own inventory, because parent help often hides nested flags. A page for retry must not inherit flags that appear only under serve or migrate in a different snapshot. Run the same checker per page, and fail the build if two pages share one inventory by accident. This separation keeps a broad tutorial from carrying a flag into a reference section that never captured it.
Review outcomes
Use a small decision table so reviewers do not fix a failure by editing the inventory to match the draft. The inventory changes only when a new help capture shows the token, followed by a human signature. A missing explanation is not a failure of this check, because the check guards interface tokens rather than prose quality. Publish neither the command page nor the inventory file while the owner field is still null.
| Observed result | Inventory state | Required action |
|---|---|---|
| Out-of-inventory flag in the draft | Snapshot current | Reject the draft; do not add the flag to make the check pass |
| Quoted default absent from help | Snapshot current | Reject the sentence or mark the default unspecified |
| Help checksum changed | Not re-signed | Block publication until a person reviews the new capture |
| Flag present in help and absent from prose | Signed | Allow; this check does not demand full coverage |
owner is null |
Parsed only | Block publication regardless of a green token check |
Proposed test plan
The following cases are expected results for the proposed checker, not observed runs from a production documentation build. Case one uses a draft that names only --max-attempts and says it defaults to 3, and the expected status is exit code 0. Case two adds --backoff, and the expected status is exit code 1 with an out-of-inventory long flag message. Case three keeps the real flag but says it defaults to 10, and the expected status is exit code 1 on the default.
Case four removes short flags from the inventory and leaves -n in the draft, which should fail as an out-of-inventory short flag. Case five points the checker at a concept page with no flags, which should pass and still not prove the concept page is correct. Record these fixtures under scripts/testdata/ so a later parser change cannot silently widen the allowed surface. Run them in the same clean worktree you use for documentation review, whether that worktree is local or remote.
Limits of the method
The script does not understand every help layout, and a custom formatter can hide flags from a naive parser. Short-flag matching can mark ordinary prose when a hyphenated note appears outside an inline code span. Keep short flags inside code spans if you later tighten the expression to reduce those misses. Exit codes that never appear in help remain a human test concern, and this page check will not invent them.
A green run means the draft stayed inside one snapshot, not that the snapshot matches every customer install. Free model access does not make the inventory optional, and a free server does not freeze your release binary for you. You still need a person who can read help text and refuse an empty supported-since cell. Teams that change flags on every commit, without a version pin, will churn the snapshot faster than the page can settle.
Conceptual guides, architecture notes, and marketing pages are outside this method because they do not quote a command surface. Those pages can still use human review, but this checker would create false confidence about facts it never measured. Use a different ownership split when the page explains a concept instead of a command readers will type. The command-page rule should stay narrow so teams do not apply it to every document in the tree.
Who should skip it
Skip this workflow when the product has no stable command help, or when the page is a concept explanation rather than a reference. Skip it when nobody on the team can sign owner and supported-since before the page is published. Skip it if you need the model to discover undocumented flags, because that discovery is the defect this check exists to block. Internal experiments can still use the script as a proposal, but published command pages should wait for a signed inventory.
If you already draft reference pages with MonkeyCode, keep the help snapshot in the repository and run this checker before review. Publish the inventory diff in the same pull request so readers of the review can see which flags changed. That review habit matters more than whichever editor happened to produce the surrounding explanatory sentences for you. The page stays useful when every product mention is removed, because the inventory and the rejection rule do not depend on a particular editor.
Top comments (0)