feat: Die Größe bepreist den ganzen Teilbaum — Kinder zählen nicht obendrauf (D69)

Der Preis eines Knotens ist seine angegebene (oder D66-geschätzte) Größe;
die frühere Rekursion (eigene Größe plus Summe/Minimum der Kinder) zählte
doppelt und bestrafte sorgfältig zerlegte Pakete — eine zerlegte
S-Alternative verlor gegen ein grobes L. Das Vereinigungs-Maß der
Closure-Suche (D42) zählt je Knoten nur noch die Marge über seine nötigen
Teilpakete hinaus. Mitgelieferter Plan wählt identisch (per Vergleich
gemessen); SPEC §9 und llms.md nachgezogen.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
mhoennig
2026-08-25 10:45:12 +02:00
co-authored by Claude Fable 5
parent 7278e74393
commit 4aaa19becd
9 changed files with 227 additions and 33 deletions
+1
View File
@@ -19,6 +19,7 @@ reverse.
## 2026-08-25
- A size prices its whole subtree on the cheapest path — sub-packages no longer add on top, so a carefully decomposed `(S)` beats a coarse `(L)`
- The size is now the last free-standing `(L)`-style token of the line — earlier ones stay in the title, and `"(L)"` or `((L))` mention a size literally
- Fix: Ctrl+click on a dependency preceded by a non-breaking space did nothing, although the parser reads it as a dependency
- Ctrl+click a dependency `:#id` in the text jumps to the line that defines the ID — Ctrl+Enter does the same at the caret
+62
View File
@@ -5098,3 +5098,65 @@ selben Zug (Schritt-3-Regel, Größen-Abschnitt, Zitier-Faustregel).
per Mutation: erster statt letzter Treffer → genau der Letztes-gewinnt-Test
fällt; Anker entfernt → genau die zwei Alleinstehend-/Zitier-Tests. Alle
Snapshots (kanonisches Beispiel §10) unverändert.
## D69 — Die Größe bepreist den ganzen Teilbaum: Kinder kommen nicht obendrauf
Gemeldet am eigenen Beispiel: Eine `|`-Gruppe mit `Manuell mit Downtime (S)`
(zerlegt in XS + S + eine Zugabe) verlor gegen `Failover (L)` — der Pfad
rechnete S(2) + XS(1) + S(2) = 5 gegen L(4). Der Einwand des Nutzers trifft
das Modell im Kern: **„Manuell mit Downtime" ist mit (S) bepreist — dann ist
egal, wie teuer die Summe der Teilpakete ist.** Ob die Zerlegung in die
Größe passt, prüft seit D62 der Größen-Konflikt; die Pfadrechnung hat die
Bewertung nicht anzuzweifeln. Das alte Modell (D18: „eigene Größe plus
Summe/Minimum der Kinder") zählte doppelt und bestrafte damit systematisch
genau die Pläne, die sorgfältig zerlegen — je ehrlicher die Zerlegung, desto
teurer sah das Paket aus.
**Neue Regel: Der Preis eines Knotens ist seine Größe.** Angegeben oder —
seit D66 — aus den Teilpaketen geschätzt; die Schätzung ist dieselbe Sorte
Gesamtaussage und übernimmt die Rolle nahtlos. Erledigtes bleibt 0 (D46).
`cheapestCost()` kollabiert damit auf `ownCost()`: Die Rekursion über die
Kinder entfällt, die Aggregation für größenlose Knoten trägt allein die
D66-Schätzregel. Die Wahl in einer Alternativgruppe vergleicht schlicht die
Größen der Alternativen.
**Die Bewertung gilt auch, wenn die Kinder sie sprengen.** Vier `(S)` unter
einem `(S)` sind ein `sizeConflict` — der Marker zeigt es, aber der Knoten
bleibt bewertet, wie er bewertet wurde (ausdrückliche Nutzer-Entscheidung:
„der übergeordnete Knoten bleibt dennoch S"). Die Alternative — die Kinder
könnten den Preis anheben (max-Variante) — war vorgeschlagen und ist damit
verworfen: Sie hätte die Bewertung des Autors stillschweigend überstimmt,
und für den Widerspruch gibt es bereits den lauten Kanal.
**Das Vereinigungs-Maß der Closure-Suche (D42) zieht mit.** Die Suche über
die gekoppelten Gruppen verglich Belegungen über die Summe der Knoten-Preise
der nötigen Menge — mit Teilbaum-Bepreisung zählte ein zerlegtes
Abhängigkeits-Ziel dann mehrfach (Eltern plus Kinder), ein grobes nur
einmal: dieselbe Zerlegungs-Strafe, nur im Suchmaß. Jeder nötige Knoten
zählt jetzt nur mit dem, was seine Größe **über die nötigen Teilpakete
hinaus** behauptet (nie negativ); die Summe dieser Margen bepreist einen
vollständig zerlegten Teilbaum mit seiner Spitzengröße, gemeinsam
Gebrauchtes zählt über die Mengen-Vereinigung weiterhin einmal. Benannte
Grenze: Wo Kinder ihre Elterngröße im Rangraum übersteigen, liegt das
Suchmaß über dem Preis der lokalen Wahl — die beiden Maße sind dann nicht
identisch; das betrifft genau die Teilbäume, die der Größen-Konflikt ohnehin
anmahnt oder die eng bepreist sind, und die lokale Wahl (der Regelfall)
folgt strikt der Nutzer-Regel.
**Benannter Verlust:** Erledigte Teilpakete unter einem offenen Knoten
senken dessen Preis nicht mehr (kein Kinder-Summieren, keine Bruchteile —
D46 lehnte anteilige Restkosten schon ab). Für die Wahl trägt das kaum:
Sobald an einer Alternative selbst gearbeitet ist, entscheidet ohnehin
`chosenPool` (D61); Stationen und Markierung behalten ihre Knoten-Genauigkeit
unverändert.
**Nachgemessen:** Der gemeldete Fall wählt jetzt „Manuell mit Downtime"
(S=2 gegen L=4). Der mitgelieferte Werkbaum-Plan wählt unter altem und neuem
Modell **identisch** (137 Pfadknoten, 57 Stationen, gleiche Menge — per
git-stash-Vergleich gemessen, nicht angenommen). 450 Tests, davon 5 neue in
`tests/pricing.test.js`; drei Alt-Tests, die die Summen-Semantik festhielten,
sind auf die neue Regel umgeschrieben. Gegenproben per Mutation: alte
Rekursion zurückgebaut → genau die drei danach benannten Zusicherungen
fallen; Vereinigungs-Maß auf schlichte Summe zurück → genau der eine
Marginal-Test (dessen erste Fassung nicht unterschied, weil Wurzeln immer
nötig sind — der Testbaum musste die Ziele unter einen unangetasteten
`+`-Zweig legen).
+26 -12
View File
@@ -598,18 +598,28 @@ wird die **noch offene** Arbeit — der Pfad beantwortet „was ist als Nächste
am günstigsten?", nicht „was hätte der Plan von vorn gekostet?". Ermittelt
werden die für die günstigste Realisierung **nötigen** Knoten:
- **Die Größe bepreist den ganzen Teilbaum.** Der Preis eines Knotens ist
seine **angegebene Größe** (§5) — die Teilpakete kommen **nicht** noch
einmal obendrauf: Wer ein Paket mit `(S)` bewertet hat, hat den Teilbaum
bewertet. Ob die Zerlegung in die Größe passt, prüft der Größen-Konflikt
(§5) — die Pfadrechnung zweifelt die Bewertung nicht an. Fehlt die Größe,
vertritt die Schätzung aus den Teilpaketen sie (unten). Siehe D69 (bis
dahin galt: eigene Größe **plus** Summe/Minimum der Kinder — das
bestrafte gerade die sorgfältig zerlegten Pakete).
- **Erledigtes kostet nichts mehr:** Ein Knoten mit `[x]` oder `[^]` (§4) geht
mit **0** in die Rechnung, unabhängig von seiner Größe. Angefangenes (`[~]`,
`[/]`) zählt dagegen **voll** — die Arbeit ist noch offen. Maßgeblich ist der
**intrinsische** Status: Investiert ist investiert, auch wenn Abhängigkeiten
den Knoten effektiv zurückhalten (§4). Abgezogen werden nur die **eigenen**
Kosten des Knotens, nicht die seines Teilbaums. Folge in Alternativgruppen:
Eine bereits realisierte Alternative gewinnt, auch wenn eine unangetastete
nominell billiger wäre — die Wahl ist getroffen und bezahlt. Siehe D46.
den Knoten effektiv zurückhalten (§4). Offene Teilpakete unter einem
erledigten Knoten bleiben auf dem Pfad und behalten ihre Stationen — die
Kostenfrage stellt sich dort nicht mehr, die Wahl ist realisiert. Folge in
Alternativgruppen: Eine bereits realisierte Alternative gewinnt, auch wenn
eine unangetastete nominell billiger wäre — die Wahl ist getroffen und
bezahlt. Siehe D46.
- **all of:** alle Kinder sind nötig.
- **any of:** nur die **günstigste** Alternative ist nötig. „Günstig" =
kleinste rekursive Kosten (eigene T-Shirt-Größe plus — je Gate — Summe bzw.
Minimum der Kinder). Bei Gleichstand gewinnt die **erste** Alternative.
- **any of:** nur die **günstigste** Alternative ist nötig. „Günstig" ist die
**Größe der Alternative selbst** — angegeben oder geschätzt (oben/unten).
Bei Gleichstand gewinnt die **erste** Alternative.
**Ist in der Gruppe etwas realisiert** (§3: `[~]`, `[/]`, `[x]`, `[^]`), ist
die Wahl damit getroffen — gewählt wird nur noch unter den realisierten
Alternativen, auch wenn eine unangetastete nominell billiger wäre. Sind es
@@ -617,10 +627,10 @@ werden die für die günstigste Realisierung **nötigen** Knoten:
`|`-Gruppe zulässig), entscheidet unter ihnen wieder die Kostenregel.
- **Optionale Knoten (`+`, §3) sind nur nötig, solange an ihnen gearbeitet
wird** — also wenn sie realisiert (§3), aber noch nicht erledigt sind:
`[~]` und `[/]`. Sonst zählen sie weder zu den Kosten ihres Elternknotens
noch liegen sie auf dem Pfad, und der Teilbaum unter ihnen ebenso wenig.
Genau dafür gibt es das Zeichen: Ohne `+` rechnet der günstigste Pfad jede
Zugabe ins Minimum ein und überschätzt es. Die Ausnahme hält den umgekehrten
`[~]` und `[/]`. Sonst liegen sie nicht auf dem Pfad (der Teilbaum unter
ihnen ebenso wenig) und zählen nicht zur Größen-Schätzung (unten).
Genau dafür gibt es das Zeichen: Ohne `+` läge jede
Zugabe auf dem günstigsten Pfad. Die Ausnahme hält den umgekehrten
Fehler heraus — eine angefangene Zugabe ist offene Arbeit, und der Pfad
zeigt die offene Front. **Erledigte Zugaben bleiben draußen:** Dort ist
nichts mehr zu tun, und was darunter offen blieb, ist mit ihnen zusammen
@@ -654,7 +664,11 @@ Gebrauchtes zählt über die Mengen-Vereinigung nur **einmal**. Regeln:
bezahlt werden. **Verfahren (D42): erschöpfende Suche** über die
**gekoppelten** Gruppen (Gruppen, deren Teilbäume Abhängigkeiten enthalten
oder gebraucht werden); alle übrigen wählen lokal wie bisher, bei
Gleichstand die erste. Wird die Suche zu groß, rechnet die Anzeige **gierig
Gleichstand die erste. Verglichen werden die Belegungen über die Summe
dessen, was jeder nötige Knoten **über seine nötigen Teilpakete hinaus**
behauptet (nie negativ) — so bepreist auch die Vereinigung einen Teilbaum
mit seiner Größe, statt Zerlegungstiefe zu bestrafen (D69). Wird die Suche
zu groß, rechnet die Anzeige **gierig
und sagt es** — Warnung `cheapApprox`, zeilenlos.
Darstellung per **Inversion**: nicht benötigte Knoten (nicht-gewählte
+4 -3
View File
@@ -43,7 +43,7 @@
- [^] #ed.deplink.calm: Visually secondary — the tree carries the message (S)
- [^] #ed.deplink.focus: Highlight what a selected node needs and feeds (S)
- [^] #ed.path: Cheapest path (XL)
- [^] #ed.path.cost: Cost model, sizes summed and minimized (S)
- [x] #ed.path.cost: Cost model, a size prices its subtree (S)
- [^] #ed.path.est: Missing size estimated from the sub-packages (S) %% see D66
- [^] #ed.path.front: Only the open front: what is done costs nothing (S) %% see D46
- [^] #ed.path.started: Started work is on the path, extras included (S) %% see D61
@@ -394,8 +394,9 @@
the cheapest alternative. This is the feature the whole notation exists for.
#ed.path.cost
Cost is the T-shirt size, summed along and-groups and minimized along
or-groups.
The cost of a node is its stated (or estimated) T-shirt size — the size
prices the whole subtree, sub-packages are not added on top. Whether they
fit is the size conflict check's job.
#ed.path.est
A node without a size is estimated from its sub-packages: at least the