agentleFS
gutohuidagutohuida/AgentWeave/.claude/skills/backlog/SKILL.md

backlog

Skill4 starsChanged 2 months agoApache-2.0View on GitHub

Regenerate spec-queue/BACKLOG.html — the standing, interactive orientation page merging open findings and operator requests, each tagged with where it came from (found by driving, found by reading code, or asked for by the operator), whether it is ready to work, and its theme. Reports what moved since the last generation and triages the ledger's own inconsistencies. Use when the user says "update the backlog", "refresh the backlog page", "regenerate BACKLOG.html", "what's open", "how many findings are open", "what is the backlog", "add this to the backlog", or after anything that changes the ledger — filing a finding, closing one, proposing a change, archiving a change, or a loop window finishing. Callable by the FILL and FIX windows as step 0.

39 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use issue, worktree and 9 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • AWSSkill

    issue

    Implement a GitHub issue end-to-end — branch, code, test, docs, and commit.

    Also in 3 projects that use this

  • MicrosoftSkill

    worktree

    Create, reuse or clean up a dedicated git worktree for working on a pull request or a private branch. Use from any PR-scoped workflow that needs an isolated checkout to keep current code and build output untouched.

    Also in 3 projects that use this

  • AWSSkill

    retro

    Conduct a retrospective on a coding session.

    Also in 4 projects that use this

  • HashiCorpSkill

    changelog

    Add a `.changelog/<PR_NUMBER>.txt` entry for a GitHub Pull Request, commit, and push.

    Also in 3 projects that use this

  • BlockSkill

    plan

    Draft a TDD, PRD, or lightweight plan in the conversation without committing it.

    Also in 4 projects that use this

  • VercelSkill

    deploy

    Deploy applications to Vercel. Use when the user says "deploy", "deploy to Vercel", "push to production", "deploy my app", or "go live".

    Also in 3 projects that use this

The file

We split this skill into the rules it gives an agent

6 rules. 0 are common, 0 are distinctive, and 6 are very specific to this project.

  • 0

    Common

    Most of the 38 edited versions we read keep these.

  • 0

    Distinctive

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    When you file a finding whose provenance you know, write the Source: and Theme: lines in rather than leaving them to inference.

    line 47
  2. Very specific:

    After any edit: py -3.11 scripts/backlog_page.py and check the printed report still makes sense.

    line 133
  3. Very specific:

    If the only difference is the generated stamp and the HEAD sha — which --check will have reported as current — there is nothing worth …

    line 212
  4. Very specific:

    Nothing fires while the operator is logged out: All tasks run as an interactive logon, because gh's keyring and the Claude credentials only …

    line 241
  5. Very specific:

    Run Get-ScheduledTask -TaskName "AgentWeave*" | Get-ScheduledTaskInfo to see what is armed and what fired last.

    line 253
  6. Very specific:

    Before proposing anything: run --check and read the report.

    line 277

“Common” is measured: kept by at least 6 in 10 of the 38 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Regenerate the backlog page and say what changed. The page is derived, never authored.

The one rule

Never edit spec-queue/BACKLOG.html by hand. It is generated from scripts/drive/FINDINGS.md, spec-queue/REQUESTS.md, openspec/changes/, spec-queue/ and the two STATE-*.json. A hand edit is lost on the next generation and, worse, makes the page disagree with the ledgers it claims to summarise — which is the exact failure night-window.md names: "a backlog that cannot say what is done is read as a backlog of everything." If the page is wrong, the fix is in scripts/backlog_page.py or in the source ledger, never in the HTML.

The two ledgers it merges

scripts/drive/FINDINGS.mddefects. Something the product does wrong, with a reproduction. Severity A/B/C/D.
spec-queue/REQUESTS.mdwhat the operator asked for. Not a defect — work wanted because they want it. R<n> ids.

They are separate files on purpose: filing a request as a finding makes it pretend to be a defect, and filing a defect as a request hides it from the night window's severity queue.

A request that names a Finding: does not become its own row. It re-sources that finding as operator-originated and lends it the operator's own words. That is what stops an ask which has already been measured into a finding from being counted twice. When the operator asks for something new, add a request section — REQUESTS.md documents the format, and nothing else is required.

The three columns the page adds

Neither ledger states these; the generator derives them, and each has an escape hatch.

  • Source — operator · drive · audit · review · unknown. Inferred by scoring the Status line and the body, because for most of the corpus the Status line records fix state ("open (no fix commit references it)") and says nothing about how the finding was found. A **Source:** <value> line in the body overrides it.
  • Ready — proposed · ready · parked · triage · thinking. proposed is computed, never claimed: a live change directory naming the F-number is the only thing that sets it, and it is the column that says whether the night window could actually build the item. A **Ready:** line overrides.
  • Theme — keyword-scored into twelve groups. A **Theme:** line overrides. A wrong guess costs a reader one glance, which is why this is a reading aid and not a taxonomy.

When you file a finding whose provenance you know, write the **Source:** and **Theme:** lines in rather than leaving them to inference. Inference is for the 373 findings that predate them.


Putting something ON the backlog

Three different things, three different files. Nothing goes into BACKLOG.html directly.

The operator asked for something → spec-queue/REQUESTS.md

Append a section. Nothing else is required, and no field is mandatory except the heading.

## R<n> — <one line, in their words>
**Asked:** YYYY-MM-DD
**Theme:** Flows & loops
**Ready:** thinking
**Finding:** F377

<Quote them. Their phrasing is the point — it is what the page shows.>
  • Next R<n>:
    py -3.11 -c "import re;t=open('spec-queue/REQUESTS.md',encoding='utf-8').read();print(max(int(n) for n in re.findall(r'^##\s*R(\d+)',t,re.M))+1)"
    Take the maximum + 1, never a count — grep -c '^## R' also matches the ## R<n> line in this file's own format example and hands you a number that is already taken.
  • Finding: whenever the ask is already measured into a finding. That re-sources the finding as operator-originated instead of creating a duplicate row. Getting this wrong is the one way to double-count the backlog.
  • Ready: — thinking (default, no criticism), ready (a spec loop could take it), proposed (a change directory exists).
  • Quote the operator rather than paraphrasing. A request is theirs; the page shows the quote.

You found a defect → scripts/drive/FINDINGS.md

Append a section. The heading form is load-bearing — the generator parses it.

## F<n> (A) — <one line saying what is wrong, not what to do about it>

**Status:** open. Filed YYYY-MM-DD by <who>, from <where>.
**Source:** drive
**Theme:** Task ledger

**What happened.** …
**Where.** file:line for each claim.
**Related:** F<n>, F<n>
  • Next F<n>:
    py -3.11 -c "import re;print(max(int(n) for n in re.findall(r'^##\s*F(\d+)',open('scripts/drive/FINDINGS.md',encoding='utf-8').read(),re.M))+1)"
  • Severity in the parenthetical: A wrong behaviour an operator will act on · B wrong or misleading surface · C friction or vestige · D minor. Omit it and the finding lands in the page's ? group and the night window's severity queue can never reach it.
  • A **Status:** line is not optional. Without one the generator counts the finding as open forever and warns about it, which is how the open number drifts upward.
  • Search before filing. --check first, then grep the ledger for the symptom. Two of the four findings filed on 2026-09-17 were re-discoveries of three-day-old rows.

Something got fixed or decided → edit the row in place

Set **Status:** fixed <sha> on the finding, or **Ready:** on the request. Do not delete rows — a retired finding stays, marked RETIRED <date> in its title, and the page excludes it from the counts while keeping it findable.


Changing what the page SHOWS → scripts/backlog_page.py

Different job from putting something on the backlog. The page's columns, themes, grouping, filters and warnings all live in the generator:

WantEdit
a new theme, or a theme that classifies badlyTHEMES — keyword tuples, scored against title (×3) and body (×1)
provenance guessed wrong across many rows_DRIVE_WORDS / _AUDIT_WORDS / _REVIEW_WORDS, or add a **Source:** line to the one row
a new readiness stateREADY, and classify_ready
a new ledger warningconsistency_warnings
layout, filters, interactionTEMPLATE — one f-string; CSS and JS braces must be doubled ({{/}})
a new figure or snapshot fieldbuild()'s snapshot dict and the TEMPLATE.format(...) call, together

After any edit: py -3.11 scripts/backlog_page.py and check the printed report still makes sense. The page is ~300 KB, so validate structure with a parser rather than by reading it.


Step 1 — Regenerate

py -3.11 scripts/backlog_page.py

py -3.11, never bare python — the bare interpreter here is a venv that behaves differently (CLAUDE.md, Testing).

It prints three blocks: the file it wrote, SINCE LAST GENERATION, and LEDGER WARNINGS.

Two other modes:

--checkreports without writing; exit 1 if the ledger has moved since the page was built. Compares the data, not the rendered bytes — the timestamp changes every run, so a byte comparison would always say stale.
--quietwrites and prints only the path. For a caller that wants the side effect, not the report.

Step 2 — Read the delta out loud

SINCE LAST GENERATION is the part the operator actually wants. Report it in your own words, and say plainly when nothing moved — "nothing moved since the last generation" is a real answer and a useful one, not a failure to find something.

Two lines deserve comment rather than restatement:

  • newly filed: F… — name what they are, not just their numbers. The operator asked for a backlog, not a diff.
  • unbuilt changes changed — this is the throttle. Say what it means for tomorrow: 2 or more → no spec loop runs at all, 1 → one loop, 0 → two loops. A drain that just went from 1 to 2 silently cancels tomorrow's proposing, and nothing else announces that.

Step 3 — Triage the warnings; do not just repeat them

LEDGER WARNINGS is the script noticing things it cannot resolve. None is conclusive alone. Decide which, if any, is worth the operator's attention now:

WarningWhat it usually meansAct on it when
N findings have no **Status:** lineOld entries predating the convention. They are counted as open, so they inflate the open number.The count grew — a window filed something and forgot the Status line.
N findings declare no severity anywhereSame vintage. The night window orders by severity, so an unrated finding is never reached by the A-before-B-before-C queue.One of them is recent, or the operator is asking why something is never picked up.
N findings read 'open' but name a commit shaThe classic stale row: fixed, and the Status line never updated. This is the single most likely reason the open count is too high.Always worth mentioning. Never "fix" it by editing the Status line on a hunch — verify against the code first, the way the night playbook's status sweep does.
unbuilt change carries a STOPPED note and still counts toward the drainA change was abandoned mid-flight but its unticked tasks still throttle the spec loop.Always mention — it is suppressing proposing for a change nobody intends to build.

Do not repair the ledger from inside this skill unless the user asks. Reporting that 24 rows may be stale is useful; rewriting 24 Status lines without verifying each against the code is how the ledger became untrustworthy in the first place. If they want the sweep, that is real work with a verification step per row, not a side effect of refreshing a page.


Step 3b — Refresh the rounds tracker, in an interactive session

spec-queue/ROUNDS.md is the operator's round-by-round plan for the B/C/D findings, and spec-queue/ROUNDS.html tracks it from the same ledger. After a regeneration that closed anything, run py -3.11 scripts/rounds_page.py too, and commit ROUNDS.html with BACKLOG.html. The unattended windows skip this step: C and D are drained by operator-guided sessions only (DECISIONS.md, the scope footnote of 2026-09-22).

Step 4 — Commit, if the page changed

The page is tracked, so a regeneration is a real diff. Commit it with whatever prompted the refresh rather than on its own where possible — a commit that only bumps a timestamp is noise.

git add spec-queue/BACKLOG.html

Stage explicitly. Never git add -A in this repo (CLAUDE.md, Critical rules).

