A once-daily administrative ritual. Process, not software: the steps are executed manually, the runtime is me.

The ledger itself lives at ~/wvl/wiedervorlage.md and is not in this repo — this repo is published to sources.profpatsch.de, and the ledger is full of customer numbers, applicant numbers and health-insurance sender IDs.

~/wvl is its own git repository, deliberately without a remote: the daily backup of $HOME covers it, and anything that could be pushed could be pushed to the wrong place. ~/wvl/notes/ holds the note files that chains point at.

Running example. Every section ends with an example, and they are one continuous story: Session 0 on Sat 2026-08-15 through Thu 2026-08-27. Each example continues the ledger state left by the previous one, so the document can be read straight through as a two-week transcript.

The cast: a Netzteil waiting at the Packstation, a Krankenkassen-Formular, an e.V. Protokoll nobody wants to write, an unpaid invoice, and a GEZ Ummeldung that refuses to get done.

I work on whatever comes to mind when I wake up. That is fine for advancing things, but it has no way of noticing time-critical items: packages with pickup deadlines, unopened letters with response dates, recurring obligations.

Opening mail implicitly means committing to deal with it, so not opening it is the rational move. The whole design follows from decoupling those two.

The daily session may only advance items one step. It must never require solving anything.

The session's only verbs are see, date, file. Opening a Finanzamt letter and writing down "respond by the 25th" is low-brain. Responding is not, and it happens outside the session, as ordinary work.

Corollary, and the reason it is safe to open anything:

During the session I may not do anything a message asks. I may only write down what it asks.

This keeps the session ~30 seconds even on days when everything is on fire, which is what makes the streak survivable.

Example — Sat 2026-08-15. The Krankenkasse letter says a form must be back by the 30th. The session does not fill in the form. It writes one line:

2026-08-18 Di [priv] Formular S1 Krankenkasse ausfüllen+zurück  ‼2026-08-30 So

Elapsed: eight seconds. The form gets filled in on the 18th, as work, in whatever mood I'm in then.

One physical spot where every piece of paper lands. Unopened is fine. Zero decisions at drop time. It is the physical inbox.

Tags: [priv] [ev] [biz], plus [raus] for anything requiring leaving the house.

Example — Sat 2026-08-15, after Session 0. Watermarks bankrupted to today; ten letters opened, six binned, four turned into lines; the rest of the pile made into a line of its own.

streak: 2026-08-15 Sa  n=1

--- watermarks ---
mail-priv   2026-08-15 Sa
mail-ev     2026-08-15 Sa
mail-biz    2026-08-15 Sa
chat        2026-08-15 Sa
post        2026-08-15 Sa

--- due ---
2026-08-16 So [priv] nächste 10 Briefe aus Tray öffnen (noch ~30)
2026-08-16 So [raus] Paket Netzteil: Packstation abholen  ‼2026-08-22 Sa
2026-08-18 Di [priv] Formular S1 Krankenkasse ausfüllen+zurück  ‼2026-08-30 So
2026-08-20 Do [priv] Stromabrechnung prüfen
2026-08-24 Mo [priv] GEZ Ummeldung
2026-09-10 Do [priv] Versicherung: prüfen ob wechseln (Kündigung)  ‼2026-10-01 Do

--- inbox ---

Inbox = undated. Due = dated. That is the entire difference, and it exists to move one decision out of a moment where I won't make it.

inbox due
when written any time, mid-task, 2am only during the session
format none, raw scribble DATE Wd [tag] next action
sorted no yes, ascending
lifetime until next session until done
decision needed zero one: when does it return?

At capture time I'm in the middle of something else and my only willingness is to type six words. If capture demanded a date, I'd skip the capture — and a skipped capture is data I never get back.

So the session is a queue drain: inbox → due. Inbox is a buffer, never a list. If it is growing, the session isn't happening.

Nothing in inbox is safe: no date, no escalation, checked once a day. Anything with a deadline must reach due to be protected.

Mail and tray never pass through inbox — I'm already in the session when I open them, so they get dated immediately.

