L 級新功能、PRD/Design/TDD/ADR 三方協作 + 互審 + M9-6 SDK 雙驗證、總計 ~9000 行文件。
範圍:
- A 階段(MVP、5 人天):KL520 + KL720 自動升級 KDP1 → KDP2
- B 階段(10.5 人天):手動降版面向一般使用者 + KL630 / KL730 擴展
- 合計 15.5 人天、安裝包 +7MB(保守 bundle 策略)
關鍵決策:
- 翻案 R5-Q9(progress.md 第二輪使用者決策「韌體燒錄 flash → B 砍掉」)
- 跨平台用 KneronPLUS Python C API、不用 DFUT.exe
- 多版本目錄結構選 C metadata(firmware/<chip>/{version}/ + CURRENT_VERSION)
- Kneron firmware redistribution 授權與 R5-B4 預置模型同性質、發佈前評估
文件產出:
- PRD v2.2(PRD-v2.md 495 行 + features/feature-firmware-management.md 599 行)
- Design v2.2(firmware-management.md 948 行 + control-panel.md §6a graceful shutdown)
- TDD v2.2(v2/firmware-management.md 823 行 + ADR-001 218 行)
- 8 份 research(含 M9-6 弱驗證 + 強驗證、~3200 行)
- 3 份三方互審報告(PM/Design/Architect cross-review)
M9-6 強驗證重大發現(影響 B 階段):
- KL730 product_id 實際是 0x732(不是 0x0730)
- KL630/KL730 firmware 是 embedded Linux rootfs(不是 .bin、不同代設計)
- KneronPLUS Python 沒 update_kdp_firmware_from_files 公開 API、warrenchen 走 ctypes
- 不影響 A 階段、B 階段 M9-8 需 spike
下一步:派 backend M9-1 起跑(bridge.py handle_firmware_upgrade)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
477 lines
26 KiB
Markdown
477 lines
26 KiB
Markdown
# Design 互審報告 — PM PRD + Architect TDD + ADR-001(v2.2 Firmware)
|
||
|
||
> 審閱者:Design Agent
|
||
> 審閱日期:2026-05-24
|
||
> 審閱對象:
|
||
> - PM:`.autoflow/02-prd/features/feature-firmware-management.md`(v2.2-draft, 523 行)
|
||
> - Architect TDD:`.autoflow/04-architecture/v2/firmware-management.md`(v2.2, 604 行)
|
||
> - Architect ADR:`.autoflow/04-architecture/adr/ADR-001-firmware-management.md`(v1.0, 210 行)
|
||
> 對照基準:`.autoflow/03-design/v2/firmware-management.md`(Design v2.2, 920 行)
|
||
|
||
---
|
||
|
||
## TL;DR
|
||
|
||
**整體評估**:🟢 三份產出與 Design 整體一致、可進 M9-12 Frontend 實作。共找出 **13 個對齊點**:
|
||
- **🔴 嚴重(需互審回合解決)**:1 個 — Architect TDD 狀態機名稱與 Design 不一致(A-MISMATCH-1)
|
||
- **🟠 中等(需 PM / Architect 補回應)**:4 個 — PM 缺 NPS / 任務完成率指標、PRD 沒明示「降版」用詞策略、Architect 沒解 graceful shutdown 拒絕、Architect 缺 token 對比實測
|
||
- **🟡 輕微(建議補但不阻塞)**:5 個 — PM 沒列「使用者怎麼知道要降版」user story、PRD 沒提 Bundle 多下載 X 秒、Architect ADR Alternatives 缺一條 Design 視角、PM 對 R-FW-12 不夠具體、PRD §10 KL520 升級時間估算不一致
|
||
- **🟢 對齊良好**:3 個 — 6 個互審待確認點中 4 個已解、API/UI DisplayName 對齊、WebSocket progress event schema 足夠
|
||
|
||
**結論**:建議先解 🔴 A-MISMATCH-1(狀態機對齊),其他 🟠 在實作前的 polish 階段補。**不阻塞 M9-1 ~ M9-5 A 階段啟動**(A 階段不涉及降版 UI、6 個對齊點都是 B2 才會踩到)。
|
||
|
||
---
|
||
|
||
## 一、對 PM PRD 的審閱
|
||
|
||
### 1.1 對齊良好(🟢)
|
||
|
||
#### 🟢 P-OK-1:6 個 Architect 互審待確認點 PM 已涵蓋 3 個
|
||
|
||
PM PRD §14.2 列了 6 個給 Architect 的互審項(A-FW-1 ~ A-FW-6),其中:
|
||
- A-FW-2(driver safety guards)→ Architect TDD §6.1 + §5.2 已對應寫具體 dispatch 與 `_validate_downgrade_request`
|
||
- A-FW-5(模組路徑 `server/internal/firmware/`)→ Architect TDD §2.1 已對應
|
||
- A-FW-6(R-FW-5 與 R5-B4 合併)→ Architect TDD §8.4 已對應
|
||
|
||
Design 視角確認:PM 給 Architect 的問題、Architect 都回答了。**對齊 OK**。
|
||
|
||
#### 🟢 P-OK-2:「降版面向一般使用者」假設(§5)的支持證據完整
|
||
|
||
PM §5.1 列 4 個假設(H1-H4)+ §5.3 5 種降版情境,Design 視角檢核:
|
||
- 4 個假設都對齊 R5 Persona 定義(P1 FAE / P2 開發者)
|
||
- 5 種情境覆蓋 Design 設計的 UX 流程(Design §6 二次確認 modal、§7 失敗復原都針對這 5 種使用者預期)
|
||
- UR-1 ~ UR-4 user research 待驗證項合理(Beta 階段 / post-launch 6 個月追蹤)
|
||
|
||
**對齊 OK**,Design 對 PM 的假設沒有體驗面異議。
|
||
|
||
#### 🟢 P-OK-3:AC-FW-2.5 二次確認 modal 警告語 4 條與 Design §6.1 對齊
|
||
|
||
PM AC-FW-2.5 列 4 條警告語:
|
||
- 「降版可能導致現有 model 無法運作」→ Design §6.1 風險列表第 1 點「部分新版 .nef 模型無法載入」
|
||
- 「降版過程不可中斷、否則裝置可能損壞」→ Design §6.1 風險列表第 3 點 + §6.3 進度 banner
|
||
- 「降版完成後可能需要重新插拔裝置」→ Design §6.4 toast「可能需要重新插拔」
|
||
- 「請確認版本相容性、降版至 KDP1 的舊版會限制可用功能」→ Design §6.2 KDP1 額外紅色 banner + 多 1 條風險
|
||
|
||
**4 條警告語 100% 對應**。Design 用詞略不同(「.nef 模型」vs 「現有 model」),但語意一致、Design 用詞更精準。
|
||
|
||
### 1.2 中等問題(🟠,需 PM 補)
|
||
|
||
#### 🟠 P-MID-1:成功指標缺「使用者感知體驗指標」
|
||
|
||
**問題**:PM §7 列 2 種指標(北極星 5 分鐘首次推論達成率 + 次要指標如升級成功率 ≥ 95% / Brick < 0.1%),**全部是技術 / 業務指標**、沒有對應使用者體驗的指標。
|
||
|
||
**Design 視角缺漏**:
|
||
- 沒有 **「降版任務完成率」**(使用者點「版本切換」→ 真正完成切換的比例。可能很多人在二次確認 modal 階段就放棄)
|
||
- 沒有 **「中途放棄率」**(多少使用者打到一半「DOWNGRADE」就取消、暗示 UX 過度恐嚇)
|
||
- 沒有 **「FW badge 點擊率」**(Devices 頁 ⚙ icon / badge 點擊後是否真的進 Settings 韌體分頁,反映 Design IA 是否讓使用者找得到)
|
||
- 沒有 **使用後 NPS / SUS 分數**(特別是 B2 階段一般使用者降版流程的可用性)
|
||
|
||
**建議**:PM 在 §7.2 加 4-5 個體驗指標。範例:
|
||
```
|
||
| 指標 | 目標 |
|
||
|------|------|
|
||
| 升級任務完成率(modal 開啟 → 完成)| ≥ 85% |
|
||
| 二次確認 modal 中途放棄率 | 50-70%(合理區間、太低暗示 UX 不夠恐嚇、太高暗示嚇跑使用者)|
|
||
| Devices 頁 FW badge 點擊率 | ≥ 30%(只算紅 / 黃 badge)|
|
||
| B 階段 SUS 分數(5 人 usability test)| ≥ 65 |
|
||
```
|
||
|
||
**阻塞性**:不阻塞 A 階段、但 B 階段上線前應補(不然沒指標可衡量 UR-1 ~ UR-3)。
|
||
|
||
#### 🟠 P-MID-2:PRD 沒明示「降版」用詞策略、可能與 UI 矛盾
|
||
|
||
**問題**:
|
||
- PM §14.1 D-FW-2「『降版』這個詞在 UI 上是否使用」標為 Design 待定
|
||
- PM 自己文件多處用「降版」(§4 US-FW-2 標題就是「一般使用者主動切版本」、但內文反覆用「降版」)
|
||
- Design 已明確採「韌體 / 版本切換」中性詞、UI 不用「降版」(Design §2.1 + §3 範例 wireframe 全部用「版本切換」)
|
||
|
||
**體驗面風險**:如果 PM PRD 的 user story 文字用「降版」、未來測試人員 / 文件譯者可能誤以為 UI 應該叫「降版」、造成 UI 文案改錯方向。
|
||
|
||
**建議**:PM 在 §14.1 D-FW-2 加註「Design 採『韌體 / 版本切換』、PRD 後續更新時 user-facing 描述應同步」。或在 §4 user story 標題明示「**進階使用者**主動切版本(內部 / 技術文件用 downgrade、UI 用『版本切換』)」。
|
||
|
||
**阻塞性**:不阻塞 A 階段、但 B 階段 PM 應明示。
|
||
|
||
#### 🟠 P-MID-3:PRD §10 KL520 升級時間估算不一致
|
||
|
||
**問題**:
|
||
- AC-FW-1.7:「KL520 升級預估 30 秒;KL720 預估 180 秒」
|
||
- §7.2 次要指標:「FW 升降版平均時長:KL520 ≤ 60s / KL720 ≤ 200s」
|
||
- AC-FW-1.7 30s vs §7.2 ≤ 60s 不一致
|
||
|
||
**Design 視角影響**:Design §5.5 進度 modal 顯示「預估剩餘 X 秒」、這個數字從哪裡來?如果以 AC 30s 為基準、實際拖到 50s 使用者會誤以為「failed」;如果以 60s 為基準、實際 30s 結束又會讓使用者懷疑「真的有寫到 flash 嗎?」
|
||
|
||
**建議**:PM 統一兩處數字、Design 建議用 §7.2 的上限(≤ 60s for KL520 / ≤ 200s for KL720)作為「預估剩餘」基準、給 UX 緩衝。
|
||
|
||
**阻塞性**:不阻塞 A 階段啟動、但 Frontend 實作 §5.5 進度 modal 前要釐清。
|
||
|
||
#### 🟠 P-MID-4:PM §14.1 D-FW-4「FW badge 三色閾值」沒明示 PM 期待
|
||
|
||
**問題**:PM 列了 D-FW-4「Design 需定具體閾值」、把這個皮球丟回 Design。
|
||
- Design §4.2 已定 3 色規則(current = 綠、older = 黃、legacy KDP1 = 紅)
|
||
- 但**沒有定義「current 之前 1 版 vs 2 版以上算什麼顏色」**——bundle 三個版本(v2.2.0 / v2.1.0 / kdp1)時、v2.1.0 是黃還是紅?
|
||
- 也沒定「壞掉的 firmware(loader mode、firmware 字串讀不到)」算什麼顏色
|
||
|
||
**Design 當前邏輯**(從 §4.2 推):
|
||
- 綠 = bundled current 完全相同(如 `v2.2.0`)
|
||
- 黃 = bundle 內較舊但可升(如 `v2.1.0`)
|
||
- 紅 = KDP1 系列(不論版本)
|
||
|
||
→ 缺「壞掉 firmware」狀態的處理。
|
||
|
||
**建議**:PM 在 D-FW-4 補一句「Design 已定 3 色規則(綠 / 黃 / 紅)、Architect 需提供 driver 層 `FirmwareIsLegacy` / `FirmwareCanUpgrade` 判定邏輯給 Design」、或 Design 直接補一條「壞掉 firmware = 灰色 badge『狀態未知』」。
|
||
|
||
**阻塞性**:不阻塞 A 階段(A 只有 KL520/KL720 current + 升級、沒有 older 中間狀態)。
|
||
|
||
### 1.3 輕微建議(🟡)
|
||
|
||
#### 🟡 P-LOW-1:缺「進階使用者怎麼知道要降版」user story
|
||
|
||
**問題**:PM §4 列 3 個 US-FW、但缺一個關鍵 user story:「使用者怎麼**發現**需要降版?」
|
||
- 情境:使用者升版後跑舊 model 出現「Error / 模型載入失敗」、怎麼從錯誤訊息推到「啊我應該降版」?
|
||
- 當前 PRD 沒明示 inference 失敗時是否暗示「可能是 FW 版本問題、考慮降版」
|
||
|
||
**Design 視角**:這個 user story 直接影響 Design 是否要在 Workspace inference 失敗的 error modal 加一條 hint「如果問題是 model 不相容、可以到 Settings → 韌體分頁切換版本」。當前 Design §7 失敗復原**只處理 FW 操作本身的失敗**、不處理「模型推論失敗指向 FW 問題」。
|
||
|
||
**建議**:PM 加 US-FW-2.5「使用者從推論錯誤推導到需要降版」、Design 後續補對應 hint UX。或標為「v2.3 未來迭代」。
|
||
|
||
**阻塞性**:不阻塞 v2.2、可延後到 v2.3。
|
||
|
||
#### 🟡 P-LOW-2:Bundle 策略對使用者的等待感 PRD 沒提
|
||
|
||
**問題**:PM §6 列 +7MB 安裝包衝擊、但沒列「使用者下載 / 安裝時可能多感覺到的 X 秒等待」。
|
||
- macOS 寬頻 ~50MB/s → +7MB = +0.14s(無感)
|
||
- 一般使用者 4G hotspot ~5MB/s → +7MB = +1.4s(無感)
|
||
- 慢速 wifi 1MB/s → +7MB = +7s(有感、但仍可接受)
|
||
|
||
**Design 視角**:這部分 Design 不需要做事(Bundle 大小是 PM/Architect 範圍)、但 PRD 缺體驗層的描述。
|
||
|
||
**建議**:PM §6.3 加一句「使用者層面:寬頻 +0.14s 安裝時間(無感)、慢速網路最多 +7s(仍可接受)」。
|
||
|
||
**阻塞性**:不阻塞、純文件 polish。
|
||
|
||
#### 🟡 P-LOW-3:R-FW-12「使用者看不懂版本」緩解措施不夠具體
|
||
|
||
**問題**:PM §8 R-FW-12「多版本管理 UX 複雜度、使用者看不懂 v2.2.0 vs v2.1.0 vs KDP1」、緩解寫「Design Agent 設計清晰版本說明文案」、太抽象。
|
||
|
||
**Design 視角**:Design 已具體做了:
|
||
- §3.3 每個版本有 displayName 後綴(`(current)` / `(older)` / `(legacy)`)
|
||
- §3.3 每個版本有獨立說明文字(「發布於 2024-08(與舊模型相容)」)
|
||
- §9 i18n keys 已涵蓋
|
||
|
||
**建議**:PM 把緩解寫具體:「Design v2.2 §3.3 + §9 i18n 已對應、含 displayName 後綴 + 版本說明文字 + KDP1 額外警告」。讓 R-FW-12 不再是 open item。
|
||
|
||
**阻塞性**:不阻塞、純風險追蹤 polish。
|
||
|
||
---
|
||
|
||
## 二、對 Architect TDD 的審閱
|
||
|
||
### 2.1 對齊良好(🟢)
|
||
|
||
#### 🟢 A-OK-1:DisplayName 格式對齊
|
||
|
||
Architect TDD §4.1 `FirmwareVersion` struct:
|
||
```go
|
||
DisplayName string `json:"displayName"` // "v2.2.0 (current)" / "v2.1.0 (older)" / "KDP1 (legacy)"
|
||
```
|
||
|
||
Design §3.1 wireframe 顯示:「KDP2 v2.2.0 (current)」、§9.2 i18n key 對應:
|
||
- `settings.firmware.card.tag.current` → `(current)`
|
||
- `settings.firmware.card.tag.legacy` → `(legacy)`
|
||
|
||
**對齊 100%**。但 Design 用「KDP2 v2.2.0 (current)」、Architect 用「v2.2.0 (current)」(沒前綴 KDP2)。
|
||
|
||
→ **小釐清**:Architect 的 `FirmwareVersion.Version` 是「v2.2.0」、Design 的 displayName 是「KDP2 v2.2.0 (current)」、兩個是「version field + displayName field 合併」嗎?建議 Architect 明示 displayName 包含 KDP 前綴:「`displayName = "{kdpFamily} {version} ({status})"`」。
|
||
|
||
#### 🟢 A-OK-2:WebSocket progress event schema 足夠支撐 Design UI
|
||
|
||
Architect TDD §4.2 `FirmwareProgress` struct:
|
||
- Percent: 0-100 → 對應 Design §5.2 進度條
|
||
- Stage: 字串列舉 → 對應 Design §5.3 階段對應表
|
||
- Direction: `upgrade` / `downgrade` → 對應 Design §6.3 「切換韌體」vs「升級韌體」標題切換
|
||
- Message / Error: 對應 Design §7.2 友善訊息
|
||
|
||
**Design 缺的:ETA(預估剩餘秒數)**。Design §5.2 範例顯示「預估剩餘 X 秒」、但 Architect schema 沒有 `EstimatedRemainingSeconds` 欄位。
|
||
|
||
→ **建議**:Architect 在 `FirmwareProgress` 加 optional `EstimatedRemainingSeconds int` 或 `ElapsedMs int`,Frontend 用 elapsed 自己算 ETA。
|
||
|
||
#### 🟢 A-OK-3:多語系策略對齊
|
||
|
||
Architect TDD §3.3 錯誤碼表(`FW_DEVICE_BUSY` / `FW_VERSION_NOT_FOUND` 等 6 個)→ Design §9.8 失敗訊息 8 個對應 friendly message keys。
|
||
|
||
**對齊 OK**、但 Architect 6 個錯誤碼 vs Design 8 個失敗類型,數量不對等(見下方 A-MISMATCH-2)。
|
||
|
||
### 2.2 嚴重問題(🔴)
|
||
|
||
#### 🔴 A-MISMATCH-1:狀態機名稱不一致
|
||
|
||
**問題**:
|
||
|
||
| 來源 | 狀態 / Stage 名稱 |
|
||
|------|----------------|
|
||
| Design §8 狀態機 | `idle` / `confirming` / **`preparing`** / **`loading`** / **`flashing`** / **`verifying`** / `success_toast` / `error_modal` |
|
||
| Architect TDD §4.3 stage 列舉 | `connecting` / `loading_loader` / `loading_firmware` / `verifying` / `done` / `error` |
|
||
| Architect TDD §5.1 流程 progressCh stage | `connecting` / `loading_firmware` / `verifying` / `done` |
|
||
| PM PRD AC-FW-1.2 | 「連線中 / 載入引導程式 / 寫入韌體 / 重新偵測 / 完成」(中文)|
|
||
|
||
**衝突點**:
|
||
- Design 用 `preparing` / `loading` / `flashing` 三階段、Architect 用 `connecting` / `loading_loader` / `loading_firmware` 三階段、PM 用「連線中 / 載入引導程式 / 寫入韌體」三階段(中文)
|
||
- 全部都意指同樣的事、但名稱完全沒對齊
|
||
|
||
**Design 視角影響**:
|
||
- Design §9.6 i18n keys 把 stage 用 `connect` / `loader` / `upgrade` / `verify` 四個 key(在 §5.3 階段對應表)
|
||
- 但 Design §8 狀態機又用 `preparing` / `loading` / `flashing` / `verifying`
|
||
- **連 Design 自己內部都不一致**——Design §5.3 用 `connect/loader/upgrade/verify`、Design §8 用 `preparing/loading/flashing/verifying`
|
||
|
||
**Design 自承錯誤**:這是 Design 自己沒對齊內部章節 + 沒採 Architect TDD 的命名。
|
||
|
||
**建議**:以 **Architect TDD §4.3 stage 列舉** 為標準(後端是 source of truth),調整:
|
||
- Design §8 狀態機:`preparing` → `connecting`、`loading` → `loading_loader`、`flashing` → `loading_firmware`
|
||
- Design §5.3 階段表的 `connect` / `loader` / `upgrade` 對齊 Architect 的 `connecting` / `loading_loader` / `loading_firmware`
|
||
- PM PRD AC-FW-1.2 不變(中文是 user-facing 文案、英文 stage code 是技術名稱)
|
||
- Design §9.6 i18n key suffix 從 `stage.connect` 改為 `stage.connecting` 等
|
||
|
||
**阻塞性**:**M9-3 後端 API 完成前必解**。如果 Frontend 不知道後端會推什麼 stage 字串、subscribe WebSocket 時對應不上、進度 modal 顯示「unknown stage」。
|
||
|
||
#### 🔴 A-MISMATCH-2:Architect 6 個錯誤碼 vs Design 8 個失敗類型不對等
|
||
|
||
**問題**:
|
||
|
||
| Architect TDD §3.3 錯誤碼 | Design §7.1 失敗類型 |
|
||
|------------------------|------------------|
|
||
| `FW_DEVICE_BUSY` | — |
|
||
| `FW_VERSION_NOT_FOUND` | — |
|
||
| `FW_INVALID_DIRECTION` | — |
|
||
| `FW_NO_CONFIRM_TOKEN` | — |
|
||
| `FW_UPGRADE_FAILED` | `upgrade` / `connect` |
|
||
| `FW_UPGRADE_BRICK_RISK` | `verify` |
|
||
| — | `scan` 找不到裝置 |
|
||
| — | `loader` 寫入失敗 |
|
||
| — | Timeout(>60s) |
|
||
| — | Disconnect during op |
|
||
|
||
**衝突點**:
|
||
- Architect 6 個是「API 層錯誤碼」(HTTP 4xx/5xx 對應)
|
||
- Design 8 個是「使用者面失敗情境」(stage 細分)
|
||
- 兩者**不在同一層**、不衝突、但對應關係沒明示
|
||
|
||
**Design 視角影響**:
|
||
- Design §7.2 失敗 modal 顯示「錯誤代碼:fw_upgrade_stage_loader_E102」、暗示有更細的代碼系統
|
||
- 但 Architect 只給 6 個 API 層代碼、沒給 stage-level 代碼
|
||
- Frontend 拿到 `FW_UPGRADE_FAILED` 後不知道對應 Design 8 種失敗類型中哪一種
|
||
|
||
**建議**:Architect TDD §3.3 補一段「失敗類型對應 stage」表:
|
||
```
|
||
| 觸發 stage | API 錯誤碼 | 給 frontend 的細分 reason 欄位 |
|
||
|----------|----------|---------------------------|
|
||
| scan 失敗 | FW_UPGRADE_FAILED | reason: "scan_not_found" |
|
||
| connect 失敗 | FW_UPGRADE_FAILED | reason: "connect_failed" |
|
||
| loader 寫入失敗 | FW_UPGRADE_FAILED | reason: "loader_write_failed" |
|
||
| upgrade 中段失敗 | FW_UPGRADE_FAILED | reason: "upgrade_mid_failed" |
|
||
| verify 失敗 | FW_UPGRADE_BRICK_RISK | reason: "verify_mismatch" |
|
||
| timeout | FW_UPGRADE_FAILED | reason: "timeout" |
|
||
| disconnect | FW_UPGRADE_FAILED | reason: "disconnect_during_op" |
|
||
```
|
||
|
||
或在 `FirmwareProgress.Error` 字串內帶結構化資訊(Frontend 解析)。
|
||
|
||
**阻塞性**:M9-3 後端 API 完成前必解、不然 Frontend 拿不到細分 reason。
|
||
|
||
### 2.3 中等問題(🟠)
|
||
|
||
#### 🟠 A-MID-1:Architect 沒解 graceful shutdown 拒絕
|
||
|
||
**問題**:Design §14.4 懸而未決第 6 點明示問:
|
||
- 降版進行中關閉 Wails 控制台 = 結束 server = 中斷降版 = 可能 brick
|
||
- Frontend / Backend 是否需要偵測「降版進行中」並擋下關閉動作?
|
||
|
||
**Architect TDD 沒對應**:
|
||
- §8.5 「Flash() method 與 restartBridge()」段提到「FW 升降版完成後設 needsReset=true」、但**沒提**降版進行中如何拒絕 server shutdown
|
||
- §5.2 流程沒提 graceful shutdown 拒絕邏輯
|
||
- §6.4 既有 handler 改動清單沒列「shutdown handler 加 FW 進行中檢查」
|
||
|
||
**Design 視角影響**:
|
||
- Design 規格已採「全螢幕 hover 攔截」(§6.3)防止 click 關 modal、但**擋不住關 Wails 控制台視窗**
|
||
- 如果 Architect 不在 server 層加保護、Design 的 UX 多層 safety net 在這個漏洞前破功
|
||
|
||
**建議**:Architect TDD 補一段 §8.6「降版進行中的 graceful shutdown 拒絕」:
|
||
- server 偵測 FW task 進行中、收到 SIGTERM / Wails 視窗關閉 → **延遲 shutdown**、等 FW task 完成或 60s timeout
|
||
- 同時推 WebSocket event 通知 frontend「使用者嘗試關閉、已擋下」
|
||
- Frontend 在 Wails 控制台顯示「降版中、無法關閉」提示(Design §13.3 應補對應 UX)
|
||
|
||
**阻塞性**:**B2 階段(M9-11/M9-12)前必解**。A 階段升級不涉及(升級失敗風險小、可中斷)、但降版必須有此保護。
|
||
|
||
#### 🟠 A-MID-2:Architect token 對比比率沒對應 Design §11.2 推導表
|
||
|
||
**問題**:Design §11.2 列了 6 個新 component token 與 Light/Dark 對比比率(4.7:1 / 5.2:1 / 4.8:1)。Design §11.2 末尾標「Architect 互審重點:請確認 Dark 模式下 legacy.fg 用黑色對紅底對比是否真的足夠」。
|
||
|
||
**Architect TDD 沒回應**:
|
||
- TDD §11 測試策略沒提 token 對比驗證
|
||
- TDD §13.2 Design 互審注意沒提此項
|
||
- ADR-001 也沒提
|
||
|
||
**Design 視角影響**:
|
||
- Design 的對比比率是「推算值」、需 Architect / Frontend 用 axe / Chrome DevTools contrast checker 工具實測
|
||
- 如果實測 Dark mode 紅底黑字 < 4.5:1、Design 必須調整 token(可能改 fg 為白色、但白配紅可能更糟)
|
||
- 不解 = 違反 Design A 層 De-A2 verification(WCAG AA 對比度達標)
|
||
|
||
**建議**:Architect TDD §11.1 加單元測試項:
|
||
```
|
||
| firmware/tokens.test | 6 個 fw-badge token 對比 ≥ 4.5:1(light + dark)| axe-core 程式化驗證 |
|
||
```
|
||
或 Architect 不主動驗、由 Design 在 M9-4 / M9-12 Frontend 實作時 Design QA 階段實測。
|
||
|
||
**阻塞性**:M9-12 Frontend 實作前必解。不解的話 Design verification 過不了。
|
||
|
||
#### 🟠 A-MID-3:Architect 失敗復原 §5.3 表只列 4 種、Design §7.1 列 8 種
|
||
|
||
**問題**:
|
||
- Architect TDD §5.3 失敗復原表:4 種(device disconnect / firmware load pre-flash / firmware load mid / verify 失敗)
|
||
- Design §7.1 失敗類型對應:8 種(scan / connect / loader / upgrade / verify / Timeout / Disconnect / 部分成功)
|
||
|
||
**衝突**:Architect 表少了 scan 失敗、connect 失敗、loader 寫入失敗、timeout 4 種。
|
||
|
||
**Design 視角影響**:
|
||
- Design 已寫對應 friendly message + 復原行動的 i18n(§9.8)
|
||
- 但如果 Architect 後端沒分這 4 種、Frontend 拿到的都是 generic「FW_UPGRADE_FAILED」、Design 顯示不出 8 種不同 modal
|
||
|
||
**建議**:與 A-MISMATCH-2 一起處理。Architect TDD §5.3 對齊 Design §7.1 8 種、或在 reason 欄位細分(見 A-MISMATCH-2 建議)。
|
||
|
||
**阻塞性**:M9-3 後端 API 完成前必解。
|
||
|
||
### 2.4 輕微建議(🟡)
|
||
|
||
#### 🟡 A-LOW-1:Architect TDD §10 風險 R-FW-12 對齊不完整
|
||
|
||
**問題**:Architect TDD §10 列 R-FW-12「多版本管理 UX 複雜度」、緩解寫「預設只顯示『升級到最新』+『切換 FW 版本』、降版必須展開 + 詳細說明」。
|
||
|
||
**Design 視角**:
|
||
- Design 已具體做(§3.3 accordion 收合、radio list 含說明)
|
||
- Architect 寫「預設只顯示...」與 Design 不完全一致(Design 是「永遠顯示升級按鈕」、不是「預設只顯示」)
|
||
|
||
**建議**:Architect 引用 Design 對應章節:「緩解措施由 Design v2.2 §3.3 落地(accordion + radio list + 版本說明)」。
|
||
|
||
**阻塞性**:不阻塞、純文件對齊。
|
||
|
||
---
|
||
|
||
## 三、對 ADR-001 的審閱
|
||
|
||
### 3.1 對齊良好(🟢)
|
||
|
||
#### 🟢 ADR-OK-1:Decision / Consequences 與 Design 整體理念一致
|
||
|
||
ADR Decision 5 條:
|
||
1. A + B 一次做完 → Design 規格已涵蓋 A + B
|
||
2. 翻案 R5-Q9 範圍切割 → Design §1.2 範圍邊界對齊
|
||
3. KneronPLUS Python C API → Design 不需要知道(後端細節)
|
||
4. 多版本目錄結構選項 C → Design §4.2 對齊(顯示版本不涉及目錄結構、但 Design 假設 bundled 版本有 metadata)
|
||
5. 保守 +7MB Bundle → Design 不影響
|
||
|
||
**對齊 OK**。
|
||
|
||
#### 🟢 ADR-OK-2:Consequences 負面影響第 3 條對齊 Design 多層 safety net
|
||
|
||
ADR Consequences 列「法律 / 簽章授權待釐清」、Design 不涉及。
|
||
列「Brick 風險未完全消除」、Design 已透過 §6 + §7 + §12 三層應對:
|
||
- §6.1 二次確認 modal + DOWNGRADE 字串
|
||
- §6.3 全螢幕 hover 攔截 + 不可關 modal
|
||
- §7 失敗復原 8 種 friendly message
|
||
- §12 R-FW Design 對策(明示對應 brick 風險路徑)
|
||
|
||
**對齊 OK**。
|
||
|
||
### 3.2 輕微建議(🟡)
|
||
|
||
#### 🟡 ADR-LOW-1:Alternatives Considered 缺一條 Design 視角
|
||
|
||
**問題**:ADR 列 5 個 Alternatives,但**沒有「替代方案:先做 dev mode 降版、不面向一般使用者」**(其實 §3 「只做內部 dev mode 降版」算半個、但 ADR 是從工時 / 痛點視角討論、沒從 UX 風險視角討論)。
|
||
|
||
**Design 視角應補**:「替代方案 6:只做 dev mode(藏在 Settings → 進階 → 開發者選項)」的 UX trade-off:
|
||
- 優點:誤觸風險降到 0
|
||
- 缺點:使用者明確要求面向一般使用者(H3 假設「藏在 dev mode 反而會讓真正需要降版的人找不到」)
|
||
- 否決原因:使用者 2026-05-24 拍板「面向一般使用者」+ Design 多層 safety net 評估足以擋誤觸
|
||
|
||
**建議**:Architect 在 ADR Alternatives §6 補上面這條 UX 視角的替代方案分析。
|
||
|
||
**阻塞性**:不阻塞、純 ADR 完整度。
|
||
|
||
---
|
||
|
||
## 四、總結與給 Orchestrator 的建議
|
||
|
||
### 4.1 對齊狀態總覽
|
||
|
||
| 類別 | 數量 | 狀態 |
|
||
|------|------|------|
|
||
| 🟢 對齊良好 | 6 | 不需處理 |
|
||
| 🟡 輕微建議 | 5 | 建議補、但不阻塞任何 milestone |
|
||
| 🟠 中等問題 | 4 | B 階段(M9-11 ~ M9-12)前必解 |
|
||
| 🔴 嚴重問題 | 2 | M9-3 後端 API 完成前必解 |
|
||
|
||
### 4.2 必解項目(按優先級)
|
||
|
||
#### 優先級 P0(M9-3 後端 API 完成前必解)
|
||
|
||
1. **A-MISMATCH-1**:狀態機名稱不一致
|
||
- 行動:以 Architect TDD §4.3 為準、Design 同步調整 §8 + §5.3 + §9.6 i18n key
|
||
- 工時:Design < 0.5h
|
||
- **誰來改**:Design Agent(Design 內部對齊)+ Architect 確認最終名稱
|
||
|
||
2. **A-MISMATCH-2**:錯誤碼 vs 失敗類型不對等
|
||
- 行動:Architect TDD §3.3 補「失敗類型對應 stage」表 + `FirmwareProgress.Reason` 欄位
|
||
- 工時:Architect < 0.5h
|
||
- **誰來改**:Architect Agent
|
||
|
||
#### 優先級 P1(B2 階段 M9-11/12 前必解)
|
||
|
||
3. **A-MID-1**:graceful shutdown 拒絕邏輯
|
||
- 行動:Architect TDD 補 §8.6 + Design 補 Wails 控制台「降版中無法關閉」UX
|
||
- 工時:Architect 1h + Design 1h
|
||
- **誰來改**:Architect Agent(主)+ Design Agent(控制台 UX)
|
||
|
||
4. **A-MID-2**:token 對比實測
|
||
- 行動:M9-12 Frontend 實作時 Design QA 階段實測、不過則調整 token
|
||
- 工時:< 0.5h(用 axe 工具)
|
||
- **誰來改**:Frontend / Design(M9-12)
|
||
|
||
5. **A-MID-3**:失敗復原表 4 vs 8 對齊
|
||
- 行動:與 A-MISMATCH-2 一起處理
|
||
- **誰來改**:Architect Agent
|
||
|
||
6. **P-MID-1**:成功指標補體驗指標
|
||
- 行動:PM 在 §7.2 補 4-5 個體驗指標
|
||
- 工時:PM 0.5h
|
||
- **誰來改**:PM Agent(B 階段上線前)
|
||
|
||
#### 優先級 P2(可延後 / polish)
|
||
|
||
7. **P-MID-2**(降版用詞)/ **P-MID-3**(升級時間估算)/ **P-MID-4**(badge 閾值):PM 補
|
||
8. **P-LOW-1 ~ P-LOW-3**:PM polish
|
||
9. **A-LOW-1**:Architect TDD R-FW-12 緩解對齊
|
||
10. **ADR-LOW-1**:ADR Alternatives 補 Design 視角
|
||
|
||
### 4.3 不阻塞 M9-1 ~ M9-5 A 階段啟動
|
||
|
||
- A 階段(升級 only)不涉及 B2 降版、狀態機名稱對齊(A-MISMATCH-1)解決後即可進
|
||
- A 階段不涉及 graceful shutdown 拒絕、failed type 8 分類也只在 B 階段需要(M9-11/12)
|
||
- 建議 Orchestrator **派 Architect 解 A-MISMATCH-1 + A-MISMATCH-2 之後**、即可啟動 M9-1 backend
|
||
|
||
### 4.4 Design 本輪不改
|
||
|
||
依任務 prompt「不改 design、本輪只審」,Design 不主動更新 `firmware-management.md`。
|
||
**待 Orchestrator 整合三方互審報告後、若決議 Design 需配合調整(如 A-MISMATCH-1 把狀態機名稱換成 connecting/loading_loader/loading_firmware/verifying),Orchestrator 另派 Design Agent 改檔**。
|
||
|
||
### 4.5 Design 自承的內部矛盾
|
||
|
||
- Design §5.3 階段對應表 vs §8 狀態機名稱不一致(Design 自己問題、不是 PM/Architect 引起)
|
||
- 處理 A-MISMATCH-1 時一併修
|
||
|
||
---
|
||
|
||
## 變更紀錄
|
||
|
||
| 日期 | 版本 | 變更 | 作者 |
|
||
|------|------|------|------|
|
||
| 2026-05-24 | v1.0 | Design 互審 PM PRD + Architect TDD + ADR-001 完成、找出 13 個對齊點(2 P0 / 4 P1 / 7 P2)| Design Agent |
|