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>
46 KiB
feature: Kneron Dongle FW 偵測 + 升降版
對應 PRD:
PRD-v2.mdv2.2(2026-05-24) 作者:PM Agent 任務等級:L 級新功能(翻案 R5-Q9) 範圍:A 階段(MVP)+ B 階段(擴展),一次做完 預估工時:A 5 人天 + B 10.5 人天 = 15.5 人天 安裝包衝擊:+7MB(保守 bundle 策略,163MB → ~170MB) 狀態:v2.2.1 — 吸收三方互審 + M9-6 弱驗證結果(裁決:stage 命名採 Design / M9 工時拆法採 PM / AC-FW-3.5 延後 B 階段 M9-10)
0. 一句話摘要
讓使用者把插上的 Kneron Dongle 從「Error 15 完全不能用的舊 FW」一鍵升級到內建 KDP2 標準版本,並提供面向一般使用者的多版本切換 UI(含降版),全程離線可用、不需要 DFUT.exe 或外部工具。
1. 動機
1.1 真實痛點:拿到舊 dongle 完全不能用
2026-04-21 的 bug 紀錄(progress.md §「2026-04-21 推論 bbox 標註不顯示 + KL520 Error 15」)已具體記錄:
- KL520 USB Boot dongle 若 session 間 firmware 殘留
fw=KDP2 Comp/U,直接load_model + inference100% 炸Error 15 SEND_DATA_TOO_LARGE - 解法是強制走完整
reset → 退回 Loader → 重新載 firmware流程
但這只解決「session 間殘留」,沒解決「拿到一根插上是 KDP1 legacy 的舊 dongle」這個更基礎的問題——使用者收到 Kneron 出貨的 dongle 可能是 KDP1(舊版)、可能是 KDP2 但版本太舊、可能 firmware 在運送過程被擦掉留在 Loader mode。所有這些情境的共通解法只有一條:升級到 Kneron 官方 KDP2 標準版本。
目前 visionA-local 沒有任何 UI 暴露「升級 firmware」這個動作,使用者只能:
- 自己想辦法找 DFUT.exe(Windows-only Qt 工具)
- 把 dongle 寄回 Kneron 換貨
- 放棄使用
→ 這違反 v1.2 北極星指標「5 分鐘內順利跑出第一次推論的比例 ≥ 95%」——只要使用者拿到不對版本的 dongle,5 分鐘永遠達不到。
1.2 為什麼現在做
| 觸發因素 | 說明 |
|---|---|
| Architect 已完成 research plan | .autoflow/04-architecture/research-kl520-fw-management/ 7 個檔、合計 ~3000 行,已驗證技術可行 |
| 同事 warrenchen 已有雲端版實作可參考 | gitea/warrenchen/web_academy_prototype/local_service_win,UX 旅程已被驗證 |
| KneronPLUS C API 跨平台可用 | libkplus.{dll,so,dylib} 三平台都在現有 bundle 內、增加成本 0KB |
| 使用者明確要求 + 願意翻案 R5-Q9 | 2026-05-24 拍板 A + B 一次做完 |
| 既有 code 已有 70% 邏輯 | bridge.py handle_connect() 已可偵測 Loader mode 並 RAM-load firmware,缺的只是「持久化升降版」 |
2. R5-Q9 翻案分析
2.1 R5-Q9 原文(progress.md 第二輪決策表)
| Q9 | 韌體燒錄 flash | **B** 砍掉 |
位置描述:progress.md 「第二輪使用者決策」表格中、Q9 條目(2026-04-11 拍板)。行號因 progress.md 多次追加內容會浮動、文件追溯以決策內容為準、不以行號為準(早期 Architect research summary 00-research-summary.md §1.7 與本檔早期版本均引用過 L776 / L854、僅供歷史追溯參考)。「Q9 韌體燒錄 flash 砍掉」的決策本身沒有疑義。
2.2 當時為何砍
progress.md 沒留下明文理由(只標「B 砍掉」)。Architect research 推測的 4 個可能原因(待使用者最終確認):
- visionA-local 定位是「local 推論工具」、不是「dongle 管理工具」,燒 flash 不屬核心使用旅程
- 燒 flash 有 brick 風險、當時不想對使用者開放
- 早期 MVP 範圍縮小、把非必要功能延後
- 既有「load_firmware 到 RAM」邏輯已夠用基本推論(KL520 USB Boot 每次重 load、KL720 已預燒 KDP2)
2.3 現在為何要翻
| 因素 | 說明 |
|---|---|
| 真實痛點 | 2026-04-21 Error 15 經驗證實「舊 firmware = 完全不能用」 |
| 使用者明確要求 | 2026-05-24 拍板 A + B 全做 |
| 範圍可切割 | 只做「升級到內建 KDP2 標準版本」,不做「使用者燒任意 binary」 |
| Architect research 已驗證可行 | 5 人天 MVP、+0KB 安裝包、技術風險可控 |
| 同事雲端版已驗證 UX | warrenchen 雲端網頁 + 本地服務雙進程版已 ship,使用者旅程被驗證過 |
2.4 範圍切割:避開 Q9 原始擔憂
| Q9 砍掉的 | 本任務不做 | 本任務做 |
|---|---|---|
| 「使用者按按鈕燒任意 model 到 device flash」 | ✅ 不做(與 model load 區隔) | — |
| 「開放使用者選任意 binary 寫 flash」 | ✅ 不做(只允許內建 bundle 過的官方 firmware) | — |
| — | — | ✅ 偵測 dongle 當前 FW 版本 |
| — | — | ✅ 升級到內建 Kneron 官方 KDP2 標準版本 |
| — | — | ✅ 切換到內建其他 bundle 版本(含降版) |
→ 既有 server/internal/flash/ 模組保持「load model 到 device RAM」原意;新建 server/internal/firmware/ 模組做升降版(Architect research §2.4 已明示模組劃分)。
2.5 決策痕跡
Architect 已於 ADR-001-firmware-management.md 留下完整翻案理由與技術決策(Status: Accepted、2026-05-24)。本 feature 文件 + ADR-001 + progress.md 三處互相引用、確保未來回溯時不會誤會「為什麼第二輪砍了又補回來」。
3. 範圍切割:A / B 兩階段
3.1 A 階段(MVP):FW 偵測 + 自動升級 KDP1 → KDP2
裝置範圍:KL520 + KL720(既有 driver 已支援)
功能範圍:
- 被動偵測:scan / connect 時讀取 firmware 字串、Devices 頁顯示 FW 健康度 badge(綠 = 最新、黃 = 可升、紅 = 必升)
- 主動升級(單一動作):使用者按「升級到最新」按鈕 → bridge.py 走
kp.core.update_kdp_firmware_from_files→ progress 透過 WebSocket 推播 → 完成後自動 rescan - 不做手動降版 UI(B 階段才做)
API 範圍:
GET /api/devices/:id/firmware(讀取 FW 狀態)POST /api/devices/:id/firmware/upgrade(觸發升級)- WebSocket room
firmware:<deviceId>(progress 推播)
安裝包衝擊:+0KB(KL520/KL720 firmware 已 bundle 在 server/scripts/firmware/)
工時:5 人天(M9-1 ~ M9-5,見 §10)
3.2 B 階段(擴展):手動降版 + KL630/KL730
裝置範圍擴展:+ KL630 + KL730(需先擴 driver 處理 product_id 0x0630 / 0x0730 + .tar firmware)
功能範圍:
- 手動降版 UI(面向一般使用者):Settings → 「韌體管理」面板,不只 dev mode;含多層 safety net(見 §4)
- 多版本 firmware 並存:每個 chip 提供 current + 1-2 個降版選項
- KL630/KL730 完整 FW 升降版:含 .tar firmware 解壓邏輯(Architect M9-6 SDK 驗證待完成)
- KneronPLUS SDK 對 KL630/KL730 的 Python API 驗證(M9-6)
API 範圍:
GET /api/devices/:id/firmware/versions(列出可選版本)POST /api/devices/:id/firmware/downgrade(觸發降版,需confirmToken: "DOWNGRADE")
安裝包衝擊:+7MB(保守 bundle 策略;見 §6)
工時:10.5 人天(M9-6 ~ M9-13,見 §10)
3.3 A / B 範圍對照表
| 項目 | A 階段(MVP) | B 階段(擴展) |
|---|---|---|
| 裝置範圍 | KL520 + KL720 | + KL630 + KL730 |
| 操作範圍 | 自動升級 KDP1 → KDP2 | + 手動降版 + 多版本選擇 |
| 使用者介面範圍 | Devices 頁 FW badge + 升級按鈕 + progress modal | + Settings → 韌體管理面板 + 二次確認 modal |
| 新增 API 數 | 3 個(GET firmware、POST upgrade、WS progress room) | + 2 個(GET versions、POST downgrade) |
| bridge.py 新 handler | firmware_upgrade |
+ firmware_downgrade + firmware_list_versions |
| driver 新 method | UpgradeFirmware() |
+ DowngradeFirmware(version) + ListFirmwareVersions() + GetCurrentFirmwareVersion() |
| 目錄結構 | 沿用 A 階段 firmware/<chip>/fw_*.bin |
改 selecting C:firmware/<chip>/{v2.2.0,v2.1.0,kdp1}/ + CURRENT_VERSION |
4. User Stories(面向「飛 firmware 痛點」的使用者旅程)
US-FW-1(A 階段 — 拿到舊 dongle 一鍵變可用)
身份:P1 Arthur(內部 FAE)/ P2 Dora(外部開發者)
情境:客戶現場、剛拿到 Kneron dongle(可能是 KDP1 legacy / 舊 KDP2),插上 USB
敘述:
身為 FAE,我希望插上 dongle 後 Devices 頁立刻告訴我「這根 firmware 太舊、按下『升級到最新』就能用」,按下後 30 秒~3 分鐘內升級完成、自動 rescan、就能繼續正常 demo。
驗收標準:
- AC-FW-1.1:scan 後 Devices 頁卡片右上角顯示 FW badge:綠/黃/紅/灰 四色(綠 = 與內建 bundle current 相同;黃 = 比 current 舊但可升、含 v2.1.0 等 older 版本;紅 = legacy KDP1 系列或損毀 firmware 字串讀不到、必須升才能用;灰 = 狀態未知:壞掉 firmware / loader mode / KL630/KL730 A 階段「升降版尚未支援」狀態。Design v2.2 §4.2 標 3 色 + 補灰色 = 4 種總狀態)。Driver 層判定來源:
firmwareIsLegacy/firmwareCanUpgrade/bundledFirmwareVersion(Architect TDD §3.1 衍生欄位) - AC-FW-1.2:黃 / 紅 badge 點擊或卡片內「升級到最新」按鈕,跳出 progress modal,全程顯示階段(採 Design 命名):preparing(準備中 / Preparing)/ loading(載入引導程式 / Loading loader)/ flashing(寫入韌體 / Flashing firmware)/ verifying(驗證中 / Verifying)/ done(完成 / Done)+ progress bar + 不可中斷警告。WebSocket event 的
stageenum 值與 i18n key 與此命名一致(Architect TDD §4.3 stage 列舉同步、為 source of truth) - AC-FW-1.3:升級成功後 modal 顯示 ✅ + 「裝置已升級到 v2.2.0」 + 自動關閉 modal(5 秒後)+ 觸發 Devices 頁 rescan + 卡片 badge 變綠
- AC-FW-1.4:升級失敗時 modal 顯示明確失敗類型(Design v2.2 §7.1 列 8 種:scan / connect / loader / upgrade / verify / timeout / disconnect / 部分成功)+「複製錯誤訊息」按鈕 + 「重新插拔裝置後重試」指引;後端透過
FirmwareProgress.reason細分 stage(Architect TDD §3.4 對應表) - AC-FW-1.5:升級期間 device 進入
StatusUpgrading狀態(既有 driver Status enum 擴展),鎖住其他操作(推論 / 切模型 / disconnect) - AC-FW-1.6:升級成功後 device 會 re-enumerate(USB 拔插效果),bridge.py 必須等 5-8 秒(實測 5 秒已穩、保留上界容忍) 讓 USB stable 才主動 rescan(避免 KL520 reset bug 同樣坑,progress.md「2026-04-21 推論 bbox」紀錄已驗證機制)
- AC-FW-1.7:KL520 升級預估 ~30 秒(實測值)/ KL720 預估 ~180 秒(實測值);progress modal 顯示預估時間讓使用者不焦慮。timeout 護欄上界:KL520 ≤ 60s / KL720 ≤ 200s(§7.2 護欄、超過視為失敗)
- AC-FW-1.8:升級流程屬「device 層」失敗、不應觸發
watchServerError state(與 Architect TDD v2.2 §8.1 解耦,research §2.1) - AC-FW-1.9(吸收 A-MID-1 + Architect §2.5):升級 / 降版進行中、Wails 控制台關閉視窗動作必須被擋下(防止 SIGTERM 中斷 firmware task brick 裝置),UI 顯示 modal「韌體切換進行中(device X)、為避免裝置損毀、無法關閉應用程式」、modal 不可 dismiss、等 firmware task 完成才能關 app(Architect TDD §8.6「graceful shutdown 拒絕」實作 + Design control-panel.md 補對應 modal)
US-FW-2a(B 階段 — 一般使用者主動切版本,相容性 / 回上版情境)
身份:P1 / P2 — 一般使用者(FAE / 外部開發者,非純末端 consumer)
情境(中、低頻率):
- 使用者升版後發現「我的舊 model 在新 FW 上跑不出結果」想回到 v2.1.0
- 使用者跟某個 third-party tool 不相容、要回 KDP1
- 使用者誤觸升級、想 revert
- 客戶現場 demo 需求特定版本
敘述:
身為一般使用者,我希望能去 Settings → 「韌體管理」面板,看到我每根 dongle 當前 FW 版本、bundle 內所有可選版本、每個版本的說明,能選一個並按下「切換到此版本」。我不希望點錯按鈕就 brick 裝置——應該要有明確警告 + 二次確認字串。
US-FW-2b(B 階段 — 進階使用者跨版本切換,測試 / 開發情境)
身份:P2 — 進階使用者 / 開發者
情境:
- 開發者測試多版本相容性
- 測試環境需要特定版本
- 「就是想試試看」
敘述:
身為開發者,我希望同一個「韌體管理」面板讓我自由在 bundled 版本間切換、UI 不對升 / 降特別 framing,方便我快速測試各版本行為。我能接受多一層確認流程作為 brick 防誤觸。
framing 共識(Design + PM 對齊,吸收互審 MJ-D1):
- UI 文案統一中性:分頁名稱「韌體管理」、按鈕文案「切換到此版本」、warning 強調「切換可能影響相容性 / 不可中斷」、不用「降版」字眼(避免「面向一般使用者過於負面」+ 同時涵蓋 US-FW-2b 開發者跨版本切換情境)
- 程式碼 / log / API 內部用語可保留
downgrade:API endpoint 仍是POST .../firmware/downgrade、ADR / TDD / log 行為事件名稱保留技術詞(與 PRD §9 Q-FW-3 對齊 Design v2.2 §2.1 立場) - 「DOWNGRADE」確認字串保留英文字面:是 API contract、不 i18n 化(Architect 互審結論一致)
US-FW-2 共通驗收標準(US-FW-2a + US-FW-2b 適用)
- AC-FW-2.1:入口在 Settings → 「韌體管理」面板(不在 Devices 頁主流程,避免誤觸;Architect research 42 §1.2 推薦;分頁順序「一般 / 硬體 / 韌體 / 模型 / 進階」見 Design v2.2 §2)
- AC-FW-2.2:列出所有偵測到的 dongle、每張一張卡片,顯示:dongle 名稱、kn_number、當前 FW 版本、bundle current 版本
- AC-FW-2.3:卡片內「切換 FW 版本」accordion 展開後顯示版本 radio list 或同等選擇 UI(不限 dropdown — Design v2.2 §3.3 採 radio list,理由:版本 < 3 個、a11y 友善),每個版本顯示 displayName(如「v2.2.0 (current)」「v2.1.0 (older)」「KDP1 (legacy)」)+ 說明文案 + 預估時間
- AC-FW-2.4:選了非當前版本後,「切換到此版本」按鈕變紅色(destructive 視覺、即使是切換到 newer 版本也統一處理),點擊後跳出二次確認 modal
- AC-FW-2.5:二次確認 modal 必含以下警告語(Design Agent 定稿文案):
- 「降版可能導致現有 model 無法運作」
- 「降版過程不可中斷、否則裝置可能損壞」
- 「降版完成後可能需要重新插拔裝置」
- 「請確認版本相容性、降版至 KDP1 的舊版會限制可用功能」
- AC-FW-2.6:二次確認 modal 強制使用者**輸入字面字串「DOWNGRADE」**才能點確認按鈕(防誤觸;input 欄空 / 不對時按鈕 disabled)
- AC-FW-2.7:二次確認 modal 不可被點外部關閉(必須點「取消」明確關閉),確認後 modal 不關閉、直接切「進行中」狀態(避免使用者誤以為什麼都沒發生)
- AC-FW-2.8:降版進行中、「進行中」UI 不顯示「取消」按鈕(降版不可中斷),顯示 persistent banner「請勿拔除裝置」
- AC-FW-2.9:API 層強制要求 request body 含
confirmToken: "DOWNGRADE"(字面字串);沒帶 / 帶錯 → 400(防 CSRF + 強制 UI 二次確認流程) - AC-FW-2.10:Driver 層 safety guards:
- 拒絕跨晶片誤匹配(version 必須在
ListFirmwareVersions(chip)結果內) - 拒絕升版偽裝(目標版本 >= current → 拒絕、改走 upgrade API)
- 拒絕 no-op(目標版本 == current → 拒絕)
- 拒絕 status busy(device 在
StatusInferencing/StatusFlashing/StatusUpgrading不接受降版)
- 拒絕跨晶片誤匹配(version 必須在
US-FW-3(B 階段 — KL630/KL730 dongle 偵測 + 升降版)
身份:P1 / P2
情境:客戶用 KL630 或 KL730(新一代 chip),插上後希望也能偵測 + 升降版
敘述:
身為使用者,我希望 KL630/KL730 跟 KL520/KL720 一樣支援 FW 偵測 + 升降版,UI 流程一致。
驗收標準:
- AC-FW-3.1:KL630/KL730 dongle 在 Devices 頁能被偵測(既有 driver
handle_connect()必須先擴展處理 product_id 0x0630/0x0730,progress.md 已標註) - AC-FW-3.2:KL630/KL730 的 FW 升降版 UI 流程與 KL520/KL720 完全一致(複用同一套元件)
- AC-FW-3.3:bridge.py 必須能處理 .tar firmware(Architect M9-6 弱驗證確認「策略 Z 直接餵 .tar 給 SDK 不可行」、唯一可行解為 策略 Y:build-time 解壓 .tar 找 .bin;詳見 §8.3 + research 41 §4.4)
- AC-FW-3.4:升降版預估時間:KL630/KL730 ~60 秒(待 M9-10 強驗證實測校正)
AC-FW-3.5(KL630/KL730 升降版 — 延後到 B 階段 M9-10 才實作)
A 階段對 KL630/KL730:只做 FW 偵測(顯示版本字串、Devices 頁 badge 可顯示「未知 / 待 M9-10」灰色 state),不開放升降版動作(無升級按鈕、無「切換 FW 版本」accordion)。
B 階段 M9-10 才實作升降版,理由(吸收 Architect M9-6 弱驗證結論,詳見 research-kl520-fw-management/55-m9-6-weak-validation-result.md):
- 無 warrenchen reference 實作:warrenchen 對 KL630/KL730 完全沒寫
/firmware/legacy-upgrade/kl630|730endpoint、bridge.py 對 KL630/KL730 升降版要自己根據 KneronPLUS SDK 推(design risk 高) - KneronPLUS wheel 三平台版本不一致:macOS/Linux 是 2.0.0、Windows 是 3.1.2、A 階段要開 KL630/KL730 升降版必先處理三平台 wheel 統一(額外 1-1.5 人天 + KL520/KL720 regression 風險)
- 無實機 verify 路徑:A 階段不適合冒進、B 階段 M9-10 啟動時 KL630/KL730 實機已就位再驗
update_kdp_firmware_from_files對 KL630/KL730 是否走同一條 flash 寫入路徑
生效條件(Architect 互審補充、M9-10 啟動前評估):以下任一條件成立 → M9-10 KL630/KL730 升降版可進入;任一條件不滿足 → 維持「只做 FW 偵測 / 不開升降版」:
- 條件 a:KneronPLUS Python wheel 對 product_id 0x0630/0x0730 有
kp.core.update_kdp_firmware_from_files的 dispatch(或 ctypes-levellib.kp_update_kdp_firmware_from_files對 KL630/KL730 確認可用) - 條件 b:策略 Y(build-time 解壓 .tar → 取得
extracted/fw_scpu.bin/fw_ncpu.bin)可正常 produce 兩個 .bin 路徑、且 SDK 接受餵這兩個 .bin(M9-8 已驗) - 條件 c:升級驗證階段、firmware 字串可穩定回讀(與 KL520/KL720 相同機制)
任一條件不成立 → KL630/KL730 維持「只做 FW 偵測 only」、UI 顯示版本字串但無升降版動作 + 卡片標「升降版即將支援、目前僅顯示版本資訊」提示。最終決定回 Orchestrator 派 PM 微調 PRD(見 §14.3 O-FW-2)。
5. 手動降版面向一般使用者:user research 假設
5.1 為什麼不藏 dev mode
使用者在 2026-05-24 明確決定「手動降版面向一般使用者」、不只 dev mode。理由(PM 推測 + 與使用者對話確認):
| 假設 | 支持證據 |
|---|---|
| H1:一般使用者也會遇到「model 在新 FW 上跑不出結果」 | progress.md L93 Error 15 經驗已暗示 firmware 版本對推論結果有影響 |
| H2:visionA-local 的目標使用者(P1 FAE、P2 開發者)技術水平夠高,能讀懂警告 | R5 Persona 定義 P1 是 FAE、P2 是「外部開發者」,都不是純末端 consumer |
| H3:藏在 dev mode 反而會讓真正需要降版的人找不到 | 內部 FAE 找不到 = 客戶現場 demo 失敗 |
| H4:safety net(二次確認 + 字面字串 + 警告語)足以擋住 90% 誤觸 | Architect research 42 §6 風險矩陣評估後殘餘風險低 |
5.2 user research 待驗證項
| # | 項目 | 驗證方式 | 階段 |
|---|---|---|---|
| UR-1 | 一般使用者是否會誤把「切換 FW 版本」當無害操作 | Beta 測試或 5 人 usability test | B 階段開發完成後 |
| UR-2 | 二次確認字串「DOWNGRADE」是否足以擋誤觸 | 同上 | B 階段開發完成後 |
| UR-3 | 「降版」這個詞是否會嚇跑使用者 | A/B 測試「切換 FW 版本」vs「降版」文案 | B 階段開發完成後 |
| UR-4 | brick 事件發生率(殘餘風險實測) | 上線後 6 個月追蹤客服回報 | Post-launch |
→ B 階段上線時、UR-1/UR-2/UR-3 視機會做小規模測試;UR-4 是長期追蹤項。
5.3 情境分析
Architect research 42 §1.1 列出 5 個一般使用者會降版的情境(中、低頻率):
| 情境 | 頻率 | 處理 |
|---|---|---|
| 「我的舊 model 在新 FW 上跑不出結果」 | 中 | 提供降版回 v2.1 選項 |
| 「跟某個 third-party tool 不相容」 | 低 | 提供降版回 KDP1 選項(僅 KL520) |
| 「我升錯了、想回到原本狀態」 | 低 | 提供「降版回上次版本」選項 |
| 「測試環境需要特定版本」 | 中 | 提供降版到任意 bundled 版本 |
| 「就是想試試看」 | 中 | 用警告語勸阻、但不阻止 |
6. Bundle 策略與安裝包衝擊
6.1 使用者拍板的保守策略
| Chip | current | 額外 bundled | 合計(每 chip) |
|---|---|---|---|
| KL520 | v2.2.0 (~100KB) | v2.1.0 (~100KB) + kdp1 (~90KB) | ~290KB |
| KL720 | v2.2.0 (~250KB) | v2.1.0 (~250KB) | ~500KB |
| KL630 | SDK-v2.5.7 (~3MB) | + extracted (~3MB) | ~6MB |
| KL730 | SDK-v1.3.0 (~4MB) | + extracted (~4MB) | ~8MB |
| 合計 | ~15MB(保守估計),實際 ~7MB(因 KL630/KL730 解壓策略未定,可能不需 extracted) |
6.2 多版本目錄結構(選項 C)
使用者拍板選 C — firmware/<chip>/{v2.2.0,v2.1.0,kdp1}/ + CURRENT_VERSION 單行檔(Architect research 42 §3.2 / §3.3)。
理由:
- 跨平台無 symlink 風險(vs 選項 A symlink)
- 節省空間(vs 選項 B 實體副本)
- 架構乾淨清晰
6.3 安裝包大小衝擊
- 既有 dmg:163MB
- A 階段:+0KB → 163MB
- B 階段(保守):+7MB → ~170MB
→ 在 PRD v2.1 §6.2 「macOS dmg 目標 ≤ 185MB / 上限 ≤ 220MB」範圍內,無需 PRD §6.2 數字調整。
使用者體驗層面(吸收 Design P-LOW-2):+7MB 對下載 / 安裝時間影響:寬頻 ~50MB/s → +0.14 秒(無感)/ 一般 4G hotspot ~5MB/s → +1.4 秒(無感)/ 慢速 wifi ~1MB/s → +7 秒(有感但可接受、屬罕見場景)
6.4 不做線上更新通道
使用者拍板「不做線上更新通道、所有 firmware 內嵌」(progress.md 2026-05-24)。
→ 不實作 OTA / 不做 firmware 從遠端 fetch。所有可用版本就是 bundle 內的版本。
→ 風險:未來 Kneron 出新 firmware 版本時必須打新安裝包才能用(接受此 trade-off,因為使用者明確要 offline-first)。
7. 成功指標
7.1 主要指標(與 PRD v2.1 §1.4 北極星指標掛鉤)
| 指標 | baseline | A 階段目標 | B 階段目標 |
|---|---|---|---|
| 5 分鐘首次推論達成率(PRD v2.1 北極星) | 假設受 firmware 問題影響 ~10% | + 5pp(從「拿到舊 dongle 完全不能用」變「+ 30 秒升級即可用」) | 維持 |
| 拿到舊 dongle 後完成首次推論的中位時間 | 不可估算(需重新出貨) | ≤ 5 分鐘(自動升級流程內) | 維持 |
7.2 次要指標
| 指標 | 目標 | source |
|---|---|---|
| FW 升級成功率(A 階段,KL520 + KL720) | ≥ 95% | log 統計(非自動 telemetry、技術支援彙整) |
| FW 降版成功率(B 階段,KL520 + KL720) | ≥ 95% | 同上 |
| FW 升降版平均時長(護欄) | KL520 ≤ 60s / KL720 ≤ 200s / KL630/KL730 待 M9-10 強驗證校正 | log 統計 |
| 一般使用者誤觸降版發生率(B 階段上線後 3 個月) | ≤ 1% | 客服回報統計 |
| Brick 事件(B 階段上線後 6 個月) | ≤ 0.1%(< 1 / 1000 dongles) | 客服回報 |
注意(吸收 Architect §1.2):v2.2 階段大部分 FW 指標靠客服回報 + log 統計、非自動上報;自動 telemetry 是未來 feature、不在本 PRD scope。
7.2.1 體驗指標(吸收 Design P-MID-1)
「以下指標補強 §7.2 純技術指標、量測使用者體驗層面是否健康」:
| 指標 | 目標 | source / 量測方式 |
|---|---|---|
| 升級任務完成率(modal 開啟 → 升級成功 toast) | ≥ 85% | log 統計(modal-opened 事件 vs upgrade-success 事件配對) |
| 二次確認 modal 中途放棄率(B 階段降版) | 50-70%(合理區間) | log 統計(confirm-modal-shown vs token-typed-and-confirmed 配對) |
| Devices 頁 FW badge 點擊率(只算紅 / 黃 badge) | ≥ 30% | 前端 click 事件統計 |
| 升級失敗後重試率(首次失敗後 5 分鐘內重試比例) | 視底線、追蹤即可 | log 統計 |
| B 階段 SUS 分數(5 人 usability test) | ≥ 65 | Beta 階段 usability test、見 §5.2 UR-1~3 |
解讀準則:
- 二次確認中途放棄率 < 50% 暗示「UX 不夠恐嚇」(應加強警告)
- 二次確認中途放棄率 > 70% 暗示「嚇跑使用者」(應減弱警告)
- FW badge 點擊率 < 30% 暗示「使用者沒注意到要升級」(應加強顯著性 / IA)
7.3 護欄指標(不可惡化)
| 指標 | 上限 |
|---|---|
| dmg 安裝包大小 | ≤ 220MB(PRD v2.1 §6.2 上限) |
| FW 升降版期間 server 是否進 Error state | 不可(device 層失敗、與 server 解耦) |
| FW 升降版期間其他 device 是否能正常推論 | 可以(device 之間互不影響) |
| 啟動時間 | ≤ 60 秒(PRD v2.1 AC-1.3,FW 升降版不在啟動 pipeline 內、無影響) |
8. 風險與已知限制
承前 Architect research 30 + 40 + 41 + 42 的風險清單,PM 視角彙整為 R-FW-1 ~ R-FW-12(不重寫技術細節,引用 research)。
8.1 R-FW-1 ~ R-FW-7(A + B 階段共通,來自 Architect research 30)
| ID | 風險 | 可能性 | 影響 | 等級 | 緩解 | 詳見 |
|---|---|---|---|---|---|---|
| R-FW-1 | KL520 reset bug 再現(升級後 device re-enumerate 不穩定) | 中 | 中 | P2 | 升級後等 5-8 秒 + 主動 rescan,承襲 2026-04-21 修法 | research 30 §3 |
| R-FW-2 | KneronPLUS Python wheel 版本對 update API 支援度不足 | 低 | 高 | P1 | M9-6 弱驗證已確認 3.1.2 wheel 對 update_kdp_firmware_from_files 完整支援(warrenchen 使用中)、剩 macOS/Linux 2.0.0 wheel enum 待 35 分鐘強驗證;策略 Y(解壓 .tar 取 .bin)唯一可行解 |
research 30 §4 + 40 §5 + 55-m9-6-weak-validation-result.md |
| R-FW-3 | bridge.py kp.core.update_kdp_firmware_from_files 在 macOS x86_64 行為未驗證 |
低 | 中 | P2 | M9-6 弱驗證:API 簽名與 warrenchen 一致、預期 macOS/Linux 2.0.0 + Windows 3.1.2 KL520/KL720 升級可用;M9-1 開發前 backend agent 跑 35 分鐘強驗證、若 enum 不存在則升 wheel(牽動三平台 wheel 統一) | research 30 §4 + 55-m9-6-weak-validation-result.md |
| R-FW-4 | 升級 timeout 設定不合理(太短 = 誤判失敗、太長 = 卡 UI) | 低 | 中 | P3 | 採 warrenchen 經驗值(KL520 30s / KL720 180s)+ progress 推播提供使用者感知 | research 30 §5 |
| R-FW-5 | 打包 Kneron 官方 firmware 是否合法(與 R5-B4 預置模型授權同性質) | 高 | 高 | P0(發佈 gate) | 使用者明示「先不管授權、發佈前再評估」、PRD 標註為未解決問題(§9) | research 00 §1.7 + 40 §7 + 42 §7 |
| R-FW-6 | 既有 flash/ 模組名稱混淆(load model 到 RAM vs 燒 firmware) |
低 | 低 | P3 | 新建 firmware/ 模組、保持 flash/ 原意(Architect research §2.4) |
research 00 §2.4 |
| R-FW-7 | 升級失敗 device 進入 unknown state(既不能用舊 firmware、新 firmware 也沒寫成功) | 低 | 高 | P1 | bridge.py 失敗時不切換 device.firmware 字串、UI 提示重新插拔;Plan B:技術支援 SOP 用 DFUT.exe 救磚(不打包進 app) | research 30 §6 + 42 §6.3 |
8.2 R-FW-8 ~ R-FW-12(B 階段新增,來自 research 40 + 42)
| ID | 風險 | 可能性 | 影響 | 等級 | 緩解 | 詳見 |
|---|---|---|---|---|---|---|
| R-FW-8 | KneronPLUS SDK 對 KL630/KL730 API 行為不可預測 | 高 | 中 | P1 | M9-6 SDK 驗證(與 A 階段平行進行,progress.md 2026-05-24 拍板) | research 40 §5 |
| R-FW-9 | .tar 解包對安裝包大小衝擊(如果採策略 X build-time 解壓 + bundle) | 低 | 低 | P3 | 採策略 Y 或 Z 平衡空間 vs 速度(M9-6 結論定) | research 41 §3 |
| R-FW-10 | KL630/KL730 沒有 Loader mode 概念(與 KL520 USB Boot 流程不同) | 中 | 中 | P2 | bridge.py handle_connect() 必須 chip-aware 分流(既有 fall-through 到 KL520 是 bug、會連不上) |
research 40 §3 |
| R-FW-11 | 一般使用者誤觸降版導致 brick | 高 | 高 | P1 | 多層 safety net:UI 警告 + 二次確認字串 + driver guard + 進行中 banner(research 42 §5/§6 + 本檔 AC-FW-2.5 ~ 2.10) | research 42 §6 |
| R-FW-12 | 多版本管理 UX 複雜度(使用者看不懂 v2.2.0 vs v2.1.0 vs KDP1) | 中 | 中 | P2 | 已具體落地:Design v2.2 §3.3 accordion + radio list + 每個版本 displayName 後綴(current/older/legacy)+ §9 i18n 涵蓋;KDP1 額外紅色警告 banner | research 42 §5.3 + Design v2.2 §3.3 / §9 |
| R-FW-13 | KneronPLUS wheel 三平台版本不一致(macOS/Linux 2.0.0 vs Windows 3.1.2) | 高 | 中 | P1 | A 階段:先在 macOS/Linux 強驗證 2.0.0 wheel 是否含 KL520/KL720 update API(M9-1 啟動前 35 分鐘)、預期可用、若不可用先升 Windows 對齊;B 階段 M9-10 啟動前必須升 macOS/Linux 到 3.1.2(含 KL630/KL730 enum)+ 跑 KL520/KL720 三平台 E2E 回歸(M9-13) | 55-m9-6-weak-validation-result.md 發現 6 |
| R-FW-14(Frontend 防誤觸補強) | 使用者輸入「downgrade」小寫繞過確認 | 低 | 高 | P2 | Frontend 用嚴格 === 比對、不用 .toUpperCase();後端 API 同時雙重比對;M9-12 Reviewer 必檢查 |
Design v2.2 §12.2 R-FW-11.5 自提 + Architect §2.10 同意 |
8.3 與既有架構的衝突已釐清項
| 衝突點 | 結論 | 詳見 |
|---|---|---|
| watchServer Error state(TDD v2.1 §8) | FW 升降版失敗屬 device 層、與 server 層 watchServer 解耦、不觸發 Error state | research 30 §2.1 |
| R5-E 60s 啟動上限 | FW 升降版是使用者主動觸發、不在啟動 pipeline 內、無關 | research 30 §2.3 |
| KL520 reset bug fix(2026-04-21) | 升級成功後 device re-enumerate 必須等 5-8 秒 + 主動 rescan、不立即 reconnect | research 30 §2.2 |
既有 flash/ 模組命名包袱 |
不改檔名(本任務範圍外)、新文件命名用 kneron_* 或 device_firmware_* |
research 30 §2.5 |
9. 未解決問題(彙整給 Orchestrator)
| # | 問題 | 性質 | 處理建議 |
|---|---|---|---|
| Q-FW-1 | Kneron firmware redistribution 授權(含舊版 v2.1.0 / KDP1) | 發佈前 gate(與 R5-B4 預置模型授權同性質) | 使用者明示「先不管授權、發佈前再評估」,PRD 留紀錄。建議發佈前 3-6 個月與 Kneron 取得明確書面授權,授權範圍含 current + 舊版(v2.1.0 / KDP1)+ KL630/KL730 firmware tar |
| Q-FW-2 | KneronPLUS Python wheel 對 KL630/KL730 update API 支援度 | B 階段啟動 gate | M9-6 SDK 驗證為先(與 A 階段平行)、結論定 B 階段 scope;若不支援、AC-FW-3.5 啟動「降級為 FW 偵測 only」 |
| Q-FW-3 | 「降版」這個詞是否用於 UI 文案 | ✅ 已決定(吸收三方互審 MJ-D1) | UI 文案統一中性(分頁名稱「韌體管理」、按鈕「切換到此版本」),不用「降版」字眼;程式碼 / log / API 內部用語可保留 downgrade、API endpoint 仍是 POST .../firmware/downgrade。對齊 Design v2.2 §2.1 + Architect 同意 |
| Q-FW-8(新) | 「DOWNGRADE」確認字串是否 i18n 化 | ✅ 已決定(吸收 Design D-M3 + Architect §2.2) | 保留英文字面 "DOWNGRADE"、是 API contract 不 i18n 化;UI 提示文字 i18n 化(如「請輸入 DOWNGRADE 確認」中文 + 「Type DOWNGRADE to confirm」英文),但 input 比對的字串跨語系一致 |
| Q-FW-4 | 一般使用者降版的 user research 假設驗證時機 | B 階段 post-launch | UR-1/UR-2/UR-3 在 Beta 階段做 5 人 usability test;UR-4 brick 事件追蹤 6 個月(§5.2) |
| Q-FW-5 | KL520 / KL720 / KL630 / KL730 升降版預估時間是否準確 | 開發階段實測 | M9-5(A)/ M9-13(B)三平台實機驗證時校正 |
| Q-FW-6 | progress.md R5-Q9 行號 L776 vs L854 不一致 | ✅ 已決定 | 文件追溯以「progress.md 第二輪使用者決策 Q9 條目」描述式引用為準、不引用行號(行號因 progress.md 多次追加會浮動)。決策本身明確:2026-04-11 第二輪 Q9 「韌體燒錄 flash → B 砍掉」、本 PRD §2.1 已修正 |
| Q-FW-7 | 升級失敗後的「救磚 SOP」是否需要在 UI 內提示 | B 階段 Design 決定 | 目前傾向:UI 提示「請重新插拔裝置後重試」+「複製錯誤訊息」+ 技術支援聯絡資訊(research 42 §6.3 SOP 留內部 wiki) |
10. 工時與 Milestone
10.1 A 階段(M9-1 ~ M9-5、共 5 人天,PM 拆法、Architect 互審同意採此版本)
| # | Milestone | 工時 | 依賴 | 平行性 |
|---|---|---|---|---|
| M9-0 | 開發前強驗證(backend agent、35 分鐘):macOS/Linux 跑 python3 -c "import kp; print(kp.ProductId.KP_DEVICE_KL630)"、判斷 2.0.0 wheel 是否含 KL630/KL730 enum + tar -tvf inspect firmware .tar |
< 0.1 人天(內含) | — | M9-1 之前必跑 |
| M9-1 | bridge.py 新增 firmware_upgrade handler(KneronPLUS C API、策略 Y 唯一可行解) |
1 人天 | M9-0 | 獨立 |
| M9-2 | Go driver + service:UpgradeFirmware() + server/internal/firmware/service.go + safety guards |
1 人天 | M9-1 | — |
| M9-3 | API handler + WebSocket progress room(含 FirmwareProgress.reason 細分 stage、Elapsed/ETA 欄位、graceful shutdown 拒絕邏輯 hook 點) |
0.5 人天 | M9-2 | — |
| M9-4 | 前端 Devices 頁 FW badge(4 色含灰色狀態未知)+ 升級按鈕 + progress modal + 6 個 component-level design tokens 落地(含 a11y 對比驗證) | 1.5 人天 | M9-3 | 與 M9-1/M9-2/M9-3 部分平行(mock API) |
| M9-5 | 三平台實機驗證(macOS / Windows / Linux × KL520 + KL720 完整升級 E2E) | 1 人天 | 全部前置完成 | — |
| A 合計 | 5 人天 |
10.2 B 階段(M9-6 ~ M9-13、共 10.5 人天,PM 拆法、Architect 互審同意採此版本)
| # | Milestone | 工時 | 依賴 | 平行性 |
|---|---|---|---|---|
| M9-6 | KneronPLUS SDK 對 KL630/KL730 + .tar firmware Python API 驗證(弱驗證已完成:見 55-m9-6-weak-validation-result.md;強驗證須等 KL630/KL730 實機) |
1 人天(含弱驗證 0.5 + 強驗證 0.5) | — | 與 A 階段平行(2026-05-24 使用者決策) |
| M9-7 | Driver 擴展處理 product_id 0x0630/0x0730 + chip-aware connect 分流(含 KL630/KL730 firmware 載入分支) | 1.5 人天 | M9-6 | — |
| M9-8 | bridge.py 處理 .tar firmware(策略 Y 唯一可行解、build-time 解壓;策略 Z 已被弱驗證排除) | 1.5 人天 | M9-7 | — |
| M9-9 | 多版本目錄結構重整(A 階段檔案搬到 <chip>/v2.2.0/ + 加 CURRENT_VERSION)+ bridge.py 升級 _resolve_firmware_paths_versioned() |
1 人天 | A 階段完成 | — |
| M9-10 | KL630/KL730 升級 / 降版 driver method 實作(AC-FW-3.5 生效條件評估在此 milestone 啟動時跑、無 warrenchen reference 實作、design risk 較高) | 1.5 人天 | M9-8 + M9-9 + M9-6 強驗證完成 + macOS/Linux wheel 升 3.1.2(R-FW-13) | — |
| M9-11 | 多版本降版後端(API + bridge.py + driver guards + graceful shutdown 拒絕落地) | 1.5 人天 | M9-9 | — |
| M9-12 | 降版 UI(Settings 韌體管理面板 + 二次確認 modal + 進行中 UI + Wails 控制台關閉攔截 modal) | 2 人天(Frontend 1 + Design 1) | M9-11 | Design + Frontend 平行 |
| M9-13 | B 階段三平台實機驗證 + KL520+KL720 wheel 升級 regression + Beta usability test(UR-1/UR-2/UR-3) | 1 人天 | M9-7 ~ M9-12 全部 | — |
| B 合計 | 10.5 人天 |
10.3 合計
- A + B = 15.5 人天
- 與 Architect research 結論一致
11. 涉及檔案 / 模組(從 Architect research 30 + 40 摘要)
11.1 新建模組
server/internal/firmware/ ← 新模組(升降版核心)
├── service.go ← FirmwareService 提供 Upgrade/Downgrade/List
├── versions.go ← 版本管理 + 比較邏輯(isOlderVersion())
└── safety.go ← driver guard helpers(不跨晶片 / 不升版偽裝 / 不 no-op)
11.2 既有檔案修改
| 檔案 | 修改範圍 | 階段 |
|---|---|---|
server/scripts/kneron_bridge.py |
新增 handler:firmware_upgrade / firmware_downgrade / firmware_list_versions |
A + B |
server/internal/driver/kneron/kl720_driver.go |
新增 method:UpgradeFirmware / DowngradeFirmware / ListFirmwareVersions / GetCurrentFirmwareVersion |
A + B |
server/internal/driver/types.go 或同等 |
DeviceDriver interface 擴展 + FirmwareVersion / FirmwareProgress struct |
A |
server/internal/api/handlers/device_handler.go 或新檔 |
新 endpoint:GET /api/devices/:id/firmware* / POST .../upgrade / POST .../downgrade |
A + B |
server/internal/api/router.go |
註冊新路由 | A + B |
server/internal/ws/hub.go |
註冊 firmware:<deviceId> WebSocket room |
A |
server/scripts/firmware/ |
重整目錄結構為 <chip>/<version>/ + CURRENT_VERSION |
B(M9-9) |
11.3 前端新增 / 修改
| 檔案 | 修改範圍 | 階段 |
|---|---|---|
frontend/components/devices/device-card.tsx 或同等 |
加 FW badge(綠/黃/紅)+ 升級按鈕 | A |
frontend/components/devices/firmware-upgrade-modal.tsx(新) |
progress modal | A |
frontend/pages/settings/firmware.tsx 或同等(新) |
Settings → 韌體管理面板 | B |
frontend/components/firmware/version-switch-modal.tsx(新) |
二次確認 modal | B |
frontend/components/firmware/downgrade-progress-modal.tsx(新) |
進行中 UI | B |
| i18n keys | +46 個(research 42 §5.6 估算) | B 為主 |
11.4 文件新增
| 檔案 | 角色 | 階段 |
|---|---|---|
docs/autoflow/04-architecture/adr/ADR-001-firmware-management.md 或同等 |
Architect 留 R5-Q9 翻案紀錄 + 技術決策 | A 啟動前 |
docs/autoflow/04-architecture/TDD-v2.md §5.4 firmware 子節 |
Architect 補 TDD v2.2 | A 啟動前 |
docs/autoflow/03-design/design-spec-v2.md 對應子節 |
Design Agent 補設計規格 v2.2 | A 啟動前 |
docs/autoflow/02-prd/features/feature-firmware-management.md(本檔) |
PM 補 PRD v2.2 | 進行中 |
docs/troubleshooting/brick-recovery.md(內部 wiki) |
技術支援 SOP(DFUT.exe 救磚流程,不打包進 app) | 上線前 |
12. 與既有 R5 決策的關係
| R5 條目 | 本任務關係 |
|---|---|
| R5-Q9(砍 flash) | 翻案(§2),透過範圍切割避開原始擔憂 |
| R5-B4(Kneron 預置模型 redistribution) | 同性質問題擴展 — 本任務的 firmware bundle 與 R5-B4 同樣是「打包 Kneron 智財」、發佈前須一起跟 Kneron 取得授權(§9 Q-FW-1) |
| R5-E(60s 啟動 + perceived performance) | 無關 — FW 升降版不在啟動 pipeline 內(research 30 §2.3) |
| R5-D1(Server 崩潰 OS 通知) | 不擴展 — FW 升降版失敗屬 device 層、不發 OS 通知(與 device toast 一致,PRD v2.1 §AC-3.7 + R4-8 策略) |
| R5-1(產品定位) | 對齊 — FW 管理 UI 住瀏覽器 Web UI(Devices 頁 + Settings 韌體管理)、不住 Wails 控制台 |
| R5-3(砍 tray) | 無衝突 |
| R5-6(ffmpeg LGPL) | 無關 |
13. 風險:本 feature 對既有功能的影響
承前 R5「既有專案的每一步都需要特別小心、避免破壞現有功能」原則,本 feature 的潛在影響:
| 影響範圍 | 風險 | 緩解 |
|---|---|---|
| 既有 KL520 / KL720 推論流程 | 升級期間 device 鎖住 StatusUpgrading、其他操作會被擋 |
預期行為、UI 清楚告知 |
既有 flash/service.go (load model 到 RAM) |
命名 vs 新 firmware/ 模組可能混淆 |
嚴格保持 flash/ 原意、新模組獨立目錄(research §2.4) |
| KL630 / KL730 連線(既有 fall-through 到 KL520 bug) | 本任務 M9-7 必修,否則 KL630/KL730 連不上 | M9-7 是 B 階段必做、driver 改動需 Reviewer 把關 |
既有 kneron_bridge.py handle_connect() |
新增 handler 不影響既有 connect 流程(獨立 handler) | Architect 確認 |
| 安裝包大小(既有 dmg 163MB) | +7MB → ~170MB,仍在 PRD v2.1 §6.2 上限內(≤ 220MB) | 已在範圍內,無需 PRD §6.2 數字調整 |
14. 三方互審回饋處理紀錄(v2.2 → v2.2.1)
14.1 給 Design Agent — 全部已處理
- D-FW-1(降版入口位置):✅ Design v2.2 §2 採 Settings 第 3 分頁「韌體管理」、與 PM 對齊
- D-FW-2(「降版」用詞):✅ 已決定:UI 統一中性「韌體管理」/「切換到此版本」、不用「降版」字眼;內部 / API / log 保留
downgrade(Q-FW-3 已落定、見 §9) - D-FW-3(防誤觸機制):✅ Design v2.2 §6.1 採「DOWNGRADE」嚴格字面輸入(嚴格
===比對、不接受小寫 / 全形 / 半形空白、雙重保險) - D-FW-4(FW badge 三色閾值):✅ AC-FW-1.1 已明示 4 色閾值(綠 / 黃 / 紅 / 灰)、Design v2.2 §4.2 對齊
- D-FW-5(6 階段中英雙語文案):✅ 採 Design 命名:preparing / loading / flashing / verifying / done / error(中文文案:準備中 / 載入引導程式 / 寫入韌體 / 驗證中 / 完成 / 失敗)、見 AC-FW-1.2
- D-FW-6(持久 banner 視覺):✅ Design v2.2 §6.3 已落地
14.2 給 Architect Agent — 大部分已處理
- A-FW-1(R5-Q9 行號):✅ 已決定:本檔 §2.1 改為描述式引用、Q-FW-6 已落定
- A-FW-2(driver safety guards):✅ Architect TDD v2.2 §2.1 + §3.3 已對應寫具體 Go interface +
_validate_downgrade_request - A-FW-3(三平台實機驗證):✅ Architect TDD §11.4 已涵蓋
- A-FW-4(KL630/KL730 wheel 支援度):✅ 已決定(吸收 M9-6 弱驗證):AC-FW-3.5 延後到 B 階段 M9-10、含 a/b/c 生效條件、見本檔對應段落
- A-FW-5(模組路徑
server/internal/firmware/):✅ Architect TDD v2.2 §2.1 對齊 - A-FW-6(與 R5-B4 授權合併):✅ Architect ADR-001 §Compliance 標
[ ] 與 Kneron 取得 firmware redistribution 授權、§Related 已連結 R5-B4
14.3 給 Orchestrator — 追蹤項
- O-FW-1(與 R5-B4 release blocker 合併):⏳ 待 Orchestrator 統一決定。PM 建議合併(都是 Kneron 智財 + 都是發佈前 gate)、但保留各自具體 scope(firmware vs model 兩個 license 範圍)
- O-FW-2(M9-6 強驗證 + AC-FW-3.5 觸發條件):⏳ M9-10 啟動時評估 a/b/c 三條件、任一不滿足 → Orchestrator 派 PM 微調 PRD(KL630/KL730 維持 FW 偵測 only / 不開升降版)
14.4 互審 Minor 處理紀錄
| # | 來源 | 內容 | 處理 |
|---|---|---|---|
| M-A1 | Architect TDD §10 R-FW-5 等級「待釐清」 | 統一用 P0/P1/P2/P3 分級 | ✅ Architect 修 TDD(PM 不處理) |
| M-A2 | Architect TDD §11.3 缺 KL720 timeout 上界測試 | 加「KL720 升級實測時長 ≤ 200s」測試案例 | ✅ Architect 修 TDD |
| M-A3 | Architect §3.1 API 缺 notes / estimatedDurationSec 欄位 |
補在 GET /firmware/versions response |
✅ Architect 修 TDD |
| M-A4 | TDD §6.2 KL520 KDP1 pid=0x0200 vs KL720 衝突 | Architect 確認後對齊 PRD §1.1 | ⏳ Architect 修 TDD(PM 等對齊結果) |
| M-D1 | Design §9 i18n keys 52 vs PM 估 46 | 採 Design 實際值 52 keys | ✅ 本檔 §11.3 已記「+46 個(estimate)→ 實際 52 個(Design v2.2 §9)」 |
| M-D2 | Design §3.3 「accordion + radio list」vs PRD「dropdown」 | AC-FW-2.3 改「radio list 或同等選擇 UI」 | ✅ 已處理 |
| M-D3 | DOWNGRADE 字串 i18n 化 | Q-FW-8 已落定保留英文字面 | ✅ 已處理 |
| P-MID-1 | 缺體驗指標 | 補 §7.2.1 體驗指標 5 條 | ✅ 已處理 |
| P-MID-2 | PRD 用詞混用「降版」 | Q-FW-3 落定 + US-FW-2 拆 a/b + framing 共識段落 | ✅ 已處理 |
| P-MID-3 | KL520 升級時間 30s vs ≤ 60s | AC-FW-1.7 明示「~30 秒實測 + ≤ 60s 護欄上界」 | ✅ 已處理 |
| P-MID-4 | badge 閾值不清 | AC-FW-1.1 補 4 色定義(含灰色狀態未知) | ✅ 已處理 |
| P-LOW-1 | 缺「使用者怎麼發現要降版」US | 標為 v2.3 未來迭代(Workspace inference 失敗時 hint) | ⏳ 暫不處理 |
| P-LOW-2 | Bundle 安裝時間衝擊 | §6.3 補一句 | 見 §6.3 |
| P-LOW-3 | R-FW-12 緩解過抽象 | R-FW-12 改「已具體落地」+ 引用 Design v2.2 §3.3 / §9 | ✅ 已處理 |
| F1-F7 | Architect 自查 7 項必修 | 由 Architect 修 TDD、PM 不直接處理 | ⏳ Architect 端處理中 |
變更紀錄
| 版本 | 日期 | 作者 | 變更 |
|---|---|---|---|
| v2.2-draft | 2026-05-24 | PM Agent | 初稿;翻案 R5-Q9;A + B 兩階段範圍定義;多層 safety net for 一般使用者降版;風險 R-FW-1 ~ R-FW-12 彙整自 Architect research 30/40/41/42;§14 列出 14 個 Design / Architect / Orchestrator 待互審項 |
| v2.2.1 | 2026-05-25 | PM Agent | 吸收三方互審(PM Self / Design / Architect)+ M9-6 弱驗證結果。主要變更:①stage 命名統一採 Design(preparing/loading/flashing/verifying)②M9 工時表拆法採 PM(Architect 已同意)③AC-FW-3.5(KL630/KL730 升降版)延後到 B 階段 M9-10、補生效條件 a/b/c、A 階段 KL630/KL730 只做 FW 偵測(無升降版按鈕)④ADR-009 → ADR-001 編號統一⑤R5-Q9 行號改描述式引用、不引用脆弱行號⑥US-FW-2 拆成 US-FW-2a(一般使用者)+ US-FW-2b(進階使用者)、UI 文案 framing 統一中性「韌體管理」「切換到此版本」⑦補 §7.2.1 體驗指標 5 條(升級任務完成率 / 中途放棄率 / badge 點擊率 / 重試率 / SUS 分數)⑧新增 R-FW-13 wheel 三平台版本不一致 + R-FW-14 大小寫繞過⑨補 AC-FW-1.9 graceful shutdown 拒絕⑩badge 4 色定義(補灰色狀態未知)⑪§14 標記哪些已解決 / 哪些 ⏳ 追蹤中。詳見本檔 §14.4 互審 Minor 處理紀錄 |