5 of my 54 open cards could actually go out

8–12 minutes
measured on my own machine
5 of my 54 open cards could actually go out

On 2026-09-07 I measured my production cockpit: 54 living cards, and 5 of them could go out without a click. The other cards looked exactly the same in the list. Some had no channel, some had no artifact, some had no destination. Whoever touched one of those was working on something that would stay where it was anyway. The same day, 0 of 15 drafts had been transmitted through the outgoing queue.

What I wanted was simple. A list in which every row is an action that changes something. The cockpit is the board where the cards from my automated loops land, and it is where I look first. If a row is there, I should be able to act on it and see something leave. I said as much in one sentence: I only want to see tickets with postable artifacts.

I believed that a card which is open is also a card that can be worked. Open meant nobody had closed it, and I read that as still to do. The list had one status and I trusted it to answer both questions. It never occurred to me that the system could keep a card alive without having any way to deliver what the card was about. I thought the backlog was a workload. Most of it was a waiting room with no door.

Open and postable are two different questions, and only one was being asked. Whether a card can go out depends on things the status does not know: is there a channel, is there a draft, did the critic pass it, has a deadline run. Each of those lived in a different exit, with its own check. The list asked none of them. The worst case was the announcement. An announcement is a promise that something goes out in 24 hours unless I object. At most two open announcements are allowed. A card that can never be fulfilled would hold one of those two slots for good, and so block the very card that works. The exit clogs itself.

b1e0ec17 · 2026-09-07

Nur ankuendigen, was auch hinausgehen kann — sonst verstopft der Ausgang sich selbst

Only announce what can actually go out — otherwise the exit clogs itself

It surfaced while re-measuring production: the autopush wanted to announce card #445, which has no site and therefore no channel. The fix was a check that runs before the announcement and answers ‘can this go out’, expressly not ‘may it’. Permission stays with the one route that already decides it; two derivations would be two truths. The check fails closed: a missing state, a missing draft, or a flag that is not exactly true announces nothing. Skipped cards are logged with number and reason.

The commit subjects of that day, in the original German. The first one names the clogged exit before the list was touched at all.
The commit subjects of that day, in the original German. The first one names the clogged exit before the list was touched at all.

One derivation, no new list

The larger change followed the same idea. I did not write a second list of what counts as postable. One function asks the exits that already exist, and those now return an identifier next to their plain-text reason. Every reason carries a class: content, system, repairable, human, done, unknown. Cards are closed automatically only for content and system. Nothing is ever closed out of ignorance. An equality test runs the autopush selection and the new function against the same small database and demands the same set.

67577c75 · 2026-09-07

Das Cockpit zeigt nur, was hinausgehen kann — und der Rest berichtet, warum nicht

The cockpit shows only what can go out — and the rest reports why not

The cockpit now shows what is postable, and above it a line that counts what is hidden, by reason. Before touching production I ran it dry against a copy: 15 post cards, 7 postable, 7 would close, 1 stays. That run found two things. Some cards I had classed as a system fault were really waiting on a human, because that site deliberately has no page to post to. And card #377 lacked its key, so a card long since live could not be closed.

  1. 2026-09-07While re-measuring production I caught the autopush about to announce a card with no channel. I put a can-it-go-out check in front of the announcement, failing closed.
  2. 2026-09-07I wrote the plan down before building: one derivation, a filter with a count line, one place for the rule about who receives a card, and a critique column. Measured first: 5 of 54.
  3. 2026-09-07Built it. One function asks the existing exits, the list shows only postable cards plus system faults, and one writer closes the rest with a reason. Then a dry run on a production copy.
  4. 2026-09-07Ran it on production. Backfilled the critique for 5 of 5 drafts and gave cards #377 and #383 the keys they were missing.
  5. 2026-09-07My midday exception for hand-made cards did not survive the afternoon. I emptied the exception list and moved everything without a postable artifact to the bottom.

The dead end was mine. At midday I added an exception: cards I had made by hand stay visible, like the system-fault cards. At that point there were only two places, up or gone, so ‘always visible’ was right. Then the hidden cards got their own section at the bottom of the board: visible, counted, with a reason. That made a third place. The exception had never been a rule about cards. It was a stand-in for a place that did not exist yet.

5f0c5e93 · 2026-09-07

Alles ohne postbares Artefakt steht unten — die letzte Ausnahme fällt

Everything without a postable artifact sits at the bottom — the last exception falls

Removing it moved 10 cards down, 9 hand-made and 1 system-fault card, measured on a copy of production. For the other 36 living cards nothing changed. A system-fault card got its own reason and is never closed automatically; otherwise a machine would close the card that carries the defect. Without that reason the defect would have vanished into ’29 without exit’ instead of standing there as ‘1 system defect’. The exception list is empty now, and a test holds that it stays empty.

The record does not name the tools I ran. It shows that test files changed, which implies node –test, and that is an inference, not something I said. The first commit reports 7 assertions, 5 mutations each checked red on its own, and a suite of 3036 green. The record also does not say how long any of this took. The cost figure it holds covers every run in the window, not this work alone, so I leave it out.

What the record supports and what it does not. The tools are inferred from changed test files, not quoted.
What the record supports and what it does not. The tools are inferred from changed test files, not quoted.

Solved for the list, not for everything behind it. On production: 15 checked, 7 postable, 4 closed, 5 bound. The dry run had said seven would close; the record does not spell out why four did. Two ticks later there were 49 open cards, 8 visible, 7 of them postable. Before, it was 5 of 54. What stays open: one loop writes no post block in 2 of 4 runs, which is why cards #438 and #440 had no key. Card #456 carries that defect. The cause is measured and visible, not fixed. The rest sits at the bottom and reports why not, instead of disappearing.

Five commits, all dated 2026-09-07, from my own repository, each checked individually before it was quoted. The figures were measured on production or on a copy of it, as the commit bodies state.

b1e0ec17 · 6c8126bb · 67577c75 · 94bcc227 · 5f0c5e93

Georg Singer

Georg Singer

I automate my own projects in public and write down what each one cost. Physics degree, doctorate in computer science, nine systems in production on hardware I own, all of it built in my own time.

More from the log