The Autonomous Author: the docs loop at the pace of the code loop
a first draft on every merge
Disclaimer. This is a portfolio design document. Google has not engaged, sponsored or endorsed this work. The sample content is adapted from the Cloud NAT documentation, which Google publishes under the Creative Commons Attribution 4.0 licence1. The adapted version is modified from the original. The sample code change is written for this document and is not Google source code. Stakeholders are job roles, not real people. The two readers in §3 are fictional.
for each merged change
with a source for every sentence
without a writer's approval
Code and docs each run a DevOps loop: plan, build, test, release, deploy, operate and monitor. With docs as code, the docs loop runs on the same Git, CI and release tooling as the code loop2. At Google the two loops turn in the same sprint, and features do not ship without docs. One arc is different. Engineers write code with AI help, and more than a quarter of all new code at Google is generated by AI3. Writers still draft every docs change by hand. That one manual arc sets the pace of the whole docs loop.
The Autonomous Author automates that one arc. When a code pull request merges, it reads the change and the linked doc ticket, finds the affected pages and opens a first-draft docs pull request within minutes. Gemini writes the draft. Fixed Python checks test every sentence against its source, the style guide and the build. The writer reviews and approves the draft, as in the DDLC today. The agent cannot merge. The same checks then run on every docs pull request, and docs publish on the code release tag.
Every draft carries an explainability report with a confidence score from 1 to 10 and the source of every new sentence. The checks compute the score, not the model. Every run is logged, so a drift check can see when confidence falls or writers start to rewrite more.
§1 Client Brief
Google publishes documentation for its data center networking products, including Cloud NAT (network address translation). This MVP uses one Cloud NAT page as its sample: Tune NAT configuration, which lists the NAT timeouts, their defaults and the gcloud flags that change them4. The docs are in MyST Markdown in Git, the format that MANIFEST, the first project in this series, migrates DITA to5.
The team already runs docs as code. Its documentation development lifecycle (DDLC) is a DevOps loop of its own, and it turns in the same sprint as the code loop of the software development lifecycle (SDLC). Figure 1 shows the two loops. Writers are part of each sprint. The doc kickoff for an epic sets the doc type, audience and pages in scope, a Jira doc ticket tracks the docs, and docs publish with the release.
The two loops pair at five points and differ in what each stage produces and checks:
| Stage | SDLC loop: code | DDLC loop: docs | Where they pair |
|---|---|---|---|
| Plan | Epic and sprint planning | Doc kickoff and Jira doc ticket | same epic |
| Code / Write | Engineers write code, with AI help | Writer drafts by hand | merge starts docs work |
| Test | Does the code work? Unit, integration and security tests | Is the text true and usable? Style and links today | same CI, required checks |
| Review | Engineer peer review | Writer review and SME accuracy check | separate |
| Release and deploy | Rollouts, canaries and rollback for live traffic | Publish a docs version; a revert is low risk | same release tag |
| Operate and monitor | Uptime, latency, errors, incidents | Broken links, support cases caused by docs | shared support signal |
| Cost of failure | An outage | Wrong guidance that a customer follows | different |
One contrast shapes the design. In the code loop, tests check the code against its specification. In the docs loop, the most useful test checks the docs against the code. The Autonomous Author adds that test (§5.3, tool 5).
The page is a good test for three reasons. A small code change, such as a new default value, changes several places on the page. The values are exact numbers and flag names, so a wrong draft is easy to detect. And the published page is a real reference answer: the MVP can replay a past change and compare its draft with what Google published.
| Term | Meaning in this document | Example |
|---|---|---|
| DevOps loop | The repeating cycle of plan, build, test, release, deploy, operate and monitor, drawn as an infinity sign. The left half is CI, the right half is CD (continuous delivery). | Figure 1 |
| SDLC and DDLC | Software development lifecycle and documentation development lifecycle. Each runs as a DevOps loop, in the same sprint. | A feature merges (SDLC). Its docs update is drafted, reviewed and published with the release (DDLC). |
| Doc kickoff and doc ticket | The meeting that starts the docs for an epic, and the Jira ticket that tracks them to publish. | Doc ticket NAT-1182, linked to the epic |
| Docs as code | Docs are text files in Git. They change through pull requests and are built and checked by CI (continuous integration). | nat/tune-nat-configuration.md |
| Change item | One fact in a code change that readers can see: a new flag, a new field, a new default value. | TCP TIME_WAIT default: 120 s to 30 s6 |
| Grounded sentence | A sentence in the draft whose facts all appear in a named source: the code change, its issue or an existing page. | "The default is 30 seconds." Source: change item C1. |
| Human in the loop (HITL) | A person approves the result before it is published. Here, a writer approves the docs pull request. | A GitHub required review on the docs repository |
§2 Problem Statement
The docs loop works. The pressure on it is pace. The 2025 DORA report found that 90% of software development professionals now use AI, and it linked AI adoption with higher software delivery throughput7. At Google, more than a quarter of all new code is generated by AI and reviewed by engineers3. When the code loop turns faster, more changes merge in each sprint, and each one needs a docs draft from the same writers.
Keeping up has a measured value. DORA found that documentation quality strengthens the effect of technical practices on organisational performance8. Figure 2 shows how large that effect is.
Build, test, release and deploy already scale through pull requests and CI. Write does not. For each merged change, the writer notices it, reads the diff, finds every page that states the old behaviour and writes the update (Figure 3).
Here is one real change. On 31 March 2026, Google announced that the default TCP TIME_WAIT timeout for Cloud NAT drops from 120 seconds to 30 seconds, with a regional rollout for new gateways6. In code, that is one changed constant. In the docs, it changes several places that the writer must find and rewrite.
| Place | What must change | Risk if missed | Today |
|---|---|---|---|
| Timeouts table | The default becomes "30 or 120 seconds, depending on gateway creation date"4. | Readers plan for the wrong value. | By hand |
| Rule for the default | Gateways created after 30 September 2026 default to 30 seconds4. | The date is not in the code change. An SME must supply it. | Needs SME |
| How to check | Run gcloud compute routers nats describe and read effectiveTcpTimeWaitTimeoutSec4. | Readers cannot tell which default they have. | By hand |
| Guidance | Set the timeout to at least 15 seconds to avoid dropped packets4. | Readers set a value that drops traffic. | By hand |
| Flag reference | --tcp-time-wait-timeout changes the value6. | None if unchanged; must stay correct. | Unchanged |
| Option | What it does | What it misses | Result |
|---|---|---|---|
| Writer drafts each change by hand | The DDLC today. The writer reads each merged change and edits the pages. | Drafting time grows with the number of merges. Less time is left for review. | Does not scale |
| Add writers | More writers for each team. | Cost grows with the amount of code, and new writers need time to learn the product. | Costly |
| Engineer drafts in the code pull request | The engineer changes the docs with the code. | Style varies. Pages outside the engineer's view are missed. A writer still reviews. | Partial |
| General AI chat assistant | A person pastes the change and asks for a docs update. | Can invent values. No source for each sentence. No record of what it changed. | Unchecked |
| The Autonomous Author | Drafts on merge inside the docs loop, tests every sentence against the code, scores and explains the draft, and waits for the writer. | Cannot know facts that are not in the change or the docs. It marks them for a person (§5.4). | Checked |
§3 User Profiles
Five roles at Google run or depend on the agent. Two readers depend on the docs it drafts.
§4 User Stories
Each story comes from the Goal and Success fields in §3. The acceptance criteria are what the checks in §5 test.
[NEEDS INPUT] placeholders, never invented text.§5 Proposed Design
The Autonomous Author does one thing. It turns a merged code change into a first-draft docs pull request, with a score and a report, for a writer to review. It is an agent built with Agent Development Kit (ADK), Google's open-source agent framework. ADK is licensed under Apache 2.0 and its agents can run on Cloud Run9. Gemini 3.8 Flash (gemini-3.8-flash, a stable model10) runs the agent and calls its tools through Gemini function calling11.
The agent has seven plain Python tools that give the same result every time, and one model step that writes and revises the draft. Its three check tools also run as a required check on every docs pull request, so the docs loop tests the writer's edits as well as the agent's. The model decides which pages to edit and how to word the change. The checks decide whether a sentence is grounded and what the confidence score is. The agent cannot change a check result, and it cannot merge.
The docs loop keeps its stages, its ceremonies and its Jira doc ticket. The agent acts at three points on it (Figure 6). At Write, the code merge starts the draft. At Test, fixed checks test the docs against the code and compute a confidence score. At Monitor, the run log shows drift in draft quality. The writer's time moves from writing to review.
The agent is one contributor to a docs pipeline that treats every docs pull request the same way, whoever wrote it. Figure 8 shows the pipeline from pull request to production.
| Pipeline rule | How it works | Why |
|---|---|---|
| One set of checks | Style, grounding, build, links and score live in one reusable workflow, docs-checks.yml. A reusable workflow is triggered by workflow_call12. The agent and every docs pull request run it. | A writer's edit is tested as strictly as the agent's draft. |
| Checks block merge | Branch protection requires the checks to pass and a writer to approve13. | No change reaches readers untested or unreviewed. |
| Review the rendered page | Each pull request gets a Firebase Hosting preview URL from a GitHub Action14. A preview channel expires after 7 days by default15. | Writers and SMEs review what readers will see, not a Markdown diff. |
| Merge is not publish | Merge to main deploys to a staging site. | Docs for unreleased features stay unpublished. |
| Publish on the code release | A workflow on a tag push, filtered to v*16, deploys staging to production. | Docs and code ship on the same event. |
| Close the loop | A daily job checks live links and the run log for drift, and opens issues for the next doc kickoff. | Monitor feeds Plan, as in the code loop. |
1 · Read the change read_change
Reads the merged pull request: the diff and the description. It reads the linked Jira doc ticket with the Jira Cloud REST API17, which gives the doc type, audience and pages in scope from the doc kickoff. Parsers extract each reader-visible change item: a changed default, a new flag, a new API field or enum value. Each item gets an ID (C1, C2 ...) and keeps its old and new value.
2 · Find the affected pages find_pages
Searches the docs repository for each change item: the flag name, the field name and the old value. It also reads the MyST substitutions file, so a value that is stored once is changed once5. Returns each page, line and the change item it matches.
3 · Draft and revise (Gemini) model step
Gemini edits the affected pages in MyST Markdown, following the doc type of each page. For each new or changed sentence it returns a source map entry: the change item, issue or page line it used. When a fact has no source, it must write a [NEEDS INPUT: question] placeholder instead. On a failed check it revises only the sentences that failed.
4 · Check the style check_style
Runs Vale with the Google package, a Vale version of the Google developer documentation style guide licensed under CC BY 4.018. Checks only the changed lines, so old issues on a page do not block a new draft. Tools 4 to 6 also run in docs-checks.yml on every docs pull request (§5.2).
5 · Check the grounding check_grounding
Runs four checks. Source: every new sentence has a source map entry, and the source exists. Literals: every number, unit, flag, field and command in the sentence appears in its source. Coverage: every change item appears in the draft. Stale values: no affected page still states an old value that the change replaced.
6 · Check the build check_build
Builds the changed pages with Sphinx and treats warnings as errors. Runs lychee over the result to check links19.
7 · Score and report write_report
Computes the confidence score from the check results (§5.5) and writes the explainability report with its sources. Opens the docs pull request, posts the report as a comment and adds each placeholder as a question to the change author. Posts the link and score on the Jira doc ticket and moves it to review. Writes one row to the run log.
8 · Learn from the review record_review
Runs when the writer merges or closes the docs pull request. Compares the draft with the merged text and records the edit ratio: the share of the draft that the writer changed. It also recomputes the confidence score on the merged text, so the run log holds the score of what readers see. Repeated writer edits, such as the same word replaced in three drafts, become a proposed Vale rule that a writer approves.
The agent runs tools 1 and 2, then asks Gemini for a draft. Tools 4 to 6 check it. When a check fails, Gemini reads the failure and revises only the failed sentences, then the checks run again. After two failed revisions, the agent stops revising. It replaces each sentence that still fails grounding with a placeholder, so no unchecked fact reaches the writer.
The agent always opens the pull request. It is a draft pull request, and the docs repository's branch protection requires a writer's approval before merge13. The confidence score sets the label: ready for review, review closely or needs writer. When a revision fixes the same failure type more than once and a writer approves it, the fix becomes a fixed rule in the tools, so the model is called less over time.
Most of a run is model time and checks. The checks run in parallel. Figure 10 shows a run for the rollout-rule sample in §6.
The confidence score tells the writer how much review a draft needs, on a scale of 1 to 10. The tools compute it from check results only. The model never scores its own work. The weights below are the MVP's starting values. The platform engineer tunes them from the edit ratio that tool 8 records, so that a higher score means fewer writer edits.
A score is only useful if the writer can see what it is based on. So the explainability report always names its sources. It has five parts: what changed (the change items), sources (the code pull request, the doc ticket, each page and the style package version, each with a link), what the agent edited and why, where each sentence came from (sentence, source and check result) and what to check (placeholders, style issues and any sentence that needed a revision). Figure 13 in §7 shows a sample.
ADK sends traces of every model and tool call to Cloud Trace through OpenTelemetry20. On Cloud Run, the trace_to_cloud option in the agent's server code turns this on21. Traces answer "what happened in this run". The run log answers "is quality changing over time".
Each run writes one row to a BigQuery table: run ID, model ID, prompt version, Vale package version, change type, confidence score and its parts, revisions, placeholders, tokens and time. Tool 8 adds the edit ratio after review. Once a day, a Cloud Run job started by Cloud Scheduler compares the last 10 runs with a baseline of 20 approved runs. When a check crosses its threshold, the job opens a drift issue in the docs repository with the runs and the rows that changed.
| Drift type | Signal in the run log | MVP threshold | Response |
|---|---|---|---|
| Quality drift | Mean confidence score of the last 10 runs | 1.0 below baseline | Drift issue. Compare prompt and model versions of the runs. |
| Review drift | Median edit ratio of the last 10 reviewed drafts | 0.15 above baseline | Drift issue. Writers are rewriting more, even if checks pass. |
| Grounding drift | Sentences replaced by placeholders after 2 revisions | More than 5% of new sentences | Drift issue. Check whether changes now carry less detail. |
| Configuration change | Model ID, prompt version or Vale version differs from baseline | Any difference | Replay the evaluation set before the new version goes live. |
| Input drift | Change type not seen in the baseline, for example a new file type | Any new type | Flag in the report. Add a replay case for the new type. |
The evaluation set is a list of past Cloud NAT changes with their published pages as reference answers, such as the TIME_WAIT change in §2.1. The replay runs with ADK's evaluation tools. It uses response_match_score for overlap with the reference, and hallucinations_v1, which labels each sentence as supported by its context or not22. The second one uses a model as judge, so it runs only in the replay, never as the gate on a live draft.
| Part | Service | Note |
|---|---|---|
| Trigger, checks and review gate | GitHub Actions with a reusable docs-checks.yml; branch protection with required checks and reviews | Standard runners are free for public repositories23. Protected branches are available on public repositories with GitHub Free13. |
| Docs sites | Firebase Hosting: preview channels, staging and production | No-cost plan: 10 GB storage and 360 MB of data transfer a day24. Enough for a sample docs set; a full docs site needs the paid plan. |
| Agent | Cloud Run service, one request per merged change | Free tier: 180,000 vCPU-seconds and 2 million requests a month25 |
| Drift check | Cloud Run job, started daily by Cloud Scheduler | Jobs free tier: 240,000 vCPU-seconds a month25. Scheduler: 3 jobs free for each billing account26. |
| Run log | BigQuery | Free tier: 10 GiB storage and 1 TiB of queries a month27. One row per run is far below this. |
| Traces | Cloud Trace | Through ADK's OpenTelemetry support20 |
| Tokens for GitHub and Jira | Secret Manager | Free tier: 6 secret versions a month28 |
| Model | Gemini API, gemini-3.8-flash | The free tier is acceptable here because the sample content is public. Free tier content is used to improve Google products, so private code and docs need the paid tier. The paid tier costs $0.75 per million input tokens and $3.75 per million output tokens until 31 December 202629. Each run logs its tokens, so the cost per draft is measured, not estimated. |
§6 Draft Simulator
The simulator runs three sample changes through the Autonomous Author. Each run shows the tools in order and the log that the agent writes. The runs are scripted to show the design. They do not call Gemini, GitHub or Vale. To run the real agent, open the live demo: commit a sample feature and get the first draft in MyST and DITA, with the report, ready for your review.
// choose a sample change and run the draft
§7 Success Metrics
The MVP runs on a replay set of past Cloud NAT changes and on new sample changes, through the full pipeline in §5.2. It succeeds if the numbers below are met. The first metric matters most: a fast draft is worth nothing if it puts an unchecked fact in front of readers.
| Metric | How it is measured | MVP target |
|---|---|---|
| Ungrounded facts merged | Facts in merged docs with no source in the report, found by a writer after merge | 0 |
| Same-release publish | Docs changes published on the same release tag as their code change | 100% |
| Time to first draft | Code merge to docs pull request open and linked on the doc ticket, from the run log | Under 15 minutes for every change |
| Change coverage | Change items in the draft ÷ change items in the change | 100% |
| Stale values left | Old values still stated in affected pages after the draft | 0 |
| Draft kept after review | 1 minus the edit ratio from tool 8 | Baseline set from the first 20 runs; tracked for each change type |
| Score agrees with review | Median edit ratio for each confidence band | Falls as the band rises: ready < review closely < needs writer |
| Writer review time | Pull request opened to approved, compared with by-hand updates of the same changes | Lower than the by-hand baseline |
| Drift alerts with a named cause | Drift issues that list the runs and the version that changed | 100% |
What changed
C1TCPTIME_WAITdefault: 120 s to 30 s for new gatewaysC2New output fieldeffectiveTcpTimeWaitTimeoutSecingcloud compute routers nats describeC3Flag--tcp-time-wait-timeoutunchanged; help text now gives a minimum
Sources
S1Code PR #4471, diff ofrouter_nat/timeouts.pyand the flag help textS2Jira doc ticket NAT-1182: doc type task, audience network operators, from the doc kickoffS3nat/tune-nat-configuration.mdandnat/troubleshooting.mdat the commit before the draftS4substitutions.yml, keynat_tcp_time_wait_defaultS5Vale Google package, version pinned in the docs repository
What the agent edited and why
- Timeouts table row: matched old value 120 for
C1· substitution updated once (S1, S4) - New step "Check the timeout in effect": added for
C2, after the describe example (S1, S3) - Troubleshooting page, line 88: typed copy of 120 replaced with the substitution · stale value scan now passes (S3, S4)
Where each sentence came from (3 of 11)
| Sentence | Source | Check |
|---|---|---|
| For new gateways, the default is 30 seconds. | S1, line 212 | literals 2/2 |
To see the value in effect, read effectiveTcpTimeWaitTimeoutSec. | S1, line 240 | literals 1/1 |
| [NEEDS INPUT: which gateways get the 30 second default?] | None found | question |
Check these
- question Which gateways get the 30 s default? The change does not give a date or rule. Asked of the change author.
- question Is the minimum value a hard limit or a recommendation? Asked of the change author.
- question Should the release note link to this section? Asked of the writer.
- revised Sentence 4 first said "in all regions". No source. Revised to a placeholder.
- style Two Vale warnings in changed lines (Google.Parens, Google.Will).
Sources
Checked on 19 October 2026.
- Google Developers, "Site Policies." developers.google.com/site-policies
- Write the Docs, "Docs as Code." writethedocs.org/guide/docs-as-code
- Sundar Pichai, "Q3 earnings call: CEO's remarks," Google blog, October 2024. blog.google/inside-google/message-ceo/alphabet-earnings-q3-2024
- Google Cloud, "Tune NAT configuration," last updated 13 October 2026. docs.cloud.google.com/nat/docs/tune-nat-configuration
- Siddharth Rao, "MANIFEST: Migrate DITA to Markdown without losing content," design document. siddharthraop.github.io/Manifest
- Google Cloud, "Cloud NAT release notes." docs.cloud.google.com/nat/docs/release-notes
- Google, "How are developers using AI? Inside our 2025 DORA report." blog.google/technology/developers/dora-report-2025
- DORA, "Documentation quality." dora.dev/capabilities/documentation-quality
- Google, Agent Development Kit documentation README. github.com/google/adk-docs
- Google AI for Developers, "Gemini models." ai.google.dev/gemini-api/docs/models
- Google AI for Developers, "Function calling with the Gemini API." ai.google.dev/gemini-api/docs/function-calling
- GitHub Docs, "Reuse workflows." docs.github.com/en/actions/how-tos/reuse-automations/reuse-workflows
- GitHub Docs, "About protected branches." docs.github.com/.../about-protected-branches
- Firebase, "Test and preview, then deploy." firebase.google.com/docs/hosting/test-preview-deploy
- Firebase, "Manage Hosting resources." firebase.google.com/docs/hosting/manage-hosting-resources
- GitHub Docs, "Workflow syntax for GitHub Actions." docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax
- Atlassian Developer, "Jira Cloud platform REST API v3." developer.atlassian.com/cloud/jira/platform/rest/v3/intro
- Vale, "Google" style package. vale.sh/hub/google
- lychee link checker, GitHub Action. github.com/lycheeverse/lychee-action
- Agent Development Kit, "Google Cloud Trace observability." adk.dev/integrations/cloud-trace
- Google Codelabs, "Deploy, Manage, and Observe ADK Agent on Cloud Run." codelabs.developers.google.com/deploy-manage-observe-adk-cloud-run
- Agent Development Kit, "Evaluation criteria." adk.dev/evaluate/criteria
- GitHub Docs, "How use of GitHub Actions is measured." docs.github.com/en/billing/concepts/product-billing/github-actions
- Firebase, "Pricing." firebase.google.com/pricing
- Google Cloud, "Cloud Run pricing." cloud.google.com/run/pricing
- Google Cloud, "Cloud Scheduler pricing." cloud.google.com/scheduler/pricing
- Google Cloud, "BigQuery pricing." cloud.google.com/bigquery/pricing
- Google Cloud, "Free Tier." cloud.google.com/free
- Google AI for Developers, "Gemini Developer API pricing." ai.google.dev/gemini-api/docs/pricing