keep-the-pool-full

$npx mdskill add github/lever/keep-the-pool-full

Once implementation, review and merging are automated, the bottleneck moves upstream to supply. Agents with nothing well-defined to pick up either sit idle or invent work. This skill keeps a pool of issues that an agent can take, finish and land on its own: each one is real, independently mergeable, small, checkable and not a duplicate. The human job shifts from "build X" to setting the pool's target and its sources.

SKILL.md

.github/skills/keep-the-pool-fullView on GitHub ↗
---
name: keep-the-pool-full
user-invocable: false
description: Backlog steward that keeps a pool of ready, independently mergeable issues above a target by mining real sources (failing tests, TODOs, gaps, audits, user reports), deduplicating, sizing and labeling them ready. It files issues, so it runs only on `/lever backlog`, inside a delivery run whose idle policy is refill, on a schedule the user set up, or on an explicit ask ("file more issues", "keep them busy", "fill the backlog", "we have nothing to do").
---

# keep-the-pool-full

Once implementation, review and merging are automated, the bottleneck moves upstream to supply. Agents with nothing well-defined to pick up either sit idle or invent work. This skill keeps a pool of issues that an agent can take, finish and land on its own: each one is real, independently mergeable, small, checkable and not a duplicate. The human job shifts from "build X" to setting the pool's target and its sources.

## When to use

- The count of ready issues is below the target, or will be within a day at current throughput.
- A delivery loop or a set of worker automations reports `NOOP(no eligible work)` repeatedly.
- On a schedule (daily, or every few hours during an active run).

## When not to use

- No one or nothing is consuming the pool. Filing issues nobody picks up is noise.
- The work needs product decisions that haven't been made. File one decision issue for a human instead.
- The repo's maintainers haven't agreed to agent-filed issues. Ask once; on other people's repos default to `DRY_RUN`.

## Steps

1. **Measure the pool.** Count open issues matching `POOL_QUERY` (default `is:open is:issue label:ready no:assignee`). Measure consumption: ready issues closed or assigned per day over the last 7 days. Pool coverage = pool size / daily consumption, in days.
2. **Decide whether to file.** If coverage ≥ `TARGET_DAYS`, end `NOOP(pool healthy: N issues, C days)` and post nothing. Otherwise the deficit is `ceil(TARGET_DAYS × consumption) − pool`, capped at `MAX_FILED_PER_RUN`.
3. **Mine sources, in `SOURCES` order.** Each candidate must cite evidence a reader can check:
   - failing or quarantined tests, and flake-tracking issues;
   - `TODO`/`FIXME` with an owner-free, local fix;
   - gaps between a spec, doc or reference implementation and the code;
   - audit and report outputs (perf, accessibility, security, dependency) already in the repo or its issues;
   - user reports that are confirmed but lack an actionable task;
   - follow-ups promised in merged PR descriptions or review replies.
4. **Shape each candidate into an issue** using the checklist below. Split anything over `SIZE_CAP` into independent issues, not a dependency chain. If a candidate can't be made independently mergeable, drop it or file it as one human-decision issue.
5. **Deduplicate.** Search open and recently closed issues and open PRs for the same file, symbol, test name or error string. Embed a source fingerprint in the body (`<!-- pool-source: <kind>:<path-or-test>:<hash> -->`) and search for it before filing. If a match exists, comment the new evidence on it once (if allowed) instead of filing.
6. **File and label.** Create the issue with `READY_LABEL` and the area label. Never assign it; consumers claim work by assignment or linked PR.
7. **Report.** One line per run: `pool: before → after (target T, coverage C days), filed n, skipped-duplicate d, dropped k`. Silent when nothing was filed.

### Issue-quality checklist

- **Title** says the change, not the symptom ("Make X cache key include Y", not "X is slow").
- **Why**: one sentence plus the source evidence link (test run, file and line, report, user issue).
- **Done when**: an observable acceptance check, ideally a command or test that fails now and passes after. If you can't write one, the issue isn't ready.
- **Loop**: how the implementer verifies it (see `find-the-loop`).
- **Scope hint**: the files or area likely touched, and what is out of scope.
- **Size**: expected diff under `SIZE_CAP`; one PR; no ordering dependency on other open issues.
- **Safety**: no secrets, credentials, internal links or personal data copied from the source.

## Dials

| Dial | Default | Options |
|---|---|---|
| `POOL_QUERY` | `is:open is:issue label:ready no:assignee` | Any issue search |
| `TARGET_DAYS` | 2 days of consumption | Integer; or a fixed count |
| `MAX_FILED_PER_RUN` | 5 | Integer; keep low until the invalid rate is known |
| `SIZE_CAP` | One PR, about 200 changed lines | Lines or files |
| `SOURCES` | tests, todos, gaps, audits, reports, follow-ups | Any subset, in priority order |
| `READY_LABEL` | `ready` | Repo label |
| Mode | `file` on repos you own; `dry_run` elsewhere | `dry_run` (write a candidate list only), `file` |
| Autonomy | L0 (issues only) | This skill never writes code; see [docs/autonomy.md](../../docs/autonomy.md) |

## Running it as an automation

Use `automate-it`. Trigger: `interval: daily` (or `hourly` during an active delivery run). Tools: `github/search_issues`, `github/search_pull_requests`, `github/issue_read`, `github/get_file_contents`, `github/search_code`, `github/actions_list`, `github/get_job_logs`, `github/list_label`, `github/create_issue`, `github/update_issue_labels`, plus `github/add_issue_comment` if dedupe-comments are on. `write_scope: repository` (there is no triggering resource). Create it paused and dry-run it once; read the candidate list before enabling.

## Outputs

