Paket 5 aus #119 (D8, D31). Ein Geburtsort, ein Name.
Erledigt (e4260fc + 6324024, Stack 7.0.0-beta.5). wikitool new project --name X --set responsibility=Y [--resume] legt jetzt Seite und Tracker-Projekt unter einem Namen an, mit der
in diesem Issue vorgezeichneten Fehlerbehandlung. Alle offenen Designfragen sind entschieden
(siehe "Ergebnis" unten); dieses Issue steht ab jetzt nur noch als Nachschlagewerk für das Warum.
Warum hier und nicht in einem eigenen Kommando
Der Moment, in dem ein Vorhaben entsteht, ist der einzige, an dem die Eindeutigkeitspruefung aus
D8 natuerlich sitzt. Unter Muster 4 ist der Name die einzige Kopplung zwischen kb/ und
Tracker; er erbt damit die Pflichten eines Identifiers, und ein Identifier wird bei der Geburt
vergeben, nicht nachtraeglich repariert.
Ein eigenes task new haette zwei Geburtsorte fuer einen Namen - und der Preflight saesse dann
an zwei Stellen oder faehlte an einer.
Was gebaut wurde
tools/wikitool new project --name "Küche renovieren" --set responsibility=haus [--resume]
Preflight: Ist der Name - case-normalisiert - in kb/ frei? Und im Tracker?
Tracker-Projekt anlegen (_ensure_tracker_project in commands/new_page.py, ueber die
neuen, geteilten chemenu.tasks.build_reader/build_writer).
Seite anlegen, wie new es ohnehin tut.
Ergebnis: die Retry-Frage aus "Schritt 2 fuer einen Provider ohne Schreibpfad"
Der urspruengliche Text unten (aus #124s Befund) sah vor, dass ein erneuter Aufruf "ueber den
Lesepfad verifiziert, bevor er fortfaehrt". In der Umsetzung zeigte sich: ein zustandsloser
CLI-Prozess kann eine echte Namenskollision im Tracker nicht von "der Mensch hat gerade getan,
worum genau dieses Kommando gebeten hat" unterscheiden - beides sieht am Lesepfad identisch aus
(Tracker hat den Namen, kb/ noch keine Seite), und ein automatisches "Treffer im Tracker = schon
erledigt" haette die im AC-Punkt "Kollision samt Fundort" geforderte harte Ablehnung fuer den
Normalfall stillschweigend aufgeweicht.
Entschieden (mit dem Betreiber, per Rueckfrage): ein explizites --resume. Ohne --resume
bleibt jeder Tracker-Treffer eine Ablehnung samt Fundort, auch bei einem Wiederholungsaufruf; mit --resume liest ein Tracker-Treffer als bestaetigte Fortsetzung, und --resume ohne einen
tatsaechlich vorhandenen Tracker-Eintrag wirft dieselbe HumanInterventionRequired-Meldung
erneut. chemenu.errors.HumanInterventionRequireds Dokumentation ist entsprechend nachgezogen
(sie beschrieb urspruenglich ein automatisches verify() als den Weg fuer einen neuen Prozess).
Die Reihenfolge ist die Fehlerbehandlung
Tracker zuerst, Seite danach - und das ist kein Detail. new ist laut AGENTS.md
§ Tool error contract nicht idempotent; ein halb gelungener Lauf ueber zwei Systeme ist
deshalb der gefaehrlichste Fall, den dieses Kommando hat.
Was scheitert
Zustand danach
Bewertung
Preflight
nichts angelegt
sauber
Tracker-Anlage (inkl. HumanInterventionRequired, solange --resume nicht bestaetigt)
nichts angelegt
sauber
Seiten-Anlage
Tracker-Projekt ohne Seite
ein Zustand, den das System bereits kennt und meldet - Pruefung 3 in #125
Andersherum - Seite zuerst - entstuende eine kb/-Seite ohne Tracker-Projekt. Die meldet
Pruefung 4 zwar auch, aber sie behauptet dabei ein Vorhaben, an dem niemand arbeiten kann.
Die gewaehlte Reihenfolge laesst jeden Teilfehler in einem Zustand landen, fuer den der
Rueckblick schon eine Meldung hat. Eigens getestet (Seiten-Schreibfehler erzwungen nach
bereits bestaetigtem Tracker-Projekt): die Meldung nennt, dass die Tracker-Seite schon steht
und nur die kb/-Seite fehlt, nie umgekehrt.
Akzeptanzkriterien
Nach jedem Abbruch gilt: entweder existieren beide, oder nur das Tracker-Projekt, oder
keines - nie nur die Seite. Ein Test erzwingt einen Fehler in Schritt 3 und prueft
genau das. (test_new_project_never_leaves_only_the_page_when_the_write_fails)
Scheitert ein Schritt, benennt die Meldung, welche der beiden Seiten existiert, statt
nur den Fehler zu melden.
Ist der Name in kb/ oder im Tracker vergeben (case-normalisiert), legt das Kommando nichts an und nennt die Kollision samt Fundort. (Ohne --resume; siehe "Ergebnis"
oben fuer die praezisierte Retry-Semantik.)
Ohne konfigurierten Provider legt es nur die Seite an und sagt das ausdruecklich.
Wirft create_projectHumanInterventionRequired, zeigt das Kommando die Anweisung
ueber needs_clearance()/Exit 42 und legt nichts an; ein erneuter Aufruf mit --resume verifiziert ueber den Lesepfad (find_project), bevor er fortfaehrt, statt
einer Nutzerbestaetigung allein zu glauben.
--responsibility ist erforderlich; ein Wert ohne layout:-Eintrag wird abgelehnt. (Galt
schon generisch ueber types/project.schema.yaml aus #123, hier nur nachgetestet.)
Der Rest von wikitool new verhaelt sich unveraendert - fuer jeden anderen Typ ist das
erzeugte Scaffold byte-identisch mit dem vor der Aenderung. (Volle Bestandssuite gruen,
1382 Tests.)
docs verify, instructions verify, pytest gruen.
tools/CONTRACT.md: die new-Zeile (und die eigene new project-Fehlervertragszeile)
nennt das erweiterte Verhalten, die Nicht-Atomizitaet ueber zwei Systeme, und den HumanInterventionRequired/--resume-Ablauf.
Abhaengigkeiten
War status/blocked auf #123 (der Typ) und #124 (der Schreibpfad) - beide erledigt, Label
entfernt.
Verifiziert
pytest (tools/chemenu): 1382 gruen, hermetisch (env -i mit leerem HOME) wie unhermetisch.
Version: --minor (Paket-Bump selbst), fortlaufend --patch fuer den Nachtrag - beide auf dem
bereits seit #123 grenzuebertretenden Kandidaten 7.0.0-beta.5 (siehe CHANGES.md).
Paket 5 aus #119 (D8, D31). Ein Geburtsort, ein Name.
**Erledigt** (`e4260fc` + `6324024`, Stack 7.0.0-beta.5). `wikitool new project --name X --set
responsibility=Y [--resume]` legt jetzt Seite und Tracker-Projekt unter einem Namen an, mit der
in diesem Issue vorgezeichneten Fehlerbehandlung. Alle offenen Designfragen sind entschieden
(siehe "Ergebnis" unten); dieses Issue steht ab jetzt nur noch als Nachschlagewerk für das Warum.
## Warum hier und nicht in einem eigenen Kommando
Der Moment, in dem ein Vorhaben entsteht, ist der einzige, an dem die Eindeutigkeitspruefung aus
D8 natuerlich sitzt. Unter Muster 4 ist der Name die **einzige** Kopplung zwischen `kb/` und
Tracker; er erbt damit die Pflichten eines Identifiers, und ein Identifier wird bei der Geburt
vergeben, nicht nachtraeglich repariert.
Ein eigenes `task new` haette zwei Geburtsorte fuer einen Namen - und der Preflight saesse dann
an zwei Stellen oder faehlte an einer.
## Was gebaut wurde
```
tools/wikitool new project --name "Küche renovieren" --set responsibility=haus [--resume]
```
1. **Preflight:** Ist der Name - case-normalisiert - in `kb/` frei? Und im Tracker?
2. **Tracker-Projekt anlegen** (`_ensure_tracker_project` in `commands/new_page.py`, ueber die
neuen, geteilten `chemenu.tasks.build_reader`/`build_writer`).
3. **Seite anlegen**, wie `new` es ohnehin tut.
## Ergebnis: die Retry-Frage aus "Schritt 2 fuer einen Provider ohne Schreibpfad"
Der urspruengliche Text unten (aus #124s Befund) sah vor, dass ein erneuter Aufruf "ueber den
Lesepfad verifiziert, bevor er fortfaehrt". In der Umsetzung zeigte sich: ein zustandsloser
CLI-Prozess kann eine echte Namenskollision im Tracker nicht von "der Mensch hat gerade getan,
worum genau dieses Kommando gebeten hat" unterscheiden - beides sieht am Lesepfad identisch aus
(Tracker hat den Namen, `kb/` noch keine Seite), und ein automatisches "Treffer im Tracker = schon
erledigt" haette die im AC-Punkt "Kollision samt Fundort" geforderte harte Ablehnung fuer den
Normalfall stillschweigend aufgeweicht.
**Entschieden (mit dem Betreiber, per Rueckfrage):** ein explizites `--resume`. Ohne `--resume`
bleibt jeder Tracker-Treffer eine Ablehnung samt Fundort, auch bei einem Wiederholungsaufruf; mit
`--resume` liest ein Tracker-Treffer als bestaetigte Fortsetzung, und `--resume` ohne einen
tatsaechlich vorhandenen Tracker-Eintrag wirft dieselbe `HumanInterventionRequired`-Meldung
erneut. `chemenu.errors.HumanInterventionRequired`s Dokumentation ist entsprechend nachgezogen
(sie beschrieb urspruenglich ein automatisches `verify()` als den Weg fuer einen neuen Prozess).
## Die Reihenfolge ist die Fehlerbehandlung
Tracker zuerst, Seite danach - und das ist kein Detail. `new` ist laut `AGENTS.md`
§ Tool error contract **nicht idempotent**; ein halb gelungener Lauf ueber zwei Systeme ist
deshalb der gefaehrlichste Fall, den dieses Kommando hat.
| Was scheitert | Zustand danach | Bewertung |
|---|---|---|
| Preflight | nichts angelegt | sauber |
| Tracker-Anlage (inkl. `HumanInterventionRequired`, solange `--resume` nicht bestaetigt) | nichts angelegt | sauber |
| Seiten-Anlage | Tracker-Projekt ohne Seite | ein Zustand, den das System bereits kennt und meldet - Pruefung 3 in #125 |
Andersherum - Seite zuerst - entstuende eine `kb/`-Seite ohne Tracker-Projekt. Die meldet
Pruefung 4 zwar auch, aber sie behauptet dabei ein Vorhaben, an dem niemand arbeiten kann.
Die gewaehlte Reihenfolge laesst jeden Teilfehler in einem Zustand landen, fuer den der
Rueckblick schon eine Meldung hat. **Eigens getestet** (Seiten-Schreibfehler erzwungen nach
bereits bestaetigtem Tracker-Projekt): die Meldung nennt, dass die Tracker-Seite schon steht
und nur die `kb/`-Seite fehlt, nie umgekehrt.
## Akzeptanzkriterien
- [x] **Nach jedem Abbruch gilt: entweder existieren beide, oder nur das Tracker-Projekt, oder
keines - nie nur die Seite.** Ein Test erzwingt einen Fehler in Schritt 3 und prueft
genau das. (`test_new_project_never_leaves_only_the_page_when_the_write_fails`)
- [x] Scheitert ein Schritt, **benennt die Meldung, welche der beiden Seiten existiert**, statt
nur den Fehler zu melden.
- [x] Ist der Name in `kb/` oder im Tracker vergeben (case-normalisiert), legt das Kommando
**nichts** an und nennt die Kollision samt Fundort. (Ohne `--resume`; siehe "Ergebnis"
oben fuer die praezisierte Retry-Semantik.)
- [x] Ohne konfigurierten Provider legt es nur die Seite an und **sagt das ausdruecklich**.
- [x] **Wirft `create_project` `HumanInterventionRequired`**, zeigt das Kommando die Anweisung
ueber `needs_clearance()`/Exit 42 und legt **nichts** an; ein erneuter Aufruf mit
`--resume` verifiziert ueber den Lesepfad (`find_project`), bevor er fortfaehrt, statt
einer Nutzerbestaetigung allein zu glauben.
- [x] `--responsibility` ist erforderlich; ein Wert ohne `layout:`-Eintrag wird abgelehnt. (Galt
schon generisch ueber `types/project.schema.yaml` aus #123, hier nur nachgetestet.)
- [x] Der Rest von `wikitool new` verhaelt sich unveraendert - fuer jeden anderen Typ ist das
erzeugte Scaffold byte-identisch mit dem vor der Aenderung. (Volle Bestandssuite gruen,
1382 Tests.)
- [x] `docs verify`, `instructions verify`, `pytest` gruen.
- [x] `tools/CONTRACT.md`: die `new`-Zeile (und die eigene `new project`-Fehlervertragszeile)
nennt das erweiterte Verhalten, die Nicht-Atomizitaet ueber zwei Systeme, und den
`HumanInterventionRequired`/`--resume`-Ablauf.
## Abhaengigkeiten
War `status/blocked` auf #123 (der Typ) und #124 (der Schreibpfad) - beide erledigt, Label
entfernt.
## Verifiziert
- `pytest` (tools/chemenu): 1382 gruen, hermetisch (`env -i` mit leerem `HOME`) wie unhermetisch.
- `tools/wikitool docs verify` / `instructions verify`: gruen.
- Version: `--minor` (Paket-Bump selbst), fortlaufend `--patch` fuer den Nachtrag - beide auf dem
bereits seit #123 grenzuebertretenden Kandidaten `7.0.0-beta.5` (siehe CHANGES.md).
Umgesetzt und geschlossen (e4260fc, 6324024). Gegenueber dem urspruenglichen Entwurf: die
Retry-Semantik nach HumanInterventionRequired ist ein explizites --resume statt eines
automatischen Lesepfad-Abgleichs - Begruendung und Rueckfrage-Ergebnis stehen im Issue-Body
unter "Ergebnis". --responsibility brauchte keinen neuen Code (galt schon aus #123), nur einen
nachgetragenen Test. #119s Tabelle ist aktualisiert; #127 (weekly-review-Skill) ist als naechstes frei.
Umgesetzt und geschlossen (`e4260fc`, `6324024`). Gegenueber dem urspruenglichen Entwurf: die
Retry-Semantik nach `HumanInterventionRequired` ist ein explizites `--resume` statt eines
automatischen Lesepfad-Abgleichs - Begruendung und Rueckfrage-Ergebnis stehen im Issue-Body
unter "Ergebnis". `--responsibility` brauchte keinen neuen Code (galt schon aus #123), nur einen
nachgetragenen Test. #119s Tabelle ist aktualisiert; #127 (`weekly-review`-Skill) ist als naechstes frei.
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.
Paket 5 aus #119 (D8, D31). Ein Geburtsort, ein Name.
Erledigt (
e4260fc+6324024, Stack 7.0.0-beta.5).wikitool new project --name X --set responsibility=Y [--resume]legt jetzt Seite und Tracker-Projekt unter einem Namen an, mit derin diesem Issue vorgezeichneten Fehlerbehandlung. Alle offenen Designfragen sind entschieden
(siehe "Ergebnis" unten); dieses Issue steht ab jetzt nur noch als Nachschlagewerk für das Warum.
Warum hier und nicht in einem eigenen Kommando
Der Moment, in dem ein Vorhaben entsteht, ist der einzige, an dem die Eindeutigkeitspruefung aus
D8 natuerlich sitzt. Unter Muster 4 ist der Name die einzige Kopplung zwischen
kb/undTracker; er erbt damit die Pflichten eines Identifiers, und ein Identifier wird bei der Geburt
vergeben, nicht nachtraeglich repariert.
Ein eigenes
task newhaette zwei Geburtsorte fuer einen Namen - und der Preflight saesse dannan zwei Stellen oder faehlte an einer.
Was gebaut wurde
kb/frei? Und im Tracker?_ensure_tracker_projectincommands/new_page.py, ueber dieneuen, geteilten
chemenu.tasks.build_reader/build_writer).newes ohnehin tut.Ergebnis: die Retry-Frage aus "Schritt 2 fuer einen Provider ohne Schreibpfad"
Der urspruengliche Text unten (aus #124s Befund) sah vor, dass ein erneuter Aufruf "ueber den
Lesepfad verifiziert, bevor er fortfaehrt". In der Umsetzung zeigte sich: ein zustandsloser
CLI-Prozess kann eine echte Namenskollision im Tracker nicht von "der Mensch hat gerade getan,
worum genau dieses Kommando gebeten hat" unterscheiden - beides sieht am Lesepfad identisch aus
(Tracker hat den Namen,
kb/noch keine Seite), und ein automatisches "Treffer im Tracker = schonerledigt" haette die im AC-Punkt "Kollision samt Fundort" geforderte harte Ablehnung fuer den
Normalfall stillschweigend aufgeweicht.
Entschieden (mit dem Betreiber, per Rueckfrage): ein explizites
--resume. Ohne--resumebleibt jeder Tracker-Treffer eine Ablehnung samt Fundort, auch bei einem Wiederholungsaufruf; mit
--resumeliest ein Tracker-Treffer als bestaetigte Fortsetzung, und--resumeohne einentatsaechlich vorhandenen Tracker-Eintrag wirft dieselbe
HumanInterventionRequired-Meldungerneut.
chemenu.errors.HumanInterventionRequireds Dokumentation ist entsprechend nachgezogen(sie beschrieb urspruenglich ein automatisches
verify()als den Weg fuer einen neuen Prozess).Die Reihenfolge ist die Fehlerbehandlung
Tracker zuerst, Seite danach - und das ist kein Detail.
newist lautAGENTS.md§ Tool error contract nicht idempotent; ein halb gelungener Lauf ueber zwei Systeme ist
deshalb der gefaehrlichste Fall, den dieses Kommando hat.
HumanInterventionRequired, solange--resumenicht bestaetigt)Andersherum - Seite zuerst - entstuende eine
kb/-Seite ohne Tracker-Projekt. Die meldetPruefung 4 zwar auch, aber sie behauptet dabei ein Vorhaben, an dem niemand arbeiten kann.
Die gewaehlte Reihenfolge laesst jeden Teilfehler in einem Zustand landen, fuer den der
Rueckblick schon eine Meldung hat. Eigens getestet (Seiten-Schreibfehler erzwungen nach
bereits bestaetigtem Tracker-Projekt): die Meldung nennt, dass die Tracker-Seite schon steht
und nur die
kb/-Seite fehlt, nie umgekehrt.Akzeptanzkriterien
keines - nie nur die Seite. Ein Test erzwingt einen Fehler in Schritt 3 und prueft
genau das. (
test_new_project_never_leaves_only_the_page_when_the_write_fails)nur den Fehler zu melden.
kb/oder im Tracker vergeben (case-normalisiert), legt das Kommandonichts an und nennt die Kollision samt Fundort. (Ohne
--resume; siehe "Ergebnis"oben fuer die praezisierte Retry-Semantik.)
create_projectHumanInterventionRequired, zeigt das Kommando die Anweisungueber
needs_clearance()/Exit 42 und legt nichts an; ein erneuter Aufruf mit--resumeverifiziert ueber den Lesepfad (find_project), bevor er fortfaehrt, statteiner Nutzerbestaetigung allein zu glauben.
--responsibilityist erforderlich; ein Wert ohnelayout:-Eintrag wird abgelehnt. (Galtschon generisch ueber
types/project.schema.yamlaus #123, hier nur nachgetestet.)wikitool newverhaelt sich unveraendert - fuer jeden anderen Typ ist daserzeugte Scaffold byte-identisch mit dem vor der Aenderung. (Volle Bestandssuite gruen,
1382 Tests.)
docs verify,instructions verify,pytestgruen.tools/CONTRACT.md: dienew-Zeile (und die eigenenew project-Fehlervertragszeile)nennt das erweiterte Verhalten, die Nicht-Atomizitaet ueber zwei Systeme, und den
HumanInterventionRequired/--resume-Ablauf.Abhaengigkeiten
War
status/blockedauf #123 (der Typ) und #124 (der Schreibpfad) - beide erledigt, Labelentfernt.
Verifiziert
pytest(tools/chemenu): 1382 gruen, hermetisch (env -imit leeremHOME) wie unhermetisch.tools/wikitool docs verify/instructions verify: gruen.--minor(Paket-Bump selbst), fortlaufend--patchfuer den Nachtrag - beide auf dembereits seit #123 grenzuebertretenden Kandidaten
7.0.0-beta.5(siehe CHANGES.md).Umgesetzt und geschlossen (
e4260fc,6324024). Gegenueber dem urspruenglichen Entwurf: dieRetry-Semantik nach
HumanInterventionRequiredist ein explizites--resumestatt einesautomatischen Lesepfad-Abgleichs - Begruendung und Rueckfrage-Ergebnis stehen im Issue-Body
unter "Ergebnis".
--responsibilitybrauchte keinen neuen Code (galt schon aus #123), nur einennachgetragenen Test. #119s Tabelle ist aktualisiert; #127 (
weekly-review-Skill) ist als naechstes frei.torben referenced this issue2026-09-25 19:14:36 +00:00