---
title: "Check Generated Documentation for Stale Outputs"
description: "Install the shared freshness checker and connect an owning project's generator and documentation gate without rewriting tracked output during validation."
sidebar:
  order: 20
archetype: "how-to"
project: "portal"
tags: ["governance", "documentation", "validation"]
---

# Check Generated Documentation for Stale Outputs

## Prerequisites

- Node.js 24 or later.
- A project-owned documentation generator and an existing documentation/CI check.
- Reviewed generation commands that can write **every generated file** into a supplied output directory. The checker runs trusted project code; it is not a process sandbox.

Follow the [shared policy](../../policies/documentation-policy.md) and
[authoring skill](../../skills/document-authoring/SKILL.md).

## Step-by-Step Implementation

### 1. Copy the common checker into the project

Copy these reviewed files into the owning repository:

| Supplied file | Project destination |
| --- | --- |
| [check-generated.mjs](check-generated.mjs) | `scripts/check-generated.mjs` |
| [check-generated.test.mjs](check-generated.test.mjs) | `scripts/check-generated.test.mjs` |
| [generated-policy.example.json](generated-policy.example.json) | `generated-policy.json` |

Keep the checker and its tests identical to the reviewed shared version. CI uses
these local copies; it does not fetch and execute code from the network.

### 2. Add an output-directory option to the owning generator

Make the project generator accept `--output-dir <directory>`. Read canonical
inputs from the project root, but place **all generated output** under that
directory while preserving project-relative paths. For example, a normal
`docs/index.md` becomes `<directory>/docs/index.md` during validation.

When that option is present, the generator must not update normal outputs,
indexes, caches, package metadata or source files elsewhere. Retain the project's
normal generation command for explicitly updating its outputs. If an index reads
a page generated in the same run, read that fresh page from the temporary output
(or memory), not its older working-tree copy.

This generator change belongs to the owning project. The shared checker cannot
add it automatically. In particular, do not pass this option to an existing
Appkit generator until that generator has been updated to honor it.

### 3. Declare the command and every generated output

Edit `generated-policy.json`. This example assumes the project's generator
writes all of its documentation under `generated/docs`; replace that path with
the project's real generated files or directories:

```json
{
  "schemaVersion": 1,
  "jobs": [
    {
      "name": "documentation",
      "command": ["node", "scripts/generate-docs.mjs", "--output-dir", "{outputDir}"],
      "outputs": ["generated/docs"],
      "timeoutMs": 60000
    }
  ]
}
```

`{outputDir}` is replaced with a newly created temporary directory. Arguments
are passed directly to the executable, without a shell. Run the checker from
the owning project root. Paths in `outputs` are relative to that root.

Use exclusive generated directories, or list individual generated files when
hand-authored guides share a directory. Include every generated artifact, not
just the introduction page. For Appkit, review README landing pages, exports
references, the document manifest, AI indexes and generated consumer metadata.
The example above is not an Appkit configuration.

A directory scope also detects obsolete files remaining there. For explicitly
listed files, remove retired output files when removing them from configuration;
the checker cannot identify formerly generated files outside declared scopes.
Paths must not overlap, traverse outside the project or include symlinks. A job
must generate at least one file for each declared scope; undeclared output is
an error. `timeoutMs` is optional and defaults to 60000 (maximum 60000).

### 4. Add the check to the existing documentation gate

Add project scripts such as:

```json
{
  "scripts": {
    "docs:generated:test": "node --test scripts/check-generated.test.mjs",
    "docs:generated:check": "node scripts/check-generated.mjs"
  }
}
```

Include both in the project's existing documentation/CI gate. For Appkit,
append `bun run docs:generated:test && bun run docs:generated:check` to
`check:docs`, preserving its README and other documentation checks. Existing
CI then runs the freshness check through `check:docs`.

AGENTS.md keeps its shared policy/skill URLs and records only the project-owned
configuration path and real check command. Do not copy the policy or this whole
guide into every AGENTS.md.

## Verification

Run in the owning project:

```bash
node --test scripts/check-generated.test.mjs
node scripts/check-generated.mjs
```

All regression tests must pass. A successful project check reports
`documentation: generated outputs are current` and exits with status 0.
Differences, generation failures and invalid configuration exit with status 1.
The checker does not repair the working tree.

| Result | Meaning | Action |
| --- | --- | --- |
| `changed` | Existing file differs from fresh generation | Run the normal project generation command and review its changes. |
| `missing` | Fresh generation produced a file absent from the working tree | Generate and include that file. |
| `extra` | A file in a declared scope is no longer produced | Review and remove the obsolete generated file. |
| Generator failure or timeout | Fresh generation did not complete | Fix that failure; do not treat it as a freshness pass. |

The comparison is byte-for-byte. It does not certify factual documentation
accuracy, runnable examples, package publication or JSDoc completeness.

## Troubleshooting / Common Pitfalls

- **No output files**: the generator may not support or honor the output-directory option. Fix it before enabling the check; do not rerun a generator that writes normal outputs during validation.
- **Unregistered output**: add the artifact to the reviewed output list, or stop generating that artifact for this job.
- **An obsolete guide is reported as extra**: declare only generated scopes; do not put hand-authored source documents under a whole-directory generated scope.
- **Every run changes output**: remove timestamps, random IDs or machine-specific paths from generated content rather than ignoring meaningful differences.
- **Different runtime output**: pin the project's Node/Bun and dependency versions in its existing toolchain.
- **Sensitive generator logs**: failure reports show the job name and exit status, not captured generator output. Diagnose the normal generation command locally using the project's existing logging policy.
