AI Engineering Governance · 2026

AI 裸奔時代的終結:幫你的多 AI 加速開發同時加裝安全煞車

當 N 個 Agent 同時變更同一個 Repo,如何進駐「原子鑄造廠」,以 5D CID 鍛造穩固的系統治理基石

想像你的 repo 是一座鑄造廠。AI 寫出來的每段程式,都會掛上一張身分證(5D CID),留下半年後還能重新驗證的 SHA256 證據包,走完從 ORIENT 到 CLOSURE 的七個階段。鑄出來的東西有名字、有合約、可以被審計、也可以被別的專案撿去重用。有了這套煞車,你可以放心同時開五個 Agent 動工,repo 也撐得住。

7 階治理生命週期ORIENT → NEXT → LOCK → EXECUTE → EVIDENCE → HANDOFF → CLOSURE。每階可被 doctor 偵測,不能跳階。
5D CID 指紋Strict / Interface / Effects / Semantic / Behavior 五維度。目前 Interface 已實作,其餘為 roadmap,非確定性訊號永不混進 identity hash。
closure-packet.v1 證據鏈每次 close 都寫入帶 commandRuns SHA256 + targetCommit + governedTreeSha 的可重放封包。schema 已上線。
TypeScript · Node ≥20 5 active atoms 7 條 INV-ATM 紅線 11 個行為類別 Charter v2.0.0

1. 多 AI 同時開發一個專案會撞到的牆

第三十天你會發現,看著三個 Agent 同時改你的 repo,比自己一個人寫還累。

?! retry() v1 withRetry() v2 doRetry() v3
圖 1:三個 Agent 各自看不到對方的上下文,於是各寫了一個幾乎一樣的 retry helper——名字不同、語意相同。這就是「重複造輪」這面牆,沒有人有全域視角去發現它。

剛開始用單一 AI 助手寫程式,那體驗真的很爽。它幫你補檔、補測試、補 README,幾乎不用打字進度就飛快。後來你開始多開幾個 AI:Claude Code 處理一張卡、Codex 跑另一張、Copilot 在 IDE 裡開第三條 PR。原本以為效率會三倍,實際上會撞到四面牆。

第一面牆是重複造輪。Agent A 寫了一個 HTTP retry helper,三週後 Agent B 在另一個 feature 又寫了一個幾乎一樣的,再兩週 Agent C 又寫了第三個。每個 Agent 都只看到自己當下的上下文,沒有人有全域視角去發現「這段東西其實已經存在了」。

第二面牆是 scope 互踩。三個 Agent 同時改一個 repo,缺一個機制告訴它們「這個檔案有人正在動」「這個權限這輪只能給一個人」。等到 git merge 才看到衝突,已經太晚。

第三面牆是結構慢性衰敗。每個 feature 都做對了,但半年後檔案還是會越來越肥。tasks.ts 從 300 行長到 1500 行,沒人主動去想「這檔案該拆了吧」「這 30 個原子裡有 12 個其實在做同一件事」。每個局部都對,整體卻在悄悄崩壞。這叫結構熵,平常的 code review 看不見,是時間慢慢累積出來的問題。

第四面牆最隱蔽——沒有身分。就算 AI 寫得再漂亮,每段程式碼都只是一串匿名字串,活在那個專案的 git history 裡。隔壁專案的某個 helper 即使語意一模一樣,兩邊也認不出彼此,下一個新專案更不可能找到它們。每段程式碼都是孤兒。

這篇文章就是在講我怎麼回應這四面牆。核心是一個比喻:把整個 repo 當成鑄造廠,每次鑄出來的是有身分證的程式細胞——有名字、有指紋、有狀態、有 evidence。它們可以被治理、被審計,未來也可以被重新組合。

2. 原子鑄造廠:把程式碼變成有身分的細胞

「原子」(atom)這個詞在這裡有非常具體的意思。它不是 task、不是 commit、不是 prompt。它是一個有規格的程式細胞

  • 有名字:每個 atom 有唯一 ID,例如 ATM-MAP-0042
  • 有語意指紋:input 簽章 + output 簽章 + 不變量會被正規化後做 SHA256,這就是 CID
  • 有版本與狀態:active / deprecated / expired / quarantined
  • 有 caller graph:誰呼叫它、它呼叫誰,都被記錄
  • 有 evidence 履歷:每次改動都會留 SHA256 證據
  • 會生長:可以分裂(split)、可以融合(merge)、可以演化(evolve)、可以休眠(sweep)

講白一點,一個 atom 在 registry 裡長這樣——它不是一段浮動的程式碼,而是一筆有欄位、有指紋、有履歷的紀錄:

{
  "atomId": "ATM-MAP-0042",
  "name": "idempotent-http-retry",
  "status": "active",
  "semanticFingerprint": "cid:a3f9c2e81b40",   // ← 這就是它的身分證
  "inputs":  ["url: string", "opts: RetryOpts"],
  "outputs": ["Promise<Response>"],
  "invariants": ["same idempotencyKey => at most one effect"],
  "callers": ["ATM-MAP-0017", "ATM-MAP-0031"],   // 誰在用它
  "bornBy": "behavior.atomize",
  "evidenceRefs": ["TASK-AAO-0042.closure-packet.json"]
}
ATM-MAP-0042 cid:a3f9c2e8
圖 2:每個 atom 都是一隻掛著身分證的細胞。身分證上的 cid: 就是它的語意指紋——這張證讓它可以被查詢、被去重、被未來的專案重新找到。

