# FR-172 交接現況（STATE）

> **這份是 living 檔**：每棒就地 Edit，只描述「此刻」。歷史脈絡看同資料夾的 `FR-172-LOG.md`。

| 項目 | 值 |
|------|-----|
| 最後更新 | 2026-11-03 17:1x（**FR-172 結案**：190 實測通過，決策者裁 172 系列卡全收 Done，下一步走 FR-173） |
| branch | 五個 repo 皆 `feature/FR-172`（工作坊分支已全部合回）；FR-173 也在這支（決策者裁） |
| 母案卡 | **CM-3401** Done（含 S-4 CM-3420）；修正母卡 **CM-3469** Done（FR-172.1，CM-3470～3479 全 Done） |
| 本棒角色 | 發版首腦（S-4 由首腦接手，不再派回工作坊） |
| 階段 | 171、172、172.1、174 結案；173 已開卡未派（CM-3462），決策者裁直接往 173 走 |
| 接手前必讀 | §0 |

## 🧭 原始需求 / WHY

> **這節寫一次，之後各棒不動。**

**決策者原話（2026-11-01，189 推 Agent 1.4.8 時）**：主系統跟 Agent 要分開來，不要像現在都包在同一包；要可以各別分開更新；Agent 那邊也要有更新中心，可以離線更新或跟主系統發動更新需求；R2 上面的安裝包要分開來；不要再用心跳帶資料。

**本 session 開場追加（2026-11-01）**：①出版分開，CI、R2 路徑與檔名分開；②Agent 獨立更新、Agent UI 有更新功能、可離線更新；③更新中心 Agent 區的狀態與進度要跟主系統一樣看得到下載、各站點進度、成敗；④不要再用心跳送指令；⑤與 FR-171 一起分析分工。

**已裁四件**：Agent 不直接連更新站；主控台發動更新＝主系統幫這一台更新；171 與 172 一起看一起拍板；172 要附雛形。

**目標長什麼樣**：見 `discussion.md` §3。

**本棒在大圖的位置**：第 1 棒，接 FR-167 收口後留的需求草稿（已搬進本資料夾 `requirement-notes.md`）與 FR-171 第 1 棒的討論稿 v1。

## §0 接手讀序

1. 本檔 🧭 WHY 節
2. `discussion.md` 全讀（§0 概述、§3 目標設計、§4 與 171 分工、§5 D1～D12）
3. `prototype/index.html` 點過十頁
4. FR-171 `discussion.md` v2（§5.3 主題 B 改法、§7.5 與 172 分工、D13）
5. 本檔 §2 已定裁示、§3 下一步
6. 細節才開：`requirement-notes.md`（心跳夾帶八種盤點）、FR-167 `agent-rollout-spec.md`、`update-site-schema-spec.md`、`release-signing-spec.md`

**冷接自檢**：①Agent 包現在怎麼走到客戶 Agent 主機（五段，哪一段掛在主系統）？②172 直接用 171 的哪三樣？③為什麼 Agent 的章要另一個 `payload_type`？④P3／P4 為什麼要等 171 批 2？

## §1 當前狀態（2026-11-03 17:1x）

### 三案

| 案 | 狀態 |
|---|---|
| **FR-171** 通訊重整 | ✅ 結案（工作坊 31、34 closed），已在 `feature/FR-172` |
| **FR-174** 網址型 Profile 存檔 | ✅ 結案（工作坊 33 closed）；出貨基線已含 dev-sec 兩列系統檔 |
| **FR-172** Agent 獨立更新 | ✅ 結案（CM-3401、修正案 CM-3469 皆 Done）；190 實測通過 |
| **FR-173** 出版管線 | 開卡未派：母卡 CM-3462、子卡 CM-3463～3468；見 FR-173 STATE |

### 合回與推送

