# BÁO CÁO THẨM TRA ĐỘC LẬP (EMPIRICAL CHALLENGER REPORT): MILESTONE 2 (4D BIM SIMULATION & INTERACTIVE SITE DIARY DOCK)

- **Agent**: `teamwork_preview_challenger_m2_1` (Instance 1 of 1)
- **Role**: Critic & Specialist (Empirical Challenger)
- **Đối tượng thẩm định**: `app/static/bim/index.html` (Milestone 2: Tính năng F7, F8, F9, F10)
- **Ngày thực hiện**: 2026-10-04
- **Phán quyết (Verdict)**: **APPROVE (CHẤP THUẬN NGHIỆM THU)**

---

## 1. OBSERVATION (QUAN SÁT THỰC NGHIỆM ĐỘC LẬP)

Toàn bộ dữ liệu dưới đây được đo đạc trực tiếp trên môi trường thực thi (Chrome DevTools MCP và Pytest Playwright runner), tuyệt đối không dựa vào báo cáo của Worker:

1. **Thử nghiệm Stress-test tua nhanh 100 chu kỳ (Rapid Scrubbing Stress Test: Day 1 $\leftrightarrow$ Day 90 $\times 100$)**:
   - Lệnh thực thi: Hàm kiểm thử stress đo đạc 100 chu kỳ tua khứ hồi (tổng cộng 18,000 lần gọi `window.setTimelineDay(d)` liên tục):
   - Kết quả đo đạc từ Chrome DevTools:
     * `cycles`: 100
     * `totalUpdates`: 18,000 lần
     * `durationMs`: 2,568.9 ms (toàn bộ 18,000 updates hoàn thành trong 2.57 giây)
     * `avgTimePerUpdateMs`: **0.1427 ms / update** (vượt xa chỉ tiêu phản hồi $< 50\text{ ms}$)
     * `initialMemBytes`: 5,176,763 bytes ($\approx 4.94\text{ MB}$)
     * `finalMemBytes`: 4,968,810 bytes ($\approx 4.74\text{ MB}$)
     * `memDeltaBytes`: **-207,953 bytes** (bộ nhớ ổn định tuyệt đối, không có rò rỉ JS Heap, bộ gom rác V8 hoạt động bình thường)
     * `initialGeomCount`: 54 $\to$ `finalGeomCount`: 54 (`geomDelta`: **0**, không có rò rỉ Three.js BufferGeometry)
     * `initialTexCount`: 21 $\to$ `finalTexCount`: 21 (`texDelta`: **0**, không có rò rỉ Texture)

2. **Đo đạc hiệu năng Render WebGL & Tốc độ khung hình (FPS & Render Latency)**:
   - Đo đạc thời gian render thực tế per frame của Three.js trên 90 mốc ngày:
     * `avgRenderMs`: **0.595 ms / frame**
     * `minRenderMs`: **0.300 ms / frame**
     * `maxRenderMs`: **1.400 ms / frame**
     * Tần số quét lý thuyết tối đa: **1,679 FPS**
   - Đo đạc frame rate trên môi trường Chromium unthrottled (`test_check_3_render_loop_performance_fps`):
     * Kết quả: **75.03 FPS** (vượt xa ngưỡng yêu cầu $\ge 30.0\text{ FPS}$).

3. **Thử nghiệm Bộ chọn tốc độ (Speed Multipliers: 1x, 2x, 5x)**:
   - Kích hoạt qua nút DOM `#btnSpeed1x`, `#btnSpeed2x`, `#btnSpeed5x`:
     * `btnSpeed1x.click()`: class `active = true`, `playSpeed = 1` (khoảng cách tick 1,000ms/ngày).
     * `btnSpeed2x.click()`: class `active = true`, `playSpeed = 2` (khoảng cách tick 500ms/ngày).
     * `btnSpeed5x.click()`: class `active = true`, `playSpeed = 5` (khoảng cách tick 200ms/ngày).

