diff --git a/readme.md b/readme.md
index 35df151..1d9725d 100644
--- a/readme.md
+++ b/readme.md
@@ -38,13 +38,13 @@ jobs:
```mermaid
flowchart TD
S1[1 判斷 bot commit 標記] -->|命中| E0[直接回報 success/failure]
- S1 -->|未命中| S2[2 偵測 AI 工具並留言]
- S2 --> S3[3 讀 .reviewignore 整理 diff 並留言]
- S3 --> S4[4 攻擊方登場留言]
- S4 --> S5[5 攻擊方 sub agent 並行找問題]
- S5 --> S6[6 防守方登場留言]
- S6 --> S7[7 防守方裁決 → 保存 findings + 誤判回寫 exclusions.json]
- S7 --> S8[8 舊留言標記解決]
+ S1 -->|未命中| S2[2 舊留言標記解決]
+ S2 --> S3[3 偵測 AI 工具並留言]
+ S3 --> S4[4 讀 .reviewignore 整理 diff 並留言]
+ S4 --> S5[5 攻擊方登場留言]
+ S5 --> S6[6 攻擊方 sub agent 並行找問題]
+ S6 --> S7[7 防守方登場留言]
+ S7 --> S8[8 防守方裁決 → 保存 findings + 誤判回寫 exclusions.json]
S8 --> S9[9 嚴重問題逐條掛行留言]
S9 --> S10[10 警告+建議彙整表格留言]
S10 --> E1[收尾 commit/push + exit code]
@@ -104,9 +104,9 @@ flowchart TD
| [roles.loadRoles](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/roles.js#L32) | [載入角色提示檔並解析 frontmatter](#rolesloadroles) |
| [roles.attackersOf](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/roles.js#L71) | [過濾出攻擊方角色](#rolesattackersof) |
| [roles.defendersOf](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/roles.js#L90) | [過濾出防守方角色](#rolesdefendersof) |
-| [templates.toolComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/templates.js#L88) | [產生步驟 2 審查工具留言](#templatestoolcomment) |
-| [templates.diffComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/templates.js#L132) | [產生步驟 3 變更摘要留言](#templatesdiffcomment) |
-| [templates.rolesComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/templates.js#L173) | [產生步驟 4/6 角色登場留言](#templatesrolescomment) |
+| [templates.toolComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/templates.js#L88) | [產生步驟 3 審查工具留言](#templatestoolcomment) |
+| [templates.diffComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/templates.js#L132) | [產生步驟 4 變更摘要留言](#templatesdiffcomment) |
+| [templates.rolesComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/templates.js#L173) | [產生步驟 5/7 角色登場留言](#templatesrolescomment) |
| [templates.severeCommentBody](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/templates.js#L215) | [產生步驟 9 單條嚴重問題留言](#templatesseverecommentbody) |
| [templates.severeReviewBody](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/templates.js#L247) | [產生步驟 9 嚴重問題 review 總覽](#templatesseverereviewbody) |
| [templates.othersComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/templates.js#L277) | [產生步驟 10 警告+建議彙整表格留言](#templatesotherscomment) |
@@ -168,8 +168,8 @@ taipeiFromIso(''); // '—'
```js
const { log } = require('./src/lib/log');
-log('步驟3', 'INF', '變更檔案 5 個,送審 3 個。');
-// [2026/07/17 16:46:13][步驟3][INF]: 變更檔案 5 個,送審 3 個。
+log('步驟4', 'INF', '變更檔案 5 個,送審 3 個。');
+// [2026/07/17 16:46:13][步驟4][INF]: 變更檔案 5 個,送審 3 個。
```
@@ -246,7 +246,7 @@ const committed = gitrepo.commitAndPushFindings(cwd, {
### gitea.whoAmI
-取得 token 對應的使用者(`GET /user`),即 bot 身分;步驟 8 以 `login` 比對留言作者辨識本 action 發過的留言。
+取得 token 對應的使用者(`GET /user`),即 bot 身分;步驟 2 以 `login` 比對留言作者辨識本 action 發過的留言。
```js
const gitea = require('./src/lib/gitea');
@@ -269,7 +269,7 @@ await gitea.createCommentOnIssue(ctx, issue.number, '🔴 嚴重|...');
```js
const created = await gitea.createIssueComment(ctx, '## 📋 變更摘要 ...');
-// created.id 記入本回合留言集合,步驟 8 標註過時時跳過
+// created.id 記入本回合留言集合,步驟 2 標註過時時跳過
```
@@ -294,7 +294,7 @@ const issue = await gitea.createIssue(ctx, { title: 'PR 標題', body: '…', la
### gitea.listIssueComments
-列出 PR 全部一般留言(自動分頁,每頁 50 筆);步驟 8 據此找出 bot 舊留言標註〔已過時〕。
+列出 PR 全部一般留言(自動分頁,每頁 50 筆);步驟 2 據此找出 bot 舊留言標註〔已過時〕。
```js
const comments = await gitea.listIssueComments(ctx);
@@ -303,7 +303,7 @@ const comments = await gitea.listIssueComments(ctx);
### gitea.editIssueComment
-以新內容整段覆寫既有一般留言(留言 id 於 repo 層級定位);步驟 8 用來替舊留言加上〔已過時〕前綴。
+以新內容整段覆寫既有一般留言(留言 id 於 repo 層級定位);步驟 2 用來替舊留言加上〔已過時〕前綴。
```js
await gitea.editIssueComment(ctx, comment.id, `> 〔已過時〕…\n\n${comment.body}`);
@@ -323,7 +323,7 @@ await gitea.createReview(ctx, '## 🔴 嚴重問題(共 2 條)…', [
### gitea.listReviews
-列出 PR 全部 review(自動分頁);步驟 8 據此逐一取出行內留言嘗試解決。
+列出 PR 全部 review(自動分頁);步驟 2 據此逐一取出行內留言嘗試解決。
```js
const reviews = await gitea.listReviews(ctx);
@@ -411,7 +411,7 @@ const defenders = defendersOf(roles); // [Paladin]
### templates.toolComment
-產生步驟 2 的審查工具留言:工具/版本/模型/審查 commit/Run Job 連結表格+審查管線 mermaid 流程圖;開頭含隱藏標記供步驟 8 辨識。
+產生步驟 3 的審查工具留言:工具/版本/模型/審查 commit/Run Job 連結表格+審查管線 mermaid 流程圖;開頭含隱藏標記供步驟 2 辨識。
```js
const body = templates.toolComment({
@@ -424,7 +424,7 @@ const body = templates.toolComment({
### templates.diffComment
-產生步驟 3 的變更摘要留言:四欄表格(檔案/用途/git diff 長度/最後更新時間),截斷送審的檔案加註,結尾統計送審與排除數。
+產生步驟 4 的變更摘要留言:四欄表格(檔案/用途/git diff 長度/最後更新時間),截斷送審的檔案加註,結尾統計送審與排除數。
```js
const body = templates.diffComment(diffRows, ignoredCount);
@@ -433,7 +433,7 @@ const body = templates.diffComment(diffRows, ignoredCount);
### templates.rolesComment
-產生步驟 4/6 共用的角色登場留言:三欄表格(角色/面向/個性),面向以「中文(原文)」並列。
+產生步驟 5/7 共用的角色登場留言:三欄表格(角色/面向/個性),面向以「中文(原文)」並列。
```js
const body = templates.rolesComment({ title: '⚔️ 攻擊方登場', roles: attackers });
@@ -534,7 +534,7 @@ await review.fillPurposes({ tool, model: ctx.model, cwd, diffRows });
### review.runAttackers
-步驟 5:每位攻擊方角色一個 sub agent 並行分析 diff,回覆經檢核標準化後合併為單一問題列表並編派 `F001…` 流水號;單一角色失敗只記 WRN 以空結果代替。
+步驟 6:每位攻擊方角色一個 sub agent 並行分析 diff,回覆經檢核標準化後合併為單一問題列表並編派 `F001…` 流水號;單一角色失敗只記 WRN 以空結果代替。
```js
const findings = await review.runAttackers({ tool, model: ctx.model, cwd, attackers, diffRows });
@@ -543,7 +543,7 @@ const findings = await review.runAttackers({ tool, model: ctx.model, cwd, attack
### review.runDefenders
-步驟 7:每位防守方角色一個 sub agent 配合 `exclusions.json` 與歷史 findings 裁決;「全部防守方都判可排除」才移除,拿不準一律保留,每條附 `verdicts` 供追溯。
+步驟 8:每位防守方角色一個 sub agent 配合 `exclusions.json` 與歷史 findings 裁決;「全部防守方都判可排除」才移除,拿不準一律保留,每條附 `verdicts` 供追溯。
```js
const { kept, excluded } = await review.runDefenders({ tool, model: ctx.model, cwd, defenders, findings });
@@ -600,7 +600,7 @@ if (ctx.createIssue && kept.length > 0) {
### review.resolveOldComments
-步驟 8:bot 舊一般留言(非本回合)編輯加〔已過時〕前綴;review 行內留言盡力呼叫 resolve API,第一次失敗即判定版本不支援並停止。任何失敗只記 WRN 不阻斷。
+步驟 2:bot 舊一般留言(非本回合)編輯加〔已過時〕前綴;review 行內留言盡力呼叫 resolve API,第一次失敗即判定版本不支援並停止。任何失敗只記 WRN 不阻斷。
```js
await review.resolveOldComments({ ctx, gitea, currentRunCommentIds });
diff --git a/src/lib/agents.js b/src/lib/agents.js
index acec87d..e7cfe73 100644
--- a/src/lib/agents.js
+++ b/src/lib/agents.js
@@ -47,7 +47,7 @@ const TOOLS = [
* @returns {{ name: string, buildArgs: Function, resultFrom: string, version: string } | null}
* 中選工具的描述物件(TOOLS 項目加上 version 欄位);所有工具皆不可用時回傳 null。
* @remarks
- * 使用情境:action 主流程(步驟 2)啟動審查前呼叫一次,取得工具描述後交給
+ * 使用情境:action 主流程(步驟 3)啟動審查前呼叫一次,取得工具描述後交給
* runAgent 執行;若回傳 null,主流程會記 ERR 並以失敗收場(無工具即無法審查)。
*/
function detectTool() {
diff --git a/src/lib/gitea.js b/src/lib/gitea.js
index 232c9db..ef71722 100644
--- a/src/lib/gitea.js
+++ b/src/lib/gitea.js
@@ -80,7 +80,7 @@ async function listAll(ctx, apiPath) {
* @returns {Promise