# BÁO CÁO PHẢN BIỆN THỰC CHỨNG (EMPIRICAL CHALLENGE REPORT) — MILESTONE 1 (PROGRESSION 2)

> **Người thực hiện**: `challenger_m1_progression_2` (teamwork_preview_challenger)  
> **Người nhận**: `orchestrator_4` (`6f4a2aa2-4315-4660-8cb7-8352a7220c95`)  
> **Vai trò**: critic, specialist  
> **Thời điểm**: 2026-10-01T02:20:00Z  
> **Kết luận / Phán quyết (Verdict)**: **APPROVE**  

---

## 1. Observation (Quan Sát Trực Tiếp)

1. **Thiết kế & Thực thi Bộ Khảo Sát Thách Thức (Adversarial Empirical Harness)**:
   - Đã biên soạn và thực thi bộ script kiểm thử độc lập tại `.agents/teamwork/challenger_m1_progression_2/challenge_progression_benchmarks.py` (294 dòng).
   - Lệnh thực thi: `python .agents/teamwork/challenger_m1_progression_2/challenge_progression_benchmarks.py`
   - Kết quả xuất ra:
     ```text
     ======================================================================
      ADVERSARIAL EMPIRICAL CHALLENGE HARNESS: PROGRESSION BENCHMARKS (M1)
     ======================================================================

     --- 1. Boundary Inputs & Query Rejection ---
       [PASS] Query level 0 safely rejected (returned None)
       [PASS] Query level 101 safely rejected (returned None)
       [PASS] Query level -1 safely rejected (returned None)
       [PASS] Query level 999 safely rejected (returned None)
       [PASS] Query level -999 safely rejected (returned None)
       [PASS] Query level 1000 safely rejected (returned None)
       [PASS] Query invalid type 1.5 returned None safely
       [PASS] Query invalid type '101' returned None safely
       [PASS] Query invalid type 'invalid_level' returned None safely
       [PASS] Query invalid type None returned None safely
       [PASS] Insert level 0 rejected by SQLite CHECK (level BETWEEN 1 AND 100)
       [PASS] Insert level 101 rejected by SQLite CHECK (level BETWEEN 1 AND 100)
       [PASS] Insert level -1 rejected by SQLite CHECK (level BETWEEN 1 AND 100)
       [PASS] Insert level 999 rejected by SQLite CHECK (level BETWEEN 1 AND 100)

     --- 2. Seeder Idempotency & Multiple Runs ---
       [PASS] Initial seed generated exactly 100 levels
       [PASS] 5 repeated force=True seeds produced identical zero-drift rows
       [PASS] force=False properly short-circuits with 'already_seeded'
       [PASS] Matrix integrity remains 100% valid after 6 total seeds

     --- 3. Column Types & SQLite CHECK Constraints ---
       [PASS] CHECK constraint enforced: negative exp_to_next_level (-1) rejected
       [PASS] CHECK constraint enforced: negative cumulative_exp (-50) rejected
       [PASS] CHECK constraint enforced: negative target_exp (-10) rejected
       [PASS] CHECK constraint enforced: death_penalty_ratio > 1.0 (1.25) rejected
       [PASS] CHECK constraint enforced: death_penalty_ratio < 0.0 (-0.05) rejected
       [PASS] CHECK constraint enforced: player_base_hp <= 0 (0.0) rejected
       [PASS] CHECK constraint enforced: player_benchmark_dps <= 0 (-5.0) rejected
       [PASS] CHECK constraint enforced: monster_base_hp <= 0 (0.0) rejected
       [PASS] CHECK constraint enforced: monster_base_dps <= 0 (0.0) rejected
       [PASS] CHECK constraint enforced: max_affix_tier_allowed < 1 (0) rejected
       [PASS] CHECK constraint enforced: max_affix_tier_allowed > 15 (16) rejected
       [PASS] CHECK constraint enforced: negative level_gap_safe_range (-1) rejected
       [PASS] CHECK constraint enforced: non-positive level_gap_penalty_exp (0.0) rejected
       [PASS] CHECK constraint enforced: non-positive monster_benchmark_exp (0) rejected
       [PASS] NOT NULL enforced: target_exp cannot be NULL
       [PASS] NOT NULL enforced: exp_to_next_level cannot be NULL
       [PASS] NOT NULL enforced: cumulative_exp cannot be NULL
       [PASS] NOT NULL enforced: player_base_hp cannot be NULL
       [PASS] PK UNIQUE on level: duplicate insertion cleanly rejected

     --- 4. In-Memory SQLite Lifecycle & Clean Validation ---
       [PASS] GameDesignMatrixService(':memory:') initialized cleanly
       [PASS] In-memory seeded 100 progression benchmarks
       [PASS] In-memory validate_game_design_integrity() reports is_valid=True with 0 violations
       [PASS] ProgressionBenchmarkRow DTO mappings verified for boundary levels (1, 99, 100)
       [PASS] GameDesignMatrixService.close() terminated memory connection cleanly
       [PASS] Multiple :memory: instances maintain strict memory isolation

     --- 5. Legacy Database Auto-Migration ---
       [PASS] Legacy 7-column schema was automatically upgraded to 13 columns
       [PASS] Upgraded legacy database seeded and queried successfully

     ======================================================================
      CHALLENGE RESULTS SUMMARY: 45 PASSED, 0 FAILED
     ======================================================================
     VERDICT: ALL ADVERSARIAL STRESS TESTS PASSED WITH 0 DEFECTS.
     ```

