Skip to content

Latest commit

 

History

History
278 lines (197 loc) · 18 KB

principles.md

File metadata and controls

278 lines (197 loc) · 18 KB

原則

唯一真實,各式投影。 解構語法之散,重塑形態之模。

根公理

程式的本質不是程式碼,也不是積木——它們都是投影。

程式是由「元件節點」和「關係邊」組成的語義結構:在檔案內是樹,在檔案間是圖,在系統間是超圖。每個節點 =(元件身分, 屬性, 子節點),每條邊 =(關係類型, 來源, 目標)。

🔴 措辭變更(2026-08-20,人拍板):「概念節點/概念身分」→「元件節點/元件身分」。

⚠️ 這一行 2026-08-31 修過一次,而它壞掉的方式值得記:箭頭左邊原本也是 「元件節點/元件身分」——那次全域改名把這條記錄自己也改掉了,於是 一條寫著「A 改成 B」的句子變成「B 改成 B」。判官掃「箭頭兩邊相同」時抓到, 依 history/109 第 8 行 「協定的名詞統一成「元件」,概念 從詞彙裡退場」還原。

一次全域改名會掃過「記錄這次改名的那句話」—— 而那句話是唯一還知道舊名字的東西。

根公理的 churn 應趨近零,所以這一次的理由要留下: concepts/元件.md 的名詞表(跨域唯一)早就定案 componentId 取代 conceptId, 而它自己標著「採用這張表意味著根公理的措辭要跟著動……此事 MUST 由人拍板, 不得順手改」。使用者 2026-08-20 拍板。

為什麼:硬體要加進來,而**「概念」對硬體讀不通** ——「電阻是一顆元件」讀得通,「電阻是一個概念」讀不通。

一個詞如果在協定要涵蓋的範圍裡有一半讀不通,那它不是統一詞彙的候選人。

⚠️ 變的是措辭,不是公理:節點仍然是(身分, 屬性, 子節點), 投影仍然是投影。轉變見 history/109。

「x++;」              ← 文字投影(程式碼)
[變數 x 加1(++)]     ← 視覺投影(積木)
 x: 0→1               ← 【不是投影】——見下

🔴 2026-08-31 修正一個放錯的分類標籤:第三行原本寫「行為投影(執行追蹤)」。 執行追蹤不是投影,是三維錨定裡「情境(Data)」的觀測。

按 P1 自己的公式 view = project(structure, scope, viewType, viewParams)——那是一個 純函數,而追蹤需要「結構以外的輸入」才算得出來。

語義樹決定的是一個【函數】,不是一個值。 投影是把那個函數換一種寫法(資訊量相同); 執行是把它用掉一次,而產出一半來自世界。

⚠️ 變的是一個例子的標籤,不是公理:節點仍然是(身分, 屬性, 子節點), 投影仍然是投影,x: 0→1 仍然看得到——它只是換了一個正確的抽屜。 轉變與四項回溯驗證見 history/198。

從根公理直接推導三件事:

  • 語義結構是唯一真實(唯一的權威表示)
  • 所有投影都是衍生的、可重建的——投影的種類是開放集合
  • 節點的元件身分和屬性是語義,投影方式是呈現(語義與呈現分離)

tree-sitter 產生的 AST 是 parser 的中間產物,接近但不等於語義結構。從 AST 到語義結構的過程稱為 lift()。

衍生原則

前四條(P1-P4)從根公理直接推導,是開放集合——允許追加新原則,只要能從根公理推導且與現有原則正交。後五條是工程與教育學的定錨。

1. P1 投影定理

推導自:根公理(所有表示都是投影)

語義結構有多種表示,每種是一個參數化投影:view = project(structure, scope, viewType, viewParams)。可逆性依投影種類分級(R0 雙射 → R4 單向),而非二分。

如何應用:R0-R1 是可編輯視圖,roundtrip 是判定標準;R2-R4 是唯讀視圖,不需 roundtrip 但需保證投影完整性(不遺漏節點)。詳見 投影。

2. P2 元件代數

推導自:根公理(節點的元件身分是語義)

元件不是散落的集合,而是有結構的代數系統:可分層、可組合、可映射。每顆元件在 ComponentRegistry 中有唯一條目,且必須路徑完備。

