506 lines
84 KiB
Plaintext
506 lines
84 KiB
Plaintext
# ===== REVIEW DIFF — Story 3.3 (baseline 52f88fdc) =====
|
||
|
||
## TRACKED DIFF:
|
||
diff --git a/_bmad-output/implementation-artifacts/sprint-status.yaml b/_bmad-output/implementation-artifacts/sprint-status.yaml
|
||
index 0b39b41..77d517d 100644
|
||
--- a/_bmad-output/implementation-artifacts/sprint-status.yaml
|
||
+++ b/_bmad-output/implementation-artifacts/sprint-status.yaml
|
||
@@ -29,7 +29,7 @@
|
||
# - Dev moves story to 'review', then runs code-review (fresh context, different LLM recommended)
|
||
# - Retrospective appends its action items to action_items; the status view surfaces open ones
|
||
generated: 08-14-2026 00:00
|
||
-last_updated: 08-19-2026 13:14
|
||
+last_updated: 08-19-2026
|
||
project: wow20
|
||
project_key: NOKEY
|
||
tracking_system: file-system
|
||
@@ -53,7 +53,7 @@ development_status:
|
||
epic-3: in-progress
|
||
3-1-inkrementellen-datenfluss-implementieren-interpret-reconcile: done
|
||
3-2-relevanzbestimmung-textual-deterministisch-umsetzen-grep-rip: done
|
||
- 3-3-bestehende-concepts-erweitern-präzisieren-korrigieren: backlog
|
||
+ 3-3-bestehende-concepts-erweitern-präzisieren-korrigieren: in-progress
|
||
3-4-wissen-aus-mehreren-sources-synthetisieren: backlog
|
||
3-5-leasing-dirty-tree-schutz-für-konkurrierende-producer-umsetz: backlog
|
||
3-6-lease-staleness-recovery-basis-absichern: backlog
|
||
diff --git a/schema/compiler.md b/schema/compiler.md
|
||
index 9b41799..85f22a2 100644
|
||
--- a/schema/compiler.md
|
||
+++ b/schema/compiler.md
|
||
@@ -267,6 +267,11 @@ Diese Sektion ist der **einzige Instruktions-Ort** der Update-Mutationsmechanik
|
||
- **No-Op-Kandidat (Review-Loop-2-Präzisierung):** Erhebt die Kandidatenerhebung einen Pfad, dessen Body die neue Evidenz **bereits vollständig enthält** (keiner der drei Update-Formen greift — keine neue belegte Aussage, keine Schärferung, keine Ersetzung), ist der Kandidat ein **No-Op**: **keine** Body-Mutation, **kein** `generated.at`-Bump, **kein** `sources`-Zusatz, **kein** `log.md`-Eintrag — der Pfad bleibt byte-identisch (Erhaltungs-Invariante, Pkt. 5). Die Entscheidung „keiner der drei Formata greift" ist selbst textuell deterministisch: sie trifft nur, wenn die neue Evidenz keine Aussage trägt, die im Body nicht bereits als belegte Aussage vorhanden ist (Term-/Stellen-Abgleich mit §5.5-Inline-Verweisen); im Zweifel (neue belegte Aussage auch nur in abgewandelter Form) greift Erweitern/Präzisieren — der No-Op ist die *engere* Auslegung.
|
||
- **Mehrfach-Treffer-Konsolidierung (ein Run, mehrere Einheiten auf denselben Concept-Pfad):** Ergeben mehrere neue Wissenseinheiten desselben Runs auf **demselben** bestehenden Concept-Pfad ein Update, werden ihre Mutationen in **einem einzigen Update dieses Pfads** konsolidiert (eine Body-Änderung, **ein** `log.md`-Eintrag „Story 3.1-Update", ein konsolidierter `sources`-Zuwachs, **ein** `generated.at`-Zeitstempel — der einmalige `at` des Runs). Die Reihenfolge der Einheiten wird dabei textual-deterministisch aus der Verarbeitung der Evidenz abgeleitet: REIHENFOLGE = **Auftritt der Einheiten in der Zuwachs-Sicht** (Datei-Reihenfolge des R-1-Zuwachsbefunds, dann Stellen-Reihenfolge innerhalb der Datei); nur bei Einheiten desselben Ortes (identischer Dateipfad + identische Stelle) greift die lexicografische Ordnung als Tie-Break (Review-Loop-2-Präzisierung: die Reihenfolge ist für *alle* Einheiten definiert, nicht nur für vollständig unabhängige). Die AD-16-Default-Erhaltung bleibt für jede betroffene Stelle gewahrt.
|
||
- **Commit-Boundary = Mutations-Boundary (AD-17f, §0):** Auch im Update-Pfad werden **Zwischenstände nie als fertige Mutation veröffentlicht** — die Mutationen der Update-Kandidaten werden als Ganzes committet, und zwar erst, nachdem der Diff-Selbsttest (Pkt. 5) ohne Ghost-Diff abgeschlossen ist. Ein Ghost-Diff ist dann als **Abbruch-Vorlauf „korrigierter Teil-Run"** im `log.md`-Eintrag des betroffenen Runs gekoppelt (siehe Disagreement-/Run-Notiz Pkt. 4), damit die Ursache textuell nachvollziehbar bleibt.
|
||
+ - **Operationelle Ausführungs-Ebene je Update-Form (Präzisierungsebene, Story 3.3 / Revision 2.8; kein neuer normativer Inhalt — deterministische Brücke Regel → Run, AD-17h/A0-19):** Die folgenden Ausführungs-Regeln präzisieren, **was der Producer bei jedem Form-Fall konkret tut und was er unangetastet lässt**. Je Form gelten (a) das **Abgrenzungskriterium** (Welche Form greift wann? — ausschließlich aus der committeten Evidenz abgeleitet), (b) die **Struktur-Erhaltungsregel** (was bleibt unverändert — die „Struktur" aus FR-6/AC-2: Frontmatter-Subset, bestehende belegte Aussagen mit §5.5-Inline-Verweisen, §5.6-Pin) und (c) der **Textgenauigkeits-Rahmen** (wie geschärft wird). Gleicher Git-State + gleiche Eingabemenge → identischer Update-Vorgang (AD-17h).
|
||
+ - **Erweitern — Abgrenzungskriterium:** greift genau dann, wenn die neue committete Evidenz eine **neue belegte Aussage** trägt, die im bestehenden Body **nicht** existiert (Term-/Stellen-Abgleich gegen die §5.5-Inline-Verweise; kein bestehender Anker). **Struktur-Erhaltungsregel (Erweitern):** die neue Aussage wird als **eigener Absatz angefügt** (Body-Ende); bestehende belegte Aussagen bleiben **byte-identisch**, keine Umschreibung bestehender Absätze; Frontmatter nur `sources`-**Zuwachs um den echten neuen Beleg** + ein `generated.at`-Bump. **Textgenauigkeits-Rahmen (Erweitern):** die neue Aussage wird eigenständig formuliert, trägt den §5.5-Inline-Beleg mit existierender Stellen-Kennung; kein Satz-Umbau des Bestands.
|
||
+ - **Präzisieren — Abgrenzungskriterium:** greift genau dann, wenn die Evidenz eine **bestehende Formulierung/Abgrenzung schärft** (präzisierende Information an derselben Aussage, ohne Ersatz). **Struktur-Erhaltungsregel (Präzisieren):** die geschärfte Aussage bleibt an ihrer **Position**, das Satzgefüge wird **nicht umgebaut**, umgebende Aussagen, §5.5-Inline-Verweise anderer Aussagen und die §5.6-Linkform bleiben unverändert; der Beleg wird bei der Aussage neu/nachgeführt (§5.5). **Textgenauigkeits-Rahmen (Präzisieren):** Schärfen = Formulierung/Abgrenzung **an der Aussage selbst**; **kein Satz-Umbau** (keine Neustrukturierung des Absatzes), **kein Neuschreiben ohne Ersetzungsbeleg** — jede ersetzte Formulierung braucht die neue/fortgeführte `raw/`-Evidenz als Inline-Verweis.
|
||
+ - **Korrigieren — Abgrenzungskriterium:** greift genau dann, wenn die Evidenz eine bestehende Aussage als **fehlerhaft/überholt ersetzt**. **Struktur-Erhaltungsregel (Korrigieren):** die ersetzte Aussage wird **nicht still gelöscht**, sondern explizit durch die ersetzende Aussage **abgelöst**; die Ersetzung trägt den **Ersetzungsbeleg** (§5.5, AD-16-Default Erhaltung); die Ablösung erfolgt an der Position der ersetzten Aussage, der Rest des Bodys bleibt unverändert. **Textgenauigkeits-Rahmen (Korrigieren):** nur die fehlerhafte/überholte Aussage wird ersetzt; keine flankierende Umschreibung.
|
||
+ - **No-Op — Abgrenzungskriterium (engere Auslegung, bestehende Regel oben):** greift nur, wenn **keine** der drei Formen greift (die Evidenz ist bereits vollständig im Body); im Zweifel trifft Erweitern/Präzisieren — die Entscheidung ist textuell deterministisch (Term-/Stellen-Abgleich).
|
||
3. **Index-/Link-Form unverändert (§5.6-Pin):** Ein reines Body-Update ändert die Concept-Identität nicht → der bestehende Index-Link (Bundleroot oder Area-`index.md`) bleibt unverändert gültig; **kein neuer Link** bei reinem Body-Update (kein Index-`index.md`-Zusatz). Die **`log.md`-Eintragspflicht** (Pkt. 4) bleibt davon **unberührt**: *jedes* Update — auch ein reines Body-Update — MUSS seinen `log.md`-Eintrag „Story 3.1-Update" führen; nur der **Index-**Link bleibt unverändert. Wird durch das Update eine Concept-Kategorie (Root vs. Area) oder die Identität berührt, ist das **Ask-First** (AD-7d-Renames/Redirects; nicht Teil von Story 3.1). Neue zulässige Concept-Links (Beziehungsschicht, §5.6) werden nur gesetzt, wenn die neue Erkenntnis eine echte, inhaltsbegründete Beziehung rechtfertigt.
|
||
4. **`log.md`-Eintragspflicht (Vertrag §5):** Jedes Update wird als datumsgruppierter Eintrag in `wiki/log.md` dokumentiert (Header = ISO-Datum `YYYY-MM-DD`, neueste zuerst), verknüpft mit dem mutierten Concept-Pfad und den genutzten `raw/`-Quellen. Für Updates wird der Eintrag als „**Story 3.1-Update**" markiert (disambiguierbar von Anlage-Einträgen). Konflikt-/Erhaltungsfälle (Pkt. 2 „Korrigieren" ohne Ersetzungsevidenz) werden explizit als Disagreement-Eintrag mit dem mutierten Concept-Pfad geführt (AD-16b, Vertrag §5) — der Epic-4-Interface-Fall bleibt dokumentiert, ohne Korrektur-Klassifikation hier.
|
||
5. **Erhaltungs-Invariante (Kern) + deterministischer Diff-Selbsttest (AD-17h, FT-6/FR-12):** Ein Compilation Run darf nur die Concepts **neu anlegen oder verändern**, die durch den erkannten Erkenntnis-Zuwachs tatsächlich betroffen sind. **Nicht betroffene Concept-Pfade bleiben byte-identisch unverändert** — es gibt **nie** „Regenerate Everything" (AD-5, A0-6). Die Inkrementalität ist als **re-executierbarer Diff-Selbsttest** mechanisch kontrollierbar: Nach jedem Run prüft der Producer ab der Workspace-Root
|
||
@@ -276,9 +281,10 @@ Diese Sektion ist der **einzige Instruktions-Ort** der Update-Mutationsmechanik
|
||
```
|
||
(erste Zeile: modifizierte/gelöschte Pfade gegen die Baseline; zweite Zeile: zusätzlich ungetrackte neue Pfade `??` und staged-Änderungen — die Duplikat-Kontrolle „keine neue Datei" braucht die `??`-Sicht, die `git diff` allein nicht liefert; `<Baseline-Commit>` siehe Pkt. 6 R-1)
|
||
dass die geänderten Dateien eine Teilmenge von **(Kandidatenliste ∪ Neu-Anlage-Zielpfade ∪ `log.md` ∪ nachgeführte `index.md`)** — mit der Kandidatenliste aus §3 Pkt. 2 (betroffene *bestehende* Concepts, relative OKF-Pfade ohne `.md`) **plus** den Zielpfaden aller im selben Run neu angelegten Concepts (§5.1/§5.7 — Misch-Runs) plus `log.md` und jede nachgeführte `index.md` als zusätzliche zulässige Einträge. **Probe-Zeitpunkt (D-1-Präzisierung):** die Probe läuft **vor dem Commit**, am Ende des P2-Check-Blocks (Pkt. 6) — nach dem Commit wäre `git diff` leer und die Probe vacuous (Commit-Boundary = Mutations-Boundary, AD-17f: der Run committiert erst, nachdem die Probe ohne Ghost-Diff abgeschlossen ist). **Pfad-Normalisierung vor dem Teilmenge-Vergleich:** die Proben-Ausgabe trägt `wiki/`-Präfix und `.md`-Endung; die Kandidaten-/Ziel-Pfade sind definiert als relative OKF-Pfade *ohne* `.md` — für den Vergleich werden von jedem Proben-Eintrag `wiki/`-Präfix und `.md`-Suffix gestrippt (deterministischer Normalisierungsschritt). Jede Abweichung (**Ghost-Diff** auf einem nicht betroffenen Pfad) ist ein Instruktions-Verstoß (FT-6): Der Producer behebt sie textuell benannt (NFR-4) und **rollt den Ghost-Diff zurück, bevor der Run als gültig vermerkt wird** — der beobachtbare Endzustand des Bundles bleibt damit konsistent (AD-6-Backstop). **Rollback-Mechanik:** der Ghost-Diff betrifft nur Pfade *außerhalb* der erlaubten Menge; der Producer stellt die betroffenen Pfade aus dem Baseline-Zustand wieder her (für modifizierte Pfade: `git checkout -- <wiki/pfad>`; für ungetrackte neue Dateien: Datei löschen; für Index-Änderungen: `git checkout -- wiki/index.md` bzw. die Area-`index.md`) — der Teilzustand-Rollback des §5.3 Pkt. 3 / §6 Pkt. 3 greift daneben unverändert. Für Story 3.1 selbst (Instruktions-Story ohne Inhalts-Mutation) ist der Nachweis: `git diff --name-only -- wiki/` liefert ausschließlich `wiki/log.md` — keine Concept-Datei, keine `index.md` (die aggressive `git diff --stat -- wiki/`-Default-Effektiv-ausgabe zeigt denselben Pfad, `wiki/log.md | 1 +`). *(Anmerkung: `schema/compiler.md` und `deferred-work.md` liegen **außerhalb** `wiki/` und sind daher kein Teil dieser Diff-Probe — sie gehören zum Instruktions-, nicht zum Bundle-Baum; der Ghost-Diff-Begriff dieser Sektion gilt nur für `wiki/`.)*
|
||
+ Die Probe verifiziert dabei **zwei Ebenen** (Struktur-Erhaltungs-Bezug, Story 3.3): **(1) die Pfad-Mengen-Ebene** (obiger Teilmenge-Vergleich — welche Pfade der Run berührt hat) und **(2) die Struktur-Ebene je berührtem Pfad** — die Struktur-Erhaltung „ohne die Struktur zu zerstören" (FR-6/AC-2) wird pro betroffenem Concept-Pfad über die Pkt.-2-Regeln geprüft (Frontmatter-Subset-Konformität: nur `sources`-Zuwachs um echte neue Belege + `generated.at`-Bump, kein neuer Key, keine Entfernung ohne Beleg; bestehende belegte Aussagen nicht umgeschrieben ohne dass Präzisieren/Korrigieren greift; §5.5-Inline-Verweise weiterhin gültig soweit Beleg Body-Bestand; §5.6-Linkform unverändert, keine neuen Links außer bei echten Beziehungen — Verstöße sind textuell zu benennen (NFR-4) und werden vor dem Commit behoben, sonst gilt der Pfad als Ghost-Diff mit Rollback gemäß dieser Pkt.-5-Konsequenz).
|
||
6. **Run-Vorphase-Bausteine (Defer R-1 + P2, in den Update-Pfad eingearbeitet):** Beide sind **keine** neuen Prozesse — wiederverwendbare, reproduzierbare textuelle Check-Blöcke innerhalb der Instruktions-Ausführung (D-3):
|
||
- **Change-Detection (Defer R-1, Input-Zuwachserkennung):** Vor der Interpretation bestimmt der Producer, **welche `raw/`-Dateien Zuwachs** sind (neu/modifiziert). Deterministische Mittel: `git diff --name-only <Baseline-Commit> -- raw/` auf das `raw/`-Verzeichnis und/oder der **SHA-256-Record aus `raw/**/source.md`** (Provenienz-Sidecar, §1 Pkt. 4). Als `<Baseline-Commit>` dient der **letzte committete Zustand des Workspace** (deterministisch: der HEAD der vorherigen Mutations-Boundary, AD-17f). **Auflösungs-Regel (D-2-Präzisierung, Review-Loop 2):** der Producer **notiert den `<Baseline-Commit>` (vollen SHA) im `wiki/log.md`-Eintrag des Runs** — damit ist er deterministisch auflösbar ohne Domain-State-Annahme an Git (AD-14: Git liefert Historie, nicht Domain-State; der log.md-Eintrag ist der State-Referenz-Punkt, keine Git-Historie-Interpretation). **Diskrepanz-Regel:** widersprechen sich `git diff`-Befund und SHA-256-Record für dieselbe Datei, **gewinnt der `git diff`-Befund** (Commit-Boundary = Mutations-Boundary, AD-17f); der SHA-256-Record bleibt Sekundär-Fingerprint. Ist der SHA-256-Record unlesbar/fehlend, wird die Datei dennoch als Zuwachs **nicht doppelt** verarbeitet (textueller Hinweis) und gegen den `git diff`-Befund abgeglichen (kein Doppel-Verdikt). **Fallback:** existiert keine vorherige Mutations-Boundary (frischer Workspace ohne Lauf-Historie), gilt **alle `raw/`-Dateien als Zuwachs**. Die Diff-Probe in Pkt. 5 läuft gegen **dasselbe** `<Baseline-Commit>` (Review-Loop-2-Korrektur des Rev-2.4.1-Claims: die Pkt.-5-Probe trägt das Baseline-Commit-Argument explizit).
|
||
- - **Pre-Run-Reconcile-Check-Block (Defer P2):** Vor jeder Mutation durchläuft der Producer den gebündelten Vorprüf-Block und hält ihn textuell fest: (1) **Input-Zustand** (AD-17a, I/O-Matrix `INPUT_UNCOMMITTED`; Review-Loop-2-D-3): Working-Copy von `raw/` und `wiki/` gegen HEAD prüfen — bei Abweichung (uncommitteder Zustand) bricht der Run mit dem **textuell benannten Abbruch „published/committed Input erforderlich"** ab, **vor** Interpretation und vor jeder Mutation (keine Mutation gegen Zwischenstände); (2) Ziel-Pfade (Ausgangs-Kandidatenliste, §3 Pkt. 2); (3) Quellen-Existenz (EC-1 via Validator-Punkt: jede referenzierte `raw/`-Datei existiert als Datei); (4) Betroffenheits-Kandidatenliste (§3 Pkt. 2, textuell-deterministisch); (5) `wiki/index.md`-V-1-Vorbedingung (fehlende Bundleroot → Run-FAIL, §3 Pkt. 3, Vertrag §2). Dieser Block ist der in `deferred-work.md` als P2 notierte Pre-Plan-Schritt und wird durch Story 3.1 als Teil des inkrementellen Runs ausgeführt. **Zeitpunkt (Review-Loop-2-Präzisierung):** der Block wird **nach Reconcile (2) und vor Mutieren (4)**, am **Anfang der Mutationsphase**, einmal pro Run durchgeführt — die Kandidatenliste (Elemente 2/4) existiert zu diesem Zeitpunkt bereits; die **Diff-Probe (Pkt. 5) läuft am Ende desselben Blocks, nach den Mutationen, vor dem Commit**. Die Kandidatenliste, die hier festgehalten wird, ist **die** Kandidatenliste, gegen die der Diff-Selbsttest (Pkt. 5) prüft (keine zweite, davon abweichende Erhebung nach der Mutation).
|
||
+ - **Pre-Run-Reconcile-Check-Block (Defer P2):** Vor jeder Mutation durchläuft der Producer den gebündelten Vorprüf-Block und hält ihn textuell fest: (1) **Input-Zustand** (AD-17a, I/O-Matrix `INPUT_UNCOMMITTED`; Review-Loop-2-D-3): Working-Copy von `raw/` und `wiki/` gegen HEAD prüfen — bei Abweichung (uncommitteder Zustand) bricht der Run mit dem **textuell benannten Abbruch „published/committed Input erforderlich"** ab, **vor** Interpretation und vor jeder Mutation (keine Mutation gegen Zwischenstände); (2) Ziel-Pfade (Ausgangs-Kandidatenliste, §3 Pkt. 2); (3) Quellen-Existenz (EC-1 via Validator-Punkt: jede referenzierte `raw/`-Datei existiert als Datei); (4) Betroffenheits-Kandidatenliste (§3 Pkt. 2, textuell-deterministisch); (5) `wiki/index.md`-V-1-Vorbedingung (fehlende Bundleroot → Run-FAIL, §3 Pkt. 3, Vertrag §2); (6) **Struktur-Erhaltungs-Check (Story-3.3-Ergänzung als zusätzliches textuelles Element):** vor dem Commit prüft der Producer an den betroffenen Concept-Pfaden, dass keinerlei unbefugte Keys im Frontmatter entstanden sind (Vertrag §3.3/§3.4-Subset, §6.5-Kriterium-1), **keine stille Löschung** bestehender belegter Aussagen/Provenienz erfolgt ist (AD-16, Pkt. 2 „Korrigieren"-Form) und **keine Links** verändert oder ohne echte Beziehung neu gesetzt wurden (§5.6-Pin, Pkt. 3); Verstöße sind textuell benannt (NFR-4) und vor dem Commit zu beheben; die Kandidatenliste bleibt **die** Liste gegen die der Diff-Selbsttest (Pkt. 5) prüft (keine zweite Erhebung nach der Mutation). Dieser Block ist der in `deferred-work.md` als P2 notierte Pre-Plan-Schritt und wird durch Story 3.1 als Teil des inkrementellen Runs ausgeführt. **Zeitpunkt (Review-Loop-2-Präzisierung):** der Block wird **nach Reconcile (2) und vor Mutieren (4)**, am **Anfang der Mutationsphase**, einmal pro Run durchgeführt — die Kandidatenliste (Elemente 2/4) existiert zu diesem Zeitpunkt bereits; die **Diff-Probe (Pkt. 5) läuft am Ende desselben Blocks, nach den Mutationen, vor dem Commit**.
|
||
7. **Worked Example (an die reale Ist-Lage gebunden, re-executiert; Review-Loop-2-Korrektur):** Ein Run mit neuer committeter Evidenz `raw/epics/epics-2026-08-14.md#FR-12` (Zuwachs über die bisher verarbeitete Stelle hinaus; die Kennung FR-12 existiert real in der Datei) trifft über `rg -l 'FR-12' -g '!log.md' wiki/` das bestehende Root-Concept `wiki/knowledge-kompilation-inkrementell.md` (Term-/Konzept-Überschneidung — re-executierter Befund: der Grep-Ausgabe-Pfad ist `knowledge-kompilation-inkrementell`, `wiki/log.md` exkludiert gemäß §3.2-Pkt.-2a; das Rev-2.4.1-Beispiel `wissensarchitektur/source-material.md` enthielt den Term **nicht** und ist damit korrigiert). Der Run aktualisiert diesen Pfad (Body-Erweiterung mit neuem §5.5-Inline-Beleg `(raw/epics/epics-2026-08-14.md#FR-12)`, `sources`-Ergänzung um diesen `resource` — sofern nicht bereits deklariert, sonst No-Op gemäß Pkt. 2, `generated.at` = aktueller Run-Zeitstempel, `log.md`-Eintrag „Story 3.1-Update"). Die Diff-Probe (Pkt. 5, `<Baseline-Commit>`-Form) zeigt ausschließlich `log` und `knowledge-kompilation-inkrementell` (betroffen, normalisiert) — kein Ghost-Diff, keine `index.md` im Diff (der Index-Link bleibt unverändert).
|
||
|
||
## 6. Validieren (mechanische Bestätigung)
|
||
@@ -373,3 +379,4 @@ Diese Instruktion ist auf die **Erzeugung neuer Concepts auf Root-Ebene und in A
|
||
- **Revision 2.5 (2026-08-19, Story 3.2):** Neue Sektion **§3.2 „Relevanzbestimmung (Story 3.2)"** eingefügt (nach §3, vor §4) — die **verbindliche Ausformulierung der §3-Pkt.-2-Kandidatenerhebung** („Erhebung nach §3.2"): (1) **Term-Ziehverfahren** deterministisch (bedeutungstragende Token-Folgen nach §2-Interpretation; Normalisierung lowercasing + `[-–_ ]`→`-`-Kollaps; **kanonischer Schreibweisen-Resolver `schema/canonical-terms.md`** — committete, append-only Registry (canon. Form + erlaubte Varianten), damit Bestandteil des Git-States und deterministisch pinbar; genau eine canon. Form je Semantik A0-18; kein stiller Ausschluss nicht auflösbarer Varianten — Verwendung wie notiert; mehrere Terme je Einheit → Vereinigung), (2) **dreistufige term-übergreifende Erhebung über `wiki/`** — (a) `rg -l '<term>' --exclude=log.md wiki/` (grep-Äquivalent `grep -rl … --exclude=log.md`; `log.md` **strukturell** exkludiert, Candidate-Liste auf Concept-Pfade definiert), (b) `index.md`-Traversal (gewurzelte Erreichbarkeit Root → Area → Concept, §5.8; TRAVERSAL_REACH_ONLY; fehlende Bundleroot → Run-FAIL V-1), (c) Link-Following mit **besuchter Menge** (file-relativ auflösen, §5.7 Pkt. 4; Zyklen enden, LINK_FOLLOWING_ZYKLUS); (3) **Candidate-Liste + Determinismus-Vertrag (AD-17h/A0-19):** relative OKF-Pfade ohne `.md` (Strip `wiki/`-Präfix + `.md`-Suffix), **Zuwachs-Sicht-Ordnung** mit Reihenfolge auch für Stufe-b/c (nach Stufe-a; lexikografisch als deterministischer Tie-Break), keine Duplikate (besuchte Menge), NO_MATCH → leere Candidate-Liste → UNTOUCHED_CONCEPT (Story-3.1-Pfad); Determinismus-Selbsttest (Membership + Zwei-Run-Identität) in Spec-Verification und `wiki/log.md` belegt. **§3 Pkt. 2:** Story-3.2-Vorbehalt **aufgelöst** — Pkt. 2 bleibt Kern-Anker, die Erhebung zeigt auf die neue Sektion („Erhebung nach §3.2"), `rg -l '<term>' --exclude=log.md wiki/` als Stufe-a-Form genannt. **§7:** Story-3.2-Vorbehalt **aufgelöst** (Relevanzbestimmung in §3.2 verankert; verbleibende 3.x-Themen: Synthese → Story 3.4, Leasing/Dirty-Tree → Story 3.5/3.6). **§8:** Normreferenzen um **AD-13** (bereits gelistet, §3.2-angeankert), **A0-18** (Deterministische Relevanzbestimmung, §3.2) und **A0-19** (Determinismus-Vertrag, §3.2 — war im Ist-§8 noch nicht gelistet, wird als Determinismus-Referenz ergänzt) sowie **PRD OQ-3** (Compilation Scope, §3.2) ergänzt; **`schema/canonical-terms.md`** als nebengeordnete committete Resolver-Registry referenziert (kein `schema/`-Root-Change; gleiche read-only-Hierarchie, append-only). Em-Dash-`—`-Varianten-Lücke als offene Determinismus-Frage an **Story 3.8** übergeben (nicht stillschweigend ergänzt). **Abschlussklausel:** Keine Änderung an `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` (AD-3); **keine neue §7-Invaliditätsklasse**; **kein Standalone** (D-3); keine Vertragsänderung; Commit-Boundary-Regel unverändert. **`sprint-status.yaml`:** Key `3-2-relevanzbestimmung-textual-deterministisch-umsetzen-grep-rip` `backlog` → **`in-progress`**. `wiki/log.md`-Eintrag (append-only, bestehende Bullets unverändert), `deferred-work.md`-epic-3-context-Eintrag → aufgegriffen (append-only), Determinismus-Selbsttest + Validator-Lauf (7/7 SUCCESS) siehe `wiki/log.md`-Nachweis.
|
||
- **Revision 2.4.2 (2026-08-19, Story 3.1, bmad-code-review Loop 2, 4 Layer; Nutzer-Entscheidungen D-1/D-2/D-3/D-4 = 1/1/1/1):** (1) **Diff-Selbsttest (Pkt. 5) operationalisiert + Blind-Spots geschlossen (D-1):** Probe erweitert auf `git diff --name-only <Baseline-Commit> -- wiki/` **plus** `git status --porcelain -- wiki/` (erfasst ungetrackte neue Dateien `??` — die Duplikat-Kontrolle „keine neue Datei" braucht diese Sicht; `git diff` allein ist blind für Untracked); **Probe-Zeitpunkt fixiert vor dem Commit** (am Ende des P2-Blocks, nach den Mutationen) — nach dem Commit wäre die Probe vacuous (leere Ausgabe, AD-17f); erlaubte Teilmenge-Menge um **Neu-Anlage-Zielpfade** (§5.1/§5.7) ergänzt — Misch-Runs (Neu-Anlage + Update im selben Run) markieren neu angelegte Pfade nicht fälschlich als Ghost-Diff; **Pfad-Normalisierung** definiert (Strip `wiki/`-Präfix + `.md`-Suffix vor dem Teilmenge-Vergleich, da Kandidaten/Ziel-Pfade als relative OKF-Pfade *ohne* `.md` definiert sind); **Rollback-Mechanik** für den Ghost-Diff deterministisch benannt (modifizierte Pfade via `git checkout -- <wiki/pfad>`, ungetrackte neue Dateien gelöscht, Index via `git checkout -- <index>`; §5.3/§6.3-Teilzustand-Rollback greift daneben unverändert). (2) **R-1-Baseline deterministisch + Abweichungsregel (D-2):** `<Baseline-Commit>` (HEAD der vorherigen Mutations-Boundary, AD-17f) wird vom Producer **im `wiki/log.md`-Run-Eintrag notiert** (voller SHA) — deterministisch auflösbar ohne Domain-State-Annahme an Git (AD-14); **Diskrepanz-Regel**: widersprechen `git diff`-Befund und SHA-256-Record derselben Datei, **gewinnt `git diff`** (Commit-Boundary-Prinzip), SHA-256 bleibt Sekundär-Fingerprint; **Fallback**: ohne vorherige Mutations-Boundary gelten alle `raw/`-Dateien als Zuwachs; Rev-2.4.1-Claim „derselbe Baseline-Commit wie Pkt. 5" **korrigiert** (die Pkt.-5-Probe trägt das Baseline-Commit-Argument jetzt explizit). (3) **INPUT_UNCOMMITTED-Abbruch (D-3) + Anker-Divergenz:** neuer P2-Check-Block-Element (1) **Input-Zustand** — Working-Copy von `raw/`/`wiki/` gegen HEAD prüfen, bei Abweichung **benannter Abbruch „published/committed Input erforderlich"** vor Interpretation und vor jeder Mutation (AD-17a, I/O-Matrix-`INPUT_UNCOMMITTED` — zuvor nur Referenz auf §1 Pkt. 1, keine Zustandsprüfung/Abbruchmeldung); die **Spec↔Anker-Divergenz** (frozen Spec zitiert 3× „§1.1", §1 ist eine nummerierte Liste Pkt. 1–4 ohne §1.1-Label; Rev-2.4.1 korrigierte nur die Anker *in* compiler.md) wird hier als dokumentierte Fußnote gesichert — die Spec bleibt frozen (nur per menschlicher Renegotiation änderbar). (4) **Sandbox-Edge-Test-Nachweis (D-4):** die fünf I/O-Matrix-Szenarien (HAPPY_PATH_UPDATE, UNTOUCHED_CONCEPT, CONCEPT_COLLISION_BESTEHEND, CHANGE_DETECTION, PRE_RUN_RECONCILE) + die D-3-Abbruch-Kontrolle sind als re-executierbare Sandbox-Skripte mit **konkreten deterministischen Ausgaben** in der Spec-`## Verification`-Sektion (Sandbox-Beleg) verankert — die `wiki/log.md`- und `deferred-work.md`-Verweise („in der Spec-Verification enthalten") auflösbar. (5) **Instruktions-Präzisierungen:** P2-Block-**Zeitpunkt** (nach Reconcile, am Anfang der Mutationsphase; Diff-Probe am Block-Ende) — löst den Widerspruch „einmal an der Spitze erhoben" vs. „Kandidatenliste entsteht erst im Reconcile"; **No-Op-Kandidat**-Regel (Pkt. 2: Pfad, der die Evidenz bereits vollständig enthält → keine Mutation/kein `at`-Bump/kein `log.md`-Eintrag, byte-identisch — die engere Auslegung); **Mehrfach-Treffer-Reihenfolge** für *alle* Einheiten definiert (Zuwachs-Sicht-Ordnung; lexicografisch nur als Tie-Break bei identischem Ort — AD-17h); **Update-Pfad-Rollback** in §5.3 Pkt. 3 (modifizierte Pfade aus Baseline-Commit wiederherstellen); **`generated.at`↔AD-17h-Gap** explizit als offener Punkt mit Home Story 3.8 benannt (Wanduhr-`at` erzeugt bei gleichem Input unterschiedliche Bundle-States; Konvention bleibt bis dahin bindend, Wechsel = Ask-First); **Term-Ableitung** (Pkt. 2 (a)) als §2-Interpretation abgegrenzt — die Erhebung *mit festem Term* ist textuell-deterministisch, der Term-Mechanismus (Kanonisierung/Synonyme) Story 3.2; **Link-Following** mit besuchter Menge (keine Schleife bei zyklischen Links); **Worked Example (Pkt. 7) auf den realen Ist-Baum korrigiert** (`rg -l 'FR-12' wiki/` trifft `wiki/knowledge-kompilation-inkrementell.md`, **nicht** `wissensarchitektur/source-material.md` — Rev-2.4.1-Beispiel enthielt den Term nicht); stale-Anker `§3.2-Kollisionsprüfung` (Pkt. 3-Zuordnung) und `§3-Voraussetzungsprüfung` (P2-Block) sowie §5.8-Pkt.-3-Zeiger („Pkt. 1" → „Pkt. 2") nachgeführt. **Abschlussklausel:** Keine Änderung an `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` (AD-3); **keine neue §7-Invaliditätsklasse**; **kein Standalone** (D-3); keine Vertragsänderung; Commit-Boundary-Regel unverändert.
|
||
- **Revision 2.7 (2026-08-19, Story 3.2, Step-04-Review Loop 3, 4 Layer; Nutzer-Entscheidungen D-1/D-2/D-3/D-4/D-5 = 1/1/1/1/1, jeweils empfohlene Option; + 2 Patches; D-3-Instruktions-Patch, kein neuer Inhalt):** (1) **§3.2-Pkt.-3b-Ordnung auf reine Lexikografie gehoben (D-4):** Stufe-a-Treffer waren „in der Reihenfolge des ziehenden Terms, dann lexikografisch als deterministischer Tie-Break" — die Term-Ordnung selbst war für Mehrfach-Terme (Pkt. 1c) nirgends festgelegt, zwei rechtmäßige Term-Ordnungen erzeugten zwei unterschiedliche Listen (AD-17h-Lücke). Jetzt: **innerhalb jeder Stufe rein lexikografisch aufsteigend (LC_ALL=C)**; die Term-Verarbeitungsreihenfolge dient nur der Interpretation/Erhebung, **nicht** der Listen-Ordnung — dieselbe Treffermenge → identische Liste. (2) **`schema/canonical-terms.md`-Lookup-Semantik vervollständigt (D-5):** Lookup-Verfahren deterministisch fixiert (lowercasing → `[-–_ ]`→`-`-Kollaps → **Lookup der normalisierten Form**; Spalten tragen ausschließlich normalisierte Formen), **Eindeutigkeits-Invariante** (jede normalisierte Form in genau einem Eintrag — Canon **oder** Variante, nie beides/zweimal) + **Konflikt-Verfahren** (keine stille Anhängung; `deferred-work.md`-Handoff / Ask-First, analog zur Umbenennungs-Regel). (3) **Statuskette `in-progress → done` dokumentiert (D-1):** der Review-Loop-Abschluss-Flip `in-progress → done` (Sprint-Sync-Konvention, Story-3.1-Präzedenz) war in keinem `wiki/log.md`-Eintrag als eigener Schritt belegt — nachgeführt als neuer oberster `wiki/log.md`-Bullet (append-only; die gefrorene Always-Klausel `→ in-progress` beschreibt den Implementierungsstand, der Review-Abschluss `done` ist der übliche Folgezustand). (4) **Mini-Sandbox um T5/T6/T7 erweitert + T1/T4-Asssertionen + T2-Kommentar-Korrektur (D-2 + Patch P-1):** T5 `LINK_FOLLOWING_ZYKLUS` (A→B→A-Links; besuchte Menge → endliche, doppelungsfreie Liste), T6 `TRAVERSAL_REACH_ONLY` (Term nur in Area-`index.md` → gewurzelte Concept-Pfade als Kandidaten; `index.md` selbst ist kein Concept-Kandidat), T7 `TERM_ABLEITUNG_SYNONYM` (Registry-Test-Doppel: Schreibvarianten → canonische Form via Lookup auf normalisierter Form; Negativ-Fall: nicht auflösbar → wie notiert, kein stiller Ausschluss); T1/T4 tragen jetzt harte Pass/Fail-Asssertionen (`exit 1` bei Abweichung) — die exakte Candidate-Liste wird erzwungen, nicht nur ausgegeben; der T2-Kommentar zu `index` korrigiert (Stufe-a-Treffer auf `wiki/index.md` löst Stufe b aus; `index.md` ist kein Concept-Kandidat). (5) **Selbsttest-Beleg (b) gegen den realen Sandbox-Ist-Baum re-executiert (D-3):** der Rev-2.5-Log-Beleg (b) beschrieb einen nicht-committierten Baum (Term `quanten-protocol`, `sub/beta.md`, SHA-256 `159092bb…`) — Stale-Evidenz-Falle (B1-Präzedenz). Der Nachweis wird jetzt gegen die echte `run-sandbox.sh`-Ausgabe (Term `deterministische-relevanz-bestimmung`, root-level `alpha`/`beta`/`gamma`) neu belegt; der Rev-2.5-Eintrag bleibt historisch unverändert, die Korrektur steht als neuer `wiki/log.md`-Bullet (append-only). (6) **Typos im normativen Text korrigiert (Patch P-2):** `Determinsmus` → `Determinismus` (§8-Referenzen + Log-/Defer-Belege), `§3.2-beankert` → `§3.2-angeankert`, `Membrum` → `Mitglied` (Spec-Design-Notes), `Konventionelle Determinismus-Lücke` → `Bekannte Determinismus-Lücke` (Defer-Beleg; `compiler.md:53` sagt „Bekannte"), `Resovierung` → `Auflösung` (Spec-Change-Log/-Verification). **Abschlussklausel:** Keine Änderung an `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` (AD-3); **keine neue §7-Invaliditätsklasse**; **kein Standalone** (D-3); keine Vertragsänderung; Commit-Boundary-Regel unverändert. (Revisionslog-Reihenfolge-Anomalie 2.6/2.5 bleibt als dokumentierter Defer bestehen — nicht in dieser Runde umgeordnet.)
|
||
+- **Revision 2.8 (2026-08-19, Story 3.3):** §5.9-Update-Formen **operationell ausformuliert** (dieselbe Evidenz + formale Struktur → identisches Update-Ergebnis, AD-17h/A0-19): (1) **Pkt. 2 — Präzisierungsebene je Update-Form** (als Sub-Bullet an die Commit-Boundary-Regel angefügt; der frozen Story-3.1-Regeltext bleibt textuell **unverändert** als normative Basis, die operationellen Regeln sind die Ausführungs-Ebene darunter — keine Re-Negotiation): je Form **(a) Abgrenzungskriterium** (aus der committeten Evidenz: neue belegte Aussage → Erweitern; Schärfung einer bestehenden Formulierung/Abgrenzung ohne Ersatz → Präzisieren; Ersetzung einer fehlerhaften/überholten → Korrigieren; keines davon → No-Op, engere Auslegung), **(b) Struktur-Erhaltungsregel** (das Geschützte — Frontmatter-Subset nur als `sources`-Zuwachs um echten neuen Beleg + `generated.at`-Bump; bestehende belegte Aussagen nicht umgeschrieben ohne dass Präzisieren/Korrigieren greift; §5.5-Inline-Verweise gültig soweit Beleg Body-Bestand; §5.6-Linkform unverändert, keine neuen Links außer bei echten Beziehungen) und **(c) Textgenauigkeits-Rahmen für Präzisieren** (Schärfen an der Aussage, kein Satz-Umbau, kein Neuschreiben ohne Ersetzungsbeleg). (2) **Pkt. 5 — Erhaltungs-Invariante um den Struktur-Erhaltungs-Bezug ergänzt:** die Diff-Probe verifiziert zwei Ebenen — die Pfad-Mengen-Ebene (bestehender Teilmenge-Vergleich) und die **Struktur-Ebene je berührtem Pfad** (pro betroffenem Concept-Pfad über die Pkt.-2-Regeln geprüft: Frontmatter-Subset, keine Umschreibung belegter Aussagen außerhalb der Formen, Inline-Verweise, Linkform — Verstöße textuell benannt (NFR-4), vor dem Commit zu beheben, sonst Ghost-Diff mit Rollback). (3) **Pkt. 6 — P2-Check-Block um den Struktur-Erhaltungs-Check erweitert** (Element (6), zusätzliches textuelles Element: keine unbefugten Keys — Vertrag §3.3/§3.4-Subset, keine stille Löschung — AD-16/„Korrigieren"-Form, Links unverändert/keine neuen ohne echte Beziehung — §5.6-Pin; Verstöße textuell benannt (NFR-4) und vor dem Commit behoben). (4) **Abschlussklausel:** Keine Änderung an `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` (AD-3); **keine neue §7-Invaliditätsklasse**; **kein Standalone** (D-3); keine Vertragsänderung; Commit-Boundary-Regel unverändert; kein Leasing-Scope (AC-4 → Story 3.5/3.6, AD-17.3-Hinweis unverändert in §7). **`sprint-status.yaml`:** Key `3-3-bestehende-concepts-erweitern-präzisieren-korrigieren` bleibt **`in-progress`** (Review-Abschluss `done` erfolgt gemäß Workflow-Konvention durch den Review-Schritt). Sandbox-Nachweis und per-Datei-Validator-Verdikt siehe `wiki/log.md`-Eintrag (Story 3.3, Revision 2.8).
|
||
diff --git a/wiki/log.md b/wiki/log.md
|
||
index 9b29777..326d011 100644
|
||
--- a/wiki/log.md
|
||
+++ b/wiki/log.md
|
||
@@ -1,6 +1,7 @@
|
||
# Log
|
||
|
||
## 2026-08-19
|
||
+- **Story 3.3 «Bestehende Concepts erweitern/präzisieren/korrigieren — Update-Formen operativ schärfen» (Implementierung, Instruktions-Story D-3; `sprint-status.yaml`: Key `3-3-bestehende-concepts-erweitern-präzisieren-korrigieren` bleibt **`in-progress`** — der Review-Abschluss-Flip `done` erfolgt gemäß Workflow-Konvention durch den Review-Schritt):** `schema/compiler.md` → **Revision 2.8** — die drei Update-Formen **operationell ausformuliert** (deterministische Brücke Regel → Run, AD-17h/A0-19; kein neuer normativer Inhalt, kein Schema-/Validator-/`raw/`-Change AD-3; der frozen Story-3.1-Regeltext bleibt unverändert als normative Basis, die operationellen Regeln sind die Präzisierungsebene darunter — keine Re-Negotiation): (1) **§5.9 Pkt. 2 — Präzisierungsebene je Update-Form** (Sub-Bullet an die Commit-Boundary-Regel angefügt): je Form **(a) Abgrenzungskriterium** (aus der committeten Evidenz — neue belegte Aussage → **Erweitern**; Schärfung einer bestehenden Formulierung/Abgrenzung ohne Ersatz → **Präzisieren**; Ersetzung einer fehlerhaften/überholten → **Korrigieren**; keines davon → **No-Op**, engere Auslegung — gleicher Git-State + gleiche Eingabemenge → identischer Update-Vorgang), **(b) Struktur-Erhaltungsregel** (das Geschützte aus FR-6/AC-2: Frontmatter-Subset — nur `sources`-Zuwachs um echten neuen Beleg + `generated.at`-Bump, kein neuer Key, keine Entfernung ohne Beleg; bestehende belegte Aussagen nicht umgeschrieben ohne dass Präzisieren/Korrigieren greift; §5.5-Inline-Verweise gültig soweit Beleg Body-Bestand; §5.6-Linkform unverändert, keine neuen Links außer bei echten Beziehungen) und **(c) Textgenauigkeits-Rahmen** (Schärfen an der Aussage selbst, kein Satz-Umbau, kein Neuschreiben ohne Ersetzungsbeleg). (2) **§5.9 Pkt. 5 — Erhaltungs-Invariante um den Struktur-Erhaltungs-Bezug ergänzt:** die Diff-Probe (§5.9 Pkt. 5, D-1-Form) verifiziert zwei Ebenen — die Pfad-Mengen-Ebene (bestehender Teilmenge-Vergleich) und die **Struktur-Ebene je berührtem Pfad** (pro betroffenem Concept-Pfad über die Pkt.-2-Regeln geprüft: Frontmatter-Subset, keine Umschreibung belegter Aussagen außerhalb der Formen, Inline-Verweise, Linkform; Verstöße textuell benannt NFR-4, vor dem Commit zu beheben, sonst Ghost-Diff mit Rollback). (3) **§5.9 Pkt. 6 — P2-Check-Block um den Struktur-Erhaltungs-Check erweitert** (Element (6), zusätzliches textuelles Element: keine unbefugten Keys — Vertrag §3.3/§3.4-Subset, keine stille Löschung — AD-16/„Korrigieren"-Form, Links unverändert/keine neuen ohne echte Beziehung — §5.6-Pin). (4) **§8 Revisionslog Revision 2.8** mit Abschlussklausel (keine Änderung an `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` AD-3; keine neue §7-Invaliditätsklasse; kein Standalone D-3; keine Vertragsänderung; Commit-Boundary-Regel unverändert; kein Leasing-Scope — AC-4 → Story 3.5/3.6, AD-17.3-Hinweis unverändert in §7). **Sandbox-Nachweis (re-executiert 2026-08-19, ab Workspace-Root, `bash _bmad-output/implementation-artifacts/sandbox-3-3/run-sandbox.sh`; Linux-Sandbox-Semantik auf einem `/tmp`-Baum, nie der reale `wiki/`-Baum; Exit **0**):** Mini-Bundle mit Concept `alpha` + nicht-betroffenem Kontroll-Concept `beta`; committete Neuevidenz je Szenario; alle drei Update-Formen + No-Op durchgespielt: **U1 ERWEITERN** (neue belegte Aussage angefügt, bestehende drei Aussagen byte-identisch — PASS; Probe `{alpha log}` ⊆ erlaubte Menge — PASS; Frontmatter-Konformität — PASS), **U2 PRAEZISIEREN** (Aussage an ihr selbst geschärft, Position/Struktur erhalten, Beleg nachgeführt §5.5 — PASS; Probe `{alpha log}` — PASS; Frontmatter — PASS), **U3 KORRIGIEREN** (fehlerhafte Aussage explizit abgelöst + Ersetzungsbeleg, keine stille Löschung AD-16-Default — PASS; Probe `{alpha log}` — PASS; Frontmatter — PASS), **U4 NO_OP** (Evidenz bereits vollständig enthalten — byte-identisch, kein `at`-Bump, kein `sources`-Zusatz, kein `log.md`-Eintrag — PASS; Probe leer = Ghost-Diff-negativ — PASS), **U5 NEGATIV-KONTROLLE** (simulierter Ghost-Diff auf `beta` wird von der Assertions-Mechanik zuverlässig als HARD-FAIL erkannt — PASS, Mechanik nicht vacuous), **U6 ZWEI-RUN-IDENTITÄT** (AD-17h/A0-19: zwei unabhängige Runs über dieselbe Evidenz → byte-identischer Update-Vorgang — SHA-256 `6b148dd1…` (alpha.md) / `a6d08427…` (log.md) identisch je Lauf, auch nach Commit — PASS), **U7 MEHRFACH_TREFFER** (I/O-Matrix-Zeile; zwei Neuevidenzen `raw/alpha-v2.md` + `raw/alpha-v3.md` desselben Runs treffen denselben Concept-Pfad `alpha` → **ein konsolidiertes Update**: eine Body-Mutation, ein `log.md`-Eintrag, ein konsolidierter `sources`-Zuwachs `s2`+`s3`, ein `generated.at`; Zuwachs-Sicht-Ordnung `v2`-vor-`v3` (lexikografischer Tie-Break bei Body-Ende); bestehende drei Aussagen byte-identisch; Probe `{alpha log}` — PASS; Frontmatter-Konformität — PASS). Die **Erhaltungs-Invariante (§5.9 Pkt. 5) wird als harte Assertion erzwungen**: Proben-Einträge (normalisiert: `wiki/`-Präfix + `.md`-Suffix strippend) ⊆ {betroffener Concept-Pfad, log}; bei Verstoß oder neuer Datei (`??`-Sicht) → HARD-FAIL + Exit 1; kein Ghost-Diff lässt sich still durchschleusen (U5). **Status-/Diff-Nachweis:** nach diesem Instruktions-Run zeigt `git status --porcelain -- wiki/` ausschließlich `wiki/log.md` (dieser Eintrag) — Erhaltungs-Invariante §5.9 Pkt. 5 gewahrt, keine Concept-Inhalts-Mutation (Instruktions-Story, kein neues committetes `raw/`-Material; Demonstration per Sandbox). **Validator-Verdikt (per-Datei, human-mechanisch ausgeführte Text-Instruktion `schema/validator.md` Rev 9, D-3 — kein CLI; unverändert zur Story 3.2, Story 3.3 mutiert keine Concept-Inhalte):** alle **7** `wiki/`-Dateien **SUCCESS** — `wiki/index.md` (Punkt 11, Bundleroot), `wiki/knowledge-kompilation-inkrementell.md`, `wiki/llm-wiki-prinzip.md`, `wiki/wissensarchitektur-trennung-states.md` (Punkte 1/2/6/7/8/9/11/12/13/14, EC-1), `wiki/log.md` (frontmatterlos, Punkt 10), `wiki/wissensarchitektur/index.md` (frontmatterlos, Punkt 10/11), `wiki/wissensarchitektur/source-material.md` (Punkte 1/2/6/7/8/9/11/12/13/14, EC-1; Punkt 11 inkl. Area-Lesart Rev 9). `schema/validator.md`/`schema/wiki-compiler.md`/`raw/` unverändert (AD-3, via `git status` geprüft); keine neue §7-Klasse; kein Standalone (D-3). Spec-Frontmatter: `status: 'in-progress'`, `review_loop_iteration: 0`.
|
||
- **Step-04-Review Loop 3 / Patch-Runde (Story 3.2, 2026-08-19):** `schema/compiler.md` → **Revision 2.7** (D-3-Instruktions-Patch, kein neuer Inhalt; bmad-code-review Loop 3, 4 Layer; Nutzer-Entscheidungen D-1/D-2/D-3/D-4/D-5 = 1/1/1/1/1, jeweils empfohlene Option; + Patches P-1/P-2). (1) **D-1 — Statuskette abgeschlossen:** der Review-Loop-Abschluss-Flip `in-progress → done` (Sprint-Sync-Konvention; Story-3.1-Präzedenz: Review-Abschluss setzt `done` im selben Loop) ist mit dieser Zeile als eigener dokumentierter Schritt nachgeführt; `sprint-status.yaml`-Key `3-2-…` bleibt **`done`** (die gefrorene Always-Klausel `→ in-progress` beschreibt den Implementierungsstand; Review-Handoff/-Abschluss ist der übliche Folgezustand, s. Sprint-Status-Workflow-Kommentar). (2) **D-2 — Sandbox erweitert:** `run-sandbox.sh` um **T5 `LINK_FOLLOWING_ZYKLUS`** (Zyklus alpha ↔ omega via Backlink; besuchte Menge → endliche, doppelungsfreie Candidate-Liste `omega`, `alpha` — der Zyklus endet), **T6 `TRAVERSAL_REACH_ONLY`** (Term `trafo-gebiet` trifft **nur** die Area-`index.md` → die gewurzelten Concept-Pfade `trafo/delta`, `trafo/epsilon` sind die Kandidaten; `index.md` selbst ist kein Concept-Kandidat) und **T7 `TERM_ABLEITUNG_SYNONYM`** (Registry-Test-Doppel: `Quanten Protocol` → Normalisierung → `quanten-protocol` (Canon-Treffer), `QuantenProtocol` → `quantenprotocol` (Variante-Treffer) → canonische Form `quanten-protocol`; Negativ-Fall `nicht-in-registry` → wie notiert, kein stiller Ausschluss); T2-Kommentar zu `index` korrigiert (Stufe-a-Treffer auf `wiki/index.md` löst Stufe b aus — kein Concept-Kandidat); **P-1** — T1/T4 jetzt mit harten Pass/Fail-Asssertionen (`exit 1` bei Abweichung). (3) **D-3 — Selbsttest-Beleg (b) neu belegt:** die Rev-2.5-Log-Zeile (b) beschrieb einen **nicht committierten** Baum (Term `quanten-protocol`, `sub/beta.md`, SHA-256 `159092bb…`) — Stale-Evidenz-Falle (B1-Präzedenz); die Rev-2.5-Zeile bleibt **historisch unverändert** (append-only, Vertrag §5), der korrigierte Nachweis steht in dieser Zeile (re-executierte Sandbox-Ausgabe, s. (5)(b)). (4) **D-4 — §3.2-Pkt.-3b-Ordnung:** Stufe-a-Treffer jetzt **rein lexikografisch (LC_ALL=C)** innerhalb jeder Stufe; die Term-Verarbeitungsreihenfolge dient nur der Interpretation/Erhebung, **nicht** der Listen-Ordnung (dieselbe Treffermenge → identische Liste, AD-17h/A0-19). (5) **D-5 — `schema/canonical-terms.md`-Lookup-Semantik:** Lookup-Verfahren deterministisch fixiert (lowercasing → `[-–_ ]`→`-`-Kollaps → **Lookup der normalisierten Form**; Spalten tragen ausschließlich normalisierte Formen), **Eindeutigkeits-Invariante** (jede normalisierte Form in genau einem Eintrag — Canon **oder** Variante, nie beides/zweimal) + **Konflikt-Verfahren** (keine stille Anhängung; `deferred-work.md`/Ask-First, analog zur Umbenennungs-Regel). (6) **P-2 — Typos korrigiert:** `Determinsmus` → `Determinismus` (compiler.md §8-Referenz, diese Log, `deferred-work.md`-Belege), `§3.2-beankert` → `§3.2-angeankert` (Rev-2.5-Log-Zeile), `Membrum` → `Mitglied` (Spec-Design-Notes), `Konventionelle Determinismus-Lücke` → `Bekannte Determinismus-Lücke` (`deferred-work.md`-Beleg; `compiler.md:53` sagt „Bekannte"), `Resovierung` → `Auflösung` (Spec-Change-Log/-Verification). **Re-executierte Selbsttest-Belege (2026-08-19, ab Workspace-Root; Sandbox-Run exit 0):** (a) live: `grep -rl 'A0-18' --exclude=log.md wiki/` → exakt `wiki/knowledge-kompilation-inkrementell.md` (ein Concept-Pfad, `log.md` ausgeschlossen); (b) **Mini-Sandbox** (`_bmad-output/implementation-artifacts/sandbox-3-2/run-sandbox.sh`, re-executierbar): alle **7** Tests **PASS** — T1 Membership (exakt `alpha`; Kontaminations-Kontrolle ohne Exklusion trifft zusätzlich `log`), T2 Zwei-Run-Identität (identisch), T3 NO_MATCH (leer), T4 Vereinigung `alpha,gamma` (hart assertierte), T5 LINK_FOLLOWING_ZYKLUS (endlich, doppelungsfrei, Zyklus endet), T6 TRAVERSAL_REACH_ONLY (`trafo/delta`, `trafo/epsilon`), T7 TERM_ABLEITUNG_SYNONYM (beide Varianten → `quanten-protocol`; Negativ-Fall wie notiert); (c) `git status --porcelain -- wiki/` nach diesem Run: ausschließlich `wiki/log.md` (dieser Eintrag) — Erhaltungs-Invariante §5.9 Pkt. 5 gewahrt, kein Ghost-Diff (die Instruktions-Story mutiert keine Concept-Inhalte). **Abschlussklausel Rev 2.7:** `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` unverändert (AD-3); keine neue §7-Invaliditätsklasse; kein Standalone (D-3); keine Vertragsänderung; Commit-Boundary-Regel unverändert. `sprint-status.yaml`: Key bleibt `done`, `last_updated` → 08-19-2026. Spec-Frontmatter: `status: 'done'`, `review_loop_iteration: 3`; Spec-`### Review Findings` abgehakt (5 Decisions + 2 Patches + 4 Defers → `deferred-work.md`).
|
||
- **Step-04-Review Loop 2 / Patch-Runde (Story 3.2, 2026-08-19):** `schema/compiler.md` → **Revision 2.6** (D-3-Instruktions-Patch, kein neuer Inhalt; bmad-code-review VG-Findings verarbeitet). (1) **§4-Überschrift wiederhergestellt** — die §3.2-Einfügung (Rev 2.5) hatte die Überschrift **`## 4. Synthetisieren (Provenienz & Trust)`** verdrängt (der §3.2-Sektionskopf ersetzte die §4-Überschrift; der gesamte Frontmatter-Body hing kopflos unter §3.2; alle §4-Referenzen wären dangling geblieben). Der §4-Kopf ist zwischen §3.2-Body und dem Frontmatter-Body wieder eingefügt. (2) **rg-Flag-Defekt behoben (`--exclude` ist kein rg-Flag):** die Rev-2.5-Form in diesem Log- plus dem §3.2-Eintrag, §3-Pkt.-2, §3.2-Pkt.-2a, §5.9-Worked Example (Pkt. 7) und §7 nutzten `rg -l '<term>' --exclude=log.md wiki/` — nicht-existent (ripgrep 14.1.1: `rg --exclude` → `unrecognized flag`; GNU grep unterstützt `--exclude`, ripgrep nutzt `-g '!log.md'` / `--glob '!log.md'`). Die Instruktion nutzt jetzt tool-korrekte Formen: rg `rg -l '<term>' -g '!log.md' wiki/` (native Glob-Exklusion) bzw. GNU grep `grep -rl '<term>' --exclude=log.md wiki/`; die §5.6-Formeln (bereits GNU-grep) und §5.9-Pkt.-7-Erhebung adoptieren die Exklusion. Dieser Eintrag zitiert den alten Defekt **historisch** (verlaufsgetreue Log-Führung; die operative Form ist jetzt tool-korrekt). (3) **§5.9-Worked Example (Pkt. 7) auf die Exklusions-Form gehoben** (`rg -l 'FR-12' -g '!log.md' wiki/`), Kommentar `wiki/log.md` exkludiert gemäß §3.2-Pkt.-2a. (4) **Mini-Sandbox re-executierbar verankert** (`_bmad-output/implementation-artifacts/sandbox-3-2/run-sandbox.sh`, Muster Story-3.1-Sandbox S1–S6): Tests T1–T4 (Membership-Pin — Term auf Concept-Bodies UND `log.md` verteilt, Candidate-Liste nur Concept-Pfade; Zwei-Run-Identität AD-17h; NO_MATCH → leere Candidate-Liste → UNTOUCHED_CONCEPT; Mehrfach-Treffer → Vereinigung + lexikografische Ordnung). (5) **`deferred-work.md`-Em-Dash-Eintrag** append-only ergänzt (Home: Story 3.8) — die §3.2-Pkt.-1b-Kollaps-Klasse deckt En-Dash/Bindestrich/Unterstrich/Leerzeichen, aber **nicht** den Em-Dash `—`; dieser Handoff wird nicht stillschweigend gelöst, sondern als offene Determinismus-Frage dokumentiert. **Re-executierte Selbsttest-Belege (2026-08-19, ab Workspace-Root):** (a) rg-Form real: `rg -l 'A0-18' -g '!log.md' wiki/` → exakt `wiki/knowledge-kompilation-inkrementell.md`; ohne Exklusion `rg -l 'A0-18' wiki/` → zusätzlich `wiki/log.md` (Selbstkontamination — der §3.2-Pkt.-2a-Fall, reell belegt); (b) GNU-grep-Äquivalent `grep -rl 'A0-18' --exclude=log.md wiki/` → identisch `wiki/knowledge-kompilation-inkrementell.md`; (c) `rg -l 'FR-12' -g '!log.md' wiki/` → `wiki/knowledge-kompilation-inkrementell.md` (§5.9-WE-Korrektur reell); (d) Mini-Sandbox T1–T4 → siehe Rev-2.6-Eintrag; (e) `git status --porcelain` → `wiki/` nur `log.md` (dieser Eintrag; Erhaltungs-Invariante §5.9 Pkt. 5 gewahrt), `schema/compiler.md` + `deferred-work.md` sind außerhalb `wiki/` (kein Teil der Diff-Probe). **Abschlussklausel Rev 2.6:** `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` unverändert (AD-3, geprüft via `git status`); keine neue §7-Invaliditätsklasse; kein Standalone (D-3); keine Vertragsänderung; Commit-Boundary-Regel unverändert. (Der Rev-2.5-Implementierungs-Eintrag oben bleibt unverändert — dokumentiert den Zustand bei Rev-2.5-Veröffentlichung inkl. der damaligen `--exclude`-Form; historische Korrektheit des Logs.)
|
||
- **Story 3.2 «Relevanzbestimmung textual-deterministisch umsetzen (grep/ripgrep + Markdown-Traversal + Link-Following)» (Implementierung, Instruktions-Story D-3; `sprint-status.yaml`: Key `3-2-relevanzbestimmung-textual-deterministisch-umsetzen-grep-rip` `backlog` → **`in-progress`**):** `schema/compiler.md` → **Revision 2.5** — die beiden **Story-3.2-Vorbehalte aufgehoben** (§3 Pkt. 2 + §7) und die feinkörnige Relevanz-Findungsmechanik als neue Sektion **§3.2 „Relevanzbestimmung (Story 3.2)"** verankert (nach §3, vor §4; Pkt. 2 bleibt Kern-Anker „Erhebung nach §3.2"): (1) **Term-Ziehverfahren deterministisch** — bedeutungstragende Token-Folgen nach §2-Interpretation; Normalisierung lowercasing + `[-–_ ]`→`-`-Kollaps (En-Dash/Bindestrich/Unterstrich/Leerzeichen); **kanonischer Schreibweisen-Resolver als committete, append-only Registry `schema/canonical-terms.md`** (canon. Form + erlaubte Varianten, `[]`; Bestandteil des Git-States → Auflösung pinbar, AD-17h/A0-19); genau eine canon. Form je Semantik (A0-18); **kein stiller Ausschluss** nicht auflösbarer Varianten (Verwendung wie notiert); mehrere Terme je Einheit → Vereinigung; **bekannte Determinismus-Lücke**: Em-Dash `—` fällt nicht unter den `[-–_ ]`-Kollaps → an **Story 3.8** übergeben (nicht still hinzugefügt); (2) **dreistufige term-übergreifende Erhebung über `wiki/`** — (a) `rg -l '<term>' --exclude=log.md wiki/` (GNU-grep-Äquivalent `grep -rl '<term>' --exclude=log.md wiki/`; **`log.md` strukturell exkludiert** — die Candidate-Liste ist auf Concept-Pfade definiert, `log.md` ist kein Kandidat), (b) `index.md`-Traversal (gewurzelte Erreichbarkeit Root → Area → Concept, §5.8; TRAVERSAL_REACH_ONLY; fehlende Bundleroot → Run-FAIL V-1), (c) Link-Following mit **besuchter Menge** (file-relativ, §5.7 Pkt. 4; Zyklen enden — LINK_FOLLOWING_ZYKLUS); (3) **Candidate-Liste + Determinismus-Vertrag** — relative OKF-Pfade ohne `.md` (Strip `wiki/`-Präfix + `.md`-Suffix), **Zuwachs-Sicht-Ordnung** mit Reihenfolge auch für Stufe-b/c (lexikografischer Tie-Break; AD-17h/A0-19), keine Duplikate (besuchte Menge), NO_MATCH → leere Candidate-Liste → UNTOUCHED_CONCEPT (Story-3.1-Pfad, Ghost-Diff-negativ); Determinismus-Selbsttest (Membership + Zwei-Run-Identität) unten belegt. **§8-Normreferenzen:** AD-13 (bereits gelistet, §3.2-beankert), **A0-18** (Deterministische Relevanzbestimmung, §3.2), **A0-19** (Determinismus-Vertrag — war im Ist-§8 noch nicht gelistet, als Determinismus-Referenz ergänzt, §3.2/AD-17h) und **PRD OQ-3** (Compilation Scope, §3.2) ergänzt; `schema/canonical-terms.md` als Resolver-Registry referenziert. **Abschlussklausel Rev 2.5:** `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` unverändert (AD-3); keine neue §7-Invaliditätsklasse; kein Standalone (D-3); keine Vertragsänderung; Commit-Boundary-Regel unverändert. **`deferred-work.md`:** der Story-3.1-Defer-Eintrag `epic-3-context.md` („Home: Story-3.2-Handoff") als **aufgegriffen** markiert (append-only); der F17/Em-Morphologie-Handoff (Story 3.8) bleibt bestehen. **Determinismus-Selbsttest (Membership + Identität, re-executiert 2026-08-19, ab Workspace-Root):** (a) `grep -rl 'A0-18' --exclude=log.md wiki/` zweimal ausgeführt → beide Ausgaben **identisch**, exakt `wiki/knowledge-kompilation-inkrementell.md` (ein Concept-Pfad; `log.md` ausgeschlossen — der `--exclude=log.md`-Fakt ist ehrlich dokumentiert: ohne die Exklusion würde `log.md` ab dem Moment selbst „Kandidat", in dem dieser Eintrag `A0-18` zitiert — die B1-`log.md`-Kontamination ist damit geschlossen); (b) **mini-Sandbox-Baum** (`/tmp/sb32-…`, Term `quanten-protocol` auf Concept-Bodies **und** `log.md` verteilt) → exakte Candidate-Liste nur Concept-Pfade (`wiki/alpha.md`, `wiki/sub/beta.md`; `log.md` ausgeschlossen, `wiki/gamma.md` ohne Term nicht getroffen); normalisiert `alpha`, `sub/beta`; **Zwei-Run-Identität** (SHA-256 `159092bb…` ≡); Kontrolle ohne `--exclude` → `log.md` wird Kandidat (B1-Falle belegt und geschlossen); (c) §5.6-Formeln unverändert re-executierbar: Formel 2 (Form-Check) `0` (Exit 0), Formel 3 (Dangling-Check) keine Ausgabe, Formel 4 Ist-Zählung **38** (kein `wiki/`-Dateimenge-Change durch Story 3.2 — keine Re-Baseline nötig). **Validator-Lauf** (human-mechanisch ausgeführte Text-Instruktion `schema/validator.md` Rev 9, D-3 — kein CLI): alle **7** `wiki/`-Dateien **SUCCESS** (Punkte 1/2/6/7/8/9/10/11/12/13/14, EC-1 — unverändert zur Story 3.1, Story 3.2 mutiert keine Concept-Inhalte; `wiki/log.md` bleibt frontmatterlos, Punkt 10); das per-Datei-Verdikt ist der Ausführungs-Nachweis der Spec-Verification Pkt. 4 und AC 5. `git status --porcelain -- wiki/` nach diesem Run: ausschließlich `log.md` (modifiziert) — Erhaltungs-Invariante §5.9 Pkt. 5 gewahrt, kein Ghost-Diff.
|
||
|
||
## NEW FILE: sandbox-3-3/run-sandbox.sh (untracked):
|
||
#!/usr/bin/env bash
|
||
# Story 3.3 — Sandbox-Tests der operationellen Update-Formen (§5.9 Pkt. 2, Revision 2.8)
|
||
# Re-executierbar: bash run-sandbox.sh (ab Workspace-Root; Sandbox unter /tmp/sb33)
|
||
# Zweck: alle drei Update-Formen (Erweitern + Präzisieren + Korrigieren) + No-Op
|
||
# durchspielen; die Erhaltungs-Invariante (§5.9 Pkt. 5) als HARDE Assertion
|
||
# erzwingen (Diff nach Normalisierung ⊆ {betroffener Concept-Pfad, log}; keine
|
||
# neue Datei; kein Ghost-Diff); Zwei-Run-Identität (AD-17h/A0-19);
|
||
# Frontmatter-Konformität je mutiertem Concept (Vertrag §3.3/§3.4-Subset).
|
||
# Linux-Sandbox-Semantik auf einem /tmp-Baum — NIE der reale wiki/-Baum.
|
||
set -u
|
||
ROOT=$(mktemp -d /tmp/sb33-XXXXXX)
|
||
SB="$ROOT/sb"
|
||
mkdir -p "$SB/wiki" "$SB/raw"
|
||
cd "$SB"
|
||
git init -q
|
||
git config user.email "sandbox@test"
|
||
git config user.name "Sandbox"
|
||
|
||
# ---------- Basis-Baum (committete Ausgangslage = Baseline-Commit) ----------
|
||
# Concept alpha mit drei belegten Aussagen; Aussagen 1/2 sind fachlich korrekt,
|
||
# Aussage 3 ist fehlerhaft (Korrigieren-Ziel des Szenarios U3). beta ist ein
|
||
# nicht-betroffenes Kontroll-Concept (Ghost-Diff-Kontrolle, U5).
|
||
cat > wiki/index.md <<'EOF'
|
||
# Index
|
||
- [Alpha](alpha.md)
|
||
- [Beta](beta.md)
|
||
EOF
|
||
cat > wiki/alpha.md <<'EOF'
|
||
---
|
||
type: concept
|
||
sources:
|
||
- resource: raw/alpha-v1.md
|
||
id: s1
|
||
generated:
|
||
by: wow-compiler/0.1.0
|
||
at: 2026-08-16T09:00:00Z
|
||
---
|
||
Das Alpha-Protokoll verwendet deterministische-init-sequenz für den Abgleich (raw/alpha-v1.md#S-1).
|
||
Alpha läuft ausschließlich auf isolierten Netzen (raw/alpha-v1.md#S-3).
|
||
Alpha rotiert seine Schlüssel nie (raw/alpha-v1.md#S-2).
|
||
EOF
|
||
cat > wiki/beta.md <<'EOF'
|
||
---
|
||
type: concept
|
||
sources:
|
||
- resource: raw/beta-v1.md
|
||
id: s1
|
||
generated:
|
||
by: wow-compiler/0.1.0
|
||
at: 2026-08-16T09:00:00Z
|
||
---
|
||
Beta beschreibt ein anderes, hier nicht betroffenes Thema.
|
||
EOF
|
||
cat > wiki/log.md <<'EOF'
|
||
# Log
|
||
EOF
|
||
cat > raw/alpha-v1.md <<'EOF'
|
||
Evidenz v1: deterministische-init-sequenz (Stelle S-1); isolierte Netze (Stelle S-3); keine Rotation (Stelle S-2).
|
||
EOF
|
||
cat > raw/beta-v1.md <<'EOF'
|
||
Evidenz v1: Beta-Thema (Stelle S-1).
|
||
EOF
|
||
git add -A
|
||
git commit -qm "Baseline"
|
||
BASE=$(git rev-parse HEAD)
|
||
echo "BASELINE-COMMIT: $BASE"
|
||
echo "Sandbox-Root: $ROOT (loeschbar: rm -rf $ROOT)"
|
||
echo
|
||
|
||
runlabel() { echo; echo "########## $1 ##########"; }
|
||
# Isolation: Worktree auf BASE zuruecksetzen (kein Carry-over ueber Szenarien)
|
||
isolate() { git checkout -q -b "$1" "$BASE" 2>/dev/null || git checkout -q "$1"; git reset -q --hard "$BASE"; git clean -qfd wiki raw; }
|
||
|
||
# Pkt.-5-Probe (D-1-Form): Baseline-Diff + porcelain, normalisiert
|
||
# (wiki/-Praefix + .md-Suffix gestrippt, LC_ALL=C-sortiert; deterministisch, AD-17h)
|
||
probe() {
|
||
{ git diff --name-only "$BASE" -- wiki/ ; git status --porcelain -- wiki/ | awk '{print $2}'; } \
|
||
| sed -e 's|^wiki/||' -e 's|\.md$||' | LC_ALL=C sort -u
|
||
}
|
||
inv_set() { probe | LC_ALL=C sort -u | paste -sd' ' -; }
|
||
|
||
# ---------- Harte Assertion der Erhaltungs-Invariante (§5.9 Pkt. 5) ----------
|
||
# Erwartete erlaubte Menge = Space-getrennte normalisierte Pfade
|
||
# (z. B. "alpha log"). Jeder Proben-Eintrag MUSS in der erlaubten Menge liegen —
|
||
# sonst Ghost-Diff (nicht betroffener Pfad) → HARD-FAIL, Exit 1 (NFR-4/FT-6).
|
||
assert_invariant() {
|
||
local expected="$1" got p bad=0 rcs=0
|
||
got=$(inv_set)
|
||
for p in $got; do
|
||
case " $expected " in
|
||
*" $p "*) ;;
|
||
*) echo "HARD-FAIL (Erhaltungs-Invariante §5.9 Pkt. 5): '$p' ist kein Ghost-Diff-negativer Eintrag — erlaubte Menge: {$expected}" >&2; bad=1;;
|
||
esac
|
||
done
|
||
# Keine neue Datei (Duplikat-Kontrolle: die ??-Sicht fehlt git diff allein)
|
||
rcs=$(git status --porcelain -- wiki/ | grep -c '^??' || true)
|
||
[ "$rcs" -eq 0 ] || { echo "HARD-FAIL (keine neue Datei): $rcs ungetrackte neue Datei(en) unter wiki/ (Duplikat/Ghost-Diff)" >&2; bad=1; }
|
||
if [ "$bad" -eq 0 ]; then
|
||
echo "RESULT: PASS — Probe {$got} ⊆ erlaubte Menge {$expected}; keine neue Datei; kein Ghost-Diff"
|
||
else
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# ---------- Frontmatter-Konformitaet je mutiertem Concept (Vertrag §3.3/§3.4, §6.5) ----------
|
||
# $1=Datei; $2...=erwartete sources[].resource-Werte. Prueft: Top-Level-Key-Subset
|
||
# {type,sources,generated,verified,status,stale_after}, sources-Eintrag-Key-Subset
|
||
# (Vertrag §3.3-Innen-Ebene), type=concept, generated.at = volle ISO-8601-Datetime
|
||
# (die erlaubten Key-Mengen sind inline im awk-Subset-Vergleich hartkodiert).
|
||
assert_frontmatter() {
|
||
local f="$1"; shift
|
||
local r bad=0
|
||
# Kontextuelle Validierung ueber awk: Top-Level-Subset {type,sources,generated,
|
||
# verified,status,stale_after}; Innen-Ebenen je Sektion — sources: Vertrag §3.3-
|
||
# Subset {resource,id,title,author,usage_count,last_modified}; generated/verified:
|
||
# {by,at} (Vertrag §3.4/§3.5). Jeder andere Key = unbefugt (Punkt 6, §6.5).
|
||
local v
|
||
v=$(awk '
|
||
/^---$/{n++; if(n==2) exit; next}
|
||
/^[A-Za-z_][A-Za-z0-9_-]*:/{
|
||
k=$0; sub(/:.*/,"",k)
|
||
if (k=="sources") top="sources"
|
||
else if (k=="generated" || k=="verified") top="genver"
|
||
else top="other"
|
||
if (k!="type" && k!="sources" && k!="generated" && k!="verified" && k!="status" && k!="stale_after") print "TOP_UNBEFUGT:" k
|
||
next
|
||
}
|
||
/^[[:space:]]/{
|
||
gsub(/^[[:space:]]+/,""); sub(/^- /,""); gsub(/^[[:space:]]+/,"");
|
||
if (match($0, /^[A-Za-z_][A-Za-z0-9_-]*:/)) {
|
||
ik=substr($0,1,RLENGTH-1)
|
||
if (top=="sources" && ik!="resource" && ik!="id" && ik!="title" && ik!="author" && ik!="usage_count" && ik!="last_modified") print "INNER_UNBEFUGT:" ik
|
||
if (top=="genver" && ik!="by" && ik!="at") print "INNER_UNBEFUGT:" ik
|
||
if (top=="other") print "INNER_UNBEFUGT:" ik
|
||
}
|
||
}
|
||
' "$f")
|
||
if [ -n "$v" ]; then
|
||
echo "HARD-FAIL (Frontmatter-Subset, Vertrag §3.3/§3.4/§3.5): $v in $f" >&2
|
||
exit 1
|
||
fi
|
||
grep -qE '^type: concept$' "$f" || { echo "HARD-FAIL: type=concept fehlt in $f" >&2; exit 1; }
|
||
grep -qE "^ at: [0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:?[0-9]{2})$" "$f" || { echo "HARD-FAIL: generated.at ist keine volle ISO-8601-Datetime in $f" >&2; exit 1; }
|
||
for r in "$@"; do
|
||
grep -qF " - resource: $r" "$f" || { echo "HARD-FAIL: sources-Eintrag 'resource: $r' fehlt in $f" >&2; exit 1; }
|
||
done
|
||
echo "RESULT: PASS — Frontmatter-Konformitaet $f (Subset ok, generated.at volles Datetime)"
|
||
}
|
||
|
||
# ---------- Update-Helfer (deterministisch; at gepinnt fuer Zwei-Run-Identitaet) ----------
|
||
AT_NEW="2026-08-19T12:00:00Z"
|
||
bump_at() { sed -i "s|^ at: .*| at: $AT_NEW|" "$1"; }
|
||
add_source() { # $1=Datei $2=resource $3=id (Eintrag vor der generated:-Zeile einfuegen)
|
||
sed -i "s|^generated:| - resource: $2\n id: $3\ngenerated:|" "$1"
|
||
}
|
||
log_update() { # $1=Concept-Pfad $2=raw-Datei
|
||
printf '\n## 2026-08-19\n- Story 3.1-Update: %s (%s; Baseline %s)\n' "$1" "$2" "$BASE" >> wiki/log.md
|
||
}
|
||
|
||
# =====================================================================
|
||
runlabel "U1: ERWEITERN — neue belegte Aussage, bestehender Pfad wird erweitert (AC-1/FR-6)"
|
||
isolate u1
|
||
cat > raw/alpha-v2.md <<'EOF'
|
||
Evidenz v2 (neue Aussage): Alpha-Replikation traegt einen zusaetzlichen Schluessel-Rotationszyklus (Stelle S-4).
|
||
EOF
|
||
git add -A; git commit -qm "Zuwachs raw/alpha-v2.md"
|
||
echo "--- Kandidaten-Erhebung: rg -l 'schluessel-rotationszyklus' wiki/ ---"
|
||
if command -v rg >/dev/null 2>&1; then rg -l 'schluessel-rotationszyklus' -g '!log.md' wiki/ || true
|
||
else grep -rl 'schluessel-rotationszyklus' --exclude=log.md wiki/ || true; fi
|
||
echo "--- UPDATE: neue Aussage als Absatz angefuegt (§5.5-Inline-Beleg), sources-Zuwachs s2, at-Bump ---"
|
||
cat >> wiki/alpha.md <<'EOF'
|
||
Alpha führt für die Replikation einen zusätzlichen Schlüssel-Rotationszyklus (raw/alpha-v2.md#S-4).
|
||
EOF
|
||
add_source wiki/alpha.md raw/alpha-v2.md s2
|
||
bump_at wiki/alpha.md
|
||
log_update alpha raw/alpha-v2.md
|
||
echo "--- Struktur-Erhaltung: bestehende drei Aussagen byte-identisch erhalten? ---"
|
||
grep -qF 'Das Alpha-Protokoll verwendet deterministische-init-sequenz für den Abgleich (raw/alpha-v1.md#S-1).' wiki/alpha.md || { echo "HARD-FAIL: Aussage 1 wurde beim Erweitern umgeschrieben" >&2; exit 1; }
|
||
grep -qF 'Alpha rotiert seine Schlüssel nie (raw/alpha-v1.md#S-2).' wiki/alpha.md || { echo "HARD-FAIL: Aussage 3 wurde beim Erweitern umgeschrieben" >&2; exit 1; }
|
||
echo "RESULT: PASS — bestehende belegte Aussagen unveraendert (Struktur-Erhaltungsregel Erweitern)"
|
||
echo "--- Probe (Pkt. 5, vor dem Commit) ---"; probe
|
||
assert_invariant "alpha log"
|
||
assert_frontmatter wiki/alpha.md raw/alpha-v1.md raw/alpha-v2.md
|
||
|
||
# =====================================================================
|
||
runlabel "U2: PRAEZISIEREN — bestehende Aussage wird an ihr selbst geschaerft (AC-2/FR-6)"
|
||
isolate u2
|
||
cat > raw/alpha-v2.md <<'EOF'
|
||
Evidenz v2 (Praezisierung): die deterministische-init-sequenz wird nach der initialen Synchronisation zusaetzlich rotiert (Stelle S-2).
|
||
EOF
|
||
git add -A; git commit -qm "Zuwachs raw/alpha-v2.md"
|
||
echo "--- UPDATE: Aussage 1 an Position geschaerft, Beleg nachgefuehrt (Multi-Beleg §5.5); kein Satz-Umbau ---"
|
||
sed -i 's|^Das Alpha-Protokoll verwendet deterministische-init-sequenz für den Abgleich (raw/alpha-v1.md#S-1)\.|Das Alpha-Protokoll verwendet deterministische-init-sequenz für den Abgleich und rotiert sie nach der initialen Synchronisation zusätzlich (raw/alpha-v1.md#S-1; raw/alpha-v2.md#S-2).|' wiki/alpha.md
|
||
add_source wiki/alpha.md raw/alpha-v2.md s2
|
||
bump_at wiki/alpha.md
|
||
log_update alpha raw/alpha-v2.md
|
||
echo "--- Struktur-Erhaltung: Aussagen 2/3 unveraendert, geschaerfte Aussage 1 an Position? ---"
|
||
grep -qF 'Das Alpha-Protokoll verwendet deterministische-init-sequenz für den Abgleich und rotiert sie nach der initialen Synchronisation zusätzlich (raw/alpha-v1.md#S-1; raw/alpha-v2.md#S-2).' wiki/alpha.md || { echo "HARD-FAIL: geschaerfte Aussage fehlt" >&2; exit 1; }
|
||
grep -qF 'Alpha läuft ausschließlich auf isolierten Netzen (raw/alpha-v1.md#S-3).' wiki/alpha.md || { echo "HARD-FAIL: Aussage 2 wurde beim Praezisieren veraendert" >&2; exit 1; }
|
||
echo "RESULT: PASS — Schaerfung an der Aussage selbst, Position/Struktur erhalten, kein Satz-Umbau"
|
||
echo "--- Probe ---"; probe
|
||
assert_invariant "alpha log"
|
||
assert_frontmatter wiki/alpha.md raw/alpha-v1.md raw/alpha-v2.md
|
||
|
||
# =====================================================================
|
||
runlabel "U3: KORRIGIEREN — fehlerhafte Aussage abgeloest, nicht still geloescht (AC-2, AD-16-Default)"
|
||
isolate u3
|
||
cat > raw/alpha-v2.md <<'EOF'
|
||
Evidenz v2 (Korrektur): Alpha rotiert seine Schluessel bei jeder Sitzung (Stelle S-2).
|
||
EOF
|
||
git add -A; git commit -qm "Zuwachs raw/alpha-v2.md"
|
||
echo "--- UPDATE: Aussage 3 wird explizit abgeloest + Ersetzungsbeleg; keine stille Loeschung ---"
|
||
sed -i 's|^Alpha rotiert seine Schlüssel nie (raw/alpha-v1.md#S-2)\.|Alpha rotierte seine Schlüssel nie (raw/alpha-v1.md#S-2) — überholt durch: Alpha rotiert seine Schlüssel bei jeder Sitzung (raw/alpha-v2.md#S-2).|' wiki/alpha.md
|
||
add_source wiki/alpha.md raw/alpha-v2.md s2
|
||
bump_at wiki/alpha.md
|
||
log_update alpha raw/alpha-v2.md
|
||
echo "--- AD-16-Default: alte Aussage textuell erhalten (nicht still geloescht)? ---"
|
||
grep -qF 'rotierte seine Schlüssel nie' wiki/alpha.md || { echo "HARD-FAIL: alte Aussage wurde still geloescht (AD-16)" >&2; exit 1; }
|
||
grep -qF 'rotiert seine Schlüssel bei jeder Sitzung (raw/alpha-v2.md#S-2)' wiki/alpha.md || { echo "HARD-FAIL: Ersetzungsbeleg fehlt" >&2; exit 1; }
|
||
echo "RESULT: PASS — Abloesung mit Ersetzungsbeleg, Provenienz erhalten (AD-16-Default Erhaltung)"
|
||
echo "--- Probe ---"; probe
|
||
assert_invariant "alpha log"
|
||
assert_frontmatter wiki/alpha.md raw/alpha-v1.md raw/alpha-v2.md
|
||
|
||
# =====================================================================
|
||
runlabel "U4: NO_OP — Evidenz ist bereits vollstaendig im Body (engere Auslegung, Pkt. 2)"
|
||
isolate u4
|
||
cat > raw/alpha-v2.md <<'EOF'
|
||
Evidenz v2 (Redundanz): deterministische-init-sequenz fuer den Abgleich; Alpha rotiert seine Schluessel nie.
|
||
EOF
|
||
git add -A; git commit -qm "Zuwachs raw/alpha-v2.md"
|
||
echo "--- Kandidaten-Erhebung: Terme treffen alpha; die Evidenz ist bereits vollstaendig enthalten ---"
|
||
echo "--- UPDATE: KEINE Body-Mutation, KEIN at-Bump, KEIN sources-Zusatz, KEIN log.md-Eintrag (byte-identisch) ---"
|
||
if git status --porcelain -- wiki/ | grep -q .; then
|
||
echo "HARD-FAIL (No-Op): Wiki-Baum ist nicht byte-identisch" >&2
|
||
git status --porcelain -- wiki/
|
||
exit 1
|
||
fi
|
||
echo "RESULT: PASS — No-Op: keine Mutation, kein at-Bump, kein sources-Zusatz, kein log.md-Eintrag (byte-identisch)"
|
||
echo "--- Probe (leer = Ghost-Diff-negativ, leere Menge ist Teilmenge jeder erlaubten Menge) ---"; probe
|
||
assert_invariant ""
|
||
|
||
# =====================================================================
|
||
runlabel "U5: NEGATIV-KONTROLLE — Assertions-Mechanik erkennt einen Ghost-Diff (nicht vacuous)"
|
||
isolate u5
|
||
echo "unbefugte Mutation auf nicht-betroffenem beta" >> wiki/beta.md # simulierter Ghost-Diff
|
||
echo "--- Probe (erwartet: beta ausserhalb der erlaubten Menge {alpha log}) ---"; probe
|
||
if ( assert_invariant "alpha log" ) >/dev/null 2>&1; then
|
||
echo "HARD-FAIL (Assertions-Mechanik): Ghost-Diff auf beta wurde NICHT erkannt" >&2
|
||
exit 1
|
||
else
|
||
echo "RESULT: PASS — Ghost-Diff auf beta wurde erkannt (Assertions-Mechanik loest verlaesslich HARD-FAIL aus, kein Ghost-Diff kommt durch)"
|
||
fi
|
||
|
||
# =====================================================================
|
||
runlabel "U6: ZWEI-RUN-IDENTITAET (AD-17h/A0-19) — gleicher Git-State + gleiches Eingabeset -> identischer Update-Vorgang"
|
||
# Zwei unabhaengige Runs ueber dieselbe Evidenz (Erweitern); die Ergebnisse
|
||
# (mutierter Body + Frontmatter + Status) muessen byte-identisch sein.
|
||
run_erweitern() { # $1 = Branchname; mutiert Worktree, dann git add -A (Staging)
|
||
isolate "$1"
|
||
cat > raw/alpha-v2.md <<'EOF'
|
||
Evidenz v2 (neue Aussage): Alpha-Replikation traegt einen zusaetzlichen Schluessel-Rotationszyklus (Stelle S-4).
|
||
EOF
|
||
git add -A; git commit -qm "Zuwachs raw/alpha-v2.md"
|
||
cat >> wiki/alpha.md <<'EOF'
|
||
Alpha führt für die Replikation einen zusätzlichen Schlüssel-Rotationszyklus (raw/alpha-v2.md#S-4).
|
||
EOF
|
||
add_source wiki/alpha.md raw/alpha-v2.md s2
|
||
bump_at wiki/alpha.md
|
||
log_update alpha raw/alpha-v2.md
|
||
git add -A # Staging — die Mutationen sind Teil des Runs (Commit-Boundary = Mutations-Boundary)
|
||
}
|
||
run_erweitern u6a
|
||
A_ALPHA=$(sha256sum wiki/alpha.md | cut -d' ' -f1) # Worktree-Inhalt = staged-Inhalt (git add)
|
||
A_LOG=$(sha256sum wiki/log.md | cut -d' ' -f1)
|
||
git commit -qm "Run A (Erweitern)"
|
||
A_ALPHA_COM=$(git show HEAD:wiki/alpha.md | sha256sum | cut -d' ' -f1)
|
||
run_erweitern u6b
|
||
B_ALPHA=$(sha256sum wiki/alpha.md | cut -d' ' -f1)
|
||
B_LOG=$(sha256sum wiki/log.md | cut -d' ' -f1)
|
||
git commit -qm "Run B (Erweitern)"
|
||
B_ALPHA_COM=$(git show HEAD:wiki/alpha.md | sha256sum | cut -d' ' -f1)
|
||
echo "Run A (alpha.md): $A_ALPHA"
|
||
echo "Run B (alpha.md): $B_ALPHA"
|
||
echo "Run A (log.md): $A_LOG"
|
||
echo "Run B (log.md): $B_LOG"
|
||
echo "Run A commit (alpha.md): $A_ALPHA_COM ; Run B commit (alpha.md): $B_ALPHA_COM"
|
||
if [ "$A_ALPHA" = "$B_ALPHA" ] && [ "$A_LOG" = "$B_LOG" ] && [ "$A_ALPHA_COM" = "$B_ALPHA_COM" ]; then
|
||
echo "RESULT: PASS — zwei unabhaengige Runs ueber dieselbe Evidenz -> identischer Update-Vorgang (AD-17h/A0-19)"
|
||
else
|
||
echo "HARD-FAIL (Determinismus-Vertrag): Run A und Run B weichen ab" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# =====================================================================
|
||
runlabel "U7: MEHRFACH_TREFFER — zwei Neuevidenzen desselben Runs treffen denselben Concept-Pfad (Konsolidierung, I/O-Matrix)"
|
||
# Matrix-Zeile MEHRFACH_TREFFER: mehrere neue Wissenseinheiten desselben Runs auf
|
||
# denselben Pfad -> EIN konsolidiertes Update (eine Body-Mutation, EIN log.md-Eintrag,
|
||
# EIN konsolidierter sources-Zuwachs, EIN generated.at). Reihenfolge = Zuwachs-Sicht
|
||
# (Ankunftsreihenfolge der Belege); lexikografischer Tie-Break bei identischem Ort
|
||
# (Body-Ende) -> alpha-v2.md vor alpha-v3.md.
|
||
isolate u7
|
||
cat > raw/alpha-v2.md <<'EOF'
|
||
Evidenz v2 (neue Aussage): Alpha-Replikation nutzt Quorum-Bestaetigung (Stelle S-4).
|
||
EOF
|
||
cat > raw/alpha-v3.md <<'EOF'
|
||
Evidenz v3 (neue Aussage): Alpha-Replikation waechst linear zum Cluster (Stelle S-4).
|
||
EOF
|
||
git add -A; git commit -qm "Zwei Einheiten, ein Run (raw/alpha-v2.md + raw/alpha-v3.md)"
|
||
echo "--- Kandidaten-Erhebung: beide Terme treffen denselben Pfad alpha ---"
|
||
echo "--- KONSOLIDIERTES UPDATE: beide Aussagen als Absaetze angehaengt (Zuwachs-Sicht: v2 vor v3), EIN log-Eintrag, sources-Zuwachs s2+s3, EIN at ---"
|
||
cat >> wiki/alpha.md <<'EOF'
|
||
Alpha-Replikation nutzt Quorum-Bestaetigung (raw/alpha-v2.md#S-4).
|
||
Alpha-Replikation waechst linear zum Cluster (raw/alpha-v3.md#S-4).
|
||
EOF
|
||
add_source wiki/alpha.md raw/alpha-v2.md s2
|
||
add_source wiki/alpha.md raw/alpha-v3.md s3
|
||
bump_at wiki/alpha.md
|
||
log_update alpha raw/alpha-v2.md
|
||
echo "--- Konsolidierung: genau EIN log.md-Eintrag und EIN generated.at trotz zweier Einheiten? ---"
|
||
[ "$(grep -c 'Story 3.1-Update: alpha' wiki/log.md)" -le 1 ] || { echo "HARD-FAIL: Mehrfach-Treffer erzeugte mehrere log.md-Eintraege (keine Konsolidierung)" >&2; exit 1; }
|
||
[ "$(grep -c '^ at:' wiki/alpha.md)" -eq 1 ] || { echo "HARD-FAIL: Mehrfach-Treffer erzeugte mehrere generated.at" >&2; exit 1; }
|
||
echo "--- Struktur-Erhaltung: alte Aussagen byte-identisch, beide neuen Aussagen vorhanden, Zuwachs-Sicht-Ordnung v2-vor-v3 ---"
|
||
grep -qF 'Das Alpha-Protokoll verwendet deterministische-init-sequenz für den Abgleich (raw/alpha-v1.md#S-1).' wiki/alpha.md || { echo "HARD-FAIL: Aussage 1 wurde beim konsolidierten Update umgeschrieben" >&2; exit 1; }
|
||
grep -qF 'Alpha läuft ausschließlich auf isolierten Netzen (raw/alpha-v1.md#S-3).' wiki/alpha.md || { echo "HARD-FAIL: Aussage 2 wurde beim konsolidierten Update umgeschrieben" >&2; exit 1; }
|
||
grep -qF 'Alpha rotiert seine Schlüssel nie (raw/alpha-v1.md#S-2).' wiki/alpha.md || { echo "HARD-FAIL: Aussage 3 wurde beim konsolidierten Update umgeschrieben" >&2; exit 1; }
|
||
grep -qF 'Quorum-Bestaetigung (raw/alpha-v2.md#S-4)' wiki/alpha.md || { echo "HARD-FAIL: neue Aussage aus v2 fehlt" >&2; exit 1; }
|
||
grep -qF 'waechst linear zum Cluster (raw/alpha-v3.md#S-4)' wiki/alpha.md || { echo "HARD-FAIL: neue Aussage aus v3 fehlt" >&2; exit 1; }
|
||
v2pos=$(grep -n 'Quorum-Bestaetigung' wiki/alpha.md | cut -d: -f1); v3pos=$(grep -n 'waechst linear' wiki/alpha.md | cut -d: -f1)
|
||
[ "$v2pos" -lt "$v3pos" ] || { echo "HARD-FAIL: Zuwachs-Sicht-Ordnung verletzt (v3 vor v2)" >&2; exit 1; }
|
||
echo "RESULT: PASS — ein konsolidiertes Update (eine Body-Aenderung, ein log-Eintrag, ein sources-Zuwachs s2+s3, ein at); Zuwachs-Sicht-Ordnung v2-vor-v3"
|
||
echo "--- Probe ---"; probe
|
||
assert_invariant "alpha log"
|
||
assert_frontmatter wiki/alpha.md raw/alpha-v1.md raw/alpha-v2.md raw/alpha-v3.md
|
||
|
||
echo
|
||
echo "===== Sandbox abgeschlossen (alle 7 Tests U1-U7) ====="
|
||
echo "Sandbox-Root: $ROOT (loeschbar: rm -rf $ROOT)"
|
||
|
||
## NEW FILE: spec-3-3 (untracked):
|
||
---
|
||
title: 'Bestehende Concepts erweitern/präzisieren/korrigieren — Update-Formen operativ schärfen (Story 3.3)'
|
||
type: 'feature'
|
||
created: '2026-08-19'
|
||
status: 'in-review'
|
||
review_loop_iteration: 0
|
||
baseline_commit: 52f88fdc5f3ea0fe5323412ca3ba8b4a1bdbf549
|
||
context:
|
||
- _bmad-output/implementation-artifacts/epic-3-context.md
|
||
---
|
||
|
||
<frozen-after-approval reason="human-owned intent — do not modify unless human renegotiates">
|
||
|
||
## Intent
|
||
|
||
**Problem:** Story 3.1 verankerte die Update-Mechanik (Erweitern/Präzisieren/Korrigieren) in `schema/compiler.md` §5.9 als Regeltext, Story 3.2 die Candidate-Erhebung (§3.2). Unoperativ bleibt die **Ausführung je Update-Form** — v. a. das Story-3.3-AC aus FR-6: „der Text wird präzisiert oder korrigiert, **ohne die Struktur zu zerstören**". Der Compiler hat keine deterministische Anleitung, wie Präzisieren (Schärfen einer bestehenden Aussage) von Erweitern (Anfügen) abzugrenzen ist und was die „Struktur" (Frontmatter, bestehende belegte Aussagen, Provenienz-Verkettung) beim Übergriff auf einen bestehenden Absatz schützt.
|
||
|
||
**Approach:** Story 3.3 schärft §5.9 (Revision 2.8): die drei Update-Formen werden **operationell** ausformuliert — je Form ein deterministisch prüfbares **Abgrenzungskriterium** (Welche Form greift wann?), die **Struktur-Erhaltungsregel** (was bleibt unverändert: Frontmatter-Subset, bestehende belegte Aussagen + §5.5-Inline-Verweise, §5.6-Pin) und der Textgenauigkeits-Rahmen (Schärfen an der Aussage, kein Satz-Umbau, kein Neuschreiben ohne Ersetzungsbeleg). Zusätzlich eine **re-executierbare Sandbox** (`sandbox-3-3/run-sandbox.sh`, Muster Story-3.1): Demonstriert einen echten Update-Run mit committeter Neuevidenz in allen drei Formen + No-Op und prüft die Erhaltungs-Invariante (§5.9 Pkt. 5) als harte Assertion. Keine Inhalts-Mutation des realen Bundles (kein neues `raw/`-Material, AD-3); kein neues Prädikat, kein Vertrag-/Validator-/`raw/`-Change; kein Standalone (D-3).
|
||
|
||
## Boundaries & Constraints
|
||
|
||
**Always:**
|
||
- **Instruktions-Story (D-3):** Schärfung ausschließlich in `schema/compiler.md` §5.9 als deterministischer Text. Kein executable, kein Standalone, keine neue §7-Invaliditätsklasse, kein Change an `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` (AD-3).
|
||
- **Struktur-Erhaltungs-Invariante (Kern, FR-6/AC-2):** Update tastet die Struktur nicht an — (1) Frontmatter bleibt Subset-konform (nur `sources`-Zuwachs um echten neuen Beleg + `generated.at`-Bump zulässig); (2) bestehende belegte Aussagen werden nicht umgeschrieben ohne Präzisieren an ihr selbst bzw. Korrigieren mit Ersetzungsbeleg (§5.5-Inline-Verweise bleiben gültig soweit Beleg Body-Bestand); (3) gepinnte Linkform unverändert, keine neuen Links außer bei echten Beziehungen (§5.9 Pkt. 3).
|
||
- **Determinismus (AD-17h/A0-19):** Form-Wahl folgt aus der committeten Evidenz; gleicher Git-State + gleiche Eingabemenge → identischer Update-Vorgang. Abgrenzungsregeln textuell prüfbar (neue Aussage → Erweitern; Schärfung einer bestehenden → Präzisieren; ersetzende → Korrigieren).
|
||
- **Kein Leasing-Scope in 3.3:** AC-4 (Mutation nur im geleasten Bereich, AD-17.3) bleibt Story 3.5/3.6; AD-17f-Basis unverändert. §5.9 Pkt. 5/6-R1/P2-Bausteine unverändert.
|
||
- `sprint-status.yaml`: Key `3-3-bestehende-concepts-erweitern-präzisieren-korrigieren` → **in-progress** (bei Implementierung).
|
||
|
||
**Ask First:** §5.6-Linkform-Änderung (A0-9) · AD-7d-Renames · Inhalts-Mutation des realen Bundles · Validator-/Vertrags-/`raw/`-Change · Commit-Boundary-Änderung · Leasing-Ausweitung (3.5-Scope).
|
||
|
||
**Never:** Änderungen an `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` (AD-3) · neue §7-Invaliditätsklasse · Standalone (D-3) · Duplikat-Anlage eines bestehenden Pfads · „Regenerate Everything" (AD-5/A0-6) · stille Löschung von Provenienz ohne Ersetzungsbeleg (AD-16) · stiller Absatz-Neuschreib (Structure-Preservation-Fall).
|
||
|
||
## I/O & Edge-Case Matrix
|
||
|
||
| Scenario | Input / State | Expected Output / Behavior | Error Handling |
|
||
|----------|--------------|---------------------------|----------------|
|
||
| HAPPY_ERWEITERN | Neue committete Evidenz trägt eine neue belegte Aussage zum bestehenden Concept | **Erweitern:** neue Aussage als Absatz ergänzt (mit §5.5-Inline-Beleg), bestehende Aussagen unverändert; `sources`-Zuwachs um echten neuen Beleg; `at`-Bump; `log.md`-Eintrag „Story 3.1-Update" | NO_MATCH → UNTOUCHED_CONCEPT (keine Mutation) |
|
||
| HAPPY_PRAEZISIEREN | Evidenz schärft eine bestehende Aussage (präzisierende Information, FR-6/AC-2) | **Präzisieren:** Formulierung/Abgrenzung an der bestehenden Aussage geschärft, Position/Struktur erhalten; Beleg nachgeführt; kein Satz-Umbau/Neuschreib | keine bestehende Aussage als Anker → nicht Präzisieren (ggf. Erweitern) |
|
||
| HAPPY_KORRIGIEREN | Evidenz ersetzt eine fehlerhafte/überholte Aussage | **Korrigieren:** ersetzte Aussage **nicht still gelöscht**, sondern explizit abgelöst + Ersetzungsbeleg (AD-16-Default Erhaltung) | widersprechender Inhalt ohne Ersetzungsevidenz → bleibt erhalten, Disagreement in `log.md` (Epic-4-Interface) |
|
||
| NO_OP_KANDIDAT | Evidenz bereits vollständig im Body enthalten | **No-Op:** keine Mutation, kein `at`-Bump, kein `sources`-Zusatz, kein `log.md`-Eintrag — byte-identisch | im Zweifel greift Erweitern/Präzisieren (No-Op = engere Auslegung) |
|
||
| STRUKTUR_ERHALT | Update greift in Body mit belegten Aussagen + Inline-Verweisen | Struktur unverändert: Subset, Verweise, Linkform; kein unbefugter Key | Verstoß → Update fehlerhaft; Rollback + textuell benannter Verstoß (NFR-4) |
|
||
| MEHRFACH_TREFFER | Mehrere Einheiten desselben Runs treffen denselben Pfad | Konsolidierung: ein Update, ein `log.md`-Eintrag, ein konsolidierter `sources`-Zuwachs, ein `at` | Reihenfolge = Zuwachs-Sicht; lexikografischer Tie-Break |
|
||
|
||
</frozen-after-approval>
|
||
|
||
## Code Map
|
||
|
||
- `schema/compiler.md` — **primär mutiert** (D-3, einziger Instruktions-Ort):
|
||
- §5.9 Pkt. 2 (`:261-269`): drei Update-Formen **operationell ausformulieren** (a) Abgrenzungskriterium je Form, (b) Struktur-Erhaltungsregel (Definition „Struktur" + was unverändert bleibt), (c) Textgenauigkeits-Rahmen für Präzisieren. Bestehender Regeltext (Form-Bullets, `sources`-Regel, `at`-Konvention, No-Op, Konsolidierung) bleibt normativ **unverändert** — Schärfung als Ausführungs-Ebene ohne neue Logik.
|
||
- §5.9 Pkt. 5 (`:272-278`): Erhaltungs-Invariante — Struktur-Erhaltungs-Bezug ergänzen (Diff-Probe erfasst Pfad-Mengen; Struktur pro Pfad über Pkt.-2-Regeln geprüft).
|
||
- §5.9 Pkt. 6 (`:279-281`): P2-Block — Struktur-Erhaltungs-Check als zusätzliches textuelles Element (keine unbefugten Keys, keine stille Löschung, Links unverändert).
|
||
- §8 Revisionslog (`:375`): **Revision 2.8** (Story 3.3) mit Abschlussklausel (kein Vertrags-/Validator-/`raw/`-Change, keine §7-Klasse, kein Standalone).
|
||
- `_bmad-output/implementation-artifacts/sandbox-3-3/run-sandbox.sh` — **neu** (re-executierbar, Muster Story-3.1-Sandbox): Mini-Bundle mit einem Concept + committeter Neuevidenz; alle drei Formen + No-Op durchspielen; Erhaltungs-Invariante als harte Assertion (Diff ⊆ {betroffener Pfad, log}; keine neue Datei; kein Ghost-Diff); Zwei-Run-Identität; Frontmatter-Konformität je mutiertem Concept.
|
||
- `wiki/log.md` — **append** (append-only, Vertrag §5): Story-3.3-Eintrag (Schärfung, Sandbox-Nachweis, Statuswechsel, Validator-Verdikt); bestehende Bullets unverändert.
|
||
- `_bmad-output/implementation-artifacts/sprint-status.yaml` — **mutiert**: Key `3-3-…` (`:56`) → `in-progress` (→ `done` bei Story-Abschluss).
|
||
- `schema/validator.md`, `schema/wiki-compiler.md`, `raw/…` — **read-only** (AD-3). Keine Concept-Inhalts-Mutation (Instruktions-Story; kein neues committetes `raw/`-Material vorhanden — Demonstration per Sandbox).
|
||
|
||
## Tasks & Acceptance
|
||
|
||
**Execution:**
|
||
- [x] `schema/compiler.md` — §5.9-Pkt.-2-Update-Formen operationell schärfen (je Form Abgrenzungskriterium + Struktur-Erhaltungsregel + Textgenauigkeits-Rahmen; bestehender Regeltext unverändert) · §5.9-Pkt.-5/-6: Struktur-Bezug + P2-Check-Element · §8 Revision 2.8; ohne Change an `schema/wiki-compiler.md`/`schema/validator.md`/`raw/`.
|
||
- [x] `sandbox-3-3/run-sandbox.sh` — Update-Run-Demonstrator (Erweitern + Präzisieren + Korrigieren + No-Op), Erhaltungs-Invariante als harte Assertion, Zwei-Run-Identität. **Erweitert um U7 MEHRFACH_TREFFER** (I/O-Matrix-Row, Konsolidierung mehrerer Einheiten auf denselben Pfad) — alle 7 Tests (U1–U7) PASS, Exit 0.
|
||
- [x] `wiki/log.md` — Story-3.3-Eintrag (Vertrag §5, append-only): Schärfung, Sandbox-Nachweis, Statuswechsel, per-Datei-Validator-Verdikt.
|
||
- [x] `sprint-status.yaml` — Key `3-3-…` → in-progress.
|
||
|
||
**Acceptance Criteria:**
|
||
- Given eine neue Erkenntnis zu einem bestehenden Concept, when der Run sie verarbeitet, then erweitert er das bestehende Concept anstelle der Anlage einer neuen Datei (AC-1; FR-6) — Erweitern-Regel in §5.9 Pkt. 2, Sandbox belegt sie (keine neue Datei im Diff).
|
||
- Given eine präzisierende Information, when sie eingearbeitet wird, then wird der Text präzisiert oder korrigiert, ohne die Struktur zu zerstören (AC-2; FR-6) — Struktur-Erhaltungsregel in §5.9 Pkt. 2/5 definiert.
|
||
- Given eine Aktualisierung, when sie erfolgt, then bleiben Beziehungen und Provenienz soweit weiterhin gültig erhalten (AC-3; FR-6) — Inline-Verweise + Linkform unverändert gültig soweit Beleg Body-Bestand; `sources`-Zuwachs nur um echte neue Belege.
|
||
- Given die Instruktion, when geprüft, then bleibt `schema/validator.md`/`schema/wiki-compiler.md`/`raw/` unverändert (AD-3), keine neue §7-Klasse, kein Standalone (D-3), kein Leasing-Scope (AC-4 → 3.5/3.6, AD-17.3-Hinweis in §7) — Validator auf Ist-Bundle SUCCESS (7/7 unverändert).
|
||
|
||
## Spec Change Log
|
||
|
||
*(Append-only — hier von step-04 während der Review-Loops befüllt. Noch leer.)*
|
||
|
||
## Design Notes
|
||
|
||
**Warum Ergänzung, nicht Umbau:** Die Story-3.3-Schärfung ist ein Ausführungs-Sub-Block an Pkt. 2 — sie definiert die offene Frage „Was tue ich konkret bei jedem Form-Fall, und was lasse ich unangetastet?" als deterministische Brücke Regel → Run (AD-17h): dieselbe Evidenz + formale Struktur → identisches Update-Ergebnis. Der frozen Story-3.1-Regeltext bleibt unverändert; die operationellen Regeln werden als Präzisierungsebene darunter angefügt (keine Re-Negotiation).
|
||
|
||
**Struktur-Definition (das Geschützte):** (1) Frontmatter (Subset + canonische Reihenfolge; zulässig: `sources`-Zuwachs, `at`-Bump; kein neuer Key, keine Entfernung ohne Beleg); (2) bestehende belegte Aussagen mit §5.5-Inline-Verweisen (nicht umgeschrieben ohne dass Präzisieren/Korrigieren greift); (3) Linkzeichen §5.6-Pin (kein Linkumbau bei reinem Body-Update). Das ist die Bedeutung von „ohne die Struktur zu zerstören" (FR-6/AC-2).
|
||
|
||
**Abgrenzungskriterium (aus der Evidenz):** (a) belegte Aussage existiert im Body nicht → Erweitern; (b) schärft bestehende Formulierung/Abgrenzung ohne Ersatz → Präzisieren; (c) ersetzt eine bestehende als fehlerhaft/überholt → Korrigieren; (d) nichts davon → No-Op. Unschärfe → zugunsten Erweitern/Präzisieren (No-Op = engere Auslegung, bestehende §5.9-Regel).
|
||
|
||
## Verification
|
||
|
||
**Commands (re-executierbar, ab Workspace-Root):**
|
||
1. `bash _bmad-output/implementation-artifacts/sandbox-3-3/run-sandbox.sh` — expected: alle Szenarien mit harten Pass/Fail-Assertionen, Erhaltungs-Invariante erzwungen, Exit 0.
|
||
2. `grep -n "Struktur-Erhaltungsregel\|operationelle\|Revision 2.8" schema/compiler.md` — liefert die operationellen Regeln + Revisionslog.
|
||
3. Read-only (AD-3): `git status --porcelain` zeigt keinen Change an `schema/validator.md`/`schema/wiki-compiler.md`/`raw/`.
|
||
4. Validator-Lauf: alle `wiki/`-Dateien SUCCESS (unverändert, keine Inhalts-Mutation).
|
||
|
||
**Manual checks:**
|
||
- §5.9 Pkt. 2 trägt Abgrenzungskriterium + Struktur-Erhaltungsregel + Textgenauigkeits-Rahmen; bestehender Regeltext unverändert; §8-Rev-2.8 mit Abschlussklausel; kein `validator.md`/`wiki-compiler.md`/`raw/`-Diff; §7 ohne neuen Platzhalter (Update-Thema entlassen, AC-4-Leasing an 3.5/3.6); `wiki/log.md`-Eintrag datiert mit Story-3.3-Semantik + Sandbox-Nachweis + Statuswechsel + Verdikt; `sprint-status.yaml` konsistent.
|