outside session   →  inbox (undated)  →  [next session]  →  due
   (2am scribble)                                            ↑
during session    →  due (dated)  ──────────────────────────┘
   (mail, tray)

Example — night of Mon 2026-08-17. Two thoughts, thirty seconds apart, neither of them worth interrupting what I'm doing:

--- inbox ---
laptop akku bestellen, der alte hält nix mehr
jemand meinte es gibt förderung für den verein??

No dates, no tags, no capitals. That is the whole point — at 2am, requiring a date means I write nothing at all.

Next morning's session drains both. One turns out to be a two-minute job and is simply done; the other becomes a dated line:

2026-08-27 Do [ev]   rausfinden welche Förderung gemeint war — M fragen

Inbox is empty again. It always is, at the end of a session.

The date on a line is when it surfaces, not when it is due. Deadline on the 25th → line dated the 18th, with ‼2026-08-25 Di at the end of the line.

This is what makes missing days safe. Deadline-dated systems fail hard on one missed day; a week of slack absorbs a bad week.

Example. The Krankenkassen-Formular is due 08-30. It is dated 08-18 — twelve days of slack:

2026-08-18 Di [priv] Formular S1 Krankenkasse ausfüllen+zurück  ‼2026-08-30 So

When I later lose four days to a cold (see Bankruptcy), this line is still not late. Had it been dated 08-30, those four days would have cost me the deadline.

The lead time is a guess about how long something takes; records what that guess was protecting. Full ISO date, because deadlines cross year boundaries and ‼01-31 is ambiguous exactly when it matters.

Written as a marker rather than as prose, it can be checked:

The must be in the future, and later than the date at the front.

Both halves are needed. The front date catches a line scheduled after its own deadline; today's date catches one that aged past it, which the first check never would, since an escalating [raus] line keeps its original front date.

The difference is not theoretical. An Einkommensteuer line sat in due reading "Frist war 07-31" for weeks after the fact and nothing noticed, because nothing was reading it. As a marker it reports itself:

2026-08-28 Fr [priv] Einkommensteuer 2025: rausfinden ob überfällig
                     FRIST VERSTRICHEN, deshalb vorgezogen  ‼2026-07-31 Fr

Two rules keep it mechanical:

Most lines have no . It marks the ones where being late is a distinct event — a fee, a lapsed claim, a rejected application — not merely a thing still undone.

2026-08-30 So, everywhere: front dates, , watermarks, dates inside the text. Redundant, but redundant at the moment the decision is made, which is the only place it could help.

Dating happens at speed, by arithmetic — "that's in three days" — and nothing in 2026-08-30 says that lands a phone call to an Amt on a Sunday. The line then surfaces, cannot be done, and re-dates itself for nothing.

Dates inside the text need it just as much. They look like records, but most are claims about how long someone else has had:

?  aws Sperrmüll abgeholt? (gemeldet 08-15 Sa, Eingang best. 08-17 Mo)
Glasfaser an QM (Jan + Lilly bis 09-04 Fr im Urlaub — erreichbar erst 09-07 Mo)

Reported on a Saturday means it sat until Monday, so impatience on Tuesday is misplaced. Back from holiday on a Friday means back properly on Monday, so a follow-up dated to that Friday is one nobody will answer. Both decide whether a ? should fire yet, and both are invisible in a bare 08-15.

Only pointers stay bare — siehe 08-27, or a # 08-28: heading. The line they point at carries the weekday already.

  1. Commit the ledger as it stands. cd ~/wvl && git commit -am "vor session $(date -I)"
  2. Empty the tray. Open everything. Each item becomes a dated line or goes in the bin. Nothing returns to the tray unopened.
  3. Scan the inboxes, newest first, stop at the watermark. Bump watermarks to today.
  4. Drain the inbox section. Give each scribble a date. Don't plan it.
  5. Re-sort due ascending.
  6. Read due from the top until the first future date. Stop there.
  7. Bump the streak.

The scan is step 2, before reading the due list, so that mail arriving with something due today is picked up in the same session.