如何應用:新增任何元件的第一步就是在 registry 註冊,再寫其他程式碼。缺任一條路徑 = coverage gap = 架構缺陷(0 容忍)。詳見 元件代數。

3. P3 開放擴充

推導自:根公理(投影種類是開放集合)+ P2(元件可分層)

系統可以在不修改既有程式碼的前提下加入新元件、新語言、新套件。核心引擎只有一條管線。

如何應用:擴充走 Layer 1(純 JSON,~80%)→ Layer 2(具名 transform,~15%)→ Layer 3(具名 strategy,~5%)。新增 pattern 不得改變既有 pattern 的匹配結果——歧義在註冊時仲裁,不在執行時碰運氣。詳見 開放擴充。

4. P4 漸進揭露

推導自:根公理(語義與呈現分離)+ 認知鷹架

同一個語義結構,在不同認知維度顯示不同的元件子集和結構範圍。

這是過濾(filtering),不是簡化(simplification)——語義結構始終完整,只是投影時隱藏超出層級的節點。

如何應用:可見集合 = f(Topic, 元件層級, View Params)。層級切換只增不減,已建立的心智模型不被破壞。詳見 漸進揭露。

⚠️ 2026-08-13 修訂兩處,理由見 history/053。

① 過濾機制必須連同「過濾條件的來源」一起設計。

原文只說了 f 長什麼樣,沒有說那三個參數誰來決定。而在真實教室裡, 決定它的是老師——面對 9 個可選節點 = 512 種組合而沒有依據。

漸進揭露為學生減少選項,而它把那些選項轉嫁給了老師。

於是老師的理性選擇是「全部打勾」,而那讓整個機制形同虛設 (使用者原話:「我會乾脆叫學生把全部都打勾,那有沒有這個漸進揭露是沒用的」)。

→ 一個過濾機制若沒有附帶「條件從哪來」,它把認知負荷搬家而不是減少。 而那個來源今天缺的是教材——見 draft/漸進揭露把選項轉嫁給了老師。

② 三個維度正交不可混用 → 收回一個軸,另外兩個仍成立。

⚠️ 這一條的第一版寫得太粗(把整句正交性都移除),而逐項查證後只有一個軸有問題:

正交嗎 證據
Topic ↔ View Params ✅ 仍成立 print 在兩個 Topic 的 L0 都可見,而投影成 cout 或 printf 由 Code Style 決定——兩者互不影響(concepts/漸進揭露.md:132 的例子)
元件層級 ↔ Topic ❌ 收回 「元件層級」今天就是 Topic 那棵 levelTree 的深度,它不獨立於 Topic

cpp-beginner.json 的實測:「函式與迴圈」與「型別系統」都是 L1, 而它們沒有任何共同的認知性質;唯一的共同點是「都掛在 L0 底下」。

兩個座標軸如果其中一個是另一個的函數,那不是二維,是一維寫成兩個欄位。

⚠️ 那一軸要重新宣告的話,得先答「n 的本質是什麼」——見 draft/Ln 的 n 只是排序。 而 concepts/漸進揭露.md:106 的另一個正交宣稱(元件層級 ↔ 表面形態) 不受影響——那一組有 F0/F1/F2 與 L0/L1/L2 兩套獨立刻度支撐。

5. 認知鷹架可退場

推導自:認知負荷理論(Sweller 1988)+ 近側發展區(Vygotsky 1978)

積木是認知鷹架,不是替代品。 目標是讓鷹架隨能力增長而退場,而非永遠依賴積木。

Sc1 鷹架可調性:同一元件在不同層級有不同的鷹架強度
Sc2 鷹架可退場:積木不可引入文字程式碼中不存在的概念
Sc3 認知一致性:一個積木 = 一個語法結構,不多不少
Sc4 最小驚訝:積木行為和生成的程式碼一致

如何應用:積木上不出現目標語言的語法符號(@、*/、<<、;);使用者看得到的所有文字都是介面,包含 mutator 彈窗內的 label。詳見 認知鷹架。

6. 誠實降級

推導自:根公理(語義結構是被發現的,不是被發明的)

降級不是失敗,而是系統的認識論承諾——選擇保留原始資訊而非強行結構化。raw_code 宣告「此處的真實超越了當前的解析能力」。

