docs(sdd): credential-primitives-wasm 封存進 archive(T10 完成,卷已結案)

leo 2026-07-21 明令封存:卷已完成,留主目錄會讓未來 session 誤以為進行中。
最後一項 T10(廢除自管加密金鑰)已於 20c7610 完成(移除約 2500 行)。

- git mv 整卷 → system-dev/docs/3-specs/archive/credential-primitives-wasm/
  design.md status: closed;superseded_by 留空(據實:非被另一卷取代,是機制整個換掉)
- 卷首補「封存時仍未完成的項目」——逐條查 code 核實,不當作完成:
  真缺口=auth_mtls 從未實作、7.6 self-hosted auth 鏈端到端從未驗;
  另有勾選過期(auth_oauth2 其實已完成)與驗收條件已作廢(與現行 rule 07 牴觸)者
- 修好 14 處引用(原盤點 10 處,實際更多):session-start-load-sdd.sh 內容嚴重過期
  (把已完成 Phase 寫成進行中)→ 改為以 frontmatter 為判準;四份 rules、CLAUDE.md、
  BACKLOG、3-specs/README、deploy.ts、credentials.ts、wrangler.toml 逐一按性質處理
- 額外:system-dev/docs/2-architecture/ 有四個規則檔重複副本(06-08 遷移遺留)
  → 同步修好,否則留一份過期真相(今日第三次撞到「同一資訊兩份副本」的債)
- 02-forbidden.md §2.1 列的三個「待刪違規 TS」其實早已不存在
  → 改標刪除線+禁止重新引入(過期文件同時製造假待辦與假進行中)

驗證:sdd-active-check exit 0(active 仍恰一份=portal-auth);
session-start-load-sdd.sh exit 0;cypher-executor 與 cli typecheck 全綠;
測試 187/188(唯一 fail 為 pre-existing,stash 覆驗相同)。

未動:pre-write-guard.sh 的 KNOWN_SDDS 白名單不含 archive 路徑
(放寬 guardrail 需明確授權,留待決定)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-21 01:57:34 +08:00
parent df1b953d1f
commit 8d8b01d240
21 changed files with 241 additions and 161 deletions
+8 -10
View File
@@ -1,23 +1,21 @@
/**
* Credentials API — 多租戶 credential 管理
*
* credential-store-migration T5D19「擁有目錄,不擁有內容物」,
* system-dev/docs/3-specs/arcrun/credential-primitives-wasm/credential-store-migration.md §2.3-2.4/§3):
* 現行做法(D19「擁有目錄,不擁有內容物」;規範見 .claude/rules/01-tech-stack.md
* 「Credential 儲存規範」。arcrun 不自管任何加密金鑰):
*
* 寫入(POST 建立 / PUT 覆寫)一律走新家
* 寫入(POST 建立 / PUT 覆寫):
* 1. 密文值 PUT 進 CF Workers per-script Secrets(掛在本 worker 上,管理 API 唯寫,
* arcrun 自己也讀不回值——D19「不持有內容物」)。
* 2. D1 `credentials` 表只寫「目錄」(api_key/name/service/sensitivity/secret_ref/
* created_at),**不含密文**。
* 不再寫 KV / 不再寫明文密文到 D1。
*
* §2.4 選項甲(傾向)client 不再 AES-GCM 加密,明文值經 TLS 送到 cyphercypher 短暫在記憶體
* 經手明文(不落地、不持久、不持金鑰)後直接 PUT 進 Workers Secrets。這與舊版
* `.claude/rules/01-tech-stack.md` 記載的「傳輸格式 {name, encrypted, iv}」不同——是本 SDD
* 2026-07-03 T1.5 spike 定案)對舊格式的刻意取代,SDD §6 Q-b 仍列為需 leo 明確接受的
* 誠實 trade-off(本次實作先落地,若 leo 不接受選項甲需回頭改)。
* 傳輸格式client **不做** AES-GCM 加密,明文值經 TLS 送到 cyphercypher 短暫在記憶體
* 經手明文(不落地、不持久、不持金鑰)後直接 PUT 進 Workers Secrets。(此為 2026-07-03
* 定案並已落地的做法,取代更早的 `{name, encrypted, iv}` 格式;rule 01 已同步。)
*
* credential-store-migration T9(§3 治理端點
* 治理端點:
* - `GET /credentials`:改讀 D1(與 `/credentials/catalog` 共用同一份 query,同時保留
* `/catalog` 別名,Console 既有呼叫不受影響)。
* - `DELETE /credentials/:name`:先查 D1 拿 secret_ref → 有則刪 Workers Secret + D1 row
@@ -35,7 +33,7 @@ export const credentialsRouter = new Hono<{ Bindings: Bindings }>();
const CYPHER_SCRIPT_NAME = 'arcrun-cypher-executor';
/**
* secret_ref 命名規則(credential-store-migration §2.3「以 CRED_ 前綴隔離命名空間):
* secret_ref 命名規則(以 CRED_ 前綴隔離命名空間):
* CRED_<NAME 大寫>_<sha256(api_key) 前 8 碼大寫>
* 加 api_key 的 hash 是為了避免跨租戶同名 credential(如兩個用戶都存 telegram_bot_token
* 撞名覆蓋彼此的 Workers Secretsecret 是掛在同一個 worker 上、全域命名空間,沒有租戶
+2 -1
View File
@@ -3,7 +3,8 @@ main = "src/index.ts"
compatibility_date = "2025-02-19"
workers_dev = true
# global_fetch_strictly_public:讓 fetch() 走公網「前門」,解 self-hosted 的 same-zone 1042
# credential-primitives-wasm Phase 72026-06-06)。
# 2026-06-06 拍板;規則見 .claude/rules/03-component-architecture.md)。
# ⚠️ 尚未在自架帳號上端到端實測(原 Phase 7.6 遺留驗收缺口)。
# 病因(官方 docs):self-hosted 的 cypher 與 auth worker 同在 {sub}.workers.dev zone
# cypher fetch auth 屬 same-zone fetchCF 預設擋(1042)。官方 cypher 在 cypher.arcrun.dev、
# 打 auth 的 *.workers.dev 屬跨 zone 故不踩。此 flag 讓 same-zone fetch 改走公網前門 → 同 zone 也通。