NEO.K / PU程式宇宙基礎
編號PU-1-04
版本v0.1
日期2026-07-27
作者Neo.K with Aletheia
狀態初版完成

下載 PDF ↓回到論文索引 ↗

責任、模組與契約:從檔案分類到系統邊界

Responsibility, Modules, and Contracts: From File Classification to System Boundaries

論文編號: PU-1-04
系列:「程式宇宙書系」第 1 冊《系統性程式設計》
作者: Neo.K with Aletheia
機構: EveMissLab/一言諾科技有限公司
版本: v0.1
日期: 2026 年 7 月 27 日


摘要

前兩篇分別建立了問題世界模型,以及資料、狀態、事件、行動的四元動力結構。本篇處理系統設計的下一個核心問題:當世界中已有實體、狀態、事件與行動後,究竟由誰負責維持它們?哪些狀態屬於哪個模組?模組之間應交換命令、事件、查詢、資料還是證據?跨邊界失敗由誰承擔?契約又應包含哪些內容?

本文提出:

ModuleFolderPackageProcessServiceDeployment Unit\boxed{ \text{Module} \neq \text{Folder} \neq \text{Package} \neq \text{Process} \neq \text{Service} \neq \text{Deployment Unit} }

資料夾是檔案組織;套件是語言或建置單位;程序是執行單位;服務是可被網路或程序邊界存取的運作單位;部署單元是發布與資源配置單位。模組則是對一組問題世界狀態、規則與失敗承擔一致責任的語意邊界。

本文將模組定義為:

M=WM,SM,IM,AM,EM,CM,FM,OM,DM\boxed{ \mathcal M = \left\langle W_M, S_M, I_M, A_M, E_M, C_M, F_M, O_M, D_M \right\rangle }

其中:

本文提出「權威狀態單一責任原則」:

每一項重要世界狀態,必須具有唯一可識別的權威責任者;它可以被複製、快取與投影,但不能由多個模組在沒有明示協議下共同直接改寫。

形式上:

sScritical,!M:Owner(M,s)\forall s\in S_{\mathrm{critical}}, \quad \exists !\,M: Owner(M,s)

此處的唯一不是要求單一機器、單一資料庫或單一程序,而是要求單一可追責的語意責任。分散式複本可以很多,但誰決定狀態合法、誰維持不變量、誰處理衝突,必須清楚。

本文將責任定義為:

Rs=Purpose,StateOwnership,DecisionAuthority,Obligation,FailureOwnership,Evidence,NonResponsibility\mathcal R_s = \left\langle Purpose, StateOwnership, DecisionAuthority, Obligation, FailureOwnership, Evidence, NonResponsibility \right\rangle

責任不只是「這個類別做什麼」,而是對目的、狀態、決策權、義務、失敗、證據與非責任的整體承諾。

本文進一步提出完整契約模型:

KAB=Intent,Input,Precondition,Authorization,Effect,Event,Failure,Retry,Time,Evidence,Version,Governance\boxed{ \mathcal K_{AB} = \left\langle Intent, Input, Precondition, Authorization, Effect, Event, Failure, Retry, Time, Evidence, Version, Governance \right\rangle }

契約不等於函式簽章、API schema 或 JSON 格式。型別只能描述資料形狀,完整契約還必須說明:

本文區分跨模組互動的五種基本形式:

  1. Query:要求資料投影,不應改變世界;
  2. Command/Action:要求另一模組執行世界變更;
  3. Event:宣告某項已發生事實;
  4. Evidence:提供完成、驗證或責任證明;
  5. Shared State:多方直接存取同一狀態,僅在責任與一致性協議明確時使用。

本文主張,共享資料庫不是免費整合。當多個模組直接修改同一資料表時,實際上形成隱藏共同責任:

Shared Write=Shared Invariant Responsibility\boxed{ \text{Shared Write} = \text{Shared Invariant Responsibility} }

如果團隊無法共同說明不變量、衝突、回復與版本,共享寫入便只是邊界消失。

本文亦分析同步呼叫、非同步命令、事件發布、共享狀態與人工工作流。不同形式不只是技術選擇,而是對時間、責任、可用性與失敗傳播方式的選擇。同步呼叫讓依賴立即可見,卻容易形成時間與故障耦合;非同步互動提高解耦與恢復能力,卻需要顯式處理延遲、重複、順序與最終一致;事件發布降低發布者對訂閱者的依賴,卻不能用事件逃避對結果的責任。

本文提出「契約邊界測試」:一個候選模組若無法獨立回答以下問題,就尚未形成真正邊界:

本文使用訂單與付款、帳號與權限、網站部署、AI Agent 工具層、研究工作流與多團隊平台等案例,說明責任如何決定模組,而不是由檔案、類別、微服務數量或組織圖自動決定。

本文最後提出可證偽研究綱領,包括共享寫入事故率、狀態擁有者辨識率、契約完整度、跨邊界失敗傳播、同步耦合成本、事件濫用率、模組交接時間、責任圖與依賴圖差異、契約版本破壞率及模組邊界與團隊邊界的關係。

本文為下一篇〈可視化作為外部結構記憶〉建立組織骨架:當責任、狀態與契約被明確後,系統才能被不同角色、不同尺度與不同時間共同看見,而不再依賴少數工程師腦內的隱性架構。

關鍵詞: 模組、責任、契約、狀態擁有權、系統邊界、共享資料、同步耦合、事件驅動、軟體架構


Abstract

This paper defines modules as semantic boundaries of responsibility rather than folders, packages, processes, services, or deployment units.

A module is modeled as:

M=WM,SM,IM,AM,EM,CM,FM,OM,DM\mathcal M = \left\langle W_M, S_M, I_M, A_M, E_M, C_M, F_M, O_M, D_M \right\rangle

Each critical state must have one identifiable authoritative responsibility, even if it is replicated across multiple machines.

The paper develops a full contract model that includes intent, input, preconditions, authorization, effects, events, failures, retries, time, evidence, versioning, and governance. It distinguishes queries, commands, events, evidence, and shared state, and analyzes synchronous, asynchronous, event-driven, shared-state, and human-mediated interactions.

The paper argues that module boundaries should be derived from state ownership, invariants, decisions, failures, and evidence rather than file structure or deployment topology.

Keywords: modules, responsibility, contracts, state ownership, system boundaries, event-driven architecture


一、問題的提出:系統為何總是被拆錯

很多專案以下列方式拆分:

controllers/
services/
models/
utils/
repositories/

或拆成:

user-service
order-service
payment-service
notification-service

但名稱相似不代表責任清楚。

一個名為 order-service 的服務可能:

反之,一項真正完整的「訂單責任」也可能分散在多個資料夾、程序與部署單元中。

因此,模組不能由檔案或部署形式定義。

它必須由責任定義。


二、模組不是什麼

2.1 模組不等於資料夾

資料夾只表示檔案被放在一起。

2.2 模組不等於套件

套件是語言、建置或發布機制。

2.3 模組不等於類別

單一類別通常只承擔局部行為或資料結構。

2.4 模組不等於程序

程序是 Runtime 隔離與資源單位。

2.5 模組不等於服務

服務可以承載一個或多個模組,也可能只是一個技術接口。

2.6 模組不等於部署單元

同一模組可以被多個部署實例承載;多個模組也可以暫時共同部署。

因此:

Semantic BoundaryPhysical Deployment Boundary\boxed{ \text{Semantic Boundary} \neq \text{Physical Deployment Boundary} }

三、模組的正式定義

本文定義:

M=WM,SM,IM,AM,EM,CM,FM,OM,DM\boxed{ \mathcal M = \left\langle W_M, S_M, I_M, A_M, E_M, C_M, F_M, O_M, D_M \right\rangle }

3.1 問題世界切片 WMW_M

模組負責理解哪一部分世界。

3.2 權威狀態 SMS_M

哪些狀態由此模組決定與維護。

3.3 不變量 IMI_M

無論如何轉移都必須成立的條件。

3.4 接受行動 AMA_M

外部主體可以要求此模組做什麼。

3.5 發布事件 EME_M

模組會對外宣告哪些已發生事實。

3.6 對外契約 CMC_M

其他模組如何合法互動。

3.7 失敗責任 FMF_M

哪些失敗由本模組重試、補償、回復或升級。

3.8 觀測與證據 OMO_M

如何證明模組做了什麼、目前如何、為何失敗。

3.9 相依與非責任 DMD_M

模組依賴誰,以及不保證什麼。


四、責任的正式結構

本文定義:

Rs=Purpose,StateOwnership,DecisionAuthority,Obligation,FailureOwnership,Evidence,NonResponsibility\mathcal R_s = \left\langle Purpose, StateOwnership, DecisionAuthority, Obligation, FailureOwnership, Evidence, NonResponsibility \right\rangle

4.1 目的

模組為何存在,試圖維持或改變哪一部分世界。

4.2 狀態擁有權

哪些權威狀態由此模組維護。

4.3 決策權

哪些世界判定只有此模組能正式作出。

4.4 義務