如何應用:不確定時標記 raw_code 並保留原始文字,禁止給出一個「看起來合理」的結構。降級必須單調遞減、必須可見、必須區分原因(程式碼錯誤 / 系統能力不足 / 非標準但正確)——否則鷹架變成認知牢籠。raw_code 覆蓋率是誠實度的度量,不是缺陷數量的度量。詳見 降級與認知邊界。

7. 三維錨定

推導自:根公理需要一個「憑什麼聲稱接近真實」的答案

系統的可信度不依賴單一權威,而是三個互設維度同時成立:公理(Protocol)∩ 情境(Data)∩ 主體(Agency)。

缺少 Protocol 對齊 → 系統幻覺(結構性錯誤)
缺少 Data 驗證   → 空想(未經實證的理論)
缺少 Agency 簽署 → 自動化偏差(無人負責的變更)

如何應用:確定性系統可自動寫入語義結構;機率性系統(LLM)只能建議,即使「很有信心」也不能自動寫入——類比:AI reviewer 可以留言,不能 merge。詳見 三維錨定。

8. 不做向後相容

推導自:根公理(語義結構是唯一真實,投影可重建)

每個 Phase 都是乾淨的切割(clean break)。不保留舊 API、不寫 migration、不做過渡期。編譯器就是驗證器。

如何應用:格式變更時直接升級、刪除舊路徑。?? 預設值是 null safety,不是向後相容機制——用它吞掉舊格式,會把資料遺失變成靜默降級(見 經驗 的「靜默降級是 bug 的藏身之處」)。

範圍釐清(2026-08-07):本條管的是投影、API、程式碼路徑——它們可以不相容,因為推導鏈說「投影可重建」。

但語義詞彙本身的變更不在此列(例如 componentId 改名):那動的是真實,沒有東西可以重建它,推導鏈對它不成立。這種變更 MUST 附一次性的轉換(載入時升級、舊格式隨即消失)——那仍然是乾淨的切割,不是相容層。

第二個缺口:「編譯器就是驗證器」假設所有程式碼都是你的。開放社群之後,第三方元件的存檔編譯器驗不到。

🟢 那個缺口 2026-09-06 有了機構(dist-sdk 出貨之後它從假設變成現況):

一個公開介面的移除,在自己的 repo 裡與一次正常的重構長得一模一樣 ——差別在別人的 CI 上。

所以「乾淨的切割」在對外那一面多一個條件:切之前要說得出切掉了什麼。 第一百零六條護欄(audit-sdk-surface)把 src/sdk/index.ts 的每一個匯出名記在基線裡 ——移除或改名要顯式下調並在 commit 訊息寫明破壞了什麼、消費者該怎麼改。

⚠️ 這不是相容層:舊的匯出照樣刪,而它刪掉的那一刻會有人被告知。 🔴 兩者的差別是「要不要留著舊的」與「有沒有人知道它沒了」 ——P8 拒絕的是前者,不是後者。

轉移見 history/026 · 210。

9. 四項獨立性(品質閘門)

推導自:P1(投影管線分離)+ P3(開放擴充)

每個 Phase 完成後必須通過:

  • 語言獨立性:拔掉 C++,只裝 Python stub → 所有視圖仍啟動,無 languages/cpp/ import
  • 視圖獨立性:拔掉任一視圖 → 其他不受影響,視圖間零 import
  • 宿主獨立性:同一套件在瀏覽器和 VSCode 中語義行為完全相同
  • 核心純淨性:src/core/ + src/languages/ + src/interpreter/ 零 DOM import,Node.js 環境可執行

不變式:Core 不 import View。View 間零 import。跨層通訊只走 Bus。

最終檢驗表:卡住時回到哪一條