2. **Kiểm tra Ranh Giới (Boundary Inputs & Type Rejections)**:
   - Gọi `GameDesignMatrixService.get_level_progression_benchmark(level)` với các giá trị ngoài phạm vi: `level in (0, 101, -1, 999, -999, 1000)` đều trả về `None` an toàn mà không phát sinh unhandled exception hay crash tiến trình.
   - Truy vấn với các kiểu dữ liệu không chuẩn (`1.5`, `'invalid_level'`, `None`) được xử lý an toàn (trả về `None`).
   - Kiểm tra tầng SQLite DDL (`server/world/game_design_matrix_schema.py:133`): `CHECK (level BETWEEN 1 AND 100)` cản phá và ném `sqlite3.IntegrityError` khi cố tình chèn các giá trị biên sai lệch trực tiếp vào DB.

3. **Tính Bất Biến Lũy Đẳng (Seeder Idempotency & Zero Drift)**:
   - Chạy seeder canonical với cờ `force=True` liên tiếp 5 lần: số lượng dòng luôn giữ nguyên chính xác 100 hàng (cấp 1 đến 100).
   - Ảnh chụp dữ liệu (snapshot tuple so sánh toàn bộ 13 trường của 100 dòng) trước và sau 5 lần seed liên tiếp khớp 100%, chứng minh không bị nhân đôi (duplication) hay trôi giá trị (drift).
   - Gọi `seed_canonical_data(force=False)` khi database đã có dữ liệu: trả về `{"status": "already_seeded"}` ngay lập tức mà không thực hiện ghi đè lãng phí tài nguyên.

4. **Kiểm Tra Ràng Buộc Schema & SQLite CHECK Constraints**:
   - `CHECK (exp_to_next_level >= 0)`: chặn cập nhật `exp_to_next_level = -1`.
   - `CHECK (death_penalty_ratio BETWEEN 0.0 AND 1.0)`: chặn cập nhật `death_penalty_ratio = 1.25` và `-0.05`.
   - `CHECK (cumulative_exp >= 0)`: chặn cập nhật `cumulative_exp = -50`.
   - `CHECK (target_exp >= 0)`: chặn cập nhật `target_exp = -10`.
   - `CHECK (player_base_hp > 0)`: chặn cập nhật `player_base_hp = 0.0`.
   - `CHECK (max_affix_tier_allowed BETWEEN 1 AND 15)`: chặn `tier = 0` và `tier = 16`.
   - Ràng buộc `NOT NULL` và `PRIMARY KEY` duy nhất trên cột `level` hoạt động nghiêm ngặt 100%.

5. **Môi Trường SQLite `:memory:` & Vòng Đời Service**:
   - Khởi tạo `GameDesignMatrixService(":memory:")` diễn ra trơn tru.
   - Nạp dữ liệu canonical trên in-memory DB đạt 100 hàng.
   - Hàm `validate_game_design_integrity()` trả về `is_valid == True` với `violations == ()`.
   - Kiểm tra cách ly: hai thực thể `GameDesignMatrixService(":memory:")` độc lập hoàn toàn không bị rò rỉ dữ liệu chéo.
   - Kiểm tra di trú tự động: khi khởi tạo trên DB cũ chỉ có 7 cột, `_check_and_migrate_schema()` tự động phát hiện, nâng cấp thành 13 cột và nạp lại dữ liệu chuẩn.

6. **Kết Quả Kiểm Thử Toàn Cục**:
   - `python -m pytest tests/unit/test_game_design_matrix.py`: 8 passed in 0.32s.
   - `python tools/lint/verify_game_design_matrix.py --sync`: PASS, exit code 0.
   - `python -m pytest tests/e2e/test_level_progression_e2e.py -k "test_f02"`: 2 passed, 3 xpassed in 0.11s.
   - `python tools/lint/check_code_and_doc_hygiene.py --strict`: PASS, 0 hard-cap errors.

---

## 2. Logic Chain (Chuỗi Suy Luận)