| repo | `feature/FR-172` HEAD | 遠端 |
|---|---|---|
| BE | `9c1539491`（1.28.3） | 已推 |
| FE | `b4463557`（1.28.3） | 已推 |
| Agent | `9296bd2`／`cd3a1f9`（1.5.5） | 已推 |
| jedi 套件 | `bc38f89a` | 已推 |
| update-center | `e5d63dc` | 沒有遠端，只合 |

### 出包（188，皆 `--skip-prod-key-check` 內部測試包）

| 版本 | 路徑 | sha256 | 備註 |
|---|---|---|---|
| 主系統 1.28.0 | `/opt/guidant-ai-be/.build/bundle/guidant-ai-1.28.0.tar.gz` | `252e52d4…f92c` | 開包驗過：無 `agent/`、release-keys 三把正式章、無測試章 |
| 主系統 1.28.1 | 同目錄 `guidant-ai-1.28.1.tar.gz` | `250e9212…c64c` | 沿用 1.28.0 映像只換版號（runbook 2.5），測升級用 |
| Agent 1.5.0 | `/opt/guidant-ai-agent/.build/compose/guidant-agent-compose-1.5.0.tar.gz` | `ded181ed…4972` | 版本說明 5 條（映像內 manifest 也是 5 條）；映像 release-keys 與 BE 一致。第一顆壞包（說明 0 條）改名 `.BAD-notes0` 保留 |
| Agent 1.5.1 | 同目錄 `…-1.5.1.tar.gz` | `efede01c…6175` | 只換版號 |
| Agent 1.5.2 | 同目錄 `…-1.5.2.tar.gz` | `683bda8d…39ef` | 只換版號；離線上傳檔在 Mac `~/Projects/Billows/Audit-Manager/.fr167-dev/offline/agent-1.5.2/guidant-agent-1.5.2.offline.tar.gz` |
| 主系統 1.28.2 | `/opt/guidant-ai-be/.build/bundle/guidant-ai-1.28.2.tar.gz` | `8e365e7f…68eda` | FR-172.1 七張合回後完整 build |
| Agent 1.5.3 | `/opt/guidant-ai-agent/.build/compose/guidant-agent-compose-1.5.3.tar.gz` | `e85b86d9…166a` | FR-172.1；版本說明 4 條；SeaweedFS `init: true` |
| 主系統 1.28.3 | `/opt/guidant-ai-be/.build/bundle/guidant-ai-1.28.3.tar.gz` | `96c9da16…20bd` | 同版重套＋Agent 區舊包先下載；無 `agent/`、三把正式章 |
| Agent 1.5.4 | `/opt/guidant-ai-agent/.build/compose/guidant-agent-compose-1.5.4.tar.gz` | `7209f72f…2aac` | 同版開關轉進容器、8444 握手修正、主控台重新套用 |
| Agent 1.5.5 | 同目錄 `…-1.5.5.tar.gz` | `55ff08d3…6704a` | 主機升級單同版放行；`--internal-test` 首包（15 分 52 秒） |

出包途中修的三件（都已推）：Agent `RELEASE_NOTES.md` 標題被吃掉致說明 0 條（`6760914`）；開機補登金鑰登記簿沒有 app context、新裝第一次開機留 Traceback（`088ca2b75`）；出包幽靈選單比對表補 `agent-keys`（`96d4e23e7`）。

### 更新站（update-center，正式 `guidantai-update.jedicotech.com`）

- 已部署新版（兩條版本線，`product` 必填）；D1 套了 0005，套前備份 `~/backup/update-center-d1-20261102_2253-before-0005.sql`。
- 🔴 188 STG、189 POC 是 1.27.x，不帶 `product`，**更新中心「檢查新版」會失敗，直到升上 1.28.0**（決策者 2026-11-02 裁照設計部署）。
- D1 現況：主系統 1.28.1、1.28.2、**1.28.3** published；Agent 1.5.1～**1.5.5** published。全部用測試章 `b91819f86eb4b4f8` 簽。1.28.0 與 Agent 1.5.0 沒上站（190 離線升）。正式章／Vault 簽的第一版留給 FR-173（1.29）。
- 測試期發布腳本：Mac `~/Projects/Billows/Audit-Manager/.fr167-dev/publish/publish2.sh host|agent <版>`（`STATUS=draft` 只登記），簽章 `sign/sign-release2.ts`，Agent 離線檔 `sign/make-agent-offline.ts`（不入版控）。

