2 Commits
4 changed files with 362 additions and 13 deletions
@@ -17,3 +17,47 @@ Noch nicht adressierte, aber real erkannte Arbeit — gesammelt aus Reviews. Ein
- source_spec: `_bmad-output/implementation-artifacts/spec-1-2-sources-lokal-unter-raw-bereitstellen.md` - source_spec: `_bmad-output/implementation-artifacts/spec-1-2-sources-lokal-unter-raw-bereitstellen.md`
summary: Asset-Zuordnung (roh-`assets/` vs. `<quelle>/assets/`) in der Konvention festlegen. summary: Asset-Zuordnung (roh-`assets/` vs. `<quelle>/assets/`) in der Konvention festlegen.
evidence: Blind-Hunter-Review (Finding 14): README nennt „einer Quelle zugeordnet oder global"; die aktuellen Sources nutzen nur global `raw/assets/`. evidence: Blind-Hunter-Review (Finding 14): README nennt „einer Quelle zugeordnet oder global"; die aktuellen Sources nutzen nur global `raw/assets/`.
- source_spec: `_bmad-output/implementation-artifacts/spec-1-3-okf-schema-vertrag-schema-wiki-compiler-md-autorisieren.md`
summary: Existenzprüfung eines `sources`-`resource`-Pfads (für Validity-Zwecke MUSS die `raw/`-Datei am Validierungszeitpunkt materialisiert vorliegen).
evidence: Edge-Case-Review (EC-1): ein `resource` unter `raw/`, das nicht existiert, würde als Provenienz akzeptiert; der Compiler konsumiert fehlende Evidenz. Validator-Verhalten (Story 1.4), nicht Schema-Text.
- source_spec: `_bmad-output/implementation-artifacts/spec-1-3-okf-schema-vertrag-schema-wiki-compiler-md-autorisieren.md`
summary: Kalender-Validität der Datumsfelder (`last_modified`, `stale_after`, `generated.at`/`verified.at`) — Phantom-Daten wie `2025-02-30` müssen abgelehnt werden.
evidence: Edge-Case-Review (EC-3): reines Regex-Matching (`YYYY-MM-DD`) akzeptiert nicht existierende Kalenderdaten. Validator-Detail (Story 1.4).
- source_spec: `_bmad-output/implementation-artifacts/spec-1-3-okf-schema-vertrag-schema-wiki-compiler-md-autorisieren.md`
summary: Operative Konsequenz von `stale_after` festlegen (Lifecycle-Übergang, Nutzungssperre als `sources`-Ziel o. ä.).
evidence: Blind-Hunter (BH-8): §3.7 definiert nur die Veraltungsschwelle, nicht was ein veraltetes Concept bedeutet; die Folgeentscheidung gehört in Story 1.4/Lifecycle (Epic 3).
- source_spec: `_bmad-output/implementation-artifacts/spec-1-3-okf-schema-vertrag-schema-wiki-compiler-md-autorisieren.md`
summary: `sources`-`id`-Eindeutigkeit (je `resource` bzw. je Concept) für zuverlässige per-Claim-Zitat-Attribution festlegen.
evidence: Blind-Hunter (BH-13): §3.3 motiviert `id` für Attribution, ohne Eindeutigkeit/Scoping zu fordern; Claim-granulare Provenienz (A0-3) wird in Epic 2 konkretisiert.
- source_spec: `_bmad-output/implementation-artifacts/spec-1-3-okf-schema-vertrag-schema-wiki-compiler-md-autorisieren.md`
summary: Verhalten nicht-Markdown-Dateien im Bundle (z. B. Bilder/Assets unter `wiki/`) definieren — Ablehnung oder Konvention.
evidence: Edge-Case-Review (EC-11): der Vertrag regelt nur `.md`-Dateien; ein `wiki/<area>/logo.png` hat keinen definierten Status. Structural-Seed-/Validator-Frage (Story 1.4).
- source_spec: `_bmad-output/implementation-artifacts/spec-1-3-okf-schema-vertrag-schema-wiki-compiler-md-autorisieren.md`
summary: Exakte ISO-8601-Form für `generated.at`/`verified.at` festlegen (z. B. `YYYY-MM-DDTHH:MM:SS(Z|±HH:MM)?`, reine Datumsangaben zulässig?).
evidence: Blind-Hunter (BH-14)/Edge-Case-Review (EC-7): „ISO-8601-Datetime" lässt den Validator-Spielraum; Story 1.4 muss eine Normalform bestimmen, um Run-Determinismus zu sichern.
- source_spec: `_bmad-output/implementation-artifacts/spec-1-3-okf-schema-vertrag-schema-wiki-compiler-md-autorisieren.md`
summary: Normalisierung von `sources: []`/`verified: []` vs. Absenz für deterministische Ausgabe-/Diff-Baselines klären.
evidence: Edge-Case-Review (F2, Loop 2): beide Formen sind laut Vertrag gültig und semantisch gleichwertig; NFR-4 („sinnvolle Diffs") bleibt unterdeterminiert. Normierungsentscheidung des Compilers/Validators — Story 1.4.
- source_spec: `_bmad-output/implementation-artifacts/spec-1-3-okf-schema-vertrag-schema-wiki-compiler-md-autorisieren.md`
summary: Trust-Semantik von `generated.by` mit `human:`-Präfix festlegen (Person als Generator vs. „human-reviewed"-Klassifikation).
evidence: Edge-Case-Review (F15, Loop 2): `generated.by: human:michael` ohne `verified` ist formzulässig, aber die Trust-Klassifikation (nicht-human-reviewed trotz `human:` in `generated.by`) ist für Leser missverständlich. Für Story 1.4/Epic 4 (Trust-Metadaten) klären.
- source_spec: `_bmad-output/implementation-artifacts/spec-1-3-okf-schema-vertrag-schema-wiki-compiler-md-autorisieren.md`
summary: Reihenfolge/atomare Kopplung von `log.md`-Eintrag (AD-16b) und `status`-Mutation (Deprecation) in denselben Compilation Run festlegen.
evidence: Edge-Case-Review (F5, Loop 2): `status: deprecated` erfordert einen `log.md`-Disagreement-Eintrag; der Vertrag regelt nicht die atomare Kopplung dieser zwei Bundle-Mutationen. AD-16/Story 4.2/Compiler-Verhalten.
- source_spec: `_bmad-output/implementation-artifacts/spec-1-3-okf-schema-vertrag-schema-wiki-compiler-md-autorisieren.md`
summary: Feingranularität von `log.md` festlegen (leeres Log zulässig? Pflicht der AD-16-Konfliktklassifikation je Eintrag?).
evidence: Edge-Case-Review (F17, Loop 2): §5 definiert Format (Datum + Eintragsliste), aber nicht, ob ein leeres `log.md` gültig ist bzw. ob die Konfliktklassifikation Pflicht-Inhalt je Eintrag ist. OKF §9-Feinheiten für Story 1.4.
- source_spec: `_bmad-output/implementation-artifacts/spec-1-3-okf-schema-vertrag-schema-wiki-compiler-md-autorisieren.md`
summary: Semantische Konsequenz von `stale_after` im Verhältnis zur Validität klären („veraltet" ist kein struktureller Validierungsfehler).
evidence: Edge-Case-Review (F18, Loop 2): §7 zählt die Konsequenz nicht auf; ein vergangenes `stale_after` ist gültiges YAML, aber „veraltet". Lifecycle-Semantik — Story 1.4/Epic 3.
@@ -0,0 +1,123 @@
---
title: 'OKF-Schema-Vertrag `schema/wiki-compiler.md` autorisieren (Story 1.3)'
type: 'feature'
created: '2026-08-14'
status: 'done'
review_loop_iteration: 1
baseline_commit: 4011dc7fc4205164402fd26251e5322042978837
context:
- _bmad-output/implementation-artifacts/epic-1-context.md
---
<frozen-after-approval reason="human-owned intent — do not modify unless human renegotiates">
## Intent
**Problem:** `schema/wiki-compiler.md` ist ein Platzhalter ohne Verbindlichkeit — alle Producer (Compiler, Adapter, Story 1.4-Validator) könnten unterschiedliche OKF-Details annehmen (z. B. `sources`-Form, `log.md`-Format, `status`-Regeln), was Portabilität und deterministische Konformität gefährdet (FR-9, NFR-6).
**Approach:** Den Platzhalter zum autorisierten, verbindlichen OKF-0.2-Schema-Vertrag ausbauen: das erlaubte Feldsubset (inkl. exakter `sources`-Form, `generated`/`verified`, `status`-Policing), `okf_version`-Regel, `log.md`-Typdefinition, Index-Regel, Validitätsprädikate für Concepts/Bundle-Root sowie das Provenienz-Verbot (nie `wiki/`-Pfade) normativ festlegen.
## Boundaries & Constraints
**Always:**
- `schema/wiki-compiler.md` ist der einzige normative Ort für das OKF-Feldsubset, `log.md`-Typ, Index-Regel, Validitätsprädikate und das `sources``raw`-Verbot (A0-1/AD-1a, FR-9, NFR-6).
- `type` ist das einzige Pflichtfeld für Concepts; die Bundle-Root `wiki/index.md` trägt zusätzlich `okf_version: "0.2"` und `type: bundle` (bereits vorhanden, wird normativ fixiert).
- Das Schema-Bindungs-Verbot gilt: `sources`-Einträge lösen ausschließlich auf `raw/`-Pfade oder extern referenzierte immutable Evidenz auf — niemals auf `wiki/`-Concept-Pfade (A0-4/AD-4b).
- Strukturelle OKF-Invalidität schlägt den Compilation Run fehl; fehlende optionale Felder sind nicht invalide (A0-2/AD-1b, F-2).
- In v1 sind nur lokal unter `raw/` materialisierte Sources unterstützt (FR-1, A-4); das Schema lässt dementsprechend keine URL-Form der Sources zu.
- Kein generiertes Concept führt ein anderes generiertes Concept als alleinige Provenienz (A0-5/AD-4c) — Teil der Schema-Validierung.
- Gültige `status`-Werte: `draft` | `stable` | `deprecated` (OKF `slotting`; Absenz ⇒ `stable`-Default wird normativ dokumentiert).
- Dokument in Deutsch; Beispiel-Frontmatter OKF-konform (YAML).
**Ask First:**
- Abweichungen vom normativen OKF-0.2-Standard (PRD §13) — jede bewusste Verschärfung gegenüber OKF 0.2 erfordert menschliche Zustimmung (z. B. falls nur lokal erlaubte Sources als Verschärfung bestätigt werden soll).
**Never:**
- Kein eigener OKF-Dialekt und kein paralleles Schema neben `schema/wiki-compiler.md` (AD-1: nur dieses eine Schema bindet).
- Keine Implementierung des Validators in dieser Story (das ist Story 1.4); keine Umschreibung von `schema/` in einen Executable-Code/Programmcode.
- Keine Änderung an `raw/` (immutable, AD-3) und keine Adapter-Semantik (AD-10).
- Keine Erfindung zusätzlicher Pflichtfelder oder eigener Statuswerte außerhalb OKF-0.2.
## I/O & Edge-Case Matrix
| Scenario | Input / State | Expected Output / Behavior | Error Handling |
|----------|--------------|---------------------------|----------------|
| HAPPY_PATH | `schema/wiki-compiler.md` autorisiert, vollständiger Feldsubset-Vertrag | Vertrag normativ; alle Producer/Adapter lesen dieselben Regeln (FR-9, NFR-6) | N/A |
| OPTIONAL | Concept ohne optionale Felder (nur `type`) | Gültig; nicht abgelehnt (A0-2/AD-1b, F-2) | N/A |
| INVALID | `sources`-Eintrag zeigt auf `wiki/`-Concept-Pfad | Schema markiert dies als nicht konform (A0-4/AD-4b) | Klare textuelle Fehlerursache (NFR-4) |
| CONFLICT | Zwei Producer interpretieren `sources`-Form unterschiedlich | Schema legt exakt eine Form fest (Liste von Maps) | N/A |
</frozen-after-approval>
## Code Map
- `schema/wiki-compiler.md`**Zieldatei**: Platzhalter → autorisierter Verbindlicher Vertrag (A0-1/AD-1a); erzwingt Feldsubset, `log.md`-Typ, Index-Regel, Validitätsprädikate, `sources``raw`-Verbot.
- `wiki/index.md` — Bundleroot (exists): `type: bundle`, `okf_version: "0.2"`, keine weiteren Field-Subsets; dient als Referenz für Bundle-Root-Prädikat.
- `wiki/log.md` — leer; strukturelle Vorlage (kein Frontmatter, reservierter Name); Typdefinition im Schema.
- `raw/prd/prd-wow20-2026-08-14.md` — normative Quelle: FR-9, NFR-6, §13 OKF-0.2-Referenz (nur lesen).
- `raw/architecture-spine/architecture-spine-2026-08-14.md` — AD-1a/1b, A0-1/A0-2/A0-4/A0-5, D-10, Structural Seed (nur lesen).
- `raw/epics/epics-2026-08-14.md` — A0-1…A0-20-Subset-Formulierungen (nur lesen).
- `_bmad-output/implementation-artifacts/spec-1-2-...md` — Continuity: `raw/`-Konvention & artefact/evidence-Grenze (nur lesen).
## Tasks & Acceptance
**Execution:**
- [x] `schema/wiki-compiler.md` — Platzhalter-Status in einen autorisierten Vertrag umwandeln; normativ festlegen: Feldsubset (Pflicht/optional), exakte `sources`-Form (Liste von Maps), `generated`/`verified`-Zulässigkeit, `status`-Werte & Default, `stale_after`, `okf_version`-Regel, `log.md`-Typdefinition, Index-Regel (jede Area hat `index.md`), Validitätsprädikate für Concepts und Bundle-Root, Provenienz-Verbot, strukturelle-Invalidität-vs.-Optimalität-Regel — AD-1a/A0-1, FR-9, NFR-6.
- [x] `schema/wiki-compiler.md` — Bundleroot-Regel: `okf_version: "0.2"` nur in `wiki/index.md` (nicht in Area-`index.md`); Area-`index.md` trägt kein Frontmatter — AD-1, AD-9.
- [x] `schema/wiki-compiler.md` — Determinismus der Provenienz-Ziellinie: `resource`-Pfade sind relative Workspace-Pfade unter `raw/`, `..`-Traversale (die aus `raw/` hinausweist) ist unzulässig; die Auflöse-Regel ist Teil der Validitätsprädikate — AD-4b/A0-4.
- [x] `schema/wiki-compiler.md` — Orthogonalität von `status` und Trust: `status`-Policing (`draft`|`stable`|`deprecated`, Absenz ⇒ `stable`) und `verified`-Status sind unabhängige Dimensionen; ein nicht-human-reviewtes Concept ist nicht deshalb nicht-`stable` — AD-15/A0-20.
- [x] `schema/wiki-compiler.md` — A0-5/AD-4c unter v1: da `sources` in v1 ausschließlich auf `raw/`-Evidenz zeigt, ist die „keine alleinige Provenienz aus generierten Concepts"-Regel tautologisch erfüllt; als Normreferenz und Wegfall-Option bei späterer Quellenerweiterung dokumentieren, nicht als eigenes Feuerbedingungs-Prädikat.
- [x] `schema/wiki-compiler.md` — Abschluss der Norm: Bundleroot-Frontmatter exklusiv `type`+`okf_version` (und `type: bundle` nur in Bundleroot); frontmatterlose, nicht-reservierte `.md`-Datei im Bundle = strukturell invalide; `sources: []`/`verified: []` zulässig (semantisch = Absenz); abweichender `okf_version`-Wert (z. B. `"0.3"`) strukturell invalide; Liste struktureller Invalidität abschließend; keine unautorisierten Keys in `sources`/`generated`/`verified`-Einträgen; leere `by`-Angaben verboten; korrekte Abschnitts-Querverweise (§7 Invalidität, §5 `log.md`, §6 Index-Regel, §6.1 Concept-Prädikat); Vertrags-Eigen-Metadaten (Autorisierungsdatum, Revision, autorisierende Story).
**Acceptance Criteria:**
- Given der autorisierte Vertrag, when ein Concept geprüft wird, then ist `type` das einzige Pflichtfeld; `sources`, `generated`, `verified`, `status`, `stale_after` werden als Subset validiert (AD-1a).
- Given ein Concept, when `sources` gesetzt ist, then muss `sources` eine Liste von Maps sein (mit `resource` als einziger Pflicht-Evidenzangabe) — keine Map-/Objekt-Form (AD-4b).
- Given ein `sources`-Eintrag, when er auf einen `wiki/`-Concept-Pfad zeigt, then ist das Bundle strukturell invalide (nie auf `wiki/`-Concept-Pfade, A0-4/AD-4b).
- Given das Schema, when ein neues Area-Verzeichnis in `wiki/` angelegt wird, then bindet es die Index-Regel (jede Area hat `index.md`) und den `log.md`-Typ (AD-1a).
- Given ein Concept mit erlaubten optionalen Feldern aber ohne `sources`/`verified`, when es validiert wird, then ist es nicht strukturell invalide (A0-2/AD-1b: fehlende optionale Felder sind kein Fehler).
- Given die Bundle-Root, when geprüft, then darf `okf_version: "0.2"` nur in `wiki/index.md` stehen; `log.md` folgt der Schema-Typdefinition (AD-1, AD-9).
## Spec Change Log
- **2026-08-15, Loop 1 (bad_spec-Loopback aus Step-04):** Der Review (Blind-Hunter + Edge-Case) fand drei norm-beherrschende Lücken, die die Planung hätte determinieren müssen.
- Trigger: BH-2 (A0-5/AD-4c unter v1 vakant, nicht prüfbar), BH-4/EC-2 (Provenienz-Ziellinie ohne deterministische Auflöse-Basis, `..`-Traversale), BH-7 (`stable`-Default kollidiert mit v1-unverified-Default).
- Amendment (non-frozen Tasks): vier neue Tasks konkretisieren (1) Determinismus der `resource`-Auflösung inkl. `..`-Verbot, (2) Orthogonalität `status`/Trust, (3) A0-5 als v1-tautologisch erfüllt statt eigenem Prädikat, (4) Abschluss der Norm inkl. Frontmatter-Exklusivität, frontmatterlose `.md`-Datei, leere Listen, `okf_version`-Fehlwert, abschließende Invaliditätsliste, verbotene leere `by`, korrekte Querverweise, Vertrags-Eigen-Metadaten.
- Bekannt-bad-State vermieden: Neuerung eines Prädikats, das nie feuert (Intransparenz), undefinierte `resource`-Auflösung (nicht reproduzierbare Kern-AC), stiller Widerspruch `stable` vs. unverified (frisch generierte Concepts als `stable`).
- KEEP (muss bei Re-Derivation überleben): die gesamte Vertragsstruktur §1–§8 (Geltungsbereich, Bundleroot/`okf_version`, Feldsubset-Themen, `sources`-Liste-von-Maps + `raw/`-Ziellinie, `generated`/`verified` inkl. Actor-Konvention und `human:`-Präfix, `log.md`-Typ, Index-Regel, Concept-/Bundle-Root-Prädikate, strukturell-invalid-vs-optional, Normreferenzen); MUSS/SOLL/KANN-Verbindlichkeitsgrade; v1-Default (generated ohne verified).
- **2026-08-15, Loop 2 (Review: Blind-Hunter + Edge-Case-Hunter + Verification-Gap, kein bad_spec):** Die drei Review-Layer fanden keinen norm-beherrschenden Defekt (kein neuer Loopback). Verbleibende Inkonsistenzen wurden als `patch` lokal in den Contract (§7) bzw. die Verification-Sektion (oben) eingearbeitet; Traceability-Ergänzungen (`verified`-Singleton-Coercing, `sources`-Eintrags-Optionalkeys) dokumentieren OKF-0.2-Konformität statt lokaler Erfindung; `log.md`-Position wurde auf die autorisierte Root-only-Position (AD-17b) zurückgeführt. Ergebnis: `schema/wiki-compiler.md` final; der Validator (Story 1.4) implementiert die abschließende 14-Punkte-Invaliditätsliste. Details in `deferred-work.md`.
## Design Notes
Normative Quelle = PRD §13 fixiert OKF-0.2 (SPEC). Das Schema **normativ legt** fest (Story 1.3 autorisiert, Story 1.4 implementiert Validierung):
```yaml
# Concept (Beispiel)
type: concept # Pflichtfeld; einziges Pflichtfeld
sources: # Liste von Maps (keine Map-Form), nur raw/- oder externe Evidenz
- resource: raw/<quelle>/<datei>.md
id: s1 # optional; effizient für Zitat-Attribution
generated: # optional; nur ({by, at}) - by Pflicht innerhalb generated
by: <producer>/<version>
at: <ISO 8601 datetime>
verified: # optional; Liste von {by, at}; human:-Präfix = human reviewed
status: draft # draft | stable | deprecated; Absenz ⇒ stable
stale_after: 2026-12-31 # absolutes Datum YYYY-MM-DD
```
- `okf_version: "0.2"` nur in Bundleroot-`index.md`.; Area-`index.md` trägt **kein** Frontmatter (AD-1/AD-9).
- `log.md`: reservierter Name, kein Frontmatter; flache Liste datumsgruppierter Einträge (neueste zuerst), `YYYY-MM-DD`-Header (OKF §9).
- `sources`-Provenienz: niemals `wiki/`-Pfade (A0-4/AD-4b); externe Evidenz in v1 nur lokal `raw/` (FR-1/A-4).
- Der Vertrag bleibt rein textuell (Markdown), kein executable code (AD-1).
## Verification
**Commands:**
- `git diff --stat` — expected: `schema/wiki-compiler.md`-Erweiterung (Platzhalter→autorisiert); keine `raw/`- und keine `wiki/`-Mutationen (Updates an `_bmad-output/`-Artefakten — Spec, Sprint-Status, Deferred-Work — sind prozessimmanent und erlaubt).
- Manuelle Konformitätsprüfung (Liste-von-Maps-Regel, `raw/`-Pfad-Bindung): `grep -c "Liste von Maps" schema/wiki-compiler.md` (expected: ≥ 1) und `grep -n "raw/" schema/wiki-compiler.md` (expected: Provenienz-Ziellinie & deterministische Auflöse-Basis in §3.3).
- Konformitäts-Smoke-Test an den Referenzdateien (Bundleroot/AC-6): `grep -nE '^type:|^okf_version:' wiki/index.md` (expected: exakt 2 Zeilen `type: bundle` und `okf_version: "0.2"`); `grep -rn "okf_version\|type: bundle" wiki/` (expected: ausschließlich `wiki/index.md`).
- Referenz-Statik des Vertrags: `grep -oE '§[0-9]+(\.[0-9]+)?' schema/wiki-compiler.md` abgleichen gegen die Markdown-Überschriften (expected: alle Verweise zeigen auf existierende Abschnitte; keine toten Verweise).
**Manual checks (if no CLI):**
- `schema/wiki-compiler.md` beginnt mit klarer `Status: autorisiert`-Kennzeichnung (kein „Platzhalter"-Text mehr).
- Alle vier AC-Aspekte (Feldsubset, `sources`-Form, Index-Regel+`log.md`-Typ, Provenienz-Verbot) sind abschnittsweise adressiert.
@@ -29,7 +29,7 @@
# - Dev moves story to 'review', then runs code-review (fresh context, different LLM recommended) # - 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 # - Retrospective appends its action items to action_items; the status view surfaces open ones
generated: 08-14-2026 00:00 generated: 08-14-2026 00:00
last_updated: 08-15-2026 04:56 last_updated: 08-15-2026
project: wow20 project: wow20
project_key: NOKEY project_key: NOKEY
tracking_system: file-system tracking_system: file-system
@@ -38,7 +38,7 @@ development_status:
epic-1: in-progress epic-1: in-progress
1-1-kanonischen-workspace-stamm-erstellen: done 1-1-kanonischen-workspace-stamm-erstellen: done
1-2-sources-lokal-unter-raw-bereitstellen: done 1-2-sources-lokal-unter-raw-bereitstellen: done
1-3-okf-schema-vertrag-schema-wiki-compiler-md-autorisieren: backlog 1-3-okf-schema-vertrag-schema-wiki-compiler-md-autorisieren: done
1-4-schema-validierung-für-bundle-implementieren: backlog 1-4-schema-validierung-für-bundle-implementieren: backlog
epic-1-retrospective: optional epic-1-retrospective: optional
+193 -11
View File
@@ -1,15 +1,197 @@
# Wiki of Wikis — Compiler-Schema-Vertrag (Platzhalter) # Wiki of Wikis — Compiler-Schema-Vertrag (OKF 0.2)
> **Status:** Platzhalter (Story 1.3 «OKF-Schema-Vertrag autorisieren» füllt diesen Vertrag aus und **autorisiert** die folgenden Entscheidungen). Dieser Liste ist eine offene Entscheidungsvorlage, keine normative Festlegung. > **Status:** autorisiert (Story 1.3) — verbindlicher, normativer OKF-0.2-Schema-Vertrag für das Knowledge Bundle.
Hier wird der **verbindliche OKF-0.2-Feldsubset-Vertrag** (AD-1a, A0-1) verankert, den Story 1.3 autorisiert. Zu entscheiden sind: > **Vertrags-Metadaten:**
> - **Autorisierende Story:** Story 1.3 «OKF-Schema-Vertrag `schema/wiki-compiler.md` autorisieren» — Spezifikation: `_bmad-output/implementation-artifacts/spec-1-3-okf-schema-vertrag-schema-wiki-compiler-md-autorisieren.md`
> - **Autorisierungsdatum:** 2026-08-15
> - **Revision:** 1 (Re-Derivation nach Loop-1-Review; Spec Change Log, Loop 1)
- erlaubtes OKF-0.2-Feldsubset`type` als einziges Pflichtfeld; optional `sources`, `generated`, `verified`, `status`, `stale_after`; Dieser Vertrag ist die **einzige normative Quelle** für das erlaubte OKF-0.2-Feldsubset, die exakte `sources`-Form, die Zulässigkeit von `generated`/`verified`, das `status`-Policing, `stale_after`, die `okf_version`-Regel, die `log.md`-Typdefinition, die Index-Regel sowie die Validitätsprädikate für Concepts und Bundle-Root (AD-1a, A0-1, D-10). Er bindet alle Producer (Compiler und Adapter) gleichermaßen und ist die Prüfgrundlage der Schema-Validierung (Story 1.4, AD-1b/F-2/A0-2). Jede inhaltliche Abweichung von diesem Vertrag erfordert eine neue Autorisierung; einzelne Producer dürfen sie nicht vornehmen. Das Schema liegt **außerhalb** des Bundles (`wiki/`) und ist keine Concept-Datei; es ist ein reiner Textvertrag (Markdown) und kein ausführbarer Code (Structural Seed, AD-1).
- Liste-vs.-Map-Form von `sources`;
- Zulässigkeit von `generated`/`verified` und `status`-Policing;
- Typdefinition von `log.md`;
- Index-Regel (jedes Area besitzt eine `index.md`);
- Validitätsprädikate für Concepts und Bundle-Root;
- Bindung des Verbots: `sources`-Einträge lösen niemals auf `wiki/`-Concept-Pfade auf (AD-4b, A0-4).
Das Schema liegt **außerhalb** des Bundles (`wiki/`) und ist keine Concept-Datei (Structural Seed, AD-1). Fachliche Verbindlichkeit: Begriffe wie „MUSS" und „DARF NICHT" sind verbindliche Regeln; Verstöße gelten, sofern hier nicht anders geregelt, als strukturelle Invalidität (§7). „SOLL" ist eine normative Empfehlung, deren Abweichung begründet werden muss. „KANN"/„darf" bezeichnet eine zulässige, aber nicht geforderte Möglichkeit.
## 1. Geltungsbereich
- Dieser Vertrag gilt für alle Markdown-Dateien innerhalb der Bundleroot `wiki/` sowie für die Pfade, auf die `sources`-Einträge von Concepts verweisen.
- Er gilt nicht für `raw/`, `schema/` und `adapters/`: Diese liegen außerhalb des Bundles und sind keine Concept-Dateien (Structural Seed, AD-1).
- Verteilte Regelwerke in `adapters/` MÜSSEN mit diesem Vertrag konform sein und DÜRFEN keine abweichende Knowledge-Semantik definieren (AD-10).
- Der Vertrag bleibt rein textuell; er wird von den konsumierenden Producern als Instruktion und von der Validierung (Story 1.4) als Prüfregelwerk gelesen (AD-1).
## 2. Bundle-Struktur und Bundleroot (`okf_version`-Regel)
- Die Bundleroot ist `wiki/` (AD-1, AD-9). Sie ist das einzige Verzeichnis, das als OKF Knowledge Bundle behandelt wird; `raw/`, `schema/` und `adapters/` sind keine Bestandteile des Bundles.
- Die Bundleroot enthält zwingend eine Datei `wiki/index.md` und — nach Anlage — eine Datei `wiki/log.md` (reservierte Namen; `index.md`-Regeln: §2/§6, `log.md`-Typdefinition: §5). Weitere `.md`-Dateien auf Root-Ebene sind Concepts und unterliegen dem Concept-Prädikat (§6.1).
- `wiki/index.md` MUSS als Bundleroot deklariert sein; ihr Frontmatter ist **ausschließlich** die Bundledeklaration `type: bundle` und `okf_version: "0.2"`:
```yaml
---
type: bundle
okf_version: "0.2"
---
```
Zusätzliche oder abweichende Frontmatter-Felder sind in der Bundleroot **nicht** zulässig.
- **`okf_version`-Regel:** `okf_version: "0.2"` MUSS ausschließlich in der Bundleroot `wiki/index.md` stehen. Es DARF NICHT in Area-`index.md`, in Concepts, in `log.md` oder in irgendeiner anderen Bundle-Datei vorkommen.
- **`type: bundle`-Regel:** `type: bundle` MUSS ausschließlich in der Bundleroot `wiki/index.md` vorkommen. Es DARF NICHT in irgendeiner anderen Datei des Bundles auftauchen.
- **Frontmatter-Exklusivität:** Area-`index.md`-Dateien (§6) und `log.md`-Dateien (§5) tragen **kein** Frontmatter. Genauer: Frontmatter ist in `index.md` ausschließlich in der Bundleroot erlaubt; jede andere `index.md` im Bundle MUSS frontmatterlos sein.
## 3. Concept-Feldsubset
Ein Concept ist eine Markdown-Datei mit YAML-Frontmatter innerhalb von `wiki/`, die weder `index.md` noch `log.md` ist. Für das Frontmatter eines Concepts gilt das folgende Feldsubset. Es ist vollständig: Kein anderes Frontmatter-Feld ist erlaubt.
### 3.1 `type` — einziges Pflichtfeld
- `type` MUSS gesetzt und darf nicht leer sein. Es ist das einzige Pflichtfeld eines Concepts. `type` MUSS ein nicht-leerer String sein; nicht-String-Werte (z. B. `null`, Zahlen, Datumsobjekte) sind nicht gesetzt im Sinne dieses Vertrags und damit strukturell invalide.
- Nicht gesperrte `.md`-Dateien im Bundle (also alle Concepts) MÜSSEN einen `type` tragen; eine `.md`-Datei im Bundle ohne Frontmatter bzw. ohne `type` ist strukturell invalide (§7) — sie ist nicht „kein Concept", sondern ein invalides Bundle-Element. «Reserviert» im Sinne dieses Vertrags sind ausschließlich `index.md` (Bundleroot und Area-`index.md`) und `log.md` (§2, §5, §6); alle übrigen `.md`-Dateien gelten als nicht-reserviert.
- Der Wert von `type` ist eine fachliche Klassifikation des Concepts und wird in der Regel `concept` oder eine spezifischere, im jeweiligen Fall bestimmte Klasse sein; die Zulässigkeit konkreter Werte legt dieser Vertrag nicht über die Nicht-Leerheit hinaus fest.
### 3.2 Optionale Felder
Optionale Felder eines Concepts sind ausschließlich: `sources`, `generated`, `verified`, `status`, `stale_after`. Alle fünf sind einzeln weglassbar. Das Fehlen eines optionalen Feldes ist niemals ein Validierungsfehler (A0-2/AD-1b, §7). Leere Werte zählen dabei wie folgt: `sources: []` und `verified: []` sind zulässig und semantisch gleichbedeutend mit Absenz; leere Listen sind also keine Invalidität.
### 3.3 `sources` — Liste von Maps
- `sources` MUSS, falls gesetzt, eine **YAML-Liste von Maps** sein. Die Map-/Objekt-Form als Quelle (ein einzelnes Mapping direkt unter `sources`) ist **nicht** zulässig. `sources: []` (leere Liste) ist zulässig und gleichbedeutend mit Absenz.
- Jeder Listeneintrag ist eine Map. `resource` ist die **einzige Pflichtangabe** je Eintrag und MUSS gesetzt und nicht leer sein. Die folgenden Angaben sind innerhalb eines Eintrags optional (OKF-0.2-Evidenz-Grammatik): `id` (stabile Kennung, effizient für Zitat-Attribution), `title`, `author`, `usage_count` (Ganzzahl ≥ 0), `last_modified` (ISO-Datum `YYYY-MM-DD`).
- **Key-Subset je Ebene:** Innerhalb eines `sources`-Eintrags sind ausschließlich die Felder `resource`, `id`, `title`, `author`, `usage_count`, `last_modified` erlaubt. Unautorisierte Keys in einem `sources`-Eintrag sind strukturell invalide (§7).
- **Provenienz-Ziellinie (Verbot):** `resource` MUSS auf einen Pfad unter `raw/` verweisen — auf lokal materialisierte, immutable Evidenz (FR-1/A-4, AD-4b/A0-4). `resource` DARF NIEMALS auf einen `wiki/`-Concept-Pfad auflösen. Pfade in `sources` sind Provenienz zur Evidenz und ersetzen keine Wiki-Links: Wiki-Links sind die Navigations-/Beziehungsschicht (AD-8) und werden formatseitig von Provenienz unterschieden.
- **Deterministische Auflöse-Basis (v1):** `resource` ist ein relativer Workspace-Pfad, der **relativ zur Workspace-Root** (oberste Ebene des Git-Arbeitsverzeichnisses) aufgelöst wird. In v1 MUSS der aufgelöste Pfad innerhalb `raw/` landen; eine URL-Form von `resource` ist in v1 nicht zulässig (FR-1, A-4). `..`-Traversale ist generell unzulässig — unabhängig davon, ob das Auflösungsziel innerhalb `raw/` liegt: `resource` DARF keinen `..`-Path-Segment enthalten und DARF bei Auflösung NICHT außerhalb `raw/` landen. Absolute Pfadformen (führender `/`), `file://`-Präfixe und Backslash-/Windows-Trenner sind in v1 ebenfalls nicht zulässig; `resource` nutzt ausschließlich `/`-getrennte relative Pfade.
- **Existenz-Prüfung als Validator-Verhalten:** Die Prüfung, ob die referenzierte `raw/`-Datei tatsächlich existiert, ist ein Validator-Verhalten der Story 1.4 und wird hier nicht durchgeführt; sie ist als Normreferenz in §8 vermerkt.
- Beispiel:
```yaml
sources:
- resource: raw/prd/prd-wow20-2026-08-14.md
id: s1
title: "Wiki of Wikis PRD"
author: "Michael Tamse"
usage_count: 3
last_modified: 2026-08-14
```
### 3.4 `generated`
- `generated` ist, falls gesetzt, eine Map mit den Feldern `by` und `at`. Die Map-Form ist die einzige zulässige Form; eine Liste ist hier nicht zulässig.
- `by` ist die Pflichtangabe innerhalb `generated` und MUSS gesetzt und **nicht leer** sein (leerer String und reiner Whitespace sind verboten). Ein `generated` ohne `by` (nur `at` oder leer) ist strukturell invalide (§7). `at` ist optional; falls gesetzt, MUSS es ein ISO-8601-Datetime sein.
- **Key-Subset:** Innerhalb von `generated` sind ausschließlich die Felder `by` und `at` erlaubt. Unautorisierte Keys sind strukturell invalide (§7).
- **Actor-Konvention für `by`:** Agenten/Tools verwenden `<producer>/<version>` (z. B. `wow-compiler/0.1.0`); Personen verwenden `human:<id>` (z. B. `human:michael`).
- `generated` kennzeichnet maschinelle Erzeugung. Der v1-Default laut A0-20 ist: maschinell erzeugt und ungeprüft → `generated` gesetzt, `verified` ungesetzt.
- Beispiel:
```yaml
generated:
by: wow-compiler/0.1.0
at: 2026-08-14T12:00:00Z
```
### 3.5 `verified`
- `verified` ist, falls gesetzt, eine Liste von `{by, at}`-Ereignissen. Eine einzelne Map (`verified: { by: ..., at: ... }`) MUSS als 1-Element-Liste interpretiert werden. `verified: []` (leere Liste) ist zulässig und gleichbedeutend mit Absenz.
- In jedem Eintrag ist `by` die Pflichtangabe (identifiziert den/die Reviewer) und MUSS gesetzt und **nicht leer** sein (leerer String und reiner Whitespace sind verboten); ein `verified`-Eintrag ohne `by` ist strukturell invalide (§7). `at` ist optional und MUSS, falls gesetzt, ein ISO-8601-Datetime sein. Konsistenz mit der OKF-0.2-Darstellung: Eine einzelne Map wird als 1-Element-Liste gelesen — diese Toleranz ist Teil des Vertrags und wird von der Schema-Validierung (Story 1.4) entsprechend umgesetzt.
- **Key-Subset:** Innerhalb eines `verified`-Eintrags sind ausschließlich die Felder `by` und `at` erlaubt. Unautorisierte Keys sind strukturell invalide (§7).
- `by` MUSS der Actor-Konvention aus §3.4 folgen.
- **Trust-Klassifikation:** Ein `by`-Wert mit `human:`-Präfix markiert human-reviewed Wissen. Ohne `human:`-Präfix kennzeichnet der Eintrag nicht-userbezogene Prüfung und begründet keine human-review-Klassifikation. Human-reviewed Knowledge bleibt dadurch von ungeprüftem maschinellem Output unterscheidbar (FR-13, AD-15, A0-20).
- `verified` bleibt ungesetzt, solange kein Mensch das Concept reviewed hat (v1-Default, A0-20).
- Beispiel:
```yaml
verified:
- by: human:reviewer-1
at: 2026-08-15T09:30:00Z
```
### 3.6 `status` — Policing (unabhängig von Trust)
- Zulässige Werte von `status` sind ausschließlich: `draft` | `stable` | `deprecated`. Kein anderer Wert ist gültig.
- Absenz von `status` bedeutet den Default `stable`: Ein Concept ohne `status` gilt als `stable`.
- Ein gesetzter `status` mit einem Wert außerhalb der erlaubten Menge ist strukturell invalide (§7).
- **Orthogonalität von `status` und Trust:** `status` (Lifecycle: `draft`/`stable`/`deprecated`) und der `verified`-Status (Trust/Review) sind **unabhängige Dimensionen** (AD-15/A0-20). Ein nicht-human-reviewtes Concept ist NICHT deshalb von `stable` ausgeschlossen; umgekehrt erzwingt `verified` keinen bestimmten `status`. Es gibt keine Regel, die „ungeprüft" mit „nicht stable" gleichsetzt. Insbesondere ist der v1-Default „maschinell erzeugt und ungeprüft" (generated ohne verified) mit dem `status`-Default `stable` vereinbar.
### 3.7 `stale_after`
- `stale_after` ist optional und MUSS, falls gesetzt, ein absolutes Datum im Format `YYYY-MM-DD` sein.
- Ein Concept gilt als veraltet, wenn das Tagesdatum `today >= stale_after` erfüllt: `today >= stale_after` ⇒ veraltet.
## 4. (reserviert)
Dieser Abschnitt ist in dieser Revision unbenutzt und für zukünftige Erweiterungen reserviert. Er ist kein Teil der Norm.
## 5. `log.md`-Typdefinition (OKF §9)
- `log.md` ist ein reservierter Name innerhalb des Bundles. In v1 ist `log.md` eine Datei an der Bundleroot (`wiki/log.md`, Lease-Root-Scope, AD-17b); der reservierte Name darf nicht an anderer Stelle im Bundle verwendet werden. (Eine Ausweitung, z. B. `log.md` pro Area, ist eine Normerweiterung und erfordert eine neue Autorisierung.)
- `log.md` trägt **kein** Frontmatter.
- Format: eine flache Liste datumsgruppierter Einträge, neueste zuerst; der Header jedes Gruppenabschnitts ist ein ISO-Datum `YYYY-MM-DD`.
- Inhalt: `log.md` dokumentiert fachliche Änderungen und Disagreements (AD-16b), einschließlich Konfliktklassifikation samt Begründung, verknüpft mit dem jeweils mutierten Concept-Pfad. Es ist Teil der Lease-Root-Scope (`wiki/` inklusive `log.md`, `index.md` und aller Root-Dateien; AD-17b).
- Struktur-Beispiel:
```text
# Log
## 2026-08-15
- AD-16b: `flowable/timers` CORRECTING, ersetzt durch ... (Logik: ...)
## 2026-08-14
- neu: `spring/testing` angelegt (sources: raw/...)
```
## 6. Index-Regel und Validitätsprädikate
**Index-Regel (progressive Discovery):**
- Jede Area innerhalb von `wiki/` MUSS eine Datei `index.md` enthalten, die die Inhalte der Area verlinkt.
- Die `index.md`-Dateien bilden zusammen mit der Bundle-Hierarchie die erste progressive-Discovery-Ebene: Ein Consumer navigiert von der Bundleroot `wiki/index.md` über die Area-`index.md`-Dateien zu den Concepts (AD-9/FR-11).
- Neue Concepts MÜSSEN in der `index.md` der zugehörigen Area verlinkt werden, damit sie entdeckbar bleiben (Story 2.5).
- Area-`index.md`-Dateien tragen **kein** Frontmatter. Frontmatter ist in `index.md` ausschließlich in der Bundleroot erlaubt (§2).
- **Reservierter Status:** `index.md` ist ein reservierter Name; er ist als Bundleroot-Datei und als Area-`index.md` erlaubt. Jede `index.md` im Bundle ist damit vom Invaliditätsfall „nicht-reservierte `.md`-Datei ohne Frontmatter bzw. ohne `type`" (§7, Fall 2) ausgenommen. Die Verletzung der Index-Regel selbst (Area ohne `index.md`, fehlender Link eines neuen Concepts) ist strukturell invalide (§7, Fall 11).
### 6.1 Concept-Prädikat
Ein Concept ist gültig genau dann, wenn alle Bedingungen erfüllt sind:
- **Format:** Markdown mit YAML-Frontmatter; Frontmatter ist gültiges YAML.
- **`type`:** vorhanden und nicht leer (§3.1). Eine nicht-reservierte `.md`-Datei im Bundle ohne Frontmatter bzw. ohne `type` ist strukturell invalide (§7).
- **Feldsubset:** das Frontmatter enthält ausschließlich Felder aus §3 (kein zusätzliches, nicht autorisiertes Feld).
- **`sources`-Form:** falls gesetzt, Liste von Maps mit `resource` je Eintrag (§3.3).
- **Provenienz-Ziellinie & Deterministische Auflösung:** kein `resource`-Eintrag löst auf einen `wiki/`-Concept-Pfad auf; kein `resource`-Eintrag verlässt bei Auflösung relativ zur Workspace-Root `raw/` (kein `..`-Traversal, keine URL-Form) (§3.3, AD-4b/A0-4).
- **Key-Subset je Ebene:** keine unautorisierten Keys innerhalb von `sources`/`generated`/`verified`-Einträgen sowie keine unautorisierten Frontmatter-Felder (§3.33.5).
- **`generated`/`verified`-Zulässigkeit:** falls gesetzt, entsprechen `generated` und `verified` den Formen und Pflichtangaben aus §3.4/§3.5; `by` ist jeweils gesetzt und nicht leer.
- **`status`:** falls gesetzt, einer der Werte aus §3.6.
- **`stale_after`:** falls gesetzt, Datum `YYYY-MM-DD` (§3.7).
- **A0-5/AD-4c (Normreferenz, v1 tautologisch erfüllt):** In v1 zeigt `sources` ausschließlich auf `raw/`-Evidenz; ein generiertes Concept kann nie ein anderes generiertes Concept als alleinige Provenienz führen. Diese Regel ist in v1 daher automatisch (tautologisch) erfüllt und erzeugt kein eigenes Validitätsprädikat. Sie ist als Normreferenz zu §8 dokumentiert und bei späterer Einführung von Quellen, die auf andere generierte Concepts zeigen können (Epic 2+), erneut zu evaluieren.
### 6.2 Bundle-Root-Prädikat
- Die Bundleroot `wiki/index.md` MUSS `type: bundle` UND `okf_version: "0.2"` tragen; deren Frontmatter ist **ausschließlich** diese beiden Felder (§2).
- `okf_version: "0.2"` DARF NICHT in irgendeiner anderen Datei des Bundles vorkommen (insbesondere nicht in Area-`index.md`, Concepts oder `log.md`).
- `type: bundle` DARF NICHT in irgendeiner anderen Datei des Bundles vorkommen.
- Nur in der Bundleroot `index.md` ist Frontmatter erlaubt; Area-`index.md` und `log.md` sind frontmatterlos.
## 7. Strukturelle Invalidität vs. optionale Felder
- **Strukturelle Invalidität** schlägt den Compilation Run fehl. Die Liste der strukturell invaliden Zustände ist **abschließend**; sie umfasst genau die folgenden Fälle:
1. ein Concept ohne `type` oder mit leerem `type`;
2. eine nicht-reservierte `.md`-Datei im Bundle ohne Frontmatter bzw. ohne `type`;
3. ein `sources`-`resource`-Eintrag, der auf einen `wiki/`-Concept-Pfad auflöst;
4. ein `sources`-`resource`-Eintrag, der bei Auflösung relativ zur Workspace-Root außerhalb `raw/` landet (insbesondere via `..`-Traversal) oder in v1 eine URL-Form von `resource` darstellt;
5. ein verbotener `status`-Wert (nicht `draft`/`stable`/`deprecated`);
6. ein nicht autorisiertes Frontmatter-Feld (für Concepts oder Bundleroot) oder ein unautorisierter Key innerhalb eines `sources`/`generated`/`verified`-Eintrags;
7. eine leere oder fehlende (reiner Whitespace eingeschlossen) `by`-Angabe in `generated` oder `verified`;
8. eine Bundleroot `wiki/index.md` ohne `type: bundle` bzw. ohne `okf_version: "0.2"`, oder ein abweichender `okf_version`-Wert (z. B. `"0.3"`) in der Bundleroot;
9. `okf_version: "0.2"` oder `type: bundle` an einer anderen Stelle als der Bundleroot;
10. Frontmatter in einer Area-`index.md` oder einer `log.md`;
11. die Verletzung der Index-Regel (§6): eine Area ohne `index.md` oder ein neues Concept ohne Verlinkung in der `index.md` der zugehörigen Area;
12. ein `sources`- oder `verified`-Eintrag in nicht erlaubter Form (z. B. `sources`/`verified` als einzelne Map statt Liste, Skalar-Einträge statt Maps) sowie ein `generated` in Listen- statt Map-Form;
13. ein doppelter Frontmatter-Key (z. B. doppeltes `type` oder doppeltes `okf_version`) — Duplikat-Keys sind strukturell invalide;
14. fehlerhafte Wert-Formate: `stale_after`/`last_modified` ungleich `YYYY-MM-DD`, `at` ungleich ISO-8601-Datetime, `usage_count` keine Ganzzahl ≥ 0, `type` kein nicht-leerer String.
- **Abschließende Liste:** Diese Liste ist abschließend. Erweiterungen der Invaliditätsdefinition sind nur über die Autorisierung bzw. das Story-Verfahren möglich, nicht stillschweigend durch einzelne Producer oder Validator-Implementierungen.
- **Fehlende optionale Felder sind niemals ein Fehler:** Ein Concept mit nur `type` und ohne `sources`/`generated`/`verified`/`status`/`stale_after` ist gültig (A0-2/AD-1b, F-2). Abwesenheit von `status` bedeutet `stable`-Default und ist keine Invalidität. Leere Listen (`sources: []`, `verified: []`) sind zulässig und keine Invalidität.
- Ein fehlgeschlagener Run lässt `raw/` unangetastet; die Fehlerursache muss textuell identifizierbar sein (NFR-4/AD-3).
- **Kalender-Validität und Datum/Vergleich:** `YYYY-MM-DD`-Felder müssen reale Kalenderdaten sein (z. B. ist `2026-02-31` invalide, obwohl textuell `YYYY-MM-DD`-konform). Der Veraltungsvergleich `today >= stale_after` erfolgt in UTC.
## 8. Normreferenzen
- PRD §13 — Fixierung von OKF 0.2 als normativer Format-Standard (FR-9, NFR-6); OKF-Spezifikation (Google Cloud, `knowledge-catalog`).
- AD-1, AD-1a, AD-1b (Schema-Bindung, Validierung F-2/A0-2); AD-2/AD-3 (Bundlegrenze, `raw/` immutable); AD-4b/A0-4 (Provenienz-Ziellinie); AD-4c/A0-5 (keine abgeleitete Provenienz; in v1 tautologisch erfüllt, §6.1); AD-9 (Index-Regel/Discovery); AD-15/A0-20 (Trust-Metadaten, v1-Default; Orthogonalität `status`/Trust); AD-16b (Disagreements in `log.md`); AD-17b (Lease-Root-Scope); Structural Seed (Bundleroot `wiki/`, `okf_version` nur in Bundleroot-`index.md`).
- Existenz-Prüfung referenzierter `raw/`-Dateien: Validator-Verhalten der Story 1.4 (hier nicht ausgeführt).
- Story 1.4 — implementiert die Validierung dieses Vertrags.