DEV Community

Avery Lin
Avery Lin

Posted on

Own the Contract, Draft the Noise: A Zero-Cost Docs Workflow

Disclosure: This article was prepared as part of MonkeyCode's product outreach.

Most AI-generated documentation fails not because the model is weak, but because the organization never defined which paragraphs the model may touch and which ones it must never touch. A free model can draft a convincing explanation of a function, yet that same model will happily rewrite a stable API contract into something plausible but wrong. The practical fix is not better prompting; it is a tiered ownership model enforced by a cheap, scriptable check that runs alongside your normal documentation workflow.

The Real Failure Mode of AI-Generated Docs

When a team gives an AI assistant unrestricted access to a documentation repository, the resulting PRs look clean but often drift from the code in subtle ways. Function signatures change, error codes get renamed, and optional parameters become required in the narrative without any corresponding source change. The doc review then becomes a full manual diff against the implementation, which is precisely the work the team wanted to avoid. I have seen this pattern repeat across small projects where nobody owns the contract and the model owns the narrative.

The alternative is to stop treating the model as a general-purpose writer and start treating it as a constrained drafter. Instead of asking the model to "write the docs," you give it a preset for each tier of content: mechanical descriptions, explanatory passages, and strategic context. The preset defines what the model may invent, what it must copy verbatim from verified sources, and what it must never modify. This turns prompting from a lottery into a workflow.

A Three-Tier Ownership Model

Tier 1 is the stable contract: function signatures, return types, error codes, and configuration keys. The human maintainer owns every byte of this tier, and the model is allowed to propose changes only when it has been explicitly told to reflect a specific source commit. Tier 2 is the mechanical narrative: parameter explanations, usage examples, and troubleshooting steps that follow from the contract. A model can draft these efficiently, but a technical writer must approve them because examples carry assumptions about runtime behavior. Tier 3 is the strategic layer: design rationale, migration history, and future roadmap. This tier needs a named human author who can defend the reasoning, even if the model provides a first draft.

The critical distinction is not quality or effort; it is reversibility. A wrong Tier 3 paragraph is annoying but recoverable, while a wrong Tier 1 signature silently breaks every downstream consumer. So the workflow should enforce Tier 1 with automation, Tier 2 with review, and Tier 3 with authorship. On a zero-dollar budget, you can automate the Tier 1 check using free model access to generate the draft and a free server to run a small validation script.

The Free-Tier Artifact: A Contract Checker

The reference implementation below is a tiny Python script that scans your source tree for function definitions, extracts their exact signature text, and then verifies that any documentation block marked with <!-- TIER1 --> contains those exact signatures. It uses only the standard library and runs on Python 3.9+, so the free server option included with your AI workflow is sufficient to execute it on a daily schedule or before every doc merge.

#!/usr/bin/env python3
"""contract_check.py - verify TIER1 docs match source signatures."""
import ast
import re
import sys
from pathlib import Path

SOURCE_DIR = Path("src")
DOCS_DIR = Path("docs")

def extract_signatures(path: Path) -> set[str]:
    tree = ast.parse(path.read_text(encoding="utf-8"))
    sigs = set()
    for node in ast.walk(tree):
        if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
            try:
                args = ast.unparse(node.args)
            except AttributeError:
                continue
            name = node.name
            sigs.add(f"def {name}({args})")
    return sigs

def collect_source_signatures() -> set[str]:
    all_sigs = set()
    for py_file in SOURCE_DIR.rglob("*.py"):
        try:
            all_sigs.update(extract_signatures(py_file))
        except SyntaxError as e:
            print(f"[skip] syntax error in {py_file}: {e}")
    return all_sigs

