Files
wow20/_bmad-output/implementation-artifacts/spec-3-12-lease-lifecycle-und-commit-abschluss-transaktional-schliessen.md
T

132 lines
19 KiB
Markdown
Raw 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: 'Story 3.12 — Lease-Lifecycle und Commit-Abschluss transaktional schließen'
type: 'feature'
created: '2026-08-21'
status: 'in-progress'
baseline_commit: '80480af3ec910b6a00d10f4fe820131bbf79c6a5'
review_loop_iteration: 0
context:
- '_bmad-output/implementation-artifacts/epic-3-context.md'
---
<frozen-after-approval reason="human-owned intent — do not modify unless human renegotiates">
## Intent
**Problem:** Die Koordinations-Dimension ist über §5.11 (Leasing/Dirty-Tree, Story 3.5), §5.12 (Staleness/Recovery, Story 3.6), §5.13 (Phasen-Trennung, Story 3.7) und §5.17 (atomare Root-Scope-Lease-Akquise, Story 3.11) verankert — aber die **Lifecycle-Klammer fehlt**: Akquise, Dirty-Tree-Schutz, Mutation, Rollback und Freigabe sind nirgends als **konsistenter, transaktionaler Lebenszyklus** instruiert, der SUCCESS und FAIL jeweils einen sauberen, wiederanlaufbaren Zustand hinterlässt. Konkret unverankert: (a) **Liveness** einer lebenden Lease (eine höhere Generation macht sie nicht stale; Staleness verlangt bestätigten Abbruch oder abgelaufene Liveness plus atomare Ownership-Prüfung — epic-3-context Z. 43 „Zielzustand Review-Loop-3, P-11" und SCP 2026-08-20 Z. 71 „Staleness/Liveness"); (b) **durable Release** — nach Release sind Mutation, zulässiger Nachweis und Freigabe dauerhaft, Lock entfernt, Worktree sauber, Folge-Run besteht den **Clean-Input-Guard**; (c) **Baseline-Rollback** (Index **+** Worktree) aus dem bezeichneten Baseline-Commit mit leerem Post-Rollback-Diff (§5.3/§6-Pkt.-3-Mechanik nennt nur Bundle-/`git checkout`-Wiederherstellung, kein Index); (d) eine **eindeutige Abort-/Protect-Zustandsmaschine** für getrackte und ungetrackte fremde Änderungen (sandbox-3-5 L4 ist nur Inline-Ablauf, keine Zustandsmaschine); (e) **stale-Übernahme genau einmal** mit ersetzter Holder-ID und genau einer aktiven Root-Lease; (f) **Kill-Point-Tests** (termini undefiniert, nirgends verankert); (g) die **Grenze des kanonischen Knowledge Logs** (`wiki/log.md` nur vertragskonforme fachliche Änderungen + notwendige Koordinationsereignisse).
**Approach:** Neue Sektion **§5.18 „Lease-Lifecycle & transaktionaler Commit-Abschluss (Story 3.12)"** (nach §5.17, vor §6; Revision 3.7): additiv über §5.11/§5.12/§5.13/§5.17, Fugen-Identität — kein Umbau bestehender Wortlaute. Sie instruiert den geschlossenen Ablauf (1) Liveness-Ownership (nur bestätigter Abbruch/abgelaufene Liveness + atomare Ownership-Prüfung macht eine Lease stale; eine höhere Generation allein nicht), (2) stale-Übernahme genau einmal (genau eine aktive Root-Lease, ersetzte Holder-ID im `log.md`), (3) Abort-/Protect-Zustandsmaschine für fremde getrackte/ungetrackte Änderungen (Scratch-Zone `scratch/<run-id>/` bzw. `git stash push`; byte-identischer Restore) samt `UNCOMMITTED_INPUT`-Abbruch abgestimmt mit §5.11 Pkt. 3, (4) Baseline-Rollback (Index **+** Worktree aus `<Baseline-Commit>`; Post-Rollback-Diff leer; Kill-Punkt nach Mutation/Staging), (5) durable Release (Mutation + zulässiger Log-/Koordinationsnachweis committet, Lock per Ref-Delete entfernt, Worktree sauber, unmittelbar folgender Run besteht den **Clean-Input-Guard** — sauberer Worktree ohne fremde/geschützte Reste), (6) kanonisches Log (§5/Koordination nur), (7) Kill-Point-Tests (vor Mutation, nach Mutation, vor Commit, nach Commit — je konsistenter Endzustand, §5.13-Pkt.-3-Zustands-Restaurations-Invariante).
## Boundaries & Constraints
**Always:**
- **Nur `schema/compiler.md` mutiert** (neue §5.18 + §7-Bullet-Erweiterung Story-3.12 + §8-Revisionslog **Revision 3.7**). `schema/validator.md`, `schema/wiki-compiler.md`, `adapters/`, `raw/` **read-only** (AD-3); `schema/canonical-terms.md` append-only unangetastet. `sprint-status.yaml`, `wiki/log.md`, `epic-3-context.md`, `deferred-work.md` werden nur append/Sync-gepflegt.
- **Referenz statt Re-Negotiation:** §5.11 (Pkt. 17), §5.12 (Pkt. 17), §5.13 und §5.17 bleiben **textuell unverändert** — §5.18 instruiert die Lifecycle-Ebene darüber und referenziert sie Wortlaut-unverändert. Fugen-Identität: Branch-Form `lease/<area>/<id>`, Lockfile-Feld-Satz, Root-Scope-Umfang §5.11 Pkt. 2, atomarer scope-bezogener Lock §5.17.
- **Kein neues Prädikat, keine neue §7-Invaliditätsklasse, kein neuer Frontmatter-/Format-Key, kein Standalone (D-3), keine Wanduhr-/Systemzeit-Steuerung** (A0-20: keine TTL über Kalenderzeit; Lifecycle deterministisch aus dem committeten Git-State, AD-17h/A0-19). Das `generated.at`-Wanduhr-Gap (§5.14 Pkt. 3) bleibt unverändert.
- **Sandbox-Nachweis re-executierbar** (Muster sandbox-3-11, Exit 0, harte PASS/FAIL, `/tmp`-Baum, nie der reale Ist-Baum; kein Zugriff auf reales Bundle/`raw/`).
**Ask First:**
- Verhalten des `generated.at` (A0-20) oder eine TTL-/Wanduhr-Steuerung ändern (bleibt benannter Defer bzw. bindend unverändert).
- Änderung an §5.17-Pkt.-2-Ask-First-Klausel (atomares create-only-Primitiv nicht zuverlässig → HALT, Alternativ-Primitiv).
- Änderung an §5.11-Pkt.-1-/Pkt.-2-Wortlaut oder §5.12-Ankern (frozen, Fugen-Identität).
- Erweiterung des `schema/validator.md` um Lease-/Koordinations-Prüfpunkte (wäre Epic-1-Vertragsänderung — nicht Teil dieser Story).
**Never:**
- Kein Umschreiben bestehender §5.11/§5.12/§5.13/§5.17-Wortlaute; keine Wanduhr-TTL; keine stille Löschung fremder uncommitteter/geschützter Änderungen (AD-17e); keine Wissensmutation bei Orphan/Hold (AD-16-Default); kein textueller Auto-Merge (AD-17c); keine neue eigene LLM-Runtime/Workflow-Engine (AD-11, D-3); kein Standalone; keine Validator-Erweiterung ohne Autorisierung.
## I/O & Edge-Case Matrix
| Scenario | Input / State | Expected Output / Behavior | Error Handling |
|----------|--------------|---------------------------|----------------|
| LIVENESS_AKTIV | lebende Lease mit höherer Generation sichtbar | Lease bleibt aktiv; keine Stale-werdung allein durch Generationshöhe (AC-1) | kein Release, keine Fremd-Übernahme |
| STALE_UEBERNAHME | nachweislich stale Lease (bestätigter Abbruch / abgelaufene Liveness) | Übernahme gelingt genau einmal; ersetzte Holder-ID benannt; genau eine aktive Root-Lease (AC-2) | Ownership-Prüfung vor Übernahme; kein Doppel-Übernehmer |
| DIRTY_GETRACKT | fremde getrackte Änderung im Mutationsbereich | Abort-/Protect-Zustandsmaschine: schützen (Scratch/Stash), Restore byte-identisch nach Run (AC-3) | UNCOMMITTED_INPUT-Abbruch abgestimmt §5.11 Pkt. 3; nie gelöscht |
| DIRTY_UNGETRACKT | fremde ungetrackte Datei im Mutationsbereich | Protect: sichern + Restore; keine stillen Löschungen (AC-3) | nie gelöscht; log.md-Eintrag |
| ROLLBACK_NACH_MUTATION | Fehler nach Mutation/Staging | Rollback aus `<Baseline-Commit>`: Index **+** Worktree restauriert; Post-Rollback-Diff leer (AC-4) | Kill-Punkt nach Mutation: konsistenter Endzustand |
| ROLLBACK_NACH_COMMIT_VOR_RELEASE | Fehler nach Commit, vor Release | Kill-Punkt vor Commit/vor Release: Zustand == Baseline oder valide committet; kein Teilzustand veröffentlicht (AC-4) | Commit-Boundary = Mutation-Boundary (AD-17f) |
| RELEASE_DURABLE | erfolgreicher Run | Mutation + zulässiger Log-/Koordinationsnachweis committet; Lock per Ref-Delete entfernt; Worktree sauber; Folge-Run besteht Clean-Input-Guard (AC-5) | Release-Fehler = HARD-FAIL; Lock nie hängend |
| KANONISCHES_LOG | Run-Historie schreiben | `wiki/log.md` nur vertragskonforme fachliche Änderungen + notwendige Koordinationsereignisse; Build-/Review-/Story-/Sandbox-Historie außerhalb (AC-6) | Verstoß = textuell benannt (NFR-4) |
| KILLPUNKT_VOR_MUTATION | vor erster Mutation | Zustand == Baseline; keine Zwischenstände (AC-7) | konsistenter Endzustand, Determinismus |
| KILLPUNKT_NACH_MUTATION | nach Mutation | Zustand == valider Zwischenstand (geplanter Plan-Freeze); kein Ghost-Diff außerhalb erlaubter Menge (AC-7) | §5.9-Pkt.-5-Ghost-Diff-Rollback |
| KILLPUNKT_VOR_COMMIT | nach Staging, vor Commit | nur erlaubte Pfad-Menge staged; kein Teilzustand committet (AC-7) | Commit-Boundary = Mutation-Boundary |
| KILLPUNKT_NACH_COMMIT | nach Commit | Bundle == valide committeter Zustand; anschließbar an Clean-Input-Guard (AC-7) | kein hängender Lock, sauberer Worktree |
## Code Map
- `schema/compiler.md`**primär mutiert** (D-3): neue Sektion **§5.18 „Lease-Lifecycle & transaktionaler Commit-Abschluss (Story 3.12)"** (nach §5.17 Z. 415424, vor §6 Z. 426; Pkt. 17); **§7-Bullet-Erweiterung** (Story-3.12-Verankerung analog §5.17-/§5.15-Ergänzung bei Z. 471ff); **§8-Revisionslog Revision 3.7** (Z. 486ff, nach Z. 527). Bestehende §5.11 (Z. 304321)/§5.12 (Z. 323342)/§5.13 (Z. 344363)/§5.17 (Z. 415424) bleiben **textuell unverändert** (Fugen-Identität; §5.17-Pkt.-1-Z. 419 „Lifecycle-Regie Story 3.12" und Pkt.-6-Z. 424 „bleibt Story 3.12" sind die Anschluss-Sutur).
- `_bmad-output/implementation-artifacts/sandbox-3-12/run-sandbox.sh`**neu** (re-executierbar, Muster `sandbox-3-11/run-sandbox.sh` 544 Z., Exit 0): Lifecycle-Szenarien L-1..L-9 (Matrix-Zeilen als harte Assertionen); übernimmt die 3-11-Bausteine (`isolate()` Z. 99109, `scopelock_acquire()` Z. 124131, `scopelock_release()` Z. 132141 mit Ownership-Prüfung, `scopelock_content()` Z. 142148, `assert_frontmatter()` Z. 164173, `runlabel`/`pass`/`fail` Z. 98/179180) und ergänzt: **Abort-/Protect-Zustandsmaschine** (aus sandbox-3-5-L4-Inline Z. 379434: `db_check` Z. 223234, Stash/Scratch Z. 416421, Restore Z. 422425), **Registry/Gen/Liveness** (aus sandbox-3-6: `reg_gen` Z. 219224, `lease_stale` Z. 277283, `reg_write`/`reg_bump` Z. 233256, `reg_stale_mark` Z. 257264, `free_lease` Z. 338343), **Baseline-Rollback Index+Worktree** (via §5.13-Pkt.-3 Z. 359 „Post-Rollback-Diff gg. Baseline leer"), **Kill-Point-Tests** (4 Konsistenz-Assertions), **Clean-Input-Guard** (Worktree-Sauberkeitsprüfung nach Release). Kein Zugriff auf reales Bundle/`raw/`.
- `_bmad-output/implementation-artifacts/sandbox-3-11/run-sandbox.sh`**read-only Vorbild** (Ableitungs-Pflicht: `scopelock_release`-Ownership, `isolate`-Ref-Reset, A-8-Relase-erneut Z. 501523; Defer „scopelock_header_banner" Z. 166/175 → Home 3.12).
- `_bmad-output/implementation-artifacts/sandbox-3-5/run-sandbox.sh`**read-only Quelle** der Dirty-Tree-Mechanik (L4 Z. 379434: `db_check` Z. 223234, UNCOMMITTED_INPUT-Abbruch Z. 395415, Stash/Scratch Z. 416421, Restore Z. 422425, NIE-gelöscht Z. 426428).
- `_bmad-output/implementation-artifacts/sandbox-3-6/run-sandbox.sh`**read-only Quelle** der Registry/Stale-/Recovery-Mechanik (Registry Z. 216245, Gen Z. 219224/246256, `lease_stale` Z. 277283, Stale-Mark/Übernahme Z. 257264/346478, `raw/`-Recovery STALE-4 Z. 451478, `assert_no_wallclock` Z. 294300).
- `_bmad-output/implementation-artifacts/sprint-status.yaml`**mutiert**: Key `3-12-lease-lifecycle-und-commit-abschluss-transaktional-schliessen` `backlog``review` (Implementierungs-Commit; finaler `done`-Flip im Step-05-Status-Sync nach konvergiertem Review-Loop); `last_updated` (Format `MM-DD-YYYY HH:MM`).
- `wiki/log.md`**append** (Vertrag §5): Story-3.12-Eintrag (Verankerung §5.18, Sandbox L-1..L-9, Status-Flip, Validator-Verdikt) — **nur** vertragskonforme fachliche + Koordinationsereignisse (AC-6).
- `_bmad-output/implementation-artifacts/deferred-work.md`**append**: Story-3.12-relevante Defers aus Review-Loop-1-Story-3.11 als aufgegriffen markieren („Sandbox-3.5/-3.6-check-then-act-Abgleich", „Banner-/I-O-Matrix-Kosmetik", „scopelock_header_banner"-Platzhalter) bzw. benannte Home-Zuordnung.
- `_bmad-output/implementation-artifacts/epic-3-context.md`**mutiert** („Edit freely"): Technical Decision Z. 43 „Transaktionaler Lifecycle" von „Zielzustand… nicht verankert" auf Ist-Zustand (§5.18) aktualisieren.
**Read-only evidence (AD-3):** `schema/validator.md` (Rev 9 — prüft **keine** Lease-/Koordinationszustände, Z. 194/195 nur `stale_after`-Lebenszyklus-WARN; Validator-Erweiterung nicht Teil dieser Story), `schema/wiki-compiler.md`, `adapters/`, `raw/` (z. B. `raw/prd/…`, `raw/epics/…`). `schema/canonical-terms.md` append-only unangetastet.
## Tasks & Acceptance
**Execution:**
- [x] `schema/compiler.md` — §5.18 einfügen (nach §5.17, vor §6): Pkt. 17 gemäß Intent; §7-Bullet und §8-Revisionslog **Revision 3.7** nachführen; bestehende §5.11/§5.12/§5.13/§5.17 textuell unverändert (Fugen-Identität)
- [x] `_bmad-output/implementation-artifacts/sandbox-3-12/run-sandbox.sh` — L-1..L-9 (Lifecycle, Abort-/Protect-Zustandsmaschine, Baseline-Rollback Index+Worktree, Kill-Point-Tests, Clean-Input-Guard), harte PASS/FAIL, Exit 0, `/tmp`-Baum, nie realer Ist-Baum
- [x] `_bmad-output/implementation-artifacts/sprint-status.yaml` — Key 3-12 → `review` (Impl-Commit; finaler `done`-Flip Step-05); `last_updated` aktualisieren
- [x] `wiki/log.md` — Story-3.12-Eintrag (Verankerung, Sandbox, Status-Flip, Validator-Verdikt) — nur vertragskonforme Inhalte (AC-6)
- [x] `_bmad-output/implementation-artifacts/deferred-work.md` — relevante Story-3.12-Home-Defers als aufgegriffen markieren/zuordnen
- [x] `_bmad-output/implementation-artifacts/epic-3-context.md` — Technical Decision Z. 43 auf Ist-Zustand (§5.18) aktualisieren
**Acceptance Criteria:**
- Given einen lebenden Lease-Halter, when eine höhere Generation sichtbar wird, then bleibt seine Lease aktiv; Staleness verlangt bestätigten Abbruch oder abgelaufene Liveness sowie atomare Ownership-Prüfung (AC-1).
- Given eine nachweislich stale Lease, when sie übernommen wird, then gelingt die Übernahme genau einmal, nennt die ersetzte Holder-ID und hinterlässt genau eine aktive Root-Lease (AC-2).
- Given getrackte oder ungetrackte fremde Änderungen im Mutationsbereich, when der Preflight läuft, then folgt er einer eindeutigen Abort-/Protect-Zustandsmaschine und stellt geschützte Bytes nach dem Run vollständig wieder her (AC-3).
- Given einen Fehler nach Mutation oder Staging, when Rollback läuft, then restauriert er explizit aus dem bezeichneten Baseline-Commit sowohl Index als auch Worktree; der Post-Rollback-Diff gegen die Baseline ist leer (AC-4).
- Given einen erfolgreichen Run, when er freigegeben wird, then sind Mutation, zulässiger Log-/Koordinationsnachweis und Release dauerhaft, der aktive Lock ist entfernt, der Worktree ist sauber und der unmittelbar folgende Run besteht den Clean-Input-Guard (AC-5).
- Given `wiki/log.md`, when ein Run protokolliert wird, then enthält das kanonische Knowledge Log nur vertragskonforme fachliche Änderungen und notwendige Koordinationsereignisse; Build-, Review-, Story- und Sandbox-Historie liegt außerhalb des Knowledge Bundle (AC-6).
- Given ein Lifecycle, when Kill-Point-Tests vor Mutation, nach Mutation, vor Commit und nach Commit laufen, then beweisen sie den jeweils konsistenten Endzustand (AC-7).
## Spec Change Log
## Design Notes
Der Lifecycle ist der **geschlossene transaktionale Rahmen** der Koordinations-Dimension: Akquise (§5.11/§5.17) → Preflight/Protect (§5.11 Pkt. 3) → Mutation (§5.9/§5.10/§5.16) → Rollback (§5.13) → durable Release (§5.11 Pkt. 1/§5.17 Pkt. 1 Ref-Delete) → Clean-Input-Guard (Nachfolger-Bedingung). §5.18 ordnet die bestehenden Mechaniken in eine Zustandsmaschine und ergänzt nur die fehlenden Klammern (Liveness/Ownership, Abort-/Protect-Zustandsmaschine, Index+Worktree-Rollback, durable Release + Clean-Input-Guard, kanonisches Log, Kill-Point-Tests).
**Kernprinzipien:**
- **Keine Wanduhr-TTL:** Staleness folgt nie aus Kalenderzeit (A0-20), sondern aus committeten Zuständen (Gen-Registry, §5.12) **plus** bestätigtem Abbruch / abgelaufener Liveness (deterministisch belegt, z. B. Halter-Branch-Verlust/Registry-Status) — Liveness ist ein beobachtbarer, kein zeitlicher Zustand.
- **Ownership-Prägung:** Akquise (create-only-Existenz, §5.17), Übernahme (atomare Ownership-Prüfung: Inhaber-Run-ID muss Lock-Inhalt tragen) und Release (Ref-Delete nur durch Inhaber) sind einheitlich ownership-gebunden.
- **Rollback = Baseline-Punkt:** Index **+** Worktree werden aus `<Baseline-Commit>` restauriert (`git reset --hard <Baseline-Commit>` ist zulässiges Beispiel — deterministisch, ohne Wanduhr); Post-Rollback-Diff leer (§5.13 Pkt. 3 Zustands-Restaurations-Invariante).
- **Clean-Input-Guard:** Nach Release muss ein Folge-Run ohne `INPUT_UNCOMMITTED`-Abbruch starten — d. h. sauberer Worktree, kein hängender Lock, geschützte Fremd-Bytes sind restauriert. Kill-Punkt „nach Commit" antizipiert genau diesen Zustand.
## Verification
**Commands:**
- `bash _bmad-output/implementation-artifacts/sandbox-3-12/run-sandbox.sh` -- expected: L-1..L-9 harte PASS, Exit 0, kein Zugriff auf reales Bundle/`raw/`.
- `grep -n "## 5.18" schema/compiler.md` und `grep -n "Revision 3.7" schema/compiler.md` -- expected: §5.18-Überschrift und §8-Revisionslogeintrag vorhanden; bestehende §5.11/§5.12/§5.13/§5.17-Texte unverändert (diff prüft nur additive/berichtigte Zeilen).
- `git diff --stat` (Repo-Root) -- expected: nur Story-3.12-Touched-Files (compiler.md, sandbox-3-12, spec, log.md, sprint-status.yaml, deferred-work.md, epic-3-context.md); `schema/validator.md`/`schema/wiki-compiler.md`/`adapters/`/`raw/` ohne Diff (AD-3); `git status --porcelain -- wiki/` zeigt nur `wiki/log.md`.
**Manual checks (if no CLI):**
- Keine Beschreibung nötig — sämtliche Nachweise laufen über die Sandbox (Exit-Code) und additive Diffs.
## Suggested Review Order
**Design-Intent (normative Instruktion)**
- Einstieg: die §5.18-Lifecycle-Sektion — Liveness/Ownership, Abort-/Protect-Zustandsmaschine, Baseline-Rollback Index+Worktree, durable Release + Clean-Input-Guard, kanonisches Log, Kill-Point-Tests (AC-1..7).
- Abgrenzungsklausel — Fugen-Identität §5.11/§5.12/§5.13/§5.17; Anschluss-Sutur §5.17-Pkt.-1-Z. 419 / Pkt.-6-Z. 424 („Lifecycle-Regie Story 3.12").
**Lifecycle-Mechanik (Sandbox)**
- Abort-/Protect-Zustandsmaschine (getrackt/ungetrackt; byte-identischer Restore) — abgeleitet aus sandbox-3-5-L4, gehärtet als Zustandsmaschine.
- Baseline-Rollback Index+Worktree + Kill-Point-Tests (vor Mutation/nach Mutation/vor Commit/nach Commit; Post-Rollback-Diff leer).
- Liveness/Ownership + stale-Übernahme genau einmal (Gen-Registry §5.12-Mechanik; ersetzte Holder-ID; genau eine aktive Root-Lease).
- Durable Release + Clean-Input-Guard (Lock per Ref-Delete; Worktree sauber; Folge-Run ohne INPUT_UNCOMMITTED-Abbruch).
**Status- & Nachweissynchronisation (peripher)**
- Revisionsnachweis Story 3.12 in der Laufzeitakte (Verankerung, Sandbox, Abschlussklausel, Erhaltungs-Invariante).
- epic-3-context Z. 43 auf Ist-Zustand nachgeführt; Defer-Homes Story-3.12 in deferred-work.md markiert.
### Review Findings
_Bmad-code-review Loop 1 (2026-08-21), 4 Layer (blind-hunter/edge-case-hunter/verification-gap/acceptance-auditor). Triage: **noch offen** — Findings werden nach dem Loop im Spec-Change-Log festgehalten._