模組收到合法行動後必須提供什麼回應、狀態與證據。

4.5 失敗擁有權

失敗發生後,誰負責:

4.6 證據

模組如何證明其決策與效果。

4.7 非責任

模組明確不保證什麼。

非責任不是卸責,而是防止邊界外效果被虛假承諾。


五、權威狀態單一責任原則

本文提出:

sScritical,!M:Owner(M,s)\forall s\in S_{\mathrm{critical}}, \quad \exists !\,M: Owner(M,s)

5.1 唯一責任不等於單一副本

一項狀態可以具有:

但必須知道哪個模組有權判定其合法狀態。

5.2 單一責任不等於單一人

責任可由團隊、制度與 Runtime 共同承擔。

重點是責任位置可識別。

5.3 多模組直接寫入

若多個模組直接寫入同一狀態,則必須共同維持所有相關不變量。

這通常意味著它們尚未真正分離。

5.4 狀態變更應經由擁有者

外部模組不應直接修改另一模組的權威狀態,而應提出行動:

MACommandMBDecisionEBM_A \xrightarrow{Command} M_B \xrightarrow{Decision} E_B

5.5 讀取與寫入不同

其他模組可以讀取投影,但必須知道:


六、不變量決定模組凝聚力

6.1 不變量

不變量是模組必須始終維持的世界條件。

例如:

6.2 凝聚力

若一組狀態與行動共同維持同一組不變量,它們通常應位於相同責任邊界。

6.3 切斷不變量

若將一項必須原子維持的不變量拆到多個模組,系統會產生:

6.4 過度聚合

反之,把沒有共同不變量的責任放在同一模組,會造成:

6.5 模組邊界問題

因此模組設計不是追求最大或最小,而是尋找:

High Internal Responsibility Coherence+Explicit External Contracts\boxed{ \text{High Internal Responsibility Coherence} + \text{Explicit External Contracts} }

七、責任圖

定義責任圖:

GR=(M,K,O,D)G_R = \left( M, K, O, D \right)

其中:

7.1 責任圖不同於呼叫圖

呼叫圖描述誰呼叫誰。

責任圖描述:

7.2 呼叫方向不等於責任方向

前端呼叫付款模組,不代表前端對付款合法性負責。

7.3 資料流不等於權威流

資料從 A 流向 B,不代表狀態所有權也轉移。

7.4 失敗傳播

責任圖應標示:


八、五種跨模組互動

8.1 Query

Query 要求資料投影:

Q:MAMBQ : M_A \rightarrow M_B

原則上不應改變問題世界。

Query 契約需說明:

8.2 Command/Action

要求另一模組執行狀態變更。

命令以祈使語意命名:

AuthorizePayment
CreateAccount
DeployRelease
RevokeAgentPermission

被要求者可以接受、拒絕、延遲或進入人工審核。

8.3 Event

宣告已發生事實:

PaymentAuthorized
AccountCreated
ReleaseDeployed
AgentPermissionRevoked

事件發布者對事件真實性負責,但不應命令所有訂閱者如何反應。

8.4 Evidence

證據支援:

證據不是普通資料附件,而是契約完成判準的一部分。

8.5 Shared State

多個模組直接讀寫同一狀態。

共享狀態需要明示:

否則共享只是隱藏共同責任。


九、共享資料庫不是免費整合

本文提出:

Shared Write=Shared Invariant Responsibility\boxed{ \text{Shared Write} = \text{Shared Invariant Responsibility} }

9.1 表面便利

共享資料庫能快速:

9.2 隱藏代價

多個模組直接寫入同一表會使:

9.3 唯讀共享

唯讀分析與投影可以共享,但要標示:

9.4 合法共享狀態

在以下條件下,共享狀態可能合理:


十、契約不等於函式簽章

函式簽章可能描述:

authorizePayment(orderId: string, amount: number): Promise<Result>

但它沒有完整說明:

所以型別只描述契約的一部分。


十一、完整契約模型

本文定義:

KAB=Intent,Input,Precondition,Authorization,Effect,Event,Failure,Retry,Time,Evidence,Version,Governance\boxed{ \mathcal K_{AB} = \left\langle Intent, Input, Precondition, Authorization, Effect, Event, Failure, Retry, Time, Evidence, Version, Governance \right\rangle }

11.1 Intent

為何存在此契約,它服務哪個問題世界目的。

11.2 Input

需要哪些資料、身份與上下文。

11.3 Precondition

呼叫前世界必須滿足何種狀態。

11.4 Authorization

哪些主體可在何種情境下使用契約。

11.5 Effect

成功後會改變哪些權威狀態與外部世界。

11.6 Event

成功、拒絕、部分成功或補償後會發布哪些事件。

11.7 Failure

失敗類型及其語意:

11.8 Retry

是否可重試、使用何種冪等身份、何時停止。

11.9 Time

期限、超時、生效時間、資料新鮮度與最大延遲。

11.10 Evidence

什麼證據足以證明契約已履行。

11.11 Version

schema、語意、規則與相容策略。

11.12 Governance

誰能修改契約、如何審查、通知、異議與淘汰。


十二、契約的四個層次

12.1 結構契約

描述資料形狀、型別與必要欄位。

12.2 語意契約

描述欄位與操作在問題世界中的意義。

例如 status = paid 究竟表示:

必須明確。

12.3 操作契約

描述:

12.4 治理契約

描述:

只有四層同時成立,契約才不會只停留在資料格式。


十三、同步互動

13.1 同步請求—回應

上游等待下游立即回覆:

MArequestMBresponseMAM_A \xrightarrow{request} M_B \xrightarrow{response} M_A

13.2 優點

13.3 代價

13.4 同步不代表一致完成

下游回覆成功,可能只表示其內部階段完成。

上游仍須理解回覆的證據層級。

13.5 適用情境

同步較適合:


十四、非同步命令

14.1 形式

MACommandQueueMBM_A \xrightarrow{Command} Queue \xrightarrow{} M_B

發送者不等待最終完成。

14.2 優點

14.3 代價

14.4 接受不等於完成

命令入列只代表:

accepted-for-processing

不代表世界效果已完成。

14.5 命令所有權

發送者對「為何要求」負責。

接收者對「是否接受、如何執行與維持不變量」負責。


十五、事件發布

15.1 形式

MAEvent{MB,MC,MD}M_A \xrightarrow{Event} \left\{ M_B, M_C, M_D \right\}

15.2 發布者責任

發布者必須保證:

15.3 訂閱者責任

訂閱者決定:

15.4 事件不應偽裝成命令

若事件名稱是:

SendEmailNow
UpdateInventoryImmediately

它其實仍在要求特定下游行動。

真正事件應描述已發生事實。

15.5 事件不能逃避責任

發布事件後,原模組不能宣稱:

我已經發事件了,
後面發生什麼不關我的事。

若原目的包含完整工作流,它仍需追蹤整體責任與完成證據。


十六、人工工作流

16.1 人類也是契約參與者

部分決策需要:

16.2 人工節點不是空白

應正式建模:

16.3 人工超時

人類未回覆不是成功,也不一定是拒絕。

需保存:

awaiting-human
human-timeout
escalated
withdrawn

16.4 人機契約

系統應讓人類知道:


十七、時間契約

17.1 契約具有時間

需要說明:

17.2 超時不是單一失敗

超時可能表示:

17.3 結果未知

unknown-outcome 應成為正式狀態,避免盲目重試。

17.4 服務水準不是世界保證

「99.9% 可用」不代表每一項世界效果都正確完成。


十八、版本與相容

18.1 結構相容不等於語意相容

新增可選欄位可能結構相容,但若欄位改變決策語意,仍可能破壞契約。

18.2 契約版本

需版本化:

18.3 生產者與消費者相容

可分別檢查:

18.4 棄用

契約棄用需要:


十九、跨邊界失敗的所有權

19.1 失敗不是自動屬於下游

上游選擇依賴下游,因此不能把所有結果責任全部推給下游。

19.2 三層責任

跨邊界失敗至少包含:

  1. 局部處理責任:哪個模組應修復自己的失敗;
  2. 流程協調責任:誰追蹤整體工作流;
  3. 使用者結果責任:誰向受影響主體解釋、補救與結案。

19.3 失敗吸收

模組可在邊界內吸收:

若失敗影響上游目的,則需對外發布或返回明確狀態。

19.4 失敗升級

需要升級的情境包括:

19.5 失敗所有者

每一重大失敗應具有:

failure:
  local_owner: "payment-module"
  workflow_owner: "order-module"
  user_resolution_owner: "support-process"

二十、委任不等於責任消失

20.1 委任

模組可以將局部執行委任給另一模組、外部服務或 Agent。

20.2 原始責任

若 A 對使用者承諾結果,再把工作委任給 B:

AdelegateBA \xrightarrow{delegate} B

A 仍需對:

負責。

20.3 接受責任

B 則對自己接受的契約、狀態與執行合法性負責。

20.4 責任鏈