def check_doc_tier1(source_sigs: set[str], doc_file: Path) -> list[str]:
    errors = []
    text = doc_file.read_text(encoding="utf-8")
    # Only inspect blocks between TIER1 markers.
    for block in re.findall(r"<!-- TIER1 -->(.*?)<!-- /TIER1 -->", text, re.S):
        code_blocks = re.findall(r"```

python\n(.*?)

```", block, re.S)
        for code in code_blocks:
            for match in re.finditer(r"^(.*?)\n", code, re.M):
                line = match.group(1).strip()
                if line.startswith("def ") and line not in source_sigs:
                    errors.append(f"{doc_file}: signature `{line}` not in source")
    return errors

def main() -> int:
    if not SOURCE_DIR.exists():
        print(f"{SOURCE_DIR} not found");
        return 1
    source_sigs = collect_source_signatures()
    all_errors = []
    for md_file in DOCS_DIR.rglob("*.md"):
        all_errors.extend(check_doc_tier1(source_sigs, md_file))
    if all_errors:
        print("\n".join(all_errors))
        return 1
    print("OK: all TIER1 signatures match source.")
    return 0

if __name__ == "__main__":
    sys.exit(main())
Enter fullscreen mode Exit fullscreen mode

This script does not check parameter defaults, return annotations, or error codes, but you can extend the extract_signatures function to parse those as well. The important part is the pattern: documentation that declares itself as stable must be mechanically comparable to the code. Once you have that property, you can confidently let the model draft everything below that boundary.

Step-by-Step: Run the Checker on Any Free Server

The following procedure assumes you already have a repository with a src/ folder of Python files and a docs/ folder of Markdown files. It takes about fifteen minutes to set up and then runs unattended.

  1. Create the script file at scripts/contract_check.py and make it executable with chmod +x. Place your source files under src/ and your documentation under docs/.
  2. Wrap each stable part of your documentation with <!-- TIER1 --> and <!-- /TIER1 --> comments. Inside those markers, include the exact Python function signatures that you expect to exist in the source.
  3. Run the script locally: python scripts/contract_check.py. It will print the exact signatures that are missing or mismatched, so you can correct the docs before any model ever sees them.
  4. Register the script as a pre-merge gate in your CI system. Because it is pure Python with no dependencies, you can run it inside a simple container on whatever free server you already use, including the one in your AI tool subscription.
  5. Add a daily cron job on that free server that runs the same script and emails the output. This catches a Tier 1 violation performed by an overconfident model that edited a non-marked block or a human who forgot the markers.

The script becomes the enforcement arm of your ownership policy. The model is still free to draft Tier 2 and Tier 3 content, but the moment it touches a signature inside a Tier 1 block, the pipeline fails with a precise diff instead of a silent semantic drift.

Decision Table: Who Approves What

Tier Example content Model can draft? Human approval needed? Automated gate?
1 Function signatures, return types, error codes Only when directed by a specific source commit Yes, maintainer must verify Must match AST from source
2 Parameter explanations, usage examples, troubleshooting Yes, with source-verbatim snippets Yes, technical writer Spell and example sanity checks
3 Architecture rationale, migration history, roadmap Yes, as a first draft Yes, named author No gate, but authorship recorded

This table is deliberately simple. Complex projects may need a fourth tier for generated compatibility layers or a special category for internal vs. external documentation, but the underlying principle stays the same: stable content is owned by the human and verified by a machine; explanatory content is owned by a reviewer; strategic content is owned by an author.

Limitations and Who Should Skip This

This approach assumes your documentation has a clear separation between code-adjacent facts and narrative, which is not true for every project. If your docs are purely conceptual and never reference concrete functions, the Tier 1 checker gives you almost no value. The script also works only with Python signatures by default; rewriting it for TypeScript or Rust requires a different AST parser, though the structure of the check remains identical. Finally, the markers are a manual convention, so a contributor who forgets to add <!-- TIER1 --> will accidentally give the model full freedom over that section.

Teams that do not have a single maintainer responsible for API stability will still struggle, because the script only detects mismatches after the fact. It does not prevent the model from generating a beautiful but incorrect paragraph in Tier 2; it only stops the most dangerous class of error. If you need a complete guardrail, pair this with a conventional code review process where one human reads every diff, even if that human is the same person who pressed the merge button.

Final Thought

The cheapest way to make AI-generated documentation trustworthy is not to invest in better models. It is to invest in a boundary that separates stable contracts from explorable prose, then enforce that boundary with a trivial script on a free server. The model drafts the noise, the human owns the contract, and the CI output tells you exactly when the noise starts leaking into the signal. If you already have a doc repo, start by adding the Tier 1 markers to your most critical API reference page and run the checker once; the resulting failure list is the first honest map of what your AI has been quietly changing.

Top comments (0)