問題 回到哪條
兩種視圖不一致了 根公理:所有視圖都是同一棵語義樹的投影
要不要支援某種投影 P1:確定可逆性等級(R0-R4)和參數空間
轉不了怎麼辦 P1:不存在轉不了——只有降級程度
積木該歸哪類 P2:它映射到哪個抽象元件?
測試夠不夠完整 P2:ComponentRegistry 每個條目的五條路徑都通過嗎?
加新套件要改哪些檔案 P3:只加 JSON,不改既有程式碼
新 pattern 會不會影響既有行為 P3:constraints 偏序可比較嗎?不可比較就強制手寫
初學者看到太多積木 P4:過濾層級,不是刪除元件
同語言但不同教學情境 Topic:不同 Topic 有不同的層級樹和積木覆蓋
Topic 切換後積木形狀變了 Topic:SemanticNode 存完整屬性,Topic 只控制投影可見性
積木設計對學習者有幫助嗎 Sc3:映射到真實的程式結構嗎?
積木應該多複雜 CLT:最小化外在負荷,一個積木做一件事
積木會不會變成依賴 Sc2:切到文字後能理解嗎?
積木排版要水平還是垂直 View Params:blocks 的投影參數,不是結構決策
要不要支援多檔案 根公理:Scope 3+ 加圖邊即可
外部套件不理解怎麼辦 P2 降級 + 可插拔執行:語義契約引用 + 最適後端執行
怎麼讓程式可以共享 語義套件:語義結構 + 投影定義 + 多後端執行體
每次打開都要重新設定 style User Context:慣性快取
打開別人的程式碼 style 錯了 User Context:語境偵測優先於個體慣性
跨語言轉換一直問相同問題 User Context:User Decision Cache 記住使用者選擇
不同角色對介面需求不同 User Context:角色意圖,同一人可切換角色
LLM 該放在哪裡 Guardrails 之上:LLM 是語用分析師,可留言不可 merge
這裡出錯會有人發現嗎 誠實降級:答案是「不會」的每一處都是等待發生的靜默降級
舊格式怎麼相容 不做向後相容:直接升級、刪除舊路徑

各子系統的關鍵原則

子系統 關鍵原則
i18n P1:Locale 是投影參數。message/tooltip 是呈現資訊,分離到 locale 檔案
coding style P1:Code Style 是 code viewType 的 viewParams,切換 = 重新投影
block style P1:Block Style 是 blocks viewType 的 viewParams。Sc4:預設值符合學習者閱讀習慣
多語言支援 P2:區分元件分層。跨語言走 抽象元件映射(R2-R3 投影)
R0-R1 投影 根公理:建立顯式語義樹。P1:roundtrip 是判定標準。P3:Pattern Engine 是唯一管線
R2-R4 投影 P1:唯讀視圖無需 roundtrip,但需保證投影完整性(不遺漏節點)
外部套件 P2:辨識語義角色。P3:只加 JSON + 可選註冊。P4:決定認知層級
主題(Topic) Topic 是投影層概念,不污染語義層。base + override 避免組合爆炸
使用者上下文 慣性是 viewParams 的推導來源,不是新原理

關鍵延伸(主題觸發必讀)

觸發關鍵字 MUST 讀
一條原則自己標記的缺口、「等 X 出現再重畫範圍」、一個建立在現況上的理由 concepts/紀錄的腐壞.md
投影、roundtrip、可逆性、R0-R4、viewType、viewParams、語義 diff、Code/Block Style、執行後端 concepts/投影.md
元件、registry、四路完備性、抽象元件、跨語言、語義阻抗、statement/expression concepts/元件代數.md
核心不認得任何語言:語言套件推、核心讀 concepts/宣告登記處.md
新增語言、新增套件、pattern、astPattern、歧義、lifter、strategy、依賴解析 concepts/開放擴充.md
認知層級、Level、Topic、toolbox、scaffold、ghost line、表面形態 concepts/漸進揭露.md
積木文字、message、tooltip、mutator label、i18n、CLT、ZPD、題目設計、課堂討論、同儕教學、PRIMM、Productive Failure、語意波 concepts/認知鷹架.md
降級、raw_code、confidence、巨集、taint、靜默失敗 concepts/降級與認知邊界.md
LLM、AI 輔助、soundness、correctness、自舉、元教學 concepts/三維錨定.md
積木定義、generator、extractor、欄位同步、動態積木、extraState concepts/積木投影管線.md
元件、命名、詞彙、埠、參數、形態、跨域、合流、ArduinoCAD、薄協定 concepts/元件.md
左值、lvalue、賦值的左邊、a[i] +=、成員存取、字串屬性裝結構、列舉式分派 concepts/左值.md
新增原則/契約/「不准」、殼、做一半、護欄、audit 測試、零容忍、完備性檢查 concepts/執行機構.md
執行、模擬、直譯器回什麼值、硬體、感測器、板子、虛擬硬體 concepts/模擬的誠實.md
狀態遷移、形狀變了、hot-fix、code_change、配對、鑰匙、strict=False、存檔改版 concepts/狀態遷移.md