diff --git a/openspec/changes/gpu-session-baseline-and-idle-reclaim/proposal.md b/openspec/changes/gpu-session-baseline-and-idle-reclaim/proposal.md new file mode 100644 index 000000000..94254971c --- /dev/null +++ b/openspec/changes/gpu-session-baseline-and-idle-reclaim/proposal.md @@ -0,0 +1,19 @@ +## Why + +自 `add-single-gpu-session-ai-review-mvp`(已於 2026-07-28 標 `Status: deferred`)切出的最小可完成切片。依 2026-07-28 read-only 盤點,該傘型 change 中真正無人認領、且不依賴 SessionBroker/IfcClash/LLM/BCF 3.0 等重物的獨有主線只有兩條: + +1. **單 GPU 容量的量化缺口至今無答案**:repo 唯一數字來源是 `docs/verification/2026-06-05-host-gpu-runtime-reality-check.md` 的一次性環境快照——無 per-stream VRAM、無 TTFF、無建立成功率、無 soak 斜率、無任何 SLO 數值;`KitGpuFleetPage` 自標「GPU busy / total = 未取得」。先量測、再談任何 admission/排程承諾(母 change MVP 哲學原文)。 +2. **忘關分頁餓死洞已有使用者裁決但未實作**(2026-07-22 原話「同意, 但是前端追加 session 進入倒數10秒顯示」):無互動軟門檻+前端 10 秒回收倒數。此路徑不依賴佇列/SessionBroker,可疊加落在既有 coordinator session close 路徑上。 + +## What Changes + +- **`gpu-session-baseline`**(New capability):量測 harness `measure-session-baseline.ps1`(nvidia-smi+WebRTC health probe+TTFF+建立成功率)、環境指紋必填 schema+驗證測試、隔離 stack ≥30 分鐘 soak 記憶體斜率、由本地實測訂 SLO 具體數值寫入部署文件(禁引用外部數字)、「指紋變動即 SLO 失效」+無基準報告時 admission 參數 loader 硬 gate。 +- **`session-lifecycle`**(New capability,slim delta):只含「回收倒數與互動保活」第二回收路徑——互動事件上報彙整、連續 T_inactivity 觸發、10 秒倒數廣播與前端倒數 UI、任一互動取消並重置、歸零經既有 session close 路徑 teardown(reason=inactivity 入 session ledger)。佇列、SessionBroker、健康探針自動復原、202 冷啟動等其餘 lifecycle 語意**不在本 change**。 +- 一律疊加式:不動凍結三檔(`app.py`/`conversion_authority.py`/`governanceProxy.ts`),不改既有 route/response shape。 + +## Impact + +- Affected specs: `gpu-session-baseline`(new)、`session-lifecycle`(new,slim)。 +- Affected code: `scripts/`(harness+最小驗證測試)、可稽核部署文件、`bim-review-coordinator`(additive:互動上報彙整+倒數觸發+close reason)、`web-viewer-sample`(倒數 UI+E2E)。 +- **與 deferred 母 change 的關係**:本 change 承接其 T1 六項(1.1–1.5、2.11)。母 change 對應 delta(`gpu-session-baseline` 三條 Requirement、`session-lifecycle` 的「回收倒數與互動保活」Requirement)於 thaw crosswalk 時標記由本 change 承接,不得平行實作;本 change 的 Requirement 名稱刻意沿用母版以利 crosswalk。 +- **明確不做**(supersede/frozen 證據見母 change Status 段):SessionBroker 抽象與 contract test、primary 佇列、202 冷啟動、健康探針自動復原、IfcClash/LLM 草稿管線、人審 triage 佇列、BCF-API 3.0(zip 骨架已有=`governance-service/bcf/bcf_writer.py`,BCF 2.1)、跨版本冪等指紋(機制已有=`governance-service/diff_engine/keys.py`)。 diff --git a/openspec/changes/gpu-session-baseline-and-idle-reclaim/specs/gpu-session-baseline/spec.md b/openspec/changes/gpu-session-baseline-and-idle-reclaim/specs/gpu-session-baseline/spec.md new file mode 100644 index 000000000..f8f50766b --- /dev/null +++ b/openspec/changes/gpu-session-baseline-and-idle-reclaim/specs/gpu-session-baseline/spec.md @@ -0,0 +1,55 @@ +## ADDED Requirements + +### Requirement: 基準量測腳本 SHALL 產出含環境指紋的結構化基準報告 + +執行 `measure-session-baseline.ps1` 時 SHALL 產出結構化基準報告,內容 SHALL 至少含:GPU 型號盤點(判定是否消費級 RTX、確認 MIG 不可用 → 鎖定軟體佇列路線)、1 primary + k spectator 下 VRAM 水位、time-to-first-frame(TTFF)、建立成功率。取樣 SHALL 使用 nvidia-smi(VRAM/利用率)+ WebRTC health probe + TTFF。報告 schema SHALL 含「環境指紋」必填欄位:GPU 型號、driver 版本、Kit 版本、量測 fixture 的 hash + 大小。 + +#### Scenario: 執行基準量測 + +- **WHEN** 在目標部署環境執行 `measure-session-baseline.ps1` +- **THEN** SHALL 產出含 GPU 型號盤點、VRAM 水位、TTFF、建立成功率的結構化報告 +- **AND** 報告 SHALL 含 GPU 型號/driver 版本/Kit 版本/fixture hash+大小的環境指紋必填欄位 + +#### Scenario: 缺環境指紋欄位 + +- **WHEN** 產生的基準報告缺任一環境指紋必填欄位 +- **THEN** 報告 SHALL 判定為不完整 +- **AND** 後續 SLO 形式化與任何 admission 參數 loader SHALL NOT 引用該報告 + +### Requirement: 長連線 soak test SHALL 在隔離量測窗產出記憶體斜率報告且門檻只由本地實測決定 + +一條 warm primary 連線 SHALL 跑 ≥30 分鐘(目標 2 小時)soak 並產出記憶體斜率報告。洩漏 watchdog 門檻 SHALL 完全依本次本地實測結果訂定,SHALL NOT 引用未經本地驗證的任何外部系統數字(含任何 GB/日 之類外部洩漏率)。soak SHALL 於隔離 stack(獨立埠、獨立 governance)+獨佔量測窗執行,harness SHALL 內建最小 keepalive health probe 維持連線活性,量測期間 SHALL NOT 共用入口。soak 期間自然斷流 SHALL 記為 finding;連兩次同點斷流 SHALL 判定為環境污染需查因,單次 SHALL 視為量測窗雜訊不逕自作結。 + +#### Scenario: 隔離 soak 產記憶體斜率 + +- **WHEN** 一條 warm primary 連線於隔離 stack + 獨佔量測窗跑 ≥30 分鐘 soak,keepalive probe 維持活性 +- **THEN** SHALL 產出記憶體斜率報告 +- **AND** 洩漏 watchdog 門檻 SHALL 只由本次實測訂出,不引用外部數字 + +#### Scenario: soak 期間自然斷流 + +- **WHEN** soak 期間發生單次自然斷流 +- **THEN** SHALL 記為 finding 並視為量測窗雜訊 +- **AND** 僅在連兩次同點斷流時 SHALL 判定為環境污染需查因 + +### Requirement: SLO SHALL 以具體數值形式化寫入部署文件並綁定環境指紋 + +設定任何 session admission 參數時 SHALL 以基準報告為前提,SHALL 以具體數值指標形式化並寫入可稽核部署文件:session 建立成功率下限、TTFF 上限、探針逾時定義、並發上限、idle-timeout、洩漏門檻。SHALL NOT 使用「合理」「足夠」等模糊詞;無基準報告則 admission 參數 SHALL NOT 上線(硬 gate)。所有 SLO 數值 SHALL 綁定基準量測報告的環境指紋;指紋任一變動即令既有 SLO 失效須重跑基準。 + +#### Scenario: 有基準報告設定 SLO + +- **WHEN** 基準報告已存在,設定 admission 參數 +- **THEN** SLO SHALL 以具體數值寫入部署文件且無模糊詞 +- **AND** 每項 SLO SHALL 綁定報告的環境指紋 + +#### Scenario: 無基準報告 + +- **WHEN** 尚無基準報告 +- **THEN** admission 參數 SHALL NOT 上線 +- **AND** admission 參數 loader SHALL 以硬 gate 拒絕未經量測的門檻 + +#### Scenario: 環境指紋變動 + +- **WHEN** GPU 型號/driver/Kit/fixture 任一變動 +- **THEN** 既有 SLO SHALL 失效 +- **AND** SHALL 要求重跑基準取得新指紋 diff --git a/openspec/changes/gpu-session-baseline-and-idle-reclaim/specs/session-lifecycle/spec.md b/openspec/changes/gpu-session-baseline-and-idle-reclaim/specs/session-lifecycle/spec.md new file mode 100644 index 000000000..8912b32f8 --- /dev/null +++ b/openspec/changes/gpu-session-baseline-and-idle-reclaim/specs/session-lifecycle/spec.md @@ -0,0 +1,24 @@ +## ADDED Requirements + +### Requirement: session 回收倒數與互動保活 SHALL 作為第二回收路徑,前端顯示 10 秒倒數且互動即取消 + +session 連續 T_inactivity 秒無任何使用者互動(viewer 輸入事件/DataChannel 指令)但仍有 readyState=4 peer 連線時,session SHALL 進入回收倒數。進入回收倒數時,前端 SHALL 對該 session 所有已連線 viewer 顯示 10 秒倒數;倒數期間任一 peer 的任何互動 SHALL 取消本次回收並重置 inactivity 計時;倒數歸零 SHALL 經既有 coordinator session close 路徑 teardown 並以 reason=inactivity 寫入 session ledger。SHALL 維持無 max-hold hard cap:有持續互動的會議 SHALL NOT 因持有時長被強制回收。T_inactivity SHALL 可設定,預設值 SHALL 於 `gpu-session-baseline` 基準取得後訂定。本 Requirement SHALL 以疊加方式落在既有 coordinator session close 路徑,SHALL NOT 依賴佇列/SessionBroker 語意(該語意屬 deferred 母 change `add-single-gpu-session-ai-review-mvp`,其「佇列中下一位獲派」段不在本 capability 範圍)。 + +> 使用者裁決(2026-07-22,母 change OQ-A/OQ-3):原話「同意, 但是前端追加 session 進入倒數10秒顯示」——同意維持無 max-hold,追加 session 進入回收時前端 10 秒倒數顯示;忘關分頁(有 peer 無互動)由本路徑回收。 + +#### Scenario: 忘關分頁回收 + +- **WHEN** session 仍有 readyState=4 peer 但連續 T_inactivity 秒無任何使用者互動,且 10 秒回收倒數內無任何互動 +- **THEN** session SHALL 經既有 close 路徑 teardown +- **AND** SHALL 以 reason=inactivity 寫入 session ledger + +#### Scenario: 倒數期間互動取消回收 + +- **WHEN** session 進入回收倒數,倒數期間任一已連線 peer 發生互動 +- **THEN** SHALL 取消本次回收並重置 inactivity 計時 +- **AND** 前端倒數顯示 SHALL 消失 + +#### Scenario: 活躍會議不因時長被回收 + +- **WHEN** 會議持續有使用者互動 +- **THEN** session SHALL NOT 因持有時長觸發任何強制回收(無 max-hold hard cap) diff --git a/openspec/changes/gpu-session-baseline-and-idle-reclaim/tasks.md b/openspec/changes/gpu-session-baseline-and-idle-reclaim/tasks.md new file mode 100644 index 000000000..21bb561dd --- /dev/null +++ b/openspec/changes/gpu-session-baseline-and-idle-reclaim/tasks.md @@ -0,0 +1,11 @@ +## 1. gpu-session-baseline(量測 harness,`scripts/`+部署文件) + +- [ ] 1.1 在 `scripts/` 建立 `measure-session-baseline.ps1`:nvidia-smi 取 VRAM/利用率+WebRTC health probe+TTFF;輸出結構化 JSON 報告含 GPU 型號盤點(判定消費級 RTX、MIG 不可用)、1 primary + k spectator VRAM 水位、TTFF、建立成功率 +- [ ] 1.2 報告 schema 加「環境指紋」必填欄位(GPU 型號/driver 版/Kit 版/fixture hash+大小),缺欄位判不完整並拒絕被下游引用;於 `scripts/` 加最小驗證測試 +- [ ] 1.3 實作 ≥30 分鐘(目標 2 小時)soak:隔離 stack(獨立埠+獨立 governance,沿用 branch E2E 隔離模式)+獨佔量測窗+內建 keepalive health probe;輸出記憶體斜率報告;自然斷流記 finding、連兩次同點才判污染 +- [ ] 1.4 由 soak 報告訂洩漏 watchdog 門檻(只用本地實測、禁引用外部數字);將 session 建立成功率下限/TTFF 上限/探針逾時/並發上限/idle-timeout/洩漏門檻以具體數值寫入可稽核部署文件並綁定環境指紋(禁模糊詞) +- [ ] 1.5 撰寫「環境指紋變動即 SLO 失效須重跑基準」部署文件段落;驗證:無基準報告時 admission 參數 loader 拒絕上線(硬 gate 測試) + +## 2. session-lifecycle(回收倒數與互動保活) + +- [ ] 2.1(coordinator+web-viewer-sample)無互動軟門檻第二回收路徑(2026-07-22 使用者裁決):viewer 互動事件(輸入/DataChannel 指令)上報彙整、連續 T_inactivity 無互動觸發回收倒數、倒數 10 秒廣播至該 session 全部已連線 viewer、前端倒數 UI 顯示、任一互動取消並重置、歸零經既有 session close 路徑 teardown(reason=inactivity 入 session ledger);測試:忘關分頁回收、倒數中互動取消、活躍會議不因時長回收;前端倒數 UI 有 E2E 截圖/trace(「佇列中下一位獲派」不在本 change,屬母 change 佇列語意)