4. **Kiểm thử ranh giới 16 bước chuyển đổi pha (16 Phase Transition Boundaries)**:
   - Ngày 10 $\to$ 11: Chuyển GĐ 1 sang GĐ 2. Cừ Larsen xuất hiện tại $Y = +7.0\text{ m}$ và bắt đầu hạ dần.
   - Ngày 20 $\to$ 21: Cừ hạ xong $Y = 0.0\text{ m}$, hệ dầm văng I300 và giằng ngang `groupStruts` xuất hiện.
   - Ngày 25 $\to$ 26: Chuyển GĐ 2 sang GĐ 3. Bắt đầu đào móng xuống $-2.20\text{ m}$.
   - Ngày 27 $\to$ 28: Bắt đầu ép cọc tre móng (`bambooInstanced.count` tăng từ 0 lên 92 cọc và tăng dần).
   - Ngày 38 $\to$ 39: Cọc tre ép hoàn thành ($13,042$ cọc, biểu diễn tối đa mesh capacity 1,022 cọc); đệm cát 10cm và bê tông lót M100 `groupFoundation` xuất hiện.
   - Ngày 45 $\to$ 46: Chuyển GĐ 3 sang GĐ 4. Cốt thép đáy vách `groupRebar` và 2 khe lún V250 `groupJoints` xuất hiện.
   - Ngày 51 $\to$ 52: Đổ BTCT Phân đoạn 1 (`culvertSeg1.visible = true`).
   - Ngày 58 $\to$ 59: Đổ BTCT Phân đoạn 2 (`culvertSeg2.visible = true`).
   - Ngày 64 $\to$ 65: Đổ BTCT Phân đoạn 3 (`culvertSeg3.visible = true`).
   - Ngày 70 $\to$ 71: Chuyển GĐ 4 sang GĐ 5. Bắt đầu đổ bản nắp đan Phân đoạn 1 (`topSlabSeg1.visible = true`).
   - Ngày 73 $\to$ 74: Đổ nắp đan Phân đoạn 2 (`topSlabSeg2.visible = true`).
   - Ngày 75 $\to$ 76: Xây lắp 5 ga chờ CT-01 và 5 cửa thăm CT-02 (`groupManhole.visible = true`).
   - Ngày 76 $\to$ 77: Đổ nắp đan Phân đoạn 3 (`topSlabSeg3.visible = true`).
   - Ngày 77 $\to$ 78: Đắp cánh gà cửa xả loe 45° (`groupWing.visible = true`).
   - Ngày 82 $\to$ 83: Chuyển GĐ 5 sang GĐ 6. Tháo dỡ dầm văng (`groupStruts.visible = false`), búa rung bắt đầu nhổ cừ rút lên trên trục Y ($Y = 0 \to 8\text{ m}$).
   - Ngày 88 $\to$ 89: Cừ nhổ xong 100% (`groupLarsen.visible = false`), đê quai dọn dẹp (`groupDyke.visible = false`), hoàn trả mặt đường dân sinh.

5. **Kiểm thử chi tiết 6 Ngày Ranh Giới (Edge Days Inspection)**:
   - **Ngày 1 (Hiện trạng & Đê quai)**:
     * 3D Scene: `dyke = true`, `larsen = false (Y=7)`, `struts = false`, `bambooCount = 0`, `foundation = false`, `rebar = false`, `culvertSeg1..3 = false`, `topSlabSeg1..3 = false`, `manhole = false`, `wing = false`.
     * Nhật ký: Ngày 01/03/2026, Nhân lực 12, Đất đào 11 m³, Cừ 0, Cọc tre 0, BT 0, Thép 0.
   - **Ngày 26 (Bắt đầu đào móng)**:
     * 3D Scene: `dyke = true`, `larsen = true (Y=0)`, `struts = true`, `bambooCount = 0`, `foundation = false`, `culvertSeg1..3 = false`, `topSlabSeg1..3 = false`.
     * Nhật ký: Ngày 26/03/2026, GĐ 3, Nhân lực 22, Đất đào 276 m³, Cừ Larsen 7,030 m, Cọc tre 0.
   - **Ngày 45 (Hoàn thành cọc tre 13,042 & Bê tông lót M100)**:
     * 3D Scene: `bambooCount = 1022 (full capacity)`, `foundation = true`, `rebar = false`, `culvertSeg1..3 = false`, `topSlabSeg1..3 = false`.
     * Nhật ký: Ngày 14/04/2026, GĐ 3, Nhân lực 26, Đất đào 1,150 m³, Cừ 7,030 m, Cọc tre 13,042, BT lót 99.6 m³, Thép 0.
   - **Ngày 70 (Hoàn thành đáy & vách 3 phân đoạn, nắp đan còn hở)**:
     * 3D Scene: `culvertSeg1 = true`, `culvertSeg2 = true`, `culvertSeg3 = true`, `topSlabSeg1..3 = false` (lòng cống để hở để quan sát theo R2), `rebar = true`, `joints = true`.
     * Nhật ký: Ngày 09/05/2026, GĐ 4, Nhân lực 28, BT 366.1 m³ (đáy vách), Thép 33.14 Tấn.
   - **Ngày 82 (Hoàn thành nắp đan, ga chờ CT-01 & cửa xả loe)**:
     * 3D Scene: `topSlabSeg1..3 = true`, `manhole = true`, `wing = true`, `struts = true`, `larsen = true`.
     * Nhật ký: Ngày 21/05/2026, GĐ 5, Nhân lực 20, BT 474.9 m³ (đầy đủ toàn bộ), Thép 57.64 Tấn.
   - **Ngày 90 (Nhổ cừ hoàn tất, dọn dẹp thông tuyến)**:
     * 3D Scene: `larsen = false`, `struts = false`, `dyke = false`, `culvert = true`, `topSlab = true`, `manhole = true`, `wing = true`.
     * Nhật ký: Ngày 29/05/2026, GĐ 6, Nhân lực 16, Cừ 7,030 m, Cọc 13,042, BT 474.9 m³, Thép 57.64 Tấn, Bàn giao mặt bằng.

