13 KiB
title, type, created, status, baseline_commit, review_loop_iteration, context
| title | type | created | status | baseline_commit | review_loop_iteration | context |
|---|---|---|---|---|---|---|
| Story 3.11 — Root-Scope-Leasing atomar und worktree-übergreifend akquirieren | feature | 2026-08-21 | done | a8b486d0f0 |
0 |
Intent
Problem: Die in schema/compiler.md §5.11/§5.12 verankerte Lease-Akquise ist eine nicht-atomare check-then-act-Operation auf einem Arbeitsbaum-Lockfile (lease/<area>/<id>.lock oben geprüft, unten per >-Write überschrieben) und wird bisher nur in sequenzieller Isolation erprobt. Ein TOCTOU-Race ist möglich: zwei Producer mit verschiedenen Run-IDs können denselben Root-Scope gleichzeitig „erwerben", weil die Run-ID Teil des Exklusivitätsschlüssels (Lockfile-Pfad + Branch-Name) ist. Der von AD-17b/A0-13 geforderte „genau ein scope-bezogener Lock im clone-geteilten Zustand" ist weder in §5.11 verankert noch durch einen realen Zwei-Worktree-/Zwei-Prozess-Test belegt (epic-3-context Z. 41, Zielzustand P-11).
Approach: §5.11 in Revision 3.6 um einen präzisierenden Abschnitt ergänzen: der Exklusivitätsschlüssel wird ein einziger, scope-bezogener Lock im clone-geteilten Zustand des Repos (geteilter Git-Ref-/Objektnamespace aller Worktrees und Prozesse eines Clones); die Run-ID ist Lock-Inhalt statt Schlüsselbestandteil; die Akquise erfolgt atomar (create-only: zweite Akquise schlägt fehl, ohne den Lock zu berühren). Eine neue Sandbox führt einen realen, zeitlich überlappenden Zwei-Worktree-/Zwei-Prozess-Test mit Zwischenzustands-Assertions aus und weist nach, dass niemals zwei aktive Root-Leases gleichzeitig existieren und der unterlegene Producer LEASE_HOLD erhält.
Boundaries & Constraints
Always:
- Fugen-Identität: Branch-Form
lease/<area>/<id>(§5.11 Pkt. 1), Lockfile-Pfadlease/<area>/<id>.lockund dessen Feld-Satz bleiben bestehen; Root-Scope-Umfang §5.11 Pkt. 2 (wiki/inkl.log.md,index.md, aller Root-Dateien; kein Bereich jenseitswiki/) bleibt unverändert. - Fugen-Identität: AD-17a/17b-Spine-Wortlaut, A0-12/A0-13-Kurzbeschreibungen, §5.12-Anker (Registry im Clone-Root-State bzw.
lease-granite-root-Marker, Gen-Invariante, kein Wanduhr/Zeitstempel A0-20) und die bestehende §5.11-Pkt.-1-Lease-Hold-Semantik bleiben unverändert maßgeblich. - Der Exklusivitätsschlüssel ist der scope-bezogene Lock im clone-geteilten Zustand; die Run-ID ist Lock-Inhalt und nicht Teil des Schlüssels (AC-a).
- Die Akquise ist atomar (create-only): genau ein Gewinner; der Abgewiesene erhält
LEASE_HOLD, überschreibt nichts, erzeugt keinen Compilation Commit, entfernt keine fremde Lease (AC-b/c). - Kein textueller Auto-Merge (AD-17c); ungleiche Änderungen am selben Concept-Pfad werden als strukturierter Kollisions-Hold mit beiden Commit-Hashes an Epic 4 übergeben (AC-e). Commit-Boundary = Mutations-Boundary (AD-17f), log.md-Eintragspflicht (Vertrag §5).
- Schema read-only (AD-3):
schema/validator.md,schema/wiki-compiler.md,adapters/,raw/bleiben unverändert; kein neuer Frontmatter-Key, keine neue §7-Invaliditätsklasse, kein Standalone (D-3).
Ask First:
- Falls das gewählte atomare create-only-Primitiv im geteilten Git-Refnamespace (z. B.
git update-ref <ref> <wert> $ZERO_SHA, create-only) auf der Ziel-Plattform (Windows/Git-Bash) nicht zuverlässig atomar belegbar ist, HALT und alternative Primitiv-Auswahl zur Autorisierung vorlegen.
Never:
- Kein Umschreiben des bestehenden §5.11-Pkt.-1/2-Wortlauts — nur additive Präzisierung (Revision 3.6); keine Änderung der Root-Scope-Umfangssemantik.
- Keine Wanduhr-/Systemzeit in der Akquise (A0-20); keine Staleness-/Recovery-Logik (bleibt Story 3.6/3.12).
- Keine Verwaist-/Stale-Behandlung, kein Lease-Branch-Lifecycle nach Übernahme (bleibt Story 3.12).
- Keine Mutation des realen Bundles oder
raw/durch die Sandbox; keine Schein-Parallelität (zwei disjunkte Repos oder Zeitversatz ohne Überlappung beweisen keine Atomarität).
I/O & Edge-Case Matrix
| Scenario | Input / State | Expected Output / Behavior | Error Handling |
|---|---|---|---|
| AKQUISE_GEWINNER | scope-frei; Worktree 1 akquiriert Root-Scope | genau ein scope-bezogener Lock mit Inhalt = Run-ID von Worktree 1 | N/A |
| AKQUISE_ABGEWIESEN | scope-Lock bereits von anderer Run-ID (anderer Worktree) gehalten | LEASE_HOLD; wiki/ und Lock unverändert; kein Compilation Commit; fremde Lease bleibt erhalten |
abgewiesener Producer beendet sauber mit LEASE_HOLD |
| AKQUISE_GLEICHZEITIG | zwei Prozesse in getrennten Worktrees, zeitlich überlappende Akquise | Zwischenzustands-Assertions: niemals zwei aktive Root-Leases gleichzeitig; genau ein Gewinner | Verlierer erhält LEASE_HOLD |
| KOLLISIONS_HOLD | zwei Branches mit ungleichen Änderungen am selben Concept-Pfad | kein textueller Auto-Merge; strukturierter Kollisions-Hold mit beiden Commit-Hashes an Epic 4 | Hold-Struktur statt Merge |
Code Map
schema/compiler.md§5.11 (Z. 304–321) / §5.12 (Z. 323–342) / §7 / §8 (Rev. bis 3.5) -- der normativ zu ergänzende Instruktions-Ort: neue Präzisierung als Abschnitt nach §5.12 (Revision 3.6); Pkt.-1/2-Wortlaut und Rückverweise (Z. 321 Seam, §7, §8) bleiben Fugen-Identität._bmad-output/implementation-artifacts/epic-3-context.mdZ. 41 -- „Zielzustand (Review-Loop-3, P-11)": zu schließender Ist/Soll-Abstand; nach Verankerung auf Ist-Zustand aktualisieren._bmad-output/implementation-artifacts/sandbox-3-5/run-sandbox.sh-- nicht-atomareakquire()(check-then-act) und L1/L2/L5-Szenarien: Ableitungspflicht des neuen atomaren Lock-Modells._bmad-output/implementation-artifacts/sandbox-3-6/run-sandbox.sh-- Registry-/Gen-Mechanik im Clone-Root-State,isolate()(Z. 97–104); Zwei-Worktree-Erweiterung muss Gen-Invariante und Registry erhalten._bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.shZ. 249–251 --git worktree add-Präzedenz über einem Baseline-Commit (bisher strikt sequenziell; Konkurrenz ist die 3.11-Neuheit)._bmad-output/implementation-artifacts/sprint-status.yamlZ. 64 -- Story-Key3-11-root-scope-leasing-atomar-akquirieren: backlog→ review.wiki/log.md-- Revisions-/Lauf-Nachweis der Verankerung.
Tasks & Acceptance
Execution:
schema/compiler.md-- neuen Präzisierungs-Abschnitt (Revision 3.6) nach §5.12 ergänzen: atomarer scope-bezogener Lock im clone-geteilten Zustand (create-only, Run-ID als Lock-Inhalt statt Exklusivitätsschlüssel),LEASE_HOLD-Semantik, Kollisions-Hold mit beiden Commit-Hashes an Epic 4; bestehende Pkt.-1/2 und §5.12 unverändert lassen; §7-Rückverweis und §8-Revisionslog ergänzen -- §5.11-Präzisierung (Story-3.11-Rationale)._bmad-output/implementation-artifacts/sandbox-3-11/run-sandbox.sh-- neue re-executierbare Sandbox: echte Zwei-Worktree-/Zwei-Prozess-Überlappung (git worktree addüber einer Baseline), atomare Akquise mit Zwischenzustands-Assertions (niemals zwei aktive Root-Leases),LEASE_HOLD-Fälle inkl. Nicht-Mutation des Arbeitsbaums, Kollisions-Hold mit beiden Commit-Hashes; Exit 0, harte PASS/FAIL; berührt reales Bundle/raw/nicht -- Tests der I/O-Matrix und der 5 ACs._bmad-output/implementation-artifacts/sprint-status.yaml-- Key3-11-root-scope-leasing-atomar-akquirierenaufreview-- Status-Sync des fertigen Drafts.wiki/log.md-- Revisions-Nachweis (Verankerung + Sandbox-Lauf) -- Vertrag §5-Eintragspflicht._bmad-output/implementation-artifacts/epic-3-context.md-- Z. 41-Zielzustand auf Ist-Zustand aktualisieren -- Planungsartefakt nachführen.
Acceptance Criteria:
- Given der Root-Scope
wiki/im clone-geteilten Zustand, when ein Producer eine Lease akquiriert, then existiert genau ein scope-bezogener Lock und die Run-ID ist Lock-Inhalt und nicht Teil des Exklusivitätsschlüssels. - Given zwei Producer mit verschiedenen IDs und getrennten Worktrees, when beide denselben Root-Scope akquirieren, then ist die Akquise atomar und genau ein Producer erhält die Lease; der andere erhält
LEASE_HOLD. - Given ein abgewiesener Producer, when die Akquise fehlschlägt, then verändert er weder
wiki/noch den bestehenden Lock, erzeugt keinen Compilation Commit und entfernt keine fremde Lease. - Given ein realer Zwei-Worktree-/Zwei-Prozess-Test mit zeitlich überlappender Akquise, when die Läufe ausgeführt werden, then beweisen Zwischenzustands-Assertions, dass niemals zwei aktive Root-Leases gleichzeitig existieren.
- Given zwei Branches mit ungleichen Änderungen am selben Concept-Pfad, when eine Kollision erkannt wird, then wird nicht automatisch textuell gemerged, sondern ein strukturierter Kollisions-Hold mit beiden Commit-Hashes an Epic 4 übergeben.
Spec Change Log
Design Notes
Der Lock muss im clone-geteilten Zustand liegen, weil nur dieser Zustand von allen Worktrees und Prozessen eines Clones gemeinsam gesehen wird: Arbeitsbaum-Lockfiles (lease/<area>/<id>.lock) sind clone-lokal und laden zur nicht-atomaren check-then-act-Akquise ein. Der geteilte Git-Ref-/Objektnamespace bietet dagegen ein natürlich atomares create-only-Primitiv (gits eigene Ref-Sperre, z. B. git update-ref <ref> <wert> 0000…0000, schlägt fehl, sobald der Ref existiert); zwei Worktrees desselben Repos streiten damit serialisiert um denselben Lock. Der Schlüssel ist der Scope (ein Ref pro wiki/), der Inhalt die Run-ID — genau die AC-a-Aussage. Die bisherige <id>-Schlüssigkeit (§5.11 Pkt. 1) bleibt als per-Lease-Ablage bestehen, trägt aber keine Exklusivität mehr allein.
Verification
Commands:
bash _bmad-output/implementation-artifacts/sandbox-3-11/run-sandbox.sh-- expected: alle Szenarien harte PASS (u.a. „niemals zwei aktive Root-Leases"-Assertion,LEASE_HOLD-Reihenfolge), Exit 0, kein Zugriff auf reales Bundle/raw/.grep -n "3.11\|3.6" schema/compiler.mdundgrep -n "Revision 3.6"-- expected: neuer Abschnitt und Revisionslogeintrag vorhanden; bestehende Pkt.-1/2-Texte unverändert (diff checkt nur additive Zeilen).git -C _bmad-output diffvs.git -C schema/compiler.md diff-- expected: nur additive Änderung anschema/compiler.md;validator.md/wiki-compiler.md/adapters//raw/ohne Diff.
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.17-Atomaritäts-Präzisierung — Exklusivitätsschlüssel im clone-geteilten Zustand, Run-ID als Lock-Inhalt, create-only-Akquise, LEASE_HOLD, Kollisions-Hold an Epic 4 (AC-a..e).
compiler.md:415 - Abgrenzungsklausel der Story-3.11-Verankerung — Fugen-Identität von §5.11-Pkt.-1/2 und §5.12 bleibt erhalten, keine neue §7-Klasse, kein Standalone.
compiler.md:527
Atomarer Lock im clone-geteilten Zustand
- Atomare create-only-Akquise (
git update-ref <lock-ref> <wert> $ZERO_SHA) — gits Ref-Sperre serialisiert Worktrees/Prozesse; deterministischer Blob-Inhalt.run-sandbox.sh:120 - Zwei-Prozess-Überlappung im Zwei-Worktree — Schlüssel-Beweis AC-b/AC-d (genau ein Gewinner, ein LEASE_HOLD, Zwischenzustands-Sampler).
run-sandbox.sh:207
Kollisions-Hold & Abweisung
- LEASE_HOLD-Nicht-Mutation: abgewiesener Producer lässt
wiki//Lock/log.mdunverändert, keine Commits, fremde Lease erhalten (AC-c) — inkl. gehärteterlog.md-Assertion.run-sandbox.sh:292 - Kollisions-Hold mit beiden Commit-Hashes + Scope in
log.mdan Epic 4 (AC-e, AD-17c, kein textueller Auto-Merge) — Datei-Level-Attest nachgeschärft.run-sandbox.sh:362
Status- & Nachweissynchronisation (peripher)
- Revisionsnachweis Story 3.11 →
reviewin der Laufzeitakte — Verankerung, Sandbox, Abschlussklausel, Erhaltungs-Invariante.log.md:47 - Planungsartefakt auf Ist-Zustand nachgeführt (epic-3-context Z. 41).
epic-3-context.md:41
Härtung & Konsistenz-Funde (defer)
- Konsistenz-, Drift- und Härtungs-Funde aus der Review in der Defer-Liste festgehalten (AC-d-Token, Zeilenanker, dynamische Negativ-Kontrolle, Platzhalter-Banner).
deferred-work.md:577