CommitmentDelegationExecutionEvidenceAcceptance\text{Commitment} \rightarrow \text{Delegation} \rightarrow \text{Execution} \rightarrow \text{Evidence} \rightarrow \text{Acceptance}

任何斷點都應有責任位置。


二十一、模組拆分方法

本文提出九步模組拆分法。

第一步:列出問題世界責任

不要先列技術層,而是列:

第二步:找出權威狀態

為每項重要狀態指定候選擁有者。

第三步:找出不變量群

將共同維持同一不變量的狀態與行動聚集。

第四步:列出接受行動

哪些外部意圖能進入此邊界。

第五步:列出發布事件

哪些已發生事實對外具有意義。

第六步:列出失敗與補償

誰負責重試、回復、升級與補救。

第七步:建立契約

將輸入、前置條件、權限、效果、證據與時間明示。

第八步:選擇物理部署

在語意邊界清楚後,再決定:

第九步:持續以事故與變更校準

若跨邊界修改頻繁、契約大量洩漏或不變量持續被破壞,邊界需重新調整。


二十二、模組邊界測試

一個候選模組應能回答:

  1. 它為何存在?
  2. 它擁有什麼狀態?
  3. 它維持什麼不變量?
  4. 它接受哪些行動?
  5. 它發布哪些事件?
  6. 它拒絕哪些行動?
  7. 它如何證明成功?
  8. 它承擔哪些失敗?
  9. 它依賴哪些外部模組?
  10. 它明確不保證什麼?
  11. 契約如何版本化?
  12. 誰能修改其規則?

若無法回答,多半只是檔案集合或技術組件,尚未形成完整責任模組。


二十三、模組過小與過大

23.1 過小模組

症狀:

23.2 過大模組

症狀:

23.3 評估原則

模組大小應依:

判定,而不是依程式碼行數。


二十四、團隊邊界與模組邊界

24.1 組織影響架構

團隊溝通結構會影響系統邊界。

24.2 不應直接等同

組織圖可能因預算與人事改變,問題世界責任不應隨意破碎。

24.3 團隊擁有權

每個模組應有明確維護團隊,但一個團隊可維護多個相近模組。

24.4 跨團隊契約

跨團隊邊界需要更強:

24.5 平台團隊

平台團隊應提供共通能力,但不應奪取所有領域狀態與決策權。


二十五、案例一:訂單與付款

25.1 訂單模組

擁有:

25.2 付款模組

擁有:

25.3 互動

訂單模組提出:

AuthorizePayment

付款模組發布:

PaymentAuthorized
PaymentDeclined
PaymentOutcomeUnknown

25.4 責任分離

付款模組不能直接把訂單設為 completed

訂單模組也不能直接修改付款授權狀態。

25.5 流程責任

訂單模組若向客戶承諾購買流程,仍需追蹤付款事件並處理結果,而不能只說「付款是另一個服務」。


二十六、案例二:帳號與權限

26.1 帳號模組

擁有:

26.2 權限模組

擁有:

26.3 邊界

刪除帳號不應由權限模組直接完成。

權限模組可在帳號停用事件後撤銷存取。

26.4 契約

必須定義帳號停用與權限撤銷之間:


二十七、案例三:網站部署

27.1 Release 模組

擁有版本、建置產物與發布候選。

27.2 Deployment 模組

擁有部署工作流、環境狀態、健康檢查與回滾。

27.3 Traffic 模組

擁有流量切換與路由狀態。

27.4 契約鏈

ApproveRelease
→ ReleaseApproved
→ DeployRelease
→ DeploymentVerified
→ ShiftTraffic
→ TrafficShifted

27.5 完成責任

部署模組可證明服務啟動與健康檢查,但產品流程是否符合目的,仍需外部驗收。


二十八、案例四:AI Agent 工具層

28.1 Agent 核心

擁有:

28.2 工具模組

各自擁有:

28.3 權限模組

獨立維持:

28.4 工具結果

工具回傳資料不應直接被 Agent 當成世界完成事件,需依契約轉換成證據與狀態。

28.5 不可逆操作

發布、付款、刪除與寄送等工具需要更高層契約與批准。


二十九、案例五:研究工作流

29.1 文獻模組

擁有來源、引用與閱讀證據。

29.2 命題模組

擁有定義、命題、依賴與證明狀態。

29.3 實驗模組

擁有執行、參數、產物與結果證據。

29.4 出版模組

擁有文件版本、格式、發布與外部識別。

29.5 責任分離

文件發布不應直接把命題標記為已證明。

實驗結果也不應直接修改論文結論,而應發布證據事件供命題模組判定。


三十、案例六:多團隊平台

