Files
ai-code-review/.gitea/ai-review/findings/2026-07-21-16:30:12.json
T
Jeffery 44c33b6c1e
node-actions/template: CI / BUILD (pull_request) Successful in 5s
CI / TEST (Antigravity) (pull_request) Successful in 1m1s
CI / TEST (Codex) (pull_request) Successful in 3m30s
CI / TEST (Claude) (pull_request) Successful in 24s
chore(ai-review 狀態): 回寫本輪已處理 findings
2026-07-21 17:21:57 +08:00

185 lines
11 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"generatedAt": "2026/07/21 16:30:12",
"commitSha": "43ad2b56d27429aa3c812522dc1d4fedce4a9b76",
"prNumber": 6,
"tool": {
"name": "codex",
"version": "codex-cli 0.144.6",
"model": "gpt-5.5"
},
"findings": [],
"excluded": [
{
"reviewer": "Bard",
"focus": "style",
"badge": "🎼",
"severity": "建議",
"file": "readme.md",
"startLine": 48,
"endLine": 48,
"problem": "Mermaid 節點代號從 `N8` 跳回 `N2`,雖然流程語意是「步驟 2 延後」,但原始碼讀起來像旋律突然倒帶;維護者在對照圖與步驟時容易被代號順序絆住。",
"suggestion": "節點 id 建議改用語意名稱,而把顯示文字保留步驟編號。例如 `ResolveOldComments[2 延後將舊留言標記解決...]`,讓圖的原始碼與顯示內容各自清楚。",
"suggestedCode": "",
"id": "F002",
"verdicts": {
"Paladin": {
"exclude": true,
"reason": "可排除(重複)。歷史 findings 已指出流程步驟編號與實際順序、README 流程圖及文件對照會產生認知落差;本條 Mermaid 節點代號問題屬同一類指控。"
}
}
},
{
"reviewer": "Bard",
"focus": "style",
"badge": "🎼",
"severity": "警告",
"file": "src/index.js",
"startLine": 167,
"endLine": 235,
"problem": "`main()` 內新增了建 issue 模式狀態、暫存佇列與三個帶長篇 JSDoc 的閉包,讓主流程的旋律被大量伴奏蓋過。這段同時管理 `issueModeActive`、`trackingIssue`、`pendingIssueCommentBodies` 與 PR 留言 id,可讀性負擔明顯升高。",
"suggestion": "把留言路由與建 issue 暫存邏輯抽成小型 helper(例如 `createCommentRouter`),`main()` 只保留流程編排;JSDoc 也移到 helper 旁,讓主流程步驟重新一眼可讀。",
"suggestedCode": "",
"id": "F003",
"verdicts": {
"Paladin": {
"exclude": true,
"reason": "可排除(重複)。已知排除事項與歷史 findings 已涵蓋 main() 內留言路由、issue 狀態、暫存佇列與發布職責耦合造成可讀性與維護負擔。"
}
}
},
{
"reviewer": "Bard",
"focus": "style",
"badge": "🎼",
"severity": "建議",
"file": "src/lib/gitrepo.js",
"startLine": 121,
"endLine": 128,
"problem": "`strategies` 以陣列位置承載語意,`[label, ...args]` 雖簡短,卻讓每個元素的第二欄之後全靠讀者猜是 git argv;這裡的可讀性像沒有小節線的樂譜。",
"suggestion": "改成物件陣列,明確標出 `label` 與 `args`,可降低後續新增 fetch 策略時的閱讀成本。",
"suggestedCode": "const strategies = [\n { label: 'deepen base', args: ['fetch', '--no-tags', '--deepen=1000', 'origin', `+refs/heads/${baseRef}:refs/remotes/${remoteBase}`] },\n { label: 'deepen PR HEAD', args: ['fetch', '--no-tags', '--deepen=1000', 'origin', headSha] },\n];",
"id": "F005",
"verdicts": {
"Paladin": {
"exclude": true,
"reason": "可排除(重複)。歷史 finding 已針對 resolveMergeBase 內 strategies 與補救策略編排使閱讀節奏偏密提出問題;本條 tuple 可讀性屬同一段策略結構的細項。"
}
}
},
{
"reviewer": "Leo",
"focus": "maintainability",
"badge": "🧰",
"severity": "警告",
"file": "src/index.js",
"startLine": 163,
"endLine": 231,
"problem": "`main()` 這次把一般模式/建問題模式/降級模式的留言去向都塞進閉包狀態:`issueModeActive`、`trackingIssue`、`pendingIssueCommentBodies`、`currentRunCommentIds` 彼此耦合。半年後要新增一種落地方式或調整「何時清舊留言」時,維護者必須同時追多個可變狀態與後續多個 `if (issueModeActive)` 分支,很容易漏掉 flush、清空、登錄留言 id 或 fallback 後的收尾行為。",
"suggestion": "把留言目的地抽成小型物件,讓主流程只呼叫 `commentSink.postContext()`、`commentSink.finalizeAfterFindings()`、`commentSink.postFinding()` 這類語意方法。一般 PR、issue buffering、fallback 的狀態轉換集中在同一個模組或工廠函式內,`main()` 保持審查流程編排,不承擔留言狀態機。",
"suggestedCode": "",
"id": "F006",
"verdicts": {
"Paladin": {
"exclude": true,
"reason": "可排除(重複)。與 F003 及既有排除事項相同,均指向 main() 以可變閉包狀態承擔留言目的地、issue 生命週期與 fallback 狀態機。"
}
}
},
{
"reviewer": "Leo",
"focus": "maintainability",
"badge": "🧰",
"severity": "警告",
"file": "src/index.js",
"startLine": 232,
"endLine": 241,
"problem": "流程註解把「將舊留言標記為解決」稱為「步驟 2(延後執行)」,但實際執行點在審查結果產生後、接近原本步驟 9 前。這種「編號是 2、時間點是 8 後」的設計已經擴散到多個檔案的 JSDoc 與 log 描述,未來查 CI log 或維護流程圖時會產生認知落差:看到 `步驟2` 不代表它真的發生在第二步。",
"suggestion": "不要用固定序號承載流程語意。建議改成穩定階段名稱,例如 `清理舊留言`、`工具偵測`、`diff整理`,或重新編號為實際執行順序並在文件說明「清理舊留言延後到結果產生後」。這樣 log、JSDoc、README 流程圖才不會互相背離。",
"suggestedCode": "",
"id": "F007",
"verdicts": {
"Paladin": {
"exclude": true,
"reason": "可排除(重複)。歷史 findings 已明確記錄步驟編號散落於 log、JSDoc、README 且實際順序變成 1、3 到 8、2、9 到 10 的維護風險。"
}
}
},
{
"reviewer": "Leo",
"focus": "maintainability",
"badge": "🧰",
"severity": "建議",
"file": "src/lib/gitrepo.js",
"startLine": 103,
"endLine": 160,
"problem": "`resolveMergeBase()` 內同時負責驗證 base ref、fetch base、重試 merge-base、補抓淺層歷史、累積診斷與組錯誤訊息。這些都和「取得 merge-base」有關,但現在全部攤在同一個函式裡,策略陣列、診斷格式與 git 操作細節混在一起;未來要新增 fetch 策略或改診斷文字時,容易不小心改壞主流程判斷。",
"suggestion": "把補抓策略與重試邏輯拆成私有 helper,例如 `fetchBaseRef()`、`mergeBaseOrNull()`、`shallowFetchStrategies()`。主函式保留高階流程:驗證 ref → 更新 base → 嘗試 merge-base → 逐一套用策略 → 丟出診斷錯誤。",
"suggestedCode": "",
"id": "F008",
"verdicts": {
"Paladin": {
"exclude": true,
"reason": "可排除(重複)。歷史 finding 已指出 resolveMergeBase 同時負責驗證、fetch 策略編排、診斷與錯誤包裝,難以分辨主流程與補救策略。"
}
}
},
{
"reviewer": "Maya",
"focus": "testing",
"badge": "🧪",
"severity": "警告",
"file": "src/index.js",
"startLine": 164,
"endLine": 232,
"problem": "建問題模式新增了「先暫存情境留言、確定有保留 finding 才建 issue、建 issue 失敗時降級回 PR 留言」這一整段流程,但目前測試只覆蓋了部分 helper,沒有驗證主流程在 create-issue=true 下的分流行為。這代表像「無保留問題時不應建 issue/不應留言」、「建立 issue 失敗時應把 pending 留言補回 PR」、「trackingIssue 建立後後續留言應改送 issue」這些行為都還沒通過試煉。",
"suggestion": "建議把 main 流程拆出可注入 gitea/review/agents/gitrepo 的 orchestrator,或至少匯出可測的流程函式,補上 create-issue=true 的案例:1. kept=[] 時不呼叫 createIssue/createIssueComment2. kept>0 時先 flush pending issue comments 再發 finding3. createIssue 拋錯時 fallbackToPrComments 會發回 PR 並記錄 currentRunCommentIds4. issueModeActive 降級後會走一般 PR 留言與 resolveOldComments。",
"suggestedCode": "",
"id": "F011",
"verdicts": {
"Paladin": {
"exclude": true,
"reason": "可排除(重複)。歷史 findings 已涵蓋建問題模式核心流程、暫存留言、issue 建立條件、發布分流、外部 API 狀態切換與降級路徑缺少測試。"
}
}
},
{
"reviewer": "Maya",
"focus": "testing",
"badge": "🧪",
"severity": "警告",
"file": "src/lib/gitrepo.js",
"startLine": 104,
"endLine": 150,
"problem": "resolveMergeBase 新增了多階段 fetch/deepen/unshallow fallback 與診斷錯誤,但測試只驗證不安全 baseRef 會被拒絕,沒有驗證任何成功或失敗 fallback 路徑。這段是 diff 基準的核心邏輯,若 shallow checkout 下 deepen PR HEAD 用錯 ref、策略順序跑錯,或全部失敗時診斷不正確,現有測試都抓不到。",
"suggestion": "建議用假的 git 執行層或臨時 git repo 補測:首次 merge-base 成功時不跑後續策略;首次失敗但 deepen base 後成功;deepen base 失敗會繼續 deepen PR HEADshallow repo 才嘗試 --unshallow;全部失敗時錯誤訊息包含各策略診斷且保留 cause。",
"suggestedCode": "",
"id": "F012",
"verdicts": {
"Paladin": {
"exclude": true,
"reason": "可排除(重複)。歷史 findings 已針對 resolveMergeBase 多階段 fetch、淺層與非淺層分支、策略停止條件、降級與最終診斷缺少測試提出相同問題。"
}
}
},
{
"reviewer": "Maya",
"focus": "testing",
"badge": "🧪",
"severity": "警告",
"file": "src/lib/gitrepo.js",
"startLine": 272,
"endLine": 322,
"problem": "commitAndPushFindings 改成一律透過 pushWithCredential 用 PAT extraheader 推送,且新增 headRef 安全檢查與固定錯誤遮蔽;但目前 gitrepo 測試沒有覆蓋 commitAndPushFindings/pushWithCredential 的推送行為。這讓「token 不進 argv」、「清掉 checkout 既有 extraheader」、「遠端 URL 不符時拒絕」、「push 失敗不洩漏 URL/token」這些失敗與安全邊界都沒有被驗證。",
"suggestion": "建議以 stub child_process.execFileSync 或可注入 git runner 的方式補測:commit 後呼叫 git push 的 argv 不含 tokenenv 內含 GIT_CONFIG_COUNT 與 Authorization extraheaderheadRef 不安全時在 git add/commit/push 前拋錯;remote origin 不符與 push 失敗時錯誤訊息不包含 token、repo URL 或 Basic header。",
"suggestedCode": "",
"id": "F013",
"verdicts": {
"Paladin": {
"exclude": true,
"reason": "可排除(重複)。歷史 findings 已涵蓋 commitAndPushFindings 與 pushWithCredential 的推送策略、認證遮蔽、失敗路徑與 token 不外洩等測試缺口。"
}
}
}
]
}