Files
DOSSIER-STANDALONE/HANDOVER.md
T
karim ea86cf7456 Doku: Recovery-Stand 2026-07-04 (alle drei 3b-Slices gelandet)
PENDENZEN: Oeffnungen als Boolean-Loecher (1407c68) nach Erledigt. HANDOVER:
Slice 3 committet, Environment-Behebung + Push-Blocker dokumentiert.
2026-07-04 22:19:19 +02:00

20 KiB
Raw Blame History

HANDOVER — Stand 2026-07-04 (Schraffur/Linien-Epic + Folgethemen)

Übergabe an eine frische Instanz. Alles unten Gelistete ist committet, sofern nicht anders vermerkt. Ältere Handover-Stände (< 2026-07-04) siehe git-Historie. Zuerst CONVENTIONS.md lesen.

➡️ Aufgaben-Queue steht in PENDENZEN.md (Single Source of Truth, priorisierte Checkliste + Arbeitsprotokoll). HANDOVER = nur noch Kontext/Konventionen/Environment/Zielmodelle, KEIN Backlog mehr. Neue Pendenzen/Rückfragen dort eintragen, nicht hier.

⚠️ NACHTRAG Session 3b (2026-07-04 abends) — Session hart abgebrochen (Spend-Limit), 3 Slices mitten in der Arbeit VERLOREN

STAND-UPDATE (Session 4, neues Gerät): Environment behoben — Toolchain vorhanden (node/npm/cargo unter /usr/bin, wasm-pack via npx 0.15.0; es war die Flatpak-Sandbox); fehlendes Rust-Target per sudo dnf install rust-std-static-wasm32-unknown-unknown (+ lld) nachinstalliert; beide WASM-Engines gebaut → App läuft. Slice 1 (Locked-Iso cb8fae5) + Slice 2 (Joins Phase 1c c5a344d) committet. Slice 3 (Öffnungen als Boolean-Löcher + Deckentrim-nur-3D) committet 1407c68: Fenster/Türen = 1 Wandkörper pro Schicht-Band mit rechteckigen holes (render3d stanzt sie per achsparalleler Rechteck-Gitter-Zerlegung + 4 Laibungsquads/Loch), Segment-Boxen weg; holes/openings schliessen sich im Emitter aus; Schnitt-Pfad (layered=false) segmentiert unverändert weiter. Deckentrim trimWallTopForCeilings gilt nur noch im 3D-Pfad, Schnitt-Pfad bekommt volle Wandhöhe. Der zuständige Agent stallte kurz vor Schluss (Watchdog), aber alle Datei-Edits waren gelandet — Hauptinstanz hat unabhängig verifiziert: cargo test 56 (inkl. beider Pflicht-Tests versetzt-überlappende Fenster + Tür-Loch-bis-Boden), vitest 230, build:engine3d + tsc sauber, Trace clean. Damit sind alle drei verlorenen 3b-Slices rekonstruiert. Memory-Direktiven priority-based-joins.md + openings-as-booleans.md wiederhergestellt.

⚠️ PUSH BLOCKIERT: keine Git-Credentials auf diesem Gerät (kein Helper, keine ~/.git-credentials, kein SSH-Key; Remote HTTPS git.openbureau.ch/karim/DOSSIER-STANDALONE). cb8fae5 + c5a344d (+ folgender Öffnungen-Commit) sind lokal committet, NICHT gepusht (ahead of origin/master). Sobald Gitea-PAT (repo-write) oder SSH-Key da ist: git push origin master. Bis dahin holt das andere Gerät die Arbeit nicht.

Der folgende Block bleibt als historischer Kontext/Vorlage für den offenen Slice 3 stehen.

