- name
- missing_docs
- description
- Find documentation gaps in Warp's Astro Starlight docs by auditing coverage against code surfaces in the public warp client repo and warp-server and against the weekly release changelog, decide which gaps actually warrant docs, then draft only those. Use when asked to find missing docs, audit documentation coverage, identify undocumented features, draft docs for new features, detect doc-impacting code changes since the last audit, or do a docs coverage check. Runs a Python audit script (coverage + snapshot-based change detection), gates every candidate against the documentation-worthiness criteria, then researches source code and writes first-pass doc pages for the ones that pass. Can run audit-only, draft-only, drift-watch (release-triggered recurring agent), or end-to-end.
# Missing Docs
Find documentation gaps, detect doc-impacting code changes, and draft missing pages.
## Agent-doc quality contract
Any PR this skill opens or updates follows the shared v1 agent-doc quality
contract in `.agents/references/doc-quality-policy.md`: apply the
`warpy-factory` label, add the `## Documentation risk` block
(`.agents/skills/doc_quality_policy/finalize_pr_contract.py build`), and keep
`## Unverified claims` (step 9.5 of `draft_docs`) current. A newly-drafted
feature page is `engineering-review-required` by default per the allowlist.
## Requirements
The audit compares docs against code, so both source repos must be available:
- the public warp client repo ([warpdotdev/warp](https://github.com/warpdotdev/warp))
and `warp-server`, auto-detected as siblings of the docs repo root (e.g.
`/workspace/docs` next to `/workspace/warp` and `/workspace/warp-server`; a
sibling named `warp-internal` is accepted as a fallback), or passed explicitly
via `--warp PATH` / `--warp-server PATH` (`--warp-internal` is a deprecated alias).
The script FAILS LOUD when a repo is missing OR when an extraction sanity guard
trips (a parser returning implausibly few surfaces means the source layout
changed and the parser needs fixing): it exits with code 2 and lists the skipped
audits in the report's `audits_skipped` field (`extraction:*` entries identify
broken parsers). Never treat an exit-2 run as a clean audit — fix the problem
and re-run. Exit 0 means all requested audits ran (findings may still exist).
### Run every command from the docs repo root
Every path in this skill — scripts, references, doc pages — is relative to the docs
repo root, and nothing resolves them for you. A sandbox commonly starts a run one level
up (`/workspace`, with the checkout at `/workspace/docs`), so `cd` before anything else:
```bash
cd "$(git rev-parse --show-toplevel)"
```
A wrong working directory fails in a way that reads like a real failure: `python3` exits
**2** with `can't open file`, the same exit code `audit_docs.py` uses to fail loud on a
broken environment. Read the message before concluding a sanity guard tripped.
### Install Node dependencies before the first build
`npm run build` is the only validation this repo has, and it needs `node_modules`, which
a fresh sandbox does not have. Install once per sandbox:
```bash
npm ci
```
### Regenerate the snapshot only from current checkouts
`--update-snapshot` rewrites `references/surface_snapshot.json` from whatever the sibling
repos hold at that moment, and it cannot tell a current checkout from a stale one. Running
it against an old or feature-branched `warp` / `warp-server` writes a baseline describing
surfaces that are not on the default branch, and the next `--diff` then reports the gap
between two wrong baselines as real drift. Confirm both repos are current and on their
default branch — `master` for `warp`, `develop` for `warp-server` — before regenerating:
```bash
for repo in ../warp ../warp-server; do
git -C "$repo" fetch --quiet origin
echo "$repo $(git -C "$repo" rev-parse --abbrev-ref HEAD) \
$(git -C "$repo" log -1 --format=%cd --date=short)"
done
```
A cloud sandbox provisions fresh checkouts and satisfies this by construction; a
developer's machine usually does not. When you cannot confirm it, leave the regen to a
scheduled run rather than committing a snapshot you cannot vouch for.
## Public vs. private surfaces (what you may document)
Only document surfaces that are **publicly released**. This is the most important guardrail in this skill: do not reveal private or unreleased surfaces in public docs. Two independent gates, both required:
1. **Source / exposure.** The OSS warp client repo ([warpdotdev/warp](https://github.com/warpdotdev/warp); locally `warp`, or the `warp-internal` fallback) is public — its feature flags, CLI commands, settings, and slash commands are documentable. **`warp-server` is a private repo** and is not public until released; its source and most of its surfaces must NOT be documented. The one exception is the public **Oz Agent API**, whose released surface is exactly the set of endpoints already present in the OpenAPI spec (`developers/agent-api-openapi.yaml`).
2. **Rollout status.** Even for public-repo surfaces, only document **GA** features. Never document dogfood, preview, or research-preview surfaces (for example, Agent Memory is research preview, so its `oz memory*` CLI and `/memory_stores` API must not be documented yet).
Rules of thumb:
- A `warp-server` API endpoint that is **not already in the OpenAPI spec** is treated as not-yet-public: do NOT hand-write docs for it. Either confirm it has been publicly released and let the `sync-openapi-spec` skill bring it into the spec, or map it `-> internal` / defer it. When unsure, defer — never expose an unreleased endpoint or feature in public docs.
- A CLI command or API route gated by a **non-GA feature flag** should be mapped `-> gated:<Flag>` (for example, `gated:AIMemories`) rather than `-> internal`: the audit auto-defers it while the flag is non-GA and auto-surfaces it for docs once the flag goes GA. (Feature flags and settings already auto-defer by rollout status; `gated:` extends that to CLI/API.)
- **A published docs page is not evidence that an API is released.** Early Access features routinely have public pages describing what the product does while their REST routes stay out of the released spec, so "we already document this feature" does not clear Gate 0 for an endpoint. For API surfaces the released OpenAPI spec is the only test. The Factory pages describe dispatching a run, yet no `/factory` path appears in `developers/agent-api-openapi.yaml` — those routes are Gate 0 deferrals despite the prose.
- The audit still *detects* these as gaps (useful signal), but detection is not permission to document. Every resolution must respect this boundary.
This section is the source of truth for **Gate 0** in
`.agents/references/docs-worthiness-criteria.md`. Passing Gate 0 only establishes that a
surface *may* be documented — it does not establish that it *should* be. Work through the
remaining gates before treating any finding as actionable.
## Workflows
### Phase 1: Audit (coverage)
Run the audit script to identify gaps:
```bash
python3 .agents/skills/missing_docs/scripts/audit_docs.py
```
Options:
- `--category consistency|features|cli|api|slash|settings|structure|staleness|map` — run a single audit category
- `--severity high|medium|low` — filter by minimum severity
- `--weak-coverage` — also flag GA features whose mapped doc exists but doesn't mention feature keywords (low-severity, noisy)
- `--output report.json` — save JSON report to file
- `--warp PATH` / `--warp-server PATH` — explicit repo paths (`--warp-internal` is a deprecated alias)
- `--diff` — change detection against the committed snapshot (see Phase 2)
- `--update-snapshot` — regenerate `references/surface_snapshot.json` after
every current delta has a machine-readable disposition (full runs only)
Snapshot regeneration reads `references/surface_snapshot_dispositions.json`.
The file uses schema version 2, records the `snapshot_fingerprint` for the input
snapshot, and includes one entry per current `--diff` finding with its exact
`change` and `surface`, a disposition (`documented`, `mapped`, `internal`,
`no_docs_needed`, or `removed`), and non-empty evidence. The update fails
before writing when the ledger is malformed, bound to a different input
snapshot, incomplete, or contains stale entries. A ledger is optional only
when no deltas exist and the file is absent. Deferred findings are not terminal
and cannot enter this ledger. Delete the ledger after committing the new
baseline; it describes the deltas being accepted, not future drift.
The script resolves doc paths from the docs repo root and accepts `.md` and `.mdx`
interchangeably (and `README.md` ↔ `index.mdx`), so surface-map entries can use the
canonical filename even when the on-disk extension differs.
The script performs these coverage audits:
1. **Cross-repository consistency** — evaluates the curated findings in
`references/consistency_seeds.json`. Each seed has a stable ID, claim,
disposition status, occurrence queries, authority or explicit owner
blocker, affected surfaces, per-surface disposition, and recheck condition.
Scoped exact-text and regex rules report every remaining occurrence.
`policy_blocker` and `owner_confirmation` seeds stay visible in
`consistency.blockers`; they are never treated as resolved because a
deterministic rule passes.
2. **Feature flag coverage** — classifies every `FeatureFlag` by rollout status using
the cargo-feature→flag bridge in the warp client repo's `app/src/features.rs` plus
`RELEASE_FLAGS`/`PREVIEW_FLAGS`/`DOGFOOD_FLAGS` in `crates/warp_features/src/lib.rs`.
GA flags must be mapped in the surface map or covered in docs; Preview flags produce
low-severity "docs needed soon" findings; dogfood/other flags are tracked by the
snapshot only.
3. **CLI command coverage** — parses the full `oz` command tree from
`crates/warp_cli/src/` (recursive subcommands like `oz run message send`, skipping
`hide = true`) and checks the CLI reference docs. Per-module `--long` flags are
additionally tracked in the snapshot for change detection.
4. **API endpoint coverage** — extracts public routes from warp-server
`router/handlers/public_api/*.go` (nested gin groups resolved, caller-passed group
prefixes matched positionally) and checks them against
`developers/agent-api-openapi.yaml` (param-name-insensitive: `{runId}` matches
`{run_id}`) and the API reference docs. For spec drift, run the docs
`sync-openapi-spec` skill (or warp-server's `update-open-api-spec`) instead of
hand-editing the YAML. **warp-server is private** (see Public vs. private
surfaces): a flagged endpoint is documentable only once it is part of the
released public Oz Agent API. Never hand-draft API docs or reveal an unreleased
endpoint — resolve released endpoints via `sync-openapi-spec`, and `-> internal`/
defer the rest.
5. **Slash command coverage** — parses the static registry in the warp client repo's
`app/src/search/slash_command_menu/static_commands/` and checks each `/command`
is mentioned in docs.
**Known limitation: this check is repo-wide, not surface-scoped.** A command counts as
covered when *any* page mentions it (`audit_slash_commands` in `scripts/audit_docs.py`
searches every docs page), so a command documented on the GUI slash-commands page reads
as covered even when the CLI reference omits it. That is how `/usage` reached a release
undocumented for CLI users — only the changelog cross-check caught it. The CLI and
settings audits scope their search to the pages that own those surfaces; this one does
not. Until that is fixed, do not read a slash command's `doc_covered` bucket as
"documented in the right place."
6. **Settings coverage** — parses every `toml_path: "section.key"` setting
registration in the warp client repo (the same registry the JSON-schema generator uses)
and checks the all-settings reference page documents it. Private and
dogfood/other-flagged settings are exempt; object-typed settings documented as
their own `[section]` count as covered.
7. **Docs staleness** — flags renamed/removed-feature terminology in prose (code
spans stripped; historical changelog pages excluded). Broader terminology and
style enforcement is owned by the `style_lint` skill — delegate pure wording
issues there.
8. **Stale doc references** — reverse checks: settings keys documented in
all-settings.mdx that no longer exist in code (catches renames like
`agents.oz.*` → `agents.warp_agent.*`), and keybinding actions (`scope:action`)
on the keyboard-shortcuts page that no longer exist anywhere in the warp client repo.
9. **Docs structure** — pages on disk that are missing from `src/sidebar.ts`
(built but unreachable through navigation). Intentionally unlisted pages go in
the surface map's "Unlisted docs pages" section.
10. **Surface map hygiene** — flags map entries whose flag/command/route/setting no
longer exists in code, and mapped doc targets that no longer exist. Verify the
doc page is still accurate, then prune or update the entry.
Snapshot-only surfaces (no standing coverage audit, but added/removed/changed items
are reported by `--diff`): Oz web app routes (`AgentsApp.tsx`), server-side agent
tools (multi_agent tool registries), bundled + channel-gated skills
(`resources/bundled/skills`, `resources/channel-gated-skills`), and per-module CLI
flags.
Present the report to the user, grouped by category and sorted by severity.
Adjacent checks owned by other skills (do not duplicate them here):
- UI menu paths and Command Palette names, including detecting when a documented control has relocated to a different Settings page → `validate_ui_refs`
- Platform error-code pages → `sync-error-docs`
- Broken links and 404s/redirects → `check_for_broken_links` / `weekly-404-monitor`
- Terminology/style sweeps → `style_lint`
### Completeness accounting (the no-slip guarantee)
Every full run computes a completeness accounting and embeds it in the report
(`summary.accounting` in JSON, a `COMPLETENESS ACCOUNTING` block in the printed
output). It partitions every extracted surface item into exactly one
accountability bucket and proves totality:
- **Feature flags**: every GA/Preview flag is `mapped` (surface map verified),
`ignored` (curated internal list), or a visible `finding`; every dogfood/other
flag is `tracked_non_ga` (snapshot diff fires on promotion or removal).
- **CLI commands**: `mapped`, `doc_covered`, `gated_non_ga` (deferred via
`gated:<Flag>` while its gating flag is non-GA), `finding`, `parent_flagged`
(suppressed because the parent command is already flagged), or `hidden`.
- **API routes**: `mapped`, `spec_covered`, `docs_covered`, `gated_non_ga`
(deferred via `gated:<Flag>` while its gating flag is non-GA), or `finding`.
- **Slash commands**: `mapped`, `doc_covered`, or `finding`.
- **Settings**: `private`, `tracked_non_ga`, `mapped`, `doc_covered`, or `finding`.
- **Consistency seeds**: every seed has one approved status, evidence from
`authoritative_sources` or an explicit owner and unresolved question, and a
disposition for every affected surface. The report includes total seeds,
counts by status, passed and failed rules, remaining occurrences, and active
blockers.
If any item escapes every bucket, the run reports `integrity:accounting` in
`audits_skipped` and exits 2 — an unaccounted item means the audit logic itself
regressed, never that the item is fine. Map hygiene additionally rejects
integrity bugs in the surface map: entries that are both mapped and ignored
(the ignore silently wins) and duplicate keys within a section.
Malformed or unaccounted consistency seeds report
`integrity:consistency_accounting` and also exit 2.
How every change path is caught, end to end:
1. **New surface item appears** (flag, command, route, slash, setting, web
route, tool, bundled skill) → the snapshot `--diff` reports it AND, once
GA/user-facing, the coverage audit produces a standing finding until it is
documented + mapped or ignored with a comment.
2. **Item is promoted** (dogfood→preview→ga, setting status change, skill
channel change) → `--diff` status-change finding + coverage finding appears.
3. **Item is removed/renamed** → `--diff` removal finding + map hygiene flags
the dead map entry + stale-doc-reference checks flag docs still naming it.
4. **Launch with no client-code change** (server-side experiment flips to 100%,
Oz web app backend feature) → the changelog cross-check is the net: every
"New features"/"Improvements"/"Oz updates" bullet newer than the snapshot
becomes a verification finding.
5. **The audit itself rots** (source layout moves, parser breaks) → extraction
sanity guards trip, dependent audits skip, exit 2.
6. **The map rots** (dead entries, conflicts, duplicates, missing doc targets,
unmapped-but-mentioned features) → map hygiene + fallback-transparency
findings keep pressure until fixed.
The mapping is updated through three enforced paths: Phase 3 step 8 makes the
map+snapshot update a mandatory part of drafting; the drift-watch triage step
requires a mapping/ignore/allowlist decision for every finding; and map hygiene
findings force pruning when code moves underneath the map.
### Phase 2: Change detection (diff mode)
The snapshot at `references/surface_snapshot.json` records all extracted surfaces
(flags + rollout status, CLI commands and per-module flags, API routes, slash
commands, settings + status, Oz web app routes, server-side agent tools, bundled
skills) plus the last-seen docs-changelog version. It makes change detection
possible: a feature flag that is deleted after stabilizing (per the warp repo's
remove-feature-flag policy) would otherwise vanish from the audit's universe
silently. When a new surface type is introduced, diffing against an older snapshot
emits a one-time "surface type newly tracked" note instead of false positives.
```bash
python3 .agents/skills/missing_docs/scripts/audit_docs.py --diff
```
Diff mode reports, since the snapshot was last updated:
- **Added / removed / promoted surfaces** — e.g. a new GA flag (high), a flag promoted
dogfood→ga (high), a removed flag ("feature stabilized or killed — verify docs and
map entry"), new/removed CLI commands and `--flags`, API routes, slash commands,
settings (with status promotions), Oz web app routes, server-side agent tools, and
bundled skills.
- **Changelog items to verify** — "New features", "Improvements", and "Oz updates"
bullets from `src/content/docs/changelog/<year>.mdx` entries newer than the
snapshot's last-seen version. This is the best signal for launches no static code
parse can see (server-side features, Oz web app, experiment rollouts). A changelog
mention is NOT documentation — verify each item has real doc coverage. ("Bug fixes"
bullets are deliberately untracked to keep weekly triage volume manageable.)
**A changelog item is a candidate, not a work item.** Detection is not permission to
document. Every item must pass `.agents/references/docs-worthiness-criteria.md` before
it becomes actionable — most will not. Read
`references/changelog_decisions.md` first and skip any PR number already decided.
#### Sources beyond the client changelog
The client changelog only covers `warpdotdev/warp`. Server and platform features ship
continuously and never appear in it, which is how they used to reach docs through the
retired spec-scan path — and why that path produced most of the unvetted drafts. Cover
them through these three layers instead, in order of preference:
1. **`oz_updates`** — the separate array in the same `client_version` payload the release
gate already fetches. Release-gated, low-noise, and currently the most direct signal
for platform-side changes. Triage these bullets exactly like changelog bullets: same
gates, same ledger, same evidence requirement.
`check_new_release.py` prints them; the audit never sees them, because it is offline
by design and they are not part of the markdown changelog it parses. Read them from
the gate's output, or `--json` for the full array. `oz_updates` is the API's field
name and stays as-is regardless of product naming.
2. **The public Agent API surface** — already covered by audit category 4 and
`sync-openapi-spec`. No new machinery; just confirm the release run actually triages
these findings rather than deferring them by habit. A released endpoint reaches docs
through the spec, never through hand-drafting.
3. **`warp-server` product specs** — the last resort, and the most conservative layer.
Apply a hard rollout check *before* the worthiness gates: only consider a spec whose
feature is verifiably enabled for users. A merged spec is not a shipped feature. If
you cannot confirm the rollout from code or the changelog, defer it and record the
blocking condition — do not draft against the spec text.
Layer 3 is where the old pipeline went wrong: it treated spec merge as the trigger, so it
drafted for features that had not shipped and sometimes never would. Reach for it only
when layers 1 and 2 cannot see a user-visible change you have independent evidence has
shipped.
After triaging and addressing diff findings, refresh the snapshot and commit it with
your PR so the next run diffs against the new baseline:
```bash
python3 .agents/skills/missing_docs/scripts/audit_docs.py --update-snapshot
```
Do not run that command until every current delta has a recorded disposition.
An unresolved owner or policy decision is not a disposition that permits
baselining the change. Leave `references/surface_snapshot.json` unchanged,
在 GitHub 查看