Step 0 runs before the session rather than after it, which is what makes it useful: the tree is clean when the session starts, so git diff during the session shows exactly what this session did, and the invariants below can be checked against it. A commit at the end would land in the one moment the session is habitually abandoned, and would record the result without ever having shown the change.

Empty day: tray empty, inboxes clean, top line in the future → bump streak, done. ~15 seconds.

Example — Sun 2026-08-16, the first real session. Forty seconds.

1. Tray. One envelope. Werbung. Bin. Tray empty.

2. Inboxes, newest first, stopping at the 08-15 watermark:

  • mail-priv, 12 new — nine newsletters (ignore, they never existed); DHL "Zustellung fehlgeschlagen" → line; Bank "Kontoauszug" → ignore; a friend asking "kommst du am 22.?" → thirty seconds, answered now, no line.
  • mail-ev, 3 new — two threads I'm not on the hook for; one asking "wer macht das Protokoll?" → line, because deciding that is work, and work does not happen during the session.
  • mail-biz — nothing new.
  • chat — one DM from K: "kriege ich noch die Rechnung für Juli?" → line.

Watermarks all bumped to 08-16.

3. Inbox section. Empty; nothing was captured yesterday.

4./5. Sort, then read from the top. Today is 08-16:

  • nächste 10 Briefe öffnen → do it. Seven junk, three lines. Twenty left, so it is re-dated to tomorrow.
  • Paket Netzteil → cannot be done at the desk. Not marked done, not re-dated. It stays.

Next line is dated 08-17. Stop.

streak: 2026-08-16 So  n=2

--- watermarks ---
mail-priv   2026-08-16 So
mail-ev     2026-08-16 So
mail-biz    2026-08-16 So
chat        2026-08-16 So
post        2026-08-16 So

--- due ---
2026-08-16 So [raus] Paket Netzteil: Packstation abholen  ‼2026-08-22 Sa  (1d offen)
2026-08-17 Mo [priv] nächste 10 Briefe aus Tray öffnen (noch ~20)
2026-08-17 Mo [priv] DHL: neuen Zustelltermin buchen
2026-08-18 Di [priv] Formular S1 Krankenkasse ausfüllen+zurück  ‼2026-08-30 So
2026-08-18 Di [biz]  Rechnung #241 an K stellen  ↻nach: ? 14d
2026-08-19 Mi [ev]   entscheiden: Protokoll selbst oder M fragen
2026-08-19 Mi [priv] Handwerker-Rechnung bezahlen
2026-08-20 Do [priv] Stromabrechnung prüfen
2026-08-21 Fr [raus] Vereinsheim Schlüssel zurückbringen
2026-08-24 Mo [priv] GEZ Ummeldung
2026-08-31 Mo [priv] Zahnarzt Termin 09-02 — hingehen
2026-09-10 Do [priv] Versicherung: prüfen ob wechseln (Kündigung)  ‼2026-10-01 Do

--- inbox ---

Three inboxes and a stack of post processed, and roughly zero minutes of actual work done. That is the point.

Bounded by a watermark per inbox: only ever look at what is newer than the last look. Otherwise "scan many inboxes" is an unbounded chore.

mail-priv, mail-ev, mail-biz — subject lines only.

chat (Signal / WhatsApp / Matrix) has no trustworthy read-watermark, so it is bounded differently: mentions and DMs only. Group chatter is not an inbox.

Web portals (Bank, ELSTER, Krankenkasse) cannot be scanned daily — login friction. They are not inboxes; they are a monthly ↻1m line in due. Same mechanism, no special case.

Example — Mon 2026-08-17. mail-priv shows 47 unread. The watermark says 08-16, so only 6 of them are in scope; the other 41 do not exist today and will never be looked at again. This is the difference between a bounded scan and "clean up your inbox", which is a thing I will not do.

The e.V. Matrix room had 80 messages overnight. Mentions and DMs only: zero in scope. Watermark bumped, done.

# outcome trace left
1 junk / FYI none — it never existed
2 under 2 min do it now, none
3 clear next action one due line
4 unclear what to do one due line: deciding is the action
5 resolves a pending ? grep the ledger, delete that line

