Umgesetzt und veröffentlicht (2026-09-20, Commit e07d1ca, Stack 7.0.0-beta.11, im selben
Publish wie #133): docs verify, instructions verify und die volle pytest-Suite (1410 Tests)
grün. Alle Akzeptanzkriterien unten sind erfüllt und abgehakt.
Der SP-Adapter bildet follow_up_at auf remindAt ab und schließt dueDay/dueWithTime
ausdrücklich aus. Die Begründung beruft sich auf #119 D9 („ein eigenes Datum, ausdrücklich nicht das Fälligkeitsdatum"). Die Berufung ist falsch: dueDay/dueWithTime sind bei Super
Productivity nicht das Fälligkeitsdatum.
Der Beleg
src/app/features/tasks/task.model.ts (geprüft gegen master, 2026-09-20) benennt seine Felder
selbst:
Feld
Docstring im Modell
dueDay
„Scheduled date as ISO date string (YYYY-MM-DD). For tasks scheduled for all-day (no specific time)"
dueWithTime
„Scheduled time as Unix timestamp (ms). For tasks scheduled with a specific time"
deadlineDay
„Deadline date as ISO string (YYYY-MM-DD). For deadlines without a specific time"
deadlineWithTime
„Deadline as Unix timestamp (ms). For deadlines with a specific time"
deadlineRemindAt
„Reminder timestamp for the deadline"
Dieselbe Datei führt den Typalias TaskPlannedWithDayOrTime = TaskWithDueTime | TaskWithDueDay.
Das due im Namen liest sich für Außenstehende wie Fälligkeit, meint aber Terminierung; SPs
Fälligkeitsdatum heißt deadline*.
D9 bleibt unverändert gültig — es schließt deadlineDay/deadlineWithTime/deadlineRemindAt
aus, und die bleiben ausgeschlossen. Korrigiert wird allein die Abbildung aus #124.
Warum das mehr ist als eine Begriffsfrage: Prüfung 2 ist heute blind
remindAt existiert nur, wenn eine Aufgabe auf eine Uhrzeit terminiert ist und jemand eine
Benachrichtigung wollte:
src/app/features/reminder/migrate-legacy-task-reminders.util.ts setzt beim Übernehmen eines
Reminders dueWithTime = reminder.remindAt — der Reminder hängt an einer Terminierung mit
Uhrzeit.
task.model.ts führt eigens den Typ TaskWithoutReminder { remindAt: undefined } für
terminierte Aufgaben ohne Erinnerung.
Der Normalfall eines Ticklers — ein waiting-Posten, ganztägig auf den 15. gelegt, ohne
Benachrichtigung — trägt damit dueDay: "2026-10-15" und keinremindAt. Prüfung 2
(tools/chemenu/review.py:175) überspringt ihn wegen follow_up_at is None. Ein korrekt
angelegter Posten fällt still durch. Das ist genau die leise Falschheit, gegen die der Stack sonst
überall anläuft.
Zweite Folge: erst damit wird der Schreibweg möglich
SPs lokale REST-API lässt remindAt nicht schreiben — ALLOWED_TASK_FIELDS
(src/app/core/electron/local-rest-api-handler.service.ts:37) führt es nicht, dueDay und dueWithTime dagegen schon. Mit der korrigierten Abbildung kann #132 einen WAITING-Posten samtfollow_up_at anlegen; mit der heutigen könnte er es nicht, und alle übrigen schreibbaren
Datumsfelder sind Deadline-Felder und damit durch D9 ausgeschlossen.
Was sich am Verhalten ändert
Prüfung 2 schlägt künftig häufiger an, aus zwei Richtungen: das geschlossene Loch (ganztägige
Tickler) und die breitere Abbildung — ein waiting-Posten, der aus einem anderen Grund terminiert
ist, liest sich jetzt als Nachfasstermin.
Das Zweite ist bewusst hingenommen: ein WAITING-Posten ist nichts, was man selbst bearbeitet, sein
Termin ist der Nachfasstermin. Für Prüfung 2 bleibt die Aussage dieselbe — der Termin ist
überschritten.
Bestehende Instanzen sehen dadurch in einem Rückblick mehr Befunde als vorher. Kein Datenverlust,
keine Handarbeit beim Upgrade, also nach instructions/dev/version-parts.md kein Grenzübertritt —
aber ein Changelog-Eintrag, der die Verhaltensänderung ausdrücklich benennt. (Umgesetzt: der
Changelog-Eintrag zu 7.0.0-beta.11 benennt sie, gemeinsam mit #133s eigener Verhaltensänderung
an Prüfung 3.)
Akzeptanzkriterien
SuperProductivityReader.open_items liest follow_up_at als dueWithTime, sonst dueDay —
in dieser Reihenfolge, weil SPs eigene Leseregel sie vorgibt („When reading, check dueWithTime FIRST (it takes priority over dueDay)").
Ein waiting-Posten mit dueDay und ohne remindAt erzeugt einen waiting_overdue-Befund,
sobald die Schwelle überschritten ist. Ein Fixture-Test hält genau diesen Fall fest — er ist
der Grund für dieses Issue.
deadlineDay, deadlineWithTime und deadlineRemindAt werden nie als follow_up_at
gelesen; ein Posten, der nur diese trägt, hat follow_up_at: None. Getestet.
remindAt wird nicht mehr gelesen, und kein Test stützt sich noch darauf.
Der Modul-Docstring von tools/chemenu/tasks/superproductivity.py sagt, welches SP-Feld
das Fälligkeitsdatum ist und warum due* nicht dazugehört — belegt mit dem Wortlaut aus task.model.ts, nicht als Behauptung.
Der D9-Absatz in tools/chemenu/tasks/protocol.py („deliberately not the item's due
date") formuliert die Regel so, dass sie auch einen Provider bindet, dessen Feldnamen anders
liegen als seine Begriffe. Genau dieser Fall ist hier eingetreten.
#128 ist um den korrigierten Wortlaut nachgezogen — es trägt die Regel für den zweiten
Adapter ausgeschrieben.
docs verify, instructions verify, pytest grün. Version gebumpt, mit einem
Changelog-Eintrag, der die Verhaltensänderung an Prüfung 2 benennt.
Abhängigkeiten
Keine blockierenden. Berührungspunkte: #132 (der Schreibweg für follow_up_at hängt daran), #133
(dieselbe Quellcode-Verifikation, inhaltlich unabhängig — beide im selben Publish umgesetzt), #128
(erbt die Regel — Body dort nachgezogen), #119 (Entscheidungsgeschichte, geschlossen — D9 selbst
bleibt gültig, nur #124s Abbildung war falsch).
Umsetzung
chemenu.tasks.superproductivity._follow_up_at: liest dueWithTime, sonst dueDay, nie remindAt/deadline* - geteilt zwischen SuperProductivityReader (Schnappschuss) und dem neuen SuperProductivityApiReader (#133) über eine gemeinsame Modulfunktion. chemenu.tasks.protocol: WaitingItems Docstring trägt jetzt die Korrektur selbst - die Regel bindet den Begriff
Fälligkeitsdatum, nicht einen Feldnamen. tasks/protocol.pys Moduldocstring (die verify()-
Begründung aus #134) korrigiert im selben Zug. Tests: test_superproductivity.py (vier neue follow_up_at-Tests: dueWithTime, dueDay-Fallback, Priorität, nie remindAt/deadline*), test_review.py (test_check2_fires_for_an_all_day_waiting_item_with_no_due_with_time - der
Fixture-Test, der der eigentliche Grund für dieses Issue war). Gitea #128s Body um die Korrektur
nachgezogen. Version: gemeinsam mit #133 auf 7.0.0-beta.11 (MAJOR, dort begründet - #133s
Feldpflicht trägt den Grenzübertritt, nicht diese Änderung für sich allein, die selbst kein
Grenzübertritt wäre). Commit e07d1ca.
**Umgesetzt und veröffentlicht** (2026-09-20, Commit `e07d1ca`, Stack `7.0.0-beta.11`, im selben
Publish wie #133): `docs verify`, `instructions verify` und die volle `pytest`-Suite (1410 Tests)
grün. Alle Akzeptanzkriterien unten sind erfüllt und abgehakt.
Der SP-Adapter bildet `follow_up_at` auf `remindAt` ab und schließt `dueDay`/`dueWithTime`
ausdrücklich aus. Die Begründung beruft sich auf #119 D9 („ein eigenes Datum, ausdrücklich
**nicht** das Fälligkeitsdatum"). Die Berufung ist falsch: `dueDay`/`dueWithTime` sind bei Super
Productivity nicht das Fälligkeitsdatum.
## Der Beleg
`src/app/features/tasks/task.model.ts` (geprüft gegen `master`, 2026-09-20) benennt seine Felder
selbst:
| Feld | Docstring im Modell |
|---|---|
| `dueDay` | „**Scheduled** date as ISO date string (YYYY-MM-DD). For tasks scheduled for all-day (no specific time)" |
| `dueWithTime` | „**Scheduled** time as Unix timestamp (ms). For tasks scheduled with a specific time" |
| `deadlineDay` | „**Deadline** date as ISO string (YYYY-MM-DD). For deadlines without a specific time" |
| `deadlineWithTime` | „**Deadline** as Unix timestamp (ms). For deadlines with a specific time" |
| `deadlineRemindAt` | „Reminder timestamp for the deadline" |
Dieselbe Datei führt den Typalias `TaskPlannedWithDayOrTime = TaskWithDueTime | TaskWithDueDay`.
Das `due` im Namen liest sich für Außenstehende wie Fälligkeit, meint aber Terminierung; SPs
Fälligkeitsdatum heißt `deadline*`.
**D9 bleibt unverändert gültig** — es schließt `deadlineDay`/`deadlineWithTime`/`deadlineRemindAt`
aus, und die bleiben ausgeschlossen. Korrigiert wird allein die Abbildung aus #124.
## Warum das mehr ist als eine Begriffsfrage: Prüfung 2 ist heute blind
`remindAt` existiert nur, wenn eine Aufgabe auf eine **Uhrzeit** terminiert ist **und** jemand eine
Benachrichtigung wollte:
- `src/app/features/reminder/migrate-legacy-task-reminders.util.ts` setzt beim Übernehmen eines
Reminders `dueWithTime = reminder.remindAt` — der Reminder hängt an einer Terminierung mit
Uhrzeit.
- `task.model.ts` führt eigens den Typ `TaskWithoutReminder { remindAt: undefined }` für
terminierte Aufgaben ohne Erinnerung.
Der Normalfall eines Ticklers — ein `waiting`-Posten, ganztägig auf den 15. gelegt, ohne
Benachrichtigung — trägt damit `dueDay: "2026-10-15"` und **kein** `remindAt`. Prüfung 2
(`tools/chemenu/review.py:175`) überspringt ihn wegen `follow_up_at is None`. Ein korrekt
angelegter Posten fällt still durch. Das ist genau die leise Falschheit, gegen die der Stack sonst
überall anläuft.
## Zweite Folge: erst damit wird der Schreibweg möglich
SPs lokale REST-API lässt `remindAt` nicht schreiben — `ALLOWED_TASK_FIELDS`
(`src/app/core/electron/local-rest-api-handler.service.ts:37`) führt es nicht, `dueDay` und
`dueWithTime` dagegen schon. Mit der korrigierten Abbildung kann #132 einen `WAITING`-Posten
**samt** `follow_up_at` anlegen; mit der heutigen könnte er es nicht, und alle übrigen schreibbaren
Datumsfelder sind Deadline-Felder und damit durch D9 ausgeschlossen.
## Was sich am Verhalten ändert
Prüfung 2 schlägt künftig häufiger an, aus zwei Richtungen: das geschlossene Loch (ganztägige
Tickler) und die breitere Abbildung — ein `waiting`-Posten, der aus einem anderen Grund terminiert
ist, liest sich jetzt als Nachfasstermin.
Das Zweite ist bewusst hingenommen: ein WAITING-Posten ist nichts, was man selbst bearbeitet, sein
Termin *ist* der Nachfasstermin. Für Prüfung 2 bleibt die Aussage dieselbe — der Termin ist
überschritten.
Bestehende Instanzen sehen dadurch in einem Rückblick mehr Befunde als vorher. Kein Datenverlust,
keine Handarbeit beim Upgrade, also nach `instructions/dev/version-parts.md` kein Grenzübertritt —
aber ein Changelog-Eintrag, der die Verhaltensänderung ausdrücklich benennt. (Umgesetzt: der
Changelog-Eintrag zu `7.0.0-beta.11` benennt sie, gemeinsam mit #133s eigener Verhaltensänderung
an Prüfung 3.)
## Akzeptanzkriterien
- [x] `SuperProductivityReader.open_items` liest `follow_up_at` als `dueWithTime`, sonst `dueDay` —
in dieser Reihenfolge, weil SPs eigene Leseregel sie vorgibt („When reading, check
`dueWithTime` FIRST (it takes priority over `dueDay`)").
- [x] Ein `waiting`-Posten mit `dueDay` und ohne `remindAt` erzeugt einen `waiting_overdue`-Befund,
sobald die Schwelle überschritten ist. Ein Fixture-Test hält genau diesen Fall fest — er ist
der Grund für dieses Issue.
- [x] `deadlineDay`, `deadlineWithTime` und `deadlineRemindAt` werden nie als `follow_up_at`
gelesen; ein Posten, der nur diese trägt, hat `follow_up_at: None`. Getestet.
- [x] `remindAt` wird nicht mehr gelesen, und kein Test stützt sich noch darauf.
- [x] Der Modul-Docstring von `tools/chemenu/tasks/superproductivity.py` sagt, **welches** SP-Feld
das Fälligkeitsdatum ist und warum `due*` nicht dazugehört — belegt mit dem Wortlaut aus
`task.model.ts`, nicht als Behauptung.
- [x] Der D9-Absatz in `tools/chemenu/tasks/protocol.py` („deliberately **not** the item's due
date") formuliert die Regel so, dass sie auch einen Provider bindet, dessen Feldnamen anders
liegen als seine Begriffe. Genau dieser Fall ist hier eingetreten.
- [x] #128 ist um den korrigierten Wortlaut nachgezogen — es trägt die Regel für den zweiten
Adapter ausgeschrieben.
- [x] `docs verify`, `instructions verify`, `pytest` grün. Version gebumpt, mit einem
Changelog-Eintrag, der die Verhaltensänderung an Prüfung 2 benennt.
## Abhängigkeiten
Keine blockierenden. Berührungspunkte: #132 (der Schreibweg für `follow_up_at` hängt daran), #133
(dieselbe Quellcode-Verifikation, inhaltlich unabhängig — beide im selben Publish umgesetzt), #128
(erbt die Regel — Body dort nachgezogen), #119 (Entscheidungsgeschichte, geschlossen — D9 selbst
bleibt gültig, nur #124s Abbildung war falsch).
## Umsetzung
`chemenu.tasks.superproductivity._follow_up_at`: liest `dueWithTime`, sonst `dueDay`, nie
`remindAt`/`deadline*` - geteilt zwischen `SuperProductivityReader` (Schnappschuss) und dem neuen
`SuperProductivityApiReader` (#133) über eine gemeinsame Modulfunktion. `chemenu.tasks.protocol`:
`WaitingItem`s Docstring trägt jetzt die Korrektur selbst - die Regel bindet den *Begriff*
Fälligkeitsdatum, nicht einen Feldnamen. `tasks/protocol.py`s Moduldocstring (die `verify()`-
Begründung aus #134) korrigiert im selben Zug. Tests: `test_superproductivity.py` (vier neue
`follow_up_at`-Tests: `dueWithTime`, `dueDay`-Fallback, Priorität, nie `remindAt`/`deadline*`),
`test_review.py` (`test_check2_fires_for_an_all_day_waiting_item_with_no_due_with_time` - der
Fixture-Test, der der eigentliche Grund für dieses Issue war). Gitea #128s Body um die Korrektur
nachgezogen. Version: gemeinsam mit #133 auf `7.0.0-beta.11` (MAJOR, dort begründet - #133s
Feldpflicht trägt den Grenzübertritt, nicht diese Änderung für sich allein, die selbst kein
Grenzübertritt wäre). Commit `e07d1ca`.
Umgesetzt und veröffentlicht: Commit e07d1ca, Stack 7.0.0-beta.11 (im selben Publish wie #133). docs verify, instructions verify, pytest (1410 Tests) grün. Body oben auf den Endzustand nachgezogen, alle Akzeptanzkriterien abgehakt, inklusive #128s nachgezogener Regel-1-Korrektur.
Umgesetzt und veröffentlicht: Commit `e07d1ca`, Stack `7.0.0-beta.11` (im selben Publish wie #133). `docs verify`, `instructions verify`, `pytest` (1410 Tests) grün. Body oben auf den Endzustand nachgezogen, alle Akzeptanzkriterien abgehakt, inklusive #128s nachgezogener Regel-1-Korrektur.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Umgesetzt und veröffentlicht (2026-09-20, Commit
e07d1ca, Stack7.0.0-beta.11, im selbenPublish wie #133):
docs verify,instructions verifyund die vollepytest-Suite (1410 Tests)grün. Alle Akzeptanzkriterien unten sind erfüllt und abgehakt.
Der SP-Adapter bildet
follow_up_ataufremindAtab und schließtdueDay/dueWithTimeausdrücklich aus. Die Begründung beruft sich auf #119 D9 („ein eigenes Datum, ausdrücklich
nicht das Fälligkeitsdatum"). Die Berufung ist falsch:
dueDay/dueWithTimesind bei SuperProductivity nicht das Fälligkeitsdatum.
Der Beleg
src/app/features/tasks/task.model.ts(geprüft gegenmaster, 2026-09-20) benennt seine Felderselbst:
dueDaydueWithTimedeadlineDaydeadlineWithTimedeadlineRemindAtDieselbe Datei führt den Typalias
TaskPlannedWithDayOrTime = TaskWithDueTime | TaskWithDueDay.Das
dueim Namen liest sich für Außenstehende wie Fälligkeit, meint aber Terminierung; SPsFälligkeitsdatum heißt
deadline*.D9 bleibt unverändert gültig — es schließt
deadlineDay/deadlineWithTime/deadlineRemindAtaus, und die bleiben ausgeschlossen. Korrigiert wird allein die Abbildung aus #124.
Warum das mehr ist als eine Begriffsfrage: Prüfung 2 ist heute blind
remindAtexistiert nur, wenn eine Aufgabe auf eine Uhrzeit terminiert ist und jemand eineBenachrichtigung wollte:
src/app/features/reminder/migrate-legacy-task-reminders.util.tssetzt beim Übernehmen einesReminders
dueWithTime = reminder.remindAt— der Reminder hängt an einer Terminierung mitUhrzeit.
task.model.tsführt eigens den TypTaskWithoutReminder { remindAt: undefined }fürterminierte Aufgaben ohne Erinnerung.
Der Normalfall eines Ticklers — ein
waiting-Posten, ganztägig auf den 15. gelegt, ohneBenachrichtigung — trägt damit
dueDay: "2026-10-15"und keinremindAt. Prüfung 2(
tools/chemenu/review.py:175) überspringt ihn wegenfollow_up_at is None. Ein korrektangelegter Posten fällt still durch. Das ist genau die leise Falschheit, gegen die der Stack sonst
überall anläuft.
Zweite Folge: erst damit wird der Schreibweg möglich
SPs lokale REST-API lässt
remindAtnicht schreiben —ALLOWED_TASK_FIELDS(
src/app/core/electron/local-rest-api-handler.service.ts:37) führt es nicht,dueDayunddueWithTimedagegen schon. Mit der korrigierten Abbildung kann #132 einenWAITING-Postensamt
follow_up_atanlegen; mit der heutigen könnte er es nicht, und alle übrigen schreibbarenDatumsfelder sind Deadline-Felder und damit durch D9 ausgeschlossen.
Was sich am Verhalten ändert
Prüfung 2 schlägt künftig häufiger an, aus zwei Richtungen: das geschlossene Loch (ganztägige
Tickler) und die breitere Abbildung — ein
waiting-Posten, der aus einem anderen Grund terminiertist, liest sich jetzt als Nachfasstermin.
Das Zweite ist bewusst hingenommen: ein WAITING-Posten ist nichts, was man selbst bearbeitet, sein
Termin ist der Nachfasstermin. Für Prüfung 2 bleibt die Aussage dieselbe — der Termin ist
überschritten.
Bestehende Instanzen sehen dadurch in einem Rückblick mehr Befunde als vorher. Kein Datenverlust,
keine Handarbeit beim Upgrade, also nach
instructions/dev/version-parts.mdkein Grenzübertritt —aber ein Changelog-Eintrag, der die Verhaltensänderung ausdrücklich benennt. (Umgesetzt: der
Changelog-Eintrag zu
7.0.0-beta.11benennt sie, gemeinsam mit #133s eigener Verhaltensänderungan Prüfung 3.)
Akzeptanzkriterien
SuperProductivityReader.open_itemsliestfollow_up_atalsdueWithTime, sonstdueDay—in dieser Reihenfolge, weil SPs eigene Leseregel sie vorgibt („When reading, check
dueWithTimeFIRST (it takes priority overdueDay)").waiting-Posten mitdueDayund ohneremindAterzeugt einenwaiting_overdue-Befund,sobald die Schwelle überschritten ist. Ein Fixture-Test hält genau diesen Fall fest — er ist
der Grund für dieses Issue.
deadlineDay,deadlineWithTimeunddeadlineRemindAtwerden nie alsfollow_up_atgelesen; ein Posten, der nur diese trägt, hat
follow_up_at: None. Getestet.remindAtwird nicht mehr gelesen, und kein Test stützt sich noch darauf.tools/chemenu/tasks/superproductivity.pysagt, welches SP-Felddas Fälligkeitsdatum ist und warum
due*nicht dazugehört — belegt mit dem Wortlaut austask.model.ts, nicht als Behauptung.tools/chemenu/tasks/protocol.py(„deliberately not the item's duedate") formuliert die Regel so, dass sie auch einen Provider bindet, dessen Feldnamen anders
liegen als seine Begriffe. Genau dieser Fall ist hier eingetreten.
Adapter ausgeschrieben.
docs verify,instructions verify,pytestgrün. Version gebumpt, mit einemChangelog-Eintrag, der die Verhaltensänderung an Prüfung 2 benennt.
Abhängigkeiten
Keine blockierenden. Berührungspunkte: #132 (der Schreibweg für
follow_up_athängt daran), #133(dieselbe Quellcode-Verifikation, inhaltlich unabhängig — beide im selben Publish umgesetzt), #128
(erbt die Regel — Body dort nachgezogen), #119 (Entscheidungsgeschichte, geschlossen — D9 selbst
bleibt gültig, nur #124s Abbildung war falsch).
Umsetzung
chemenu.tasks.superproductivity._follow_up_at: liestdueWithTime, sonstdueDay, nieremindAt/deadline*- geteilt zwischenSuperProductivityReader(Schnappschuss) und dem neuenSuperProductivityApiReader(#133) über eine gemeinsame Modulfunktion.chemenu.tasks.protocol:WaitingItems Docstring trägt jetzt die Korrektur selbst - die Regel bindet den BegriffFälligkeitsdatum, nicht einen Feldnamen.
tasks/protocol.pys Moduldocstring (dieverify()-Begründung aus #134) korrigiert im selben Zug. Tests:
test_superproductivity.py(vier neuefollow_up_at-Tests:dueWithTime,dueDay-Fallback, Priorität, nieremindAt/deadline*),test_review.py(test_check2_fires_for_an_all_day_waiting_item_with_no_due_with_time- derFixture-Test, der der eigentliche Grund für dieses Issue war). Gitea #128s Body um die Korrektur
nachgezogen. Version: gemeinsam mit #133 auf
7.0.0-beta.11(MAJOR, dort begründet - #133sFeldpflicht trägt den Grenzübertritt, nicht diese Änderung für sich allein, die selbst kein
Grenzübertritt wäre). Commit
e07d1ca.Umgesetzt und veröffentlicht: Commit
e07d1ca, Stack7.0.0-beta.11(im selben Publish wie #133).docs verify,instructions verify,pytest(1410 Tests) grün. Body oben auf den Endzustand nachgezogen, alle Akzeptanzkriterien abgehakt, inklusive #128s nachgezogener Regel-1-Korrektur.torben referenced this issue2026-09-23 15:45:37 +00:00