0.7.0: one run, your decisions, no state of its own

· Release · written for 0.7.0

0.7.0 is the biggest change the suite has seen so far. It is a breaking release, and it changes how you work with the suite day to day. This post explains what changed, why, and what a project onboarded on 0.6 has to do. If you only want the steps, jump to Migrating from 0.6.

How 0.6 worked

Up to 0.6, the suite was a loop. Each call of /continuous-refactoring made one pass: it picked the most overdue of the four Tracks (Safety Net, Guardrails, Housekeeping, Investigation), each with its own cadence, and handed it to that Track's skill. That skill ran scan → prioritise → design → implement → learn, each step its own skill. Eleven skills in all, with refactor-learn as the only one allowed to write the suite's records.

Those records lived in files under .scratch/refactor/:

  • config.md, per person and machine: where the bookkeeping lives, and whether tickets and merge requests are created automatically or after asking (Ticket-create-mode, MR-create-mode)
  • bookkeeping.md, or a tracker issue instead: each Track's cadence, last scan and open items
  • merge-requests.md and out-of-scope/ for remembered merge requests and rejections

As a safeguard from the start, the suite held back at two open merge requests and five open candidates: a pass at that limit ended without new work.

What was in the way

Up to 0.6, two things got in the way:

  • Autonomy was set per machine. A config file decided once whether the suite filed tickets and opened merge requests by itself or asked first. You could not say "show me" on one call and "just do it" on the next.
  • It kept its own records. A bookkeeping document, local or in a tracker issue, recorded what had been scanned and filed. That document could drift from what the tracker actually showed, and which Track came next was computed from a staleness ratio nobody could predict.

One run, a chain of decision points

/continuous-refactoring now does one run: from your open refactoring tickets to one opened merge request. On the way it passes a fixed chain of decision points: reconcile, Track choice, scan, filing tickets, selecting a ticket, design, implementation, merge request.

Every decision point shows the same three things: what it found, the options, and one recommendation with a short reason. Nothing is written to your tracker, forge or files except as the result of one.

By default the run is interactive: you answer each decision point. The call itself can say more, in your own words:

/continuous-refactoring
/continuous-refactoring do it yourself
/continuous-refactoring diy
/continuous-refactoring Safety Net, without asking
/continuous-refactoring work ticket #42
/continuous-refactoring only the Rector tools

"Do it yourself", or just "diy", makes the run autonomous: it takes its own recommendation at every decision point. It still posts the same findings it would have shown you, plus the recommendation it took, so you can read afterwards why the run went the way it did. If you start interactively and change your mind, say "carry on yourself from here" and the run goes on autonomously from the next decision point.

No state of its own

The suite no longer keeps any records. On every run it searches your tracker and forge for its tickets, merge requests and rejections. So these are gone:

  • the config file and the bookkeeping document, local and remote
  • Ticket-create-mode and MR-create-mode
  • the Track cadences

Tickets are recognised by their subject, not by a fixed label or title. A ticket you wrote yourself is picked up when it carries your Candidate mark, if your tracker has one, or when you name it in the call. A Track is scanned once; after that, its tickets are the record.

The suite finds all this through the Refactoring operations in docs/agents/issue-tracker.md. That section changes too:

  • Search is new and required: how tickets are searched by words, open and closed together.
  • Rejected, Blocked by and Housekeeping are new and optional. Without Rejected, the run proposes a place the first time it records a rejection.
  • Bookkeeping, Filed date and Comment author and time are removed.

The limits are gone

The limits of two open merge requests and five open candidates were a safeguard from the start, not a flaw. Using the suite over time showed they are not needed, as long as two things hold:

  • the merge requests are not stacked on top of each other, and
  • the agent sees when an open merge request will conflict with the planned change, and takes that into account when planning.

So 0.7.0 drops both limits. If you want such a limit in your project, you can still set one there.

Dropping the two-merge-request limit opened up something else: one ticket can now be delivered in several smaller merge requests instead of one large one. Each branches off the default branch on its own, and each is easier for a human to review.

Two skills instead of eleven

The suite is now continuous-refactoring and continuous-housekeeping. The nine others are gone.

The split had two purposes: the whole loop should not sit in one skill file, and you should be able to jump into a single step of the loop. Using the suite showed that neither needs separate skills:

  • Routing between skills was unreliable across different agents. Reference files that are read only when needed work more reliably with all of them.
  • Jumping into a step works without its own skill. Naming the step to start from in the call worked then and still works today.

If your project has its own skills for planning and implementing, a run now recommends those and uses the suite's own procedures only as a fallback. Before, a project's own skills were ignored for refactoring work.

Housekeeping as a standing ticket

Housekeeping is now one standing ticket, made from a template in your repository, with a rhythm you choose. Refactoring ideas that are too small for their own ticket go on it as comments. It has its own command, /continuous-housekeeping, which you can schedule, and which an agent may also start by itself when the ticket is due. See Housekeeping.

Migrating from 0.6

