x‑hakt

Four tags, one lifecycle

control

yamlgit

Every run of the planner’s scheduled draft happens with nobody watching. Claude works through the queue for all three sites on a job before the operator is awake, and there’s no one in the room to ask “should I write this one” while it runs. Whatever review the work needed had to happen without anyone present at the moment it mattered, which meant it couldn’t live in a conversation. It had to live somewhere the operator could leave instructions ahead of time and Claude could read them back later, on its own schedule, days apart if need be.

The planner runs as its own hull in the fleet, a self-hosted instance I’ve written about before for a different reason. What matters here is one thing it already had before I touched it: every post, scheduled or not, can carry tags. Building a review screen from nothing, with its own states and buttons and a table to track them, felt like laying a new keel just to answer a yes-or-no question. So I didn’t. I hung the whole review process off tags that were already sitting there.

Four flags, and nothing else

A suggested idea lands on the calendar as a short draft, a working headline and a rough angle, tagged Topic. It isn’t a post anyone will ever see; it’s a placeholder for a decision, sitting at the slot where Claude thinks the finished piece belongs. From there the operator has exactly three moves: leave it alone, tag it Skip (or just delete it, if Skip feels like ceremony for something that was never going to happen), or tag it Write.

Write is the only flag that turns a suggestion into work. When Claude next picks up the queue, it reads whatever text is currently sitting on the card over the same connection it drafts through, not the text it originally suggested, so a headline or angle the operator rewrote by hand steers the piece instead of getting overwritten. It drafts the whole thing and writes the finished html into that same draft: same slot, same channel. The tag it adds on the way out is Ready. Four flags, Topic, Write, Skip, Ready, and every card’s life was one of two short paths: Topic to Write to Ready, or Topic to Skip.

None of that governs how many cards get written in one run, or how far ahead a site’s calendar has to stay covered. Those limits live in one config file, read once at the start of a run; the flags only ever decide what happens to a single card. And none of it ever touches a post once it’s live: only drafts carry these flags in the first place, so there’s no path from a tag to something going out that wasn’t meant to.

Topictags WriteWriteexpands itReadySkipor Skip, from eitherRevisecommentsreworked
Four flags plotted a straight line: Topic to Write to Ready, with Skip as the only exit from either of the first two. Revise came later, as a loop back onto Ready.

One flag doesn’t take another one down

The part that isn’t obvious from the names alone is what happens to a flag once a card moves past it. It doesn’t come down. Turning a Write card into a Ready one adds Ready and only removes Topic; Write stays exactly where it was, still flying, doing nothing more useful now than recording that this card once needed drafting. Open today’s board and the finished cards carry both Write and Ready at once, every one of them. It isn’t a leftover somebody forgot to clean up. It’s the design: a card’s tags are a small, mostly-append history of what’s been asked of it, not one box that gets wiped and refilled.

TopiccreatedTopicWriteoperator tags WriteWriteReadyexpanded, Topic dropsWrite and Ready, once raised, stay up
Tags never get replaced, only added or dropped one at a time. Topic and Revise are the only two that ever come back down; Write and Ready stay flying once they go up.

That only works if something is willing to look at a card wearing three flags at once and say which one actually counts.

Which flag wins

The rule is fixed, and it runs in the same order every single time: skip beats everything, then revise, then ready, then write, and a card with none of those left standing is still just a topic.

skip > revise > ready > write > topic

Whichever of those is the highest one still flying, that’s the card’s status, no matter what else is stuck to it further down. A card goes wherever its top flag says it goes. That’s what a ship is, you know. The rest of the system never has to work out which order the flags went up in, only which one’s on top right now.

one card, three flags still flyingWriteReadyReviseSkip flying?noRevise flying?yes, stop herestatus: reviseReady flying? (not reached)Write flying? (not reached)else: topic (not reached)
This card is flying Write, Ready and Revise all at once. The checks run in a fixed order and stop at the first match, so Revise wins even though Ready is also still up there.

The fifth flag

Four was the whole plan for a while, and it held for the first stretch of the project. It stopped being enough the first time a Ready draft came back almost right: one clumsy paragraph, a fact that needed a source, a joke that landed wrong. Rewriting the entire piece from a blank Write card felt like scrapping a hull over a chipped rail. What the operator needed was a way to leave a note on a finished draft and have only that note acted on. That became Revise: tag a Ready draft Revise, leave comments on it saying what to fix, and Claude reads only the comments marked new since the last pass, so a second or third round doesn’t redo feedback that already landed. It reworks the html, keeps whatever the operator already changed by hand, and drops the Revise tag back to Ready when it’s done. Ready doesn’t mean finished forever. It means finished for now, and free to go round again.

The comment that didn’t get the memo

Revise went in cleanly everywhere except one place: a code comment sitting right above the precedence rule, still reading through skip, ready, write and topic the way it did when there were four flags to name, with revise missing from the sentence entirely even though the function underneath it has checked for Revise, in the right slot, since the day it was added. A look back through the project’s own history shows why: Revise was filed and shipped as its own small piece of work, weeks after the first four flags, and the comment above the precedence check simply wasn’t part of that patch.

Nothing about the behaviour is broken. Skip still wins, Revise still comes right after it, and everything downstream of that has been correct since the day it shipped. The comment above it is the only thing that’s out of date, and it still says four.

Five flags now, doing the work four used to. The name stuck anyway. Fair winds.

-x