平台可能包含:

若所有團隊直接共享使用者、內容與權限資料表,會形成巨大隱藏共同模組。

更成熟的結構是:


三十一、主要失敗模式

  1. 資料夾即模組: 檔案放在一起就被視為責任一致。
  2. 服務即邊界: 建立網路服務便假定語意邊界已成立。
  3. 部署即責任: 同時部署的內容被迫共享所有責任。
  4. 類別即領域: 單一類別名稱被當成完整問題世界模組。
  5. 狀態無主: 重要狀態沒有唯一可識別的權威責任者。
  6. 多方直接寫入: 多模組任意修改同一權威狀態。
  7. 共享資料庫免費論: 忽略 schema、權限、不變量與遷移耦合。
  8. 唯讀投影僭位: 快取或查詢投影被拿來作權威判定。
  9. 契約等於 schema: 只有資料形狀,沒有語意、時間與失敗。
  10. 成功語意模糊: 回傳成功卻不說完成到哪一層。
  11. 命令事件混用: 以事件名稱要求下游執行特定命令。
  12. 事件逃責: 發布事件後便放棄整體流程責任。
  13. 同步鏈蔓延: 服務間長鏈呼叫造成故障與延遲放大。
  14. 非同步即解耦: 改用佇列卻未處理重複、亂序與追蹤。
  15. 超時即失敗: 不保留結果未知狀態而盲目重試。
  16. 委任即卸責: 上游把工作交給下游後不再追蹤承諾。
  17. 失敗無流程所有者: 各模組只處理局部錯誤,無人負責使用者結果。
  18. 補償責任不明: 部分成功後無模組決定是否補償。
  19. 契約永久不變: 沒有版本、棄用、遷移與治理。
  20. 結構相容迷思: JSON 可解析就宣稱語意相容。
  21. 模組過小: 不變量被切碎,跨邊界協調成本爆炸。
  22. 模組過大: 無關責任集中,權限與修改範圍失控。
  23. 組織圖即架構: 人事分工被直接固化為世界邊界。
  24. 平台奪取領域: 共通平台集中所有狀態與決策權。
  25. 人工流程空白化: 人類節點沒有期限、證據、狀態與責任。
  26. 非責任未聲明: 模組被迫對無法控制的外部效果作承諾。

三十二、可證偽研究綱領

32.1 狀態擁有者辨識率

測量團隊成員能否一致回答每項關鍵狀態由哪個模組權威維護。

32.2 共享寫入事故率

統計多模組直接寫入同一資料結構造成的:

32.3 契約完整度

對契約十二元結構評分:

CK=declared contract dimensions12C_K = \frac{ |\text{declared contract dimensions}| }{ 12 }

研究完整度與事故率、整合時間、交接成本的關係。

32.4 結構—語意相容差異

統計 schema 驗證通過但實際語意破壞的版本事件。

32.5 同步耦合成本

測量呼叫鏈深度與:

之間的關係。

32.6 非同步追蹤完整率

檢查非同步工作流是否能從原始意圖追蹤到最終事件、狀態與證據。

32.7 事件濫用率

統計名為事件、實際要求特定下游行動的接口比例。

32.8 失敗所有權覆蓋

檢查每類重大失敗是否具有:

32.9 模組交接時間

比較責任與契約明確、以及只依賴檔案結構的專案,新成員理解與接手時間。

32.10 責任圖—依賴圖差異

比較呼叫圖、部署圖與責任圖,研究哪些隱藏責任無法從技術拓撲看出。

32.11 邊界變更率

記錄事故與需求變更中,有多少需要重新調整模組責任,而非只修改內部實作。

32.12 契約版本破壞率

追蹤每次契約更新對既有消費者造成的結構、語意、時間與治理破壞。

32.13 模組大小與變更擴散

研究模組內責任凝聚度、跨模組契約數量與修改影響範圍的關係。

32.14 團隊—模組對齊效應

比較團隊與責任模組較一致、及高度交錯的組織,在交付、事故與知識集中上的差異。


三十三、本文的二十二項命題

  1. 模組是語意責任邊界,不是檔案、套件、程序、服務或部署單元。
  2. 模組必須能說明其問題世界、狀態、不變量、行動、事件、契約、失敗與證據。
  3. 每項關鍵狀態都需要唯一可識別的權威責任者。
  4. 單一責任不要求單一機器或單一資料副本。
  5. 外部模組應透過行動要求狀態擁有者修改權威狀態。
  6. 共同維持同一不變量的狀態與行動,通常應位於相同責任邊界。
  7. 呼叫圖、資料流圖與部署圖不能取代責任圖。
  8. Query、Command、Event、Evidence 與 Shared State 具有不同語意。
  9. Query 原則上不應改變問題世界。
  10. Command 是世界變更請求,Event 是已發生事實。
