Pseudo-Code 文件輸出模板
寫入
spec/{feature}/{feature}.pseudo.md的標準格式。 Partner skill 在最終輸出時組裝此模板。
全域編碼:被下游(Code Javadoc/別份 spec)引用的 §-section(公開方法契約)是本階段「對外」項目,於該節標題掛全域碼
§{SHORT}-PC-{N}(NUMBER 沿用本地 § 號、保留完整小數階層,如 §7.3.6 →§{SHORT}-PC-7.3.6)。{SHORT}查 spec-codes.md。純內部、未被跨界引用的子節點維持本地 §N.M.Z 不動(兩層並存)。引用上游 FS 邊界用其全域碼§{SHORT}-FS-{n}。格式見 workflow §可追溯性「全域編碼」。
模板全文
# {功能名稱} 虛擬碼
> 來源:[OOA]({feature}.ooa.md)
> 上游 functional spec:[fp]({feature}.fp.md)
> 最後同步 commit:`{git sha — 由實作者於每次 PR 更新}`
> 狀態:living doc — 程式碼異動時必須同步本檔
---
## 0. 名詞表
| 名詞 | 中文 | 定義 |
|---|---|---|
| {Term} | {中文} | {定義 — 與 OOA 領域詞彙一致} |
| ... | ... | ... |
> 名詞表必須涵蓋所有出現在後續虛擬碼中的非標準詞彙。
> 未列入名詞表的詞不得出現在虛擬碼中。
---
## 1. {高階流程名稱}
### 1.1 {子流程名稱}
**對應實作**:`com.leanplay.{module}.{layer}.{ClassName}#{methodName}`
**輸入**:
- `arg1`: {說明}
- `arg2`: {說明}
**輸出**:
- {說明}
**虛擬碼**:
```pseudo
function {methodName}(arg1, arg2):
// 1.1.1 {步驟說明}
if {condition}:
{action}
// 1.1.2 {步驟說明}
{action}
// 1.1.3 {步驟說明}
while {condition}:
{action}
return {result}
```
**設計理由**:
- 為何選此演算法(如:greedy vs. backtracking)
- 替代方案:{未採用的方案與原因}
**例外情境**:
- §1.1.1 — `InvalidInputException` when {condition}
- §1.1.3 — `CapacityExceededException` when {condition}
**測試對應**:
- 正常:functional-spec §UC A1 正常值
- 異常:functional-spec `§{SHORT}-FS-2`
- 邊界:functional-spec `§{SHORT}-FS-5`
---
### 1.2 {下一個子流程}
(同上格式)
---
## 2. {下一個高階流程}
(同上格式)
---
## 廢棄歷史
> 為保留追溯,廢棄段落不刪除,僅標記。
### ~~§1.3 {舊段落名}~~
**廢棄於**:{commit sha} / {日期}
**廢棄原因**:{原因}
**替代**:見 §1.5
---
## 簽核
- **編輯者**:____ / 日期:____
- **Reviewer**:____ / 日期:____各區塊撰寫指南
標頭區塊(檔案最上方)
- 來源 與 上游 functional spec:相對路徑 markdown 連結(本檔在
spec/{feature}/(兩層深);同 feature 各階段為同層 sibling、直接用檔名),方便 IDE / 編輯器跳轉 - 最後同步 commit:實作 PR 合併後由實作者更新;首次建立時填
初版 - 狀態行:照抄,提醒讀者這是 living doc
連結慣例(GFM)
完整規則見 product-module-development-workflow.md §可追溯性「連結慣例(GFM)」。本階段重點與一條不變量:
- breadcrumb / 跨檔:相對路徑 markdown 連結
[文字](../path.md)。 - 同檔 §章節跳轉:§X、§X.Y 是標準 heading(
## 1.、### 1.1),同檔引用用 markdown 連結[§1.1](#11-子流程名稱)。 - §編號穩定性與連結語法無關:§ 為 append-only、永不重編;廢棄段落保留並標
~~刪除線~~。Code 的 Javadoc 引用的是 § 文字編號(如§1.1.2),不是 block-id——兩套機制獨立,不要用^id取代 § 編號。 - 標籤一律含非數字字元;純數字
#1不是合法 tag。
§0 名詞表
- 三欄:英文(與 class 名一致)、中文、定義
- 動詞與名詞並列
- 不放普世概念(
Repository、Service不需要解釋;SlidingWindow、pending RSR需要) - 領域名詞對齊 OOA 領域詞彙與 vault 根 glossary.md 的標準形;遇 glossary 沒有的新領域術語,提醒使用者登記
每個子流程(§X.Y)必含區塊
| 區塊 | 必須 | 說明 |
|---|---|---|
| 對應實作 | ✅ | 完整 package + class + method |
| 輸入 | ✅ | 一行一參數,含領域意涵 |
| 輸出 | ✅ | 一句話 |
| 虛擬碼 | ✅ | 步驟編號 §X.Y.Z |
| 設計理由 | ⚠️ | 若有分歧必填 |
| 例外情境 | ⚠️ | 若有 raise 必填 |
| 測試對應 | ✅ | 指向 functional spec 的 use case I/O 範例或邊界條件編號 |
虛擬碼語法(重申)
function name(arg):
// §X.Y.Z 中文註解
if condition:
action
while condition:
action
for item in collection:
action
raise SomeException
return result關鍵字:function / if / else / while / for / in / return / raise / and / or / not / is / null
- 賦值用
:=(與==視覺區隔) - 不寫 Java 型別
- 不寫 DI、log、技術 exception
- 中文註解就是 §X.Y.Z 編號的載體;對外 §-section 的權威引用形式為全域碼
§{SHORT}-PC-{N},code Javadoc 引用此全域碼
廢棄段落
### ~~§1.3 舊的批次擴張規則~~
**廢棄於**:2026-06-15 commit `abc123`
**廢棄原因**:客戶要求改為齊套優先,原批次優先邏輯不適用
**替代**:見 §1.5不刪除、不重編號。讓 Javadoc 中的舊引用仍可定位。
完整範例片段
來自 spec/fine-schedule/fine-schedule.pseudo.md(節錄):
## 1. 主迴圈
### 1.1 滑動窗口推進
**對應實作**:`com.leanplay.fineschedule.application.FineScheduler#run`
**輸入**:
- `request`: 含 VSMs、Rough RSRs、Resources、Horizon
- `windowSize`: 預設一日
**輸出**:
- `FineScheduleResult`:ScheduledOperations + 未排工單 + Trace
**虛擬碼**:
```pseudo
function run(request, windowSize):
// 1.1.1 初始化
cursor := request.horizon.start
ledger := new SchedulingLedger()
pending := request.roughRSRs
// 1.1.2 主迴圈
while cursor < request.horizon.end:
window := SlidingWindow(cursor, cursor + windowSize)
// 1.1.3 三策略協作
supply := supplyStrategy.supplyFor(window, request.resources)
decision := assignmentStrategy.assign(window, supply, pending, ledger)
result := stackingStrategy.stack(decision, supply, ledger)
// 1.1.4 推進
pending := pending minus result.confirmed
cursor := cursor + windowSize
return FineScheduleResult(ledger.scheduled, pending, ledger.trace)
```
**設計理由**:
- 為何 sliding window 而非一次性整段最佳化:客戶資料規模 (~10k 工單) 使整段 NP-hard 不可行;window 大小可調,預設 1 日對齊工廠日曆。
- 替代方案:CP-SAT 整段求解(已試,求解時間不可接受)
**例外情境**:
- 主迴圈本身不 raise;下游策略可 raise,由主迴圈不捕捉直接往上拋
**測試對應**:
- 正常:functional-spec §UC A1 正常值(單一資源、24h horizon)
- 邊界:functional-spec `§{SHORT}-FS-3`(horizon = 1 window size,跑一輪即結束)
- 邊界:functional-spec `§{SHORT}-FS-4`(pending 為空,主迴圈跑 0 輪)