Files
DOSSIER-STANDALONE/HANDOVER.md
T
karim 35299307d6 Akkumulierten grünen Arbeitsstand landen (Basis für Weiterarbeit)
Bündelt den über mehrere Sessions gewachsenen, uncommitteten Stand in
einem Basis-Commit, damit Folge-Features isoliert darauf aufsetzen.
Verifikation: tsc --noEmit sauber, vitest 600/600 grün.

Enthalten (Details in PENDENZEN.md -Liste / HANDOVER.md):
- truck-Integration: Profil-Extrusion + Verjüngung + Boolean-CSG (csgrs),
  Crate src-tauri/trucksolid, Werkzeug `extrude`, ExtrudedSolid-Modell.
- kernel2d-Port nach Rust/WASM (Phasen 1–5, Diff-Harness).
- render3d 3D-Live-Schnitt = 2D-Schnitt: geschichteter Bodenaufbau,
  Prioritäts-Verschneidung (section_boolean.rs), einstellbare
  Schichttrennlinien, per-Hatch-Strichstärke, relativeToWall-Orientierung.
- Interop-Export IFC4/STL/OBJ (Loch-Ausschnitt wallMeshCut), Schnellexport.
- Projektdatei .obp + OS-Lock (lock.rs, LockConflictDialog).
- Layout-Blätter (Modell/Editor/Panel/PDF), Ausschnitte, Override-Engine,
  Tragwerk-Stützen (Column), BIM-Tree-Panel.
- Bauteil-Typsystem (Tür/Fenster/Treppe-Typen), Betontreppe mit schräger
  Laufplatte, Text-/Textbox-Werkzeug, Mess-Werkzeug, 2D/3D-Griffe für
  Öffnungen/Treppen, Snap-Symbol-Restyle.
2026-07-09 00:57:29 +02:00

34 KiB
Raw Blame History

HANDOVER — Stand 2026-07-08 spät (Schnitt-Parität + Projektdatei, ALLES uncommittet)

Fortsetzungs-Session (nach dem älteren 2026-07-08-Handover weiter unten). Alles uncommittet. Schwerpunkt: 3D-Live-Schnitt = 2D-Schnitt + eigene Projektdatei.

Verifikations-Baseline (zuletzt grün)

npx tsc --noEmit sauber · npx vitest run 588 · cargo test -p render3d --features render 76 · cargo check --features native3d grün · WASM npm run build:engine3d neu gebaut (nötig nach Rust/WGSL-Änderungen). Vor Weiterarbeit einmal tsc+vitest neu fahren.

