← Archive
lm-002095 · 2026-08

04_遞歸閉包積木組合語言_折疊展開引用與再封裝_v0.1

下載 MD 檔 ⬇

遞歸閉包積木組合語言:折疊、展開、引用與再封裝

Recursive Closure Block Composition Language: Collapse, Expansion, Reference, and Re-encapsulation

系列名稱: 遞歸自適應積木組合語言(Recursive Adaptive Block Composition Language, RABCL)
系列編號: EML-RABCL-2026-04
作者: Neo.K(許筌崴)with Aletheia(GPT)
機構: EveMissLab/一言諾科技有限公司
版本: v0.1 基礎理論稿
日期: 2026 年 7 月 30 日
文件定位: 積木語言閉包、結構嵌套、定義/實例分離、引用語義、折疊/展開、版本與再封裝


摘要

前述 RABCL 文件已建立三個基礎:第一,工作流可以在受約束條件下升格為新的高階積木;第二,封裝前必須經過局部靜止、快照、分析、驗證與原子提交;第三,積木不能被簡化成無狀態純函數,而應被描述為具有邊界、端口、契約、狀態、副作用、權限與證據輸出的可契約呼叫單元。

然而,若要使這些積木真正構成一種語言,仍需回答更基本的問題:封裝後的大積木如何再次進入畫布?同一積木在不同位置出現時,是複製、引用還是實例化?展開後修改內部結構,會不會同步改變所有使用者?積木可以包含積木,但能否包含自身?多層封裝如何避免無限展開?版本更新後,既有工作流應追蹤最新版本、固定舊版本,還是建立相容性分支?

本文提出 RABCL 的受約束遞歸閉包模型。令合法積木定義集合為 B\mathfrak B ,合法組合關係為 ComposeOK\operatorname{ComposeOK} ,則閉包條件不是無條件的:

B1,,BnBComposeOK(B1,,Bn)Pack(B1,,Bn)B.B_1,\ldots,B_n\in\mathfrak B \land \operatorname{ComposeOK}(B_1,\ldots,B_n) \Longrightarrow \operatorname{Pack}(B_1,\ldots,B_n)\in\mathfrak B.

這種閉包同時要求型別、契約、效果、權限、版本與治理條件成立。積木的外觀可以被折疊為單一節點,但其權威結構仍保存為可尋址的定義圖;折疊與展開只是同一權威對象的不同投影。本文進一步區分四個核心對象:積木定義、積木版本、積木實例與積木引用。其中定義描述「它是什麼」,版本描述「哪一個不可變修訂」,實例描述「在本次工作流中具有何種狀態」,引用則描述「此處如何找到並約束該定義或版本」。

本文也區分三種不同的遞歸:結構遞歸、執行遞歸與演化遞歸。結構遞歸允許積木包含其他積木;執行遞歸涉及積木在運行時直接或間接呼叫自己;演化遞歸則是 AEREC 對積木實現進行多代生成、驗證與選擇。三者必須分別受控,不能因「積木可嵌套」便推論所有執行遞歸都安全,也不能因版本持續演化便宣稱形成無限計算。

本文最終建立折疊、展開、引用、實例化、內聯、分叉、升版與再封裝八個基本操作,以及回環一致性、邊界保存、無隱藏捕獲、版本可重現、引用可解析與權威單一性六項核心不變量。由此,工作流不再只是被動保存的圖,而能形成一個持續增長、可引用、可驗證、可回滾且可再次組合的局部語言。

關鍵詞: 遞歸閉包、積木語言、工作流、折疊、展開、引用、實例、內容定址、版本、再封裝、RABCL


0. 問題定位

RABCL 的第四個核心問題不是「畫布能不能把幾個節點框起來」,而是:

一個已封裝積木如何成為下一層組合的合法語言基元,同時保留可展開、可修改、可追溯與可回滾的能力?

若缺少明確語義,產品容易落入下列混亂:

  • 折疊只是 UI 隱藏,展開後卻找不到原始結構;
  • 拖入兩個同名積木,修改其中一個卻意外改動另一個;
  • 工作流保存了「最新版本」的模糊指標,日後無法重現;
  • 內部節點被直接複製,導致相同實現散落多份並逐漸漂移;
  • 積木包含積木後,除錯器每次都遞歸展開全部層級;
  • 自我引用與結構嵌套被混為一談,形成不可停止的執行;
  • AI 為了最佳化而修改共用定義,卻未取得所有使用者同意;
  • 視覺圖、執行圖、版本圖與來源圖各自維護,逐漸形成多份真相。

因此,本篇不只定義一種畫布操作,而是建立 RABCL 的語言物件模型


1. 從「大方塊」到語言基元

1.1 大方塊不是像素區域

一個真正的高階積木不能以畫布座標或矩形框作為本體。畫布上的方塊只是投影:

Πcanvas(B)=可視化節點.\Pi_{\mathrm{canvas}}(B) = \text{可視化節點}.

積木本體應是權威結構中的可尋址物件:

B=(I,C,,P,D,V,G,H).B = (I,C,\partial,P^\ast,D,V,G,H).

其中:

  • II :身分與命名資訊;
  • CC :外部契約;
  • \partial :端口、狀態、效果與權限邊界;
  • PP^\ast :權威中介表示;
  • DD :依賴與內部成員;
  • VV :版本與相容性;
  • GG :治理與存取政策;
  • HH :來源、歷史與證據。

方塊可以改變顏色、位置、縮放或是否展開,但這些視覺操作不應自動改變 BB 的語義。

1.2 語言基元的最低資格

一個物件要成為 RABCL 的語言基元,至少應滿足:

Primitive(B)=Named(B)Addressable(B)Contracted(B)Callable(B)Composable(B)Inspectable(B).\operatorname{Primitive}(B) = \operatorname{Named}(B) \land \operatorname{Addressable}(B) \land \operatorname{Contracted}(B) \land \operatorname{Callable}(B) \land \operatorname{Composable}(B) \land \operatorname{Inspectable}(B).

也就是它必須:

  1. 可命名;
  2. 可穩定尋址;
  3. 有明確契約;
  4. 能被 Runtime 呼叫;
  5. 能與其他積木合法組合;
  6. 能在需要時檢查其內部與來源。

只具備「可拖曳」或「可重用」仍不足以成為完整語言基元。


2. 四個不可混淆的核心對象

2.1 積木定義

積木定義描述一個相對穩定的語義身分:

BlockDef=(name,namespace,contract family,governance).\mathsf{BlockDef} = (\text{name},\text{namespace},\text{contract family},\text{governance}).

例如:

eml.media/GenerateValidatedAsset

它回答的是「這是什麼能力」,而不是「目前哪一版實現」或「此次呼叫的狀態」。

2.2 積木版本

版本是某個積木定義的一次不可變修訂:

B(v)=Revision(BlockDef,v).B^{(v)} = \operatorname{Revision}(\mathsf{BlockDef},v).

版本應固定:

  • 契約;
  • 權威結構;
  • 依賴鎖定;
  • 驗證證據;
  • 建構與執行需求;
  • 內容指紋。

一旦發布,版本內容不得就地覆寫。任何語義或實現改動都形成新版本或候選分支。

2.3 積木實例

實例是積木版本在某張工作流中的具體出現:

ιk=Instantiate(B(v),θk,Sk,Lk).\iota_k = \operatorname{Instantiate} (B^{(v)},\theta_k,S_k,L_k).

其中:

  • θk\theta_k :該實例的配置;
  • SkS_k :該實例的局部狀態;
  • LkL_k :該實例在工作流中的局部連線。

同一版本可以有多個實例:

ι1ι2,Def(ι1)=Def(ι2).\iota_1\neq\iota_2, \qquad \operatorname{Def}(\iota_1) = \operatorname{Def}(\iota_2).

兩個實例共享定義與版本,但不必共享運行狀態。

2.4 積木引用

引用不是積木本身,而是找到積木的規則:

ρ=(target,version constraint,resolution policy).\rho = (\text{target},\text{version constraint},\text{resolution policy}).

常見引用可分為:

  • 精確版本引用:固定到 B(1.2.3)B^{(1.2.3)}
  • 內容引用:固定到某一內容雜湊;
  • 相容範圍引用:接受一組契約相容版本;
  • 符號引用:例如 stableapprovedlatest-tested
  • 本地分支引用:指向工作區內尚未發布的候選版本。

引用解析後才得到可執行版本:

Resolve(ρ,Rt)=B(v),\operatorname{Resolve}(\rho,\mathcal R_t) = B^{(v)},

其中 Rt\mathcal R_t 是時間 tt 的註冊表與政策狀態。


3. 定義圖與實例圖的分離

3.1 為何需要兩張圖

RABCL 至少需要區分:

GD=(VD,ED),G_D=(V_D,E_D),

以及:

GI=(VI,EI).G_I=(V_I,E_I).

其中:

  • GDG_D :積木定義與版本之間的依賴圖;
  • GIG_I :某次工作流中的積木實例與資料/控制連線圖。

若不區分兩者,使用者刪除畫布實例可能誤刪全域定義;修改定義則可能被誤解成只調整單一節點。

3.2 定義圖的基本要求

定義圖應保存:

  • 積木版本依賴哪些版本;
  • 依賴是內嵌、動態載入還是能力需求;
  • 契約與版本約束;
  • 來源與驗證鏈;
  • 是否存在循環依賴。

在最小 MVP 中,定義依賴圖應優先限制為有向無環圖:

DAG(GD)=.\operatorname{DAG}(G_D)=\top.

這不是宣稱所有合法軟體架構都必須無環,而是為了讓初版的建構、版本解析、快取、展開與垃圾回收保持可控。

3.3 實例圖可以具有執行循環

工作流本身可能含有:

  • 重試;
  • 迴圈;
  • 回饋;
  • 狀態機轉移;
  • 事件等待;
  • 遞歸呼叫。

因此 GIG_I 不必是 DAG。但循環必須具有明確的控制語義:

Cycle(GI)GuardedBoundedExternallyTerminated.\operatorname{Cycle}(G_I) \Longrightarrow \operatorname{Guarded} \lor \operatorname{Bounded} \lor \operatorname{ExternallyTerminated}.

換言之,結構上出現回邊不等於錯誤,但不能只靠一條視覺連線隱含無限循環。


4. 折疊與展開

4.1 折疊不是刪除

折疊操作為:

Collapse:(P,σ)(ΠB,σ),\mathsf{Collapse}: (P^\ast,\sigma) \rightarrow (\Pi_B,\sigma'),

其中:

  • PP^\ast :權威結構;
  • σ\sigma :原操作狀態;
  • ΠB\Pi_B :單一積木投影;
  • σ\sigma' :保存折疊資訊後的操作狀態。

折疊只改變視圖與操作粒度,不應刪除內部結構,也不應將所有內部節點序列化成無法再解析的黑盒字串。

4.2 展開是受控投影

展開操作為:

Expand(B(v),d,m)Πd,m(P),\mathsf{Expand}(B^{(v)},d,m) \rightarrow \Pi_{d,m}(P^\ast),

其中:

  • dd :展開深度;
  • mm :展開模式。

模式至少包括:

  • 唯讀展開:檢查內部但不可修改;
  • 實例展開:查看該實例的配置與狀態;
  • 候選分支展開:建立可編輯草稿;
  • 除錯展開:顯示 Trace、狀態與效果;
  • 來源展開:查看版本、依賴與證據。

因此,展開不等於取得共用定義的直接寫入權。

4.3 往返一致性

若沒有修改,積木經展開與重新折疊後應保持語義一致:

Collapse(Expand(B(v)))CB(v).\mathsf{Collapse} (\mathsf{Expand}(B^{(v)})) \equiv_C B^{(v)}.

其中 C\equiv_C 表示相對於外部契約 CC 的一致,而不要求畫布座標、折疊狀態或註解完全相同。

4.4 有損與無損展開

某些積木可能只有:

  • 外部契約;
  • 已編譯工件;
  • 來源摘要;
  • 不完整或受保護的內部表示。

因此應標示:

Expandability(B){full,partial,opaque}.\operatorname{Expandability}(B) \in \{ \text{full}, \text{partial}, \text{opaque} \}.

只有 full 積木能保證完整往返;partial 可展開到允許的抽象層;opaque 則只能顯示契約與證據,不能假裝可還原全部內部。


5. 引用、複製與實例化

5.1 拖入畫布預設應是實例化

當使用者將既有積木拖入畫布時,預設操作應是:

Drag(B(v))Instantiate(B(v)),\operatorname{Drag}(B^{(v)}) \Rightarrow \operatorname{Instantiate}(B^{(v)}),

而不是複製整份積木定義。

這可避免每次使用都產生一份逐漸漂移的內部副本。

5.2 複製實例

複製實例表示:

CloneInstance(ι1)=ι2,\operatorname{CloneInstance}(\iota_1) = \iota_2,

並滿足:

Version(ι1)=Version(ι2).\operatorname{Version}(\iota_1) = \operatorname{Version}(\iota_2).

配置可以選擇複製,運行狀態通常不應默認複製,尤其是:

  • 憑證;
  • 鎖;
  • 長期任務游標;
  • 交易狀態;
  • 外部資源所有權。

5.3 分叉定義

若使用者希望改造積木內部並保留獨立演化路徑,應執行:

ForkDef(B(v),N)=B~(0.1.0).\operatorname{ForkDef} (B^{(v)},N') = \widetilde B^{(0.1.0)}.

新定義保留來源:

Origin(B~)=B(v),\operatorname{Origin}(\widetilde B) = B^{(v)},

但具有新的命名空間、治理權與版本序列。

5.4 內聯

內聯操作將引用的積木版本展開並嵌入當前候選圖:

Inline(ρ)Pembedded.\operatorname{Inline}(\rho) \rightarrow P^\ast_{\mathrm{embedded}}.

內聯後,該結構不再自動追蹤原積木更新。這適合:

  • 需要深度修改;
  • 要消除 Runtime 呼叫邊界;
  • 要產生獨立、可離線部署的工件;
  • 需要將依賴固定進封裝內。

但內聯會提高重複、漂移與安全修補遺漏風險,因此必須保存來源指紋。

5.5 引用優先、複製例外

RABCL 的預設原則應是:

Reference by default, copy only by explicit intent.\boxed{ \text{Reference by default, copy only by explicit intent.} }

中文可表述為:預設引用,明確分叉;預設實例化,不默認複製定義。


6. 三種遞歸必須分離

6.1 結構遞歸

結構遞歸表示積木可以包含積木:

Bk=Pack(B1,,Bn).B_k = \operatorname{Pack} (B_1,\ldots,B_n).

這是 RABCL 最基本的高階組合能力。

只要每層封裝都有有限權威表示,結構深度雖可增長,任何具體版本仍是有限物件:

B(v),P(B(v))<.\forall B^{(v)}, \quad |P^\ast(B^{(v)})|<\infty.

6.2 執行遞歸

執行遞歸表示積木在 Runtime 直接或間接呼叫自身:

BB,B\rightarrow B,

或:

B1B2B1.B_1\rightarrow B_2\rightarrow\cdots\rightarrow B_1.

這與結構嵌套不同。執行遞歸必須具備:

  • 終止條件;
  • 深度或資源預算;
  • 重入政策;
  • 狀態隔離;
  • 取消與逾時;
  • Trace 關聯。

最低安全要求可表示為:

RecursiveCall(B)Budget(B)<ExternalStop(B).\operatorname{RecursiveCall}(B) \Longrightarrow \operatorname{Budget}(B)<\infty \lor \operatorname{ExternalStop}(B).

6.3 演化遞歸

演化遞歸表示 AEREC 對積木實現進行多代變換:

B(v,0)B(v,1)B(v,n).B^{(v,0)} \rightarrow B^{(v,1)} \rightarrow \cdots \rightarrow B^{(v,n)}.

它不是積木在同一次執行中呼叫自身,而是版本或候選實現的跨代生成。

演化遞歸需要:

  • 契約錨定;
  • 每代證據;
  • 選擇函數;
  • 負知識;
  • 停止準則;
  • 回滾路徑。

6.4 三者的正交表示

可以定義積木的遞歸向量:

r(B)=(rs,rx,re),\mathbf r(B) = (r_s,r_x,r_e),

其中:

  • rsr_s :結構遞歸深度;
  • rxr_x :執行遞歸特性;
  • rer_e :演化代數或演化深度。

一個積木可以具有深層結構嵌套,卻完全沒有執行遞歸;也可以結構很簡單,卻在 Runtime 中執行遞歸演算法。這三者不能再以單一「遞歸」標籤混合描述。


7. 受約束遞歸閉包

7.1 閉包算子

令合法積木集合為 B\mathfrak B ,封裝算子為:

P:Bn×W×QB{},\mathcal P: \mathfrak B^n \times \mathcal W \times \mathcal Q \rightarrow \mathfrak B\cup\{\bot\},

其中:

  • W\mathcal W :連線與工作流結構;
  • Q\mathcal Q :契約、權限、版本與治理條件;
  • \bot :封裝失敗或拒絕。

只有當:

TypeOKContractOKEffectOKPermissionOKVersionOKGovernanceOK\operatorname{TypeOK} \land \operatorname{ContractOK} \land \operatorname{EffectOK} \land \operatorname{PermissionOK} \land \operatorname{VersionOK} \land \operatorname{GovernanceOK}

全部成立,才有:

P(B1,,Bn;W,Q)B.\mathcal P(B_1,\ldots,B_n;\mathcal W,\mathcal Q) \in \mathfrak B.

7.2 相對閉包

閉包永遠相對於某個環境與政策:

BΓ,P,t.\mathfrak B_{\Gamma,P,t}.

同一組積木可能在開發環境可合法組合,在生產環境卻因權限、資料區域或模型政策而不可部署。

因此:

Closed(BΓ1,P1)⇏Closed(BΓ2,P2).\operatorname{Closed} (\mathfrak B_{\Gamma_1,P_1}) \not\Rightarrow \operatorname{Closed} (\mathfrak B_{\Gamma_2,P_2}).

RABCL 的閉包不是宇宙性的代數閉包,而是工程與治理條件下的可組合閉包。

7.3 封裝不保證純化

將多個有副作用積木封裝成大積木,不會自動消除副作用:

E(Pack(B1,,Bn))i=1nE(Bi)Einternalized.\mathcal E (\operatorname{Pack}(B_1,\ldots,B_n)) \supseteq \bigcup_{i=1}^{n}\mathcal E(B_i) - \mathcal E_{\mathrm{internalized}}.

只有已被封裝內部完全吸收、不再外顯的效果,才可從外部契約中隱藏。網路存取、檔案寫入、付費 API、資料庫交易與人工審批仍須顯式保留。


8. 八個基本語言操作

RABCL v0.1 的語言操作可先固定為八個:

8.1 collapse

將展開工作流投影為單一積木節點,不改變權威語義。

8.2 expand

按深度、權限與模式查看積木內部。

8.3 reference

建立對積木定義或版本的受約束引用。

8.4 instantiate

在工作流中建立具有局部配置與狀態的積木實例。

8.5 inline

將引用版本內嵌至候選結構,切斷自動升版關係。

8.6 fork

從既有版本建立新的獨立積木定義與演化線。

8.7 revise

對同一積木定義建立新版本,不覆寫舊版本。

8.8 repack

將已修改或重新組合的候選圖,經 EQB、契約推斷與驗證後,再次提交為積木版本。

可以用簡化語法表示:

block eml.media/GenerateValidatedAsset@1.0.0 {
  import image.source@1
  import model.generate@2
  import quality.validate@1

  export generateValidatedAsset

  compose {
    source -> generate -> validate
    validate.reject -> generate.retry
    validate.accept -> output
  }
}

這段語法的重點不在具體字面格式,而是明示:

  • 使用的是哪些積木與版本;
  • 哪些能力被導入;
  • 哪些接口被導出;
  • 內部如何連線;
  • 哪些內部能力被封裝後不再外露。

9. 身分、版本與內容定址

9.1 四層識別

RABCL 不應只使用一個 id 欄位承擔所有語義。至少需要:

I(B)=(Idef,Iver,Icontent,Iinst).I(B) = (I_{\mathrm{def}},I_{\mathrm{ver}},I_{\mathrm{content}},I_{\mathrm{inst}}).

其中:

  • IdefI_{\mathrm{def}} :積木定義身分;
  • IverI_{\mathrm{ver}} :語義版本身分;
  • IcontentI_{\mathrm{content}} :不可變內容指紋;
  • IinstI_{\mathrm{inst}} :工作流實例身分。

9.2 內容指紋

可定義:

Icontent=H(P,C,Dlocked,Qbuild),I_{\mathrm{content}} = H ( P^\ast, C, D_{\mathrm{locked}}, Q_{\mathrm{build}} ),

其中:

  • HH :密碼雜湊;
  • PP^\ast :規範化權威表示;
  • CC :契約;
  • DlockedD_{\mathrm{locked}} :鎖定依賴;
  • QbuildQ_{\mathrm{build}} :會影響工件的建構條件。

相同內容應得到相同內容識別;內容一旦改變,指紋必須改變。

9.3 符號引用與不可變內容分離

stableapprovedlatest-tested 等符號引用可以移動,但其所指向的內容版本不可變:

Reft1(stable)=B(1.2),\operatorname{Ref}_{t_1}(\texttt{stable}) =B^{(1.2)}, Reft2(stable)=B(1.3).\operatorname{Ref}_{t_2}(\texttt{stable}) =B^{(1.3)}.

工作流發布時,應將符號引用解析並鎖定:

Lock(ρsymbolic)=(Iver,Icontent).\operatorname{Lock}(\rho_{\mathrm{symbolic}}) = (I_{\mathrm{ver}},I_{\mathrm{content}}).

如此才能兼顧易用的名稱與可重現的執行。

9.4 依賴閉包指紋

積木的可重現性不只取決於自身內容,也取決於完整依賴閉包:

Hclosure(B)=H(Icontent(B),{Hclosure(Di)}).H_{\mathrm{closure}}(B) = H \left( I_{\mathrm{content}}(B), \{H_{\mathrm{closure}}(D_i)\} \right).

這允許系統判斷兩個表面相同的積木是否實際依賴不同模型、工具或 Runtime。


10. 版本相容性不是只看版本號

10.1 契約指紋

對外契約可產生規範化指紋:

HC(B)=H(Normalize(CB)).H_C(B) = H ( \operatorname{Normalize}(C_B) ).

版本更新時,系統比較:

  • 輸入是否擴張或收縮;
  • 輸出是否改型;
  • 新增或刪除哪些效果;
  • 權限是否升級;
  • 錯誤集合是否改變;
  • 狀態遷移是否相容;
  • 資源上限是否改變。

10.2 相容關係

可定義:

B(v2)CB(v1),B^{(v_2)} \preceq_C B^{(v_1)},

表示 v2v_2 可在所有依賴 v1v_1 契約的合法位置安全替換 v1v_1

這比「主版本號沒變,所以應該相容」更精確。

10.3 自動升版條件

只有在:

ContractCompatibleEffectNonEscalatingPermissionNonEscalatingTestsPassPolicyAllows\operatorname{ContractCompatible} \land \operatorname{EffectNonEscalating} \land \operatorname{PermissionNonEscalating} \land \operatorname{TestsPass} \land \operatorname{PolicyAllows}

成立時,系統才可建議或自動進行版本替換。

若新增網路、檔案、付費服務或更高資料權限,即使輸入輸出型別未變,也不應視為無害的小版本更新。


11. 再封裝的正式程序

11.1 再封裝不是保存按鈕

當積木被展開並修改後,不能直接覆寫原版本。正確程序為:

B(v)ExpandPvEditP~EQBP~qInfer+ValidateB~CommitB(v+1).B^{(v)} \xrightarrow{\mathsf{Expand}} P^\ast_v \xrightarrow{\mathsf{Edit}} \widetilde P \xrightarrow{\mathsf{EQB}} \widetilde P_q \xrightarrow{\mathsf{Infer+Validate}} \widetilde B \xrightarrow{\mathsf{Commit}} B^{(v+1)}.

11.2 變更分類

再封裝前應判定:

Δ=(ΔC,ΔE,ΔP,ΔS,ΔD,ΔI),\Delta = (\Delta_C,\Delta_E,\Delta_P,\Delta_S,\Delta_D,\Delta_I),

其中:

  • ΔC\Delta_C :契約變更;
  • ΔE\Delta_E :效果變更;
  • ΔP\Delta_P :權限變更;
  • ΔS\Delta_S :狀態模型變更;
  • ΔD\Delta_D :依賴變更;
  • ΔI\Delta_I :內部實現變更。

若只有 ΔI\Delta_I 且外部契約與效果不變,可形成實現修訂或 AEREC 候選。若 ΔC\Delta_CΔE\Delta_EΔP\Delta_P 發生不相容改動,則必須形成新語義版本,甚至新積木定義。

11.3 再封裝輸出

一次成功再封裝至少產生:

  • 新版本清單;
  • 新權威結構;
  • 契約與效果差異;
  • 鎖定依賴;
  • 測試與驗證報告;
  • 遷移建議;
  • 回滾目標;
  • 內容與閉包指紋。

12. 六項核心不變量

12.1 往返不變量

無修改的展開與折疊應保持契約語義:

Collapse(Expand(B))CB.\mathsf{Collapse} (\mathsf{Expand}(B)) \equiv_C B.

12.2 邊界保存不變量

折疊後所有外部可觀測的輸入、輸出、狀態、效果、錯誤與權限必須仍可由積木邊界表達:

Obsexternal(P)=Obsexternal(B).\operatorname{Obs}_{\mathrm{external}} (P^\ast) = \operatorname{Obs}_{\mathrm{external}} (B).

12.3 無隱藏捕獲不變量

封裝不得偷偷捕獲畫布外變數、未宣告工具、環境祕密或全域狀態:

FreeDeps(P)DeclaredImports(B).\operatorname{FreeDeps}(P^\ast) \subseteq \operatorname{DeclaredImports}(B).

12.4 版本可重現不變量

精確版本與內容指紋應解析到同一不可變結構:

Resolve(Iver,Icontent)=P.\operatorname{Resolve} (I_{\mathrm{ver}},I_{\mathrm{content}}) =P^\ast.

12.5 引用可解析不變量

所有可發布工作流中的引用都必須能在部署前解析,或被明確標示為由 Runtime/Host 提供的能力:

ρR,Resolved(ρ)HostProvided(ρ).\forall \rho\in R, \quad \operatorname{Resolved}(\rho) \lor \operatorname{HostProvided}(\rho).

12.6 權威單一性不變量

畫布、文字 DSL、狀態機視圖、執行計畫與除錯視圖只能是投影:

Π1(P),Π2(P),,Πn(P).\Pi_1(P^\ast), \Pi_2(P^\ast), \ldots, \Pi_n(P^\ast).

不能各自成為獨立真相來源。


13. AI 在遞歸組合語言中的角色

13.1 AI 可以提出的操作

AI 可協助:

  • 辨識可封裝子圖;
  • 建議積木名稱與命名空間;
  • 推斷端口與契約;
  • 判斷引用或內聯較合適;
  • 偵測重複積木與可共用定義;
  • 生成折疊後摘要;
  • 比較版本與契約差異;
  • 建議分叉、升版或保持鎖定;
  • 推斷最佳展開深度;
  • 發現循環依賴與隱藏捕獲;
  • 生成再封裝候選。

13.2 AI 不應單獨決定的操作

AI 不應在無政策與驗證條件下:

  • 修改共用積木的已發布版本;
  • 將符號引用自動升級到權限更高版本;
  • 把引用悄悄改成內聯;
  • 複製機密狀態到新實例;
  • 將不可逆副作用隱藏進封裝;
  • 自動解除依賴鎖定;
  • 將執行循環誤判為結構嵌套;
  • 無限制展開或遞歸執行。

13.3 提案與提交分離

AI 生成的操作先形成提案:

O~=ProposeAI(O,P,C,Q).\widetilde O = \operatorname{Propose}_{AI} (O,P^\ast,C,Q).

只有在驗證與政策通過後:

Commit(O~)=O.\operatorname{Commit}(\widetilde O) =O'.

這延續 RABCL 前三篇的基本原則:AI 可以提出結構,但不能跳過權威提交與治理邊界。


14. 與現有元件與內容定址思想的關係

WebAssembly Component Model 已展示一個重要工程事實:具有機器可讀 import/export 介面的元件,可以被組合為新的元件;組合後,已被滿足的依賴可成為內部實現細節,而未滿足的依賴繼續暴露為新元件的 import。其元件也可以嵌套其他元件,並透過介面檢查判定組合是否成立。RABCL 接受這種「介面驅動組合後仍為同類元件」的方向,但把範圍擴大到視覺工作流、狀態、效果、權限、來源、AI 推斷與可逆展開。

Git 的物件與引用機制則說明了不可變內容與可移動名稱可以分離:內容物件由內容定址,符號引用則提供人類可讀、可更新的入口。IPFS 的 Merkle DAG 也展示內容識別與圖形關係可以共同形成可驗證的物件結構。RABCL 不需要複製 Git 或 IPFS 的全部架構,但可借用兩個原則:

  1. 已發布積木版本應具有不可變內容指紋;
  2. stableapproved 等可移動名稱只能是引用,不能把其當成可重現版本本身。

因此,RABCL 的積木可以同時具有語義名稱、版本名稱、內容指紋與工作流實例識別,而不再把所有身分壓縮到一個可變 ID。


15. 常見失敗模式

15.1 展開即修改共用定義

使用者只是為了查看內部而展開,卻因拖動節點直接改變所有引用者。解法是唯讀展開與候選分支分離。

15.2 拖入即複製

每次使用積木都複製全部內部內容,造成修補與升版無法同步。解法是預設實例化與引用,只有明確內聯或分叉才複製結構。

15.3 latest 污染可重現性

工作流只保存 latest,數週後重跑得到不同結果。解法是編輯期可使用符號引用,提交與部署時必須解析為精確版本與內容指紋。

15.4 版本號相容假象

僅依賴主次版本號,忽略新增權限、副作用或資料外流。解法是加入契約、效果與權限差異檢查。

15.5 結構遞歸誤當執行遞歸

積木包含自己的舊版本或同族元件,不代表 Runtime 必須無限自我呼叫。解法是分離定義依賴圖與實例執行圖。

15.6 無限制全展開

除錯器展開所有子積木與依賴,造成認知與計算爆炸。解法是深度限制、按需載入與摘要視圖。

15.7 隱藏能力捕獲

封裝後積木表面只有一個輸入輸出,內部卻偷偷使用網路、檔案、祕密或付費模型。解法是自由依賴掃描與能力 import 顯式化。

15.8 自我引用版本環

新版本依賴符號 stable,而 stable 又更新指向新版本自身,形成解析循環。解法是發布時鎖定不可變版本,禁止內容閉包中的未解析自指符號。


16. MVP 前置資料結構

本篇仍不開始實作,但可以先鎖定最小資料物件:

block_definition:
  id: eml.media/GenerateValidatedAsset
  title: Generate Validated Asset
  namespace: eml.media

block_version:
  version: 1.0.0
  content_hash: sha256:...
  contract_hash: sha256:...
  closure_hash: sha256:...
  authority_ir: cair://objects/...
  expandability: full

imports:
  - ref: eml.media/ImageSource@1.1.0
    content_hash: sha256:...
    mode: reference
  - ref: eml.model/GenerateImage@2.0.3
    content_hash: sha256:...
    mode: reference

exports:
  - interface: generate-validated-asset

instances:
  state_policy: isolated
  config_schema: schema://...

recursion:
  structural_depth: 2
  runtime_recursion: guarded
  max_call_depth: 8

provenance:
  parent_version: null
  source_workflow: workflow://...
  validation_certificate: cert://...

MVP 的初始限制可以是:

  • 定義依賴圖必須為 DAG;
  • 不支援直接自我依賴;
  • 執行循環必須使用顯式迴圈或狀態機節點;
  • 發布版本不可變;
  • 拖入預設建立實例;
  • 編輯共用積木必須建立候選分支;
  • 部署時鎖定精確版本與內容指紋;
  • 展開深度預設為一層;
  • 只有 full 積木支援完整往返編輯;
  • opaque 積木僅顯示契約、來源與證書。

17. 主要命題

命題一:同類組合命題

合法積木在組合條件成立時,封裝結果仍是合法積木,而不是另一種不可再組合的特殊物件。

命題二:定義/實例分離命題

積木定義與工作流實例必須具有不同身分、版本與狀態生命週期。

命題三:折疊非刪除命題

折疊只改變投影與操作粒度,不得破壞權威內部結構與來源鏈。

命題四:展開非寫入命題

查看積木內部不等於取得修改已發布共用定義的權限。

命題五:引用優先命題

積木重用應預設透過引用與實例化完成;複製定義、內聯與分叉必須是明確操作。

命題六:不可變版本命題

已發布積木版本與其內容指紋不得就地覆寫,任何改動都形成新候選或新版本。

命題七:遞歸分離命題

結構遞歸、執行遞歸與演化遞歸是三種不同機制,必須分別建模與治理。

命題八:相對閉包命題

RABCL 的閉包只在型別、契約、效果、權限、版本、環境與治理條件下成立。

命題九:再封裝事務命題

展開後的修改不能直接覆寫權威版本,必須重新經過靜止、差異分析、驗證與原子提交。

命題十:局部語言增長命題

每次成功封裝都可為命名空間增加新的語言基元,但新基元必須納入引用、版本、來源與相容性治理。


18. 理論邊界

本文不主張:

  • 所有工作流都能形成合法積木;
  • 所有積木都可完整展開為原始碼;
  • 結構嵌套可無限免費展開;
  • 內容雜湊本身能證明語義正確;
  • 版本號可以取代契約與效果驗證;
  • 自我引用天然安全;
  • 遞歸封裝突破圖靈可計算性;
  • 局部語言增長等同模型獲得自主主權;
  • AI 可以在無審核下修改共用積木與生產依賴;
  • 初版 MVP 應支援任意循環依賴與跨組織自動升版。

本文只主張:

工作流可被封裝成積木;積木可作為下一層工作流的合法成員;合法組合可再次封裝成同類高階積木;此過程必須由明確的定義、版本、實例、引用與治理語義約束。\boxed{ \begin{aligned} &\text{工作流可被封裝成積木;}\\ &\text{積木可作為下一層工作流的合法成員;}\\ &\text{合法組合可再次封裝成同類高階積木;}\\ &\text{此過程必須由明確的定義、版本、實例、引用與治理語義約束。} \end{aligned} }

19. 結論

RABCL 所謂的「積木組合語言」不能只停留在視覺上把幾個節點框成一個大方塊。真正的語言化要求:大方塊必須成為可命名、可尋址、可契約、可版本化、可實例化、可展開、可引用、可再次封裝的一級計算物件。

其基本循環為:

積木引用工作流實例化合法組合封裝新積木版本再次引用\boxed{ \text{積木引用} \rightarrow \text{工作流實例化} \rightarrow \text{合法組合} \rightarrow \text{封裝} \rightarrow \text{新積木版本} \rightarrow \text{再次引用} }

而其雙向操作為:

展開態封裝態\boxed{ \text{展開態} \rightleftarrows \text{封裝態} }

其遞歸性則不是無條件的「任何東西都能包任何東西」,而是:

有限權威結構+顯式接口+鎖定依賴+受控引用+可驗證再封裝=受約束遞歸閉包\boxed{ \text{有限權威結構} + \text{顯式接口} + \text{鎖定依賴} + \text{受控引用} + \text{可驗證再封裝} = \text{受約束遞歸閉包} }

一旦這些概念成立,工作流工具就不再只是固定節點庫的使用介面。人類與 AI 可以在實際工作中,把已完成、已驗證的計算結構提升為新的語言基元,再用這些新基元構造更高階工作流。語言因此不再只由平台開發者預先寫死,而能在可治理、可追溯與可回滾的前提下,隨使用過程逐步增長。

下一篇將處理這些積木如何同時存在於格子語言操作表面、CAIR 權威結構、MSSP 描述索引與 RDR 執行派發之中,並避免四個層次各自維護一份互相漂移的系統真相。


參考資料

  1. Bytecode Alliance, WebAssembly Component Model — Components. https://component-model.bytecodealliance.org/design/components.html
  2. Bytecode Alliance, WebAssembly Component Model — Composing Components. https://component-model.bytecodealliance.org/composing-and-distributing/composing.html
  3. Bytecode Alliance, WebAssembly Component Model — Interfaces. https://component-model.bytecodealliance.org/design/interfaces.html
  4. Bytecode Alliance, WebAssembly Component Model — Worlds. https://component-model.bytecodealliance.org/design/worlds.html
  5. Git Project, Pro Git — Git Objects. https://git-scm.com/book/en/v2/Git-Internals-Git-Objects
  6. Git Project, Pro Git — Git References. https://git-scm.com/book/en/v2/Git-Internals-Git-References
  7. IPFS Docs, Merkle Directed Acyclic Graphs. https://docs.ipfs.tech/concepts/merkle-dag/
  8. IPFS Docs, Content Identifiers. https://docs.ipfs.tech/concepts/content-addressing/