A project onboarded on 0.6.0 needs three steps.

  1. Run the onboarding again. Call /continuous-refactoring. It adds Search to your ## Refactoring operations section and removes the bullets that no longer exist. Then it ends the run; commit the changed tracker file and call it again.
  2. Delete the old files under .scratch/refactor/: config.md, bookkeeping.md, merge-requests.md and the folder out-of-scope/. They are no longer read. Tickets kept as Markdown files in .scratch/refactor/issues/ stay. If you want to keep your old rejections, name their folder under Rejected instead of deleting it. A rejection that should come back once your project reaches a PHP version needs a line Blocker: PHP >= X.Y. If your bookkeeping lived in a tracker issue, close that issue.
  3. Remove the symlinks of the removed skills from your skills folder: refactor-loop, refactor-scan, refactor-prioritize, refactor-design, refactor-implement, refactor-learn, continuous-safety-net, continuous-guardrails, continuous-investigation.

Nothing is migrated. The first scan of each Track rebuilds the worklist as tickets.

Smaller changes

  • The onboarding now tries its search and merge-request commands before it shows you the summary. If one fails, for example with an older glab or gh, it asks about a working variant then, so you confirm only once.
  • The onboarding now ends the run instead of carrying on in the same call.
  • The suite no longer sets or reads the triage labels needs-info and ready-for-agent. Whether a ticket waits for an answer is read from its comments. The suite stays compatible with other engineering skills, such as mattpocock/skills, and needs none of them.
  • The Housekeeping ticket's date line, template line and title can be worded freely. Runs read them by what they hold.

The run page describes the run as it is today. Questions about the change are welcome in GitHub Discussions.

Changelog 0.7.0

The upstream changelog entries for 0.7.0, verbatim. Also on GitHub: release 0.7.0.

Show changelog entries
  • Breaking, for 0.7.0: the suite is rebuilt around one run of decision points, with all state in your tracker and forge. /continuous-refactoring now leads from your open refactoring tickets to one opened merge request and, at every step — reconcile, Track choice, scan, filing tickets, selecting, design, implementation, merge request — shows what it found, the options and one recommendation. By default you decide each time; say in the call that it should do the run itself ("do it yourself"), or mid-run "carry on yourself from here", and it takes its own recommendations. The call also takes a Track, a ticket or a restriction ("only the Rector tools") in your own words. The suite keeps no state of its own any more: the config file, the bookkeeping document (local and remote), Ticket-create-mode, MR-create-mode and the Track cadences are gone, and so are the limits of two open merge requests and five open candidates. Tickets are found by their subject instead of a fixed label or title, a ticket you wrote yourself is picked up through a Candidate mark or by naming it, and a Track is scanned once — afterwards its tickets are the record. Where your project has its own skills for planning and implementing, a run recommends those and uses the suite's procedures as a fallback. Housekeeping is now one standing ticket made from a template in your repository, with a rhythm you choose, refactoring ideas left on it as comments, and its own command /continuous-housekeeping that can be scheduled and that an agent may start by itself. The suite is two skills, continuous-refactoring and continuous-housekeeping; the nine others are removed. The operations in docs/agents/issue-tracker.md change their cut: Search is new and required; Rejected, Blocked by and Housekeeping are new and optional; Bookkeeping, Filed date and Comment author and time are removed.

    A project onboarded on 0.6.0 needs three steps. (1) Run the onboarding again: call /continuous-refactoring, which adds Search to your ## Refactoring operations section and removes the bullets that no longer exist. (2) Delete the suite's old files under .scratch/refactor/ — config.md, bookkeeping.md, merge-requests.md and the folder out-of-scope/; they are no longer read. Tickets kept as local Markdown files under .scratch/refactor/issues/ stay. To keep your old rejections where they are instead of deleting them, name that folder under Rejected in the section (a rejection that should come back by itself once a PHP version is reached needs a line Blocker: PHP >= X.Y). Where the bookkeeping lived in a tracker issue, close that issue. (3) Remove the symlinks of the removed skills from your skills folder: refactor-loop, refactor-scan, refactor-prioritize, refactor-design, refactor-implement, refactor-learn, continuous-safety-net, continuous-guardrails, continuous-investigation. Nothing is migrated; the first scan of each Track rebuilds the worklist as tickets.

  • The Housekeeping ticket's date line, template line and title are described by what they hold, not by a fixed wording: the onboarding words the Housekeeping bullet itself, and later runs read the due date and the template from the ticket in whatever words it states them.

  • The suite no longer sets or reads the triage labels needs-info and ready-for-agent. Whether a ticket waits for an answer or is ready to work is read from its comments, so it works in a tracker without them. It stays compatible with other engineering skills, such as those of mattpocock/skills, and needs none of them.

  • The onboarding now ends the run. Instead of offering to go on in the same call, /continuous-refactoring reports the onboarding as complete, points out the changes it left in the working tree (the tracker file) and recommends committing them and calling the skill again.

  • The onboarding now tries its search and merge-request commands before it shows you the summary, not after writing the tracker file. When one fails, for example because your installed glab or gh is older, the onboarding asks about a working variant at that point, so the summary you confirm already contains commands that work and no second confirmation follows after writing. A run on its own takes a working variant it found itself; without one, it writes nothing and names the open question.

Questions or comments on this post? Welcome in GitHub Discussions (Q&A).