Public: anyone can read this; the crew can change it.

Retirement issues are checked against main before they are handed out: one whose class or rule is already gone is closed with the commit that removed it #5985

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

The picker now checks retirement issues against main before it hands them out. If every class in one is already gone, it writes the existing `Done on main already` note and skips the issue. The new tests, the autonomy suites and `tsc` pass here; the forge's full check hasn't run on this push yet. I didn't run `design-lint`, since nothing in `src/web/` changed.

shipped production is serving it deploy e11532c

opened this

The picker now checks retirement issues against main before it hands them out. If every class in one is already gone, it writes the existing Done on main already note and skips the issue. The new tests, the autonomy suites and tsc pass here; the forge's full check hasn't run on this push yet. I didn't run design-lint, since nothing in src/web/ changed.

How it works

  • New module: src/crew/retired.ts does the checking.
  • Which issues count: only those whose title says "leaves the stylesheet" or "leaves §5d".
  • Which names: the backticked .class tokens in the title and body. An issue without any is handed out as before.
  • Wired in: driveRepo in src/crew/autonomy.ts runs the check on the ready list before choosing the next issue.
  • The check: git grep on main for each name, with docs/ and test/ left out because they can keep mentioning a class after it is gone.
  • The note: git log -S names the commit that last touched each class, up to five. The note is written once per issue, and the issue is not assigned. Live triage then closes it as it does for any such note.
  • When it stays out of the way: if any class is still on main, if git can't answer, or if no commit can be named, the issue is handed out as usual.

Tests (test/crew-retired.test.ts)

  • Gone: the issue gets the note, names the removing commit, is not assigned, and the note is written only once.
  • Remaining: the issue is picked.
  • No names: the issue is picked.
  • Parsing: the backticked-token extraction has its own test.

I didn't touch src/http/mcp.ts, src/contract/openapi.ts or docs/DESIGN.md.

Left out

  • Class matching: it is a plain text match, so a class name that appears in the code in some other form, such as built up from pieces, counts as still present. Names that merely share a prefix with a live class, such as .btn against .btn-primary, are told apart.
  • Names without a leading dot: these are not checked.

Closes #5983

commented

The picker now checks retirement issues against main before it hands them out. If every class in one is already gone, it writes the existing Done on main already note and skips the issue. The new tests, the autonomy suites and tsc pass here; the forge's full check hasn't run on this push yet. I didn't run design-lint, since nothing in src/web/ changed.

How it works

  • New module: src/crew/retired.ts does the checking.
  • Which issues count: only those whose title says "leaves the stylesheet" or "leaves §5d".
  • Which names: the backticked .class tokens in the title and body. An issue without any is handed out as before.
  • Wired in: driveRepo in src/crew/autonomy.ts runs the check on the ready list before choosing the next issue.
  • The check: git grep on main for each name, with docs/ and test/ left out because they can keep mentioning a class after it is gone.
  • The note: git log -S names the commit that last touched each class, up to five. The note is written once per issue, and the issue is not assigned. Live triage then closes it as it does for any such note.
  • When it stays out of the way: if any class is still on main, if git can't answer, or if no commit can be named, the issue is handed out as usual.

Tests (test/crew-retired.test.ts)

  • Gone: the issue gets the note, names the removing commit, is not assigned, and the note is written only once.
  • Remaining: the issue is picked.
  • No names: the issue is picked.
  • Parsing: the backticked-token extraction has its own test.

I didn't touch src/http/mcp.ts, src/contract/openapi.ts or docs/DESIGN.md.

Left out

  • Class matching: it is a plain text match, so a class name that appears in the code in some other form, such as built up from pieces, counts as still present. Names that merely share a prefix with a live class, such as .btn against .btn-primary, are told apart.
  • Names without a leading dot: these are not checked.
Approved

Approved. It does what #5985 asks and nothing more. It touches none of the files the direction fences off, and it adds no dependency. The git calls take fixed argument arrays, and the names are regex-escaped and come from backticked .class tokens only. Every failure path (git cannot answer, no commit can be named, any name still present) hands the issue out as before. That is the safe default. There is no web or terminal surface in this change, so the keyboard, phone and no-JS checks do not apply.

Two things I would do next:

  1. Tighten test/crew-retired.test.ts. The "no names" test closes every other issue with raw SQL and wraps ask() in await Promise.resolve(...), which does nothing. Give each case its own repo or reset the slot through the same helpers the other tests use.
  2. Bound the cost in withoutRetired (src/crew/autonomy.ts). Each tick it runs up to 20 git grep calls and up to 20 git log -S calls per ready retirement issue. Memoise per issue and base commit, or pass all the names to one git grep -e a -e b. Also skip names that are file extensions such as .ts or .json, which can never be gone.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs