Ein Ingest, zwei Schichten: die Seite ablegen und die Verpflichtung im Tracker anlegen #132

Closed
opened 2026-09-20 10:19:17 +00:00 by torben · 5 comments
Owner

Eine Quelle kann beides tragen — Wissen und eine Verpflichtung. Bis zu diesem Paket konnte der
Ingest nur die erste Hälfte: der Schreibpfad in den Tracker kannte genau ein Kommando, und das legte
ein Projekt an, keinen Posten.

Umgesetzt und ausgeliefert mit Stack 7.0.0-beta.12, Commit cfbe3ea (2026-09-20).

Was es jetzt gibt

wikitool task new legt einen Posten im Tracker an, ohne jede kb/-Seite:

wikitool task new --title "<Titel>" (--project "<Name>" | --inbox) \
  [--waiting [--follow-up-at YYYY-MM-DD]] [--notes "<Freitext>"]

Darunter liegt TaskWriter.create_item(title, *, project_name, waiting, follow_up_at, notes) -
die zweite Methode des Schreibprotokolls neben create_project, umgesetzt im
Super-Productivity-Adapter über POST /tasks. Der Ingest-Skill fragt in Schritt 5 jetzt auch nach
einer Verpflichtung und legt sie, falls bestätigt, vor der Quellenseite an.

Damit gibt es einen zweiten Schreibweg in den Tracker in derselben Haltung wie der erste: nichts
wird gelesen und nichts abgeglichen, es wird einmal etwas hineingeschrieben. Die
Zwei-Schichten-Trennung bleibt unberührt - der Posten lebt ausschließlich im Tracker, keine
kb/-Seite trägt einen Aufgabenzustand, und ein Agent hat weiterhin keinen Anlass, die
Aufgabenliste außerhalb des Wochenrückblicks zu lesen.

Fallbeispiel, an dem das Paket entworfen wurde

Ein Kunde reklamiert per Mail. Die Mail geht nach incoming/. Chemenu legt daraus

  1. die Reklamation inhaltlich ab, verknüpft mit dem zugehörigen Projekt, und
  2. die Verpflichtung, das Ganze nachzufassen, als Posten im Tracker.

Das ist kein Sonderfall, sondern der Normalfall für alles, was von außen hereinkommt und nicht bloß
Lesestoff ist: eine Mail, ein Protokoll, ein Angebot, ein Prüfbericht. Jedes davon hinterlässt etwas
zu wissen und etwas zu tun. Die ursprüngliche Frage „was geht wohin — kb/, kb/gtd/ oder
Tracker" war richtig gestellt und falsch beantwortet: die Ziele schließen sich nicht aus.

Die Entscheidungen

D1 — Ein zweites Schreibkommando, bewusst schmal

Ein Posten trägt: Projekt (oder Eingang), Titel, optional WAITING mit follow_up_at, optional
einen Freitext-Rückverweis. Kein Fälligkeitsdatum, kein Aufwand, keine Zuständigkeit - die Regel
aus #128 gilt unverändert: ein gemeinsames Modell, das je Provider verschieden viel weiß, ist kein
gemeinsames Modell. Die Methode bindet jeden künftigen Adapter, also auch #128, bevor er existiert.

D2 — Der Mensch klärt, der Agent schlägt vor: eine Frage im Skill, kein Gate

Eine Verpflichtung, die niemand eingegangen ist, ist schlimmer als eine vergessene: sie sieht aus
wie ein Commitment, steht in der Liste und wird beim nächsten Rückblick als echter offener Posten
behandelt. GTDs Clarify ist eine menschliche Entscheidung und wird nicht aus einer Mail erraten.

Kein eigenes Gate im Code, sondern eine Frage im Skill. Ein Gate ist für Unumkehrbares und
Massenhaftes da (docs/why-gates-are-code.md); ein einzelner Posten ist beides nicht - new hat
aus demselben Grund keines, und ein Gate, das bei jedem Ingest feuerte, wäre genau das reflexhaft
Geräumte. Die Verbindlichkeit liegt darin, dass der Agent das Kommando mit einem vom Nutzer
bestätigten Titel aufruft.

Ausdrücklich ohne Auflage an #112 (Betreiber, 2026-09-20): die Gegenposition — läuft der
Ingest-Weg irgendwann unbeaufsichtigt, fehlt genau die Skill-Ebene — besteht fort und ist hier
nicht adressiert. Wer einen unbeaufsichtigten Stapellauf spezifiziert, stellt die Frage dort neu.

D3 — Reihenfolge: Tracker vor Seite

Entscheidend ist, welcher Zwischenzustand entdeckt wird:

  • Posten angelegt, Seite scheitert → die Rohdatei bleibt ohne Quellenseite, und das meldet lint
    als uncovered_raw_files.
  • Seite angelegt, Posten scheitert → nichts meldet das. Die Verpflichtung ist still verloren,
    und sie ist die dringlichere Hälfte.

Umgesetzt als Schrittfolge im Ingest-Skill: task new in Schritt 5, Quellenseite in Schritt 6. Die
Beförderung nach raw/ (Schritt 1) blieb, wo sie war - dazu #136, siehe § Was bewusst offen
blieb.

D4 — Fehlt das Projekt, hält der Ingest an und fragt: drei Wege, kein Default

Existiert weder eine Projektseite noch ein Tracker-Projekt, rät der Agent nicht: er hält an und legt
drei Wege vor - ein vorhandenes Projekt benennen, new project (hält den Ingest auf jeder Instanz
an, weil kein Provider ein Tracker-Projekt selbst anlegen kann), oder in den Eingang des
Trackers
als ausdrücklich gewählte Notausfahrt.

Der Eingang ist nie ein Default, nur eine Wahl, und der Skill nennt beim Anbieten ihre Kosten:
ein Posten ohne Projekt ist für den Rückblick unerreichbar (siehe § Der Rückblick erreicht Posten
nur über ihr Projekt). Der Unterschied zwischen dieser Route und einem Default ist der ganze Punkt:
ein Mensch, der sie wählt, weiß, dass der Posten außer Sicht liegt; ein Default hätte es ihm
verschwiegen. Deshalb hat sie eine eigene Form am Kommando (--inbox) - ein weggelassenes
--project ist ein Fehler, keine stille Eingangs-Ablage.

D5 — Der Rückverweis auf die Seite ist Freitext und wird nie geparst

Genau die Haltung, die WaitingItem.title schon hat. Ein maschinenlesbarer Verweis wäre eine zweite
Kopplung neben dem Projektnamen und damit etwas, das auseinanderlaufen kann -
docs/knowledge-and-commitment.md § „One name, carrying the duties of an identifier" ist die
Begründung, warum es bei einer bleibt. Umgesetzt über notes.

D6 — Die Projekterkennung schlägt vor, sie ordnet nicht zu

Vorschlag per search im Skill, Bestätigung durch den Nutzer, keine automatische Zuordnung, auch
nicht bei einem eindeutigen Treffer
. Der Join bleibt exakte, case-normalisierte Gleichheit
(normalize_project_name); eine unscharfe Zuordnung wäre eine zweite, schwächere Matching-Regel
daneben, und rät sie falsch, landet die Verpflichtung in einem fremden Projekt, wo sie gültig
aussieht und von keiner Prüfung je auffällt. Ein falscher Treffer ist teurer als ein ausgebliebener.
Das Suchen blieb deshalb beim Skill: das Kommando sucht nicht selbst.

Ein Dialogschritt, nicht drei

D2, D4 und D6 verlangen dieselbe menschliche Auskunft an derselben Stelle des Laufs und sind in der
Umsetzung auf einen Bestätigungsschritt zusammengefallen: der Skill legt Titel und
vorgeschlagenes Projekt gemeinsam als Frage vor, die Antwort ist eine Bestätigung, eine Korrektur
oder einer der drei Wege aus D4, danach ein Kommandoaufruf.

Gegen den Quellcode verifiziert (super-productivity/super-productivity@master, 2026-09-20)

  • POST /tasks existiert (src/app/core/electron/local-rest-api-handler.service.ts).
    Schreibbar sind ausschließlich die Felder in ALLOWED_TASK_FIELDS: title, notes, isDone,
    timeEstimate, timeSpent, projectId, tagIds, dueDay, dueWithTime, plannedAt,
    deadlineDay, deadlineWithTime, deadlineRemindAt. Alles andere wirft pickAllowedFields
    still weg. Der Fall, der create_project zu Exit 42 zwingt, tritt hier also nicht ein.
  • Der waiting-Tag muss schon existieren. tagIds ist schreibbar, Tags sind über die API nicht
    anlegbar (GET /tags ist die einzige Tag-Route). Umgesetzt: die Tag-Auflösung läuft vor dem
    einen POST, sodass nie ein Posten ohne seinen Status entsteht.
  • follow_up_at wird als dueDay geschrieben - die Spiegelung der mit #135 korrigierten
    Leseregel (dueWithTime, sonst dueDay; nie deadline*).
  • Ein Posten landet nie im Backlog (isAddToBacklog fest false). Für dieses Paket ohne
    Folgen - Someday/Maybe wird hier nicht geschrieben -, aber es ist die Grenze des Schreibwegs.
  • Der Eingang erscheint nicht in GET /projects. INBOX_PROJECT ist zwar immer ein echtes
    Projekt-Entity im Store (_addInboxProjectIfNecessary legt es an, falls es fehlt), aber
    selectUnarchivedProjects - der Selektor hinter GET /projects - filtert es unbedingt über seine
    feste id heraus (p.id !== INBOX_PROJECT.id, project.selectors.ts/project.const.ts).
    Folge: Prüfung 3 (unpaged_project_weeks) braucht keine Ausnahme für den Eingang - er
    taucht in tracker_projects nie auf, es gibt nichts auszunehmen. Der Adapter schreibt die feste
    id deshalb explizit (INBOX_PROJECT_ID), statt projectId wegzulassen: ohne Angabe fällt Super
    Productivity auf den gerade aktiven Work Context zurück, also auf das zufällig geöffnete Projekt.

Der Rückblick erreicht Posten nur über ihr Projekt

run_review erreicht Posten ausschließlich über projects() → open_items(project.name)
(tools/chemenu/review.py). Ein Posten ohne Projekt ist für den Rückblick unsichtbar - es
bleibt kein Befund aus, es entsteht schlicht nie einer. Kein Argument gegen den Eingang als
Ablageort, sondern eines dafür, dass diese Route ihre Kosten beim Anbieten nennt statt beim
Vermissen (D4); der Ingest-Skill tut das.

Akzeptanzkriterien

  • Ein Posten lässt sich über wikitool in einem benannten Tracker-Projekt anlegen, optional als
    WAITING mit follow_up_at und mit einem Freitext-Rückverweis in notes; gegen Fixtures
    getestet, kein Test braucht eine laufende Super-Productivity-Instanz.
  • Der Posten taucht anschließend in wikitool review auf: als offener Posten des Projekts, und
    bei gesetztem follow_up_at nach Ablauf der Schwelle in Prüfung 2 - über den Lesepfad
    getestet, angelegt und wiedergelesen
    (test_created_item_appears_in_review_as_an_open_and_overdue_waiting_item).
  • Fehlt der waiting-Tag im Tracker, scheitert die Anlage eines WAITING-Postens laut; es
    entsteht kein Posten ohne seinen Status. Getestet auf beiden Ebenen (Adapter und Kommando),
    jeweils mit der Zusicherung, dass kein POST abgesetzt wurde.
  • Die Eingangs-Route hat eine eigene Form am Kommando (--inbox); ein weggelassenes --project
    ist ein Fehler, keine stille Eingangs-Ablage. Getestet, in beiden Richtungen (keines von
    beiden angegeben, und beide zugleich).
  • Verifiziert beim Bauen: der Eingang erscheint nicht in GET /projects - siehe
    § Gegen den Quellcode verifiziert. Prüfung 3 braucht folglich keine Ausnahme, und der Skill
    sagt beim Anbieten der Route ausdrücklich, dass review den Posten nicht sieht.
  • Der Schreibweg steht nur einer Instanz mit access: api zur Verfügung; auf einer
    snapshot-Instanz gibt es ihn nicht (test_snapshot_access_has_no_write_path, exit 1 mit
    Verweis auf die api-Instanz).
  • Ein Adapter kann den Schreibweg nicht anbieten, ohne dass der Lesepfad berührt wird -
    create_item ist eine zweite TaskWriter-Methode, unverändert getrennt von TaskReader.
  • Keine Seite trägt nach dem Lauf einen Aufgabenzustand. Durch Bauart erfüllt: task new
    schreibt nirgends eine Seite.
  • Kein Skill und keine Instruction nennt den Provider. test_gtd_weekly_review_skill_names_no_provider
    ist zu test_task_tracker_skills_name_no_provider geworden und läuft parametrisiert über
    gtd-weekly-review und wiki-ingest.
  • Das Kommando ordnet kein Projekt selbst zu: es nimmt den Namen als Angabe, sucht nicht und
    vergleicht nicht unscharf. Der Ingest-Skill legt Titel und vorgeschlagenes Projekt in einem
    Schritt als Frage vor, und die drei Wege aus D4 stehen dort benannt.
  • Nachgezogen: docs/knowledge-and-commitment.md, tools/CONTRACT.md (Kommandotabelle und
    Fehlervertrag), der Ingest-Skill, README.md und INSTALL.md (beide nannten bislang nur
    new project als Schreibweg), sowie #128 um das Kriterium, dass ein Azure-DevOps-Adapter
    create_item mitliefert. types/project.md und kb/gtd/COLLECTION.md blieben unverändert
    - beide beschreiben nur die Seite und ihr Frontmatter, nie einen Schreibweg, also gab es dort
    nichts nachzuziehen.
  • docs verify, instructions verify, pytest grün; Version gebumpt (--minor, neues Kommando
    plus Protokollerweiterung, beidseitig drop-in).
  • Scheitert die Anlage des Postens, ist keine Seite geschrieben und keine Rohdatei
    befördert
    — zur einen Hälfte erfüllt, zur anderen bewusst abgetrennt. „Keine Seite"
    ist durch Bauart erfüllt (task new rührt raw//kb/ nie an) und durch die Schrittfolge im
    Skill gesichert (Posten in Schritt 5, Seite in Schritt 6); „keine Rohdatei befördert" ist es
    nicht, weil raw accept weiterhin Schritt 1 des Ingest ist und damit vor der
    Verpflichtungserkennung läuft. Das ist der von lint/sources coverage ohnehin gemeldete
    Zustand „Rohdatei ohne Quellenseite", also genau der entdeckte Zwischenzustand, den D3 als
    den akzeptablen benennt. Ob die Beförderung trotzdem hinter die Verpflichtungsentscheidung
    rücken soll, ist eine Änderung am Anfang jedes Ingest-Laufs und damit eine eigene
    Entscheidung: #136.

Was bewusst offen blieb

  • #136 — soll raw accept hinter die Verpflichtungsentscheidung rücken? Siehe das gestrichene
    Kriterium oben.
  • #112 — die Gegenposition zu D2 (unbeaufsichtigter Ingest) ist notiert und nicht gebaut; dieses
    Paket setzt sie nicht voraus.

Verifiziert

  • pytest: 1429 Tests grün (davon neu: 6 Adapter-Tests in test_superproductivity.py, 12
    Kommando-Tests in test_task_cmd.py, der parametrisierte Skill-Regressionstest).
  • tools/wikitool docs verify: grün, 58 dokumentierte Kommandos, keine Issue-Referenzen in 78
    ausgelieferten Dokumenten.
  • tools/wikitool instructions verify: grün, 23 Instructions und 8 Skills, 16 publizierte Kopien
    deckungsgleich.
  • Ausgeliefert als Commit cfbe3ea auf origin/main, Stack 7.0.0-beta.12; der Nachzug an
    README.md/INSTALL.md folgte im Abschluss-Commit derselben Arbeit.

Berührungspunkte

#128 (der zweite Adapter muss create_item mitliefern — dort eingetragen), #133 (der Schreibweg
setzt access: api voraus), #135 (Voraussetzung für den follow_up_at-Teil, eingearbeitet),
#136 (die abgetrennte Reihenfolgefrage), #112 (unbeaufsichtigter Ingest), #131 (die Leserichtung).

