From fad5da0e17a16568130d55c2df5848d8390354b7 Mon Sep 17 00:00:00 2001 From: uncle6me-web Date: Wed, 12 Aug 2026 23:50:53 +0800 Subject: [PATCH] =?UTF-8?q?rules/07=20=C2=A73.6=EF=BC=9A=E8=87=AA=E8=88=89?= =?UTF-8?q?=E4=BE=8B=E5=A4=96=E2=80=94=E2=80=94=E8=83=BD=E5=8A=9B=E5=8F=AA?= =?UTF-8?q?=E5=AF=A6=E4=BD=9C=E4=B8=80=E6=AC=A1=EF=BC=8C=E4=BD=86=E4=B8=8D?= =?UTF-8?q?=E4=B8=80=E5=AE=9A=E8=A6=81=E6=98=AF=20HTTP=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 代補 PR #111 的 agent 想加但改不動的段落(該檔受保護)。 立這條的原因不是理論:#97 的修法一開始寫在 cli/src/lib/resource-resolver.ts (能力住在介面層,違反 §0)⇒ 安裝器拿不到它 ⇒ 同一個 bug 只修了一半, 走 acr 的人有保護、走 install.arcrun.dev 的人沒有——而所有真實用戶走後者。 leo 2026-08-12:「根本就不應該在 CLI,我要的是一個大家都可以用到的規則。」 記三件,都是為了不讓下一個人「修正」回去: ① 為什麼不放 cypher API(自舉/輸入是使用者自己的帳號狀態/它是純函式) ② §0 的正確讀法是「只准有一份、不准住在單一介面裡」,放 API 只是常見手段 ③ npm 打包例外:cli/ 下的逐位元組副本由 sync --check 機械擋漂移,不是第二份實作 📍 repo:matrix/arcrun(shared/resource-rule/、cli/、.claude/rules/07) + products/arcrun-rag(安裝器待接上,已派工) Co-Authored-By: Claude Opus 5 --- .claude/rules/07-thin-shell.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/.claude/rules/07-thin-shell.md b/.claude/rules/07-thin-shell.md index 6a6f995..708119a 100644 --- a/.claude/rules/07-thin-shell.md +++ b/.claude/rules/07-thin-shell.md @@ -99,6 +99,38 @@ CLI / MCP / Python lib / JS lib 全是薄殼:只做「介面轉換 + 暴露」 --- +## 3.6 自舉例外:能力該「只實作一次」,但不一定要是 HTTP API(2026-08-12 立) + +> 立這條的原因:`Arcrun#97`(更新把使用者的工作流與登入弄不見)的修法一開始寫在 +> `cli/src/lib/resource-resolver.ts` ——**能力住在介面層,違反 §0**。 +> 後果不是理論:**安裝器(arcrun-rag)拿不到它,於是同一個 bug 只修了一半**, +> 走 `acr` 的人有保護、走 `install.arcrun.dev` 的人沒有——**而所有真實用戶走後者**。 +> leo 2026-08-12:「**根本就不應該在 CLI,我要的是一個大家都可以用到的規則。**」 + +修法(PR #111)把它搬到 **`shared/resource-rule/`:一份零依賴 ESM**, +`acr` 與安裝器共用。**它刻意不是 cypher 的 API 端點**,三個理由: + +| 為什麼不放 API | 說明 | +|---|---| +| **自舉** | 這條規則要在「決定怎麼裝」的當下用得到,而安裝器的工作正是把 cypher 生出來。放進 cypher = 要先有雞才能有蛋。 | +| **輸入是使用者自己的帳號狀態** | 判斷依據是使用者 CF 帳號上的綁定。送去平台託管的 worker 換答案 ⇒ ①「能不能安裝」綁在平台是否活著 ②使用者的帳號拓撲交給第三方。 | +| **它根本不需要是服務** | 這是**純函式**,唯一的 IO 由呼叫端注入。**§0 要求「能力只實作一次」,不是「能力一定要是 HTTP」。** | + +🔴 **所以本檔 §0 的正確讀法是**:能力**只准有一份**,且**不准住在任何單一介面裡**。 +「放 API」是達成它的**常見手段**,不是唯一手段。 +**判準仍然是那句口訣**:「這段邏輯換一個介面要不要重寫?」要 → 它是能力。 + +📌 **給下一個人**:看到 `shared/` 底下的純函式**不要「修正」成 API 端點**—— +先讀 `shared/resource-rule/README.md §2`,那裡記著評估過並否決的其他形態 +(共用 npm 套件=自舉問題換位置;做成零件=要用 TinyGo 重寫一次,那才是第二份實作)。 + +📌 **打包例外**:`acr` 是獨立 npm 套件,`npm pack` 打不進套件目錄外的檔案 ⇒ +`cli/` 下必須有一份**逐位元組副本**。那不是第二份實作—— +`scripts/sync-resource-rule.mjs --check` 一有漂移就 exit 1,且 `build`/`test` 都會先跑它 +(同 `cli/harness/` 的既有慣例)。**手改副本 = build 紅 = publish 擋下。** + +--- + ## 4. 統一帳號來源(薄殼共用同一身份) 所有薄殼讀**同一份**身份設定: