DEV Community

Morgan Sun
Morgan Sun

Posted on

The Docs Ownership Split: What AI Drafts, What Humans Sign Off

A new endpoint shipped on a Tuesday. The AI docs generator produced 200 words of confident prose: "This endpoint returns 204 No Content on success." The code returned 201 Created. The reviewer skimmed, approved, and merged. Two incidents later, an engineer followed the docs and trusted the wrong response code.

That story repeats because of a category error. We treat AI-generated documentation as a finished artifact. It is not. It is a draft that happens to read like a final version.

Fluency is not accuracy. Code has a compiler; docs have nothing. So every confident mistake survives until a human hits it.

Why "Review the Diff" Fails for Docs

Most teams handle AI docs the same way they handle AI code: generate, skim, merge. That works for code because tests act as a safety net. Docs have no tests.

The review process needs a mechanism, not good intentions. My approach has three parts:

  1. A declared ownership policy for every docs folder
  2. A review trailer that records who verified an AI draft
  3. A CI check that rejects AI-drafted docs without that trailer

No policy buried in a README. No "please review carefully" reminders. A machine-enforced signal that makes the ownership split visible.

Decide What AI May Draft

Not all docs deserve the same treatment. Start with four categories:

Doc type AI may draft Human must own Minimum verification
API reference Yes Yes Run every sample against live code
Troubleshooting guide Yes Yes Reproduce each step in a clean environment
Migration guide Draft only Yes Dry-run on a staging dataset
Architecture Decision Record No Yes Written by the decision owner

The rule of thumb: if a wrong statement is expensive, let the AI draft but require a human to execute something. If the doc records judgment — an ADR, a roadmap call — the AI has no business drafting it.

The Ownership Manifest

The policy lives in a machine-readable file:

# docs/ownership.yml
categories:
  api-reference:
    path: "docs/api/**"
    drafter: "ai"
    reviewer: "human"
  architecture:
    path: "docs/adr/**"
    drafter: "human"
    reviewer: "human"
  troubleshooting:
    path: "docs/guides/**"
    drafter: "ai"
    reviewer: "human"
Enter fullscreen mode Exit fullscreen mode

Enforce it with a small script that checks every changed doc: if the category says drafter: ai, the file must contain a Reviewed-by trailer:

#!/usr/bin/env python3
"""Reject AI-drafted docs that lack a human review trailer."""
import re
import sys
from pathlib import Path

import yaml

OWNERSHIP_FILE = Path("docs/ownership.yml")
TRAILER = re.compile(r"^Reviewed-by:\s+.+$", re.MULTILINE)

def main(changed_files):
    rules = yaml.safe_load(OWNERSHIP_FILE.read_text())["categories"]
    failures = []

    for raw in changed_files:
        path = Path(raw)
        if path.suffix not in {".md", ".mdx", ".rst"}:
            continue

        category = next(
            (name for name, rule in rules.items() if path.match(rule["path"])),
            None,
        )
        if not category:
            continue

        rule = rules[category]
        content = path.read_text()
        has_review = bool(TRAILER.search(content))

        if rule["drafter"] == "ai" and not has_review:
            failures.append(f"{path}: drafted by AI but missing Reviewed-by trailer")

    if failures:
        print("\n".join(failures))
        sys.exit(1)
    print("All AI-drafted docs carry a human review.")

if __name__ == "__main__":
    main(sys.argv[1:])
Enter fullscreen mode Exit fullscreen mode

Hook it into a PR workflow:

# .github/workflows/docs-ownership.yml
name: docs ownership

on:
  pull_request:
    paths: ["docs/**", "docs/ownership.yml"]

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - run: pip install pyyaml
      - run: |
          python scripts/check_doc_ownership.py \
            $(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep '^docs/')
Enter fullscreen mode Exit fullscreen mode

Now a reviewer cannot "skim and merge" an AI draft by accident. The pipeline refuses.

The Drafting Step, on a Free Stack

To test the workflow for real, I ran three PRs against a small docs repo. The drafting backend was MonkeyCode's free model access, and the pipeline itself ran on MonkeyCode's free server option — no cloud function, no compute bill, just the repo and the manifest.

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

The practical result: the model produced the first prose pass, and review time went into verification, not generation. Across those three PRs, the pattern was consistent — more time spent fixing an AI-generated sample than confirming the behavior it documented. That is exactly what the manifest makes visible: verification becomes an explicit step, not an implicit assumption.

Limitations and Who Should Not Use This

The manifest catches one failure mode: AI drafts without a human sign-off. It does not:

  • Verify that the Reviewed-by trailer was honest. A reviewer can add it without running a single command.
  • Catch silent errors in human-drafted docs. The policy only gates AI drafts.
  • Protect against stale docs after merge. Ownership is verified at PR time, not at runtime.

Do not use this workflow if:

  • No human can actually verify the docs. A bot-enforced trailer is theater when nobody is accountable.
  • Your docs are generated deterministically from schemas. The ownership check adds friction without value.
  • You need docs for a regulated audit trail. A lightweight trailer will not satisfy compliance review.

What This Buys You

The ownership split does not make AI writing better. It makes the human half of the loop explicit.

When the pipeline fails, the reviewer has to confront one question: am I willing to sign this? That question is worth more than any amount of fluent prose.

Start small: pick one docs folder, keep the human reviewer for two weeks, and only then expand the drafting scope.

Top comments (0)