處理工作日誌的 CLI 工具會在這種輸入上 panic:

1byte index 2 is not a char boundary; it is inside '⏳' (bytes 0..3) of `⏳ |`

原因是 markdown 表格的狀態欄位裡有一個沙漏 emoji,而工具在切字串時以位元組為單位,切點落在多位元組字元的中間。

工作日誌同時被人與工具讀取,格式因此有兩組要求,而它們不會自動相容。

工作日誌的本質

工作日誌不是私人筆記,也不是 log 檔。它是一份版本企劃書,給下一個接手的人看的。

讀它的人可能是三個月後的自己,也可能是第一次接觸這個版本的人。要能快速取得的是三件事:這個版本要做什麼、為什麼這樣設計、現在到哪了。

所以工作日誌最重要的特質是自給自足:拿起來讀,不需要問任何人,就能理解完整脈絡。

三個核心原則

原則一:工具相容性優先

markdown 表格單元格裡不放 emoji。工具鏈裡只要有一個環節以位元組切字串,多位元組字元就是一顆待觸發的地雷,而觸發時機取決於誰先讀到那一格。

表格外的段落、標題、列表可以自由用 emoji,限制只針對表格單元格。

錯誤的寫法:

1| Ticket ID | 狀態 |
2|-----------|------|
3| W1-001    | ⏳   |
4| W1-002    | 🔄   |

正確的寫法:

1| Ticket ID | 狀態 |
2|-----------|------|
3| W1-001    | 待處理 |
4| W1-002    | 進行中 |

一份無法被工具讀取的文件,等於沒有文件。

原則二:狀態符號標準化

表格只能用純文字,那就把詞彙統一:

  • 等待開始:待處理
  • 正在執行:進行中
  • 執行完畢:已完成
  • 主動取消:取消
  • 跳過不做:跳過
  • 被阻塞中:阻塞
  • 失敗或錯誤:失敗

詞彙固定,Hook 和解析工具才能依賴它計算——統計完成率、自動產生摘要、偵測卡住的任務。詞彙一飄移,自動化就跟著失效。

原則三:標準化結構

結構固定,任何人拿到都知道去哪找什麼。標準模板的必要部分:

版本基本資訊(最上方):版本號、開始日期、當前狀態、Git 分支。五秒內確認自己看的是哪個版本。

版本目標:幾句話說這個版本要做什麼。夠高層次讓非技術的人能讀懂,夠具體讓接手工程師能判斷方向對不對。

執行階段與 Ticket 清單:每個階段一張表,欄位固定:Ticket ID、操作動詞(Analyze、Design、Fix、Implement)、目標、負責人、依賴、狀態。Ticket ID 格式是 版本號-Wave-序號,例如 0.25.0-W1-001,看到 ID 就知道它屬於哪個版本哪個批次。

技術筆記:記錄開發過程中的發現和決策。沒有固定格式,但很重要——「為什麼這樣做」不寫下來,幾個月後就消失了。

細節下沉原則

工作日誌只寫大方向。分析過程、測試結果、錯誤訊息,放到 Ticket 文件裡。

工作日誌回答「要做什麼」和「為什麼」,Ticket 回答「怎麼做」和「結果如何」。違反這個原則的工作日誌會變成大雜燴:目標、程式碼片段、技術細節、執行記錄全部混在一起,要找什麼資訊得從頭讀到尾。

讓格式守護自己

靠記得維持格式的執行率取決於當下的注意力。worklog-format-check 這個 Hook 在每次寫入或編輯工作日誌後自動觸發,掃描表格裡有沒有問題字元,有就輸出警告並指出位置。

它不阻擋操作,只提醒。阻擋會打斷當下的工作,沉默放行則讓問題累積到被工具踩到為止;警告落在中間:問題被指出來,修不修由當下的人決定。

格式規則各自對應一個讀取者

三條規則對應三種讀取方式:結構標準化對應人的查找(知道去哪找什麼)、狀態詞彙固定對應工具的解析(統計完成率、產生摘要、偵測卡住的任務)、表格禁 emoji 對應工具鏈裡最脆弱的那個環節。

規則看起來瑣碎,而每一條都可以指出它服務的是哪一種讀取——指不出來的規則就是可以刪掉的規則。

Ticket 該記什麼、狀態放在哪裡,走 把 Ticket 狀態放進 frontmatter