Case 4 is the one that matters — it is where I currently stall, and stalling on it is why "unopened" is the rational default. "I don't know what to do about this" is not a blocker, it is an action I haven't named yet:

entscheiden, richtig lesen, nachfragen are legitimate next actions. This is what keeps the 10-second budget honest: I never need to understand a message during the scan, only name what would move it.

Example — the five outcomes, all from the 08-16 scan above:

# message what happened
1 nine newsletters binned, no trace
2 "kommst du am 22.?" answered on the spot, no line
3 DHL Zustellung fehlgeschlagen 2026-08-17 Mo [priv] DHL: neuen Zustelltermin buchen
4 "wer macht das Protokoll?" 2026-08-19 Mi [ev] entscheiden: Protokoll selbst oder M fragen
5 nothing pending yet; see Thu 2026-08-20 below

Outcome 4 is the interesting one. I did not decide anything about the Protokoll. I did not even think about it. I named the deciding as the action and moved on, and that is why the mail could be opened at all.

Record the next physical action, not the topic. Krankenkasse is a topic and will rot. Formular S1 ausfüllen + zurückschicken is an action.

Example — the same letter, written two ways.

2026-08-18 Di [priv] Krankenkasse                                    # rots
2026-08-18 Di [priv] Formular S1 ausfüllen+zurück  ‼2026-08-30 So      # gets done

On the 18th the first version requires me to reconstruct what the letter wanted, which means re-reading it, which means I skip it. The second version can be executed while half awake.

kind next date computed from cancellable?
recurring the calendar, drift-free no
follow-up when I did the thing yes, usually
chain the outcome of this step n/a

Three markers, carried in the line so it is self-describing:

↻nach: says what the successor is, and the successor need not be the same kind of line:

written on completion, spawns
↻nach: ? 14d a tripwire in 14 days — did they react?
↻nach: ↻2w a recurring line every 2 weeks

The second form is how a one-off task installs a habit: Backup-Checkliste anlegen ↻nach: ↻2w means the checklist does not exist yet, and once it does, it goes on the calendar fortnightly. Writing that at creation time is the same trick as everywhere else here — the thinking happens once, and completing the task is then pure transcription.

↻1y vs ↻+3w is the drift question: do the taxes three weeks late and ↻1y still lands next March, whereas ↻+3w walks the date forward every year until it is in November.

Example — Mon 2026-08-24, the monthly portal check.

2026-08-24 Mo [priv] ↻1m  Bank-Postfach checken

I do it on the 27th, three days late. Because it is ↻1m and not ↻+1m, the successor is computed from the calendar, not from when I got round to it:

2026-09-24 Do [priv] ↻1m  Bank-Postfach checken

With ↻+1m it would have become 09-27, then 10-02, then mid-October — the monthly check would have drifted into a quarterly one without me noticing.

A or ? line may not be deleted. It may only be replaced by its successor, written in the same breath.

Two-step chains are where these systems leak, so the spawn rule is written when the task is created, not remembered at completion time.

Example — Tue 2026-08-18, the invoice. Top of the list:

2026-08-18 Di [biz] Rechnung #241 an K stellen  ↻nach: ? 14d

Sending it takes two minutes, so it happens now. Before the line is crossed off, its successor is written:

- 2026-08-18 Di [biz] Rechnung #241 an K stellen  ↻nach: ? 14d
+ 2026-09-01 Di [biz] ?  Rechnung #241 bezahlt? (gestellt 08-18) — sonst Mahnung

Line 1 was a task I do. Line 2 is a tripwire I hope never fires. Note that ↻nach: ? 14d was written back on 08-16, when the task was created — so writing the successor now is pure transcription, no thinking. That is what keeps the rule survivable at step 5 of a forty-second session.

On 09-01, either the money arrived (and the line was deleted during some earlier scan) or it did not, and I am looking at a line that already tells me the next step: Mahnung.

Cancellation is what makes ? work. A follow-up usually gets cancelled rather than done — I set it because the reply might not come. When the reply arrives (outcome 5 above), the line dies before the safety net fires. That is the system working, not a wasted line. If ? lines accumulate, outcome 5 is being skipped and the list is silently getting less trustworthy.

Example — Wed 08-19 and Thu 08-20, the Protokoll.

On 08-19 the entscheiden line comes up. I decide: ask M. Asking takes thirty seconds, so it happens now — and spawns its own safety net:

- 2026-08-19 Mi [ev]   entscheiden: Protokoll selbst oder M fragen
+ 2026-08-26 Mi [ev]   ?  Antwort M wegen Protokoll (gefragt 08-19) — sonst selbst machen

On 08-20 the mail-ev scan turns up M's reply: "mach ich." Outcome 5 — grep for Protokoll, delete the line:

- 2026-08-26 Mi [ev]   ?  Antwort M wegen Protokoll (gefragt 08-19) — sonst selbst machen

The safety net never fired. Six days of not thinking about the Protokoll, and a guarantee that if M had gone quiet I would have found out on the 26th with the fallback already written down.

This is the one place the ledger gets searched rather than read top-down, which is why plain text with a distinctive token per topic (#241, Protokoll) earns its keep.

Chains: only the current step goes in the ledger. Multi-step procedures get a note file, and the line points at it:

2026-08-24 Mo [priv] Ummeldung Schritt 2: Unterlagen sammeln → notes/ummeldung.md

Otherwise due becomes a project plan, which is a list I avoid opening — the exact failure being designed against. due holds next actions only.

Anything needing to leave the house cannot be done at the desk, so it is not marked done — it stays dated today and reappears tomorrow, and the day after, with a (Nd offen) counter, until the deadline. Sorted-ascending plus read-from-the-top means an overdue line structurally cannot be scrolled past.

Tag [raus] to batch several into one trip.

Example — the Netzteil, four days running. Top line of the list, every single morning:

2026-08-16 So [raus] Paket Netzteil: Packstation abholen  ‼2026-08-22 Sa
2026-08-16 So [raus] Paket Netzteil: Packstation abholen  ‼2026-08-22 Sa  (1d offen)
2026-08-16 So [raus] Paket Netzteil: Packstation abholen  ‼2026-08-22 Sa  (2d offen)
2026-08-16 So [raus] Paket Netzteil: Packstation abholen  ‼2026-08-22 Sa  (3d offen)

On the 19th two more [raus] lines have joined it — Formular S1 zur Post bringen and Vereinsheim Schlüssel zurückbringen (see Doing the work). Three errands, one trip — and the trip happens, because by day four the Netzteil is the first thing I see every morning and the Frist is three days out.

All three lines are then deleted outright: none is or ?, so they leave no successor.

I never remembered this package, never prioritised it, and never planned around it. Nothing that has a date can be silently lost.

The session is over. Now the actual day starts — and the most important thing about it:

due is not a work queue. The ledger has no opinion about my day.

It is not a todo list, it does not rank my projects, and git-blimey never appears in it. It guarantees one narrow property — nothing dated gets silently lost — and has nothing else to say. I still work on whatever comes to mind; that was never the thing being fixed. So there are two modes, which must not compete on one list:

admin real work
source the ledger whatever comes to mind
size bounded, minutes unbounded
when picked the dates picked it I pick it
if skipped today escalates fine

Merge them and either admin crowds out real work and I come to resent the list, or real work crowds out admin and I am back where I started.

The sort order is the priority order. Dates already encode urgency, the top line is the most overdue, and I never compare two items against each other. Three situations:

  1. Energy, and I know what I want to build → do that. The list says nothing. This is the default; most days end without touching it.
  2. The day's admin exists (lines dated ≤ today, sitting at the top) → that is the batch. Usually 0–2 lines. Do them top-down right after the session, if at all — that is the one moment I am guaranteed to be looking at the file. Skipping is allowed: the (Nd offen) counter is what handles a "no".
  3. Low energy, procrastinating, no idea what to donow the list earns its keep, as a dispenser of known-good small tasks. Pull items forward from the top.

Case 3 needs one rule stated carefully, because it looks like it contradicts read until the first future date, stop:

Reading ahead is forbidden during the session. It is free in work mode.

The difference is obligation versus option. During the session the list is a demand, so it must be bounded or the session gets long and I stop doing it. In work mode I have already chosen to work, browsing ahead is voluntary, and doing admin early is strictly good. Pulling something forward and then not doing it costs nothing — no dates changed, so nothing happened.

Constantly, including outside the session. Editing is not cheating; the list is a draft, not a record.

operation when rule
delete a done line immediately, always the one edit that may never be deferred — otherwise the list lies
write the /? successor same breath as deleting invariant 5 holds in work mode too
rewrite to the next action partial completion see below
add a new item never into dueappend to inbox no exceptions; dating needs session-brain

The last row is the only restriction, and it is what keeps due sorted and trustworthy between sessions: due is written only by the session.

Partial completion is a rewrite, not a re-date. Doing half of something changes what the next action is:

- 2026-08-18 Di [priv] Formular S1 ausfüllen+zurück  ‼2026-08-30 So
+ 2026-08-19 Mi [raus] Formular S1 zur Post bringen  ‼2026-08-30 So

Same obligation, different verb, different tag — and it now batches with my other errands. This is the chain rule applied to my own unfinished work.

Example — Tue 2026-08-18, after that morning's session.

Rechnung #241 went out during the session itself (two minutes, tripwire spawned). One line is left dated today:

2026-08-18 Di [priv] Formular S1 Krankenkasse ausfüllen+zurück  ‼2026-08-30 So

I skip it and work on what I actually wanted to work on. All day. The ledger stays closed.

Late afternoon, energy gone, I do the form after all — twenty minutes, and it ends up filled in but unposted. So it gets rewritten as above: [raus], dated tomorrow.

Which is why Wed 08-19 opens with three errands rather than two:

2026-08-16 So [raus] Paket Netzteil: Packstation abholen  ‼2026-08-22 Sa  (3d offen)
2026-08-19 Mi [raus] Formular S1 zur Post bringen  ‼2026-08-30 So
2026-08-21 Fr [raus] Vereinsheim Schlüssel zurückbringen

One trip, three things — the Packstation and the Post are next door to each other. Nobody planned that batching; it fell out of the tag and the sort.

If one of these breaks, the system is lying to me.

  1. Tray is empty at end of session.
  2. inbox section is empty at end of session.
  3. Every line in due has a date and a next action.
  4. due is sorted ascending.
  5. A /? line is only ever replaced by its successor, in the same breath.
  6. All watermarks bumped to today.
  7. Every is still in the future, and later than the date at the front of its line.

Seven is the odd one out: not about the ritual being performed, but about a line being wrong, and the only one worth checking mechanically.

grep -n '‼' ~/wvl/wiedervorlage.md

A violation is not a slip in the session — it means a deadline passed while the line was still sitting in due looking ordinary.

Example — Fri 2026-08-21, a quiet day. Fifteen seconds.

Tray empty. Four inboxes: newsletters and group chatter only, watermarks bumped. Inbox section empty. Top line is 2026-08-24 GEZ Ummeldung, three days out. Stop, bump streak, close the file.

streak: 2026-08-21 Fr  n=7

--- watermarks ---
mail-priv   2026-08-21 Fr
mail-ev     2026-08-21 Fr
mail-biz    2026-08-21 Fr
chat        2026-08-21 Fr
post        2026-08-21 Fr

--- due ---
2026-08-24 Mo [priv] GEZ Ummeldung
2026-08-24 Mo [priv] ↻1m  Bank-Postfach checken
2026-08-27 Do [ev]   rausfinden welche Förderung gemeint war — M fragen
2026-08-31 Mo [priv] Zahnarzt Termin 09-02 — hingehen
2026-09-01 Di [biz]  ?  Rechnung #241 bezahlt? (gestellt 08-18) — sonst Mahnung
2026-09-10 Do [priv] Versicherung: prüfen ob wechseln (Kündigung)  ‼2026-10-01 Do

--- inbox ---

All seven invariants hold. The tray pile is gone, the Netzteil is collected, the invoice is out with a tripwire on it, and the Protokoll is M's problem. Most days look like this one.

symptom diagnosis
line at top for 2 weeks the line is wrong, not me — usually not a next action, or needs a context I don't have at the desk. Rewrite it smaller, or tag [raus].
line re-dated 3× in a row the interval is wrong. ↻1m that never happens is really ↻3m. Change the number.
? fires repeatedly they're ghosting. Escalate or drop it — a follow-up that fired twice with no reply has told me what I needed to know.
a day opens with a wall of items dating is cheap during a session, so days silently accumulate load — and a day that opens with a wall of obligations gets skipped wholesale, costing the streak and not just the day. Push the least urgent ones out (a session action, not a work-mode one).
inbox section growing the session isn't happening.
? lines accumulating outcome 5 is being skipped during the scan.
missed a few days fine — lead time covers it. Run the session normally.
missed >2 weeks declare bankruptcy (below).

Example — the GEZ Ummeldung, 08-24 through 08-27. It comes up on the 24th. I skip it. It comes up on the 25th, the 26th, the 27th. Four re-datings is the signal, and the signal does not mean try harder:

2026-08-24 Mo [priv] GEZ Ummeldung

Diagnosed: this is a topic, not a next action, and it silently contains "find the old Beitragsnummer" plus "find the Meldebescheinigung" plus a form. Every morning I read it, felt the size of it, and moved on — correctly. So it gets rewritten as a chain, with only the current step in the ledger:

- 2026-08-24 Mo [priv] GEZ Ummeldung
+ 2026-08-28 Fr [priv] Ummeldung Schritt 1: Beitragsnummer aus Ordner "Rundfunk" raussuchen → notes/ummeldung.md

That one is executable while half awake, which was the whole test. Note the repair took ten seconds and no willpower — the failure mode is a property of the line, and lines are cheap to rewrite.

Empty the tray, re-date everything in the past to today, reset streak to 1. Do not catch up item by item — that is the trap that makes people abandon the system rather than restart it.

Example — three weeks off, back on Mon 2026-09-21. Flu, then travel. The streak is dead at n=7 and the tray has forty things in it.

The wrong move is to reconstruct the missing three weeks. Instead:

streak: 2026-09-21 Mo  n=1

--- watermarks ---
mail-priv   2026-09-21 Mo   # bankrupted
mail-ev     2026-09-21 Mo
mail-biz    2026-09-21 Mo
chat        2026-09-21 Mo
post        2026-09-21 Mo

--- due ---
2026-09-21 Mo [priv] nächste 10 Briefe aus Tray öffnen (noch ~40)
2026-09-21 Mo [biz]  ?  Rechnung #241 bezahlt? (gestellt 08-18) — sonst Mahnung
2026-09-21 Mo [priv] Versicherung: prüfen ob wechseln (Kündigung)  ‼2026-10-01 Do
2026-09-24 Do [priv] ↻1m  Bank-Postfach checken

Everything overdue is now dated today; the ↻1m line was already in the future and is untouched. Two things survived three weeks of total neglect and are sitting at the top of the list: an unpaid invoice, and an insurance deadline that is still ten days out because it was dated with lead time.

Streak back to 1. Nothing was lost.

Two different problems, two different answers:

Example — Sat 2026-08-15, where the story started. Thirty minutes, once.

Watermarks set to today; roughly 4000 unread messages formally stop existing. Then ten letters off the top of the pile: six junk, four lines — the Krankenkasse form, the Stromabrechnung, the GEZ Ummeldung, the Versicherung with its 10-01 Kündigungsfrist. A DHL Benachrichtigungskarte turns up too: that is the Netzteil, and its Frist is 08-22.

The remaining thirty letters become one line. The resulting ledger is the one shown under State above, and everything in the following two weeks — including the invoice, the Protokoll and the Ummeldung — descends from it.