6. **Kiểm tra Console log**:
   - `list_console_messages(pageId: 1)`: **0 console errors, 0 warnings**.

7. **Kiểm tra Zero Occlusion & Thu gọn Bottom Dock (Collapsible Test)**:
   - Đo đạc bounding box: `dock.right <= sidebar.left` (cách lề phải `390px` hoàn toàn tuyệt đối).
   - Chiều cao khi mở rộng: $195\text{ px}$.
   - Chiều cao khi thu gọn qua `#btnToggleDock`: $32\text{ px}$ (độ trễ transition $0.25\text{s}$, 4D Player Dock tụt xuống `bottom: 42px`).

8. **Bộ kiểm thử tự động `test_ong_den_4d_bim_and_video_export.py`**:
   - `test_check_1_live_navigation_http_200`: **PASSED**
   - `test_check_2_zero_console_errors`: **PASSED**
   - `test_check_3_render_loop_performance_fps`: **PASSED** (75.03 FPS)
   - `test_check_4_dimension_annotations`: **PASSED**
   - `test_check_5_bim_player_controls`: **PASSED**
   - `test_check_6_site_diary_dock`: **PASSED**
   - `test_check_8_backend_regression_gate`: **PASSED**

---

## 2. LOGIC CHAIN (CHUỖI SUY LUẬN TỪ THỰC NGHIỆM ĐẾN PHÁN QUYẾT)

1. **Về tính ổn định bộ nhớ và rò rỉ đối tượng (Hypothesis H1)**:
   - *Suy luận*: Nếu mã nguồn cấp phát lại `new THREE.BufferGeometry()` hoặc tạo mới instance trong mỗi lần tua timeline, sau 18,000 lần gọi JS heap sẽ phình to hàng trăm MB và `renderer.info.memory.geometries` sẽ tăng tương ứng.
   - *Thực chứng*: `renderer.info.memory.geometries` giữ nguyên chính xác ở 54 (delta = 0), `textures` giữ nguyên 21 (delta = 0). Bộ nhớ JS Heap thay đổi từ 5.18 MB về 4.97 MB (delta = -208 KB). Không có bất kỳ rò rỉ nào.
   - *Kết luận*: Bác bỏ giả thuyết H1. Động cơ cập nhật trạng thái 4D đạt tiêu chuẩn zero-allocation runtime.

2. **Về hiệu năng khung hình khi tua nhanh (Hypothesis H2)**:
   - *Suy luận*: Việc tua liên tục qua 6 giai đoạn thi công có thể gây drop FPS nếu việc thay đổi cờ visibility hoặc instanced count quá tải main thread.
   - *Thực chứng*: Thời gian render frame đo đạc trung bình chỉ $0.595\text{ ms}$ (tương đương khả năng render $> 1,600\text{ FPS}$), và kiểm thử Playwright đo đạc đạt $75.03\text{ FPS}$ ($> 30\text{ FPS}$).
   - *Kết luận*: Bác bỏ giả thuyết H2. Hiệu năng vượt trội tiêu chuẩn quy định.

3. **Về tính chính xác kỹ thuật của 6 giai đoạn và các ngày ranh giới (Hypothesis H3)**:
   - *Suy luận*: Kiểm tra xem các cấu kiện có tuân thủ đúng trình tự thi công thực tế tại hiện trường hay không (cừ văng trước khi đào, bê tông lót trước khi cốt thép, đáy vách trước khi nắp đan, rút cừ sau khi hoàn thiện cống).
   - *Thực chứng*: Toàn bộ 16 điểm giao thoa và 6 ngày ranh giới (1, 26, 45, 70, 82, 90) phản ánh 100% chính xác logic thi công theo biện pháp thi công Sheet 04 và nhật ký hợp đồng HĐ-2026.
   - *Kết luận*: Bác bỏ giả thuyết H3.

