安全與信任
由於此套件的部分功能會在使用者機器上操作 AI Agent 來協助導入,
希望以下聲明可以釐清使用者在安全性上的疑慮 —— 每項聲明均可於原始碼中查證。
預設不啟動任何 AI Agent —— 除非使用者明確要求
blueprint 為 AI Agent 準備素材,預設不代替使用者操作 Agent。
它產出的是純 markdown 格式的守則檔(CLAUDE.md、AGENTS.md、Cursor 與 Windsurf 規則檔),在既有專案上另產出一份導入作業手冊,完成後即交棒。
它不會設定 claude、codex 或任何 Agent CLI,亦不會向其進行身分驗證。
此套件不存在憑證、權杖或授權介面:init、survey、inspect 所執行的分析均為決定性的檔案操作,而非 Agent 呼叫。
唯一的例外必須由使用者明確啟用:init --agent claude|codex 會以導入作業手冊為輸入,啟動使用者自己的 Agent CLI。
此選項的安全邊界如下:
- 執行前先印出完整指令 ——
與使用者親自貼上執行的指令完全相同;--agent除了代為執行之外,不做任何額外的事 - 前景互動模式 ——
工作階段執行於使用者 Agent CLI 自身的權限確認機制之下。
Blueprint 不代為授權、不傳遞任何權杖、亦不讀取工作階段的內容 - 所有產出結果在子行程啟動之前均已寫入磁碟 ——
啟動失敗或 Agent 中途停止時,即回歸手動路徑;手動路徑與 Agent 路徑是同一條路徑 --dry-run一律不啟動任何 Agent
零網路存取
每個指令僅操作本機檔案。
無遙測、無版本更新檢查、不回傳任何資料 —— 套件內不含任何網路程式碼。
零執行期依賴
npm install @kekkai/blueprint 僅安裝此一套件。
稽核所見即為實際執行的全部內容。
子行程:事先明列、可以跳過
Blueprint 僅執行兩種外部指令,且執行前均事先明列:
其一為 init 的依賴安裝(npm install -D …,列印於執行計畫中,可以 --no-install 跳過);
其二為前述須明確啟用的 Agent 啟動。
除此之外不執行任何外部指令。
安裝這一步也是刻意排在最後:所有檔案寫入都排在它之前,
所以一次被中斷的執行留下的是「一棵完整的樹,只少了 node_modules」,而不是一套接到一半的工具鏈。
它是唯一一個可能卡上好幾分鐘的步驟(套件管理工具連不到 registry 時會安靜地重試),
所以它上面那行會把接下來要跑的指令印出來,說明安靜是正常的、安靜好幾分鐘代表它連不上 —— 這時把它停掉、自己跑那行,或加 --no-install 重跑就好,
並且說清楚停掉會少什麼:package.json 裡的這幾個套件。
在那行跑完之前,任何指名其中一個套件的失敗都是這個缺口,不是導入壞掉。
寫入行為均有宣告與邊界
- 不會寫到 repo 外面。
emit.handbook與emit.agents[].path是來自使用者 config、會一路走到檔案系統的字串;
路徑一旦解析到專案根目錄之外(開頭的../、絕對路徑、磁碟機代號),在寫入第一個檔案之前就會被拒絕,
並且指名是哪個路徑、什麼都沒寫、以及會設出這種路徑的那兩個 config 欄位。
真實情境不是攻擊,而是 monorepo 裡少算一層的相對路徑,通常還是 blueprint 請去撰寫 config 的那個 Agent 寫的;
config 本身是可執行的 JavaScript,所以這不是權限邊界,而是「這種路徑會大聲失敗」的承諾。
拒絕發生在計畫階段,也正是這件事讓--dry-run不可能印出一份真正執行時會被拒絕的計畫 init --dry-run列印全部效果,不寫入任何檔案inspect與deps為唯讀(inspect --update-baseline僅寫入一個明列的檔案:.blueprint-baseline.json;檢測項目為零時不產生任何檔案)- 使用者持有的檔案僅在可無損重寫時才會修改(即無註解的
tsconfig.json/jsconfig.json);
其餘情況 —— 包括任何既有的 ESLint config 與手寫的 Agent 守則檔 —— 一律提供可直接使用的合併指引,絕不覆蓋。
承載該指引的參考檔,後綴是加在副檔名之前(context.mdc→context.blueprint.mdc),dotfile 則保留原名(.gitignore→.gitignore.blueprint),
所以自訂的emit.agents[].path不可能讓產生的區塊落到「它本來只是要待在旁邊」的那份文件上 - 唯一的範圍例外:於全新初始化的專案(blueprint config 於同一次執行中產生),
init 會將匯入別名一併寫入範本的vite.config.*與含註解的 tsconfig,並在lintscript 沒跑 eslint 時幫它接上(讓 lint 跑得到產生的規則)——
這些是前置條件保護的文字修改,僅處理已知的範本形態,於--dry-run中完整可見,形態不符時退回指引。
既有專案一律不走此路徑 - 重複執行
init具冪等性;
共用守則檔中的手寫內容受標記區塊保護,不會被更動
發佈附來源簽章
每個版本均由 GitHub Actions 發佈,並附 npm provenance 來源證明 ——
建置來源可於 Sigstore 公開查驗。
發佈流程的關卡依序是:程式碼檢查、型別檢查、完整測試套件(涵蓋率 100%)、建置,
最後再驗建置產物本身 —— 實際執行 dist/bin.js、解析 bin 欄位、匯入套件進入點。
最後這一層存在的理由是:發佈的那個 job 會自己建一份 dist/,而 npm 收到的就是那一份;
它同時也是唯一看得到「缺陷躲在打包邊界之後」的一層,而那種狀態在每一項行程內測試裡都是通過的。
細節見實測相容性。
