Skip to content

Commit 03bf0d2

Browse files
Axel051171claude
andcommitted
docs(formate): Phase 4c — PH-2 entfernte einen von fuenf aus derselben Include-Gruppe (MF-959)
Sechste Phase des Architektur-Durchgangs, Teilstueck 4c: PC / CP-M / Japan. Umfang frisch aus `git ls-files`: **50 Dateien, 23 672 Zeilen**. ## P3-254 — vier Phantom-Header, und wie sie stehen blieben `PH-2` (MF-549, `814fa5ff`, 2026-08-24) hat eine Klasse gemessen und **ein** Mitglied entfernt: `uft_xdf_mxdf.h` — 336 Zeilen, 27 Prototypen, 100 % ohne Rumpf, eingebunden von genau einer Datei, die keines seiner Symbole ruft. Die vier Geschwister blieben stehen: `include/uft/xdf/uft_xdf_{dxdf,pxdf,txdf,zxdf}.h`, zusammen **900 Zeilen, 39 Prototypen, 0 Umsetzungen, 0 Aufrufe**, eingebunden von derselben `uft_xdf_api_impl.c`, die auch von ihnen nichts ruft. **Und sie standen im selben Block.** Die fuenf Einbindungen lagen als zusammenhaengende Zeilen 17–21; `814fa5ff` entfernte Zeile 21, die vier darueber blieben unberuehrt. Der Commit meldete dabei den Gesamtstand „Phantom-Deklarationen 294 -> 237". Das ist die Signaturklasse dieses Baums in ihrer reinsten Form — **Aufzaehlung statt Messung** —, diesmal nicht in einer Doku, sondern in einem **Aufraeum-Commit**, dessen Zahl den Eindruck erweckte, die Klasse sei abgearbeitet. Die vier stehen seit dem v4.1.0-Release (`4d622192`, 2026-02-08), also sieben Monate. Ihre Kopfzeilen lesen sich wie eine Merkmalsliste („Supports D64, G64, NIB and raw GCR", „Protection Types: V-MAX!, RapidLok, Vorpal") — Bestand, nicht Faehigkeit. Ein fuenfter derselben Ecke: `include/uft/formats/uft_cpm_defs.h` (205 Z., 3/3 ohne Rumpf), eingebunden von der **Produktionsdatei** `src/protection/uft_supercopy_detect.c`, gerufen von nichts. Antwort wie MF-366 und wie PH-2 selbst: entfernen, nicht umsetzen — der Code liegt in der Historie. Aber nicht ungeprueft: die Entfernung beruehrt `uft_xdf_api_impl.c`, das unter ARCH-6 als zweite Formatschicht ohne Aufrufer gefuehrt wird. Die Reihenfolge gehoert dorthin. ## `DEFERRED.md` — und was ich beinahe als neu ausgegeben haette `src/formats/xdf/DEFERRED.md` erklaerte `uft_xdf_adapter.c` und `uft_xdf_api_impl.c` fuer „intentionally NOT restored" und nannte `<fnmatch.h>` als Windows-Blocker. Beide Dateien liegen im Baum (254 und 1124 Zeilen) und in `SOURCES`; den Blocker loest `uft/compat/uft_fnmatch.h` seit `1535dfab` — **einen Tag** nach Entstehung des Dokuments, mit dem Commit-Titel „fnmatch shim + xdf adapter". Das Dokument stand 4½ Monate falsch. **Das war kein neuer Befund.** `docs/KNOWN_ISSUES.md` hat ihn in MF-459 festgehalten. Ich habe die Stelle gelesen, bevor ein zweiter Eintrag daraus geworden waere — die Lehre aus `measurement_hit_wrong_class` gilt in beide Richtungen: nicht nur „was kann meine Messung nicht sehen", sondern auch „steht das schon irgendwo". Statt eines Eintrags ist das Dokument jetzt **korrigiert**: es sagt, was gemessen ist, benennt die drei offenen Punkte (ARCH-18 API ohne Aufrufer, ARCH-6 zweite Formatschicht, P3-254) und verweist fuer die Entscheidung auf ARCH-6. ## Was sauber zurueckkam Vier CP/M-Header mit aehnlichen Namen (`cpm.h`, `uft_cpm_defs.h`, `uft_cpm_diskdef.h`, `uft_cpm_diskdefs.h`) geprueft: **keine** Kollision, verschiedene Einbinder, verschiedene Inhalte. `test_libdsk_formats` steht mit ehrlicher Begruendung in `EXCLUDED_TESTS`. ## Zur Arbeitsweise Diese Phase lief in einem Baum, in dem eine **zweite Sitzung gleichzeitig arbeitete** (MF-949…958). Ein frueherer Push wurde vom Pre-Push-Haken zu Recht abgewiesen, weil `BACKLOG.md` C1 durch deren neue Schutz-Tests driftete. Die richtige Reaktion war **warten** statt den fremden Index aufzuraeumen: ein Commit haette deren halbfertige Arbeit eingesammelt. Dieser Commit stagt ausschliesslich die vier eigenen Dateien. Gemessen: `check_consistency.py` exit 0, keine Befunde. Artefakt: `memory/arch_formate_pc.md`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BHdqfaZ5RFb1HPcw7NYoEY
1 parent 5c7f458 commit 03bf0d2

4 files changed

Lines changed: 52 additions & 43 deletions

File tree

docs/OPEN_ITEMS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,7 @@ offen).
435435
| P3-251 | **UFT-33 schlaegt zwei HAL-Erweiterungen vor, die es bereits gibt — und die Luecke dahinter war ganz woanders. Behoben MF-958.** | am Baum gegengeprueft (MF-957), behoben und gemessen (MF-958) | ✅ **behoben — aber NICHT durch Durchreichen der Taktfrequenz, und das ist der Punkt.** **E1/E2 existieren:** `uft_hal_cap_t` mit acht `HAL_CAP_*`-Bits steht in `uft_hal.h:119`, `uft_hal_get_caps()` in Z175, und der vorgeschlagene Typname `uft_hal_caps_t` ist dort bereits das **Struct** (Z134). `sample_rate_hz` wird je Treiber korrekt gefuellt (72 M / 24,027 M / 40 M / 8 M, vier Stellen gemessen). Ein `_ps`-Getter waere die DRITTE Darstellung derselben Groesse gewesen, und die Begruendung traegt nicht: 24 027 428 Hz ist als Ganzzahl exakt. **Die Diagnose war falsch, der Befund echt:** `uft_hal_read_flux()` liefert gar keine Takte, sondern **Nanosekunden-INTERVALLE** — der Treiber rechnet an der Geraetekante um (`uft_hal_unified.c`, beide Richtungen), und die Summe eines erzeugten Stroms ergibt dessen Gesamtdauer (MF-957: 1200 Werte = 14,432 ms). `uft_fuzzy_bits.c` braucht die Taktfrequenz also **nie**. Haette man sie durchgereicht, waere die falsche Annahme festgeschrieben worden. Siehe P3-253 fuer das, was statt dessen dort stand |
436436
| P3-252 | **UFT-32 rev. 6.1 wuerde MF-951 rueckgaengig machen — der Vorbehalt im Dokument war berechtigt** | gegen `uft_greaseweazle_full.c:1350` gemessen (MF-957) | ⚠ **offen als BERICHTIGUNG, vom Eigentuemer vorgeschlagen; hier gemessen.** Das Dokument schreibt „Greaseweazle: index_times sind ZEITSTEMPEL (Ticks), keine Indizes" und setzt darauf ein `gw_index_time_to_sample()`, das eine kumulierte Zeit gegen `index_time[i]` vergleicht — mit dem eigenen, ausdruecklichen Vorbehalt „Einheit … pruefen, bevor diese Schleife uebernommen wird". Geprueft: es sind **Dauern**, keine Zeitstempel. Die Schleife wuerde fuer Umdrehung 2 und 3 an den **Stromanfang** zeigen. `uft_rev_grenzen_aus_dauern()` (MF-951) macht es bereits richtig und laeuft ueber Dauern. Bemerkenswert: das Dokument warnt an anderer Stelle genau vor dieser Klasse — der Vorbehalt hat gehalten, die Aussage darueber nicht |
437437
| P3-253 | **Fuenf Fehler uebereinander in `uft_fuzzy_bits.c` — drei beim Lesen, zwei beim Schreiben. Behoben MF-958.** Die Datei rechnete mit Takten, kumulierten Zeitstempeln und einer eigenen, falschen MFM-Fenstertabelle | `tests/test_protection_detection.c` +4 Faelle, Mutationsprobe **5 von 5 getoetet** (MF-958) | ✅ **behoben, und die Schwere gehoert eingeordnet: beide Funktionen haben KEINEN Produktionsaufrufer** (gemessen: nur die eigenen Prototypen und ein Testkommentar). Das ist „Bestand, nicht Faehigkeit" wie P0-2 — die Fehler waren latent, nicht scharf. **Lesepfad `uft_capture_fuzzy_flux()`:** (1) `flux[i] - prev` behandelte INTERVALLE wie kumulierte Zeitstempel — auf einer sauberen Spur nahe null, und bei FALLENDEM Abstand ein Unterlauf in `uint32_t` (4000-8000 = 4 294 963 296, gemessen ~59 s statt 4 us); (2) die Multiplikation mit `1e9/72000000.0` skalierte Werte, die bereits Nanosekunden waren, um Faktor 13,89 (aus 4 us wurden 55,6 us); (3) die Fenstertabelle `4000.0 * w / 2.0` mit `w = 1..3` ergibt **2/4/6 us** und widersprach **drei Zeugen in derselben Datei**: dem Kommentar zwei Zeilen darueber („4us=short, 6us=medium, 8us=long"), den Konstanten `UFT_MFM_FLUX_4US/6US/8US` im eigenen Header, und `uft_is_valid_mfm_timing()` weiter oben. Folge: ein sauberer **8-us-Abstand**, der haeufigste lange auf jeder DD-Spur, lag in keinem Fenster und wurde als „mehrdeutig" gemeldet. **Schreibpfad `uft_write_fuzzy_flux()`, der gefaehrlichere — er brennt auf eine echte Diskette:** (4) er rechnete nach TAKTEN, waehrend `uft_hal_write_flux()` ns nimmt; (5) er KUMULIERTE, waehrend die Schnittstelle Intervalle nimmt. **Behoben durch Herausziehen zweier reiner Wandlungen** (`uft_fuzzy_timings_aus_flux_ns` / `uft_fuzzy_flux_ns_aus_timings`), damit die Rechnung ohne Geraet pruefbar ist — dieselbe Form wie MF-957. Die Fenstertabelle wurde nicht berichtigt, sondern **entfernt**: es wird die vorhandene, benannte `uft_is_valid_mfm_timing()` gerufen. Zwei Fensterdefinitionen in einer Datei waren der Fehler; drei waeren keine Loesung |
438+
| P3-254 | **PH-2 entfernte EINEN von fünf gleichartigen Phantom-Headern — die vier übrigen stehen in derselben `#include`-Gruppe.** `include/uft/xdf/uft_xdf_{dxdf,pxdf,txdf,zxdf}.h`: zusammen **900 Zeilen, 39 Prototypen, 0 Umsetzungen, 0 Aufrufe**. Alle vier werden von genau einer Datei eingebunden — `src/formats/xdf/uft_xdf_api_impl.c` —, und die ruft **kein einziges** ihrer Symbole. Ihre Kopfzeilen lesen sich wie eine Merkmalsliste: *„Supports D64, G64, NIB and raw GCR"*, *„Protection Types: V-MAX!, RapidLok, Vorpal"* | **gemessen MF-959.** `814fa5ff` (2026-08-24, PH-2/MF-549) löschte `uft_xdf_mxdf.h` (336 Z., 27 Prototypen, dieselbe Eigenschaft) und **eine** `#include`-Zeile aus `uft_xdf_api_impl.c`. Die fünf Einbindungen standen als **zusammenhängender Block, Zeilen 17–21**; entfernt wurde Zeile 21. Die vier darüber blieben unberührt. PH-2 meldete dabei den Gesamtstand „Phantom-Deklarationen 294 → 237". Die vier stehen seit dem **v4.1.0-Release (`4d622192`, 2026-02-08)**, also sieben Monate | ⚠ **offen.** Das ist die Signaturklasse dieses Baums in ihrer reinsten Form: **Aufzählung statt Messung**, diesmal nicht in einer Doku, sondern in einem **Aufräum-Commit**, der eine Gesamtzahl nannte, während vier gleiche Fälle in derselben Zeilengruppe stehen blieben. Antwort wie MF-366 und PH-2 selbst: **entfernen, nicht umsetzen** — der Code liegt in der Historie. **Aber nicht ungeprüft:** die Entfernung berührt `uft_xdf_api_impl.c`, das unter ARCH-6 als zweite Formatschicht ohne Aufrufer geführt wird; die Reihenfolge gehört dorthin. **Nachtrag, gemessen:** ein **fünfter** Phantom-Header derselben Ecke, `include/uft/formats/uft_cpm_defs.h` (205 Z., 3/3 ohne Rumpf), wird von der **Produktionsdatei** `src/protection/uft_supercopy_detect.c` eingebunden — gerufen wird davon nichts; die einzige Nennung steht in `test_libdsk_formats.c`, das mit ehrlicher Begründung in `EXCLUDED_TESTS` steht. **Kennzahl (Regel 9):** keine der vier |
438439
"`. **Und der Baum bezeugt es selbst:** `audit/adfcopy/mock_adfcopy.py:34` trägt wörtlich `# Opcodes — needs-source (see extract_ref.py): values from UFT comments only.` — nachgemessen. **Die Prüfkette ist geschlossen:** Mock spiegelt `adfcopy_provider_v2.cpp`, `firmware_state_machine.c` spiegelt den Mock, `test_adfcopy_runners_protocol.cpp` prüft die Runner gegen den Mock. Die 15 Tier-1-Tests sind grün, weil **UFT gegen UFT** geprüft wird — dieselbe Klasse wie MF-301 | gemeldet vom Eigentümer, In-Baum-Teile nachgemessen (MF-807) | ⚠ **offen, in drei Schritten.** (1) **Die Probe:** `teensy_probe.cpp:67` sendet als ADF-Copy-Identify ein einzelnes `0x00` (nachgemessen). Die Firmware nimmt das als Kommandozeile, findet keinen Treffer und antwortet gar nicht — kein Default-Zweig. `ping_ok` ist damit **immer** false, die Einordnung fällt auf `Unknown`, und `Unknown` löst absichtlich keine Warnung aus. Die Zusage in `RELEASE_NOTES.md` („prevents disk-corrupting cross-wire") besteht so nicht. Fix: `ver
439440
` statt `0x00` — das Kommando ist reines `Serial.printf`, kein Motor, kein Kopf, keine Medienberührung — **und die Einordnung auf INHALT umstellen** (Teilzeichenkette `ADF-Drive`), sonst antwortet die Applesauce mit ihrer Unknown-Command-Zeile, beides ist „plausibel", und man landet wieder bei `Unknown`. (2) **Die Statuszeile berichtigen:** Read/Write stehen auf `—`, aber `get <n>`+`download` liest und `upload`+`put <n>` schreibt sektorbasiert — ADF-Copy ist ein **Decoded-Image**-Provider wie USB-Floppy, kein Flux-Provider. `kAdfcStatusFluxCapable` und die 25-ns-Angabe sind unbelegt: `flux` liefert 256 × uint32 LE **Histogramm-Bins**, also eine Timing-Verteilung, keinen Transitionsstrom; der Tick-Takt von `capf`/`getcells` über FTM0 auf einem Teensy 3.2 ist zu **messen**, nicht aus SCP abzuschreiben. (3) **Die Runner sind ein Neuschrieb, kein Bump** — Zeilenprotokoll statt Byte-Opcodes, und Mock plus Emulator müssen mit, sonst bleibt die Zirkularität. Wegen **GPLv3** gehört (3) in die Nachbau-Werkstatt (`uft-nachbau`): die Firmware ist Referenz für das **Wire-Protokoll**, nicht für Code — Kommandonamen und Antwortformate sind Schnittstellenfakten, aber die Runner gehören gegen ein destilliertes Protokoll-Gutachten geschrieben, nicht neben den offenen Firmware-Puffer. **NACHTRAG MF-856 — derselbe Denkfehler ein drittes Mal, und diesmal steht er als `static_assert` im Code.** `adfcopy_provider_v2.h:493` verbietet die Faehigkeit ausdruecklich: `static_assert(!MeasuresRPM<ADFCopyProviderV2>, "… V1 measureRPM() returns constant 300.0 with no serial dialog …")`. Die Firmware hat dafuer ein Kommando: `index` antwortet `"%d microseconds\nOK\n"`, bei fehlender Diskette `"NO DISK"`. Die Pruefung hat also **UFTs eigene, unvollstaendige V1-Umsetzung** begutachtet und daraus geschlossen, die HARDWARE koenne es nicht — dieselbe Verwechslung wie bei `WritesRawFlux` („Honest audit: hardware cannot do this", waehrend die Firmware `write`, `testwrite`, `upload`, `enc`/`dec` fuehrt). **Ein `static_assert` mit falscher Begruendung ist schlimmer als ein fehlendes Mixin:** er zementiert den Irrtum und macht die Korrektur zu einer Aenderung an einer Zusage, nicht an einer Auslassung. Gehoert in denselben Neuschrieb wie (3), also in die Nachbau-Werkstatt. **Nebenbefund, forensisch wertvoll:** `weak` gibt die Retry-Zahl des letzten Lesevorgangs zurück, `exterr` eine Klartext-Fehlerursache — die Provenienz-Metadaten-Schicht, die die anderen Provider nicht liefern |
440441
| P3-20 | **`dummy.bad`: eine Diskette, die gesund aussieht und es nicht ist (MF-790).** **Der wichtigste offene Punkt aus dem Hinweis des Eigentümers, weil er die Mission unmittelbar trifft.** `AllowBad 0.7` (1996) und `badformat 0.2` sind **Anti-Preservation-Werkzeuge**: sie schreiben absichtlich auf beschädigte Medien und **verstecken** den Schaden. AllowBad belegt die defekten Spuren mit einer Scheindatei `dummy.bad`, gegen Lesen/Ändern/Löschen geschützt — das Dateisystem meidet sie, und die Diskette ist wieder benutzbar. **Für ein Werkzeug, das den Marker nicht kennt, liest sich so eine Diskette als gesund:** 880 K, eine Datei, Bitmap stimmig. Der Befund wäre falsch, und zwar in genau der Richtung, die dieses Projekt ausschließt — „keine stille Veränderung" gilt auch für den *Bericht*. Im Baum findet sich dazu **nichts** (gemessen). **Klar umrissener Prüfauftrag:** `dummy.bad` erkennen, benennen, und die belegten Bereiche als **schadensverdächtig** statt als belegt führen. Der Marker ist dafür gut geeignet — benannt, geschützt, an Spurgrenzen ausgerichtet. Kennzahl: keine der vier direkt, aber es ist ein **Falschbefund**, und die stehen in diesem Baum über Kennzahlen |

docs/STAND.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Stand: 2026-09-08
4141

4242
## Was offen ist
4343

44-
`docs/OPEN_ITEMS.md` führt **7588** Zeilen in **82** Abschnitten.
44+
`docs/OPEN_ITEMS.md` führt **7589** Zeilen in **82** Abschnitten.
4545

4646
**erledigt** (1):
4747
- GCR-1 — der 6-and-2-Dekoder steht, 560 von 560 Sektoren belegt (MF-715)

docs/plans/ARCHITEKTUR_DURCHGANG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,8 @@ jeder Befund eine Registerzeile hat.
189189
| 3 |**Verträge vollständig gemessen** — Artefakt `memory/arch_dateisysteme.md`. Vier Phantom-Header und 26 Header-Namenskollisionen gefunden (P3-228, P3-229) |
190190
| 4a |**CBM gemessen** (49 Dateien, 23 122 Z.) — Artefakt `memory/arch_formate_cbm.md`. Registry sauber: 88 Plugin-Tafeln, **kein `.name` doppelt**, also fällt keines still heraus. Zwei Befunde (P3-232 GCR-Tabelle sechsfach + getestete API ohne Produktionspfad, P3-233 zweite BAM-API ohne Umsetzung und ohne Einbinder). **Nicht** gemessen: ob die Leser richtig lesen — das hängt an `VERIFICATION_TIERS.md` |
191191
| 4b |**Atari + Apple gemessen** (62 Dateien, 24 188 Z.) — Artefakt `memory/arch_formate_atari_apple.md`. Zwei Befunde (P3-234 Apple-GCR-Tabelle siebenfach, oracle-geprüfte Einheit ohne Produktionsaufrufer, `nib` auf T3; P3-235 fünf Zusagen ohne Rumpf). Drei Prüfungen kamen **sauber** zurück: kein neuer Phantom-Header, kein Format fehlt in der Tier-Tafel (88 = 88, zwei Schreibweisen), Tor 57 auf 0. Elf Schreib-Rundlauf-Tests verschärft — **ohne Defekt**, die Vermutung „blind" wurde gemessen und verworfen |
192-
| 4c–10 | offen |
192+
| 4c |**PC / CP-M / Japan gemessen** (50 Dateien, 23 672 Z.) — Artefakt `memory/arch_formate_pc.md`. Ein Befund, aber ein scharfer: **P3-254** — PH-2/MF-549 entfernte **einen von fünf** gleichartigen Phantom-Headern aus einer zusammenhängenden `#include`-Gruppe und meldete den Gesamtstand; die vier übrigen (900 Z., 39 Prototypen, 0 Umsetzungen, 0 Aufrufe) stehen seit v4.1.0. `src/formats/xdf/DEFERRED.md` auf den gemessenen Stand gesetzt — der Befund war **nicht neu**, er stand seit MF-459 in `KNOWN_ISSUES` |
193+
| 4d–10 | offen |
193194

194195
**Aus Phase 1 gefallen — beide durch Lesen mit Frage, nicht durch Lektüre:**
195196

src/formats/xdf/DEFERRED.md

Lines changed: 48 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,48 @@
1-
# XDF Restore — Deferred Files
2-
3-
Two v3.7.0 XDF files were intentionally NOT restored in this pass
4-
because they depend on modules that don't exist in v4.1.x or break
5-
Windows/MinGW portability.
6-
7-
## `uft_xdf_adapter.c` (256 LOC) — deferred
8-
9-
Depends on `include/uft/core/uft_error_codes.h` (14 KB) and its
10-
companion `.c` (13 KB). Restoring those would pull a parallel error-
11-
code system into the tree, conflicting with the SSOT-error work
12-
closed by MF-003 in M1 (`data/errors.tsv``include/uft/uft_error.h`).
13-
14-
Re-implementing the adapter against the current SSOT error system
15-
is a separate task — scope: ~50 LOC of error-code remapping.
16-
17-
The adapter's header `include/uft/xdf/uft_xdf_adapter.h` is restored
18-
so consumers can see the API surface; they'll just get unresolved
19-
references until the impl lands.
20-
21-
## `uft_xdf_api_impl.c` (1088 LOC) — deferred
22-
23-
Uses `<fnmatch.h>` (POSIX) for filename-pattern matching at
24-
`uft_xdf_api.c:103` (`fnmatch(pattern, entry->d_name, 0)`). MinGW/
25-
Windows does not provide this header. Restoration requires either:
26-
27-
(a) A portable fnmatch replacement (small, ~80 LOC glob matcher)
28-
(b) `#ifdef _WIN32` guards around the fnmatch branches
29-
(c) A conditional include that falls back to our own globbing
30-
31-
The other ~1000 LOC of this file is portable and is the main
32-
catalog-of-disk-images implementation. Well worth a follow-up.
33-
34-
## Restored successfully
35-
36-
- `uft_xdf_core.c` (875 LOC) — XDF file-format reader/writer core
37-
- `uft_xdf_api.c` (910 LOC) — public API + probe functions for 6
38-
source formats (ADF, D64, IMG, ST, TRD, XDF)
39-
40-
Both compile clean under `-Wall -Wextra -Werror` after minor
41-
unused-parameter fixes that v3.7 shipped with.
1+
# XDF — Stand, gemessen (MF-959, 2026-09-08)
2+
3+
**Diese Datei stand 4½ Monate falsch.** Sie erklärte
4+
`uft_xdf_adapter.c` und `uft_xdf_api_impl.c` für *„intentionally NOT
5+
restored"* und nannte `<fnmatch.h>` als Windows-Blocker. **Am Tag nach
6+
ihrer Entstehung** lieferte `1535dfab` (2026-04-25) beides — der
7+
Commit-Titel sagt wörtlich *„fnmatch shim + xdf adapter"*.
8+
9+
`docs/KNOWN_ISSUES.md` hielt schon in MF-459 fest, das Dokument sei
10+
veraltet; korrigiert wurde es nicht. Das ist dieselbe Klasse wie MF-938:
11+
eine Behauptung wird weitergetragen statt nachgemessen.
12+
13+
## Was heute wirklich im Baum liegt
14+
15+
| Datei | Zeilen | in `SOURCES` |
16+
|---|---|---|
17+
| `uft_xdf_core.c` | 1006 | ja |
18+
| `uft_xdf_api.c` | 941 | ja |
19+
| `uft_xdf_api_impl.c` | 1124 | ja |
20+
| `uft_xdf_adapter.c` | 254 | ja |
21+
22+
Der `fnmatch`-Blocker ist gelöst: `uft_xdf_api_impl.c:39` bindet
23+
`uft/compat/uft_fnmatch.h` ein, hinter `#ifdef _WIN32`.
24+
25+
## Was wirklich offen ist
26+
27+
**Nicht die Restaurierung — die Erreichbarkeit.** Der Zweig wird gebaut
28+
und ruft niemand:
29+
30+
* die öffentliche API (`xdf_api_batch_create`, `xdf_api_batch_process`,
31+
`xdf_api_compare`) hat **null** Aufrufer in `src/` und `tests/`
32+
(ARCH-18)
33+
* `import_d64` liest D64 mit **eigener** Zonentabelle — eine zweite
34+
Format-Schicht neben dem D64-Plugin (ARCH-6)
35+
* vier Header sagen zusammen **39 Funktionen** zu, die es nicht gibt:
36+
`uft_xdf_{dxdf,pxdf,txdf,zxdf}.h`, 900 Zeilen, **0** Umsetzungen,
37+
**0** Aufrufe. `uft_xdf_api_impl.c` bindet alle vier ein und ruft
38+
keine. Sie stehen seit dem v4.1.0-Release (2026-02-08). **P3-254**
39+
ihr fünfter Bruder `uft_xdf_mxdf.h` wurde in PH-2/MF-549 aus
40+
derselben `#include`-Gruppe entfernt, die vier blieben stehen.
41+
42+
## Was hier NICHT entschieden ist
43+
44+
Ob der Zweig verdrahtet oder entfernt wird. Verdrahten hieße, eine
45+
zweite Format-Schicht scharf zu schalten, die ARCH-6 gerade abbaut;
46+
Entfernen ist ein eigener Schritt mit der MF-369-Beweispipeline. Beides
47+
gehört zu **ARCH-6**, nicht hierher. Diese Datei sagt nur noch, was
48+
gemessen ist.

0 commit comments

Comments
 (0)