Was diese Session gebaut wurde

  • 3D-Live-Schnitt = 2D-Schnitt (Kernfunktion): (a) 45°-Schraffur-Verdrehung gefixt (Shader auf 2D-parallelLines-Konvention kalibriert, angle 0 = horizontal); (b) geschichteter Bodenaufbau (Decke per-Schicht statt Einkörper, emitSlabs); (c) Prioritäts-Verschneidung von 2D nach Rust portiert (section_boolean.rs = Port von subtractDominantBands/subtractRect; Bänder tragen join_priority via CutBandMeta); (d) collectCeilingCutters emittiert per-Schicht-Cutter → Backstein (50) schneidet Estrich/Dämmung (30/20) korrekt weg, nur Beton (100) kappt ihn; (e) einstellbare Schichttrennlinien aus jointLineStyleId; (f) Schraffur-Strichstärke pro Hatch aus deren lineStyleId (hatch-hair 0.02 / thin 0.13); (g) relativeToWall-Orientierung: Boden-Dämmung vertikal, Wand horizontal (via resolveHatch(axisAngle) wie 2D). Betrifft src-tauri/render3d/src/{shaders,gpu,section,section_fill,section_boolean,types}.rs + src/plan/toWalls3d.ts. native.rs WallInput-Literal um die additiven Felder ergänzt.
  • Projekt als Einzeldatei .obp („openbureau project"): src/io/projectFile.ts (PROJECT_EXT, nativer Öffnen/Speichern-Dialog, alte .json weiter ladbar) + OS-Lock gegen Doppelöffnung (src-tauri/src/lock.rs, fs4 exklusiver flock über gehaltenes Handle → Auto-Freigabe bei Absturz/Exit; LockConflictDialog). QA: Lock-Logik korrekt, einzige Lücke: „schreibgeschützt" == „erzwingen" auf Datenebene (kein app-weiter Read-only-Modus).
  • Identität: Open-Source-CAAD statt „BIM für Wohnbau"; about.desc (de/en) + README + package.json (license: AGPL-3.0-or-later, author). LICENSE-File fehlt noch (README verlinkt darauf) — offizieller AGPL-Text muss rein (nicht fabrizieren; curl gnu.org/licenses/agpl-3.0.txt). About-Dialog-Umbruch gefixt (.about-dialog { white-space: normal } — er erbt nowrap von .topbar).
  • 2D: Text-Platzierungswerkzeug als 2D-Element (text-Command + Freitext-Eingabe in der Command-Engine); 2D-Zeichenwerkzeuge auf "drawing"-Ebenen freigegeben (ToolsPanel-Gating = floorOnly, Parität mit Ribbon).
  • Teil B — 2D-Annotationen auf Layout-Blättern: LayoutAnnotation (line/rect/text in mm) + CRUD (layoutModel.ts) + Editor in LayoutSheet.tsx (zeichnen/selektieren/verschieben/löschen, PromptDialog für Text) + layoutSheetMath.ts (Hit-Tests). Bewusst ohne: Resize-Griffe, Text-Rotation, Snapping.

Offene Fäden

  1. Idee 1 — per-Wand „an Decke enden" (Terminierung ≠ Priorität): AGENT LÄUFT gerade (per-Wand sliceTermination, Default off). Details/Design im Memory design-schicht-verschneidung-3d-schnitt.md. Idee 2 (Schichteinzüge, per-Schicht Endversätze) = größeres Folge-Feature, noch nicht gebaut.
  2. Ressourcen-Fenster als eigenes OS-Fenster (Nutzer-Wunsch): machbar (Tauri WebviewWindow + BroadcastChannel-Sync, „Ausklappen"-Button, Browser bleibt intern). Noch NICHT gebaut — braucht Store-Sync-Architektur-Entscheidung.
  3. Visuelle Tauri-Abnahme aller 3D-Schnitt-Änderungen steht aus (render3d nur naga-validiert + WASM gebaut; Nutzer testet selbst). Der Backstein hat prioritäts-korrekt noch ein Stück oberhalb des Betons — das ist Idee 1 (Option), nicht ein Bug.
  4. Konventionen: wie immer — keine KI-Spuren, nicht committen, disjunkte Agent-Lanes, echte Eigenschaft prüfen (nicht nur grüne Tests).

HANDOVER — Stand 2026-07-08 (Account-/Instanzwechsel, ALLES uncommittet)

Übergabe an eine frische Instanz (Nutzer wechselt Account, Budget aufgebraucht). Alles unten ist UNCOMMITTET (Bearbeiter committet nie selbst). Zuerst PENDENZEN.md lesen (Single Source of Truth, -Erledigt-Liste + offene Items ganz konkret). Diese Session war eine sehr lange Feature-/Fix-Serie mit vielen Sub-Agents.

Verifikations-Baseline (zuletzt grün)

npx tsc --noEmit sauber · npx vitest run 491/491 · cargo check --manifest-path src-tauri/Cargo.toml grün · vite build OK. (Der letzte Layout-Viewport-Agent meldete 491; nach dem interaktiven Ausschnitte-Fix waren es 465 → 491 ist der aktuelle Stand nach dem Layout-2b-Agenten.) Vor Weiterarbeit einmal tsc+vitest neu fahren, da alles uncommittet nebeneinander liegt.

Was diese Session gebaut wurde (alles in PENDENZEN dokumentiert)

  • Interop-Export: IFC4 (exportIfc.ts, jetzt IfcTriangulatedFaceSet mit ausgeschnittenen Fenster/Tür-Löchern + SOLIDE Wände — Winding-Fix), STL+OBJ (exportMesh.ts), gemeinsamer Loch-Ausschnitt src/plan/wallMeshCut.ts (Port von render3d extrude_layer_segment_with_holes, isWatertight via Gauss/Volumen). Schnellexport-Dialog (ExportSaveDialog, Format+Name).
  • Nativer Speichern-Dialog: Tauri plugin-dialog+plugin-fs (Cargo/lib.rs/capabilities), src/io/saveFile.ts (saveTextFile: nativ unter Tauri, Blob-Fallback im Browser). App.tsx downloadTextFilesaveTextFile.
  • Ausschnitte (View-Snapshots) Phase 1: Project.viewSnapshots, state/viewSnapshots.ts, ViewSnapshotsPanel (Speicher-Fix: Inline-Input statt window.prompt).
  • Layout-Blätter Phase 2a+2b: Modell Layout/LayoutViewport/MasterLayout (Project.layouts/masterLayouts), In-Viewport-Editor (activeLayoutId in App.tsx → LayoutSheetView/LayoutSheet.tsx, Maus-Editing, layoutSheetMath.ts), LayoutsPanel. Floating LayoutEditor wurde ersetzt.
  • Tragwerk-Stützen: Column/ColumnProfile, geometry/column.ts, Platzieren/2D/3D/Selektion/Attribute/move.
  • Weiteres: A1 Override-Regel-Engine, kernel2d Phase 5 komplett, Bauteil-CSV volles Element-Set, SIA-416 AGF, Kamera-Presets Kardinal+Iso, Decken-UK/OK, BIM-Tree-Panel, ObjectInfo-Volumen, Basis-Material-Texturen, OSM 7 Kat., IndexedDB-Kern, Rich-Text super/sub, Auto-Zoom-Geo, Raumstempel Personen/Rundung, diverse TopBar-Feinschliffe (Export-Sammelmenü, Über-Dialog, Petrol-Punkt, Detailgrad+Darstellung gestapelt, Arbeitsumgebung in Settings).

⚠️ WICHTIG / offene Fäden (Details in PENDENZEN, Abschnitt „In Arbeit"/oben)

  1. NOCH NICHTS VISUELL IN TAURI ABGENOMMEN: IFC/OBJ/STL-Geometrie, nativer Speichern-Dialog, Layout-im-Viewport, Ausschnitte — alle agent-/testverifiziert, aber der Nutzer hat sie im laufenden Fenster noch NICHT gesehen. Tauri-Dev NEU STARTEN (npm run tauri:dev, ggf. Vite separat auf Port 5187 — es gibt KEIN beforeDevCommand) wegen der neuen Rust-Plugins.
  2. window.prompt/confirm-SWEEP: in Tauri-WKWebView DEAKTIVIERT (→ null). Gefixt: ViewSnapshotsPanel, LayoutsPanel. NOCH betroffen: ComboMenu (Kombinationen speichern), TopBar Massstab „frei" (topbar.scale.prompt), evtl. weitere. Grep window.prompt|window.confirm über src/, alle auf Inline-Eingaben umstellen.
  3. NÄCHSTES GROSSES ITEM (fertig gescoped, war startbereit als Opus-Agent): „Layouts als Ordner-/Baumstruktur" — voller Auftrag steht in PENDENZEN (Ordner-Baum, ein „+" für Ordner/Layout/Masterlayout, Inline-Rename, Layout-Erstell-Dialog mit Master-Vorlage/freie Grösse, Masterlayout mit Grössenwahl, Ordner→Mehrseiten-PDF). Direkt umsetzbar.
  4. Konventionen: keine Fremd-Tool-Spuren/Co-Authored-By im Repo; Sub-Agents in disjunkte Datei-Lanes schicken (i18n de.ts/en.ts + App.tsx sind Hotspots → exklusiv EINEM Agent pro Welle, sonst NUL-Byte-Kollision); grüne Tests NICHT als alleinigen Beweis nehmen (echte Eigenschaft prüfen — z. B. beim IFC-Solidity-Fix war der naive Manifold-Test falsch, Gauss/Volumen war richtig).

HANDOVER — Stand 2026-07-07 abends (Instanzwechsel, alles uncommittet)

Übergabe an eine frische Instanz (Nutzer wechselt bewusst die Instanz). Alles unten Gelistete ist NOCH UNCOMMITTET — Bearbeiter committet laut Arbeitsprotokoll nicht selbst. Zuerst CONVENTIONS.md + PENDENZEN.md lesen (dort steht die volle, aktuelle Aufgaben-Historie inkl. aller Details der truck-Integration/Deep-Review-Fixes unten — hier nur die Kurzfassung + der offene Faden).

Sofort-Kontext für die neue Instanz

Environment: macOS-Gerät, Toolchain vollständig (node/npm/cargo/wasm-pack), npm run tauri:build läuft. Kein Blocker.

Verifikations-Baseline (zuletzt geprüft, alles grün): npx tsc --noEmit sauber · npx vitest run 341/341 · cargo test in src-tauri/trucksolid 15/15 · cargo test --manifest-path src-tauri/Cargo.toml -p render3d 58/58.

Was in dieser Session geschah (chronologisch, Details je in PENDENZEN.md „truck-Integration" Phase 5 / Backlog):

  1. Vorherige Session ist wegen RAM-Absturz des Geräts abgebrochen (lief eine LOKALE LLM auf dem Laptop, nicht diese Instanz) — Stand war: truck-Integration Phasen 14 fertig (Extrusion + Verjüngung/Taper + Boolean-CSG via csgrs), aber noch uncommittet.
  2. Diese Instanz hat den übernommenen Stand deep-reviewt (8-Winkel-Review: Korrektheit/Reuse/Simplify/Efficiency/Altitude/Conventions) und mehrere echte Bugs gefunden + gefixt — volle Liste in PENDENZEN.md unter „truck-Integration" → „Deep-Review + Fixes (2026-07-07)": konkave Profil-Triangulierung (Fächer→Ohr-Clipping), 6 fehlende Selektions-Resets für Extrusionen, Mirror/Copy ignorierten Extrusions-Auswahl, DXF-Export verlor den Layer, truckMeshCache-Leak + Flacker-Bug, unnötige fitTargetDist-Neuberechnung, fehlende i18n (Schnittebene-Button + Farbwähler-Tooltip).
  3. Danach auf Nutzer-Wunsch eigenständig durch PENDENZEN.md gearbeitet (nur unblockierte Items, keine Design-Entscheidungen geraten): Ortho-Ray-Picking gefixt (cameraRay in src/viewport/raycast3d.ts konnte nur perspektivisch — jetzt echte parallele Strahlen bei perspective:false, rückwärtskompatibel; +2 Tests). Siehe PENDENZEN.md „3D-REST" Abschnitt.

ERLEDIGT 2026-07-07 (Folge-Instanz) — Bauteil-CSV volles Element-Set (D2, vertieft A6), umgesetzt exakt nach dem Scope unten; Treppen-Fläche = null (leer), Aggregat-Zellen leer statt 0.00. Details/Status in PENDENZEN.md „ Erledigt".

src/export/exportSchedule.ts deckt aktuell nur Wand + Decke ab (Muster: evalWall/evalCeilingScheduleRow, siehe Datei). PENDENZEN-Backlog-Item „AUDIT (DOSSIER-Studie)" nennt D2 = „Bauteil-CSV mit vollem Element-Set". Ich habe das untersucht und bewusst gescoped, aber NICHT umgesetzt (Instanzwechsel kam dazwischen) — der Datei-Zustand ist unverändert/clean (ein Testballon-Import wurde wieder entfernt, tsc ist grün). Damit die nächste Instanz nicht neu recherchieren muss, hier die bereits getroffenen, gut begründeten Scope-Entscheidungen:

  • Aufnehmen: Door (Tür), Opening (kind="window"→Fenster, kind="door"→Öffnung), Stair (Treppe), ExtrudedSolid (Extrusion, aus der truck-Integration).
  • NICHT aufnehmen: Room — Räume haben bereits einen eigenen, dedizierten CSV-Export (roomsToCsv in src/geometry/roomArea.ts, SIA-Flächenbilanz-Spalten). Eine zweite Raum-Zeile in der allgemeinen Bauteilliste wäre Duplikation.
  • Spalten-Mapping (bestehende feste Header „Länge/Höhe/Dicke/Fläche" — nur dort füllen, wo eine Ableitung wirklich verlässlich ist, sonst leer lassen wie es evalCeiling heute schon für Decken macht):
    • Door/Opening: length = width (lichte Breite), heightM = height, thickness = null (keine sinnvolle Entsprechung), area = width * height. Geschoss auflösen über hostWallIdproject.walls.find(w => w.id === hostWallId)?.floorId (neuer kleiner Helper nötig, Wand evtl. verwaist behandeln wie bei evalWall/evalCeiling).
    • Stair: length = runLength + (run2Length ?? 0) (Näherung, bei Wendel evtl. wenig aussagekräftig — akzeptabel, da nur „verlässlich Ableitbares" Anspruch gilt), heightM = stair.totalRise ?? null (KEINE Geschosshöhen-Fallback-Auflösung nachbauen — Kopplung/Risiko vermeiden), thickness = null, area: noch nicht entschieden — eine echte Footprint-Fläche bräuchte geometry/stair.tss stairGeometry() (Kopplung an Geschoss-Höhen-Fallback) → einfachster sicherer Weg ist vermutlich area = null lassen (ehrlich statt erfunden), aber nochmal gegen die bestehenden Tests/Konventionen prüfen, bevor final entschieden wird.
    • ExtrudedSolid: typeName = "Extrusion", Geschoss über levelId, length = null, heightM = solid.height, thickness = null, area = polygonArea(solid.points) (Import aus geometry/roomArea.ts, bereits im File importiert).
    • Neue kind-Werte in ScheduleRow/TypeAggregate: "Tür" | "Fenster" | "Öffnung" | "Treppe" | "Extrusion" zusätzlich zu "Wand" | "Decke".
  • Aggregat-Zeile (aggregateByType/Summary-Block): die bestehende Zeile fmtNum(agg.kind === "Wand" ? agg.totalLength : null) sollte verallgemeinert werden zu agg.totalLength > 0 ? fmtNum(agg.totalLength) : "" — dann zeigen Tür/Fenster/Öffnung/Treppe (die jetzt auch eine length-Spalte befüllen) automatisch korrekt eine Summe, während Decke/Extrusion (deren length immer null→0 bleibt) weiterhin korrekt leer bleiben. Kein Sonderfall pro Kind nötig.
  • Tests: src/export/exportSchedule.test.ts folgt einem klaren fixtureProject()-Muster (2 Wände + 1 Decke) — beim Erweitern eine Tür/ein Fenster/eine Treppe/eine Extrusion in die Fixture aufnehmen und je einen Zeilen-Assert wie bei den bestehenden Wand-/Decken-Zeilen ergänzen.
  • Warum nicht in dieser Session fertig: Instanzwechsel kam mitten in der Umsetzung. Kein Blocker, keine Nutzer-Entscheidung nötig — reine Fleissarbeit nach obigem Schema, dann tsc/vitest grün prüfen und in PENDENZEN.md abhaken.

Aus dieser Session bewusst NICHT angefasst (recherchiert, aber zu unsicher/blockiert)

  • Treppe Pfeil-Style „filled" + Tür swing_invert/aussenseite (PENDENZEN „BAUTEILE… Gruppe B"): die Referenzquelle (/tmp/dossier-ref/rhino/*.py) existiert auf diesem Gerät/dieser Session NICHT (geprüft, find liefert nichts) — ohne das exakte Rhino-Verhalten zu kennen, wäre die visuelle Ausgestaltung geraten. Nicht angefasst, um nicht falsch zu raten.
  • E2b Schraffur-Kachel-Motiv: MotifEditor (src/ui/MotifEditor.tsx) wird schon für Linienstil-Motive wiederverwendet (1D, entlang einer Linie) — ein Flächen-Kachel-Motiv für HatchStyle wäre ein NEUES Datenmodell (2D-Tile-Grid), kein reines Wiederverwenden. Braucht eigentlich einen Scope-Entscheid.
  • Alles, was in PENDENZEN.md explizit „Mit Nutzer klären"/„Nutzer-Entscheid nötig" trägt (Ribbon 3D-Tab, kernel2d Phase 6, Feld-Controller, Schnitt/Ansicht Phase 3, Teamwork-Granularität, Geo-Block-Priorität, Textur-Pipeline-Scope, STRATEGIE-Priorisierung, Bildschraffur-Freigabe) — bewusst übersprungen, nicht neu bewertet.

Wichtige Memory-Notiz (persistiert, gilt für zukünftige Instanzen dieses Repos)

Der Nutzer lässt teils eine lokale LLM auf seinem Laptop autonom an diesem Projekt arbeiten (kann abstürzen, z. B. RAM). Deren Output sah in dieser Session strukturell sauber + gut getestet aus, enthielt aber einen echten geometrischen Bug (Fächer-Triangulierung bricht bei konkaven Profilen), den die eigene Testsuite NICHT gefangen hatte (Tests prüften nur Form/Anzahl, nicht geometrische Korrektheit). Bei Übernahme von Arbeit aus solchen Sessions: grüne Tests allein NICHT als Beweis nehmen, gezielt nachprüfen ob die Tests die richtige Eigenschaft testen.


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 2026-07-04 abends — Unterbruch, 3 Slices 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. Alle Datei-Edits waren gelandet — 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 Arbeit wurde unerwartet unterbrochen — mehrere Tasks liefen parallel. Diese Übergabe wurde nachträglich 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 fertig gebaut und quantitativ verifiziert (Parallelogramm-Kantenvergleich vor/nach Orbit, 225/225 Tests grün), aber nicht mehr committet, bevor der Unterbruch kam. 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. Die Umsetzung war weit fortgeschritten (schrieb bereits in joins.ts), dann abgebrochen. 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 Engine-Direktiven vom alten Stand fehlen (priority-based-joins.md, openings-as-booleans.md): die in Punkt 2/3 beschriebenen Zielverhalten waren 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 festhalten.

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 (lag unversioniert im Repo-Root) und die lokale package-lock.json-Änderung waren dirty/untracked. Die txt-Datei gehört nicht ins Repo — außerhalb verschieben oder löschen. 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 Fremd-Tool-Spuren im Repo: vor jedem Commit Trace-Scan (git diff | grep -iE "co-authored|generated with") → 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.
  • Verifikation: tsc --noEmit clean + vitest run + trace-scan vor jedem Commit. Nur Task-Dateien stagen (Kollisionen: parallele Tasks disjunkte Datei-Lanes geben; i18n exklusiv einem Task).
  • 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.

Verifikation

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