Skip to main content
Doctorine
Menu

Docs as code guide

Docs as code is a release discipline, not a Git repository.

A sound docs-as-code workflow reviews API behavior, OpenAPI, prose, examples, generated reference, SDKs, and the deployed portal as one change. Git provides history and review. It does not keep those surfaces accurate by itself.

Author
Aria Shishegaran
Accountable owner
Aria Shishegaran
Review scope
Product claims and release systems
Published
Modified
Last tested
Refresh due
Product commit
abfc80e446cf

The short answer

Treat documentation as part of the API release. Put authored content and the API description under version control, generate dependent surfaces from accepted inputs, test the developer’s path, review one immutable preview, and activate an identifiable build. The workflow is healthy when a reviewer can answer four questions: what changed, why it changed, which developer tasks are affected, and which exact output reached production.

This does not mean every sentence belongs in OpenAPI. The specification can describe paths, operations, parameters, schemas, responses, and security requirements. It is not a substitute for conceptual guidance, migration advice, runnable tutorials, or implementation tests. The current OpenAPI Specification defines a machine-readable interface description; your release process must connect that description to real behavior and human learning material.

A repository boundary that stays legible

There is no universal folder layout. The important distinction is authored input versus generated output. This small example lets reviewers find the contract, prose, examples, and release policy without treating built HTML as editable content.

api/
  openapi.yaml              # accepted HTTP contract
docs/
  quickstart.md             # authored developer task
  authentication.md
  errors.md
examples/
  create-widget.sh          # executed in CI
policy/
  review-owners.yaml
  release-gates.yaml
generated/                  # build output; never hand-edited
  reference/
  sdk-manifest.json
  mcp-manifest.json

Markdown syntax can follow the current CommonMark specification, but consistency matters more than choosing every extension. Document any custom components and keep essential instructions readable in plain source so a format migration does not trap the knowledge.

Seven-stage workflow

Carry one change from behavior to release evidence

The stages are ordered because each later check depends on a trustworthy input and an explicit owner. Adapt the tools, but keep the evidence chain intact.

  1. Define ownership before choosing tools

    Write down who owns the API behavior, the OpenAPI contract, conceptual guides, code examples, generated outputs, and release approval. One person can hold several roles, but every artifact needs one accountable owner. This prevents the common stalemate where engineering assumes writers maintain the contract while writers assume the generated reference is authoritative.

    Required evidence: Receipt: a CODEOWNERS or review-policy entry that routes contract, guide, and release changes to the right reviewers.

  2. Keep authored and generated material visibly separate

    Store prose, examples, and the OpenAPI input in source control. Write generated reference, SDK output, and built HTML to deterministic build directories or artifacts. Do not invite editors to repair generated files by hand. If a generated description is wrong, fix the contract or the transform and rebuild. A clean boundary makes reviews meaningful and keeps the repository from acquiring hidden sources of truth.

    Required evidence: Receipt: a clean rebuild leaves the working tree unchanged and regenerated output has a recorded input hash.

  3. Change the contract with the implementation

    When behavior changes, update the API implementation and the OpenAPI description in the same work item. Add or revise operation identifiers, parameters, schemas, examples, security requirements, and error responses. OpenAPI is a language-agnostic description of an HTTP API, but it cannot prove the service behaves as described. Contract tests and implementation tests still own that proof.

    Required evidence: Receipt: CI validates the description and exercises representative requests against the implementation or a controlled test environment.

  4. Update the learning path, not only the reference

    A new field in a schema may need no prose. A new authentication flow, retry rule, pagination model, or lifecycle state does. Review quickstarts, task guides, error handling, migration notes, and changelog entries from the developer’s point of view. The reference answers what exists. A guide must explain when to use it, what to send, what success looks like, and how to recover.

    Required evidence: Receipt: the pull request names every affected developer task and either updates it or records why no change is needed.

  5. Generate every dependent surface from the accepted input

    Build API reference, code samples, SDKs, and machine-readable agent artifacts from the same accepted contract. Generation should fail on missing required identities or invalid shapes rather than inventing names silently. When a transform applies a convention, record that convention. A reviewer must be able to trace a public method or tool back to the operation that produced it.

    Required evidence: Receipt: generated surfaces share stable operation identities and include toolchain or provenance evidence.

  6. Review the diff as a developer experience

    A file diff catches syntax changes but not a broken onboarding path. Preview the rendered portal. Run the first quickstart request with a test credential. Compile at least one generated client. Inspect a representative agent tool schema. Check mobile navigation, internal links, error examples, and copy-paste commands. Make the preview immutable so every reviewer sees the same output.

    Required evidence: Receipt: the review links to one preview and records the request, SDK, link, and accessibility checks that passed.

  7. Publish an identifiable, reversible release

    Tie the deployed portal and generated artifacts to a version, commit, or content hash. Activate only the reviewed build. Preserve the previous release long enough to roll back without rebuilding from mutable inputs. After deployment, request the quickstart against production, inspect the canonical URL, and confirm that the deployed reference matches the accepted contract.

    Required evidence: Receipt: a release record connects source revision, contract digest, build result, activation time, and rollback target.