If the only difference is the generated stamp and the HEAD sha — which --check will have reported as current — there is nothing worth committing. Say so and leave the tree alone.


When the windows run

The backlog is read and written by two unattended windows and one person. Knowing the clock matters here, because "call it at close" and "step 0" mean nothing without it, and because a refresh at the wrong moment reports a ledger someone else is mid-way through changing.

07:10  AgentWeaveResearch    reads the web, outside the repo
08:55  AgentWeaveArmDay      arms the day — settles the branch, writes STATE-day.json, registers DayLoop
09:00  ├─ FILL   ──────────┐ AgentWeaveDayLoop, every 5 min, PROPOSES (never implements)
17:00  ┘                   │ unregisters itself
17:00  ├─ DECIDE ──────────┐ the operator. Writes APPROVALS.md, the only file FIX reads
23:00  ┘                   │
22:55  AgentWeaveArmNight    arms the night, same shape
23:00  ├─ FIX    ──────────┐ AgentWeaveNightLoop, every 5 min, BUILDS (never proposes)
07:00  ┘                   │ unregisters itself
07:00–09:00  margin
  • The two working loops are transient by design. Each driver unregisters itself at its stop time; that is what stops a dead loop firing forever. Only the three arming tasks are permanent.
  • Each arm fires five minutes before its window. install-tasks.ps1 is the authority for those times, not this file and not the live Task Scheduler — the live ArmDay trigger had drifted to 10:15 and silently cost three days of FILL windows (F380).
  • Nothing fires while the operator is logged out. All tasks run as an interactive logon, because gh's keyring and the Claude credentials only resolve there.
  • Both windows run --check as step 0 of iteration 1 — the first firing only — and again at close, before the final log entry.

Practical consequences for this skill:

  • During FILL or FIX, a window may be committing while you read. Check git status --porcelain before committing a regenerated page; if a window is mid-iteration, say what the page shows and let the window commit its own refresh.
  • The best moment to refresh is DECIDE (17:00–23:00): both loops are stopped, the night's work is in, and the operator is deciding from exactly this page.
  • Run Get-ScheduledTask -TaskName "AgentWeave*" | Get-ScheduledTaskInfo to see what is armed and what fired last. A State of Running on a *Loop task means a window is live right now.

Callable interface

Other skills and the loop windows may invoke this:

skill: "backlog"                    regenerate, report, offer to commit
skill: "backlog", args: "--check"   report only; non-zero exit means the ledger moved

Both windows run --check as step 0 of iteration 1 (day-window.md, night-window.md). It is one tool call and it stops the two failures this loop keeps having: filing something already filed, and queueing a finding that has no proposal and therefore cannot be built.

Never cat the HTML. It is ~300 KB and reading it burns the context the iteration needs. The printed report is the interface; the page is for the operator's browser.

Call it again at close, after the last queue item and before the final log entry — the window has just changed the ledger, and the delta belongs in the log.

Before proposing anything: run --check and read the report. Two of the four findings filed on 2026-09-17 turned out to be re-discoveries of F361 and F363, caught only because the ledger was searched first — and they were three days old.

What the operator gets in the browser

Worth knowing, because it changes what is worth saying in chat. The page is interactive: filter chips for source / ready / severity, a text filter over id, title and theme, a group-by toggle between theme and severity, and collapsible groups. Groups are closed at rest and open automatically while a filter is live — a 217-row page that opened flat was 17,000px of wall.

So do not read long lists out loud. Give them the delta, the warnings that matter, and let the page carry the enumeration.


Where the page lives

spec-queue/BACKLOG.html          the page — open it in a browser
spec-queue/REQUESTS.md           what the operator asked for; add asks here
scripts/drive/FINDINGS.md        defects; add findings here
scripts/backlog_page.py          the generator — edit this, not the page
spec-queue/README.md             the spec-queue contract, including this file's row

The page embeds its own counts as JSON in <script type="application/json" id="backlog-data">. That is what the next run compares against, and what any other tool should read rather than scraping the rendered numbers.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.