鑄造廠這個比喻其實滿準的。一般工廠出貨的是組裝好的成品;鑄造廠出貨的是每件都帶序號的鑄件。鑄件可以單獨追溯、單獨入庫、單獨被下一個產品引用。程式碼也該這樣。

你的 repo 進入這個模式之後,AI Agent 的工作會變得很單純:要嘛鑄造新原子,要嘛對既有原子做受治理的變換。它寫不出沒身分的浮動程式碼,因為鑄造廠只收有序號的東西。

3. 原子之上的 map:拆解 legacy 大模組的治理替代表面

看到這裡你可能會想:「OK,每段程式都變成有身分證的細胞了,那 checkout.py 這種 1500 行的 legacy 大功能呢?是不是把它切成 30 顆 atom 就解決了?」很可惜,還沒。原子負責的是「單一能力」,整體怎麼組合起來,要交給 map 來承載

原子是細胞,map 是器官。少了 map,就算 legacy 大模組被切成 30 顆漂亮的細胞,也沒有任何一個能站出來說「我就是新的 checkout,舊那條可以退役了」。

3.1 為什麼需要 atom map

把原子切得很細,代價是「整體入口不見了」。一個 checkout 流程被拆成 30 顆 atom 之後,下面這幾個問題還是要回答:

  • 新的 entry point 是哪一顆?哪些 atom 是 entry-adapter、validator、side-effect-adapter?
  • data-flow / control-flow / validation 這三種邊在哪幾顆 atom 之間流?
  • 跑起來和舊的 checkout.py 行為一樣嗎?有哪些已知差異?
  • 如果不對,可不可以無痛 rollback 回 legacy 路徑?

這些問題單顆 atom 回答不了,所以 ATM 在 atom 之上多加了一層治理單位——atomic map。對應的 schema 是 atomic-map.schema.json,存放路徑與 atom 平行:atomic_workbench/maps/<mapId>/map.spec.json

3.2 Map 的四個替代契約

一張正式 map 比「members 清單 + 連邊」做得更多,它對外給出四個承諾——四件加起來就是「治理替代表面」(governance replacement surface)

結構語義

members[].role(entry-adapter / validator / side-effect-adapter…)與 edges[].edgeKind(data-flow / control-flow / validation)。沒有 role 與 edgeKind 的 map 不能升級。

替代宣告

replacement.legacyUris[] 明列被替代的 legacy 入口,例如 legacy://app/checkout.py#L1-L1500。沒有這欄,map 永遠停在 draft,不准宣稱替代。

可驗證等價

map-equivalence-report 證明 map 與 legacy 行為等價。允許已知差異——但必須明列入 knownDivergences[],否則 gate 不過。

安全退場

legacy-retired 階段前,必須有 rollback-proofretirement-proof。沒有回頭路就不准把 legacy 入口拆掉。

3.3 五階替代生命週期:draft → shadow → canary → active → legacy-retired

替代 legacy 不是一刀切,而是一條被 gate 管住的五階流水線。每個 transition 都有對應的 police 與 evidence:

draftmap 建立尚未宣稱替代 shadow與 legacy 並行只比對不影響結果 canary小範圍真正接入保留 rollback 路徑 active成為正式入口legacy 退為次要 legacy-retired舊入口退場需 rollback-proof 每個 transition 都被 police + evidence 守住,不能跳階 shadow→canary:map-integration pass|canary→active:equivalence + propagation + human review|active→retired:rollback proof
圖 3:Atom map 的五階替代生命週期。Legacy 大模組不是一刀切,而是先在 shadow 偷偷比對、在 canary 試水溫、確定 equivalence 後才升 active,最後憑 rollback proof 把舊入口退場。

3.4 三層資料分類:什麼可刪、什麼是地基

v2 計畫書(map-replacement-protocol v2-r2)把整套資料分成三層,每層的容錯規則不同:

層級例子規則
Source-of-truthatom source、map.spec.json、capsule manifest必須可驗證、可重建;快取絕不可覆蓋
衍生狀態registry、Mermaid 圖、health report可被刪除、可被重建;必須帶 generatedAt
本機揮發態daemon PID、guide cache預設不進 git;損壞時直接清除即可

這個分類加上 M26 Rescue PoliceM27 Disaster Recovery CLI(map-replacement-protocol 的兩張任務卡),保證了一個黃金性質:只要 source-of-truth 還在,所有 registry 與 derived 報告都能從零重建。也就是說,就算 map 把 legacy 拔了、衍生資料壞了,你永遠都有路可退回安全狀態。

所以 atom map 才是 ATM 處理「legacy 大模組」真正的那一層。*原子(§2)回答「這段程式碼是什麼」;map 回答「這一坨 legacy 要怎麼被有秩序、有 evidence、有 rollback 路徑地替換掉」。少了 map,你只是把一堆細胞掛在牆上;有了 map,才有真正能替換舊器官的新器官。

4. CID 衝突仲裁:讓兩個 Agent 真的能同時動手的關鍵技術

到這裡我們有了「有身分的細胞(atom)」跟「有契約的器官(map)」。但實際多 Agent 同時開發時,最關鍵的一個問題還沒回答:給我兩張任務卡,框架要怎麼判斷它們能不能同時做?

Git 解決物理衝突:你跟我改了同一行。CID 解決邏輯衝突:你跟我改的是同一個合約指紋。兩個合在一起才完整,少一邊都不夠。

4.1 為什麼「同檔案就擋」是錯的

