Files
werkbaum/docs/prs/2026-09-07-PR#4-lean-path-angefangene-zugabe.md
mhoennigandClaude Fable 5.1 4c40ebd0c6
Deploy to GitHub Pages / build (push) Canceled after 0s
Deploy to GitHub Pages / deploy (push) Canceled after 0s
docs(prs): PR#4 — angefangene Zugabe bleibt eine Zugabe
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-07 13:35:22 +02:00

105 lines
5.0 KiB
Markdown

> **Hinweis:** Dieses Dokument beschreibt nur die Änderung dieses PR.
> Es kann veraltet sein, sobald der nächste PR gemergt ist.
> Historische PR-Dokumentation wird nicht nachgepflegt — sie ist eine Momentaufnahme, keine aktuelle Doku.
## Das Problem
In einem geteilten Plan lief der günstigste Pfad durch `#fe.accounts`, ein `-`-Kind der angefangenen Zugabe `+ [~] #fe`.
`#fe.accounts` ist nur für die Erfüllung von `#fe` Pflicht; ist `#fe` optional, ist `#fe.accounts` effektiv auch optional.
Dasselbe galt für die angefangenen Geschwister `#fe.rel` und `#fe.rbac`.
Die Ursache war kein Baufehler, sondern die Ausnahme aus D61: Eine Zugabe lag auf dem Pfad, solange an ihr gearbeitet wurde.
`pathChildren()` nahm sie deshalb wie ein Pflicht-Kind mit — samt Teilbaum, weil alle Nutzer über diese eine Funktion gehen.
An einem Blatt fiel das nicht auf; an einem angefangenen Paket zog es jedes `-`-Kind auf den Pfad.
## Nicht das Ziel
- Die zweite Hälfte von D61 bleibt: Eine realisierte Alternative gewinnt ihre `|`/`=`-Gruppe (`chosenPool`) — dort geht es um eine getroffene Wahl, nicht um Notwendigkeit.
- Keine Änderung an der Dependency Closure (D42): Eine Abhängigkeit aus dem nötigen Teil holt einen Knoten aus einem optionalen Zweig weiterhin herein.
- Keine Änderung an Färbung oder Stationen — nur die Menge der nötigen Knoten ändert sich.
## Die Szenarien
### Feature: Eine angefangene Zugabe bleibt eine Zugabe
#### Hintergrund
- `+` sagt „entbehrlich“, `[~]` sagt „daran wird gearbeitet“; die beiden Achsen sind unabhängig (SPEC §3).
- Die Pfadrechnung liest nur die erste Achse.
#### Szenario#4.01: Das Pflicht-Kind einer angefangenen Zugabe liegt nicht auf dem Pfad
Damit der Pfad nicht durch Arbeit führt, die der Plan für entbehrlich erklärt.
- **Gegeben** eine Zugabe `+ [~] Zugabe (L)` mit den Kindern `- [~] Teil A`, `- [ ] Teil B` und `+ Extra`
- **Wenn** der günstigste Pfad gerechnet wird
- **Dann** liegen weder die Zugabe noch ihre Kinder darauf
##### Nachgewiesen durch
- `tests/optional.test.js`: „holt das Pflicht-Kind einer angefangenen Zugabe nicht herein“.
- Headless gegen den gemeldeten Server-Stand gerechnet: `#fe`, `#fe.rel`, `#fe.rbac`, `#fe.accounts` außerhalb des Pfads.
#### Szenario#4.02: Eine angefangene Zugabe selbst liegt nicht auf dem Pfad
Damit der Status nicht über Notwendigkeit entscheidet.
- **Gegeben** `+ [~] Zugabe (S)` bzw. `+ [/] Zugabe (S)` unter einer Wurzel
- **Wenn** der günstigste Pfad gerechnet wird
- **Dann** liegt nur die Wurzel darauf und ist allein Station
##### Nachgewiesen durch
- `tests/optional.test.js`: „lässt eine `[~]`-Zugabe draußen“, „lässt eine `[/]`-Zugabe ebenso draußen“, „die Wurzel bleibt allein Station“.
#### Szenario#4.03: Eine Abhängigkeit holt das Pflicht-Kind trotzdem herein
Damit die vom Nutzer benannte Ausnahme gilt: Was ein nötiger Knoten braucht, ist nötig.
- **Gegeben** `- [ ] Pflicht (S) :#b` und unter einer angefangenen Zugabe `- [ ] #b: Teil B`
- **Wenn** der günstigste Pfad gerechnet wird
- **Dann** liegt `Teil B` darauf, die Zugabe selbst nicht
##### Nachgewiesen durch
- `tests/optional.test.js`: „eine Abhängigkeit aus dem nötigen Teil zieht das Pflicht-Kind trotzdem herein“.
#### Szenario#4.04: Die Wahl in einer Alternativgruppe bleibt unverändert
Damit die Rücknahme nur die Zugaben trifft.
- **Gegeben** eine `|`- oder `=`-Gruppe mit einer angefangenen und einer billigeren unangetasteten Alternative
- **Wenn** der günstigste Pfad gerechnet wird
- **Dann** gewinnt weiterhin die angefangene
##### Nachgewiesen durch
- `tests/frontier.test.js`, Block „Auswahl — die getroffene Wahl gewinnt“, unverändert grün.
- Gegenprobe per Mutation: Die `isStarted`-Ausnahme wieder eingebaut, fallen genau die fünf neuen Zusicherungen; die Alternativen-Tests bleiben grün.
## Die Lösung
- `pathChildren()` in `frontend/src/model.js` filtert optionale Kinder ohne Ausnahme heraus; `isStarted()` ist entfallen, es hatte keinen Abnehmer mehr.
- SPEC §9 (Günstigster Pfad) beschreibt die Regel neu, `llms.md` zieht nach.
- D97 hält die Entscheidung samt der verworfenen Blatt-Ausnahme und dem benannten Preis fest: Eine angefangene Zugabe steht blass ohne Station da, der Stationen-Knopf führt nicht mehr dorthin.
- Der Plan-Knoten `#ed.path.started` beschreibt die neue Regel und steht auf `[x]`.
Warum die allgemeine Regel und nicht eine Ausnahme nur für Blätter: Die hinge davon ab, ob jemand ein Paket zerlegt hat — dieselbe Zugabe läge vor der Zerlegung auf dem Pfad und danach nicht mehr.
## Offene Fragen
- Keine.
## Weitere Änderungen
- Der mitgelieferte Werkbaum-Plan ändert sich an einer Stelle: `+ [/] #not.tag` tritt mit zwei Knoten vom Pfad zurück (196 → 194 Pfadknoten, 55 → 53 Stationen).
- `CLAUDE.md`: Gitea ist der Arbeitsstand; jeder Branch wird sofort nach `origin` gepusht, GitHub bekommt nie Branches. `remote.pushDefault=origin` und `push.autoSetupRemote=true` sind lokal gesetzt.
## Vorausgesetzte PRs
- Keine.
## Folge-PRs
- Keine geplant.