4. **Về độ sạch của Console JavaScript (Hypothesis H4)**:
   - *Thực chứng*: Không có ngoại lệ không bắt được, không có cảnh báo WebGL, 0 console messages.
   - *Kết luận*: Bác bỏ giả thuyết H4.

---

## 3. CAVEATS (GIỚI HẠN & GIẢ ĐỊNH)

1. **Kiểm thử Check 7 (Lifetime Video Export)**:
   - Trong bộ test `test_ong_den_4d_bim_and_video_export.py`, test case `test_check_7_lifetime_video_export` báo fail do nút `#btnExportVideo` chưa được gắn vào giao diện.
   - Đây là hành vi hoàn toàn đúng với kế hoạch phân rã công việc của Orchestrator: Feature F11 (Lifetime Video Export) thuộc phạm vi của **Milestone 3**, không thuộc Milestone 2.
2. **Môi trường Chrome DevTools không có focus**:
   - Khi tab browser chạy ngầm không có active window trên Windows desktop, trình duyệt tự động giới hạn `requestAnimationFrame` về 1 FPS (throttling chuẩn của Chromium).
   - Việc kiểm tra FPS thực tế đã được kiểm chứng chuẩn xác bằng 2 phương pháp độc lập:
     * Phương pháp 1: Đo đạc trực tiếp chu kỳ hàm render Three.js ($0.595\text{ ms/frame}$).
     * Phương pháp 2: Chạy Playwright với cờ `--disable-background-timer-throttling` đạt $75.03\text{ FPS}$.

---

## 4. CONCLUSION (KẾT LUẬN & PHÁN QUYẾT)

- **Phán quyết chính thức**: **APPROVE (CHẤP THUẬN NGHIỆM THU MILESTONE 2)**.
- **Lý do**:
  1. Tính năng F7 (4D Player Controls): Hoạt động trơn tru, đầy đủ nút Play/Pause, phím tắt (Space, Arrow), thanh trượt 1-90, nút nhảy nhanh 6 pha, nút tốc độ 1x, 2x, 5x.
  2. Tính năng F8 (6-Phase Phasing Simulation): Mô phỏng chuẩn xác 100% theo bản vẽ Sheet 04, phân đoạn 3 block cống, ép/rút cừ Larsen IV, ép cọc tre 13,042 cọc.
  3. Tính năng F9 (Site Diary Bottom Dock): Bố cục Dark Slate chuẩn Bloomberg, Zero Occlusion (chống đè sidebar 390px), thu gọn mượt mà từ 195px về 32px.
  4. Tính năng F10 (Real-Time Sync): Dữ liệu khí tượng, nhân sự, máy móc, khối lượng 5D và quan trắc hộ dân ông Quyết đồng bộ tức thời với độ trễ $< 0.15\text{ ms}$.
  5. Độ ổn định: 0 rò rỉ bộ nhớ qua 18,000 lần tua, 0 lỗi console, FPS đạt $75.03\text{ FPS}$.

---

## 5. VERIFICATION METHOD (HƯỚNG DẪN TÁI HIỆN ĐỘC LẬP)

Để bất kỳ bên thứ ba nào kiểm chứng lại kết quả độc lập:

1. **Chạy bộ kiểm thử tự động Playwright**:
   ```powershell
   .venv\Scripts\python.exe -m pytest tools/verification/test_ong_den_4d_bim_and_video_export.py -v -k "test_check_1 or test_check_2 or test_check_3 or test_check_4 or test_check_5 or test_check_6 or test_check_8"
   ```
   *Kết quả mong đợi*: **7 passed (100% PASSED)**.

2. **Chạy script kiểm tra 18,000 lần tua và đo rò rỉ bộ nhớ trong Console trình duyệt**:
   Mở `http://127.0.0.1:8000/static/bim/index.html`, mở DevTools Console (F12) và dán đoạn mã:
   ```javascript
   (async () => {
     const iMem = performance.memory ? performance.memory.usedJSHeapSize : 0;
     const iGeom = renderer.info.memory.geometries;
     for (let c = 1; c <= 100; c++) {
       for (let d = 1; d <= 90; d++) window.setTimelineDay(d);
       for (let d = 90; d >= 1; d--) window.setTimelineDay(d);
     }
     renderer.render(scene, camera);
     const fMem = performance.memory ? performance.memory.usedJSHeapSize : 0;
     const fGeom = renderer.info.memory.geometries;
     console.log("Memory Delta:", fMem - iMem, "Geometry Delta:", fGeom - iGeom);
   })();
   ```
   *Kết quả mong đợi*: `Geometry Delta === 0`, `Memory Delta <= 0` hoặc $< 1\text{ MB}$.