傳統多人協作的衝突偵測只看一件事:兩個人有沒有改同一個檔案。這對檔案級 IDE 夠用,但「同一個 monorepo 跑五個 Agent」就會出兩種錯:

  • 偽陽性(誤擋):兩個 Agent 改 tasks.ts 的不同函式,邏輯獨立,卻被「同檔」鎖死成序列化。
  • 偽陰性(漏擋):兩個 Agent 改不同檔,但都動到了同一個 generator 或 validator 的對外契約。Git 看不到衝突,等部署才崩。

ATM 的做法是:把「檔案」降級成 fallback,把「CID」升級成第一信號。檔案重疊只是次要訊號,真正的衝突是兩邊改到同一張 CID

4.2 八種判定 verdict

給定任務 A 跟任務 B,框架的 parallel conflict advisor 會回傳八種判定之一(依嚴重度排序):

判定含義行為
parallel-safeCID 不同、檔案不重、無共享表面✅ 兩 Agent 各做各的,框架不介入
needs-physical-splitCID 不同但檔案重疊🔄 可平行;交給 deterministic composer 或 Neutral Write Steward 合併
blocked-cid-conflict同一個 atom_cid❌ 真語意衝突,必須序列化或 Captain 仲裁
blocked-shared-generator共用同一個 code generator❌ 拆原子或序列化
blocked-shared-validator共用同一個 validator❌ 同上
blocked-shared-projection共用同一個視圖/索引❌ 同上
blocked-shared-artifact共用同一份輸出 artifact❌ 同上
blocked-active-lease已被另一個 active lease 持有❌ 等釋放或換 scope
Task A + Task B atom_cid + 檔案範圍 + 共享表面集合 Parallel Conflict Advisor atm tasks parallel --task A --with B ✅ parallel-safe CID 不同、檔案不重、無共享表面 → 兩個 Agent 直接並行寫,框架不介入 🔄 needs-physical-split CID 不同但檔案重疊(Git 級衝突) → 可平行;用 deterministic composer 合併 ❌ blocked-cid-conflict 同一個 atom_cid(真語意衝突) → 序列化、Captain 仲裁或建議拆原子 另有 5 種 blocked-shared-* 與 blocked-active-lease 判定,覆蓋 generator / validator / projection / artifact / lease 等共享表面。
圖 4:parallel conflict advisor 的三條主要路徑。注意中間那條 needs-physical-split——這就是 CID 比「同檔就鎖」聰明的地方:物理層交給 Git,邏輯層交給 CID,兩條軌道並行運作。

4.3 「擋住」之外,還會告訴你怎麼拆

遇到 blocked-cid-conflictneeds-physical-split,advisor 會多回一份 merge plan,包含:

  • 衝突原因:哪一張 CID、哪一個共享 generator、哪一份 artifact 撞上了。
  • 建議 lane:走 deterministic composer(範圍清楚,工具能合)、Neutral Write Steward(雙方都有語意判斷,要找個中立的寫手)、還是 shared-surface guard(要先拆表面)。
  • hotspot 報告:這個衝突點在最近 N 張卡裡撞過幾次;撞越多次,代表越該優先把那個 atom 或那個檔案拆掉。
  • 需要的 evidence:merge 之後要過哪幾個 validator 才能 close。

這就是「先派調度雷達、確認要撞才派合併工」的設計哲學。框架平常讓任務自由跑,只有真的撞上同一張 CID,才會升級到序列化或仲裁。

關鍵洞察:這是邏輯層的解法,物理層交給 Git。Git 處理「保存歷史、分支、merge、commit、rollback」這些;CID 處理「這兩個改動在語意上會不會撞」這個合約問題。有了 atom 跟 atom map,CID 才有可以指向的單位;有了 CID,多 Agent 並行才能從「祈禱不撞」升級到「可以計算判定」。三層一起出現,整套煞車才真的成立。*

5. 治理骨架:七階生命週期 + 五個原子 + 完整行為集合

講「煞車」之前要先講「煞車裝在哪」。鑄造廠的骨架不是「派一個 Agent 從頭做到尾」,而是把一次完整工作切成七個機器能偵測的階段,再用「原子(atom)」跟「行為(behavior)」這兩個對外穩定的合約綁住每一次變動。下面這張圖是目前已經跑起來的實作:

ORIENT框架簽名偵測framework / adopter NEXT路由器決策下一步 CLI 命令 LOCK編輯前必鎖INV-ATM-002 EXECUTE實際工作事後驗證鎖內 EVIDENCE證據沉澱SHA256 + gate HANDOFF交接摘要跨 session 延續 CLOSUREclosure-packet.v1git HEAD pin 每階都可被 doctor 偵測「完成 / 未完成」;agent 不能跳階 node atm.mjs orient → next → lock acquire → ... → evidence verify --gate close → tasks close 5 個 active 原子(atoms)作為治理單位 ATM-CORE-0001 種子身分・ATM-CORE-0003 中性掃描・ATM-CORE-0004 原子生成器・ATM-CORE-0005 語意指紋・ATM-FIXTURE-0001 自證 fixture 10 個 plugin 行為:split / atomize / merge / dedup-merge / compose / evolve / polymorphize / expire / sweep / infect(另含 anchorize、promote 兩個 capsule 階梯輔助)
圖 5:ATM 七階治理生命週期。每階都有對應的 CLI 命令、對應的失敗守則(doctor check)、對應的驗證契約。下方橫條是「對外穩定的治理單位」:5 個 active 原子(governed tier)負責身分基礎與生成 / 中性 / 指紋計算;11 個行為類別則是對原子做的合法動詞。

