From 3cf2e3cbc9a86f932e803f9127352ad6d9c7b77d Mon Sep 17 00:00:00 2001 From: Rachael Rose Renk <91027132+rachaelrenk@users.noreply.github.com> Date: Tue, 25 Aug 2026 13:04:22 -0600 Subject: [PATCH 1/3] missing_docs: keep at most one bookkeeping PR open The PR strategy said a bookkeeping PR "is independently mergeable in any order." That is true against feature PRs, which is the case it was written for. It is false against a second bookkeeping PR: both edit feature_surface_map.md and surface_snapshot.json, and the snapshot is a wholesale regen, so a conflict between two of them cannot be resolved by hand at all -- it has to be regenerated on the merged tree. #614 and #624 are that collision, sitting open right now. Two drift-watch runs a day apart independently triaged the same two /factory routes, reached the same Gate 0 verdict, and each added the same two map lines. Neither looked for the other's PR, and they used different branch-naming schemes, so there was no way to find one from the other. Run #2's ledger eway to find one from the other. Run #2's ledger eway to find one from the other. Run #2's ledger eway to find one from the other. Run #2's ledger eway to find one from the other. Run #2's ledgeran stays rare. Changes: - Scope the independence claim to feature PRs, and add the rule: check for an open bookkeeping PR first, extend that branch, and re-run --commit and --update-snapshot there so the marker and snapshot stay one regen covering every release the PR carries. Wait for the merge instead when it is already approved. - Standardize the title (missing_docs bookkeeping: ) and branch (missing-docs/boo (missing-docs/boo (mise search (missing-docs/boo (missing-docs/boo (mise search (missing-docs/boo (miste their inconsistent titles. - Triage now reads the ledger and map as they stand on any open bookkeeping PR, not just on main. A verdict in an unmerged PR is still a verdict. - Carry both into drift-watch step 8 and the scheduled-agent prompt, which is the only copy a cron run is guaranteed to read. Co-Authored-By: Warp --- .agents/skills/missing_docs/SKILL.md | 56 +++++++++++++++++++++------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/.agents/skills/missing_docs/SKILL.md b/.agents/skills/missing_docs/SKILL.md index 1b720e5d..f96a4a85 100644 --- a/.agents/skills/missing_docs/SKILL.md +++ b/.agents/skills/missing_docs/SKILL.md @@ -423,9 +423,31 @@ their area. Do NOT bundle unrelated features into a single mega PR. snapshot is a wholesale regen. Put every `Flag -> page` mapping, ignore/`internal`/ `gated:` entry, and the `--update-snapshot` regen into one bookkeeping PR. Its mappings may point at pages that land in the sibling feature PRs — map hygiene only requires the - target page to exist on the base branch, so the bookkeeping PR is independently - mergeable in any order. If a run documents exactly one feature, fold its map + snapshot - changes into that single PR and skip the companion. + target page to exist on the base branch, so the bookkeeping PR merges independently of + those feature PRs, in any order. If a run documents exactly one feature, fold its map + + snapshot changes into that single PR and skip the companion. +- **Keep at most one bookkeeping PR open. Extend the open one rather than opening a + second.** The independence above holds against *feature* PRs; it does not hold against + another bookkeeping PR. Two of those edit the same shared files, and + `surface_snapshot.json` is regenerated wholesale, so a conflict between them cannot be + resolved by hand — it has to be regenerated on the merged tree. Look for an existing one + before opening yours: + + ```bash + gh pr list --state open --search "missing_docs bookkeeping in:title" \ + --json number,headRefName,title + ``` + + If one exists, check out its branch and add this run's map entries and ledger rows on + top, then re-run `check_new_release.py --commit` and `--update-snapshot` there so the + marker and snapshot stay a single regen covering every release the PR now carries. + Update its title and body to name them all. The one exception: if it is already approved + and about to merge, wait for the merge and branch from the result. + + For the search to find it, title every bookkeeping PR `missing_docs bookkeeping: + ` and name its branch `missing-docs/bookkeeping-`. #614 and #624 used + two different branch-naming schemes and neither run looked for the other's PR, which is + how both ended up adding the same two `/factory` map entries. - **API spec gaps stay separate** — released endpoints go through the `sync-openapi-spec` skill as their own change, never bundled into a feature PR. - **Validate once, then split.** Run `npm run build` on the combined working tree (all @@ -467,10 +489,13 @@ with the product. Each run: --diff --output /tmp/docs_audit.json ``` 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. + already decided. Read the ledger and surface map as they stand on any open bookkeeping + PR too, not only the copies on `main` — a verdict recorded in an unmerged PR is still a + verdict, and re-triaging it burns the run and produces duplicate map entries. 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. **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 @@ -522,10 +547,11 @@ with the product. Each run: owners as a partial result worth naming in the run output. 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), 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: every drafting PR body opens with the required + owner), each carrying its content design plan as a section in the PR body, plus the + run's bookkeeping changes to `feature_surface_map.md`, `changelog_decisions.md`, + `last_release_processed.json`, and `surface_snapshot.json`. Extend the open bookkeeping + PR if there is one; open a new one titled `missing_docs bookkeeping: ` only if + there is not. Use the `create_pr` skill: every drafting PR body opens with the required `## What this feature does` summary, and every PR gets its owning reviewer requested per step 7 before the run is done. Summarize remaining (deferred) findings in the relevant PR body so nothing is silently dropped. @@ -557,8 +583,12 @@ Recommended scheduled-agent prompt (copy when setting up the agent): > source files behind each addressed finding. Open one focused PR per documented feature > (grouping only features that share a doc file or owner), each opening with the required > "## What this feature does" summary and carrying 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. +> its body, plus the bookkeeping changes to feature_surface_map.md, +> changelog_decisions.md, last_release_processed.json, and surface_snapshot.json. Before +> opening a bookkeeping PR, search for an open one with gh pr list --state open --search +> "missing_docs bookkeeping in:title" and extend that branch instead of opening a second; +> two open bookkeeping PRs conflict on a snapshot that is regenerated wholesale. Title a +> new one "missing_docs bookkeeping: ". > Request the resolved owner as reviewer on every PR with gh pr edit --add-reviewer, > falling back to dannyneira when nothing resolves, and verify the requested-reviewers > list is non-empty before you finish — a PR with no requested reviewer is an incomplete From bdd27197f431547ba1d8d00758424a683d3c34b0 Mon Sep 17 00:00:00 2001 From: Rachael Rose Renk <91027132+rachaelrenk@users.noreply.github.com> Date: Tue, 25 Aug 2026 13:28:09 -0600 Subject: [PATCH 2/3] missing_docs: use the repo's existing prefix style for bookkeeping PR titles The convention I introduced, "missing_docs bookkeeping: ", quietly contradicted create_pr's existing rule that docs PR titles carry a prefix. It also invented a third naming shape in a change whose whole point is that two competing shapes are what let #614 and #624 miss each other. "chore(missing_docs): bookkeeping for " matches the shape #614 already used, matches the repo's conventional-commit practice, and still carries both terms the documented search keys on -- verified against #614, whose title has exactly this form and which the search finds. Co-Authored-By: Warp --- .agents/skills/missing_docs/SKILL.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/.agents/skills/missing_docs/SKILL.md b/.agents/skills/missing_docs/SKILL.md index f96a4a85..1d1fb9fb 100644 --- a/.agents/skills/missing_docs/SKILL.md +++ b/.agents/skills/missing_docs/SKILL.md @@ -444,10 +444,11 @@ their area. Do NOT bundle unrelated features into a single mega PR. Update its title and body to name them all. The one exception: if it is already approved and about to merge, wait for the merge and branch from the result. - For the search to find it, title every bookkeeping PR `missing_docs bookkeeping: - ` and name its branch `missing-docs/bookkeeping-`. #614 and #624 used - two different branch-naming schemes and neither run looked for the other's PR, which is - how both ended up adding the same two `/factory` map entries. + For the search to find it, title every bookkeeping PR `chore(missing_docs): bookkeeping + for ` and name its branch `missing-docs/bookkeeping-`. The title keeps + the repo's existing prefix style (see `create_pr` → Best Practices) while carrying both + search terms. #614 and #624 used two different naming schemes and neither run looked for + the other's PR, which is how both ended up adding the same two `/factory` map entries. - **API spec gaps stay separate** — released endpoints go through the `sync-openapi-spec` skill as their own change, never bundled into a feature PR. - **Validate once, then split.** Run `npm run build` on the combined working tree (all @@ -550,11 +551,11 @@ with the product. Each run: owner), each carrying its content design plan as a section in the PR body, plus the run's bookkeeping changes to `feature_surface_map.md`, `changelog_decisions.md`, `last_release_processed.json`, and `surface_snapshot.json`. Extend the open bookkeeping - PR if there is one; open a new one titled `missing_docs bookkeeping: ` only if - there is not. Use the `create_pr` skill: every drafting PR body opens with the required - `## What this feature does` summary, and every PR gets its owning reviewer requested - per step 7 before the run is done. Summarize remaining (deferred) findings in the - relevant PR body so nothing is silently dropped. + PR if there is one; open a new one titled `chore(missing_docs): bookkeeping for + ` only if there is not. Use the `create_pr` skill: every drafting PR body + opens with the required `## What this feature does` summary, and every PR gets its + owning reviewer requested per step 7 before the run is done. 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 @@ -588,7 +589,7 @@ Recommended scheduled-agent prompt (copy when setting up the agent): > opening a bookkeeping PR, search for an open one with gh pr list --state open --search > "missing_docs bookkeeping in:title" and extend that branch instead of opening a second; > two open bookkeeping PRs conflict on a snapshot that is regenerated wholesale. Title a -> new one "missing_docs bookkeeping: ". +> new one "chore(missing_docs): bookkeeping for ". > Request the resolved owner as reviewer on every PR with gh pr edit --add-reviewer, > falling back to dannyneira when nothing resolves, and verify the requested-reviewers > list is non-empty before you finish — a PR with no requested reviewer is an incomplete From aae1f6575d515cb2703ccbf85c7e61ab467ac83b Mon Sep 17 00:00:00 2001 From: "warp-agent-staging[bot]" <240773466+warp-agent-staging[bot]@users.noreply.github.com> Date: Tue, 25 Aug 2026 20:18:28 +0000 Subject: [PATCH 3/3] missing_docs: restrict bookkeeping-PR search to avoid self-match The gh pr list --search "missing_docs bookkeeping in:title" query ANDs the two words anywhere in the title, so it also matches this rule-only PR's own title ("...keep at most one bookkeeping PR open"). The next drift-watch run would then check out and extend this PR's branch instead of a real bookkeeping PR. Restrict the search to the quoted "bookkeeping for" phrase, which matches the canonical and legacy bookkeeping-PR titles but not this PR's title, and add reviewDecision to the output so the already- approved exception can be applied without a second query. Apply the same corrected query to the recommended scheduled-agent prompt. Co-Authored-By: Warp --- .agents/skills/missing_docs/SKILL.md | 37 ++++++++++++++++++---------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/.agents/skills/missing_docs/SKILL.md b/.agents/skills/missing_docs/SKILL.md index 1d1fb9fb..eb115ceb 100644 --- a/.agents/skills/missing_docs/SKILL.md +++ b/.agents/skills/missing_docs/SKILL.md @@ -434,21 +434,29 @@ their area. Do NOT bundle unrelated features into a single mega PR. before opening yours: ```bash - gh pr list --state open --search "missing_docs bookkeeping in:title" \ - --json number,headRefName,title + gh pr list --state open --search '"bookkeeping for" in:title' \ + --json number,headRefName,title,reviewDecision ``` - If one exists, check out its branch and add this run's map entries and ledger rows on - top, then re-run `check_new_release.py --commit` and `--update-snapshot` there so the - marker and snapshot stay a single regen covering every release the PR now carries. - Update its title and body to name them all. The one exception: if it is already approved - and about to merge, wait for the merge and branch from the result. + Match on the quoted phrase, not the two words separately. An unquoted + `missing_docs bookkeeping in:title` search ANDs the two words anywhere in the title, so + it also matches this rule-only PR's own title ("...keep at most one bookkeeping PR + open") — the next run would then check out and extend this PR's branch instead of a real + bookkeeping PR. + + If one exists and `reviewDecision` is not `APPROVED`, check out its branch and add this + run's map entries and ledger rows on top, then re-run `check_new_release.py --commit` and + `--update-snapshot` there so the marker and snapshot stay a single regen covering every + release the PR now carries. Update its title and body to name them all. The one + exception: if `reviewDecision` is already `APPROVED` (it's about to merge), wait for the + merge and branch from the result instead of extending it. For the search to find it, title every bookkeeping PR `chore(missing_docs): bookkeeping for ` and name its branch `missing-docs/bookkeeping-`. The title keeps - the repo's existing prefix style (see `create_pr` → Best Practices) while carrying both - search terms. #614 and #624 used two different naming schemes and neither run looked for - the other's PR, which is how both ended up adding the same two `/factory` map entries. + the repo's existing prefix style (see `create_pr` → Best Practices) while carrying the + `bookkeeping for` phrase the search matches on. #614 and #624 used two different naming + schemes and neither run looked for the other's PR, which is how both ended up adding the + same two `/factory` map entries. - **API spec gaps stay separate** — released endpoints go through the `sync-openapi-spec` skill as their own change, never bundled into a feature PR. - **Validate once, then split.** Run `npm run build` on the combined working tree (all @@ -587,9 +595,12 @@ Recommended scheduled-agent prompt (copy when setting up the agent): > its body, plus the bookkeeping changes to feature_surface_map.md, > changelog_decisions.md, last_release_processed.json, and surface_snapshot.json. Before > opening a bookkeeping PR, search for an open one with gh pr list --state open --search -> "missing_docs bookkeeping in:title" and extend that branch instead of opening a second; -> two open bookkeeping PRs conflict on a snapshot that is regenerated wholesale. Title a -> new one "chore(missing_docs): bookkeeping for ". +> '"bookkeeping for" in:title' --json number,headRefName,title,reviewDecision — the quoted +> phrase, not the two words separately, so the search doesn't also match this rule-only +> PR's own title. Extend that branch instead of opening a second, unless reviewDecision is +> already APPROVED, in which case wait for the merge and branch from the result; two open +> bookkeeping PRs conflict on a snapshot that is regenerated wholesale. Title a new one +> "chore(missing_docs): bookkeeping for ". > Request the resolved owner as reviewer on every PR with gh pr edit --add-reviewer, > falling back to dannyneira when nothing resolves, and verify the requested-reviewers > list is non-empty before you finish — a PR with no requested reviewer is an incomplete