docs: Gate 3 — and the accepted ADR that forbids the plan as approved

Option A said FRAMEWORK-BEFUNDE.md would cease to exist as a file. It
cannot: ADR-0024 is accepted, links it twice, and an accepted record is
never edited. Deleting the file breaks validate.py at a line nobody is
allowed to repair.

Resolved without touching the record: the file stays as a generated
signpost of a few lines carrying no inventory of its own. The data live in
the pages, the overview in STATUS.md, and the file only says where both
are. Every reference stays valid and nothing can rot, because a signpost
holds nothing that could. It also means AGENTS.md needs exactly one change
- the duplicated rule - rather than two.

Eleven new pages, not twelve: FB-02 already owns one. collect() already
reads artifacts by directory and type, so the generator gains a filter
rather than a second reader.

The assertions that matter are the ones about absence: a page without a
state must show up as a finding rather than vanish, and harvested without
harvested_in must fail. The difference between "no state set" and "not
there" is the failure class this whole register was started for.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F2Q4Ri8NGwyTZzScvKnWFM
This commit is contained in:
Thore Cimbal
2026-08-21 12:00:00 +00:00
co-authored by Claude Opus 5
parent afaa74a6b6
commit 0f161d0c91
3 changed files with 117 additions and 4 deletions
+1 -1
View File
@@ -91,7 +91,7 @@ Bedeutung der Meilensteine: siehe [roadmap.md](roadmap.md).
| Design | Gate | Title |
|---|---|---|
| [2026-08-21-v031-adoption-stage-2](docs/design/2026-08-21-v031-adoption-stage-2.md) | gate-2 | Design: Die Übernahme von v0.3.1 zu Ende bringen — Etappe 2 |
| [2026-08-21-v031-adoption-stage-2](docs/design/2026-08-21-v031-adoption-stage-2.md) | gate-3 | Design: Die Übernahme von v0.3.1 zu Ende bringen — Etappe 2 |
## ADRs (24)
+113 -2
View File
@@ -1,6 +1,6 @@
---
type: design
status: gate-2
status: gate-3
date: 2026-08-21
size: L
related:
@@ -226,4 +226,115 @@ Umzug der Befundübersicht nach `STATUS.md` und das Ende von
`FRAMEWORK-BEFUNDE.md` als Datei ist eine dauerhafte Richtungsentscheidung
mit Verweisänderungen in `AGENTS.md`. Bei Option B keine.
> **STOP — Freigabe für Gate 2**, insbesondere zur Wahl A oder B.
> **Gate 2 freigegeben durch sorb, 2026-08-21: Option A.**
## Gate 3 — Program Design
⚠️ **Ein Fund, der die Ausführung von A verändert — nicht die Wahl.**
`FRAMEWORK-BEFUNDE.md` kann **nicht verschwinden**: ADR-0024 ist
`accepted`, verweist zweimal darauf (Frontmatter und Fließtext), und eine
angenommene ADR wird nie editiert, nur abgelöst. Die Datei zu löschen
bricht `validate.py` an einer Stelle, die niemand reparieren darf.
**Auflösung:** Die Datei bleibt — als **erzeugter Wegweiser** von wenigen
Zeilen, ohne eigenen Bestand. Die Daten leben in den Seiten, die Übersicht
in `STATUS.md`, und die Datei sagt nur noch, wo beides steht. Damit bleibt
jeder Verweis gültig, keine angenommene ADR wird angefasst, und
Doppelpflege entsteht trotzdem nicht: ein Wegweiser trägt nichts, was
veralten könnte. Nebeneffekt — der Verweis in `AGENTS.md` bleibt gültig,
sodass an dieser Datei nur die eine abgestimmte Änderung nötig ist.
**Files.**
*Neu — elf Seiten, nicht zwölf:*
| Pfad | Muster |
|---|---|
| `docs/wiki/stolpersteine/aar-pflicht-ohne-werkzeug.md` | FB-01 |
| `docs/wiki/stolpersteine/befunde-die-niemand-beheben-kann.md` | FB-03 |
| `docs/wiki/stolpersteine/issues-behaupten-ueberholte-zustaende.md` | FB-04 |
| `docs/wiki/stolpersteine/artefakt-existiert-liefert-aber-nichts.md` | FB-05 |
| `docs/wiki/stolpersteine/dokumente-ergaenzt-nicht-revidiert.md` | FB-06 |
| `docs/wiki/stolpersteine/werkzeug-misst-die-falsche-instanz.md` | FB-07 |
| `docs/wiki/stolpersteine/dokumente-angelesen-nicht-durchgelesen.md` | FB-08 |
| `docs/wiki/stolpersteine/gelesene-anweisungen-nicht-befolgt.md` | FB-09 |
| `docs/wiki/stolpersteine/gesperrte-dateien-werden-bearbeitet.md` | FB-10 |
| `docs/wiki/stolpersteine/regeln-ohne-widerspruch.md` | FB-11 |
| `docs/wiki/stolpersteine/upgrade-pfad-nie-begangen.md` | FB-12 |
Dazu `docs/adr/0025-befunduebersicht-erzeugt-statt-gepflegt.md` und ein
`docs/verdict/`-Artefakt aus dem Judge-Lauf.
*Angefasst:*
| Pfad | Änderung |
|---|---|
| `scripts/gen_status.py` | neuer Abschnitt in `STATUS.md`; erzeugt zusätzlich den Wegweiser; `--check` deckt beide Erzeugnisse |
| `docs/wiki/stolpersteine/meldet-erfolg-ist-aber-blind.md` | **nur** `status` und `harvested_in` — FB-02 hat seine Seite bereits |
| `FRAMEWORK-BEFUNDE.md` | wird zum erzeugten Wegweiser |
| `AGENTS.md` | **eine** Änderung: der doppelte Regeltext im Projektabschnitt entfällt (ADR-Pflicht steht seit v0.1.2 upstream). Abgleich mit `HERKUNFT.md` nach ADR-0024 |
| `README.md`, `roadmap.md` | Formulierung an den Wegweiser angepasst |
| `.gitlab-ci.yml`, `scripts/pruefe_sperrliste.py`, `scripts/pruefe_upstream_drift.py` | Kommentar-Nennungen nachziehen |
**Signatures.** Kein neues Modul — `collect()` gibt es bereits und wird
wiederverwendet:
```python
def stolpersteine(root: Path) -> list[tuple[Path, dict, str]]: ...
# collect(root, "docs/wiki", "wiki-page"), gefiltert auf area == "stolpersteine"
def render_fehlerklassen(items) -> list[str]: ... # Abschnitt für STATUS.md
def render_wegweiser(items) -> str: ... # Inhalt von FRAMEWORK-BEFUNDE.md
```
**Call stack.**
```
main
├── render(root) → … bestehende Abschnitte … + render_fehlerklassen
│ → STATUS.md
├── render_wegweiser(items) → FRAMEWORK-BEFUNDE.md
└── --check → beide Dateien vergleichen, rot bei Abweichung
```
**Test assertions.** Positivkontrolle im selben Zug, nicht danach:
1. Eine Seite mit `status: harvested` erscheint unter *geerntet*, eine mit
`open` unter *offen*.
2. Eine Seite **ohne** `status` erscheint als **Befund** in einem eigenen
Block „ohne Stand" — sie verschwindet nicht still. Der Unterschied
zwischen „kein Stand gesetzt" und „nicht vorhanden" ist genau die Klasse
FB-02.
3. `harvested` **ohne** `harvested_in` ist ein Fehler, kein stiller Durchlauf.
4. `--check` wird rot, wenn eine der beiden erzeugten Dateien von Hand
geändert wird — je einmal für beide gezeigt.
5. Ein Lauf ohne jede Stolpersteine-Seite erzeugt einen leeren, aber
gültigen Abschnitt statt einer Ausnahme.
**Boundaries — DO NOT CHANGE.**
- **ADR-0024 und jede andere angenommene ADR.** Der Fund oben ist die
Begründung dieses ganzen Gates, nicht ein Grund zur Ausnahme.
- `docs/sources/**` — unverändert, auch die alte Baseline.
- Der Upstream-Teil von `AGENTS.md` und `WORKFLOW.md` als Ganzes.
- **Die Befundtexte.** Sie ziehen um, sie werden nicht redigiert.
- Das Rahmenwerks-Repo. Hier wird nichts geerntet.
**Shakiest calls.**
1. **Der Wegweiser weicht von dem ab, was freigegeben wurde.** Gate 2 sagte
„`FRAMEWORK-BEFUNDE.md` entfällt als Datei"; sie bleibt jetzt als
erzeugte Zeile stehen. Sachlich klein, aber es ist eine Abweichung von
einer Freigabe, und sie steht hier statt in einer Fußnote.
2. **FB-07 und FB-08 bekommen `open`, obwohl das Rahmenwerk sie abgelehnt
hat.** Der Enum hat keinen dritten Wert. `open` ist falsch, aber weniger
falsch als `harvested`, und die Seite sagt im Text, was wirklich gilt.
Der Zustandsraum-Befund geht in die nächste Ernte.
3. **Die Seitennamen tragen die FB-Nummern nicht mehr.** Die Nummer war die
Zeile des Registers, das verschwindet. Jede Seite nennt ihre Herkunft im
Text, sonst reißt die Spur zu den Commits.
4. **`harvested_in` ist maschinell nur auf Vorhandensein prüfbar.** Ob die
genannte Version das Muster wirklich abdeckt, kann nur ein Mensch
beurteilen. Das steht so in der Prüfung, damit niemand ihr mehr zutraut.
> **STOP — Freigabe für Gate 3.**
@@ -14,7 +14,8 @@ related:
| gate | commit | approval | status | note |
|---|---|---|---|---|
| 1 | acbef08 | sorb | DONE | Zuschnitt einmal komplett neu gefasst, weil die Messung ergab, dass Etappe 1 schon lief. Freigabe mit Auflage: erst pruefen, ob v0.3.1 laengst adaptiert ist. |
| 2 | | | NEEDS_CONTEXT | Auflage erfuellt: Regeln vollstaendig uebernommen, inhaltlicher Rest offen. Wahl A/B fuer den Ort der erzeugten Uebersicht liegt bei sorb. |
| 2 | afaa74a | sorb | DONE | Auflage erfuellt: Regeln vollstaendig uebernommen, inhaltlicher Rest offen. Option A gewaehlt. |
| 3 | | | NEEDS_CONTEXT | Ausfuehrung von A angepasst: die Datei kann nicht entfallen, ADR-0024 ist accepted und verlinkt sie. Bleibt als erzeugter Wegweiser. |
## Ladder
@@ -26,6 +27,7 @@ related:
| `scripts/gen_status.py`, als Vorbild für die erzeugte Befundübersicht | erzeugt aus Frontmatter, trägt `--check`, in der CI verdrahtet | reused: dasselbe Werkzeug erweitern, statt einen zweiten Erzeugungsweg zu erfinden | |
| `gen_status.py` hier **und** upstream v0.3.1, ob eine Befundübersicht schon existiert | keine der beiden Fassungen kennt `stolpersteine` oder `harvested` | built: der Abschnitt muss entstehen — erste Sprosse geprüft, sie hält nicht | |
| `docs/wiki/stolpersteine/`, bevor für FB-02 eine Seite angelegt wird | `meldet-erfolg-ist-aber-blind.md` existiert und wird vom Befund zweimal verlinkt | reused: keine neue Seite, nur der Status kommt dazu | |
| `collect()` in `gen_status.py`, bevor ein Leser für die Wiki-Seiten geschrieben wird | liest jedes Artefakt nach Verzeichnis und Typ, inklusive Frontmatter | reused: nur ein Filter auf `area` kommt dazu, kein zweiter Leser | |
## Notes