什麼是 atom(原子)?它不是 task 也不是 commit,而是有唯一 ATM-{BUCKET}-{NNNN} 編號、有 hash-locked spec、有 evidence-required 驗證指令的最小治理單位。目前註冊表中有 5 個 active 原子(governed tier):種子(0001)、中性掃描器(0003)、原子生成器(0004)、語意指紋(0005)、生成器自證 fixture(FIXTURE-0001)。不能直接編輯 atomic-registry.json——所有新原子必須走 ATM-CORE-0004,且須過 INV-ATM-003 的 schema gate(這就是 charter 的紅線之一)。

什麼是 behavior(行為)?對原子做的合法動詞,全部集中於 plugin-behavior-pack,按家族分類:

Split 家族

split 把既有原子拆成更清楚的範圍;atomize 從廣域 / legacy 抽出一個全新的可治理原子。

Merge 家族

merge 兩原子合一;dedup-merge 為去重而合;compose 把多個治理單位組合成更高層成品。

Evolution 家族

evolve 同一原子版本前進;polymorphize 身分不變但走變體 / 替代形式。

Lifecycle 家族

expire 正式退役;sweep 清理過時殘留。此家族目前仍在 dry-run / proposal 狀態,不直接 host apply。

Propagation 家族

infect 把治理變更外推到下游依賴,必過 neutrality scan + human review。這是「原子市場」(§10)的傳遞機制。

七階對映角色矩陣

原子在哪些階段「主導 / 協同 / 偵測 / 不介入」是有矩陣可查的。例如語意指紋(0005)分布最廣(NEXT / EXECUTE / EVIDENCE / HANDOFF / CLOSURE 都有角色)。

6. 5D CID:給每個原子的多維身分證

這張身分證是整個鑄造廠比喻的核心。每個 atom 都領一張 CID(content-addressable identifier)。它不是「程式語意」的指紋(那種東西計算機科學還做不到),而是這個原子對外宣告的合約指紋

CID 是確定性的——只看 atom 自己宣告的合約欄位(input/output ports、語言、效能預算),跳過原始碼解析、AST、LLM、embedding。同樣的宣告永遠算出同一張證;任何會飄移的訊號都被擋在門外。

用一個例子走一次。假設兩個 Agent 各寫了一個 retry helper,實作寫法不同,但對外宣告的合約是一樣的

// 寫法 A:for 迴圈
async function retry(url, opts) { /* ... */ }

// 寫法 B:while 迴圈、箭頭函式
const withRetry = async (u, o) => { /* ... */ };

實作不同,所以「字面雜湊」(CID.Strict)會不同。但他們的 atom spec 宣告了同樣的對外合約:

// 兩個 atom 各自的 atom spec(這才是 CID 真正去 hash 的對象)
const spec = {
  inputs: [
    { name: "url",  kind: "string" },
    { name: "opts", kind: "RetryOpts" }
  ],
  outputs: [
    { name: "result", kind: "Promise<Response>" }
  ],
  language: { primary: "typescript" },
  validation: { evidenceRequired: true },
  performanceBudget: { hotPath: false, inputMutation: "forbidden", maxDurationMs: 5000 }
};

// CID.Interface = SHA256 over the normalized declared contract
const cidInterface = "sf:sha256:" + sha256(canonicalize(spec));

// 因為兩個 atom 宣告的合約一致,所以:
//   A → sf:sha256:a3f9c2e8…1b40
//   B → sf:sha256:a3f9c2e8…1b40   ← 同一張 CID.Interface

注意這個過程跳過了「抽 effects」「抽 invariants」「砍變數名」這些猜測動作。CID 不去推程式碼在做什麼,只看 atom 自己明文承諾了什麼介面跟執行約束。介面一致 → 雜湊一致 → 同一張身分證——工程上做得出來,目前 ATM 也已經在跑。

身分這件事一共有五個維度,目前只有 CID.Interface 已經實作,其餘四個是 roadmap 上的提案:

維度它認證什麼狀態
CID.Strict正規化原始碼的 SHA256,用於 git 層級竄改檢查部分(capsule / hash-lock)
CID.Interface上面那張,宣告式合約指紋✅ 已實作(=現況 semanticFingerprint)
CID.Effects副作用標籤(NET / FS / DB…),純函數 vs IO 不可替換提案,未實作
CID.Semanticembedding 向量,只當去重候選排序提示提案,未實作
CID.Behavior綁 test harness id:「在這組測試下不可區分」提案,未實作

後三個(Effects / Semantic / Behavior)永遠留在 advisory 層,不會混進 identity hash。這條防火牆叫確定性原則:身分必須穩定、可重算、跟模型版本無關。

{ } atom 宣告的對外合約 normalize spec SHA256 ports + language + 執行約束 ATOM ID CARD ATM-MAP-0042 cid:a3f9c2e8 status: active 合約一致 → 同一張證
圖 6:把 atom 對外宣告的合約(ports、語言、執行約束)丟進機器,機器正規化後蓋上 SHA256 鋼印,吐出 CID.Interface。實作寫法不同沒關係——只要對外宣告一致,就會得到同一張身分證。

有了這張證,下面這些事就變得可能(也誠實標清楚哪些已經在跑、哪些還在 roadmap):

  • 專案內介面去重(已實作):Dedup Police 用 CID.Interface 前綴比對,秒抓「兩個 atom 對外宣告一模一樣,要不要合併?」——這是 advisory finding,不會自己動手。
  • 跨專案介面查詢(已實作的查詢層 + 待補的索引):在你機器上既有的 ATM repos 內,這個查詢已經可以跑;跨組織的查詢還沒有。
  • 跨組織原子市場(roadmap,需先把本地端跑成熟):見最後一段「§10」的誠實邊界。