### 190 測試機

| 項 | 狀態 |
|---|---|
| 主系統 | 1.28.3（11-03 15:48 指令升級，八步皆 0）；`/etc/guidant/release-keys/` 四把：測試章＋三把正式章 |
| Agent | 1.5.5（1.5.4→1.5.5 由更新中心不預先下載直接推、自動下載成功；同版重套 1.5.5 成功）；SeaweedFS `init: true` 後無殭屍 |
| 同版重套開關（只在 190） | `/srv/guidant-ai/guidant.env` `PRODUCT_UPDATE_ALLOW_SAME_VERSION=1`、`/srv/guidant-ai-agent/.env` `AGENT_UPDATE_ALLOW_SAME_VERSION=1`；改前備份 `.bak-20261103-160922`。要關就刪這兩行，主系統 `sudo guidantai start`、Agent `sudo guidant-agent-compose start` |

**為什麼 Agent 要手動升一次**：1.28.0 只用 FR-171 的 `POST /update` 直推升級、心跳不再帶升級指令；1.4.x 沒有這支端點，主系統推不動。1.4.7 對 1.28.0 心跳 401→重註冊循環，是預期的。189 的 Agent（1.4.7／1.4.8）上 1.28.0 時也要手動升一次。

### 驗章規則（查證過）

主系統驗主系統包與 Agent 包、主機升級腳本、Agent 主控台離線上傳，**全部只認本機已裝的公鑰**，不拿包內公鑰驗自己。所以 188／189／190 要先裝上 1.28.0 才認得正式章與 Vault 章（1.29 用 Vault 簽時不能跳過 1.28.0）；用 1.28.0 全新安裝的機器不認測試章，但新裝不經線上驗章，下一次線上升級是 1.29（正式章／Vault）。Agent 收主系統推送只核大小與 sha256（數字來自主系統驗過的清單），主機端另用舊版 Agent 驗新版程式樹的完整性章（另一套，與發布章無關）。

## §2 已定裁示（不要重新討論）

| 裁示 | 何時 | 誰 |
|---|---|---|
| Agent 不直接連更新站；包只從主系統拿、離線靠主控台上傳 | 2026-11-01 | 決策者 |
| Agent 主控台「發動更新」＝主系統建單幫這一台下載並推，不是跳轉 | 2026-11-01 | 決策者 |
| 171 與 172 同週期一起拍板；兩個 FR、兩棵卡樹 | 2026-11-01 | 決策者 |
| 討論稿附可點雛形 | 2026-11-01 | 決策者 |
| 心跳不再帶任何訊息，只表存活 | 2026-11-01 | 決策者（FR-167 session） |
| FR-167 待辦 62（compose 標籤）不併本案 | 2026-11-01 | 決策者 |
| **CM-3410 H-5（待辦 61，CINC 網址型 Profile）暫緩、移出 FR-172，另開 FR-174（`docs/features/FR-174-2611-url-profile-snapshot-sync/`，已登記、需求紀錄已寫、未討論未開卡）；方向採 A 案**：網址型匯入時下載內容存成 `upload_files`、該版改記檔案型、原網址存成「來源網址」欄。要改 jedi-detection 套件（推翻「網址型不落儲存」不變式）＋migration＋環境卡，約三張卡。代價：189 Demo 的 CINC 下拉在新案前仍空 | 2026-11-01 | 決策者（工作坊首腦回報後） |
| 出貨前無客戶：所有舊版相容、備援期、過渡搬包全拿掉 | 2026-11-01 | 決策者 |
| 雛形定稿：Agent 主控台文案「開始更新／有新版本」；Agent 進度與主系統更新中同一套 `.steplist` 直式清單（E-5、G-3 卡已 append） | 2026-11-01 | 決策者 |
| **1.28.0 先出（Mac 手簽），FR-173 跟 1.29**；S-4 把 Vault 公鑰 `05086455d42ca0d6.pub` 放進 `scripts/installer/release-keys/` 並列入 `PROD_KIDS`，1.29 才能換 Vault 簽（裁示已 append 到 CM-3420） | 2026-11-02 | 決策者 |
| 1.28.0 用測試章簽、包內只帶三把正式章；測試章公鑰移出 `release-keys/`；出貨基線由首腦重產 | 2026-11-02 | 決策者 |
| 173 與 172 共用 `feature/FR-172`；173 開卡不派 | 2026-11-02 | 決策者 |
| S-4 由首腦接手到底、不派回工作坊；放行部署更新站（接受 188／189 升 1.28.0 前檢查新版失敗）、190 升 1.28.0＋手動升 Agent、出 1.28.1／Agent 1.5.1／1.5.2 測升級（1.5.2 先草稿，主系統端測完再發） | 2026-11-02 | 決策者 |