Eine Quelle kann beides tragen — Wissen **und** eine Verpflichtung. Bis zu diesem Paket konnte der Ingest nur die erste Hälfte: der Schreibpfad in den Tracker kannte genau ein Kommando, und das legte ein Projekt an, keinen Posten. **Umgesetzt und ausgeliefert** mit Stack `7.0.0-beta.12`, Commit `cfbe3ea` (2026-09-20). ## Was es jetzt gibt `wikitool task new` legt **einen Posten im Tracker an, ohne jede `kb/`-Seite**: ``` wikitool task new --title "<Titel>" (--project "<Name>" | --inbox) \ [--waiting [--follow-up-at YYYY-MM-DD]] [--notes "<Freitext>"] ``` Darunter liegt `TaskWriter.create_item(title, *, project_name, waiting, follow_up_at, notes)` - die zweite Methode des Schreibprotokolls neben `create_project`, umgesetzt im Super-Productivity-Adapter über `POST /tasks`. Der Ingest-Skill fragt in Schritt 5 jetzt auch nach einer Verpflichtung und legt sie, falls bestätigt, **vor** der Quellenseite an. Damit gibt es einen zweiten Schreibweg in den Tracker in derselben Haltung wie der erste: nichts wird gelesen und nichts abgeglichen, es wird einmal etwas hineingeschrieben. Die Zwei-Schichten-Trennung bleibt unberührt - der Posten lebt ausschließlich im Tracker, keine `kb/`-Seite trägt einen Aufgabenzustand, und ein Agent hat weiterhin keinen Anlass, die Aufgabenliste außerhalb des Wochenrückblicks zu lesen. ## Fallbeispiel, an dem das Paket entworfen wurde Ein Kunde reklamiert per Mail. Die Mail geht nach `incoming/`. Chemenu legt daraus 1. die Reklamation **inhaltlich** ab, verknüpft mit dem zugehörigen Projekt, und 2. die **Verpflichtung**, das Ganze nachzufassen, als Posten im Tracker. Das ist kein Sonderfall, sondern der Normalfall für alles, was von außen hereinkommt und nicht bloß Lesestoff ist: eine Mail, ein Protokoll, ein Angebot, ein Prüfbericht. Jedes davon hinterlässt etwas zu wissen und etwas zu tun. Die ursprüngliche Frage „was geht wohin — `kb/`, `kb/gtd/` oder Tracker" war richtig gestellt und falsch beantwortet: die Ziele schließen sich nicht aus. ## Die Entscheidungen ### D1 — Ein zweites Schreibkommando, bewusst schmal Ein Posten trägt: Projekt (oder Eingang), Titel, optional `WAITING` mit `follow_up_at`, optional einen Freitext-Rückverweis. **Kein Fälligkeitsdatum, kein Aufwand, keine Zuständigkeit** - die Regel aus #128 gilt unverändert: ein gemeinsames Modell, das je Provider verschieden viel weiß, ist kein gemeinsames Modell. Die Methode bindet jeden künftigen Adapter, also auch #128, bevor er existiert. ### D2 — Der Mensch klärt, der Agent schlägt vor: eine Frage im Skill, kein Gate Eine Verpflichtung, die niemand eingegangen ist, ist schlimmer als eine vergessene: sie sieht aus wie ein Commitment, steht in der Liste und wird beim nächsten Rückblick als echter offener Posten behandelt. GTDs *Clarify* ist eine menschliche Entscheidung und wird nicht aus einer Mail erraten. **Kein eigenes Gate im Code, sondern eine Frage im Skill.** Ein Gate ist für Unumkehrbares und Massenhaftes da (`docs/why-gates-are-code.md`); ein einzelner Posten ist beides nicht - `new` hat aus demselben Grund keines, und ein Gate, das bei jedem Ingest feuerte, wäre genau das reflexhaft Geräumte. Die Verbindlichkeit liegt darin, dass der Agent das Kommando mit einem vom Nutzer bestätigten Titel aufruft. **Ausdrücklich ohne Auflage an #112** (Betreiber, 2026-09-20): die Gegenposition — läuft der Ingest-Weg irgendwann unbeaufsichtigt, fehlt genau die Skill-Ebene — besteht fort und ist hier nicht adressiert. Wer einen unbeaufsichtigten Stapellauf spezifiziert, stellt die Frage dort neu. ### D3 — Reihenfolge: Tracker vor Seite Entscheidend ist, welcher Zwischenzustand *entdeckt* wird: - Posten angelegt, Seite scheitert → die Rohdatei bleibt ohne Quellenseite, und das meldet `lint` als `uncovered_raw_files`. - Seite angelegt, Posten scheitert → **nichts meldet das.** Die Verpflichtung ist still verloren, und sie ist die dringlichere Hälfte. Umgesetzt als Schrittfolge im Ingest-Skill: `task new` in Schritt 5, Quellenseite in Schritt 6. Die Beförderung nach `raw/` (Schritt 1) blieb, wo sie war - dazu **#136**, siehe § Was bewusst offen blieb. ### D4 — Fehlt das Projekt, hält der Ingest an und fragt: drei Wege, kein Default Existiert weder eine Projektseite noch ein Tracker-Projekt, rät der Agent nicht: er hält an und legt drei Wege vor - ein vorhandenes Projekt benennen, `new project` (hält den Ingest auf jeder Instanz an, weil kein Provider ein Tracker-Projekt selbst anlegen kann), oder **in den Eingang des Trackers** als ausdrücklich gewählte Notausfahrt. Der Eingang ist **nie ein Default, nur eine Wahl**, und der Skill nennt beim Anbieten ihre Kosten: ein Posten ohne Projekt ist für den Rückblick unerreichbar (siehe § Der Rückblick erreicht Posten nur über ihr Projekt). Der Unterschied zwischen dieser Route und einem Default ist der ganze Punkt: ein Mensch, der sie wählt, weiß, dass der Posten außer Sicht liegt; ein Default hätte es ihm verschwiegen. Deshalb hat sie eine eigene Form am Kommando (`--inbox`) - ein weggelassenes `--project` ist ein Fehler, keine stille Eingangs-Ablage. ### D5 — Der Rückverweis auf die Seite ist Freitext und wird nie geparst Genau die Haltung, die `WaitingItem.title` schon hat. Ein maschinenlesbarer Verweis wäre eine zweite Kopplung neben dem Projektnamen und damit etwas, das auseinanderlaufen kann - `docs/knowledge-and-commitment.md` § „One name, carrying the duties of an identifier" ist die Begründung, warum es bei einer bleibt. Umgesetzt über `notes`. ### D6 — Die Projekterkennung schlägt vor, sie ordnet nicht zu Vorschlag per `search` im Skill, Bestätigung durch den Nutzer, **keine automatische Zuordnung, auch nicht bei einem eindeutigen Treffer**. Der Join bleibt exakte, case-normalisierte Gleichheit (`normalize_project_name`); eine unscharfe Zuordnung wäre eine zweite, schwächere Matching-Regel daneben, und rät sie falsch, landet die Verpflichtung in einem fremden Projekt, wo sie gültig aussieht und von keiner Prüfung je auffällt. Ein falscher Treffer ist teurer als ein ausgebliebener. Das Suchen blieb deshalb beim Skill: **das Kommando sucht nicht selbst.** ### Ein Dialogschritt, nicht drei D2, D4 und D6 verlangen dieselbe menschliche Auskunft an derselben Stelle des Laufs und sind in der Umsetzung auf **einen** Bestätigungsschritt zusammengefallen: der Skill legt Titel und vorgeschlagenes Projekt gemeinsam als Frage vor, die Antwort ist eine Bestätigung, eine Korrektur oder einer der drei Wege aus D4, danach ein Kommandoaufruf. ## Gegen den Quellcode verifiziert (`super-productivity/super-productivity@master`, 2026-09-20) - **`POST /tasks` existiert** (`src/app/core/electron/local-rest-api-handler.service.ts`). Schreibbar sind ausschließlich die Felder in `ALLOWED_TASK_FIELDS`: `title`, `notes`, `isDone`, `timeEstimate`, `timeSpent`, `projectId`, `tagIds`, `dueDay`, `dueWithTime`, `plannedAt`, `deadlineDay`, `deadlineWithTime`, `deadlineRemindAt`. Alles andere wirft `pickAllowedFields` still weg. Der Fall, der `create_project` zu Exit 42 zwingt, tritt hier also nicht ein. - **Der `waiting`-Tag muss schon existieren.** `tagIds` ist schreibbar, Tags sind über die API nicht anlegbar (`GET /tags` ist die einzige Tag-Route). Umgesetzt: die Tag-Auflösung läuft **vor** dem einen `POST`, sodass nie ein Posten ohne seinen Status entsteht. - **`follow_up_at` wird als `dueDay` geschrieben** - die Spiegelung der mit #135 korrigierten Leseregel (`dueWithTime`, sonst `dueDay`; nie `deadline*`). - **Ein Posten landet nie im Backlog** (`isAddToBacklog` fest `false`). Für dieses Paket ohne Folgen - Someday/Maybe wird hier nicht geschrieben -, aber es ist die Grenze des Schreibwegs. - **Der Eingang erscheint nicht in `GET /projects`.** `INBOX_PROJECT` ist zwar immer ein echtes Projekt-Entity im Store (`_addInboxProjectIfNecessary` legt es an, falls es fehlt), aber `selectUnarchivedProjects` - der Selektor hinter `GET /projects` - filtert es unbedingt über seine feste id heraus (`p.id !== INBOX_PROJECT.id`, `project.selectors.ts`/`project.const.ts`). **Folge:** Prüfung 3 (`unpaged_project_weeks`) braucht **keine** Ausnahme für den Eingang - er taucht in `tracker_projects` nie auf, es gibt nichts auszunehmen. Der Adapter schreibt die feste id deshalb explizit (`INBOX_PROJECT_ID`), statt `projectId` wegzulassen: ohne Angabe fällt Super Productivity auf den gerade aktiven Work Context zurück, also auf das zufällig geöffnete Projekt. ## Der Rückblick erreicht Posten nur über ihr Projekt `run_review` erreicht Posten ausschließlich über `projects()` → `open_items(project.name)` (`tools/chemenu/review.py`). Ein Posten **ohne Projekt ist für den Rückblick unsichtbar** - es bleibt kein Befund aus, es entsteht schlicht nie einer. Kein Argument gegen den Eingang als Ablageort, sondern eines dafür, dass diese Route ihre Kosten beim Anbieten nennt statt beim Vermissen (D4); der Ingest-Skill tut das. ## Akzeptanzkriterien - [x] Ein Posten lässt sich über `wikitool` in einem benannten Tracker-Projekt anlegen, optional als `WAITING` mit `follow_up_at` und mit einem Freitext-Rückverweis in `notes`; gegen Fixtures getestet, kein Test braucht eine laufende Super-Productivity-Instanz. - [x] Der Posten taucht anschließend in `wikitool review` auf: als offener Posten des Projekts, und bei gesetztem `follow_up_at` nach Ablauf der Schwelle in Prüfung 2 - über den Lesepfad getestet, angelegt und wiedergelesen (`test_created_item_appears_in_review_as_an_open_and_overdue_waiting_item`). - [x] Fehlt der `waiting`-Tag im Tracker, scheitert die Anlage eines `WAITING`-Postens laut; es entsteht kein Posten ohne seinen Status. Getestet auf beiden Ebenen (Adapter und Kommando), jeweils mit der Zusicherung, dass **kein** `POST` abgesetzt wurde. - [x] Die Eingangs-Route hat eine eigene Form am Kommando (`--inbox`); ein weggelassenes `--project` ist ein Fehler, keine stille Eingangs-Ablage. Getestet, in beiden Richtungen (keines von beiden angegeben, und beide zugleich). - [x] **Verifiziert beim Bauen:** der Eingang erscheint **nicht** in `GET /projects` - siehe § Gegen den Quellcode verifiziert. Prüfung 3 braucht folglich keine Ausnahme, und der Skill sagt beim Anbieten der Route ausdrücklich, dass `review` den Posten nicht sieht. - [x] Der Schreibweg steht nur einer Instanz mit `access: api` zur Verfügung; auf einer `snapshot`-Instanz gibt es ihn nicht (`test_snapshot_access_has_no_write_path`, exit 1 mit Verweis auf die `api`-Instanz). - [x] Ein Adapter kann den Schreibweg nicht anbieten, ohne dass der Lesepfad berührt wird - `create_item` ist eine zweite `TaskWriter`-Methode, unverändert getrennt von `TaskReader`. - [x] Keine Seite trägt nach dem Lauf einen Aufgabenzustand. Durch Bauart erfüllt: `task new` schreibt nirgends eine Seite. - [x] Kein Skill und keine Instruction nennt den Provider. `test_gtd_weekly_review_skill_names_no_provider` ist zu `test_task_tracker_skills_name_no_provider` geworden und läuft parametrisiert über `gtd-weekly-review` **und** `wiki-ingest`. - [x] Das Kommando ordnet kein Projekt selbst zu: es nimmt den Namen als Angabe, sucht nicht und vergleicht nicht unscharf. Der Ingest-Skill legt Titel und vorgeschlagenes Projekt in **einem** Schritt als Frage vor, und die drei Wege aus D4 stehen dort benannt. - [x] Nachgezogen: `docs/knowledge-and-commitment.md`, `tools/CONTRACT.md` (Kommandotabelle und Fehlervertrag), der Ingest-Skill, `README.md` und `INSTALL.md` (beide nannten bislang nur `new project` als Schreibweg), sowie #128 um das Kriterium, dass ein Azure-DevOps-Adapter `create_item` mitliefert. **`types/project.md` und `kb/gtd/COLLECTION.md` blieben unverändert** - beide beschreiben nur die Seite und ihr Frontmatter, nie einen Schreibweg, also gab es dort nichts nachzuziehen. - [x] `docs verify`, `instructions verify`, `pytest` grün; Version gebumpt (`--minor`, neues Kommando plus Protokollerweiterung, beidseitig drop-in). - [x] ~~Scheitert die Anlage des Postens, ist keine Seite geschrieben **und keine Rohdatei befördert**~~ — **zur einen Hälfte erfüllt, zur anderen bewusst abgetrennt.** „Keine Seite" ist durch Bauart erfüllt (`task new` rührt `raw/`/`kb/` nie an) und durch die Schrittfolge im Skill gesichert (Posten in Schritt 5, Seite in Schritt 6); „keine Rohdatei befördert" ist es nicht, weil `raw accept` weiterhin Schritt 1 des Ingest ist und damit vor der Verpflichtungserkennung läuft. Das ist der von `lint`/`sources coverage` ohnehin gemeldete Zustand „Rohdatei ohne Quellenseite", also genau der *entdeckte* Zwischenzustand, den D3 als den akzeptablen benennt. Ob die Beförderung trotzdem hinter die Verpflichtungsentscheidung rücken soll, ist eine Änderung am Anfang **jedes** Ingest-Laufs und damit eine eigene Entscheidung: **#136.** ## Was bewusst offen blieb - **#136** — soll `raw accept` hinter die Verpflichtungsentscheidung rücken? Siehe das gestrichene Kriterium oben. - **#112** — die Gegenposition zu D2 (unbeaufsichtigter Ingest) ist notiert und nicht gebaut; dieses Paket setzt sie nicht voraus. ## Verifiziert - `pytest`: 1429 Tests grün (davon neu: 6 Adapter-Tests in `test_superproductivity.py`, 12 Kommando-Tests in `test_task_cmd.py`, der parametrisierte Skill-Regressionstest). - `tools/wikitool docs verify`: grün, 58 dokumentierte Kommandos, keine Issue-Referenzen in 78 ausgelieferten Dokumenten. - `tools/wikitool instructions verify`: grün, 23 Instructions und 8 Skills, 16 publizierte Kopien deckungsgleich. - Ausgeliefert als Commit `cfbe3ea` auf `origin/main`, Stack `7.0.0-beta.12`; der Nachzug an `README.md`/`INSTALL.md` folgte im Abschluss-Commit derselben Arbeit. ## Berührungspunkte #128 (der zweite Adapter muss `create_item` mitliefern — dort eingetragen), #133 (der Schreibweg setzt `access: api` voraus), #135 (Voraussetzung für den `follow_up_at`-Teil, eingearbeitet), #136 (die abgetrennte Reihenfolgefrage), #112 (unbeaufsichtigter Ingest), #131 (die Leserichtung).
torben added the prio/plannedsize/Larea/kbkind/decision labels 2026-09-20 10:19:17 +00:00
torben changed title from Capture und Zielwahl: was geht nach raw/kb, was nach kb/gtd, was in den Tracker? to Ein Ingest, zwei Schichten: die Seite ablegen und die Verpflichtung im Tracker anlegen 2026-09-20 10:27:11 +00:00
Author
Owner