CID 順便解決了一個老問題:「我這個 codebase 到底有多少地方的對外介面其實一模一樣?」過去要靠靜態分析勉強猜,現在每個 atom 都帶確定性指紋,這就是個 O(1) 查表的問題。要記得一件事——介面一致只代表「合約相同」,行為等價要靠執行期測試(這就是 roadmap 上 CID.Behavior 跟零信任沙盒要做的事)。CID 本身只負責「誰宣稱了什麼合約」這一層。

7. 權限就是裝備:lease 取代資料夾隔離

兩個 Agent 不可能同時拿到同一張寫入權,因為這層在 git 之前就攔下來了。

多 Agent 並行最容易撞牆的地方就是「誰可以寫什麼」。傳統做法是用資料夾權限或工具白名單,但兩個方式都有同一個問題:它們是靜態的,跟著任務跑不動

鑄造廠的做法是把權限拆成有名字的物件,每個都有 mode 屬性:

權限模式誰預設拿意義
task.lifecycleexclusiveCaptainclose / checkpoint / advance
git.writeexclusiveCaptainstage / commit / tag / push
file.writeexclusiveImplementer寫 source;範圍必須是 allowedFiles 子集
file.readshareable多人讀檔案與 source
exec.validatorshareable多人跑不會 mutate 的驗證指令
database.writeexclusive顯式授權寫外部 DB;不在預設 recipe
ci.writeexclusive顯式授權觸發或修改 CI
web.downloadexclusive顯式授權下載外部資料或套件

exclusive 權限同一時間只給一個人。第二個 Agent 要拿,框架直接回 ATM_TEAM_PERMISSION_CONFLICT 錯誤碼,連 git 都還沒跑就被擋了。實際跑起來長這樣:

$ node atm.mjs team lease --agent builder-01 \
    --permission file.write --paths "packages/cli/src/commands/**"
✓ lease granted — file.write → builder-01

# 另一個 Agent 想同時拿同一把寫入權:
$ node atm.mjs team lease --agent builder-02 \
    --permission file.write --paths "packages/cli/src/commands/**"
✗ ATM_TEAM_PERMISSION_CONFLICT
  file.write 是 exclusive,已被 builder-01 持有(自 12:04:11)
  → builder-02 要嘛等釋放,要嘛換一塊不衝突的 scope
builder-01 file.write exclusive · 只有一把 builder-02 CONFLICT
圖 7:file.write 是一把唯一的鑰匙。builder-01 拿著的時候,builder-02 連碰都碰不到——衝突在權限層就被擋下,不必等到 git merge 才發現。

權限可以轉交,但要走 team leaseteam release CLI,每次轉交都留下時間戳、agentId、權限範圍。這份 lease 履歷會跟著 closure-packet 一起寫進永久證據。

8. 共享記憶:charter 是最高權威、ATMChart 是執行期煞車、closure-packet 是證據鏈

多 AI 協作另一個容易翻車的地方是「上下文漂移」——Agent A 跟我講過一個假設,Agent B 進場時並不知道,於是寫出來的程式碼跟 A 的版本對不上。等發現時,三個檔案已經飄向四個方向。鑄造廠的對策很直接:把治理規則寫成三層機器能讀的合約,由它們在現場把關:

  • 最高權威 = atomic charter(.atm/charter/atomic-charter.md)+ 7 條 INV-ATM。Charter 是 framework 的最終裁判,當前版本 v2.0.0;INV-ATM-001~007 是不可逾越的紅線(由 gate / doctor / waiver-required 三種機制執行)。違反 invariant 不能繞過,必須走 charter waiver 流程(behavior.evolve + charterWaiver + HumanReviewDecision)。
  • 執行期煞車 = ATMChart(.atm/memory/atm-chart.md)的 SHA256 drift detection。它不是最高權威,但它是「拿著過期地圖會被當場攔下」的那把鎖。
  • 證據鏈 = closure-packet.v1。每次 close 寫入永久 ledger,可被半年後 audit 逐條重放。

下面先把後兩個機制(ATMChart、closure-packet)攤開講;7 條 INV-ATM 留到下一節跟警察家族一起講。

ATMChart 漂移偵測

把 5 份核心治理 schema(guards、charter、integrations、agent-prompt、upgrade-proposal)用 SHA256 鎖進 .atm/memory/atm-chart.md 的 frontmatter。任何 schema 改動 → drift → ATM_CHART_STALE 直接擋,AI 不能拿著過期地圖去動手。每張地圖都附 framework 版本與支援範圍,舊版本進場會被 ATM_CHART_VERSION_UNSUPPORTED 拒絕。

Closure-packet 證據鏈

每張卡 close 時寫入 atm.closurePacket.v1:commitDelta、commandRuns(每條指令的 stdout/stderr SHA256)、runnerVersion、teamRunId。半年後你可以重新驗證「當時跑的指令輸出,跟今天重跑是否一致」。這條 hash chain 就是 ATM 跟「PR 註解」最大的差別。

一份 closure-packet 攤開來長這樣——它記的是「我跑了哪些指令、各自的退出碼、輸出的 SHA256 是多少」,而不只是 Agent 自己說「做完了」:

{
  "schemaId": "atm.closurePacket.v1",
  "taskId": "TASK-AAO-0042",
  "commandRuns": [
    { "command": "npm run typecheck",
      "exitCode": 0,
      "stdoutSha256": "sha256:dade4751…655da0" },
    { "command": "node atm.mjs test --spec",
      "exitCode": 0,
      "stdoutSha256": "sha256:9f1c0a…b3e7" }
  ],
  "commitDelta": { "changedFiles": 3, "governedTreeSha": "9f1c2d…" },
  "teamRunId": "team-abc123",
  "runnerVersion": "0.1.0"
}

