Files
wow20/_bmad-output/implementation-artifacts/spec-3-5-leasing-dirty-tree-schutz-für-konkurrierende-producer-umsetzen.md

136 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: 'Leasing & Dirty-Tree-Schutz für konkurrierende Producer operationalisieren (Story 3.5)'
type: 'feature'
created: '2026-08-19'
status: 'done'
review_loop_iteration: 0
baseline_commit: fae648e688781d281fa668310e179fd002ba812f
context:
- _bmad-output/implementation-artifacts/epic-3-context.md
---
<frozen-after-approval reason="human-owned intent — do not modify unless human renegotiates">
## Intent
**Problem:** §0/§5.3 verankern die Commit-Boundary = Mutations-Boundary (AD-17f) als einzigen bisherigen Schutz. Es fehlt die **Koordinations-Dimension für konkurrierende Producer** (AD-17a..f, A0-12..A0-16, FR-2/FR-12): wie zwei Producer denselben Concept-Pfad nicht stillschweigend überschreiben, wie eine Lease auf `lease/<area>/<id>`-Branches mit Root-Scope und Merge-Base-Disziplin erworben wird, und wie fremde uncommittete Änderungen (Dirty Tree) geschützt statt als Nebenwirkung gelöscht werden. Der §7-Vorbehalt (`:357`) zeigt unbehoben auf Story 3.5/3.6.
**Approach:** Story 3.5 verankert die Leasing-/Dirty-Tree-Mechanik als neue Sektion **§5.11 „Leasing & Dirty-Tree-Schutz für konkurrierende Producer (Story 3.5)"** (nach §5.10, vor §6, Revision 3.0): deterministische Regeln für Lease-Akquise (Branch-Form `lease/<area>/<id>`, Lockfile, Merge-Base-Disziplin), Root-Scope-Lease (inkl. `log.md`, `index.md`, Root-Dateien), Dirty-Tree-Schutz (Pre-Mutation-Prüfung, Stash/Scratch-Zone, `log.md`-Dokumentation) und compiler-vermittelten Merge als AD-16-Pfad (kein stiller textueller Auto-Merge). Zusätzlich eine **re-executierbare Sandbox** (`sandbox-3-5/run-sandbox.sh`, Muster Story-3.4): demonstriert Lease-Akquise + Dirty-Tree-Schutz + Merge-Verweigerung an echten Git-Szenarien und assertet die Invarianten hart. Keine Inhalts-Mutation des realen Bundles (AD-3); kein neues `raw/`-Material; kein Standalone (D-3).
## Boundaries & Constraints
**Always:**
- **Instruktions-Story (D-3):** Verankerung ausschließlich in `schema/compiler.md` §5.11 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).
- **Leasing-Modell (AD-17a, A0-12):** Producer arbeiten auf `lease/<area>/<id>`-Branches; die Lease wird gegen einen **eindeutigen Commit-Object-Wert** (Merge-Base-Disziplin) akquiriert; ein **Lockfile** realisiert semantisch identisch in jedem Adapter — die Realisierung ist nicht pro Adapter frei wählbar.
- **Root-Scope-Lease (AD-17b, A0-13):** Die Lease umfasst `wiki/` inklusive `log.md`, `index.md` und aller Root-Dateien — nicht nur den mutierten Concept-Pfad.
- **Kein textueller Auto-Merge (AD-17c, A0-14):** Zwei Branches mit ungleichem Inhalt am selben Concept-Pfad werden nie textuell automatisch gemerged; der Merge ist compiler-vermittelt und durchläuft die AD-16-Klassifikation mit explizitem `log.md`-Eintrag (Interface zu Epic 4).
- **Dirty-Tree-Schutz (AD-17e/f, A0-16):** Vor jeder Mutation wird die Working Copy auf den mutierten Bereich geprüft; fremde uncommittete Änderungen werden geschützt (Stash/Scratch-Zone) und in `log.md` dokumentiert; Mutationen operieren nur auf Directory-/Commit-Ebene — Commit-Boundary = Mutations-Boundary.
- **Determinismus (AD-17h/A0-19):** Lease-Akquise, Lockfile-Inhalte und Merge-Klassifikation folgen deterministisch aus dem committeten Git-State; gleicher Git-State + gleiche Eingabemenge → identische Koordinationsentscheidung.
- **Struktur-Erhaltung (FR-6/AC-2, Story 3.3):** Die §5.9-Pkt.-2-Struktur-Erhaltungsregeln gelten je berührtem Pfad unverändert; Leasing erzwingt keine neuen Concept-Felder (Vertrag §3.1–§3.7-Subset unverändert).
- **Erhaltungs-Invariante (AD-5/FT-6):** Der §5.9-Pkt.-5-Diff-Selbsttest gilt für Leasing-fähige Runs unverändert (Pfad-Menge ⊆ Kandidatenliste Neu-Anlage `log.md` Index).
- `sprint-status.yaml`: Key `3-5-leasing-dirty-tree-schutz-für-konkurrierende-producer-umsetz`**in-progress** (bei Implementierung).
**Ask First:** Inhalts-Mutation des realen Bundles (Demo per Sandbox) · AD-7d-Renames · §5.6-Linkform-Änderung · Validator-/Vertrags-/`raw/`-Change · Lease-Staleness/Recovery-Scope (3.6) · Lease-Bereich jenseits `wiki/` (AD-17b-Root-Scope) · neuer Concept-Frontmatter-Key für Lease-Metadaten.
**Never:** Änderungen an `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` (AD-3) · neue §7-Invaliditätsklasse · Standalone (D-3) · stiller textueller Auto-Merge (AD-17c) · stille Löschung fremder uncommitteter Änderungen (AD-17e) · Leasing außerhalb von Git-Branches/Lockfile · Embeddings/Vector im Compiler-Kern (AD-13) · Scope-Ausweitung auf Lease-Staleness/Recovery (Story 3.6).
## I/O & Edge-Case Matrix
| Scenario | Input / State | Expected Output / Behavior | Error Handling |
|----------|--------------|---------------------------|----------------|
| LEASE_AKQUISE | Producer bearbeitet Area, keine Lease vorhanden | Arbeits-Branch `lease/<area>/<id>` auf Merge-Base; Lockfile geschrieben; Root-Scope-Lease dokumentiert | Lockfile existiert bereits → Lease-Hold, kein Überschreiben |
| LEASE_KONFLIKT | Zweiter Producer, Lockfile von Producer A vorhanden/Konflikt am selben Pfad | Kein stiller textueller Auto-Merge; compiler-vermittelter AD-16-Pfad mit `log.md`-Eintrag | Unentscheidbar → menschliche Eskalation (AD-17g) |
| DIRTY_TREE_SCHUTZ | Fremde uncommittete Änderung im mutierten Bereich | Schutz (Stash/Scratch-Zone) + `log.md`-Dokumentation; keine Löschung | Screen-Artefakte beim Schutz → textuell benannt |
| UNCOMMITTED_INPUT | `raw/`/`wiki/`-Working-Copy weicht von HEAD ab | Benannter Abbruch „published/committed Input erforderlich" (AD-17a) vor jeder Mutation | Keine Mutation, Bundle konsistent |
| COMMIT_BOUNDARY | Run nach Mutation + Validierung | Commit-Boundary = Mutations-Boundary; Zwischenstände nie veröffentlicht | Validierungs-FAIL → Rollback §5.3 |
</frozen-after-approval>
## Code Map
- `schema/compiler.md`**primär mutiert** (D-3):
- Neue Sektion **§5.11** (nach §5.10, vor §6): Lease-Akquise (Branch-Form `lease/<area>/<id>`, Lockfile, Merge-Base-Disziplin — deterministisch, AD-17h), Root-Scope-Lease (AD-17b, A0-13), Dirty-Tree-Schutz (Pre-Mutation-Prüfung, Stash/Scratch-Zone, `log.md`-Dokumentation, AD-17e/f), compiler-vermittelter Merge als AD-16-Pfad (kein textueller Auto-Merge, AD-17c/A0-14), Commit-Boundary = Mutations-Boundary (§0/§5.3-Verweis unverändert), `log.md`-Eintragspflicht (Lease-Akquise, Schutz-Dokumentation, Merge-Klassifikation), Determinismus-Vertrag.
- §7 (`:357`): Lease-Vorbehalt **auflösen** („→ §5.11 verankert (Story 3.5)").
- §8 Revisionslog: **Revision 3.0** mit Abschlussklausel (AD-3, keine neue §7-Klasse, kein Standalone, kein Vertrags-Change; Lease-Staleness/Recovery bleibt → Story 3.6).
- `_bmad-output/implementation-artifacts/sandbox-3-5/run-sandbox.sh`**neu** (re-executierbar, Muster Story-3.4-Sandbox): Mini-Git-Repo mit `wiki/`+`raw/`; Szenarien L1L6 (Lease-Akquise auf `lease/<area>/<id>`-Branch mit Lockfile · Lockfile-Konflikt → Lease-Hold · Root-Scope-Lease inkl. `log.md`/`index.md` · Dirty-Tree-Schutz mit Stash/Scratch-Zone + `log.md`-Dokumentation · kein textueller Auto-Merge bei ungleichem Pfad-Inhalt · Commit-Boundary-Verletzung → HARD-FAIL) + **Negativ-Kontrollen** (fremde uncommittete Änderung wird nie gelöscht; `??`-Sicht auf Ghost-Diffs). Harte Pass/Fail-Assertionen (exit 1), Erhaltungs-Invariante, `assert_frontmatter` (Muster Story-3.4).
- `wiki/log.md`**append** (append-only, Vertrag §5): Story-3.5-Eintrag (Verankerung, Sandbox-Nachweis, Statuswechsel, Validator-Verdikt); bestehende Bullets unverändert.
- `_bmad-output/implementation-artifacts/sprint-status.yaml`**mutiert**: Key `3-5-…` → in-progress (→ done bei Story-Abschluss).
- `schema/validator.md`, `schema/wiki-compiler.md`, `adapters/…`, `raw/…`**read-only** (AD-3). Keine Concept-Inhalts-Mutation (Demonstration per Sandbox).
## Tasks & Acceptance
**Execution:**
- [x] `schema/compiler.md` — §5.11 Leasing-/Dirty-Tree-Sektion einfügen (Branch-Form, Lockfile, Merge-Base-Disziplin, Root-Scope, Dirty-Tree-Schutz, AD-17c-Merge-Pfad, Commit-Boundary-Verweis, log.md, Determinismus) · §7-Vorbehalt `:357` auflösen · §8 Revision 3.0; ohne Change an `wiki-compiler.md`/`validator.md`/`raw/`.
- [x] `sandbox-3-5/run-sandbox.sh` — Leasing-Run-Demonstrator (Akquise, Konflikt, Root-Scope, Dirty-Tree-Schutz, Merge-Verweigerung, Commit-Boundary); harte Pass/Fail-Assertionen; Exit 0.
- [x] `wiki/log.md` — Story-3.5-Eintrag (append-only): Verankerung, Sandbox-Nachweis, Statuswechsel, per-Datei-Validator-Verdikt.
- [x] `sprint-status.yaml` — Key `3-5-…` → in-progress.
**Acceptance Criteria:**
- Given ein Producer, when er einen Bereich bearbeitet, then arbeitet er auf einem `lease/<area>/<id>`-Branch und akquiriert die Lease gegen einen eindeutigen Commit-Object-Wert (AC-1; AD-17a, A0-12) — §5.11, Sandbox L1.
- Given eine vergebene Lease, when sie aktiv ist, then umfasst sie die Root-Scope inklusive `log.md`, `index.md` und aller Root-Dateien (AC-2; AD-17b, A0-13) — §5.11, Sandbox L3.
- Given eine vorliegende uncommittete Fremdänderung im mutierten Bereich, when ein Producer mutieren will, then schützt er sie (Stash/Scratch-Zone) und dokumentiert den Vorgang in `log.md` (AC-3; AD-17e, A0-16) — §5.11, Sandbox L4, Negativ-Kontrolle „nie gelöscht".
- Given zwei Branches mit ungleichem Inhalt am selben Concept-Pfad, when gemerged werden soll, then erfolgt kein stiller textueller Auto-Merge; die Auflösung ist compiler-vermittelt über AD-16 mit explizitem `log.md`-Eintrag (AC-4; AD-17c, A0-14) — §5.11, Sandbox L5.
- Given die Instruktion, when geprüft, then bleiben `schema/validator.md`/`schema/wiki-compiler.md`/`raw/` unverändert (AD-3), keine neue §7-Klasse, kein Standalone (D-3), kein neuer Frontmatter-Key, Lease-Staleness/Recovery bleibt an Story 3.6 — Validator auf Ist-Bundle SUCCESS.
## Spec Change Log
- **Review-Loop 1 (2026-08-19, step-04; 3 Layer: blind-hunter / edge-case-hunter / verification-gap):** Autofix-`patch`-Findings in `schema/compiler.md` (§5.11) und `sandbox-3-5/run-sandbox.sh`; **kein bad_spec/intent_gap**, `review_loop_iteration` bleibt 0. **Text-Fixes (§5.11):** (1) Pkt.-1-Querverweis „Pkt. 3" → „Pkt. 2" (Root-Scope-Lease; dangling ref); (2) `UNCOMMITTED_INPUT`-Name als I/O-Matrix-Szenario-Deklaration geführt und **explizit mit der §5.9-P2-Element-(1)-`INPUT_UNCOMMITTED`-Prüfung gleichgesetzt** (kein zweiter, separater Abbruch-Pfad — Namens-Kollision aufgelöst); (3) Pkt. 6 um „neueste zuerst" (Vertrag-§5-Datumsgruppe, wie §5.9 Pkt. 4) ergänzt; (4) **Lease-Freigabe (Release)** als deterministischer Pkt.-1-Sub-Bullet + Pkt.-6-Eintragstyp (e) verankert — Lockfiles häufen sich nicht (Staleness-/Recovery-Aspekte der Freigabe verbleiben Story 3.6); (5) **testbares 3.5/3.6-Seam-Kriterium** (3.5 = committed-state-deterministisch / 3.6 = Zeit- bzw. Umgebungs-Zustands-Frage) ergänzt; (6) §7-Enum: AD-17d/A0-15 als **Norm-Rückverweis** gekennzeichnet (Staleness ist nicht Teil der §5.11-Auflösung); (7) §8-Revision 3.1. **Sandbox-Fixes:** (a) log-Helfer: Header-Bullet-**Paar** je Eintrag statt `\n##`-je-Zeile (Datumsgruppen-Format, Vertrag §5; kumulativer Append — neue D2-Szenario „Kumulative Koordinations-Aufzeichnung": 4 Entscheidungen in EINEM log.md, neueste zuerst); (b) L2-Lease-Hold hart über Exit-Status assertet (kein toter Code); (c) L4: `UNCOMMITTED_INPUT`-Abbruch-**Wirkung** hard asserted (HEAD unverändert, nur der fremde alpha-Pfad weicht ab, keine Mutation) + **Restore-Weg** (Scratch→Bundle) demonstriert; `^ M `-porcelain-Form werkzeugunabhängig; (d) L6: `BROKEN_HEAD`/`COMMIT_AFTER_RUN`-Tautologie beseitigt (`BUILD_HEAD`), Frontmatter-Validierungs-FAIL via Subshell (Exit-Propagation), Restore-Assertion korrekt; (e) L5: `log.md`-Klassifikations-Label als Header-Bullet asserted (kein bloßer Substring); (f) L3: `??`-Sicht nicht vacuous — neue legal angelegte `wiki/beta.md` als erlaubte Neu-Anlage durch die Invariante klassifiziert; (g) N1: „Pkt. 8" auf §5.10 Pkt. 8 (Orphan-Nachbarschaft) statt §5.9-Pkt.-8 quasi-finalisiert. **Defers**`deferred-work.md` (holder_id-Quelle; baseline_commit-Resolver; eigener `# Log`-Stand vs. Akkumulator; Revisionsnummer-1.0-Defer). **Nachweis:** Sandbox Exit 0, 21 harte PASS-Assertionen (L1L6, N1, D1, D2); AD-3 unverändert.
## Design Notes
**Warum §5.11, nicht §0-Erweiterung:** Die Commit-Boundary (§0/§5.3) ist der *Schutz bei Einzel-Validierung*; Leasing/Dirty-Tree ist die *Koordination vor/nach der Mutation an Branches* — eine eigenständige Dimension, die die Branch-/Lockfile-/Stash-Semantik beschreibt. §5.9/§5.10 (Update/Synthese) beschreiben die *Inhalts-Mechanik*; §5.11 beschreibt die *Werkzeug-Koordination*, die um jede Mutations-Form herum läuft. Das spiegelt den §7-Vorbehalt (`:357`) als eigenes Thema.
**Grenzfläche zu 3.6:** Story 3.5 deckt Akquise, Konflikt-Hold, Root-Scope und Dirty-Tree-Schutz. Staleness (TTL, Lease-Registrierung, verwaiste Leases, `raw/`-Recovery) bleibt der Story 3.6 vorbehalten — §5.11 verweist auf 3.6 und mutiert deren Mechanik nicht.
**Lease-Schutz ohne neue Fields:** Die Lease lebt in **Git/Datei-Ebene** (Branch-Name, Lockfile) — nicht in Concept-Frontmatter (Vertrag §3.1–§3.7 unverändert, keine neue §7-Klasse). Ein Lockfile realisiert semantisch identisch in jedem Adapter (A0-12); die Satzform präzisiert das Format, damit deterministisch (AD-17h).
## Verification
**Commands (re-executierbar, ab Workspace-Root):**
1. `bash _bmad-output/implementation-artifacts/sandbox-3-5/run-sandbox.sh` — expected: alle Szenarien L1L6 + Negativ-Kontrollen mit harten Pass/Fail-Assertionen, Erhaltungs-Invariante erzwungen, Exit 0.
2. `grep -n "Leasing & Dirty-Tree-Schutz\|Revision 3.0" schema/compiler.md` — liefert die Leasing-Sektion + Revisionslog-Eintrag.
3. Read-only (AD-3): `git status --porcelain` zeigt keinen Change an `schema/validator.md`/`schema/wiki-compiler.md`/`adapters/`/`raw/`.
4. Validator-Lauf: alle `wiki/`-Dateien SUCCESS (unverändert, keine Inhalts-Mutation).
**Manual checks:**
- §5.11 trägt Branch-Form `lease/<area>/<id>`, Lockfile, Merge-Base-Disziplin, Root-Scope-Lease, Dirty-Tree-Schutz (Stash/Scratch-Zone + log.md), AD-17c-Merge-Pfad, Commit-Boundary-Verweis, Determinismus; §7-Vorbehalt `:357` auf §5.11 aufgelöst; §8-Rev-3.0 mit Abschlussklausel; kein `validator.md`/`wiki-compiler.md`/`adapters/`/`raw/`-Diff; kein neuer Standalone (D-3) / keine neue §7-Klasse / kein neuer Frontmatter-Key; Lease-Staleness bleibt an 3.6; `wiki/log.md`-Eintrag datiert mit Story-3.5-Semantik + Sandbox-Nachweis + Statuswechsel + Verdikt; `sprint-status.yaml` konsistent.
## Suggested Review Order
**Leasing-Koordinations-Dimension (§5.11)**
- Einstiegspunkt: die verbindliche Verankerung der Koordinations-Dimension — Lease-Akquise, Root-Scope, Dirty-Tree-Schutz, Merge- und Determinismus-Vertrag
[`compiler.md:303`](../../schema/compiler.md#L303)
- Pkt. 1 Lease-Akquise: Branch-Form, Lockfile, Merge-Base-Disziplin, deterministische Lease-Freigabe
[`compiler.md:307`](../../schema/compiler.md#L307)
- Pkt. 2/3 Root-Scope-Lease + Dirty-Tree-Schutz: Stash/Scratch-Zone, UNCOMMITTED_INPUT-Abbruch (nicht-vacuous)
[`compiler.md:312`](../../schema/compiler.md#L312)
- Pkt. 47: compiler-vermittelter Merge (AD-16), Commit-Boundary, log.md-Pflicht, Determinismus-Vertrag & 3.5/3.6-Seam
[`compiler.md:317`](../../schema/compiler.md#L317)
- §8-Revisionslog „Revision 3.0" mit Abschlussklausel (AD-3, keine neue §7-Klasse, kein Standalone)
[`compiler.md:416`](../../schema/compiler.md#L416)
**Nachweis: Sandbox & Story-Protokoll**
- Szenario-Matrix L1L6 + Negativ-Kontrollen als re-executierbarer Beweis der Invarianten
[`run-sandbox.sh:6`](../../_bmad-output/implementation-artifacts/sandbox-3-5/run-sandbox.sh#L6)
- L1 Lease-Akquise / L2 Lease-Hold: hart assertierte Akquise- und Fehlerpfade
[`run-sandbox.sh:269`](../../_bmad-output/implementation-artifacts/sandbox-3-5/run-sandbox.sh#L269)
- L4 Dirty-Tree-Schutz: Pre-Mutation-Prüfung, Restore-Weg, „nie gelöscht"-Assertion
[`run-sandbox.sh:379`](../../_bmad-output/implementation-artifacts/sandbox-3-5/run-sandbox.sh#L379)
- L6 Commit-Boundary: Zwischenstand nie veröffentlicht, Validierungs-FAIL → Rollback
[`run-sandbox.sh:476`](../../_bmad-output/implementation-artifacts/sandbox-3-5/run-sandbox.sh#L476)
- Story-3.5-`wiki/log.md`-Eintrag: Verankerung, Sandbox-Nachweis, Statuswechsel, Verdikt (append-only)
[`log.md:3`](../../wiki/log.md#L3)
- 4 Defers (holder_id-Quelle, baseline_commit-Merge-Base, Sandbox-Akkumulator, native `git stash`) — Homes Story 3.6/3.8
[`deferred-work.md:416`](../../_bmad-output/implementation-artifacts/deferred-work.md#L416)