# סיכום סשן — 0039
תאריך: 2026-06-03
אפליקציה: Vitruvius (פלאגין Revit לתיקון עברית/RTL ב-DWG)
נושא: M10 (two-track tests) + M11 prep (beta docs) במקביל

## מה נבנה/הושלם

### M10 ✓ — Two-track testing infrastructure

**Decision (after research subagent):** ricaun.RevitTest **דורש Revit installed** — לא רץ headless ב-CI חינמי. הפתרון: שני test projects, לא אחד.

**Track A — `tests\Vitruvius.Core.Tests\`:**
- `Vitruvius.Core.Tests.csproj` — net48, NUnit 3.14, NUnit3TestAdapter 4.5, NUnit.Analyzers 4.2, Microsoft.NET.Test.Sdk 17.10. project reference ל-`Vitruvius.Core` בלבד (אפס תלות ב-Revit).
- **72 tests, 72 passing, ~3.4s total run.**
- כיסוי לפי קובץ:
  - `FontMapTests.cs` (9) — ShxFontMapWriter merge: empty file, new mapping, preserve user entry, skip already-mapped, update managed entry, no-op when no recommendation, roundtrip read after write, sorted output.
  - `ScanTests.cs` (11) — TextStyleDetector (DXF parse, normalize "MIRYL"→"MIRYL.shx", filter ltypeshp + TTF, defer binary DWG, report source_missing); FontRecommender (Hebrew Visual mapping, Latin→Arial guard, None confidence for unknown, case-insensitive, RecommendAll preserves order, AllKnown ≥13).
  - `OverlayTests.cs` (15) — HebrewOrderDetector (visual/logical/ambiguous scoring); HebrewTextRemapper (EN-typed positive, English denylist negative, %%c/%%d/%%p code negative, uppercase code negative, already-Hebrew passthrough); DxfTextReverser (en-typed fixture flip + leaves Latin alone + creates backup, logical Unicode idempotent, visual Unicode → logical, non-existent file returns failure not throw).
  - `SemVerTests.cs` (16, TestCase-driven) — Compare release/prerelease/lexical, TryParse shapes, unparseable returns 0.
  - `StateCacheTests.cs` (6) — record/persist, roundtrip, case-insensitive key, remove, null backup serialized, corrupt cache non-fatal.
  - `BackupDiscoveryTests.cs` (7) — no backups null, oldest-first ordering, legacy 4-digit timestamp, dwg variant, legacy Python format, rejects unrelated .bak, missing folder doesn't throw.
  - `TelemetryGuardTests.cs` (9) — known event accepted, unknown event rejected, path-like value rejected (forward+back slash), token too long rejected, string array accepted, schema_version reserved key, IsKnownEvent covers full taxonomy.

**Track B — `tests\Vitruvius.Revit2024.Tests\`:**
- `Vitruvius.Revit2024.Tests.csproj` — net48, ricaun.RevitTest.TestAdapter 1.11.1, NUnit 3.13.3 (pinned to match adapter; 4.x incompatible), Nice3point.Revit.Api.RevitAPI/RevitAPIUI 2024.*, AssemblyMetadata NUnit.Version=2024 / Open=true / Close=true.
- `SmokeTests.cs` — 2 tests (`RevitApplication_IsInjected`, `RevitApplication_HasLicensingProduct`) שמוודאים ש-ricaun מצליח להפעיל Revit ולהזריק `Application` ל-`[OneTimeSetUp]`.
- `Fixtures\README.md` — מפרט 15-20 fixtures שצריך להפיק מ-`A_Mivne roi.rvt` (slimmed-down `.rvt`, dedicated `.dxf` per encoding type). **לא ביצענו ב-0039** — דורש Revit Setup ו-curation ידנית, לא מובן מאליו ב-spawn.

**Solution registration:** `Vitruvius.slnx` עודכן עם folder `/tests/` שמכיל את שני הפרויקטים.

### M11 prep ✓ — Beta documentation

3 קבצים חדשים ב-`installer\`:

- **`BETA-RELEASE-NOTES-0.2.0.md`** (~80 שורות) — מה הוא Vitruvius, מה כלול (3 קידודים, auto re-fix, restore, update check), מה לא (חתימה דיגיטלית, 2025/2026, ערבית), פרטיות בקצרה (telemetry off by default, אפס נתיבים, DWG לעולם לא יוצא מהמכונה), דרישות, רישוי בבטא = MVP חינמי.

- **`BETA-INSTALL-GUIDE.md`** (~130 שורות) — 7 שלבים עם handling של SmartScreen ("More info → Run anyway") + dual-mode dialog (for me only vs all users) + Unsigned Add-In ב-Revit ("Always Load"). Quickstart 6 שלבים, 3 טיפוסי עברית בטבלה, troubleshooting (4 בעיות נפוצות), הסרת התקנה.

- **`BETA-FEEDBACK.md`** (~150 שורות) — שאלון בעברית RTL, 22 שאלות ב-6 חלקים:
  - חלק 1 (4 שאלות): הקשר משרד — תפקיד, גודל, נפח DWG, מה עשו עד היום
  - חלק 2 (2): התקנה
  - חלק 3 (4): שימוש ראשון — הצלחה, איכות התיקון, זמן, restore
  - חלק 4 (4): שימוש שוטף — תדירות, auto re-fix, פונטים לא מזוהים, תכונות חסרות
  - חלק 5 (4): מוצר+כסף — willingness-to-pay ב-₪29 וב-₪19, decision maker, רב-לשוניות
  - חלק 6 (4): חוויה כללית — best/worst/recommend/freeform + opt-in לבטא הבאה

### PLAN.md updated
- M10 line marked ✓ עם תיאור two-track + 72/72 + הערה ש-fixtures דחויים
- M11 line — Prep ✓ עם רשימת 3 הקבצים + 2 החוסמים הפיזיים שנותרו

## החלטות שהתקבלו

1. **two-track, לא single-track** — Track A (Core, no Revit) רץ ב-CI; Track B (integration, ricaun) רץ local-only כ-pre-tag gate. הסיבה: ricaun.RevitTest דורש Revit installed (אומת ע"י subagent — לא ניתן לרוץ headless בלי APS billing).
- **alternative considered**: `ricaun.RevitTest.DA` — מריץ tests ב-Autodesk Design Automation cloud. דחוי — billed per cloud-minute + צריך APS app provisioning. שווה רק כשיש gating pre-merge רציני.

2. **NUnit 3.14 ב-Track A, 3.13.3 ב-Track B** — Track B חייב לשמור 3.13.3 כי ricaun.RevitTest.TestAdapter 1.11.1 לא תואם NUnit 4.x. Track A יכול היה להישאר 3.13.3 לאחידות, אבל 3.14 מציע analyzer וfix-ים קלים — אין שום השלכה כי הם פרויקטים נפרדים.

3. **net48 לשני הפרויקטים, לא netstandard2.0** — Track A יכול היה להישאר netstandard, אבל NUnit3TestAdapter ו-VSTest פועלים נקי יותר ב-net48. Track B חייב net48 (ricaun + Revit references).

4. **לא מימשנו fixtures אמיתיים ב-Track B עכשיו** — דורש לפתוח Revit, לעשות Save As, לפרק views, audit + save. work intrinsic. נדחה למשתמש או לסשן ייעודי שבו הוא נמצא ליד המכונה ויכול לעבוד מולה.

5. **synthetic fixtures ב-Track A במקום real-world** — `styles-mixed.dxf` + `hebrew-en-typed.dxf` נכתבו ידנית כדי שיהיו minimal + reproducible + commit-able to repo. הקבצים האמיתיים ב-`test materials\` גדולים מדי ולא נחוצים לבדיקות-יחידה.

6. **`installer\BETA-*.md`, לא `docs\BETA-*.md`** — כל ה-installer-related material יושב יחד. אם בעתיד יהיה `docs\` עיקרי, נשקול לעבור.

## בעיות שנפתרו

### `Contains.Item("...").IgnoreCase` לא קיים ב-NUnit 3.14
**Symptom:** `dotnet build` נכשל ב-ScanTests.cs:54-55 עם `'SomeItemsConstraint' does not contain a definition for 'IgnoreCase'`.

**Root cause:** ה-syntax `Contains.Item(x).IgnoreCase` עובד רק על single-item constraints (e.g., `Has.Some.Items()...`). על `SomeItemsConstraint` (שהוא מה ש-`Contains.Item` מחזיר) אין `IgnoreCase`.

**Fix:** החלפה ל-`Assert.That(result.ShxFontNames.Any(n => n.Equals("MIRYL.shx", StringComparison.OrdinalIgnoreCase)), Is.True)`. מפורש יותר וברור יותר ממה שניסיתי. בנייה עוברת, tests עוברים.

### PowerShell `2>&amp;1` escaping issue
**Symptom:** הריצה הראשונה של `dotnet restore` החזירה parser error כי PowerShell חוזה `&amp;` כ-XML entity ולא כ-redirection.

**Fix:** השתמשתי ב-`2>&1` רגיל. הבעיה הייתה בכלי ה-Bash שכנראה מקודד `&` אוטומטית למניעת shell escape — נכון רק לפשוט bash-style redirection.

## מה לא עבד / צריך להיזהר

- **אי אפשר להריץ Track B ללא Revit 2024 installed.** במכונה שלנו זה זמין (`D:\REVIT 2024\Revit 2024\`), אבל בכל CI runner שלא נשתמש בו זה ייפול ב-discovery time, לא ב-test time — כשהאדפטר מנסה לאתר Revit ולא מוצא, הוא זורק לפני שאף test רץ. **מסקנה לעתיד:** אם בונים GitHub Actions, Track A בלבד ב-CI. Track B מסומן `Local-only — runs manually before tag`.

- **fixtures אמיתיים `.rvt` חייבים להיות slimmed-down + sanitized + reproducible.** השמירה הישירה של `A_Mivne roi.rvt` ה-50MB ל-repo: רע — bloats checkouts, לא reproducible (תלוי Google Drive online), ועלול לחשוף שמות פרויקט/יועצים שאסור לדלוף לציבור. מסמך README ב-Fixtures מנחה איך להפיק.

- **אל תוסיף fixtures לפני שהם slimmed.** משהו מתחת ל-2MB. אם זה גדול מזה — fixtures שגויות.

- **אסור לרוץ tests של Track B במקביל לסשן Revit פתוח** — adapter שולח addin משלו לתיקיית `Addins\2024\` ומשגר instance חדש; שני sessions ביחד = collision. סגור Revit לפני `dotnet test tests\Vitruvius.Revit2024.Tests`.

- **anti-pattern — לא להוסיף test שמסתמך על נתיב חיצוני** (Google Drive, BIM360 cloud). כל test fixture חייב להיות `Copy to Output Directory = PreserveNewest` ולגור בתוך `tests\<project>\Fixtures\`.

## קבצים שנוצרו/שונו

### נוצרו (Track A — Core.Tests, 9 files)
- `tests\Vitruvius.Core.Tests\Vitruvius.Core.Tests.csproj`
- `tests\Vitruvius.Core.Tests\FontMapTests.cs`
- `tests\Vitruvius.Core.Tests\ScanTests.cs`
- `tests\Vitruvius.Core.Tests\OverlayTests.cs`
- `tests\Vitruvius.Core.Tests\SemVerTests.cs`
- `tests\Vitruvius.Core.Tests\StateCacheTests.cs`
- `tests\Vitruvius.Core.Tests\BackupDiscoveryTests.cs`
- `tests\Vitruvius.Core.Tests\TelemetryGuardTests.cs`
- `tests\Vitruvius.Core.Tests\Fixtures\styles-mixed.dxf` (synthetic — 4 styles: STANDARD/txt, MIRYL-STYLE/MIRYL, ARIAL-STYLE/arial.ttf, LINETYPE-NOISE/ltypeshp.shx)
- `tests\Vitruvius.Core.Tests\Fixtures\hebrew-en-typed.dxf` (synthetic — 4 TEXT entities, 2 EN-typed Hebrew + 1 English + 1 diameter code)

### נוצרו (Track B — Revit2024.Tests, 3 files)
- `tests\Vitruvius.Revit2024.Tests\Vitruvius.Revit2024.Tests.csproj`
- `tests\Vitruvius.Revit2024.Tests\SmokeTests.cs`
- `tests\Vitruvius.Revit2024.Tests\Fixtures\README.md`

### נוצרו (M11 beta docs)
- `installer\BETA-RELEASE-NOTES-0.2.0.md`
- `installer\BETA-INSTALL-GUIDE.md`
- `installer\BETA-FEEDBACK.md`

### שונו
- `Vitruvius.slnx` (+`/tests/` folder עם 2 projects)
- `PLAN.md` (M10 ✓, M11 prep ✓ + remaining blockers)

## הצעד הבא

**Path A (מומלץ אם המשתמש רוצה להמשיך לבטא):**
1. הורד Inno Setup 6.x מ-https://jrsoftware.org/isdl.php (~6MB installer)
2. `iscc D:\Vitruvius Ecosystem\Vitruvius\installer\Vitruvius.iss` → מפיק `installer\Output\Vitruvius-Setup-0.2.0.exe`
3. בחרו 2-3 משרדי אדריכלות לבטא (המלצות: WhatsApp Communities, lead magnet, או היכרויות אישיות של המשתמש)
4. שליחה אישית של 4 הקבצים (.exe + 3 MDים)
5. המתנה 2-3 שבועות, איסוף feedback
6. החלטה אם להתחיל phase 2 או PMF הוכח → תשלום אמיתי

**Path B (אם הבטא נדחית):**
- מימוש fixtures אמיתיים ל-Track B (15-20 .rvt files) + 5-8 integration tests
- אומדן: יום עבודה אם הגישה לקבצים זמינה
- ערך: מגן מפני רגרסיות באמת. מתאים לפני שדוחפים M11.5 או refactor רחב.

**Path C — תיקוני polish:**
- Track B fixture: `mivne-roi-lite.rvt` (sanitized) + integration test ראשון
- Track A: extend FontRecommender table לפי מה שעלה ב-feedback אמיתי
- אופציה לשקול: GitHub Actions workflow שמריץ Track A על push

## ricaun.RevitTest gotchas (לזכור)
- Adapter מתקין `RevitTest.addin` משלו ב-`%PROGRAMDATA%\Autodesk\Revit\Addins\2024\` בזמן הרצה. אם test ריצה נכשלה באמצע, ייתכן ש-addin נשאר → ghost-load בהפעלת Revit הבאה. ניקוי: `Remove-Item "$env:PROGRAMDATA\Autodesk\Revit\Addins\2024\RevitTest*"`.
- `NUnit.Open=true` + `NUnit.Close=true` ב-csproj מבטיחים שRevit נפתח אחת ונסגר אחת — אחרת תהליכי revit.exe ghost.
- חלון Revit "Unresolved References" יכול לעצור את הריצה. אם זה קורה — להוסיף `<AssemblyMetadata Include="NUnit.Language">ENU /viewer</AssemblyMetadata>` כדי לרוץ ב-Viewer mode (לא דורש license, פותח מהר).
- `NUnit.Verbosity=2` עוזר ל-debug.

## הערות לסשן הבא
- ה-installer מוכן לקומפילציה אבל לא קומפל — Inno Setup לא מותקן. הורד מ-jrsoftware.org.
- 3 docs בעברית מוכנים — אם המשתמש רוצה שינויי copywriting (יותר מקצועי / יותר חברי / קצר יותר) ניתן לעדכן.
- Track B skeleton מוכן ל-test ראשון אמיתי ברגע שיהיה fixture `.rvt`. השאר את המבנה — הקובץ הראשון יהיה sample בסגנון `FixGibberishIntegrationTests` (ראה התיעוד ב-`Fixtures\README.md`).