## §3 下一步

FR-172 已結案，下一步走 **FR-173 出版管線**（`docs/features/FR-173-2611-release-pipeline/handoff/FR-173-STATE.md`）。

**留給後續的事（未開卡）**
- 189 POC 升級時機、release note 1.27.x～1.28.x 補寫：待裁。
- 守衛測試 8 條紅（乾淨 HEAD 一樣紅，非本案造成）：`test_route_guard_inventory` 的 `detection.remote-agent.upgrade` 沒有守門端點登記（P-5 遺留）、`test_agent_console_allow_cidr` 缺 app context、兩條測試順序相依。
- Agent 主控台由主系統發動更新時最慢 30 秒才鎖畫面（平常輪詢間隔）：決策者裁先這樣。
- Agent 主控台背景輪詢 `/update/status` 會寫「看過更新頁」稽核（CM-3469 F-6 驗收時記，未修）。
- 測試機只改主機腳本的修正無法只換 `.sh`：主機每次從現行 Agent 映像讀 `install-lib/upgrade_order.sh`，要驗就得出版；要不要做測試機本機覆寫，另議。

> ⚠️ 這節是建議清單，不是執行授權。

## §4 待辦與風險

- **S-4 範圍（已做完）**：主系統發布清單 `release_json.sh` 補 `"product": "host"`（否則 register-draft 400）；出貨基線重產（見 §3 第 4 條）；手冊三句（前門 CSP Agent 位址最多 5 分鐘生效、換鑰期間只發 Agent 不算新章生效、runbook 2.2 等 Agent 出包段搬走）；H-4 沒實點的「有新版本／已下載」兩態在 1.28.0 上補點。
- **事件碼**：主線 6249／6250 已被 FR-171 用掉，`AGENT_BUNDLE_DOWNLOAD` 改 6251（`367c0bde7`）。DEV system_logs 若有 H-2 實測留下的 6249 一筆，開發期資料不回填。
- **離線上傳來源值**：FE（H-4）約定 Agent 主控台離線上傳的 rollout `source` 用 `offline`；G-1／G-2 要用同一個字。
- **套件鏡像測試**：jedi-agent-protocol `test_mirror::test_agent_sends_only_contract_keys` 紅（找 Agent 舊心跳函式 `_heartbeat_once`，FR-170 搬家後沒跟上），P-1 前就紅、不屬 172 範圍。
- 雛形十頁**未開瀏覽器看**（規範不開瀏覽器）；`grep border-left` 為 0。決策者若看到版面壞掉，先看 `proto.css` 是否與 FR-167 那份同步。
- mermaid 兩張圖只靜態檢查首行 init。
- `requirement-notes.md` 是從 `docs/draft_requirement_spec/` `git mv` 過來的，內文仍是需求紀錄體（含「目前的做法」段），不是說明文件，拍板後不改寫。
- FR-167 CM-3378 結案出包（1.27.11）裁等本案與 171 一起出。
- 🔴 **共用 `.venv` 會被卡改掉**：卡工作區的 `.venv` 連到主資料夾那份，任何一張卡 `poetry update` 都會改到 8000 的環境（今天 171 E-0b、174 Z-1 各踩一次）。172 剩下的卡若要改套件版本，先要求小弟回報不要直接 update。已寫進 `closing-and-handoff` skill「runner 環境紀律」②；根治要改 agent-workshop（每個工作坊一份 venv），未提案。
- 🔴 **跨工作坊合回不自動**：工作坊只把卡合回自己的 `ws-<母卡>`；要讓別的工作坊看到，要按該工作坊「合回」（要全部子卡 Done）。主 FR＋副 FR 的提議（主 FR 排先後、放行）決策者表示方向可以，未落地成規範。
- **jedi 套件 Z-6 改了程式碼但沒發版**：protocol 0.2.0／remote-agent 1.12.1 在 Nexus 上仍帶 `console_events` 兩個沒人用的鍵，不影響執行，留給下次發版。
- **指令端點錯誤格式不一致**：`/tasks`、`/restart`、`/update` body 驗證錯回 `{error}`，其他端點回 `{error_code, msg}`；記在 FR-171 `agent-api-spec.md`。