- New issues labeled ready, each with evidence, acceptance check, loop and size.
- A per-run line in the run summary or ledger.

## This skill's own feedback loop

Track weekly, per source:
- **Pick-up rate**: filed issues claimed within `TARGET_DAYS`.
- **Merged-per-filed**: filed issues closed by a merged PR.
- **Invalid rate**: filed issues closed as not planned, duplicate or invalid. Above 20% for a source → tighten or drop that source.
- **Pool coverage** over time. If the pool drains to zero every day, raise `TARGET_DAYS` or `MAX_FILED_PER_RUN`; if issues age past 14 days unclaimed, lower them.

## Failure modes it prevents

- Idle workers, or workers inventing their own work.
- Big, coupled issues that stall review and CI.
- Duplicate issues from multiple agents mining the same failure.
- "Ready" issues with no way to tell when they're done.

## Why this exists

- In one unattended delivery loop, once implement, review and merge were automated, supply became the bottleneck. The human's prompts shifted from "build X" to "file real, independently mergeable issues and keep the pool full."
- "The answer can never be that we have nothing to do": idle was fixed with a standing backlog, not with more agents.
- Small, independently mergeable units are what let review, CI and merge keep up without a human; large units stalled.
- A backlog curation job run every 30–60 minutes also served as recovery memory when the coordinating session went down.

More from github/lever

SkillDescription
automate-itTurns a task you keep doing by hand into a paused GitHub Copilot Automation with an event trigger, a least-privilege tool list, a PARAMETERS + CONTRACT prompt, a quiet exit and a propose-only improver sibling. It creates automations, so it runs only on `/lever automate` or an explicit ask ("automate this", "run this on every PR/issue", "do this nightly", "make this run in the cloud"). When the same task has been done 3 or more times by hand, or a local self-wake has fired 5 or more times for the same job, suggest it in one line instead of running it.
autonomous-deliveryRuns long-lived delivery as a coordinator with parallel lanes. Sets authority and pacing dials up front, keeps lanes alive and fed, lands work through a single-writer release train, and reports status only when something changed. Runs only on `/lever deliver`, "/autonomous-delivery" or an explicit request to run multi-hour, overnight or multi-lane delivery ("run this overnight", "keep N streams going", "don't stop until it ships"), or to re-arm an existing run after a restart.
autonomy-dialResolves how far an agent may take a change, from L0 propose to L5 release. It reads the repo's real GitHub rules (rulesets, branch protection, CODEOWNERS, merge queue) and `.github/lever.yml`, applies per-path and per-class limits, records every grant verbatim with its source and expiry, and exposes a `may_merge` check that delivery skills call before landing anything. Use when a delivery skill or automation starts, when creating an automation, before any merge or enqueue, or when the user says "merge", "ship it", "land it", "then merge", "hand off", "do not merge", "freeze" or "you can merge X".
briefTurns a short intent, often around 20 words, into a brief that can run unattended. The brief has the user's words verbatim, an outcome owner, an observable done-when, a feedback loop, constraints and neighbors, a budget, an autonomy level, an absence window, stop conditions and a report contract. Runs only on `/lever brief`, when another lever skill delegates, or on an explicit request to write a brief or hand work off ("kick off", "spin up", "hand this to", "while I'm asleep", "I'll be away"). It files issues, so it never runs just because work is happening in parallel.
cross-model-reviewReviews a PR, diff, plan or skill with 2–3 models from different providers working blind and independently, and surfaces only the findings they agree on or that survive a contradiction-first proof; a precision mode runs one automated reviewer that posts at most two proven findings and stays silent otherwise. Use when asked to "review this with opus, codex and gemini", "rubber duck this plan", "second opinion", "only show me issues the models agree on", when a plan is about to drive a day or more of work, when work has been stuck for hours, or when setting up review-on-ready automation.
experiment-armsRuns many single-hypothesis "arms" as do-not-merge PRs, measures each with paired, interleaved runs against a cost-matched control, keeps only the arms that clear a keep bar set in advance, records every negative, and composes the winners into a stack that is re-measured on real traffic after merge. It opens PRs and burns CI, so it runs only on `/lever arms` or an explicit ask to measure ideas ("which of these ideas actually helps?", "is this change worth it?", "try that tip I saw", "run arms on this") for a CI, perf, eval, benchmark or cost hill-climb where the system can be run on demand.
find-the-loop>-
landing-planTurns a set of open PRs into a merge plan. It maps their dependencies, puts the PRs into merge-queue batches with strict order only where they overlap, and writes a hand-off with evidence for each PR. At L2 it gives the plan to the human who will merge; at L4 it enqueues the PRs itself. It can enqueue, so it runs only on `/lever land`, a hand-off from a lever coordinator, or an explicit ask ("what order should these merge in", "land the stack", "why is landing taking all day").
leverThe one lever command. `/lever <verb> [args]` runs a lever skill directly (loop, arms, review, brief, deliver, refactor, backlog, shepherd, land, status, automate, health, mirror, steer, autonomy, spend, setup, help). `/lever <plain words>` picks the verb for you, says which in one line, then runs it. Also reads and writes the user's personal dials in `~/.copilot/lever.yml`. Use when the user types /lever, asks "which lever skill should I use?", or wants to see or change their autonomy or spend dial.
pr-shepherdDrives an open pull request to landed through an event-driven loop. On each wake it does one batched read, fixes root causes of red required checks, dispositions every review thread, and lands at the level set by the autonomy dial. It pushes and can merge, so it runs only on `/lever shepherd`, a hand-off from a lever coordinator, a PR labeled for shepherding, or an explicit ask ("monitor CI until green", "push fixes until green", "resolve the review threads", "merge when green", "babysit this PR", "shepherd #123").