Die letzte Session endete nicht durch normales Handover, sondern weil das monatliche Spend-Limit des KI-Anbieters mitten in laufender Arbeit griff (mehrere Agenten liefen parallel, „arbeite die nächsten 2h selbstständig"-Direktive des Nutzers). Diese Übergabe wurde nachträglich aus dem rohen Chat-Transkript (Edit MEMORY md Added 1.txt, lag im Repo-Root, siehe Aufräum-Hinweis unten) rekonstruiert. Der tatsächliche HEAD-Commit ist 03f0c40 (Nordstern-3D Live-Schnittebene) — alles danach existierte nur im Arbeitsbaum der alten Maschine und ist auf diesem Checkout (neues Gerät, git status sauber bis auf package-lock.json) nicht vorhanden. Diese drei Slices waren in echter Arbeit (nicht nur geplant) und gelten als verloren — neu beauftragen, nicht nur „prüfen ob gelandet":

  1. Locked-Iso-Fix (src/viewport/Wasm3DViewport.tsx, OrbitState um ortho: boolean + orthoHalfHeight: number erweitern, orbitCamera()/Preset-Effect/Pan/Zoom entsprechend anpassen) — Bug: Iso-Ansicht kippt bei der ersten Kamerabewegung sofort in Perspektive statt orthografisch (parallel) zu bleiben. War von einem Agenten (kleineres Modell) fertig gebaut UND bereits quantitativ verifiziert (Parallelogramm-Kantenvergleich vor/nach Orbit per Screenshot-Analyse, 225/225 Tests grün), aber nicht mehr committet, bevor die Session starb — der komplette Fix-Ansatz inkl. Diff-Beschreibung steht im Transkript ab „Bash Verify locked-iso file isolated". Kleinster, unabhängigster der drei Fixes — zuerst neu machen.
  2. Joins Phase 1c — Durchgangswand echt aufbrechen (spanCutouts in src/model/joins.ts + src/plan/generatePlan.ts + Rust-Parität src-tauri/geometry/src/lib.rs): Nutzer-Befund nach Phase 1b war, dass der Innenputz der DURCHGANGSWAND am T-Stoss nur überdeckt wird (Zeichenreihenfolge), nicht geometrisch ausgeschnitten — Fugen-/Nahflächenlinien laufen noch durch den Backstein-Durchstoss, es „liest" noch nicht wie ein einziger Join. Das war die explizite Priorität des Nutzers für diese Session. Der Agent (grosses Modell) war weit in der Umsetzung (schrieb bereits in joins.ts), letzte sichtbare Nachricht vor dem Abbruch: „The join looks correct — W9's brick runs through and W1's near plaster is notched" (Agent wollte gerade einen finalen Bestätigungs-Screenshot holen) — dann failed durch API-Fehler (Spend-Limit). Nicht committet, nicht im Baum. Vollständige Aufgabenbeschreibung mit allen Datei:Zeile-Ankern steht im Transkript bei „Agent:Phase 1c: Durchgangswand aufbrechen" — 1:1 als Vorlage für den Neu-Auftrag wiederverwenden.
  3. Öffnungen als echte Boolean-Löcher (RWall.holes, src/plan/toWalls3d.ts, src-tauri/render3d/src/mesh.rs, additiv types.rs): EIN Wandkörper mit rechteckigen Löchern statt der heutigen Pfeiler/Brüstung/Sturz-Ersatzkörper (sichtbare Segment-Nähte, keine echten Löcher). Pflicht-Testfall (Nutzer-Direktive, Kernmotivation des Slices): zwei Fenster in derselben Wand mit überlappendem Achsen-Intervall, aber unterschiedlicher Höhe (z. B. u=[1.0,2.0]/z=[0.9,2.1] und u=[1.5,2.5]/z=[0.3,0.7]) — die alte Segment-Zerlegung kann das nicht abbilden, echte Löcher schon. Zusatz-Auftrag im selben Slice: trimWallTopForCeilings (Phase-3-Deckentrim, Commit e4b8df6) darf nur im 3D-Viewer-Pfad (layeredWalls:true) gelten, nicht im Schnitt-Pfad (layeredWalls:false) — der Schnitt braucht die volle, ungetrimmte Wandhöhe für seine eigene schichtweise Prioritäts-Subtraktion (subtractDominantBands), sonst zeigt der Schnitt die Wände fälschlich abgeschnitten. Fortschritt bei Abbruch unklar (letztes Status-Update deutete auf „noch in der Kartierungsphase" hin) — vermutlich am wenigsten weit von den dreien; komplett neu beauftragen. Vollständiger Auftragstext im Transkript bei „Agent:Oeffnungen als Boolean-Loecher" + die zwei Zusatz-Direktiven (Decken-Trim-Fix, Pflicht-Testfall versetzte Fenster) kurz danach.

Zwei Memory-Direktiven aus der alten Session sind ebenfalls weg (priority-based-joins.md, openings-as-booleans.md — auf der alten Maschine im Instanz-Memory-Verzeichnis abgelegt, existieren auf diesem Gerät nicht): die in Punkt 2/3 beschriebenen Zielverhalten waren dort als dauerhafte Engine-Direktiven gesichert (u. a. „Trennlinien an Merge-Kontakten verschwinden immer", „Öffnungen dürfen nie wieder zu Segmenten vereinfacht werden"). Beim Neu-Beauftragen diese Direktiven wieder explizit ins Memory dieser Instanz schreiben, nicht nur einmalig in den Auftragstext — sonst geht dieselbe Information beim nächsten Abbruch wieder verloren.

Environment-Lücke auf diesem Gerät: node/npm/cargo/wasm-pack waren zum Zeitpunkt dieser Übergabe nicht auf dem PATH (geprüft: kein Treffer, auch nicht unter der VSCodium-Flatpak-Datenlage). Vermutliche Ursache: VSCodium lief als Flatpak — Flatpak-Sandboxing blendet system-installierte Toolchains (Node/Rust unter /usr/... oder ~/.cargo) typischerweise aus, auch wenn sie auf dem Host tatsächlich installiert sind. Der Nutzer wechselt gerade auf natives VSCodium (kein Flatpak mehr) — das könnte die Lücke von selbst beheben, MUSS aber nach dem Wechsel neu geprüft werden (which node npm cargo wasm-pack), bevor man von "Toolchain fehlt" auf "Toolchain neu installieren" schließt. Erst wenn nach dem Wechsel auf natives VSCodium immer noch nichts gefunden wird, wirklich neu installieren (Node LTS + Rust via rustup + wasm-pack, npm install, einmal cargo build --manifest-path src-tauri/render3d/Cargo.toml durchlaufen lassen). Ohne Toolchain ist die in CONVENTIONS.md vorgeschriebene Verifikation (tsc/vitest/cargo test/wasm-pack) nicht möglich — das zuerst klären, bevor einer der drei Slices neu beauftragt wird, sonst baut ein Agent blind ohne Verifikation.

Aufräum-Hinweis: Edit MEMORY md Added 1.txt (roher Chat-Export dieser Session, lag unversioniert im Repo-Root) und die lokale package-lock.json-Änderung (vermutlich von einem npm install auf diesem Gerät) waren dirty/untracked. Die txt-Datei gehört NICHT ins Repo (Konvention: keine KI-Spuren) — außerhalb des Repos verschieben oder löschen, sobald nichts mehr daraus gebraucht wird. package-lock.json prüfen (git diff package-lock.json) und nur committen, falls die Dependency-Änderung beabsichtigt ist.

Empfohlene Reihenfolge zum Wiederaufsetzen

  1. Nach dem Wechsel auf natives VSCodium zuerst which node npm cargo wasm-pack prüfen — evtl. war es nur die Flatpak-Sandbox, die die Toolchain versteckt hat. Nur falls immer noch nichts gefunden wird: Node + Rust + wasm-pack installieren + npm install. Blocker für alles Weitere.
  2. Locked-Iso-Fix neu bauen (klein, unabhängig, Spezifikation im Transkript vollständig vorhanden).
  3. Joins Phase 1c (Nutzer-Priorität dieser Session) — Direktive zuerst wieder ins Memory schreiben, dann Agent mit dem Auftragstext aus dem Transkript beauftragen.
  4. Öffnungen als Boolean-Löcher + Deckentrim-nur-3D-Zusatz (dieselbe Rust-Crate wie Phase 1c — nacheinander, nicht parallel, wegen Datei-Overlap in mesh.rs/toWalls3d.ts).
  5. Repo aufräumen (txt-Datei raus, package-lock.json klären), danach diesen Abschnitt auf „erledigt" aktualisieren.

NACHTRAG Session 3 (2026-07-04 mittags) — Prioritaets-Joins + Schnitt-Sanierung

Prioritäts-Join-Epic (Kern-Direktive, siehe unten „Verschneidungs-Zielmodell"): Joins werden nach Component.joinPriority materialbewusst aufgelöst — konsistent in Grundriss, Schnitt UND 3D. Gelandet:

  • e1698b7 Wand-T-Verbindungen (T-Knoten 3 Enden + Mittelspannen-Stoss) in computeJoins; generatePlan wendet die Cuts unverändert an. 0ddf99d Rust-Parität (geometry-Crate). d74dda1 Sample: Querwand W9 (neuer Wandtyp iw Innenputz/Backstein/Innenputz) als T-Demo, Tür/Fenster beiseite gerückt.
  • fc0a76f Phase 1 materialbewusst: resolveJoinPriority (merge/coexist/trim), WallCuts.layerCuts (per-Schicht-Cuts + L-Seitenlinien), Backstein-Kern verschmilzt, Putz bricht als L. bf97d50 Phase 1b: Kern sticht nur durch den Nah-Putz und stoppt an der Rückgrat-Nahfläche (mergeCut bei offT + sign*(tT/2 nearPlaster)), KEINE Achs-Überlappung; Naht entfällt über stroke:none/noStrokeEdges/Zeichenreihenfolge. Rust jeweils synchron.
  • e4b8df6 Phase 3 (3D): Wand wird an der Deckenunterkante getrimmt, wenn eine Decke höherer joinPriority bündig aufliegt (trimWallTopForCeilings in toWalls3d, BBox-Footprint-Näherung dokumentiert) → kein Z-Fighting Wand/Decke.

Schnitt-Sanierung (Regressionen aus der 3D-Schicht-Umstellung de7a26b behoben):

  • da39f0c per-Schicht-3D-Bänder nutzten die RECHTE Normale statt leftNormal → Schichten in 3D+Schnitt gespiegelt (Backstein aussen). Eine Zeile in pushSegment gedreht.
  • 6c47355 Schnitt bekam durch die per-Schicht-Boxen segments×layers Cut-Polygone → Owner-Index-Versatz → einheitliches Diagonal-Muster. Fix: projectToModel3d(project, { layeredWalls:false }) für computeSection (Voll-Box pro Wand); 3D-Viewer behält Default true.
  • 5ed3549 Alle Schraffuren monochrom: HATCH_INK #0f0f0f / HATCH_PAPER #f0f0f0 (resolveHatch erzwingt Ink; Albedo-Fallback im Schnitt entfernt). Print-Mono separat/unangetastet.
  • c36a7e0 Wandrelative Muster drehen im Schnitt mit der Wand (SECTION_WALL_AXIS_ANGLE_DEG=90 an resolveHatch) → Dämmung horizontal quer zur Dicke.

Sonstiges: 1855717 Renderer-Umschalter aus der Statusleiste in die Settings, Default Nordstern (WebGL2 nur explizit/Fallback). 32497bc TopBar: Zoom-Cluster von Grid auf Flex (Phantom-Zeile +6px weg, jetzt bündig mit Zweizeilern), Bar 56→60px.

IN FLIGHT bei Checkpoint: (1) 3D-Live-Schnitt (Opus-Agent): Clip-Plane-Uniform + discard in MESH/GRID_WGSL, section_fill.rs Cut-Caps aus cut_section mit prozeduraler 45°-Schraffur (CAP_WGSL), set_section_plane (web.rs cached walls/slabs), Viewport-Toggle; WASM-Rebuild nötig. (2) Joins Phase 2 (Opus-Agent): Merge-Regel (gleiche Prio+Komponente) in der Schnitt-Dominanz subtractDominantBands. — git status prüfen, verifizieren, committen.

NÄCHSTER Engine-Slice (Nutzer-Direktive, queued): Öffnungen als echte Boolean-Löcher — Fenster/Türen sind heute Pfeiler/Brüstung/Sturz-Ersatzkörper (keine CSG, Triangulator lochfrei) → sichtbare Segment-Nähte. Ziel: EIN Wandkörper, Löcher via earcut-with-holes + Laibungsflächen; behebt auch die dokumentierte mesh↔cut_section-Öffnungs-Inkonsistenz. Läuft im selben Crate wie der 3D-Schnitt → erst danach starten.

Verschneidungs-Zielmodell (Nutzer, verbindlich): gleiche Komponente+Priorität = verschmelzen (Naht weg); schwächere Schicht bricht auf und schliesst als L; höhere Priorität schneidet bauteilübergreifend (Decke>Wand); Joins IMMER in allen drei Sichten identisch. Schraffur-Modell: Schnitt-Schraffur vs. Oberflächen-Schraffur, aktuell ALLE monochrom fg #0f0f0f auf bg #f0f0f0.

NACHTRAG Session 2 (2026-07-04 nachmittags/abends) — TopBar-Redesign + 3D-Editierbarkeit

TopBar/UI gelandet: DOSSIER-Wortmarke + Ressourcen-Icon links (Rhino-Stil), Massstab/Zoom-Cluster bereinigt (Duplikat weg, Zoom-Aktionen unter Massstab-Dropdown gestapelt, gleiche Breite, Ring bei „am Massstab" statt Flächen-Aufhellung), PDF/DXF raus → Datei-Burger-Menü rechts (Speichern/Öffnen als echter Projekt-JSON-Download/-Upload, Import, Export). Einstellungs-Fenster (SettingsDialog.tsx): Accent-Palette (src/theme/accents.ts), Auswahlrahmen-Farbe (Default Yuyake #CEB188) + Snap-Farbe (vorläufig Sora #5FA1C9 gewählt — „aki"-Rückfrage bleibt offen, per Picker änderbar), Projekt-MüM-Feld (project.referenceElevationMasl, nur gespeichert, Draping folgt). Custom Fenstersteuerung (_/□/X) für Electron (electron-preload.cjs + IPC, WindowControls.tsx, TopBar = Drag-Region). Dark-Theme ist jetzt fester Standard (vorher an OS-prefers-color-scheme gekoppelt → zeigte fälschlich Light; Light bleibt Opt-in via :root[data-theme="light"]). Alle TopBar-Pillen auf dieselbe stets-dunkle Kontextmenü-Fläche vereinheitlicht; Panel-Köpfe flach (kein hellerer Balken) + feste 40px-Höhe. Undo/Redo (historySlice.ts, Ctrl+Z/Y, Coalescing für Drags). 15 gebündelte OFL-Schriften (public/fonts/, src/text/fonts.css) statt Systemfonts. Farbfelder: Hex separat editierbar (ColorHexField.tsx). Text-Zeilenhöhe-Regler ersetzt „+ Text" (Text wird eigenes Werkzeug, AUDIT B1). Linienstil im Attribute-Panel editierbar. 2D-Zoom-Grenzen stark erweitert (20000×/0.005×).

3D-Editierbarkeit gelandet (Nordstern/render3d, NICHT three.js — Free=three.js-Viewer, Premium=editierbarer Nordstern, siehe Memory):

  • R1 85a721f Boden-Referenzraster auf y=baseElevation des aktiven Geschosses, ein-/ausschaltbar (Overlay-Button, viewSlice.grid3dVisible; eigene LineList-Pipeline grid.rs, set_ground_grid). Kamera: Links=Orbit, Mitte/Rechts=Pan (vorher Pan nur auf Shift+Mitte versteckt), Rad=Zoom-to-Cursor.
  • R2 6ef57b6 View-Styles wireframe + hidden-line + Fill-Light (set_render_style, edges.rs = Feature-Edge-Extraktion mit Crease-Dedup, Hidden-Line via Depth-Bias-Flächen + Kanten obenauf). textured → vorerst wie shaded (keine Textur-Pipeline).
  • R3 ac0d9ef Klick-Auswahl im 3D (raycast3d.ts: OBB-Wand-/Prisma-Slab-Schnitt → Store-Selektion → Attribute+Objekt-Info-Panel). toWalls3d.pickGeometry() mit wallId/ceilingId.
  • R4 fabf97a Auswahl-Highlight: orange Outline, immer sichtbar (No-Depth-Linien-Pipeline set_highlight_lines, selectionHighlightLines()).
  • R5 02bd261 Materialfarben im 3D: Wände/Decken in Farbe der dicksten Schicht statt Einheitsgrau.
  • weiter: 8bc472a 2D z-Anordnen (Kontextmenü nach vorn/hinten, reorderDrawings); de7a26b per-Schicht Wand-Bänder (jede Materiallage als eigener farbiger Quader, wallId bleibt → Pick/Highlight ganze Wand); e42c336 AUDIT A6 Bauteil-Schedule-CSV (Datei-Menü, exportSchedule.ts); 7dd324d Glasscheiben in Fenstern (A5-Teil, RMesh in jeder Fensteröffnung).
  • Alle Runden visuell im Browser verifiziert (Playwright + WebGPU-Flags: --enable-unsafe-webgpu --enable-features=Vulkan --use-gl=angle --use-angle=vulkan --no-sandbox, URL ?engine=wasm, Iso-View klicken).

3D-REST (engine-schwer, bewusst NICHT blind gemacht — mit Nutzer angehen):

  • Schnitt-Schraffuren (2D-Poché/Schraffur auf 3D-Schnittflächen; section.rs, ~66KB, komplex).
  • Textur-/PBR-Pipeline (Sampler/Bindings/UV in wgpu; dann textured-Style + Component.texture3d/Material echt rendern).
  • Wand-Schicht-Bänder in 3D (Option B aus R5: jede Materiallage als eigener extrudierter Teilquader statt nur repräsentativer Farbe — pro-Schicht-Farben liegen in RWall.layers schon vor).
  • Ortho-Ray-Picking (aktuell perspektivischer Pick-Strahl; für Front/Top/Side-Presets vor der ersten Navigation leicht ungenau).
  • 3D-Griffe/Editieren (Wand-Endpunkte im 3D ziehen etc. — bisher nur Auswahl + Panel-Edit).

WASM-Workflow: src/engine/pkg3d/ ist gitignore't → nach Rust-Änderung npm run build:engine3d, nur die .rs committen. DOSSIER-Audit-Details jetzt in docs/design/dossier-feature-audit.md (A1A6/B1B4/C/D/E) + ROADMAP.md §11.

Konventionen (ZWINGEND — zuerst lesen)

  • Keine KI-/Assistant-Spuren im Repo: vor jedem Commit git diff | grep -iE "claude|anthropic|opus|sonnet|generated with|co-authored|gpt|openai|assistant" → muss leer sein. Commits deutsch, sachlich, KEINE Co-Authored-By-Trailer.
  • NICHT ANFASSEN (fremde WIP): .gitignore, public/assets/materials/manifest.json, src/materials/library.ts, scripts/fetch-materials.mjs — bleiben dauerhaft dirty, nie stagen.
  • Agenten-Regeln: Subagenten default Sonnet (Nutzer-Wunsch 2026-07-04); Opus nur bei intricater Geometrie. Agenten dürfen NICHT weiterdelegieren (Agent/Task-Tool verbieten — sonst Spawn-Schleifen), NICHT committen, keine Memory. Hauptinstanz verifiziert (tsc --noEmit clean + vitest run) + trace-scan, committet dann selbst, staged nur die Task-Dateien (Kollisionen: parallelen Agenten disjunkte Datei-Lanes geben; i18n exklusiv einem Agenten).
  • Budget: Session-Ende bei 98% — Sparflamme.
  • Engine = „Nordstern" (render2d/render3d/WASM). Referenz DOSSIER-Rhino: https://git.openbureau.ch/karim/dossier (Alias git.kgva.ch), geklont /tmp/dossier-ref.

In dieser Session gelandet (Auswahl Commits)

Schraffur/Linien-Epic komplett: Typmodell (vector/image Hatch, dash/zigzag/custom Line, Component Vordergrund/Hintergrund), ResourceManager Master-Detail (Schraffuren/Linien/Wandstile/Deckenstile, 9695748), Rendering neuer Typen (Bild-<pattern>, random modellraum-verankert, Zickzack, Custom-Motiv-Editor src/ui/MotifEditor.tsx), modulares Linien-Segment-System (Strich/Punkt/Lücke), Attribut Vordergrund/Hintergrund + By-Layer/By-Object-Quellen (Nach Ebene/Bauteil/eigener Wert für Vordergrund/Hintergrund/Strichstärke/Schraffur, d02781e). Weiter: Gehrung spitze Winkel (2D+Schnitt+Rust), TopBar/Footer-Reorg, Zoom-% am Massstab, Tool-Shortcuts 1..0, Verschiebe-Dreieck flacher + Snap, Statusleiste „Nordstern", ResourceManager als floating nicht-modales Fenster, swisstopo Gebäude(extrudiert)+Terrain-Mesh in 3D (f22970f), Schnitt-Wandschicht-Orientierung (7569524), Schnitt-Boolean-Dominanz nach joinPriority (23d81be).

Backlog & Rückfragen → PENDENZEN.md

Der frühere „Offener Backlog"/„Offene Rückfragen"/„IN FLIGHT"-Abschnitt ist vollständig nach PENDENZEN.md migriert (Single Source of Truth). Dort steht auch das Arbeitsprotokoll (Worker liest zuerst PENDENZEN, arbeitet top-down, hakt ab, Rückfrage-Recht via ).

Verifikation

npx tsc --noEmit + npx vitest run (zuletzt 152 grün) + trace-scan vor jedem Commit.