185 lines
11 KiB
JSON
185 lines
11 KiB
JSON
{
|
||
"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/createIssueComment;2. kept>0 時先 flush pending issue comments 再發 finding;3. createIssue 拋錯時 fallbackToPrComments 會發回 PR 並記錄 currentRunCommentIds;4. 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 HEAD;shallow 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 不含 token;env 內含 GIT_CONFIG_COUNT 與 Authorization extraheader;headRef 不安全時在 git add/commit/push 前拋錯;remote origin 不符與 push 失敗時錯誤訊息不包含 token、repo URL 或 Basic header。",
|
||
"suggestedCode": "",
|
||
"id": "F013",
|
||
"verdicts": {
|
||
"Paladin": {
|
||
"exclude": true,
|
||
"reason": "可排除(重複)。歷史 findings 已涵蓋 commitAndPushFindings 與 pushWithCredential 的推送策略、認證遮蔽、失敗路徑與 token 不外洩等測試缺口。"
|
||
}
|
||
}
|
||
}
|
||
]
|
||
}
|