Shared Write=Shared Invariant Responsibility\boxed{ \text{Shared Write} = \text{Shared Invariant Responsibility} }
  1. 契約不等於函式簽章或資料 schema。
  2. 完整契約必須包含意圖、條件、授權、效果、失敗、時間、證據、版本與治理。
  3. 同步互動造成時間與故障耦合;非同步互動要求顯式處理延遲、重複與最終狀態。
  4. 發布事件不能消除原始承諾與流程責任。
  5. 人類工作流必須具備正式狀態、證據、期限與升級。
  6. 超時可能代表結果未知,而非單純失敗。
  7. 委任局部執行,不會自動消除原始責任。
  8. 跨邊界失敗需要局部、流程與使用者結果三層所有者。
  9. 模組大小應依不變量、狀態生命週期、決策語意與變更方向決定。
  10. 團隊邊界可以承接模組,但不應任意取代問題世界責任。
架構的核心不是把程式拆開,\boxed{ \text{架構的核心不是把程式拆開,} } 而是讓每一項世界責任都有清楚的擁有者,\boxed{ \text{而是讓每一項世界責任都有清楚的擁有者,} } 並讓責任之間只透過可理解、可驗證、\boxed{ \text{並讓責任之間只透過可理解、可驗證、} } 可演化的契約連接。\boxed{ \text{可演化的契約連接。} }

三十四、與前後篇的關係

34.1 承接 PU-1-01

PU-1-01 將程式定義為可執行問題模型。

本篇進一步說明:程式的世界責任不能全部集中在一份來源碼中,而必須形成可識別模組。

34.2 承接 PU-1-02

PU-1-02 建立實體、關係、規則與系統邊界。

本篇把世界邊界轉化為:

34.3 承接 PU-1-03

PU-1-03 區分資料、狀態、事件與行動。

本篇決定:

34.4 銜接 PU-1-05

下一篇將研究如何把責任、狀態、事件、契約、依賴與失敗投影成多種可視結構,讓:

能在不同尺度理解同一系統,而不把所有知識鎖在少數人腦中。


三十五、結論:模組不是切割程式碼,而是承擔世界

程式碼可以依任何方式切割。

可以按語言、檔案類型、功能、框架、部署或團隊分類。

但只有其中一部分切割能形成真正模組。

真正模組必須承擔世界:

因此,模組不是容器,而是承諾。

契約也不是資料格式,而是模組間對世界變化的可驗證承諾。

本文將系統架構收束為:

System Architecture=Responsibility Modules+State Ownership+Explicit Contracts+Failure Ownership\boxed{ \text{System Architecture} = \text{Responsibility Modules} + \text{State Ownership} + \text{Explicit Contracts} + \text{Failure Ownership} }

一個成熟架構不應只回答:

有哪些服務?
它們如何呼叫?
部署在哪裡?

還必須回答:

誰決定這項狀態?
誰維持這條不變量?
誰可以要求改變?
成功究竟代表什麼?
失敗由誰重試、補償與結案?
哪些資料只是投影?
契約改變時誰受影響?
哪一部分世界沒有任何模組負責?

如果這些問題沒有答案,即使系統擁有漂亮的資料夾、微服務、API Gateway 與事件匯流排,也仍可能只是被技術拓撲切碎的責任混合物。

本文的最終命題是:

好的模組,使責任聚合;\boxed{ \text{好的模組,使責任聚合;} } 好的契約,使邊界可穿越;\boxed{ \text{好的契約,使邊界可穿越;} } 好的架構,使世界能改變,\boxed{ \text{好的架構,使世界能改變,} } 卻不讓責任在改變中消失。\boxed{ \text{卻不讓責任在改變中消失。} }

附錄 A:模組描述格式

module:
  module_id: "payment"

  purpose:
    - "maintain payment attempts, authorization, settlement claims, and refunds"

  owned_state:
    - "payment-attempt"
    - "payment-authorization"
    - "refund"

  invariants:
    - "same payment action cannot produce duplicate charge"
    - "refund cannot exceed captured amount"

  accepts:
    commands:
      - "AuthorizePayment"
      - "RefundPayment"

  emits:
    events:
      - "PaymentAuthorized"
      - "PaymentDeclined"
      - "PaymentOutcomeUnknown"
      - "PaymentRefunded"

  failure_ownership:
    local:
      - "provider timeout retry"
      - "duplicate callback deduplication"
    escalates:
      - "unknown settlement outcome"

  evidence:
    - "provider receipt"
    - "idempotency record"

  non_responsibilities:
    - "order fulfillment"
    - "physical delivery"

