<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>寫作方法論 on Tarragon</title><link>https://tarrragon.github.io/blog/tags/%E5%AF%AB%E4%BD%9C%E6%96%B9%E6%B3%95%E8%AB%96/</link><description>Recent content in 寫作方法論 on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Wed, 20 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/%E5%AF%AB%E4%BD%9C%E6%96%B9%E6%B3%95%E8%AB%96/index.xml" rel="self" type="application/rss+xml"/><item><title>Source to Teaching Analysis — 外部分析材料轉教學文章</title><link>https://tarrragon.github.io/blog/skills/compositional-writing/source-to-teaching-analysis/</link><pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/skills/compositional-writing/source-to-teaching-analysis/</guid><description>&lt;p>本 reference 為「把外部分析文章或高密度研究材料，轉成教學型分析文章」情境。適用於分析師文章、投資人備忘錄、產業評論、研究摘要、AI 轉寫稿。目標是把 source 轉成讀者可重用的判讀框架，不是只做摘要、翻譯或語氣改寫。&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>自包含聲明&lt;/strong>：本文件不依賴其他 reference。讀完本文件即可獨立執行外部分析材料到教學文章的轉換。&lt;/p>&lt;/blockquote>
&lt;hr>
&lt;h2 id="何時參閱本文件">何時參閱本文件&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>觸發情境&lt;/th>
 &lt;th>動作&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>要把外部分析師文章改寫成自己的教學文章&lt;/td>
 &lt;td>跑完整 source-to-teaching pass&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>AI 改寫稿讀起來流暢、但像原文摘要&lt;/td>
 &lt;td>跑 deliverable pass&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>文章術語密度像寫給同業、目標讀者跟不上&lt;/td>
 &lt;td>跑 reader-level pass&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>來源文章的觀點與本文結論混在一起&lt;/td>
 &lt;td>跑 source layering pass&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>文章已套決策框架、但正文像分析過程記錄&lt;/td>
 &lt;td>跑 title promise 與 teaching narrative pass&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>不適用：純翻譯逐句校稿、學術論文正式摘要、內部 analyst-to-analyst 報告。這些產物可以保留原文的 reader contract 或 process metadata。&lt;/p>
&lt;hr>
&lt;h2 id="為什麼外部分析改寫需要獨立指引">為什麼外部分析改寫需要獨立指引&lt;/h2>
&lt;p>外部分析文章同時帶有三種東西：事實材料、原作者 frame、原作者 reader contract。AI 或人類若只做風格轉換，會把三者一起搬進新文章。結果是文字符合目標風格，但結論仍沿用原作者視角，讀者仍需要原領域背景，文章也缺少可遷移的教學框架。&lt;/p>
&lt;p>教學型分析文章要做的是「source transformation」：保留可驗證事實，辨識原作者判讀，重建適合目標讀者的推導，最後交付可重用的判斷問題與預警訊號。&lt;/p>
&lt;hr>
&lt;h2 id="五個-pass">五個 Pass&lt;/h2>
&lt;h3 id="pass-1source-layering">Pass 1：Source Layering&lt;/h3>
&lt;p>Source layering 是把材料拆成事實、原作者判讀、本文推導。每句材料進正文前先問：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>問題&lt;/th>
 &lt;th>層級&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>這件事有公開來源可驗證嗎？&lt;/td>
 &lt;td>事實&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>這是不是原作者或市場敘事的解釋？&lt;/td>
 &lt;td>原作者判讀&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>這是不是本文從多個材料合成出的框架？&lt;/td>
 &lt;td>本文推導&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>寫法規則：&lt;/p>
&lt;ul>
&lt;li>事實放在背景或事件段。&lt;/li>
&lt;li>原作者判讀只當 hypothesis prior，不直接當本文結論。&lt;/li>
&lt;li>本文推導要明確標成本文整理出的框架或判斷問題。&lt;/li>
&lt;/ul>
&lt;p>反例：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">這代表基礎設施廠商正在垂直整合 data pipeline。&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>問題：若「垂直整合」是本文推導，這句把推導寫成事實。&lt;/p>
&lt;p>正例：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">本文把這個收購視為「基礎設施廠商往 data pipeline 延伸」的訊號。這是本文判讀，不是事件本身。&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="pass-2reader-level">Pass 2：Reader Level&lt;/h3>
&lt;p>Reader-level pass 是把原文 reader contract 改成目標讀者 contract。先辨識原文寫給誰，再決定是否降一級。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>原文類型&lt;/th>
 &lt;th>常見 reader contract&lt;/th>
 &lt;th>轉換策略&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>大眾新聞&lt;/td>
 &lt;td>只需要知道事件&lt;/td>
 &lt;td>補機制與可遷移框架&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>投資人備忘錄&lt;/td>
 &lt;td>預設懂市場 shorthand&lt;/td>
 &lt;td>降術語密度、補因果鏈&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>產業內部文&lt;/td>
 &lt;td>預設懂供應鏈與競爭格局&lt;/td>
 &lt;td>補背景角色與資料形狀&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>教材型文章&lt;/td>
 &lt;td>已經有教學推導&lt;/td>
 &lt;td>檢查是否符合本站段落責任&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>檢查法：&lt;/p>
&lt;ul>
&lt;li>三句內連續三個以上跨領域術語，拆段或補卡。&lt;/li>
&lt;li>一句話跨三個以上因果步，拆成多段。&lt;/li>
&lt;li>讀者能背結論但說不出推導，補機制、公式、數字或例子。&lt;/li>
&lt;/ul>
&lt;h3 id="pass-3internal-analysis">Pass 3：Internal Analysis&lt;/h3>
&lt;p>Internal analysis 是作者背後的 hypothesis 探索，不等於文章章節。可以用 WRAP 或其他決策框架做內部檢查：&lt;/p>
&lt;ul>
&lt;li>要回答什麼問題？&lt;/li>
&lt;li>手上 evidence 夠不夠？&lt;/li>
&lt;li>有哪些本質不同的合理解釋？&lt;/li>
&lt;li>每個解釋的 evidence weight 是什麼？&lt;/li>
&lt;li>哪些觀察會推翻本文判讀？&lt;/li>
&lt;/ul>
&lt;p>這些問題要做完，但不直接當正文標題。正文標題描述讀者會學到什麼，不描述作者正在執行哪個分析步驟。&lt;/p>
&lt;h3 id="pass-4title-promise">Pass 4：Title Promise&lt;/h3>
&lt;p>Title promise 是標題對讀者做的合約。跑完內部分析後，列出文章每段是否服務標題承諾。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>檢查項&lt;/th>
 &lt;th>行動&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>某段超過 20% 篇幅但不在標題承諾內&lt;/td>
 &lt;td>壓縮成背景句、移到別篇、或刪除&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>來源 prior 比正文機制更長&lt;/td>
 &lt;td>縮減 prior，讓主體回到本文承諾&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>標題承諾的是框架、正文卻在解釋作者動機&lt;/td>
 &lt;td>改寫主體或重命名標題&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Title promise pass 保護讀者不被作者的分析過程帶離主題。&lt;/p>
&lt;h3 id="pass-5deliverable">Pass 5：Deliverable&lt;/h3>
&lt;p>Deliverable pass 確認文章交付的是可遷移框架，而不是原文摘要。結尾至少回答：&lt;/p>
&lt;ul>
&lt;li>下次遇到同類事件要看哪些訊號？&lt;/li>
&lt;li>哪些機制若成立，本文判讀才成立？&lt;/li>
&lt;li>哪些觀察會削弱或推翻本文判讀？&lt;/li>
&lt;li>讀者下一步該看哪個概念、卡片或案例？&lt;/li>
&lt;/ul>
&lt;p>常見責任順序：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">事件本身 → 結構性機制 → 長期影響 → 預警訊號 → 可遷移框架&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>這是責任清單，各文章可以調整順序。不同文章可以調整順序，但不能缺少可遷移框架與失效條件。&lt;/p>
&lt;hr>
&lt;h2 id="自檢清單">自檢清單&lt;/h2>
&lt;ul>
&lt;li>&lt;input disabled="" type="checkbox"> 每個來源句子都能標成事實、原作者判讀、本文推導之一。&lt;/li>
&lt;li>&lt;input disabled="" type="checkbox"> 原作者 frame 沒有被寫成事件事實。&lt;/li>
&lt;li>&lt;input disabled="" type="checkbox"> 目標讀者不需要原文 reader contract 也能理解主體推導。&lt;/li>
&lt;li>&lt;input disabled="" type="checkbox"> 三句內沒有未解釋的連續跨領域術語。&lt;/li>
&lt;li>&lt;input disabled="" type="checkbox"> 內部分析框架沒有外露成正文標題。&lt;/li>
&lt;li>&lt;input disabled="" type="checkbox"> 正文段落都服務 title promise。&lt;/li>
&lt;li>&lt;input disabled="" type="checkbox"> 結尾提供可遷移框架、預警訊號與下一步路由。&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="反模式速查">反模式速查&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>反模式&lt;/th>
 &lt;th>修法&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>只要求 AI「改成我們的風格」&lt;/td>
 &lt;td>改成「抽出可遷移判讀框架」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>把原作者分類直接當本文標題&lt;/td>
 &lt;td>標出這是原作者 frame 或本文 frame&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>引用機構名但沒有具體來源&lt;/td>
 &lt;td>刪具名 attribution 或重新查證&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>章節標題是分析 process&lt;/td>
 &lt;td>改成教學標題&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>文章結尾只有事件結論&lt;/td>
 &lt;td>補下次遇到同類事件的判斷問題&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>讀者需要懂原領域 shorthand 才懂&lt;/td>
 &lt;td>降術語密度，補 bridge sentence&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>核心原則&lt;/strong>：外部分析文章改寫的核心是 source transformation。保留事實、分離原作者判讀、重建目標讀者可理解的推導，最後交付可遷移框架。&lt;/p></description><content:encoded><![CDATA[<p>本 reference 為「把外部分析文章或高密度研究材料，轉成教學型分析文章」情境。適用於分析師文章、投資人備忘錄、產業評論、研究摘要、AI 轉寫稿。目標是把 source 轉成讀者可重用的判讀框架，不是只做摘要、翻譯或語氣改寫。</p>
<blockquote>
<p><strong>自包含聲明</strong>：本文件不依賴其他 reference。讀完本文件即可獨立執行外部分析材料到教學文章的轉換。</p></blockquote>
<hr>
<h2 id="何時參閱本文件">何時參閱本文件</h2>
<table>
  <thead>
      <tr>
          <th>觸發情境</th>
          <th>動作</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>要把外部分析師文章改寫成自己的教學文章</td>
          <td>跑完整 source-to-teaching pass</td>
      </tr>
      <tr>
          <td>AI 改寫稿讀起來流暢、但像原文摘要</td>
          <td>跑 deliverable pass</td>
      </tr>
      <tr>
          <td>文章術語密度像寫給同業、目標讀者跟不上</td>
          <td>跑 reader-level pass</td>
      </tr>
      <tr>
          <td>來源文章的觀點與本文結論混在一起</td>
          <td>跑 source layering pass</td>
      </tr>
      <tr>
          <td>文章已套決策框架、但正文像分析過程記錄</td>
          <td>跑 title promise 與 teaching narrative pass</td>
      </tr>
  </tbody>
</table>
<p>不適用：純翻譯逐句校稿、學術論文正式摘要、內部 analyst-to-analyst 報告。這些產物可以保留原文的 reader contract 或 process metadata。</p>
<hr>
<h2 id="為什麼外部分析改寫需要獨立指引">為什麼外部分析改寫需要獨立指引</h2>
<p>外部分析文章同時帶有三種東西：事實材料、原作者 frame、原作者 reader contract。AI 或人類若只做風格轉換，會把三者一起搬進新文章。結果是文字符合目標風格，但結論仍沿用原作者視角，讀者仍需要原領域背景，文章也缺少可遷移的教學框架。</p>
<p>教學型分析文章要做的是「source transformation」：保留可驗證事實，辨識原作者判讀，重建適合目標讀者的推導，最後交付可重用的判斷問題與預警訊號。</p>
<hr>
<h2 id="五個-pass">五個 Pass</h2>
<h3 id="pass-1source-layering">Pass 1：Source Layering</h3>
<p>Source layering 是把材料拆成事實、原作者判讀、本文推導。每句材料進正文前先問：</p>
<table>
  <thead>
      <tr>
          <th>問題</th>
          <th>層級</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>這件事有公開來源可驗證嗎？</td>
          <td>事實</td>
      </tr>
      <tr>
          <td>這是不是原作者或市場敘事的解釋？</td>
          <td>原作者判讀</td>
      </tr>
      <tr>
          <td>這是不是本文從多個材料合成出的框架？</td>
          <td>本文推導</td>
      </tr>
  </tbody>
</table>
<p>寫法規則：</p>
<ul>
<li>事實放在背景或事件段。</li>
<li>原作者判讀只當 hypothesis prior，不直接當本文結論。</li>
<li>本文推導要明確標成本文整理出的框架或判斷問題。</li>
</ul>
<p>反例：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">這代表基礎設施廠商正在垂直整合 data pipeline。</span></span></code></pre></div><p>問題：若「垂直整合」是本文推導，這句把推導寫成事實。</p>
<p>正例：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">本文把這個收購視為「基礎設施廠商往 data pipeline 延伸」的訊號。這是本文判讀，不是事件本身。</span></span></code></pre></div><h3 id="pass-2reader-level">Pass 2：Reader Level</h3>
<p>Reader-level pass 是把原文 reader contract 改成目標讀者 contract。先辨識原文寫給誰，再決定是否降一級。</p>
<table>
  <thead>
      <tr>
          <th>原文類型</th>
          <th>常見 reader contract</th>
          <th>轉換策略</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>大眾新聞</td>
          <td>只需要知道事件</td>
          <td>補機制與可遷移框架</td>
      </tr>
      <tr>
          <td>投資人備忘錄</td>
          <td>預設懂市場 shorthand</td>
          <td>降術語密度、補因果鏈</td>
      </tr>
      <tr>
          <td>產業內部文</td>
          <td>預設懂供應鏈與競爭格局</td>
          <td>補背景角色與資料形狀</td>
      </tr>
      <tr>
          <td>教材型文章</td>
          <td>已經有教學推導</td>
          <td>檢查是否符合本站段落責任</td>
      </tr>
  </tbody>
</table>
<p>檢查法：</p>
<ul>
<li>三句內連續三個以上跨領域術語，拆段或補卡。</li>
<li>一句話跨三個以上因果步，拆成多段。</li>
<li>讀者能背結論但說不出推導，補機制、公式、數字或例子。</li>
</ul>
<h3 id="pass-3internal-analysis">Pass 3：Internal Analysis</h3>
<p>Internal analysis 是作者背後的 hypothesis 探索，不等於文章章節。可以用 WRAP 或其他決策框架做內部檢查：</p>
<ul>
<li>要回答什麼問題？</li>
<li>手上 evidence 夠不夠？</li>
<li>有哪些本質不同的合理解釋？</li>
<li>每個解釋的 evidence weight 是什麼？</li>
<li>哪些觀察會推翻本文判讀？</li>
</ul>
<p>這些問題要做完，但不直接當正文標題。正文標題描述讀者會學到什麼，不描述作者正在執行哪個分析步驟。</p>
<h3 id="pass-4title-promise">Pass 4：Title Promise</h3>
<p>Title promise 是標題對讀者做的合約。跑完內部分析後，列出文章每段是否服務標題承諾。</p>
<table>
  <thead>
      <tr>
          <th>檢查項</th>
          <th>行動</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>某段超過 20% 篇幅但不在標題承諾內</td>
          <td>壓縮成背景句、移到別篇、或刪除</td>
      </tr>
      <tr>
          <td>來源 prior 比正文機制更長</td>
          <td>縮減 prior，讓主體回到本文承諾</td>
      </tr>
      <tr>
          <td>標題承諾的是框架、正文卻在解釋作者動機</td>
          <td>改寫主體或重命名標題</td>
      </tr>
  </tbody>
</table>
<p>Title promise pass 保護讀者不被作者的分析過程帶離主題。</p>
<h3 id="pass-5deliverable">Pass 5：Deliverable</h3>
<p>Deliverable pass 確認文章交付的是可遷移框架，而不是原文摘要。結尾至少回答：</p>
<ul>
<li>下次遇到同類事件要看哪些訊號？</li>
<li>哪些機制若成立，本文判讀才成立？</li>
<li>哪些觀察會削弱或推翻本文判讀？</li>
<li>讀者下一步該看哪個概念、卡片或案例？</li>
</ul>
<p>常見責任順序：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">事件本身 → 結構性機制 → 長期影響 → 預警訊號 → 可遷移框架</span></span></code></pre></div><p>這是責任清單，各文章可以調整順序。不同文章可以調整順序，但不能缺少可遷移框架與失效條件。</p>
<hr>
<h2 id="自檢清單">自檢清單</h2>
<ul>
<li><input disabled="" type="checkbox"> 每個來源句子都能標成事實、原作者判讀、本文推導之一。</li>
<li><input disabled="" type="checkbox"> 原作者 frame 沒有被寫成事件事實。</li>
<li><input disabled="" type="checkbox"> 目標讀者不需要原文 reader contract 也能理解主體推導。</li>
<li><input disabled="" type="checkbox"> 三句內沒有未解釋的連續跨領域術語。</li>
<li><input disabled="" type="checkbox"> 內部分析框架沒有外露成正文標題。</li>
<li><input disabled="" type="checkbox"> 正文段落都服務 title promise。</li>
<li><input disabled="" type="checkbox"> 結尾提供可遷移框架、預警訊號與下一步路由。</li>
</ul>
<hr>
<h2 id="反模式速查">反模式速查</h2>
<table>
  <thead>
      <tr>
          <th>反模式</th>
          <th>修法</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>只要求 AI「改成我們的風格」</td>
          <td>改成「抽出可遷移判讀框架」</td>
      </tr>
      <tr>
          <td>把原作者分類直接當本文標題</td>
          <td>標出這是原作者 frame 或本文 frame</td>
      </tr>
      <tr>
          <td>引用機構名但沒有具體來源</td>
          <td>刪具名 attribution 或重新查證</td>
      </tr>
      <tr>
          <td>章節標題是分析 process</td>
          <td>改成教學標題</td>
      </tr>
      <tr>
          <td>文章結尾只有事件結論</td>
          <td>補下次遇到同類事件的判斷問題</td>
      </tr>
      <tr>
          <td>讀者需要懂原領域 shorthand 才懂</td>
          <td>降術語密度，補 bridge sentence</td>
      </tr>
  </tbody>
</table>
<p><strong>核心原則</strong>：外部分析文章改寫的核心是 source transformation。保留事實、分離原作者判讀、重建目標讀者可理解的推導，最後交付可遷移框架。</p>
]]></content:encoded></item><item><title>Translation Review — 文章翻譯與轉譯檢查</title><link>https://tarrragon.github.io/blog/skills/compositional-writing/translation-review/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/skills/compositional-writing/translation-review/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>本檔位置&lt;/strong>：&lt;code>compositional-writing&lt;/code> 的文章轉譯 / 翻譯 / 術語改寫 reference。&lt;/p>
&lt;p>&lt;strong>何時讀&lt;/strong>：把英文材料轉成中文、把既有文章改寫成另一種語言、整理 AI / 工程 / 方法論術語，或 reviewer 指出「這個翻譯放在句子裡怪怪的」時。&lt;/p>&lt;/blockquote>
&lt;h2 id="核心命題">核心命題&lt;/h2>
&lt;p>翻譯 review 的核心是句內邏輯對位，不是詞典對位。翻譯完成後要把譯名放回原句，檢查它跟主詞、動詞、修飾語、因果關係是否仍然成立；如果譯名讓句子多出原文沒有的前提，或讓讀者追問方向改變，這個翻譯就有問題。&lt;/p>
&lt;p>翻譯錯誤常在中文很順時被放過。順口只代表中文語感成立，不代表原文概念、句內角色、後續推論成立。多輪檢查時要把「順不順」跟「邏輯是否對位」分開看。&lt;/p>
&lt;hr>
&lt;h2 id="為什麼文章轉譯容易誤譯">為什麼文章轉譯容易誤譯&lt;/h2>
&lt;p>文章轉譯容易誤譯，是因為譯者會同時壓縮三件事：讀懂原文、找中文詞、讓句子順。這三件事會互相干擾，尤其在 AI / 工程 / 方法論文章中，原文詞常同時有字根、日常語意、術語語意。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>便利訊號&lt;/th>
 &lt;th>看起來合理的原因&lt;/th>
 &lt;th>失效方式&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>字根聯想&lt;/td>
 &lt;td>字根提供直覺線索&lt;/td>
 &lt;td>字根不是術語定義，容易把詞帶到錯的概念場&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>上下文補完&lt;/td>
 &lt;td>句子附近有相似語氣或情境&lt;/td>
 &lt;td>補完的是譯者腦中的情境，不一定是原文責任&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>中文順口度&lt;/td>
 &lt;td>讀起來像自然中文&lt;/td>
 &lt;td>順口可能只是中文搭配成立，不代表邏輯成立&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>常見譯名記憶&lt;/td>
 &lt;td>以前看過類似翻法&lt;/td>
 &lt;td>不同領域同詞不同義，舊翻法可能換場景失效&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>AI 自動補詞&lt;/td>
 &lt;td>模型會補出完整片語&lt;/td>
 &lt;td>補出的中文可能比原文多一層未明說的前提&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>翻譯 review 的任務是把這些便利訊號重新拆開。先問原文概念在句子中承擔什麼責任，再決定中文詞是否能承擔同一個責任。&lt;/p>
&lt;hr>
&lt;h2 id="句內邏輯檢查">句內邏輯檢查&lt;/h2>
&lt;p>句內邏輯檢查要求把翻譯後的中文詞放回原句，逐項檢查語法角色與論證角色。這一步比查字典更早，因為很多錯譯不是「查不到正確譯名」，而是譯名放進句子後改變了原句的邏輯。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>檢查層&lt;/th>
 &lt;th>問題&lt;/th>
 &lt;th>失效訊號&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>主詞角色&lt;/td>
 &lt;td>這個詞描述的是誰的行為或關係？&lt;/td>
 &lt;td>句子在談 A，譯名把它帶成 B&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>動詞搭配&lt;/td>
 &lt;td>這個詞能自然承接後面的動作嗎？&lt;/td>
 &lt;td>放回原句後語意卡住&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>修飾語關係&lt;/td>
 &lt;td>中文修飾語是否引入額外前提？&lt;/td>
 &lt;td>修飾語找不到原文來源&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>受詞邊界&lt;/td>
 &lt;td>這個詞作用到的對象是否一樣？&lt;/td>
 &lt;td>原文作用在 decision，中文變成 person&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>因果方向&lt;/td>
 &lt;td>這個詞是否支撐段落原本的因果？&lt;/td>
 &lt;td>原本「因為 X」被譯名暗示成「因為 Y」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>讀者追問方向&lt;/td>
 &lt;td>reader 看到這個詞會問哪個問題？&lt;/td>
 &lt;td>追問方向偏離原文核心&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>檢查時可以把原句拆成一句話：「因為 X，所以 Y」。若中文譯名把 X 換成 X&amp;rsquo;，後面 Y 還能成立嗎？不能成立就要重譯。&lt;/p>
&lt;hr>
&lt;h2 id="casepaternalism-不是父權式保護">Case：paternalism 不是父權式保護&lt;/h2>
&lt;p>&lt;code>paternalism&lt;/code> 被翻成「父權式保護」的問題是句內邏輯錯位。這個譯名同時抓到 &lt;code>paternal&lt;/code> 的父系字根與「保護他人」的語境，所以中文看似能讀；但放回句子後，它讓句子多出原文沒有的前提：這裡似乎涉及父權或性別權力結構。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>檢查層&lt;/th>
 &lt;th>&lt;code>父權式保護&lt;/code> 的問題&lt;/th>
 &lt;th>較合理的對位&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>主詞角色&lt;/td>
 &lt;td>段落在談規則對自主性的介入，不是在談父權&lt;/td>
 &lt;td>家長主義（paternalism）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>修飾語關係&lt;/td>
 &lt;td>「父權式」引入 gender / patriarchy 前提&lt;/td>
 &lt;td>「家長」對位替對方決定何者對他好&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>動詞搭配&lt;/td>
 &lt;td>「通過父權式保護 4 條件測試」語意卡住&lt;/td>
 &lt;td>「通過家長主義 4 條件測試」可承接&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>因果方向&lt;/td>
 &lt;td>原因是替對方決定，不是父權結構&lt;/td>
 &lt;td>因為限制自主，所以要檢查介入正當性&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>讀者追問方向&lt;/td>
 &lt;td>reader 會問「父權在哪？」&lt;/td>
 &lt;td>reader 會問「自主性與介入邊界在哪？」&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>修法的重點是補定義句讓邏輯回到原文責任：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">家長主義（paternalism）在本文指「以對方利益之名限制對方自主」。
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">常見譯名也包含「家長作風」；本文統一用「家長主義」。&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="casesteelman-不是最強版本測試">Case：Steelman 不是最強版本測試&lt;/h2>
&lt;p>&lt;code>Steelman&lt;/code> 被翻成「最強版本測試」的問題是概念角色被換掉。這個譯名在 checklist 語境裡看似自然，因為 reviewer 確實會問「有沒有通過」；但 &lt;code>Steelman&lt;/code> 的核心責任是把被放棄選項或反方立場重建成最有力版本。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>檢查層&lt;/th>
 &lt;th>&lt;code>最強版本測試&lt;/code> 的問題&lt;/th>
 &lt;th>較合理的對位&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>來源角色&lt;/td>
 &lt;td>把論證方法壓成檢查動作&lt;/td>
 &lt;td>最強版本論證（Steelman）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>本文角色&lt;/td>
 &lt;td>只保留 checklist 用途&lt;/td>
 &lt;td>保留降低確認偏誤的推理方法&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>動詞搭配&lt;/td>
 &lt;td>reader 追問「怎樣算測試通過」&lt;/td>
 &lt;td>reader 追問「反方是否重建」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Surface 面&lt;/td>
 &lt;td>heading / checklist 會傳播錯誤角色&lt;/td>
 &lt;td>全文統一同一概念角色&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>修法的重點是保留概念角色：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">最強版本論證（Steelman）在本文指：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">先把被放棄選項或反方立場重建成最有力版本，再檢查自己的選擇是否仍站得住腳。&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h2 id="多輪檢查流程">多輪檢查流程&lt;/h2>
&lt;p>翻譯 review 要獨立成一輪，放在一般命名 / grep-ability 檢查附近。它不取代文章的意圖檢查、語氣檢查或邊界檢查，而是補上「語言轉換後邏輯是否仍成立」這個角度。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Pass&lt;/th>
 &lt;th>問題&lt;/th>
 &lt;th>操作&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>1. 來源定位&lt;/td>
 &lt;td>哪些句子來自翻譯 / 轉譯？&lt;/td>
 &lt;td>標記英文材料、AI 產出、改寫段落&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>2. 術語枚舉&lt;/td>
 &lt;td>哪些中文詞由英文概念翻來？&lt;/td>
 &lt;td>grep 英文括號、標題、表格第一欄、index entry&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>3. 原文錨點&lt;/td>
 &lt;td>第一次出現是否保留 original term？&lt;/td>
 &lt;td>補「中文術語（original term）」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>4. 句內角色&lt;/td>
 &lt;td>中文詞在句中扮演的角色是否對？&lt;/td>
 &lt;td>標出主詞、動詞、受詞、修飾語&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>5. 前提檢查&lt;/td>
 &lt;td>中文是否多出原文沒有的前提？&lt;/td>
 &lt;td>問「這個修飾語 / 判斷從原文哪裡來？」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>6. 因果檢查&lt;/td>
 &lt;td>譯名是否改變段落推論方向？&lt;/td>
 &lt;td>重寫「因為 X，所以 Y」，確認 X 沒被換掉&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>7. 追問檢查&lt;/td>
 &lt;td>reader 看到中文會追問正確問題嗎？&lt;/td>
 &lt;td>問「他會問 A 還是 B？」；問錯方向就重譯&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>8. Surface 同步&lt;/td>
 &lt;td>metadata / navigation 是否也對位？&lt;/td>
 &lt;td>掃 title、description、heading、link label&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>這輪可以很短，但不能省。文章轉譯時，最容易被放過的錯誤就是「中文通順、邏輯錯位」。&lt;/p></description><content:encoded><![CDATA[<blockquote>
<p><strong>本檔位置</strong>：<code>compositional-writing</code> 的文章轉譯 / 翻譯 / 術語改寫 reference。</p>
<p><strong>何時讀</strong>：把英文材料轉成中文、把既有文章改寫成另一種語言、整理 AI / 工程 / 方法論術語，或 reviewer 指出「這個翻譯放在句子裡怪怪的」時。</p></blockquote>
<h2 id="核心命題">核心命題</h2>
<p>翻譯 review 的核心是句內邏輯對位，不是詞典對位。翻譯完成後要把譯名放回原句，檢查它跟主詞、動詞、修飾語、因果關係是否仍然成立；如果譯名讓句子多出原文沒有的前提，或讓讀者追問方向改變，這個翻譯就有問題。</p>
<p>翻譯錯誤常在中文很順時被放過。順口只代表中文語感成立，不代表原文概念、句內角色、後續推論成立。多輪檢查時要把「順不順」跟「邏輯是否對位」分開看。</p>
<hr>
<h2 id="為什麼文章轉譯容易誤譯">為什麼文章轉譯容易誤譯</h2>
<p>文章轉譯容易誤譯，是因為譯者會同時壓縮三件事：讀懂原文、找中文詞、讓句子順。這三件事會互相干擾，尤其在 AI / 工程 / 方法論文章中，原文詞常同時有字根、日常語意、術語語意。</p>
<table>
  <thead>
      <tr>
          <th>便利訊號</th>
          <th>看起來合理的原因</th>
          <th>失效方式</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>字根聯想</td>
          <td>字根提供直覺線索</td>
          <td>字根不是術語定義，容易把詞帶到錯的概念場</td>
      </tr>
      <tr>
          <td>上下文補完</td>
          <td>句子附近有相似語氣或情境</td>
          <td>補完的是譯者腦中的情境，不一定是原文責任</td>
      </tr>
      <tr>
          <td>中文順口度</td>
          <td>讀起來像自然中文</td>
          <td>順口可能只是中文搭配成立，不代表邏輯成立</td>
      </tr>
      <tr>
          <td>常見譯名記憶</td>
          <td>以前看過類似翻法</td>
          <td>不同領域同詞不同義，舊翻法可能換場景失效</td>
      </tr>
      <tr>
          <td>AI 自動補詞</td>
          <td>模型會補出完整片語</td>
          <td>補出的中文可能比原文多一層未明說的前提</td>
      </tr>
  </tbody>
</table>
<p>翻譯 review 的任務是把這些便利訊號重新拆開。先問原文概念在句子中承擔什麼責任，再決定中文詞是否能承擔同一個責任。</p>
<hr>
<h2 id="句內邏輯檢查">句內邏輯檢查</h2>
<p>句內邏輯檢查要求把翻譯後的中文詞放回原句，逐項檢查語法角色與論證角色。這一步比查字典更早，因為很多錯譯不是「查不到正確譯名」，而是譯名放進句子後改變了原句的邏輯。</p>
<table>
  <thead>
      <tr>
          <th>檢查層</th>
          <th>問題</th>
          <th>失效訊號</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>主詞角色</td>
          <td>這個詞描述的是誰的行為或關係？</td>
          <td>句子在談 A，譯名把它帶成 B</td>
      </tr>
      <tr>
          <td>動詞搭配</td>
          <td>這個詞能自然承接後面的動作嗎？</td>
          <td>放回原句後語意卡住</td>
      </tr>
      <tr>
          <td>修飾語關係</td>
          <td>中文修飾語是否引入額外前提？</td>
          <td>修飾語找不到原文來源</td>
      </tr>
      <tr>
          <td>受詞邊界</td>
          <td>這個詞作用到的對象是否一樣？</td>
          <td>原文作用在 decision，中文變成 person</td>
      </tr>
      <tr>
          <td>因果方向</td>
          <td>這個詞是否支撐段落原本的因果？</td>
          <td>原本「因為 X」被譯名暗示成「因為 Y」</td>
      </tr>
      <tr>
          <td>讀者追問方向</td>
          <td>reader 看到這個詞會問哪個問題？</td>
          <td>追問方向偏離原文核心</td>
      </tr>
  </tbody>
</table>
<p>檢查時可以把原句拆成一句話：「因為 X，所以 Y」。若中文譯名把 X 換成 X&rsquo;，後面 Y 還能成立嗎？不能成立就要重譯。</p>
<hr>
<h2 id="casepaternalism-不是父權式保護">Case：paternalism 不是父權式保護</h2>
<p><code>paternalism</code> 被翻成「父權式保護」的問題是句內邏輯錯位。這個譯名同時抓到 <code>paternal</code> 的父系字根與「保護他人」的語境，所以中文看似能讀；但放回句子後，它讓句子多出原文沒有的前提：這裡似乎涉及父權或性別權力結構。</p>
<table>
  <thead>
      <tr>
          <th>檢查層</th>
          <th><code>父權式保護</code> 的問題</th>
          <th>較合理的對位</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>主詞角色</td>
          <td>段落在談規則對自主性的介入，不是在談父權</td>
          <td>家長主義（paternalism）</td>
      </tr>
      <tr>
          <td>修飾語關係</td>
          <td>「父權式」引入 gender / patriarchy 前提</td>
          <td>「家長」對位替對方決定何者對他好</td>
      </tr>
      <tr>
          <td>動詞搭配</td>
          <td>「通過父權式保護 4 條件測試」語意卡住</td>
          <td>「通過家長主義 4 條件測試」可承接</td>
      </tr>
      <tr>
          <td>因果方向</td>
          <td>原因是替對方決定，不是父權結構</td>
          <td>因為限制自主，所以要檢查介入正當性</td>
      </tr>
      <tr>
          <td>讀者追問方向</td>
          <td>reader 會問「父權在哪？」</td>
          <td>reader 會問「自主性與介入邊界在哪？」</td>
      </tr>
  </tbody>
</table>
<p>修法的重點是補定義句讓邏輯回到原文責任：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">家長主義（paternalism）在本文指「以對方利益之名限制對方自主」。
</span></span><span class="line"><span class="ln">2</span><span class="cl">常見譯名也包含「家長作風」；本文統一用「家長主義」。</span></span></code></pre></div><h2 id="casesteelman-不是最強版本測試">Case：Steelman 不是最強版本測試</h2>
<p><code>Steelman</code> 被翻成「最強版本測試」的問題是概念角色被換掉。這個譯名在 checklist 語境裡看似自然，因為 reviewer 確實會問「有沒有通過」；但 <code>Steelman</code> 的核心責任是把被放棄選項或反方立場重建成最有力版本。</p>
<table>
  <thead>
      <tr>
          <th>檢查層</th>
          <th><code>最強版本測試</code> 的問題</th>
          <th>較合理的對位</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>來源角色</td>
          <td>把論證方法壓成檢查動作</td>
          <td>最強版本論證（Steelman）</td>
      </tr>
      <tr>
          <td>本文角色</td>
          <td>只保留 checklist 用途</td>
          <td>保留降低確認偏誤的推理方法</td>
      </tr>
      <tr>
          <td>動詞搭配</td>
          <td>reader 追問「怎樣算測試通過」</td>
          <td>reader 追問「反方是否重建」</td>
      </tr>
      <tr>
          <td>Surface 面</td>
          <td>heading / checklist 會傳播錯誤角色</td>
          <td>全文統一同一概念角色</td>
      </tr>
  </tbody>
</table>
<p>修法的重點是保留概念角色：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">最強版本論證（Steelman）在本文指：
</span></span><span class="line"><span class="ln">2</span><span class="cl">先把被放棄選項或反方立場重建成最有力版本，再檢查自己的選擇是否仍站得住腳。</span></span></code></pre></div><hr>
<h2 id="多輪檢查流程">多輪檢查流程</h2>
<p>翻譯 review 要獨立成一輪，放在一般命名 / grep-ability 檢查附近。它不取代文章的意圖檢查、語氣檢查或邊界檢查，而是補上「語言轉換後邏輯是否仍成立」這個角度。</p>
<table>
  <thead>
      <tr>
          <th>Pass</th>
          <th>問題</th>
          <th>操作</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1. 來源定位</td>
          <td>哪些句子來自翻譯 / 轉譯？</td>
          <td>標記英文材料、AI 產出、改寫段落</td>
      </tr>
      <tr>
          <td>2. 術語枚舉</td>
          <td>哪些中文詞由英文概念翻來？</td>
          <td>grep 英文括號、標題、表格第一欄、index entry</td>
      </tr>
      <tr>
          <td>3. 原文錨點</td>
          <td>第一次出現是否保留 original term？</td>
          <td>補「中文術語（original term）」</td>
      </tr>
      <tr>
          <td>4. 句內角色</td>
          <td>中文詞在句中扮演的角色是否對？</td>
          <td>標出主詞、動詞、受詞、修飾語</td>
      </tr>
      <tr>
          <td>5. 前提檢查</td>
          <td>中文是否多出原文沒有的前提？</td>
          <td>問「這個修飾語 / 判斷從原文哪裡來？」</td>
      </tr>
      <tr>
          <td>6. 因果檢查</td>
          <td>譯名是否改變段落推論方向？</td>
          <td>重寫「因為 X，所以 Y」，確認 X 沒被換掉</td>
      </tr>
      <tr>
          <td>7. 追問檢查</td>
          <td>reader 看到中文會追問正確問題嗎？</td>
          <td>問「他會問 A 還是 B？」；問錯方向就重譯</td>
      </tr>
      <tr>
          <td>8. Surface 同步</td>
          <td>metadata / navigation 是否也對位？</td>
          <td>掃 title、description、heading、link label</td>
      </tr>
  </tbody>
</table>
<p>這輪可以很短，但不能省。文章轉譯時，最容易被放過的錯誤就是「中文通順、邏輯錯位」。</p>
<hr>
<h2 id="原文錨點與完整名詞頭">原文錨點與完整名詞頭</h2>
<p>原文錨點負責保留概念邊界，完整名詞頭負責讓中文術語離開原句仍能獨立成立。兩者是翻譯 review 的輔助工具，不是最終目的；最終目的仍是句內邏輯對位。</p>
<table>
  <thead>
      <tr>
          <th>工具</th>
          <th>解決什麼問題</th>
          <th>檢查問題</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>原文錨點</td>
          <td>中文譯名可能偏離原概念</td>
          <td>第一次出現是否保留 original term</td>
      </tr>
      <tr>
          <td>完整名詞頭</td>
          <td>中文壓縮後像片語殘片</td>
          <td>這個詞是否能回答「這是什麼」</td>
      </tr>
      <tr>
          <td>定義句</td>
          <td>reader 不知道本文採用哪個概念邊界</td>
          <td>是否用一句話說明本文用法</td>
      </tr>
      <tr>
          <td>常見譯名段</td>
          <td>同一英文有多個中文譯名</td>
          <td>是否列出但選一個 canonical</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="反模式">反模式</h2>
<table>
  <thead>
      <tr>
          <th>反模式</th>
          <th>症狀</th>
          <th>修法</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>字根直譯</td>
          <td>中文每個字都像對，但整句邏輯多出前提</td>
          <td>回到句內角色與概念責任</td>
      </tr>
      <tr>
          <td>中文順口即放行</td>
          <td>reviewer 覺得好讀，後面論證卻換了問題</td>
          <td>加句內邏輯 pass</td>
      </tr>
      <tr>
          <td>只查字典不放回原句</td>
          <td>譯名本身可用，放進本文語境不成立</td>
          <td>用本文句子重新測試</td>
      </tr>
      <tr>
          <td>只保留原文但不定義</td>
          <td>reader 知道英文，仍不知道本文採用哪個邊界</td>
          <td>補本文定義句</td>
      </tr>
      <tr>
          <td>只改正文、不改 navigation</td>
          <td>title / heading / link label 仍傳播舊譯名</td>
          <td>跑 surface 同步</td>
      </tr>
      <tr>
          <td>AI 翻譯後只做潤稿</td>
          <td>潤稿讓錯譯更順，反而更難發現</td>
          <td>潤稿前先做翻譯邏輯 review</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="最小檢查表">最小檢查表</h2>
<ul>
<li><input disabled="" type="checkbox"> 所有翻譯 / 轉譯來的術語第一次出現都有原文錨點</li>
<li><input disabled="" type="checkbox"> 每個譯名放回原句後，主詞、動詞、受詞、修飾語都成立</li>
<li><input disabled="" type="checkbox"> 中文修飾語沒有引入原文沒有的前提</li>
<li><input disabled="" type="checkbox"> 段落因果可寫成「因為 X，所以 Y」，且 X 沒被譯名換掉</li>
<li><input disabled="" type="checkbox"> reader 看到中文詞會追問原文核心問題</li>
<li><input disabled="" type="checkbox"> title、heading、description、link label 沒有殘留舊譯名</li>
</ul>
<p><strong>核心</strong>：翻譯 review 的核心是確認語言轉換後，句子仍在說同一件事。</p>
]]></content:encoded></item><item><title>Compositional Writing — 組合式寫作方法論</title><link>https://tarrragon.github.io/blog/skills/compositional-writing/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/skills/compositional-writing/</guid><description>&lt;h2 id="這個資料夾是什麼">這個資料夾是什麼&lt;/h2>
&lt;p>&lt;code>compositional-writing&lt;/code> 是一套寫作方法論 skill，原生位置在 &lt;a href="https://github.com/tarrragon/blog/tree/main/.claude/skills/compositional-writing">&lt;code>.claude/skills/compositional-writing/&lt;/code>&lt;/a> 供 Claude runtime 呼叫；這份是&lt;strong>同內容的文章版本&lt;/strong>，讓人類讀者也能直接在 blog 閱讀。&lt;/p>
&lt;p>核心是把寫作看成「原子卡片組合」：每段文字只承載一個概念、可獨立閱讀、可跨情境重用。適用情境涵蓋程式碼註解、文件、log、prompt、欄位設計、完整長篇技術文章與外部分析材料轉教學文章。&lt;/p>
&lt;h2 id="閱讀順序">閱讀順序&lt;/h2>
&lt;h3 id="場景-1第一次接觸">場景 1：第一次接觸&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>順序&lt;/th>
 &lt;th>檔案&lt;/th>
 &lt;th>目的&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>1&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/skills/compositional-writing/skill/" data-link-title="Compositional Writing" data-link-desc="Composes atomic, intent-revealing, grep-friendly writing (Zettelkasten) for code comments, docs, log">SKILL.md&lt;/a>&lt;/td>
 &lt;td>核心支柱 + 核心原則速查、觸發路由&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>2&lt;/td>
 &lt;td>依情境挑一份 reference（見下表）&lt;/td>
 &lt;td>把原則翻譯成可套用的檢查項與範例&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>3&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/skills/compositional-writing/meta-metrics/" data-link-title="Meta Metrics — 寫作品質量化驗收" data-link-desc="compositional-writing reference：M1–M5 指標定義、量測方式、自評表。">meta-metrics.md&lt;/a>&lt;/td>
 &lt;td>用 M1–M2 自評寫作成果&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="場景-2已熟悉原則想直接解決當前任務">場景 2：已熟悉原則、想直接解決當前任務&lt;/h3>
&lt;p>直接依觸發情境跳對應 reference：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>觸發情境&lt;/th>
 &lt;th>reference&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>要寫或改一段程式碼註解 / doc comment&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/skills/compositional-writing/writing-code-comments/" data-link-title="Writing Code Comments — 程式碼註解撰寫指引" data-link-desc="compositional-writing reference：將核心原則翻譯成程式碼註解 / doc comment 的具體檢查項與範例。">writing-code-comments&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>要起草 / 改寫一份文件（worklog、spec、README）&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/skills/compositional-writing/writing-documents/" data-link-title="Writing Documents — 文件撰寫指引" data-link-desc="compositional-writing reference：worklog、spec、README 等文件起草與改寫。">writing-documents&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>要設計 log / 錯誤訊息 / 結構化輸出&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/skills/compositional-writing/writing-logs/" data-link-title="Writing Logs — log 與結構化輸出撰寫指引" data-link-desc="compositional-writing reference：log / 錯誤訊息 / 結構化輸出的欄位設計與措辭。">writing-logs&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>要撰寫給 AI 的 prompt / instruction&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/skills/compositional-writing/writing-prompts/" data-link-title="Writing Prompts — AI prompt / instruction 撰寫指引" data-link-desc="compositional-writing reference：prompt / Agent 派發 / Ticket Context Bundle 的撰寫規範。">writing-prompts&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>要撰寫完整長篇技術文章&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/skills/compositional-writing/writing-articles/" data-link-title="Writing Articles — 完整長篇技術文章撰寫指引" data-link-desc="compositional-writing reference：blog post、post-mortem、架構決策、除錯復盤等需要保留思考過程的長篇內容。">writing-articles&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>要把外部分析材料轉成教學型分析文章&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/skills/compositional-writing/source-to-teaching-analysis/" data-link-title="Source to Teaching Analysis — 外部分析材料轉教學文章" data-link-desc="compositional-writing reference：把分析師文章、投資人備忘錄、產業評論、研究摘要或 AI 轉寫稿，轉成讀者可重用的教學型分析文章。">source-to-teaching-analysis&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>要管理多篇相關文章的結構（系列、文集、知識庫）&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/skills/compositional-writing/managing-article-collections/" data-link-title="Managing Article Collections — 跨多篇相關文章的結構設計" data-link-desc="compositional-writing reference：跨多篇相關文章的結構設計（三層、素材庫比例、MOC、Pattern 卡片、跨篇引用 idiom）。">managing-article-collections&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>要設計 ticket 欄位 / schema frontmatter&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/skills/compositional-writing/designing-fields/" data-link-title="Designing Fields — 欄位設計指引" data-link-desc="compositional-writing reference：ticket 欄位、schema frontmatter、表單欄位的六欄位角度總表。">designing-fields&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>六欄位範例詳查（正確 + 混淆對照）&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/skills/compositional-writing/designing-fields-ticket-6w/" data-link-title="Designing Fields Ticket 6W — 六欄位詳細範例" data-link-desc="compositional-writing reference：正確 &amp;#43; 混淆共 12 項的六欄位範例（搭配 designing-fields 按需閱讀）。">designing-fields-ticket-6w&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>驗證寫作品質（認知負擔、獨立理解率）&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/skills/compositional-writing/meta-metrics/" data-link-title="Meta Metrics — 寫作品質量化驗收" data-link-desc="compositional-writing reference：M1–M5 指標定義、量測方式、自評表。">meta-metrics&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>新增或修改一份 Skill reference&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/skills/compositional-writing/reference-authoring-standards/" data-link-title="Reference Authoring Standards — Skill reference 撰寫品質規範" data-link-desc="compositional-writing reference：新增或修改 Skill reference 的結構標準與撰寫品質規範。">reference-authoring-standards&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>驗收 Skill 發布品質（dry-run）&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/skills/compositional-writing/dry-run-guide/" data-link-title="Dry-run Guide — Skill 發布前語意層驗收" data-link-desc="compositional-writing reference：Phase 2 dry-run 流程 — 驗收 Skill 發布品質的語意層方法。">dry-run-guide&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>每份 reference 自包含：讀任一份不需要回頭讀其他 reference。&lt;/p></description><content:encoded><![CDATA[<h2 id="這個資料夾是什麼">這個資料夾是什麼</h2>
<p><code>compositional-writing</code> 是一套寫作方法論 skill，原生位置在 <a href="https://github.com/tarrragon/blog/tree/main/.claude/skills/compositional-writing"><code>.claude/skills/compositional-writing/</code></a> 供 Claude runtime 呼叫；這份是<strong>同內容的文章版本</strong>，讓人類讀者也能直接在 blog 閱讀。</p>
<p>核心是把寫作看成「原子卡片組合」：每段文字只承載一個概念、可獨立閱讀、可跨情境重用。適用情境涵蓋程式碼註解、文件、log、prompt、欄位設計、完整長篇技術文章與外部分析材料轉教學文章。</p>
<h2 id="閱讀順序">閱讀順序</h2>
<h3 id="場景-1第一次接觸">場景 1：第一次接觸</h3>
<table>
  <thead>
      <tr>
          <th>順序</th>
          <th>檔案</th>
          <th>目的</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1</td>
          <td><a href="/blog/skills/compositional-writing/skill/" data-link-title="Compositional Writing" data-link-desc="Composes atomic, intent-revealing, grep-friendly writing (Zettelkasten) for code comments, docs, log">SKILL.md</a></td>
          <td>核心支柱 + 核心原則速查、觸發路由</td>
      </tr>
      <tr>
          <td>2</td>
          <td>依情境挑一份 reference（見下表）</td>
          <td>把原則翻譯成可套用的檢查項與範例</td>
      </tr>
      <tr>
          <td>3</td>
          <td><a href="/blog/skills/compositional-writing/meta-metrics/" data-link-title="Meta Metrics — 寫作品質量化驗收" data-link-desc="compositional-writing reference：M1–M5 指標定義、量測方式、自評表。">meta-metrics.md</a></td>
          <td>用 M1–M2 自評寫作成果</td>
      </tr>
  </tbody>
</table>
<h3 id="場景-2已熟悉原則想直接解決當前任務">場景 2：已熟悉原則、想直接解決當前任務</h3>
<p>直接依觸發情境跳對應 reference：</p>
<table>
  <thead>
      <tr>
          <th>觸發情境</th>
          <th>reference</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>要寫或改一段程式碼註解 / doc comment</td>
          <td><a href="/blog/skills/compositional-writing/writing-code-comments/" data-link-title="Writing Code Comments — 程式碼註解撰寫指引" data-link-desc="compositional-writing reference：將核心原則翻譯成程式碼註解 / doc comment 的具體檢查項與範例。">writing-code-comments</a></td>
      </tr>
      <tr>
          <td>要起草 / 改寫一份文件（worklog、spec、README）</td>
          <td><a href="/blog/skills/compositional-writing/writing-documents/" data-link-title="Writing Documents — 文件撰寫指引" data-link-desc="compositional-writing reference：worklog、spec、README 等文件起草與改寫。">writing-documents</a></td>
      </tr>
      <tr>
          <td>要設計 log / 錯誤訊息 / 結構化輸出</td>
          <td><a href="/blog/skills/compositional-writing/writing-logs/" data-link-title="Writing Logs — log 與結構化輸出撰寫指引" data-link-desc="compositional-writing reference：log / 錯誤訊息 / 結構化輸出的欄位設計與措辭。">writing-logs</a></td>
      </tr>
      <tr>
          <td>要撰寫給 AI 的 prompt / instruction</td>
          <td><a href="/blog/skills/compositional-writing/writing-prompts/" data-link-title="Writing Prompts — AI prompt / instruction 撰寫指引" data-link-desc="compositional-writing reference：prompt / Agent 派發 / Ticket Context Bundle 的撰寫規範。">writing-prompts</a></td>
      </tr>
      <tr>
          <td>要撰寫完整長篇技術文章</td>
          <td><a href="/blog/skills/compositional-writing/writing-articles/" data-link-title="Writing Articles — 完整長篇技術文章撰寫指引" data-link-desc="compositional-writing reference：blog post、post-mortem、架構決策、除錯復盤等需要保留思考過程的長篇內容。">writing-articles</a></td>
      </tr>
      <tr>
          <td>要把外部分析材料轉成教學型分析文章</td>
          <td><a href="/blog/skills/compositional-writing/source-to-teaching-analysis/" data-link-title="Source to Teaching Analysis — 外部分析材料轉教學文章" data-link-desc="compositional-writing reference：把分析師文章、投資人備忘錄、產業評論、研究摘要或 AI 轉寫稿，轉成讀者可重用的教學型分析文章。">source-to-teaching-analysis</a></td>
      </tr>
      <tr>
          <td>要管理多篇相關文章的結構（系列、文集、知識庫）</td>
          <td><a href="/blog/skills/compositional-writing/managing-article-collections/" data-link-title="Managing Article Collections — 跨多篇相關文章的結構設計" data-link-desc="compositional-writing reference：跨多篇相關文章的結構設計（三層、素材庫比例、MOC、Pattern 卡片、跨篇引用 idiom）。">managing-article-collections</a></td>
      </tr>
      <tr>
          <td>要設計 ticket 欄位 / schema frontmatter</td>
          <td><a href="/blog/skills/compositional-writing/designing-fields/" data-link-title="Designing Fields — 欄位設計指引" data-link-desc="compositional-writing reference：ticket 欄位、schema frontmatter、表單欄位的六欄位角度總表。">designing-fields</a></td>
      </tr>
      <tr>
          <td>六欄位範例詳查（正確 + 混淆對照）</td>
          <td><a href="/blog/skills/compositional-writing/designing-fields-ticket-6w/" data-link-title="Designing Fields Ticket 6W — 六欄位詳細範例" data-link-desc="compositional-writing reference：正確 &#43; 混淆共 12 項的六欄位範例（搭配 designing-fields 按需閱讀）。">designing-fields-ticket-6w</a></td>
      </tr>
      <tr>
          <td>驗證寫作品質（認知負擔、獨立理解率）</td>
          <td><a href="/blog/skills/compositional-writing/meta-metrics/" data-link-title="Meta Metrics — 寫作品質量化驗收" data-link-desc="compositional-writing reference：M1–M5 指標定義、量測方式、自評表。">meta-metrics</a></td>
      </tr>
      <tr>
          <td>新增或修改一份 Skill reference</td>
          <td><a href="/blog/skills/compositional-writing/reference-authoring-standards/" data-link-title="Reference Authoring Standards — Skill reference 撰寫品質規範" data-link-desc="compositional-writing reference：新增或修改 Skill reference 的結構標準與撰寫品質規範。">reference-authoring-standards</a></td>
      </tr>
      <tr>
          <td>驗收 Skill 發布品質（dry-run）</td>
          <td><a href="/blog/skills/compositional-writing/dry-run-guide/" data-link-title="Dry-run Guide — Skill 發布前語意層驗收" data-link-desc="compositional-writing reference：Phase 2 dry-run 流程 — 驗收 Skill 發布品質的語意層方法。">dry-run-guide</a></td>
      </tr>
  </tbody>
</table>
<p>每份 reference 自包含：讀任一份不需要回頭讀其他 reference。</p>
<h2 id="與-blog-專案其他資料的關係">與 blog 專案其他資料的關係</h2>
<table>
  <thead>
      <tr>
          <th>位置</th>
          <th>角色</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>.claude/skills/compositional-writing/</code></td>
          <td>實際 skill — Claude runtime 呼叫的檔案來源</td>
      </tr>
      <tr>
          <td><code>content/skills/compositional-writing/</code>（本處）</td>
          <td>文章版本 — 人類讀者在 blog 閱讀</td>
      </tr>
      <tr>
          <td><code>content/posts/markdown-writing-spec.md</code></td>
          <td>Blog 自己的 markdown 寫作規範（mdtools 檢查項目、與本 skill 並行）</td>
      </tr>
      <tr>
          <td><code>content/posts/tech_writing_structure.md</code></td>
          <td>長篇技術文章結構（writing-articles 的來源之一）</td>
      </tr>
  </tbody>
</table>
<h2 id="last-updated">Last Updated</h2>
<p>2026-05-20 — 同步到 <code>.claude/skills/compositional-writing/</code> @ v0.9.2：</p>
<ul>
<li>v0.9.2 — 新增 source-to-teaching-analysis.md，處理外部分析材料轉教學型分析文章</li>
</ul>
<p>歷史版本：</p>
<ul>
<li>
<p>v0.4.0 — 新增 managing-article-collections.md（跨多篇文章結構）</p>
</li>
<li>
<p>v0.5.0 — 機會成本語氣補強（選項數由議題決定、idiom 庫、三類 structure 模板）</p>
</li>
<li>
<p>v0.6.0 — references 拆分減少過載 + 規則八「自我應用 (dogfooding)」</p>
</li>
<li>
<p>2026-04-24 — 初版文章化：v0.3.0 同步</p>
</li>
</ul>
]]></content:encoded></item><item><title>Managing Article Collections — 跨多篇相關文章的結構設計</title><link>https://tarrragon.github.io/blog/skills/compositional-writing/managing-article-collections/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/skills/compositional-writing/managing-article-collections/</guid><description>&lt;p>本文件處理「一個主題累積多篇相關文章後、如何維持可導航、可組合、不發散」的情境。適用於開發檢討集（report folder）、系列 blog post、技術知識庫、產品文件群。&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>自包含聲明&lt;/strong>：本文件不依賴其他 reference。讀完即可獨立判斷一個 article collection 該怎麼結構化。&lt;/p>
&lt;p>&lt;strong>與 writing-articles.md 的分工&lt;/strong>：那篇處理「單篇文章內部如何寫」、本篇處理「多篇文章之間如何組合」。兩篇互補、各管不同 scale。&lt;/p>&lt;/blockquote>
&lt;hr>
&lt;h2 id="適用範圍">適用範圍&lt;/h2>
&lt;p>當以下任一條件成立、考慮讀本檔：&lt;/p>
&lt;ul>
&lt;li>同一主題下已有 ≥ 5 篇文章、且預期還會增加&lt;/li>
&lt;li>多篇文章之間發現「重複的概念、重複的範例、重複的引用」&lt;/li>
&lt;li>索引（MOC / TOC）變得龐大、超過 200 行仍無法路由清楚&lt;/li>
&lt;li>寫第 N 篇時發現「我這條原則已經在前幾篇講過了、但讀者每次都要重讀」&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="三層結構">三層結構&lt;/h2>
&lt;p>跨多篇的 article collection 自然呈現三層、每層職責不同。寫作前先判斷你要寫的篇章屬於哪一層、避免層級混淆。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>層&lt;/th>
 &lt;th>角色&lt;/th>
 &lt;th>焦點&lt;/th>
 &lt;th>例（report folder）&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>抽象原則&lt;/strong>&lt;/td>
 &lt;td>跨情境共用的元規則&lt;/td>
 &lt;td>「這條原則為什麼成立」&lt;/td>
 &lt;td>#42 2 次門檻&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>情境檢討&lt;/strong>&lt;/td>
 &lt;td>「這次任務該怎麼做」&lt;/td>
 &lt;td>「這次的取捨選了什麼、付了什麼代價」&lt;/td>
 &lt;td>#14 Selector 精準度&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Pattern 卡片&lt;/strong>&lt;/td>
 &lt;td>「某做法什麼時候用」&lt;/td>
 &lt;td>「這個 pattern 的適用邊界與實作細節」&lt;/td>
 &lt;td>#46 Document 全文件 query&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="各層的內容邊界">各層的內容邊界&lt;/h3>
&lt;p>&lt;strong>抽象原則層&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>不寫具體 case（具體 case 在情境檢討層）&lt;/li>
&lt;li>寫「機制 / 為什麼這條規則成立 / 跨情境如何辨識」&lt;/li>
&lt;li>結尾列出對應的情境檢討篇、各自示範這條原則的哪個面向&lt;/li>
&lt;li>不寫「跟其他原則的關係」（那是 MOC 的責任）&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>情境檢討層&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>寫「這次的具體任務、當時的限制、選了什麼、為什麼」&lt;/li>
&lt;li>用機會成本語氣描述方案（A/B/C/D 多選項、不用「正確 vs 不足」）&lt;/li>
&lt;li>取捨段落中可引用 Pattern 卡片&lt;/li>
&lt;li>結尾可援引抽象原則層、但不重述&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Pattern 卡片層&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>寫「這個 pattern 的核心動作、適合 / 不適合的情境、設計細節」&lt;/li>
&lt;li>結尾列出「跟其他做法的取捨」（橫向比較同維度的其他 pattern）&lt;/li>
&lt;li>不寫該 pattern 在某個具體任務的應用（那是情境檢討層）&lt;/li>
&lt;li>卡片可被多篇情境檢討篇共同引用&lt;/li>
&lt;/ul>
&lt;h3 id="層級混淆的失敗模式">層級混淆的失敗模式&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>失敗模式&lt;/th>
 &lt;th>表現&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>抽象原則寫具體 case&lt;/td>
 &lt;td>變成又一篇情境檢討、跟對應實作篇重複&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>情境檢討寫成 Pattern 卡片&lt;/td>
 &lt;td>變成「這個做法的完整指引」、失去「這次任務」脈絡&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Pattern 卡片寫成情境檢討&lt;/td>
 &lt;td>變成「這次我用 X 做了 Y」、失去 pattern 跨情境可重用性&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>寫之前自問：「這篇是給『遇到同類問題的讀者』看、還是給『要套用某個 pattern 的讀者』看、還是給『要學一條跨情境原則的讀者』看？」答案決定該寫哪一層。&lt;/p>
&lt;hr>
&lt;h2 id="抽象層辨識訊號">抽象層辨識訊號&lt;/h2>
&lt;p>抽象層卡片不是隨意添加的、有明確觸發訊號：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>訊號&lt;/th>
 &lt;th>行動&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>多篇實作隱含同一原則但都沒寫出來&lt;/td>
 &lt;td>抽出抽象層卡片&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>寫第三篇 X 類情境時、自我意識「這條原則我已經講過三次」&lt;/td>
 &lt;td>抽出抽象層卡片、之後三篇引用即可&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>三篇實作篇都用「2 次門檻」當隱含假設&lt;/td>
 &lt;td>抽出抽象層卡片明寫&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>反訊號&lt;/strong>（不該抽抽象層）：&lt;/p>
&lt;ul>
&lt;li>只有兩篇看似相關 — 證據不足、可能只是巧合相似&lt;/li>
&lt;li>抽出來後讀者沒有獨立 grep 該抽象層的需求&lt;/li>
&lt;li>抽象層內容會跟某篇實作篇高度重疊（表示原則跟情境綁太緊、抽不出真正的抽象）&lt;/li>
&lt;/ul>
&lt;p>抽象層是&lt;strong>精煉&lt;/strong>、不是分類 — 必須有獨立的「機制 / 為什麼」可寫、不只是把幾篇實作篇的標題列在一起。&lt;/p>
&lt;hr>
&lt;h2 id="pattern-卡片辨識訊號">Pattern 卡片辨識訊號&lt;/h2>
&lt;p>Pattern 卡片從情境檢討的「設計取捨段落」中抽出。判讀訊號：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>訊號&lt;/th>
 &lt;th>行動&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>取捨段落某選項的內容超過 3-4 個段落&lt;/td>
 &lt;td>評估抽 Pattern 卡片&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>寫到「這個做法在 #N 也有用到」第二次&lt;/td>
 &lt;td>抽 Pattern 卡片、之後多篇共用&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>該選項有獨立的失敗模式 / 設計細節 / 應用範例&lt;/td>
 &lt;td>適合抽&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>取捨段落變成「我先把這個 pattern 完整說完、再講其他選項」&lt;/td>
 &lt;td>該抽、不然取捨段落失衡&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>反訊號&lt;/strong>（不該抽 Pattern 卡片）：&lt;/p>
&lt;ul>
&lt;li>該選項只在「容忍度」這類單一參數上跟其他選項不同 — 留 inline、抽出收益低&lt;/li>
&lt;li>該選項是反模式、沒有獨立應用情境 — 留 inline 當對比&lt;/li>
&lt;li>該選項只在這一篇出現、未來不太可能被其他篇引用 — 留 inline&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>核心判準&lt;/strong>：抽出後是否多篇受惠？只有一篇用到、抽出純粹是 fragmentation。&lt;/p>
&lt;hr>
&lt;h2 id="素材庫與情境比例設計">素材庫與情境比例設計&lt;/h2>
&lt;p>跨多篇文章需要同時管理「讀者會看到的情境」與「作者用來支撐情境的素材」。文章情境負責教讀者推演，素材庫負責支撐反向驗證、壓力變體與後續擴寫；兩者的數量不必相同。&lt;/p>
&lt;h3 id="比例原則">比例原則&lt;/h3>
&lt;p>當一組文章要靠真實案例、研究來源或事件材料支撐時，採「少情境、多素材」比例。文章只選 4-5 個主情境，素材庫保留約 2-3 倍的 field cases 或 source cards。&lt;/p></description><content:encoded><![CDATA[<p>本文件處理「一個主題累積多篇相關文章後、如何維持可導航、可組合、不發散」的情境。適用於開發檢討集（report folder）、系列 blog post、技術知識庫、產品文件群。</p>
<blockquote>
<p><strong>自包含聲明</strong>：本文件不依賴其他 reference。讀完即可獨立判斷一個 article collection 該怎麼結構化。</p>
<p><strong>與 writing-articles.md 的分工</strong>：那篇處理「單篇文章內部如何寫」、本篇處理「多篇文章之間如何組合」。兩篇互補、各管不同 scale。</p></blockquote>
<hr>
<h2 id="適用範圍">適用範圍</h2>
<p>當以下任一條件成立、考慮讀本檔：</p>
<ul>
<li>同一主題下已有 ≥ 5 篇文章、且預期還會增加</li>
<li>多篇文章之間發現「重複的概念、重複的範例、重複的引用」</li>
<li>索引（MOC / TOC）變得龐大、超過 200 行仍無法路由清楚</li>
<li>寫第 N 篇時發現「我這條原則已經在前幾篇講過了、但讀者每次都要重讀」</li>
</ul>
<hr>
<h2 id="三層結構">三層結構</h2>
<p>跨多篇的 article collection 自然呈現三層、每層職責不同。寫作前先判斷你要寫的篇章屬於哪一層、避免層級混淆。</p>
<table>
  <thead>
      <tr>
          <th>層</th>
          <th>角色</th>
          <th>焦點</th>
          <th>例（report folder）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>抽象原則</strong></td>
          <td>跨情境共用的元規則</td>
          <td>「這條原則為什麼成立」</td>
          <td>#42 2 次門檻</td>
      </tr>
      <tr>
          <td><strong>情境檢討</strong></td>
          <td>「這次任務該怎麼做」</td>
          <td>「這次的取捨選了什麼、付了什麼代價」</td>
          <td>#14 Selector 精準度</td>
      </tr>
      <tr>
          <td><strong>Pattern 卡片</strong></td>
          <td>「某做法什麼時候用」</td>
          <td>「這個 pattern 的適用邊界與實作細節」</td>
          <td>#46 Document 全文件 query</td>
      </tr>
  </tbody>
</table>
<h3 id="各層的內容邊界">各層的內容邊界</h3>
<p><strong>抽象原則層</strong>：</p>
<ul>
<li>不寫具體 case（具體 case 在情境檢討層）</li>
<li>寫「機制 / 為什麼這條規則成立 / 跨情境如何辨識」</li>
<li>結尾列出對應的情境檢討篇、各自示範這條原則的哪個面向</li>
<li>不寫「跟其他原則的關係」（那是 MOC 的責任）</li>
</ul>
<p><strong>情境檢討層</strong>：</p>
<ul>
<li>寫「這次的具體任務、當時的限制、選了什麼、為什麼」</li>
<li>用機會成本語氣描述方案（A/B/C/D 多選項、不用「正確 vs 不足」）</li>
<li>取捨段落中可引用 Pattern 卡片</li>
<li>結尾可援引抽象原則層、但不重述</li>
</ul>
<p><strong>Pattern 卡片層</strong>：</p>
<ul>
<li>寫「這個 pattern 的核心動作、適合 / 不適合的情境、設計細節」</li>
<li>結尾列出「跟其他做法的取捨」（橫向比較同維度的其他 pattern）</li>
<li>不寫該 pattern 在某個具體任務的應用（那是情境檢討層）</li>
<li>卡片可被多篇情境檢討篇共同引用</li>
</ul>
<h3 id="層級混淆的失敗模式">層級混淆的失敗模式</h3>
<table>
  <thead>
      <tr>
          <th>失敗模式</th>
          <th>表現</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>抽象原則寫具體 case</td>
          <td>變成又一篇情境檢討、跟對應實作篇重複</td>
      </tr>
      <tr>
          <td>情境檢討寫成 Pattern 卡片</td>
          <td>變成「這個做法的完整指引」、失去「這次任務」脈絡</td>
      </tr>
      <tr>
          <td>Pattern 卡片寫成情境檢討</td>
          <td>變成「這次我用 X 做了 Y」、失去 pattern 跨情境可重用性</td>
      </tr>
  </tbody>
</table>
<p>寫之前自問：「這篇是給『遇到同類問題的讀者』看、還是給『要套用某個 pattern 的讀者』看、還是給『要學一條跨情境原則的讀者』看？」答案決定該寫哪一層。</p>
<hr>
<h2 id="抽象層辨識訊號">抽象層辨識訊號</h2>
<p>抽象層卡片不是隨意添加的、有明確觸發訊號：</p>
<table>
  <thead>
      <tr>
          <th>訊號</th>
          <th>行動</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>多篇實作隱含同一原則但都沒寫出來</td>
          <td>抽出抽象層卡片</td>
      </tr>
      <tr>
          <td>寫第三篇 X 類情境時、自我意識「這條原則我已經講過三次」</td>
          <td>抽出抽象層卡片、之後三篇引用即可</td>
      </tr>
      <tr>
          <td>三篇實作篇都用「2 次門檻」當隱含假設</td>
          <td>抽出抽象層卡片明寫</td>
      </tr>
  </tbody>
</table>
<p><strong>反訊號</strong>（不該抽抽象層）：</p>
<ul>
<li>只有兩篇看似相關 — 證據不足、可能只是巧合相似</li>
<li>抽出來後讀者沒有獨立 grep 該抽象層的需求</li>
<li>抽象層內容會跟某篇實作篇高度重疊（表示原則跟情境綁太緊、抽不出真正的抽象）</li>
</ul>
<p>抽象層是<strong>精煉</strong>、不是分類 — 必須有獨立的「機制 / 為什麼」可寫、不只是把幾篇實作篇的標題列在一起。</p>
<hr>
<h2 id="pattern-卡片辨識訊號">Pattern 卡片辨識訊號</h2>
<p>Pattern 卡片從情境檢討的「設計取捨段落」中抽出。判讀訊號：</p>
<table>
  <thead>
      <tr>
          <th>訊號</th>
          <th>行動</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>取捨段落某選項的內容超過 3-4 個段落</td>
          <td>評估抽 Pattern 卡片</td>
      </tr>
      <tr>
          <td>寫到「這個做法在 #N 也有用到」第二次</td>
          <td>抽 Pattern 卡片、之後多篇共用</td>
      </tr>
      <tr>
          <td>該選項有獨立的失敗模式 / 設計細節 / 應用範例</td>
          <td>適合抽</td>
      </tr>
      <tr>
          <td>取捨段落變成「我先把這個 pattern 完整說完、再講其他選項」</td>
          <td>該抽、不然取捨段落失衡</td>
      </tr>
  </tbody>
</table>
<p><strong>反訊號</strong>（不該抽 Pattern 卡片）：</p>
<ul>
<li>該選項只在「容忍度」這類單一參數上跟其他選項不同 — 留 inline、抽出收益低</li>
<li>該選項是反模式、沒有獨立應用情境 — 留 inline 當對比</li>
<li>該選項只在這一篇出現、未來不太可能被其他篇引用 — 留 inline</li>
</ul>
<p><strong>核心判準</strong>：抽出後是否多篇受惠？只有一篇用到、抽出純粹是 fragmentation。</p>
<hr>
<h2 id="素材庫與情境比例設計">素材庫與情境比例設計</h2>
<p>跨多篇文章需要同時管理「讀者會看到的情境」與「作者用來支撐情境的素材」。文章情境負責教讀者推演，素材庫負責支撐反向驗證、壓力變體與後續擴寫；兩者的數量不必相同。</p>
<h3 id="比例原則">比例原則</h3>
<p>當一組文章要靠真實案例、研究來源或事件材料支撐時，採「少情境、多素材」比例。文章只選 4-5 個主情境，素材庫保留約 2-3 倍的 field cases 或 source cards。</p>
<table>
  <thead>
      <tr>
          <th>層</th>
          <th>建議數量</th>
          <th>責任</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>主文章情境</td>
          <td>4-5 個</td>
          <td>讓讀者看完後能實際演練或套用</td>
      </tr>
      <tr>
          <td>Field cases / source cards</td>
          <td>10-12 張</td>
          <td>支撐情境、反向驗證、補壓力變體</td>
      </tr>
      <tr>
          <td>Scenario cards</td>
          <td>4-5 張</td>
          <td>把多個來源轉成可重播的中性情境</td>
      </tr>
      <tr>
          <td>Pattern cards</td>
          <td>5-7 張</td>
          <td>抽出跨情境共用的做法與判讀欄位</td>
      </tr>
  </tbody>
</table>
<p>比例的核心是讓每個主情境背後至少有 2-3 個來源可支撐。這樣文章能保持可讀，素材庫也能提供足夠的反例、變體與後續延伸材料。</p>
<h3 id="source-first-規則">Source-first 規則</h3>
<p>Field case 的責任是保存可回溯材料。案例型素材先找來源，再抽出觀察、壓力、控制缺口、判讀訊號與可轉譯情境。</p>
<p>Scenario card 的責任是把來源轉譯成可演練情境。情境可以把多個來源合成中性服務壓力，但每個主要壓力點都要能回查到 field case 或 source card。</p>
<p>Pattern card 的責任是歸納。模式可以比單一案例更抽象，但要保留支撐來源、適用邊界、判讀訊號與下一步路由。</p>
<h3 id="何時補素材庫">何時補素材庫</h3>
<table>
  <thead>
      <tr>
          <th>訊號</th>
          <th>行動</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>每個 scenario 只靠 1 個來源支撐</td>
          <td>先補 field cases，再改文章</td>
      </tr>
      <tr>
          <td>情境看起來合理但缺少真實壓力</td>
          <td>查來源，補 defender / operator pressure</td>
      </tr>
      <tr>
          <td>文章只能展示 4-5 個情境，但後續還要擴寫</td>
          <td>素材庫維持 2-3 倍來源量</td>
      </tr>
      <tr>
          <td>Pattern card 只有單一案例支撐</td>
          <td>補第二個來源或降低抽象層級</td>
      </tr>
  </tbody>
</table>
<h3 id="何時停止補素材">何時停止補素材</h3>
<p>素材庫達到「每個主情境 2-3 個來源、每個 pattern 至少 1-2 個支撐案例」後，就先停止擴充。繼續補素材的收益會下降，下一步應轉向寫文章、跑 review，或把素材回寫到 MOC。</p>
<hr>
<h2 id="mocmap-of-content設計">MOC（Map of Content）設計</h2>
<p>跨多篇 collection 的入口（collection index / README / TOC）是 MOC、不是內容。</p>
<h3 id="入口的職責邊界">入口的職責邊界</h3>
<table>
  <thead>
      <tr>
          <th>職責</th>
          <th>是否屬於 MOC</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>列出所有篇、各一行 hook</td>
          <td>是</td>
      </tr>
      <tr>
          <td>按情境分組（路徑 / 場景導讀）</td>
          <td>是</td>
      </tr>
      <tr>
          <td>解釋這個 collection 是什麼</td>
          <td>是（簡短）</td>
      </tr>
      <tr>
          <td>重述各篇的「概要」「outline」</td>
          <td><strong>否</strong>（各篇本身已存在、是冗餘）</td>
      </tr>
      <tr>
          <td>寫實質內容（症狀對應位置表）</td>
          <td><strong>否</strong>（屬於某篇文章內、抽出獨立篇）</td>
      </tr>
  </tbody>
</table>
<h3 id="每條索引條目格式">每條索引條目格式</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">- [<span class="nt">#N 標題</span>](<span class="na">slug/</span>) — 一句話 hook（≤ 150 字）</span></span></code></pre></div><p>關鍵約束：</p>
<ul>
<li>一行為限、不超過 150 字</li>
<li>Hook 講「這篇講什麼問題」、不重述「該怎麼做」</li>
<li>連結用 slug、不用標題（grep 友善）</li>
</ul>
<h3 id="場景導讀">場景導讀</h3>
<p>按任務情境列出多篇路徑、是 MOC 的合理擴展：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl"><span class="gu">### 路徑 N：[任務情境]
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="gu"></span><span class="sb">`#A 標題`</span> → <span class="sb">`#B 標題`</span> → <span class="sb">`#C 標題`</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl">[一兩句說明這條路徑的閱讀邏輯]</span></span></code></pre></div><p>每條路徑長度 3-5 篇、長度超過表示「這條情境本身需要一篇 master」。</p>
<h3 id="moc-該避免的內容">MOC 該避免的內容</h3>
<table>
  <thead>
      <tr>
          <th>反模式</th>
          <th>為什麼避免</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>大綱式內容（每篇下面寫「涵蓋情境」+「理想做法」）</td>
          <td>跟各篇本身重複、各篇自己已寫</td>
      </tr>
      <tr>
          <td>「待補完」狀態標記長期不更新</td>
          <td>索引變成 staleness 來源、誤導讀者</td>
      </tr>
      <tr>
          <td>多層巢狀（「這個是 X、X 包含 A B C、A 包含 a1 a2」）</td>
          <td>讀者迷失導航、超過引用一層深</td>
      </tr>
      <tr>
          <td>各篇的判讀徵兆都列在 MOC</td>
          <td>那是文章內容、MOC 只給入口</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="跨篇引用-protocol">跨篇引用 protocol</h2>
<p>多篇 collection 內互相引用是常態、但要有紀律：</p>
<h3 id="引用要說明為什麼">引用要說明「為什麼」</h3>
<p><strong>好的引用</strong>：</p>
<blockquote>
<p>具體做法（<code>@import url(...) layer(...)</code>）與升級兼容性、其他外部組件的 layer 策略，由 [#24 CSS Layers 取代 specificity 戰] 完整展開。在邊界辨識上、本篇要記住的是：遇到 specificity 30+ 的覆寫戰、改去看 layer 維度。</p></blockquote>
<p><strong>不好的引用</strong>：</p>
<blockquote>
<p>另見 #24。</p></blockquote>
<p>差別是：好引用告訴讀者「為什麼引這個、引去看什麼」、不好引用要讀者自己猜。</p>
<h3 id="引用最多一層深">引用最多一層深</h3>
<p>A 引 B、B 引 C — 讀者從 A 出發、要看完 A + B + C 才能理解、認知負擔過大。</p>
<p>修正方式：</p>
<ul>
<li>把 C 的關鍵點濃縮進 B、B 自包含</li>
<li>或把 B 從引用鏈中移除、A 直接連 C</li>
</ul>
<h3 id="引用方向避免循環">引用方向避免循環</h3>
<p>A 引 B、B 也引 A — 讀者在兩篇之間來回跳、永遠不知道哪篇是「主」。</p>
<p>通常這表示<strong>抽象層缺漏</strong> — A 跟 B 都在援引一個沒寫出來的共同概念、那個概念該抽成抽象層。</p>
<h3 id="引用-idiom-庫">引用 idiom 庫</h3>
<p>從實際 corpus 累積的引用句型、各有適用情境。讀者看到這些句型就知道引用的責任分工：</p>
<h4 id="idiom-1抽象--情境情境檢討引用抽象層">Idiom 1：抽象 ← 情境（情境檢討引用抽象層）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">&gt; 本篇是 [<span class="nt">#42 2 次門檻</span>](<span class="na">path/</span>) 抽象原則在「驗證工具切換」這個面向的應用。</span></span></code></pre></div><ul>
<li><strong>位置</strong>：情境檢討文章開頭、核心原則段落之後</li>
<li><strong>效果</strong>：讀者一眼知道「這篇是某抽象原則的具體應用」、可以選擇先讀抽象層理解 mechanism、或直接讀本篇學具體做法</li>
<li><strong>適用</strong>：情境檢討文章、有對應的抽象層原則時</li>
</ul>
<h4 id="idiom-2責任分工拆分後篇章互相聲明範圍">Idiom 2：責任分工（拆分後篇章互相聲明範圍）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">&gt; </span><span class="ge">本篇焦點：客製 UI 該放哪。
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="ge"></span>&gt; - **framework 元件本身需要動時的安全規則**由 [<span class="nt">#13 JS 操作 framework 元件</span>](<span class="na">path/</span>) 處理</span></span></code></pre></div><ul>
<li><strong>位置</strong>：核心原則段落之後、為什麼段落之前</li>
<li><strong>效果</strong>：明確劃分「本篇 vs 相關篇」的責任邊界、避免讀者期待錯</li>
<li><strong>適用</strong>：拆分過的篇章群（例如 #5/#13 拆分後互相聲明）</li>
</ul>
<h4 id="idiom-3內聯引用段落內援引另一篇處理細節">Idiom 3：內聯引用（段落內援引另一篇處理細節）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">具體做法（<span class="sb">`@import url(...) layer(...)`</span>）與升級兼容性、其他外部組件的
</span></span><span class="line"><span class="ln">2</span><span class="cl">layer 策略、由 [<span class="nt">#24 CSS Layers</span>](<span class="na">path/</span>) 完整展開。在邊界辨識上、
</span></span><span class="line"><span class="ln">3</span><span class="cl">本篇要記住的是：遇到 specificity 30+ 的覆寫戰、改去看 layer 維度。</span></span></code></pre></div><ul>
<li><strong>位置</strong>：段落正文中、講到引用篇主題的地方</li>
<li><strong>效果</strong>：讀者拿到「為什麼引、引去看什麼、本篇仍要記住什麼」三件資訊</li>
<li><strong>適用</strong>：段落主題跟引用篇高度重疊、不適合在本篇重述</li>
</ul>
<h4 id="idiom-4moc-連結索引條目">Idiom 4：MOC 連結（索引條目）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">- [<span class="nt">#42 2 次門檻：第一次是運氣、第二次是訊號</span>](<span class="na">path/</span>) — 串 <span class="ni">#11</span> / <span class="ni">#15</span> / <span class="ni">#20</span> / <span class="ni">#23</span>、跨工具/測試/思路/溝通四面向</span></span></code></pre></div><ul>
<li><strong>位置</strong>：collection index / MOC</li>
<li><strong>效果</strong>：標題 + 一句話 hook、讓讀者選擇要不要進入該篇</li>
<li><strong>格式</strong>：<code>- [#N 標題](slug/) — hook（≤ 150 字）</code></li>
</ul>
<h4 id="idiom-5跨原則的關係表抽象層之間互相對位">Idiom 5：跨原則的關係表（抽象層之間互相對位）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">| 抽象層原則 | 跟本原則的關係 |
</span></span><span class="line"><span class="ln">2</span><span class="cl">|---------|-------------|
</span></span><span class="line"><span class="ln">3</span><span class="cl">| [<span class="nt">#43 最小必要範圍</span>](<span class="na">path/</span>) | 「最小必要範圍」聚焦「縮影響範圍」、本篇聚焦「縮值來源數」、兩者都是「讓行為可預測」的不同面向 |</span></span></code></pre></div><ul>
<li><strong>位置</strong>：抽象層原則篇的「跟其他原則的關係」段落</li>
<li><strong>效果</strong>：讀者看到原則網的形狀、知道哪些原則可以一起援引</li>
</ul>
<h4 id="idiom-6對應的實作篇表抽象--情境--pattern">Idiom 6：對應的實作篇表（抽象 → 情境 / pattern）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">| 篇 | 議題 | 範圍對象 |
</span></span><span class="line"><span class="ln">2</span><span class="cl">|----|------|---------|
</span></span><span class="line"><span class="ln">3</span><span class="cl">| [<span class="nt">#13 元件邊界與 JS 操作</span>](<span class="na">path/</span>) | JS 元件邊界 | 「我可以動什麼」契約 |
</span></span><span class="line"><span class="ln">4</span><span class="cl">| [<span class="nt">#14 Selector 精準度</span>](<span class="na">path/</span>) | DOM query 範圍 | 起點 / 範圍 / 過濾三維度 |</span></span></code></pre></div><ul>
<li><strong>位置</strong>：抽象層原則篇結尾</li>
<li><strong>效果</strong>：讀者依議題挑實作篇、不需要逐篇讀</li>
</ul>
<hr>
<h2 id="三層-structure-詳細對照">三層 structure 詳細對照</h2>
<p>跨多篇 collection 中、三類文章各有不同的 standard structure。對照表先給快速判斷依據、之後是各類完整模板。</p>
<h3 id="段落對照表">段落對照表</h3>
<table>
  <thead>
      <tr>
          <th>段落</th>
          <th>情境檢討</th>
          <th>抽象層原則</th>
          <th>Pattern 卡片</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>核心原則 / 核心做法</td>
          <td>有</td>
          <td>有</td>
          <td>有</td>
      </tr>
      <tr>
          <td>為什麼（商業邏輯 / 機制）</td>
          <td>有</td>
          <td>有</td>
          <td>有</td>
      </tr>
      <tr>
          <td>這次任務情境</td>
          <td>有</td>
          <td>無</td>
          <td>無</td>
      </tr>
      <tr>
          <td>設計取捨 A/B/C/D</td>
          <td>有</td>
          <td>無</td>
          <td>無</td>
      </tr>
      <tr>
          <td>跨情境的應用面向</td>
          <td>無</td>
          <td>有</td>
          <td>無</td>
      </tr>
      <tr>
          <td>適合 / 不適合</td>
          <td>（在設計取捨內）</td>
          <td>有（適用邊界）</td>
          <td>有</td>
      </tr>
      <tr>
          <td>設計細節</td>
          <td>（在執行段內）</td>
          <td>無</td>
          <td>有</td>
      </tr>
      <tr>
          <td>跟其他做法 / 原則的關係</td>
          <td>有，簡短</td>
          <td>有，明文</td>
          <td>有，橫向對照</td>
      </tr>
      <tr>
          <td>對應的實作篇</td>
          <td>無</td>
          <td>有</td>
          <td>無</td>
      </tr>
      <tr>
          <td>應用範例</td>
          <td>（在執行段內）</td>
          <td>無</td>
          <td>有</td>
      </tr>
      <tr>
          <td>判讀徵兆</td>
          <td>有</td>
          <td>有</td>
          <td>有</td>
      </tr>
  </tbody>
</table>
<p><strong>分類錯了、structure 也錯</strong>。寫文章前先判斷：</p>
<ul>
<li>「這篇是某次任務的紀錄嗎？」→ 情境檢討</li>
<li>「這篇是跨多情境的元規則嗎？」→ 抽象層原則</li>
<li>「這篇是某做法的深入指引嗎？」→ Pattern 卡片</li>
</ul>
<h3 id="情境檢討-structure-模板">情境檢討 structure 模板</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## 核心原則
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>[一句話、加粗]
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu">## 為什麼 [這個議題重要]
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu">### 商業邏輯
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu">### [可能的子議題]
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gu">## 這次任務的實際情境
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu">### 觀察
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu">### 判讀
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu">### 執行
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu">## 設計取捨：[維度]
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="gu">### A：[做法]（這個專案的預設）
</span></span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="gu">### B：[替代]
</span></span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="gu">### C：[另一條路]
</span></span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="gu">### D：[極端 / 反模式]
</span></span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="gu">## 跟其他原則的關係（選用）
</span></span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">## 判讀徵兆</span></span></code></pre></div><h3 id="抽象層原則-structure-模板">抽象層原則 structure 模板</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## 核心原則
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>[一句話、加粗]
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu">## 為什麼 [這條原則成立]
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu">### [機制：為什麼這條規則在多情境都成立]
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu">## [這條原則的多個應用面向]
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gu">### 應用 1：[情境名]（→ 實作篇 #N）
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu">### 應用 2：[情境名]（→ 實作篇 #M）
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu">### 應用 3：...
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu">## 不該套用 [本原則] 的情境
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu"></span>[適用邊界]
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="gu">## 跟其他原則的關係
</span></span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="gu"></span>[本原則跟其他抽象層原則的關係]
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="gu">## 對應的實作篇
</span></span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="gu"></span>[一個表、列出每篇示範的面向]
</span></span><span class="line"><span class="ln">20</span><span class="cl">
</span></span><span class="line"><span class="ln">21</span><span class="cl">## 判讀徵兆</span></span></code></pre></div><p>抽象層的取捨在情境邊界、不在方案選項。抽象層讀者面對的決定是「我這次的情境該不該套用這條原則」 — 答案在「適用 vs 不適用的情境邊界」、不在「四個並列方案中選一個」。所以抽象層的對應段落是「不該套用 X 的情境」（邊界釐清）、而非「設計取捨 A/B/C/D」（方案選擇）。</p>
<h3 id="pattern-卡片-structure-模板">Pattern 卡片 structure 模板</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## 核心做法
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>[做法簡述、code 範例]
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu">## 這個做法存在的價值
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu"></span>[為什麼這個做法獨立存在、什麼是它獨有的]
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu">## 適合的情境
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gu"></span>[表格：情境 / 為什麼合理]
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu">## 不適合的情境
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu"></span>[表格：情境 / 為什麼不夠 / 改用 <span class="ni">#N</span> 其他 pattern]
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu">## 設計細節
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="gu"></span>[實作的具體技巧、邊界 case 處理]
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="gu">## 跟其他 pattern 的關係
</span></span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="gu"></span>[橫向比較同維度的其他 pattern、引用情境檢討的設計取捨段落]
</span></span><span class="line"><span class="ln">18</span><span class="cl">
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="gu">## 應用範例
</span></span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="gu"></span>[具體 code 範例]
</span></span><span class="line"><span class="ln">21</span><span class="cl">
</span></span><span class="line"><span class="ln">22</span><span class="cl">## 判讀徵兆</span></span></code></pre></div><p>Pattern 卡片的取捨在橫向對照、不在自家 A/B/C/D。Pattern 卡片本身是某情境檢討「設計取捨 A/B/C/D」中的一個選項（例如某「document query」就是「起點選擇」中的選項 A）。它的讀者面對的決定是「什麼時候用這個 pattern」 — 答案在「跟同維度其他 pattern 的橫向對照」、而非「自家內再分 A/B/C/D」。所以 Pattern 卡片的對應段落是「跟其他 pattern 的關係」（橫向）、而非「設計取捨 A/B/C/D」（縱向）。</p>
<h3 id="structure-分類錯誤的徵兆">structure 分類錯誤的徵兆</h3>
<table>
  <thead>
      <tr>
          <th>徵兆</th>
          <th>分類錯誤</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>抽象層原則寫了「這次任務的實際情境」</td>
          <td>寫成情境檢討 — 抽象層該講機制、不該講某次任務</td>
      </tr>
      <tr>
          <td>抽象層原則硬擠 A/B/C/D 設計取捨</td>
          <td>抽象層該談「適用邊界」、不是方案選項</td>
      </tr>
      <tr>
          <td>Pattern 卡片硬擠 A/B/C/D 設計取捨</td>
          <td>Pattern 卡片該用「跟其他 pattern 橫向對照」</td>
      </tr>
      <tr>
          <td>情境檢討跳過「設計取捨」段落</td>
          <td>情境檢討的核心就是記錄「這次選了什麼、為什麼」</td>
      </tr>
      <tr>
          <td>三類文章共用同一個段落 template</td>
          <td>每類讀者問題不同、template 也該不同</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="拆分判準focus-是議題完整度">拆分判準：focus 是議題完整度</h2>
<p>當不確定一篇該不該拆、判讀的核心問題是：「<strong>這篇文章聚焦在什麼問題？有沒有議題切了一半？</strong>」</p>
<h3 id="兩個常見誤判">兩個常見誤判</h3>
<table>
  <thead>
      <tr>
          <th>誤判</th>
          <th>為什麼錯</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>「兩篇沒衝突 → 不需要拆」</td>
          <td>兩篇可能各切了一半同樣議題、誰都沒講完整</td>
      </tr>
      <tr>
          <td>「邊界很清晰 → 不需要拆」</td>
          <td>篇章內部仍可能塞了兩個獨立議題、傘式標題遮蓋發散</td>
      </tr>
  </tbody>
</table>
<h3 id="寫作--review-雙階段自問">寫作 / review 雙階段自問</h3>
<p>寫作時、寫完先自問三題：</p>
<ol>
<li>這篇聚焦的問題用一句話能說完嗎？</li>
<li>內文每段都服務這個問題嗎？</li>
<li>有沒有段落像是「順便提一下」的離題內容？</li>
</ol>
<p>任一題答否、檢視該段是否該拆 / 移除 / 補進其他篇。</p>
<p>review 時、讀完先問三題：</p>
<ol>
<li>這篇實際聚焦在什麼問題（<strong>不看標題、看內文</strong>判斷）？</li>
<li>標題與內文焦點對得起來嗎？</li>
<li>有沒有兩個獨立議題各佔半篇？</li>
</ol>
<p>兩階段共同特徵：<strong>都需要讀完內文、不能只看大綱</strong>。大綱式 review 看不出議題切了一半、看不出語氣絕對主義、看不出 focus 發散。</p>
<h3 id="議題切了一半的辨識訊號">議題切了一半的辨識訊號</h3>
<ul>
<li>標題用「+」「與」「以及」綁兩個獨立概念</li>
<li>內文有兩段獨立的「為什麼這個機制成立」、各對應一個概念</li>
<li>讀者通常一次只 grep 其中一個關鍵字</li>
<li>列出讀者最可能 grep 的 3 個關鍵字、發現一個關鍵字無法涵蓋全文</li>
<li>即使不衝突、仍該拆</li>
</ul>
<h3 id="反例-vs-正例">反例 vs 正例</h3>
<p><strong>反例</strong>：標題「Selector + Observer 精準度」、合在一篇</p>
<ul>
<li>雖然都用「精準度」這個傘綁、機制完全不同（同步查詢 vs 非同步監聽）</li>
<li>讀者來查「我的 selector 撈太多」只關心 selector 半邊</li>
<li>讀者來查「我的 observer 觸發太頻繁」只關心 observer 半邊</li>
<li>沒有人會兩個問題同時問</li>
</ul>
<p><strong>正例</strong>：拆成兩篇「Selector 精準度」+「Observer 範圍與觸發頻率」、各自完整深入。</p>
<h3 id="拆分後的次要判準">拆分後的次要判準</h3>
<p>議題完整度（focus）通過後、再看共用價值與獨立可讀性：</p>
<table>
  <thead>
      <tr>
          <th>判準</th>
          <th>問題</th>
          <th>行動</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>共用價值</td>
          <td>拆出來的卡片會被多篇引用嗎？</td>
          <td>是 → 拆出成共用素材；否 → 留 inline</td>
      </tr>
      <tr>
          <td>獨立可讀性</td>
          <td>拆出的卡片自己能成立嗎？</td>
          <td>有獨立「機制 / 適用情境 / 失敗模式」可寫 → 能成立</td>
      </tr>
  </tbody>
</table>
<h3 id="不該當判準的偽指標">不該當判準的偽指標</h3>
<ul>
<li><strong>行數多寡</strong>：8KB 的文章可能 focus 緊、3KB 的文章可能議題切兩半</li>
<li><strong>篇章邊界是否清晰</strong>：兩篇沒衝突 ≠ 各自完整</li>
<li><strong>寫的時候是否方便</strong>：方便不是優先序</li>
</ul>
<h3 id="完成標準">完成標準</h3>
<p>寫完後讀者能用一句話說出「這篇在講什麼問題」、且這句話精確到「換成同義不同詞也能說清楚」。若讀者要用兩句話才能涵蓋、表示有兩個議題、該拆。</p>
<hr>
<h2 id="review-與重構訊號">review 與重構訊號</h2>
<p>定期回顧 collection、看下列訊號：</p>
<table>
  <thead>
      <tr>
          <th>訊號</th>
          <th>重構動作</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>多篇用同樣 case 當例子</td>
          <td>抽抽象層、各篇引用</td>
      </tr>
      <tr>
          <td>一篇有 5+ 個取捨段落</td>
          <td>評估抽 Pattern 卡片</td>
      </tr>
      <tr>
          <td>索引重複「概要」+「文章本身」</td>
          <td>索引瘦身</td>
      </tr>
      <tr>
          <td>標題與內文焦點不一致</td>
          <td>改名 / 重寫 / 拆篇</td>
      </tr>
      <tr>
          <td>寫新篇時發現「我這個 pattern 已經在 #N 寫過了」</td>
          <td>抽 Pattern 卡片、新篇引用</td>
      </tr>
      <tr>
          <td>大綱式 review 通過、實際讀內文發現問題</td>
          <td>review process 必須讀內文</td>
      </tr>
  </tbody>
</table>
<h3 id="大綱式-review-的限制">大綱式 review 的限制</h3>
<p>只看標題與大綱、無法判讀：</p>
<ul>
<li>文章內議題是否切了一半</li>
<li>語氣是否絕對主義</li>
<li>各段落是否服務同一個 focus</li>
<li>引用是否有實質說明</li>
</ul>
<p><strong>review 必須讀實際內文</strong> — 大綱只能看「topic 對不對」、不能看「議題完整度 / 語氣 / focus」。</p>
<hr>
<h2 id="自檢清單">自檢清單</h2>
<p>跨多篇 collection 提交前自檢：</p>
<ul>
<li><input disabled="" type="checkbox"> 三層結構就位（抽象原則 / 情境檢討 / Pattern 卡片各層該有的有）</li>
<li><input disabled="" type="checkbox"> 各篇的層級不混淆（抽象層不寫具體 case、情境層不寫成 pattern 完整指引）</li>
<li><input disabled="" type="checkbox"> MOC 入口只做路由、無大綱式冗餘</li>
<li><input disabled="" type="checkbox"> MOC 每條索引一行、不超過 150 字</li>
<li><input disabled="" type="checkbox"> 跨篇引用都說明了「為什麼引用、引去看什麼」</li>
<li><input disabled="" type="checkbox"> 沒有 A→B→C 多層跳躍引用</li>
<li><input disabled="" type="checkbox"> 沒有 A↔B 雙向循環引用（若有、抽抽象層）</li>
<li><input disabled="" type="checkbox"> 沒有議題切了一半的篇章（標題與內文焦點一致）</li>
<li><input disabled="" type="checkbox"> 機會成本語氣跨篇一致（沒有混用「正確概念」與「預設選擇」）</li>
<li><input disabled="" type="checkbox"> 「待補完」狀態標記都更新或移除</li>
</ul>
<hr>
<h2 id="與核心原則的映射">與核心原則的映射</h2>
<table>
  <thead>
      <tr>
          <th>本 reference 規則</th>
          <th>對應核心原則</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>三層結構</td>
          <td>原子化 + 索引建立</td>
          <td>各層卡片獨立、層間用引用串成網</td>
      </tr>
      <tr>
          <td>抽象層辨識</td>
          <td>原子化 + 意圖顯性</td>
          <td>把跨情境的隱含原則明寫成獨立卡片</td>
      </tr>
      <tr>
          <td>Pattern 卡片辨識</td>
          <td>原子化 + 可重用性</td>
          <td>把可跨情境共用的做法抽成獨立素材</td>
      </tr>
      <tr>
          <td>素材庫比例設計</td>
          <td>索引建立 + 可重用性</td>
          <td>文章保留少數主情境、素材庫保留更多來源</td>
      </tr>
      <tr>
          <td>MOC 入口只做路由</td>
          <td>索引建立</td>
          <td>入口不承載細節、避免重複</td>
      </tr>
      <tr>
          <td>跨篇引用要說明為什麼</td>
          <td>意圖顯性</td>
          <td>引用本身要表達意圖、不只連結</td>
      </tr>
      <tr>
          <td>議題完整度優先</td>
          <td>原子化</td>
          <td>拆分依據是 focus、不是邊界</td>
      </tr>
      <tr>
          <td>review 讀內文不只大綱</td>
          <td>可查詢性 + 意圖顯性</td>
          <td>內文是 source of truth、大綱可能 stale</td>
      </tr>
  </tbody>
</table>
<hr>
<p><strong>Last Updated</strong>: 2026-04-30
<strong>Version</strong>: 0.4.0 — 補「素材庫與情境比例設計」：文章主情境維持 4-5 個、field/source 素材維持約 2-3 倍；新增 source-first、scenario 轉譯與 pattern 歸納規則，避免以自行生成情境取代可回溯素材
<strong>Version</strong>: 0.3.0 — 從 writing-articles.md 過載反思整合內容：「拆分判準（focus 是議題完整度）」完整搬入（含寫作 / review 自問三題、議題切一半的辨識訊號、反例 vs 正例、完成標準）+「三層 structure 詳細對照」展開為完整模板（情境 / 抽象 / Pattern 各一份）+「structure 分類錯誤的徵兆」清單。現在這份 reference 完整涵蓋「跨多篇相關文章的結構設計」、不需要回 writing-articles.md 找
<strong>Version</strong>: 0.2.0 — 從批量改寫 35 篇的經驗回流：補「跨篇引用 idiom 庫」（6 種句型 + 適用情境）+「三層 structure 對照」（quick reference、詳細在 writing-articles.md 規則九）
<strong>Version</strong>: 0.1.0 — 初版（從 report folder 累積 50+ 篇文章、整理跨篇結構心得）</p>
]]></content:encoded></item><item><title>Designing Fields — 欄位設計指引</title><link>https://tarrragon.github.io/blog/skills/compositional-writing/designing-fields/</link><pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/skills/compositional-writing/designing-fields/</guid><description>&lt;p>本文件為「設計欄位」情境的完整指引。適用於 ticket 模板、YAML frontmatter、API response、database schema、配置檔案等任何&lt;strong>多欄位結構&lt;/strong>的設計。&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>為什麼獨立成篇&lt;/strong>：欄位設計的錯誤會被模板放大。一個設計不良的 ticket 模板會產生上百個混淆 ticket、上千則語意空洞的資料。欄位一旦上線就難以撤回，因為後續所有資料都已按此格式寫入。&lt;/p>&lt;/blockquote>
&lt;blockquote>
&lt;p>&lt;strong>自包含聲明&lt;/strong>：閱讀本文件不需要先讀其他 reference。核心原則的精要在本文件內展開於「欄位設計」情境；需要跨情境套用時，才去讀對應的 &lt;code>writing-*.md&lt;/code>。&lt;/p>&lt;/blockquote>
&lt;hr>
&lt;h2 id="tldr30-秒版本">TL;DR（30 秒版本）&lt;/h2>
&lt;ol>
&lt;li>&lt;strong>每個欄位承載一個維度&lt;/strong>，不同欄位描述同一件事的不同面向（what 描述動作、why 陳述動機、acceptance 定義可驗證條件）。&lt;/li>
&lt;li>&lt;strong>frontmatter 欄位為程式化查詢服務&lt;/strong>，ID 格式、enum 值、布林命名要穩定可 grep。&lt;/li>
&lt;li>&lt;strong>欄位名稱暗示其問什麼問題&lt;/strong>（&lt;code>why&lt;/code> 問動機，&lt;code>how&lt;/code> 問策略，&lt;code>blockedBy&lt;/code> 問阻塞關係）。&lt;/li>
&lt;li>&lt;strong>欄位值格式一致&lt;/strong>，enum 有限集優於自由文字，複合值用穩定分隔符。&lt;/li>
&lt;li>&lt;strong>新增欄位前問七個問題&lt;/strong>（見「新增欄位的決策框架」章節），避免欄位膨脹。&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="目錄">目錄&lt;/h2>
&lt;ol>
&lt;li>原子化 × 欄位：每個欄位承載一個維度&lt;/li>
&lt;li>索引 × 欄位：程式化查詢、ID 格式、frontmatter 設計&lt;/li>
&lt;li>意圖顯性 × 欄位：欄位名稱即提問&lt;/li>
&lt;li>可查詢性 × 欄位：值格式一致性、enum 命名&lt;/li>
&lt;li>欄位設計 meta：新增欄位的決策框架&lt;/li>
&lt;li>Ticket 六欄位角度解析（六欄位總表 + 詳細範例連結）&lt;/li>
&lt;li>非 ticket 情境：YAML 配置、API response&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="1-原子化--欄位每個欄位承載一個維度">1. 原子化 × 欄位：每個欄位承載一個維度&lt;/h2>
&lt;p>&lt;strong>原則&lt;/strong>：每個欄位只回答一個問題。若一個欄位同時承載兩個維度，填寫者會混淆，查詢者會誤讀。&lt;/p>
&lt;h3 id="判斷標準">判斷標準&lt;/h3>
&lt;p>一個欄位的內容若出現以下徵兆，代表「承載太多維度」，應拆分：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>徵兆&lt;/th>
 &lt;th>範例&lt;/th>
 &lt;th>拆分方式&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>描述需要「和」連接&lt;/td>
 &lt;td>&lt;code>status: &amp;quot;in_progress 且 blocked by API&amp;quot;&lt;/code>&lt;/td>
 &lt;td>拆成 &lt;code>status&lt;/code> + &lt;code>blockedBy&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>同一欄位混用動作與動機&lt;/td>
 &lt;td>&lt;code>what: &amp;quot;修 bug 因為用戶回報崩潰&amp;quot;&lt;/code>&lt;/td>
 &lt;td>拆成 &lt;code>what&lt;/code>（修 bug）+ &lt;code>why&lt;/code>（用戶回報崩潰影響可用性）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>單欄位塞多個可查詢值&lt;/td>
 &lt;td>&lt;code>tags: &amp;quot;p0 security urgent&amp;quot;&lt;/code>&lt;/td>
 &lt;td>改為 &lt;code>priority: p0&lt;/code> + &lt;code>category: security&lt;/code> + &lt;code>urgency: high&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>用自由文字藏結構資料&lt;/td>
 &lt;td>&lt;code>notes: &amp;quot;owner=alice, due=2026-04-20&amp;quot;&lt;/code>&lt;/td>
 &lt;td>拆成 &lt;code>owner: alice&lt;/code> + &lt;code>due: 2026-04-20&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="反例一個欄位承載兩個維度">反例：一個欄位承載兩個維度&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c"># 錯誤：status 同時表達「進度」和「阻塞原因」&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">status&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;in_progress_waiting_for_api_team&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>問題：&lt;/p>
&lt;ul>
&lt;li>查詢「所有 in_progress 的 ticket」需要字串前綴比對，不穩定。&lt;/li>
&lt;li>改阻塞對象時，狀態字串也要改，污染查詢歷史。&lt;/li>
&lt;li>報表無法分別統計「進度分佈」和「阻塞分佈」。&lt;/li>
&lt;/ul>
&lt;h3 id="正確兩個維度各自一個欄位">正確：兩個維度各自一個欄位&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="nt">status&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">in_progress&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">blockedBy&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">team&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">api&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">reason&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;等待 /v2/users 端點上線&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>每個欄位&lt;strong>只回答一個問題&lt;/strong>：&lt;code>status&lt;/code> 回答「目前在哪個階段」，&lt;code>blockedBy&lt;/code> 回答「被什麼擋住」。&lt;/p>
&lt;h3 id="原子化測試">原子化測試&lt;/h3>
&lt;p>拿一個欄位問三個問題：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>這個欄位回答什麼問題？&lt;/strong> — 若答案需要「和」連接兩個問題，必須拆分。&lt;/li>
&lt;li>&lt;strong>這個欄位的值能獨立變更嗎？&lt;/strong> — 若必須連動其他資訊，代表混在一起了。&lt;/li>
&lt;li>&lt;strong>能用此欄位單獨做統計/排序嗎？&lt;/strong> — 若不能，代表它混入了其他維度。&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="2-索引--欄位程式化查詢id-格式frontmatter-設計">2. 索引 × 欄位：程式化查詢、ID 格式、frontmatter 設計&lt;/h2>
&lt;p>&lt;strong>原則&lt;/strong>：frontmatter 欄位存在的理由之一是&lt;strong>讓程式能查詢&lt;/strong>。人眼看不出結構，程式才看得出。所以 ID 格式、enum 值、布林欄位的命名要為「程式化查詢」服務。&lt;/p>
&lt;h3 id="id-格式設計">ID 格式設計&lt;/h3>
&lt;p>好的 ID 同時對人和程式友善。以下是穩定 ID 格式的檢查點：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>要求&lt;/th>
 &lt;th>正確範例&lt;/th>
 &lt;th>錯誤範例&lt;/th>
 &lt;th>原因&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>分層結構可拆解&lt;/td>
 &lt;td>&lt;code>v1.2.0-W03-021.4&lt;/code>&lt;/td>
 &lt;td>&lt;code>ticket_74_sub7&lt;/code>&lt;/td>
 &lt;td>前者可用分隔符拆成版本/wave/序號/子序號&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>穩定分隔符&lt;/td>
 &lt;td>用 &lt;code>-&lt;/code> 分層、&lt;code>.&lt;/code> 分子層&lt;/td>
 &lt;td>混用 &lt;code>_&lt;/code>、&lt;code>-&lt;/code>、&lt;code> &lt;/code>&lt;/td>
 &lt;td>程式 regex 才能一致比對&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>固定位數（可選）&lt;/td>
 &lt;td>&lt;code>P001&lt;/code>、&lt;code>P002&lt;/code>&lt;/td>
 &lt;td>&lt;code>P1&lt;/code>、&lt;code>P10&lt;/code>、&lt;code>P100&lt;/code>&lt;/td>
 &lt;td>字典序排序才會等於數值序&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>不含空白與特殊字元&lt;/td>
 &lt;td>&lt;code>prop-cache-cleanup&lt;/code>&lt;/td>
 &lt;td>&lt;code>prop cache cleanup!&lt;/code>&lt;/td>
 &lt;td>避免需要引號與跳脫&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>可預測的命名空間&lt;/td>
 &lt;td>&lt;code>PROP-&lt;/code> / &lt;code>UC-&lt;/code> / &lt;code>SPEC-&lt;/code> 前綴&lt;/td>
 &lt;td>無前綴純數字&lt;/td>
 &lt;td>能靠前綴快速過濾類別&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="frontmatter-為查詢服務">frontmatter 為查詢服務&lt;/h3>
&lt;p>frontmatter 的目的是「讓特定查詢變快」、不是「把資訊塞進去」 — 因為光把資訊塞進去只是換個地方存、查詢仍然要 scan；要查詢變快、欄位要做特定設計（穩定鍵名、可索引的值類型、前綴命名空間）才能匹配查詢工具的索引機制。把目的搞錯會做出「資訊完整但查詢仍要全文掃」的 frontmatter、讀者得到結果但工具拿不到效益。&lt;/p></description><content:encoded><![CDATA[<p>本文件為「設計欄位」情境的完整指引。適用於 ticket 模板、YAML frontmatter、API response、database schema、配置檔案等任何<strong>多欄位結構</strong>的設計。</p>
<blockquote>
<p><strong>為什麼獨立成篇</strong>：欄位設計的錯誤會被模板放大。一個設計不良的 ticket 模板會產生上百個混淆 ticket、上千則語意空洞的資料。欄位一旦上線就難以撤回，因為後續所有資料都已按此格式寫入。</p></blockquote>
<blockquote>
<p><strong>自包含聲明</strong>：閱讀本文件不需要先讀其他 reference。核心原則的精要在本文件內展開於「欄位設計」情境；需要跨情境套用時，才去讀對應的 <code>writing-*.md</code>。</p></blockquote>
<hr>
<h2 id="tldr30-秒版本">TL;DR（30 秒版本）</h2>
<ol>
<li><strong>每個欄位承載一個維度</strong>，不同欄位描述同一件事的不同面向（what 描述動作、why 陳述動機、acceptance 定義可驗證條件）。</li>
<li><strong>frontmatter 欄位為程式化查詢服務</strong>，ID 格式、enum 值、布林命名要穩定可 grep。</li>
<li><strong>欄位名稱暗示其問什麼問題</strong>（<code>why</code> 問動機，<code>how</code> 問策略，<code>blockedBy</code> 問阻塞關係）。</li>
<li><strong>欄位值格式一致</strong>，enum 有限集優於自由文字，複合值用穩定分隔符。</li>
<li><strong>新增欄位前問七個問題</strong>（見「新增欄位的決策框架」章節），避免欄位膨脹。</li>
</ol>
<hr>
<h2 id="目錄">目錄</h2>
<ol>
<li>原子化 × 欄位：每個欄位承載一個維度</li>
<li>索引 × 欄位：程式化查詢、ID 格式、frontmatter 設計</li>
<li>意圖顯性 × 欄位：欄位名稱即提問</li>
<li>可查詢性 × 欄位：值格式一致性、enum 命名</li>
<li>欄位設計 meta：新增欄位的決策框架</li>
<li>Ticket 六欄位角度解析（六欄位總表 + 詳細範例連結）</li>
<li>非 ticket 情境：YAML 配置、API response</li>
</ol>
<hr>
<h2 id="1-原子化--欄位每個欄位承載一個維度">1. 原子化 × 欄位：每個欄位承載一個維度</h2>
<p><strong>原則</strong>：每個欄位只回答一個問題。若一個欄位同時承載兩個維度，填寫者會混淆，查詢者會誤讀。</p>
<h3 id="判斷標準">判斷標準</h3>
<p>一個欄位的內容若出現以下徵兆，代表「承載太多維度」，應拆分：</p>
<table>
  <thead>
      <tr>
          <th>徵兆</th>
          <th>範例</th>
          <th>拆分方式</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>描述需要「和」連接</td>
          <td><code>status: &quot;in_progress 且 blocked by API&quot;</code></td>
          <td>拆成 <code>status</code> + <code>blockedBy</code></td>
      </tr>
      <tr>
          <td>同一欄位混用動作與動機</td>
          <td><code>what: &quot;修 bug 因為用戶回報崩潰&quot;</code></td>
          <td>拆成 <code>what</code>（修 bug）+ <code>why</code>（用戶回報崩潰影響可用性）</td>
      </tr>
      <tr>
          <td>單欄位塞多個可查詢值</td>
          <td><code>tags: &quot;p0 security urgent&quot;</code></td>
          <td>改為 <code>priority: p0</code> + <code>category: security</code> + <code>urgency: high</code></td>
      </tr>
      <tr>
          <td>用自由文字藏結構資料</td>
          <td><code>notes: &quot;owner=alice, due=2026-04-20&quot;</code></td>
          <td>拆成 <code>owner: alice</code> + <code>due: 2026-04-20</code></td>
      </tr>
  </tbody>
</table>
<h3 id="反例一個欄位承載兩個維度">反例：一個欄位承載兩個維度</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="c"># 錯誤：status 同時表達「進度」和「阻塞原因」</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="nt">status</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;in_progress_waiting_for_api_team&#34;</span></span></span></code></pre></div><p>問題：</p>
<ul>
<li>查詢「所有 in_progress 的 ticket」需要字串前綴比對，不穩定。</li>
<li>改阻塞對象時，狀態字串也要改，污染查詢歷史。</li>
<li>報表無法分別統計「進度分佈」和「阻塞分佈」。</li>
</ul>
<h3 id="正確兩個維度各自一個欄位">正確：兩個維度各自一個欄位</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">status</span><span class="p">:</span><span class="w"> </span><span class="l">in_progress</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="nt">blockedBy</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">  </span>- <span class="nt">team</span><span class="p">:</span><span class="w"> </span><span class="l">api</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w">    </span><span class="nt">reason</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;等待 /v2/users 端點上線&#34;</span></span></span></code></pre></div><p>每個欄位<strong>只回答一個問題</strong>：<code>status</code> 回答「目前在哪個階段」，<code>blockedBy</code> 回答「被什麼擋住」。</p>
<h3 id="原子化測試">原子化測試</h3>
<p>拿一個欄位問三個問題：</p>
<ol>
<li><strong>這個欄位回答什麼問題？</strong> — 若答案需要「和」連接兩個問題，必須拆分。</li>
<li><strong>這個欄位的值能獨立變更嗎？</strong> — 若必須連動其他資訊，代表混在一起了。</li>
<li><strong>能用此欄位單獨做統計/排序嗎？</strong> — 若不能，代表它混入了其他維度。</li>
</ol>
<hr>
<h2 id="2-索引--欄位程式化查詢id-格式frontmatter-設計">2. 索引 × 欄位：程式化查詢、ID 格式、frontmatter 設計</h2>
<p><strong>原則</strong>：frontmatter 欄位存在的理由之一是<strong>讓程式能查詢</strong>。人眼看不出結構，程式才看得出。所以 ID 格式、enum 值、布林欄位的命名要為「程式化查詢」服務。</p>
<h3 id="id-格式設計">ID 格式設計</h3>
<p>好的 ID 同時對人和程式友善。以下是穩定 ID 格式的檢查點：</p>
<table>
  <thead>
      <tr>
          <th>要求</th>
          <th>正確範例</th>
          <th>錯誤範例</th>
          <th>原因</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>分層結構可拆解</td>
          <td><code>v1.2.0-W03-021.4</code></td>
          <td><code>ticket_74_sub7</code></td>
          <td>前者可用分隔符拆成版本/wave/序號/子序號</td>
      </tr>
      <tr>
          <td>穩定分隔符</td>
          <td>用 <code>-</code> 分層、<code>.</code> 分子層</td>
          <td>混用 <code>_</code>、<code>-</code>、<code> </code></td>
          <td>程式 regex 才能一致比對</td>
      </tr>
      <tr>
          <td>固定位數（可選）</td>
          <td><code>P001</code>、<code>P002</code></td>
          <td><code>P1</code>、<code>P10</code>、<code>P100</code></td>
          <td>字典序排序才會等於數值序</td>
      </tr>
      <tr>
          <td>不含空白與特殊字元</td>
          <td><code>prop-cache-cleanup</code></td>
          <td><code>prop cache cleanup!</code></td>
          <td>避免需要引號與跳脫</td>
      </tr>
      <tr>
          <td>可預測的命名空間</td>
          <td><code>PROP-</code> / <code>UC-</code> / <code>SPEC-</code> 前綴</td>
          <td>無前綴純數字</td>
          <td>能靠前綴快速過濾類別</td>
      </tr>
  </tbody>
</table>
<h3 id="frontmatter-為查詢服務">frontmatter 為查詢服務</h3>
<p>frontmatter 的目的是「讓特定查詢變快」、不是「把資訊塞進去」 — 因為光把資訊塞進去只是換個地方存、查詢仍然要 scan；要查詢變快、欄位要做特定設計（穩定鍵名、可索引的值類型、前綴命名空間）才能匹配查詢工具的索引機制。把目的搞錯會做出「資訊完整但查詢仍要全文掃」的 frontmatter、讀者得到結果但工具拿不到效益。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l">ticket-001</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w"></span><span class="nt">title</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;修復登入崩潰&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w"></span><span class="nt">status</span><span class="p">:</span><span class="w"> </span><span class="l">in_progress</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w"></span><span class="nt">priority</span><span class="p">:</span><span class="w"> </span><span class="l">P0</span><span class="w">
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="w"></span><span class="nt">blockedBy</span><span class="p">:</span><span class="w"> </span><span class="p">[]</span><span class="w">
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="w"></span><span class="nt">version</span><span class="p">:</span><span class="w"> </span><span class="l">v1.2.0</span><span class="w">
</span></span></span><span class="line"><span class="ln">8</span><span class="cl"><span class="w"></span><span class="nt">wave</span><span class="p">:</span><span class="w"> </span><span class="m">3</span><span class="w">
</span></span></span><span class="line"><span class="ln">9</span><span class="cl"><span class="w"></span><span class="nn">---</span></span></span></code></pre></div><p>每個欄位服務一種查詢需求：</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>服務什麼查詢</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>status</code></td>
          <td>列出所有「進行中」的項目</td>
      </tr>
      <tr>
          <td><code>priority</code></td>
          <td>依優先順序排序</td>
      </tr>
      <tr>
          <td><code>blockedBy</code></td>
          <td>找出被阻塞的項目</td>
      </tr>
      <tr>
          <td><code>version</code> / <code>wave</code></td>
          <td>按發佈批次篩選</td>
      </tr>
  </tbody>
</table>
<p><strong>欄位不服務的查詢就不要存</strong>。例如「建立者的辦公座位」放在 frontmatter 只會污染欄位密度。</p>
<h3 id="為程式能看優先為人能看是加分">為「程式能看」優先，為「人能看」是加分</h3>
<p>frontmatter 的值優先讓程式 grep/parse，再由顯示層（UI、報表）翻譯給人。</p>
<table>
  <thead>
      <tr>
          <th>優先程式</th>
          <th>優先人</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>status: in_progress</code></td>
          <td><code>status: &quot;進行中（已派發工程師）&quot;</code></td>
      </tr>
      <tr>
          <td><code>priority: P0</code></td>
          <td><code>priority: &quot;緊急 — 阻塞發佈&quot;</code></td>
      </tr>
      <tr>
          <td><code>blockedBy: [ticket-042]</code></td>
          <td><code>blockedBy: &quot;等 ticket-042 的 API 做完&quot;</code></td>
      </tr>
  </tbody>
</table>
<p>若需要給人看的補充描述，用獨立的自由文字欄位承接（如 <code>blockedByReason</code>），frontmatter 主欄位保持結構化。</p>
<hr>
<h2 id="3-意圖顯性--欄位欄位名稱即提問">3. 意圖顯性 × 欄位：欄位名稱即提問</h2>
<p><strong>原則</strong>：欄位名稱本身就是一個問題。填寫者看到欄位名，應立刻知道要填什麼答案。若欄位名需要額外文件解釋，代表命名不夠顯性。</p>
<h3 id="好欄位名--好問題">好欄位名 = 好問題</h3>
<table>
  <thead>
      <tr>
          <th>欄位名</th>
          <th>它問的問題</th>
          <th>填寫者的思考</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>what</code></td>
          <td>「做了什麼？」</td>
          <td>描述動作/內容</td>
      </tr>
      <tr>
          <td><code>why</code></td>
          <td>「為什麼需要？」</td>
          <td>陳述動機/業務理由</td>
      </tr>
      <tr>
          <td><code>when</code></td>
          <td>「什麼時候觸發？」</td>
          <td>條件/時機</td>
      </tr>
      <tr>
          <td><code>where</code></td>
          <td>「影響範圍？」</td>
          <td>檔案/模組/層級</td>
      </tr>
      <tr>
          <td><code>how</code></td>
          <td>「怎麼做？」</td>
          <td>實作策略</td>
      </tr>
      <tr>
          <td><code>acceptance</code></td>
          <td>「怎樣算完成？」</td>
          <td>可驗證條件</td>
      </tr>
      <tr>
          <td><code>blockedBy</code></td>
          <td>「被什麼擋住？」</td>
          <td>依賴項目</td>
      </tr>
      <tr>
          <td><code>owner</code></td>
          <td>「誰負責？」</td>
          <td>單一責任人</td>
      </tr>
      <tr>
          <td><code>deprecatedAt</code></td>
          <td>「何時廢棄？」</td>
          <td>日期或版本號</td>
      </tr>
  </tbody>
</table>
<h3 id="反例名稱無法暗示問題">反例：名稱無法暗示問題</h3>
<table>
  <thead>
      <tr>
          <th>模糊欄位名</th>
          <th>問題</th>
          <th>改善</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>data</code></td>
          <td>什麼資料？</td>
          <td><code>payload</code> / <code>userProfile</code> / <code>metrics</code> 依內容</td>
      </tr>
      <tr>
          <td><code>info</code></td>
          <td>什麼資訊？</td>
          <td><code>description</code> / <code>errorDetail</code> / <code>author</code></td>
      </tr>
      <tr>
          <td><code>meta</code></td>
          <td>描述什麼？</td>
          <td><code>createdBy</code> / <code>source</code> / <code>tags</code></td>
      </tr>
      <tr>
          <td><code>config</code></td>
          <td>配置什麼？</td>
          <td><code>retryPolicy</code> / <code>cacheTtl</code></td>
      </tr>
      <tr>
          <td><code>flag</code></td>
          <td>什麼旗標？</td>
          <td><code>isPublished</code> / <code>hasWarning</code></td>
      </tr>
      <tr>
          <td><code>type</code></td>
          <td>什麼類型？</td>
          <td><code>eventType</code> / <code>userRole</code> / <code>errorCategory</code></td>
      </tr>
  </tbody>
</table>
<h3 id="布林欄位用-is_--has_--can_-開頭">布林欄位用 <code>is_</code> / <code>has_</code> / <code>can_</code> 開頭</h3>
<table>
  <thead>
      <tr>
          <th>錯誤</th>
          <th>正確</th>
          <th>原因</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>active</code></td>
          <td><code>isActive</code></td>
          <td>看到就知道是 true/false</td>
      </tr>
      <tr>
          <td><code>permission</code></td>
          <td><code>hasPermission</code></td>
          <td>暗示「擁有關係」</td>
      </tr>
      <tr>
          <td><code>edit</code></td>
          <td><code>canEdit</code></td>
          <td>暗示「能力檢查」</td>
      </tr>
      <tr>
          <td><code>visible</code></td>
          <td><code>isVisible</code></td>
          <td>避免與名詞混淆</td>
      </tr>
  </tbody>
</table>
<h3 id="欄位名稱體現抽象層">欄位名稱體現抽象層</h3>
<p>一份文件內的欄位應處於<strong>同一抽象層</strong>。混層會讓讀者不知道該看哪個。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="c"># 錯誤：混抽象層</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="nt">what</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;修 bug&#34;</span><span class="w">                           </span><span class="c"># 業務層</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w"></span><span class="nt">implementationDetail</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;修改 auth.py 第 42 行&#34;</span><span class="w">  </span><span class="c"># 實作層</span></span></span></code></pre></div><p>改善：<code>what</code> 留在業務層，實作細節進 <code>how</code> 或 <code>where.files</code>。</p>
<hr>
<h2 id="4-可查詢性--欄位值格式一致性enum-命名">4. 可查詢性 × 欄位：值格式一致性、enum 命名</h2>
<p><strong>原則</strong>：同一個欄位的值要有<strong>穩定格式</strong>，讓 grep/filter/sort 可預測。格式不一致會讓查詢需要 N 個 regex 才能覆蓋，最終退化成「用肉眼翻」。</p>
<h3 id="enum-優於自由文字">enum 優於自由文字</h3>
<p>有限集合的欄位應列出所有合法值：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="c"># 正確：status 有固定集合</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="nt">status</span><span class="p">:</span><span class="w"> </span><span class="l">in_progress   </span><span class="w"> </span><span class="c"># 僅限 pending / in_progress / blocked / completed / cancelled</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w"></span><span class="c"># 錯誤：狀態用自由文字</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w"></span><span class="nt">status</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;進行中，但有點卡&#34;</span></span></span></code></pre></div><p>enum 的三個好處：</p>
<ol>
<li>grep 精確（<code>status: in_progress</code> 無歧義）</li>
<li>值變更能被編譯器/驗證器捕捉</li>
<li>統計時不用做語意聚類</li>
</ol>
<h3 id="enum-命名規則">enum 命名規則</h3>
<table>
  <thead>
      <tr>
          <th>要求</th>
          <th>正確</th>
          <th>錯誤</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>全小寫、單字用 <code>_</code> 連接</td>
          <td><code>in_progress</code></td>
          <td><code>inProgress</code> / <code>In-Progress</code></td>
      </tr>
      <tr>
          <td>語意中立（不帶情緒）</td>
          <td><code>cancelled</code></td>
          <td><code>abandoned_by_team</code></td>
      </tr>
      <tr>
          <td>涵蓋周延（加 <code>unknown</code> 或 <code>other</code> 兜底）</td>
          <td><code>unknown</code></td>
          <td>漏 fallback 導致必填卡關</td>
      </tr>
      <tr>
          <td>避免數字後綴（除非真的有序）</td>
          <td><code>high</code> / <code>medium</code> / <code>low</code></td>
          <td><code>level1</code> / <code>level2</code></td>
      </tr>
  </tbody>
</table>
<h3 id="複合值的穩定分隔符">複合值的穩定分隔符</h3>
<p>若欄位必須承載複合值，用<strong>穩定的分隔符</strong>讓 regex 可拆。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="c"># 正確：用 : 分隔方向和目標</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="nt">direction</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;to-sibling:ticket-045&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w"></span><span class="c"># 錯誤：自由文字</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w"></span><span class="nt">direction</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;指向兄弟 ticket 045&#34;</span></span></span></code></pre></div><p>常見分隔符慣例：</p>
<table>
  <thead>
      <tr>
          <th>分隔符</th>
          <th>用途</th>
          <th>範例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>:</code></td>
          <td>維度:值</td>
          <td><code>scope:api</code>、<code>type:bug</code></td>
      </tr>
      <tr>
          <td><code>/</code></td>
          <td>路徑</td>
          <td><code>src/auth/login.py</code></td>
      </tr>
      <tr>
          <td><code>,</code></td>
          <td>多值列表（若不用陣列）</td>
          <td><code>a11y,i18n,perf</code></td>
      </tr>
      <tr>
          <td><code>→</code> / <code>-&gt;</code></td>
          <td>流向</td>
          <td><code>pending → in_progress</code></td>
      </tr>
  </tbody>
</table>
<p><strong>禁止混用分隔符</strong>。若一個欄位用 <code>:</code>，整個系統都要用 <code>:</code>。</p>
<h3 id="欄位值前綴做分類">欄位值前綴做分類</h3>
<p>當同類型但需細分時，用固定前綴而非混在自由文字中。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="c"># 正確：ID 前綴暗示類別</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="nt">id: PROP-042    # proposal (portability-allow</span><span class="p">:</span><span class="w"> </span><span class="l">teaching example)</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w"></span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l">UC-007     </span><span class="w"> </span><span class="c"># use case</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w"></span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l">SPEC-012   </span><span class="w"> </span><span class="c"># spec</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="w"></span><span class="c"># 錯誤：自由文字描述類別</span><span class="w">
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="w"></span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;proposal 42&#34;</span></span></span></code></pre></div><h3 id="日期時間統一-iso-8601">日期時間統一 ISO 8601</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="c"># 正確</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="nt">createdAt</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;2026-04-16&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w"></span><span class="nt">startedAt</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;2026-04-16T09:30:00+08:00&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w"></span><span class="c"># 錯誤</span><span class="w">
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="w"></span><span class="nt">createdAt</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;2026/4/16&#34;</span><span class="w">       </span><span class="c"># 分隔符不穩</span><span class="w">
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="w"></span><span class="nt">createdAt</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;April 16, 2026&#34;</span><span class="w">  </span><span class="c"># 不可排序</span><span class="w">
</span></span></span><span class="line"><span class="ln">8</span><span class="cl"><span class="w"></span><span class="nt">createdAt</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;昨天&#34;</span><span class="w">             </span><span class="c"># 不可重複解析</span></span></span></code></pre></div><hr>
<h2 id="5-欄位設計-meta新增欄位的決策框架">5. 欄位設計 meta：新增欄位的決策框架</h2>
<p><strong>原則</strong>：欄位一旦加入就難以撤回。新增前必問以下七個問題，避免欄位膨脹、語意重疊。</p>
<h3 id="新增欄位前必問清單">新增欄位前必問清單</h3>
<table>
  <thead>
      <tr>
          <th>#</th>
          <th>問題</th>
          <th>若答「否」的處理</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1</td>
          <td><strong>這個欄位回答什麼問題？（單一維度）</strong></td>
          <td>若回答多個問題 → 拆成多欄位</td>
      </tr>
      <tr>
          <td>2</td>
          <td><strong>是否已有欄位涵蓋同一維度？</strong></td>
          <td>若有 → 擴充既有欄位或重新命名，不新增</td>
      </tr>
      <tr>
          <td>3</td>
          <td><strong>至少有一個查詢情境需要它嗎？</strong></td>
          <td>若無 → 放入自由文字 notes，不進 frontmatter</td>
      </tr>
      <tr>
          <td>4</td>
          <td><strong>值域是否有限可枚舉？</strong></td>
          <td>若是 → 用 enum；若否 → 確認自由文字真的必要</td>
      </tr>
      <tr>
          <td>5</td>
          <td><strong>缺省值（missing）有明確語意嗎？</strong></td>
          <td>若無 → 補上預設值或註明 <code>nullable</code></td>
      </tr>
      <tr>
          <td>6</td>
          <td><strong>填寫者有能力正確填寫嗎？</strong></td>
          <td>若否 → 改成程式自動填，或提供 enum 選單</td>
      </tr>
      <tr>
          <td>7</td>
          <td><strong>停用時如何淘汰？</strong></td>
          <td>若無計畫 → 先標註 <code>deprecatedAt</code> 欄位策略</td>
      </tr>
  </tbody>
</table>
<h3 id="欄位語意重疊檢查">欄位語意重疊檢查</h3>
<p>新增欄位時最常見的錯誤是「與既有欄位語意重疊」。檢查方式：</p>
<ol>
<li>列出新欄位的<strong>提問</strong>（它要回答什麼問題）。</li>
<li>對照既有欄位的<strong>提問</strong>，找是否有重複。</li>
<li>若有重複，選其一：
<ul>
<li><strong>合併</strong>：新增的維度其實可以塞進既有欄位（若不違反原子化）。</li>
<li><strong>改名</strong>：讓兩個欄位的提問有明確區別。</li>
<li><strong>捨棄</strong>：若既有欄位已能滿足，不新增。</li>
</ul>
</li>
</ol>
<h3 id="欄位膨脹的警訊">欄位膨脹的警訊</h3>
<table>
  <thead>
      <tr>
          <th>警訊</th>
          <th>意義</th>
          <th>行動</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>一個 schema 超過 15 個 frontmatter 欄位</td>
          <td>單一物件承載過多責任</td>
          <td>分拆為子物件（nested）或獨立 schema</td>
      </tr>
      <tr>
          <td>有些欄位在 &gt; 80% 的資料中為空</td>
          <td>該欄位的查詢需求薄弱</td>
          <td>降級為自由文字 notes</td>
      </tr>
      <tr>
          <td>欄位的填寫規則寫在多份 wiki</td>
          <td>規則太複雜</td>
          <td>改為 enum 或引入驗證器</td>
      </tr>
      <tr>
          <td>兩個欄位經常「一起填/一起空」</td>
          <td>語意耦合</td>
          <td>合併或用 nested 結構</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="6-ticket-六欄位角度解析">6. Ticket 六欄位角度解析</h2>
<p>ticket 模板的 <code>what / why / when / where / how / acceptance</code> 六欄位是<strong>刻意設計的多角度描述系統</strong>。每個欄位從不同角度描述同一個 ticket，合起來才是完整規格。</p>
<h3 id="六欄位角度總表">六欄位角度總表</h3>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>角度</th>
          <th>正確範例摘要</th>
          <th>不該寫什麼</th>
          <th>常見混淆模式</th>
          <th>檢驗標準</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>what</code></td>
          <td>做什麼</td>
          <td><code>&quot;新增 2FA 設定開關，支援 TOTP 與 email 驗證碼&quot;</code></td>
          <td>動機、實作、驗收</td>
          <td>用「因為&hellip;所以」開頭，把 <code>why</code> 塞進來</td>
          <td>讀者能立刻想像成品</td>
      </tr>
      <tr>
          <td><code>why</code></td>
          <td>為什麼做</td>
          <td><code>&quot;登入崩潰影響 8% 用戶，每週 40 張客服工單&quot;</code></td>
          <td>動作、實作細節</td>
          <td>寫「要修 X bug，修改 Y 檔案」，把 <code>what</code>/<code>how</code> 塞進來</td>
          <td>含業務指標或成本數字</td>
      </tr>
      <tr>
          <td><code>when</code></td>
          <td>何時啟動 / 何時截止</td>
          <td><code>&quot;v1.2.0 發佈前；依賴 W03-021 完成後啟動&quot;</code></td>
          <td>產品行為時序</td>
          <td>寫「當用戶點擊&hellip;系統會&hellip;」，描述產品行為而非 ticket 啟動條件</td>
          <td>條件可被程式或人工驗證</td>
      </tr>
      <tr>
          <td><code>where</code></td>
          <td>影響範圍</td>
          <td><code>layer: Application; files: [src/auth/login_service.py, ...]</code></td>
          <td>抽象功能名</td>
          <td>寫「相關的所有地方」，不列具體路徑</td>
          <td>有具體檔案/模組清單</td>
      </tr>
      <tr>
          <td><code>how</code></td>
          <td>怎麼做</td>
          <td><code>&quot;加 guard clause → Result 模式 → 補 6 個失敗情境測試&quot;</code></td>
          <td>驗收條件、動機</td>
          <td>寫「做完要通過所有測試，成功率 ≥ 99.5%」，把 <code>acceptance</code> 塞進來</td>
          <td>有步驟、順序、技術選擇</td>
      </tr>
      <tr>
          <td><code>acceptance</code></td>
          <td>怎樣算完成</td>
          <td><code>&quot;[ ] Staging 連續 24h 成功率 ≥ 99.5%&quot;</code></td>
          <td>做法、動機</td>
          <td>寫「體驗變好」「品質提升」等不可量測描述</td>
          <td>每條都能被勾選（量化或證據性）</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p><strong>詳細範例</strong>（每個欄位各 1 個正確 + 1 個混淆共 12 項）：<code>designing-fields-ticket-6w.md</code></p></blockquote>
<hr>
<h2 id="7-非-ticket-情境yaml-配置api-response">7. 非 ticket 情境：YAML 配置、API response</h2>
<p>核心原則不只適用 ticket。以下兩個情境示範同樣的思維。</p>
<h3 id="71-yaml-配置檔案">7.1 YAML 配置檔案</h3>
<p><strong>原則應用</strong>：</p>
<table>
  <thead>
      <tr>
          <th>原則</th>
          <th>在配置檔案的具體形式</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>原子化</td>
          <td>每個配置鍵承載一個決定（超時、重試、快取各自獨立）</td>
      </tr>
      <tr>
          <td>索引</td>
          <td>用 namespace 分組（<code>database.pool.size</code> 而非 <code>dbPoolSize</code>）</td>
      </tr>
      <tr>
          <td>意圖顯性</td>
          <td><code>retryMaxAttempts</code> 優於 <code>retry</code> 或 <code>attempts</code></td>
      </tr>
      <tr>
          <td>可查詢性</td>
          <td>布林用 <code>isEnabled</code> / <code>hasFallback</code>；時長用 <code>timeoutSeconds</code> 後綴</td>
      </tr>
      <tr>
          <td>欄位設計</td>
          <td>新增配置前問「這個值會隨環境變嗎？（是→配置；否→常數）」</td>
      </tr>
  </tbody>
</table>
<p><strong>範例（正確）</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="nt">database</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="w">  </span><span class="nt">host</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;db.internal&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="w">  </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="m">5432</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="w">  </span><span class="nt">pool</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="w">    </span><span class="nt">minSize</span><span class="p">:</span><span class="w"> </span><span class="m">5</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="w">    </span><span class="nt">maxSize</span><span class="p">:</span><span class="w"> </span><span class="m">50</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="w">    </span><span class="nt">acquireTimeoutSeconds</span><span class="p">:</span><span class="w"> </span><span class="m">10</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="w"></span><span class="nt">retry</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="w">  </span><span class="nt">maxAttempts</span><span class="p">:</span><span class="w"> </span><span class="m">3</span><span class="w">
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="w">  </span><span class="nt">initialDelayMs</span><span class="p">:</span><span class="w"> </span><span class="m">100</span><span class="w">
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="w">  </span><span class="nt">backoffMultiplier</span><span class="p">:</span><span class="w"> </span><span class="m">2</span><span class="w">
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="w">  </span><span class="nt">retryableErrors</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="w">    </span>- <span class="l">connection_timeout</span><span class="w">
</span></span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="w">    </span>- <span class="l">transient_network_error</span></span></span></code></pre></div><p><strong>範例（常見混淆）</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="c"># 錯誤：單位混亂、命名模糊、enum 變自由文字</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="nt">db</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">  </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="m">10</span><span class="w">          </span><span class="c"># 秒？毫秒？</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w">  </span><span class="nt">retry</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">          </span><span class="c"># 布林還是次數？</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w">  </span><span class="nt">errors</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;timeout,network&#34;</span><span class="w">  </span><span class="c"># 為何不用列表？</span><span class="w">
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="w">  </span><span class="nt">mode</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;production, maybe&#34;</span><span class="w">  </span><span class="c"># enum 還是形容詞？</span></span></span></code></pre></div><p><strong>混淆分析</strong>：</p>
<ul>
<li><code>timeout</code> 沒標單位 → 應為 <code>timeoutSeconds</code> 或 <code>timeoutMs</code></li>
<li><code>retry: true</code> 語意不清 → 改為 <code>retry.isEnabled</code> + <code>retry.maxAttempts</code></li>
<li><code>errors</code> 用字串列表 → 應為 YAML 陣列以利 parse</li>
<li><code>mode</code> 含「maybe」 → enum 必須是有限集合</li>
</ul>
<hr>
<h3 id="72-api-response-schema">7.2 API Response Schema</h3>
<p><strong>原則應用</strong>：</p>
<table>
  <thead>
      <tr>
          <th>原則</th>
          <th>在 API response 的具體形式</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>原子化</td>
          <td>資料欄位與 meta 欄位分開（資料放 <code>data</code>，狀態放 <code>status</code>）</td>
      </tr>
      <tr>
          <td>索引</td>
          <td>穩定 ID 欄位（<code>id</code>、<code>cursor</code>）讓分頁與查詢可預測</td>
      </tr>
      <tr>
          <td>意圖顯性</td>
          <td><code>isPaginated</code>、<code>hasMore</code>、<code>totalCount</code> 各司其職</td>
      </tr>
      <tr>
          <td>可查詢性</td>
          <td>錯誤碼用 enum（<code>errorCode: &quot;INVALID_TOKEN&quot;</code>）而非自由文字</td>
      </tr>
      <tr>
          <td>欄位設計</td>
          <td>新增欄位前問「client 真的會用嗎？還是只是 server 方便？」</td>
      </tr>
  </tbody>
</table>
<p><strong>範例（正確）</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  <span class="nt">&#34;status&#34;</span><span class="p">:</span> <span class="s2">&#34;success&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">  <span class="nt">&#34;data&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">    <span class="nt">&#34;users&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">      <span class="p">{</span> <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;usr_001&#34;</span><span class="p">,</span> <span class="nt">&#34;email&#34;</span><span class="p">:</span> <span class="s2">&#34;alice@example.com&#34;</span><span class="p">,</span> <span class="nt">&#34;role&#34;</span><span class="p">:</span> <span class="s2">&#34;admin&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  <span class="nt">&#34;pagination&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    <span class="nt">&#34;hasMore&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">    <span class="nt">&#34;nextCursor&#34;</span><span class="p">:</span> <span class="s2">&#34;eyJpZCI6InVzcl8wMDEifQ==&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">    <span class="nt">&#34;totalCount&#34;</span><span class="p">:</span> <span class="mi">1247</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">  <span class="nt">&#34;meta&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">    <span class="nt">&#34;requestId&#34;</span><span class="p">:</span> <span class="s2">&#34;req_abc123&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">    <span class="nt">&#34;serverTime&#34;</span><span class="p">:</span> <span class="s2">&#34;2026-04-16T09:30:00Z&#34;</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p><strong>範例（常見混淆）</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="ln">1</span><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">  <span class="nt">&#34;ok&#34;</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">  <span class="nt">&#34;data&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">    <span class="nt">&#34;result&#34;</span><span class="p">:</span> <span class="s2">&#34;...&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">    <span class="nt">&#34;error&#34;</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl">    <span class="nt">&#34;nextPage&#34;</span><span class="p">:</span> <span class="s2">&#34;yes&#34;</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="ln">8</span><span class="cl">  <span class="nt">&#34;info&#34;</span><span class="p">:</span> <span class="s2">&#34;取得 10 筆資料，還有更多&#34;</span>
</span></span><span class="line"><span class="ln">9</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p><strong>混淆分析</strong>：</p>
<ul>
<li><code>ok: 1</code> 數字當布林 → 應為 <code>status: &quot;success&quot;</code> enum</li>
<li><code>data</code> 同時放業務資料與錯誤（<code>result</code> + <code>error</code>）→ 原子化違反，應分開</li>
<li><code>nextPage: &quot;yes&quot;</code> 字串當布林 → 應為 <code>hasMore: true</code></li>
<li><code>info</code> 為自由文字夾帶結構資訊 → 拆成 <code>totalCount: 10</code> + <code>hasMore: true</code></li>
</ul>
<hr>
<h2 id="可攜性自檢">可攜性自檢</h2>
<p>本文件可獨立閱讀，不引用任何特定專案的路徑、ticket ID、commit hash 或 hook 系統。核心原則與 ticket 六欄位範例皆為通用概念，可套用於任何採用多欄位結構的文件系統。</p>
<hr>
<h2 id="速查表">速查表</h2>
<table>
  <thead>
      <tr>
          <th>想做的事</th>
          <th>看哪一節</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>判斷欄位是否承載太多維度</td>
          <td>第 1 節「原子化測試」</td>
      </tr>
      <tr>
          <td>設計 ID 格式</td>
          <td>第 2 節「ID 格式設計」</td>
      </tr>
      <tr>
          <td>讓欄位名自我說明</td>
          <td>第 3 節「好欄位名 = 好問題」</td>
      </tr>
      <tr>
          <td>enum 命名規則</td>
          <td>第 4 節「enum 命名規則」</td>
      </tr>
      <tr>
          <td>新增欄位前的檢核</td>
          <td>第 5 節「新增欄位前必問清單」</td>
      </tr>
      <tr>
          <td>ticket what vs why 混淆</td>
          <td>第 6 節「六欄位角度總表」+ <code>designing-fields-ticket-6w.md</code> <code>what</code>/<code>why</code> 章節</td>
      </tr>
      <tr>
          <td>可驗證的 acceptance 寫法</td>
          <td>第 6 節「六欄位角度總表」+ <code>designing-fields-ticket-6w.md</code> <code>acceptance</code> 章節</td>
      </tr>
      <tr>
          <td>YAML 配置命名</td>
          <td>第 7.1</td>
      </tr>
      <tr>
          <td>API response 欄位設計</td>
          <td>第 7.2</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>Designing Fields Ticket 6W — 六欄位詳細範例</title><link>https://tarrragon.github.io/blog/skills/compositional-writing/designing-fields-ticket-6w/</link><pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/skills/compositional-writing/designing-fields-ticket-6w/</guid><description>&lt;p>本文件為 &lt;code>designing-fields.md&lt;/code> Ticket 六欄位角度解析段的詳細附錄。
每個欄位提供 1 個正確範例 + 1 個常見混淆範例，共 12 項。&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>前置閱讀&lt;/strong>：先讀 &lt;code>designing-fields.md&lt;/code>「六欄位角度總表」，理解六個欄位的角色分工後再閱讀本文件。&lt;/p>&lt;/blockquote>
&lt;hr>
&lt;h2 id="what-欄位">&lt;code>what&lt;/code> 欄位&lt;/h2>
&lt;h3 id="正確範例">正確範例&lt;/h3>
&lt;p>&lt;strong>欄位提問&lt;/strong>：這個 ticket 要做什麼？（描述動作/內容，不含動機）&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="nt">what&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;在使用者設定頁新增「雙因素驗證（2FA）」開關，支援 TOTP 與 email 驗證碼兩種方式&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>為什麼正確&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>描述「做了什麼」（新增開關、支援兩種方式）&lt;/li>
&lt;li>不解釋為什麼做（動機屬於 &lt;code>why&lt;/code>）&lt;/li>
&lt;li>不描述怎麼做（實作策略屬於 &lt;code>how&lt;/code>）&lt;/li>
&lt;li>範圍具體（使用者設定頁、TOTP + email），閱讀者能立刻想像成品&lt;/li>
&lt;/ul>
&lt;h3 id="常見混淆把動機寫進-what">常見混淆：把動機寫進 what&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c"># 錯誤&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">what&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;因為最近有用戶帳號被盜，所以要加強安全，做一個 2FA&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>為什麼混淆&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>「因為&amp;hellip;所以」的結構顯示這是動機（why），不是動作（what）&lt;/li>
&lt;li>讀者需要剝離「因為&amp;hellip;」才能看到真正的動作&lt;/li>
&lt;li>與 &lt;code>why&lt;/code> 欄位內容重複，降低欄位密度&lt;/li>
&lt;li>查詢「做了什麼」時會讀到動機雜訊&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>改善&lt;/strong>：動機搬到 &lt;code>why&lt;/code>，&lt;code>what&lt;/code> 只留動作：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="nt">what&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;新增 2FA 設定開關，支援 TOTP 與 email 驗證碼&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">why&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;最近三個月有 N 起帳號盜用事件，2FA 可降低風險&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h2 id="why-欄位">&lt;code>why&lt;/code> 欄位&lt;/h2>
&lt;h3 id="正確範例-1">正確範例&lt;/h3>
&lt;p>&lt;strong>欄位提問&lt;/strong>：為什麼需要做這件事？（業務動機，不含實作原因）&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="nt">why&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;過去三個月登入頁崩潰影響 8% 活躍用戶，平均每位受影響用戶嘗試 3 次才成功登入。修復後預期可提升首週留存 1.5 個百分點，並減少客服工單量（當前每週 40 張與登入相關）&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>為什麼正確&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>陳述業務動機（用戶影響、留存、客服成本）&lt;/li>
&lt;li>含具體數字讓重要性可衡量&lt;/li>
&lt;li>不解釋「怎麼修」（那是 how 的責任）&lt;/li>
&lt;li>不描述「做什麼」（那是 what 的責任）&lt;/li>
&lt;/ul>
&lt;h3 id="常見混淆把-what-寫進-why">常見混淆：把 what 寫進 why&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c"># 錯誤&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">why&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;要修復登入頁的崩潰 bug，會修改 auth.py 第 42 行並加 try-catch&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>為什麼混淆&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>「修復崩潰 bug」是 what，不是 why&lt;/li>
&lt;li>「修改 auth.py 第 42 行」是 how（實作細節）&lt;/li>
&lt;li>完全沒回答「為什麼要修」的業務問題&lt;/li>
&lt;li>讀者讀完 &lt;code>why&lt;/code> 仍不知道這個 ticket 的價值在哪&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>改善&lt;/strong>：動機與實作各歸各位：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="nt">why&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;登入崩潰導致 8% 用戶流失，每週產生 40 張客服工單&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">what&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;修復登入頁 authentication flow 的 null pointer&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">how&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;在 auth.py token 解析前加 guard clause；補 unit test 覆蓋 null token 情境&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h2 id="when-欄位">&lt;code>when&lt;/code> 欄位&lt;/h2>
&lt;h3 id="正確範例-2">正確範例&lt;/h3>
&lt;p>&lt;strong>欄位提問&lt;/strong>：什麼時候觸發/執行這個 ticket？（條件/時機，不是動作內容）&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="nt">when&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;v1.2.0 發佈前（預計 2026-05-10），依賴 W03-021 架構草案完成後即可啟動&amp;#34;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># portability-allow: educational when-field example&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>為什麼正確&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>回答「什麼時候」的問題（版本截止、前置依賴）&lt;/li>
&lt;li>條件可被驗證（檢查 W03-021 狀態即可）&lt;!-- portability-allow: educational reference example -->&lt;/li>
&lt;li>不混入「要做什麼」或「為什麼」&lt;/li>
&lt;/ul>
&lt;h3 id="常見混淆把-what-重述一遍">常見混淆：把 what 重述一遍&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c"># 錯誤&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">when&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;當使用者點擊登入按鈕時，系統會驗證帳密並嘗試登入&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>為什麼混淆&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>這描述的是&lt;strong>產品行為的觸發時機&lt;/strong>，不是 ticket 執行的時機&lt;/li>
&lt;li>把 &lt;code>what&lt;/code>（驗證流程）用時序包裝後重述&lt;/li>
&lt;li>真正的 &lt;code>when&lt;/code>（ticket 啟動條件）完全缺失&lt;/li>
&lt;li>讀者不知道何時該開始做這個 ticket&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>改善&lt;/strong>：分清「ticket 啟動時機」與「產品行為時機」：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="nt">when&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;登入崩潰回報量超過每週 20 起即啟動；最遲在下一個 minor 版本發佈前完成&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">what&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;修復登入流程：驗證帳密 → 產生 session → 導向首頁&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h2 id="where-欄位">&lt;code>where&lt;/code> 欄位&lt;/h2>
&lt;h3 id="正確範例-3">正確範例&lt;/h3>
&lt;p>&lt;strong>欄位提問&lt;/strong>：影響哪些檔案/模組/層級？（範圍定位，不是做什麼）&lt;/p></description><content:encoded><![CDATA[<p>本文件為 <code>designing-fields.md</code> Ticket 六欄位角度解析段的詳細附錄。
每個欄位提供 1 個正確範例 + 1 個常見混淆範例，共 12 項。</p>
<blockquote>
<p><strong>前置閱讀</strong>：先讀 <code>designing-fields.md</code>「六欄位角度總表」，理解六個欄位的角色分工後再閱讀本文件。</p></blockquote>
<hr>
<h2 id="what-欄位"><code>what</code> 欄位</h2>
<h3 id="正確範例">正確範例</h3>
<p><strong>欄位提問</strong>：這個 ticket 要做什麼？（描述動作/內容，不含動機）</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">what</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;在使用者設定頁新增「雙因素驗證（2FA）」開關，支援 TOTP 與 email 驗證碼兩種方式&#34;</span></span></span></code></pre></div><p><strong>為什麼正確</strong>：</p>
<ul>
<li>描述「做了什麼」（新增開關、支援兩種方式）</li>
<li>不解釋為什麼做（動機屬於 <code>why</code>）</li>
<li>不描述怎麼做（實作策略屬於 <code>how</code>）</li>
<li>範圍具體（使用者設定頁、TOTP + email），閱讀者能立刻想像成品</li>
</ul>
<h3 id="常見混淆把動機寫進-what">常見混淆：把動機寫進 what</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="c"># 錯誤</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="nt">what</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;因為最近有用戶帳號被盜，所以要加強安全，做一個 2FA&#34;</span></span></span></code></pre></div><p><strong>為什麼混淆</strong>：</p>
<ul>
<li>「因為&hellip;所以」的結構顯示這是動機（why），不是動作（what）</li>
<li>讀者需要剝離「因為&hellip;」才能看到真正的動作</li>
<li>與 <code>why</code> 欄位內容重複，降低欄位密度</li>
<li>查詢「做了什麼」時會讀到動機雜訊</li>
</ul>
<p><strong>改善</strong>：動機搬到 <code>why</code>，<code>what</code> 只留動作：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">what</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;新增 2FA 設定開關，支援 TOTP 與 email 驗證碼&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="nt">why</span><span class="p">:</span><span class="w">  </span><span class="s2">&#34;最近三個月有 N 起帳號盜用事件，2FA 可降低風險&#34;</span></span></span></code></pre></div><hr>
<h2 id="why-欄位"><code>why</code> 欄位</h2>
<h3 id="正確範例-1">正確範例</h3>
<p><strong>欄位提問</strong>：為什麼需要做這件事？（業務動機，不含實作原因）</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">why</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;過去三個月登入頁崩潰影響 8% 活躍用戶，平均每位受影響用戶嘗試 3 次才成功登入。修復後預期可提升首週留存 1.5 個百分點，並減少客服工單量（當前每週 40 張與登入相關）&#34;</span></span></span></code></pre></div><p><strong>為什麼正確</strong>：</p>
<ul>
<li>陳述業務動機（用戶影響、留存、客服成本）</li>
<li>含具體數字讓重要性可衡量</li>
<li>不解釋「怎麼修」（那是 how 的責任）</li>
<li>不描述「做什麼」（那是 what 的責任）</li>
</ul>
<h3 id="常見混淆把-what-寫進-why">常見混淆：把 what 寫進 why</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="c"># 錯誤</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="nt">why</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;要修復登入頁的崩潰 bug，會修改 auth.py 第 42 行並加 try-catch&#34;</span></span></span></code></pre></div><p><strong>為什麼混淆</strong>：</p>
<ul>
<li>「修復崩潰 bug」是 what，不是 why</li>
<li>「修改 auth.py 第 42 行」是 how（實作細節）</li>
<li>完全沒回答「為什麼要修」的業務問題</li>
<li>讀者讀完 <code>why</code> 仍不知道這個 ticket 的價值在哪</li>
</ul>
<p><strong>改善</strong>：動機與實作各歸各位：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">why</span><span class="p">:</span><span class="w">  </span><span class="s2">&#34;登入崩潰導致 8% 用戶流失，每週產生 40 張客服工單&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="nt">what</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;修復登入頁 authentication flow 的 null pointer&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w"></span><span class="nt">how</span><span class="p">:</span><span class="w">  </span><span class="s2">&#34;在 auth.py token 解析前加 guard clause；補 unit test 覆蓋 null token 情境&#34;</span></span></span></code></pre></div><hr>
<h2 id="when-欄位"><code>when</code> 欄位</h2>
<h3 id="正確範例-2">正確範例</h3>
<p><strong>欄位提問</strong>：什麼時候觸發/執行這個 ticket？（條件/時機，不是動作內容）</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">when</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;v1.2.0 發佈前（預計 2026-05-10），依賴 W03-021 架構草案完成後即可啟動&#34;</span><span class="w"> </span><span class="c"># portability-allow: educational when-field example</span></span></span></code></pre></div><p><strong>為什麼正確</strong>：</p>
<ul>
<li>回答「什麼時候」的問題（版本截止、前置依賴）</li>
<li>條件可被驗證（檢查 W03-021 狀態即可）<!-- portability-allow: educational reference example --></li>
<li>不混入「要做什麼」或「為什麼」</li>
</ul>
<h3 id="常見混淆把-what-重述一遍">常見混淆：把 what 重述一遍</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="c"># 錯誤</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="nt">when</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;當使用者點擊登入按鈕時，系統會驗證帳密並嘗試登入&#34;</span></span></span></code></pre></div><p><strong>為什麼混淆</strong>：</p>
<ul>
<li>這描述的是<strong>產品行為的觸發時機</strong>，不是 ticket 執行的時機</li>
<li>把 <code>what</code>（驗證流程）用時序包裝後重述</li>
<li>真正的 <code>when</code>（ticket 啟動條件）完全缺失</li>
<li>讀者不知道何時該開始做這個 ticket</li>
</ul>
<p><strong>改善</strong>：分清「ticket 啟動時機」與「產品行為時機」：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">when</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;登入崩潰回報量超過每週 20 起即啟動；最遲在下一個 minor 版本發佈前完成&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="nt">what</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;修復登入流程：驗證帳密 → 產生 session → 導向首頁&#34;</span></span></span></code></pre></div><hr>
<h2 id="where-欄位"><code>where</code> 欄位</h2>
<h3 id="正確範例-3">正確範例</h3>
<p><strong>欄位提問</strong>：影響哪些檔案/模組/層級？（範圍定位，不是做什麼）</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">where</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">  </span><span class="nt">layer</span><span class="p">:</span><span class="w"> </span><span class="l">Application</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">  </span><span class="nt">files</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w">    </span>- <span class="l">src/auth/login_service.py</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w">    </span>- <span class="l">src/auth/session_manager.py</span><span class="w">
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="w">    </span>- <span class="l">tests/auth/test_login_flow.py</span></span></span></code></pre></div><p><strong>為什麼正確</strong>：</p>
<ul>
<li>明確列出修改範圍（檔案 + 層級）</li>
<li>讓驗收者知道要檢查哪些檔案</li>
<li>協作者能預判 merge 衝突</li>
<li>不混入動作描述</li>
</ul>
<h3 id="常見混淆寫抽象功能而非具體位置">常見混淆：寫抽象功能而非具體位置</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="c"># 錯誤</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="nt">where</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;使用者登入流程相關的所有地方&#34;</span></span></span></code></pre></div><p><strong>為什麼混淆</strong>：</p>
<ul>
<li>「所有地方」無法定位，等於沒說</li>
<li>驗收者無法確認範圍是否完整</li>
<li>協作者無法預判衝突</li>
<li>若未來 refactor，沒有具體檔案可追溯</li>
</ul>
<p><strong>改善</strong>：改為具體檔案清單與層級：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">where</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">  </span><span class="nt">layer</span><span class="p">:</span><span class="w"> </span><span class="l">Application + Infrastructure</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">  </span><span class="nt">files</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w">    </span>- <span class="l">src/auth/login_service.py       </span><span class="w"> </span><span class="c"># 主邏輯</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w">    </span>- <span class="l">src/auth/token_validator.py     </span><span class="w"> </span><span class="c"># token 驗證</span><span class="w">
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="w">    </span>- <span class="l">src/infra/redis_session_store.py</span><span class="w"> </span><span class="c"># session 儲存</span></span></span></code></pre></div><hr>
<h2 id="how-欄位"><code>how</code> 欄位</h2>
<h3 id="正確範例-4">正確範例</h3>
<p><strong>欄位提問</strong>：用什麼策略/順序實作？（實作計畫，不是業務內容）</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">how</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">  </span><span class="nt">task_type</span><span class="p">:</span><span class="w"> </span><span class="l">Implementation</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">  </span><span class="nt">strategy</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="sd">    1. 在 token_validator 加 guard clause 處理 null/malformed token
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="sd">    2. 將 session_manager 的錯誤處理改為 Result 模式而非例外
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="sd">    3. 補 unit test 覆蓋 6 種失敗情境（null / expired / malformed / revoked / ip_mismatch / ua_mismatch）
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="sd">    4. 跑 integration test 驗證與 Redis 互動正確</span></span></span></code></pre></div><p><strong>為什麼正確</strong>：</p>
<ul>
<li>提供實作步驟與順序</li>
<li>選擇具體技術方案（guard clause、Result 模式）</li>
<li>不重述業務需求（那是 what）</li>
<li>不寫動機（那是 why）</li>
</ul>
<h3 id="常見混淆把-acceptance-寫進-how">常見混淆：把 acceptance 寫進 how</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="c"># 錯誤</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="nt">how</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">  </span><span class="nt">strategy</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;做完要通過所有單元測試，且 login 成功率回到 99.5% 以上&#34;</span></span></span></code></pre></div><p><strong>為什麼混淆</strong>：</p>
<ul>
<li>「通過測試」「成功率 99.5%」是驗收條件（acceptance），不是實作策略</li>
<li>沒回答「怎麼做」的問題</li>
<li>讀者不知道實際要改什麼</li>
<li>驗收與實作責任混淆</li>
</ul>
<p><strong>改善</strong>：分離「做法」與「驗收標準」：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">how</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">  </span><span class="nt">strategy</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;先加 guard clause → 改為 Result 模式 → 補單元測試 → 跑整合測試&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w"></span><span class="nt">acceptance</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w">  </span>- <span class="s2">&#34;[ ] 所有單元測試通過&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w">  </span>- <span class="s2">&#34;[ ] Staging 環境 login 成功率 ≥ 99.5%（觀察 24 小時）&#34;</span></span></span></code></pre></div><hr>
<h2 id="acceptance-欄位"><code>acceptance</code> 欄位</h2>
<h3 id="正確範例-5">正確範例</h3>
<p><strong>欄位提問</strong>：怎樣算完成？（可驗證的條件清單）</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">acceptance</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">  </span>- <span class="s2">&#34;[ ] auth 模組所有單元測試通過（含新增的 6 個失敗情境測試）&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">  </span>- <span class="s2">&#34;[ ] Staging 環境連續 24 小時 login 成功率 ≥ 99.5%&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w">  </span>- <span class="s2">&#34;[ ] 客服工單中「登入無法使用」類別在部署後 7 天內下降 ≥ 50%&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w">  </span>- <span class="s2">&#34;[ ] Code review 由另一位後端工程師核可（需涵蓋錯誤處理章節）&#34;</span></span></span></code></pre></div><p><strong>為什麼正確</strong>：</p>
<ul>
<li>每條都<strong>可驗證</strong>（有明確判斷標準）</li>
<li>每條都<strong>可觀察</strong>（測試結果、指標、核可紀錄）</li>
<li>數字具體（99.5%、24 小時、50%、7 天）</li>
<li>不抽象（沒有「讓系統更穩定」這種不可驗證的描述）</li>
</ul>
<h3 id="常見混淆不可驗證的模糊條件">常見混淆：不可驗證的模糊條件</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="c"># 錯誤</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="nt">acceptance</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">  </span>- <span class="s2">&#34;[ ] 使用者體驗變好&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w">  </span>- <span class="s2">&#34;[ ] 程式碼品質提升&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w">  </span>- <span class="s2">&#34;[ ] 沒有引入新的 bug&#34;</span></span></span></code></pre></div><p><strong>為什麼混淆</strong>：</p>
<ul>
<li>「體驗變好」無法量測（多好算好？）</li>
<li>「品質提升」主觀（誰評？）</li>
<li>「沒有新 bug」無法證明（只能證偽）</li>
<li>驗收者無法勾選，ticket 永遠完不成或隨意完成</li>
</ul>
<p><strong>改善</strong>：每條都要能「勾得下去」：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">acceptance</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">  </span>- <span class="s2">&#34;[ ] 登入完成時間 p95 從 3.2s 降至 ≤ 1.5s（1 週平均）&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">  </span>- <span class="s2">&#34;[ ] Linter 無新增 warning；cyclomatic complexity 不增加&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w">  </span>- <span class="s2">&#34;[ ] 迴歸測試套件（237 個）全數通過，且新增至少 6 個測試&#34;</span></span></span></code></pre></div><hr>
<h2 id="速查表">速查表</h2>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>常見混淆模式</th>
          <th>判斷快問</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>what</code></td>
          <td>把 <code>why</code>（動機）塞進來，用「因為&hellip;所以&hellip;」開頭</td>
          <td>有「因為」→ 搬到 <code>why</code></td>
      </tr>
      <tr>
          <td><code>why</code></td>
          <td>把 <code>what</code>（動作）和 <code>how</code>（實作）寫進來</td>
          <td>有動詞動作 → 搬到 <code>what</code> 或 <code>how</code></td>
      </tr>
      <tr>
          <td><code>when</code></td>
          <td>描述產品行為時序（用戶點了什麼），不是 ticket 啟動條件</td>
          <td>主詞是「用戶」→ 可能寫錯了</td>
      </tr>
      <tr>
          <td><code>where</code></td>
          <td>寫「所有相關地方」等抽象描述，不列具體檔案</td>
          <td>沒有路徑 → 補具體清單</td>
      </tr>
      <tr>
          <td><code>how</code></td>
          <td>把驗收條件（pass/fail 判斷）混入實作計畫</td>
          <td>有「要通過」→ 搬到 <code>acceptance</code></td>
      </tr>
      <tr>
          <td><code>acceptance</code></td>
          <td>寫「變好」「提升」「沒有新問題」等不可驗證描述</td>
          <td>無法勾選 → 加量化指標或可觀察證據</td>
      </tr>
  </tbody>
</table>
<hr>
<p><strong>來源</strong>：從 <code>designing-fields.md</code> Ticket 六欄位角度解析段獨立拆出，保留全部詳細範例
<strong>Last Updated</strong>: 2026-04-18
<strong>Version</strong>: 1.0.0</p>
]]></content:encoded></item><item><title>Dry-run Guide — Skill 發布前語意層驗收</title><link>https://tarrragon.github.io/blog/skills/compositional-writing/dry-run-guide/</link><pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/skills/compositional-writing/dry-run-guide/</guid><description>&lt;p>本文件定義 compositional-writing Skill 的 Phase 2 語意層驗收流程。Phase 1 是自動化形式掃描（portability-check.sh），Phase 2 是語意層驗收——驗證一個不熟悉本框架的新使用者，只讀 SKILL.md 和對應 reference 後，能否獨立套用寫作方法論。&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>Phase 2 的核心問題&lt;/strong>：形式合規不代表內容可理解。本流程解答「Skill 內容品質是否足以讓陌生讀者自立運作」。&lt;/p>&lt;/blockquote>
&lt;hr>
&lt;h2 id="適用時機">適用時機&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>觸發情境&lt;/th>
 &lt;th>說明&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Skill 發布至 marketplace 前&lt;/td>
 &lt;td>必須執行，作為最終品質門&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>新增或大幅修改 reference 後&lt;/td>
 &lt;td>必須針對變動的 reference 跑對應場景&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>meta-metrics.md 顯示 M2 疑慮&lt;/td>
 &lt;td>以本流程做進一步驗證&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>定期健檢（每季）&lt;/td>
 &lt;td>建議執行，確認內容未因周邊框架演進而失效&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="前置條件">前置條件&lt;/h2>
&lt;p>執行 Phase 2 前，以下條件必須已成立：&lt;/p>
&lt;ul>
&lt;li>&lt;input disabled="" type="checkbox"> Phase 1 通過：&lt;code>./scripts/portability-check.sh&lt;/code> exit 0&lt;/li>
&lt;li>&lt;input disabled="" type="checkbox"> SKILL.md 和所有核心 reference 均已完成（writing-code-comments / writing-documents / writing-logs / writing-prompts / writing-articles / translation-review / designing-fields）&lt;/li>
&lt;li>&lt;input disabled="" type="checkbox"> meta-metrics.md 已完成（M1-M2 量測方式已定義）&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="測試人員要求">測試人員要求&lt;/h2>
&lt;p>Phase 2 測試人員必須符合：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>要求&lt;/th>
 &lt;th>說明&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>對本框架陌生&lt;/td>
 &lt;td>未曾閱讀過 &lt;code>.claude/&lt;/code> 目錄任何框架規則&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>有基礎寫作能力&lt;/td>
 &lt;td>能寫 markdown，有寫程式碼或文件的基本經驗&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>可取用的資料&lt;/td>
 &lt;td>僅限 SKILL.md + 指定 reference（不可額外 Google、詢問他人）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>若找不到完全陌生的測試人員，可使用「情境隔離法」：測試者在全新 session 中（不帶任何框架記憶），只閱讀指定文件後完成場景。&lt;/p>
&lt;hr>
&lt;h2 id="測試場景3-個基本場景">測試場景（3 個基本場景）&lt;/h2>
&lt;p>每個場景設計原則：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>輸入&lt;/strong>：只給測試人員 SKILL.md + 1 個對應 reference&lt;/li>
&lt;li>&lt;strong>任務&lt;/strong>：測試人員獨立完成寫作任務&lt;/li>
&lt;li>&lt;strong>時限&lt;/strong>：每個場景 10 分鐘&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="場景-a撰寫程式碼-doc-comment">場景 A：撰寫程式碼 doc comment&lt;/h3>
&lt;p>&lt;strong>對應 reference&lt;/strong>：&lt;code>writing-code-comments.md&lt;/code>&lt;/p>
&lt;h4 id="任務描述給測試人員的指示">任務描述（給測試人員的指示）&lt;/h4>
&lt;p>你有一個 JavaScript 函式，功能是「驗證使用者輸入的書名是否符合格式（非空、長度 1-200 字元）」。&lt;/p>
&lt;p>請只閱讀 SKILL.md 和 &lt;code>writing-code-comments.md&lt;/code>，為以下函式撰寫一則 doc comment：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="kd">function&lt;/span> &lt;span class="nx">validateBookTitle&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">title&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="nx">title&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="nx">title&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="nx">length&lt;/span> &lt;span class="o">===&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="kc">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">title&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="nx">length&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">200&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="kc">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="輸入限制">輸入限制&lt;/h4>
&lt;ul>
&lt;li>可讀：SKILL.md、references/writing-code-comments.md&lt;/li>
&lt;li>不可讀：其他任何文件&lt;/li>
&lt;/ul>
&lt;h4 id="預期產出">預期產出&lt;/h4>
&lt;p>符合以下條件的 doc comment：&lt;/p>
&lt;ul>
&lt;li>說明業務意圖（為什麼驗證，不是程式碼在做什麼）&lt;/li>
&lt;li>說明輸入語意和邊界條件&lt;/li>
&lt;li>說明回傳值的含義&lt;/li>
&lt;li>不描述實作語法&lt;/li>
&lt;/ul>
&lt;h4 id="評估標準">評估標準&lt;/h4>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>評估項目&lt;/th>
 &lt;th>通過條件&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>意圖顯性&lt;/td>
 &lt;td>comment 說明「為何」而非「如何」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>原子化&lt;/td>
 &lt;td>comment 只解釋此函式的一個職責&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>輸入輸出語意&lt;/td>
 &lt;td>明確說明 &lt;code>title&lt;/code> 的合法格式與 &lt;code>false&lt;/code> 的意義&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>無多餘翻譯&lt;/td>
 &lt;td>不出現「如果 title 為空則回傳 false」這類程式碼翻譯句&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>通過判定&lt;/strong>：4 項中達到 3 項以上 = 通過。&lt;/p>
&lt;hr>
&lt;h3 id="場景-b起草技術文件段落">場景 B：起草技術文件段落&lt;/h3>
&lt;p>&lt;strong>對應 reference&lt;/strong>：&lt;code>writing-documents.md&lt;/code>&lt;/p>
&lt;h4 id="任務描述給測試人員的指示-1">任務描述（給測試人員的指示）&lt;/h4>
&lt;p>你需要為一份「書庫同步錯誤處理設計」文件撰寫開頭章節（Introduction 或 Overview）。&lt;/p>
&lt;p>背景資訊（只有這些）：&lt;/p>
&lt;ul>
&lt;li>系統名稱：Readmoo 書庫管理器&lt;/li>
&lt;li>問題：書庫同步會遇到網路中斷、資料格式不符、API 限流三種錯誤&lt;/li>
&lt;li>讀者：接手此模組的開發者（假設有基礎 JavaScript 能力，不熟悉 Readmoo 平台）&lt;/li>
&lt;/ul>
&lt;p>請只閱讀 SKILL.md 和 &lt;code>writing-documents.md&lt;/code>，撰寫一個 150-300 字的開頭段落，讓讀者第一眼就知道「這份文件解決什麼問題、讀它能得到什麼」。&lt;/p>
&lt;h4 id="輸入限制-1">輸入限制&lt;/h4>
&lt;ul>
&lt;li>可讀：SKILL.md、references/writing-documents.md&lt;/li>
&lt;li>不可讀：其他任何文件&lt;/li>
&lt;/ul>
&lt;h4 id="預期產出-1">預期產出&lt;/h4>
&lt;p>符合以下條件的開頭段落：&lt;/p>
&lt;ul>
&lt;li>第一句說清楚文件解決的問題（不從背景鋪陳）&lt;/li>
&lt;li>指明讀者是誰&lt;/li>
&lt;li>列出文件涵蓋的三種錯誤類型&lt;/li>
&lt;li>不超過 300 字&lt;/li>
&lt;/ul>
&lt;h4 id="評估標準-1">評估標準&lt;/h4>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>評估項目&lt;/th>
 &lt;th>通過條件&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>意圖前置&lt;/td>
 &lt;td>第一句即說明文件解決的問題，不先鋪背景&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>讀者定位&lt;/td>
 &lt;td>明確說明目標讀者是誰&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>範圍聲明&lt;/td>
 &lt;td>列出本文件涵蓋的三種錯誤類型&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>精簡&lt;/td>
 &lt;td>不超過 300 字、無填充詞（「在這份文件中，我們將&amp;hellip;」）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>通過判定&lt;/strong>：4 項中達到 3 項以上 = 通過。&lt;/p></description><content:encoded><![CDATA[<p>本文件定義 compositional-writing Skill 的 Phase 2 語意層驗收流程。Phase 1 是自動化形式掃描（portability-check.sh），Phase 2 是語意層驗收——驗證一個不熟悉本框架的新使用者，只讀 SKILL.md 和對應 reference 後，能否獨立套用寫作方法論。</p>
<blockquote>
<p><strong>Phase 2 的核心問題</strong>：形式合規不代表內容可理解。本流程解答「Skill 內容品質是否足以讓陌生讀者自立運作」。</p></blockquote>
<hr>
<h2 id="適用時機">適用時機</h2>
<table>
  <thead>
      <tr>
          <th>觸發情境</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Skill 發布至 marketplace 前</td>
          <td>必須執行，作為最終品質門</td>
      </tr>
      <tr>
          <td>新增或大幅修改 reference 後</td>
          <td>必須針對變動的 reference 跑對應場景</td>
      </tr>
      <tr>
          <td>meta-metrics.md 顯示 M2 疑慮</td>
          <td>以本流程做進一步驗證</td>
      </tr>
      <tr>
          <td>定期健檢（每季）</td>
          <td>建議執行，確認內容未因周邊框架演進而失效</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="前置條件">前置條件</h2>
<p>執行 Phase 2 前，以下條件必須已成立：</p>
<ul>
<li><input disabled="" type="checkbox"> Phase 1 通過：<code>./scripts/portability-check.sh</code> exit 0</li>
<li><input disabled="" type="checkbox"> SKILL.md 和所有核心 reference 均已完成（writing-code-comments / writing-documents / writing-logs / writing-prompts / writing-articles / translation-review / designing-fields）</li>
<li><input disabled="" type="checkbox"> meta-metrics.md 已完成（M1-M2 量測方式已定義）</li>
</ul>
<hr>
<h2 id="測試人員要求">測試人員要求</h2>
<p>Phase 2 測試人員必須符合：</p>
<table>
  <thead>
      <tr>
          <th>要求</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>對本框架陌生</td>
          <td>未曾閱讀過 <code>.claude/</code> 目錄任何框架規則</td>
      </tr>
      <tr>
          <td>有基礎寫作能力</td>
          <td>能寫 markdown，有寫程式碼或文件的基本經驗</td>
      </tr>
      <tr>
          <td>可取用的資料</td>
          <td>僅限 SKILL.md + 指定 reference（不可額外 Google、詢問他人）</td>
      </tr>
  </tbody>
</table>
<p>若找不到完全陌生的測試人員，可使用「情境隔離法」：測試者在全新 session 中（不帶任何框架記憶），只閱讀指定文件後完成場景。</p>
<hr>
<h2 id="測試場景3-個基本場景">測試場景（3 個基本場景）</h2>
<p>每個場景設計原則：</p>
<ul>
<li><strong>輸入</strong>：只給測試人員 SKILL.md + 1 個對應 reference</li>
<li><strong>任務</strong>：測試人員獨立完成寫作任務</li>
<li><strong>時限</strong>：每個場景 10 分鐘</li>
</ul>
<hr>
<h3 id="場景-a撰寫程式碼-doc-comment">場景 A：撰寫程式碼 doc comment</h3>
<p><strong>對應 reference</strong>：<code>writing-code-comments.md</code></p>
<h4 id="任務描述給測試人員的指示">任務描述（給測試人員的指示）</h4>
<p>你有一個 JavaScript 函式，功能是「驗證使用者輸入的書名是否符合格式（非空、長度 1-200 字元）」。</p>
<p>請只閱讀 SKILL.md 和 <code>writing-code-comments.md</code>，為以下函式撰寫一則 doc comment：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="ln">1</span><span class="cl"><span class="kd">function</span> <span class="nx">validateBookTitle</span><span class="p">(</span><span class="nx">title</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">title</span> <span class="o">||</span> <span class="nx">title</span><span class="p">.</span><span class="nx">trim</span><span class="p">().</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nx">title</span><span class="p">.</span><span class="nx">trim</span><span class="p">().</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">200</span><span class="p">)</span> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">    <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><h4 id="輸入限制">輸入限制</h4>
<ul>
<li>可讀：SKILL.md、references/writing-code-comments.md</li>
<li>不可讀：其他任何文件</li>
</ul>
<h4 id="預期產出">預期產出</h4>
<p>符合以下條件的 doc comment：</p>
<ul>
<li>說明業務意圖（為什麼驗證，不是程式碼在做什麼）</li>
<li>說明輸入語意和邊界條件</li>
<li>說明回傳值的含義</li>
<li>不描述實作語法</li>
</ul>
<h4 id="評估標準">評估標準</h4>
<table>
  <thead>
      <tr>
          <th>評估項目</th>
          <th>通過條件</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>意圖顯性</td>
          <td>comment 說明「為何」而非「如何」</td>
      </tr>
      <tr>
          <td>原子化</td>
          <td>comment 只解釋此函式的一個職責</td>
      </tr>
      <tr>
          <td>輸入輸出語意</td>
          <td>明確說明 <code>title</code> 的合法格式與 <code>false</code> 的意義</td>
      </tr>
      <tr>
          <td>無多餘翻譯</td>
          <td>不出現「如果 title 為空則回傳 false」這類程式碼翻譯句</td>
      </tr>
  </tbody>
</table>
<p><strong>通過判定</strong>：4 項中達到 3 項以上 = 通過。</p>
<hr>
<h3 id="場景-b起草技術文件段落">場景 B：起草技術文件段落</h3>
<p><strong>對應 reference</strong>：<code>writing-documents.md</code></p>
<h4 id="任務描述給測試人員的指示-1">任務描述（給測試人員的指示）</h4>
<p>你需要為一份「書庫同步錯誤處理設計」文件撰寫開頭章節（Introduction 或 Overview）。</p>
<p>背景資訊（只有這些）：</p>
<ul>
<li>系統名稱：Readmoo 書庫管理器</li>
<li>問題：書庫同步會遇到網路中斷、資料格式不符、API 限流三種錯誤</li>
<li>讀者：接手此模組的開發者（假設有基礎 JavaScript 能力，不熟悉 Readmoo 平台）</li>
</ul>
<p>請只閱讀 SKILL.md 和 <code>writing-documents.md</code>，撰寫一個 150-300 字的開頭段落，讓讀者第一眼就知道「這份文件解決什麼問題、讀它能得到什麼」。</p>
<h4 id="輸入限制-1">輸入限制</h4>
<ul>
<li>可讀：SKILL.md、references/writing-documents.md</li>
<li>不可讀：其他任何文件</li>
</ul>
<h4 id="預期產出-1">預期產出</h4>
<p>符合以下條件的開頭段落：</p>
<ul>
<li>第一句說清楚文件解決的問題（不從背景鋪陳）</li>
<li>指明讀者是誰</li>
<li>列出文件涵蓋的三種錯誤類型</li>
<li>不超過 300 字</li>
</ul>
<h4 id="評估標準-1">評估標準</h4>
<table>
  <thead>
      <tr>
          <th>評估項目</th>
          <th>通過條件</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>意圖前置</td>
          <td>第一句即說明文件解決的問題，不先鋪背景</td>
      </tr>
      <tr>
          <td>讀者定位</td>
          <td>明確說明目標讀者是誰</td>
      </tr>
      <tr>
          <td>範圍聲明</td>
          <td>列出本文件涵蓋的三種錯誤類型</td>
      </tr>
      <tr>
          <td>精簡</td>
          <td>不超過 300 字、無填充詞（「在這份文件中，我們將&hellip;」）</td>
      </tr>
  </tbody>
</table>
<p><strong>通過判定</strong>：4 項中達到 3 項以上 = 通過。</p>
<hr>
<h3 id="場景-c設計-yaml-欄位命名">場景 C：設計 YAML 欄位命名</h3>
<p><strong>對應 reference</strong>：<code>designing-fields.md</code></p>
<h4 id="任務描述給測試人員的指示-2">任務描述（給測試人員的指示）</h4>
<p>你正在設計一份 YAML 格式的「書籍匯出任務」結構，需要包含以下資訊：</p>
<ol>
<li>任務的唯一識別碼</li>
<li>任務被建立的原因（是使用者手動觸發，還是排程自動觸發）</li>
<li>任務的目標輸出格式（CSV 或 JSON）</li>
<li>任務目前的執行狀態（待執行、執行中、完成、失敗）</li>
<li>任務完成後通知的方式（email 或 webhook）</li>
</ol>
<p>請只閱讀 SKILL.md 和 <code>designing-fields.md</code>，設計上述 5 個欄位的名稱與值的格式（用 YAML 示例呈現即可）。</p>
<h4 id="輸入限制-2">輸入限制</h4>
<ul>
<li>可讀：SKILL.md、references/designing-fields.md</li>
<li>不可讀：其他任何文件</li>
</ul>
<h4 id="預期產出-2">預期產出</h4>
<p>一段 YAML 示例，每個欄位有名稱和示例值，並附一行說明「此欄位承載什麼維度的資訊」。</p>
<h4 id="評估標準-2">評估標準</h4>
<table>
  <thead>
      <tr>
          <th>評估項目</th>
          <th>通過條件</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>欄位職責單一</td>
          <td>每個欄位只描述一個維度，無複合欄位（如 <code>trigger_and_format</code>）</td>
      </tr>
      <tr>
          <td>名稱即提問</td>
          <td>欄位名稱讀者能猜到「它在問什麼問題」</td>
      </tr>
      <tr>
          <td>值格式一致</td>
          <td>狀態類欄位使用 enum（固定可選值），不用自由文字</td>
      </tr>
      <tr>
          <td>grep 友善</td>
          <td>欄位名稱無縮寫、蛇形命名（如 <code>output_format</code> 非 <code>outFmt</code>）</td>
      </tr>
  </tbody>
</table>
<p><strong>通過判定</strong>：4 項中達到 3 項以上 = 通過。</p>
<hr>
<h2 id="通過標準量化">通過標準（量化）</h2>
<p>整體 Phase 2 通過條件：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>通過值</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>場景通過率</td>
          <td>100%（3/3 場景）</td>
          <td>任一場景未通過即整體 FAIL</td>
      </tr>
      <tr>
          <td>單場景完成時間</td>
          <td>10 分鐘內</td>
          <td>超時視為理解障礙，需調查根因</td>
      </tr>
      <tr>
          <td>場景內評估項通過率</td>
          <td>75% 以上（至少 3/4 項）</td>
          <td>低於此值視為該場景 FAIL</td>
      </tr>
  </tbody>
</table>
<p><strong>通過計算式</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">Phase 2 通過 = (所有場景通過) AND (所有場景在 10 分鐘內完成)
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl">場景通過 = 評估項通過率 &gt;= 75%</span></span></code></pre></div><hr>
<h2 id="評估問卷測試後請測試人員回答">評估問卷（測試後請測試人員回答）</h2>
<p>每個場景完成後，請測試人員回答以下問題（1-5 分，5 分最高）：</p>
<table>
  <thead>
      <tr>
          <th>問題</th>
          <th>目的</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Q1. SKILL.md 的觸發路由表讓你清楚知道要讀哪個 reference 嗎？</td>
          <td>驗證 M1 路徑設計</td>
      </tr>
      <tr>
          <td>Q2. 你讀完指定 reference 後，能獨立完成任務而不需要其他資料嗎？</td>
          <td>驗證 M2 獨立理解率</td>
      </tr>
      <tr>
          <td>Q3. reference 中是否有你不理解的名詞或概念？（有請列出）</td>
          <td>發現就地定義缺失</td>
      </tr>
      <tr>
          <td>Q4. 如果你要把本方法論教給同事，你覺得這份文件夠完整嗎？</td>
          <td>整體可遷移性</td>
      </tr>
  </tbody>
</table>
<p><strong>問卷通過標準</strong>：Q1 + Q2 平均分 &gt;= 4 分，Q3 無未解答的名詞。</p>
<hr>
<h2 id="執行步驟">執行步驟</h2>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">1. 確認前置條件：執行 ./scripts/portability-check.sh，exit 0 才繼續
</span></span><span class="line"><span class="ln">2</span><span class="cl">2. 找到測試人員（符合「對本框架陌生」條件）
</span></span><span class="line"><span class="ln">3</span><span class="cl">3. 依序執行場景 A → B → C，記錄每個場景的完成時間和評估項結果
</span></span><span class="line"><span class="ln">4</span><span class="cl">4. 場景結束後請測試人員完成評估問卷
</span></span><span class="line"><span class="ln">5</span><span class="cl">5. 計算通過率（場景 + 問卷）
</span></span><span class="line"><span class="ln">6</span><span class="cl">6. 填寫下方結果記錄表
</span></span><span class="line"><span class="ln">7</span><span class="cl">7. 若有場景 FAIL，記錄根因並提交修正 Ticket</span></span></code></pre></div><hr>
<h2 id="結果記錄表執行後填寫">結果記錄表（執行後填寫）</h2>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">Phase 2 Dry-Run 結果（日期：_____ / 執行者：_____）
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">場景結果
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">| 場景 | 完成時間 | 評估項通過數 | 通過判定 |
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">|------|---------|------------|---------|
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">| A：程式碼 doc comment | ___ 分鐘 | ___/4 | PASS / FAIL |
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">| B：技術文件段落 | ___ 分鐘 | ___/4 | PASS / FAIL |
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">| C：YAML 欄位設計 | ___ 分鐘 | ___/4 | PASS / FAIL |
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl">問卷結果
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl">| 問題 | 分數（1-5） | 備註 |
</span></span><span class="line"><span class="ln">14</span><span class="cl">|------|-----------|------|
</span></span><span class="line"><span class="ln">15</span><span class="cl">| Q1 觸發路由清晰度 | ___ | |
</span></span><span class="line"><span class="ln">16</span><span class="cl">| Q2 reference 獨立理解率 | ___ | |
</span></span><span class="line"><span class="ln">17</span><span class="cl">| Q3 不理解的名詞 | N/A（列出：_____） | |
</span></span><span class="line"><span class="ln">18</span><span class="cl">| Q4 整體可遷移性 | ___ | |
</span></span><span class="line"><span class="ln">19</span><span class="cl">
</span></span><span class="line"><span class="ln">20</span><span class="cl">整體結論：PASS / FAIL
</span></span><span class="line"><span class="ln">21</span><span class="cl">FAIL 時的修正清單：
</span></span><span class="line"><span class="ln">22</span><span class="cl">- （列出需要修正的 reference 或章節）</span></span></code></pre></div><hr>
<h2 id="常見失敗根因與對應修正">常見失敗根因與對應修正</h2>
<table>
  <thead>
      <tr>
          <th>症狀</th>
          <th>根因</th>
          <th>修正方向</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>測試人員完成時間 &gt; 10 分鐘</td>
          <td>reference 資訊密度過高或結構不清</td>
          <td>重新組織 reference，讓 TL;DR 或 Quick Reference 更突出</td>
      </tr>
      <tr>
          <td>測試人員需要查閱第二個 reference</td>
          <td>reference 未自包含（M2 FAIL）</td>
          <td>把被引用內容的精要直接寫入當前 reference</td>
      </tr>
      <tr>
          <td>評估項「意圖顯性」通過率低</td>
          <td>SKILL.md 對「意圖顯性」的定義不夠具體</td>
          <td>在對應 reference 加入更多示例（正例 + 反例）</td>
      </tr>
      <tr>
          <td>問卷 Q3 列出未解答名詞</td>
          <td>首次出現的術語缺少就地定義</td>
          <td>在術語首次出現處加入一行定義（括號說明或 note block）</td>
      </tr>
      <tr>
          <td>場景 C 欄位設計評估項通過率低</td>
          <td>designing-fields.md 的「欄位名稱即提問」原則不夠清楚</td>
          <td>在該原則下加更多反例對照（好名稱 vs 壞名稱）</td>
      </tr>
  </tbody>
</table>
<hr>
<p><strong>Last Updated</strong>: 2026-04-18
<strong>Version</strong>: 1.0.0</p>
]]></content:encoded></item><item><title>Meta Metrics — 寫作品質量化驗收</title><link>https://tarrragon.github.io/blog/skills/compositional-writing/meta-metrics/</link><pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/skills/compositional-writing/meta-metrics/</guid><description>&lt;p>本 reference 定義 compositional-writing Skill 的品質量化驗收方式。寫得好不好是主觀判斷，metric 讓它變成可重複驗證的客觀評估。&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>核心理念&lt;/strong>：Metric 是自評工具，不是硬性 KPI。目的是讓「達成/未達成」可被重複驗證，並在 Skill 演化過程中守住設計底線。&lt;/p>&lt;/blockquote>
&lt;hr>
&lt;h2 id="何時參閱本檔">何時參閱本檔&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>觸發情境&lt;/th>
 &lt;th>動作&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>驗收本 Skill 新增或修改的 reference&lt;/td>
 &lt;td>跑 M1-M2 檢查&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>決定是否拆分/合併 reference&lt;/td>
 &lt;td>用 M2 評估獨立理解率&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>懷疑 SKILL.md 路由設計失靈&lt;/td>
 &lt;td>用 M1 跑 6 情境預期路徑&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Skill 發布前的品質門&lt;/td>
 &lt;td>M1 + M2 全綠才允許發布（M3-M5 待定後納入）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="metric-總覽">Metric 總覽&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>ID&lt;/th>
 &lt;th>名稱&lt;/th>
 &lt;th>類別&lt;/th>
 &lt;th>目標值&lt;/th>
 &lt;th>量測方式&lt;/th>
 &lt;th>狀態&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>M1&lt;/td>
 &lt;td>找到答案路徑長度&lt;/td>
 &lt;td>認知負擔&lt;/td>
 &lt;td>≤ 2 個檔案&lt;/td>
 &lt;td>6 情境預期路徑對照&lt;/td>
 &lt;td>正式&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>M2&lt;/td>
 &lt;td>reference 獨立理解率&lt;/td>
 &lt;td>認知負擔&lt;/td>
 &lt;td>100%&lt;/td>
 &lt;td>逐 reference 獨立閱讀檢查&lt;/td>
 &lt;td>正式&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>M3&lt;/td>
 &lt;td>SKILL.md 主檔 token 上限&lt;/td>
 &lt;td>Token&lt;/td>
 &lt;td>≤ 5000 tokens（候選）&lt;/td>
 &lt;td>Tokenizer 計數&lt;/td>
 &lt;td>未決（待實際範例後定）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>M4&lt;/td>
 &lt;td>單一 reference 觸發載入 token&lt;/td>
 &lt;td>Token&lt;/td>
 &lt;td>≤ 3000 tokens（候選）&lt;/td>
 &lt;td>Tokenizer 計數&lt;/td>
 &lt;td>未決（待實際範例後定）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>M5&lt;/td>
 &lt;td>grep 定位問題的 token 成本&lt;/td>
 &lt;td>Token&lt;/td>
 &lt;td>&amp;lt; 500 tokens（候選）&lt;/td>
 &lt;td>grep + tokenizer 實測&lt;/td>
 &lt;td>未決（待實際範例後定）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>認知負擔類（M1-M2）為本版正式 metric；Token 類（M3-M5）為候選，待 references/ 內容穩定後再定最終閾值。&lt;/p>
&lt;hr>
&lt;h2 id="m1--找到答案路徑長度">M1 — 找到答案路徑長度&lt;/h2>
&lt;h3 id="定義">定義&lt;/h3>
&lt;p>讀者帶著一個寫作問題從 SKILL.md 開始，&lt;strong>需要開啟幾個檔案&lt;/strong>才能解決問題。路徑長度 = SKILL.md 外額外開啟的 reference 檔案數。&lt;/p>
&lt;ul>
&lt;li>路徑 1：只讀 SKILL.md 就解決（極罕見，只適用於速查表即可回答的問題）&lt;/li>
&lt;li>路徑 2：SKILL.md 指引 → 開啟 1 個 reference（預期主流）&lt;/li>
&lt;li>路徑 3+：SKILL.md → reference A → reference B（違反本 metric）&lt;/li>
&lt;/ul>
&lt;h3 id="目標值">目標值&lt;/h3>
&lt;p>&lt;strong>≤ 2&lt;/strong>（SKILL.md + 1 個 reference 即解決）。&lt;/p>
&lt;h3 id="量測方式">量測方式&lt;/h3>
&lt;p>針對本 Skill 支援的 6 個觸發情境，逐一演練：&lt;/p>
&lt;ol>
&lt;li>模擬讀者帶著該情境的問題進入 SKILL.md&lt;/li>
&lt;li>依照 SKILL.md 觸發路由表選擇 reference&lt;/li>
&lt;li>計算需開啟的檔案總數（含 SKILL.md）&lt;/li>
&lt;li>任一情境路徑長度 &amp;gt; 2 即 M1 FAIL&lt;/li>
&lt;/ol>
&lt;h3 id="6-個觸發情境的預期路徑">6 個觸發情境的預期路徑&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>#&lt;/th>
 &lt;th>觸發情境&lt;/th>
 &lt;th>典型讀者問題&lt;/th>
 &lt;th>預期路徑&lt;/th>
 &lt;th>路徑長度&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>1&lt;/td>
 &lt;td>要寫一段程式碼註解&lt;/td>
 &lt;td>「這個函式的註解該寫什麼？doc comment 和 inline 要怎麼選？」&lt;/td>
 &lt;td>SKILL.md → writing-code-comments.md&lt;/td>
 &lt;td>2&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>2&lt;/td>
 &lt;td>要起草一份文件（worklog/markdown）&lt;/td>
 &lt;td>「章節怎麼切？哪些資訊該放、哪些不該放？」&lt;/td>
 &lt;td>SKILL.md → writing-documents.md&lt;/td>
 &lt;td>2&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>3&lt;/td>
 &lt;td>要設計 log 訊息&lt;/td>
 &lt;td>「這個 log 要寫什麼關鍵字才搜得到？」&lt;/td>
 &lt;td>SKILL.md → writing-logs.md&lt;/td>
 &lt;td>2&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>4&lt;/td>
 &lt;td>要撰寫 prompt&lt;/td>
 &lt;td>「怎麼讓 prompt 更省 token 又講清楚意圖？」&lt;/td>
 &lt;td>SKILL.md → writing-prompts.md&lt;/td>
 &lt;td>2&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>5&lt;/td>
 &lt;td>要設計 ticket/schema 欄位&lt;/td>
 &lt;td>「what 和 why 欄位怎麼分？frontmatter 要有哪些欄位？」&lt;/td>
 &lt;td>SKILL.md → designing-fields.md&lt;/td>
 &lt;td>2&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>6&lt;/td>
 &lt;td>要驗證寫作品質（自評）&lt;/td>
 &lt;td>「我寫完了，怎麼知道有沒有達標？」&lt;/td>
 &lt;td>SKILL.md → meta-metrics.md&lt;/td>
 &lt;td>2&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>預期總平均&lt;/strong>：2（所有情境都是 SKILL.md + 1 個 reference）。&lt;/p></description><content:encoded><![CDATA[<p>本 reference 定義 compositional-writing Skill 的品質量化驗收方式。寫得好不好是主觀判斷，metric 讓它變成可重複驗證的客觀評估。</p>
<blockquote>
<p><strong>核心理念</strong>：Metric 是自評工具，不是硬性 KPI。目的是讓「達成/未達成」可被重複驗證，並在 Skill 演化過程中守住設計底線。</p></blockquote>
<hr>
<h2 id="何時參閱本檔">何時參閱本檔</h2>
<table>
  <thead>
      <tr>
          <th>觸發情境</th>
          <th>動作</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>驗收本 Skill 新增或修改的 reference</td>
          <td>跑 M1-M2 檢查</td>
      </tr>
      <tr>
          <td>決定是否拆分/合併 reference</td>
          <td>用 M2 評估獨立理解率</td>
      </tr>
      <tr>
          <td>懷疑 SKILL.md 路由設計失靈</td>
          <td>用 M1 跑 6 情境預期路徑</td>
      </tr>
      <tr>
          <td>Skill 發布前的品質門</td>
          <td>M1 + M2 全綠才允許發布（M3-M5 待定後納入）</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="metric-總覽">Metric 總覽</h2>
<table>
  <thead>
      <tr>
          <th>ID</th>
          <th>名稱</th>
          <th>類別</th>
          <th>目標值</th>
          <th>量測方式</th>
          <th>狀態</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>M1</td>
          <td>找到答案路徑長度</td>
          <td>認知負擔</td>
          <td>≤ 2 個檔案</td>
          <td>6 情境預期路徑對照</td>
          <td>正式</td>
      </tr>
      <tr>
          <td>M2</td>
          <td>reference 獨立理解率</td>
          <td>認知負擔</td>
          <td>100%</td>
          <td>逐 reference 獨立閱讀檢查</td>
          <td>正式</td>
      </tr>
      <tr>
          <td>M3</td>
          <td>SKILL.md 主檔 token 上限</td>
          <td>Token</td>
          <td>≤ 5000 tokens（候選）</td>
          <td>Tokenizer 計數</td>
          <td>未決（待實際範例後定）</td>
      </tr>
      <tr>
          <td>M4</td>
          <td>單一 reference 觸發載入 token</td>
          <td>Token</td>
          <td>≤ 3000 tokens（候選）</td>
          <td>Tokenizer 計數</td>
          <td>未決（待實際範例後定）</td>
      </tr>
      <tr>
          <td>M5</td>
          <td>grep 定位問題的 token 成本</td>
          <td>Token</td>
          <td>&lt; 500 tokens（候選）</td>
          <td>grep + tokenizer 實測</td>
          <td>未決（待實際範例後定）</td>
      </tr>
  </tbody>
</table>
<p>認知負擔類（M1-M2）為本版正式 metric；Token 類（M3-M5）為候選，待 references/ 內容穩定後再定最終閾值。</p>
<hr>
<h2 id="m1--找到答案路徑長度">M1 — 找到答案路徑長度</h2>
<h3 id="定義">定義</h3>
<p>讀者帶著一個寫作問題從 SKILL.md 開始，<strong>需要開啟幾個檔案</strong>才能解決問題。路徑長度 = SKILL.md 外額外開啟的 reference 檔案數。</p>
<ul>
<li>路徑 1：只讀 SKILL.md 就解決（極罕見，只適用於速查表即可回答的問題）</li>
<li>路徑 2：SKILL.md 指引 → 開啟 1 個 reference（預期主流）</li>
<li>路徑 3+：SKILL.md → reference A → reference B（違反本 metric）</li>
</ul>
<h3 id="目標值">目標值</h3>
<p><strong>≤ 2</strong>（SKILL.md + 1 個 reference 即解決）。</p>
<h3 id="量測方式">量測方式</h3>
<p>針對本 Skill 支援的 6 個觸發情境，逐一演練：</p>
<ol>
<li>模擬讀者帶著該情境的問題進入 SKILL.md</li>
<li>依照 SKILL.md 觸發路由表選擇 reference</li>
<li>計算需開啟的檔案總數（含 SKILL.md）</li>
<li>任一情境路徑長度 &gt; 2 即 M1 FAIL</li>
</ol>
<h3 id="6-個觸發情境的預期路徑">6 個觸發情境的預期路徑</h3>
<table>
  <thead>
      <tr>
          <th>#</th>
          <th>觸發情境</th>
          <th>典型讀者問題</th>
          <th>預期路徑</th>
          <th>路徑長度</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1</td>
          <td>要寫一段程式碼註解</td>
          <td>「這個函式的註解該寫什麼？doc comment 和 inline 要怎麼選？」</td>
          <td>SKILL.md → writing-code-comments.md</td>
          <td>2</td>
      </tr>
      <tr>
          <td>2</td>
          <td>要起草一份文件（worklog/markdown）</td>
          <td>「章節怎麼切？哪些資訊該放、哪些不該放？」</td>
          <td>SKILL.md → writing-documents.md</td>
          <td>2</td>
      </tr>
      <tr>
          <td>3</td>
          <td>要設計 log 訊息</td>
          <td>「這個 log 要寫什麼關鍵字才搜得到？」</td>
          <td>SKILL.md → writing-logs.md</td>
          <td>2</td>
      </tr>
      <tr>
          <td>4</td>
          <td>要撰寫 prompt</td>
          <td>「怎麼讓 prompt 更省 token 又講清楚意圖？」</td>
          <td>SKILL.md → writing-prompts.md</td>
          <td>2</td>
      </tr>
      <tr>
          <td>5</td>
          <td>要設計 ticket/schema 欄位</td>
          <td>「what 和 why 欄位怎麼分？frontmatter 要有哪些欄位？」</td>
          <td>SKILL.md → designing-fields.md</td>
          <td>2</td>
      </tr>
      <tr>
          <td>6</td>
          <td>要驗證寫作品質（自評）</td>
          <td>「我寫完了，怎麼知道有沒有達標？」</td>
          <td>SKILL.md → meta-metrics.md</td>
          <td>2</td>
      </tr>
  </tbody>
</table>
<p><strong>預期總平均</strong>：2（所有情境都是 SKILL.md + 1 個 reference）。</p>
<h3 id="量測通過條件">量測通過條件</h3>
<ul>
<li><input disabled="" type="checkbox"> 6 個情境逐一演練，每個路徑長度 ≤ 2</li>
<li><input disabled="" type="checkbox"> 無需開啟 reference 後再被引導到另一個 reference（禁止鏈式引用）</li>
<li><input disabled="" type="checkbox"> SKILL.md 的觸發路由表涵蓋 6 個情境，且每個情境對應唯一 reference</li>
</ul>
<h3 id="量測失敗的典型訊號">量測失敗的典型訊號</h3>
<table>
  <thead>
      <tr>
          <th>訊號</th>
          <th>根因</th>
          <th>對應修正</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>讀者讀完某 reference 仍需再開第二個 reference</td>
          <td>reference 未自包含，資訊散落</td>
          <td>把缺漏的原則說明直接寫入該 reference</td>
      </tr>
      <tr>
          <td>同一問題在 SKILL.md 路由表找到兩個候選 reference</td>
          <td>情境切分重疊</td>
          <td>重新畫 reference 邊界，情境不重複</td>
      </tr>
      <tr>
          <td>某情境找不到對應 reference</td>
          <td>情境覆蓋不足</td>
          <td>新增 reference 或擴充最近情境的覆蓋範圍</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="m2--reference-獨立理解率">M2 — reference 獨立理解率</h2>
<h3 id="定義-1">定義</h3>
<p>隨機挑選一個 reference，讀者<strong>不看其他 reference、不看 SKILL.md</strong> 的情況下，能否獨立理解該 reference 的完整意義並套用到寫作情境。</p>
<h3 id="目標值-1">目標值</h3>
<p><strong>100%</strong>（每個 reference 都必須能獨立理解）。</p>
<h3 id="量測方式-1">量測方式</h3>
<p>對每個 reference 執行「獨立閱讀檢查」：</p>
<ol>
<li>隨機挑一個 reference（不提供 SKILL.md 和其他 reference）</li>
<li>讀完後自問以下四個問題：
<ul>
<li>我能否說出這份 reference 在講什麼情境？</li>
<li>我能否判斷自己遇到的問題適不適合用這份 reference？</li>
<li>我能否直接套用它給出的原則到我的寫作？</li>
<li>我是否需要去翻其他檔案才能理解某個名詞或規則？</li>
</ul>
</li>
<li>任一問題答案為「否」（第 4 題為「是」也算否）即 M2 FAIL</li>
</ol>
<p><strong>量測注意事項：必須讀實際內文</strong>。大綱式 review（只看標題、目錄、frontmatter 描述）無法判讀：</p>
<ul>
<li>議題是否切了一半（標題用「+」綁兩概念但內文機制完全不同）</li>
<li>語氣是否絕對主義（「正確概念是 X」vs「比較好的做法是 A、因為 [情境]」）</li>
<li>各段落是否服務同一個 focus（內文段落離題、與標題承諾不符）</li>
<li>引用是否有實質說明（「另見 X」vs「具體做法由 X 完整展開、本篇要記住的是 [&hellip;]」）</li>
</ul>
<p>M2 評估必須讀完整內文、不能只看標題與大綱。</p>
<h3 id="量測通過條件-1">量測通過條件</h3>
<ul>
<li><input disabled="" type="checkbox"> 每個 reference 內部有完整的「情境說明」章節，讀者不看 SKILL.md 也能判斷適用性</li>
<li><input disabled="" type="checkbox"> 所有核心原則（原子化、索引、意圖顯性與商業邏輯、可查詢性、欄位設計）在該 reference 需要時<strong>就地說明</strong>（不引用其他 reference）</li>
<li><input disabled="" type="checkbox"> 專有名詞（Zettelkasten/MOC/原子化等）在首次出現時給出就地定義或連結到外部公認資源</li>
<li><input disabled="" type="checkbox"> reference 間無內部交叉引用（禁止 A→B→C 鏈式）</li>
</ul>
<h3 id="獨立理解率計算">獨立理解率計算</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">獨立理解率 = 通過檢查的 reference 數 / reference 總數 × 100%</span></span></code></pre></div><p>目標 100%，任一 reference 失敗即整體 M2 FAIL。</p>
<h3 id="量測失敗的典型訊號-1">量測失敗的典型訊號</h3>
<table>
  <thead>
      <tr>
          <th>訊號</th>
          <th>根因</th>
          <th>對應修正</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>讀者讀完後說「我要先去看另一個 reference 才懂」</td>
          <td>內部交叉引用</td>
          <td>把被引用的原則說明複製/濃縮到本 reference</td>
      </tr>
      <tr>
          <td>讀者無法判斷「這份 reference 講的是什麼情境」</td>
          <td>情境說明章節缺失或模糊</td>
          <td>開頭新增「何時參閱本檔」或「適用情境」章節</td>
      </tr>
      <tr>
          <td>讀者看到專有名詞卡住</td>
          <td>未就地定義</td>
          <td>在首次出現處加一行解釋或外部連結</td>
      </tr>
      <tr>
          <td>大綱式 review 通過、讀內文發現議題切一半 / 語氣絕對主義 / focus 發散</td>
          <td>M2 量測只看標題大綱、沒讀內文</td>
          <td>量測流程加上「讀完整內文」要求；review 標題與內文一致、不能只信任標題承諾</td>
      </tr>
      <tr>
          <td>教某條規則的段落本身違反該規則（dogfooding 失敗）</td>
          <td>reference 寫作沒套用自己教的規則</td>
          <td>寫完每段教學文字後跑「這段教學的規則 X 適用於這段文字本身嗎？適用 → 符合嗎？」自問</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="m3--skillmd-主檔-token-上限候選未決">M3 — SKILL.md 主檔 token 上限（候選，未決）</h2>
<h3 id="定義-2">定義</h3>
<p>SKILL.md 主檔被 Claude 載入時的 token 消耗總量。</p>
<h3 id="候選目標值">候選目標值</h3>
<p><strong>≤ 5000 tokens</strong>（對齊 Anthropic 官方建議：SKILL.md body &lt; 5k tokens）。</p>
<h3 id="量測方式候選">量測方式（候選）</h3>
<ol>
<li>用 Anthropic tokenizer 或 Claude Code 內建計數計算 SKILL.md 全文 token 數</li>
<li>扣除 YAML frontmatter（frontmatter 常駐 system prompt，另計）</li>
<li>body token 數須 ≤ 5000</li>
</ol>
<h3 id="狀態">狀態</h3>
<p><strong>未決</strong>。實際閾值待 SKILL.md 與各 reference 完成後，量測實際 token 數再定最終值。可能調整方向：</p>
<ul>
<li>若實際 SKILL.md 穩定在 2000 tokens 內，閾值可降為 3000 tokens 作為緩衝</li>
<li>若 SKILL.md 接近 5000 tokens，需拆分更多內容到 references 而非放寬閾值</li>
</ul>
<hr>
<h2 id="m4--單一-reference-觸發載入-token候選未決">M4 — 單一 reference 觸發載入 token（候選，未決）</h2>
<h3 id="定義-3">定義</h3>
<p>單一 reference 被 Claude 按需載入時的 token 消耗量。</p>
<h3 id="候選目標值-1">候選目標值</h3>
<p><strong>≤ 3000 tokens</strong>（避免單一 reference 過大，讓讀者/Claude 只能全讀）。</p>
<h3 id="量測方式候選-1">量測方式（候選）</h3>
<ol>
<li>對每個 reference 計算 token 數</li>
<li>任一 reference &gt; 3000 tokens 即 FAIL</li>
<li>超標的 reference 應檢討：是否混入多個情境？是否能切分？</li>
</ol>
<h3 id="狀態-1">狀態</h3>
<p><strong>未決</strong>。實際閾值待所有 reference 完成後依分佈定案。候選分級：</p>
<ul>
<li>嚴格（&lt; 2000）：強制 reference 高度原子化</li>
<li>寬鬆（&lt; 4000）：允許情境 reference 包含更多實例</li>
<li>最終選擇依 Skill 各 reference 完成後的實測資料定</li>
</ul>
<hr>
<h2 id="m5--grep-定位問題的-token-成本候選未決">M5 — grep 定位問題的 token 成本（候選，未決）</h2>
<h3 id="定義-4">定義</h3>
<p>讀者/AI 用 grep + 關鍵字在 Skill 內定位到答案時，所讀取的 token 總成本。</p>
<h3 id="候選目標值-2">候選目標值</h3>
<p><strong>&lt; 500 tokens</strong>（grep 結果片段 + 關鍵命中行的上下文即能回答問題）。</p>
<h3 id="量測方式候選-2">量測方式（候選）</h3>
<ol>
<li>挑選 10 個代表性寫作問題</li>
<li>用對應關鍵字 grep 全 Skill 內容</li>
<li>取前 N 個命中（N=3），計算閱讀命中上下文所需 token</li>
<li>任一問題 &gt; 500 tokens 即 FAIL</li>
</ol>
<h3 id="狀態-2">狀態</h3>
<p><strong>未決</strong>。此 metric 需要：</p>
<ul>
<li>先建立「代表性問題」清單（10-20 個）</li>
<li>實測 grep 命中品質（關鍵字設計是否到位）</li>
<li>依實測結果決定 500/1000/2000 tokens 哪個是可行閾值</li>
</ul>
<hr>
<h2 id="自評流程">自評流程</h2>
<h3 id="何時執行">何時執行</h3>
<table>
  <thead>
      <tr>
          <th>場景</th>
          <th>執行的 Metric</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>新增 reference 時</td>
          <td>M1（新增情境路徑）+ M2（新 reference 獨立理解率）</td>
      </tr>
      <tr>
          <td>修改 reference 內容時</td>
          <td>M2（該 reference 獨立理解率）+ M1（若觸發路由變動）</td>
      </tr>
      <tr>
          <td>修改 SKILL.md 路由表時</td>
          <td>M1 全 6 情境重測</td>
      </tr>
      <tr>
          <td>Skill 版本發布前</td>
          <td>M1 + M2 全綠（M3-M5 定案後納入）</td>
      </tr>
      <tr>
          <td>定期健檢（每季）</td>
          <td>全部 metric 重跑</td>
      </tr>
  </tbody>
</table>
<h3 id="由誰執行">由誰執行</h3>
<ul>
<li>撰寫者自評：寫完立即跑 M1 + M2</li>
<li>審查者覆核：Skill PR/Ticket 驗收時跑全 metric</li>
<li>跨專案使用者：在 marketplace 下載 Skill 後，建議跑 M2 確認獨立理解率</li>
</ul>
<h3 id="用什麼工具">用什麼工具</h3>
<table>
  <thead>
      <tr>
          <th>Metric</th>
          <th>工具</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>M1</td>
          <td>手動演練（6 情境對照表）+ 本檔「量測通過條件」清單</td>
      </tr>
      <tr>
          <td>M2</td>
          <td>手動獨立閱讀 + 四問檢查清單</td>
      </tr>
      <tr>
          <td>M3</td>
          <td>Anthropic tokenizer / Claude Code 內建 token 計數</td>
      </tr>
      <tr>
          <td>M4</td>
          <td>同 M3，per-file 計數</td>
      </tr>
      <tr>
          <td>M5</td>
          <td>grep（或 ripgrep）+ tokenizer</td>
      </tr>
  </tbody>
</table>
<h3 id="自評產出格式">自評產出格式</h3>
<p>建議自評結果以下表記錄（貼到 Skill 或相關 ticket 的驗收區）：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">Metric 自評結果（日期 / 執行者）
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">| Metric | 結果 | 備註 |
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">|--------|------|------|
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">| M1 | PASS (所有情境 ≤ 2) | — |
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">| M2 | PASS (6/6 reference 獨立理解) | — |
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">| M3 | N/A（未決） | SKILL.md 實測 XXXX tokens |
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">| M4 | N/A（未決） | 最大 reference XXXX tokens |
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">| M5 | N/A（未決） | 待關鍵字清單定案 |
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl">整體結論：PASS / FAIL + 須修正項目清單</span></span></code></pre></div><hr>
<h2 id="metric-間的優先級">Metric 間的優先級</h2>
<p>當 metric 之間出現張力時，依下列順序取捨：</p>
<ol>
<li><strong>M2 &gt; M1</strong>：若為了降低路徑長度而讓某 reference 依賴另一個 reference，優先維持獨立理解（M2），重新設計路由而非犧牲獨立性</li>
<li><strong>M1 &gt; M3/M4</strong>：若為了壓 token 而切得太細導致路徑長度 &gt; 2，優先維持 M1，放寬單檔 token 閾值</li>
<li><strong>M2 &gt; M5</strong>：若為了 grep 定位成本而在多處重複同一關鍵說明，優先維持 M2（獨立理解），允許 grep 命中多個檔案但每個命中都能獨立看懂</li>
</ol>
<p><strong>核心排序</strong>：M2 &gt; M1 &gt; M5 &gt; M3 ≈ M4</p>
<p>這個排序反映：獨立理解是 compositional writing 的命脈（卡片盒核心），路徑長度是讀者體驗，token 是工程成本；若三者衝突，優先守住可理解性。</p>
<hr>
<h2 id="與上層原則的對應">與上層原則的對應</h2>
<table>
  <thead>
      <tr>
          <th>Metric</th>
          <th>守護的寫作原則</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>M1</td>
          <td>情境匹配度（一個情境對應一張卡）</td>
      </tr>
      <tr>
          <td>M2</td>
          <td>原子化（一張卡獨立自足）+ 可查詢性（就地定義）</td>
      </tr>
      <tr>
          <td>M3</td>
          <td>精簡至上（Concise is Key）</td>
      </tr>
      <tr>
          <td>M4</td>
          <td>原子化（reference 不過度肥大）</td>
      </tr>
      <tr>
          <td>M5</td>
          <td>可查詢性（關鍵字設計到位）</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="變更歷史">變更歷史</h2>
<table>
  <thead>
      <tr>
          <th>版本</th>
          <th>變更</th>
          <th>日期</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>0.1.0</td>
          <td>初版，M1-M2 正式、M3-M5 候選未決</td>
          <td>2026-04-16</td>
      </tr>
      <tr>
          <td>0.2.0</td>
          <td>M2 量測方式補強「必須讀實際內文」注意事項與失敗訊號（從 report folder 50+ 篇 review 經驗回流：大綱式 review 漏了議題切一半、語氣絕對主義、focus 發散等內文層問題）</td>
          <td>2026-04-25</td>
      </tr>
      <tr>
          <td>0.3.0</td>
          <td>M2 失敗訊號加 dogfooding 失敗 — 教某條規則的段落本身違反該規則（從 v0.5.0 / v0.6.0 寫作經驗回流）</td>
          <td>2026-04-25</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>Reference Authoring Standards — Skill reference 撰寫品質規範</title><link>https://tarrragon.github.io/blog/skills/compositional-writing/reference-authoring-standards/</link><pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/skills/compositional-writing/reference-authoring-standards/</guid><description>&lt;p>本文件為 compositional-writing Skill 的 reference 撰寫品質規範。適用對象：新增或修改本 Skill 任何 reference 的作者（人類或代理人）。&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>自包含聲明&lt;/strong>：閱讀本文件不需要先讀其他 reference。品質驗收 metric（M1-M2）見 &lt;code>meta-metrics.md&lt;/code>；本文件聚焦「如何寫出符合品質的 reference」。&lt;/p>&lt;/blockquote>
&lt;hr>
&lt;h2 id="何時參閱本文件">何時參閱本文件&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>觸發情境&lt;/th>
 &lt;th>動作&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>新增一份 reference&lt;/td>
 &lt;td>遵循本文件的結構模板和品質標準&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>修改現有 reference&lt;/td>
 &lt;td>確認改後仍符合五項必要要素&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>審查 Skill PR/Ticket&lt;/td>
 &lt;td>逐項對照本文件的「驗收清單」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>懷疑某 reference 違反原子化&lt;/td>
 &lt;td>執行「職責單一性測試」&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="一份合格-reference-的五項必要要素">一份合格 Reference 的五項必要要素&lt;/h2>
&lt;h3 id="要素-1情境聲明何時讀這份文件">要素 1：情境聲明（何時讀這份文件）&lt;/h3>
&lt;p>每份 reference 的開頭必須有明確的「情境說明」段落，讓讀者在 30 秒內判斷適用性。&lt;/p>
&lt;p>&lt;strong>必須回答的問題&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>這份 reference 服務哪種寫作情境？&lt;/li>
&lt;li>讀者帶著什麼問題進來？&lt;/li>
&lt;li>不適用的情境是什麼？&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>範本&lt;/strong>：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">本 reference 為「撰寫 prompt / instruction / Agent 派發」情境。
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">適用：給 AI 模型的指令；Ticket Context Bundle；結構化派發 prompt。
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">不適用：文件（見 writing-documents.md）；程式碼註解（見 writing-code-comments.md）。&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>反例&lt;/strong>（情境不明確）：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">本文件說明寫作原則的應用。&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h3 id="要素-2職責單一性原子化測試">要素 2：職責單一性（原子化測試）&lt;/h3>
&lt;p>每份 reference 只服務一個讀者群體、回答一類問題。&lt;/p>
&lt;p>&lt;strong>判斷方法（原子化測試）&lt;/strong>：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>問題&lt;/th>
 &lt;th>若需要「和」連接兩個答案&lt;/th>
 &lt;th>行動&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>「這份文件的讀者是誰？」&lt;/td>
 &lt;td>兩個不同讀者群體&lt;/td>
 &lt;td>必須拆分&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>「讀者帶著什麼問題來？」&lt;/td>
 &lt;td>兩類不相關問題&lt;/td>
 &lt;td>必須拆分&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>「讀完後讀者能做什麼？」&lt;/td>
 &lt;td>兩件不相關的事&lt;/td>
 &lt;td>必須拆分&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>反例&lt;/strong>（雙重職責）：&lt;/p>
&lt;p>一份 reference 同時說明「如何撰寫 prompt」AND「如何撰寫其他 reference」——兩個讀者群體、兩種產出，必須拆分。&lt;/p>
&lt;hr>
&lt;h3 id="要素-3自包含性m2-通過">要素 3：自包含性（M2 通過）&lt;/h3>
&lt;p>讀者&lt;strong>不看 SKILL.md 和其他 reference&lt;/strong> 的情況下，能獨立理解並套用。&lt;/p>
&lt;p>&lt;strong>自包含清單&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>&lt;input disabled="" type="checkbox"> 開頭有情境說明（不依賴 SKILL.md 判斷適用性）&lt;/li>
&lt;li>&lt;input disabled="" type="checkbox"> 文件內所有原則在本文件內展開（不引用其他 reference）&lt;/li>
&lt;li>&lt;input disabled="" type="checkbox"> 專有名詞在首次出現時給出就地定義&lt;/li>
&lt;li>&lt;input disabled="" type="checkbox"> 無「見 writing-xxx.md」的交叉引用（禁止鏈式）&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>可接受的外部引用&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>引用外部公認資源（Anthropic 官方文件、業界標準）&lt;/li>
&lt;li>引用 SKILL.md 觸發路由（只在「閱讀決策」表格中）&lt;/li>
&lt;li>引用 meta-metrics.md 的量測方式（品質驗收場景）&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="要素-4結構一致性">要素 4：結構一致性&lt;/h3>
&lt;p>本 Skill 的所有 reference 遵循相同的段落骨架，便於讀者跨文件快速定位。&lt;/p>
&lt;p>&lt;strong>標準骨架&lt;/strong>：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="gh"># [Reference 名稱]
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">&lt;span class="gh">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">[1-3 行情境說明，含適用/不適用聲明]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="k">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">&lt;span class="k">&amp;gt; &lt;/span>&lt;span class="ge">**自包含聲明**：[說明閱讀本文件是否需要其他前置文件]
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">&lt;span class="ge">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">---
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">&lt;span class="gu">## 何時參閱本文件（或：情境定位）
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">&lt;span class="gu">&lt;/span>[觸發情境表格]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">&lt;span class="gu">## 為什麼 [情境] 需要獨立指引
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">&lt;span class="gu">&lt;/span>[說明此情境的特殊性，與一般文件的差異]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl">&lt;span class="gu">## [核心原則 × 情境] 的應用
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">16&lt;/span>&lt;span class="cl">&lt;span class="gu">&lt;/span>（依情境選擇相關原則展開，每個原則含判斷標準 + 反例 + 正確做法）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">17&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">18&lt;/span>&lt;span class="cl">&lt;span class="gu">## [情境特有章節]
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">19&lt;/span>&lt;span class="cl">&lt;span class="gu">&lt;/span>（例如：Token 節省策略、結構化範例、自檢清單、反模式速查）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">20&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">21&lt;/span>&lt;span class="cl">## 延伸閱讀（可選）&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>允許調整&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>章節名稱可隨情境調整（「Token 節省策略」僅適用 prompt；「Log 結構化格式」僅適用 logs）&lt;/li>
&lt;li>字數無硬性上限，但每個章節應只承載一個概念（M4 候選閾值 ≤ 3000 tokens）&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="要素-5范例的具體性">要素 5：范例的具體性&lt;/h3>
&lt;p>範例必須足夠具體，讀者能「複製後略作修改直接套用」。&lt;/p>
&lt;p>&lt;strong>範例品質標準&lt;/strong>：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>標準&lt;/th>
 &lt;th>說明&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>有反例對照&lt;/td>
 &lt;td>每個原則至少一組「錯 vs 對」範例&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>反例真實&lt;/td>
 &lt;td>反例應來自真實常見錯誤，不是刻意構造的極端案例&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>正例可直接套用&lt;/td>
 &lt;td>正例使用佔位符 &lt;code>{ticket_id}&lt;/code> 等，讀者換掉佔位符即可使用&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>說明節省量（如適用）&lt;/td>
 &lt;td>Token 節省策略應標注估計節省比例&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="新增-reference-的決策流程">新增 Reference 的決策流程&lt;/h2>
&lt;p>在建立新 reference 前，先回答以下問題：&lt;/p></description><content:encoded><![CDATA[<p>本文件為 compositional-writing Skill 的 reference 撰寫品質規範。適用對象：新增或修改本 Skill 任何 reference 的作者（人類或代理人）。</p>
<blockquote>
<p><strong>自包含聲明</strong>：閱讀本文件不需要先讀其他 reference。品質驗收 metric（M1-M2）見 <code>meta-metrics.md</code>；本文件聚焦「如何寫出符合品質的 reference」。</p></blockquote>
<hr>
<h2 id="何時參閱本文件">何時參閱本文件</h2>
<table>
  <thead>
      <tr>
          <th>觸發情境</th>
          <th>動作</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>新增一份 reference</td>
          <td>遵循本文件的結構模板和品質標準</td>
      </tr>
      <tr>
          <td>修改現有 reference</td>
          <td>確認改後仍符合五項必要要素</td>
      </tr>
      <tr>
          <td>審查 Skill PR/Ticket</td>
          <td>逐項對照本文件的「驗收清單」</td>
      </tr>
      <tr>
          <td>懷疑某 reference 違反原子化</td>
          <td>執行「職責單一性測試」</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="一份合格-reference-的五項必要要素">一份合格 Reference 的五項必要要素</h2>
<h3 id="要素-1情境聲明何時讀這份文件">要素 1：情境聲明（何時讀這份文件）</h3>
<p>每份 reference 的開頭必須有明確的「情境說明」段落，讓讀者在 30 秒內判斷適用性。</p>
<p><strong>必須回答的問題</strong>：</p>
<ul>
<li>這份 reference 服務哪種寫作情境？</li>
<li>讀者帶著什麼問題進來？</li>
<li>不適用的情境是什麼？</li>
</ul>
<p><strong>範本</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">本 reference 為「撰寫 prompt / instruction / Agent 派發」情境。
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl">適用：給 AI 模型的指令；Ticket Context Bundle；結構化派發 prompt。
</span></span><span class="line"><span class="ln">4</span><span class="cl">不適用：文件（見 writing-documents.md）；程式碼註解（見 writing-code-comments.md）。</span></span></code></pre></div><p><strong>反例</strong>（情境不明確）：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">本文件說明寫作原則的應用。</span></span></code></pre></div><hr>
<h3 id="要素-2職責單一性原子化測試">要素 2：職責單一性（原子化測試）</h3>
<p>每份 reference 只服務一個讀者群體、回答一類問題。</p>
<p><strong>判斷方法（原子化測試）</strong>：</p>
<table>
  <thead>
      <tr>
          <th>問題</th>
          <th>若需要「和」連接兩個答案</th>
          <th>行動</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>「這份文件的讀者是誰？」</td>
          <td>兩個不同讀者群體</td>
          <td>必須拆分</td>
      </tr>
      <tr>
          <td>「讀者帶著什麼問題來？」</td>
          <td>兩類不相關問題</td>
          <td>必須拆分</td>
      </tr>
      <tr>
          <td>「讀完後讀者能做什麼？」</td>
          <td>兩件不相關的事</td>
          <td>必須拆分</td>
      </tr>
  </tbody>
</table>
<p><strong>反例</strong>（雙重職責）：</p>
<p>一份 reference 同時說明「如何撰寫 prompt」AND「如何撰寫其他 reference」——兩個讀者群體、兩種產出，必須拆分。</p>
<hr>
<h3 id="要素-3自包含性m2-通過">要素 3：自包含性（M2 通過）</h3>
<p>讀者<strong>不看 SKILL.md 和其他 reference</strong> 的情況下，能獨立理解並套用。</p>
<p><strong>自包含清單</strong>：</p>
<ul>
<li><input disabled="" type="checkbox"> 開頭有情境說明（不依賴 SKILL.md 判斷適用性）</li>
<li><input disabled="" type="checkbox"> 文件內所有原則在本文件內展開（不引用其他 reference）</li>
<li><input disabled="" type="checkbox"> 專有名詞在首次出現時給出就地定義</li>
<li><input disabled="" type="checkbox"> 無「見 writing-xxx.md」的交叉引用（禁止鏈式）</li>
</ul>
<p><strong>可接受的外部引用</strong>：</p>
<ul>
<li>引用外部公認資源（Anthropic 官方文件、業界標準）</li>
<li>引用 SKILL.md 觸發路由（只在「閱讀決策」表格中）</li>
<li>引用 meta-metrics.md 的量測方式（品質驗收場景）</li>
</ul>
<hr>
<h3 id="要素-4結構一致性">要素 4：結構一致性</h3>
<p>本 Skill 的所有 reference 遵循相同的段落骨架，便於讀者跨文件快速定位。</p>
<p><strong>標準骨架</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gh"># [Reference 名稱]
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gh"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">[1-3 行情境說明，含適用/不適用聲明]
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="k">
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="k">&gt; </span><span class="ge">**自包含聲明**：[說明閱讀本文件是否需要其他前置文件]
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="ge"></span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">---
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu">## 何時參閱本文件（或：情境定位）
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu"></span>[觸發情境表格]
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu">## 為什麼 [情境] 需要獨立指引
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu"></span>[說明此情境的特殊性，與一般文件的差異]
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="gu">## [核心原則 × 情境] 的應用
</span></span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="gu"></span>（依情境選擇相關原則展開，每個原則含判斷標準 + 反例 + 正確做法）
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="gu">## [情境特有章節]
</span></span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="gu"></span>（例如：Token 節省策略、結構化範例、自檢清單、反模式速查）
</span></span><span class="line"><span class="ln">20</span><span class="cl">
</span></span><span class="line"><span class="ln">21</span><span class="cl">## 延伸閱讀（可選）</span></span></code></pre></div><p><strong>允許調整</strong>：</p>
<ul>
<li>章節名稱可隨情境調整（「Token 節省策略」僅適用 prompt；「Log 結構化格式」僅適用 logs）</li>
<li>字數無硬性上限，但每個章節應只承載一個概念（M4 候選閾值 ≤ 3000 tokens）</li>
</ul>
<hr>
<h3 id="要素-5范例的具體性">要素 5：范例的具體性</h3>
<p>範例必須足夠具體，讀者能「複製後略作修改直接套用」。</p>
<p><strong>範例品質標準</strong>：</p>
<table>
  <thead>
      <tr>
          <th>標準</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>有反例對照</td>
          <td>每個原則至少一組「錯 vs 對」範例</td>
      </tr>
      <tr>
          <td>反例真實</td>
          <td>反例應來自真實常見錯誤，不是刻意構造的極端案例</td>
      </tr>
      <tr>
          <td>正例可直接套用</td>
          <td>正例使用佔位符 <code>{ticket_id}</code> 等，讀者換掉佔位符即可使用</td>
      </tr>
      <tr>
          <td>說明節省量（如適用）</td>
          <td>Token 節省策略應標注估計節省比例</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="新增-reference-的決策流程">新增 Reference 的決策流程</h2>
<p>在建立新 reference 前，先回答以下問題：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">1. 此情境是否已有 reference 覆蓋？
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">   是 → 擴充現有 reference（不新增）
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">   否 → 繼續
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">2. 此情境的讀者群體是否唯一（原子化測試）？
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">   否 → 拆分或重新定義情境邊界
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">   是 → 繼續
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">3. 此情境是否需要對核心原則的「情境翻譯」？
</span></span><span class="line"><span class="ln">10</span><span class="cl">   否 → 考慮是否應放入 SKILL.md 核心原則速查表（不需要獨立 reference）
</span></span><span class="line"><span class="ln">11</span><span class="cl">   是 → 建立新 reference
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl">4. 新 reference 加入後，SKILL.md 路由表的每個情境是否仍然唯一對應？
</span></span><span class="line"><span class="ln">14</span><span class="cl">   否 → 情境切分重疊，重新設計邊界
</span></span><span class="line"><span class="ln">15</span><span class="cl">   是 → 確認可新增</span></span></code></pre></div><hr>
<h2 id="驗收清單">驗收清單</h2>
<p>新增或修改 reference 後，逐項確認：</p>
<h3 id="職責單一性">職責單一性</h3>
<ul>
<li><input disabled="" type="checkbox"> 原子化測試通過（一個讀者群體、一類問題）</li>
<li><input disabled="" type="checkbox"> 無在標題或聲明中宣稱承擔多重職責</li>
</ul>
<h3 id="自包含性對應-m2">自包含性（對應 M2）</h3>
<ul>
<li><input disabled="" type="checkbox"> 情境說明段落存在，30 秒內可判斷適用性</li>
<li><input disabled="" type="checkbox"> 核心原則的必要內容在本文件內就地展開</li>
<li><input disabled="" type="checkbox"> 無交叉引用其他 reference（只允許外部公認資源引用）</li>
</ul>
<h3 id="結構一致性">結構一致性</h3>
<ul>
<li><input disabled="" type="checkbox"> 遵循標準骨架（情境說明 → 為什麼獨立 → 原則應用 → 情境章節 → 自檢清單）</li>
<li><input disabled="" type="checkbox"> 所有原則有反例 + 正例對照</li>
</ul>
<h3 id="路由一致性對應-m1">路由一致性（對應 M1）</h3>
<ul>
<li><input disabled="" type="checkbox"> SKILL.md 觸發路由表已更新</li>
<li><input disabled="" type="checkbox"> Directory Index 已更新</li>
<li><input disabled="" type="checkbox"> 新情境與現有情境無重疊</li>
</ul>
<h3 id="范例品質">范例品質</h3>
<ul>
<li><input disabled="" type="checkbox"> 每個原則有至少一組「錯 vs 對」</li>
<li><input disabled="" type="checkbox"> 正例使用 snake_case 佔位符，可直接套用</li>
</ul>
<hr>
<h2 id="與-meta-metricsmd-的分工">與 meta-metrics.md 的分工</h2>
<table>
  <thead>
      <tr>
          <th>文件</th>
          <th>職責</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>本文件（reference-authoring-standards.md）</td>
          <td>如何寫出合格 reference（撰寫指南）</td>
      </tr>
      <tr>
          <td><code>meta-metrics.md</code></td>
          <td>如何量測寫作品質（M1-M5 量化驗收）</td>
      </tr>
  </tbody>
</table>
<p>兩者互補：先用本文件的標準寫，再用 meta-metrics.md 的方法量測。</p>
<hr>
<p><strong>Last Updated</strong>: 2026-04-18
<strong>Version</strong>: 1.0.0 — 從 writing-prompts.md 雙職責拆分：Skill 品質規範獨立為本檔，writing-prompts.md 保留 prompt 寫作情境</p>
]]></content:encoded></item><item><title>Skills — Claude skill 的文章版本</title><link>https://tarrragon.github.io/blog/skills/</link><pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/skills/</guid><description>&lt;h2 id="這個資料夾是什麼">這個資料夾是什麼&lt;/h2>
&lt;p>&lt;code>content/skills/&lt;/code> 收錄&lt;strong>從 &lt;code>.claude/skills/&lt;/code> 轉成文章&lt;/strong>的 skill 版本。&lt;/p>
&lt;p>同一份 skill 有兩種存在形式，各自負責不同角色：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>位置&lt;/th>
 &lt;th>角色&lt;/th>
 &lt;th>讀者&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;code>.claude/skills/&amp;lt;name&amp;gt;/&lt;/code>&lt;/td>
 &lt;td>實際 skill，Claude runtime 呼叫&lt;/td>
 &lt;td>Claude&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>content/skills/&amp;lt;name&amp;gt;/&lt;/code>（本處）&lt;/td>
 &lt;td>文章版本，Hugo 渲染成 blog 頁&lt;/td>
 &lt;td>人類讀者&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>兩處內容相同、結構略有差異：&lt;code>.claude/&lt;/code> 版本保留原始 &lt;code>SKILL.md + references/&lt;/code> 巢狀結構以配合 Claude 的路徑解析；&lt;code>content/&lt;/code> 版本扁平化（references 內容升級到同層），以契合 blog 的單層文章呈現。&lt;/p>
&lt;h2 id="目前收錄的-skill">目前收錄的 skill&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Skill&lt;/th>
 &lt;th>主題&lt;/th>
 &lt;th>入口&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>compositional-writing&lt;/td>
 &lt;td>Zettelkasten 式組合寫作方法論&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/skills/compositional-writing/" data-link-title="Compositional Writing — 組合式寫作方法論" data-link-desc="以 Zettelkasten 為核心、針對程式碼註解、文件、log、prompt、欄位、長篇技術文章、外部分析材料轉教學文章、跨多篇 collection 結構的寫作方法論。核心原則 &amp;#43; 觸發路由 &amp;#43; 情境 reference。">/skills/compositional-writing/&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>requirement-protocol&lt;/td>
 &lt;td>需求確認到實作的對話協議（模糊指令、失敗轉折、漸進驗證等）&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/skills/requirement-protocol/" data-link-title="Requirement Protocol — 需求確認到實作的對話協議" data-link-desc="從需求確認到實作的對話協議：模糊指令澄清、可決定 vs 該確認、失敗 2 次轉折、覆寫成本告知、revert checkpoint、漸進驗證、工具切換時機。六大原則 &amp;#43; 五份情境 reference。">/skills/requirement-protocol/&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>frontend-with-playwright&lt;/td>
 &lt;td>框架無關的前端開發 + Playwright 驗證 + Filter × Source 跨領域 stream 操作（DOM / CSS / JS / framework 共處 / a11y / 資料流）&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/skills/frontend-with-playwright/" data-link-title="Frontend with Playwright — 框架無關的前端開發 &amp;#43; Playwright 驗證" data-link-desc="框架無關的前端開發協議 &amp;#43; Playwright 驗證：DOM topology 先於 CSS、CSS / JS 邊界辨識、Playwright 三個位置（假設 / 行為 / 互動驗證）、framework 共處、Reactive 效能、A11y、Filter × Source 跨領域 stream 操作。六大原則 &amp;#43; 七份情境 reference。">/skills/frontend-with-playwright/&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>wrap-decision&lt;/td>
 &lt;td>WRAP 決策框架（錨點確認、資料充足度、擴增選項、實境檢驗、機會成本、行前預想與絆腳索）&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/skills/wrap-decision/" data-link-title="WRAP 決策框架 — 認知偏誤防護與決策品質" data-link-desc="WRAP 決策框架的 blog 好讀版：用錨點確認、資料充足度、選項擴增、現實檢驗、機會成本、行前預想與絆腳索防止自動駕駛式決策。">/skills/wrap-decision/&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="把新-skill-轉成文章的標準流程">把新 skill 轉成文章的標準流程&lt;/h2>
&lt;p>以下步驟假設新 skill 已經放在 &lt;code>.claude/skills/&amp;lt;name&amp;gt;/&lt;/code>，包含 &lt;code>SKILL.md&lt;/code> 和（可能的）&lt;code>references/&lt;/code> 子資料夾。&lt;/p>
&lt;h3 id="step-1複製一份到-contentskills">Step 1：複製一份到 content/skills/&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">cp -R .claude/skills/&amp;lt;name&amp;gt; content/skills/&amp;lt;name&amp;gt;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Claude 版保持原樣、不再動它；所有後續修改都只改文章版。&lt;/p>
&lt;h3 id="step-2扁平化-references">Step 2：扁平化 references/&lt;/h3>
&lt;p>Blog 的文章層級為&lt;strong>單層&lt;/strong>，不保留 references 子資料夾。把所有 reference 移到跟 SKILL.md 同一層：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="nb">cd&lt;/span> content/skills/&amp;lt;name&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">git mv references/*.md .
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">git rm references/.gitkeep &lt;span class="c1"># 如果有&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">rmdir references&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="step-3把-skillmd-改成小寫-skillmd">Step 3：把 &lt;code>SKILL.md&lt;/code> 改成小寫 &lt;code>skill.md&lt;/code>&lt;/h3>
&lt;p>Hugo pretty URL 會把檔名小寫輸出（&lt;code>SKILL.md&lt;/code> → &lt;code>/skills/&amp;lt;name&amp;gt;/skill/&lt;/code>），但 &lt;code>mdtools cards&lt;/code> 連結檢查以&lt;strong>檔名大小寫敏感&lt;/strong>的方式解析 URL 回檔案位置。若檔案是 &lt;code>SKILL.md&lt;/code>，cards 嘗試開啟 &lt;code>skill.md&lt;/code> 找不到，就會報 &lt;code>L1-broken-link&lt;/code>。&lt;/p></description><content:encoded><![CDATA[<h2 id="這個資料夾是什麼">這個資料夾是什麼</h2>
<p><code>content/skills/</code> 收錄<strong>從 <code>.claude/skills/</code> 轉成文章</strong>的 skill 版本。</p>
<p>同一份 skill 有兩種存在形式，各自負責不同角色：</p>
<table>
  <thead>
      <tr>
          <th>位置</th>
          <th>角色</th>
          <th>讀者</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>.claude/skills/&lt;name&gt;/</code></td>
          <td>實際 skill，Claude runtime 呼叫</td>
          <td>Claude</td>
      </tr>
      <tr>
          <td><code>content/skills/&lt;name&gt;/</code>（本處）</td>
          <td>文章版本，Hugo 渲染成 blog 頁</td>
          <td>人類讀者</td>
      </tr>
  </tbody>
</table>
<p>兩處內容相同、結構略有差異：<code>.claude/</code> 版本保留原始 <code>SKILL.md + references/</code> 巢狀結構以配合 Claude 的路徑解析；<code>content/</code> 版本扁平化（references 內容升級到同層），以契合 blog 的單層文章呈現。</p>
<h2 id="目前收錄的-skill">目前收錄的 skill</h2>
<table>
  <thead>
      <tr>
          <th>Skill</th>
          <th>主題</th>
          <th>入口</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>compositional-writing</td>
          <td>Zettelkasten 式組合寫作方法論</td>
          <td><a href="/blog/skills/compositional-writing/" data-link-title="Compositional Writing — 組合式寫作方法論" data-link-desc="以 Zettelkasten 為核心、針對程式碼註解、文件、log、prompt、欄位、長篇技術文章、外部分析材料轉教學文章、跨多篇 collection 結構的寫作方法論。核心原則 &#43; 觸發路由 &#43; 情境 reference。">/skills/compositional-writing/</a></td>
      </tr>
      <tr>
          <td>requirement-protocol</td>
          <td>需求確認到實作的對話協議（模糊指令、失敗轉折、漸進驗證等）</td>
          <td><a href="/blog/skills/requirement-protocol/" data-link-title="Requirement Protocol — 需求確認到實作的對話協議" data-link-desc="從需求確認到實作的對話協議：模糊指令澄清、可決定 vs 該確認、失敗 2 次轉折、覆寫成本告知、revert checkpoint、漸進驗證、工具切換時機。六大原則 &#43; 五份情境 reference。">/skills/requirement-protocol/</a></td>
      </tr>
      <tr>
          <td>frontend-with-playwright</td>
          <td>框架無關的前端開發 + Playwright 驗證 + Filter × Source 跨領域 stream 操作（DOM / CSS / JS / framework 共處 / a11y / 資料流）</td>
          <td><a href="/blog/skills/frontend-with-playwright/" data-link-title="Frontend with Playwright — 框架無關的前端開發 &#43; Playwright 驗證" data-link-desc="框架無關的前端開發協議 &#43; Playwright 驗證：DOM topology 先於 CSS、CSS / JS 邊界辨識、Playwright 三個位置（假設 / 行為 / 互動驗證）、framework 共處、Reactive 效能、A11y、Filter × Source 跨領域 stream 操作。六大原則 &#43; 七份情境 reference。">/skills/frontend-with-playwright/</a></td>
      </tr>
      <tr>
          <td>wrap-decision</td>
          <td>WRAP 決策框架（錨點確認、資料充足度、擴增選項、實境檢驗、機會成本、行前預想與絆腳索）</td>
          <td><a href="/blog/skills/wrap-decision/" data-link-title="WRAP 決策框架 — 認知偏誤防護與決策品質" data-link-desc="WRAP 決策框架的 blog 好讀版：用錨點確認、資料充足度、選項擴增、現實檢驗、機會成本、行前預想與絆腳索防止自動駕駛式決策。">/skills/wrap-decision/</a></td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="把新-skill-轉成文章的標準流程">把新 skill 轉成文章的標準流程</h2>
<p>以下步驟假設新 skill 已經放在 <code>.claude/skills/&lt;name&gt;/</code>，包含 <code>SKILL.md</code> 和（可能的）<code>references/</code> 子資料夾。</p>
<h3 id="step-1複製一份到-contentskills">Step 1：複製一份到 content/skills/</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">cp -R .claude/skills/&lt;name&gt; content/skills/&lt;name&gt;</span></span></code></pre></div><p>Claude 版保持原樣、不再動它；所有後續修改都只改文章版。</p>
<h3 id="step-2扁平化-references">Step 2：扁平化 references/</h3>
<p>Blog 的文章層級為<strong>單層</strong>，不保留 references 子資料夾。把所有 reference 移到跟 SKILL.md 同一層：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">cd</span> content/skills/&lt;name&gt;
</span></span><span class="line"><span class="ln">2</span><span class="cl">git mv references/*.md .
</span></span><span class="line"><span class="ln">3</span><span class="cl">git rm references/.gitkeep       <span class="c1"># 如果有</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">rmdir references</span></span></code></pre></div><h3 id="step-3把-skillmd-改成小寫-skillmd">Step 3：把 <code>SKILL.md</code> 改成小寫 <code>skill.md</code></h3>
<p>Hugo pretty URL 會把檔名小寫輸出（<code>SKILL.md</code> → <code>/skills/&lt;name&gt;/skill/</code>），但 <code>mdtools cards</code> 連結檢查以<strong>檔名大小寫敏感</strong>的方式解析 URL 回檔案位置。若檔案是 <code>SKILL.md</code>，cards 嘗試開啟 <code>skill.md</code> 找不到，就會報 <code>L1-broken-link</code>。</p>
<p>避免這個陷阱，把 content 版本的檔名直接改成小寫：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">git mv content/skills/&lt;name&gt;/SKILL.md content/skills/&lt;name&gt;/skill.md</span></span></code></pre></div><p><code>.claude/</code> 版保留原本的 <code>SKILL.md</code>（符合 Claude skill 慣例）。兩邊檔名不同是刻意的：runtime 讀 <code>.claude/SKILL.md</code>、Hugo 渲染 <code>content/skill.md</code>、cards check 能解析。</p>
<h3 id="step-4修改-skillmd-的內部連結">Step 4：修改 skill.md 的內部連結</h3>
<p>skill.md 裡原本的 <code>references/X.md</code> 引用要改。有兩種合法寫法擇一：</p>
<ul>
<li><strong>Markdown 相對路徑</strong>：<code>./X.md</code> — 最無痛，Hugo render hook 會自動解析到對應頁面</li>
<li><strong>Hugo content-root 絕對路徑</strong>：<code>/skills/&lt;name&gt;/&lt;slug&gt;/</code> — 最穩，跟 blog 其他文章遷移後的寫法一致</li>
</ul>
<p>批次替換範例（將 <code>references/</code> 前綴整串刪除）：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s|references/|./|g&#39;</span> content/skills/&lt;name&gt;/skill.md</span></span></code></pre></div><p>記得同時更新 <code>## Directory Index</code> 區塊那張 ASCII tree — 刪掉 <code>└── references/</code> 那一層、所有 reference 檔案縮排提到 skill.md 同層。</p>
<h3 id="step-5建立-_indexmdsection-索引">Step 5：建立 <code>_index.md</code>（section 索引）</h3>
<p><code>content/skills/&lt;name&gt;/_index.md</code> 是 Hugo section 的 landing page，URL 是 <code>/skills/&lt;name&gt;/</code>。</p>
<p>必備欄位（Hugo + mdtools 要求）：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="nt">title</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;&lt;Skill 名稱中英對照&gt;&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w"></span><span class="nt">date</span><span class="p">:</span><span class="w"> </span><span class="l">&lt;YYYY-MM-DD&gt;</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w"></span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;&lt;一句話描述 skill 做什麼&gt;&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w"></span><span class="nt">tags</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">...]</span><span class="w">
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="w"></span><span class="nn">---</span></span></span></code></pre></div><p>內容建議包含：</p>
<ol>
<li><strong>簡述</strong>：這個 skill 是什麼、解決什麼問題</li>
<li><strong>閱讀順序</strong>：場景 1（第一次接觸）與場景 2（已熟悉、直接解決任務）兩個切入點</li>
<li><strong>觸發路由表</strong>：複製 SKILL.md 的「When to Consult This Skill」表，但把檔案路徑替換成 Hugo 絕對 URL（<code>/skills/&lt;name&gt;/&lt;slug&gt;/</code>）</li>
<li><strong>與 blog 其他資料的關係</strong>：對照表（<code>.claude/skills/&lt;name&gt;/</code>、相關 <code>content/posts/...</code>）</li>
<li><strong>Last Updated</strong>：同步日期與 <code>.claude/</code> 版 SKILL.md 的 version</li>
</ol>
<p>可參考 <a href="https://github.com/tarrragon/blog/blob/main/content/skills/compositional-writing/_index.md">compositional-writing 的 <code>_index.md</code></a> 當範本。</p>
<h3 id="step-6補-hugo-frontmatter-到-skillmd-與每份-reference">Step 6：補 Hugo frontmatter 到 skill.md 與每份 reference</h3>
<p>原始 skill.md 與 reference 的 frontmatter 是為 Claude runtime 設計的（欄位多為 <code>name</code>/<code>license</code>/<code>metadata</code>），Hugo 與 mdtools 需要的是 <code>title</code> + <code>date</code>。每份檔案：</p>
<ol>
<li>把原 frontmatter 保留或替換成 Hugo 規格（<code>title</code>、<code>date</code>、<code>description</code>、<code>tags</code>）</li>
<li>刪掉 body 開頭的 <code># H1</code>（Hugo 會從 <code>title</code> 自動生成 H1，保留會觸發 <code>MD025-no-body-h1</code>）</li>
</ol>
<h3 id="step-7跑-make-check-與-hugo-驗收">Step 7：跑 <code>make check</code> 與 <code>hugo</code> 驗收</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">make check    <span class="c1"># fmt + lint + cards，三個閘門全綠</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">hugo          <span class="c1"># 確認無 WARN/ERROR，page count 多了對應檔數</span></span></span></code></pre></div><p>幾個常見訊號與對應的修補點：</p>
<table>
  <thead>
      <tr>
          <th>訊號</th>
          <th>原因</th>
          <th>回頭修</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>lint <code>front-matter-required</code> / <code>MD025</code></td>
          <td>有檔案漏掉 frontmatter 或 body H1 沒刪</td>
          <td>Step 6</td>
      </tr>
      <tr>
          <td>cards <code>L1-broken-link target not found</code> 且路徑是 <code>skill/</code></td>
          <td>SKILL.md 沒改成 skill.md（檔名大小寫）</td>
          <td>Step 3</td>
      </tr>
      <tr>
          <td>hugo <code>REF_NOT_FOUND</code></td>
          <td>連結還指向 <code>references/</code></td>
          <td>Step 4</td>
      </tr>
  </tbody>
</table>
<h3 id="step-8更新本-contentskills_indexmd-的目前收錄表">Step 8：更新本 <code>content/skills/_index.md</code> 的「目前收錄」表</h3>
<p>把新 skill 加入上方的表格，含主題一句話與 Hugo URL。</p>
<h3 id="step-9commit">Step 9：commit</h3>
<p>單一 commit 收尾：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">git add .claude/skills/&lt;name&gt; content/skills/&lt;name&gt; content/skills/_index.md
</span></span><span class="line"><span class="ln">2</span><span class="cl">git commit -m <span class="s2">&#34;docs(skills): import &lt;name&gt; skill&#34;</span></span></span></code></pre></div><hr>
<h2 id="設計決策備忘">設計決策備忘</h2>
<h3 id="為什麼-claude-保留-referencescontent-扁平">為什麼 <code>.claude/</code> 保留 references/、<code>content/</code> 扁平？</h3>
<p><code>.claude/</code> 是 Claude runtime 的 SKILL 執行環境，SKILL.md 的路徑解析（<code>references/X.md</code>）是 skill 原生協議的一部分 — 改了會破壞 Claude 讀取行為。</p>
<p><code>content/</code> 是 blog 文章，Hugo 的 pretty URL 傾向單層結構（<code>/skills/name/page/</code> 比 <code>/skills/name/references/page/</code> 乾淨）。扁平化也讓 render hook 的 tooltip 與 mdtools 的 card graph 不必穿一層目錄。</p>
<p>兩種結構並行、各自最佳化、用 step 1 的複製動作維持同步。</p>
<h3 id="為什麼不直接-symlink-contentskills--claudeskills">為什麼不直接 symlink <code>content/skills/</code> → <code>.claude/skills/</code>？</h3>
<p>Symlink 會讓兩邊共用 frontmatter 與路徑規範。<code>.claude/</code> 版的 frontmatter 是 skill protocol（<code>name</code>/<code>license</code>/<code>metadata</code>），與 Hugo 要的（<code>title</code>/<code>date</code>）相衝；body 開頭的 <code># H1</code> 是 Claude 讀者的 context signpost，但在 Hugo 會跟 <code>title</code> 生的 H1 重複。結構上看似省事，語意上兩邊是不同受眾的產出，應該允許各自演化。</p>
<hr>
<h2 id="last-updated">Last Updated</h2>
<p>2026-04-24 — 初版：compositional-writing 轉文章完成，記錄標準流程。</p>
]]></content:encoded></item><item><title>Writing Articles — 完整長篇技術文章撰寫指引</title><link>https://tarrragon.github.io/blog/skills/compositional-writing/writing-articles/</link><pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/skills/compositional-writing/writing-articles/</guid><description>&lt;p>本文件為「撰寫完整長篇技術文章」情境的指引。適用於 blog post、post-mortem、架構決策文件、技術評估報告、概念深度說明等&lt;strong>需要保留思考過程&lt;/strong>的長篇內容。&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>自包含聲明&lt;/strong>：本文件不依賴其他 reference。讀完本文件即可獨立寫出合格技術文章。&lt;/p>
&lt;p>&lt;strong>來源&lt;/strong>：methodology 骨架整合自 &lt;code>tarrragon/blog&lt;/code> 的 &lt;code>tech_writing_structure.md&lt;/code>（2026-04-17）；與 compositional-writing 核心原則的映射由本檔補充。&lt;/p>&lt;/blockquote>
&lt;hr>
&lt;h2 id="與原子化寫作的分工">與原子化寫作的分工&lt;/h2>
&lt;p>compositional-writing 的核心主張是「寫原子卡片」，但完整文章是另一種產物：卡片是最小重用單元，文章是把多張卡片用&lt;strong>思考過程&lt;/strong>組織起來。兩者分工如下：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>原子化寫作（其他 references）&lt;/th>
 &lt;th>完整文章（本 reference）&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>產物形態&lt;/td>
 &lt;td>可單獨檢索的卡片、欄位、段落&lt;/td>
 &lt;td>有首尾、有推導的完整文章&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>讀者行為&lt;/td>
 &lt;td>grep / 點對點查詢&lt;/td>
 &lt;td>從頭讀到尾，追思考過程&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>組織原則&lt;/td>
 &lt;td>可重用、可跨情境&lt;/td>
 &lt;td>可複製思考路徑、不只複製結論&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>長度決策&lt;/td>
 &lt;td>越短越好（原子性優先）&lt;/td>
 &lt;td>需要多長就多長（完整性優先）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>失敗模式&lt;/td>
 &lt;td>卡片混雜多概念、無法獨立理解&lt;/td>
 &lt;td>觀察直接跳執行、判讀被省略&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>核心目標的差異&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>原子化：讓讀者「用最小認知負擔找到答案」&lt;/li>
&lt;li>完整文章：讓讀者「能複製思考過程，不只複製結論」。結論一行就能給；思考過程才是文章主體。&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="適用範圍">適用範圍&lt;/h2>
&lt;p>本 reference 適用於下列技術文章類型：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>類型&lt;/th>
 &lt;th>典型產物&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>概念說明&lt;/td>
 &lt;td>技術原理、系統架構、協定規格&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>實作教學&lt;/td>
 &lt;td>操作步驟、範例、API 用法&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>架構決策&lt;/td>
 &lt;td>方案比較、選型紀錄、設計文件&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>除錯復盤&lt;/td>
 &lt;td>事故紀錄、疑難排解、post-mortem&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>技術評估&lt;/td>
 &lt;td>工具調研、可行性評估&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="八條核心規則">八條核心規則&lt;/h2>
&lt;p>規則一-七 處理「單篇文章內部怎麼寫」的不同層面（段落結構、句子層級、方案對照）。規則八是 meta-level、跨所有規則。規則九指向 &lt;code>managing-article-collections.md&lt;/code> 處理跨多篇的議題。&lt;/p>
&lt;h3 id="規則一階段分層觀察--判讀--策略--執行">規則一：階段分層（觀察 → 判讀 → 策略 → 執行）&lt;/h3>
&lt;h4 id="規則的商業邏輯">規則的商業邏輯&lt;/h4>
&lt;p>技術文章的內容從「事實或需求」推導到「動作或結論」，這個過程有四個功能不同的階段。每個階段處理的問題不同、失敗模式不同：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>階段&lt;/th>
 &lt;th>處理的問題&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>觀察&lt;/td>
 &lt;td>描述現況、需求、事實或訊息&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>判讀&lt;/td>
 &lt;td>說明本質、原理、問題所在&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>策略&lt;/td>
 &lt;td>列出可選方案並比較&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>執行&lt;/td>
 &lt;td>具體操作或實作&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>四階段若混著寫，讀者無法區分「這一段失敗是哪個階段」，也無法判斷自己的類似情境卡在哪一步。文章只能被原封不動複製，不能被理解後套用。&lt;/p>
&lt;h4 id="做法">做法&lt;/h4>
&lt;p>每個主題段落應包含四階段。不同文章類型中四階段的對應：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>階段&lt;/th>
 &lt;th>概念說明&lt;/th>
 &lt;th>實作教學&lt;/th>
 &lt;th>架構決策&lt;/th>
 &lt;th>除錯復盤&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>觀察&lt;/td>
 &lt;td>需求或背景&lt;/td>
 &lt;td>使用情境&lt;/td>
 &lt;td>現況限制&lt;/td>
 &lt;td>錯誤訊息&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>判讀&lt;/td>
 &lt;td>概念本質&lt;/td>
 &lt;td>工具的位置與功能&lt;/td>
 &lt;td>需求本質&lt;/td>
 &lt;td>問題根因&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>策略&lt;/td>
 &lt;td>不同用法&lt;/td>
 &lt;td>不同操作路徑&lt;/td>
 &lt;td>可選方案&lt;/td>
 &lt;td>可行解法&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>執行&lt;/td>
 &lt;td>程式碼範例&lt;/td>
 &lt;td>操作步驟&lt;/td>
 &lt;td>選定實作&lt;/td>
 &lt;td>修復動作&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h4 id="反例跳過判讀觀察直接進執行">反例（跳過判讀，觀察直接進執行）&lt;/h4>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="gu">## 錯誤
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="gu">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">flutter_broadcasts_4m：Kotlin 1.8 vs Java 17 mismatch
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">&lt;span class="gu">## 解法
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">&lt;span class="gu">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">在 subprojects 加上：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl">tasks.withType(KotlinCompile).configureEach { jvmTarget = &amp;#39;17&amp;#39; }&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>問題：讀者能複製貼上，但無法回答「為什麼是 configureEach 不是其他方式」「遇到下一個類似問題怎麼想」。思考過程沒有被保存。&lt;/p>
&lt;h4 id="正例">正例&lt;/h4>
&lt;p>每個節點顯式展開成六個子段落：當下看到 → 判讀 → 可選策略 → 選擇與理由 → 結果 → 事後檢視。讀者看完後即使遇到不同錯誤訊息，也能套用同一個四階段推導。&lt;/p>
&lt;h4 id="反模式避開">反模式（避開）&lt;/h4>
&lt;ul>
&lt;li>從觀察直接跳執行，省略判讀與策略&lt;/li>
&lt;li>判讀留下未解問題就進策略&lt;/li>
&lt;li>文章中出現「選擇」卻只列一個選項&lt;/li>
&lt;/ul>
&lt;h4 id="例外">例外&lt;/h4>
&lt;p>純介紹性段落（例如 API 參數說明）可省略「策略」階段，但&lt;strong>不得省略判讀&lt;/strong>。&lt;/p>
&lt;hr>
&lt;h3 id="規則二商業邏輯先於-case">規則二：商業邏輯先於 CASE&lt;/h3>
&lt;h4 id="規則的商業邏輯-1">規則的商業邏輯&lt;/h4>
&lt;p>技術文章的內容包含兩種資訊層次：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>層次&lt;/th>
 &lt;th>內容&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>商業邏輯&lt;/td>
 &lt;td>系統層的概念（為什麼這件事存在、在體系中代表什麼）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>CASE&lt;/td>
 &lt;td>實例層的資料（具體的數值、路徑、屬性、設定）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>CASE 單獨存在沒有意義。「&lt;code>jvmTarget = 17&lt;/code>」這個值需要「為什麼 JVM target 要一致」這個概念當容器才能被理解。&lt;/p>
&lt;p>順序顛倒（先 CASE 後商業邏輯）等於讓讀者先記一組沒有脈絡的資料，再倒推抽象概念。這條認知路徑是反向的，多數讀者在倒推失敗後會放棄，即使專業讀者能勉強跟上也會覺得閱讀成本偏高。&lt;/p>
&lt;h4 id="做法-1">做法&lt;/h4>
&lt;p>每個主題段落包含兩層，&lt;strong>順序不得顛倒&lt;/strong>：&lt;/p>
&lt;p>&lt;strong>商業邏輯層&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>主題涉及的系統層概念&lt;/li>
&lt;li>該概念為什麼存在、解決什麼問題&lt;/li>
&lt;li>該類內容的共通本質&lt;/li>
&lt;li>&lt;strong>此層不討論具體數值、路徑、屬性名&lt;/strong>&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>CASE 層&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>訊息或規格中的關鍵字對應商業邏輯的哪個位置&lt;/li>
&lt;li>具體數值或內容&lt;/li>
&lt;li>從 CASE 推論的結論&lt;/li>
&lt;/ul>
&lt;h4 id="反例直接給-case預設讀者懂背景">反例（直接給 CASE，預設讀者懂背景）&lt;/h4>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="gu">### 判讀
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="gu">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">&lt;span class="k">-&lt;/span> 這個子專案的 Java task 產出 bytecode target = 17
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="k">-&lt;/span> 同一個子專案的 Kotlin task 產出 bytecode target = 1.8
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">- 兩者不一致觸發 Kotlin 2.2 的 strict validation&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>專業人士看了懂，但讀者若不知道「bytecode target」「strict validation」在系統中代表什麼，只能抓到字面字串，無法建立模型。&lt;/p></description><content:encoded><![CDATA[<p>本文件為「撰寫完整長篇技術文章」情境的指引。適用於 blog post、post-mortem、架構決策文件、技術評估報告、概念深度說明等<strong>需要保留思考過程</strong>的長篇內容。</p>
<blockquote>
<p><strong>自包含聲明</strong>：本文件不依賴其他 reference。讀完本文件即可獨立寫出合格技術文章。</p>
<p><strong>來源</strong>：methodology 骨架整合自 <code>tarrragon/blog</code> 的 <code>tech_writing_structure.md</code>（2026-04-17）；與 compositional-writing 核心原則的映射由本檔補充。</p></blockquote>
<hr>
<h2 id="與原子化寫作的分工">與原子化寫作的分工</h2>
<p>compositional-writing 的核心主張是「寫原子卡片」，但完整文章是另一種產物：卡片是最小重用單元，文章是把多張卡片用<strong>思考過程</strong>組織起來。兩者分工如下：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>原子化寫作（其他 references）</th>
          <th>完整文章（本 reference）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>產物形態</td>
          <td>可單獨檢索的卡片、欄位、段落</td>
          <td>有首尾、有推導的完整文章</td>
      </tr>
      <tr>
          <td>讀者行為</td>
          <td>grep / 點對點查詢</td>
          <td>從頭讀到尾，追思考過程</td>
      </tr>
      <tr>
          <td>組織原則</td>
          <td>可重用、可跨情境</td>
          <td>可複製思考路徑、不只複製結論</td>
      </tr>
      <tr>
          <td>長度決策</td>
          <td>越短越好（原子性優先）</td>
          <td>需要多長就多長（完整性優先）</td>
      </tr>
      <tr>
          <td>失敗模式</td>
          <td>卡片混雜多概念、無法獨立理解</td>
          <td>觀察直接跳執行、判讀被省略</td>
      </tr>
  </tbody>
</table>
<p><strong>核心目標的差異</strong>：</p>
<ul>
<li>原子化：讓讀者「用最小認知負擔找到答案」</li>
<li>完整文章：讓讀者「能複製思考過程，不只複製結論」。結論一行就能給；思考過程才是文章主體。</li>
</ul>
<hr>
<h2 id="適用範圍">適用範圍</h2>
<p>本 reference 適用於下列技術文章類型：</p>
<table>
  <thead>
      <tr>
          <th>類型</th>
          <th>典型產物</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>概念說明</td>
          <td>技術原理、系統架構、協定規格</td>
      </tr>
      <tr>
          <td>實作教學</td>
          <td>操作步驟、範例、API 用法</td>
      </tr>
      <tr>
          <td>架構決策</td>
          <td>方案比較、選型紀錄、設計文件</td>
      </tr>
      <tr>
          <td>除錯復盤</td>
          <td>事故紀錄、疑難排解、post-mortem</td>
      </tr>
      <tr>
          <td>技術評估</td>
          <td>工具調研、可行性評估</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="八條核心規則">八條核心規則</h2>
<p>規則一-七 處理「單篇文章內部怎麼寫」的不同層面（段落結構、句子層級、方案對照）。規則八是 meta-level、跨所有規則。規則九指向 <code>managing-article-collections.md</code> 處理跨多篇的議題。</p>
<h3 id="規則一階段分層觀察--判讀--策略--執行">規則一：階段分層（觀察 → 判讀 → 策略 → 執行）</h3>
<h4 id="規則的商業邏輯">規則的商業邏輯</h4>
<p>技術文章的內容從「事實或需求」推導到「動作或結論」，這個過程有四個功能不同的階段。每個階段處理的問題不同、失敗模式不同：</p>
<table>
  <thead>
      <tr>
          <th>階段</th>
          <th>處理的問題</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>觀察</td>
          <td>描述現況、需求、事實或訊息</td>
      </tr>
      <tr>
          <td>判讀</td>
          <td>說明本質、原理、問題所在</td>
      </tr>
      <tr>
          <td>策略</td>
          <td>列出可選方案並比較</td>
      </tr>
      <tr>
          <td>執行</td>
          <td>具體操作或實作</td>
      </tr>
  </tbody>
</table>
<p>四階段若混著寫，讀者無法區分「這一段失敗是哪個階段」，也無法判斷自己的類似情境卡在哪一步。文章只能被原封不動複製，不能被理解後套用。</p>
<h4 id="做法">做法</h4>
<p>每個主題段落應包含四階段。不同文章類型中四階段的對應：</p>
<table>
  <thead>
      <tr>
          <th>階段</th>
          <th>概念說明</th>
          <th>實作教學</th>
          <th>架構決策</th>
          <th>除錯復盤</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>觀察</td>
          <td>需求或背景</td>
          <td>使用情境</td>
          <td>現況限制</td>
          <td>錯誤訊息</td>
      </tr>
      <tr>
          <td>判讀</td>
          <td>概念本質</td>
          <td>工具的位置與功能</td>
          <td>需求本質</td>
          <td>問題根因</td>
      </tr>
      <tr>
          <td>策略</td>
          <td>不同用法</td>
          <td>不同操作路徑</td>
          <td>可選方案</td>
          <td>可行解法</td>
      </tr>
      <tr>
          <td>執行</td>
          <td>程式碼範例</td>
          <td>操作步驟</td>
          <td>選定實作</td>
          <td>修復動作</td>
      </tr>
  </tbody>
</table>
<h4 id="反例跳過判讀觀察直接進執行">反例（跳過判讀，觀察直接進執行）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl"><span class="gu">## 錯誤
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">flutter_broadcasts_4m：Kotlin 1.8 vs Java 17 mismatch
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="gu">## 解法
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">7</span><span class="cl">在 subprojects 加上：
</span></span><span class="line"><span class="ln">8</span><span class="cl">tasks.withType(KotlinCompile).configureEach { jvmTarget = &#39;17&#39; }</span></span></code></pre></div><p>問題：讀者能複製貼上，但無法回答「為什麼是 configureEach 不是其他方式」「遇到下一個類似問題怎麼想」。思考過程沒有被保存。</p>
<h4 id="正例">正例</h4>
<p>每個節點顯式展開成六個子段落：當下看到 → 判讀 → 可選策略 → 選擇與理由 → 結果 → 事後檢視。讀者看完後即使遇到不同錯誤訊息，也能套用同一個四階段推導。</p>
<h4 id="反模式避開">反模式（避開）</h4>
<ul>
<li>從觀察直接跳執行，省略判讀與策略</li>
<li>判讀留下未解問題就進策略</li>
<li>文章中出現「選擇」卻只列一個選項</li>
</ul>
<h4 id="例外">例外</h4>
<p>純介紹性段落（例如 API 參數說明）可省略「策略」階段，但<strong>不得省略判讀</strong>。</p>
<hr>
<h3 id="規則二商業邏輯先於-case">規則二：商業邏輯先於 CASE</h3>
<h4 id="規則的商業邏輯-1">規則的商業邏輯</h4>
<p>技術文章的內容包含兩種資訊層次：</p>
<table>
  <thead>
      <tr>
          <th>層次</th>
          <th>內容</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>商業邏輯</td>
          <td>系統層的概念（為什麼這件事存在、在體系中代表什麼）</td>
      </tr>
      <tr>
          <td>CASE</td>
          <td>實例層的資料（具體的數值、路徑、屬性、設定）</td>
      </tr>
  </tbody>
</table>
<p>CASE 單獨存在沒有意義。「<code>jvmTarget = 17</code>」這個值需要「為什麼 JVM target 要一致」這個概念當容器才能被理解。</p>
<p>順序顛倒（先 CASE 後商業邏輯）等於讓讀者先記一組沒有脈絡的資料，再倒推抽象概念。這條認知路徑是反向的，多數讀者在倒推失敗後會放棄，即使專業讀者能勉強跟上也會覺得閱讀成本偏高。</p>
<h4 id="做法-1">做法</h4>
<p>每個主題段落包含兩層，<strong>順序不得顛倒</strong>：</p>
<p><strong>商業邏輯層</strong>：</p>
<ul>
<li>主題涉及的系統層概念</li>
<li>該概念為什麼存在、解決什麼問題</li>
<li>該類內容的共通本質</li>
<li><strong>此層不討論具體數值、路徑、屬性名</strong></li>
</ul>
<p><strong>CASE 層</strong>：</p>
<ul>
<li>訊息或規格中的關鍵字對應商業邏輯的哪個位置</li>
<li>具體數值或內容</li>
<li>從 CASE 推論的結論</li>
</ul>
<h4 id="反例直接給-case預設讀者懂背景">反例（直接給 CASE，預設讀者懂背景）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl"><span class="gu">### 判讀
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="k">-</span> 這個子專案的 Java task 產出 bytecode target = 17
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="k">-</span> 同一個子專案的 Kotlin task 產出 bytecode target = 1.8
</span></span><span class="line"><span class="ln">5</span><span class="cl">- 兩者不一致觸發 Kotlin 2.2 的 strict validation</span></span></code></pre></div><p>專業人士看了懂，但讀者若不知道「bytecode target」「strict validation」在系統中代表什麼，只能抓到字面字串，無法建立模型。</p>
<h4 id="正例加上商業邏輯層當容器">正例（加上商業邏輯層當容器）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">### 判讀
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gs">**這類錯誤的本質（商業邏輯）**</span>：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">Android 每個 module 會分別編譯 Java 跟 Kotlin 原始碼，各自產出
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">JVM bytecode。每個 bytecode 有 target version，決定能在哪些 JVM
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">runtime 上跑。同 module 內若兩種語言產出不同 target，runtime
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">可能觸發 API 相容性問題。Kotlin 2.2 把這個從 warning 提升為 error。
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gs">**這次訊息具體說了什麼（CASE）**</span>：
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="k">-</span> compileDebugJavaWithJavac (17) → Java 產出 target 17
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="k">-</span> compileDebugKotlin (1.8) → Kotlin 產出 target 1.8
</span></span><span class="line"><span class="ln">14</span><span class="cl">- 符合上面「module 內不一致」的 pattern</span></span></code></pre></div><h4 id="完成標準">完成標準</h4>
<p>段落結束前，讀者應能回答：</p>
<ol>
<li>這個主題在系統中為什麼重要？</li>
<li>這個主題的具體案例對應商業邏輯的哪個位置？</li>
</ol>
<p>若只能回答第二題，<strong>商業邏輯層不足</strong>。</p>
<hr>
<h3 id="規則三評估用內在屬性用品質維度把時間成本留給排程">規則三：評估用內在屬性（用品質維度、把時間成本留給排程）</h3>
<h4 id="規則的商業邏輯-2">規則的商業邏輯</h4>
<p>技術文章經常包含選擇或比較：選 A 不選 B、用 X 不用 Y、選這個架構不選另一個。選擇的優劣取決於方案的<strong>內在屬性</strong>，不取決於執行者的<strong>時間消耗</strong>：</p>
<table>
  <thead>
      <tr>
          <th>類別</th>
          <th>包含</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>內在屬性</td>
          <td>覆蓋完整性、風險、可逆性、維護成本、可理解性、依賴前提</td>
      </tr>
      <tr>
          <td>時間消耗</td>
          <td>實作要多久、多少人工時</td>
      </tr>
  </tbody>
</table>
<p>時間消耗是執行者的資源考量，跟方案本身的正確性無關。用時間當評估維度會造成結構性偏差：<strong>投資型方案</strong>（擴大影響、建立基礎）看起來總是比<strong>消費型方案</strong>（解當前問題）差，但兩者能力的性質不同，不應以同一量度比較。</p>
<p>讀者讀到時間評估會誤以為「這個方案比較好」，但真正該學到的是「兩個方案各自適合什麼情境」。</p>
<h4 id="做法-2">做法</h4>
<p>每個方案比較<strong>必須包含下列維度中至少三項</strong>：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>評估內容</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>覆蓋完整性</td>
          <td>處理所有同類情境，還是只處理當前</td>
      </tr>
      <tr>
          <td>風險</td>
          <td>失敗機率與代價</td>
      </tr>
      <tr>
          <td>可逆性</td>
          <td>出錯能否回滾</td>
      </tr>
      <tr>
          <td>維護成本</td>
          <td>長期需要多少精力</td>
      </tr>
      <tr>
          <td>可理解性</td>
          <td>未來接手者能否理解</td>
      </tr>
      <tr>
          <td>依賴前提</td>
          <td>建立在什麼假設上，前提變了會如何</td>
      </tr>
  </tbody>
</table>
<h4 id="反例用時間成本換算划不划算">反例（用時間成本換算划不划算）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">這一步多 2 分鐘掃一遍 pub-cache，但可以省下後來約 30 分鐘的
</span></span><span class="line"><span class="ln">2</span><span class="cl">build-炸-修循環。明顯划算。</span></span></code></pre></div><p>讀者學到的是「划不划算」這個執行層結論，沒學到兩個方案的結構性差異。</p>
<h4 id="正例用內在屬性列出方案差異">正例（用內在屬性列出方案差異）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">若當下選擇「A2 + 同步盤點 pub-cache」：
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="k">-</span> 優點：一次盤點所有同類地雷，修復範圍完整；避免之後
</span></span><span class="line"><span class="ln">4</span><span class="cl">  遇到一個修一個的反應式除錯
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="k">-</span> 缺點：盤點結果可能含假陽性；擴大修復範圍可能引入新變數
</span></span><span class="line"><span class="ln">6</span><span class="cl">
</span></span><span class="line"><span class="ln">7</span><span class="cl">當下漏掉這個選項的本質問題是：
</span></span><span class="line"><span class="ln">8</span><span class="cl">單點錯誤修復後沒有主動擴大搜尋同類問題。
</span></span><span class="line"><span class="ln">9</span><span class="cl">這是決策是否涵蓋完整問題面的問題，不是執行層的快慢考量。</span></span></code></pre></div><h4 id="反模式避開-1">反模式（避開）</h4>
<p>不得以時間成本作為主要評估維度，包含：</p>
<ul>
<li>「這方案比較快」</li>
<li>「多花 X 分鐘省下 Y 分鐘」</li>
<li>「立即可完成」</li>
</ul>
<hr>
<h3 id="規則四事後檢視看判讀品質">規則四：事後檢視看判讀品質</h3>
<h4 id="規則的商業邏輯-3">規則的商業邏輯</h4>
<p>技術文章的品質檢視（review、事故檢討、復盤）常只看「結論對不對」，但多數失敗的根源在<strong>判讀階段</strong>：</p>
<table>
  <thead>
      <tr>
          <th>判讀階段的失敗類型</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>判讀未確認的推論被當結論</td>
      </tr>
      <tr>
          <td>判讀觀察範圍不足（只看單點）</td>
      </tr>
      <tr>
          <td>判讀用類比代替機制驗證</td>
      </tr>
  </tbody>
</table>
<p>這類問題會表現成「結論失敗」的樣子，但改善方向完全不同：</p>
<ul>
<li>結論失敗 → 下次多列幾個選項</li>
<li>判讀失敗 → 下次判讀要更嚴謹、更廣、更實證</li>
</ul>
<p>兩者混為一談會得到「要更仔細」這種無法行動的結論。</p>
<h4 id="做法-3">做法</h4>
<p>文章或決策完成後，<strong>必須回答下列四題</strong>：</p>
<ol>
<li>判讀階段的「需要確認」項目是否全部解答？</li>
<li>觀察範圍是否涵蓋同類情境，或僅處理當前一個？</li>
<li>推論中的類比假設是否驗證？</li>
<li>策略列舉是否完整？</li>
</ol>
<p>任一題答「否」，對應失敗類型必須明確標示：</p>
<table>
  <thead>
      <tr>
          <th>答「否」的題</th>
          <th>失敗類型</th>
          <th>改善方向</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>題 1</td>
          <td>未確認推論帶入結論</td>
          <td>判讀完成標準要收緊</td>
      </tr>
      <tr>
          <td>題 2</td>
          <td>觀察範圍不足</td>
          <td>擴大搜尋類似情境</td>
      </tr>
      <tr>
          <td>題 3</td>
          <td>類比代替驗證</td>
          <td>機制差異需實證</td>
      </tr>
      <tr>
          <td>題 4</td>
          <td>策略列舉不足</td>
          <td>至少列兩個選項</td>
      </tr>
  </tbody>
</table>
<h4 id="反例只檢視結論歸因模糊">反例（只檢視結論，歸因模糊）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">這次修復走了彎路，下次應該更仔細。</span></span></code></pre></div><p>無法行動。下次遇到類似情境仍會犯同樣錯誤。</p>
<h4 id="正例分類失敗類型對應不同改善方向">正例（分類失敗類型，對應不同改善方向）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">七個節點中四個失敗，分類：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">| 節點    | 失敗類型                     | 根本來源                                  |
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">| ------- | ---------------------------- | ----------------------------------------- |
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">| 節點 C  | 需要新資訊（toolchain 時機） | 節點 B 判讀留下「需要確認」但沒補         |
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">| 節點 D1 | 對稱假設                     | 節點 D 判讀用「結構對稱」取代「機制驗證」 |
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">| 節點 F  | 方法呼叫時機                 | 節點 E 判讀沒展開 API 的兩階段行為        |
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">三個失敗都源自判讀未完成就進策略。不是策略選錯，是判讀階段
</span></span><span class="line"><span class="ln">10</span><span class="cl">進入策略時，還帶著未解決的問題。</span></span></code></pre></div><p>這樣的檢視產出具體改善方向：「判讀完成標準要收緊」、「機制差異需實證」，而不是模糊的「要更仔細」。</p>
<h4 id="進階避免-hindsight-論述汙染判讀記錄">進階：避免 hindsight 論述汙染判讀記錄</h4>
<p>事後檢視類文章（post-mortem / 設計缺陷分析 / retrospective）有一個常見的失敗模式：論述依賴「結局已發生」的視角、產出的判斷工具只在 case 已出問題後才能用。</p>
<p>例：「[工具] 預設為 [限制版本]、被當 [通用版本] 用了一段時間沒事、後來才爆發問題 → 設計缺陷」——這個論述需要讀者知道結局、且歸因落在個人預見性。換成當下三軸論述「在零成本差異 + 強領域先驗下選了限制更高的選項 → 設計缺陷」、判斷不依賴結局、歸因轉到工具預設與制度。</p>
<p>寫設計檢討時、輪 5「反例 / 邊界」要加掃這個 frame：</p>
<ul>
<li>論述是否需要「後來」「最終」「結果」這類時序詞才站得住？</li>
<li>歸因是否落在「沒預見」「沒考慮」這類個人能力？</li>
<li>結論是否寫成 case-bound 規則（「下次要記得 X」）而不是 portable 工具（「下次跑三軸」）？</li>
</ul>
<p>詳細展開、修法、跨情境多面向應用見 <a href="/blog/report/design-flaw-by-current-axes-not-hindsight/" data-link-title="設計檢討用當下三軸論證、不依賴 hindsight" data-link-desc="本卡提倡用「當下成本對稱條件下選了限制更高的選項」當設計缺陷的判定方式、避免 hindsight 論述把需求演化誤判成設計缺陷。當下三軸論證（成本對稱性 / 可逆性 / 領域先驗）讓判斷不依賴結局發生、且歸因偏向工具預設與制度而非個人預見性。">design-flaw-by-current-axes-not-hindsight</a>。</p>
<hr>
<h3 id="規則五最重要的話優先說資訊優先序">規則五：最重要的話優先說（資訊優先序）</h3>
<h4 id="規則的商業邏輯-4">規則的商業邏輯</h4>
<p>技術說明包含三種資訊：核心原則（是什麼）、示例（長什麼樣）、提醒（不可如何）。AI 產出的技術文章傾向先給觀察或示例，再補「這不是任意的，而是…」的後置定義，導致讀者讀完整句才能理解首句的意義。</p>
<table>
  <thead>
      <tr>
          <th>類型</th>
          <th>說明</th>
          <th>應在何處</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>核心原則／定義</td>
          <td>這個概念是什麼、遵守什麼規則</td>
          <td>句首／段首</td>
      </tr>
      <tr>
          <td>示例／參考</td>
          <td>具體實例</td>
          <td>原則之後</td>
      </tr>
      <tr>
          <td>提醒／邊界</td>
          <td>不可如何、注意事項</td>
          <td>最後</td>
      </tr>
  </tbody>
</table>
<h4 id="做法-4">做法</h4>
<p>每個技術解釋段落完成後，自問：「如果讀者只讀第一句，他知道這個概念是什麼嗎？」若答案是「不知道，他只看到一個例子」，把核心原則移到第一句。</p>
<h4 id="反例示例先定義後">反例（示例先，定義後）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl"><span class="sb">`omitempty`</span> 表示欄位為零值時可以不輸出。它不是單純省字，而是宣告
</span></span><span class="line"><span class="ln">2</span><span class="cl">「這個欄位在某些訊息類型中不是必要資料」。</span></span></code></pre></div><p>讀者先記住「為零值時可以不輸出」，才得知這是一個「可選欄位語義標記」——認知路徑反向。</p>
<h4 id="正例定義先行為描述後">正例（定義先，行為描述後）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl"><span class="sb">`omitempty`</span> 宣告「這個欄位在某些訊息類型中不是必要資料」——它不是
</span></span><span class="line"><span class="ln">2</span><span class="cl">單純省字，而是可選欄位的語義標記；欄位為零值時 JSON 序列化會跳過輸出。</span></span></code></pre></div><h4 id="反模式避開-2">反模式（避開）</h4>
<ul>
<li>「X 是 Y。它不是單純的…，而是…」（觀察在前，定義在後）</li>
<li>「Go 欄位用 A，JSON 欄位用 B。這不是任意轉換…」（示例在前，原則在後）</li>
</ul>
<h4 id="結構推論尾端重點--總結段是資訊優先序失敗的訊號">結構推論：尾端「重點 / 總結」段是資訊優先序失敗的訊號</h4>
<p>資訊優先序講「核心原則放段首」、它的結構對偶是「文章不需要尾端重述」。若一篇文章要靠尾端「重點 / 小結 / 結論 / TL;DR」段重述前文才能讓讀者記住、訊號不是「需要總結」、是正文發散 —— 概念沒在它該出現的位置講清、被攤散、所以尾端要再收一次。把概念補回正文的對應位置（即本規則的 front-load）、尾端重述就失去存在理由。</p>
<p>判準是「<strong>刪掉尾端總結段、看正文站不站得住</strong>」：</p>
<ul>
<li>站得住 → 總結本就冗餘、刪是淨減負擔。</li>
<li>站不住 → 問題在正文組織、該重拆正文段落、不是靠總結救。</li>
</ul>
<p>兩種結果都指向不留尾端重述段。處理段內容時分兩類：純提醒（「養成 X 習慣」「記得回頭確認」）刪 —— 提醒不傳遞新概念、讀者需要時自己回前文；有概念價值的（某設計選擇的理由）併回它在正文該出現的段落、強化 front-load。</p>
<p><strong>位置決定性質、不是「有沒有摘要」</strong>：放文首的摘要（一段 abstract、文件的 description 欄位）服務「讀者決定要不要讀、先建全局框架」、在讀者<strong>還沒讀正文時</strong>提供導航；放文尾的重述在讀者<strong>讀完之後</strong>把已知內容再講一次、無導航功能。同一句「本文講 X 的三個取捨」放文首是合理摘要、放文尾是重述補丁。</p>
<p><strong>例外</strong>：跨章模組 / 長篇的<strong>導覽型結尾</strong>（串連各章、給下一步路由、列模組地圖）傳遞「結構關係」這個正文沒有的新資訊、不是重述、保留。真實內容裡最常見的是「一段重述 + 一句路由」的混合型 —— 修法是外科式：切重述段、留路由句、別整段刪。</p>
<hr>
<h3 id="規則六反例段落用正向陳述建立概念">規則六：反例段落用正向陳述建立概念</h3>
<h4 id="規則的商業邏輯-5">規則的商業邏輯</h4>
<p>「常見錯誤」「反模式」「禁止事項」段落的寫作目標是讓讀者<strong>建立正確概念</strong>，不是讓他記住禁止清單。</p>
<p>讀者在壓力情境下不會回想「規則 4：資料庫不是狀態邊界的替代品」——他只會應用「狀態邊界是程式碼架構的責任」這個概念。負面陳述只告訴讀者什麼是錯的，沒有給讀者正向的概念錨點；沒有錨點的規則記憶壽命短，在新情境中也無法套用。</p>
<h4 id="做法-5">做法</h4>
<p>每個錯誤或反模式段落包含三層，<strong>順序不得顛倒</strong>：</p>
<table>
  <thead>
      <tr>
          <th>層</th>
          <th>內容</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1</td>
          <td><strong>正向概念</strong></td>
          <td>這個主題正確的責任劃分是什麼（一句話）</td>
      </tr>
      <tr>
          <td>2</td>
          <td><strong>錯誤的對比</strong></td>
          <td>常見的誤解或替代品，作為概念的反面</td>
      </tr>
      <tr>
          <td>3</td>
          <td><strong>為什麼不足</strong></td>
          <td>誤解為何無法替代正確概念（不只說「不行」）</td>
      </tr>
  </tbody>
</table>
<h4 id="反例只有負面陳述沒有概念錨點">反例（只有負面陳述，沒有概念錨點）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl"><span class="gu">### 錯誤四：過早把 memory repository 換成 ORM
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">資料庫不是狀態邊界的替代品。即使使用資料庫，仍然需要清楚的方法、
</span></span><span class="line"><span class="ln">4</span><span class="cl">交易語意、copy/DTO 邊界與測試。</span></span></code></pre></div><p>讀者拿到的是「資料庫 ≠ 狀態邊界」這個排除式定義。沒有正向錨點，無法內化，壓力下會遺忘。</p>
<h4 id="正例正向概念先錯誤作對比說明原因">正例（正向概念先，錯誤作對比，說明原因）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl"><span class="gu">### 錯誤四：過早把 memory repository 換成 ORM
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">狀態邊界是程式碼架構的責任；資料庫只負責持久化。換成 ORM 只解決
</span></span><span class="line"><span class="ln">4</span><span class="cl">「資料去哪裡存」，沒解決「誰有權利寫、怎麼寫才一致」——後者是持久化層
</span></span><span class="line"><span class="ln">5</span><span class="cl">無法代勞的架構責任。
</span></span><span class="line"><span class="ln">6</span><span class="cl">
</span></span><span class="line"><span class="ln">7</span><span class="cl">引入資料庫之後，清楚的寫入方法、交易語意、copy/DTO 邊界與測試仍需
</span></span><span class="line"><span class="ln">8</span><span class="cl">顯式設計。</span></span></code></pre></div><p>讀者拿到「狀態邊界 = 程式碼架構責任」這個概念。即使忘了這條規則，概念仍能指引新情境的判斷。</p>
<h4 id="反模式避開-3">反模式（避開）</h4>
<ul>
<li>「X 不是 Y 的替代品」作為段落的唯一說明</li>
<li>「仍然需要 A、B、C」但沒解釋為什麼這些屬於程式碼而非資料庫的責任</li>
<li>錯誤列表只有禁令，沒有對應的正向概念</li>
</ul>
<h4 id="完成標準-1">完成標準</h4>
<p>讀者讀完後能回答：「這個主題正確的責任劃分是什麼？」若只能回答「不能用 X 替代」，<strong>正向概念層不足</strong>。</p>
<hr>
<h3 id="規則七用機會成本語氣多選項並列各標適用情境">規則七：用機會成本語氣（多選項並列、各標適用情境）</h3>
<h4 id="規則的商業邏輯-6">規則的商業邏輯</h4>
<p>技術文章涉及方案選擇、選擇本身有成本與收益。用「正確 / 錯誤」「應該 / 不應該」「正確概念 / 替代方案不足」這種絕對二元語氣描述方案、會誤導讀者：</p>
<table>
  <thead>
      <tr>
          <th>絕對主義（誤導）</th>
          <th>機會成本（準確）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>「正確概念是 A」</td>
          <td>「比較好的做法是 A、因為 [情境]」</td>
      </tr>
      <tr>
          <td>「替代方案 B 不足」</td>
          <td>「B 在 [其他情境] 合理、跟 A 的取捨是 [&hellip;]」</td>
      </tr>
      <tr>
          <td>「不應該用 D」</td>
          <td>「D 的成本特別高、只在 [極端情境] 才划算」</td>
      </tr>
      <tr>
          <td>「應該這樣做」</td>
          <td>「預設選 A、依賴前提是 [&hellip;]」</td>
      </tr>
  </tbody>
</table>
<p>絕對主義教讀者「規則」、機會成本教讀者「思考方式」。前者壓力下會忘、後者能套用到新情境。</p>
<p>程式設計極少有絕對正確 — 大部分選擇都是在多目標（覆蓋完整性、風險、可逆性、維護成本、可理解性、依賴前提）之間取捨。把這個事實顯現在語氣上。</p>
<h4 id="做法-6">做法</h4>
<p>設計取捨段落用 A/B/C/D 多選項並列、不用「正確 vs 不足」二元。樣板：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## 設計取捨：[維度名]
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">[情境簡述、為什麼這個維度有取捨]
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu">### A：[做法名]（這個專案的預設）
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">-</span> **機制**：[做法的核心動作]
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="k">-</span> **選 A 的理由**：[依賴前提 / 維護成本 / 風險容忍度]
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="k">-</span> **適合**：[情境特徵]
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="k">-</span> **代價**：[換到的東西要付的成本]
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu">### B：[替代做法]
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="k">-</span> **機制**：[...]
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">-</span> **跟 A 的取捨**：[B 換到什麼 / 失去什麼]
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="k">-</span> **B 比 A 好的情境**：[具體 case]
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="gu">### C：[另一條路]
</span></span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">[同上]
</span></span><span class="line"><span class="ln">21</span><span class="cl">
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="gu">### D：[極端做法 / 反模式]
</span></span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="k">-</span> **機制**：[...]
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="k">-</span> **成本特別高的原因**：[...]
</span></span><span class="line"><span class="ln">26</span><span class="cl">- <span class="gs">**D 才合理的情境**</span>：[極特殊情境、若有；若無則寫「實務上幾乎不存在」]</span></span></code></pre></div><p>關鍵設計原則：</p>
<ol>
<li>預設選項標「（這個專案的預設）」、不是「正確」</li>
<li>每選項都有「適合情境」+「代價」</li>
<li><strong>選項數由議題決定、不強湊到 4 個</strong>（見下節）</li>
<li>多取捨情境分多區塊、不混在一起</li>
</ol>
<h4 id="設計取捨的選項數由議題本身決定">設計取捨的選項數由議題本身決定</h4>
<p>機會成本框架的核心是「呈現議題的真實取捨空間」 — 議題有 N 個合理選項就寫 N 個。A/B/C/D 是這個 corpus 中常見的形態（多數技術議題確實有 3-4 個合理選項）、不該倒推成必須遵守的格式：</p>
<table>
  <thead>
      <tr>
          <th>議題實際選項數</th>
          <th>應該寫幾個</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>2 個合理選項 + 1 個反模式</td>
          <td>寫 A / B + D 反模式</td>
      </tr>
      <tr>
          <td>3 個合理選項</td>
          <td>寫 A / B / C</td>
      </tr>
      <tr>
          <td>4 個合理選項</td>
          <td>寫 A / B / C / D</td>
      </tr>
      <tr>
          <td>1 個合理選項（其他都不合理）</td>
          <td>不該用「設計取捨」段落、改用「為什麼選這個」單方論述</td>
      </tr>
  </tbody>
</table>
<p>強湊 4 個的徵兆：</p>
<ul>
<li>反覆出現「實務上幾乎不存在」 — 這是「湊不出 D 的合理情境」的承認、不是有用的描述</li>
<li>「D 才合理的情境」內容很模糊（「極特殊情境」「罕見」） — 表示 D 是強湊的</li>
<li>B / C 的「比 A 好的情境」高度重疊 — 表示 B 與 C 其實是同一選項的兩種表述</li>
</ul>
<h4 id="真反模式直接標明">真反模式直接標明</h4>
<p>當某選項真的是反模式（在所有可預期情境都壞）、不要套「才合理的情境：實務上幾乎不存在」的格式、直接標：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl"><span class="gu">### D：[反模式名]（反模式）
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="k">-</span> **為什麼是反模式**：違反 [X 原則] / 在 [Y 情境] 造成 [Z 後果]
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="k">-</span> **看起來吸引人的原因**：[為什麼有人會選這個 — 通常是「看似省時間」「看似簡單」]
</span></span><span class="line"><span class="ln">5</span><span class="cl">- <span class="gs">**實際發生的代價**</span>：[具體後果]</span></span></code></pre></div><p>這個格式比「假裝有合理情境」更誠實 — 讀者拿到「為什麼不該用」的明確理由、而不是模糊的「幾乎不存在」。</p>
<h4 id="反模式避開-4">反模式（避開）</h4>
<ul>
<li>「正確概念是 X」/「應該用 X」/「不應該用 Y」</li>
<li>把規則六（反例段落）的「正向概念 vs 替代方案不足」直接套到方案對照、變成偽機會成本（仍然絕對主義）</li>
<li>用「最佳實踐」「業界標準」當論證依據（常常是個人偏好的包裝）</li>
<li>強湊 4 個選項導致「實務上幾乎不存在」的低品質 D</li>
<li>抽象層原則 / Pattern 卡片硬寫「設計取捨 A/B/C/D」（這兩類有不同 structure、見規則九）</li>
</ul>
<h4 id="例外-1">例外</h4>
<p>絕對主義語氣只在以下情境合理：</p>
<ul>
<li>安全性（SQL injection、XSS — 是物理層原則、不是工程取捨）</li>
<li>數據完整性（race condition、ACID 違反 — 不該在 production 容忍）</li>
<li>法律 / 合規（GDPR 個資處理、accessibility 法規）</li>
</ul>
<p>這些是「物理 / 法律事實」、不是工程取捨。可以用絕對語氣。</p>
<h4 id="規則七與規則六的關係">規則七與規則六的關係</h4>
<p>規則六處理「反例段落」這個 special case — 當段落只在說「不要做 X」時、要有正向概念當錨點。規則七處理「方案對照段落」這個更廣的情境 — 多選項都有適用範圍、不能用「正確 vs 不足」二元描述。兩規則不衝突：</p>
<ul>
<li>反例 / 常見錯誤段落 → 規則六（正向概念 + 對比錯誤）</li>
<li>多方案對照段落 → 規則七（A/B/C/D 機會成本）</li>
</ul>
<hr>
<h3 id="規則八自我應用-dogfooding--文章在說明某條規則時自己也遵守該規則">規則八：自我應用 (dogfooding) — 文章在說明某條規則時、自己也遵守該規則</h3>
<h4 id="規則的商業邏輯-7">規則的商業邏輯</h4>
<p>教某條規則的文字、本身就是該規則的最自然示範。違反時讀者拿到的訊號是「教學者自己都不信這條規則、那為什麼我要信」 — 比規則內容寫得不好還傷害可信度。</p>
<p>這條規則是 meta-level、跨所有 object-level 規則：</p>
<ul>
<li>教「最重要的話優先說」（規則五）→ 教學文字本身的句首就要寫核心定義</li>
<li>教「反例段落用正向陳述」（規則六）→ 教學文字本身遇到反例也用正向陳述</li>
<li>教「機會成本語氣」（規則七）→ 教學文字本身討論做法選擇時也用 A/B 並列、不用「正確 vs 不足」</li>
<li>教「focus 是議題完整度」→ 教學文字本身的 focus 也要單一</li>
</ul>
<h4 id="做法-7">做法</h4>
<p>寫完每段教學文字後、自問：</p>
<ol>
<li>這段教學的規則 X 適用於這段文字本身嗎？</li>
<li>適用 → 這段文字符合規則 X 嗎？</li>
<li>不符合 → 改寫到符合</li>
</ol>
<p>特別常見的違反：</p>
<table>
  <thead>
      <tr>
          <th>教的規則</th>
          <th>容易違反的句型</th>
          <th>修正方向</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>規則五 最重要的話優先說</td>
          <td>「X 不是 Y、是 Z」（否定先、定義後）</td>
          <td>「X 是 Z；不是 Y」（定義先）</td>
      </tr>
      <tr>
          <td>規則六 反例段落用正向陳述</td>
          <td>教反例段落結構時、自己只列禁止事項</td>
          <td>教學前先給正向概念錨點</td>
      </tr>
      <tr>
          <td>規則七 機會成本語氣</td>
          <td>教 A/B/C/D 時用「不是格式要求、是工具」</td>
          <td>「A/B/C/D 是工具；選項數由議題決定」</td>
      </tr>
      <tr>
          <td>規則八 自我應用</td>
          <td>寫這條規則時自己沒檢查上面幾條</td>
          <td>寫完每段後跑一次 1-3 自問</td>
      </tr>
  </tbody>
</table>
<h4 id="反例">反例</h4>
<p>寫規則七（機會成本語氣）時、用句型「<strong>A/B/C/D 不是格式要求、是工具</strong>」當小節標題。這個句型本身就違反規則五（最重要的話優先說）— 否定先、定義後。</p>
<p>讀者看到的是：「教我用機會成本語氣的人、自己用絕對主義句型」 — 規則的可信度受傷。</p>
<h4 id="正例-1">正例</h4>
<p>同一個小節改寫成「<strong>A/B/C/D 是工具：選項數由議題決定</strong>」 — 定義先、用法明確。讀者看到的是：「教這條規則的文字本身遵守上一條規則」 — 規則網互相補強、可信度上升。</p>
<h4 id="反模式避開-5">反模式（避開）</h4>
<ul>
<li>教「最重要的話優先說」的段落本身、定義被推到後面</li>
<li>教「反例段落用正向陳述」的段落本身、純列禁止事項沒有正向錨點</li>
<li>教「機會成本語氣」的段落本身、用「正確 vs 不足」二元對立描述方案</li>
<li>教某條規則的範例本身違反該規則（看起來像 placeholder 或臨時寫的）</li>
</ul>
<h4 id="完成標準-2">完成標準</h4>
<p>讀者讀完每段教學後、不會察覺「這段文字違反了它教的規則」。每段是該規則的可工作示範。</p>
<hr>
<h3 id="規則九拆分判準與三類文章-structure--由-managing-article-collectionsmd-處理">規則九：拆分判準與三類文章 structure → 由 <code>managing-article-collections.md</code> 處理</h3>
<p>跨多篇 collection 的議題（拆分判準、三類文章 structure 模板、跨篇引用 idiom）由 <code>managing-article-collections.md</code> 統一處理。本 reference 聚焦「單篇文章內部怎麼寫」、不重複展開：</p>
<ul>
<li><strong>拆分判準（focus 是議題完整度）</strong>：見 <a href="/blog/skills/compositional-writing/managing-article-collections/#%e6%8b%86%e5%88%86%e5%88%a4%e6%ba%96focus-%e6%98%af%e8%ad%b0%e9%a1%8c%e5%ae%8c%e6%95%b4%e5%ba%a6" data-link-title="Managing Article Collections — 跨多篇相關文章的結構設計" data-link-desc="compositional-writing reference：跨多篇相關文章的結構設計（三層、素材庫比例、MOC、Pattern 卡片、跨篇引用 idiom）。">managing-article-collections.md → 拆分判準</a></li>
<li><strong>三類文章 structure 模板</strong>：見 <a href="/blog/skills/compositional-writing/managing-article-collections/#%e4%b8%89%e5%b1%a4-structure-%e8%a9%b3%e7%b4%b0%e5%b0%8d%e7%85%a7" data-link-title="Managing Article Collections — 跨多篇相關文章的結構設計" data-link-desc="compositional-writing reference：跨多篇相關文章的結構設計（三層、素材庫比例、MOC、Pattern 卡片、跨篇引用 idiom）。">managing-article-collections.md → 三層 structure 詳細對照</a></li>
</ul>
<p>當寫的是多篇 collection 中的一篇、先讀那邊判斷文章類型（情境檢討 / 抽象層原則 / Pattern 卡片）、再回本 reference 套用對應規則。</p>
<hr>
<h2 id="判讀徵兆對照">判讀徵兆對照</h2>
<p>撰寫過程常見的徵兆與對應的判讀要求。看到徵兆時，作者必須回答對應問題，才能讓判讀階段完成。</p>
<table>
  <thead>
      <tr>
          <th>徵兆</th>
          <th>必答的判讀問題</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>單一位置指向（檔案、行號、屬性名）</td>
          <td>為什麼是這個位置出問題？是目標狀態錯了，還是呼叫時機錯了？（現場不一定是根因）</td>
      </tr>
      <tr>
          <td>同類情境第二次出現</td>
          <td>還有哪些同類情境？是否有共通原因？（前次處理範圍不完整）</td>
      </tr>
      <tr>
          <td>修改看似合理但未生效</td>
          <td>修改的生效時機是否晚於覆蓋對象？覆蓋機制是否真的能蓋過目標？</td>
      </tr>
      <tr>
          <td>訊息含「final」「already」「cannot」</td>
          <td>目標何時進入不可修改狀態？修改能否提前到狀態轉換之前？</td>
      </tr>
      <tr>
          <td>訊息含「inconsistent」「mismatch」</td>
          <td>哪一邊是正確的目標值？不一致的方向決定治理施加在哪一邊</td>
      </tr>
  </tbody>
</table>
<p><strong>用法</strong>：把徵兆欄當 grep key，文章寫到該徵兆時展開對應的判讀問題，不得跳過。</p>
<hr>
<h2 id="術語">術語</h2>
<table>
  <thead>
      <tr>
          <th>術語</th>
          <th>定義</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>商業邏輯</td>
          <td>系統層次的概念說明，不涉及具體值</td>
      </tr>
      <tr>
          <td>CASE</td>
          <td>具體內容（數值、路徑、屬性名）</td>
      </tr>
      <tr>
          <td>判讀</td>
          <td>從事實推導本質的過程</td>
      </tr>
      <tr>
          <td>策略</td>
          <td>可選方案</td>
      </tr>
      <tr>
          <td>現場</td>
          <td>訊息直接指向的位置</td>
      </tr>
      <tr>
          <td>根因</td>
          <td>底層原因，不一定等於現場</td>
      </tr>
      <tr>
          <td>投資型策略</td>
          <td>有長期回報的方案（擴大覆蓋、建立認知）</td>
      </tr>
      <tr>
          <td>消費型策略</td>
          <td>只處理當前問題的方案</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="提交自檢清單">提交自檢清單</h2>
<p>提交文章前自檢：</p>
<ul>
<li><input disabled="" type="checkbox"> 四階段（觀察／判讀／策略／執行）完整，或已說明可省略的階段</li>
<li><input disabled="" type="checkbox"> 每個主題段落先商業邏輯後 CASE</li>
<li><input disabled="" type="checkbox"> 技術解釋的資訊優先序正確：核心原則在前，示例居中，提醒在後</li>
<li><input disabled="" type="checkbox"> 無「X 是 Y。它不是單純的…，而是…」這種定義後置句型</li>
<li><input disabled="" type="checkbox"> 尾端無重述型「重點 / 小結 / 結論 / TL;DR」段（刪掉它正文仍站得住=冗餘該刪、站不住=正文要重組；導覽型路由結尾除外）</li>
<li><input disabled="" type="checkbox"> 判讀中所有「需要確認」項目已解答或註明可暫不確認</li>
<li><input disabled="" type="checkbox"> 每個方案比較至少三個評估維度</li>
<li><input disabled="" type="checkbox"> 未以時間成本為主要評估維度</li>
<li><input disabled="" type="checkbox"> 事後檢視四題已回答</li>
<li><input disabled="" type="checkbox"> 失敗類型已標示（若有）</li>
<li><input disabled="" type="checkbox"> 判讀徵兆對照表中出現的徵兆都已展開對應問題</li>
<li><input disabled="" type="checkbox"> 反例／常見錯誤段落有正向概念層（能回答「正確的責任劃分是什麼」）</li>
<li><input disabled="" type="checkbox"> 無純負面陳述段落（「X 不是 Y」沒有對應正向錨點）</li>
<li><input disabled="" type="checkbox"> Title / description / heading / link label / MOC 索引條已跟正文跑同一輪正向陳述、對意圖、grep-ability review</li>
<li><input disabled="" type="checkbox"> 方案對照段落用機會成本語氣（A/B/C/D 多選項並列、不用「正確 vs 不足」二元）</li>
<li><input disabled="" type="checkbox"> 沒有「正確概念是 X」「應該用 X」「不應該用 Y」這類絕對主義語句（除非是安全 / 合規 / 數據完整性等物理 / 法律事實）</li>
<li><input disabled="" type="checkbox"> 文章聚焦的問題能用一句話說完</li>
<li><input disabled="" type="checkbox"> 沒有「+」「與」「以及」綁兩個獨立概念的標題（議題切了一半的訊號）</li>
<li><input disabled="" type="checkbox"> 設計取捨段落的選項數由議題決定（不強湊到 4 個、避免「實務上幾乎不存在」的假反模式）</li>
<li><input disabled="" type="checkbox"> 真反模式直接標「反模式 — 違反 X 原則」、不假裝有合理情境</li>
<li><input disabled="" type="checkbox"> 教某條規則的段落本身遵守該規則（規則八 dogfooding）</li>
<li><input disabled="" type="checkbox"> 文章類型分類正確（情境檢討 / 抽象層原則 / Pattern 卡片、見 <code>managing-article-collections.md</code>）、用對應的 structure</li>
<li><input disabled="" type="checkbox"> 開頭語氣：把「你」換成「我們」後語句仍自然嗎？（彆扭 = 恐嚇式、改分享式）</li>
<li><input disabled="" type="checkbox"> 每段補充：這段消失後讀者的閱讀體驗會變差嗎？（不會 = meta 資訊或主題偏移、刪除）</li>
<li><input disabled="" type="checkbox"> 描述行為的句子：在描述事實、還是在分配責任？（「承認」「暴露」→ 改「信號」「反映」「顯示」）</li>
<li><input disabled="" type="checkbox"> 把 pattern 歸因為 AI 特有的句子：這個 pattern 人類作者也會犯嗎？（會 → 改為通用觀察、AI 降為觸發脈絡；「AI 的發生率更高」需要對照證據、沒有就降為假說或刪除）</li>
</ul>
<hr>
<h2 id="多輪-re-read-passmulti-pass-refinement">多輪 Re-read Pass（multi-pass refinement）</h2>
<p>寫完上方自檢還不是 done — 自檢是「同 frame 的最後一掃」、不是 multi-pass。Multi-pass 要求每輪用<strong>不同 frame</strong> catch 不同層的錯（<a href="/blog/report/literal-interception-vs-behavioral-refinement/" data-link-title="字面攔截 vs 行為精煉：驗證手段跟錯誤層次的對齊" data-link-desc="驗證手段必須跟錯誤層次對齊：字面錯誤（typo / syntax / 缺欄位）用 hook / lint / CI 攔截；行為錯誤（思考偏差 / 判斷錯位 / collapse 反模式）用 multi-pass spiral 收斂。強行用 hook 蓋行為錯誤 = 給出 false confidence、反而比沒保護危險。本卡是 #72 結構性對策在「驗證粒度」維度的 ceiling — 不是所有錯誤都該被攔截。">literal-interception-vs-behavioral-refinement</a> / <a href="/blog/report/writing-multi-pass-review/" data-link-title="Writing 的 multi-pass review：N 輪 review、每輪換 frame" data-link-desc="寫文章 / 註解 / 文件 / prompt 的「寫」不是單次動作 — 是 N 輪 review。第 1 輪生成、第 2 輪對意圖（#67）、第 3 輪檢查機會成本語氣、第 4 輪 grep-ability、第 5 輪反例 / 邊界。每輪不同 frame、單輪寫不出全部維度。本卡是 #82 在「寫」這個 output 動作的具體實例。">writing-multi-pass-review</a>）。</p>
<p>跑下表前先做 surface enumeration：列出 body surface（段落、表格、範例）與 metadata / navigation surface（title、description、tags、heading、link label、MOC / index entry、slug / filename）。每輪 frame 都掃同一份 surface 清單，讓正文與讀者入口維持同一個概念錨點。細節見 <a href="/blog/report/metadata-surface-in-writing-review/" data-link-title="Metadata surface 要納入寫作 review 範圍" data-link-desc="寫作 review 的 surface 包含正文與 metadata surface：title、description、frontmatter、heading、link label、MOC 索引條。正文通過 positive wording 或 multi-pass review 只代表 body surface 收斂；讀者入口與索引入口也要跑同一套 frame，才能讓文章在第一眼、搜尋與跨篇路由上維持同一個概念錨點。">metadata-surface-in-writing-review</a>。</p>
<p>文章用的五輪 + 兩輪文章專屬：</p>
<table>
  <thead>
      <tr>
          <th>輪</th>
          <th>Frame</th>
          <th>文章專用 checklist</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1</td>
          <td>生成</td>
          <td>idea 從頭寫到尾、不停下改、預期會有粗糙</td>
      </tr>
      <tr>
          <td>2</td>
          <td>對意圖（<a href="/blog/report/ease-of-writing-vs-intent-alignment/" data-link-title="寫作便利度跟意圖對齊反相關" data-link-desc="寫程式時最容易寫出的版本、通常是離意圖最遠的版本。便利度建立在「現有上下文 / 已 materialize 資料 / 已存在 API」上、而意圖對齊需要找到正確的層、處理上游、跨抽象層 — 兩者方向相反。識別這個反相關 = 識別自己掉進「容易寫的陷阱」。">ease-of-writing-vs-intent-alignment</a>）</td>
          <td>開頭一句、title、description、MOC hook 都點同一個核心責任嗎？段落順序由「易讀」決定不是「好寫」決定？去掉視覺標記後還能讀嗎？</td>
      </tr>
      <tr>
          <td>3</td>
          <td>機會成本語氣</td>
          <td>全 surface grep「應該/必須/不行/正確/唯一」、絕對詞翻成 trade-off</td>
      </tr>
      <tr>
          <td>4</td>
          <td>Grep-ability / 命名 / 術語</td>
          <td>title / heading / link label / 段首關鍵字前置、表格欄位用 <code>:</code> <code>|</code> <code>→</code> 友善分隔、slug 對應 title；術語保留原文錨點與完整名詞頭</td>
      </tr>
      <tr>
          <td>5</td>
          <td>反例 / 邊界</td>
          <td>「何時不適用」段寫了嗎？「跟其他卡的關係」表完整嗎？反模式給「為什麼不好」+「修法」嗎？設計檢討類文章另掃 <a href="/blog/report/design-flaw-by-current-axes-not-hindsight/" data-link-title="設計檢討用當下三軸論證、不依賴 hindsight" data-link-desc="本卡提倡用「當下成本對稱條件下選了限制更高的選項」當設計缺陷的判定方式、避免 hindsight 論述把需求演化誤判成設計缺陷。當下三軸論證（成本對稱性 / 可逆性 / 領域先驗）讓判斷不依賴結局發生、且歸因偏向工具預設與制度而非個人預見性。">hindsight 論述</a></td>
      </tr>
      <tr>
          <td>6</td>
          <td>Cross-link 健康度</td>
          <td>引用的卡都還在嗎、被引用該卡是否反向引回（雙向）、新卡有沒有加進 collection index</td>
      </tr>
      <tr>
          <td>7</td>
          <td>索引條 vs 內容</td>
          <td>MOC / index entry 的索引描述、link label、文章 title 與正文第一段是否指向同一個核心責任</td>
      </tr>
      <tr>
          <td>8</td>
          <td>Keyword bank（換工具）</td>
          <td>跑 grep 比對固定 keyword list（口語修辭 / 廢話前綴 / 地區漂移 / 依賴 code / 裝飾符號 / 對讀者喊話 / 自評誇飾 / 必然性框架）、不靠 reviewer 記憶；<strong>命中是候選不是判決</strong>、命中後要語意判定（建立概念的違規 vs 合規的 hook / 反例 / 真必然）——詳見 <a href="/blog/report/colloquial-rhetoric-erodes-technical-precision/" data-link-title="口語化修辭在判斷工具型段落會稀釋技術精度" data-link-desc="技術文章的「判斷工具型段落」（讀者用來判斷自己 case 的論述）用「一輩子」「碰巧能用」「立刻撞牆」「沒事」這類口語修辭、會稀釋精度。修法是把口語修辭翻譯回技術屬性語言。但 hook / 引言 / narrative 段落用口語仍然合理——這是情境化的取捨、不是精度永遠優於可讀性。">colloquial-rhetoric</a> + <a href="/blog/report/regional-terminology-alignment/" data-link-title="地區用語對齊：寫作前先確定讀者的中文語料" data-link-desc="繁中 vs 簡中的用詞差異不只是字形（屏 / 螢幕、視頻 / 影片）、更是技術術語跟業務情境的精度差。寫作前要先確定讀者的中文語料、避免用對方語料中不存在或意思偏移的詞。常見漂移：硬體（屏 / 螢幕）、檔案系統（文件 / 檔案）、概念詞（默認 / 預設）、修辭詞（質量 / 品質）、混雜情境的英文中文比例。">regional-terminology</a> + <a href="/blog/report/prose-self-contained-without-code-reference/" data-link-title="商業邏輯論述要 self-contained：不依賴 code 才能被理解" data-link-desc="技術文章在「不放 code 的段落」仍然要 self-contained——商業邏輯論述不能預設讀者已經看過 code、用「那個 payload 第二段」「剛才的變數」這類 reference 等於把理解門檻轉嫁給讀者去翻 code。修法是把 reference 翻譯成「用名詞 / 角色 / 條件描述」的 self-contained 句子、即使讀者跳過所有 code block 也能理解論述。">prose-self-contained</a> + <code>decorative-symbols</code>（skill 內部支撐卡） + <a href="/blog/report/teaching-register-states-not-addresses-reader/" data-link-title="教材用中性陳述、不對讀者喊話" data-link-desc="教材的 register 是中性陳述概念、不是對讀者說話。三種對讀者喊話的形式 —— 安撫情緒（很多人卡在）、第二人稱代入（你天天寫）、祈使控制閱讀（先讀懂 / 別搞混）—— 表面不同、共同違反是把讀者當成要管理的對話對象、而非把概念講清楚。問題不在精度（「你天天寫的 int count」精度完全正確）、在 stance。修法是換成中性陳述（常見的 int count）或描述性名詞標題（簽章的型別與名字拆解）。邊界：hook / narrative 段落的輕度第二人稱可幫讀者進入、不一律禁。">teaching-prose-neutral-register</a></td>
      </tr>
      <tr>
          <td>9</td>
          <td>Reader simulation（換視角）</td>
          <td>四個 lens：(a) <strong>自包含性</strong>——拿掉所有 code block 重讀論述是否仍能 parse？跳段直接讀能拿到關鍵資訊？(b) <strong>register/stance</strong>——這段在「陳述概念」、還是在「管理 / 評價 / 絕對化 / 恐嚇讀者」（喊話 / 誇飾 / 必然 / 恐嚇）？register 類無穩定關鍵詞、keyword bank（輪 8）抓不到、<strong>reader-sim 是主、keyword bank 是輔</strong>；且這類最依賴 external cold-read、同 reviewer 模擬有限——production 教材建議刻意換視角或外部讀者。(c) <strong>meta 資訊 vs 內容</strong>——這段在描述內容、還是在描述寫作過程（「整理目的」「先交代脈絡，否則…」「本文邊界是…」）？meta 資訊服務作者的組織需求、不是讀者的閱讀需求；判準是「這段消失後、讀者的閱讀體驗會變差嗎？」——不會 → 刪除。AI 生成的文章高頻出現 meta 殘留、因為 AI 的「規劃→組織→寫作」推理過程會外露到文章中。同類問題（AI prompt context 中的系統知識洩漏到面向讀者的論述）也用此 lens catch：每段補充問「回答的是文章標題承諾的問題、還是衍生子問題？」。(d) <strong>AI 歸因過度</strong>——這段把 pattern 歸因為 AI 特有現象、人類作者也會犯嗎？AI 生成內容系統性地把通用寫作 / 工程 pattern 框為「AI 特有」（「AI 的發生率更高」「因為推理和生成在同一序列」），縮窄適用範圍且背上無法證實的舉證負擔。判準：把句中「AI」換成「作者」、論點是否仍然成立？成立 → 改為通用觀察、AI 降為觸發脈絡（「兩個 case 來自 AI 生成的文件、但此 pattern 不限於 AI」）；斷言 AI 發生率更高需要對照證據、沒有就降為假說或刪除。詳見 <a href="/blog/report/teaching-register-states-not-addresses-reader/" data-link-title="教材用中性陳述、不對讀者喊話" data-link-desc="教材的 register 是中性陳述概念、不是對讀者說話。三種對讀者喊話的形式 —— 安撫情緒（很多人卡在）、第二人稱代入（你天天寫）、祈使控制閱讀（先讀懂 / 別搞混）—— 表面不同、共同違反是把讀者當成要管理的對話對象、而非把概念講清楚。問題不在精度（「你天天寫的 int count」精度完全正確）、在 stance。修法是換成中性陳述（常見的 int count）或描述性名詞標題（簽章的型別與名字拆解）。邊界：hook / narrative 段落的輕度第二人稱可幫讀者進入、不一律禁。">teaching-prose-neutral-register</a></td>
      </tr>
      <tr>
          <td>10</td>
          <td>Self-criticism（換層次）</td>
          <td>我跑的 N 輪 catch 哪些問題類型？同個規則下還有哪些違反句型沒掃到？framework 是否有 known blind spot？——詳見 <a href="/blog/report/multi-pass-review-frame-granularity-blindspot/" data-link-title="Multi-pass review 的 frame 顆粒度盲點：抽象規則 → 具體訊號的轉譯不完整" data-link-desc="Multi-pass review 跑了 4 輪、字句層問題（口語修辭 / 地區用語 / 依賴 code / 廢話前綴）仍漏 catch——揭露 frame 顆粒度盲點：抽象規則（如「機會成本語氣」「正向陳述」「最重要的話優先說」）沒被轉譯成具體訊號（如 grep keyword bank：「一輩子 / 碰巧 / 撞牆 / 下次 X 時 / 不是 A 而是 B」）。修法是把每條規則展開成可 grep 的 keyword bank、加 reader simulation 輪、加 self-criticism 輪。">multi-pass-review-frame-granularity</a></td>
      </tr>
  </tbody>
</table>
<p>跳輪規則同 <a href="/blog/report/writing-multi-pass-review/" data-link-title="Writing 的 multi-pass review：N 輪 review、每輪換 frame" data-link-desc="寫文章 / 註解 / 文件 / prompt 的「寫」不是單次動作 — 是 N 輪 review。第 1 輪生成、第 2 輪對意圖（#67）、第 3 輪檢查機會成本語氣、第 4 輪 grep-ability、第 5 輪反例 / 邊界。每輪不同 frame、單輪寫不出全部維度。本卡是 #82 在「寫」這個 output 動作的具體實例。">writing-multi-pass-review</a> — 短文 / 即時 note 跳 4-7、production 卡片 / 教學文章全跑；輪 8-10 是 production 教學文章專用、catch 字句層問題、跑 N 輪後仍漏 catch 同類問題時觸發。</p>
<h3 id="術語檢查中文入口--原文錨點--完整名詞頭">術語檢查：中文入口 + 原文錨點 + 完整名詞頭</h3>
<p>術語檢查屬於輪 4 的命名子場景，production 卡片 / 教學文章要把它當成獨立子 pass。技術文章中的術語同時承擔可讀性、可搜尋性與概念邊界；中文讓 reader 進入段落，原文讓概念可回溯，完整名詞頭讓中文離開原句仍能獨立成立。</p>
<p>翻譯檢查先看句內邏輯。把中文譯名放回原句後，要檢查它跟主詞、動詞、修飾語、因果關係是否成立；如果譯名讓句子多出原文沒有的前提，或讓讀者追問方向改變，這個翻譯就有問題。</p>
<table>
  <thead>
      <tr>
          <th>檢查項</th>
          <th>問題</th>
          <th>修法</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>原文錨點</td>
          <td>學術 / 標準 / 方法論術語第一次出現是否保留原文？</td>
          <td>寫成「中文術語（original term）」</td>
      </tr>
      <tr>
          <td>譯名對位</td>
          <td>中文是否帶入原詞沒有的文化 / 政治 / 日常語意？</td>
          <td>回原文語境重選中文，必要時在定義段列常見譯名</td>
      </tr>
      <tr>
          <td>完整名詞頭</td>
          <td>中文壓縮後是否仍回答「這是什麼」？</td>
          <td>補「盲點 / 偏誤 / 風險 / 模式 / 檢查 / 策略」等 head noun</td>
      </tr>
      <tr>
          <td>全文一致</td>
          <td>同一術語是否出現多個中文譯名或多個詞尾？</td>
          <td>選 canonical 譯名與 head noun 後全篇替換</td>
      </tr>
      <tr>
          <td>Metadata / navigation 同步</td>
          <td>title、description、heading、link label 是否同樣對位？</td>
          <td>跟正文第一個定義使用同一組術語</td>
      </tr>
      <tr>
          <td>句內邏輯</td>
          <td>譯名是否讓句子多出原文沒有的前提？</td>
          <td>標出主詞 / 動詞 / 修飾語 / 因果，逐項檢查是否成立</td>
      </tr>
      <tr>
          <td>讀者追問</td>
          <td>reader 看到中文會追問正確問題嗎？</td>
          <td>問「他會問 A 還是 B？」；問錯方向就重譯</td>
      </tr>
  </tbody>
</table>
<p>例：<code>paternalism</code> 在決策 / 倫理脈絡裡較接近「家長主義」；翻成帶 gender 聯想的詞會讓概念漂移。例：中文壓縮詞若只剩「盲」一個字，reader 無法判斷它是盲點、盲區或盲測；補成「多步驟成功率盲點」才有完整分類。</p>
<p>完整翻譯 / 轉譯流程見 <a href="/blog/skills/compositional-writing/translation-review/" data-link-title="Translation Review — 文章翻譯與轉譯檢查" data-link-desc="compositional-writing reference：把英文材料轉成中文、把既有文章改寫成另一種語言、檢查術語誤譯與句內邏輯對位。">translation-review</a>。支撐原則見 <a href="/blog/report/terminology-keeps-original-anchor/" data-link-title="術語翻譯要保留原文錨點" data-link-desc="翻譯術語時、中文名稱負責降低閱讀門檻，原文名稱負責鎖定概念邊界。只留中文會把 reader 帶進中文詞的日常歧義，只留英文會提高閱讀成本；中文後接英文括號是技術文章的穩定折衷。">terminology-keeps-original-anchor</a> 與 <a href="/blog/report/compressed-chinese-terms-need-head-noun/" data-link-title="中文壓縮術語要保留完整名詞頭" data-link-desc="中文技術寫作可以壓縮長詞，但不能省到只剩形容詞或單字修飾。像「多步驟 perplexity 盲」這類詞少了完整名詞頭，讀者無法判斷是在說盲點、盲區、盲測或失明比喻。壓縮後仍要能獨立回答「這是什麼」。">compressed-chinese-terms-need-head-noun</a>。</p>
<h3 id="層次意識frame-是-horizontallayer-是-vertical">層次意識：frame 是 horizontal、layer 是 vertical</h3>
<p>Multi-pass review 的「N 輪不同 frame」是 horizontal 軸（同一份文字、5 個視角輪流看）。常見的誤區是 5 輪都落在同一個 vertical layer（例如全部在看視覺層）、漏掉語意 / 邏輯層 — frame 換了但 layer 沒換、根本問題不會被觸碰。</p>
<p>技術文章中常見的三個檢查層次（每輪 frame 內、都要掃一次三層）：</p>
<table>
  <thead>
      <tr>
          <th>層次</th>
          <th>檢查內容</th>
          <th>修法</th>
          <th>根本問題的訊號</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>邏輯層</strong></td>
          <td>論證是否完整、推導是否跳過、方案是否充分列舉</td>
          <td>重新分概念、補論證</td>
          <td>「有未回答的假設」「觀察直接跳執行」「只列一個選項」</td>
      </tr>
      <tr>
          <td><strong>語意層</strong></td>
          <td>概念是否清晰、有無依賴視覺標記、概念邊界是否明確</td>
          <td>改表達結構、加分段</td>
          <td>「用 emoji 作為唯一區分」「同一行表達兩個不同概念」「去掉顏色就無法理解」</td>
      </tr>
      <tr>
          <td><strong>視覺層</strong></td>
          <td>排版是否對齊、圖表是否正確渲染、容器寬度是否適配</td>
          <td>CSS / 排版 / 渲染</td>
          <td>「emoji 斷行」「圖表無法顯示」「文字超出邊界」</td>
      </tr>
  </tbody>
</table>
<p><strong>關鍵原則</strong>：</p>
<ol>
<li>邏輯和語意錯誤會表現成視覺問題（症狀在淺層、根因在深層）</li>
<li>視覺工具的 ceiling 在語意 / 邏輯層 — 用 CSS / emoji 蓋下游症狀 = false confidence、根因換 context 復發</li>
<li>若多輪都在檢查視覺問題、表示 frame 換了但 layer 沒換、根本問題還沒被觸碰</li>
</ol>
<p><strong>反例（修錯層次）</strong>：</p>
<p>emoji 在容器窄時斷行：</p>
<ul>
<li><strong>第一直覺修視覺</strong>：加 <code>white-space: nowrap</code> → 文字溢出 → 加 <code>overflow: hidden</code> → 症狀堆疊、根因（兩個概念擠在一行）更深埋</li>
<li><strong>追問層次後修結構</strong>：HIGHLIGHT 跟 REVERSE 是兩個獨立概念、不該擠在同一行 — 拆成獨立列表項、所有下游症狀同時消失</li>
</ul>
<p>判讀層次比修法重要 — 純視覺問題（容器寬度、字體大小、跨瀏覽器）用 CSS 是對的；語意 / 邏輯下游症狀用 CSS 是 false confidence。</p>
<hr>
<h2 id="與核心原則的映射">與核心原則的映射</h2>
<p>本規則四條與 compositional-writing 核心原則對應關係：</p>
<table>
  <thead>
      <tr>
          <th>本 reference 規則</th>
          <th>對應核心原則</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>規則一：階段分層</td>
          <td>原子化 + 意圖顯性</td>
          <td>每個階段是自包含的認知單元；階段名即宣告該段功能</td>
      </tr>
      <tr>
          <td>規則二：商業邏輯先於 CASE</td>
          <td>意圖顯性 + 原子化</td>
          <td>商業邏輯段是可跨 CASE 重用的容器；CASE 是該容器的實例填充</td>
      </tr>
      <tr>
          <td>規則三：評估用內在屬性</td>
          <td>欄位設計</td>
          <td>內在屬性是穩定的比較軸；時間消耗是執行者的狀態，不應混入評估欄位</td>
      </tr>
      <tr>
          <td>規則四：事後檢視看判讀品質</td>
          <td>可查詢性 + 欄位設計</td>
          <td>失敗類型是可 grep 的分類鍵；改善方向與失敗類型分欄，避免「要更仔細」這種無欄位化結論。設計檢討類文章另外要避免 hindsight 論述汙染判讀（見 <a href="/blog/report/design-flaw-by-current-axes-not-hindsight/" data-link-title="設計檢討用當下三軸論證、不依賴 hindsight" data-link-desc="本卡提倡用「當下成本對稱條件下選了限制更高的選項」當設計缺陷的判定方式、避免 hindsight 論述把需求演化誤判成設計缺陷。當下三軸論證（成本對稱性 / 可逆性 / 領域先驗）讓判斷不依賴結局發生、且歸因偏向工具預設與制度而非個人預見性。">principles/design-flaw-by-current-axes-not-hindsight</a>）</td>
      </tr>
      <tr>
          <td>規則五：最重要的話優先說</td>
          <td>意圖顯性</td>
          <td>核心原則必須在句首，示例和提醒跟在後面；禁止「觀察→示例→事後定義」的反向認知路徑</td>
      </tr>
      <tr>
          <td>規則六：反例段落用正向陳述</td>
          <td>意圖顯性 + 原子化</td>
          <td>錯誤段落先說正確概念，再用錯誤作對比；禁止只有排除式定義（「X 不是 Y」）而無正向錨點</td>
      </tr>
      <tr>
          <td>規則七：機會成本語氣</td>
          <td>意圖顯性 + 欄位設計</td>
          <td>方案對照用 A/B/C/D 多選項並列、不用「正確 vs 不足」二元；選項數由議題決定不強湊；真反模式直接標明</td>
      </tr>
      <tr>
          <td>規則八：自我應用 (dogfooding)</td>
          <td>意圖顯性（meta）</td>
          <td>教某條規則的段落本身遵守該規則；違反時規則的可信度受傷</td>
      </tr>
      <tr>
          <td>規則九：跨多篇議題 → managing-article-collections.md</td>
          <td>（指引轉介）</td>
          <td>拆分判準（focus）/ 三類文章 structure / 跨篇引用 idiom 由跨篇 reference 處理</td>
      </tr>
  </tbody>
</table>
<p><strong>反向理解</strong>：原子化要求「每張卡一個概念」，完整文章要求「每個階段一個功能」；兩者是同一個認知負擔原則在不同粒度上的體現。</p>
<hr>
<p><strong>Last Updated</strong>: 2026-06-25
<strong>Version</strong>: 0.9.0 — 從工具 opinion 文章 review 回流：(1) 輪 9 reader-sim 加第三 lens「meta 資訊 vs 內容」— 涵蓋 meta-commentary 殘留（AI 推理過程外露）+ 主題偏移（prompt context 系統知識洩漏）兩個 design gap；(2) 提交自檢清單加 3 個生成端自問句（恐嚇式 hook「你→我們」測試 / meta 刪除測試 / 歸因語氣判斷）。生成端自問句成本低於審查端 grep 擴充、且 4 個 design gap 中 meta-commentary 和 topic-drift 沒有穩定通用關鍵詞不適合 grep。</p>
<p><strong>Last Updated</strong>: 2026-05-06
<strong>Version</strong>: 0.8.1 — WRAP 審視後降 over-claim：5 張對應 report 卡（#110-114）都加「論述基礎與限制」段揭露樣本量限制；補上 <a href="/blog/report/regional-terminology-alignment/" data-link-title="地區用語對齊：寫作前先確定讀者的中文語料" data-link-desc="繁中 vs 簡中的用詞差異不只是字形（屏 / 螢幕、視頻 / 影片）、更是技術術語跟業務情境的精度差。寫作前要先確定讀者的中文語料、避免用對方語料中不存在或意思偏移的詞。常見漂移：硬體（屏 / 螢幕）、檔案系統（文件 / 檔案）、概念詞（默認 / 預設）、修辭詞（質量 / 品質）、混雜情境的英文中文比例。"><code>regional-terminology-alignment</code></a> portable principle（地區用語對齊、輪 8 keyword bank 引用）；同步 <a href="/blog/report/design-flaw-by-current-axes-not-hindsight/" data-link-title="設計檢討用當下三軸論證、不依賴 hindsight" data-link-desc="本卡提倡用「當下成本對稱條件下選了限制更高的選項」當設計缺陷的判定方式、避免 hindsight 論述把需求演化誤判成設計缺陷。當下三軸論證（成本對稱性 / 可逆性 / 領域先驗）讓判斷不依賴結局發生、且歸因偏向工具預設與制度而非個人預見性。"><code>design-flaw-by-current-axes-not-hindsight</code></a> 的 WRAP 修補（個人 vs 制度歸因軟化、多面向標假設性對比）
<strong>Version</strong>: 0.8.0 — Multi-pass review 加輪 8-10（keyword bank / reader simulation / self-criticism）、處理「跑了 N 輪、字句層問題仍漏」的盲點；新增三張內部 principle：<a href="/blog/report/colloquial-rhetoric-erodes-technical-precision/" data-link-title="口語化修辭在判斷工具型段落會稀釋技術精度" data-link-desc="技術文章的「判斷工具型段落」（讀者用來判斷自己 case 的論述）用「一輩子」「碰巧能用」「立刻撞牆」「沒事」這類口語修辭、會稀釋精度。修法是把口語修辭翻譯回技術屬性語言。但 hook / 引言 / narrative 段落用口語仍然合理——這是情境化的取捨、不是精度永遠優於可讀性。"><code>colloquial-rhetoric</code></a>（口語修辭 keyword bank）、<a href="/blog/report/prose-self-contained-without-code-reference/" data-link-title="商業邏輯論述要 self-contained：不依賴 code 才能被理解" data-link-desc="技術文章在「不放 code 的段落」仍然要 self-contained——商業邏輯論述不能預設讀者已經看過 code、用「那個 payload 第二段」「剛才的變數」這類 reference 等於把理解門檻轉嫁給讀者去翻 code。修法是把 reference 翻譯成「用名詞 / 角色 / 條件描述」的 self-contained 句子、即使讀者跳過所有 code block 也能理解論述。"><code>prose-self-contained</code></a>（reader simulation 自測）、<a href="/blog/report/multi-pass-review-frame-granularity-blindspot/" data-link-title="Multi-pass review 的 frame 顆粒度盲點：抽象規則 → 具體訊號的轉譯不完整" data-link-desc="Multi-pass review 跑了 4 輪、字句層問題（口語修辭 / 地區用語 / 依賴 code / 廢話前綴）仍漏 catch——揭露 frame 顆粒度盲點：抽象規則（如「機會成本語氣」「正向陳述」「最重要的話優先說」）沒被轉譯成具體訊號（如 grep keyword bank：「一輩子 / 碰巧 / 撞牆 / 下次 X 時 / 不是 A 而是 B」）。修法是把每條規則展開成可 grep 的 keyword bank、加 reader simulation 輪、加 self-criticism 輪。"><code>multi-pass-review-frame-granularity</code></a>（meta 層、self-criticism 三機制論述）
<strong>Version</strong>: 0.7.6 — 規則四補進階段「避免 hindsight 論述汙染判讀記錄」、輪 5 補設計檢討類另掃 hindsight 論述；新增內部 principle <a href="/blog/report/design-flaw-by-current-axes-not-hindsight/" data-link-title="設計檢討用當下三軸論證、不依賴 hindsight" data-link-desc="本卡提倡用「當下成本對稱條件下選了限制更高的選項」當設計缺陷的判定方式、避免 hindsight 論述把需求演化誤判成設計缺陷。當下三軸論證（成本對稱性 / 可逆性 / 領域先驗）讓判斷不依賴結局發生、且歸因偏向工具預設與制度而非個人預見性。"><code>design-flaw-by-current-axes-not-hindsight</code></a>——把「設計缺陷的精準定義」從「沒預測到後來需求」改成「在當下成本對稱條件下選了限制更高的選項」、用三軸論證代替 hindsight、確保產出 portable 判斷工具
<strong>Version</strong>: 0.7.5 — 將翻譯 / 轉譯 review 升級為獨立 reference：<code>translation-review.md</code>，聚焦句內邏輯對位、前提檢查、因果檢查與讀者追問方向；writing-articles 保留短檢查表並轉介。
<strong>Version</strong>: 0.7.4 — 強化術語翻譯的句內邏輯檢查：譯名放回原句後要檢查主詞、動詞、修飾語、因果與讀者追問方向；避免中文順口但讓句子多出原文沒有的前提。
<strong>Version</strong>: 0.7.3 — 輪 4 補術語檢查：翻譯術語第一次出現保留原文錨點，中文壓縮術語保留完整名詞頭；新增 <code>terminology-keeps-original-anchor</code> 與 <code>compressed-chinese-terms-need-head-noun</code> 兩張內部 principle。
<strong>Version</strong>: 0.7.2 — 補 metadata / navigation surface review：title、description、heading、link label、MOC / index entry、slug / filename 先列入 surface enumeration，再跟正文跑同一輪對意圖、正向陳述與 grep-ability pass；新增內部 principle 連結，維持 skill 可攜性
<strong>Version</strong>: 0.7.1 — 修正 0.7.0 的兩個違規：(a) 移除對外部 content path 的跨引用（違反 reference-authoring-standards 自包含性、修正後段內就地展開層次論述）；(b)「不能用視覺修補替代邏輯或語意修正」改機會成本語氣（違反規則七絕對主義）；標題「層次意識」副題改成「frame 是 horizontal、layer 是 vertical」更精準描述兩軸正交；表格「檢查時機」欄改「修法」更實用、修正「對齐」錯字；加反例段落（emoji 症狀堆疊 vs 改結構）。本 reference 自包含、不引用外部內容系統
<strong>Version</strong>: 0.7.0 — 補強 multi-pass review：第 2 輪檢查清單新增「層次意識」（去掉視覺標記後還能讀嗎、有無依賴 emoji/顏色/圖表）；新增「層次意識」段落說明邏輯層 / 語意層 / 視覺層的區別與優先順序
<strong>Version</strong>: 0.6.0 — 從 references 過載的反思：把「跨多篇議題」（拆分判準、三類 structure 模板、跨篇引用 idiom）整合搬到 <code>managing-article-collections.md</code>；本 reference 聚焦「單篇文章內部怎麼寫」、瘦身 130 行；舊規則八 / 九 整合到那邊。新增規則八「自我應用 (dogfooding)」 — 教某條規則的段落本身遵守該規則
<strong>Version</strong>: 0.5.0 — 從批量改寫 35 篇的經驗回流：規則七補強（選項數由議題決定不強湊、真反模式直接標明、抽象層 / Pattern 卡片不寫「設計取捨 A/B/C/D」）；新增規則九「三類文章用三種 structure」（情境 / 抽象 / Pattern 各自的段落 template）；自檢清單新增五項
<strong>Version</strong>: 0.4.0 — 新增規則七「機會成本語氣」（程式設計極少絕對正確、討論的是多目標取捨；方案對照用 A/B/C/D 多選項並列）；新增規則八「focus 是議題完整度」（拆分判準是 focus、不是邊界清晰；review 必須讀內文）；自檢清單新增四項
<strong>Version</strong>: 0.3.0 — 新增規則六「反例段落用正向陳述」（排除式定義無法建立概念錨點；反例段落仍需正向概念層）；自檢清單新增兩項
<strong>Version</strong>: 0.2.0 — 新增規則五「最重要的話優先說」（資訊優先序；對應核心原則 Explicit Intent；針對 AI 生成文章主次不分反模式）
<strong>Version</strong>: 0.1.0 — 初版（整合外部 methodology + 補充與核心原則的映射）</p>
]]></content:encoded></item><item><title>Writing Code Comments — 程式碼註解撰寫指引</title><link>https://tarrragon.github.io/blog/skills/compositional-writing/writing-code-comments/</link><pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/skills/compositional-writing/writing-code-comments/</guid><description>&lt;p>本 reference 提供撰寫程式碼註解的完整指引，整合核心寫作原則在註解情境的具體應用。讀者只需讀本文件，即可獨立寫出合格的註解，不需再讀其他 reference。&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>核心命題&lt;/strong>：註解是業務需求和設計意圖的守護者。註解的認知依賴必須跟著程式依賴一起降低——介面的註解只寫契約，不洩漏實作；實作的註解說明業務規則，不描述語法選擇。&lt;/p>&lt;/blockquote>
&lt;hr>
&lt;h2 id="適用時機">適用時機&lt;/h2>
&lt;p>當你準備寫 / 改 / 審查以下任一註解時，應用本指引：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>情境&lt;/th>
 &lt;th>說明&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Doc comment（&lt;code>///&lt;/code>、&lt;code>/** */&lt;/code>、&lt;code>&amp;quot;&amp;quot;&amp;quot;...&amp;quot;&amp;quot;&amp;quot;&lt;/code>）&lt;/td>
 &lt;td>位於函式、類別、介面、模組宣告前方，供外部閱讀者和工具消費&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Inline comment（&lt;code>//&lt;/code>、&lt;code>#&lt;/code>）&lt;/td>
 &lt;td>位於實作內部，說明「為什麼這樣做」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>模組 README 或檔案頂部 header&lt;/td>
 &lt;td>描述此模組解決的問題&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>介面 / 抽象類別的 docstring&lt;/td>
 &lt;td>定義契約（做什麼、輸入輸出語意、使用情境）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>不適用&lt;/strong>：commit message、PR description、ticket context（另見其他情境 reference）。&lt;/p>
&lt;hr>
&lt;h2 id="原則一原子化--註解">原則一：原子化 × 註解&lt;/h2>
&lt;p>&lt;strong>一則註解只解釋一個概念。&lt;/strong> 一個函式若需要註解說明多個不相關的關注點，應先拆分函式，再為每個函式寫獨立註解。&lt;/p>
&lt;h3 id="正例">正例&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-dart" data-lang="dart">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c1">/// 【需求】UC-003 書籍狀態轉換
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="c1">/// 書籍從「閱讀中」改為「已完成」時，自動將進度設為 100%
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">&lt;span class="c1">/// 約束：不可覆蓋使用者手動設定的進度值
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">void&lt;/span> &lt;span class="n">markBookCompleted&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">BookId&lt;/span> &lt;span class="n">id&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="cm">/* ... */&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">&lt;span class="c1">/// 【需求】UC-003 書籍狀態轉換
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">&lt;span class="c1">/// 書籍從「未開始」改為「閱讀中」時，初始化進度為 0%
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl">&lt;span class="c1">/// 約束：不重置已有的閱讀時間紀錄
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">9&lt;/span>&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">void&lt;/span> &lt;span class="n">markBookReading&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">BookId&lt;/span> &lt;span class="n">id&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="cm">/* ... */&lt;/span> &lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>每則註解只描述一個狀態轉換規則，閱讀者不需同時記住兩條規則才能理解一個函式。&lt;/p>
&lt;h3 id="反例">反例&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-dart" data-lang="dart">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c1">/// 【需求】UC-003 書籍狀態轉換
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="c1">/// 處理所有狀態變化：未開始→閱讀中時進度設 0%、閱讀中→完成時進度設 100%、
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">&lt;span class="c1">/// 完成→未開始時清空進度、任何狀態→暫停時保留進度並記錄暫停時間
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="c1">/// 約束：不覆蓋使用者手動進度，除了清空場景
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">&lt;span class="c1">/// 例外：管理員可跳過轉換規則直接設定任何狀態
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">void&lt;/span> &lt;span class="n">handleBookStatusChange&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">BookId&lt;/span> &lt;span class="n">id&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">Status&lt;/span> &lt;span class="n">from&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">Status&lt;/span> &lt;span class="n">to&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="cm">/* ... */&lt;/span> &lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>註解承擔 4 種狀態轉換的全部規則，閱讀者認知負擔爆表（規則數 × 例外數 = 複合爆炸），函式本身也違反單一職責。&lt;/p>
&lt;h3 id="判斷標準">判斷標準&lt;/h3>
&lt;ul>
&lt;li>註解超過 5 行且包含 2+ 個「且」「或」「除了」「同時」？→ 拆分函式&lt;/li>
&lt;li>同一註解內有多個無關的約束條件？→ 拆分函式&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="原則二索引--註解">原則二：索引 × 註解&lt;/h2>
&lt;p>&lt;strong>需求編號（UC-XXX、BR-XXX、TKT-ID）是註解的「連結卡」&lt;/strong>，讓註解與規格文件、ticket、worklog 之間建立可追溯的索引。&lt;/p>
&lt;h3 id="正例-1">正例&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-dart" data-lang="dart">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c1">/// 【需求】UC-004 書籍搜尋功能
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="c1">/// 【規格】docs/spec/search.md#fuzzy-match
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">&lt;span class="c1">/// 支援書名、作者、標籤的模糊搜尋
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="c1">/// 擴展指引：新增搜尋條件時必須更新 SearchCriteria 值物件
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">List&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Book&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">searchBooks&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">SearchCriteria&lt;/span> &lt;span class="n">criteria&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="cm">/* ... */&lt;/span> &lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>閱讀者可從 UC-004 跳到需求文件，從規格路徑跳到設計細節。三者互為索引卡片。&lt;/p>
&lt;h3 id="反例-1">反例&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-dart" data-lang="dart">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c1">/// 實作書籍搜尋功能，根據某些條件查找
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">List&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Book&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">searchBooks&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">SearchCriteria&lt;/span> &lt;span class="n">criteria&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="cm">/* ... */&lt;/span> &lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>沒有需求索引，閱讀者無法回溯「這個函式為什麼存在」「規格在哪」。&lt;/p>
&lt;h3 id="索引內容建議">索引內容建議&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>索引類型&lt;/th>
 &lt;th>格式&lt;/th>
 &lt;th>用途&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>需求來源&lt;/td>
 &lt;td>&lt;code>【需求】UC-003&lt;/code> 或 &lt;code>【需求】BR-007&lt;/code>&lt;/td>
 &lt;td>連回需求規格&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>規格文件&lt;/td>
 &lt;td>&lt;code>【規格】docs/spec/xxx.md#section&lt;/code>&lt;/td>
 &lt;td>連回設計細節&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>相依模組&lt;/td>
 &lt;td>&lt;code>【相依】[ModuleA], [ModuleB]&lt;/code>&lt;/td>
 &lt;td>用命名引用，不解釋實作&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>禁止&lt;/strong>：註解內放 ticket ID（如 &lt;code>v1.2.3-W5-001&lt;/code>、&lt;code>TKT-1234&lt;/code>），ticket 是臨時追蹤編號，會被搬移歸檔；需求編號（UC/BR）才是穩定索引。&lt;!-- portability-allow: educational example of prohibited pattern -->&lt;/p>
&lt;hr>
&lt;h2 id="原則三意圖顯性與商業邏輯--註解">原則三：意圖顯性與商業邏輯 × 註解&lt;/h2>
&lt;p>&lt;strong>Doc comment 描述業務情境，不解釋語法選擇。&lt;/strong> 閱讀者想知道「這段程式解決什麼業務問題」「什麼情境下會觸發」「如果不這樣做會發生什麼產品層面後果」；語法細節（while vs if、async、late 變數）讀者看 code 就能推斷，不需要 doc comment 佔用最靠近視線的位置解釋。&lt;/p>
&lt;h3 id="31-語法-vs-業務情境區分">3.1 語法 vs 業務情境區分&lt;/h3>
&lt;p>註解的語法層 vs 業務層區分：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>層級&lt;/th>
 &lt;th>註解回答的問題&lt;/th>
 &lt;th>範例&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>語法層（禁止在 doc comment）&lt;/td>
 &lt;td>為什麼用 &lt;code>while&lt;/code> 而不是 &lt;code>if&lt;/code>？為什麼 &lt;code>late&lt;/code>？為什麼 &lt;code>async&lt;/code>？&lt;/td>
 &lt;td>讀 code 可推斷，寫在 doc 浪費視線位置&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>業務層（doc comment 聚焦）&lt;/td>
 &lt;td>此程式解決什麼業務問題？什麼情境觸發？不這樣做會發生什麼產品後果？&lt;/td>
 &lt;td>「印表機鎖定時，後續任務必須排隊等待；若跳過鎖定會導致列印頁面交錯」&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h4 id="反例語法選擇解釋">反例：語法選擇解釋&lt;/h4>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-dart" data-lang="dart">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c1">/// 使用 while 迴圈而非 if，因為 job queue 可能有多筆任務需要依序處理
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="c1">/// 使用 async 以避免阻塞 UI thread
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">&lt;span class="c1">/// 使用 late 變數因為 printer 物件在建構時尚未就緒
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">Future&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">processPrintJobs&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="kd">async&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">jobs&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">isNotEmpty&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="cm">/* ... */&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>這三行都在解釋語法選擇，讀者看 code 已能推斷 &lt;code>async&lt;/code>、&lt;code>late&lt;/code>、&lt;code>while&lt;/code> 的技術動機。沒有任何業務資訊。&lt;/p></description><content:encoded><![CDATA[<p>本 reference 提供撰寫程式碼註解的完整指引，整合核心寫作原則在註解情境的具體應用。讀者只需讀本文件，即可獨立寫出合格的註解，不需再讀其他 reference。</p>
<blockquote>
<p><strong>核心命題</strong>：註解是業務需求和設計意圖的守護者。註解的認知依賴必須跟著程式依賴一起降低——介面的註解只寫契約，不洩漏實作；實作的註解說明業務規則，不描述語法選擇。</p></blockquote>
<hr>
<h2 id="適用時機">適用時機</h2>
<p>當你準備寫 / 改 / 審查以下任一註解時，應用本指引：</p>
<table>
  <thead>
      <tr>
          <th>情境</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Doc comment（<code>///</code>、<code>/** */</code>、<code>&quot;&quot;&quot;...&quot;&quot;&quot;</code>）</td>
          <td>位於函式、類別、介面、模組宣告前方，供外部閱讀者和工具消費</td>
      </tr>
      <tr>
          <td>Inline comment（<code>//</code>、<code>#</code>）</td>
          <td>位於實作內部，說明「為什麼這樣做」</td>
      </tr>
      <tr>
          <td>模組 README 或檔案頂部 header</td>
          <td>描述此模組解決的問題</td>
      </tr>
      <tr>
          <td>介面 / 抽象類別的 docstring</td>
          <td>定義契約（做什麼、輸入輸出語意、使用情境）</td>
      </tr>
  </tbody>
</table>
<p><strong>不適用</strong>：commit message、PR description、ticket context（另見其他情境 reference）。</p>
<hr>
<h2 id="原則一原子化--註解">原則一：原子化 × 註解</h2>
<p><strong>一則註解只解釋一個概念。</strong> 一個函式若需要註解說明多個不相關的關注點，應先拆分函式，再為每個函式寫獨立註解。</p>
<h3 id="正例">正例</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1">/// 【需求】UC-003 書籍狀態轉換
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1">/// 書籍從「閱讀中」改為「已完成」時，自動將進度設為 100%
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1">/// 約束：不可覆蓋使用者手動設定的進度值
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"></span><span class="kt">void</span> <span class="n">markBookCompleted</span><span class="p">(</span><span class="n">BookId</span> <span class="n">id</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* ... */</span> <span class="p">}</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="c1">/// 【需求】UC-003 書籍狀態轉換
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="c1">/// 書籍從「未開始」改為「閱讀中」時，初始化進度為 0%
</span></span></span><span class="line"><span class="ln">8</span><span class="cl"><span class="c1">/// 約束：不重置已有的閱讀時間紀錄
</span></span></span><span class="line"><span class="ln">9</span><span class="cl"><span class="c1"></span><span class="kt">void</span> <span class="n">markBookReading</span><span class="p">(</span><span class="n">BookId</span> <span class="n">id</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* ... */</span> <span class="p">}</span></span></span></code></pre></div><p>每則註解只描述一個狀態轉換規則，閱讀者不需同時記住兩條規則才能理解一個函式。</p>
<h3 id="反例">反例</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1">/// 【需求】UC-003 書籍狀態轉換
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1">/// 處理所有狀態變化：未開始→閱讀中時進度設 0%、閱讀中→完成時進度設 100%、
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1">/// 完成→未開始時清空進度、任何狀態→暫停時保留進度並記錄暫停時間
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1">/// 約束：不覆蓋使用者手動進度，除了清空場景
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1">/// 例外：管理員可跳過轉換規則直接設定任何狀態
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="c1"></span><span class="kt">void</span> <span class="n">handleBookStatusChange</span><span class="p">(</span><span class="n">BookId</span> <span class="n">id</span><span class="p">,</span> <span class="n">Status</span> <span class="n">from</span><span class="p">,</span> <span class="n">Status</span> <span class="n">to</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* ... */</span> <span class="p">}</span></span></span></code></pre></div><p>註解承擔 4 種狀態轉換的全部規則，閱讀者認知負擔爆表（規則數 × 例外數 = 複合爆炸），函式本身也違反單一職責。</p>
<h3 id="判斷標準">判斷標準</h3>
<ul>
<li>註解超過 5 行且包含 2+ 個「且」「或」「除了」「同時」？→ 拆分函式</li>
<li>同一註解內有多個無關的約束條件？→ 拆分函式</li>
</ul>
<hr>
<h2 id="原則二索引--註解">原則二：索引 × 註解</h2>
<p><strong>需求編號（UC-XXX、BR-XXX、TKT-ID）是註解的「連結卡」</strong>，讓註解與規格文件、ticket、worklog 之間建立可追溯的索引。</p>
<h3 id="正例-1">正例</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1">/// 【需求】UC-004 書籍搜尋功能
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1">/// 【規格】docs/spec/search.md#fuzzy-match
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1">/// 支援書名、作者、標籤的模糊搜尋
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1">/// 擴展指引：新增搜尋條件時必須更新 SearchCriteria 值物件
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1"></span><span class="n">List</span><span class="o">&lt;</span><span class="n">Book</span><span class="o">&gt;</span> <span class="n">searchBooks</span><span class="p">(</span><span class="n">SearchCriteria</span> <span class="n">criteria</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* ... */</span> <span class="p">}</span></span></span></code></pre></div><p>閱讀者可從 UC-004 跳到需求文件，從規格路徑跳到設計細節。三者互為索引卡片。</p>
<h3 id="反例-1">反例</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1">/// 實作書籍搜尋功能，根據某些條件查找
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1"></span><span class="n">List</span><span class="o">&lt;</span><span class="n">Book</span><span class="o">&gt;</span> <span class="n">searchBooks</span><span class="p">(</span><span class="n">SearchCriteria</span> <span class="n">criteria</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* ... */</span> <span class="p">}</span></span></span></code></pre></div><p>沒有需求索引，閱讀者無法回溯「這個函式為什麼存在」「規格在哪」。</p>
<h3 id="索引內容建議">索引內容建議</h3>
<table>
  <thead>
      <tr>
          <th>索引類型</th>
          <th>格式</th>
          <th>用途</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>需求來源</td>
          <td><code>【需求】UC-003</code> 或 <code>【需求】BR-007</code></td>
          <td>連回需求規格</td>
      </tr>
      <tr>
          <td>規格文件</td>
          <td><code>【規格】docs/spec/xxx.md#section</code></td>
          <td>連回設計細節</td>
      </tr>
      <tr>
          <td>相依模組</td>
          <td><code>【相依】[ModuleA], [ModuleB]</code></td>
          <td>用命名引用，不解釋實作</td>
      </tr>
  </tbody>
</table>
<p><strong>禁止</strong>：註解內放 ticket ID（如 <code>v1.2.3-W5-001</code>、<code>TKT-1234</code>），ticket 是臨時追蹤編號，會被搬移歸檔；需求編號（UC/BR）才是穩定索引。<!-- portability-allow: educational example of prohibited pattern --></p>
<hr>
<h2 id="原則三意圖顯性與商業邏輯--註解">原則三：意圖顯性與商業邏輯 × 註解</h2>
<p><strong>Doc comment 描述業務情境，不解釋語法選擇。</strong> 閱讀者想知道「這段程式解決什麼業務問題」「什麼情境下會觸發」「如果不這樣做會發生什麼產品層面後果」；語法細節（while vs if、async、late 變數）讀者看 code 就能推斷，不需要 doc comment 佔用最靠近視線的位置解釋。</p>
<h3 id="31-語法-vs-業務情境區分">3.1 語法 vs 業務情境區分</h3>
<p>註解的語法層 vs 業務層區分：</p>
<table>
  <thead>
      <tr>
          <th>層級</th>
          <th>註解回答的問題</th>
          <th>範例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>語法層（禁止在 doc comment）</td>
          <td>為什麼用 <code>while</code> 而不是 <code>if</code>？為什麼 <code>late</code>？為什麼 <code>async</code>？</td>
          <td>讀 code 可推斷，寫在 doc 浪費視線位置</td>
      </tr>
      <tr>
          <td>業務層（doc comment 聚焦）</td>
          <td>此程式解決什麼業務問題？什麼情境觸發？不這樣做會發生什麼產品後果？</td>
          <td>「印表機鎖定時，後續任務必須排隊等待；若跳過鎖定會導致列印頁面交錯」</td>
      </tr>
  </tbody>
</table>
<h4 id="反例語法選擇解釋">反例：語法選擇解釋</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1">/// 使用 while 迴圈而非 if，因為 job queue 可能有多筆任務需要依序處理
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1">/// 使用 async 以避免阻塞 UI thread
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1">/// 使用 late 變數因為 printer 物件在建構時尚未就緒
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"></span><span class="n">Future</span><span class="o">&lt;</span><span class="kt">void</span><span class="o">&gt;</span> <span class="n">processPrintJobs</span><span class="p">()</span> <span class="kd">async</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">  <span class="k">while</span> <span class="p">(</span><span class="n">jobs</span><span class="p">.</span><span class="n">isNotEmpty</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* ... */</span> <span class="p">}</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>這三行都在解釋語法選擇，讀者看 code 已能推斷 <code>async</code>、<code>late</code>、<code>while</code> 的技術動機。沒有任何業務資訊。</p>
<h4 id="正例業務情境聚焦">正例：業務情境聚焦</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1">/// 【需求】UC-008 列印佇列管理
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1">/// 印表機一次只能處理一份任務；若同時送出多份會造成頁面交錯（使用者投訴 #234）。
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1">/// 此函式確保所有 pending 任務依送出順序依序處理，直到佇列清空。
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1">/// 約束：佇列處理期間不可接受新任務（由呼叫端的鎖保證）
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1">/// 【相依】[PrinterLockService]
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="c1"></span><span class="n">Future</span><span class="o">&lt;</span><span class="kt">void</span><span class="o">&gt;</span> <span class="n">processPrintJobs</span><span class="p">()</span> <span class="kd">async</span> <span class="p">{</span> <span class="cm">/* ... */</span> <span class="p">}</span></span></span></code></pre></div><p>讀完可理解：業務情境（印表機獨佔）、觸發條件（多份任務同時送出）、失敗後果（頁面交錯 + 使用者投訴）、約束（外部鎖）。技術細節（async/while）由 code 自明。</p>
<h3 id="32-doc-comment-聚焦業務情境">3.2 Doc comment 聚焦業務情境</h3>
<p>Doc comment 是函式、類別、介面的契約說明，應回答三個問題：</p>
<ol>
<li><strong>解決什麼業務問題</strong>：此程式存在的商業原因</li>
<li><strong>什麼情境觸發</strong>：使用者的哪個動作、系統的哪個狀態會進入此路徑</li>
<li><strong>不這樣做的產品後果</strong>：錯誤實作會造成什麼使用者可見的問題</li>
</ol>
<h4 id="反例純技術描述">反例：純技術描述</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1">/// 將 Book 物件序列化為 JSON 字串並寫入 SharedPreferences
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1">/// 使用 jsonEncode 和 keyPrefix = &#39;book_&#39;
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1"></span><span class="kt">void</span> <span class="n">saveBook</span><span class="p">(</span><span class="n">Book</span> <span class="n">book</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* ... */</span> <span class="p">}</span></span></span></code></pre></div><p>只描述「怎麼做」，沒說「為什麼做」「什麼時候該做」。</p>
<h4 id="正例業務情境驅動">正例：業務情境驅動</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1">/// 【需求】UC-002 離線書庫
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1">/// 使用者關閉 app 後重開仍能看到書庫清單（不需重新從 Readmoo 抓取）。
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1">/// 觸發時機：使用者匯入新書、編輯書籍標籤、標記進度時。
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1">/// 若未持久化，使用者每次開 app 都要等網路載入，離線時完全無法使用。
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1"></span><span class="kt">void</span> <span class="n">saveBook</span><span class="p">(</span><span class="n">Book</span> <span class="n">book</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* ... */</span> <span class="p">}</span></span></span></code></pre></div><h3 id="33-禁止-doc-comment-寫-todo--placeholder">3.3 禁止 Doc comment 寫 TODO / placeholder</h3>
<p>Doc comment 描述穩定契約，不應包含「等等要做 X」「暫時這樣」「未來會改」等臨時性內容。TODO/placeholder 應該：</p>
<table>
  <thead>
      <tr>
          <th>內容</th>
          <th>放哪裡</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>未完成工作</td>
          <td>Ticket 或 inline comment（<code>// TODO: ...</code>）</td>
      </tr>
      <tr>
          <td>暫時實作說明</td>
          <td>Inline comment，並建立 ticket 追蹤</td>
      </tr>
      <tr>
          <td>臨時 workaround</td>
          <td>Inline comment 指向 issue link</td>
      </tr>
      <tr>
          <td>穩定契約</td>
          <td>Doc comment</td>
      </tr>
  </tbody>
</table>
<h4 id="反例-2">反例</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1">/// 【需求】UC-005 閱讀進度同步
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1">/// TODO: 之後要加入衝突解決邏輯
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1">/// 暫時實作：直接覆蓋本地值，不處理同時間多裝置修改
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1">/// 注意：此函式還沒寫單元測試（placeholder）
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1"></span><span class="n">Future</span><span class="o">&lt;</span><span class="kt">void</span><span class="o">&gt;</span> <span class="n">syncProgress</span><span class="p">(</span><span class="n">Book</span> <span class="n">book</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* ... */</span> <span class="p">}</span></span></span></code></pre></div><p>Doc comment 是契約，卻充滿「之後」「暫時」「還沒」——讀者無法判斷哪些是契約、哪些是待辦。</p>
<h4 id="正例-2">正例</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1">/// 【需求】UC-005 閱讀進度同步
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1">/// 將本地進度寫入雲端。同時間多裝置修改時，採 last-write-wins。
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1">/// 約束：網路失敗時本地變更會留在 outbox 等待重試（呼叫端不需處理失敗）
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"></span><span class="n">Future</span><span class="o">&lt;</span><span class="kt">void</span><span class="o">&gt;</span> <span class="n">syncProgress</span><span class="p">(</span><span class="n">Book</span> <span class="n">book</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* ... */</span> <span class="p">}</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="c1">// TODO(&lt;ticket-id&gt;): last-write-wins 是暫時策略，實作 vector clock 衝突解決
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="c1"></span><span class="o">//</span> <span class="err">暫時不寫測試，</span><span class="o">&lt;</span><span class="n">ticket</span><span class="o">-</span><span class="n">id</span><span class="o">&gt;</span> <span class="err">追蹤</span></span></span></code></pre></div><p>Doc 只描述當前契約（LWW 策略是<strong>當前的契約</strong>，不是「暫時」），TODO 放 inline 並指向 ticket。</p>
<h3 id="34-註解貼合抽象層級">3.4 註解貼合抽象層級</h3>
<p><strong>介面的註解只寫契約，不洩漏實作。</strong> 程式刻意解耦（介面 vs 實作、模組 vs 模組）是為了讓讀/改某一層時不需通盤理解其他層；若註解又把實作細節拉回介面裡，讀介面等於要先認識實作，抽象帶來的好處被註解抵消掉。</p>
<p><strong>核心原則</strong>：註解的認知依賴必須跟著程式依賴一起降低。</p>
<h4 id="反例介面-doc-洩漏實作">反例：介面 doc 洩漏實作</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln">1</span><span class="cl"><span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">OrderRepository</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">  <span class="c1">/// 取得訂單清單。
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1"></span>  <span class="c1">/// 資料來源由實作層決定（目前為定時輪詢 [IOnlineOrderService]），
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"></span>  <span class="c1">/// 消費端不需關心來源為輪詢或推播。
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1"></span>  <span class="n">Future</span><span class="o">&lt;</span><span class="n">List</span><span class="o">&lt;</span><span class="n">Order</span><span class="o">&gt;&gt;</span> <span class="n">fetchOrders</span><span class="p">();</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>既說「不需關心」又主動告知「目前是輪詢」，自相矛盾且洩漏實作。讀者看完反而<strong>被迫知道</strong>實作是輪詢，介面的抽象價值被註解抵消。</p>
<h4 id="正例只寫契約--命名引用">正例：只寫契約 + 命名引用</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln">1</span><span class="cl"><span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">OrderRepository</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">  <span class="c1">/// 取得訂單清單。
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1"></span>  <span class="c1">/// 保證按建立時間由新到舊排序。空結果回傳空陣列（不拋例外）。
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"></span>  <span class="c1">/// 資料來源：[IOnlineOrderService]
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1"></span>  <span class="n">Future</span><span class="o">&lt;</span><span class="n">List</span><span class="o">&lt;</span><span class="n">Order</span><span class="o">&gt;&gt;</span> <span class="n">fetchOrders</span><span class="p">();</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>讀者想知道資料來源細節可跳轉到 <code>IOnlineOrderService</code>；不想知道可跳過。註解的認知依賴和程式的依賴方向一致（介面 → 服務命名引用，不反向揭露實作）。</p>
<h4 id="同理適用範圍">同理適用範圍</h4>
<table>
  <thead>
      <tr>
          <th>位置</th>
          <th>只寫什麼</th>
          <th>不寫什麼</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>介面 doc</td>
          <td>契約（做什麼、輸入輸出語意、使用情境）</td>
          <td>「目前實作用什麼方式」</td>
      </tr>
      <tr>
          <td>模組 README</td>
          <td>此模組解決的問題、對外 API</td>
          <td>內部類別結構、用了什麼演算法</td>
      </tr>
      <tr>
          <td>函式 docstring</td>
          <td>解決什麼問題、輸入輸出約定</td>
          <td>內部怎麼解決（除非行為細節是契約，如冪等性、順序保證）</td>
      </tr>
      <tr>
          <td>抽象類別 doc</td>
          <td>子類需實作的契約、行為承諾</td>
          <td>某個子類的具體實作方式</td>
      </tr>
  </tbody>
</table>
<p><strong>例外</strong>：當行為細節本身就是契約的一部分時（例如「保證冪等」「保證依序處理」「保證不阻塞」），這些細節<strong>就是契約</strong>，必須寫在 doc 中。關鍵判斷：消費端會因此細節而改變使用方式嗎？是 → 寫進 doc；否 → 留給實作層。</p>
<hr>
<h2 id="原則四可查詢性--註解">原則四：可查詢性 × 註解</h2>
<p><strong>註解的關鍵字設計讓 grep / AI 能定位。</strong> 當維護者搜尋「哪個函式處理書籍狀態轉換」時，註解應包含讓搜尋命中的詞彙。</p>
<h3 id="關鍵字設計建議">關鍵字設計建議</h3>
<table>
  <thead>
      <tr>
          <th>類型</th>
          <th>格式</th>
          <th>範例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>需求索引</td>
          <td><code>【需求】UC-XXX</code></td>
          <td><code>【需求】UC-003 書籍狀態轉換</code></td>
      </tr>
      <tr>
          <td>業務概念</td>
          <td>使用業務詞彙而非技術詞彙</td>
          <td>用「狀態轉換」而不只寫「update」</td>
      </tr>
      <tr>
          <td>分類標記</td>
          <td><code>【事件】</code>、<code>【約束】</code>、<code>【相依】</code></td>
          <td><code>【事件】BookAddedEvent</code> 處理</td>
      </tr>
      <tr>
          <td>警告標記</td>
          <td><code>【警告】</code>、<code>【維護】</code></td>
          <td><code>【維護】修改前檢查 3 個呼叫端</code></td>
      </tr>
  </tbody>
</table>
<h3 id="正例-3">正例</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1">/// 【需求】UC-006 借閱到期提醒
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1">/// 【事件】ReminderTriggeredEvent 消費端
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1">/// 當借閱書籍距離到期日 &lt; 3 天時觸發提醒。
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1">/// 【約束】同一本書 24 小時內只提醒一次（由 ReminderDebouncer 處理）
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1">/// 【維護】修改提醒閾值需同步更新 ReminderDebouncer.windowHours
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="c1"></span><span class="n">Future</span><span class="o">&lt;</span><span class="kt">void</span><span class="o">&gt;</span> <span class="n">sendDueReminder</span><span class="p">(</span><span class="n">Loan</span> <span class="n">loan</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* ... */</span> <span class="p">}</span></span></span></code></pre></div><p>搜尋「到期提醒」、「ReminderTriggeredEvent」、「ReminderDebouncer」都能命中；<code>【事件】</code> 標記讓過濾所有事件消費端變可能。</p>
<h3 id="反例-3">反例</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1">/// 檢查並處理到期相關的事情
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1"></span><span class="n">Future</span><span class="o">&lt;</span><span class="kt">void</span><span class="o">&gt;</span> <span class="n">sendDueReminder</span><span class="p">(</span><span class="n">Loan</span> <span class="n">loan</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* ... */</span> <span class="p">}</span></span></span></code></pre></div><p>「相關的事情」是語意黑洞，grep 搜尋業務詞彙無法命中。</p>
<h3 id="分隔符規範">分隔符規範</h3>
<p>使用一致的分隔符讓結構可被 regex 解析：</p>
<ul>
<li><code>【XXX】</code> 全形方括號：語義標記（需求、事件、約束、維護、相依）</li>
<li><code>[ModuleName]</code> 半形方括號：類別 / 模組命名引用（可被 LSP 跳轉）</li>
<li><code>UC-XXX</code>、<code>BR-XXX</code>、<code>#section</code>：索引格式固定，便於全專案統一搜尋</li>
</ul>
<hr>
<h2 id="原則五欄位設計--註解不同抽象層的註解寫法">原則五：欄位設計 × 註解（不同抽象層的註解寫法）</h2>
<p><strong>不同抽象層的註解寫法不同</strong>——這是「欄位設計精神」在註解的應用：同一概念在不同位置用不同角度描述，避免重複。</p>
<h3 id="抽象層級對照表">抽象層級對照表</h3>
<table>
  <thead>
      <tr>
          <th>層級</th>
          <th>註解角度</th>
          <th>回答的問題</th>
          <th>範例重點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>介面 / 抽象類別</td>
          <td>契約視角</td>
          <td>做什麼？承諾什麼？</td>
          <td>「保證按建立時間排序」</td>
      </tr>
      <tr>
          <td>實作類別</td>
          <td>策略視角</td>
          <td>用什麼策略達成契約？（策略選擇理由，非語法）</td>
          <td>「用資料庫 ORDER BY 而非記憶體排序，因為訂單數可能 &gt; 10 萬」</td>
      </tr>
      <tr>
          <td>函式</td>
          <td>步驟視角</td>
          <td>此函式在整個流程扮演什麼角色？</td>
          <td>「在轉帳流程中負責扣款步驟」</td>
      </tr>
      <tr>
          <td>Inline（行內）</td>
          <td>決策視角</td>
          <td>這行為何必要？不這樣會怎樣？</td>
          <td><code>// 必須先 flush cache，否則下一行的 read 會拿到舊值</code></td>
      </tr>
  </tbody>
</table>
<h3 id="正例同一業務概念的多層寫法">正例：同一業務概念的多層寫法</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1">// 介面層：只寫契約
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1"></span><span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">OrderSearcher</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">  <span class="c1">/// 【需求】UC-004 訂單查詢
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"></span>  <span class="c1">/// 依關鍵字搜尋訂單。結果按建立時間新到舊排序。
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="c1"></span>  <span class="c1">/// 無結果回傳空陣列（不拋例外）。
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="c1"></span>  <span class="n">Future</span><span class="o">&lt;</span><span class="n">List</span><span class="o">&lt;</span><span class="n">Order</span><span class="o">&gt;&gt;</span> <span class="n">searchByKeyword</span><span class="p">(</span><span class="kt">String</span> <span class="n">keyword</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="c1">// 實作層：解釋策略選擇
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="c1"></span><span class="kd">class</span> <span class="nc">DbOrderSearcher</span> <span class="kd">implements</span> <span class="n">OrderSearcher</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">  <span class="c1">/// 【需求】UC-004 訂單查詢
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="c1"></span>  <span class="c1">/// 使用資料庫全文索引（非記憶體 filter），因訂單量可能達十萬級。
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="c1"></span>  <span class="c1">/// 【相依】[FullTextIndex]
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="c1"></span>  <span class="err">@</span><span class="n">override</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">  <span class="n">Future</span><span class="o">&lt;</span><span class="n">List</span><span class="o">&lt;</span><span class="n">Order</span><span class="o">&gt;&gt;</span> <span class="n">searchByKeyword</span><span class="p">(</span><span class="kt">String</span> <span class="n">keyword</span><span class="p">)</span> <span class="kd">async</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">    <span class="c1">// ... 實作
</span></span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="c1"></span>    <span class="c1">// 先 normalize 輸入（小寫 + 移除標點），否則索引無法命中
</span></span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="c1"></span>    <span class="kd">final</span> <span class="n">normalized</span> <span class="o">=</span> <span class="n">_normalize</span><span class="p">(</span><span class="n">keyword</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">    <span class="c1">// ... 查詢
</span></span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="c1"></span>  <span class="p">}</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><ul>
<li>介面註解：讀者想知道契約即足夠</li>
<li>實作註解：讀者想知道「為什麼用 DB 不用記憶體」</li>
<li>Inline 註解：讀者想知道「這行 normalize 為什麼不可刪」</li>
</ul>
<p>三處註解從不同角度描述同一業務概念，不重複。</p>
<h3 id="反例三層寫相同內容">反例：三層寫相同內容</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">OrderSearcher</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  <span class="c1">/// 使用資料庫全文索引搜尋訂單，依建立時間排序
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="c1"></span>  <span class="n">Future</span><span class="o">&lt;</span><span class="n">List</span><span class="o">&lt;</span><span class="n">Order</span><span class="o">&gt;&gt;</span> <span class="n">searchByKeyword</span><span class="p">(</span><span class="kt">String</span> <span class="n">keyword</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="kd">class</span> <span class="nc">DbOrderSearcher</span> <span class="kd">implements</span> <span class="n">OrderSearcher</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  <span class="c1">/// 使用資料庫全文索引搜尋訂單，依建立時間排序
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="c1"></span>  <span class="n">Future</span><span class="o">&lt;</span><span class="n">List</span><span class="o">&lt;</span><span class="n">Order</span><span class="o">&gt;&gt;</span> <span class="n">searchByKeyword</span><span class="p">(</span><span class="kt">String</span> <span class="n">keyword</span><span class="p">)</span> <span class="kd">async</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    <span class="c1">// 使用資料庫全文索引搜尋訂單，依建立時間排序
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="c1"></span>    <span class="c1">// ...
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="c1"></span>  <span class="p">}</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>介面洩漏實作（違反原則 3.4）、三層內容重複（違反 DRY）、實作沒解釋策略選擇（讀者看不到「為什麼用 DB」）。</p>
<hr>
<h2 id="禁止模式清單">禁止模式清單</h2>
<p>以下註解模式<strong>禁止使用</strong>，CR 時應要求修改：</p>
<table>
  <thead>
      <tr>
          <th>禁止模式</th>
          <th>反例</th>
          <th>問題</th>
          <th>替代做法</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>程式碼翻譯</strong></td>
          <td><code>// 將計數器加 1</code> → <code>counter++</code></td>
          <td>重述程式碼做什麼，違反 DRY</td>
          <td>刪除註解或改寫為「為什麼加 1」</td>
      </tr>
      <tr>
          <td><strong>Doc 寫 TODO</strong></td>
          <td><code>/// TODO: 之後加驗證</code></td>
          <td>契約文件混入待辦</td>
          <td>移到 inline <code>// TODO(TKT-X): ...</code></td>
      </tr>
      <tr>
          <td><strong>Doc 寫 placeholder</strong></td>
          <td><code>/// 暫時先這樣做</code></td>
          <td>契約不應是臨時的</td>
          <td>寫成當前的真實契約，待辦另外追蹤</td>
      </tr>
      <tr>
          <td><strong>語法選擇解釋</strong></td>
          <td><code>// 用 while 因為要處理多筆</code></td>
          <td>讀 code 可推斷，浪費視線位置</td>
          <td>改寫為業務情境（為什麼有多筆）</td>
      </tr>
      <tr>
          <td><strong>技術實作描述</strong></td>
          <td><code>// 使用 Map 快速查找</code></td>
          <td>讀 code 可推斷</td>
          <td>若效能是契約，寫「保證 O(1) 查詢」</td>
      </tr>
      <tr>
          <td><strong>模糊業務描述</strong></td>
          <td><code>// 處理書籍相關邏輯</code></td>
          <td>語意黑洞，grep 無法命中</td>
          <td>具體描述觸發情境和規則</td>
      </tr>
      <tr>
          <td><strong>過時 TODO</strong></td>
          <td><code>// TODO: 加驗證</code>（但驗證已完成）</td>
          <td>誤導維護者</td>
          <td>刪除</td>
      </tr>
      <tr>
          <td><strong>介面洩漏實作</strong></td>
          <td>介面 doc 寫「目前用輪詢」</td>
          <td>破壞抽象，認知依賴爆增</td>
          <td>改為命名引用 + 只寫契約</td>
      </tr>
      <tr>
          <td><strong>無索引業務邏輯</strong></td>
          <td>純技術描述，無 UC/BR 編號</td>
          <td>無法回溯需求</td>
          <td>加 <code>【需求】UC-XXX</code></td>
      </tr>
      <tr>
          <td><strong>冗長混合責任</strong></td>
          <td>一則註解含 4 種狀態轉換規則</td>
          <td>認知負擔爆表</td>
          <td>拆函式 + 拆註解</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="自檢清單寫完註解問自己">自檢清單（寫完註解問自己）</h2>
<ul>
<li><input disabled="" type="checkbox"> 這則註解描述的是業務問題還是語法選擇？（若是後者，刪除或改寫）</li>
<li><input disabled="" type="checkbox"> 若這是 doc comment，讀者不看實作能理解契約嗎？</li>
<li><input disabled="" type="checkbox"> 若這是介面註解，有洩漏任何「目前實作用什麼」嗎？</li>
<li><input disabled="" type="checkbox"> 註解包含 TODO / placeholder / 暫時 嗎？（若是，移到 inline + ticket）</li>
<li><input disabled="" type="checkbox"> 一則註解只解釋一個概念嗎？（若不是，拆函式）</li>
<li><input disabled="" type="checkbox"> 有需求索引（UC/BR）讓閱讀者能回溯嗎？</li>
<li><input disabled="" type="checkbox"> 關鍵字設計讓 grep / AI 能找到嗎？（業務詞彙而非通用詞彙）</li>
<li><input disabled="" type="checkbox"> 註解貼合所在抽象層嗎？（介面寫契約、實作寫策略、inline 寫決策）</li>
</ul>
<hr>
<h2 id="多輪-re-read-passmulti-pass-refinement">多輪 Re-read Pass（multi-pass refinement）</h2>
<p>寫完上方自檢還不是 done — 自檢是「同 frame 的最後一掃」、不是 multi-pass。Multi-pass 要求每輪用<strong>不同 frame</strong> catch 不同層的錯（<a href="/blog/report/literal-interception-vs-behavioral-refinement/" data-link-title="字面攔截 vs 行為精煉：驗證手段跟錯誤層次的對齊" data-link-desc="驗證手段必須跟錯誤層次對齊：字面錯誤（typo / syntax / 缺欄位）用 hook / lint / CI 攔截；行為錯誤（思考偏差 / 判斷錯位 / collapse 反模式）用 multi-pass spiral 收斂。強行用 hook 蓋行為錯誤 = 給出 false confidence、反而比沒保護危險。本卡是 #72 結構性對策在「驗證粒度」維度的 ceiling — 不是所有錯誤都該被攔截。">literal-interception-vs-behavioral-refinement</a> / <a href="/blog/report/writing-multi-pass-review/" data-link-title="Writing 的 multi-pass review：N 輪 review、每輪換 frame" data-link-desc="寫文章 / 註解 / 文件 / prompt 的「寫」不是單次動作 — 是 N 輪 review。第 1 輪生成、第 2 輪對意圖（#67）、第 3 輪檢查機會成本語氣、第 4 輪 grep-ability、第 5 輪反例 / 邊界。每輪不同 frame、單輪寫不出全部維度。本卡是 #82 在「寫」這個 output 動作的具體實例。">writing-multi-pass-review</a>）。</p>
<p>註解用的核心三輪 + 兩輪程式碼專屬：</p>
<table>
  <thead>
      <tr>
          <th>輪</th>
          <th>Frame</th>
          <th>程式碼註解專用 checklist</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1</td>
          <td>生成</td>
          <td>把「為什麼」寫出來、預期語句不順</td>
      </tr>
      <tr>
          <td>2</td>
          <td>對意圖（<a href="/blog/report/ease-of-writing-vs-intent-alignment/" data-link-title="寫作便利度跟意圖對齊反相關" data-link-desc="寫程式時最容易寫出的版本、通常是離意圖最遠的版本。便利度建立在「現有上下文 / 已 materialize 資料 / 已存在 API」上、而意圖對齊需要找到正確的層、處理上游、跨抽象層 — 兩者方向相反。識別這個反相關 = 識別自己掉進「容易寫的陷阱」。">ease-of-writing-vs-intent-alignment</a>）</td>
          <td>寫的是「為什麼這樣做」嗎、不是「程式在做什麼」？業務需求 vs 語法選擇分清楚？</td>
      </tr>
      <tr>
          <td>3</td>
          <td>機會成本語氣</td>
          <td>「必須」「不可」翻成「在 X 情境下選擇 A 因為 ⋯⋯」</td>
      </tr>
      <tr>
          <td>4'</td>
          <td>介面 vs 實作分層</td>
          <td>doc comment 不洩漏 impl、inline comment 講 why 不講 what、抽象層對齊嗎？</td>
      </tr>
      <tr>
          <td>5'</td>
          <td>時間軸 robust</td>
          <td>5 個月後讀還看得懂嗎？依賴的 ticket / 連結還活著嗎？</td>
      </tr>
  </tbody>
</table>
<h3 id="naming-子場景四輪-reviewnaming-as-iterated-artifact">Naming 子場景：四輪 review（<a href="/blog/report/naming-as-iterated-artifact/" data-link-title="Naming 是 iterated artifact：第一個名字幾乎不對、四輪 review 才收斂" data-link-desc="命名（變數 / 函式 / 檔名 / slug / API endpoint）幾乎沒有「一次寫對」的可能：第一個名字基於當下狹窄的 context、會在後續 cross-call-site / grep / 重構中暴露錯位。命名的正確設計是 iterated — 寫第一版 → grep-ability 測試 → cross-call-site 一致性 → impl 洩漏 → 重命名。本卡是 #83 在「命名」場景的特化。">naming-as-iterated-artifact</a>）</h3>
<p>註解寫完該 review 一次「這段程式碼涉及的命名」。命名是 iterated artifact、第一版幾乎不對：</p>
<table>
  <thead>
      <tr>
          <th>輪</th>
          <th>Frame</th>
          <th>命名專用 checklist</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1</td>
          <td>第一版</td>
          <td>反映「做什麼 / 是什麼」、不是「怎麼做」；不超過 4 單字</td>
      </tr>
      <tr>
          <td>2</td>
          <td>Grep-ability</td>
          <td><code>grep -r &quot;&lt;name&gt;&quot;</code> 能命中目標、不被別的 entity 蓋過、不撞 framework reserved（<code>data</code> 等）</td>
      </tr>
      <tr>
          <td>3</td>
          <td>Cross-call-site 一致</td>
          <td>同概念在不同 file 用同名嗎？動詞時態一致嗎？跟同 module 命名格式一致嗎？</td>
      </tr>
      <tr>
          <td>4</td>
          <td>Impl 洩漏檢查</td>
          <td>名字含 impl 細節嗎（<code>fetchUserViaSql</code>）？換 impl 後名字還對嗎？data structure 細節洩漏嗎？</td>
      </tr>
  </tbody>
</table>
<p>跳輪規則：</p>
<ul>
<li>Loop counter / close-up var：跑輪 1</li>
<li>Test code 內部 helper：1 + 4</li>
<li>跨 team API / DB schema：每輪都跑、跑兩遍</li>
<li>Production-facing URL / endpoint：不可跳</li>
</ul>
<p>詳見 <a href="/blog/report/naming-as-iterated-artifact/" data-link-title="Naming 是 iterated artifact：第一個名字幾乎不對、四輪 review 才收斂" data-link-desc="命名（變數 / 函式 / 檔名 / slug / API endpoint）幾乎沒有「一次寫對」的可能：第一個名字基於當下狹窄的 context、會在後續 cross-call-site / grep / 重構中暴露錯位。命名的正確設計是 iterated — 寫第一版 → grep-ability 測試 → cross-call-site 一致性 → impl 洩漏 → 重命名。本卡是 #83 在「命名」場景的特化。">naming-as-iterated-artifact</a>。</p>
<hr>
<h2 id="常見意外場景">常見意外場景</h2>
<h3 id="場景-1改-bug-時順手改壞註解">場景 1：改 bug 時順手改壞註解</h3>
<p>修 bug 改了實作，忘記檢查 doc 是否仍成立。<strong>SOP</strong>：改實作前先讀 doc comment；改完後回檢「doc 描述是否仍準確」。若契約變了，doc 必須同步修。</p>
<h3 id="場景-2抄別的函式的-doc-comment">場景 2：抄別的函式的 doc comment</h3>
<p>抄來的 doc 描述可能來自另一個業務情境。<strong>SOP</strong>：抄完後必須重寫需求索引和業務描述，確認「這個函式解決的問題」與原函式相同才能保留 doc。</p>
<h3 id="場景-3用-ai-產生-doc-comment">場景 3：用 AI 產生 doc comment</h3>
<p>AI 傾向產生「語法翻譯式」註解（使用 while 因為&hellip;）。<strong>SOP</strong>：AI 產出後必須人工審查，把「語法理由」全刪，補「業務理由」。</p>
<h3 id="場景-4介面加新方法時-copy-實作的-doc">場景 4：介面加新方法時 copy 實作的 doc</h3>
<p>實作的 doc 可能包含策略細節，直接 copy 到介面會洩漏實作。<strong>SOP</strong>：新增介面方法時，只保留契約描述部分（做什麼、輸入輸出、使用情境），刪除策略細節（用什麼演算法、為什麼用 DB）。</p>
<hr>
<h2 id="回顧總結">回顧總結</h2>
<table>
  <thead>
      <tr>
          <th>原則</th>
          <th>在註解情境的具體意義</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>原子化</td>
          <td>一則註解只解釋一個概念；函式需多條規則就拆函式</td>
      </tr>
      <tr>
          <td>索引</td>
          <td>用 UC/BR 編號建立註解 → 需求 → 規格的追溯鏈</td>
      </tr>
      <tr>
          <td>意圖顯性與商業邏輯</td>
          <td>Doc 聚焦業務情境；區分語法 vs 業務；不寫 TODO/placeholder；貼合抽象層級</td>
      </tr>
      <tr>
          <td>可查詢性</td>
          <td>使用業務詞彙、語義標記（<code>【XXX】</code>）、命名引用（<code>[ModuleName]</code>）</td>
      </tr>
      <tr>
          <td>欄位設計</td>
          <td>不同抽象層用不同角度寫註解，介面/實作/函式/inline 各司其職</td>
      </tr>
  </tbody>
</table>
<p>寫合格的註解是讓每個維護者（包括你自己三個月後）能在最短時間內理解業務意圖、避免破壞設計、安全地擴展功能。</p>
]]></content:encoded></item><item><title>Writing Documents — 文件撰寫指引</title><link>https://tarrragon.github.io/blog/skills/compositional-writing/writing-documents/</link><pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/skills/compositional-writing/writing-documents/</guid><description>&lt;blockquote>
&lt;p>Situation: You are about to compose any markdown document — worklog, README, spec, methodology, error-pattern record, or ticket — where both human cognitive load and downstream AI token consumption matter.&lt;/p>&lt;/blockquote>
&lt;h2 id="before-you-start-identify-document-type">Before You Start: Identify Document Type&lt;/h2>
&lt;p>Different document types have different readers, lifespans, and structural demands. Pick the type first; the rest of this reference applies the five compositional principles to each.&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Document type&lt;/th>
 &lt;th>Primary reader&lt;/th>
 &lt;th>Lifespan&lt;/th>
 &lt;th>Volatility&lt;/th>
 &lt;th>Core job&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Worklog&lt;/td>
 &lt;td>Future self / handoff receiver&lt;/td>
 &lt;td>Per version (archived)&lt;/td>
 &lt;td>High (appended daily)&lt;/td>
 &lt;td>Record decisions and milestones, not execution details&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>README&lt;/td>
 &lt;td>Newcomer / marketplace visitor&lt;/td>
 &lt;td>Permanent&lt;/td>
 &lt;td>Low (stable)&lt;/td>
 &lt;td>Orient readers in one screen, route to deeper docs&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Spec (requirement / use case)&lt;/td>
 &lt;td>Implementers, reviewers, QA&lt;/td>
 &lt;td>Permanent (versioned)&lt;/td>
 &lt;td>Medium (evolves with scope)&lt;/td>
 &lt;td>Define acceptable behaviour in testable terms&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Methodology&lt;/td>
 &lt;td>Framework users (cross-project)&lt;/td>
 &lt;td>Permanent&lt;/td>
 &lt;td>Low (distilled)&lt;/td>
 &lt;td>Give framework users and AI an explicit, directly-applicable judgment standard&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Error-pattern&lt;/td>
 &lt;td>Debuggers, reviewers&lt;/td>
 &lt;td>Permanent&lt;/td>
 &lt;td>Low (append-only)&lt;/td>
 &lt;td>Capture root cause + prevention so it doesn&amp;rsquo;t recur&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Ticket&lt;/td>
 &lt;td>Executor, dispatcher&lt;/td>
 &lt;td>Per task (archived)&lt;/td>
 &lt;td>Medium (mutated during execution)&lt;/td>
 &lt;td>Carry a single atomic intent from creation to completion&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Two rules follow from the table:&lt;/p>
&lt;ol>
&lt;li>High-volatility documents (worklog, ticket) must stay append-only; rewriting history breaks the record.&lt;/li>
&lt;li>Permanent documents (methodology, error-pattern, spec) must be distilled; every paragraph earns its keep.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="principle-1--atomization--documents-section-granularity-and-when-to-split">Principle 1 — Atomization × Documents: Section granularity and when to split&lt;/h2>
&lt;h3 id="core-question">Core question&lt;/h3>
&lt;p>How much content belongs in a single file, and when do you cut?&lt;/p></description><content:encoded><![CDATA[<blockquote>
<p>Situation: You are about to compose any markdown document — worklog, README, spec, methodology, error-pattern record, or ticket — where both human cognitive load and downstream AI token consumption matter.</p></blockquote>
<h2 id="before-you-start-identify-document-type">Before You Start: Identify Document Type</h2>
<p>Different document types have different readers, lifespans, and structural demands. Pick the type first; the rest of this reference applies the five compositional principles to each.</p>
<table>
  <thead>
      <tr>
          <th>Document type</th>
          <th>Primary reader</th>
          <th>Lifespan</th>
          <th>Volatility</th>
          <th>Core job</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Worklog</td>
          <td>Future self / handoff receiver</td>
          <td>Per version (archived)</td>
          <td>High (appended daily)</td>
          <td>Record decisions and milestones, not execution details</td>
      </tr>
      <tr>
          <td>README</td>
          <td>Newcomer / marketplace visitor</td>
          <td>Permanent</td>
          <td>Low (stable)</td>
          <td>Orient readers in one screen, route to deeper docs</td>
      </tr>
      <tr>
          <td>Spec (requirement / use case)</td>
          <td>Implementers, reviewers, QA</td>
          <td>Permanent (versioned)</td>
          <td>Medium (evolves with scope)</td>
          <td>Define acceptable behaviour in testable terms</td>
      </tr>
      <tr>
          <td>Methodology</td>
          <td>Framework users (cross-project)</td>
          <td>Permanent</td>
          <td>Low (distilled)</td>
          <td>Give framework users and AI an explicit, directly-applicable judgment standard</td>
      </tr>
      <tr>
          <td>Error-pattern</td>
          <td>Debuggers, reviewers</td>
          <td>Permanent</td>
          <td>Low (append-only)</td>
          <td>Capture root cause + prevention so it doesn&rsquo;t recur</td>
      </tr>
      <tr>
          <td>Ticket</td>
          <td>Executor, dispatcher</td>
          <td>Per task (archived)</td>
          <td>Medium (mutated during execution)</td>
          <td>Carry a single atomic intent from creation to completion</td>
      </tr>
  </tbody>
</table>
<p>Two rules follow from the table:</p>
<ol>
<li>High-volatility documents (worklog, ticket) must stay append-only; rewriting history breaks the record.</li>
<li>Permanent documents (methodology, error-pattern, spec) must be distilled; every paragraph earns its keep.</li>
</ol>
<hr>
<h2 id="principle-1--atomization--documents-section-granularity-and-when-to-split">Principle 1 — Atomization × Documents: Section granularity and when to split</h2>
<h3 id="core-question">Core question</h3>
<p>How much content belongs in a single file, and when do you cut?</p>
<h3 id="decision-table">Decision table</h3>
<table>
  <thead>
      <tr>
          <th>Condition</th>
          <th>Action</th>
          <th>Reason</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>One document covers one concept cleanly, body &lt; ~500 lines</td>
          <td>Keep single file</td>
          <td>Atomic at file level</td>
      </tr>
      <tr>
          <td>Body crosses ~500 lines but concept is still one</td>
          <td>Split into sub-sections, not separate files</td>
          <td>File is still atomic</td>
      </tr>
      <tr>
          <td>Body contains two independently retrievable concepts (reader consults only one at a time)</td>
          <td>Split into two files</td>
          <td>Violates atomicity</td>
      </tr>
      <tr>
          <td>Single file is consulted as five different situations (e.g. worklog + spec + methodology stacked)</td>
          <td>Split by situation</td>
          <td>Situation match beats line count</td>
      </tr>
      <tr>
          <td>Document is &lt; 100 lines and only referenced from one place</td>
          <td>Consider merging upward</td>
          <td>Under-atomic, creates navigation cost</td>
      </tr>
  </tbody>
</table>
<h3 id="split-heuristics-by-document-type">Split heuristics by document type</h3>
<ul>
<li><strong>Worklog</strong>: Stays single per version. Append chronologically. Do not split by Wave unless the file exceeds ~2000 lines (rare).</li>
<li><strong>README</strong>: Always single file per directory. Route outward via links; do not fork README for sub-topics.</li>
<li><strong>Spec</strong>: Split by use case (one UC per file). Do not bundle multiple UCs for &ldquo;efficiency&rdquo;.</li>
<li><strong>Methodology</strong>: One methodology per file. If a second concept appears, it is a second methodology.</li>
<li><strong>Error-pattern</strong>: One pattern per file. Multiple root causes → multiple files, cross-linked.</li>
<li><strong>Ticket</strong>: One ticket per file is the atomic contract. Splitting a ticket means creating child tickets, not subdividing the file.</li>
</ul>
<h3 id="anti-patterns">Anti-patterns</h3>
<table>
  <thead>
      <tr>
          <th>Anti-pattern</th>
          <th>What happens</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Stuffing three specs into one &ldquo;spec-v2.md&rdquo;</td>
          <td>Readers scan past unrelated sections; grep lands on wrong context</td>
      </tr>
      <tr>
          <td>Splitting a methodology into methodology-part-1/2/3</td>
          <td>Cross-references explode; readers lose the recall benefit</td>
      </tr>
      <tr>
          <td>Merging two error-patterns because &ldquo;they feel similar&rdquo;</td>
          <td>Prevention measures dilute each other; future query returns ambiguity</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="principle-2--indexing--documents-moc-directory-structure-cross-document-references">Principle 2 — Indexing × Documents: MOC, directory structure, cross-document references</h2>
<h3 id="core-question-1">Core question</h3>
<p>Given many atomic documents, how does a reader find the right one?</p>
<h3 id="three-indexing-mechanisms">Three indexing mechanisms</h3>
<ol>
<li><strong>Directory layout</strong> — the physical grouping implies a taxonomy. Keep depths shallow (≤ 3 levels); deeper trees hide documents.</li>
<li><strong>MOC (Map of Content)</strong> — a landing document that lists siblings with one-line summaries. Every directory with more than 5 documents earns an MOC (README.md or index.md).</li>
<li><strong>Inline cross-reference</strong> — when one document must point to another, use a stable relative path and describe <em>why</em> the reader should click, not just that they can.</li>
</ol>
<h3 id="cross-reference-format">Cross-reference format</h3>
<!-- example: Example column contains literal string samples wrapped in backticks (inline code). Paths like ./validation.md are placeholders, not real links. -->
<table>
  <thead>
      <tr>
          <th>Reference type</th>
          <th>Format</th>
          <th>Example</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Same-directory sibling</td>
          <td>Relative path + intent</td>
          <td><code>See [validation rules](./validation.md) for acceptable field values</code></td>
      </tr>
      <tr>
          <td>Cross-directory</td>
          <td>Full repo-relative path</td>
          <td><code>Detailed flow: rules/decision-tree.md</code></td>
      </tr>
      <tr>
          <td>External (stable)</td>
          <td>URL with context</td>
          <td><code>Anthropic skill spec: https://...</code></td>
      </tr>
      <tr>
          <td>External (volatile: ticket ID, commit hash, worklog path)</td>
          <td><strong>Allowed only in volatile documents</strong></td>
          <td>Never in spec / methodology / error-pattern content</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p>A reference without intent (&ldquo;see X.md&rdquo;) is a broken signpost. Always say what the reader gains by clicking.</p></blockquote>
<h3 id="reference-anchors-semantic-titles-not-positional-numbers">Reference anchors: semantic titles, not positional numbers</h3>
<p>引用另一個章節 / 階段 / 條列項時、錨點用語意標題、不用位置編號（「見核心問題」、不是「見 Stage 3」；「如『底線告知協議』所述」、不是「如第 4 點」）。編號是結構排列的 derivation — 插入或搬移一個單位、後續編號全部位移、引用句字面完好、語意卻 silent 指向錯的內容（misdirected 比 broken link 難偵測：連結斷掉會報錯、編號錯位會成功解析到錯的東西）。對應要求：每個結構單位的標題要承載核心意義（「Stage 3：核心問題」、編號只是排序前綴）、引用一律取語意半邊。例外是發布方凍結的編號（RFC 段號、法條）— 那是 fact、可引用。重排結構的 commit 要全 repo 掃編號式引用。完整判準與失效案例見 <a href="/blog/report/reference-by-semantic-title-not-number/" data-link-title="引用章節用語意標題、不用位置編號：編號是結構排列的 derivation、會隨版本漂移" data-link-desc="跨段落、跨檔引用結構單位（章節 / 階段 / 條列項）時、引用語意標題（副標題）、不引用位置編號（Stage 3、第 5 章、第 3 點）。編號是「目前結構排列」的 derivation、不是 fact；結構重排時編號全部位移、引用點不會報錯、而是 silent 指向錯的內容 — 比 broken link 更難偵測。標題的存在意義就是承載可被引用的語意。是 #44 SSoT 在結構引用維度的實例、#93 identifier-as-fact 家族的 sibling、#84 命名承載語意的引用面延伸。">reference-by-semantic-title-not-number</a>。</p>
<p>標題要能當穩定錨、名稱本身得先是純 fact：集合命名（問題清單 / 階段序列 / 原則組）只承載角色與層級、把成員數量留給清單呈現 —「核心七問」加一問就在每個複製過名稱的地方失真、「核心問題」承受任意成員增減。判準與邊界（外部凍結品牌 / 概念閾值可留數字）見 <a href="/blog/report/name-collections-by-role-not-count/" data-link-title="集合命名用角色、不內嵌數量：「核心七問」的七是成員數的 derivation、加一問就全面失真" data-link-desc="「核心七問」「成長六階段」「四大支柱」這類名稱把成員數量烤進名字裡 — 數量是集合當前成員的 derivation、不是集合的語意身分；成員增減時名稱失真、且名稱是被複製最多次的字串、缺陷隨每次引用繁殖。修法：命名只承載角色與層級（核心問題 / 次要問題 / 撞牆階段）、數量讓清單自己呈現。本卡是 #155 的命名端 sibling（#155 修引用端、本卡讓「語意標題是穩定錨」的前提真正成立）、#44 SSoT 在名稱內容的實例、#84 命名檢驗的數量維度。">name-collections-by-role-not-count</a>。</p>
<h3 id="indexing-by-document-type">Indexing by document type</h3>
<ul>
<li><strong>Worklog</strong>: The worklog itself is an index of tickets. Each ticket row points into a detail file.</li>
<li><strong>README</strong>: Is the MOC for its directory. Must list every sibling one-line.</li>
<li><strong>Spec</strong>: Indexed by use case ID. Use cases form a flat catalogue; requirements nest under them.</li>
<li><strong>Methodology</strong>: Indexed by <code>methodologies/README.md</code>. Methodologies do not cross-reference methodologies-of-methodologies; keep one hop deep.</li>
<li><strong>Error-pattern</strong>: Indexed by a stable ID prefix scheme (e.g. category abbreviation + running number). The ID itself is the index key.</li>
<li><strong>Ticket</strong>: Indexed by worklog + <code>ticket track list</code>. CLI is the primary index, not a markdown TOC.</li>
</ul>
<h3 id="anti-patterns-1">Anti-patterns</h3>
<table>
  <thead>
      <tr>
          <th>Anti-pattern</th>
          <th>What happens</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>README that says &ldquo;this folder contains various utilities&rdquo;</td>
          <td>Provides no routing; reader opens every file</td>
      </tr>
      <tr>
          <td>Spec referencing a ticket ID</td>
          <td>Spec stability breaks when ticket is archived</td>
      </tr>
      <tr>
          <td>Methodology A references methodology B which references A</td>
          <td>Circular chase; no real content at the end</td>
      </tr>
      <tr>
          <td>&ldquo;See Stage 3&rdquo; / &ldquo;as listed in item 2&rdquo; pointing into a living document</td>
          <td>Structure reorder shifts numbers; reference silently lands on wrong content</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="principle-3--explicit-intent--business-logic--documents-inverted-pyramid-spec-vs-process">Principle 3 — Explicit Intent &amp; Business Logic × Documents: Inverted pyramid, spec vs process</h2>
<h3 id="core-question-2">Core question</h3>
<p>How do you make the point land in the first paragraph — and how do you separate &ldquo;what the rules are&rdquo; from &ldquo;how we got here&rdquo;?</p>
<h3 id="the-inverted-pyramid">The inverted pyramid</h3>
<p>Put the conclusion first. A reader who stops after the opening paragraph should still leave with the main takeaway.</p>
<table>
  <thead>
      <tr>
          <th>Pyramid level</th>
          <th>Content</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Opening sentence</td>
          <td>One-line answer or rule</td>
      </tr>
      <tr>
          <td>First paragraph</td>
          <td>The concrete action or constraint</td>
      </tr>
      <tr>
          <td>Middle</td>
          <td>Context, reasoning, exceptions</td>
      </tr>
      <tr>
          <td>End</td>
          <td>Historical notes, references</td>
      </tr>
  </tbody>
</table>
<h3 id="spec-vs-process-record--a-mandatory-split">Spec vs process record — a mandatory split</h3>
<table>
  <thead>
      <tr>
          <th>Aspect</th>
          <th>Spec (stable)</th>
          <th>Process record (volatile)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Voice</td>
          <td>Imperative / declarative</td>
          <td>Narrative / chronological</td>
      </tr>
      <tr>
          <td>Tense</td>
          <td>Present (&ldquo;the system must&rdquo;)</td>
          <td>Past (&ldquo;we found that&rdquo;)</td>
      </tr>
      <tr>
          <td>Citations allowed</td>
          <td>Other specs, external standards</td>
          <td>Tickets, commits, worklog entries</td>
      </tr>
      <tr>
          <td>Ages well?</td>
          <td>Yes — designed to outlast implementation</td>
          <td>No — tied to a moment</td>
      </tr>
      <tr>
          <td>Safe to rewrite?</td>
          <td>Yes (versioned)</td>
          <td>No (append-only)</td>
      </tr>
  </tbody>
</table>
<p><strong>Rule</strong>: Never mix the two in one document. A spec paragraph written in past tense is a process note; move it to worklog. A worklog entry that begins &ldquo;the system must&rdquo; is a spec fragment; promote it.</p>
<h3 id="business-logic-not-syntax-translation">Business logic, not syntax translation</h3>
<p>Documents that touch business concepts must describe the <em>why</em>, not the <em>what of the syntax</em>.</p>
<table>
  <thead>
      <tr>
          <th>Description style</th>
          <th>Fits</th>
          <th>Fails</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>&ldquo;Readmoo extractor falls back to alternate selector when primary fails&rdquo;</td>
          <td>Business / design intent</td>
          <td>—</td>
      </tr>
      <tr>
          <td>&ldquo;A try-catch wraps the primary selector call&rdquo;</td>
          <td>—</td>
          <td>Syntax translation, reader could get this from the code</td>
      </tr>
  </tbody>
</table>
<p>Rule: if the sentence describes code mechanics a compiler already enforces, delete it and write the business reason instead.</p>
<h3 id="anti-patterns-2">Anti-patterns</h3>
<table>
  <thead>
      <tr>
          <th>Anti-pattern</th>
          <th>Fix</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Opening with &ldquo;This document describes&hellip;&rdquo; meta-talk</td>
          <td>Delete, start with the actual rule</td>
      </tr>
      <tr>
          <td>Spec paragraph citing a ticket ID (e.g. <code>v{X}-W{Y}-{seq}</code>)</td>
          <td>Move citation to worklog; keep spec ID-free</td>
      </tr>
      <tr>
          <td>Methodology paragraph preserving &ldquo;we used to do X but found Y&rdquo; narrative</td>
          <td>Keep the distilled rule; move the narrative to error-pattern or worklog</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="principle-4--searchability--documents-titles-frontmatter-grep-friendly-structure">Principle 4 — Searchability × Documents: Titles, frontmatter, grep-friendly structure</h2>
<h3 id="core-question-3">Core question</h3>
<p>When a human or AI greps for a concept, does the right document surface, and does the right section surface within it?</p>
<h3 id="title-conventions">Title conventions</h3>
<table>
  <thead>
      <tr>
          <th>Document type</th>
          <th>Title format</th>
          <th>grep target</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Worklog</td>
          <td><code>v{version} {theme} 工作日誌</code></td>
          <td><code>v{X.Y.Z}</code>, <code>工作日誌</code></td>
      </tr>
      <tr>
          <td>README</td>
          <td><code>{directory name}</code> or <code>{concept name}</code></td>
          <td>Directory keyword</td>
      </tr>
      <tr>
          <td>Spec</td>
          <td><code>{UC ID} {behaviour name}</code></td>
          <td>UC ID is the key</td>
      </tr>
      <tr>
          <td>Methodology</td>
          <td><code>{subject} 方法論</code></td>
          <td><code>方法論</code> + subject</td>
      </tr>
      <tr>
          <td>Error-pattern</td>
          <td><code>{ID}: {one-line symptom}</code></td>
          <td>Pattern ID + symptom keyword</td>
      </tr>
      <tr>
          <td>Ticket</td>
          <td><code>{ID} {verb + target}</code></td>
          <td>Ticket ID + verb</td>
      </tr>
  </tbody>
</table>
<h3 id="heading-conventions">Heading conventions</h3>
<ul>
<li>Every H2 heading contains a concept keyword that a reader would actually search for (&ldquo;Split heuristics&rdquo;, not &ldquo;More details&rdquo;).</li>
<li>Avoid generic headings: &ldquo;Overview&rdquo;, &ldquo;Introduction&rdquo;, &ldquo;Details&rdquo;, &ldquo;Notes&rdquo;. They produce grep hits on every document.</li>
<li>Prefer question-form or imperative headings: &ldquo;When to split&rdquo;, &ldquo;How to cite a sibling doc&rdquo;.</li>
</ul>
<h3 id="yaml-frontmatter">YAML frontmatter</h3>
<p>Frontmatter is the most grep-friendly slice of a document. Use it for:</p>
<table>
  <thead>
      <tr>
          <th>Field</th>
          <th>Purpose</th>
          <th>Document types</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>id</code></td>
          <td>Stable anchor</td>
          <td>Ticket, error-pattern, spec</td>
      </tr>
      <tr>
          <td><code>status</code></td>
          <td>Lifecycle state</td>
          <td>Ticket, worklog</td>
      </tr>
      <tr>
          <td><code>type</code></td>
          <td>Taxonomy</td>
          <td>Ticket (IMP / ANA / DOC), error-pattern (PC / IMP / ARCH)</td>
      </tr>
      <tr>
          <td><code>relatedTo</code></td>
          <td>Weak link to siblings</td>
          <td>Ticket, spec</td>
      </tr>
      <tr>
          <td><code>version</code></td>
          <td>Scoping</td>
          <td>Worklog, ticket, spec</td>
      </tr>
      <tr>
          <td><code>tags</code></td>
          <td>Cross-cutting search</td>
          <td>Methodology, error-pattern</td>
      </tr>
  </tbody>
</table>
<p>Frontmatter must be machine-parseable. Never include narrative text in values; keep values atomic (ID strings, statuses, dates).</p>
<h3 id="grep-friendly-body-conventions">Grep-friendly body conventions</h3>
<ul>
<li>Put the keyword in the same line as the assertion: &ldquo;Worklog must be append-only&rdquo; (not &ldquo;It must be append-only&rdquo; on its own line).</li>
<li>When listing rules, repeat the subject: every row of a rule table should contain the rule&rsquo;s noun, not rely on column headers alone.</li>
<li>Use separators (<code>→</code>, <code>:</code>, <code>|</code>) consistently so regex-based tooling can parse structure.</li>
</ul>
<h3 id="anti-patterns-3">Anti-patterns</h3>
<table>
  <thead>
      <tr>
          <th>Anti-pattern</th>
          <th>Fix</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Document with no <code>id</code> field searched by filename only</td>
          <td>Add frontmatter for stable ID</td>
      </tr>
      <tr>
          <td>H2 <code>## Details</code> appearing in 30 documents</td>
          <td>Rename to concept-specific heading</td>
      </tr>
      <tr>
          <td>Rules written as &ldquo;It does X; it does Y&rdquo; (pronoun-only)</td>
          <td>Repeat the subject in each row</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="principle-5--field-design--documents-structural-templates-by-type">Principle 5 — Field Design × Documents: Structural templates by type</h2>
<h3 id="core-question-4">Core question</h3>
<p>What sections must a document of type X contain, and how do those sections differ in angle?</p>
<p>Each field in a template exists to answer a specific question. Two fields answering the same question are a bug.</p>
<h3 id="worklog-template">Worklog template</h3>
<table>
  <thead>
      <tr>
          <th>Section</th>
          <th>Answers</th>
          <th>Angle</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Metadata</td>
          <td>Which version, dates, status?</td>
          <td>Identification</td>
      </tr>
      <tr>
          <td>版本目標</td>
          <td>What did this version set out to do?</td>
          <td>Intent</td>
      </tr>
      <tr>
          <td>進度追蹤</td>
          <td>What happened and when?</td>
          <td>Chronological record</td>
      </tr>
      <tr>
          <td>Phase tables</td>
          <td>Which tickets exist, what state?</td>
          <td>Snapshot</td>
      </tr>
      <tr>
          <td>技術筆記</td>
          <td>What non-ticket decisions were made?</td>
          <td>Lateral knowledge</td>
      </tr>
  </tbody>
</table>
<p>Append-only sections: 進度追蹤, 技術筆記. Mutable: Phase tables (statuses flip).</p>
<h3 id="readme-template">README template</h3>
<table>
  <thead>
      <tr>
          <th>Section</th>
          <th>Answers</th>
          <th>Angle</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Title + one-line purpose</td>
          <td>What is this directory / project?</td>
          <td>Orient</td>
      </tr>
      <tr>
          <td>Sibling index</td>
          <td>What&rsquo;s inside?</td>
          <td>Route</td>
      </tr>
      <tr>
          <td>Quick start (if applicable)</td>
          <td>How do I use this in 60 seconds?</td>
          <td>Action</td>
      </tr>
      <tr>
          <td>Further reading</td>
          <td>Where do I go next?</td>
          <td>Defer</td>
      </tr>
  </tbody>
</table>
<h3 id="spec-template">Spec template</h3>
<table>
  <thead>
      <tr>
          <th>Section</th>
          <th>Answers</th>
          <th>Angle</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>UC metadata</td>
          <td>Stable IDs, priority</td>
          <td>Identification</td>
      </tr>
      <tr>
          <td>Actors</td>
          <td>Who uses this?</td>
          <td>Scope</td>
      </tr>
      <tr>
          <td>Preconditions</td>
          <td>What must be true before?</td>
          <td>Entry guard</td>
      </tr>
      <tr>
          <td>Main flow</td>
          <td>What happens on success?</td>
          <td>Happy path</td>
      </tr>
      <tr>
          <td>Alternative / error flows</td>
          <td>What else can happen?</td>
          <td>Edge cases</td>
      </tr>
      <tr>
          <td>Acceptance criteria</td>
          <td>When is this UC done?</td>
          <td>Test hook</td>
      </tr>
  </tbody>
</table>
<p>Angles must not overlap: preconditions are entry guards, not flows; acceptance criteria are pass/fail, not behaviour descriptions.</p>
<h3 id="methodology-template-from-methodology-writing-core">Methodology template (from methodology-writing core)</h3>
<table>
  <thead>
      <tr>
          <th>Section</th>
          <th>Answers</th>
          <th>Angle</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>核心概念</td>
          <td>What is this methodology in one sentence?</td>
          <td>Recall trigger</td>
      </tr>
      <tr>
          <td>執行步驟</td>
          <td>What do I do, in order?</td>
          <td>Action list</td>
      </tr>
      <tr>
          <td>檢查清單</td>
          <td>How do I verify I did it right?</td>
          <td>Self-check</td>
      </tr>
      <tr>
          <td>Reference</td>
          <td>Where is the full implementation guide?</td>
          <td>Defer to SKILL</td>
      </tr>
  </tbody>
</table>
<p>Length discipline: keep only judgment criteria and core rules in the methodology; move operational flows, code examples, and error-handling to a SKILL. Length is whatever makes the criteria explicit and directly applicable — it is not bounded by reading time.</p>
<h3 id="error-pattern-template">Error-pattern template</h3>
<table>
  <thead>
      <tr>
          <th>Section</th>
          <th>Answers</th>
          <th>Angle</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Symptom</td>
          <td>What did the reader see?</td>
          <td>Recognition</td>
      </tr>
      <tr>
          <td>Root cause</td>
          <td>Why did it happen?</td>
          <td>Diagnosis</td>
      </tr>
      <tr>
          <td>Prevention</td>
          <td>How to stop it next time?</td>
          <td>Forward-looking action</td>
      </tr>
      <tr>
          <td>Detection</td>
          <td>How do we catch it early?</td>
          <td>Tooling / hook</td>
      </tr>
  </tbody>
</table>
<p>Each section answers a different question. Symptom is not cause; cause is not prevention.</p>
<h3 id="ticket-template">Ticket template</h3>
<p>Ticket fields are extensively defined elsewhere (designing-fields.md). Key angles here:</p>
<table>
  <thead>
      <tr>
          <th>Field cluster</th>
          <th>Angle</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>what</code></td>
          <td>Description of the action and target</td>
      </tr>
      <tr>
          <td><code>why</code></td>
          <td>Motivation (distinct from <code>what</code>)</td>
      </tr>
      <tr>
          <td><code>acceptance</code></td>
          <td>Pass/fail criteria (distinct from <code>what</code> and <code>why</code>)</td>
      </tr>
      <tr>
          <td><code>how</code></td>
          <td>Strategy (distinct from <code>what</code> — <code>what</code> is the outcome, <code>how</code> is the path)</td>
      </tr>
  </tbody>
</table>
<p>Overlap between <code>what</code> and <code>why</code> is the most common ticket bug. Keep them at different angles.</p>
<h3 id="anti-patterns-4">Anti-patterns</h3>
<table>
  <thead>
      <tr>
          <th>Anti-pattern</th>
          <th>Fix</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>README lists &ldquo;features&rdquo; and &ldquo;what it does&rdquo; as two sections</td>
          <td>Collapse — same angle</td>
      </tr>
      <tr>
          <td>Spec has &ldquo;preconditions&rdquo; and &ldquo;setup requirements&rdquo; as two sections</td>
          <td>Collapse — same angle</td>
      </tr>
      <tr>
          <td>Ticket <code>what</code> describes motivation</td>
          <td>Move motivation to <code>why</code>, keep <code>what</code> for action</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="worklog-specific-extensions-distilled-from-worklog-writing-methodology">Worklog-Specific Extensions (distilled from worklog-writing methodology)</h2>
<h3 id="tool-compatibility">Tool compatibility</h3>
<p>Markdown table cells in worklogs must not contain multi-byte status emoji (<code>⏳</code>, <code>[SYNC]</code>, <code>[FAIL]</code>, etc.). CLI parsers have hit Rust panics on char-boundary issues. Use plain text:</p>
<table>
  <thead>
      <tr>
          <th>Status</th>
          <th>Plain text</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Waiting</td>
          <td>待處理</td>
      </tr>
      <tr>
          <td>In progress</td>
          <td>進行中</td>
      </tr>
      <tr>
          <td>Done</td>
          <td>已完成</td>
      </tr>
      <tr>
          <td>Cancelled</td>
          <td>取消</td>
      </tr>
      <tr>
          <td>Skipped</td>
          <td>跳過</td>
      </tr>
      <tr>
          <td>Blocked</td>
          <td>阻塞</td>
      </tr>
      <tr>
          <td>Failed</td>
          <td>失敗</td>
      </tr>
  </tbody>
</table>
<p>Emoji is allowed outside table cells (in prose headings).</p>
<h3 id="five-events-that-must-be-logged">Five events that must be logged</h3>
<p>Worklog records <em>decisions and milestones</em>, not execution detail (detail lives in tickets).</p>
<table>
  <thead>
      <tr>
          <th>Event</th>
          <th>Trigger</th>
          <th>Format</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Ticket completed</td>
          <td><code>ticket track complete</code></td>
          <td><code>{date}: {id} 完成 — {summary}</code></td>
      </tr>
      <tr>
          <td>Task split</td>
          <td>Child tickets created</td>
          <td><code>{date}: {parent} 拆分 — {child1}, {child2}</code></td>
      </tr>
      <tr>
          <td>Unplanned finding</td>
          <td>New ticket created mid-execution</td>
          <td><code>{date}: 新增 {id} — {reason}</code></td>
      </tr>
      <tr>
          <td>UC progression</td>
          <td>Group of related tickets done</td>
          <td><code>{date}: UC-XX 步驟 Y 完成 — {outcome}</code></td>
      </tr>
      <tr>
          <td>Blocker / risk</td>
          <td>Block or design issue found</td>
          <td><code>{date}: {id} 阻塞 — {cause}</code></td>
      </tr>
  </tbody>
</table>
<p>Prefer bullet list over table: easier to append, diff-friendly, still readable past 20 entries.</p>
<h3 id="narrative-summary-as-legal-alternative">Narrative summary as legal alternative</h3>
<p>When a session closes many tickets in a sprint, per-ticket bullets become impractical. A narrative summary covering the ticket ID range + key outcomes is acceptable:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl"><span class="gu">### {date}: {theme} 衝刺
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="gu"></span><span class="k">-</span> {ticket-range} 可觀測性修復：全域錯誤處理、靜默失敗路徑消除
</span></span><span class="line"><span class="ln">3</span><span class="cl">- {ticket-range} 審查結論全部修復：AppLogger 遷移、ErrorHandler 防護</span></span></code></pre></div><p>Priority order: per-ticket bullets &gt; narrative summary &gt; no record. Sprint-style summary is the fallback, not the default.</p>
<hr>
<h2 id="methodology-specific-extensions-distilled-from-methodology-writing">Methodology-Specific Extensions (distilled from methodology-writing)</h2>
<h3 id="reader-is-an-expert">Reader is an expert</h3>
<p>Readers already know the content; they just forgot a detail. Your job is to help them recall, not to teach.</p>
<p>Forbidden phrasings:</p>
<ul>
<li>&ldquo;You should&hellip;&rdquo; (condescending)</li>
<li>&ldquo;Remember that&hellip;&rdquo; (teaching)</li>
<li>&ldquo;The lesson here is&hellip;&rdquo; (sermonising)</li>
</ul>
<p>Replace with description of what was done and what was observed.</p>
<h3 id="length-discipline-criteria-stay-flows-leave">Length discipline: criteria stay, flows leave</h3>
<p>A methodology carries the framework&rsquo;s judgment criteria and core rules, written explicitly enough for a reader — including an AI applying them during development — to use directly. Operational detail, not the criteria themselves, belongs in a SKILL or reference.</p>
<p>If rewriting an old verbose methodology, the test is:</p>
<table>
  <thead>
      <tr>
          <th>Check</th>
          <th>If fail</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Does the file contain a complete operational workflow?</td>
          <td>Move it to a SKILL</td>
      </tr>
      <tr>
          <td>Does it contain runnable code examples or error-handling detail?</td>
          <td>Move to a SKILL</td>
      </tr>
      <tr>
          <td>Are the judgment criteria compressed into hint-like bullets a reader cannot apply directly?</td>
          <td>Restore them explicitly in the methodology</td>
      </tr>
  </tbody>
</table>
<p>The methodology keeps its judgment criteria explicit and applicable; the SKILL holds the full walk-through. Never compress the criteria themselves to save length.</p>
<h3 id="experience-sharing-variant-six-guidelines">Experience-sharing variant (six guidelines)</h3>
<p>When the document is an experience-sharing write-up (not a methodology), six additional rules apply:</p>
<ol>
<li>Share experience, do not teach. No &ldquo;you should&rdquo; / &ldquo;remember to&rdquo;.</li>
<li>State facts, do not dramatise. Avoid &ldquo;totally blew up&rdquo;, &ldquo;I was lazy&rdquo;, etc.</li>
<li>Use functional description, not function names, in prose.</li>
<li>Not every problem is your own fault — don&rsquo;t self-blame for library bugs.</li>
<li>Every case needs discovery → diagnosis → fix, not just &ldquo;problem was X, fixed as Y&rdquo;.</li>
<li>Avoid specific product/SDK names in prose; describe the structural problem.</li>
</ol>
<hr>
<h2 id="self-validation-checklist-run-before-committing-the-document">Self-Validation Checklist (run before committing the document)</h2>
<ul>
<li><input disabled="" type="checkbox"> Document type identified, and structure matches the type&rsquo;s template</li>
<li><input disabled="" type="checkbox"> Opening paragraph states the conclusion / rule (inverted pyramid)</li>
<li><input disabled="" type="checkbox"> Spec content contains no process narrative; process content is not dressed as spec</li>
<li><input disabled="" type="checkbox"> No section duplicates another section&rsquo;s angle (no double-answered questions)</li>
<li><input disabled="" type="checkbox"> Cross-references state <em>why</em> to click, not just <em>where</em> to click</li>
<li><input disabled="" type="checkbox"> No reference to a ticket ID / commit hash / worklog path inside a stable document (spec / methodology / error-pattern)</li>
<li><input disabled="" type="checkbox"> Table cells in worklogs contain plain-text status, not emoji</li>
<li><input disabled="" type="checkbox"> File length is either atomic (&lt; ~500 lines) or the body holds a single concept despite length</li>
<li><input disabled="" type="checkbox"> Headings contain searchable concept keywords (no generic &ldquo;Overview&rdquo; / &ldquo;Details&rdquo;)</li>
<li><input disabled="" type="checkbox"> Frontmatter fields, if present, are atomic and machine-parseable</li>
</ul>
<hr>
<h2 id="multi-pass-re-readrefinement-protocol">Multi-pass Re-read（refinement protocol）</h2>
<p>The checklist above is a single-frame final sweep — not multi-pass. Multi-pass requires each round to use a <strong>different frame</strong> to catch errors at different layers (<a href="/blog/report/literal-interception-vs-behavioral-refinement/" data-link-title="字面攔截 vs 行為精煉：驗證手段跟錯誤層次的對齊" data-link-desc="驗證手段必須跟錯誤層次對齊：字面錯誤（typo / syntax / 缺欄位）用 hook / lint / CI 攔截；行為錯誤（思考偏差 / 判斷錯位 / collapse 反模式）用 multi-pass spiral 收斂。強行用 hook 蓋行為錯誤 = 給出 false confidence、反而比沒保護危險。本卡是 #72 結構性對策在「驗證粒度」維度的 ceiling — 不是所有錯誤都該被攔截。">literal-interception-vs-behavioral-refinement</a> / <a href="/blog/report/writing-multi-pass-review/" data-link-title="Writing 的 multi-pass review：N 輪 review、每輪換 frame" data-link-desc="寫文章 / 註解 / 文件 / prompt 的「寫」不是單次動作 — 是 N 輪 review。第 1 輪生成、第 2 輪對意圖（#67）、第 3 輪檢查機會成本語氣、第 4 輪 grep-ability、第 5 輪反例 / 邊界。每輪不同 frame、單輪寫不出全部維度。本卡是 #82 在「寫」這個 output 動作的具體實例。">writing-multi-pass-review</a>).</p>
<p>For documents (worklog / spec / methodology / error-pattern):</p>
<table>
  <thead>
      <tr>
          <th>Round</th>
          <th>Frame</th>
          <th>Document-specific checklist</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1</td>
          <td>Generation</td>
          <td>Get content end-to-end; expect rough phrasing</td>
      </tr>
      <tr>
          <td>2</td>
          <td>Intent (<a href="/blog/report/ease-of-writing-vs-intent-alignment/" data-link-title="寫作便利度跟意圖對齊反相關" data-link-desc="寫程式時最容易寫出的版本、通常是離意圖最遠的版本。便利度建立在「現有上下文 / 已 materialize 資料 / 已存在 API」上、而意圖對齊需要找到正確的層、處理上游、跨抽象層 — 兩者方向相反。識別這個反相關 = 識別自己掉進「容易寫的陷阱」。">ease-of-writing-vs-intent-alignment</a>)</td>
          <td>Does the document type match the structure used? Spec / process / methodology not mixed?</td>
      </tr>
      <tr>
          <td>3</td>
          <td>Opportunity-cost tone</td>
          <td>Grep &ldquo;must / should / always / never&rdquo; — translate absolutes to &ldquo;A in scenario X / B in Y&rdquo;</td>
      </tr>
      <tr>
          <td>4</td>
          <td>Grep-ability / naming</td>
          <td>Headings contain concept keywords (not &ldquo;Overview&rdquo;); cross-references explain <em>why</em> to click</td>
      </tr>
      <tr>
          <td>5</td>
          <td>Counter-cases / boundaries</td>
          <td>&ldquo;When not to apply&rdquo; section present? Examples cover edge cases not just happy path?</td>
      </tr>
      <tr>
          <td>6'</td>
          <td>Stability layer</td>
          <td>If this is a stable document (spec/methodology), are ticket IDs / commit hashes scrubbed?</td>
      </tr>
      <tr>
          <td>7'</td>
          <td>Atomic check</td>
          <td>&lt; 500 lines OR single concept despite length? Sections each answer one question?</td>
      </tr>
  </tbody>
</table>
<p>Skip rules: quick worklog notes can skip rounds 4-7&rsquo;; stable specs / methodology should run all rounds twice.</p>
<hr>
<h2 id="quick-routing-by-scenario">Quick Routing by Scenario</h2>
<table>
  <thead>
      <tr>
          <th>You are about to&hellip;</th>
          <th>Jump to</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Write or append a worklog entry</td>
          <td>Principle 1 + Worklog extensions</td>
      </tr>
      <tr>
          <td>Start a README from scratch</td>
          <td>Principle 2 (indexing) + Principle 5 (README template)</td>
      </tr>
      <tr>
          <td>Draft a use-case spec</td>
          <td>Principle 3 (spec vs process) + Principle 5 (spec template)</td>
      </tr>
      <tr>
          <td>Rewrite a bloated methodology</td>
          <td>Methodology extensions (length discipline) + Principle 1 (atomize)</td>
      </tr>
      <tr>
          <td>Record a new error-pattern</td>
          <td>Principle 5 (error-pattern template) + Principle 4 (ID as grep anchor)</td>
      </tr>
      <tr>
          <td>Fill a ticket&rsquo;s fields</td>
          <td>Principle 5 (ticket template), then consult designing-fields.md</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>Writing Logs — log 與結構化輸出撰寫指引</title><link>https://tarrragon.github.io/blog/skills/compositional-writing/writing-logs/</link><pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/skills/compositional-writing/writing-logs/</guid><description>&lt;p>本文件為「撰寫 log 輸出」情境的完整寫作指引。Log 的讀者是未來的除錯者（人或 AI），寫作目標是讓讀者在最短時間內理解&lt;strong>發生了什麼、在哪裡、影響什麼&lt;/strong>。&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>自包含聲明&lt;/strong>：本文件不依賴其他 reference。讀完本文件即可獨立寫出合格 log。&lt;/p>&lt;/blockquote>
&lt;hr>
&lt;h2 id="tldr--五條核心規則">TL;DR — 五條核心規則&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>規則&lt;/th>
 &lt;th>說明&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>一條 log 一個事件&lt;/td>
 &lt;td>不合併多事件；迴圈用摘要&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>結構化優先&lt;/td>
 &lt;td>Key-Value 或 JSON；禁止純字串拼接&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>描述業務事件，不描述程式碼位置&lt;/td>
 &lt;td>&lt;code>event=order.created&lt;/code> 而非 &lt;code>Entering function processOrder()&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Severity 標準：誰該被叫醒&lt;/td>
 &lt;td>error=立刻處理；warn=定期檢視；info=查詢用；debug=開發用&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>跨元件必有 correlation ID&lt;/td>
 &lt;td>2+ 元件流程必帶 &lt;code>request_id&lt;/code> / &lt;code>trace_id&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="1-原子化--log--一條-log-一個事件">1. 原子化 × Log — 一條 log 一個事件&lt;/h2>
&lt;h3 id="原則">原則&lt;/h3>
&lt;p>一條 log 記錄&lt;strong>一個可識別的事件&lt;/strong>。不要把多個事件合併成一條；也不要把一個事件拆成多條無法關聯的 log。&lt;/p>
&lt;h3 id="判斷標準">判斷標準&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>條件&lt;/th>
 &lt;th>是否該寫成一條 log&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>這是一個有開始和結束的行動（如「載入檔案」）？&lt;/td>
 &lt;td>是，一條&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>這個行動橫跨多個階段（如「下載 → 驗證 → 儲存」）？&lt;/td>
 &lt;td>每階段一條，用 correlation ID 串接&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>這是迴圈中的重複事件（如「處理第 N 筆」）？&lt;/td>
 &lt;td>摘要一條（「處理 1000 筆完成」），不是每筆一條&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>這是異常發生的瞬間？&lt;/td>
 &lt;td>一條（含完整上下文）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="正確範例">正確範例&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">正確：每個事件一條 log，可獨立理解
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">[INFO] request_id=abc123 user_id=42 event=order.created amount=NTD 1500
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">[INFO] request_id=abc123 event=payment.authorized gateway=stripe
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">[INFO] request_id=abc123 event=order.confirmed duration_ms=342&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="反例">反例&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">錯誤：三個事件混在一條，無法單獨分析
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">[INFO] Order abc123 created for user 42, paid via stripe, confirmed in 342ms&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>問題：&lt;/p>
&lt;ul>
&lt;li>監控系統難以從這條 log 提取「付款成功率」&lt;/li>
&lt;li>若只有付款失敗，這條 log 會變成「半成品」或「根本不輸出」&lt;/li>
&lt;li>無法用 grep 找到「所有 payment.authorized 事件」&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="2-索引--log--結構化-log-設計">2. 索引 × Log — 結構化 log 設計&lt;/h2>
&lt;h3 id="原則-1">原則&lt;/h3>
&lt;p>Log 必須能被&lt;strong>機器聚合&lt;/strong>和&lt;strong>人類搜尋&lt;/strong>。結構化 log（key-value 或 JSON）同時滿足兩者；純文字只滿足人類，且在規模擴大後難以維護。&lt;/p>
&lt;h3 id="兩種結構化格式">兩種結構化格式&lt;/h3>
&lt;h4 id="格式-akey-value人類友善機器可解析">格式 A：Key-Value（人類友善，機器可解析）&lt;/h4>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">[INFO] 2026-04-16T12:00:00Z level=info component=checkout event=order.created request_id=abc123 user_id=42 amount=1500 currency=NTD&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>適用場景&lt;/strong>：CLI 工具、開發環境、日誌檔案。&lt;/p>
&lt;p>&lt;strong>寫作要求&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>時間戳固定放最前面（ISO 8601 格式）&lt;/li>
&lt;li>&lt;code>level&lt;/code> &lt;code>component&lt;/code> &lt;code>event&lt;/code> 固定三欄位（後述）&lt;/li>
&lt;li>其餘欄位按「通用 → 業務」順序排列&lt;/li>
&lt;li>欄位名稱全小寫，使用下底線（&lt;code>user_id&lt;/code> 非 &lt;code>userId&lt;/code>）&lt;/li>
&lt;/ul>
&lt;h4 id="格式-bjson機器友善適合日誌平台">格式 B：JSON（機器友善，適合日誌平台）&lt;/h4>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="p">{&lt;/span>&lt;span class="nt">&amp;#34;timestamp&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="s2">&amp;#34;2026-04-16T12:00:00Z&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="nt">&amp;#34;level&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="s2">&amp;#34;info&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="nt">&amp;#34;component&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="s2">&amp;#34;checkout&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="nt">&amp;#34;event&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="s2">&amp;#34;order.created&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="nt">&amp;#34;request_id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="s2">&amp;#34;abc123&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="nt">&amp;#34;user_id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="mi">42&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="nt">&amp;#34;amount&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="mi">1500&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="nt">&amp;#34;currency&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="s2">&amp;#34;NTD&amp;#34;&lt;/span>&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>適用場景&lt;/strong>：生產環境、日誌平台（ELK/Loki/CloudWatch）、需要聚合分析。&lt;/p>
&lt;p>&lt;strong>寫作要求&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>單行 JSON（不要換行，否則無法每行一事件聚合）&lt;/li>
&lt;li>欄位順序不重要（機器會解析），但建議時間戳放第一個便於肉眼掃描&lt;/li>
&lt;li>數值型欄位不加引號（&lt;code>&amp;quot;amount&amp;quot;:1500&lt;/code> 非 &lt;code>&amp;quot;amount&amp;quot;:&amp;quot;1500&amp;quot;&lt;/code>）&lt;/li>
&lt;/ul>
&lt;h3 id="correlation-id跨元件追蹤">Correlation ID（跨元件追蹤）&lt;/h3>
&lt;p>&lt;strong>強制要求&lt;/strong>：任何跨越 2+ 元件或 2+ 行動的流程，必須有 correlation ID。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>場景&lt;/th>
 &lt;th>Correlation ID 類型&lt;/th>
 &lt;th>範例欄位名&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>HTTP 請求流程&lt;/td>
 &lt;td>請求 ID&lt;/td>
 &lt;td>&lt;code>request_id&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>使用者 session&lt;/td>
 &lt;td>Session ID&lt;/td>
 &lt;td>&lt;code>session_id&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>批次任務&lt;/td>
 &lt;td>Job ID&lt;/td>
 &lt;td>&lt;code>job_id&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>跨服務 RPC&lt;/td>
 &lt;td>Trace ID&lt;/td>
 &lt;td>&lt;code>trace_id&lt;/code>（配合 &lt;code>span_id&lt;/code>）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>正確範例&lt;/strong>：&lt;/p></description><content:encoded><![CDATA[<p>本文件為「撰寫 log 輸出」情境的完整寫作指引。Log 的讀者是未來的除錯者（人或 AI），寫作目標是讓讀者在最短時間內理解<strong>發生了什麼、在哪裡、影響什麼</strong>。</p>
<blockquote>
<p><strong>自包含聲明</strong>：本文件不依賴其他 reference。讀完本文件即可獨立寫出合格 log。</p></blockquote>
<hr>
<h2 id="tldr--五條核心規則">TL;DR — 五條核心規則</h2>
<table>
  <thead>
      <tr>
          <th>規則</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>一條 log 一個事件</td>
          <td>不合併多事件；迴圈用摘要</td>
      </tr>
      <tr>
          <td>結構化優先</td>
          <td>Key-Value 或 JSON；禁止純字串拼接</td>
      </tr>
      <tr>
          <td>描述業務事件，不描述程式碼位置</td>
          <td><code>event=order.created</code> 而非 <code>Entering function processOrder()</code></td>
      </tr>
      <tr>
          <td>Severity 標準：誰該被叫醒</td>
          <td>error=立刻處理；warn=定期檢視；info=查詢用；debug=開發用</td>
      </tr>
      <tr>
          <td>跨元件必有 correlation ID</td>
          <td>2+ 元件流程必帶 <code>request_id</code> / <code>trace_id</code></td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="1-原子化--log--一條-log-一個事件">1. 原子化 × Log — 一條 log 一個事件</h2>
<h3 id="原則">原則</h3>
<p>一條 log 記錄<strong>一個可識別的事件</strong>。不要把多個事件合併成一條；也不要把一個事件拆成多條無法關聯的 log。</p>
<h3 id="判斷標準">判斷標準</h3>
<table>
  <thead>
      <tr>
          <th>條件</th>
          <th>是否該寫成一條 log</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>這是一個有開始和結束的行動（如「載入檔案」）？</td>
          <td>是，一條</td>
      </tr>
      <tr>
          <td>這個行動橫跨多個階段（如「下載 → 驗證 → 儲存」）？</td>
          <td>每階段一條，用 correlation ID 串接</td>
      </tr>
      <tr>
          <td>這是迴圈中的重複事件（如「處理第 N 筆」）？</td>
          <td>摘要一條（「處理 1000 筆完成」），不是每筆一條</td>
      </tr>
      <tr>
          <td>這是異常發生的瞬間？</td>
          <td>一條（含完整上下文）</td>
      </tr>
  </tbody>
</table>
<h3 id="正確範例">正確範例</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">正確：每個事件一條 log，可獨立理解
</span></span><span class="line"><span class="ln">2</span><span class="cl">[INFO] request_id=abc123 user_id=42 event=order.created amount=NTD 1500
</span></span><span class="line"><span class="ln">3</span><span class="cl">[INFO] request_id=abc123 event=payment.authorized gateway=stripe
</span></span><span class="line"><span class="ln">4</span><span class="cl">[INFO] request_id=abc123 event=order.confirmed duration_ms=342</span></span></code></pre></div><h3 id="反例">反例</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">錯誤：三個事件混在一條，無法單獨分析
</span></span><span class="line"><span class="ln">2</span><span class="cl">[INFO] Order abc123 created for user 42, paid via stripe, confirmed in 342ms</span></span></code></pre></div><p>問題：</p>
<ul>
<li>監控系統難以從這條 log 提取「付款成功率」</li>
<li>若只有付款失敗，這條 log 會變成「半成品」或「根本不輸出」</li>
<li>無法用 grep 找到「所有 payment.authorized 事件」</li>
</ul>
<hr>
<h2 id="2-索引--log--結構化-log-設計">2. 索引 × Log — 結構化 log 設計</h2>
<h3 id="原則-1">原則</h3>
<p>Log 必須能被<strong>機器聚合</strong>和<strong>人類搜尋</strong>。結構化 log（key-value 或 JSON）同時滿足兩者；純文字只滿足人類，且在規模擴大後難以維護。</p>
<h3 id="兩種結構化格式">兩種結構化格式</h3>
<h4 id="格式-akey-value人類友善機器可解析">格式 A：Key-Value（人類友善，機器可解析）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">[INFO] 2026-04-16T12:00:00Z level=info component=checkout event=order.created request_id=abc123 user_id=42 amount=1500 currency=NTD</span></span></code></pre></div><p><strong>適用場景</strong>：CLI 工具、開發環境、日誌檔案。</p>
<p><strong>寫作要求</strong>：</p>
<ul>
<li>時間戳固定放最前面（ISO 8601 格式）</li>
<li><code>level</code> <code>component</code> <code>event</code> 固定三欄位（後述）</li>
<li>其餘欄位按「通用 → 業務」順序排列</li>
<li>欄位名稱全小寫，使用下底線（<code>user_id</code> 非 <code>userId</code>）</li>
</ul>
<h4 id="格式-bjson機器友善適合日誌平台">格式 B：JSON（機器友善，適合日誌平台）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="ln">1</span><span class="cl"><span class="p">{</span><span class="nt">&#34;timestamp&#34;</span><span class="p">:</span><span class="s2">&#34;2026-04-16T12:00:00Z&#34;</span><span class="p">,</span><span class="nt">&#34;level&#34;</span><span class="p">:</span><span class="s2">&#34;info&#34;</span><span class="p">,</span><span class="nt">&#34;component&#34;</span><span class="p">:</span><span class="s2">&#34;checkout&#34;</span><span class="p">,</span><span class="nt">&#34;event&#34;</span><span class="p">:</span><span class="s2">&#34;order.created&#34;</span><span class="p">,</span><span class="nt">&#34;request_id&#34;</span><span class="p">:</span><span class="s2">&#34;abc123&#34;</span><span class="p">,</span><span class="nt">&#34;user_id&#34;</span><span class="p">:</span><span class="mi">42</span><span class="p">,</span><span class="nt">&#34;amount&#34;</span><span class="p">:</span><span class="mi">1500</span><span class="p">,</span><span class="nt">&#34;currency&#34;</span><span class="p">:</span><span class="s2">&#34;NTD&#34;</span><span class="p">}</span></span></span></code></pre></div><p><strong>適用場景</strong>：生產環境、日誌平台（ELK/Loki/CloudWatch）、需要聚合分析。</p>
<p><strong>寫作要求</strong>：</p>
<ul>
<li>單行 JSON（不要換行，否則無法每行一事件聚合）</li>
<li>欄位順序不重要（機器會解析），但建議時間戳放第一個便於肉眼掃描</li>
<li>數值型欄位不加引號（<code>&quot;amount&quot;:1500</code> 非 <code>&quot;amount&quot;:&quot;1500&quot;</code>）</li>
</ul>
<h3 id="correlation-id跨元件追蹤">Correlation ID（跨元件追蹤）</h3>
<p><strong>強制要求</strong>：任何跨越 2+ 元件或 2+ 行動的流程，必須有 correlation ID。</p>
<table>
  <thead>
      <tr>
          <th>場景</th>
          <th>Correlation ID 類型</th>
          <th>範例欄位名</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>HTTP 請求流程</td>
          <td>請求 ID</td>
          <td><code>request_id</code></td>
      </tr>
      <tr>
          <td>使用者 session</td>
          <td>Session ID</td>
          <td><code>session_id</code></td>
      </tr>
      <tr>
          <td>批次任務</td>
          <td>Job ID</td>
          <td><code>job_id</code></td>
      </tr>
      <tr>
          <td>跨服務 RPC</td>
          <td>Trace ID</td>
          <td><code>trace_id</code>（配合 <code>span_id</code>）</td>
      </tr>
  </tbody>
</table>
<p><strong>正確範例</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">[INFO] request_id=abc123 component=api event=request.received path=/orders
</span></span><span class="line"><span class="ln">2</span><span class="cl">[DEBUG] request_id=abc123 component=db event=query.start query=select_orders
</span></span><span class="line"><span class="ln">3</span><span class="cl">[DEBUG] request_id=abc123 component=db event=query.end duration_ms=45 rows=3
</span></span><span class="line"><span class="ln">4</span><span class="cl">[INFO] request_id=abc123 component=api event=response.sent status=200 duration_ms=89</span></span></code></pre></div><p>單一 correlation ID <code>abc123</code> 串起整個請求生命週期。</p>
<hr>
<h2 id="3-意圖顯性--log--描述業務事件而非技術動作">3. 意圖顯性 × Log — 描述業務事件而非技術動作</h2>
<h3 id="原則-2">原則</h3>
<p>Log 訊息描述<strong>發生了什麼業務事件</strong>，而不是<strong>程式碼執行到哪一行</strong>。讀者想知道系統的狀態，不是程式的控制流。</p>
<h3 id="對照表">對照表</h3>
<table>
  <thead>
      <tr>
          <th>技術動作（差）</th>
          <th>業務事件（好）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>Entering function processOrder()</code></td>
          <td><code>event=order.processing_started order_id=123</code></td>
      </tr>
      <tr>
          <td><code>if branch taken</code></td>
          <td><code>event=order.payment_method_selected method=credit_card</code></td>
      </tr>
      <tr>
          <td><code>Loop iteration 5/10</code></td>
          <td><code>event=batch.progress processed=5 total=10 job_id=xyz</code></td>
      </tr>
      <tr>
          <td><code>Exception caught</code></td>
          <td><code>event=order.validation_failed reason=invalid_shipping_address order_id=123</code></td>
      </tr>
      <tr>
          <td><code>Returning null</code></td>
          <td><code>event=user.lookup_miss user_id=42 reason=not_found</code></td>
      </tr>
  </tbody>
</table>
<h3 id="錯誤-log-必含上下文">錯誤 log 必含上下文</h3>
<p>錯誤 log 的目的是「提供診斷所需的所有資訊」、不是「告訴讀者出錯了」 — 因為「出錯了」這件事系統其他訊號（HTTP 5xx、alert、使用者抱怨）已經傳達、log 此時的角色是讓除錯者重現問題、所以判準對齊到「重現所需的最小資訊集」。光寫「Failed to process order」沒有 order_id / user_id / 錯誤類型、除錯者要從頭追、log 等於白寫。</p>
<p><strong>必填欄位</strong>（錯誤 log）：</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>範例</th>
          <th>為什麼必要</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>error_type</code></td>
          <td><code>validation_error</code></td>
          <td>分類錯誤，便於聚合統計</td>
      </tr>
      <tr>
          <td><code>error_message</code></td>
          <td><code>shipping_address_invalid</code></td>
          <td>人類可讀的原因</td>
      </tr>
      <tr>
          <td><code>component</code></td>
          <td><code>order-service</code></td>
          <td>定位出錯元件</td>
      </tr>
      <tr>
          <td>業務識別</td>
          <td><code>order_id=123 user_id=42</code></td>
          <td>定位受影響的資料/使用者</td>
      </tr>
      <tr>
          <td>Correlation ID</td>
          <td><code>request_id=abc123</code></td>
          <td>串接事件鏈</td>
      </tr>
      <tr>
          <td>錯誤瞬間的狀態</td>
          <td><code>order_status=pending amount=1500</code></td>
          <td>重現問題時的關鍵資訊</td>
      </tr>
  </tbody>
</table>
<p><strong>可選欄位</strong>：<code>stack_trace</code>（長，建議另存檔）、<code>retry_count</code>、<code>upstream_error</code>。</p>
<h3 id="正確範例-1">正確範例</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">錯誤的錯誤 log：
</span></span><span class="line"><span class="ln">2</span><span class="cl">[ERROR] Failed to process order
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl">正確的錯誤 log：
</span></span><span class="line"><span class="ln">5</span><span class="cl">[ERROR] component=order-service event=order.processing_failed request_id=abc123 order_id=123 user_id=42 error_type=payment_declined error_message=insufficient_funds gateway=stripe order_status=pending amount=1500 retry_count=2</span></span></code></pre></div><p>第二條 log 讓讀者不需要重現問題就能理解：</p>
<ul>
<li>哪個元件出錯（<code>order-service</code>）</li>
<li>哪筆訂單、哪個使用者受影響（<code>order_id=123 user_id=42</code>）</li>
<li>錯誤類型和原因（<code>payment_declined / insufficient_funds</code>）</li>
<li>事件背景（<code>gateway=stripe amount=1500</code>）</li>
<li>已重試幾次（<code>retry_count=2</code>）</li>
</ul>
<hr>
<h2 id="4-可查詢性--log--關鍵字一致性與-severity-分級">4. 可查詢性 × Log — 關鍵字一致性與 Severity 分級</h2>
<h3 id="41-事件名稱的關鍵字一致性">4.1 事件名稱的關鍵字一致性</h3>
<p><strong>強制要求</strong>：<code>event</code> 欄位使用固定命名慣例，讓 grep/聚合工具能精確匹配。</p>
<p><strong>推薦慣例</strong>：<code>&lt;domain&gt;.&lt;action&gt;[_&lt;result&gt;]</code></p>
<table>
  <thead>
      <tr>
          <th>範例</th>
          <th>解釋</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>order.created</code></td>
          <td>訂單被建立（動作完成）</td>
      </tr>
      <tr>
          <td><code>order.creation_failed</code></td>
          <td>訂單建立失敗</td>
      </tr>
      <tr>
          <td><code>payment.authorized</code></td>
          <td>付款授權成功</td>
      </tr>
      <tr>
          <td><code>payment.declined</code></td>
          <td>付款被拒</td>
      </tr>
      <tr>
          <td><code>user.login_attempted</code></td>
          <td>使用者嘗試登入（動作開始）</td>
      </tr>
      <tr>
          <td><code>user.login_succeeded</code></td>
          <td>登入成功</td>
      </tr>
  </tbody>
</table>
<p><strong>禁止不一致命名</strong>：</p>
<table>
  <thead>
      <tr>
          <th>禁止</th>
          <th>原因</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>order.created</code> 和 <code>OrderCreated</code> 混用</td>
          <td>破壞 grep 精確匹配</td>
      </tr>
      <tr>
          <td><code>payment.ok</code> 和 <code>payment.authorized</code> 同義混用</td>
          <td>聚合時變成兩種事件</td>
      </tr>
      <tr>
          <td><code>event=處理成功</code>（中文）</td>
          <td>跨系統相容性差、regex 難寫</td>
      </tr>
  </tbody>
</table>
<h3 id="42-severity-分級判斷標準">4.2 Severity 分級判斷標準</h3>
<p>Severity 的<strong>唯一標準</strong>是「誰應該被叫醒」 — 因為 severity 在 production 的角色是「分流通知對象」（on-call / 工程師日報 / 查詢用 / 開發 debug）、判準應對齊到「該叫誰」。常被誤用的兩個替代判準都對不上分流目的：「問題嚴重度」會把使用者輸入錯誤判成 info（嚴重度低）、但若需要監控異常率該分到 warn；「發生頻率」會把高頻 debug 訊息誤升為 warn（頻率高）、但實際無人需要被叫醒。</p>
<table>
  <thead>
      <tr>
          <th>Severity</th>
          <th>觸發條件</th>
          <th>必填資訊</th>
          <th>誰該關注</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>error</code></td>
          <td>業務功能失敗且需要介入（使用者看到錯誤、資料遺失風險）</td>
          <td>元件、錯誤類型、業務識別、correlation ID、錯誤瞬間狀態</td>
          <td><strong>on-call 工程師需立刻處理</strong></td>
      </tr>
      <tr>
          <td><code>warn</code></td>
          <td>降級運作、重試成功、非預期但可自行恢復</td>
          <td>元件、警告類型、業務識別、恢復方式</td>
          <td>工程師需定期檢視（日報/週報）</td>
      </tr>
      <tr>
          <td><code>info</code></td>
          <td>業務事件發生（訂單建立、使用者登入、任務完成）</td>
          <td>元件、事件名稱、業務識別</td>
          <td>供查詢使用，不主動通知</td>
      </tr>
      <tr>
          <td><code>debug</code></td>
          <td>程式內部狀態、決策分支、效能測量</td>
          <td>元件、狀態描述、相關變數</td>
          <td>開發者除錯用，生產環境可關閉</td>
      </tr>
  </tbody>
</table>
<h3 id="severity-判斷流程">Severity 判斷流程</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">這條 log 記錄的事件是否需要有人立刻處理？
</span></span><span class="line"><span class="ln">2</span><span class="cl">├─ 是 → error
</span></span><span class="line"><span class="ln">3</span><span class="cl">└─ 否 → 這個事件是否偏離預期但系統已自行處理？
</span></span><span class="line"><span class="ln">4</span><span class="cl">        ├─ 是 → warn
</span></span><span class="line"><span class="ln">5</span><span class="cl">        └─ 否 → 這是業務事件還是技術細節？
</span></span><span class="line"><span class="ln">6</span><span class="cl">                ├─ 業務事件（使用者可感知） → info
</span></span><span class="line"><span class="ln">7</span><span class="cl">                └─ 技術細節（內部狀態） → debug</span></span></code></pre></div><h3 id="常見誤用">常見誤用</h3>
<table>
  <thead>
      <tr>
          <th>誤用</th>
          <th>問題</th>
          <th>正確做法</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Retry 成功寫 <code>error</code></td>
          <td>最終成功不該叫醒 on-call</td>
          <td>寫 <code>warn</code>（記錄重試次數）</td>
      </tr>
      <tr>
          <td>使用者輸入錯誤寫 <code>error</code></td>
          <td>使用者錯誤不是系統問題</td>
          <td>寫 <code>info</code>（業務事件）或 <code>warn</code>（若需監控異常率）</td>
      </tr>
      <tr>
          <td>查詢未命中寫 <code>warn</code></td>
          <td>「查不到」通常是正常業務</td>
          <td>寫 <code>info</code>（<code>user.lookup_miss</code>）</td>
      </tr>
      <tr>
          <td>每次函式進入寫 <code>info</code></td>
          <td>污染業務事件流</td>
          <td>寫 <code>debug</code></td>
      </tr>
  </tbody>
</table>
<h3 id="43-欄位值的可查詢設計">4.3 欄位值的可查詢設計</h3>
<table>
  <thead>
      <tr>
          <th>設計</th>
          <th>好查詢</th>
          <th>壞查詢</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>枚舉值用固定小寫字串</td>
          <td><code>status=pending</code></td>
          <td><code>status=PENDING</code> 和 <code>status=pending</code> 混用</td>
      </tr>
      <tr>
          <td>數值不包單位</td>
          <td><code>duration_ms=342</code></td>
          <td><code>duration=&quot;342ms&quot;</code>（regex 難處理）</td>
      </tr>
      <tr>
          <td>布林用明確字串</td>
          <td><code>is_retry=true</code></td>
          <td><code>is_retry=1</code> 或 <code>is_retry=yes</code> 混用</td>
      </tr>
      <tr>
          <td>陣列用分隔符</td>
          <td><code>tags=urgent,priority,vip</code></td>
          <td><code>tags=[&quot;urgent&quot;,&quot;priority&quot;,&quot;vip&quot;]</code>（key-value 格式中難解析）</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="5-欄位設計--log--不同-severity-的必填欄位">5. 欄位設計 × Log — 不同 Severity 的必填欄位</h2>
<h3 id="通用必填欄位所有-severity">通用必填欄位（所有 severity）</h3>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>範例</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>timestamp</code></td>
          <td><code>2026-04-16T12:00:00Z</code></td>
          <td>ISO 8601 帶時區</td>
      </tr>
      <tr>
          <td><code>level</code></td>
          <td><code>info</code></td>
          <td>小寫，見 Severity 分級</td>
      </tr>
      <tr>
          <td><code>component</code></td>
          <td><code>order-service</code></td>
          <td>元件名稱，kebab-case</td>
      </tr>
      <tr>
          <td><code>event</code></td>
          <td><code>order.created</code></td>
          <td>事件名稱，見 4.1 節</td>
      </tr>
  </tbody>
</table>
<h3 id="severity-特定必填欄位">Severity 特定必填欄位</h3>
<table>
  <thead>
      <tr>
          <th>Severity</th>
          <th>必填欄位</th>
          <th>格式範例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>error</code></td>
          <td><code>error_type</code>、<code>error_message</code>、業務識別（至少一個）、Correlation ID（跨元件時）、錯誤瞬間關鍵狀態</td>
          <td><code>[ERROR] timestamp=... level=error component=... event=... error_type=... error_message=... order_id=... request_id=...</code></td>
      </tr>
      <tr>
          <td><code>warn</code></td>
          <td><code>warn_type</code>、業務識別、恢復方式（若有）</td>
          <td><code>[WARN] timestamp=... level=warn component=... event=... warn_type=... order_id=... retry_count=2</code></td>
      </tr>
      <tr>
          <td><code>info</code></td>
          <td>業務識別（讓這條 log 可被單獨查詢）</td>
          <td><code>[INFO] timestamp=... level=info component=... event=... order_id=...</code></td>
      </tr>
      <tr>
          <td><code>debug</code></td>
          <td>無硬性業務欄位；允許記錄內部狀態、分支決策、變數值；必須能在生產環境關閉</td>
          <td><code>[DEBUG] timestamp=... level=debug component=... event=... &lt;狀態欄位&gt;</code></td>
      </tr>
  </tbody>
</table>
<h3 id="禁止記錄的欄位">禁止記錄的欄位</h3>
<table>
  <thead>
      <tr>
          <th>禁止</th>
          <th>原因</th>
          <th>替代</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>密碼、API key、token 完整值</td>
          <td>安全風險</td>
          <td>記錄遮罩後的片段（<code>token_prefix=sk_abc...</code>）</td>
      </tr>
      <tr>
          <td>完整使用者 PII（姓名、地址、信用卡）</td>
          <td>隱私合規</td>
          <td>記錄 ID（<code>user_id=42</code>）</td>
      </tr>
      <tr>
          <td>完整請求/回應 body</td>
          <td>太大、可能含敏感資料</td>
          <td>記錄摘要（<code>body_size_bytes=1024</code>）</td>
      </tr>
      <tr>
          <td>完整 SQL 查詢（含參數）</td>
          <td>可能含使用者資料</td>
          <td>記錄參數化 SQL + 參數雜湊</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="6-反模式對照表">6. 反模式對照表</h2>
<table>
  <thead>
      <tr>
          <th>反模式</th>
          <th>症狀</th>
          <th>正確做法</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>字串拼接代替結構化欄位</td>
          <td><code>[ERROR] Order 123 for user 42 failed because of insufficient funds at stripe</code> — grep 找不到這條</td>
          <td><code>[ERROR] event=order.failed order_id=123 user_id=42 error_type=payment_declined error_message=insufficient_funds gateway=stripe</code></td>
      </tr>
      <tr>
          <td>Severity 表達「問題嚴重度」而非「應否叫醒 on-call」</td>
          <td><code>[ERROR] User entered wrong password</code> — 使用者輸入錯誤不該觸發 on-call</td>
          <td><code>[INFO] event=user.login_failed user_id=42 reason=wrong_password</code></td>
      </tr>
      <tr>
          <td>Log 訊息依程式碼位置命名而非業務事件</td>
          <td><code>[DEBUG] Entering orderController.create() at line 142</code> — 重構時立刻失效</td>
          <td><code>[DEBUG] event=order.creation.input_validating component=order-controller order_id=pending</code></td>
      </tr>
      <tr>
          <td>迴圈中每次迭代都寫 info log</td>
          <td><code>[INFO] Processing item 1</code> × 1000 條 — 污染 log、掩蓋真實事件</td>
          <td><code>[INFO] event=batch.started job_id=xyz total=1000</code> + 完成時摘要</td>
      </tr>
      <tr>
          <td>錯誤 log 只有 error_message 沒有業務識別</td>
          <td><code>[ERROR] Database connection timeout</code> — 哪個查詢？哪個使用者？無法定位</td>
          <td><code>[ERROR] event=db.query_timeout component=order-service request_id=abc123 query=select_orders timeout_ms=5000</code></td>
      </tr>
      <tr>
          <td>混用時間格式或時區</td>
          <td><code>2026-04-16 12:00:00</code> vs <code>Apr 16 12:00:00</code> — 跨系統聚合無法排序</td>
          <td>統一 ISO 8601 + UTC（<code>2026-04-16T12:00:00Z</code>）</td>
      </tr>
      <tr>
          <td>Stack trace 塞進 log 訊息本體</td>
          <td><code>[ERROR] Failed: at func.a (line 12), at func.b (line 34)...</code> — 訊息被稀釋、工具解析困難</td>
          <td><code>[ERROR] event=order.failed error_type=null_pointer stack_trace_id=st_abc123</code>（stack trace 另存）</td>
      </tr>
      <tr>
          <td>使用主觀形容詞</td>
          <td><code>[WARN] Query is slow</code> — 「慢」沒有量化，無法監控</td>
          <td><code>[WARN] event=db.query_slow duration_ms=3200 threshold_ms=1000 query_name=select_user_orders</code></td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="7-自評檢查清單">7. 自評檢查清單</h2>
<p>寫完一條 log 後，自問以下問題。任一答「否」即需修改。</p>
<h3 id="內容自評">內容自評</h3>
<ul>
<li><input disabled="" type="checkbox"> 半年後陌生工程師能僅憑這條 log 理解發生了什麼嗎？</li>
<li><input disabled="" type="checkbox"> 這條 log 有明確的業務事件名稱（<code>event</code> 欄位）嗎？</li>
<li><input disabled="" type="checkbox"> Severity 是依「誰該被叫醒」選的，不是依「感覺多嚴重」嗎？</li>
<li><input disabled="" type="checkbox"> 錯誤 log 含足夠診斷資訊（錯誤類型、業務識別、瞬間狀態）嗎？</li>
<li><input disabled="" type="checkbox"> 跨元件流程有 correlation ID 串接嗎？</li>
</ul>
<h3 id="格式自評">格式自評</h3>
<ul>
<li><input disabled="" type="checkbox"> 結構化（key-value 或 JSON）而非純字串拼接嗎？</li>
<li><input disabled="" type="checkbox"> 欄位命名一致（小寫 + 下底線）嗎？</li>
<li><input disabled="" type="checkbox"> 時間戳是 ISO 8601 + UTC 嗎？</li>
<li><input disabled="" type="checkbox"> 數值不含單位字元（<code>duration_ms=342</code> 而非 <code>duration=342ms</code>）嗎？</li>
<li><input disabled="" type="checkbox"> 事件名稱符合 <code>&lt;domain&gt;.&lt;action&gt;[_&lt;result&gt;]</code> 慣例嗎？</li>
</ul>
<h3 id="安全自評">安全自評</h3>
<ul>
<li><input disabled="" type="checkbox"> 沒有記錄密碼、完整 token、信用卡號嗎？</li>
<li><input disabled="" type="checkbox"> 沒有記錄完整 PII（改記 ID）嗎？</li>
<li><input disabled="" type="checkbox"> 沒有記錄完整請求/回應 body 嗎？</li>
</ul>
<h3 id="可查詢自評">可查詢自評</h3>
<ul>
<li><input disabled="" type="checkbox"> grep <code>event=&lt;事件名&gt;</code> 能精確找到所有相關 log 嗎？</li>
<li><input disabled="" type="checkbox"> grep <code>&lt;業務識別&gt;=&lt;值&gt;</code> 能找到所有影響該實體的 log 嗎？</li>
<li><input disabled="" type="checkbox"> 日誌聚合工具能從這條 log 提取統計指標嗎？</li>
</ul>
<hr>
<h2 id="8-速查表寫作時在手邊">8. 速查表（寫作時在手邊）</h2>
<h3 id="severity-決策">Severity 決策</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">需要立刻叫醒 on-call？ → error
</span></span><span class="line"><span class="ln">2</span><span class="cl">降級/自行恢復的異常？ → warn
</span></span><span class="line"><span class="ln">3</span><span class="cl">業務事件（使用者可感知）？ → info
</span></span><span class="line"><span class="ln">4</span><span class="cl">程式內部狀態/除錯？ → debug</span></span></code></pre></div><h3 id="必填欄位">必填欄位</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">所有：timestamp, level, component, event
</span></span><span class="line"><span class="ln">2</span><span class="cl">error：+ error_type, error_message, 業務識別, correlation_id
</span></span><span class="line"><span class="ln">3</span><span class="cl">warn：+ warn_type, 業務識別
</span></span><span class="line"><span class="ln">4</span><span class="cl">info：+ 業務識別
</span></span><span class="line"><span class="ln">5</span><span class="cl">debug：無硬性要求</span></span></code></pre></div><h3 id="事件命名">事件命名</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">&lt;domain&gt;.&lt;action&gt;          — 動作完成：order.created
</span></span><span class="line"><span class="ln">2</span><span class="cl">&lt;domain&gt;.&lt;action&gt;_failed   — 動作失敗：order.creation_failed
</span></span><span class="line"><span class="ln">3</span><span class="cl">&lt;domain&gt;.&lt;action&gt;_started  — 動作開始：batch.started
</span></span><span class="line"><span class="ln">4</span><span class="cl">&lt;domain&gt;.&lt;action&gt;ing       — 動作進行中：order.processing（罕用）</span></span></code></pre></div><h3 id="格式選擇">格式選擇</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">開發/CLI/小型系統       → Key-Value
</span></span><span class="line"><span class="ln">2</span><span class="cl">生產/日誌平台/大規模    → JSON（單行）
</span></span><span class="line"><span class="ln">3</span><span class="cl">跨服務追蹤必要         → 加 trace_id / span_id</span></span></code></pre></div><hr>
<h2 id="附錄為什麼-log-寫不好就等於沒寫">附錄：為什麼 log 寫不好就等於沒寫</h2>
<p>好 log 與壞 log 的差距在事件發生時才被感受到。壞 log 的代價：</p>
<table>
  <thead>
      <tr>
          <th>壞 log 症狀</th>
          <th>除錯代價</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>訊息模糊（<code>error happened</code>）</td>
          <td>需要重現問題才能定位</td>
      </tr>
      <tr>
          <td>缺少識別（沒有元件/使用者/請求 ID）</td>
          <td>無法串接跨模組事件</td>
      </tr>
      <tr>
          <td>Severity 用錯（info 當 error）</td>
          <td>監控噪音太多，真實警報被淹沒</td>
      </tr>
      <tr>
          <td>散落格式（半 JSON 半文字）</td>
          <td>無法用工具聚合分析</td>
      </tr>
  </tbody>
</table>
<p><strong>本文件目標</strong>：讓你寫的 log 在半年後被陌生工程師搜尋到時，仍能單憑訊息本身理解事件。</p>
<hr>
<p><strong>Scope</strong>: Log output writing (所有程式語言與框架通用)
<strong>Dependencies</strong>: 無（自包含）
<strong>Last Updated</strong>: 2026-04-18</p>
]]></content:encoded></item><item><title>Writing Prompts — AI prompt / instruction 撰寫指引</title><link>https://tarrragon.github.io/blog/skills/compositional-writing/writing-prompts/</link><pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/skills/compositional-writing/writing-prompts/</guid><description>&lt;h2 id="檔案定位">檔案定位&lt;/h2>
&lt;p>本檔案為 &lt;strong>&lt;code>.claude/rules/core/ai-communication-rules.md&lt;/code> 的詳細版庫&lt;/strong>（portability-allow: 本 skill 架構性橋接至框架 auto-load 規則，非可攜性違規）。&lt;/p>
&lt;p>框架級 auto-load 規則保留 90 行骨架（核心原則、強制規則、檢查清單），本檔提供完整 Agent Prompt / Context Bundle 骨架、Token 節省深度策略、情境範例與反模式解析。&lt;/p>
&lt;p>&lt;strong>閱讀決策&lt;/strong>：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>需求&lt;/th>
 &lt;th>讀哪份&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>快速對照對話規範（預設每次 session auto-load）&lt;/td>
 &lt;td>&lt;code>.claude/rules/core/ai-communication-rules.md&lt;/code> (portability-allow)&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>寫大型 Agent Prompt / Ticket Context Bundle&lt;/td>
 &lt;td>本檔（完整骨架範例）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>深度理解 Token 節省取捨&lt;/td>
 &lt;td>本檔「Token 節省策略」章節&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>新增或修改 Skill reference 的撰寫品質規範&lt;/td>
 &lt;td>&lt;code>references/reference-authoring-standards.md&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="情境定位">情境定位&lt;/h2>
&lt;p>本 reference 為 &lt;code>compositional-writing&lt;/code> skill 的情境應用：撰寫 prompt。&lt;/p>
&lt;p>Prompt 的讀者是 AI 模型，但維護者是人類。寫作目標是在&lt;strong>最少 token 內傳遞最精準的意圖&lt;/strong>，同時維持人類可讀性（prompt 需要被維護和迭代）。與其他寫作情境不同，prompt 的每一個冗詞都是直接成本——但過度精簡又會讓意圖模糊，導致 AI 輸出偏離目標。本文件說明如何平衡 token 成本與意圖清晰度。&lt;/p>
&lt;hr>
&lt;h2 id="為什麼-prompt-寫作需要獨立指引">為什麼 Prompt 寫作需要獨立指引&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>差異點&lt;/th>
 &lt;th>一般文件&lt;/th>
 &lt;th>Prompt&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>主要讀者&lt;/td>
 &lt;td>人類&lt;/td>
 &lt;td>AI 模型&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>次要讀者&lt;/td>
 &lt;td>無&lt;/td>
 &lt;td>維護者（人類）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>冗餘成本&lt;/td>
 &lt;td>低（只佔螢幕）&lt;/td>
 &lt;td>高（直接 token 費用）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>語氣偏差代價&lt;/td>
 &lt;td>讀者重讀&lt;/td>
 &lt;td>AI 執行失敗、產出錯誤&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>結構化標記&lt;/td>
 &lt;td>錦上添花&lt;/td>
 &lt;td>必要（AI 靠標記定位）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>核心結論：&lt;strong>Prompt 必須在 token 預算內達成「意圖無歧義 + AI 可快速定位關鍵段落」兩個目標&lt;/strong>。&lt;/p>
&lt;hr>
&lt;h2 id="核心原則在-prompt-情境的應用">核心原則在 Prompt 情境的應用&lt;/h2>
&lt;h3 id="1-原子化atomization-prompt">1. 原子化（Atomization）× Prompt&lt;/h3>
&lt;p>&lt;strong>核心&lt;/strong>：一個 prompt 一個任務目標。&lt;/p>
&lt;p>Prompt 的「原子單位」是「一個可被驗收的任務」、不是「一句話」 — 因為「句子」是語法層的單位、AI 執行 prompt 時的單位是「能否完整交付一個可驗收的結果」。一句話可以跨多個任務（例如「幫我寫測試 + 順便重構 + 檢查安全性」）、AI 接到後分散注意力、每個子任務都做得不完整；反之、多句話描述同一個任務（前提 / 動作 / 驗收條件）仍是一個原子 prompt。判準在「驗收完整性」、不在「句數」。&lt;/p>
&lt;p>&lt;strong>判斷標準&lt;/strong>：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>問題&lt;/th>
 &lt;th>若答「是」&lt;/th>
 &lt;th>行動&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Prompt 目標是否可用單一動詞 + 單一受詞描述？&lt;/td>
 &lt;td>是&lt;/td>
 &lt;td>原子&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>是否存在兩個以上的「和」連接不同動作？&lt;/td>
 &lt;td>是&lt;/td>
 &lt;td>拆分&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>驗收條件是否可並列表達而非混合？&lt;/td>
 &lt;td>是&lt;/td>
 &lt;td>可能不原子&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>反例&lt;/strong>：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="err">#&lt;/span> &lt;span class="nx">違反原子化&lt;/span>&lt;span class="err">：&lt;/span>&lt;span class="nx">三個任務混在一起&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="nx">請閱讀檔案&lt;/span> &lt;span class="nx">X&lt;/span>&lt;span class="err">，&lt;/span>&lt;span class="nx">找出函式&lt;/span> &lt;span class="nx">Y&lt;/span> &lt;span class="nx">的測試覆蓋缺口&lt;/span>&lt;span class="err">，&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">&lt;span class="nx">補上缺失的測試&lt;/span>&lt;span class="err">，&lt;/span>&lt;span class="nx">並順便重構重複的&lt;/span> &lt;span class="nx">setup&lt;/span> &lt;span class="nx">程式碼&lt;/span>&lt;span class="err">，&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="nx">最後把所有&lt;/span> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span> &lt;span class="nx">改成&lt;/span> &lt;span class="nx">logger&lt;/span>&lt;span class="err">。&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>正確&lt;/strong>（拆為 3 個獨立 prompt 或 3 個明確分段）：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="err">#&lt;/span> &lt;span class="nx">任務&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="err">：&lt;/span>&lt;span class="nx">分析測試覆蓋缺口&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">&lt;span class="nx">輸入&lt;/span>&lt;span class="err">：&lt;/span>&lt;span class="nx">檔案&lt;/span> &lt;span class="nx">X&lt;/span> &lt;span class="nx">的函式&lt;/span> &lt;span class="nx">Y&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">&lt;span class="nx">輸出&lt;/span>&lt;span class="err">：&lt;/span>&lt;span class="nx">未被測試覆蓋的分支清單&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">&lt;span class="err">#&lt;/span> &lt;span class="nx">任務&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="err">：&lt;/span>&lt;span class="nx">補缺測試&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">&lt;span class="nx">輸入&lt;/span>&lt;span class="err">：&lt;/span>&lt;span class="nx">任務&lt;/span> &lt;span class="mi">1&lt;/span> &lt;span class="nx">的缺口清單&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">&lt;span class="nx">輸出&lt;/span>&lt;span class="err">：&lt;/span>&lt;span class="nx">新增的測試案例&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">&lt;span class="err">#&lt;/span> &lt;span class="nx">任務&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="err">：&lt;/span>&lt;span class="nx">清理&lt;/span>&lt;span class="err">（&lt;/span>&lt;span class="nx">獨立&lt;/span> &lt;span class="nx">ticket&lt;/span>&lt;span class="err">）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">&lt;span class="nx">輸入&lt;/span>&lt;span class="err">：&lt;/span>&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span> &lt;span class="nx">位置清單&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">&lt;span class="nx">輸出&lt;/span>&lt;span class="err">：&lt;/span>&lt;span class="nx">logger&lt;/span> &lt;span class="nx">替換後的&lt;/span> &lt;span class="nx">diff&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h3 id="2-索引建立indexing-prompt">2. 索引建立（Indexing）× Prompt&lt;/h3>
&lt;p>&lt;strong>核心&lt;/strong>：結構化標記讓 AI 快速定位關鍵段落。&lt;/p>
&lt;p>AI 讀 prompt 時會建立「段落角色模型」——哪段是目標、哪段是約束、哪段是輸出格式。如果 prompt 是純散文，AI 必須從頭讀到尾才能判斷每段角色，token 和注意力都被浪費。結構化標記（章節標題、列表、表格、標籤）讓 AI 跳讀定位。&lt;/p>
&lt;p>&lt;strong>結構化標記工具箱&lt;/strong>：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>標記&lt;/th>
 &lt;th>用途&lt;/th>
 &lt;th>AI 解讀&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;code>## 標題&lt;/code>&lt;/td>
 &lt;td>大段角色分隔（任務 / 約束 / 輸出格式）&lt;/td>
 &lt;td>跳讀定位&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>### 子標題&lt;/code>&lt;/td>
 &lt;td>同一大段內的細分&lt;/td>
 &lt;td>細節索引&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Markdown 表格&lt;/td>
 &lt;td>對照型資訊（選項、規則、映射）&lt;/td>
 &lt;td>一次載入多維度&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>有序列表 &lt;code>1./2./3.&lt;/code>&lt;/td>
 &lt;td>步驟順序&lt;/td>
 &lt;td>執行序列&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>無序列表 &lt;code>- &lt;/code>&lt;/td>
 &lt;td>條件集合&lt;/td>
 &lt;td>平行規則&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>XML 標籤 &lt;code>&amp;lt;task&amp;gt;&amp;lt;/task&amp;gt;&lt;/code>&lt;/td>
 &lt;td>明確邊界（用於需要嚴格分隔的區塊）&lt;/td>
 &lt;td>強制邊界&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>程式碼圍欄 &lt;code>```&lt;/code>&lt;/td>
 &lt;td>字面值保護（AI 不會誤解為指令）&lt;/td>
 &lt;td>不執行區域&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>建議章節骨架&lt;/strong>（大型 prompt）：&lt;/p></description><content:encoded><![CDATA[<h2 id="檔案定位">檔案定位</h2>
<p>本檔案為 <strong><code>.claude/rules/core/ai-communication-rules.md</code> 的詳細版庫</strong>（portability-allow: 本 skill 架構性橋接至框架 auto-load 規則，非可攜性違規）。</p>
<p>框架級 auto-load 規則保留 90 行骨架（核心原則、強制規則、檢查清單），本檔提供完整 Agent Prompt / Context Bundle 骨架、Token 節省深度策略、情境範例與反模式解析。</p>
<p><strong>閱讀決策</strong>：</p>
<table>
  <thead>
      <tr>
          <th>需求</th>
          <th>讀哪份</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>快速對照對話規範（預設每次 session auto-load）</td>
          <td><code>.claude/rules/core/ai-communication-rules.md</code> (portability-allow)</td>
      </tr>
      <tr>
          <td>寫大型 Agent Prompt / Ticket Context Bundle</td>
          <td>本檔（完整骨架範例）</td>
      </tr>
      <tr>
          <td>深度理解 Token 節省取捨</td>
          <td>本檔「Token 節省策略」章節</td>
      </tr>
      <tr>
          <td>新增或修改 Skill reference 的撰寫品質規範</td>
          <td><code>references/reference-authoring-standards.md</code></td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="情境定位">情境定位</h2>
<p>本 reference 為 <code>compositional-writing</code> skill 的情境應用：撰寫 prompt。</p>
<p>Prompt 的讀者是 AI 模型，但維護者是人類。寫作目標是在<strong>最少 token 內傳遞最精準的意圖</strong>，同時維持人類可讀性（prompt 需要被維護和迭代）。與其他寫作情境不同，prompt 的每一個冗詞都是直接成本——但過度精簡又會讓意圖模糊，導致 AI 輸出偏離目標。本文件說明如何平衡 token 成本與意圖清晰度。</p>
<hr>
<h2 id="為什麼-prompt-寫作需要獨立指引">為什麼 Prompt 寫作需要獨立指引</h2>
<table>
  <thead>
      <tr>
          <th>差異點</th>
          <th>一般文件</th>
          <th>Prompt</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>主要讀者</td>
          <td>人類</td>
          <td>AI 模型</td>
      </tr>
      <tr>
          <td>次要讀者</td>
          <td>無</td>
          <td>維護者（人類）</td>
      </tr>
      <tr>
          <td>冗餘成本</td>
          <td>低（只佔螢幕）</td>
          <td>高（直接 token 費用）</td>
      </tr>
      <tr>
          <td>語氣偏差代價</td>
          <td>讀者重讀</td>
          <td>AI 執行失敗、產出錯誤</td>
      </tr>
      <tr>
          <td>結構化標記</td>
          <td>錦上添花</td>
          <td>必要（AI 靠標記定位）</td>
      </tr>
  </tbody>
</table>
<p>核心結論：<strong>Prompt 必須在 token 預算內達成「意圖無歧義 + AI 可快速定位關鍵段落」兩個目標</strong>。</p>
<hr>
<h2 id="核心原則在-prompt-情境的應用">核心原則在 Prompt 情境的應用</h2>
<h3 id="1-原子化atomization-prompt">1. 原子化（Atomization）× Prompt</h3>
<p><strong>核心</strong>：一個 prompt 一個任務目標。</p>
<p>Prompt 的「原子單位」是「一個可被驗收的任務」、不是「一句話」 — 因為「句子」是語法層的單位、AI 執行 prompt 時的單位是「能否完整交付一個可驗收的結果」。一句話可以跨多個任務（例如「幫我寫測試 + 順便重構 + 檢查安全性」）、AI 接到後分散注意力、每個子任務都做得不完整；反之、多句話描述同一個任務（前提 / 動作 / 驗收條件）仍是一個原子 prompt。判準在「驗收完整性」、不在「句數」。</p>
<p><strong>判斷標準</strong>：</p>
<table>
  <thead>
      <tr>
          <th>問題</th>
          <th>若答「是」</th>
          <th>行動</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Prompt 目標是否可用單一動詞 + 單一受詞描述？</td>
          <td>是</td>
          <td>原子</td>
      </tr>
      <tr>
          <td>是否存在兩個以上的「和」連接不同動作？</td>
          <td>是</td>
          <td>拆分</td>
      </tr>
      <tr>
          <td>驗收條件是否可並列表達而非混合？</td>
          <td>是</td>
          <td>可能不原子</td>
      </tr>
  </tbody>
</table>
<p><strong>反例</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="ln">1</span><span class="cl"><span class="err">#</span> <span class="nx">違反原子化</span><span class="err">：</span><span class="nx">三個任務混在一起</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="nx">請閱讀檔案</span> <span class="nx">X</span><span class="err">，</span><span class="nx">找出函式</span> <span class="nx">Y</span> <span class="nx">的測試覆蓋缺口</span><span class="err">，</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="nx">補上缺失的測試</span><span class="err">，</span><span class="nx">並順便重構重複的</span> <span class="nx">setup</span> <span class="nx">程式碼</span><span class="err">，</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="nx">最後把所有</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span> <span class="nx">改成</span> <span class="nx">logger</span><span class="err">。</span></span></span></code></pre></div><p><strong>正確</strong>（拆為 3 個獨立 prompt 或 3 個明確分段）：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="err">#</span> <span class="nx">任務</span> <span class="mi">1</span><span class="err">：</span><span class="nx">分析測試覆蓋缺口</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="nx">輸入</span><span class="err">：</span><span class="nx">檔案</span> <span class="nx">X</span> <span class="nx">的函式</span> <span class="nx">Y</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="nx">輸出</span><span class="err">：</span><span class="nx">未被測試覆蓋的分支清單</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="err">#</span> <span class="nx">任務</span> <span class="mi">2</span><span class="err">：</span><span class="nx">補缺測試</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="nx">輸入</span><span class="err">：</span><span class="nx">任務</span> <span class="mi">1</span> <span class="nx">的缺口清單</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="nx">輸出</span><span class="err">：</span><span class="nx">新增的測試案例</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="err">#</span> <span class="nx">任務</span> <span class="mi">3</span><span class="err">：</span><span class="nx">清理</span><span class="err">（</span><span class="nx">獨立</span> <span class="nx">ticket</span><span class="err">）</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="nx">輸入</span><span class="err">：</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span> <span class="nx">位置清單</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="nx">輸出</span><span class="err">：</span><span class="nx">logger</span> <span class="nx">替換後的</span> <span class="nx">diff</span></span></span></code></pre></div><hr>
<h3 id="2-索引建立indexing-prompt">2. 索引建立（Indexing）× Prompt</h3>
<p><strong>核心</strong>：結構化標記讓 AI 快速定位關鍵段落。</p>
<p>AI 讀 prompt 時會建立「段落角色模型」——哪段是目標、哪段是約束、哪段是輸出格式。如果 prompt 是純散文，AI 必須從頭讀到尾才能判斷每段角色，token 和注意力都被浪費。結構化標記（章節標題、列表、表格、標籤）讓 AI 跳讀定位。</p>
<p><strong>結構化標記工具箱</strong>：</p>
<table>
  <thead>
      <tr>
          <th>標記</th>
          <th>用途</th>
          <th>AI 解讀</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>## 標題</code></td>
          <td>大段角色分隔（任務 / 約束 / 輸出格式）</td>
          <td>跳讀定位</td>
      </tr>
      <tr>
          <td><code>### 子標題</code></td>
          <td>同一大段內的細分</td>
          <td>細節索引</td>
      </tr>
      <tr>
          <td>Markdown 表格</td>
          <td>對照型資訊（選項、規則、映射）</td>
          <td>一次載入多維度</td>
      </tr>
      <tr>
          <td>有序列表 <code>1./2./3.</code></td>
          <td>步驟順序</td>
          <td>執行序列</td>
      </tr>
      <tr>
          <td>無序列表 <code>- </code></td>
          <td>條件集合</td>
          <td>平行規則</td>
      </tr>
      <tr>
          <td>XML 標籤 <code>&lt;task&gt;&lt;/task&gt;</code></td>
          <td>明確邊界（用於需要嚴格分隔的區塊）</td>
          <td>強制邊界</td>
      </tr>
      <tr>
          <td>程式碼圍欄 <code>```</code></td>
          <td>字面值保護（AI 不會誤解為指令）</td>
          <td>不執行區域</td>
      </tr>
  </tbody>
</table>
<p><strong>建議章節骨架</strong>（大型 prompt）：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## 任務目標
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>（1-2 句話）
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu">## 輸入
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu"></span><span class="k">-</span> 檔案路徑 / 資料內容 / 前置條件
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu">## 約束
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gu"></span><span class="k">-</span> 禁止項
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="k">-</span> 必要項
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu">## 輸出格式
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu"></span><span class="k">-</span> 預期產出的結構
</span></span><span class="line"><span class="ln">13</span><span class="cl">
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="gu">## 驗收條件
</span></span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="gu"></span>- [ ] 可勾選的具體條件</span></span></code></pre></div><p>小型 prompt 可壓縮為單段，但仍要保留「任務—約束—輸出」三段訊號。</p>
<hr>
<h3 id="3-意圖顯性與商業邏輯explicit-intent--business-logic-prompt">3. 意圖顯性與商業邏輯（Explicit Intent &amp; Business Logic）× Prompt</h3>
<p><strong>核心</strong>：開頭直述任務目標，明確預期輸出格式，告訴 AI 為什麼。</p>
<h4 id="31-開頭即表達意圖">3.1 開頭即表達意圖</h4>
<p>Prompt 第一句就說清楚「要 AI 做什麼」。AI 讀 prompt 時會根據前幾句建立初始任務模型——如果前段是背景鋪陳，AI 可能在建立錯誤假設後才讀到真正目標，導致輸出偏差。</p>
<p><strong>反例</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl"># 意圖埋在後段
</span></span><span class="line"><span class="ln">2</span><span class="cl">我們的系統最近遇到一些效能問題，昨天 profile 發現
</span></span><span class="line"><span class="ln">3</span><span class="cl">BookRepository 的 getAll() 呼叫量暴增，估計是 cache 失效。
</span></span><span class="line"><span class="ln">4</span><span class="cl">我之前試過加 memoization 但沒效果，可能是 key 設計問題。
</span></span><span class="line"><span class="ln">5</span><span class="cl">所以，請幫我重寫 getAll() 的快取層。</span></span></code></pre></div><p><strong>正確</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl"># 開頭直述目標
</span></span><span class="line"><span class="ln">2</span><span class="cl">任務：重寫 BookRepository.getAll() 的快取層。
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl">背景（供參考，非必讀）：
</span></span><span class="line"><span class="ln">5</span><span class="cl">- 現有 memoization 的 key 設計有問題
</span></span><span class="line"><span class="ln">6</span><span class="cl">- profile 顯示 getAll() 被大量呼叫</span></span></code></pre></div><h4 id="32-明確輸出格式">3.2 明確輸出格式</h4>
<p>告訴 AI 預期產出結構，而非期待它自行推斷。</p>
<p><strong>反例</strong>：「幫我分析一下這段程式碼」
<strong>正確</strong>：「分析下列程式碼，以 Markdown 表格列出：問題 | 影響 | 建議修正。每個問題另附 3-5 行說明。」</p>
<h4 id="33-告訴-ai-為什麼">3.3 告訴 AI 「為什麼」</h4>
<p>當約束或做法不直觀時，補上理由，避免 AI 基於「合理預設」覆寫規則。</p>
<p><strong>反例</strong>：「不要使用 async/await」
<strong>正確</strong>：「不要使用 async/await（本專案目標環境不支援 ES2017+，只能用 Promise.then）」</p>
<p>沒有理由的禁令，AI 可能在重構時基於「現代寫法更好」的預設還原。</p>
<hr>
<h3 id="4-可查詢性searchability-prompt">4. 可查詢性（Searchability）× Prompt</h3>
<p><strong>核心</strong>：模板設計讓維護者能 grep；變數佔位符命名規範讓 AI 和人類都清楚。</p>
<p>Prompt 不是一次性文字，會被反覆維護和調整。未來 6 個月後，維護者需要 grep 找到「所有派發 engineer 代理人的 prompt」「所有包含 context bundle 的 prompt」。如果 prompt 沒有可搜尋的穩定關鍵字，維護成本會爆炸。</p>
<h4 id="41-穩定關鍵字">4.1 穩定關鍵字</h4>
<p>在 prompt 模板的關鍵位置保留穩定詞彙，讓 grep 能一次命中所有同類 prompt。</p>
<table>
  <thead>
      <tr>
          <th>查詢需求</th>
          <th>穩定關鍵字範例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>找所有 ticket 派發 prompt</td>
          <td>在開頭統一寫 <code>Ticket: {id}</code></td>
      </tr>
      <tr>
          <td>找所有驗收條件區段</td>
          <td>統一用 <code>## 驗收條件</code> 標題</td>
      </tr>
      <tr>
          <td>找所有需要 ticket track complete 的 prompt</td>
          <td>統一包含 <code>ticket track complete</code> 字串</td>
      </tr>
  </tbody>
</table>
<h4 id="42-變數佔位符命名規範">4.2 變數佔位符命名規範</h4>
<p>模板中的變數必須用明確且可 grep 的佔位符，避免 <code>{x}</code> <code>{var}</code> 這類模糊名稱。</p>
<table>
  <thead>
      <tr>
          <th>反例</th>
          <th>正確</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>{x}</code></td>
          <td><code>{ticket_id}</code></td>
      </tr>
      <tr>
          <td><code>{name}</code></td>
          <td><code>{agent_name}</code> 或 <code>{file_path}</code></td>
      </tr>
      <tr>
          <td><code>{content}</code></td>
          <td><code>{context_bundle_text}</code></td>
      </tr>
  </tbody>
</table>
<p>佔位符規則：</p>
<ul>
<li>全小寫 + 底線分隔（snake_case）</li>
<li>名詞片語，描述「這個變數代表什麼」</li>
<li>避免縮寫（用 <code>file_path</code> 而非 <code>fp</code>）</li>
</ul>
<h4 id="43-區塊邊界標記">4.3 區塊邊界標記</h4>
<p>大型 prompt 內部若有可重用區塊（例如「約束」「輸出格式」），用標記界定邊界方便剪貼和 diff。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl"><span class="c">&lt;!-- BEGIN: 通用代理人約束 --&gt;</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="k">-</span> 不修改 src/ 以外的檔案
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="k">-</span> commit 訊息格式：<span class="sb">`&lt;type&gt;({ticket_id}): &lt;summary&gt;`</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c">&lt;!-- END: 通用代理人約束 --&gt;</span></span></span></code></pre></div><hr>
<h3 id="5-欄位設計field-design-prompt">5. 欄位設計（Field Design）× Prompt</h3>
<p><strong>核心</strong>：Context bundle 的每個欄位獨立角度，避免混淆。</p>
<p>Prompt 常見的欄位污染：把「做什麼」「為什麼」「如何驗收」「禁止事項」混在一段。AI 讀這種段落時必須反覆解析每句角色，容易漏掉約束。</p>
<p><strong>標準欄位骨架</strong>（適用 ticket context bundle 或任何結構化派發 prompt）：</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>角度</th>
          <th>內容類型</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>任務</code> / <code>Task</code></td>
          <td>動作</td>
          <td>動詞 + 受詞，一句話</td>
      </tr>
      <tr>
          <td><code>輸入</code> / <code>Inputs</code></td>
          <td>材料</td>
          <td>檔案 / 資料 / 前置條件</td>
      </tr>
      <tr>
          <td><code>約束</code> / <code>Constraints</code></td>
          <td>邊界</td>
          <td>禁止項 + 必要項</td>
      </tr>
      <tr>
          <td><code>驗收</code> / <code>Acceptance</code></td>
          <td>終點判定</td>
          <td>可勾選的條件</td>
      </tr>
      <tr>
          <td><code>背景</code> / <code>Context</code></td>
          <td>理由（可選）</td>
          <td>為什麼選此方案</td>
      </tr>
      <tr>
          <td><code>參考</code> / <code>References</code></td>
          <td>延伸資料</td>
          <td>相關文件路徑</td>
      </tr>
  </tbody>
</table>
<p>每個欄位<strong>只</strong>寫該角度的內容，禁止跨欄位混合。</p>
<p><strong>反例</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">任務：重寫快取層，不要使用 memoization，因為 key 設計有問題，完成後要跑 npm test。</span></span></code></pre></div><p>（動作 + 約束 + 理由 + 驗收全擠在一行）</p>
<p><strong>正確</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">任務：重寫 BookRepository.getAll() 的快取層。
</span></span><span class="line"><span class="ln">2</span><span class="cl">約束：不使用現有 memoization 機制。
</span></span><span class="line"><span class="ln">3</span><span class="cl">背景：memoization 的 key 設計失效，profile 確認大量重複計算。
</span></span><span class="line"><span class="ln">4</span><span class="cl">驗收：npm test 通過；profile 顯示 getAll() 呼叫量下降 &gt; 50%。</span></span></code></pre></div><hr>
<h2 id="token-節省策略">Token 節省策略</h2>
<p>Prompt 的每個 token 都是成本。以下策略在<strong>不傷害意圖清晰度</strong>的前提下節省 token。</p>
<h3 id="策略-1用符號取代連接詞">策略 1：用符號取代連接詞</h3>
<p><strong>前</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">如果使用者已經登入並且擁有管理員權限，那麼允許存取，否則回傳 403 錯誤。</span></span></code></pre></div><p><strong>後</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">已登入 AND 管理員 → 允許存取；否則 → 403。</span></span></code></pre></div><p><strong>節省</strong>：約 40% token。符號（<code>AND</code>、<code>→</code>、<code>;</code>）是 AI 可無歧義解讀的通用邏輯標記。</p>
<hr>
<h3 id="策略-2表格取代重複句型">策略 2：表格取代重複句型</h3>
<p><strong>前</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">當輸入是 JSON 時，回傳 JSON；當輸入是 YAML 時，回傳 YAML；
</span></span><span class="line"><span class="ln">2</span><span class="cl">當輸入是 CSV 時，回傳 CSV；當輸入格式無法辨識時，回傳錯誤訊息。</span></span></code></pre></div><p><strong>後</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">| 輸入格式 | 輸出 |
</span></span><span class="line"><span class="ln">2</span><span class="cl">|---------|------|
</span></span><span class="line"><span class="ln">3</span><span class="cl">| JSON | JSON |
</span></span><span class="line"><span class="ln">4</span><span class="cl">| YAML | YAML |
</span></span><span class="line"><span class="ln">5</span><span class="cl">| CSV | CSV |
</span></span><span class="line"><span class="ln">6</span><span class="cl">| 未知 | 錯誤訊息 |</span></span></code></pre></div><p><strong>節省</strong>：約 35% token。表格消除重複的句型骨架（「當 X 時，回傳 Y」），AI 解析更快。</p>
<hr>
<h3 id="策略-3引用路徑取代完整內容貼入">策略 3：引用路徑取代完整內容貼入</h3>
<p><strong>前</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">根據以下規則處理：
</span></span><span class="line"><span class="ln">2</span><span class="cl">（貼入 500 行規則文件全文）</span></span></code></pre></div><p><strong>後</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">規則：docs/quality-baseline.md（請閱讀後套用）</span></span></code></pre></div><p><strong>節省</strong>：依文件大小，通常 &gt; 90% token。前提是 AI 能存取該路徑（檔案必須存在於執行環境）。</p>
<p><strong>適用判斷</strong>：</p>
<table>
  <thead>
      <tr>
          <th>場景</th>
          <th>應貼內容？</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>規則文件已存在於專案</td>
          <td>否，引用路徑</td>
      </tr>
      <tr>
          <td>只用文件中一小段</td>
          <td>否，精確引用章節（<code>file.md#section</code>）</td>
      </tr>
      <tr>
          <td>臨時性規則，不存在於檔案</td>
          <td>是，需貼入</td>
      </tr>
      <tr>
          <td>AI 無法存取該路徑（跨 session / 跨環境）</td>
          <td>是，需貼入</td>
      </tr>
  </tbody>
</table>
<hr>
<h3 id="策略-4刪除客套與鋪陳">策略 4：刪除客套與鋪陳</h3>
<p><strong>前</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">您好，我希望您能幫我處理一個問題。最近我們在開發一個新功能，
</span></span><span class="line"><span class="ln">2</span><span class="cl">遇到了一些挑戰。我想請您幫我看看下列程式碼有什麼問題。謝謝！</span></span></code></pre></div><p><strong>後</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">任務：找出下列程式碼的問題。</span></span></code></pre></div><p><strong>節省</strong>：約 70% token。AI 不需要客套語境——直接給任務比「禮貌請求」更有效。</p>
<hr>
<h3 id="策略-5用預設約定取代顯式枚舉">策略 5：用預設約定取代顯式枚舉</h3>
<p><strong>前</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">輸出格式：請用 Markdown 格式，標題使用 # 開頭，列表使用 - 開頭，
</span></span><span class="line"><span class="ln">2</span><span class="cl">程式碼使用三個反引號包起來，表格使用 | 分隔。</span></span></code></pre></div><p><strong>後</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">輸出格式：Markdown。</span></span></code></pre></div><p><strong>節省</strong>：約 80% token。Markdown 的語法細節是通用知識，不需要重新定義。</p>
<p><strong>適用原則</strong>：若約定是通用知識（JSON、Markdown、YAML、常見技術術語），直接用名稱；若是專案特定約定，必須顯式說明。</p>
<hr>
<h2 id="結構化標記範例">結構化標記範例</h2>
<h3 id="範例-aagent-prompt派發代理人">範例 A：Agent Prompt（派發代理人）</h3>
<p>完整 agent prompt 骨架：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">Ticket: {ticket_id}
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">任務: {short_task_description}
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">Ticket 路徑: {ticket_file_path}
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">請 Read Ticket 取得完整 Context Bundle 和驗收條件（位於 Problem Analysis section）。
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu">## 輸入
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gu"></span><span class="k">-</span> 目標檔案：{target_files}
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="k">-</span> 依賴 ticket：{dependency_ticket_ids}
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu">## 約束
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu"></span><span class="k">-</span> 不修改 .claude/ 以外的 rules/ 目錄
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="k">-</span> 保留既有測試不動
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="k">-</span> commit 訊息格式：<span class="sb">`&lt;type&gt;({ticket_id}): &lt;summary&gt;`</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="gu">## 執行步驟
</span></span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="gu"></span><span class="k">1.</span> <span class="sb">`ticket track claim {ticket_id}`</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">2.</span> 依 Context Bundle 執行實作
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="k">3.</span> <span class="sb">`ticket track append-log {ticket_id} --section &#34;Solution&#34; &#34;...&#34;`</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="k">4.</span> <span class="sb">`ticket track complete {ticket_id}`</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="gu">## 驗收
</span></span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> {acceptance_1}
</span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="k">- [ ]</span> {acceptance_2}
</span></span><span class="line"><span class="ln">25</span><span class="cl">
</span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="gu">## 一行摘要回報
</span></span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="gu"></span>格式：「{file_name}:{lines}行 {metric_1}:{N} {metric_2}:{N} 狀態:{status}」</span></span></code></pre></div><p><strong>設計要點</strong>：</p>
<table>
  <thead>
      <tr>
          <th>區塊</th>
          <th>功能</th>
          <th>可搜尋性</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>Ticket: {id}</code></td>
          <td>穩定關鍵字，grep 能找到所有派發 prompt</td>
          <td>高</td>
      </tr>
      <tr>
          <td><code>## 輸入</code> / <code>## 約束</code> / <code>## 執行步驟</code> / <code>## 驗收</code></td>
          <td>標準化章節，AI 快速定位</td>
          <td>高</td>
      </tr>
      <tr>
          <td>變數佔位符 <code>{ticket_id}</code> 等</td>
          <td>snake_case 自說明</td>
          <td>高</td>
      </tr>
      <tr>
          <td>一行摘要回報格式</td>
          <td>統一回報格式，PM 可 grep 聚合</td>
          <td>高</td>
      </tr>
  </tbody>
</table>
<hr>
<h3 id="範例-bticket-context-bundle">範例 B：Ticket Context Bundle</h3>
<p>Ticket YAML frontmatter 的 Problem Analysis 區塊作為 context bundle：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Problem Analysis
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### Context Bundle
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gs">**執行步驟**</span>:
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">1.</span> <span class="sb">`ticket track claim {ticket_id}`</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">2.</span> Read {dependency_ticket_solution_path} 取得 {needed_info}
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="k">3.</span> 撰寫 <span class="sb">`{target_file_path}`</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="k">4.</span> {integration_step}
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="k">5.</span> 可攜性自檢後 <span class="sb">`ticket track complete`</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gs">**關鍵參考**</span>:
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="k">-</span> {reference_1_description}: <span class="sb">`{reference_1_path}`</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="k">-</span> {reference_2_description}: <span class="sb">`{reference_2_path}`</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="gs">**約束**</span>:
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">-</span> {constraint_1}
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">-</span> {constraint_2}
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="k">-</span> 一行摘要回報：「{field_1}:{X} {field_2}:{N} 狀態:{status}」
</span></span><span class="line"><span class="ln">20</span><span class="cl">
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="gu">### 問題根因
</span></span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">{root_cause_description}
</span></span><span class="line"><span class="ln">24</span><span class="cl">
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="gu">### 影響範圍
</span></span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">27</span><span class="cl">{impact_scope}
</span></span><span class="line"><span class="ln">28</span><span class="cl">
</span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="gu">### 相關 Error Pattern
</span></span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">31</span><span class="cl">{error_pattern_reference_or_none}</span></span></code></pre></div><p><strong>設計要點</strong>：</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>角度</th>
          <th>避免混淆規則</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>執行步驟</td>
          <td>How</td>
          <td>具體命令，不寫理由</td>
      </tr>
      <tr>
          <td>關鍵參考</td>
          <td>Where</td>
          <td>檔案路徑 + 用途，不貼內容</td>
      </tr>
      <tr>
          <td>約束</td>
          <td>Must not / Must</td>
          <td>可驗證的邊界條件</td>
      </tr>
      <tr>
          <td>問題根因</td>
          <td>Why</td>
          <td>因果陳述，不寫解法</td>
      </tr>
      <tr>
          <td>影響範圍</td>
          <td>What</td>
          <td>檔案 / 模組清單</td>
      </tr>
  </tbody>
</table>
<p><strong>Context Bundle 的 DRY 原則</strong>：YAML frontmatter 的 <code>what</code> / <code>why</code> / <code>how</code> 已分角度填寫，Context Bundle 不重複這些欄位的內容，只補「執行細節」與「關鍵參考」。</p>
<hr>
<h3 id="範例-c小型內聯-prompt對話中">範例 C：小型內聯 Prompt（對話中）</h3>
<p>適用於對話中快速派發單一任務：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">任務：檢查 {file} 是否有 {pattern}。
</span></span><span class="line"><span class="ln">2</span><span class="cl">輸出：匹配行數列表（檔案:行號）。
</span></span><span class="line"><span class="ln">3</span><span class="cl">若無匹配：回報「無匹配」。</span></span></code></pre></div><p><strong>設計要點</strong>：不需要完整章節，但仍保留「任務—輸出—邊界」三層訊號。</p>
<hr>
<h2 id="自檢清單">自檢清單</h2>
<p>撰寫 prompt 完成後，逐項檢查：</p>
<h3 id="原子化">原子化</h3>
<ul>
<li><input disabled="" type="checkbox"> Prompt 目標可用單一動詞 + 單一受詞描述</li>
<li><input disabled="" type="checkbox"> 無多個不相關任務混合</li>
</ul>
<h3 id="索引建立">索引建立</h3>
<ul>
<li><input disabled="" type="checkbox"> 有結構化標記（章節 / 表格 / 列表）</li>
<li><input disabled="" type="checkbox"> 大型 prompt 有「任務 / 輸入 / 約束 / 輸出 / 驗收」骨架</li>
</ul>
<h3 id="意圖顯性">意圖顯性</h3>
<ul>
<li><input disabled="" type="checkbox"> 第一句即表達任務目標</li>
<li><input disabled="" type="checkbox"> 明確指定輸出格式</li>
<li><input disabled="" type="checkbox"> 不直觀的約束有附理由</li>
</ul>
<h3 id="可查詢性">可查詢性</h3>
<ul>
<li><input disabled="" type="checkbox"> 有穩定關鍵字供 grep（ticket ID / 章節名 / 工具名）</li>
<li><input disabled="" type="checkbox"> 變數佔位符為 snake_case 且自說明</li>
<li><input disabled="" type="checkbox"> 可重用區塊有邊界標記（如適用）</li>
</ul>
<h3 id="欄位設計">欄位設計</h3>
<ul>
<li><input disabled="" type="checkbox"> 每個欄位只寫該角度內容</li>
<li><input disabled="" type="checkbox"> 無「動作 + 約束 + 理由 + 驗收」擠在一起</li>
<li><input disabled="" type="checkbox"> Context Bundle 不重複 YAML frontmatter 已有欄位</li>
</ul>
<h3 id="token-節省">Token 節省</h3>
<ul>
<li><input disabled="" type="checkbox"> 無多餘客套與鋪陳</li>
<li><input disabled="" type="checkbox"> 重複句型已用表格取代</li>
<li><input disabled="" type="checkbox"> 規則以路徑引用取代全文貼入（如適用）</li>
<li><input disabled="" type="checkbox"> 邏輯關係用符號（<code>AND</code> / <code>→</code> / <code>;</code>）取代連接詞（如適用）</li>
<li><input disabled="" type="checkbox"> 通用知識（Markdown / JSON）用名稱指定，不枚舉語法</li>
</ul>
<hr>
<h2 id="多輪-re-read-passmulti-pass-refinement">多輪 Re-read Pass（multi-pass refinement）</h2>
<p>寫完上方自檢還不是 done — 自檢是「同 frame 的最後一掃」、不是 multi-pass。Multi-pass 要求每輪用<strong>不同 frame</strong> catch 不同層的錯（<a href="/blog/report/literal-interception-vs-behavioral-refinement/" data-link-title="字面攔截 vs 行為精煉：驗證手段跟錯誤層次的對齊" data-link-desc="驗證手段必須跟錯誤層次對齊：字面錯誤（typo / syntax / 缺欄位）用 hook / lint / CI 攔截；行為錯誤（思考偏差 / 判斷錯位 / collapse 反模式）用 multi-pass spiral 收斂。強行用 hook 蓋行為錯誤 = 給出 false confidence、反而比沒保護危險。本卡是 #72 結構性對策在「驗證粒度」維度的 ceiling — 不是所有錯誤都該被攔截。">literal-interception-vs-behavioral-refinement</a> / <a href="/blog/report/writing-multi-pass-review/" data-link-title="Writing 的 multi-pass review：N 輪 review、每輪換 frame" data-link-desc="寫文章 / 註解 / 文件 / prompt 的「寫」不是單次動作 — 是 N 輪 review。第 1 輪生成、第 2 輪對意圖（#67）、第 3 輪檢查機會成本語氣、第 4 輪 grep-ability、第 5 輪反例 / 邊界。每輪不同 frame、單輪寫不出全部維度。本卡是 #82 在「寫」這個 output 動作的具體實例。">writing-multi-pass-review</a>）。</p>
<p>Prompt 用的核心三輪 + 兩輪 prompt 專屬：</p>
<table>
  <thead>
      <tr>
          <th>輪</th>
          <th>Frame</th>
          <th>Prompt 專用 checklist</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1</td>
          <td>生成</td>
          <td>寫完任務 / 輸入 / 約束 / 輸出 / 驗收骨架、預期文字粗糙</td>
      </tr>
      <tr>
          <td>2</td>
          <td>對意圖（<a href="/blog/report/ease-of-writing-vs-intent-alignment/" data-link-title="寫作便利度跟意圖對齊反相關" data-link-desc="寫程式時最容易寫出的版本、通常是離意圖最遠的版本。便利度建立在「現有上下文 / 已 materialize 資料 / 已存在 API」上、而意圖對齊需要找到正確的層、處理上游、跨抽象層 — 兩者方向相反。識別這個反相關 = 識別自己掉進「容易寫的陷阱」。">ease-of-writing-vs-intent-alignment</a>）</td>
          <td>自己讀一遍、能想像 LLM 會做出什麼？跟你想要的一致嗎？</td>
      </tr>
      <tr>
          <td>3</td>
          <td>機會成本語氣</td>
          <td>「必須」「不可」翻成具體條件「在 X 條件下做 Y、否則做 Z」</td>
      </tr>
      <tr>
          <td>4''</td>
          <td>模糊指令清查</td>
          <td>grep「對齊 / 靠近 / 適當 / 合理 / 隔離」這類詞、翻成具體數字 / 條件；可用「定義域 / 資料源型態 / 空狀態」三問把模糊詞轉成可驗收條件</td>
      </tr>
      <tr>
          <td>5''</td>
          <td>邊界 case 預期</td>
          <td>「邊界 case 預期行為」明示了嗎？空 input、超大 input、衝突指令各會怎樣？</td>
      </tr>
  </tbody>
</table>
<p>跳輪規則：</p>
<ul>
<li>One-shot quick prompt：跑輪 1-2</li>
<li>Production agent / 反覆執行：全跑、每輪都跑</li>
<li>給多個不同 LLM 用：跑輪 4&rsquo;&rsquo; 兩遍（不同 LLM 對模糊詞解讀差異大）</li>
</ul>
<hr>
<h2 id="反模式速查">反模式速查</h2>
<table>
  <thead>
      <tr>
          <th>反模式</th>
          <th>症狀</th>
          <th>正確做法</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>多任務混合 prompt</td>
          <td>「幫我做 A 和 B 和 C」</td>
          <td>拆為獨立 prompt</td>
      </tr>
      <tr>
          <td>意圖埋在後段</td>
          <td>前三段背景鋪陳，任務在第四段</td>
          <td>第一句即任務</td>
      </tr>
      <tr>
          <td>無輸出格式</td>
          <td>「分析一下」</td>
          <td>指定結構（表格 / 列表 / JSON）</td>
      </tr>
      <tr>
          <td>無理由禁令</td>
          <td>「不要用 X」無理由</td>
          <td>補「因為 Y」</td>
      </tr>
      <tr>
          <td>模糊佔位符</td>
          <td><code>{x}</code>、<code>{var}</code></td>
          <td>snake_case 自說明名</td>
      </tr>
      <tr>
          <td>客套語氣</td>
          <td>「您好，希望您能幫我&hellip;」</td>
          <td>直接下指令</td>
      </tr>
      <tr>
          <td>重複句型</td>
          <td>「當 X 時 Y，當 X2 時 Y2&hellip;」</td>
          <td>表格</td>
      </tr>
      <tr>
          <td>全文貼入規則</td>
          <td>把 500 行規則複製進 prompt</td>
          <td>引用路徑</td>
      </tr>
      <tr>
          <td>欄位混合</td>
          <td>任務 + 約束 + 驗收擠一行</td>
          <td>分欄位列出</td>
      </tr>
      <tr>
          <td>無結構化標記</td>
          <td>純散文</td>
          <td>章節 / 列表 / 表格</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="延伸閱讀">延伸閱讀</h2>
<ul>
<li>Anthropic 官方 Prompt Engineering 文件（platform.claude.com）</li>
<li>Zettelkasten 原子化原則（本 skill <code>writing-documents.md</code> 的原子化章節）</li>
<li>結構化 output（JSON Schema / XML tags）在 AI 工具呼叫的應用</li>
</ul>
]]></content:encoded></item></channel></rss>