The pull-request gate

Copy this checklist into the repository policy or pull-request template. Keep each item binary enough that a reviewer can cite evidence instead of answering “looks good.”

  • The change names one developer task and one expected outcome.
  • API behavior and OpenAPI changes are reviewed together when both are affected.
  • Generated files were rebuilt from accepted inputs, not edited directly.
  • Authentication, pagination, errors, retries, and versioning are updated where relevant.
  • At least one request and one generated sample or client path were executed.
  • The rendered preview is keyboard usable, readable on mobile, and free of broken links.
  • Public claims are backed by current behavior; planned features are not written in present tense.
  • The release has an input revision, output identity, activation record, and rollback target.

Run the build twice, then prove that it reverses

Start from a clean worktree and install from the locked dependency file. Validate the OpenAPI document, build every generated surface, and record the source commit, tool versions, input digest, and a sorted digest manifest for the outputs. Delete the generated directory and repeat the build without changing the input. The two manifests should match byte for byte. If they do not, inspect timestamps, random identifiers, unstable object-key order, network-fetched templates, and environment-dependent paths before accepting the workflow as reproducible.

Next, change one schema field on a temporary branch and rebuild. Review which reference pages, samples, and client artifacts changed. An unrelated output change usually reveals a hidden input or an overly broad transform. Run the affected quickstart against a controlled environment and compile the changed client path. Then revert the contract change, rebuild again, and compare the output manifest with the original. A reversible input should restore the original output; a stale file left behind is a release defect, even when the site still renders.

Store the three manifests and the request or compilation result with the preview. This gives a reviewer evidence for determinism, impact scope, and rollback instead of one undifferentiated “build passed” signal. Keep credentials and response bodies containing customer data out of the receipt.

Failure modes to inspect before launch

Most docs-as-code failures are governance failures disguised as tooling problems. Look for the symptom in the built and deployed experience, then repair the ownership or evidence step that allowed it.

The portal repository becomes the API source of truth
Symptom: Reference pages contain fixes that never reach the contract or service.
Response: Make generated reference read-only. Route corrections back to the OpenAPI input or implementation and verify a clean rebuild.
A passing build is mistaken for accurate documentation
Symptom: The site renders, but examples use stale fields or the quickstart cannot complete.
Response: Add behavior checks: execute a representative request, compile samples, and compare documented errors with controlled responses.
Every change requires every reviewer
Symptom: Small prose corrections wait behind platform and security approvals.
Response: Use path and risk-based review rules. Authentication, schema compatibility, and public claims need specialist review; punctuation does not.
Generated files swamp the pull request
Symptom: Reviewers cannot see the authored change among thousands of mechanical lines.
Response: Review source changes first, attach a generated summary, and publish large outputs as build artifacts unless consumers require them in Git.
Git access becomes the only authoring path
Symptom: Subject experts avoid improvements because local setup and syntax are a barrier.
Response: Offer a controlled editor or contribution form that still produces reviewable source changes. Docs as code describes governance, not a mandatory text editor.
Version labels drift across surfaces
Symptom: The portal, SDK, examples, and changelog describe different releases.
Response: Derive release labels and provenance from one accepted build record, then test deployed surfaces against that record.

When docs as code is the wrong first fix

Do not begin with a repository migration when the API behavior itself is undocumented, the team has no contract owner, or subject experts cannot review changes. First capture one developer task, one observed request, and the accountable service owner. Moving contradictory pages into Git only gives the contradiction better history.

A Git-only authoring experience can also be a poor fit for support, legal, product, or partner experts who make frequent contributions. Keep the review and release evidence in code while allowing a controlled editor to propose source changes. The test is not whether every author runs Git locally. The test is whether every published change has an identifiable source, reviewer, preview, and release.

Finally, do not generate reference from OpenAPI when the description is known to lag the service. Add implementation checks and repair the contract first. Automation should shorten the distance from accepted truth to public output; it should never accelerate a source that nobody trusts.

Where Doctorine fits, and where it stops

Doctorine applies this discipline to an OpenAPI-first delivery path. It imports an OpenAPI document, compiles one canonical graph, publishes hosted portal releases, and generates verified TypeScript, Python, and Go SDK artifacts. It can also publish llms.txt on entitled public portals; a customer-accessible MCP generation path is not shipped. The API delivery platform overview explains how those surfaces share a release model.

Doctorine does not prove that the service implementation matches the contract, replace an API gateway, or make every protocol an OpenAPI API. It does not currently support AsyncAPI, gRPC, or OpenRPC as equivalent inputs. Git reconciliation exists, but the customer GitHub connection is not yet a zero-touch self-service flow. Generated SDK registry publishing is also not a shipped promise. Keep those steps in your existing CI or release system until their product evidence moves from qualified to available.

If your next problem is the agent surface rather than the review workflow, continue with the OpenAPI-to-MCP implementation guide. To plan the human-facing output, review the developer portal release workflow.

Put one contract through the complete release path.

Import an OpenAPI spec, inspect the generated portal and client surfaces, and review a reproducible output instead of another disconnected preview.

Import an OpenAPI spec