注意 exitCodestdoutSha256 是綁在一起的。Agent 想把 exitCode: 1 的 validator 講成「通過」也辦不到——退出碼只要不是 0,就只能記成 diagnostic,算不了 pass。證據自己會說話。

這兩個機制合起來給了一個強保證:規則的版本、hash、支援範圍,全都明文寫在地圖上。Agent 拿著過期地圖會被當場擋下,「我以為規則是這樣」這種辯解再也行不通。

9. 7 條 INV-ATM 紅線 + 常駐警察家族:合約煞車與結構良心

你睡覺的時候,警察還在巡;invariants 一直釘在那裡,從來沒下班。

鑄造廠的「煞車」分兩層。合約層的煞車是 charter 上的 7 條 INV-ATM(公開、穩定、寫進 framework);偵測層的煞車是常駐警察家族(advisory,機器自動跑,把判斷權留給人類)。它們的分工是:

合約紅線(INV-ATM-00X)對應煞車類型白話意義
INV-ATM-001 No second registrygate(直接拒絕)整個 repo 只能有一個 atomic-registry 真相來源。
INV-ATM-002 Lock before editdoctor(引導修復)編輯前必須持有 ScopeLock
INV-ATM-003 Schema-validated promotion onlygate所有原子升級必須過 schema 驗證,直接改 registry 禁止。
INV-ATM-004 No competing highest authoritydoctor沒有任何 host rule 可以聲稱地位等於或高於 charter。
INV-ATM-005 Host rule amendments require waiver flowwaiver-required違反 invariant 的合法路徑:behavior.evolve + charterWaiver + HumanReviewDecision
INV-ATM-006 Framework work tracking stays target-localdoctorframework 任務 ledger 必須留在 framework repo 自己的 .atm/history/tasks/
INV-ATM-007 Public framework docs remain English-onlydoctorframework 公開文件英文化、中性化;ATM-CORE-0003 中性掃描器負責執行。

7 條 INV-ATM 是公開合約,違反需走 charter waiver;警察家族則是 advisory 偵測——它們不在 charter 上,但天天在 registry 與 source 裡巡邏,把慢性結構衰敗抓出來。一次 mutation 安全是 INV-ATM 的事;幾百次 mutation 累積後 repo 還健不健康,是警察家族的事。

下面挑幾個最常見的警察給你看(完整清單共十多個家族):

Dedup Police

掃 CID 前綴重疊。一旦 registry 裡出現兩個 atom 指紋很近,自動產 advisory finding,路由到 behavior.dedup-merge

Demand Police

掃 caller-graph 過載。某個 atom 的呼叫者數量超過門檻(預設 6)→ 建議走 behavior.split

Decomposition Police

用 source-inventory 算 LOC,超過神檔門檻 → 推 atomize plan draft。每日有上限避免一次刷出 100 條 finding 淹沒人類。

Quality Police

比對品質指標前後變化。回歸大於門檻 → blocker。新原子品質低於 baseline → 不過 quality gate。

Evolution / Polymorph

看 atom 是否該升級到下一版、是否該抽成 template + variants。advisory only,最終決策回人類。

Rollback Police

守 reversibility。任何 mutation 要 apply 前都要有 rollback proof。沒有就擋。這條線守住所有 map replacement / evolution / atomization / infect / expire / retirement 流程的安全。

dup? ⚑ 產出 findingadvisory · 不動手
圖 8:警察 bot 沿著 registry 巡邏,發現一個語意指紋跟別人很近的細胞,就掛一張 dup? 旗子、產出一筆 finding——然後就停在這裡。它只通報,不會自己動手合併。

這些警察都共用一條鐵律:directApplyAllowed: false。它們可以發現問題、建議方向、產出 plan draft,但動手的事永遠交給人類。一筆 finding 攤開來其實很樸素,重點在最後那一行:

{
  "policeFamily": "dedup",
  "severity": "advisory",
  "trigger": "semantic-fingerprint-overlap",
  "scope": "ATM-MAP-0042,ATM-MAP-0088",
  "message": "兩個 atom 的語意指紋高度重疊,建議評估合併",
  "routeHint": "behavior.dedup-merge",
  "directApplyAllowed": false   // ← 警察只通報,動手要人類批准
}

所有 apply 都要經過 ReviewAdvisory machine-finding + HumanReviewDecision。「advisory 升 blocker」這一步固定由人類拍板,框架不會替你決定。

鑄造廠刻意把「24 小時全自動演進」收掉——當你已經有 N 個 Agent 同時改 repo 時,再多加一個自主重構機器人只會引爆寫-寫衝突。警察的價值是「看見」,把「動手」留給人。

10. 從 git clone 到第一張卡 close:採用 ATM 的最小路徑

聽起來複雜,採用門檻其實不高。ATM 的官方分發單位是單檔 runner atm.mjs(大約 3.1 MB 的 strip-types bundle,零 transitive dep)。部署走「framework 端顯式 push 給 adopter」的 sync,跟 npm install 是不一樣的路徑。從 0 到第一張 closure-packet 的最小流程如下:

# 0-15 min:取得 runner + ORIENT
# Framework 端(onefile 已 build 好):
#   npm run build  →  release/atm-onefile/atm.mjs(約 3.1 MB)
# Adopter 端:把 onefile sync 進來
node release/atm-onefile/atm.mjs internal-release sync \
    --repo /path/to/my-app --json
cd /path/to/my-app
node atm.mjs orient --cwd . --json
node atm.mjs doctor  --cwd . --json
# 看每條 doctor 守則(lock-before-edit、charter-integrity、neutrality-scanner-active…)全綠