Changelog: Body und Titel vollständig neu geschrieben am Fallbeispiel des Betreibers
(Kundenreklamation per Mail → Inhalt mit Projektbezug ablegen und das Nachfassen als Verpflichtung
anlegen).

  • Gestrichen: der MCP-Capture-Rahmen und der mobile Fall — beides Spielerei (siehe #131). Der
    Weg über incoming/ bleibt, den es ohnehin gibt.
  • Korrigiert: die alte Fassung fragte „was geht wohin — kb/, kb/gtd/ oder Tracker" und nahm
    die drei Ziele als exklusiv an. Sie sind es nicht: eine Quelle erzeugt in der Regel beides.
  • Neu belegt: TaskWriter kennt genau create_project — für einen Posten gibt es weder
    Protokoll noch Kommando, das ist die eigentliche Lücke. Die SP-REST-API hat Task-CRUD (nur
    Projekt-CRUD fehlt), der HumanInterventionRequired-Fall tritt hier also nicht ein.
    „Nachfassen" fällt exakt auf das vorhandene WAITING/follow_up_at-Paar, womit Prüfung 2 des
    Rückblicks die Verpflichtung ohne neuen Mechanismus wieder anfasst. Reihenfolge Tracker-vor-Seite
    jetzt mit eigenem Beleg: „Posten ohne Seite" meldet lint als uncovered_raw_files, „Seite ohne
    Posten" meldet nichts.
  • Neue Entscheidungen: D1 zweites Schreibkommando, D2 Klärung durch den Menschen, D3
    Reihenfolge, D4 Projektzuordnung, D5 Rückverweis im Posten.
**Changelog:** Body und Titel vollständig neu geschrieben am Fallbeispiel des Betreibers (Kundenreklamation per Mail → Inhalt mit Projektbezug ablegen *und* das Nachfassen als Verpflichtung anlegen). - **Gestrichen:** der MCP-Capture-Rahmen und der mobile Fall — beides Spielerei (siehe #131). Der Weg über `incoming/` bleibt, den es ohnehin gibt. - **Korrigiert:** die alte Fassung fragte „was geht wohin — `kb/`, `kb/gtd/` oder Tracker" und nahm die drei Ziele als exklusiv an. Sie sind es nicht: eine Quelle erzeugt in der Regel beides. - **Neu belegt:** `TaskWriter` kennt genau `create_project` — für einen Posten gibt es weder Protokoll noch Kommando, das ist die eigentliche Lücke. Die SP-REST-API hat Task-CRUD (nur Projekt-CRUD fehlt), der `HumanInterventionRequired`-Fall tritt hier also nicht ein. „Nachfassen" fällt exakt auf das vorhandene `WAITING`/`follow_up_at`-Paar, womit Prüfung 2 des Rückblicks die Verpflichtung ohne neuen Mechanismus wieder anfasst. Reihenfolge Tracker-vor-Seite jetzt mit eigenem Beleg: „Posten ohne Seite" meldet `lint` als `uncovered_raw_files`, „Seite ohne Posten" meldet nichts. - **Neue Entscheidungen:** D1 zweites Schreibkommando, D2 Klärung durch den Menschen, D3 Reihenfolge, D4 Projektzuordnung, D5 Rückverweis im Posten.
Author
Owner

Changelog: Die Endpunkt-Verifikation gegen den SP-Quellcode ist gelaufen (2026-09-20) und
erledigt den letzten der vier Punkte unter „Vorher zu klären". Die drei Entscheidungsfragen D2, D4
und die Projekterkennung bleiben offen — kind/decision steht unverändert.

  • Neu: § Der Schreibweg, gegen den Quellcode verifiziert. POST /tasks existiert, die
    schreibbare Feldliste steht vollständig im Body.
  • Neu, vier Auflagen: der waiting-Tag muss vorher existieren (Tags sind über die API nicht
    anlegbar); follow_up_at ist erst nach #135 schreibbar; ein Posten landet nie im Backlog
    (isAddToBacklog fest false); notes ist schreibbar, D5 also umsetzbar.
  • Geschärft: die erste der „drei Dinge, die den Weg kurz machen" stand als Notiz unter
    Verifikationsvorbehalt und ist jetzt belegt — samt der Abgrenzung, warum create_project Exit 42
    braucht und dieser Weg nicht.
  • Neu bei D4: dass new project das Tracker-Projekt auf keiner Instanz selbst anlegen kann,
    ist eine Randbedingung der Entscheidung — die Variante „erst new project" hält den Ingest
    immer an.
  • Neues Kriterium: fehlender waiting-Tag muss laut scheitern statt stumm einen Posten ohne
    Status anzulegen.
  • Abhängigkeit: der follow_up_at-Teil der Umsetzung setzt #135 voraus.
**Changelog:** Die Endpunkt-Verifikation gegen den SP-Quellcode ist gelaufen (2026-09-20) und erledigt den letzten der vier Punkte unter „Vorher zu klären". Die drei Entscheidungsfragen D2, D4 und die Projekterkennung bleiben offen — `kind/decision` steht unverändert. - **Neu:** § Der Schreibweg, gegen den Quellcode verifiziert. `POST /tasks` existiert, die schreibbare Feldliste steht vollständig im Body. - **Neu, vier Auflagen:** der `waiting`-Tag muss vorher existieren (Tags sind über die API nicht anlegbar); `follow_up_at` ist erst nach #135 schreibbar; ein Posten landet nie im Backlog (`isAddToBacklog` fest `false`); `notes` ist schreibbar, D5 also umsetzbar. - **Geschärft:** die erste der „drei Dinge, die den Weg kurz machen" stand als Notiz unter Verifikationsvorbehalt und ist jetzt belegt — samt der Abgrenzung, warum `create_project` Exit 42 braucht und dieser Weg nicht. - **Neu bei D4:** dass `new project` das Tracker-Projekt auf **keiner** Instanz selbst anlegen kann, ist eine Randbedingung der Entscheidung — die Variante „erst `new project`" hält den Ingest immer an. - **Neues Kriterium:** fehlender `waiting`-Tag muss laut scheitern statt stumm einen Posten ohne Status anzulegen. - **Abhängigkeit:** der `follow_up_at`-Teil der Umsetzung setzt #135 voraus.
torben added size/Mkind/build and removed size/Lkind/decision labels 2026-09-20 15:52:52 +00:00
Author
Owner

Changelog: Die drei offenen Punkte sind am 2026-09-20 entschieden; „Vorher zu klären" ist leer.
kind/decision → kind/build, size/L → size/M (die offenen Designfragen vor dem ersten Commit
waren das L-Kriterium, und sie sind weg — mehrere Dateien plus Contract-/Instruction-Änderung mit
eigenem Testaufwand bleiben).

  • D2 entschieden: Skill-Frage, kein Gate — und ausdrücklich ohne Auflage an #112. Die
    Gegenposition (unbeaufsichtigter Stapellauf) ist im Body als bestehend und unadressiert notiert;
    wer sie baut, stellt die Frage dort neu.
  • D4 entschieden: kein Default. Der Ingest hält an und legt drei Wege vor — vorhandenes Projekt
    benennen, new project, oder in den Eingang des Trackers. Der Eingang ist die ausdrücklich
    gewählte Notausfahrt, nie ein Default, und der Skill nennt beim Anbieten ihre Kosten. Dazu neu:
    das Kommando braucht für sie eine eigene Form (--inbox), ein weggelassenes --project ist ein
    Fehler.
  • D6 neu, entschieden: die Projekterkennung schlägt per search vor und ordnet nie automatisch
    zu, auch nicht bei einem eindeutigen Treffer. Das Suchen bleibt beim Skill; das Kommando nimmt den
    Namen als Angabe.
  • Neuer Befund aus dem Lesepfad: § Der Rückblick erreicht Posten nur über ihr Projekt.
    run_review erreicht Posten ausschließlich über projects() → open_items(project.name)
    (tools/chemenu/review.py:145-184) — ein Posten ohne Projekt ist für Prüfung 2 unsichtbar. Das
    beschneidet D4 Weg 3 und ist der Grund, warum diese Route ihre Kosten beim Anbieten nennen muss.
  • Neues Kriterium, eine Verifikation beim Bauen: erscheint der SP-Eingang in GET /projects?
    Wenn ja, nimmt Prüfung 3 ihn aus (getestet); wenn nein, sagt der Skill beim Anbieten der Route,
    dass review den Posten nicht sieht. Das Ergebnis wird im Body nachgezogen statt als Annahme in
    den Code geschrieben.
  • Neuer Abschnitt § Ein Dialogschritt, nicht drei: D2, D4 und D6 verlangen dieselbe menschliche
    Auskunft an derselben Stelle und fallen in der Umsetzung auf eine Frage zusammen (Titel +
    vorgeschlagenes Projekt), danach ein Kommandoaufruf.
  • Geschärft: D1 nennt den Freitext-Rückverweis aus D5 als Feld mit; das Kriterium zum
    Schreibweg nennt notes jetzt ausdrücklich.
**Changelog:** Die drei offenen Punkte sind am 2026-09-20 entschieden; „Vorher zu klären" ist leer. `kind/decision` → `kind/build`, `size/L` → `size/M` (die offenen Designfragen vor dem ersten Commit waren das L-Kriterium, und sie sind weg — mehrere Dateien plus Contract-/Instruction-Änderung mit eigenem Testaufwand bleiben). - **D2 entschieden:** Skill-Frage, kein Gate — **und ausdrücklich ohne Auflage an #112.** Die Gegenposition (unbeaufsichtigter Stapellauf) ist im Body als bestehend und unadressiert notiert; wer sie baut, stellt die Frage dort neu. - **D4 entschieden:** kein Default. Der Ingest hält an und legt drei Wege vor — vorhandenes Projekt benennen, `new project`, oder in den Eingang des Trackers. Der Eingang ist die ausdrücklich gewählte Notausfahrt, nie ein Default, und der Skill nennt beim Anbieten ihre Kosten. Dazu neu: das Kommando braucht für sie eine eigene Form (`--inbox`), ein weggelassenes `--project` ist ein Fehler. - **D6 neu, entschieden:** die Projekterkennung schlägt per `search` vor und ordnet nie automatisch zu, auch nicht bei einem eindeutigen Treffer. Das Suchen bleibt beim Skill; das Kommando nimmt den Namen als Angabe. - **Neuer Befund aus dem Lesepfad:** § Der Rückblick erreicht Posten nur über ihr Projekt. `run_review` erreicht Posten ausschließlich über `projects()` → `open_items(project.name)` (`tools/chemenu/review.py:145-184`) — ein Posten ohne Projekt ist für Prüfung 2 unsichtbar. Das beschneidet D4 Weg 3 und ist der Grund, warum diese Route ihre Kosten beim Anbieten nennen muss. - **Neues Kriterium, eine Verifikation beim Bauen:** erscheint der SP-Eingang in `GET /projects`? Wenn ja, nimmt Prüfung 3 ihn aus (getestet); wenn nein, sagt der Skill beim Anbieten der Route, dass `review` den Posten nicht sieht. Das Ergebnis wird im Body nachgezogen statt als Annahme in den Code geschrieben. - **Neuer Abschnitt § Ein Dialogschritt, nicht drei:** D2, D4 und D6 verlangen dieselbe menschliche Auskunft an derselben Stelle und fallen in der Umsetzung auf eine Frage zusammen (Titel + vorgeschlagenes Projekt), danach ein Kommandoaufruf. - **Geschärft:** D1 nennt den Freitext-Rückverweis aus D5 als Feld mit; das Kriterium zum Schreibweg nennt `notes` jetzt ausdrücklich.
Author
Owner

Changelog: Umgesetzt (2026-09-20). Alle Akzeptanzkriterien bis auf eines abgehakt - siehe die
Anmerkung an der einen offenen Zeile für eine Lesart, die zur Bestätigung vorgelegt wird statt
selbst entschieden zu sein.

  • Neu: wikitool task new, TaskWriter.create_item im Protokoll, SuperProductivityWriters
    Umsetzung (INBOX_PROJECT-Konstante, Projekt-Id- und waiting-Tag-Auflösung vor dem einen
    POST /tasks).
  • Der Ingest-Skill (instructions/wiki-ingest/SKILL.md) hat Schritt 5 um die
    Verpflichtungs-Erkennung erweitert: ein Dialogschritt (D2/D4/D6), task new vor Schritt 6
    (Quellenseite).
  • docs/knowledge-and-commitment.md, tools/CONTRACT.md nachgezogen; #128 aktualisiert.
  • Tests: test_superproductivity.py (Schreibpfad), test_task_cmd.py (CLI, inkl. Rundlauf durch
    review), test_instructions_cmd.py (Provider-Regressionstest parametrisiert).
  • docs verify/instructions verify/pytest grün.

Eine Lesart zur Bestätigung: Die Kriteriumszeile zu „keine Rohdatei befördert, wenn die
Postenanlage scheitert" ist nur teilweise erfüllt - task new selbst rührt raw//kb/ nie an,
aber Schritt 1 (raw accept) läuft weiterhin vor der Verpflichtungserkennung, nicht danach. Details
und Begründung stehen an der Zeile selbst im Body. Wenn die Beförderung ebenfalls hinter die
Verpflichtungsentscheidung soll, ist das ein Nachzug an Schritt 1 des Ingest-Skills - noch nicht
gebaut.

**Changelog:** Umgesetzt (2026-09-20). Alle Akzeptanzkriterien bis auf eines abgehakt - siehe die Anmerkung an der einen offenen Zeile für eine Lesart, die zur Bestätigung vorgelegt wird statt selbst entschieden zu sein. - Neu: `wikitool task new`, `TaskWriter.create_item` im Protokoll, `SuperProductivityWriter`s Umsetzung (`INBOX_PROJECT`-Konstante, Projekt-Id- und `waiting`-Tag-Auflösung vor dem einen `POST /tasks`). - Der Ingest-Skill (`instructions/wiki-ingest/SKILL.md`) hat Schritt 5 um die Verpflichtungs-Erkennung erweitert: ein Dialogschritt (D2/D4/D6), `task new` vor Schritt 6 (Quellenseite). - `docs/knowledge-and-commitment.md`, `tools/CONTRACT.md` nachgezogen; #128 aktualisiert. - Tests: `test_superproductivity.py` (Schreibpfad), `test_task_cmd.py` (CLI, inkl. Rundlauf durch `review`), `test_instructions_cmd.py` (Provider-Regressionstest parametrisiert). - `docs verify`/`instructions verify`/`pytest` grün. **Eine Lesart zur Bestätigung:** Die Kriteriumszeile zu „keine Rohdatei befördert, wenn die Postenanlage scheitert" ist nur teilweise erfüllt - `task new` selbst rührt `raw/`/`kb/` nie an, aber Schritt 1 (`raw accept`) läuft weiterhin vor der Verpflichtungserkennung, nicht danach. Details und Begründung stehen an der Zeile selbst im Body. Wenn die Beförderung ebenfalls hinter die Verpflichtungsentscheidung soll, ist das ein Nachzug an Schritt 1 des Ingest-Skills - noch nicht gebaut.
Author
Owner

Changelog: Abschluss-Rewrite. Der Body ist jetzt der Endzustand statt einer Spezifikation:
„Wo es heute abbricht" ist durch „Was es jetzt gibt" ersetzt, die Entscheidungen D1-D6 lesen sich
als entschieden, und die Verifikationsergebnisse (inkl. des Befunds zum SP-Eingang) stehen im Body
statt verteilt in den Kommentaren.

  • Alle Akzeptanzkriterien abgehakt bis auf eines: „keine Rohdatei befördert" ist gestrichen und
    als #136 abgetrennt (kind/decision, size/S) — task new rührt raw//kb/ nie an, aber
    raw accept bleibt Schritt 1 des Ingest und läuft damit vor der Verpflichtungserkennung; ob das
    so bleibt, ist eine Änderung am Anfang jedes Ingest-Laufs und damit eine eigene Entscheidung.
  • Neu im Nachzug: README.md und INSTALL.md nannten bislang nur new project als Schreibweg
    in den Tracker - beide nennen jetzt auch task new (Commit 88e7cc1).
  • Festgehalten: types/project.md und kb/gtd/COLLECTION.md blieben bewusst unverändert.
  • Verifikation benannt: pytest (1429 grün), docs verify, instructions verify, Commits
    cfbe3ea und 88e7cc1, Stack 7.0.0-beta.12.
**Changelog:** Abschluss-Rewrite. Der Body ist jetzt der Endzustand statt einer Spezifikation: „Wo es heute abbricht" ist durch „Was es jetzt gibt" ersetzt, die Entscheidungen D1-D6 lesen sich als entschieden, und die Verifikationsergebnisse (inkl. des Befunds zum SP-Eingang) stehen im Body statt verteilt in den Kommentaren. - **Alle Akzeptanzkriterien abgehakt** bis auf eines: „keine Rohdatei befördert" ist gestrichen und als **#136** abgetrennt (`kind/decision`, `size/S`) — `task new` rührt `raw/`/`kb/` nie an, aber `raw accept` bleibt Schritt 1 des Ingest und läuft damit vor der Verpflichtungserkennung; ob das so bleibt, ist eine Änderung am Anfang jedes Ingest-Laufs und damit eine eigene Entscheidung. - **Neu im Nachzug:** `README.md` und `INSTALL.md` nannten bislang nur `new project` als Schreibweg in den Tracker - beide nennen jetzt auch `task new` (Commit `88e7cc1`). - **Festgehalten:** `types/project.md` und `kb/gtd/COLLECTION.md` blieben bewusst unverändert. - **Verifikation benannt:** `pytest` (1429 grün), `docs verify`, `instructions verify`, Commits `cfbe3ea` und `88e7cc1`, Stack `7.0.0-beta.12`.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: torben/chemenu#132