1. Từ Observation 1 và 2: Cả hai tầng (Python Application Layer và SQLite Storage Engine) đều bảo vệ nghiêm ngặt miền giá trị hợp lệ của cấp độ (1-100). Không có bất kỳ kẽ hở nào cho phép cấp độ âm hoặc vượt quá 100 tồn tại trong hệ thống.
2. Từ Observation 3: Lệnh `INSERT OR REPLACE` kết hợp với kiểm tra `SELECT COUNT(*)` khi `force=False` mang lại độ an toàn tuyệt đối cho các tác vụ CI/CD và deployment khởi động lại nhiều lần mà không lo ngại database bị hỏng hay trùng lặp bản ghi.
3. Từ Observation 4: Toàn bộ 13 cột được bảo vệ bằng các ràng buộc CHECK cấp độ cơ sở dữ liệu (`CHECK (exp_to_next_level >= 0)`, `CHECK (death_penalty_ratio BETWEEN 0.0 AND 1.0)`). Điều này ngăn ngừa triệt để lỗi logic toán học (như tỷ lệ phạt âm hay exp âm) ngay cả khi có bug từ tầng ứng dụng.
4. Từ Observation 5: Môi trường `:memory:` hoạt động hoàn hảo, đáp ứng điều kiện tiên quyết để chạy các bộ unit test song song tốc độ cao (0.3s) mà không tạo rác trên ổ cứng. Cơ chế auto-migration giải quyết triệt để rủi ro xung đột schema khi người dùng nâng cấp từ phiên bản cũ.
5. Từ Observation 6: Sự đồng thuận hoàn toàn giữa bộ stress-test độc lập (45/45 pass) và các bộ test chính thống của dự án (unit test, linter, hygiene audit) chứng minh sản phẩm của Milestone 1 đạt chất lượng sản xuất (production-grade).

---

## 3. Caveats (Các Điểm Cần Lưu Ý)

1. **Ranh giới trách nhiệm Milestone 1 vs Milestone 2**:
   - Kiểm thử này tập trung vào bảng `progression_benchmarks`, schema SQLite, seeder toán học, và `GameDesignMatrixService`.
   - Logic phân phối EXP khi quái chết (`award_monster_exp`) và trừ EXP khi nhân vật tử trận (`apply_death_penalty`) thuộc phạm vi của `LevelProgressionService` (Milestone 2) và sẽ được kiểm thử riêng khi M2 hoàn thành.
2. **Quy chuẩn trả về khi query boundary**:
   - `GameDesignMatrixService.get_level_progression_benchmark(level)` trả về `None` khi `level` không tìm thấy trong database (đúng chuẩn idiom `Optional[ProgressionBenchmarkRow]` của Python). Khi `LevelProgressionService` được triển khai ở M2, các method nghiệp vụ nhận `level` có thể bổ sung thêm `ValueError` validation nếu hợp đồng yêu cầu.

---

## 4. Conclusion (Kết Luận & Phán Quyết)

**Phán quyết: APPROVE (Chấp thuận nghiệm thu 100%)**

Triển khai của Milestone 1 về cấu trúc bảng `progression_benchmarks`, 13 trường dữ liệu chuẩn, các ràng buộc SQLite CHECK constraints, tính lũy đẳng của seeder và khả năng vận hành in-memory SQLite đều hoàn toàn vững chắc, không phát hiện bất kỳ lỗi hay rủi ro bảo mật nào. Đề xuất Orchestrator tiến hành đóng Milestone 1 và kích hoạt Milestone 2 (`LevelProgressionService`).

---

## 5. Verification Method (Phương Pháp Kiểm Chứng Độc Lập)

Bất kỳ reviewer hoặc orchestrator nào cũng có thể kiểm chứng lại kết quả độc lập bằng chuỗi lệnh sau:

```powershell
# 1. Chạy bộ stress harness độc lập của challenger (45 test cases)
python .agents/teamwork/challenger_m1_progression_2/challenge_progression_benchmarks.py

# 2. Chạy test suite Unit Test của matrix service
python -m pytest tests/unit/test_game_design_matrix.py -v

# 3. Chạy kiểm toán ma trận thiết kế game
python tools/lint/verify_game_design_matrix.py --sync

# 4. Chạy kiểm toán vệ sinh mã nguồn
python tools/lint/check_code_and_doc_hygiene.py --strict
```

**Điều kiện bất hiệu hóa (Invalidation Conditions)**:
- Bất kỳ test case nào trong `challenge_progression_benchmarks.py` trả về `FAIL`.
- Cho phép chèn `exp_to_next_level < 0` hoặc `death_penalty_ratio > 1.0` vào database mà không ném `sqlite3.IntegrityError`.
- Seeder nhiều lần tạo ra số hàng khác 100.
