16 KiB
title, type, created, status, baseline_commit, review_loop_iteration, context
| title | type | created | status | baseline_commit | review_loop_iteration | context | |
|---|---|---|---|---|---|---|---|
| Story 3.6 — Lease-Staleness & Recovery-Basis absichern | feature | 2026-08-19 | done | 895b006f7f |
0 |
|
Intent
Problem: Ein abgebrochener Run hinterlässt eine Lease, die §5.11 (Lease-Hold) akquiriert, doch deren Freigabe (Release) nur nach committetem Run erfolgt. Ohne Staleness-Mechanik blockiert eine verwaiste Lease alle nachfolgenden Runs dauerhaft — Wissen bleibt blockiert (AD-17d/A0-15; §5.11 Pkt. 1 „verbleibt bis zum Staleness-/Recovery-Mechanismus der Story 3.6", §5.11 Pkt. 7-Seam: 3.6 = Zeit-/Umgebungs-Zustands-Frage, §7 verbleibendes 3.x-Thema).
Approach: Neue Sektion §5.12 „Lease-Staleness & Recovery-Basis (Story 3.6)" (nach §5.11, vor §6): TTL + Lease-Registrierung im Clone-Root-State deterministisch einführen — das TTL-Ablauf-Kriterium ist generationen-basiert (ohne Wanduhr, AD-17h-konform; die A0-20 zugelassene at-Notation bleibt dokumentierend) — plus Verwaist-Handling (Übernehmen/Stale-Markieren mit log.md-Protokollierung) und die raw/-Recovery-Basis (Zugriffs-/Consistency-Basis, AD-3 unverändert). Die vier Story-3.5-Defers mit Home 3.6 werden aufgegriffen (holder_id-Ableitung, baseline_commit-Diskrepanz-Regel, kumulative Registrierung über Runs, native git stash-Variante + Verwaist-Übungs-Thema). Verwaiste/hängende Leases werden dabei nie gelöscht (AD-17e) und raw/ nie verändert (AD-3).
Boundaries & Constraints
Always:
- Nur
schema/compiler.md(neue §5.12 + §7-Auflösung + §8 Revisionslog-Revision 3.1) mutiert (D-3);schema/validator.md,schema/wiki-compiler.md,adapters/,raw/read-only (AD-3). Kein Standalone (D-3), keine neue §7-Invaliditätsklasse, kein Vertrags-Change. - Deterministisch aus dem committeten Git-State ableitbar (AD-17h/A0-19): Registrierungs-Aufbau, Ablauf-Kriterium, Verwaist-Klassifikation, log.md-Texte; kein Wanduhr-Timestamp im Lockfile- oder Registrierungs-Format (A0-20-Konvention, §5.11 D1).
raw/ist die Zugriffs- und Consistency-Recovery-Basis (AD-17d/A0-15) und bleibt bei jedem Vorgang unverändert (AD-3).- Verwaiste/hängende Leases werden nie still gelöscht und fremde uncommittete Änderungen nie als Seitenwirkung entfernt (AD-17e).
Ask First:
- Wanduhr-basierte TTL (Timeout nach Kalenderzeit) statt Generationen-Ablauf — wäre ein deterministischer Bruch, weil wanduhr-
atvon der Laufzeit abhängt; die A0-20-Konvention ließe einen dokumentierenden Zeitstempel zu, ein streng durchsetzendes Zeit-TTL wäre Ask-First. - Konflikt zweier gültiger Leases, die nicht per Generationen-Reihenfolge auflösbar ist (Older-wins außerhalb der definierten Klasse).
Never:
raw/-Inhalte verändern (AD-3); uncommittete fremdewiki/-Änderungen löschen (AD-17e); textuelle Auto-Merge bei Branch-Konvergenz (AD-17c); Leasing überlease/<area>/<id>-Branches hinaus; Zeitstempel/now-Wanduhr als Leasing-Steuer-Größe; neuer Frontmatter-Key für Lease-Metadaten (Vertrag §3.1–§3.7, §7); Prädikat-/Format-Erweiterung des Validators; EOF-# Log-eigener Stand in der Registry (wiki/log.md-Akkumulator ist alleiniger Aufzeichnungs-Ort, Vertrag §5).
I/O & Edge-Case Matrix
| Scenario | Input / State | Expected Output / Behavior | Error Handling |
|---|---|---|---|
| STALE_ABLAUF | uncommittete Lease nach abgebrochenem Run; nachfolgender Run trifft auf sie | Lease gilt als stale, blockiert nicht; Übernahme oder Stale-Markierung mit log.md-Eintrag | verwaiste Lease nie gelöscht (AD-17e); Abbruch „published/committed Input erforderlich" (AD-17a, §5.11 Pkt. 3) unverändert |
| VERWAIST_UEBERNEHMEN | neuer Run findet verwaiste Lease | übernimmt die Lease gegen die erneute Merge-Base-Prüfung, protokolliert die Übernahme | bei bestehendem Konflikt → AD-16-Pfad / menschliche Eskalation (AD-17g, §5.11 Pkt. 4) |
| VERWAIST_STALE_MARKIEREN | verwaiste Lease, Übernahme nicht sinnvoll | als stale markiert (Registry-Marker) und protokolliert; Blockade aufgehoben | Registrierungs-Invariante (Gen > erzeugend oder gleiche Gen, hält den sichtbar höchsten Reg-Generator) |
| RECOVERY_RAW_BASIS | uncommittete Änderungen aus abgebrochenem Run wiederherstellen | raw/ (immutable, AD-3) als Zugriffs-/Consistency-Basis; Konformität re-bestätigt |
raw/ unverändert; kein git diff-/SHA-256-Beweis gegen raw/-Inhaltsebene auf dem realen Ist-Baum (Grenzen beachten: EC-1 auf sandbox-Evidenzwege beschränkt) |
| HOLD_GEGEN_HEAD | Lease existiert; zu mutierender Bereich liegt nicht unter der akquirierten Lease | Lease-Hold gegen HEAD; keine Mutation; kein Abbruch-Text | §5.11 Pkt. 1 (Lease-Hold) unverändert |
| DIRTY_TREE_UNVERWAIST | uncommittete fremde Änderung (Verdacht) ohne verwaiste Lease | §5.11 Pkt. 3 (Schutz/Scratch-Zone, nie gelöscht) greift; keine Staleness-Marke | textuell benannt (NFR-4); Restore-Weg dokumentiert |
Code Map
schema/compiler.md— primär mutiert (D-3): neue Sektion §5.12 „Lease-Staleness & Recovery-Basis (Story 3.6)" (nach §5.11, vor §6; §5.11-Seam-Kriterium S-1 und Pkt.-7-Text bleiben unverändert); §7 (:376-Bullet) Staleness/Recovery-Vorbehalt auflösen („in §5.12 verankert (Story 3.6)"); §8 Revisionslog Revision 3.1 mit Abschlussklausel; §8 Normreferenzen AD-17d/A0-15 von reiner Story-Zuordnung auf §5.12-Anker angehoben (AD-17d (Lease-Staleness, §5.12)); konsistente§5.12-Verweise in §5.11-Pkt.-1/Pkt.-7/§7 (nur Wortlaut, kein neuer Inhalt). Anker§5.12-Sektion: Z. nach §5.11-Ende (nach Z. 320); §7-Bullet Z. 376; §8-AD-17d Z. 387, A0-15 Z. 389; Revisionslog nach Z. 416.wiki/log.md— append (append-only, Vertrag §5): Story-3.6-Eintrag (Verankerung, Sandbox-Nachweis, Statuswechsel, Validator-Verdikt); bestehende Bullets unverändert._bmad-output/implementation-artifacts/sandbox-3-6/run-sandbox.sh— neu (re-executierbar, Muster sandbox-3-5, Exit 0): Szenarien STALE-1..STALE-6 (s. Design Notes), harte Pass/Fail-Assertionen, Erhaltungs-Invariante erzwungen, keine Berührung des realen Ist-Baums._bmad-output/implementation-artifacts/sprint-status.yaml— mutiert:3-6-…backlog→in-progress;last_updated(FormatMM-DD-YYYY HH:MM, HEAD-Präzision)._bmad-output/implementation-artifacts/deferred-work.md— append: erneut aufgreifen der vier Story-3.5-Defers Home 3.6 (holder_id, baseline_commit, Registry-Akkumulator, git-stash) + ggf. neue Story-3.6-Defers._bmad-output/implementation-artifacts/epic-3-context.md,spec-3-5-…md— read-only (continue-context; die epics-/spec-3-5-acme-Kette unverändert).
Tasks & Acceptance
Execution:
schema/compiler.md-- §5.12 einfügen (§5.11 Pkt. 1/7 + §7 + §8 + Revisionslog-3.1 + Abschlussklausel); Wortlaut nur, kein neuer Prädikat-/Format-Keyschema/compiler.md-- Revision 3.1 in §8 belegen (Anker-Zahlen + Abschlussklausel) und §5.11-/§7-Verweise §5.12-wortgleich_bmad-output/implementation-artifacts/sandbox-3-6/run-sandbox.sh-- Szenarien STALE-1..6 + Erhaltungs-Invariante (vertraut auf §5.9-Pkt.-5-Probe-Muster), Exit 0_bmad-output/implementation-artifacts/deferred-work.md-- vier Story-3.5-Defers Home 3.6 als aufgegriffen markieren + ggf. neuewiki/log.md-- (Implementierung) Story-3.6-Eintrag,sprint-status.yaml→ in-progress; Review-Abschlussdoneim Review-Schritt (Workflow-Konvention)
Acceptance Criteria:
- Given ein abgebrochener Run, when uncommittete Leases hinterlassen wurden, then gelten sie als stale (TTL plus Lease-Registrierung im Clone-Root-State), blockieren keine nachfolgenden Runs, und
raw/bleibt Zugriffs-/Consistency-Basis (AD-17d, A0-15; AC-1/AC-2/AC-4). - Given ein neuer Run, when er eine verwaiste Lease vorfindet, then kann er sie übernehmen oder als stale markieren und protokollieren (AC-3; Alt-Branch nie gelöscht, AD-17e).
- Given ein Story-3.5-Defer mit Home 3.6, when umgesetzt, then ist der Story-3.5-Defer-Bezug nachgezeichnet (holder_id/baseline_commit/Registry-Akkumulator/git-stash; Defer-
### Aufgegriffen-Block-append).
Spec Change Log
Noch leer — wird von step-04 während der Review-Loops befüllt (append-only Konvention).
- Review-Loop 1 (2026-08-19, Step-04-Review, 3 Layer, kein Loopback; review_loop_iteration bleibt 0): Stapel Autofix-Patches — Terminologie-Inversion „jünger→älter" (§5.12 Pkt. 1/3/6 + §8-Revisionslog-3.1-Text + log.md + Spec-Design-Notes; Gen kleiner = älter, ältere/niedrigere Erzeugungs-Generation = stale), Generations-Quellen-Präzedenz deterministisch gepinnt (§5.12 Pkt. 1: committeter
lease-granite-root-Marker gewinnt, sonstlease/-Baumableitung, sonst Startwertgen = 0), STALE-1-kern generationen-basiertes TTL gegen dieselbeid(HOLD→stale→Akquise), STALE-3-Re-Akquise nach Stale-Markierung, STALE-5-Same-id-A/B (aktiv verweigert / stale-Markierung erlaubt), holder_id-genuine Ableitung (STALE-2), baseline_commit-Merge-Base-Diskrepanz real (Descendant-Commit,git merge-basegewinnt), STALE-4-lesender-raw/-Bind (Zugriffs-/Consistency-Basis, aufgelösteraw/-Ressourcen-Referenz), Marker-Idempotenz-Regex, STALE-6-Full-State-Invariante (Registry/Lockfiles/Lease-Branches/log.md SHA-256 byte-identisch), log_bullet-Datumsgruppen-Konvention; 1 neuer Defer (Branch-Ref-Schicksal nach Übernahme/Stale-Markierung → deferred-work.md). Sandbox re-executiert: Exit 0, 12 harte PASS; AD-3-Readonly +wiki/-Scope nurwiki/log.mdverifiziert; alle Schritte der## Verification-Sektion re-ausgeführt.
Design Notes
Warum §5.12 als eigene Sektion, nicht §5.11-Erweiterung? §5.11 (3.5) ist strikt committed-state-deterministisch (AD-17h) und hält das Seam-Kriterium S-1 explizit fest — 3.6 verlässt den committeten Zustand (Zeit-/Umgebungs-Zustands-Frage). Das nicht als Punkt an §5.11 anzuhängen, sondern als Eigen-Sektion zu verankern, spiegelt die gekoppelte Abschlussklausel (kein Leasing-Scope, Staleness → Story 3.6) und hält §5.11 als Denk-Basis des Reviews erreichbar.
Zeit ohne Wanduhr zwingend? (Beste alternative Bestätigung der Voranalyse): AD-17d nennt als erste Option „TTL + registration of the lease in the clone-root state". Wall-clock-TTL ist deterministisch unhaltbar (AD-17h/A0-19: identische Artifakte bei gleichem Git-State). A0-20 lebt die at-Notation als dokumentierendes Konzept (Master-Satz generated.at), nicht als steuerndes Leasing-Element; der at-Handoff wäre Ask-First. Deshalb: generationen-basiert — die Registrierung trägt einen monotonen Run-Generator (ein Highlight-generation-Zähler je Clone-Root, aus lease/-Baumableitung oder einem Mono-Commit-lease-granite-root-Marker), ein Run älterer (geringerer) Erzeugungs-Generation gilt als stale (TTL-Ablauf-Äquivalent, Gen kleiner = älter, §5.12 Pkt. 1), ohne Wanduhr.
Der Story-3.5-Seam (S-1) bleibt unbewegt: „3.5 = committed-state-deterministisch, 3.6 = Zeit-/Umgebungs-Zustands-Frage (TTL-Ablauf, verwaiste/hängende Leases, Registrierung, raw/-Recovery)". §5.12 greift ihn auf, ohne ihn zu ändern — die Review-Layer prüfen die Fuge.
Defer-Handoff (exakter Pfad): vier Einträge deferred-work.md (Z. 420–437, Home Story 3.6): holder_id-Quelle (→ §5.12 Pkt. 2, deterministischer Default), baseline_commit-Merge-Base-Diskrepanz-Regel (→ §5.12 Pkt. 4, Vereinheitlichung), Sandbox-log-Akkumulator (→ §5.12 Pkt. 6, cumulative über Runs; kein eigener # Log-Stand), native git stash-Variante (→ §5.12 Pkt. 5-Recovery, als Sandbox-Doppel abgebildet). Neu-Defers möglich.
Sandbox (STALE-1..STALE-6, bash run-sandbox.sh, Exit 0):
- STALE-1: abgebrochener Run erzeugt Lease + Registrierung ohne Release; nachfolgender Run findet sie → stale, kein Blockade-fail
- STALE-2: verwaiste Lease übernehmen (± Merge-Base-Prüfung), Übernahme protokolliert
- STALE-3: verwaiste Lease als stale markieren (Registry-Marker), Blockade aufgehoben,
log.md-Eintrag - STALE-4:
raw/-Recovery-Basis — Ablauf, derraw/-Inhalte unveränderlich lässt (Assertion), Konsistenz belegt - STALE-5: Registrierungs-Invariante (Gen vollständig, höchster-Reg-Invariant) — Verwaiste Kanten nie gelöscht, HOLD-Gegen-HEAD deterministisch
- STALE-6: Determinismus Zwei-Run (AD-17h/A0-19) — gleicher Baum-Input → identische Registrierungs-/Markierungs-Outputs
(Code-/Zahlgenauigkeiten: Die obigen Szenario-Labels sind Fixierung der I/O-Matrix; die Implementierung trägt die harten Assertionen in der Sandbox.)
Verification
Commands (re-executierbar, ab Workspace-Root):
bash _bmad-output/implementation-artifacts/sandbox-3-6/run-sandbox.sh— expected: STALE-1..STALE-6 harte PASS/Fail, Erhaltungs-Invariante erzwungen, Exit 0.grep -n "§5.12\|Revision 3.1" schema/compiler.md— liefert §5.12-Sektion + Revisionslog-Eintrag;grep -n "Lease-Staleness & Recovery-Basis" schema/compiler.md— die §5.12-Überschrift wortgleich (inkl. §5.11-Pkt.-7-Seam-Satz „Lease-Staleness/Recovery … TTL, Lease-Registrierung, verwaiste Leases,raw/-Recovery").- Read-only (AD-3):
git status --porcelainzeigt keinen Change anschema/validator.md/schema/wiki-compiler.md/adapters//raw/. - Validator-Lauf: alle
wiki/-Dateien SUCCESS (unverändert, keine Inhalts-Mutation). - Auf den
wiki/-Scope begrenzt (git status --porcelain -- wiki/): ausschließlichwiki/log.md(dieser Eintrag) — Erhaltungs-Invariante §5.9 Pkt. 5 gewahrt;sprint-status.yaml/deferred-work.md/sandbox-3-6/liegen außerhalbwiki/und sind nicht Teil der Diff-Probe (wie §5.9 Pkt. 5-Doku, Story-3.5-Präzedenz).
Zu beachten (beim step-04-Review): (a) §5.11 Pkt. 1 „verbleibt bis Story 3.6" und Pkt. 7-Seam S-1 (sowie §7-Bullet) müssen textuell unverändert bleiben, wenn §5.12 auf sie verweist (Haltbarkeits-Fuge); (b) raw/-Berührung ist auf Sandbox-Evidenzwege beschränkt (kein realer Ist-raw/-Beweis nötig); (c) die vorhandene §8-Revisionslog-Umsetzungsnummer ist Revision 3.0 (Story 3.5); die Spec--Change-Log-Notiz „§8-Revision 3.1" der Story 3.5 (Review-Loop-1-Fix) wurde nicht real als eigener Revisionslog-Eintrag übernommen (compiler.md-Revisionslog enthält keine Revision 3.1; grep-verifiziert) — Revision 3.1 ist für Story 3.6 frei.
Suggested Review Order
- §5.12-Leasing-Staleness-Sektion (
schema/compiler.md§5.12, nach §5.11 vor §6): 7 Punkte — Registrierung & generationenbasiertes TTL (Pkt. 1, Quellen-Präzedenz-Marker/Baum/Startwert), holder_id (Pkt. 2), Verwaist-Klassifikation (Pkt. 3), Merge-Base-Diskrepanz (Pkt. 4),raw/-Recovery & git stash (Pkt. 5), Registry-Invariante (Pkt. 6), log.md-Pflicht & Determinismus (Pkt. 7). - §7/§8-Nachweis (
schema/compiler.md): §7-Leasing-Enum-Bullet „Lease-Staleness/Recovery — in §5.12 verankert (Story 3.6)" (Vorbehalt aufgelöst, §5.11-Rückverweis unverändert); §8-Normreferenzen AD-17d/A0-15 „(Lease-Staleness, §5.12)"; §8-Revisionslog Revision 3.1 mit Abschlussklausel. - Sandbox-Nachweis (
_bmad-output/implementation-artifacts/sandbox-3-6/run-sandbox.sh): STALE-1..STALE-6, harte PASS/Fail-Assertionen, Erhaltungs-Invariante §5.9 Pkt. 5 — re-executierbarbash run-sandbox.sh→ Exit 0, 12 PASS. - Story-Protokoll/Defers (
wiki/log.md→done-Eintrag;_bmad-output/implementation-artifacts/sprint-status.yaml→3-6: done;deferred-work.md→ 4 aufgegriffene Story-3.5-Defers + 1 neuer Story-3.6-Defer (Branch-Ref-Schicksal)).