## §5 Pre-flight（唯讀）

```bash
cd ~/Projects/Billows/Audit-Manager/compliance-manager-be
git status --short | grep -v "^??"; git log --oneline -3
ls docs/features/FR-172-2611-agent-independent-update/ docs/features/FR-172-2611-agent-independent-update/prototype/
grep -n "FR-172" docs/features/README.md | cut -c1-60
grep -n "需求討論稿 v2" docs/features/FR-171-2610-agent-command-channel/discussion.md | head -1
```

## §6 環境座標

- 本機 Agent：`~/guidant-agent-local/start-agent.sh` 連 DEV BE 8000。
- 不碰 STG／POC。189 POC 的 Agent 是 1.4.8（121）／1.4.7（60.167，磁碟已清待重推）。
- update-center repo：`~/Projects/Billows/Audit-Manager/update-center/`（TypeScript Worker，`src/releases.ts` 的 `r2Key()` 是 R2 路徑唯一拼法）。
- Agent build 機 188 `/opt/guidant-ai-agent`，沒有 node；Agent repo 目前沒有 CI。

## §7 行為規範提醒（輔助首腦）

**直接拍板的**：卡片範圍怎麼解讀、design 沒寫到但在已裁方向內的技術選擇、小弟回報「前置沒做」或撞檔時退回／改卡／調批、暫緩或放回卡片、補開漏掉的小卡、往卡上補說明、驗收爭議。
**要停下問決策者的**：推翻已裁決定（三案 design §1、本檔 §2）、超出 FR-171／172／173 範圍的需求、使用者看得到且雛形沒畫的畫面或文案、碰 STG／POC、推 main、卡片改 Done。
**每個決定寫回對應卡片（append「輔助首腦裁示」段）與 STATE**，工作坊首腦下一棒才讀得到。

- 不開 subagent（決策者沒明說就不開）；探脈自己 grep。
- 改卡內文先改 `handoff/cards.py`／`gen_notion_cards.py`，再 append 到 Notion，不手改。
- **心跳不帶訊息、不做舊版相容**是三案鐵律，小弟 diff 往心跳加欄位或留 deprecated 分支就是阻斷級。
- 雛形與 FE 禁 `border-left` 粗邊框；資料區塊上下疊。
- 回報白話、繁中；輸出裡有 `token`、`Unseal Key` 的行一律不貼、不寫進文件。
- 決策者說「先不要急著寫文件」時就不寫，等令。