# 15-30 min:問 NEXT、鎖 LOCK
node atm.mjs next --prompt "your first small change" --json
# 拿到 nextAction → 依 command 字串執行(例如 lock acquire)
node atm.mjs lock acquire --workItem <workItemId> \
    --files src/foo.ts --reason "first small change" --json

# 30-60 min:EXECUTE → EVIDENCE
# 在 lock 範圍內改檔、跑你的測試
npm test
node atm.mjs evidence add --task <workItemId> --actor codex-main \
    --kind test --summary "unit tests passed" --artifacts reports/test.json --json

# 60-80 min:HANDOFF + 證據 verify
node atm.mjs evidence verify --task <workItemId> --gate close --json
node atm.mjs handoff summarize --task <workItemId> --json

# 80-90 min:CLOSURE
node atm.mjs tasks close --task <workItemId> --actor codex-main --status done --json
# 寫入 .atm/history/evidence/<taskId>/closure-packet.json
# 內含 commandRuns[].stdoutSha256 + targetCommit + governedTreeSha
# 後續任何 audit 重跑同樣命令 → byte-for-byte 比對

90 分鐘結束你會擁有什麼?

  • 一個 commit,帶 teamRunId 與 closure 證據引用
  • 一份 .atm/history/evidence/TASK-XXXX.closure-packet.json,含每一條指令的 stdout SHA256
  • 一份 patrol-report.md,記錄這張卡 close 時的結構健康度*
  • 一份 team-memory-shard.md,把這次的教訓用模板形式落檔,供下一個人類或 Captain 開卡時主動翻閱*

這四樣是鑄造廠跟一般 vibe coding 流程最直接的差異:除了改完的程式,你還拿到永久證據跟結構快照。memory shard 跟 patrol report 是 git 裡的 markdown,由人類或 Captain 在下次開卡時主動引用,框架本身不會自動把它們塞進下一個 Agent 的上下文。

11. 容易失敗的地方(與對應的 doctor 守則)

老實說,鑄造廠也有踩過的坑。下面六個是我最常遇到、ATM doctor 守則直接點名的場景。每一個都對應一條具體的 doctor 檢查,失敗時會回傳 firstFailedChecksuggestion,Agent 直接照著做就行,不用猜:

lock-before-edit(INV-ATM-002)

未持鎖就編輯。下一次 atm next 回 blocked,suggestion 直接給 atm lock acquire --files <list>。最常見也最容易修。

evidence-freshness

任務 reopen 後想用舊證據 close。閘門擋下,要求收集 reopenedAt 之後的新證據。這條是 commit 85b92ce 加入的硬化,杜絕「悄悄重開再用舊證據 close」的繞道。

git-head-evidence

closure packet 的 targetCommit 對不上當前 git HEAD。Doctor 拒絕,要求 rebase 或重新 close。讓「封包描述的狀態 vs 實際 repo 狀態」不能漂移。

registry-sole-source(INV-ATM-001)

repo 裡跑出第二個 atomic-registry.json(通常是某 plugin「為了方便」自建)。直接 gate 拒絕,要求合併回根註冊表並走 ATM-CORE-0004。

neutrality-scanner-active(INV-ATM-007)

Framework 公開文件出現 adopter 私有名詞或非英文段落。ATM-CORE-0003 中性掃描器報 violation;改不掉就走 charter waiver。

charter-integrity

charter.md 與 charter-invariants.json 不同步(charterVersion / lastAmendedAt 對不上)。Doctor 要求對齊兩端。這是「最高權威」自身的健康檢查。

這六個坑都有一個共同點:它們是治理紀律問題,不是 framework bug。框架幫你把攔截機制、結構化失敗回報、可執行的修復指令都備好了;剩下的工作是把 atm doctor 串進你的 pre-commit hook 或 CI 步驟,這樣你睡覺時這套煞車才會一直幫你看著。

12. CID-Native 原子代碼市場:北極星,不是明天就上線

前面講的都是單一專案內怎麼治理。從這裡開始是 roadmap。我想先講清楚哪一段已經做得到、哪一段還在 north star 階段,免得讓人以為「明天就能用」。

骨牌可以這樣排:CID.Interface 是確定性的,同一份對外宣告 → 同一張 CID.Interface → 不分作者、不分專案都會一致。如果一萬個專案都採用同一套治理協議,每個專案都會產出帶 CID 的 atom 清單。哪天你在新專案需要 idempotent-http-retry-with-jitter

  1. 本地算這個需求的 CID.Interface 前綴
  2. 查跨組織 CID 索引
  3. 命中 N 個候選 atom(不同實作、不同語言、不同 quality / trust tier)
  4. 每個候選 atom 都帶它自己的 closure-packet、evidence、police clean record、宣告的能力(網路 / 檔案 / DB 權限)
  5. 人類審 → 通過 → atm infect 把它接進你的專案,並依本地契約建立 caller graph

它要填的位置是 npm + Docker Hub + Stack Overflow 之間一個還沒人補上的中間層:npm 給你 package、看不到內部結構;Stack Overflow 給你 snippet、缺 audit;Docker 給你 image、顆粒又太粗。函式級、帶完整治理履歷、可被機器搜尋的程式細胞——這個空缺值得填上去。

幾個重要邊界:跨組織市場屬於最後一個 epoch,要先等本地端跑成熟、Trust Tier 跟零信任沙盒落地。它跟 npm / Docker 是補位關係,處理的是「函式級 + 被治理 + 可重組」這個顆粒度。`infect` 永遠走 advisory + 人審,不會自動把陌生原子接進你的程式。*

