Entwurf · Issue cf2a3bc
Das Done eines Sprints
Entwurf zu Issue cf2a3bc, Meilenstein 1 und 3 von docs/plans/cf2a3bc-done-belongs-to-its-sprint.md. Die Tabelle unten ruft inCycle beim Rendern auf, statt sein Verhalten zu beschreiben — ändert sich die Regel, ändert sich die Seite.
Das Board teilt die offenen Karten in zwei Sprints und die fertigen in gar nichts. Deshalb steht am zweiten Tag eines Sprints alles in Done, was die vorangegangenen zwei Wochen erledigt haben — und ein Sprint, der noch nichts geschlossen hat, sieht aus wie einer, der den ganzen Zyklus geschafft hat.
Die Frage dieses Kapitels ist nicht, wo man einen Filter einbaut, sondern wovon das Done eines Boards ein Protokoll ist.
01Der Stand heute
Ein Zyklus sind 28 Tage, geteilt in zwei Sprints zu je 14. Beide sind eine Zusage mit einem Enddatum — das Board leitet aus genau diesem Enddatum die Fälligkeit jeder offenen Karte ab.
Für die fertigen Karten gibt es diese Teilung nicht. inCycle vergleicht cycleIndex und wirft die Sprinthälfte weg; ohne ?cycle= in der Adresse ist der Filter null und damit überhaupt keine Grenze. Beides zusammen ergibt diese Tabelle, und sie ist nicht abgeschrieben, sondern gerechnet:
| Karte | geplant in | ohne ?cycle= | ?cycle=2026-09 |
|---|---|---|---|
| Kontoblockgeschlossen im ersten Sprint des laufenden Zyklus | cycle/2026-09.1 | steht in Done | steht in Done |
| Board zeigt eine Seitegeschlossen im laufenden Sprint | cycle/2026-09.2 | steht in Done | steht in Done |
| Pläne im Repogeschlossen in einem früheren Zyklus | cycle/2026-08.2 | steht in Done | — |
Die erste Spalte ist der Fehler: eine Karte aus der ersten Hälfte steht auf dem laufenden Board, als wäre sie eben fertig geworden. Die dritte Zeile zeigt, dass es nicht am Zyklus liegt — auch ein Zyklus weiter zurück fällt durch, solange niemand filtert.
02Zwei mögliche Antworten
Done gehört dem Zyklus. Dann sind die Sprintzeilen der Leiste eine Ansicht auf die offene Arbeit, und die fertige wird pro Zyklus gezählt. Das ist der heutige Code, zu Ende gedacht — und es macht die Zusage eines Sprints unlesbar: wer am 24. August auf das Board sieht, bekommt die Lieferungen der vorangegangenen vierzehn Tage als seine eigenen ausgewiesen.
Done gehört dem Sprint, und das betrachtete Board entscheidet, welchem. Das ist, was ein Sprint bedeutet. Eine Zusage, die die Lieferungen der vorigen Zusage als ihre eigenen meldet, meldet nichts.
Der Entwurf wählt die zweite. Sie kostet keine neue Adresse und keine neue Grammatik: ?cycle=2026-09 wird ohne Hälfte geschrieben, die Leiste verlinkt Zyklen, und ein gefiltertes Board antwortet weiterhin für beide Hälften. Wer einen Zyklus verlangt, bekommt einen Zyklus — so bleibt die fertige Arbeit einer früheren Hälfte erreichbar, sobald das laufende Board sie nicht mehr zeigt.
03Offen und geschlossen werden gegenläufig gelesen
Das ist der Punkt, an dem der Entwurf eine Unsymmetrie behauptet statt sie zu vermeiden:
- Eine offene Karte zeigt nach vorn. Alles, was noch nicht getan ist, ist jetzt relevant — auch das, was in einen noch nicht begonnenen Zyklus geplant wurde. Das ungefilterte Board zeigt sie deshalb weiterhin alle.
- Eine geschlossene Karte zeigt nach hinten. Sie ist das Protokoll eines Zeitraums, und ein Protokoll gehört dem Zeitraum, den es protokolliert.
Der Kommentar über inCycle behauptet heute, geschlossene Karten würden nach dem Ort einsortiert, an dem sie fertig wurden. Das hat der Code nie getan. Er wird ersetzt durch den Satz, der oben steht — die Unsymmetrie ist die Absicht und muss dort nachlesbar sein, wo sie gilt.
04Woher der Moment des Schließens kommt
Eine Grenze allein genügt nicht. Eine Karte, die aus ihrem geplanten Sprint mitgewandert und erst später fertig geworden ist, würde weiterhin dem Sprint gutgeschrieben, der sie nicht fertig gemacht hat — denn einsortiert wird nach placement, also danach, wo geplant wurde. Wo etwas fertig wurde, liest heute nichts. Das Seed-Gate liefert den materialisierten COB — rad cob show in cobsOf — und der trägt genau fünf Schlüssel:
assigneeslabelsstatethreadtitle
Kein Zeitstempel für den Zustandswechsel. Er ist aber billig zu haben: Ein COB ist ein gewöhnlicher Git-Ref, jede Operation ein Commit, und der jüngste Commit mit dem Betreff Lifecycle trägt den Moment als Autorendatum. Nachgesehen werden muss nur bei Issues, deren Zustand ohnehin closed ist — hier vier von sechzig, innerhalb des bestehenden 60-Sekunden-Caches des Gates.
Das ist ein Patch in tessera-infra, und er wird getrennt ausgerollt. Deshalb liest das Board den Moment als optionales Feld: ist er da, entscheidet er; fehlt er, behält die Karte die Einordnung von heute. Das ist kein Übergangsbehelf — ein Gate ist ein fremder Dienst, und ein Leser, der über ein fehlendes Feld stolpert, wäre unabhängig davon der falsche Leser.