overviewdocs/REVIEW-SWEEP.md

The review sweep, and which tickets it is asking about

Which tickets the sweep is asking about

The review sweep

OPS-149. The owner asked for this on 2026-09-17:

And I think each ticket should have, like, a last reviewed on, like, a date that it was last reviewed. So maybe now we do, like, a sweep, but maybe from here, we say, like, if a ticket was lying around for, like, a certain amount of time, then we revise it and keep it, like, a parameter that we can play with. Um, but I think, like, ten days, two weeks sounds reasonable to me. maybe it start even less.

Everything below the marker is generated by python3.12 scripts/check_ticket_lifecycle.py --write. It is a function of the clock, so it is the one generated document in this repository that make doc-gates does not drift-check - a --check on it would go red every midnight and teach everybody to ignore the gate. It carries its own as of date instead, and a reader judges its age by reading it. Re-run the generator rather than quoting this file from memory.

The three things the owner asked for, and where each one lives

he asked forit iswhere
a terminal status, so a finished ticket can be filtered outalready there, three times over: merged, accepted, withdrawn. done is a retired spelling on purposebacklog/schema.toml, the [[status]] blocks and [retired.status]
tickets not deleteda gate that did not exist. Four ticket ids have left the registerscripts/check_ticket_lifecycle.py --ever and --deletions
last_reviewed_on, and a sweep with a threshold he can play witha new optional field, seeded from each ticket's filing datethe field in backlog/schema.toml, the sweep below

No status was added. CLAUDE.md forbids a second name for something that has one, and the ask was about filtering and about enforcement rather than about a missing word. What merged and accepted already do, gen_state.py's stage_of already reports: unbuilt, built, closed, so a terminal ticket drops out of every count a planner reads while its file and its id stay exactly where they are.

Four ids have left the register, and no subject has

python3.12 scripts/check_ticket_lifecycle.py --ever, on 2026-09-17: 513 ids ever written, 510 now, 4 gone. Thirteen ticket files were deleted across seven commits between 2026-09-12 and 2026-09-16. The two counts differ because most of those deletions replaced a file in place, and an id is what the register is keyed on.

idwhat happenedwhere the subject went
ADAPT-003deleted at af2404ab, "drop five duplicate tickets, keep three"CORE-019, the uncalled adapter layer
CORE-020deleted in the same commitbacklog/cli/export-claims-matches-a-bare-name.md
CORE-021renumbered to CORE-034 in the same commit, same fileCORE-034
OPS-065renumbered to OPS-068 during an id collision on 2026-09-13OPS-068

So the answer to "I hope we haven't" is: we have, thirteen times, and no subject was lost - each deletion folded its content into a surviving ticket or replaced a reserved stub. Two costs remain and neither is recoverable by a gate:

--deletions is the half that is cheap enough to run every build. It compares against the merge base with the trunk rather than against the trunk itself, because main moves about 170 times in two days here and an id it gained after a branch was cut would otherwise read as that branch deleting one.

<!-- BEGIN GENERATED review-sweep -->

<!-- Generated by check_ticket_lifecycle.py --write. As of 2026-09-17. -->

As of 2026-09-17, at a threshold of 10 days and a limit of 20: 0 of 247 reviewable tickets are eligible, 0 of them because nothing has ever recorded a review.

Reviewable means unbuilt. A merged, accepted or withdrawn ticket is not in the pool, which is the owner's "then it can easily filter them out" and needed no new status to do - scripts/gen_state.py's stage_of already answers it from the schema.

What each row is asking for

Three verdicts, and two of them are an edit to the ticket:

verdictwhat it meanshow it is recorded
keepit still matters, as writtenpython3.12 scripts/check_ticket_lifecycle.py --reviewed <ID>
re-scoreit matters differently nowedit value, urgency, importance, then python3.12 scripts/score.py --check
retireit will not happen, or it already didstatus: withdrawn with a reason - or merged/accepted if the work landed. Never delete the file

OPS-150 is the open question behind the second one: nothing in this repository recomputes a score, so re-scoring today is a person re-asserting a number.

When the queue arrives

Every ticket in this backlog was filed between 2026-09-11 and 2026-09-17, so seeding last_reviewed_on from the filing date moves the queue rather than spreading it. This is the table to read before changing the threshold.

datenewly eligibleeligible in total
2026-09-1700
2026-09-1800
2026-09-1900
2026-09-2000
2026-09-2100
2026-09-2299
2026-09-238089
2026-09-2438127
2026-09-2537164
2026-09-2641205
2026-09-2734239
2026-09-288247
2026-09-290247
2026-09-300247
2026-10-010247

--limit is why that is survivable. The sweep asks for 20 decisions, oldest first, and recording them is what makes tomorrow's list different.

The head of the queue, 20 of 247

Ordered by age of review, then by derived priority. The eligible column is where the 10-day threshold falls, so moving the parameter moves a line through this one table rather than producing a different one - which is the only way to see what a threshold is worth before choosing it.

never in the last-reviewed column would mean no review has ever been recorded. Nothing shows it today because --seed gave all 247 of these their filing date, which is the date somebody last asserted the ticket mattered - see backlog/schema.toml.

ticketeligibleprioritystatuslast reviewedagethe decision
DOC-001not yetP1pending2026-09-116dkeep, re-score, or withdraw
DOC-004not yetP1pending2026-09-116dkeep, re-score, or withdraw
OPS-004not yetP2pending2026-09-116dkeep, re-score, or withdraw
OPS-006not yetP2pending2026-09-116dkeep, re-score, or withdraw
COMP-006not yetP3pending2026-09-116dkeep, re-score, or withdraw
COMP-007not yetP3pending2026-09-116dkeep, re-score, or withdraw
CLI-002not yetunscoredunscoped2026-09-116dno reason and no scores: scope it, or withdraw it
COMP-002not yetunscoredunscoped2026-09-116dno reason and no scores: scope it, or withdraw it
COMP-004not yetunscoredunscoped2026-09-116dno reason and no scores: scope it, or withdraw it
CORE-040not yetP0pending2026-09-125dkeep, re-score, or withdraw
CORE-043not yetP0pending2026-09-125dkeep, re-score, or withdraw
OPS-038not yetP0in_progress2026-09-125dis anybody still on this? (no branch named) - if not, back to pending or withdraw
COMP-014not yetP1pending2026-09-125dkeep, re-score, or withdraw
COMP-016not yetP1pending2026-09-125dblocked on unbuilt COMP-077: keep, or withdraw as overtaken
COMP-019not yetP1pending2026-09-125dkeep, re-score, or withdraw
COMP-020not yetP1pending2026-09-125dkeep, re-score, or withdraw
COMP-022not yetP1pending2026-09-125dkeep, re-score, or withdraw
COMP-026not yetP1pending2026-09-125dkeep, re-score, or withdraw
COMP-031not yetP1pending2026-09-125dkeep, re-score, or withdraw
CORE-010not yetP1pending2026-09-125dkeep, re-score, or withdraw

python3.12 scripts/check_ticket_lifecycle.py --limit 100 prints more of it, and --threshold 5 is the parameter moved to the number the owner guessed at when he said "maybe it start even less".

<!-- END GENERATED review-sweep -->