所以老實說:CID 原子市場是北極星,不是下一個版本的承諾。我目前能在合理時間內交付的,是把單一專案內的 CID.Interface + 證據鏈 + 巡邏警察跑紮實。市場是同一套協議外推到跨組織時自然會浮現的東西,要等地基穩了才會出現。

說回我最終想看到的畫面:AI 寫的每一段程式碼,都該是有名字、可被審計、可被找到的細胞,而不只是活在我這個 repo 裡的孤兒。這件事今天就能開始——從你正在開的這個 repo,給每個 atom 一個確定性的 CID.Interface,就算起點了。

13. 結語

2025 年大家在比「我的 AI Agent 有多聰明」。2026 年我覺得題目該換成:當 N 個聰明的 Agent 同時改一個 repo 時,這個 repo 還撐得住嗎?

我給自己的答案是:鑄造廠 + 多維身分證 + 七階煞車。每段程式碼變成有名字的細胞、每次改動留下有 hash 的證據、7 條 INV-ATM 釘成 charter 紅線、常駐警察家族盯著結構健康度、ORIENT→CLOSURE 走成不能跳階的生命週期。規矩多了一點,回報很實在:半年後我的 repo 還讀得懂、查得到、能被重用——而且我同時開 5 個 Agent,它也撐得住

如果只是要做一個小 feature,這套協議確實 overkill。但你的專案要跑半年、多個 AI 同時介入、未來要送合規,甚至想把寫過的好 atom 分享出去——這時候就會需要一座有煞車的鑄造廠。

這篇是入門介紹。想看具體實作、API、police family 機制、權限模型細節,可以看 github.com/eaglhuang/AI-Atomic-Framework。框架本身是 Apache 2.0,整套治理協議可以直接 fork、替換成你自己的 governance bundle,或者只挑其中一部分用(例如只接證據鏈,只接 ATMChart)。

* 註:roadmap 與目前實作狀態

這篇文章為了好讀,把「已實作」跟「規劃中」放在同一張地圖上講。下面把分界一次補清楚——掃過去就好,要查的時候再回來看。

  • 已實作(你 clone 下來就能跑):七階生命週期 + node atm.mjs onefile runner、CID.Interface(=現況 semanticFingerprint)、ScopeLock + INV-ATM-002「lock-before-edit」、closure-packet.v1(含 commandRuns SHA256)、ATMChart drift detection、七條 INV-ATM 紅線、Atomization / Dedup / Demand / Quality / Lifecycle / Rollback / Boundary / Map-Integration 等警察家族 advisory 偵測、atomic-map.schema.json v0.1.0 與 basic map integration test。
  • 規劃中(roadmap,文章內以 * 標註)
    • 5D CID 的其他四維(Strict / Effects / Semantic / Behavior):只有 Interface 已實作,其餘為提案;非確定性訊號永遠不准進 identity hash。
    • Team Agents laneteam lease CLI、權限表(task.lifecycle / git.write / file.write …)、15 角色 4 層協作、`team-memory-shard.md`、`patrol-report.md` 都是這條 lane 的設計提案;目前 lease 只走 ScopeLockRecord + INV-ATM-002 這條最小路徑,memory shard 與 patrol report 屬模板,**不會被自動載入下一個 Agent 上下文**,需由人類或 Captain 主動引用。
    • Map Replacement Protocol v2-r2:本文 §3 介紹的 replacement.legacyUris[]、五階 lifecycle(draft → shadow → canary → active → legacy-retired)、map-equivalence-reportcreate-map / test --equivalence-fixtures / test --propagate CLI、M26 Rescue Police、M27 Disaster Recovery CLI 屬於 TASK-MRP-0011~0027(17 張任務卡)。其中 MRP-0018 / 0021 已完成,MRP-0026 進行中,MRP-0022(Daemon)/ MRP-0024(Guide Cache)為 opt-in 預設 OFF。
    • Parallel Conflict Advisor(§4):本文 §4 介紹的 atm tasks parallel CLI、八種 verdict、merge plan / hotspot 報告屬於 TASK-CID-0005(P0 planning-only contract card)。CID / semanticFingerprint 本身已確定性實作;advisor 的合約已定義,後續實作走 AAF target-repo card。Write Broker / Steward lane 整合(TASK-CID-0009~0012)也屬同一條 P0 規劃線。
    • CID 原子市場(§12):跨組織查詢與市場是北極星,需先等本地端跑成熟、Trust Tier 制度化、零信任沙盒落地。不會取代 npm / Docker,補位「函式級 + 被治理 + 可重組」的中間層。infect 永遠是 advisory + 人審。
    • Tier 3 證據:本機 sandbox 證據只能達 Tier 2。要升到 Tier 3 / marketplace-grade,closure 必須帶外部 AttestationProvider 的簽章與可驗證 provenance(GitHub Actions 為第一個 reference adapter)。突變測試與對抗 QA 永不掛同步 close 路徑,要走 async police。

正式 spec、charter 文字、warrant 範例可以在 github.com/eaglhuang/AI-Atomic-Framework 找到。

關於作者

Eagl Huang,台灣獨立工程師。目前主力是 AI-Atomic-Framework——一個多 AI 並行協作的工程治理框架,以及 3KLife,一個三國題材的 AI 遊戲專案。每天讓 5 個 Agent 同時改一條 repo,所以非常在意這套煞車能不能撐住。

喜歡這篇就分享給其他正被多 AI 開發逼瘋的朋友;有想法歡迎到 GitHub Discussions 來聊。