Speclink 第一版先沿用我最熟悉的 Spectra discuss:根據找到的程式碼,決定先列出假設讓我確認(Assumptions),還是一次問一題(Interview),最後再整理結論。這部分跑起來後,我接著想補上的,就是讓討論能留下來,換個 session 也能繼續談。
【Day - 14】提過,我一次可能會和 AI 談 5~10 個主題。下次回來時,我需要知道哪些已經談妥、哪些還沒談完,也想找得到當時為什麼這樣決定。如果這些都只留在對話裡,就得重新翻找,連自己都不一定記得前面談到哪裡了XD。
所以,最直接的作法好像就是把整段對話全部留下來。反正 AI 可以幫忙整理,逐字稿再長,之後請它找出重點就好了。但這樣真的足夠嗎?
把整段對話保存下來,確實能保留談過的內容。但同一個問題可能前面選了 A,後來又改成 B;有些只是順口提出的想法,有些才是最後決定。下次回來時,我還是得重新看過,才知道現在到底要照哪個方向做。
所以,我希望留下的紀錄能直接告訴我:目前決定了什麼、為什麼這樣選,以及哪些問題還沒談完。換到新的 session 後,AI 也能先讀這份紀錄,不用每次都從整串對話重新判斷。
要做到這件事,discussion 文件需要分別留下三件事:一開始為什麼要談、每一輪的決定怎麼改變,以及最後得到什麼結論。因此,文件固定成三個部分:

這三個部分怎麼來的? Context/Rounds/Conclusion 是我當時和 Claude Code 的 Fable 5 討論後,整理出的作法。Context 先固定討論的起點,Rounds 逐輪留下決定怎麼改變,Conclusion 再保存最後確認的答案。這樣不需要保留整份逐字稿,也不會只剩下最後結論,卻找不到中間為什麼改變方向。
這三個部分會放在同一份 Markdown,保存在 openspec/discussions/<slug>.md,不會分成三份文件。以登入流程的討論為例,檔案大概會像這樣:

文件最上面會先記下主題、用來命名檔案的識別名稱、目前狀態與建立時間。這一小段資料叫做 frontmatter,後面才是從 Context 開始的討論內容。
接下來,我們就把這三個部分一個個拆開來看。
Context 放的是這場 discussion 的起點。它要讓下一個讀到文件的人知道:什麼事情引發了這次討論、目前想處理的範圍,以及開始以前已經知道哪些相關背景。
例如,我想討論「通知功能到底要使用即時推送,還是定時查詢」,Context 可以先留下目前的需求、已經存在的系統限制,以及這次真正要決定的問題。它不需要把整個專案背景全部複製進來,只要讓後面的 Rounds 看得懂就夠了。精簡後,大概像這樣:
## Context
目前通知只會在重新整理頁面後出現。
這次要確認是否需要即時推送,以及現有架構適合採用哪一種方式。
Context 只需要設定一次。後面的想法如果改變,不會回頭改寫這個起點,而是繼續新增一個 Round,把改變的原因留在討論過程中。
Rounds 才是 discussion 最主要的內容。每一輪只處理一個焦點,並留下四種資訊:
### Round 1
**Focus**: 這一輪要回答的問題
**Position**: 目前採用的方向,以及為什麼
**Ruled out**: 已經排除的作法與原因
**Open**: 還沒有確認、下一輪需要繼續處理的問題
假設第一輪原本偏向 WebSocket,後來查完 codebase,發現目前只是伺服器單向推送通知,第二輪改成 SSE。Speclink 不會回頭把第一輪改掉,而是新增一輪,說明方向從 WebSocket 改成 SSE,以及改變的原因。
### Round 1
**Focus**: 通知更新需要雙向連線嗎?
**Position**: 先考慮 WebSocket,保留雙向互動的可能。
**Open**: 目前是否真的有 Client 主動傳送即時訊息的需求?
### Round 2
**Focus**: 現有需求是否需要雙向連線?
**Position**: 不需要,目前只有 Server 主動推送,因此改用 SSE。
**Ruled out**: WebSocket,目前會增加不必要的連線管理。
**Open**: 斷線重連時要怎麼補回遺漏的通知?
這樣做的目的,就是不要只留下最後答案。下一次重新開啟 session 時,AI 讀完這些 Rounds,就能知道我們不是一開始就選 SSE,而是先考慮過 WebSocket,後來因為需求其實只有單向推送才改變方向。我不用再回想當時講過什麼,也不用重新解釋為什麼前面的作法沒有採用。
如果一場 discussion 同時談了好幾個主題,discuss Skill 會把尚未處理的項目留在 Open,每完成一個主題,下一輪再更新剩餘清單。這樣即使一次談了 5~10 個主題,也看得出哪些已經處理、哪些還留著下一次繼續。
實際打開 Speclink Desktop 的「討論過程」後,每一輪的 Focus、Position、Ruled out 與 Open 也會分開顯示:

Rounds 留下了每次怎麼想、為什麼改變方向。等這次要處理的問題都談妥了,再把最後的決定整理到 Conclusion,下次就能先看結果,需要時再回頭找原因。
這份整理後的結果就是 Conclusion。它保存的是目前已經確定的決定、為什麼選擇這個方向、排除了哪些作法,以及哪些事情刻意留到以後再處理。
## Conclusion
**Decision**: 通知更新採用 SSE。
**Rationale**: 目前只需要 Server 單向推送,實作與連線管理都比 WebSocket 單純。
**Rejected alternatives**: WebSocket,現階段沒有雙向通訊需求。
**Deferred**: 歷史通知補送機制留到下一個需求處理。
**Next**: 透過 propose 建立 change,整理這次變更的 delta specs 與 tasks。
為了方便說明,我請 Codex 建立了一份示範用的 login-flow discussion。打開 Speclink Desktop 的 Conclusion 後,前面幾輪談過的內容會分成決定、理由、排除方案、擱置項目、記錄去向與下一步:

我現在回頭查看 discussion 時,大多會先看最後的 Conclusion,因為它已經把目前採用的答案整理好了。如果真的想知道「當時為什麼會這樣決定」,其實我也不會自己從 Round 1 開始慢慢讀XD,而是直接請 AI 根據這份討論,把中間的過程重新整理清楚給我。
這也是 discussion 文件和 Claude Code Plan Mode 不太一樣的地方。Plan Mode 比較接近準備實作的最後規劃;discussion 則保留答案形成以前的過程。平常只想知道結果時看 Conclusion,需要追查原因時,Rounds 仍然都在。
確定 discussion 該留下哪些內容後,接著遇到的問題就不是文件要怎麼寫,而是這份文件應該在什麼時候建立。
實際用了幾輪後,我很快就碰到這個問題。有時候我只是想先問某個作法是否可行,AI 回答完第一個問題後,我就決定不做了。如果一呼叫 discuss 就立刻建立文件,這些沒有繼續談下去的 discussion 就會一直留在那裡,後面還得自己清理,感覺也很奇怪。
所以,我把建立文件的時間往後移。AI 先查資料、列出假設或提出第一個問題時,都還不建檔。等我確認或修正假設,或回答問題、釐清一個決定,Skill 才建立 discussion,寫下 Context 與第一個 Round。

如果只是問一個問題,得到答案後就結束,不需要另外留一份 discussion。原本就有還沒談完的紀錄,則直接讀取原紀錄、接著新增 Rounds,不必再建一份。
討論後決定「不做」,也可以留下來。如果前面已經比較過幾種作法,最後才決定放棄,這個原因仍然值得保存。把 discussion 歸檔,在 Conclusion 說清楚就好,不需要硬是建立一個 change。
如果文件已經建立,最後卻沒有形成任何值得保留的內容,也可以手動刪除文件,或直接請 AI 幫忙清掉就好。
有了這份紀錄,下次回來時,我可以先看最後的決定,再請 AI 根據前面的討論繼續處理,不用重新交代一次背景。
不過,談妥了要做什麼,接下來還得建立或更新 change,才能繼續準備規格與 tasks。如果只有其中一個主題先談好,其他還想繼續聊,又該怎麼處理呢?
接下來,我們就看看怎麼把談好的內容帶進新的 change,或補回已經在做的 change,同時把還沒談完的問題留下來吧!