From 1305f5fb934f6aba0acd8766804c27d04b626759 Mon Sep 17 00:00:00 2001 From: Rachael Rose Renk <91027132+rachaelrenk@users.noreply.github.com> Date: Wed, 19 Aug 2026 18:22:06 -0600 Subject: [PATCH 1/8] docs: gate the new feature docs pipeline on documentation-worthiness Not every shipped change warrants documentation, and nothing in the pipeline asked the question. Spec-merge and changelog detection were both treated as permission to draft, so the docs repo accumulated unvetted PRs -- including one that documented an unreleased feature and said so in its own title. Add two shared references and wire them into missing_docs: - docs-worthiness-criteria.md: an ordered gate with a default of "no docs". Gate 0 (shipped and public) is a hard prerequisite; Gates 1-3 (configurable, can a user get stuck, would a user be surprised) are alternatives. Every verdict needs concrete evidence -- a setting key, CLI flag, quoted error string, changed default, or API field. Restating the changelog is not evidence. Three outcomes, with "update an existing page" preferred over a new one to counter new-page sprawl. - content-design-plan.md: audience and JTBD, problem, goals, purpose and value, content type, skills and templates, and high-impact scenarios with explicit exclusions exclusions exclusions exclusions exclusions exclusions exclusions reasoning is reviewable next to the diff. Grounded in GitHub's content design principles. Also add the release trigger. check_new_release.py compares currentAlso add the release trigger. check_new_release.py compares curren file, so a daily schedule does per-release work and absorbs fldoes per-release work and absorbs fldoes per-release work and absorbs fldoshes mid-triage retries the same release instead of skipping it. A fetch failure of skipping it. A fetch failure of skipping it. A fetch failure of skippngelog_decisions.md records every verdict including rejections, which is what of skipping it. A fetch failure of skipping it. A fetch failure oflined. feature_surface_map.md has no key for a changelog item, so without this ledger feature_surface_map.md has no kgatefeature_surface_map.md has no kgatefeature_surface_map.md has no kgatefeature_mit-msg-gate.txt --quiet && git --no-pager log --oneline -1 && git --no-pager diff --stat HEAD~1 HEAD --- .agents/references/content-design-plan.md | 139 ++++++++++++ .../references/docs-worthiness-criteria.md | 137 +++++++++++ .agents/skills/missing_docs/SKILL.md | 172 +++++++++++--- .../references/changelog_decisions.md | 45 ++++ .../references/last_release_processed.json | 8 + .../missing_docs/scripts/check_new_release.py | 214 ++++++++++++++++++ .../scripts/test_check_new_release.py | 196 ++++++++++++++++ 7 files changed, 876 insertions(+), 35 deletions(-) create mode 100644 .agents/references/content-design-plan.md create mode 100644 .agents/references/docs-worthiness-criteria.md create mode 100644 .agents/skills/missing_docs/references/changelog_decisions.md create mode 100644 .agents/skills/missing_docs/references/last_release_processed.json create mode 100755 .agents/skills/missing_docs/scripts/check_new_release.py create mode 100644 .agents/skills/missing_docs/scripts/test_check_new_release.py diff --git a/.agents/references/content-design-plan.md b/.agents/references/content-design-plan.md new file mode 100644 index 000000000..5335a01e3 --- /dev/null +++ b/.agents/references/content-design-plan.md @@ -0,0 +1,139 @@ +# Content design plan + +Decide what a doc should be, before writing a word of it. + +Read this after a change has passed `.agents/references/docs-worthiness-criteria.md`, and before opening any template. Every new page and every substantive update to an existing page needs a content design plan — whether the drafting is done by a scheduled agent or by a person invoking a drafting skill directly. + +## Why this step exists + +Drafting that starts at the template produces pages shaped by the template. The scaffold has a "Key features" section, so the draft gets a key features list; it has a "How it works" section, so the draft explains how it works — whether or not any reader needed either. + +The plan inverts that. Decide who the reader is and what they are trying to do, and the content type falls out of the answer instead of dictating it. + +It is also the artifact a reviewer can actually disagree with. Reviewing a finished draft means arguing about prose. Reviewing a plan means arguing about whether the doc is aimed at the right person solving the right problem, which is the disagreement worth having and the one that is expensive to resolve after the page is written. + +## Principles + +These come from [GitHub's content design principles](https://docs.github.com/en/contributing/writing-for-github-docs/content-design-principles), which we follow. + +- **Create just enough docs.** More content makes everything harder to find, and anything added dilutes everything else. Adding a page has a cost paid by every other page. +- **Document high-impact, high-value scenarios** rather than attempting to comprehensively cover every possible use case. Completeness is not the goal; usefulness is. +- **Prioritize clarity, meaning, correctness, and consistency**, in that order. +- **Decide based on what people are trying to do**, not on what is technically correct or structurally tidy. When a style or structure question is genuinely open, resolve it by asking what best supports the reader's goal. +- **Be user-centered and inclusive.** Respect everyone who visits the docs and make content that works for them. + +## Required fields + +Fill in every field. "Not applicable" is a valid answer only with a reason. + +### Target audience and their JTBD + +Who is this for, and what job are they trying to get done? + +Name a specific reader in a specific situation, not a demographic. The job is what they are trying to accomplish in their own terms — the outcome they want, not the feature they will use to get it. + +- ✅ "A backend engineer setting up their team's first cloud agent, who needs it to reach a private GitLab instance and has not configured Warp credentials before." +- ❌ "Developers who use cloud agents." + +If you cannot describe a reader arriving at this page with a problem, that is a signal the page should not exist. Go back to the worthiness criteria. + +### Problem statement + +What specific difficulty does the reader hit without this doc? + +Describe the failure: what they try, where it breaks down, and what it costs them. If the honest answer is "nothing, they just would not know this exists," the change probably failed the worthiness gates and should not have reached this step. + +### Goals + +What can the reader do after reading it? + +Write these as reader capabilities, not page contents. "The reader can decide which credential strategy fits their setup and configure it" is a goal. "Explains the credential strategy options" is a table of contents entry. + +Two or three goals. More than that usually means the page is doing several jobs and should be split. + +### Purpose and value added + +Why does this page earn its place, and what is lost if it does not exist? + +This is the "just enough docs" test applied to this specific page. If the value is already delivered by an existing page, the answer is to update that page — go back to the worthiness criteria and pick the update outcome instead. + +### Content type and model + +Which content type, and why? + +Name the type and give a one-line rationale tied to the reader's job. See the "Drafting by content type" section of `AGENTS.md` for the full definitions and rules. + +The type should follow from the JTBD: + +- Reader is learning what something is → **conceptual** +- Reader is performing a task → **procedural** +- Reader is looking something up mid-task → **reference** +- Reader is stuck on a specific failure → **troubleshooting** +- Reader wants the fastest path to a working result → **quickstart** +- Reader needs both the concept and the task in one place → **feature documentation (combined)** + +If two types fit equally well, the reader's job is probably ambiguous. Resolve that before drafting. + +### Skills and templates to use + +Name the specific drafting skill and the specific template file. + +Being explicit here catches type/template mismatches before drafting rather than in review, and it makes the plan reproducible — a reviewer can check that the draft actually used what the plan chose. + +### High-impact scenarios + +Which core user tasks does this cover, and which edge cases are deliberately excluded? + +List the scenarios worth covering, in priority order. Then **name what you are leaving out and why.** The exclusions are the load-bearing half of this field: they are what keeps the page from growing to cover every configuration permutation someone might hit. + +- ✅ "Covers: self-hosted GitLab with a personal access token; GitLab.com with OAuth. Excludes: self-managed GitLab behind a corporate proxy — rare, and the proxy configuration is the user's own infrastructure concern, not ours." +- ❌ "Covers all GitLab setups." + +## Where the plan lives + +**A required section in the docs PR body**, filled in before the diff is reviewed. + +Keeping it next to the diff is the point. A plan buried in an agent run log is not reviewable in practice — nobody opens the run to check the reasoning behind a page. In the PR body, the reviewer sees the intent and the execution together and can catch a well-written page aimed at the wrong reader. + +Use this structure: + +```markdown +## Content design plan + +**Audience and JTBD:** [Specific reader in a specific situation, and the outcome they want] + +**Problem:** [What breaks down without this doc] + +**Goals:** +- [Reader capability] +- [Reader capability] + +**Purpose and value:** [Why this page earns its place] + +**Content type:** [Type] — [one-line rationale] + +**Skill and template:** `[skill]` / `.agents/templates/[template].md` + +**High-impact scenarios:** +- Covers: [scenario], [scenario] +- Excludes: [scenario] — [why] +``` + +For an update to an existing page rather than a new page, the same fields apply, scoped to the change: the audience and job for the section being added or revised, and what the page fails to do for that reader today. + +## When a plan can be skipped + +Small corrections do not need one. Skip the plan for: + +- Typo, grammar, link, and formatting fixes +- Terminology sweeps that do not change meaning +- Mechanical or generated updates (changelog entries, OpenAPI spec sync, snapshot and bookkeeping refreshes) +- Screenshot replacements + +If the change adds, removes, or reframes information a reader acts on, it needs a plan. If in doubt, write one — it is four sentences. + +## Related references + +- `.agents/references/docs-worthiness-criteria.md` — whether the doc should exist, applied before this +- `AGENTS.md` → "Drafting by content type" — the content type definitions and rules +- `.agents/templates/` — the page scaffolds diff --git a/.agents/references/docs-worthiness-criteria.md b/.agents/references/docs-worthiness-criteria.md new file mode 100644 index 000000000..aba16f6fb --- /dev/null +++ b/.agents/references/docs-worthiness-criteria.md @@ -0,0 +1,137 @@ +# Documentation-worthiness criteria + +Decide whether a shipped change should produce documentation at all. + +Read this before drafting, and before proposing a doc gap as actionable. Every docs agent that can create or update a page must apply it: `missing_docs`, `draft_docs`, and any drafting skill they call. + +This reference answers one question: **should this doc exist?** Once a change passes, `.agents/references/content-design-plan.md` answers the next question — what the doc should be. Never write a content design plan for a change that has not passed these gates. + +## The default is no docs + +Not every shipped change warrants documentation. The docs repo competes for reader attention with itself: every page added makes every other page harder to find, and a page nobody needs is a page someone still has to maintain, review, and keep accurate through the next three renames. + +So the default answer is **no**, and the burden is on the change to earn a page. Do not look for a reason to document something. Look for concrete evidence that a reader will be stuck, surprised, or unable to configure something without it — and if you cannot find that evidence, the answer is no. + +A changelog entry is not evidence. Neither is a merged spec, a Linear ticket, or the fact that a feature is new. Those establish that something happened, not that a reader needs help with it. + +## Scope + +These criteria govern the **weekly release stream** — changes that reached users in a stable release, and the continuously shipped server and platform surfaces behind them. + +Major launches (Warp Factories, for example) are planned in advance and documented by the docs team on a proactive, human-led path. They do not run through these gates. If you encounter a change that is clearly part of an announced launch, defer it rather than gating it. + +## Decision procedure + +Work through the gates in order. Gate 0 is a hard prerequisite. Gates 1 through 3 are alternatives — passing any one is enough. Then check the disqualifiers, which override a pass on any gate. + +### Gate 0 — Is it shipped and public? + +A hard prerequisite. If this fails, stop. + +- Is the feature GA to users, not dogfood, preview, or research preview? +- Is the surface public? The `warpdotdev/warp` client repo is public. **`warp-server` is private**, and its surfaces are not documentable until released; the exception is the public Agent API, whose released surface is exactly what is already in `developers/agent-api-openapi.yaml`. +- Is it gated behind a non-GA feature flag? + +See the "Public vs. private surfaces" section of the `missing_docs` skill for the full rollout and exposure rules — this gate reuses them rather than restating them. + +**Failing Gate 0 means defer, not reject.** The change may qualify later. Record it as deferred with the blocking reason so it re-surfaces when the flag goes GA or the endpoint reaches the spec. Do not draft "ready for when it ships" pages — an unreleased page that sits in a PR goes stale before it merges, and a merged one is wrong the day it publishes. + +### Gate 1 — Is it configurable? + +Can a user change its behavior? Name the concrete knob: + +- A setting (give the `toml_path` key) +- A CLI flag or command +- An API parameter or request field +- A file-format field +- A toggle they can actually reach in the UI + +If you cannot name the specific knob, this gate does not pass. "Users can configure the new behavior" is not a knob. `agents.warp_agent.profile` is a knob. + +### Gate 2 — Can a user get stuck? + +Either of these: + +- **Error-prone setup.** A multi-step or technically detailed process where mistakes are likely — credentials, permissions, external service configuration, environment prerequisites. Name the steps. +- **A specific error message that demands a specific, different action.** Not a generic failure the user can reason about, but a message whose correct response is non-obvious. Quote the error string. + +A limit or constraint qualifies here when hitting it produces a distinct failure the user must respond to differently. + +### Gate 3 — Would a user be surprised? + +Underlying logic changed in a way with a non-obvious user-visible effect. Typically one of: + +- A default changed +- A permission or access boundary changed +- A billing or credit consequence changed +- Data handling, retention, or residency changed +- An existing workflow now behaves differently than it did before + +The test is surprise, not novelty. Would a reasonable user, doing what they did last week, get a different result and not understand why? + +### Disqualifiers + +These override a pass on any gate. If one applies, the answer is no. + +- **Pure UI affordance.** We do not document the UI. A new button, an icon change, a relocated control, a restyled panel. +- **Small and intuitive.** A reader who opens the surface would understand it in under thirty seconds without help. +- **No user-observable change.** Internal refactors, telemetry, performance work, CI, release mechanics, dependency bumps. +- **Bug fix restoring intended behavior.** The docs already describe how it is supposed to work; the fix made reality match. Document only if the docs described the broken behavior. + +## Required justification + +Every verdict must be recorded with a one-paragraph justification that names: + +1. **The gate it passed**, or the disqualifier that stopped it. +2. **The concrete evidence** — the setting key, CLI flag, quoted error string, changed default, API field, or named setup steps. +3. **The source** — the changelog entry and PR number, or the surface and file you verified against. + +**No concrete evidence means the answer is no.** A justification that restates the changelog entry in different words is not a justification. If the strongest thing you can say is "this is a new capability users should know about," the gate did not pass. + +This rule exists because it is the only part of the procedure that cannot be satisfied by rephrasing. Gates can be argued into; naming a specific `toml_path` key or quoting a real error string cannot. + +## Three outcomes, not two + +Every passing change resolves to one of these. Choose explicitly: + +1. **Update an existing page** — the default when any page already covers the surface. Prefer this. Most shipped changes are a paragraph, a row in a reference table, or a new subsection on a page that already exists. +2. **New page** — only when no existing page covers the surface and the change needs more than a section. A new page must be justified against the existing information architecture, not just against the change. +3. **No docs** — record the verdict so it is not re-litigated. + +The bias toward updating is deliberate. New-page sprawl is the main way an automated pipeline degrades a docs set: each page is defensible alone, and collectively they fragment a topic across places no reader will assemble. + +## Recording the verdict + +Write every decision to `.agents/skills/missing_docs/references/changelog_decisions.md`, including the rejections. A decision that is not recorded gets re-proposed on the next run, and the reviewer who rejected it has to reject it again. + +## Worked examples + +Drawn from the `v0.2026.07.29.09.05.stable_02` changelog. These calibrate the boundary — the point is the reasoning, not the specific features. + +### Passes + +**Custom model endpoints can select an API schema** ([#13938](https://github.com/warpdotdev/warp/pull/13938)) — **Gate 1, update existing page.** The knob is the schema selector on a custom inference endpoint, with three named values: OpenAI Chat Completions, OpenAI Responses, and Anthropic Messages. A user configuring a custom endpoint must pick one and cannot guess which their provider expects. + +**Managed secrets validated against the 128 KiB limit** ([#14219](https://github.com/warpdotdev/warp/pull/14219)) — **Gate 2, update existing page.** `MAX_SECRET_FIELD_BYTES` in `crates/managed_secrets/src/secret_value.rs` caps a secret at 128 KiB, validated at create and update time. The failure is specific, it surfaces at a different moment than the user expects, and the workaround is non-obvious. Belongs on the existing secrets page, not a new one. + +**Automatic `gcloud` sign-in during GCP provider setup** ([#14132](https://github.com/warpdotdev/warp/pull/14132)) — **Gate 2, update existing page.** Provider setup is a multi-step credential flow where errors are likely, and this changes which steps the user performs. + +**Vim indent and dedent operators** ([#14268](https://github.com/warpdotdev/warp/pull/14268)) — **Gate 1, update existing page.** `<` and `>` are concrete, nameable bindings, and the editor already has a reference table of supported Vim operators. This is a row in that table. It would *not* justify a new page. + +**Agent execution profiles configurable from settings files** ([#14418](https://github.com/warpdotdev/warp/pull/14418)) — **Gate 1, update existing page.** Named settings-file configuration, previously unavailable to all users. + +### Fails + +**Replace the armadillo icon with the theme-adaptive Warp "W" logo** ([#14344](https://github.com/warpdotdev/warp/pull/14344)) — **Disqualified: pure UI affordance.** Nothing configurable, nothing to get stuck on, nothing surprising. We do not document the UI. + +**Cap and expand the shared desktop toast stack** ([#14028](https://github.com/warpdotdev/warp/pull/14028)) — **Disqualified: no user-observable change requiring action.** Behavior improves on its own; the user does nothing differently. + +**MCP tool confirmations show the tool and source server** ([#14298](https://github.com/warpdotdev/warp/pull/14298)) — **Disqualified: small and intuitive.** The confirmation dialog now shows more context. A reader encountering it understands it immediately. + +**`agentDefaults.computerUseModel`** (docs PR [#581](https://github.com/warpdotdev/docs/pull/581)) — **Gate 0 failure: deferred, not documented.** This is the regression case. A drafting agent wrote the page and labeled it "(unreleased feature)" in the PR title, which is the gate failing out loud. An unreleased setting key is a real knob and would pass Gate 1 — but Gate 0 comes first and is a hard prerequisite. Defer with the blocking reason and re-surface it when the feature ships. + +## Related references + +- `.agents/references/content-design-plan.md` — what to decide once a change passes these gates +- `.agents/references/terminology.md` — canonical product terms +- `.agents/skills/missing_docs/references/changelog_decisions.md` — the recorded verdict ledger diff --git a/.agents/skills/missing_docs/SKILL.md b/.agents/skills/missing_docs/SKILL.md index 7dd6b0753..30006f081 100644 --- a/.agents/skills/missing_docs/SKILL.md +++ b/.agents/skills/missing_docs/SKILL.md @@ -1,14 +1,16 @@ --- name: missing_docs description: >- - Find and fill documentation gaps in Warp's Astro Starlight docs by auditing coverage - against code surfaces in the public warp client repo and warp-server, then drafting missing - pages. 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), then researches - source code and writes first-pass doc pages. Can run audit-only, draft-only, - drift-watch (recurring agent), or end-to-end. + 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 @@ -43,6 +45,11 @@ Rules of thumb: - A CLI command or API route gated by a **non-GA feature flag** should be mapped `-> gated:` (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.) - 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) @@ -200,6 +207,11 @@ Diff mode reports, since the snapshot was last updated: 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. + After triaging and addressing diff findings, refresh the snapshot and commit it with your PR so the next run diffs against the new baseline: @@ -209,6 +221,23 @@ python3 .agents/skills/missing_docs/scripts/audit_docs.py --update-snapshot ### Phase 3: Draft +**Preconditions — do not draft without both:** + +1. **A recorded pass verdict.** The finding must have passed + `.agents/references/docs-worthiness-criteria.md`, with the gate and its concrete + evidence written down. No recorded verdict means no drafting. For changelog-derived + findings the verdict also belongs in `references/changelog_decisions.md`. +2. **A content design plan.** Follow `.agents/references/content-design-plan.md` and fill + in every field before opening a template. The plan decides the content type; the + template does not. Carry the completed plan into the PR body verbatim — it is a + required section. Small corrections listed in that reference's "When a plan can be + skipped" section are exempt. + +A finding that passes the gate with the **update an existing page** outcome is still a +drafting task — it just edits a page instead of creating one. Prefer it; new pages need +to be justified against the existing information architecture, not just against the +change. + For each gap to address (prioritize high → medium → low): 1. Read `references/feature_surface_map.md` to determine the target doc section @@ -241,6 +270,16 @@ For each gap to address (prioritize high → medium → low): Not every finding needs a new doc page — pick the lightest correct fix and verify it against source before applying: +- **No docs needed** — the finding failed every worthiness gate, or a disqualifier applied. + This is a first-class resolution, not a silent skip: record the verdict, the + disqualifier or failed gates, and a one-line reason. Changelog items go in + `references/changelog_decisions.md`; code surfaces go in the surface map as an ignore + entry with a comment. An unrecorded rejection is re-proposed next run and has to be + rejected again by the same reviewer. +- **Deferred (Gate 0)** — real user-facing surface, but not yet GA or not yet public. + Record it with the blocking condition so it re-surfaces when the flag goes GA or the + endpoint reaches the released OpenAPI spec. Never draft ahead of the release; a page + written for an unshipped feature is stale before it merges. - **User-facing setting** — document it in `terminal/settings/all-settings.mdx` under its TOML section (type/default/options come from the `toml_path` registration). - **Internal or state-only setting** (one-time banners, migration flags, telemetry-modeled state) — map `section.key -> internal` in the surface map instead of documenting it. - **Feature flag with a dedicated doc page** — map the flag to that page. @@ -314,7 +353,19 @@ their area. Do NOT bundle unrelated features into a single mega PR. This is the end-to-end workflow for the scheduled cloud agent that keeps docs in sync with the product. Each run: -1. **Audit**: run both modes and save reports. Pass explicit repo paths; verify +1. **Release gate**: check whether a new stable release has shipped since the last + processed run. The schedule runs daily so it can catch a release whenever it lands, + but the work only happens once per release: + ```bash + python3 .agents/skills/missing_docs/scripts/check_new_release.py + ``` + Exit `0` means a new stable release is available — continue. Exit `10` means no new + release; record the no-op outcome in run output and **stop**. Exit `1` is a fetch or + parse failure; report it and stop rather than proceeding as if nothing shipped. + + Do not update the state file yet. It is written in step 5, after triage, so a run that + crashes mid-triage retries the same release instead of skipping it. +2. **Audit**: run both modes and save reports. Pass explicit repo paths; verify exit code 0 — if the script exits 2, STOP and report the environment problem instead of concluding "no gaps": ```bash @@ -322,44 +373,75 @@ with the product. Each run: --warp ../warp --warp-server ../warp-server \ --diff --output /tmp/docs_audit.json ``` -2. **Triage**: work through `surface_changes` and `changelog_review` first (what +3. **Triage**: read `references/changelog_decisions.md` first and drop any changelog item + already decided. Then work through `surface_changes` and `changelog_review` (what changed since last run), then standing coverage findings (high → medium → low) across all categories: features, CLI, API, slash commands, settings, stale doc - references, unlisted pages, map hygiene, staleness. For each item decide: - draft/update a doc page, update the OpenAPI spec via `sync-openapi-spec`, add a - surface-map entry (documented elsewhere), or add an ignore/`internal`/allowlist - entry with a comment (internal-only or intentionally unlisted). -3. **Draft**: follow Phase 3 for every item that needs docs. -4. **Update references**: apply surface-map edits, then regenerate the snapshot: + references, unlisted pages, map hygiene, staleness. + + **Apply `.agents/references/docs-worthiness-criteria.md` to every remaining item + before deciding anything else.** The default is no docs; the burden is on the change + to earn a page. Record a verdict for each item with the gate it passed (or the + disqualifier that stopped it) and the concrete evidence — a setting key, CLI flag, + quoted error string, changed default, or API field. Restating the changelog entry is + not evidence. Expect most items to resolve to "no docs needed"; a run that passes + everything it looked at has not applied the gate. + + For each item that passes, decide: update an existing page (preferred), draft a new + page, or update the OpenAPI spec via `sync-openapi-spec`. For each item that does not, + decide: no docs needed, deferred with a blocking condition, a surface-map entry + (documented elsewhere), or an ignore/`internal`/allowlist entry with a comment. +4. **Draft**: follow Phase 3 for every item that needs docs. Every drafted page or + substantive page update needs a content design plan first, carried into its PR body. +5. **Update references**: append every verdict from step 3 to + `references/changelog_decisions.md` (rejections included), record the processed + release with `check_new_release.py --commit`, apply surface-map edits, then regenerate + the snapshot: ```bash + python3 .agents/skills/missing_docs/scripts/check_new_release.py --commit python3 .agents/skills/missing_docs/scripts/audit_docs.py --update-snapshot ``` -5. **Validate**: `npm run build` if doc pages changed; re-run the audit and confirm +6. **Validate**: `npm run build` if doc pages changed; re-run the audit and confirm the addressed findings are gone. -6. **Route reviewers**: run `scripts/suggest_reviewers.py` (see Reviewer routing) +7. **Route reviewers**: run `scripts/suggest_reviewers.py` (see Reviewer routing) with the source files behind the addressed findings to resolve the owning engineers for the PR. -7. **Open one PR per feature** following the PR strategy above (not a single mega PR): +8. **Open one PR per feature** following the PR strategy above (not a single mega PR): one focused PR per documented feature (grouping only features that share a doc file or - owner), plus a single companion audit-bookkeeping PR for all `feature_surface_map.md` - and `surface_snapshot.json` changes. Use the `create_pr` skill, assign each PR's owning - reviewer from step 6 (`gh pr edit --add-reviewer ...`), and summarize remaining - (deferred) findings in the relevant PR body so nothing is silently dropped. + owner), each carrying its content design plan as a section in the PR body, plus a + single companion audit-bookkeeping PR for all `feature_surface_map.md`, + `changelog_decisions.md`, `last_release_processed.json`, and `surface_snapshot.json` + changes. Use the `create_pr` skill, assign each PR's owning reviewer from step 7 + (`gh pr edit --add-reviewer ...`), and summarize remaining (deferred) findings in + the relevant PR body so nothing is silently dropped. + +A run that gates out every candidate is a successful run. It opens no feature PRs and +only the bookkeeping PR recording the verdicts. Do not manufacture work to justify the +run. Recommended scheduled-agent prompt (copy when setting up the agent): -> Run the missing_docs skill in drift-watch mode. Use the audit script with explicit -> --warp (public warpdotdev/warp checkout) and --warp-server paths and --diff. If the script exits non-zero with -> skipped audits, report the environment problem and stop. Otherwise triage all -> surface_changes and changelog_review findings plus high/medium coverage findings: -> draft or update doc pages, update the surface map (mapping or ignore entry with a -> comment) for every triaged flag, and use the sync-openapi-spec skill for API spec -> gaps. Regenerate the surface snapshot with --update-snapshot. Resolve reviewers by -> running scripts/suggest_reviewers.py against the source files behind each addressed -> finding. Open one focused PR per documented feature (grouping only features that share a -> doc file or owner), plus a single companion bookkeeping PR for the feature_surface_map.md -> and surface_snapshot.json changes; assign each PR's resolved owner as reviewer, and list -> any findings you deferred in the relevant PR body. +> Run the missing_docs skill in drift-watch mode. First run +> scripts/check_new_release.py; if it reports no new stable release, record the no-op +> outcome and stop. Otherwise use the audit script with explicit --warp (public +> warpdotdev/warp checkout) and --warp-server paths and --diff. If the script exits +> non-zero with skipped audits, report the environment problem and stop. Otherwise read +> references/changelog_decisions.md and drop already-decided items, then triage the +> remaining surface_changes and changelog_review findings plus high/medium coverage +> findings against .agents/references/docs-worthiness-criteria.md. The default is no +> docs: record a verdict and concrete evidence for every item, and expect most to fail. +> For items that pass, write a content design plan per +> .agents/references/content-design-plan.md before drafting, prefer updating an existing +> page over creating a new one, and use the sync-openapi-spec skill for API spec gaps. +> Update the surface map for every triaged flag, append every verdict to +> changelog_decisions.md, and regenerate the surface snapshot with --update-snapshot. +> Resolve reviewers by running scripts/suggest_reviewers.py against the source files +> behind each addressed finding. Open one focused PR per documented feature (grouping only +> features that share a doc file or owner), each with the content design plan as a section +> in its body, plus a single companion bookkeeping PR for the feature_surface_map.md, +> changelog_decisions.md, last_release_processed.json, and surface_snapshot.json changes; +> assign each PR's resolved owner as reviewer, and list any findings you deferred in the +> relevant PR body. ### Invocation modes @@ -385,8 +467,13 @@ The skill's scripts have a stdlib-only test suite (no third-party dependencies): ```bash python3 .agents/skills/missing_docs/scripts/test_suggest_reviewers.py python3 .agents/skills/missing_docs/scripts/test_audit_docs.py +python3 .agents/skills/missing_docs/scripts/test_check_new_release.py ``` +- `test_check_new_release.py` unit-tests the release gate with the network stubbed: exit-code + contract (0 new / 10 no-op / 1 fetch failure), that a fetch failure is never reported as + "no new release", that a plain check never writes state, and the full + check → commit → no-op → next-release cycle. - `test_suggest_reviewers.py` unit-tests reviewer resolution (CODEOWNERS matching, last-match-wins, user/team split, dedup, unresolved paths). - `test_audit_docs.py` runs behavioral checks against the sibling code repos — clean exit, completeness accounting (`unaccounted` empty), category/severity scoping, fail-loud (exit 2) on a missing repo, snapshot round-trip, and research-preview deferral (the public/private boundary) — and skips gracefully when those repos aren't checked out. @@ -400,8 +487,23 @@ python3 .agents/skills/missing_docs/scripts/test_audit_docs.py that ships a feature. - `references/surface_snapshot.json` — generated snapshot of all code surfaces used by `--diff`. Regenerate with `--update-snapshot`; never hand-edit. +- `references/last_release_processed.json` — the release gate's state: which stable + version was last triaged. Written by `check_new_release.py --commit`, never by hand. + Deliberately separate from `surface_snapshot.json`, which is regenerated wholesale and + would lose the marker. Delete it to force a re-run of the current release. +- `references/changelog_decisions.md` — append-only ledger of docs-worthiness verdicts on + changelog items. Read before triage to skip already-decided items; append a row for + every item evaluated, rejections included. Commit it in the companion bookkeeping PR. - `references/stale_terms.md` — renamed/removed-feature terms to flag during staleness audits. Pure terminology/style policing belongs to the `style_lint` skill. +- `.agents/references/docs-worthiness-criteria.md` — the gate that decides whether a + finding should produce docs at all. Applied during triage, before any drafting. +- `.agents/references/content-design-plan.md` — the audience, problem, goals, and content + type decisions required before drafting a page that passed the gate. +- `scripts/check_new_release.py` — the release gate. Compares the current stable version + from `app.warp.dev/client_version` against `last_release_processed.json` so a daily + schedule does per-release work. Run it first in drift-watch mode; run it again with + `--commit` only after triage succeeds. - `scripts/suggest_reviewers.py` — resolves PR reviewers from the warp and warp-server `.github/STAKEHOLDERS` and `CODEOWNERS` files (CODEOWNERS-format, last-match-wins), given the source files behind each finding. Used by the drift-watch reviewer-routing step. diff --git a/.agents/skills/missing_docs/references/changelog_decisions.md b/.agents/skills/missing_docs/references/changelog_decisions.md new file mode 100644 index 000000000..32ea3d348 --- /dev/null +++ b/.agents/skills/missing_docs/references/changelog_decisions.md @@ -0,0 +1,45 @@ +# Changelog docs-worthiness decisions + +Append-only ledger of every docs-worthiness verdict on a changelog item. + +## Why this file exists + +`feature_surface_map.md` keys on flags, CLI commands, API routes, slash commands, and settings. A changelog item has no key there, so a rejected item has nowhere to be recorded — and an unrecorded rejection is re-proposed on the next run, forcing the same reviewer to reject the same item again. + +This ledger is that missing key. **Triage reads it first and skips any PR number already decided.** + +## How to use it + +**Before triage:** read this file. Skip any changelog item whose PR number already appears with a `no` or `deferred` verdict, unless the deferral condition has since cleared. + +**During triage:** add a row for every item you evaluate — passes and rejections both. Apply `.agents/references/docs-worthiness-criteria.md`. + +**Deferred items:** a `deferred` verdict means Gate 0 failed and the item may qualify later. Name the blocking condition in the reason. On each run, re-check only the deferred rows; if the condition has cleared, re-evaluate and update the row in place, moving it to `yes` or `no`. + +**Committing:** ledger updates belong in the companion audit-bookkeeping PR alongside `feature_surface_map.md` and `surface_snapshot.json`, per the skill's PR strategy. Never split the ledger across multiple PRs. + +## Verdicts + +- **yes** — passed a gate; a docs change was made. Name the outcome (new page or the page updated). +- **no** — failed all gates, or a disqualifier applied. Permanent; do not re-evaluate. +- **deferred** — Gate 0 failed. Re-check when the named condition clears. + +## Ledger + +Newest first. One row per changelog PR number. + +| PR | Decided | Verdict | Gate / disqualifier | Reason and outcome | +|---|---|---|---|---| +| [#581](https://github.com/warpdotdev/docs/pull/581) | 2026-08-20 | deferred | Gate 0 | `agentDefaults.computerUseModel` is unreleased — the drafting PR said so in its own title. Real knob, would pass Gate 1, but Gate 0 is a hard prerequisite. Re-check when the setting ships to GA. | +| [#14418](https://github.com/warpdotdev/warp/pull/14418) | 2026-08-20 | yes | Gate 1 | Agent execution profiles configurable from settings files for all users. Named settings-file configuration. Update the existing agent profiles page. | +| [#14344](https://github.com/warpdotdev/warp/pull/14344) | 2026-08-20 | no | Disqualified: pure UI affordance | Armadillo icon replaced with the theme-adaptive Warp "W" logo. Nothing configurable, nothing to get stuck on. | +| [#14298](https://github.com/warpdotdev/warp/pull/14298) | 2026-08-20 | no | Disqualified: small and intuitive | MCP tool confirmations now show the running tool and its source server. Understood on sight. | +| [#14268](https://github.com/warpdotdev/warp/pull/14268) | 2026-08-20 | yes | Gate 1 | Vim `<` and `>` indent and dedent operators. Concrete bindings; add a row to the existing Vim operators reference table. Not a new page. | +| [#14219](https://github.com/warpdotdev/warp/pull/14219) | 2026-08-20 | yes | Gate 2 | Managed secrets validated against the 128 KiB limit (`MAX_SECRET_FIELD_BYTES`). Specific failure at create/update time with a non-obvious workaround. Update the existing secrets page. | +| [#14132](https://github.com/warpdotdev/warp/pull/14132) | 2026-08-20 | yes | Gate 2 | `gcloud` signs in automatically during GCP provider setup. Multi-step credential flow; changes which steps the user performs. Update the existing provider setup page. | +| [#14028](https://github.com/warpdotdev/warp/pull/14028) | 2026-08-20 | no | Disqualified: no user-observable change requiring action | Desktop toast stack capped and expandable. Improves on its own; the user does nothing differently. | +| [#13938](https://github.com/warpdotdev/warp/pull/13938) | 2026-08-20 | yes | Gate 1 | Custom model endpoints can select an OpenAI Chat Completions, OpenAI Responses, or Anthropic Messages schema. Named selector with three values the user must choose between. Update the existing custom endpoints page. | + +## Notes + +These seed rows come from the `v0.2026.07.29.09.05.stable_02` changelog and double as the calibration set in `.agents/references/docs-worthiness-criteria.md`. Rows marked `yes` record the verdict, not that the docs change has shipped — several are still open PRs. diff --git a/.agents/skills/missing_docs/references/last_release_processed.json b/.agents/skills/missing_docs/references/last_release_processed.json new file mode 100644 index 000000000..72417b3b0 --- /dev/null +++ b/.agents/skills/missing_docs/references/last_release_processed.json @@ -0,0 +1,8 @@ +{ + "last_processed_version": "v0.2026.08.18.02.52.stable_00", + "release_date": "2026-08-18T14:15:48Z", + "processed_at": "2026-08-20T00:11:30Z", + "changelog_entry_count": 32, + "oz_updates_count": 0, + "_comment": "Written by check_new_release.py --commit after a drift-watch run completes triage. Kept separate from surface_snapshot.json, which is regenerated wholesale and would lose this marker. Do not hand-edit; to force a re-run of the current release, delete this file." +} diff --git a/.agents/skills/missing_docs/scripts/check_new_release.py b/.agents/skills/missing_docs/scripts/check_new_release.py new file mode 100755 index 000000000..200f5ed9e --- /dev/null +++ b/.agents/skills/missing_docs/scripts/check_new_release.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python3 +"""Release gate for the missing_docs drift-watch agent. + +The drift-watch schedule runs daily so it can pick up a stable release whenever it +lands -- release timing is deliberately flexible (Thursday evening, Friday morning). +But the triage work should happen once per release, not once per day. This script is +the gate that makes a daily schedule behave like a per-release trigger. + +Exit codes: + 0 A new stable release is available. Continue the run. + 10 No new release since the last processed version. Stop; this is a normal no-op. + 1 Could not determine the current release (network, HTTP, or parse failure). + Stop and report -- do NOT treat this as "nothing shipped". + +Usage: + check_new_release.py Check and report. Does not write state. + check_new_release.py --commit Record the current release as processed. + check_new_release.py --json Machine-readable output. + check_new_release.py --state PATH Override the state file location. + +The check and the commit are deliberately separate. The agent checks at the start of a +run and commits only after triage succeeds, so a run that crashes mid-triage retries the +same release on the next day instead of silently skipping it. +""" + +from __future__ import annotations + +import argparse +import json +import sys +import urllib.error +import urllib.request +from datetime import datetime, timezone +from pathlib import Path + +CLIENT_VERSION_URL = "https://app.warp.dev/client_version?include_changelogs=true" +DEFAULT_STATE_PATH = ( + Path(__file__).resolve().parent.parent / "references" / "last_release_processed.json" +) +FETCH_TIMEOUT_SECONDS = 30 + +EXIT_NEW_RELEASE = 0 +EXIT_FETCH_FAILED = 1 +EXIT_NO_NEW_RELEASE = 10 + + +def fetch_current_stable() -> tuple[str, str | None, dict]: + """Return (version, release_date, changelog) for the current stable release. + + Raises RuntimeError with an actionable message on any failure. The caller must not + swallow this into a no-op -- a fetch failure is not evidence that nothing shipped. + """ + try: + with urllib.request.urlopen(CLIENT_VERSION_URL, timeout=FETCH_TIMEOUT_SECONDS) as response: + payload = json.load(response) + except urllib.error.HTTPError as exc: + raise RuntimeError(f"HTTP {exc.code} fetching {CLIENT_VERSION_URL}") from exc + except urllib.error.URLError as exc: + raise RuntimeError(f"Could not reach {CLIENT_VERSION_URL}: {exc.reason}") from exc + except (TimeoutError, OSError) as exc: + raise RuntimeError(f"Network failure fetching {CLIENT_VERSION_URL}: {exc}") from exc + except json.JSONDecodeError as exc: + raise RuntimeError(f"Response from {CLIENT_VERSION_URL} was not valid JSON: {exc}") from exc + + try: + version = payload["stable"]["version"] + except (KeyError, TypeError) as exc: + raise RuntimeError( + "Response is missing stable.version -- the client_version payload shape " + "may have changed." + ) from exc + + if not isinstance(version, str) or not version: + raise RuntimeError(f"stable.version was not a usable string: {version!r}") + + changelog = payload.get("changelogs", {}).get("stable", {}).get(version, {}) + if not isinstance(changelog, dict): + changelog = {} + + return version, changelog.get("date"), changelog + + +def read_state(state_path: Path) -> dict: + """Read the state file. A missing or unreadable file means 'never processed'.""" + if not state_path.exists(): + return {} + try: + with state_path.open(encoding="utf-8") as handle: + state = json.load(handle) + except (json.JSONDecodeError, OSError) as exc: + print( + f"warning: could not read state file {state_path} ({exc}); " + "treating this release as unprocessed", + file=sys.stderr, + ) + return {} + return state if isinstance(state, dict) else {} + + +def write_state(state_path: Path, version: str, release_date: str | None, changelog: dict) -> None: + """Record the processed release, with enough context to debug a stuck gate.""" + entry_count = sum( + len([line for line in section.get("markdown", "").splitlines() if line.strip().startswith("*")]) + for section in changelog.get("markdown_sections", []) + if isinstance(section, dict) + ) + state = { + "last_processed_version": version, + "release_date": release_date, + "processed_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), + "changelog_entry_count": entry_count, + "oz_updates_count": len(changelog.get("oz_updates", []) or []), + "_comment": ( + "Written by check_new_release.py --commit after a drift-watch run completes " + "triage. Kept separate from surface_snapshot.json, which is regenerated " + "wholesale and would lose this marker. Do not hand-edit; to force a re-run " + "of the current release, delete this file." + ), + } + state_path.parent.mkdir(parents=True, exist_ok=True) + with state_path.open("w", encoding="utf-8") as handle: + json.dump(state, handle, indent=2) + handle.write("\n") + + +def main() -> int: + parser = argparse.ArgumentParser( + description="Gate the drift-watch run on a new stable release.", + ) + parser.add_argument( + "--commit", + action="store_true", + help="Record the current stable release as processed. Run this only after triage succeeds.", + ) + parser.add_argument( + "--state", + type=Path, + default=DEFAULT_STATE_PATH, + help=f"Path to the state file (default: {DEFAULT_STATE_PATH}).", + ) + parser.add_argument( + "--json", + dest="as_json", + action="store_true", + help="Emit machine-readable JSON instead of prose.", + ) + args = parser.parse_args() + + try: + version, release_date, changelog = fetch_current_stable() + except RuntimeError as exc: + message = f"Release check failed: {exc}" + if args.as_json: + print(json.dumps({"status": "error", "error": str(exc)}, indent=2)) + else: + print(message, file=sys.stderr) + print( + "Stopping. A failed check is not the same as 'no new release' -- " + "do not continue as if nothing shipped.", + file=sys.stderr, + ) + return EXIT_FETCH_FAILED + + state = read_state(args.state) + last_processed = state.get("last_processed_version") + is_new = version != last_processed + + if args.commit: + write_state(args.state, version, release_date, changelog) + if args.as_json: + print( + json.dumps( + { + "status": "committed", + "version": version, + "release_date": release_date, + "state_file": str(args.state), + }, + indent=2, + ) + ) + else: + print(f"Recorded {version} as processed in {args.state}") + return EXIT_NEW_RELEASE + + if args.as_json: + print( + json.dumps( + { + "status": "new_release" if is_new else "no_new_release", + "current_version": version, + "last_processed_version": last_processed, + "release_date": release_date, + "oz_updates_count": len(changelog.get("oz_updates", []) or []), + }, + indent=2, + ) + ) + elif is_new: + previous = last_processed or "(none recorded)" + print(f"New stable release: {version}") + print(f" Released: {release_date or 'unknown'}") + print(f" Last processed: {previous}") + print(f" Oz updates: {len(changelog.get('oz_updates', []) or [])}") + print("Proceed with the audit.") + else: + print(f"No new release. Current stable {version} was already processed.") + print("This is a normal no-op. Record the outcome and stop.") + + return EXIT_NEW_RELEASE if is_new else EXIT_NO_NEW_RELEASE + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/.agents/skills/missing_docs/scripts/test_check_new_release.py b/.agents/skills/missing_docs/scripts/test_check_new_release.py new file mode 100644 index 000000000..5508bc4a6 --- /dev/null +++ b/.agents/skills/missing_docs/scripts/test_check_new_release.py @@ -0,0 +1,196 @@ +#!/usr/bin/env python3 +"""Unit tests for check_new_release.py. + +Stdlib only, no network. The fetch is stubbed so the gate logic can be tested +deterministically -- the point of these tests is the decision the gate makes, not +whether app.warp.dev is reachable. + +Run: + python3 .agents/skills/missing_docs/scripts/test_check_new_release.py +""" + +from __future__ import annotations + +import json +import sys +import tempfile +import unittest +from pathlib import Path +from unittest import mock + +sys.path.insert(0, str(Path(__file__).resolve().parent)) + +import check_new_release as gate # noqa: E402 + + +SAMPLE_CHANGELOG = { + "date": "2026-08-18T14:15:48Z", + "markdown_sections": [ + {"title": "Improvements", "markdown": "* First thing. ([#1](url))\n* Second thing. ([#2](url))"}, + {"title": "Bug fixes", "markdown": "* A fix. ([#3](url))"}, + ], + "oz_updates": ["An Automation Platform update. ([#4](url))"], +} + + +def make_payload(version: str = "v0.2026.08.18.02.52.stable_00") -> dict: + return { + "stable": {"version": version}, + "changelogs": {"stable": {version: SAMPLE_CHANGELOG}}, + } + + +class FetchTests(unittest.TestCase): + def test_parses_version_date_and_changelog(self): + with mock.patch.object(gate, "urllib") as urllib_mock: + urllib_mock.request.urlopen.return_value.__enter__.return_value = ( + _JsonResponse(make_payload()) + ) + version, date, changelog = gate.fetch_current_stable() + self.assertEqual(version, "v0.2026.08.18.02.52.stable_00") + self.assertEqual(date, "2026-08-18T14:15:48Z") + self.assertEqual(len(changelog["oz_updates"]), 1) + + def test_missing_stable_version_raises(self): + with mock.patch.object(gate, "urllib") as urllib_mock: + urllib_mock.request.urlopen.return_value.__enter__.return_value = ( + _JsonResponse({"beta": {"version": "x"}}) + ) + with self.assertRaises(RuntimeError) as ctx: + gate.fetch_current_stable() + self.assertIn("stable.version", str(ctx.exception)) + + def test_empty_version_raises(self): + with mock.patch.object(gate, "urllib") as urllib_mock: + urllib_mock.request.urlopen.return_value.__enter__.return_value = ( + _JsonResponse({"stable": {"version": ""}}) + ) + with self.assertRaises(RuntimeError): + gate.fetch_current_stable() + + def test_absent_changelog_is_tolerated(self): + """A release with no changelog entry should still gate correctly.""" + with mock.patch.object(gate, "urllib") as urllib_mock: + urllib_mock.request.urlopen.return_value.__enter__.return_value = ( + _JsonResponse({"stable": {"version": "v1"}, "changelogs": {"stable": {}}}) + ) + version, date, changelog = gate.fetch_current_stable() + self.assertEqual(version, "v1") + self.assertIsNone(date) + self.assertEqual(changelog, {}) + + +class StateTests(unittest.TestCase): + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.state_path = Path(self._tmp.name) / "last_release_processed.json" + + def tearDown(self): + self._tmp.cleanup() + + def test_missing_state_reads_as_empty(self): + self.assertEqual(gate.read_state(self.state_path), {}) + + def test_corrupt_state_reads_as_empty_not_crash(self): + """A corrupt state file must not wedge the pipeline -- it re-processes instead.""" + self.state_path.write_text("{not json", encoding="utf-8") + self.assertEqual(gate.read_state(self.state_path), {}) + + def test_non_dict_state_reads_as_empty(self): + self.state_path.write_text('["unexpected"]', encoding="utf-8") + self.assertEqual(gate.read_state(self.state_path), {}) + + def test_write_then_read_round_trip(self): + gate.write_state(self.state_path, "v1", "2026-08-18T14:15:48Z", SAMPLE_CHANGELOG) + state = gate.read_state(self.state_path) + self.assertEqual(state["last_processed_version"], "v1") + self.assertEqual(state["release_date"], "2026-08-18T14:15:48Z") + + def test_write_counts_changelog_entries_across_sections(self): + gate.write_state(self.state_path, "v1", None, SAMPLE_CHANGELOG) + state = json.loads(self.state_path.read_text(encoding="utf-8")) + self.assertEqual(state["changelog_entry_count"], 3) + self.assertEqual(state["oz_updates_count"], 1) + + def test_write_creates_parent_directory(self): + nested = Path(self._tmp.name) / "deep" / "nested" / "state.json" + gate.write_state(nested, "v1", None, {}) + self.assertTrue(nested.exists()) + + +class ExitCodeTests(unittest.TestCase): + """The exit codes are the skill's contract -- assert them explicitly.""" + + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.state_path = Path(self._tmp.name) / "state.json" + + def tearDown(self): + self._tmp.cleanup() + + def _run(self, argv, fetch_result=None, fetch_error=None): + args = ["check_new_release.py", "--state", str(self.state_path)] + argv + patcher = ( + mock.patch.object(gate, "fetch_current_stable", side_effect=fetch_error) + if fetch_error + else mock.patch.object(gate, "fetch_current_stable", return_value=fetch_result) + ) + with mock.patch.object(sys, "argv", args), patcher: + return gate.main() + + def test_new_release_exits_zero(self): + code = self._run([], fetch_result=("v2", "2026-08-18T00:00:00Z", SAMPLE_CHANGELOG)) + self.assertEqual(code, gate.EXIT_NEW_RELEASE) + + def test_same_release_exits_ten(self): + gate.write_state(self.state_path, "v2", None, {}) + code = self._run([], fetch_result=("v2", None, SAMPLE_CHANGELOG)) + self.assertEqual(code, gate.EXIT_NO_NEW_RELEASE) + + def test_fetch_failure_exits_one_not_ten(self): + """A fetch failure must never be mistaken for 'nothing shipped'.""" + code = self._run([], fetch_error=RuntimeError("network down")) + self.assertEqual(code, gate.EXIT_FETCH_FAILED) + self.assertNotEqual(code, gate.EXIT_NO_NEW_RELEASE) + + def test_check_does_not_write_state(self): + """The check is read-only; only --commit writes. This is what makes a + crashed run retry the same release instead of skipping it.""" + self._run([], fetch_result=("v2", None, SAMPLE_CHANGELOG)) + self.assertFalse(self.state_path.exists()) + + def test_commit_writes_state_and_exits_zero(self): + code = self._run(["--commit"], fetch_result=("v2", None, SAMPLE_CHANGELOG)) + self.assertEqual(code, gate.EXIT_NEW_RELEASE) + self.assertEqual(gate.read_state(self.state_path)["last_processed_version"], "v2") + + def test_full_cycle_new_then_commit_then_noop(self): + result = ("v3", "2026-08-25T00:00:00Z", SAMPLE_CHANGELOG) + self.assertEqual(self._run([], fetch_result=result), gate.EXIT_NEW_RELEASE) + self.assertEqual(self._run(["--commit"], fetch_result=result), gate.EXIT_NEW_RELEASE) + self.assertEqual(self._run([], fetch_result=result), gate.EXIT_NO_NEW_RELEASE) + + def test_next_release_reopens_the_gate(self): + gate.write_state(self.state_path, "v3", None, {}) + code = self._run([], fetch_result=("v4", None, SAMPLE_CHANGELOG)) + self.assertEqual(code, gate.EXIT_NEW_RELEASE) + + +class _JsonResponse: + """Minimal stand-in for the urlopen context-manager result. + + `json.load(fp)` just calls `fp.read()` and hands the result to `json.loads`, which + accepts bytes as well as str. Returning encoded bytes here matches what a real + HTTP response yields, so no patching of `json.load` is needed -- and patching it + globally would break `read_state`, which reads a text file through the same call. + """ + + def __init__(self, payload): + self._payload = payload + + def read(self): + return json.dumps(self._payload).encode("utf-8") + + +if __name__ == "__main__": + unittest.main(verbosity=2) From a248b61e79499f8cc2fed54388cccb925ddcb9d6 Mon Sep 17 00:00:00 2001 From: Rachael Rose Renk <91027132+rachaelrenk@users.noreply.github.com> Date: Wed, 19 Aug 2026 18:23:47 -0600 Subject: [PATCH 2/8] docs: require the gate and content design plan across drafting skills The gate only works if every path into the docs repo runs it. Wiring it into missing_docs alone would leave draft_docs -- the skill a person invokes directly -- able to produce a page nobody gated. draft_docs: add step 3.5, which runs the worthiness gate and then the content design plan before any template is opened. Step 4 now records the content type the plan chose rather than choosing it, because starting at the template is what produces pages shaped by the template instead of by the reader's need. Note explicitly that a human asking for a page is not itself evidence the page should exist. create_pr: add a required "Content design plan" section to the PR description guidelines, alongside the existing "Unverified claims" section, with a filled-in example. Keeping the plan next to the diff lets a reviewer disagree with who the page is for -- the disagreement worth having, and the expensive one to resolve after the prose is written. missing_docs: document the three sources beyond the client changelog. The client changelog only covers warpdotdev/warp, so server and platform features never appear in it -- which is exactly why they used to reach docs through the sssssssssssssssssssssssssssssssssssssssn the release-gate payload), then the public Agent API via sync-openapi-spec, and treat warp-server specs as a last resort behind a hard rollout check. A merged spec is not a shipped feature. Co-Authored-By: Warp --- .agents/skills/create_pr/SKILL.md | 28 ++++++++++++++++++++++++++++ .agents/skills/draft_docs/SKILL.md | 21 ++++++++++++++++++++- .agents/skills/missing_docs/SKILL.md | 26 ++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/.agents/skills/create_pr/SKILL.md b/.agents/skills/create_pr/SKILL.md index 7b988bfd7..894cfd96e 100644 --- a/.agents/skills/create_pr/SKILL.md +++ b/.agents/skills/create_pr/SKILL.md @@ -132,6 +132,34 @@ This PR updates the Terminal and Agent modes documentation for the Oz launch. - Updated navigation entry title ``` +### Content design plan (required on drafting PRs) + +Any PR that adds a page or makes a substantive update to one must carry the content design plan that preceded the draft. Keeping it next to the diff is the point: a reviewer can then disagree with who the page is for and what job it serves, which is far cheaper to resolve before the prose is written. See `.agents/references/content-design-plan.md` for the field definitions and `.agents/references/docs-worthiness-criteria.md` for the gate that runs before it. + +```markdown +## Content design plan + +**Audience and JTBD:** A backend engineer connecting their first factory to a self-hosted GitLab instance, who needs runs to authenticate without a personal token. + +**Problem:** The GitLab integration page covers GitLab.com only, so self-hosted users follow steps that silently fail at the auth step. + +**Goals:** +- The reader can tell whether their GitLab instance needs the self-hosted path. +- The reader can complete the self-hosted connection and confirm it worked. + +**Purpose and value:** Without it, self-hosted users file support tickets after the happy path fails. No existing page covers the self-hosted variant. + +**Content type:** Procedural — the reader is performing a setup task, not learning a concept. + +**Skill and template:** `draft_procedural` / `.agents/templates/procedural.md` + +**High-impact scenarios:** +- Covers: self-hosted GitLab with a project access token; verifying the connection. +- Excludes: GitLab behind a corporate proxy — rare, and the proxy config is the user's own infrastructure concern. +``` + +For the small corrections listed under "When a plan can be skipped" — typos, link fixes, terminology sweeps, generated updates, screenshot swaps — omit the section rather than filling it with placeholders. + ### Unverified claims (required on drafting PRs) Any PR that adds or updates page content must state which UI labels, Settings paths, CLI flags, permission defaults, plan eligibility, and platform-support claims could not be verified against `warp-internal`, `warp-server`, or a live build. See step 9.5 of the `draft_docs` skill. diff --git a/.agents/skills/draft_docs/SKILL.md b/.agents/skills/draft_docs/SKILL.md index 782d2f357..e008dd924 100644 --- a/.agents/skills/draft_docs/SKILL.md +++ b/.agents/skills/draft_docs/SKILL.md @@ -50,8 +50,24 @@ Also clarify: Is this a new page or an update to an existing page? ### 3. Read the style guide Read `AGENTS.md` in the docs repo root. This is required — it contains all voice/tone rules, formatting standards, content type structures, terminology, and the quality checklist. Do not draft without reading it first. +### 3.5. Confirm the doc should exist, then design it + +Two gates, in order. Both come before you open a template. + +**First, should this doc exist at all?** Apply `.agents/references/docs-worthiness-criteria.md`. The default is no docs, and the burden is on the change to earn a page. Record the verdict with the gate it passed and the concrete evidence — a setting key, CLI flag, quoted error string, changed default, or API field. If nothing passes, say so and stop; "this is new and users should know about it" is not a reason to write a page. + +This applies to human-invoked drafting too. A person asking for a page is not by itself evidence that the page should exist — if the request fails the gates, say so and propose the alternative (usually a section on an existing page). + +When the change passes, choose the outcome explicitly: **update an existing page** (preferred), **new page**, or **no docs**. Prefer updating whenever a page already covers the surface. + +**Second, what should the doc be?** Write a content design plan per `.agents/references/content-design-plan.md`, filling in every field: audience and JTBD, problem statement, goals, purpose and value, content type and model, skills and templates, and high-impact scenarios with explicit exclusions. + +The plan decides the content type — step 4 records that decision rather than making it. Starting at the template produces pages shaped by the template instead of by the reader's need. + +Carry the completed plan into the PR body as a `## Content design plan` section. Small corrections listed under "When a plan can be skipped" in that reference are exempt from both gates. + ### 4. Identify the content type and template -Using the "Drafting by content type" section in `AGENTS.md`, determine which content type the page is: +Record the content type chosen in the design plan, and pick its template and type-specific skill from this table. If drafting has diverged from the plan's chosen type, revisit the plan rather than silently switching templates. | Content type | Use when | Template | Skill | |---|---|---|---| @@ -139,6 +155,9 @@ Skip steps 1–3 in local/interactive sessions. ### 9. Review against checklist Before presenting the draft, verify against the quality checklist in `AGENTS.md`: +- [ ] The change passed `.agents/references/docs-worthiness-criteria.md`, and the verdict names a gate plus concrete evidence +- [ ] A content design plan exists with every field filled in, and the draft matches the content type it chose +- [ ] The outcome is the lightest correct one — an existing page was updated unless a new page is genuinely justified - [ ] Frontmatter description is a standalone search summary (benefit + keywords; not "This page describes..." and not a restatement of the title) - [ ] Content follows the structure for its content type - [ ] Section order follows reader chronology (requirements → setup → usage → advanced → troubleshooting) diff --git a/.agents/skills/missing_docs/SKILL.md b/.agents/skills/missing_docs/SKILL.md index 30006f081..2b7ecfe03 100644 --- a/.agents/skills/missing_docs/SKILL.md +++ b/.agents/skills/missing_docs/SKILL.md @@ -212,6 +212,32 @@ Diff mode reports, since the snapshot was last updated: 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. +2. **The public Agent API surface** — already covered by audit category 3 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: From f86a35b53fcb3df89d8ebbd960d24f2b991d99f8 Mon Sep 17 00:00:00 2001 From: Rachael Rose Renk <91027132+rachaelrenk@users.noreply.github.com> Date: Wed, 19 Aug 2026 18:39:41 -0600 Subject: [PATCH 3/8] docs: align content types with GitHub's content model Compared Warp's eight content types against GitHub's content model. Conceptual, procedural, reference, troubleshooting, quickstart, and combined already agree, as does the content-order rule. Four gaps were real: FAQ now has admission rules and defaults to "not an FAQ". GitHub has no FAQ type because an FAQ page pulls answers away from the page that owns the topic -- the reader on the owning page does not find the answer, the reader on the FAQ gets one without context, and the two drift apart. Keeping the type, but all three admission rules must hold, and the same test applies to adding a question to an existing FAQ page, since these grow by accretion. Guide is split into quickstart and tutorial. "Guides" stays as the section name and holds both; the split is by scope. A quickstart is ~5 minutes and ~600 words for someone who already knows the product. A tutorial walks a full workflow, includes its own troubleshooting and a conclusion, and requires that a quickstart already exist -- otherwise it absorbs setup content that belongs in a shorter page. The one-word "Guide" gave authors no scope guidance at all. The combined type gets a guardrail: no quickstart or tutThe combined type gets a guardrail: no quickstart oe budget and a single continuous path, and both lose their purpose once embedded. Cotheir purpose once embedded. Cotheir purpose once embedded. Cotheir purpose ongetheir purpose once embedded. Cotheir purpose once embedded. Cotheir purposes "About [subject]" or a noun, procedural a gerund, reference a noun without stack[subject]" or a noun, procedural a gerund, reference a noun without stack[se per[subject]" or a noun, procedural a gerund, refes/ a[subject]" or a noun, procedural a gerund, reference a noun without stack[sery a[subject]" or a noun, procedural a gerund, reference a noun without stack[sntent/docs/university/, which is now guides/. Co-Authored-By: Warp --- .agents/skills/draft_conceptual/SKILL.md | 2 +- .agents/skills/draft_docs/SKILL.md | 9 +- .agents/skills/draft_faq/SKILL.md | 24 +++- .agents/skills/draft_guide/SKILL.md | 27 +++- .agents/skills/draft_quickstart/SKILL.md | 22 ++- .agents/skills/draft_reference/SKILL.md | 2 +- .agents/skills/draft_troubleshooting/SKILL.md | 2 +- AGENTS.md | 128 +++++++++++++----- 8 files changed, 162 insertions(+), 54 deletions(-) diff --git a/.agents/skills/draft_conceptual/SKILL.md b/.agents/skills/draft_conceptual/SKILL.md index 09b59d003..4234fb2de 100644 --- a/.agents/skills/draft_conceptual/SKILL.md +++ b/.agents/skills/draft_conceptual/SKILL.md @@ -9,7 +9,7 @@ Draft a conceptual documentation page that explains what a feature or concept is ## Workflow -Follow the workflow in `.warp/skills/draft_docs/SKILL.md`, using the **conceptual template** at `.warp/templates/conceptual.md`. +Follow the workflow in `.agents/skills/draft_docs/SKILL.md`, using the **conceptual template** at `.agents/templates/conceptual.md`. ## Frontmatter description diff --git a/.agents/skills/draft_docs/SKILL.md b/.agents/skills/draft_docs/SKILL.md index e008dd924..ecd4336b8 100644 --- a/.agents/skills/draft_docs/SKILL.md +++ b/.agents/skills/draft_docs/SKILL.md @@ -76,10 +76,15 @@ Record the content type chosen in the design plan, and pick its template and typ | **Quickstart** | Fast path to a working result | `.agents/templates/quickstart.md` | `draft_quickstart` | | **Reference** | Structured information for lookup | `.agents/templates/reference.md` | `draft_reference` | | **Troubleshooting** | Problem → cause → solution | `.agents/templates/troubleshooting.md` | `draft_troubleshooting` | -| **FAQ** | Question-and-answer format | `.agents/templates/faq.md` | `draft_faq` | -| **Guide** | Task-oriented walkthrough (Guides section) | `.agents/templates/guide-page.md` | `draft_guide` | +| **FAQ** | Rarely — cross-cutting questions with no canonical home | `.agents/templates/faq.md` | `draft_faq` | +| **Tutorial** | Full workflow walkthrough (Guides section) | `.agents/templates/guide-page.md` | `draft_guide` | | **Feature documentation** | Combined conceptual + procedural (most common) | `.agents/templates/feature-doc.md` | `draft_feature_doc` | +Two of these carry admission rules rather than just structure, and both are checked in review: + +- **FAQ** defaults to "not an FAQ." All three admission rules in `AGENTS.md` must hold before you create or extend one. Most FAQ-shaped content belongs on the page that owns the topic. +- **Quickstart vs. tutorial** is a scope decision, not a location one. A quickstart is ~5 minutes and ~600 words for someone who already knows the product; a tutorial walks a full workflow and requires that a quickstart already exists. "Guides" is the section name and holds both. + Once the content type is identified: - Use the corresponding **template** as the starting scaffold for the page. - If a **type-specific skill** exists (listed above), read it for additional rules and examples specific to that content type. diff --git a/.agents/skills/draft_faq/SKILL.md b/.agents/skills/draft_faq/SKILL.md index 58ce877c3..8358f8ab1 100644 --- a/.agents/skills/draft_faq/SKILL.md +++ b/.agents/skills/draft_faq/SKILL.md @@ -1,15 +1,34 @@ --- name: draft_faq -description: Draft a new FAQ documentation page or update an existing one. Use for pages that collect frequently asked questions about a topic area. Questions are written in the user's voice and grouped by theme. +description: Draft or extend an FAQ documentation page. Use rarely - only for genuinely cross-cutting questions that span several features and have no canonical home on an existing page. Check the admission rules first; most FAQ-shaped content belongs on the page that owns the topic, not on an FAQ page. --- # Draft FAQ page Draft an FAQ page with questions grouped by theme and answers that lead with a direct response. +## Check the admission rules first + +**Default to "not an FAQ."** An FAQ page pulls answers away from the page that owns the topic. The reader who lands on the owning page does not find the answer, the reader who lands on the FAQ gets an answer without its context, and the two drift apart as the product changes. + +All three must hold before you create or extend an FAQ page: + +1. **The questions are genuinely cross-cutting** — they span several features or pages, so no single page owns them. +2. **There is no canonical home** — no existing page could answer the question in context. "It would be buried there" means that page needs restructuring, not that the answer needs a second home. +3. **A reader actually asks it**, in their own words, sourced from support tickets, Slack, or community threads — not invented to organize existing content. + +This test applies to **adding a question to an existing FAQ page** too. FAQ pages grow by accretion; each addition has to justify itself. + +If the rules do not all hold, say so and redirect: + +- "What is X / how does X work?" → conceptual page for X +- "What are the limits / which plans include X?" → reference section on the owning page +- "Why did I get error Y?" → troubleshooting section, keyed on the error +- "How do I do Z?" → procedural section on the owning page + ## Workflow -Follow the workflow in `.warp/skills/draft_docs/SKILL.md`, using the **FAQ template** at `.warp/templates/faq.md`. +Follow the workflow in `.agents/skills/draft_docs/SKILL.md`, using the **FAQ template** at `.agents/templates/faq.md`. ## Frontmatter description @@ -27,6 +46,7 @@ These rules are specific to FAQ pages (from the "Drafting by content type" secti - Lead with a direct answer, then provide detail. - Keep answers concise — link to full documentation for deeper topics. - Group questions by theme (e.g., "General", "Billing", "Errors"). +- **Never let an FAQ answer become the only place a fact lives.** It should summarize and link, not own. - Title convention: "[Feature] FAQs" or "Frequently asked questions" ## Heading case diff --git a/.agents/skills/draft_guide/SKILL.md b/.agents/skills/draft_guide/SKILL.md index 2f6162dbe..edd76d929 100644 --- a/.agents/skills/draft_guide/SKILL.md +++ b/.agents/skills/draft_guide/SKILL.md @@ -1,11 +1,22 @@ --- name: draft_guide -description: Draft a new guide page for the Guides section (src/content/docs/guides/). Use for practical, task-oriented walkthroughs that help developers accomplish a specific goal — like setting up a tool, completing a workflow, or learning a technique. Guides focus on the "how" with real prompts and reproducible results, targeting non-branded search queries. +description: Draft a tutorial for the Guides section (src/content/docs/guides/). Use for a full workflow walkthrough that helps a developer solve a real problem end to end - setting up a tool, completing a workflow, or learning a technique. Tutorials focus on the "how" with real prompts and reproducible results, targeting non-branded search queries. For a five-minute essential-steps path, use draft_quickstart instead. --- -# Draft guide page +# Draft tutorial page -Draft a practical guide that walks a developer through accomplishing a specific goal. +Draft a tutorial that walks a developer through an entire workflow, start to finish. + +## Tutorial or quickstart? + +"Guides" is the name of the section, not a content type. It holds both, and the choice is about scope: + +- **Quickstart** — about five minutes, ~600 words, essential steps only, for someone who already knows the product. Use `draft_quickstart`. +- **Tutorial** — a full workflow with context at the decision points, for someone extending a basic understanding to solve a real problem. This skill. + +**A tutorial requires that a quickstart already exists** for the product area. Check before drafting. If there is no quickstart, write that first — otherwise the tutorial absorbs setup content that belongs in a shorter page, and readers who only wanted to get started have to wade through the whole workflow. + +Tutorials are more conversational than other content: a developer-to-developer conversation that stays accessible to varied technical backgrounds. ## Workflow @@ -40,11 +51,15 @@ See "Descriptions by content type" under Frontmatter in `AGENTS.md` for the full These rules are specific to guide pages (from the "Drafting by content type" section of `AGENTS.md`): -- **Titles should be task-oriented** and read like a search query. Use shortened titles in the Astro Starlight nav and full descriptive titles in the article H1. +- **Titles should be task-oriented** and read like a search query. Use shortened titles in the Astro Starlight nav and full descriptive titles in the article H1. Do not put "tutorial" or "guide" in the title. - **For SEO: capture the non-branded query.** Write the title a developer would actually search for, not "How to do X in Warp." Example: "How to set up Claude Code" not "How to set up Claude Code in Warp." - All procedural rules apply (focused steps, motivate steps, expected outcomes). -- Link to relevant feature documentation in the main docs (`docs/`) where concepts need deeper explanation. -- When a guide has a companion video, the written content should stand alone. +- **Give real examples, not placeholders.** Do not write "enter a commit message" — supply an appropriate one that matches the preceding steps. +- **Include troubleshooting.** Name what commonly goes wrong in this workflow and how to recover. This is the clearest line between a tutorial and a quickstart, which only links to existing troubleshooting. +- **End with a conclusion, then next steps.** Review what the reader built, referring back to the example from the introduction, then give 2-3 actionable next steps. +- **Do not state an expected completion time.** It varies too much by experience level. (Quickstarts do state one; tutorials do not.) +- Link to relevant feature documentation in the main docs where concepts need deeper explanation. +- When a tutorial has a companion video, the written content should stand alone. - The optional **Productivity tips** section should showcase Warp features as natural extensions of the workflow — not as a separate pitch. ## SEO and AEO optimization diff --git a/.agents/skills/draft_quickstart/SKILL.md b/.agents/skills/draft_quickstart/SKILL.md index 9a99561be..2a0b3af83 100644 --- a/.agents/skills/draft_quickstart/SKILL.md +++ b/.agents/skills/draft_quickstart/SKILL.md @@ -1,15 +1,23 @@ --- name: draft_quickstart -description: Draft a new quickstart documentation page or update an existing one. Use for first-time experiences that get the reader to a working result fast (~10 minutes). Quickstarts focus on the critical path with minimal prerequisites and link to deeper guides for edge cases. +description: Draft a new quickstart documentation page or update an existing one. Use when the reader already understands the product and wants the fastest path to a working result - about five minutes and 600 words, essential steps only. If the task needs explanation along the way or exceeds that budget, it is a tutorial, not a quickstart. --- # Draft quickstart page -Draft a quickstart that gets the reader from zero to a working result in about 10 minutes. +Draft a quickstart that gets the reader to a working result in about five minutes. + +## Scope is the defining constraint + +**About five minutes and roughly 600 words.** This is a budget, not a target. A quickstart that outgrows it has become a tutorial and should be reworked as one rather than allowed to sprawl. + +Quickstarts are for readers who **already understand the feature or product** and are ready to try it. Deliberately omit how it works and why they would want it — if the reader needs that, they need conceptual content. If the task needs context at its decision points, they need a tutorial. + +A tutorial for a product area requires that its quickstart already exist. If you are drafting the first page for an area, it is probably this one. ## Workflow -Follow the workflow in `.warp/skills/draft_docs/SKILL.md`, using the **quickstart template** at `.warp/templates/quickstart.md`. +Follow the workflow in `.agents/skills/draft_docs/SKILL.md`, using the **quickstart template** at `.agents/templates/quickstart.md`. ## Frontmatter description @@ -24,12 +32,14 @@ See "Descriptions by content type" under Frontmatter in `AGENTS.md` for the full These rules are specific to quickstart pages (from the "Drafting by content type" section of `AGENTS.md`): - **Give every quickstart a descriptive H1 title.** Don't use a bare "Quickstart" — include the feature or topic name. +- **Open by stating who it is for**, the prerequisites and prior knowledge assumed, what the reader ends up with, and the time budget. - Minimize prerequisites — the reader should be able to start quickly. -- Target ~10 minutes or less. - Keep steps focused on the critical path — defer edge cases and advanced options to other pages. -- Steps can be less formal than full procedural content. Use heavy visual cues (code blocks, screenshots). +- **Link out rather than replicating** other pages' content, so the flow is not interrupted. +- Steps can be less formal than full procedural content, because the audience already knows the product. Use heavy visual cues (code blocks, screenshots). - All procedural rules apply (focused steps, motivate steps, expected outcomes). -- End with 2-3 actionable next steps linking to deeper content. +- **Troubleshooting is optional and link-only.** Point at existing troubleshooting content; do not write new troubleshooting into a quickstart. +- End with a one-line recap, then 2-3 actionable next steps. Always include a link to the conceptual page for the feature. - Title convention: "[Feature] quickstart" or "Quickstart for [product]" ## Heading case diff --git a/.agents/skills/draft_reference/SKILL.md b/.agents/skills/draft_reference/SKILL.md index feb2a5c4c..c1b33eed3 100644 --- a/.agents/skills/draft_reference/SKILL.md +++ b/.agents/skills/draft_reference/SKILL.md @@ -9,7 +9,7 @@ Draft a reference documentation page with structured, exhaustive information for ## Workflow -Follow the workflow in `.warp/skills/draft_docs/SKILL.md`, using the **reference template** at `.warp/templates/reference.md`. +Follow the workflow in `.agents/skills/draft_docs/SKILL.md`, using the **reference template** at `.agents/templates/reference.md`. ## Frontmatter description diff --git a/.agents/skills/draft_troubleshooting/SKILL.md b/.agents/skills/draft_troubleshooting/SKILL.md index 91888a40c..0138cc0ee 100644 --- a/.agents/skills/draft_troubleshooting/SKILL.md +++ b/.agents/skills/draft_troubleshooting/SKILL.md @@ -9,7 +9,7 @@ Draft a troubleshooting page that helps users diagnose and fix common issues. ## Workflow -Follow the workflow in `.warp/skills/draft_docs/SKILL.md`, using the **troubleshooting template** at `.warp/templates/troubleshooting.md`. +Follow the workflow in `.agents/skills/draft_docs/SKILL.md`, using the **troubleshooting template** at `.agents/templates/troubleshooting.md`. ## Frontmatter description diff --git a/AGENTS.md b/AGENTS.md index 86dfd21ba..8ee4d63f1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -83,11 +83,11 @@ These practices serve both human accessibility needs and AI agent consumption (A - **Explicit context**: Don't assume the reader arrived from a parent page. State what a thing is before explaining how to use it. This helps agents extract self-contained answers. - **Frontmatter descriptions**: Agents and search engines use the `description` field to determine relevance before reading the full page. Write descriptions as standalone summaries. - **Consistent terminology**: Agents struggle when the same concept has multiple names. Use the glossary terms consistently. -- **Machine-parseable patterns**: Consistent list formats, code block labeling, and parameter tables help agents extract structured information. The templates in `.warp/templates/` enforce this. +- **Machine-parseable patterns**: Consistent list formats, code block labeling, and parameter tables help agents extract structured information. The templates in `.agents/templates/` enforce this. ## Content structure -These structural rules apply to all pages regardless of content type. For type-specific page structures, see the templates in `.warp/templates/`. +These structural rules apply to all pages regardless of content type. For type-specific page structures, see the templates in `.agents/templates/`. ### Frontmatter Every page must include YAML frontmatter with a `description` field. @@ -400,6 +400,20 @@ Use consistent verbs that match the type of UI element: Every documentation page should be drafted according to its content type. Identify the type before you start writing, then follow the structure and rules for that type below. +The type is not a formatting choice — it follows from what the reader is trying to do. Decide that first in the content design plan (`.agents/references/content-design-plan.md`), then pick the type that serves it. Picking a template first produces pages shaped by the template. + +### Titles by content type + +Each type has its own title convention. Sentence case applies to all of them; this is the additional per-type rule. + +- **Conceptual** — "About [subject]", or a plain noun phrase naming the subject. ✅ `About environments` ✅ `Deployment patterns` ❌ `Understanding how environments work` +- **Procedural** — begin with a gerund, naming the task. ✅ `Configuring a self-hosted GitLab integration` ❌ `Self-hosted GitLab integration setup` +- **Reference** — a noun phrase naming what can be looked up. Avoid stacked nouns; use prepositions to break them up. ✅ `Keyboard shortcuts for the code editor` ❌ `Code editor keyboard shortcut reference` +- **Troubleshooting** — the symptom or the exact error message, so search matches what the reader typed. +- **Quickstart** — name the feature. ✅ `Quickstart for cloud agents` ❌ a bare `Quickstart` +- **Tutorial** — follow the procedural convention. Do not put "tutorial" or "guide" in the title. +- **Feature documentation (combined)** — if the page contains a procedure, use a task-based gerund title. Keep it general enough to cover the range of tasks on the page, and agnostic about which option the reader picks. ✅ `Setting repository visibility` ❌ `Making a private repository public` + ### General guidance (all content types) These rules apply regardless of content type: @@ -442,7 +456,7 @@ These rules apply regardless of content type: **Existing examples**: `platform/deployment-patterns.mdx`, `platform/index.mdx` -**Template**: `.warp/templates/conceptual.md` +**Template**: `.agents/templates/conceptual.md` ### Procedural @@ -471,32 +485,37 @@ These rules apply regardless of content type: **Existing examples**: `reference/cli/api-keys.mdx`, `platform/integrations/slack.mdx` -**Template**: `.warp/templates/procedural.md` +**Template**: `.agents/templates/procedural.md` ### Quickstart -**What it is**: A specialized procedural doc designed to get the reader to a working result fast. Style "quickstart" as one word, lowercase (unless starting a sentence or in a title). +**What it is**: A specialized procedural doc that gets the reader to a working result fast, with only the essential steps. Style "quickstart" as one word, lowercase (unless starting a sentence or in a title). -**When to use**: For first-time experiences with a product area. The reader should go from zero to a working result in ~10 minutes. +**When to use**: When the reader already understands the feature or product and is ready to try it. A quickstart deliberately omits explanation of how something works or why they would want it — if the reader needs that, they need conceptual content, and if the task is complex enough to need context along the way, they need a tutorial. + +**Scope**: About five minutes and roughly 600 words. That budget is the defining constraint, not a suggestion. A quickstart that no longer fits it has become a tutorial and should be reworked as one. **Structure**: -1. Opening paragraph with what the reader will accomplish and a time estimate +1. Opening paragraph: who it is for, the prerequisites and prior knowledge assumed, what the reader will end up with, and the time budget ("in about five minutes") 2. Prerequisites (minimal — link to full setup docs rather than inlining lengthy setup) 3. Numbered steps (as few as possible to reach a working result) -4. Next steps (links to deeper guides, advanced usage, related features) +4. Troubleshooting (optional — link to existing troubleshooting content rather than writing new) +5. Next steps: a one-line recap, then 2-3 actionable next steps, always including a link to the conceptual page for the feature **Rules**: - **Give every quickstart a descriptive H1 title.** Don't use a bare "Quickstart" — include the feature or topic name. - - ✅ `# Cloud Agents Quick Start` + - ✅ `# Quickstart for cloud agents` - ❌ `# Quickstart` (quickstart for what?) - Minimize prerequisites — the reader should be able to start quickly. -- Target ~10 minutes or less. - Keep steps focused on the critical path — defer edge cases and advanced options to other pages. +- Link out rather than replicating content, so the flow is not interrupted. +- Use code blocks and screenshots generously; visual confirmation reassures the reader they are on track. +- Steps can be less explicit than in full procedural content, because the audience already knows the product. - All procedural rules apply (focused steps, motivate steps, expected outcomes). **Existing examples**: `platform/quickstart.mdx`, `getting-started/quickstart/installation-and-setup.mdx` -**Template**: `.warp/templates/quickstart.md` +**Template**: `.agents/templates/quickstart.md` ### Reference @@ -519,7 +538,7 @@ These rules apply regardless of content type: **Existing examples**: `reference/cli/index.mdx`, `reference/api-and-sdk/index.mdx` -**Template**: `.warp/templates/reference.md` +**Template**: `.agents/templates/reference.md` ### Troubleshooting @@ -541,13 +560,30 @@ These rules apply regardless of content type: **Existing examples**: `support-and-community/troubleshooting-and-support/known-issues.mdx`, `reference/cli/troubleshooting.mdx` -**Template**: `.warp/templates/troubleshooting.md` +**Template**: `.agents/templates/troubleshooting.md` ### FAQ **What it is**: Question-and-answer format for common questions. -**When to use**: For pages that collect frequently asked questions about a topic area. +**When to use**: Rarely. **Default to "not an FAQ."** + +An FAQ page pulls answers away from the page that owns the topic. The reader who lands on the owning page does not find the answer, the reader who lands on the FAQ gets an answer without its context, and the two drift apart as the product changes. Most content that arrives as "we should FAQ this" belongs on an existing conceptual, reference, or troubleshooting page. + +**Admission rules — all three must hold before creating or extending an FAQ page:** + +1. **The questions are genuinely cross-cutting.** They span several features or pages, so no single page owns them. Questions about one feature belong on that feature's page. +2. **There is no canonical home.** If any existing page could answer the question in context, answer it there instead. "It would be buried on that page" is a signal the page needs restructuring, not that the answer needs a second home. +3. **The question is one a reader actually asks**, in their own words, sourced from support tickets, Slack, or community threads — not one invented to organize existing content. + +Before adding a question to an existing FAQ page, apply the same test. FAQ pages grow by accretion; each addition should have to justify itself. + +**Where it goes instead:** + +- "What is X / how does X work?" → conceptual page for X +- "What are the limits / which plans include X?" → reference section on the owning page +- "Why did I get error Y?" → troubleshooting section, keyed on the error +- "How do I do Z?" → procedural section on the owning page **Structure**: ```markdown @@ -560,16 +596,24 @@ Direct answer with actionable information. Include links to relevant documentati - Lead with a direct answer, then provide detail. - Keep answers concise — link to full documentation for deeper topics. - Group questions by theme (e.g., "General", "Billing", "Errors"). +- Never let an FAQ answer become the only place a fact lives. It should summarize and link, not own. -**Template**: `.warp/templates/faq.md` +**Template**: `.agents/templates/faq.md` **Existing examples**: `agent-platform/getting-started/faqs.mdx`, `support-and-community/plans-and-billing/pricing-faqs.mdx` -### Guide (Guides section) +### Tutorial (Guides section) + +**What it is**: A practical, task-oriented walkthrough of an entire workflow, start to finish. Tutorials live in the `src/content/docs/guides/` directory (the "Guides" Astro Starlight space) and can include video, written steps, or both. -**What it is**: A practical, task-oriented walkthrough that helps a developer accomplish a specific goal using Warp. Guides live in the `src/content/docs/university/` directory (the "Guides" Astro Starlight space) and can include video, written steps, or both. +"Guides" is the name of the section, not a content type. It holds both **tutorials** and **quickstarts**; pick between them by scope before drafting: -**When to use**: For educational content that teaches a workflow or use case — not feature documentation (which belongs in the main docs). Guides focus on the "how" with real prompts and reproducible results. +- **Quickstart** — about five minutes, ~600 words, essential steps only, for someone who already understands the product. +- **Tutorial** — a full workflow with context at the decision points, for someone extending a basic understanding to solve a real problem. + +**A tutorial requires that a quickstart already exists** for the product area. If there is no quickstart, write that first — otherwise the tutorial absorbs setup content that belongs in a shorter page, and readers who only wanted to get started have to wade through the whole workflow. + +**When to use**: For educational content that teaches a workflow or use case — not feature documentation (which belongs in the main docs). Tutorials focus on the "how" with real prompts and reproducible results, and are more conversational than other content: a developer-to-developer conversation that stays accessible to varied technical backgrounds. **Structure**: 1. Frontmatter with `description` (for SEO and search) @@ -583,15 +627,19 @@ Direct answer with actionable information. Include links to relevant documentati 9. "What you achieved" summary at the end with links to related docs **Rules**: -- Titles should be task-oriented and scannable. Use shortened titles in the Astro Starlight nav and full descriptive titles in the article H1. +- Titles should be task-oriented and scannable. Use shortened titles in the Astro Starlight nav and full descriptive titles in the article H1. Do not put "tutorial" or "guide" in the title. - For SEO: capture the non-branded query when possible. Write the title a developer would actually search for ("How to Set Up Claude Code" not "How to Set Up Claude Code in Warp"). - All procedural rules apply (focused steps, motivate steps, expected outcomes). +- **Give real examples, not placeholders.** Do not write "enter a commit message" — supply an appropriate one that matches the preceding steps. +- **Include troubleshooting.** Acknowledge what commonly goes wrong in this workflow and how to recover. This is what most distinguishes a tutorial from a quickstart, which only links to existing troubleshooting. +- **End with a conclusion, then next steps.** Review what the reader built, referring back to the example from the introduction, then give 2-3 actionable next steps. +- Do not state an expected completion time — it varies too much by experience level. (Quickstarts do state one.) - Link to relevant feature documentation in the main docs where concepts need deeper explanation. -- When a guide has a companion video, the written content should stand alone — a reader should be able to follow the guide without watching the video. +- When a tutorial has a companion video, the written content should stand alone — a reader should be able to follow it without watching the video. -**Template**: A copyable starting template is available at `.warp/templates/guide-page.md`. Use this when creating new guide pages. +**Template**: A copyable starting template is available at `.agents/templates/guide-page.md`. The filename is a holdover from when this type was called "guide"; the `draft_guide` skill uses it too. -**Existing examples**: `university/mcp-servers/sentry-mcp-fix-sentry-error-in-empower-website.mdx`, `university/end-to-end-builds/building-a-real-time-chat-app-github-mcp-+-railway.mdx` +**Existing examples**: `guides/external-tools/sentry-mcp-fix-sentry-error-in-empower-website.mdx`, `guides/build-an-app-in-warp/building-a-real-time-chat-app-github-mcp-railway.mdx` ### Feature documentation (combined pattern) @@ -609,23 +657,28 @@ This is the most common page type in Warp's docs (~75+ pages). A feature documen - Apply the **conceptual** rules to the explanatory sections (explain what and why, define terms, no procedures in the overview). - Apply the **procedural** rules to the step-by-step sections (one action per step, motivate steps, expected outcomes). - Keep the conceptual and procedural sections clearly separated with distinct headers. +- **Never fold quickstart or tutorial content into a combined page.** Conceptual, procedural, reference, and troubleshooting sections can coexist here; quickstarts and tutorials cannot. Both are defined by a scope budget and a single continuous path, and both lose their purpose once embedded in a longer page. Link to them instead. +- **Order sections from broad to specific**: conceptual, then reference, then procedures in lifecycle order (enable, use, manage, disable, destructive actions), then troubleshooting. +- Use a task-based gerund title that stays agnostic about which option the reader chooses — `Setting repository visibility`, not `Making a private repository public`. + +This is the type most prone to sprawl, precisely because it accepts the most kinds of content. If the page is growing past roughly 1500 words, split the procedures onto their own pages rather than adding another section. **Existing examples**: `agent-platform/capabilities/skills.mdx`, `platform/environments.mdx` -**Template**: `.warp/templates/feature-doc.md` +**Template**: `.agents/templates/feature-doc.md` ## Page templates -Concrete page scaffolds for each content type are in `.warp/templates/`. Use these as starting points when creating new pages: +Concrete page scaffolds for each content type are in `.agents/templates/`. Use these as starting points when creating new pages — but pick the type from the content design plan first, not by browsing this list: -- `.warp/templates/conceptual.md` -- `.warp/templates/procedural.md` -- `.warp/templates/quickstart.md` -- `.warp/templates/reference.md` -- `.warp/templates/troubleshooting.md` -- `.warp/templates/faq.md` -- `.warp/templates/guide-page.md` -- `.warp/templates/feature-doc.md` +- **Conceptual** — `.agents/templates/conceptual.md` +- **Procedural** — `.agents/templates/procedural.md` +- **Quickstart** — `.agents/templates/quickstart.md` +- **Reference** — `.agents/templates/reference.md` +- **Troubleshooting** — `.agents/templates/troubleshooting.md` +- **FAQ** — `.agents/templates/faq.md` (read the FAQ admission rules before using this one) +- **Tutorial** — `.agents/templates/guide-page.md` (filename is a holdover from when the type was called "guide") +- **Feature documentation (combined)** — `.agents/templates/feature-doc.md` Each template includes inline HTML comments explaining what to put in each section and why. @@ -818,14 +871,19 @@ All documentation should be written with search discoverability in mind — both - For feature documentation: use the feature name as the developer knows it. ### SEO data -When creating or updating content, use SEO and AEO data to inform titles, descriptions, and content coverage. The `docs-seo-audit` skill (`.warp/skills/docs-seo-audit/`) can identify technical SEO issues. +When creating or updating content, use SEO and AEO data to inform titles, descriptions, and content coverage. The `docs-seo-audit` skill (`.agents/skills/docs-seo-audit/`) can identify technical SEO issues. ## Quality checklist Before publishing any documentation, verify: +- [ ] The change passed `.agents/references/docs-worthiness-criteria.md`, with a recorded gate and concrete evidence — not just "it's new" +- [ ] A content design plan exists per `.agents/references/content-design-plan.md` and appears in the PR body +- [ ] An existing page was updated rather than a new page created, unless a new page is genuinely justified - [ ] Frontmatter includes a one-sentence description (50-160 chars) written as a standalone summary, with no filler opener -- [ ] Content type is identified and the page follows the structure for that type (see `.warp/templates/`) +- [ ] Content type is identified and the page follows the structure for that type (see `.agents/templates/`) +- [ ] The title follows the convention for its content type (see "Titles by content type") +- [ ] No quickstart or tutorial content is folded into a combined feature page - [ ] Headers use sentence case (with proper feature name capitalization) - [ ] Lists use bold term + dash + explanation format - [ ] All links work and point to correct destinations @@ -922,7 +980,7 @@ Content lives in `src/content/docs/`, organized by topic: - **support-and-community/** — Troubleshooting, billing, privacy - **enterprise/** — Enterprise features, SSO, team management - **changelog/** — Release changelog -- **university/** — Guides and tutorials +- **guides/** — Quickstarts and tutorials (the "Guides" space) ### Content model The docs site has multiple levels of hierarchy: From 2f6e719b63bc907458817e363ce6424a231d29b6 Mon Sep 17 00:00:00 2001 From: Rachael Rose Renk <91027132+rachaelrenk@users.noreply.github.com> Date: Wed, 19 Aug 2026 18:41:16 -0600 Subject: [PATCH 4/8] docs: record the gate replay against the two recurrence cases Validation, not new policy. Replayed the worthiness gate against the two open docs PRs that showed the gap was still live, and recorded both verdicts. docs#581 fails Gate 0: it documents agentDefaults.computerUseModel and says "(unreleased feature)" in its own title. Deferred with the blocking condition. docs#582 passes on Gate 3. Factory Dashboard metric counting rules are non-obvious and live only in hover tooltips -- the By-model view caps at eight and folds the rest into Other, there is an Unknown bucket, and opened/merged PR counts can legitimately disagree. A reader interpreting the dashboard without them draws wrong conclusions, and no existing page carries per-metric detail. Keeping a pass in the regression set is the point. A gate that rejects everything is as broken as one that accepts everything, and only having rejections as worked examples would teach the wrong bias. Co-Authored-By: Warp --- .../missing_docs/references/changelog_decisions.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.agents/skills/missing_docs/references/changelog_decisions.md b/.agents/skills/missing_docs/references/changelog_decisions.md index 32ea3d348..f74c38e9c 100644 --- a/.agents/skills/missing_docs/references/changelog_decisions.md +++ b/.agents/skills/missing_docs/references/changelog_decisions.md @@ -26,11 +26,12 @@ This ledger is that missing key. **Triage reads it first and skips any PR number ## Ledger -Newest first. One row per changelog PR number. +Newest first. One row per PR number — usually a `warpdotdev/warp` changelog item, occasionally a `warpdotdev/docs` PR evaluated against the gate after the fact. | PR | Decided | Verdict | Gate / disqualifier | Reason and outcome | |---|---|---|---|---| -| [#581](https://github.com/warpdotdev/docs/pull/581) | 2026-08-20 | deferred | Gate 0 | `agentDefaults.computerUseModel` is unreleased — the drafting PR said so in its own title. Real knob, would pass Gate 1, but Gate 0 is a hard prerequisite. Re-check when the setting ships to GA. | +| [docs#582](https://github.com/warpdotdev/docs/pull/582) | 2026-08-20 | yes | Gate 3 | Factory Dashboard metric definitions (APP-5546). The counting rules are non-obvious and currently live only in hover tooltips: the By-model view caps at eight and folds the rest into Other, there is an Unknown bucket, and opened/merged pull request counts can legitimately disagree. A reader reading the dashboard without them draws wrong conclusions. New reference page justified — no existing page carries per-metric detail. | +| [docs#581](https://github.com/warpdotdev/docs/pull/581) | 2026-08-20 | deferred | Gate 0 | `agentDefaults.computerUseModel` is unreleased — the drafting PR said so in its own title. Real knob, would pass Gate 1, but Gate 0 is a hard prerequisite. Re-check when the setting ships to GA. | | [#14418](https://github.com/warpdotdev/warp/pull/14418) | 2026-08-20 | yes | Gate 1 | Agent execution profiles configurable from settings files for all users. Named settings-file configuration. Update the existing agent profiles page. | | [#14344](https://github.com/warpdotdev/warp/pull/14344) | 2026-08-20 | no | Disqualified: pure UI affordance | Armadillo icon replaced with the theme-adaptive Warp "W" logo. Nothing configurable, nothing to get stuck on. | | [#14298](https://github.com/warpdotdev/warp/pull/14298) | 2026-08-20 | no | Disqualified: small and intuitive | MCP tool confirmations now show the running tool and its source server. Understood on sight. | @@ -42,4 +43,6 @@ Newest first. One row per changelog PR number. ## Notes -These seed rows come from the `v0.2026.07.29.09.05.stable_02` changelog and double as the calibration set in `.agents/references/docs-worthiness-criteria.md`. Rows marked `yes` record the verdict, not that the docs change has shipped — several are still open PRs. +The `warpdotdev/warp` rows come from the `v0.2026.07.29.09.05.stable_02` changelog and double as the calibration set in `.agents/references/docs-worthiness-criteria.md`. Rows marked `yes` record the verdict, not that the docs change has shipped — several are still open PRs. + +The two `warpdotdev/docs` rows were the regression cases used to validate the gate when it was introduced: docs#581 must fail Gate 0 because it documents an unreleased setting, and docs#582 must pass, because a gate that rejects everything is as broken as one that accepts everything. From f984c707641f083e93d5e13d000f6c1dafe8f585 Mon Sep 17 00:00:00 2001 From: Rachael Rose Renk <91027132+rachaelrenk@users.noreply.github.com> Date: Thu, 20 Aug 2026 12:36:58 -0600 Subject: [PATCH 5/8] docs: scope the worthiness gate by who is asking The gate as written applied in full to human-invoked drafting, and told the agent to decline a person's request and propose an alternative. That went further than intended and further than the problem justified. The failure mode this work exists to fix is automation flooding the repo. Human-invoked drafting was never it. And the evidence bar -- name a toml_path key, quote an error string -- is calibrated for an agent triaging a changelog with no context. A docs writer who has been in the planning meeting will routinely fail that bar while being right, which turns the gate into an agent arguing with someone who knows more than it does. Split the gate by who is asking: - Automated runs apply the full gate. A scheduled agent has no context beyond what it can read, and unattended drafting at scale is the thing being controlled. - A person asking directly is subject to Gate 0 only. "Has this shipped, is the surface public" is factual and a requester can be wrong about it, so it is worth verifying regard worth verifying regard worth verifying regard worth verifying regard at worth verifying regard worth verifying regard worth verifying regardoe worth verifying regard worth verifying regara Gate 1-3 conce worth verifying regard worth verifying regard t drafts: prefer updating worth verifying regard worth verifying regard w needs. Applied in draft_dApplied in draft_dApplied in draft_dApplied in draftd checklist so an agent rechecklist so an agent rechecklist so an agent rechhored-By: Warp --- .agents/references/docs-worthiness-criteria.md | 10 ++++++++++ .agents/skills/draft_docs/SKILL.md | 9 +++++++-- AGENTS.md | 2 +- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.agents/references/docs-worthiness-criteria.md b/.agents/references/docs-worthiness-criteria.md index aba16f6fb..1144c648a 100644 --- a/.agents/references/docs-worthiness-criteria.md +++ b/.agents/references/docs-worthiness-criteria.md @@ -20,6 +20,16 @@ These criteria govern the **weekly release stream** — changes that reached use Major launches (Warp Factories, for example) are planned in advance and documented by the docs team on a proactive, human-led path. They do not run through these gates. If you encounter a change that is clearly part of an announced launch, defer it rather than gating it. +### How much applies depends on who is asking + +**Automated runs apply the full gate.** A scheduled agent has no context beyond what it can read, and unattended drafting at scale is what this reference exists to control. Default to no docs; make the change earn the page. + +**A person asking directly is subject to Gate 0 only.** Gate 0 is factual — has this shipped, is the surface public — and a requester can be wrong about it, so it is worth verifying no matter who asked. Gates 1 through 3 are judgment, and someone requesting a page usually has context an agent does not: the roadmap, the support queue, a conversation the agent was not in. + +So do not decline a person's request on Gates 1-3. Raise the concern once — "an existing page already covers this," "this looks like a UI-only change" — then defer to their answer. An agent arguing with someone who knows more than it does is a worse failure than one extra page. + +The gates still shape *how* you draft for a human request: they push toward updating an existing page over creating a new one, and toward naming the concrete thing a reader needs. + ## Decision procedure Work through the gates in order. Gate 0 is a hard prerequisite. Gates 1 through 3 are alternatives — passing any one is enough. Then check the disqualifiers, which override a pass on any gate. diff --git a/.agents/skills/draft_docs/SKILL.md b/.agents/skills/draft_docs/SKILL.md index ecd4336b8..beb1bde0b 100644 --- a/.agents/skills/draft_docs/SKILL.md +++ b/.agents/skills/draft_docs/SKILL.md @@ -54,9 +54,14 @@ Read `AGENTS.md` in the docs repo root. This is required — it contains all voi Two gates, in order. Both come before you open a template. -**First, should this doc exist at all?** Apply `.agents/references/docs-worthiness-criteria.md`. The default is no docs, and the burden is on the change to earn a page. Record the verdict with the gate it passed and the concrete evidence — a setting key, CLI flag, quoted error string, changed default, or API field. If nothing passes, say so and stop; "this is new and users should know about it" is not a reason to write a page. +**First, should this doc exist at all?** Apply `.agents/references/docs-worthiness-criteria.md`. -This applies to human-invoked drafting too. A person asking for a page is not by itself evidence that the page should exist — if the request fails the gates, say so and propose the alternative (usually a section on an existing page). +How much of the gate applies depends on who is asking: + +- **Automated runs** (`missing_docs` drift-watch, or any scheduled agent) apply the **full gate**. The default is no docs and the burden is on the change to earn a page. Record the verdict with the gate it passed and the concrete evidence — a setting key, CLI flag, quoted error string, changed default, or API field. If nothing passes, say so and stop; "this is new and users should know about it" is not a reason to write a page. +- **A person asking directly** is subject to **Gate 0 only**. Gate 0 is a factual check — has this shipped, is the surface public — and a requester can simply be wrong about it, so verify it and stop if it fails. Drafting for an unshipped feature is the most common failure regardless of who asked. + + Gates 1 through 3 are judgment, and a person requesting the page usually has context you do not: the roadmap, the support queue, a conversation you were not in. **Do not decline their request on Gates 1-3.** If something looks off — an existing page already covers the surface, or the change looks like a pure UI affordance — say so once, then defer to their answer and proceed. When the change passes, choose the outcome explicitly: **update an existing page** (preferred), **new page**, or **no docs**. Prefer updating whenever a page already covers the surface. diff --git a/AGENTS.md b/AGENTS.md index 8ee4d63f1..1bbb743cf 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -877,7 +877,7 @@ When creating or updating content, use SEO and AEO data to inform titles, descri Before publishing any documentation, verify: -- [ ] The change passed `.agents/references/docs-worthiness-criteria.md`, with a recorded gate and concrete evidence — not just "it's new" +- [ ] The change passed `.agents/references/docs-worthiness-criteria.md` — the full gate with recorded evidence for automated runs, Gate 0 (shipped and public) for human-requested pages - [ ] A content design plan exists per `.agents/references/content-design-plan.md` and appears in the PR body - [ ] An existing page was updated rather than a new page created, unless a new page is genuinely justified - [ ] Frontmatter includes a one-sentence description (50-160 chars) written as a standalone summary, with no filler opener From d140ef5159da6c9f396159d9c53a21d77b57ccd3 Mon Sep 17 00:00:00 2001 From: Rachael Rose Renk <91027132+rachaelrenk@users.noreply.github.com> Date: Thu, 20 Aug 2026 13:09:40 -0600 Subject: [PATCH 6/8] Revise content design plan for clarity on purpose Clarify the purpose and audience definition in the content design plan. --- .agents/references/content-design-plan.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.agents/references/content-design-plan.md b/.agents/references/content-design-plan.md index 5335a01e3..62808bcb5 100644 --- a/.agents/references/content-design-plan.md +++ b/.agents/references/content-design-plan.md @@ -1,6 +1,6 @@ # Content design plan -Decide what a doc should be, before writing a word of it. +Before we begin drafting a docs page, we need to be extremely clear on it's purpose, value, and audience. We define these things by completing a content design plan before making any changes to the docs. Read this after a change has passed `.agents/references/docs-worthiness-criteria.md`, and before opening any template. Every new page and every substantive update to an existing page needs a content design plan — whether the drafting is done by a scheduled agent or by a person invoking a drafting skill directly. @@ -8,7 +8,7 @@ Read this after a change has passed `.agents/references/docs-worthiness-criteria Drafting that starts at the template produces pages shaped by the template. The scaffold has a "Key features" section, so the draft gets a key features list; it has a "How it works" section, so the draft explains how it works — whether or not any reader needed either. -The plan inverts that. Decide who the reader is and what they are trying to do, and the content type falls out of the answer instead of dictating it. +The plan inverts that. Start by determining who the reader is and what they are trying to do, and the content type falls out of the answer instead of dictating it. It is also the artifact a reviewer can actually disagree with. Reviewing a finished draft means arguing about prose. Reviewing a plan means arguing about whether the doc is aimed at the right person solving the right problem, which is the disagreement worth having and the one that is expensive to resolve after the page is written. From 63cf15b6ed02da4e191c80234d6981da85994d47 Mon Sep 17 00:00:00 2001 From: Rachael Rose Renk <91027132+rachaelrenk@users.noreply.github.com> Date: Thu, 20 Aug 2026 13:25:04 -0600 Subject: [PATCH 7/8] docs: align content-type templates with GitHub's content model Reviewed all eight templates against GitHub's templates page. Three real bugs and several gaps. Six templates taught a pattern no page uses. faq, feature-doc, procedural, quickstart, reference, and troubleshooting showed a body "# [Title]" H1 with no frontmatter title. All 377 pages under src/content/docs use frontmatter title, and Starlight renders it as the H1 -- conceptual.md and guide-page.md already said so explicitly. All eight now set title in frontmatter with no body H1. quickstart.md contradicted what shipped earlier in this branch. It still said ~10 minutes in two places after AGENTS.md and draft_quickstart moved to ~5 minutes / ~600 words, and it put Next steps before Troubleshooting so the closing section was not last. Both fixed, and the scope budget is now stated in the template itself the way GitHub's quickstart does. Four templates had no closing cross-link section at all -- faq, procedural, reference, troubleshooting -- while the AGENTS.md checklist required one. The rule is now explicit and applied everywhere: Next steps for quickstarts and tutorials, because the reader just finished something and needs forward momentum; Related pages for every other type, because they want lateral material. Not "Further reading", which GitHub uses but appears zero times in our corpus against 54 Related pages and 46 Next steps. Adopted from GitHub: a "[BEFORE PUBLISHING: delete every bracketed instruction]" note at the top of every template. GitHub says this in each of theirs and we said it nowhere, so nothing told an author to strip the guidance before shipping. Also added their note that content not under a header is not linkable in the table of contents. Kept brackets rather than adopting GitHub's comment blocks. Instructions in comments get deprioritized by agents, which is the whole reason we use brackets. Corrected AGENTS.md, which claimed the templates use HTML comments -- they do not, and have not. Trimmed the duplicated AEO-brief and pre-handoff-review blocks in procedural.md and guide-page.md to one-line pointers at the owning skills. Net 460 to 390 lines across the set despite adding the removal notes and scope guidance. Co-Authored-By: Warp --- .agents/skills/draft_docs/SKILL.md | 6 +- .agents/templates/conceptual.md | 45 ++++++-------- .agents/templates/faq.md | 51 +++++++++------- .agents/templates/feature-doc.md | 87 ++++++++-------------------- .agents/templates/guide-page.md | 66 ++++++++++----------- .agents/templates/procedural.md | 64 +++++++++----------- .agents/templates/quickstart.md | 58 ++++++------------- .agents/templates/reference.md | 54 +++++++++-------- .agents/templates/troubleshooting.md | 45 +++++++------- AGENTS.md | 13 ++++- 10 files changed, 216 insertions(+), 273 deletions(-) diff --git a/.agents/skills/draft_docs/SKILL.md b/.agents/skills/draft_docs/SKILL.md index beb1bde0b..caa163280 100644 --- a/.agents/skills/draft_docs/SKILL.md +++ b/.agents/skills/draft_docs/SKILL.md @@ -138,7 +138,7 @@ These rules are frequently violated by agents. Apply them carefully during draft - **Section order follows reader chronology** — Prerequisites and requirements before setup, setup before usage, usage before advanced options. ✅ `## Prerequisites` → `## Set up the integration` → `## Start a run` ❌ setup steps before the reader knows what they need - **Keep error messages out of the main flow** — Do not weave full error strings through conceptual or procedural sections. Put them in a dedicated `## Troubleshooting` section near the end, formatted symptom → cause → fix. ✅ one Troubleshooting section with the exact error as a bold lead-in ❌ repeating the same error callout after every step - **Use callouts sparingly** — Prefer body prose. At most one or two callouts per page unless the content type template requires more. ✅ a single `:::note` for a non-obvious prerequisite ❌ a `:::note` / `:::tip` after every subsection -- **Descriptive link text, and no dead-end pages** — Never use "here", "this page", or a bare URL as link text. End every new page with a `## Related pages` section (or the type-equivalent, such as `## Next steps` on a quickstart) containing at least one internal link whose anchor names the destination topic. ✅ `Learn more about [Codebase Context](/code/codebase-context/)` ❌ `Click [here](/code/codebase-context/)` ❌ ending a new feature page with no cross-links +- **Descriptive link text, and no dead-end pages** — Never use "here", "this page", or a bare URL as link text. End every new page with `## Next steps` (quickstarts and tutorials) or `## Related pages` (every other type), containing at least one internal link whose anchor names the destination topic. Do not use "Further reading" or "See also". ✅ `Learn more about [Codebase Context](/code/codebase-context/)` ❌ `Click [here](/code/codebase-context/)` ❌ ending a new feature page with no cross-links - **Disambiguate conditional and multi-clause wording** — If a sentence has two plausible readings (especially with "when", "if", "can", or stacked clauses), rewrite it so only one meaning remains. Prefer one idea per sentence. ✅ `Cloud handoff keeps your conversation's model only when that model is available in the cloud.` ❌ `Cloud handoff keeps your conversation's model when it can run in the cloud.` (keeps the model when it can? or only when cloud supports the model?) - **Lead instructional sentences with the action or goal** — In steps, keyboard shortcuts, and "how to" sentences, put the action or goal first, then the control or condition. Readers should not need prior context to know what values or targets you mean. ✅ `To open the searchable environment and model selectors, press Ctrl+E.` ❌ `To change either value, press Ctrl+E.` (which values?) - **Screenshots for hard-to-describe UI** — When a page documents a visual surface (statusline chips, tab bars, settings panes, multi-control layouts), include a screenshot after the prose that introduces that surface. Prefer prose for straightforward clicks, and prefer one well-placed figure over repeating the same surface. Always use descriptive alt text, never "screenshot". Do not invent or request screenshots of internal-only, flagged, or unfinished UI. ✅ a statusline screenshot after the paragraph that names the chips ❌ describing chip layout in a long paragraph with no image when humans keep asking "should we include a screenshot?" @@ -177,7 +177,9 @@ Before presenting the draft, verify against the quality checklist in `AGENTS.md` - [ ] Headers use sentence case (with proper feature name capitalization) - [ ] Headers name a specific topic (not bare Overview / More details / Other) - [ ] Lists use `*` markers with bold term + hyphen + explanation format -- [ ] Cross-references are included, and every new page ends with `## Related pages` or a type-equivalent `## Next steps` +- [ ] Cross-references are included, and the page ends with `## Next steps` (quickstart or tutorial) or `## Related pages` (every other type) +- [ ] Every bracketed template instruction has been deleted, including the `[BEFORE PUBLISHING: ...]` note +- [ ] The title is in frontmatter and there is no H1 in the body - [ ] Link text names the destination topic (not "here" / "this page" / raw URLs) - [ ] The first Settings path, CLI command, or URL on the page names the app or tool - [ ] Instructions include expected outcomes diff --git a/.agents/templates/conceptual.md b/.agents/templates/conceptual.md index 592af528d..3b2e08650 100644 --- a/.agents/templates/conceptual.md +++ b/.agents/templates/conceptual.md @@ -1,47 +1,38 @@ --- -title: [Feature or concept name — sentence case. Title convention: noun or "About [subject]". The title field renders as the page H1; do not add a separate H1 in the body. - Use {{TOKEN}} syntax for any product names in src/data/vars.ts.] +title: [Sentence case. Use "About [subject]" or a plain noun phrase naming the subject. Not "Understanding how X works". This renders as the page H1 — do not add an H1 in the body.] description: >- - [One sentence, 50-160 characters: what the concept is and why it matters. - Start with the subject, not "Learn about" or "This page covers." - Example: "Environments give cloud agents the same toolchain and setup on every run, no matter what triggers them." - See AGENTS.md > Frontmatter > Descriptions by content type for the full rules. - Use {{TOKEN}} syntax for any product names in src/data/vars.ts.] + [One sentence, 50-160 characters: what the thing is and why it matters. Start with the + subject, not "Learn about". Example: "Environments give cloud agents the same toolchain + and setup on every run, no matter what triggers them." + Use {{TOKEN}} syntax for product names in src/data/vars.ts.] --- -[VARS: Add this line immediately after the closing --- above if this page references any product names from src/data/vars.ts. Then use {VARS.KEY} for those names in the prose below. -`import { VARS } from '@data/vars';` -See AGENTS.md → Content variables for the full variable list and usage rules.] +[BEFORE PUBLISHING: Delete every bracketed instruction in this file, including this one. They are guidance for the author, not page content.] +[VARS: If this page names a product from src/data/vars.ts, add `import { VARS } from '@data/vars';` on the line directly below the frontmatter, then use {VARS.KEY} in prose. See AGENTS.md → Content variables.] -[Opening paragraph: What this feature/concept is and its primary benefit. -1-3 sentences. Lead with what the user gains from understanding this.] +[Opening paragraph: what this concept is and its primary benefit. 1-3 sentences. Lead with what the reader gains from understanding it. Assume they arrived here directly, not from a parent page.] -## [Key concepts or components — sentence case, specific to the subject. Not "Overview", "More details", or "Other"] +## [Key concepts — sentence case, renamed to match the subject] -[Explain the main ideas, components, or building blocks the reader needs -to understand. Use `*` bulleted lists with bold term + hyphen + description.] +[The main ideas or components the reader needs. Bold term + hyphen + description.] * **Concept A** - What it is and why it matters. * **Concept B** - What it is and why it matters. ## How it works -[Explain the system behavior, architecture, or data flow. -Focus on "what" and "why" before "how." -Define new terms when they first appear. -Use diagrams or architecture descriptions where they clarify relationships. -IMPORTANT: Do NOT include step-by-step procedures here. -Link to a procedural or quickstart page instead.] +[System behavior, architecture, or data flow. Answer "what" and "why" before "how". Define new terms on first use. Diagrams help where relationships are hard to describe in prose.] -## When to use [feature name] +[Do NOT put step-by-step procedures here. Link to a procedural or quickstart page instead.] -[Decision guidance: when to use this feature and when not to. -Help the reader decide if this is the right tool for their situation.] +## When to use [subject] + +[Decision guidance: when this is the right tool, and when it is not. The "when not to" half is the part readers cannot get anywhere else.] ## Related pages -[Required on new conceptual pages so the page does not dead-end. -Cross-reference related features, procedural guides, and deeper references. -Use descriptive link text that names the destination — not "here" or "this page".] +[Cross-links to related features, the procedural page for doing this, and deeper references. Use descriptive link text that names the destination.] * [Related feature](path/to/page.md) * [How to configure X](path/to/procedural-page.md) + +[STRUCTURE: Every block of content should sit under a header. Content before the first header is not linkable in the table of contents.] diff --git a/.agents/templates/faq.md b/.agents/templates/faq.md index 7d7474fab..c53f62905 100644 --- a/.agents/templates/faq.md +++ b/.agents/templates/faq.md @@ -1,35 +1,44 @@ --- +title: [Sentence case. Use "[Feature] FAQs" or "Frequently asked questions". This renders as the page H1 — do not add an H1 in the body.] description: >- - [One sentence, 50-160 characters: name the topic area these questions cover. - Don't just say "Frequently asked questions." - Example: "Answers to common questions about cloud agent billing, credits, and plan limits." - See AGENTS.md > Frontmatter > Descriptions by content type for the full rules. - Use {{TOKEN}} syntax for any product names in src/data/vars.ts.] + [One sentence, 50-160 characters: name the topic area these questions cover. Not just + "Frequently asked questions". Example: "Answers to common questions about cloud agent + billing, credits, and plan limits." + Use {{TOKEN}} syntax for product names in src/data/vars.ts.] --- -[VARS: Add this line immediately after the closing --- above if this page references any product names from src/data/vars.ts. Then use {VARS.KEY} for those names in the prose below. -`import { VARS } from '@data/vars';` -See AGENTS.md → Content variables for the full variable list and usage rules.] +[BEFORE PUBLISHING: Delete every bracketed instruction in this file, including this one. They are guidance for the author, not page content.] +[VARS: If this page names a product from src/data/vars.ts, add `import { VARS } from '@data/vars';` on the line directly below the frontmatter, then use {VARS.KEY} in prose. See AGENTS.md → Content variables.] -# [Title — sentence case. Title convention: "[Feature] FAQs" or "Frequently asked questions"] +[STOP — check the admission rules before using this template. The default is "not an FAQ". An FAQ page pulls answers away from the page that owns the topic: the reader on the owning page does not find the answer, the reader on the FAQ gets one without context, and the two drift apart as the product changes. -[Opening paragraph: Brief context about what this FAQ covers and -who it's for. 1-2 sentences.] +All three must hold: +1. The questions are genuinely cross-cutting — they span several features, so no single page owns them. +2. There is no canonical home. If any existing page could answer it in context, answer it there. "It would be buried there" means that page needs restructuring, not that the answer needs a second home. +3. A reader actually asks it, in their own words, sourced from support tickets, Slack, or community threads — not invented to organize existing content. -## [Theme group — sentence case. e.g., "General", "Billing", "Configuration"] +This test applies to adding a question to an existing FAQ page too. These grow by accretion. -[Group questions by theme so readers can scan for their topic.] +If the rules do not all hold: "What is X?" → conceptual page. "What are the limits?" → reference section on the owning page. "Why did I get error Y?" → troubleshooting. "How do I do Z?" → procedural section on the owning page.] -### [Question in the user's voice? e.g., "Can I use my own API key?" not "BYOK support"] +[Opening: what this FAQ covers and who it is for. 1-2 sentences.] -[Lead with a direct 1-2 sentence answer. Then provide detail if needed. -Keep answers concise — link to full documentation for deeper topics.] +## [Theme — sentence case, e.g. "Billing", "Configuration"] -### [Another question in the user's voice?] +[Group by theme so readers can scan to their topic.] -[Direct answer first, then detail. Link out for depth.] +### [Question in the reader's own words, ending in a question mark] -## [Another theme group — sentence case] +[QUESTION PHRASING: "Can I use my own API key?" not "BYOK support". Write what a person would type, not the feature name.] -### [Question] +[Lead with a direct answer in the first sentence, then detail. Keep it short and link out for depth — an FAQ answer should summarize and link, never be the only place a fact lives.] -[Answer] +### [Another question] + +[Direct answer first, then detail.] + +## Related pages + +[Cross-links to the pages that own these topics. Use descriptive link text that names the destination.] + +* [Feature documentation](path/to/page.md) +* [Reference](path/to/page.md) diff --git a/.agents/templates/feature-doc.md b/.agents/templates/feature-doc.md index b7a61ccaf..357501f47 100644 --- a/.agents/templates/feature-doc.md +++ b/.agents/templates/feature-doc.md @@ -1,94 +1,55 @@ --- +title: [Sentence case, task-based gerund when the page contains a procedure. Keep it general enough to cover the range of tasks on the page and agnostic about which option the reader picks: "Setting repository visibility", not "Making a private repository public". This renders as the page H1 — do not add an H1 in the body.] description: >- - [One sentence, 50-160 characters: what the feature does and its primary benefit. - Start with the verb or the feature, not "Documentation for." - Example: "Control what the agent can do with permission cards, auto-approve, and execution profiles." - See AGENTS.md > Frontmatter > Descriptions by content type for the full rules. - Use {{TOKEN}} syntax here for any product names that have a var in src/data/vars.ts.] + [One sentence, 50-160 characters: what the feature does and its primary benefit. Example: + "Control what the agent can do with permission cards, auto-approve, and execution profiles." + Use {{TOKEN}} syntax for product names in src/data/vars.ts.] --- -[VARS: Add this line immediately after the closing --- above if this page references any product names from src/data/vars.ts. Then use {VARS.KEY} for those names in the prose below. -`import { VARS } from '@data/vars';` -See AGENTS.md → Content variables for the full variable list and usage rules.] +[BEFORE PUBLISHING: Delete every bracketed instruction in this file, including this one. They are guidance for the author, not page content.] +[VARS: If this page names a product from src/data/vars.ts, add `import { VARS } from '@data/vars';` on the line directly below the frontmatter, then use {VARS.KEY} in prose. See AGENTS.md → Content variables.] -# [Feature name — sentence case, capitalize only the first word and proper feature names] +[This is the most common page type in Warp's docs (~75+ pages) and the one most prone to sprawl, because it accepts the most kinds of content. Two limits: -[Opening paragraph: What this feature does and its primary benefit. -1-3 sentences. Lead with what the user can accomplish.] +1. Never fold quickstart or tutorial content in here. Both are defined by a scope budget and a single continuous path, and both lose their purpose once embedded in a longer page. Link to them instead. Conceptual, procedural, reference, and troubleshooting sections can coexist here; those two cannot. +2. Past roughly 1500 words, split the procedures onto their own pages rather than adding another section.] + +[Opening paragraph: what the feature does and its primary benefit. 1-3 sentences. Lead with what the reader can accomplish, not the implementation.] :::note -[Optional: Key context the reader needs upfront, e.g., when they -DON'T need this feature, or a prerequisite they should know about. -Remove this callout if not needed.] +[Optional. Key context the reader needs upfront — a prerequisite, a limitation, or when NOT to use this. Delete if nothing applies.] ::: ## Key features -[Bulleted list. Bold term + dash + description for each. -Focus on what each capability means for the user. -If one capability is a genuine differentiator (e.g., an agent- or API-driven alternative to the default UI flow), give it real visual weight here or in its own callout near the top of the relevant section — don't bury it as a footnote after the primary flow is already documented.] +[2-4 capabilities. Bold term + hyphen + what it means for the reader. Collapse this into the opening paragraph if the feature is simple enough that a list is padding.] * **Feature A** - What it does and why it matters to the user. * **Feature B** - What it does and why it matters to the user. ## How it works -[CONCEPTUAL section: explain the system behavior, architecture, or flow. -Explain "what" and "why" before "how." -Define new terms when they first appear. -IMPORTANT: Do NOT include step-by-step procedures in this section. -Keep the conceptual and procedural sections clearly separated. -State platform, plan, preview, or interactive-only limits next to the behavior they constrain. -Do not invent internal tool names or implementation details the reader cannot act on. -Do not cite exact counts of tools, steps, or subcomponents (e.g., "ten tools") if they could change — describe the capability instead; a stale number is worse than no number. -Do NOT embed full error messages here — put failures in Troubleshooting at the end.] - -[SCREENSHOTS: If this feature has a distinctive visual surface (statusline, tab bar, side pane, multi-control layout), place a screenshot immediately after the paragraph that introduces that surface. Use descriptive alt text. Skip screenshots for purely textual CLI behavior.] - -## [Usage/configuration section — sentence case. Rename to match the feature, e.g., "Creating environments", "Configuring integrations"] - -[PROCEDURAL section: step-by-step instructions. -Order sections for the reader: Prerequisites → setup/config → day-to-day usage → advanced options. -Apply all procedural rules from AGENTS.md: -- Motivate steps before giving instructions -- Include expected outcomes after key steps -- Group related actions when they share the same UI context -- Name the app before the first Settings path or CLI command on this page -- Verify every UI label, Settings path, and CLI flag against source or the live product before publishing. If you cannot verify one, omit it or mark it with an inline `{/* VERIFY: ... */}` comment and report it per step 9.5 of the draft_docs skill -- Prefer durable actions and outcomes over ephemeral chrome (glyph colors, pure layout narration) -- Lead instructional sentences with the action or goal, then the control (✅ "To open the selector, press `Ctrl+E`." ❌ "To change either value, press `Ctrl+E`.") -- Disambiguate conditionals and multi-clause sentences so only one reading remains] +[CONCEPTUAL section. System behavior, architecture, or flow. Answer "what" and "why" before "how". Define new terms on first use. No step-by-step procedures here — keep the conceptual and procedural halves clearly separated.] + +## [Usage or configuration — sentence case, renamed to match the feature, e.g. "Creating environments"] + +[PROCEDURAL section. Motivate before instructing, include expected outcomes after key steps, and group related actions that share a UI context.] ### Prerequisites -[Bulleted list with inline context for each prerequisite. -Include: what the thing is, where to get it, link to full reference. -For integrations and team features, include admin requirements, who gains access after install, and any per-user auth steps.] +[Inline context for each: what it is, where to get it, and a link to the full reference.] -### [Task name — sentence case. e.g., "Create an environment with the CLI"] +### [Task name — sentence case, e.g. "Create an environment with the CLI"] 1. Step description. 2. Step description. -3. Step description. - -## [Additional sections as needed — sentence case. e.g., "Managing X", "Advanced usage"] - -[Repeat the conceptual or procedural pattern as appropriate. -Keep sections clearly delineated by type. -Avoid stacking multiple callouts; prefer short prose unless a caveat is easy to miss.] -## Troubleshooting +## [Additional sections as needed] -[Optional but recommended when the feature has common failures, permission errors, or exact platform error strings. -Place this section near the end of the page, before Related pages. -Format each item as: bold symptom or exact error message, then cause, then fix. -Do not scatter the same error callouts through earlier sections.] +[ORDER: broad to specific. Conceptual, then reference, then procedures in lifecycle order — enable, use, manage, disable, destructive actions — then troubleshooting.] ## Related pages -[Required on new feature and integration pages so the page does not dead-end. -Cross-reference related features, sibling integrations, next steps, and deeper references. -Use descriptive link text that names the destination — not "here" or "this page". -Include at least one sibling or overview link and one next-step workflow link.] +[Cross-links. Use descriptive link text that names the destination. If a quickstart or tutorial exists for this feature, link it here rather than inlining it above.] * [Related feature](path/to/page.md) -* [Deeper guide](path/to/page.md) +* [Quickstart for this feature](path/to/page.md) diff --git a/.agents/templates/guide-page.md b/.agents/templates/guide-page.md index 5369f3bed..b10cb5454 100644 --- a/.agents/templates/guide-page.md +++ b/.agents/templates/guide-page.md @@ -1,67 +1,65 @@ --- -title: [Task-oriented title in sentence case — reads like a search query. Capture the non-branded query a developer would actually search for, not "How to do X in Warp." The title field renders as the page H1; do not add a separate H1 in the body.] +title: [Sentence case, task-oriented, reading like a search query. Capture the non-branded query a developer would actually type: "How to set up Claude Code", not "How to set up Claude Code in Warp". Do not put "tutorial" or "guide" in the title. This renders as the page H1 — do not add an H1 in the body.] description: >- - [One sentence, 50-160 characters: what the reader will build or accomplish, - using the non-branded phrasing they would actually search for. - Example: "Set up Claude Code and run your first agentic coding session from the terminal." - See AGENTS.md > Frontmatter > Descriptions by content type for the full rules.] + [One sentence, 50-160 characters: what the reader will build or accomplish, in the + non-branded phrasing they would search for. Example: "Set up Claude Code and run your + first agentic coding session from the terminal."] --- +[BEFORE PUBLISHING: Delete every bracketed instruction in this file, including this one. They are guidance for the author, not page content.] +[VARS: If this page names a product from src/data/vars.ts, add `import { VARS } from '@data/vars';` below, then use {VARS.KEY} in prose and {{TOKEN}} in frontmatter. See AGENTS.md → Content variables.] +[AEO: If this page is driven by Peec, search-query, or answer-engine data, run `.agents/skills/aeo_brief/SKILL.md` first.] -[One sentence: what you'll accomplish by following this guide. Mention Warp by name. Include a time estimate if possible (e.g., "takes about 10 minutes").] +[SCOPE: This is a tutorial — a full workflow, start to finish, with context at the decision points. If the task fits in about five minutes and 600 words of essential steps, it is a quickstart instead; use `.agents/templates/quickstart.md`. A tutorial also requires that a quickstart already exists for this product area. If none does, write that first.] -[AEO GUIDANCE: If this guide is based on Peec, answer-engine prompts, search-query data, or AEO goals, create an AEO brief first using `.agents/skills/aeo_brief/SKILL.md`. Use the brief to preserve high-intent vocabulary naturally, translate awkward source-data phrasing into developer-friendly docs language, and decide whether this should be a new guide or an update to an existing page.] +[Introduction: who this is for, what prior knowledge it assumes, and what the reader will build. Do NOT state an expected completion time — it varies too much by experience level. (Quickstarts do state one; tutorials do not.)] import VideoEmbed from '@components/VideoEmbed.astro'; -{/* VARS: Also add the line below if this guide references product names from src/data/vars.ts. Then use {VARS.KEY} in prose. Use {{TOKEN}} in frontmatter YAML values above. See AGENTS.md → Content variables. */} -{/* import { VARS } from '@data/vars'; */} -{/* VIDEO: Always include a specific title prop naming the workflow/feature shown. Remove the entire VideoEmbed block if there is no video. */} - +[VIDEO: The `title` prop must name the workflow or feature shown, never "video" or "demo". Delete this block entirely if there is no video. The written content must stand alone either way — a reader should never need to watch to follow along.] + ## Prerequisites -[List what the reader needs before starting. Include inline context: what each prerequisite is, where to get it, and a link to more info. Orient the reader by naming the application before any menu paths.] +[Each item: what it is, where to get it, and a link. Name the application before any menu path.] -* **[Prerequisite 1]** — [What it is and where to get it]. See [link to docs] for details. -* **[Prerequisite 2]** — [Brief context]. +* **[Prerequisite]** — [What it is and where to get it]. See [link](path) for details. -[Use numbered H2 headings for each step (e.g., "## 1. Install Claude Code"). Do not add a "## Steps" wrapper heading — jump straight into the numbered steps after Prerequisites. Motivate each step: explain WHY before HOW, especially for setup steps. End each numbered sub-step with a period. Use ALL_CAPS for placeholder values in commands (e.g., YOUR_API_KEY). Do not use em dashes in procedural or instructional text. If there's an open-source repo for an example, link it. When referencing a Settings path or menu for the first time, orient the reader: "in the Warp app, go to **Settings** > ...".] +## [1. First step — action-oriented title] -## [Action-oriented step title] +[STEP HEADINGS: Number each H2. Do not add a "## Steps" wrapper heading — go straight into the numbered steps after Prerequisites.] -[Why you're doing this step — 1 sentence of motivation.] +[One sentence of motivation: why the reader is doing this.] -[Exact prompt, command, or instruction:] +[Give the real prompt or command, not a placeholder. Use ALL_CAPS for values the reader substitutes, like YOUR_API_KEY.] ``` -[prompt or command here] +[prompt or command] ``` -[Expected outcome — what should happen after this step.] +[Expected outcome: what should happen after this step.] -## [Next step title] +## [2. Next step] -[Motivation + instruction + expected outcome, same pattern as above.] +[Same pattern: motivation, instruction, expected outcome.] -## [Final step title] +## Troubleshooting -[Complete the workflow.] +[Required for tutorials — this is the clearest line between a tutorial and a quickstart, which only links out. Name what commonly goes wrong in this specific workflow and how to recover.] + +**[What the reader sees when it breaks]**\ +Why it happens, and how to recover. ## Productivity tips -[OPTIONAL SECTION — include when the guide naturally leads to workflow improvements. Use this to showcase Warp features (voice, images, vertical tabs, notifications, code review, etc.) as natural extensions of the workflow the reader just completed — not as a separate sales pitch. Remove this section if there are no relevant tips for the guide topic.] +[OPTIONAL. Warp features that extend the workflow the reader just completed — not a sales pitch. Delete this section if nothing fits naturally.] -* **[Tip 1 — feature name]** — [How it improves the workflow the reader just learned. Link to feature docs.] -* **[Tip 2]** — [Same pattern.] +* **[Feature]** — [How it improves the workflow they just learned.] See [link](path). ## Next steps -[2-3 sentence summary of what the reader accomplished. Then list links to related content. CROSS-LINKING: Always link to at least one other guide in the Guides section and one feature documentation page in the main docs. If this guide relates to features covered in the Third-Party CLI Agents section (src/content/docs/agent-platform/cli-agents/), link there too. If a standalone summary section feels valuable, add a ## Recap heading above the summary paragraph.] - -* [Link to related guide in the Guides section] -* [Link to relevant feature documentation in the main docs] -* [Link to deeper reference or advanced usage] +[Recap what the reader built, referring back to the example from the introduction. Then 2-3 actionable next steps.] -[LINK VERIFICATION: Before publishing, verify every internal link points to an existing file under `src/content/docs/` and, when the page should appear in navigation, a matching entry in `src/sidebar.ts`. If a target page is planned but not live, use the closest existing page and add a TODO comment.] +[CROSS-LINKING: Link at least one other page in the Guides section and one feature page in the main docs. Verify every internal link resolves to a real file under `src/content/docs/` before publishing — do not invent plausible-looking paths.] -[PRE-HANDOFF REVIEW: Before presenting the draft, check whether procedures are easy to scan, whether dense sections should become numbered steps or bullets, whether UI surfaces use canonical product names, whether the page adds value beyond existing docs, and whether any product behavior needs human testing.] +* [Related tutorial in the Guides section](path/to/page.md) +* [Feature documentation in the main docs](path/to/page.md) diff --git a/.agents/templates/procedural.md b/.agents/templates/procedural.md index fbb26174c..95c69b42c 100644 --- a/.agents/templates/procedural.md +++ b/.agents/templates/procedural.md @@ -1,61 +1,51 @@ --- +title: [Sentence case, beginning with a gerund that names the task. Example: "Configuring a self-hosted GitLab integration". Not "Self-hosted GitLab integration setup". This renders as the page H1 — do not add an H1 in the body.] description: >- - [One sentence, 50-160 characters: the task the reader will complete. - Start with an imperative verb, not "This page explains." - Example: "Connect Slack to Oz so mentions and channel messages can trigger cloud agent runs." - See AGENTS.md > Frontmatter > Descriptions by content type for the full rules. - Use {{TOKEN}} syntax here for any product names that have a var in src/data/vars.ts.] + [One sentence, 50-160 characters: the task the reader will complete. Start with an + imperative verb, not "This page explains". Example: "Connect Slack to the Automation + Platform so mentions and channel messages can trigger cloud agent runs." + Use {{TOKEN}} syntax for product names in src/data/vars.ts.] --- -[VARS: Add this line immediately after the closing --- above if this page references any product names from src/data/vars.ts. Then use {VARS.KEY} for those names in the prose below. -`import { VARS } from '@data/vars';` -See AGENTS.md → Content variables for the full variable list and usage rules.] +[BEFORE PUBLISHING: Delete every bracketed instruction in this file, including this one. They are guidance for the author, not page content.] +[VARS: If this page names a product from src/data/vars.ts, add `import { VARS } from '@data/vars';` on the line directly below the frontmatter, then use {VARS.KEY} in prose. See AGENTS.md → Content variables.] +[AEO: If this page is driven by Peec, search-query, or answer-engine data, run `.agents/skills/aeo_brief/SKILL.md` first.] -# [Task-oriented title — sentence case. Title convention: gerund, e.g., "Configuring X" or "Managing X"] - -[Opening paragraph: What the reader will accomplish and why. -1-2 sentences. Focus on the goal, not the tool.] - -[AEO GUIDANCE: If this procedure is based on Peec, answer-engine prompts, search-query data, or AEO goals, create an AEO brief first using `.agents/skills/aeo_brief/SKILL.md`. Use the brief to translate source-data vocabulary into precise, natural docs language and confirm whether this belongs in a new page or an existing page.] +[Opening paragraph: what the reader will accomplish and why. 1-2 sentences. Focus on the goal, not the tool.] ## Prerequisites -[Only if needed. Bulleted list with inline context for each prerequisite. -Each item should include: what it is (1 short clause), where to get or -create it, and a link to the full reference. -Example: -* **A Warp API key** - Authenticate API requests with a key from - **Settings** > **Cloud platform** > **Oz Cloud API Keys** in the Warp app. See [API Keys](path) for details.] +[Only if needed. Each item needs inline context: what it is in one clause, where to get it, and a link to the full reference. Assume the reader arrived here directly.] -## [Primary task name — sentence case. e.g., "Creating API keys"] +* **A Warp API key** - Authenticate API requests with a key from **Settings** > **Platform** in the Warp app. See [API keys](path) for details. -[Brief motivation: why the reader would do this (1 sentence). -Then numbered steps.] +## [Primary task — sentence case, e.g. "Creating an API key"] -1. Step description. +[One sentence of motivation before the steps. Explain why the reader is doing this, so they are not left wondering. Then the numbered steps.] + +1. Step description. [Include the expected outcome where it is not obvious, so the reader can confirm they are on track.] 2. Step description. 3. Step description. +[STEP SIZING: Aim for one primary action per step, but group tightly related actions that share the same UI context — up to about three. A simple task should not need 10+ steps, and a single step should not be a mini-procedure.] + :::note -[Optional: tip, clarification, or "good to know" context -relevant to the steps above.] +[Optional. One or two callouts per page at most; prefer body prose. Delete if nothing applies.] ::: -## [Secondary task or follow-up — sentence case. e.g., "Managing API keys"] +## [Secondary task — sentence case, e.g. "Rotating an API key"] -[Repeat the pattern: brief context, then numbered steps or -descriptive content as appropriate.] +[Same pattern: motivation, then steps. Order sections by reader chronology — requirements, setup, usage, management, then destructive actions.] ## Troubleshooting -[Optional but recommended. Common issues the reader might encounter -while following these steps. -Format: symptom/error as bold text, then cause and fix.] +[Recommended. Keep error messages here rather than woven through the steps above. Format each as the symptom in bold, then cause, then fix.] -## Best practices +**Exact error message the user sees**\ +Why it happens, and how to fix it. -[Optional. Bulleted list of actionable recommendations. -Bold the key action at the start of each item.] +## Related pages -* **Use environment variables** - Avoid passing secrets directly in commands. +[Cross-links. Use descriptive link text that names the destination.] -[PRE-HANDOFF REVIEW: Before presenting the draft, check whether steps are easy to scan, whether each important step has an expected outcome, whether UI names and Settings paths are current, whether AEO vocabulary is natural rather than stuffed, and whether any step needs human product testing.] +* [Conceptual page for this feature](path/to/page.md) +* [Related task](path/to/page.md) diff --git a/.agents/templates/quickstart.md b/.agents/templates/quickstart.md index f44cbb848..26dce20cd 100644 --- a/.agents/templates/quickstart.md +++ b/.agents/templates/quickstart.md @@ -1,61 +1,41 @@ --- +title: [Sentence case, naming the feature. Use "Quickstart for [product]" or "[Feature] quickstart". Never a bare "Quickstart". This renders as the page H1 — do not add an H1 in the body.] description: >- [One sentence, 50-160 characters: what the reader ends up with, plus the time budget. - Start with an imperative verb, not "Learn how to" or "Get started with." - Example: "Install the {{WARP_AGENT_CLI}}, log in, and run your first agent conversation in about five minutes." - See AGENTS.md > Frontmatter > Descriptions by content type for the full rules. - Use {{TOKEN}} syntax here for any product names that have a var in src/data/vars.ts.] + Start with an imperative verb, not "Learn how to" or "Get started with". Example: + "Install the {{WARP_AGENT_CLI}}, log in, and run your first agent conversation in about + five minutes." Use {{TOKEN}} syntax for product names in src/data/vars.ts.] --- -[VARS: Add this line immediately after the closing --- above if this page references any product names from src/data/vars.ts. Then use {VARS.KEY} for those names in the prose below. -`import { VARS } from '@data/vars';` -See AGENTS.md → Content variables for the full variable list and usage rules.] +[BEFORE PUBLISHING: Delete every bracketed instruction in this file, including this one. They are guidance for the author, not page content.] +[VARS: If this page names a product from src/data/vars.ts, add `import { VARS } from '@data/vars';` on the line directly below the frontmatter, then use {VARS.KEY} in prose. See AGENTS.md → Content variables.] -# [Descriptive title — sentence case. Title convention: "[Feature] quickstart" or "Quickstart for [product]". Do NOT use a bare "Quickstart" — include the feature name.] +[SCOPE — the defining constraint: about five minutes and roughly 600 words. This is a budget, not a target. A quickstart that outgrows it has become a tutorial and should be reworked as one. Written for someone who already understands the product and is ready to try it, so leave out how it works and why they would want it. If the task needs context at its decision points, it is a tutorial.] -[Opening paragraph: What the reader will accomplish, who it's for, -and approximately how long it takes (~10 minutes). -1-3 sentences. Keep it brief — this is about speed.] - -*** +[Opening paragraph: who this is for, what prior knowledge it assumes, what the reader will end up with, and the time budget. 2-3 sentences.] ## Prerequisites -[Minimal. Link to full setup docs rather than inlining lengthy setup. -The reader should be able to start quickly.] - -* **Prerequisite 1** - Brief description with [link to details](path) -* **Prerequisite 2** - Brief description +[Minimal. Link to full setup docs rather than inlining them — interrupting the flow defeats the purpose.] -*** +* **Prerequisite** - Brief description with a [link to details](path). -## [Primary workflow — sentence case. e.g., "Running your first cloud agent"] +## [Primary workflow — sentence case, e.g. "Run your first cloud agent"] -_~10 minutes_ +### 1. [Step title] -### 1. Step title +[Steps can be less explicit than full procedural content, because the audience already knows the product. Use code blocks and screenshots generously — visual confirmation reassures the reader they are on track. Stay on the critical path and defer edge cases to other pages.] -[Steps can be less formal than full procedural content. -Use heavy visual cues: code blocks, screenshots. -Keep on the critical path — defer edge cases to other pages.] +### 2. [Step title] -### 2. Step title +### 3. [Step title] -### 3. Step title +## Troubleshooting -*** +[Optional, and link-only. Point at existing troubleshooting content. Do not write new troubleshooting here — that is tutorial territory and it will blow the word budget.] ## Next steps -[2-3 actionable next steps. Always link to conceptual content about the -feature and to deeper procedural guides.] +[One-line recap of what the reader just accomplished, then 2-3 actionable next steps. Always include a link to the conceptual page for the feature. This section goes last.] +* [Conceptual page for this feature](path/to/page.md) * [Deeper guide](path/to/page.md) -* [Related feature](path/to/page.md) - -## Troubleshooting - -[Brief. Only the most common issues someone might hit during the quickstart. -For comprehensive troubleshooting, link to the dedicated page.] - -**Issue description**\ -Cause and fix. diff --git a/.agents/templates/reference.md b/.agents/templates/reference.md index b1dc4a3f0..6eec6bd0e 100644 --- a/.agents/templates/reference.md +++ b/.agents/templates/reference.md @@ -1,47 +1,39 @@ --- +title: [Sentence case. A noun phrase naming what can be looked up. Break up stacked nouns with prepositions: "Keyboard shortcuts for the code editor", not "Code editor keyboard shortcut reference". Never a bare "Overview" or "Reference". This renders as the page H1 — do not add an H1 in the body.] description: >- - [One sentence, 50-160 characters: what the reader can look up here. - Name the artifacts (flags, endpoints, shortcuts), not the genre. - Example: "Look up {{WARP_AGENT_CLI}} flags, environment variables, slash commands, and keyboard shortcuts." - See AGENTS.md > Frontmatter > Descriptions by content type for the full rules. - Use {{TOKEN}} syntax for any product names in src/data/vars.ts.] + [One sentence, 50-160 characters: what the reader can look up here. Name the artifacts — + flags, endpoints, shortcuts — not the genre. Example: "Look up {{WARP_AGENT_CLI}} flags, + environment variables, slash commands, and keyboard shortcuts." + Use {{TOKEN}} syntax for product names in src/data/vars.ts.] --- -[VARS: Add this line immediately after the closing --- above if this page references any product names from src/data/vars.ts. Then use {VARS.KEY} for those names in the prose below. -`import { VARS } from '@data/vars';` -See AGENTS.md → Content variables for the full variable list and usage rules.] +[BEFORE PUBLISHING: Delete every bracketed instruction in this file, including this one. They are guidance for the author, not page content.] +[VARS: If this page names a product from src/data/vars.ts, add `import { VARS } from '@data/vars';` on the line directly below the frontmatter, then use {VARS.KEY} in prose. See AGENTS.md → Content variables.] -# [Title — sentence case. Title convention: noun describing contents, e.g., "CLI commands", "Keyboard shortcuts". Not a bare "Overview" or "Reference".] +[Opening: what this reference covers and how to use it. 1-2 sentences. The reader already knows what they want — this is for lookup, not learning.] -[Brief intro: what this reference covers and how to use it. -1-2 sentences. This is for lookup, not learning.] +## [Entry group — sentence case and specific, e.g. "Running agents"] -## [Section name — sentence case and specific. e.g., "Installing the CLI", "Authentication". Not "More details".] +[One sentence introducing the group.] -[Introductory sentence or conceptual context for this section.] +[REPEATING PATTERN: pick one structure per page and apply it to every entry without exception. Consistency matters more here than in any other content type, because readers scan rather than read. -## [Command/endpoint/option group — sentence case. e.g., "Running agents"] +For commands and endpoints: name → syntax → description → flags → example. +For settings and options: name → type → default → description. -[Use a strict repeating pattern for each entry. Every entry must -follow the same structure. Consistency is more important than style. - -For commands/endpoints: name → syntax → description → flags/params → example -For settings/options: name → type → default → description - -Use H2 for major sections, H3 for individual entries. -Use tables for multiple parameters, lists for single elements.] +Use H2 for groups, H3 for individual entries. Tables for multiple parameters, lists for single elements. Alphabetize where order does not carry meaning.] ### `command-name` -[Brief description of what this command does.] +[What this command does, in one or two sentences.] ```sh command-name [options] ``` -**Key flags:** +**Flags:** -* `--flag-name` (`-f`) — Description of what this flag does. -* `--another-flag` — Description. +* `--flag-name` (`-f`) — What it does. +* `--another-flag` — What it does. **Example:** @@ -51,5 +43,11 @@ command-name --flag-name value ### `another-command` -[Repeat the same structure for every entry. -Alphabetize entries where ordering doesn't matter.] +[Same structure, every time. Be exhaustive: document every option, flag, and value. A reference with gaps sends the reader to the source.] + +## Related pages + +[Cross-links. Use descriptive link text that names the destination.] + +* [Conceptual page for this feature](path/to/page.md) +* [How to use it](path/to/procedural-page.md) diff --git a/.agents/templates/troubleshooting.md b/.agents/templates/troubleshooting.md index c72d2f145..35ea20183 100644 --- a/.agents/templates/troubleshooting.md +++ b/.agents/templates/troubleshooting.md @@ -1,40 +1,43 @@ --- +title: [Sentence case. Use "Troubleshooting [feature]" or "Known issues with [feature]". This renders as the page H1 — do not add an H1 in the body.] description: >- - [One sentence, 50-160 characters: name the symptoms covered, not the act of troubleshooting. - Example: "Fix sign-in failures, failed conversation resumes, and update problems in the {{WARP_AGENT_CLI}}." - See AGENTS.md > Frontmatter > Descriptions by content type for the full rules. - Use {{TOKEN}} syntax for any product names in src/data/vars.ts.] + [One sentence, 50-160 characters: name the symptoms covered, not the act of + troubleshooting. Example: "Fix sign-in failures, failed conversation resumes, and update + problems in the {{WARP_AGENT_CLI}}." + Use {{TOKEN}} syntax for product names in src/data/vars.ts.] --- -[VARS: Add this line immediately after the closing --- above if this page references any product names from src/data/vars.ts. Then use {VARS.KEY} for those names in the prose below. -`import { VARS } from '@data/vars';` -See AGENTS.md → Content variables for the full variable list and usage rules.] +[BEFORE PUBLISHING: Delete every bracketed instruction in this file, including this one. They are guidance for the author, not page content.] +[VARS: If this page names a product from src/data/vars.ts, add `import { VARS } from '@data/vars';` on the line directly below the frontmatter, then use {VARS.KEY} in prose. See AGENTS.md → Content variables.] -# [Title — sentence case. Title convention: "Troubleshooting [feature]" or "Known issues with [feature]"] +[The reader arrived because something broke. Lead with the fix, not background. Skip a general introduction unless it genuinely helps them find their symptom faster.] :::note -[Optional: link to GitHub issues page, support channels, or related resources.] +[Optional. Link to the GitHub issues page or support channels. Delete if not useful.] For a complete list of issues and feature requests, visit our [GitHub issues page](https://github.com/warpdotdev/Warp/issues). ::: -## [Category header — sentence case. e.g., "Environments", "Authentication", "CLI"] +## [Category — sentence case, e.g. "Authentication", "Environments"] -[Group related issues under broad category headers. -Each issue gets its own H3 with the symptom or error message as the header.] +[Group related issues under broad categories so the reader can scan to their area.] -### [Symptom or error message — use the exact text the user sees] +### [The exact error message or symptom the user sees] -[Cause: 1-2 sentences explaining why this happens.] +[HEADER: Use the literal error text where there is one. This is what the reader pastes into search, and matching it exactly is the single highest-value thing on the page.] -[Solution: numbered steps following procedural rules.] +[Cause: 1-2 sentences on why this happens.] -1. Step to fix the issue. +1. Step to fix it. 2. Next step. -[Workaround (if no full fix is available): -Describe an alternative approach the user can take.] +[Workaround: if no full fix exists, describe the alternative and say plainly that it is a workaround.] ### [Another symptom or error message] -[Repeat the pattern: cause → solution → workaround. -The reader arrived because something broke — lead with the fix, -not background context.] +[Same pattern every time: symptom as the header, then cause, then fix, then workaround.] + +## Related pages + +[Cross-links. Use descriptive link text that names the destination.] + +* [Feature documentation](path/to/page.md) +* [Related troubleshooting](path/to/page.md) diff --git a/AGENTS.md b/AGENTS.md index 1bbb743cf..cfabdf252 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -680,7 +680,18 @@ Concrete page scaffolds for each content type are in `.agents/templates/`. Use t - **Tutorial** — `.agents/templates/guide-page.md` (filename is a holdover from when the type was called "guide") - **Feature documentation (combined)** — `.agents/templates/feature-doc.md` -Each template includes inline HTML comments explaining what to put in each section and why. +Each template carries its guidance as **bracketed instructions** in the body, not HTML comments — agents deprioritize comments, so the guidance would be skipped. Every template opens with a `[BEFORE PUBLISHING: ...]` note; delete every bracketed instruction, including that one, before the page ships. + +Each template also sets `title` in frontmatter and adds no H1 to the body. Starlight renders the frontmatter title as the page H1, so a body H1 produces a duplicate. + +### Closing section + +Every page ends with one of two sections, chosen by content type: + +- **`## Next steps`** — quickstarts and tutorials. The reader just finished something and needs forward momentum: a one-line recap, then 2-3 actionable next steps, always including the conceptual page for the feature. +- **`## Related pages`** — every other type. The reader wants lateral material, not a sequel. + +Do not use "Further reading" or "See also"; neither appears anywhere in the corpus. Whichever section applies, it goes last and contains at least one internal link whose anchor text names the destination. ## Terminology standards From 0d08520f15f6c3ec7f368c519ec1879bdafbef20 Mon Sep 17 00:00:00 2001 From: Rachael Rose Renk <91027132+rachaelrenk@users.noreply.github.com> Date: Thu, 20 Aug 2026 13:50:26 -0600 Subject: [PATCH 8/8] docs: split the content design plan into reference plus template, and fix its review-timing claim Two changes, one of them a correction to a claim that was simply wrong. The reference argued that a plan is cheaper to disagree with than finished prose, and then told the author to put it in the PR body. Those do not go together. If the plan lands in the PR body, the draft already exists and the expensive work is done -- the reviewer is not saved a rewrite. The argument described a pre-draft checkpoint while the placement described a record. The pipeline deliberately opens draft PRs rather than proposing first, so the automated path has no pre-draft human checkpoint by design. Overclaiming here obscured that tradeoff instead of stating it. Now framed by mode, because the two cases really are different: - Interactive drafting is a real checkpoint. draft_docs presents the plan and waits before writing prose, the way write-feature-docs already waits on its outline. Redirecting costs a conversation instead of a rewrite. - Automated runs get a record and a consistency check. The prose exists by the time anyone reads it, but the reasoning is inspectable next to the diff, so a reviewer can catch drift and reject on aim rather than on prose. The benefit that survives in both cases is that writing the plan disciplines the agent -- it inverts the template default regardless of when a human reads it. Separately, the reference was doing two jobs: explaining the fields and carrying the fill-in artifact. Split them along the same line the repo already uses for content types, where AGENTS.md defines and .agents/templates/ scaffolds. The artifact moves to .agents/templates/content-design-plan.md; the reference keeps the definitions and the reasoning. It is the one template that is not a page scaffold, so AGENTS.md now scopes the frontmatter-title rule to page templates and says why this one is exempt. Co-Authored-By: Warp --- .agents/references/content-design-plan.md | 41 +++++++---------------- .agents/skills/draft_docs/SKILL.md | 8 +++-- .agents/skills/missing_docs/SKILL.md | 11 +++--- .agents/templates/content-design-plan.md | 29 ++++++++++++++++ AGENTS.md | 6 ++-- 5 files changed, 58 insertions(+), 37 deletions(-) create mode 100644 .agents/templates/content-design-plan.md diff --git a/.agents/references/content-design-plan.md b/.agents/references/content-design-plan.md index 62808bcb5..4b42535e7 100644 --- a/.agents/references/content-design-plan.md +++ b/.agents/references/content-design-plan.md @@ -1,6 +1,6 @@ # Content design plan -Before we begin drafting a docs page, we need to be extremely clear on it's purpose, value, and audience. We define these things by completing a content design plan before making any changes to the docs. +Before we begin drafting a docs page, we need to be extremely clear on its purpose, value, and audience. We define these things by completing a content design plan before making any changes to the docs. Read this after a change has passed `.agents/references/docs-worthiness-criteria.md`, and before opening any template. Every new page and every substantive update to an existing page needs a content design plan — whether the drafting is done by a scheduled agent or by a person invoking a drafting skill directly. @@ -10,7 +10,14 @@ Drafting that starts at the template produces pages shaped by the template. The The plan inverts that. Start by determining who the reader is and what they are trying to do, and the content type falls out of the answer instead of dictating it. -It is also the artifact a reviewer can actually disagree with. Reviewing a finished draft means arguing about prose. Reviewing a plan means arguing about whether the doc is aimed at the right person solving the right problem, which is the disagreement worth having and the one that is expensive to resolve after the page is written. +That benefit does not depend on when a human reads the plan. Writing it is what shapes the draft. + +**What the plan is for depends on where it is reviewed**, and the two cases are genuinely different: + +- **Interactive drafting — a real checkpoint.** When a person invoked the drafting skill, present the plan and wait before writing any prose. Here the plan is cheap to disagree with: redirecting the audience or the content type costs a conversation instead of a rewrite. `write-feature-docs` already works this way with its Step 3 outline confirmation. +- **Automated runs — a record and a consistency check.** A scheduled run opens a draft PR without a pre-draft checkpoint, so by the time anyone reads the plan the prose exists. It is not saving the reviewer a rewrite. What it does is make the reasoning inspectable next to the diff, so a reviewer can catch drift — the plan says "backend engineer configuring self-hosted GitLab" and the page reads like a conceptual overview — and can reject on aim rather than on prose. + +Do not claim the automated path buys early disagreement. It does not, and pretending otherwise obscures a real tradeoff: the pipeline was deliberately built to open draft PRs rather than propose first, accepting late review in exchange for not gating every candidate on a human. ## Principles @@ -91,33 +98,10 @@ List the scenarios worth covering, in priority order. Then **name what you are l ## Where the plan lives -**A required section in the docs PR body**, filled in before the diff is reviewed. - -Keeping it next to the diff is the point. A plan buried in an agent run log is not reviewable in practice — nobody opens the run to check the reasoning behind a page. In the PR body, the reviewer sees the intent and the execution together and can catch a well-written page aimed at the wrong reader. - -Use this structure: - -```markdown -## Content design plan - -**Audience and JTBD:** [Specific reader in a specific situation, and the outcome they want] - -**Problem:** [What breaks down without this doc] - -**Goals:** -- [Reader capability] -- [Reader capability] - -**Purpose and value:** [Why this page earns its place] - -**Content type:** [Type] — [one-line rationale] - -**Skill and template:** `[skill]` / `.agents/templates/[template].md` +Fill in `.agents/templates/content-design-plan.md`, then: -**High-impact scenarios:** -- Covers: [scenario], [scenario] -- Excludes: [scenario] — [why] -``` +- **Present it to the requester before drafting** when a person invoked the drafting skill. This is the checkpoint, and skipping it forfeits the only cheap chance to redirect. +- **Include it in the PR body** as a `## Content design plan` section, in every case. A plan that lives only in an agent run log is not reviewable in practice — nobody opens the run to check the reasoning behind a page. For an update to an existing page rather than a new page, the same fields apply, scoped to the change: the audience and job for the section being added or revised, and what the page fails to do for that reader today. @@ -134,6 +118,7 @@ If the change adds, removes, or reframes information a reader acts on, it needs ## Related references +- `.agents/templates/content-design-plan.md` — the fill-in artifact this reference explains - `.agents/references/docs-worthiness-criteria.md` — whether the doc should exist, applied before this - `AGENTS.md` → "Drafting by content type" — the content type definitions and rules - `.agents/templates/` — the page scaffolds diff --git a/.agents/skills/draft_docs/SKILL.md b/.agents/skills/draft_docs/SKILL.md index caa163280..2f16e9c9c 100644 --- a/.agents/skills/draft_docs/SKILL.md +++ b/.agents/skills/draft_docs/SKILL.md @@ -65,11 +65,15 @@ How much of the gate applies depends on who is asking: When the change passes, choose the outcome explicitly: **update an existing page** (preferred), **new page**, or **no docs**. Prefer updating whenever a page already covers the surface. -**Second, what should the doc be?** Write a content design plan per `.agents/references/content-design-plan.md`, filling in every field: audience and JTBD, problem statement, goals, purpose and value, content type and model, skills and templates, and high-impact scenarios with explicit exclusions. +**Second, what should the doc be?** Fill in `.agents/templates/content-design-plan.md`, using `.agents/references/content-design-plan.md` for what each field is asking. The plan decides the content type — step 4 records that decision rather than making it. Starting at the template produces pages shaped by the template instead of by the reader's need. -Carry the completed plan into the PR body as a `## Content design plan` section. Small corrections listed under "When a plan can be skipped" in that reference are exempt from both gates. +**When a person invoked this skill, present the plan and wait before drafting.** This is the checkpoint: redirecting the audience or content type now costs a conversation, and after the prose exists it costs a rewrite. Do not skip it just because the requester seems confident about what they want. + +Carry the completed plan into the PR body as a `## Content design plan` section either way. In an unattended run there is no one to present it to, so the PR body is the only place a human will see the reasoning. + +Small corrections listed under "When a plan can be skipped" in that reference are exempt from both gates. ### 4. Identify the content type and template Record the content type chosen in the design plan, and pick its template and type-specific skill from this table. If drafting has diverged from the plan's chosen type, revisit the plan rather than silently switching templates. diff --git a/.agents/skills/missing_docs/SKILL.md b/.agents/skills/missing_docs/SKILL.md index 2b7ecfe03..21f767aeb 100644 --- a/.agents/skills/missing_docs/SKILL.md +++ b/.agents/skills/missing_docs/SKILL.md @@ -253,11 +253,12 @@ python3 .agents/skills/missing_docs/scripts/audit_docs.py --update-snapshot `.agents/references/docs-worthiness-criteria.md`, with the gate and its concrete evidence written down. No recorded verdict means no drafting. For changelog-derived findings the verdict also belongs in `references/changelog_decisions.md`. -2. **A content design plan.** Follow `.agents/references/content-design-plan.md` and fill - in every field before opening a template. The plan decides the content type; the - template does not. Carry the completed plan into the PR body verbatim — it is a - required section. Small corrections listed in that reference's "When a plan can be - skipped" section are exempt. +2. **A content design plan.** Fill in `.agents/templates/content-design-plan.md` before + opening a page template, using `.agents/references/content-design-plan.md` for what each + field is asking. The plan decides the content type; the template does not. Carry it into + the PR body verbatim — a scheduled run has no one to present it to, so the PR body is the + only place a human will see the reasoning. Small corrections listed in that reference's + "When a plan can be skipped" section are exempt. A finding that passes the gate with the **update an existing page** outcome is still a drafting task — it just edits a page instead of creating one. Prefer it; new pages need diff --git a/.agents/templates/content-design-plan.md b/.agents/templates/content-design-plan.md new file mode 100644 index 000000000..66fa4468e --- /dev/null +++ b/.agents/templates/content-design-plan.md @@ -0,0 +1,29 @@ +## Content design plan + +[BEFORE SUBMITTING: Delete every bracketed instruction, including this one. Fill in every field — "not applicable" is a valid answer only with a reason. See `.agents/references/content-design-plan.md` for what each field is asking and why.] + +[WHERE THIS GOES: Present it to the requester before drafting when a person invoked the drafting skill. Include it in the PR body either way. This is not a page — it is a section of a PR description, or terminal output during an interactive session.] + +**Audience and JTBD:** [A specific reader in a specific situation, and the outcome they want in their own terms. Not a demographic. ✅ "A backend engineer setting up their team's first cloud agent, who needs it to reach a private GitLab instance and has not configured Warp credentials before." ❌ "Developers who use cloud agents."] + +**Problem:** [What the reader tries, where it breaks down, and what it costs them. If the honest answer is "nothing, they just would not know this exists," go back to the worthiness criteria.] + +**Goals:** + +[Two or three, written as reader capabilities rather than page contents. More than three usually means the page is doing several jobs and should be split. ✅ "The reader can decide which credential strategy fits their setup and configure it." ❌ "Explains the credential strategy options."] + +- [Reader capability] +- [Reader capability] + +**Purpose and value:** [Why this page earns its place, and what is lost without it. If the value is already delivered by an existing page, update that page instead.] + +**Content type:** [Type] — [one-line rationale tied to the reader's job, not to the page's shape] + +**Skill and template:** `[drafting skill]` / `.agents/templates/[template].md` + +**High-impact scenarios:** + +[The exclusions are the load-bearing half. They are what keeps the page from growing to cover every configuration permutation someone might hit.] + +- Covers: [scenario], [scenario] +- Excludes: [scenario] — [why] diff --git a/AGENTS.md b/AGENTS.md index cfabdf252..b618bef58 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -680,9 +680,11 @@ Concrete page scaffolds for each content type are in `.agents/templates/`. Use t - **Tutorial** — `.agents/templates/guide-page.md` (filename is a holdover from when the type was called "guide") - **Feature documentation (combined)** — `.agents/templates/feature-doc.md` -Each template carries its guidance as **bracketed instructions** in the body, not HTML comments — agents deprioritize comments, so the guidance would be skipped. Every template opens with a `[BEFORE PUBLISHING: ...]` note; delete every bracketed instruction, including that one, before the page ships. +One template is not a page scaffold: `.agents/templates/content-design-plan.md` is the fill-in artifact completed *before* drafting, presented to the requester in an interactive session and included in the PR body in every case. See `.agents/references/content-design-plan.md`. -Each template also sets `title` in frontmatter and adds no H1 to the body. Starlight renders the frontmatter title as the page H1, so a body H1 produces a duplicate. +Every template carries its guidance as **bracketed instructions** in the body, not HTML comments — agents deprioritize comments, so the guidance would be skipped. Each one opens with a removal note; delete every bracketed instruction, including that one, before shipping. + +Each **page** template also sets `title` in frontmatter and adds no H1 to the body. Starlight renders the frontmatter title as the page H1, so a body H1 produces a duplicate. This does not apply to the content design plan template, which is a PR body section rather than a page. ### Closing section