# FR-171 交接紀錄（LOG，append-only）

> 每棒追加一個 block，寫完不改。發現舊 block 有誤，在新 block「推翻了什麼」欄寫明。現況看 `FR-171-STATE.md`。

## 第 1 棒｜2026-10-31～11-01｜首腦：探脈、三輪問答、討論稿 v1

**角色**：首腦（分析決策人員），決策者派工 prompt 以 FR-170 第 4 棒 P4 分析為前置事實。

**時序**
1. 讀 FR-170 LOG 第 4 棒、design §3.x、Agent 架構憲章與兩支資安規範、`update_notify.py`、`data_plane_auth.py`、`cloud_channel.py`、`enroll.py` 心跳迴圈；主系統側 `jwt_util.py`、`agent_enrollment_service.py`、`heartbeat_upgrade.py`、`agent_credential_client.py`、`agent_update_notify_client.py`、`core/plugins/remote_agent.py` 接線；契約 `jedi_agent_protocol/heartbeat.py`、`tasks.py`。
2. 回報理解（六個發現：取消已是直推、派工直推有現成入口、心跳 pending 天生是備援、restart／update 是旗標即清、版本號現況只有兩類、op 綁定只套一個前綴）。
3. 決策者問「直推機制是什麼、怎麼驗身分」→ 回四道門（mTLS、60 秒 JWT、op 綁定、回應指紋）＋撤銷模型。
4. 決策者問「這機制好嗎、10 年憑證怎麼換、JWT 由主系統發 Agent 怎麼驗真偽」→ 查證：換證只有 60 天前通知＋人工 `re-enroll`，CA 與簽章鑰無輪換；Agent 用註冊時拿到的公鑰驗簽。提五個洞。
5. 決策者要求「客戶沒 IT、換證要全自動；其他洞要有方案；機制要統一」→ 查到 `prior_key_proof` 是自動換證缺的那半塊；提自動換證、信任錨清單、分鑰、op 全面化、jti、client 收斂、心跳改 mTLS（列第二期）。
6. 決策者要求「要真的分析過、不合理要反駁」→ 逐項對 RFC 7030／8725／9449／8705、NIST 800-57、kubelet 重看。**撤回兩項**：三種票共用一把私鑰不是洞（RFC 8725 §3.11 現況合規）、CA 不該排程縮到 3 年（NIST 要求能換不是定期換）。**改一項**：換證起算從剩 30 天改剩 90 天（離線機器容忍度）。**提一項替代**：心跳持有證明用 DPoP 式（RFC 9449）取代 mTLS，不動前門、兩向同規則，納入本案不留第二期。
7. 決策者問 DPoP 是什麼 → 白話解釋「票加上只有主人簽得出來的簽名」。
8. 決策者要看現況全貌 → 畫四條路（註冊／心跳／直推／瀏覽器票）、十種憑證材料表、業界對照、五種替代方案。決策者「畫成討論稿」。
9. 登記 FR-171、寫 `discussion.md` v1（§0 概述、§2 現況地圖 6 張 mermaid、§3 業界對照、§4 九個洞分四級、§5 六主題、§6 相容矩陣、§7 D1～D12、§8 不做、§9 風險）、README、build 站，commit `03feb84ae`。
10. 決策者問註冊 token「重新產生跟撤銷差在哪」→ 查證 `agent_enroll_token_service.py`：一租戶一組永久有效、產生＝停舊加新、撤銷＝停舊不加新；明文只顯示一次不是只能用一次。建議 D9 擴大成多把並存／到期／次數／單把撤銷。決策者再問「已註冊的會不會因此斷線」→ 不會，token 只在註冊那一刻看一次。
11. 決策者「轉給另一個首腦主持」→ 本棒寫 STATE／LOG 交接。

**決策**（本棒提、決策者未拍板，全部進 discussion §7 D1～D12）
- 範圍建議全收六主題（約 15 張卡）而非只做指令通道（約 5 張）。
- 指令端點各自前綴、守門改「除 health／agent-info 外全部受保護」。
- 直推失敗不重試不排隊，交給心跳（單一真相在主系統 DB）。
- 憑證 1 年、剩 90 天換、過期寬限 90 天；CA 長效只做能換。
- DPoP 分兩階段：先記 log 再強制。
- `/update/notify` 退役。

**推翻了什麼**
- 首腦自己在第 4 步說的「三種票共用一把私鑰是洞」與第 5 步說的「CA 縮到 3 年」，第 6 步撤回。
- 首腦第 5 步把「心跳改 mTLS」列第二期，第 6 步改成「DPoP 式納入本案」。
- **討論稿 v1 的主題 B（心跳帶 `config_versions`）與 11-01 決策者在另一 session 的「心跳不帶訊息」裁示衝突**，v1 寫在裁示之前。接手首腦要出 v2 重審，見 STATE §3。

**教訓**
- 決策者明說「不要順著我講」後，每個方案都要附規範依據；自己先前的說法對不上規範就當場撤回並寫進 README 紀錄，不硬撐。
- 探脈時 `grep --include` 在這台的 zsh 會被吃掉，改 `grep -r` 不帶 include 或用 `rg`。
- 討論稿寫完發現另一 session 同日有新裁示（memory 檔變動）——交接前要 `cat` 一次 memory 目錄的新檔，否則 v1 交出去就過期。
- 決策者對「token 一次性」的理解與實作不符（明文只顯示一次 ≠ 只能用一次），這類命名誤導要寫進討論稿當洞，不只口頭回答。

**commits**：BE `03feb84ae`（登記＋討論稿 v1）、本棒交接 commit。本棒不動 Agent／jedi／FE。未 push。

**交給下一棒**：STATE §3——先用 11-01 裁示重審主題 B 出 v2，再等決策者裁 D1～D12；D9 擴大成 token 多把並存。