附錄 B:完整契約格式

contract:
  contract_id: "authorize-payment-v2"
  provider: "payment-module"
  consumer: "order-module"

  intent: "request payment authorization for an order"

  input:
    order_id: "string"
    amount: "money"
    payment_method_ref: "token"
    idempotency_key: "string"

  preconditions:
    - "order is payment-pending"
    - "amount matches authoritative order amount"

  authorization:
    allowed_callers:
      - "order-module"

  effects:
    authoritative:
      - "create or reuse payment attempt"
    external:
      - "request authorization from provider"

  events:
    success:
      - "PaymentAuthorized"
    rejection:
      - "PaymentDeclined"
    uncertain:
      - "PaymentOutcomeUnknown"

  retry:
    safe: true
    identity: "idempotency_key"

  time:
    request_timeout: "10s"
    final_outcome_deadline: "24h"

  evidence:
    required:
      - "provider receipt"

  version:
    schema: "2.0"
    semantics: "2.1"

  governance:
    owner: "payments-team"
    deprecation_notice: "90d"

附錄 C:責任圖邊格式

responsibility_edge:
  from: "order-module"
  to: "payment-module"
  interaction: "command"

  purpose: "authorize payment"
  contract: "authorize-payment-v2"

  upstream_responsibility:
    - "customer purchase workflow"
    - "order completion tracking"

  downstream_responsibility:
    - "payment legality"
    - "provider interaction"
    - "payment evidence"

  failure:
    local_owner: "payment-module"
    workflow_owner: "order-module"
    user_resolution_owner: "support-process"

附錄 D:模組邊界檢查表

問題 必須回答
為何存在 問題世界目的
擁有什麼 權威狀態
保護什麼 不變量
接受什麼 Query/Command
宣告什麼 Event
如何證明 Evidence
如何失敗 Retry/Compensation/Escalation
依賴什麼 外部模組與服務
不保證什麼 Non-responsibility
如何演化 Version/Governance

附錄 E:第 1 冊六篇位置

  1. PU-1-01 程式不等於程式碼:可執行問題模型的基本定義
  2. PU-1-02 問題世界建模:實體、關係、規則與系統邊界
  3. PU-1-03 資料—狀態—事件—行動:程式系統的四元動力結構
  4. PU-1-04 責任、模組與契約:從檔案分類到系統邊界
  5. PU-1-05 可視化作為外部結構記憶:多角色、多尺度的程式理解
  6. PU-1-06 失敗也是程式:驗證、可觀測、恢復與長期維護

參考文獻

Neo.K/EveMissLab 相關理論

  1. Neo.K with Aletheia,《程式不等於程式碼:可執行問題模型的基本定義》,2026。
  2. Neo.K with Aletheia,《問題世界建模:實體、關係、規則與系統邊界》,2026。
  3. Neo.K with Aletheia,《資料—狀態—事件—行動:程式系統的四元動力結構》,2026。
  4. Neo.K with Aletheia,《數位宇宙作為人工存在域:實體、狀態、規則與歷史》,2026。
  5. Neo.K with Aletheia,《Agent Runtime:能力規劃、工具調用與可恢復執行》,2026。
  6. Neo.K with Aletheia,《人類可見狀態:意圖程式系統的稽核、解釋與可逆治理》,2026。

一般理論背景

  1. Parnas, D. L., “On the Criteria To Be Used in Decomposing Systems into Modules,” 1972.
  2. Meyer, B., Object-Oriented Software Construction, 1997.
  3. Evans, E., Domain-Driven Design, 2003.
  4. Fowler, M., Patterns of Enterprise Application Architecture, 2002.
  5. Hoare, C. A. R., “An Axiomatic Basis for Computer Programming,” 1969.
  6. Liskov, B. and Wing, J., “A Behavioral Notion of Subtyping,” 1994.
  7. Gamma, E. et al., Design Patterns, 1994.
  8. Hohpe, G. and Woolf, B., Enterprise Integration Patterns, 2003.
  9. Newman, S., Building Microservices, 2015.
  10. Kleppmann, M., Designing Data-Intensive Applications, 2017.
  11. Conway, M. E., “How Do Committees Invent?”, 1968.
  12. Team Topologies, Skelton, M. and Pais, M., 2019.

版本紀錄

v0.1 — 2026-07-27