Files
ai-code-review/.gitea/ai-review/exclusions.json
T

949 lines
66 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.
[
{
"addedAt": "2026/07/20 13:53:11",
"prNumber": 6,
"reviewer": "Mage",
"severity": "警告",
"file": "src/index.js",
"startLine": 205,
"endLine": 215,
"problem": "建立 issue 與寫入暫存留言不是可重入操作。最小重現:`createIssue` 成功後,第一則 `createCommentOnIssue` 因暫時性 500 或網路中斷而失敗;主流程退出,但已建立的 issue 不會被記錄或回貼 PR。workflow 重跑時 `issue` 又從 null 開始,因此會再建立一個內容相同的 issue,留下孤兒與重複追蹤項目。後續嚴重問題留言或 PR 回貼失敗也有相同結果。",
"reason": "Paladin:可排除(重複)。與 F004 指涉同一段 issue 建立及暫存留言沖刷流程,也描述相同的中途失敗後重跑會建立重複 issue 問題。"
},
{
"addedAt": "2026/07/20 15:03:30",
"prNumber": 6,
"reviewer": "Leo",
"severity": "警告",
"file": "src/index.js",
"startLine": 205,
"endLine": 218,
"problem": "`ensureIssueCreated` 把「建立 issue」與「逐筆沖刷暫存留言」綁成一個不可恢復的流程。若 issue 已成功建立,但其中一則留言失敗,主流程會中止;下次重跑又會建立另一張 issue,留下重複且內容不完整的追蹤單。半年後維護者也很難從現有狀態判斷應重試留言、沿用既有 issue,還是重新建立。",
"reason": "Paladin:可排除(命中已知排除事項)。其指涉的正是 issue 建立成功、留言沖刷失敗後重跑會產生重複追蹤單的同一問題。"
},
{
"addedAt": "2026/07/20 15:26:21",
"prNumber": 6,
"reviewer": "Leo",
"severity": "警告",
"file": "src/index.js",
"startLine": 179,
"endLine": 234,
"problem": "`main()` 新增了留言路由、issue 狀態、緩衝佇列、issue 建立與緩衝留言沖刷等職責,後續流程又多次以 `ctx.createIssue` 分支決定發布方式。這使主流程同時負責審查編排與發布狀態機;六個月後若再增加發布管道或重試策略,模式判斷會繼續散落,難以獨立測試各種狀態轉換。",
"reason": "Paladin:可排除(重複)。與 F006 指涉同一段 main() 內的留言路由、issue 狀態及緩衝佇列職責,亦提出相同的發布器抽離方向。"
},
{
"addedAt": "2026/07/20 15:26:21",
"prNumber": 6,
"reviewer": "Leo",
"severity": "警告",
"file": "src/index.js",
"startLine": 213,
"endLine": 233,
"problem": "`ensureIssueCreated` 在建立 issue 後逐則寫入 `issueBuffer`,但整段沒有可恢復或冪等機制。若寫到一半 API 失敗,主流程會中止;重新執行時無法辨識已建立但內容不完整的 issue,因而可能再建立一張重複 issue。這類部分完成狀態日後會很難人工清理與追查。",
"reason": "Paladin:可排除(命中已知排除事項且與歷史 finding 重複)。其描述的 issue 建立後沖刷留言失敗、重跑產生重複 issue,正是既有排除事項與歷史 finding 已記錄的問題。"
},
{
"addedAt": "2026/07/20 15:26:21",
"prNumber": 6,
"reviewer": "Leo",
"severity": "建議",
"file": "src/lib/gitea.js",
"startLine": 171,
"endLine": 194,
"problem": "新增並匯出的 `addLabelsToIssue` 沒有被本次流程使用,註解也明確表示主流程已不再需要它。保留這個預想中的通用 API 會擴大公開介面與測試範圍;未來 Gitea API 行為改變時,維護者仍得判斷這個無使用者的函式是否需要同步修改。",
"reason": "Paladin:可排除(重複)。與 F007 指涉相同的未使用 addLabelsToIssue 函式及匯出,問題與移除建議均相同。"
},
{
"addedAt": "2026/07/20 15:26:21",
"prNumber": 6,
"reviewer": "Mage",
"severity": "嚴重",
"file": "src/index.js",
"startLine": 331,
"endLine": 331,
"problem": "建問題模式在此直接建立新的追蹤 issue,卻沒有任何可重入或去重機制。最小重現:issue 建立成功後,寫入 `issueBuffer`、發布 finding、回貼 PR 連結或最後 push 任一步驟失敗,整個 Action 會以失敗結束;重新執行同一個 commit 時仍會再次呼叫 `ensureIssueCreated`,因此產生內容相同的重複 issue。失敗若持續發生,每次重跑都會再新增一筆。",
"reason": "Paladin:可排除(命中已知排除事項且與 F009、歷史 finding 重複)。同樣是建立 issue 後任一步驟失敗,重跑無法沿用既有 issue 而重複建立的問題。"
},
{
"addedAt": "2026/07/20 15:26:21",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/index.js",
"startLine": 190,
"endLine": 238,
"problem": "新增的一般模式/建問題模式留言分流與 `issueBuffer` 清空流程,這次 diff 沒有對應測試。尚未驗證 issue 建立前留言只暫存、建立後依序送出、建立後的新留言直接送往 issue,以及任一 API 寫入失敗時的行為;這是本次建問題模式的核心路徑,沒有測試即無法確認留言不會遺失、重複或誤發到 PR。",
"reason": "Paladin:可排除(與歷史 finding 重複)。歷史 finding 已明確涵蓋建問題模式核心流程、暫存留言依序送出、發布分流及外部 API 狀態切換缺乏測試。"
},
{
"addedAt": "2026/07/20 15:26:21",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/index.js",
"startLine": 312,
"endLine": 389,
"problem": "建問題模式新增了「無 finding 靜默通過」「有 finding 才建 issue」「標籤失敗降級」「嚴重/其他問題分流」「PR 回貼連結」「相依 API 失敗不阻斷」等多個分支,但本次 diff 沒有測試驗證這些結果。尤其 `kept`、`severe`、`others` 的空集合組合與 API 失敗路徑未經試煉,重構後很容易出現 `issue` 為 null 卻被取用、建立空 issue,或意外在 PR 留言。",
"reason": "Paladin:可排除(與歷史 finding 重複)。歷史 finding 已列出有問題才建立 issue、無問題靜默通過、嚴重與非嚴重問題分流、標籤失敗及 PR 回貼等相同未測試分支。"
},
{
"addedAt": "2026/07/20 15:26:21",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/gitrepo.js",
"startLine": 103,
"endLine": 157,
"problem": "`resolveMergeBase` 新增多階段 fetch/重試狀態機,卻沒有新增測試驗證策略順序與停止條件。未驗證非 shallow、`--unshallow` 成功、各 fetch 失敗、補抓後仍無共同祖先等邊界,可能讓正常 checkout 多做 fetch,或在仍可恢復時提早拋錯。",
"reason": "Paladin:可排除(與歷史 finding 重複)。歷史 finding 已針對 resolveMergeBase 的多階段 fetch、淺層與非淺層分支、降級及最終失敗路徑缺少測試提出相同問題。"
},
{
"addedAt": "2026/07/20 15:26:21",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/review.js",
"startLine": 16,
"endLine": 77,
"problem": "新增的失敗診斷與機密遮罩會處理 CI 日誌中的敏感輸出,但本次 diff 沒有測試其邊界與失敗情境。未驗證 debug 預設關閉、大小寫/空白解析、控制字元單行化、各 token 格式遮罩、500 字截斷,以及 `error``stderr``output` 缺漏時仍能穩定回傳摘要。",
"reason": "Paladin:可排除(與歷史 finding 重複)。歷史 finding 已指出 agent 失敗診斷的退出狀態、空輸出、單行化與截斷等邊界缺少測試;本條只是進一步枚舉相同測試缺口。"
},
{
"addedAt": "2026/07/20 15:26:21",
"prNumber": 6,
"reviewer": "Rogue",
"severity": "警告",
"file": "src/index.js",
"startLine": 226,
"endLine": 228,
"problem": "`issueBuffer` 內每則留言以 `await` 串行送出,建立 issue 的等待時間會線性累加為約 `留言數 × API RTT`;若每次往返 200~500 ms,6 則留言便額外卡住約 1.2~3 秒。",
"reason": "Paladin:可排除(誤判)。此處逐筆 await 用來維持暫存留言的 FIFO 發布順序;留言數量有限,所述短暫延遲不足以證明缺陷,而改成並行反而可能破壞順序並增加 API 限流風險。"
},
{
"addedAt": "2026/07/20 15:44:22",
"prNumber": 6,
"reviewer": "Leo",
"severity": "警告",
"file": "src/index.js",
"startLine": 179,
"endLine": 230,
"problem": "建問題模式的狀態管理、留言路由、issue 建立及緩衝區清空都直接塞進已負責整條審查流程的 `main()`,並透過 `issue`、`issueBuffer` 兩個可變閉包共享狀態。後續若再增加重試、不同發布目的地或補償處理,維護者必須同時追蹤閉包狀態與主流程分支;目前 `ensureIssueCreated` 若在逐則寫入緩衝留言時失敗,issue 已建立但狀態沒有可恢復的進度,重跑也可能再建立重複 issue。",
"reason": "Paladin:可排除(命中已知排除事項且重複)。已知排除事項已涵蓋 main() 中留言路由、issue 狀態與緩衝佇列職責散落;其中重跑產生重複 issue 的部分也與歷史 finding 相同。"
},
{
"addedAt": "2026/07/20 15:44:22",
"prNumber": 6,
"reviewer": "Leo",
"severity": "建議",
"file": "src/lib/gitea.js",
"startLine": 171,
"endLine": 195,
"problem": "新增的 `addLabelsToIssue` 沒有任何呼叫端,註解甚至明確說明主流程已不再使用它。現在就保留這個公開匯出會擴大 Gitea client 的 API 表面,未來維護者仍需替它維護文件、測試與版本相容性,卻沒有實際需求驗證其語意。",
"reason": "Paladin:可排除(命中已知排除事項且重複)。已知排除事項已記錄相同的未使用 addLabelsToIssue 函式、公開匯出及移除建議。"
},
{
"addedAt": "2026/07/20 15:44:22",
"prNumber": 6,
"reviewer": "Mage",
"severity": "警告",
"file": "src/index.js",
"startLine": 216,
"endLine": 225,
"problem": "追蹤 issue 的建立與暫存留言寫入不是可重入操作:`createIssue` 成功後,只要任一 `createCommentOnIssue` 失敗,主流程就直接中止,但已建立的 issue 不會回滾或留下可供重跑辨識的狀態。最小重現為:建立 issue 成功、第一則留言遇到暫時性 5xx;workflow 重跑後會再建立一張相同 issue,產生孤兒或重複追蹤問題。",
"reason": "Paladin:可排除(命中已知排除事項且重複)。issue 建立成功、留言失敗後重跑會建立重複 issue,正是已知排除事項及歷史 finding 已記錄的同一問題。"
},
{
"addedAt": "2026/07/20 15:44:22",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/index.js",
"startLine": 184,
"endLine": 374,
"problem": "建問題模式新增了大量分支行為,但本次 diff 沒有對應測試驗證:留言先暫存再依序寫入 issue、無保留問題時靜默通過、標籤挑選失敗時降級、嚴重與非嚴重問題分流、PR 回貼連結,以及建立相依失敗時不中斷流程。這些都是可觀察的核心流程;沒有測試時,任何分支回歸都可能造成漏建 issue、留言送錯位置或流程意外失敗。",
"reason": "Paladin:可排除(與歷史 finding 重複)。歷史 finding 已涵蓋建問題模式的暫存留言、靜默通過、問題分流、標籤失敗及 PR 回貼等核心分支缺少測試。"
},
{
"addedAt": "2026/07/20 15:44:22",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/gitrepo.js",
"startLine": 105,
"endLine": 157,
"problem": "`resolveMergeBase` 新增多階段 fetch/重試策略,卻沒有測試驗證最容易出錯的淺層歷史與失敗路徑,包括非 shallow repo、`--unshallow` 成功後立即停止、某次 fetch 失敗後繼續下一策略,以及全部失敗時的 diagnostics 與 `cause`。這類命令編排很容易因呼叫順序或 off-by-one 次重試而產生多餘網路請求,甚至在其實可取得 merge-base 時仍失敗。",
"reason": "Paladin:可排除(與歷史 finding 重複)。歷史 finding 已指出 resolveMergeBase 多階段 fetch 在淺層、非淺層、降級及最終失敗路徑缺少測試。"
},
{
"addedAt": "2026/07/20 15:44:22",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/review.js",
"startLine": 17,
"endLine": 81,
"problem": "新增的 AI CLI 失敗診斷只在失敗與 debug 模式執行,但沒有測試覆蓋其邊界:`res`/`error` 缺值、逾時與 signal、debug 大小寫及空白、控制字元單行化、500 字截斷,以及多種 token/URL 帳密遮罩。這些失敗路徑若回歸,可能使診斷完全缺失或將未遮罩內容寫入 CI log。",
"reason": "Paladin:可排除(與歷史 finding 重複)。歷史 finding 已記錄 AI CLI 失敗診斷在退出狀態、空輸出、單行化、截斷及相關邊界缺少測試;本條是對同一測試缺口的細項枚舉。"
},
{
"addedAt": "2026/07/20 15:57:46",
"prNumber": 6,
"reviewer": "Mage",
"severity": "嚴重",
"file": "src/index.js",
"startLine": 268,
"endLine": 268,
"problem": "舊審查留言仍在本回合結果完整發布前就被標記為過時;建議把清理舊留言移到本輪所有必要結果均成功產生之後,避免失敗重跑留下「舊結果已清除、新結果不完整」的中間狀態。",
"reason": "維護者裁示(議題 #8 留言 #4838,系統管理員):此功能用途為把前一輪 PR 產生的訊息標記為已解決/過時,讓審查人員辨識舊訊息,因此刻意在本回合結果之前執行,不可延後,否則會誤導審查人員。依維護者決定不採納此修改,記為排除以免後續審查重複提出。"
},
{
"addedAt": "2026/07/20 16:03:44",
"prNumber": 6,
"reviewer": "Assassin",
"severity": "嚴重",
"file": "src/lib/review.js",
"startLine": 54,
"endLine": 75,
"problem": "開啟 `ACTIONS_STEP_DEBUG=true` 後會把 AI CLI 的原始 stderr/stdout 寫入永久 CI log,但 `redactSecrets` 是可繞過的黑名單,也完全沒有移除 PII。攻擊者可透過惡意 diff/提示注入,要求 CLI 以未涵蓋的格式輸出憑證、電子郵件或其他敏感資料;例如短版金鑰、含標點的 token、JWT 或拆段輸出都可能避開現有正規表示式,造成機密與 PII 外洩。",
"reason": "Paladin:可排除(重複)。歷史 finding 已針對 debug 模式輸出 AI CLI stderr/stdout、黑名單遮罩可繞過及敏感內容外洩提出相同問題。"
},
{
"addedAt": "2026/07/20 16:03:44",
"prNumber": 6,
"reviewer": "Bard",
"severity": "建議",
"file": "src/index.js",
"startLine": 220,
"endLine": 231,
"problem": "`ensureIssueCreated` 之名暗示「若尚未建立才建立」的冪等保證,實作卻會無條件建立新 issue。即使目前只呼叫一次,命名仍會誤導後續維護者,長註解也無法替代準確的動詞。",
"reason": "Paladin:可排除(重複)。歷史 finding 已明確指出 `ensureIssueCreated` 名稱暗示冪等沿用,實際卻建立新 issue 並修改外層狀態。"
},
{
"addedAt": "2026/07/20 16:03:44",
"prNumber": 6,
"reviewer": "Bard",
"severity": "建議",
"file": "action.yml",
"startLine": 45,
"endLine": 57,
"problem": "新增的 `push-token` 以區塊註解、欄位描述、選填註解與預設值註解反覆敘述「PAT 觸發 CI、留空退回 token」;同一旋律重奏過多,真正重要的使用方式反而埋在十餘行說明裡,且明顯比鄰近 input 冗長。",
"reason": "Paladin:可排除(重複)。歷史 finding 已針對 `push-token` 在註解、description、required 與 default 說明中重複敘述相同問題。"
},
{
"addedAt": "2026/07/20 16:03:44",
"prNumber": 6,
"reviewer": "Leo",
"severity": "警告",
"file": "src/index.js",
"startLine": 180,
"endLine": 234,
"problem": "`main()` 新增 `issueBuffer`、可變的 `issue`、`postComment` 與 `ensureIssueCreated`,把「決定留言目的地、建立 issue、暫存與沖刷留言」等多項職責綁在閉包狀態中。後續流程又必須知道 issue 是否已建立並直接讀取 `issue.number`;半年後若增加留言種類、重試或其他發布目的地,維護者得同時修改多個分支,也很難隔離單元測試發布狀態轉換。",
"reason": "Paladin:可排除(命中已知排除事項且重複)。已知排除事項與歷史 finding 均已涵蓋 `main()` 內留言路由、issue 狀態、緩衝佇列及發布職責耦合的問題。"
},
{
"addedAt": "2026/07/20 16:03:44",
"prNumber": 6,
"reviewer": "Leo",
"severity": "警告",
"file": "src/index.js",
"startLine": 221,
"endLine": 234,
"problem": "`ensureIssueCreated` 在所有暫存留言成功寫入前,就先把閉包中的 `issue` 設為已建立;沖刷途中任何一則 API 呼叫失敗,都會留下只寫入部分內容的 issue,且主流程沒有保存進度或可重入機制。重新執行時又會建立另一個 issue。這種部分完成狀態日後很難追查,也會讓重試與錯誤處理持續累積例外分支。",
"reason": "Paladin:可排除(命中已知排除事項且重複)。issue 建立後沖刷留言失敗、留下部分完成狀態並在重跑時建立重複 issue,正是既有排除事項與歷史 finding 記錄的同一問題。"
},
{
"addedAt": "2026/07/20 16:03:44",
"prNumber": 6,
"reviewer": "Mage",
"severity": "嚴重",
"file": "src/index.js",
"startLine": 342,
"endLine": 344,
"problem": "一般模式在發布新的嚴重/警告留言前,就先把舊審查留言標為過時。最小重現:`resolveOldComments` 成功後,步驟 9 的 `createReview` 或步驟 10 的留言 API 暫時失敗;本次 action 以失敗結束,但上一回合完整結果已被清除,新結果也未完整發布,PR 會失去可信的審查結果。這仍違反本次改動宣稱的「沒有新結果時保留舊結果」語義。",
"reason": "Paladin:可排除(命中已知排除事項)。維護者已明確裁示舊留言必須刻意在本回合結果之前標記為過時,以免舊資訊繼續誤導審查人員。"
},
{
"addedAt": "2026/07/20 16:03:44",
"prNumber": 6,
"reviewer": "Mage",
"severity": "警告",
"file": "src/index.js",
"startLine": 224,
"endLine": 233,
"problem": "追蹤 issue 的建立與暫存留言寫入不是可重入操作。最小重現:`createIssue` 成功,但寫入 `issueBuffer` 第 2 則留言時 API 失敗;action 結束前沒有在 PR 留下連結或保存已建立的 issue 編號。工作流程重跑時會再建立一個新 issue,留下孤立且內容不完整的舊 issue,並可能持續產生重複 issue。",
"reason": "Paladin:可排除(命中已知排除事項且重複)。建立 issue 後留言寫入失敗、未保存可恢復狀態而使重跑建立重複 issue,已由多筆既有排除事項及歷史 finding 完整涵蓋。"
},
{
"addedAt": "2026/07/20 16:03:44",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/index.js",
"startLine": 311,
"endLine": 386,
"problem": "建問題模式的核心流程已大幅改寫,但本次 diff 沒有對應測試驗證:有保留問題時才建立 issue、標籤失敗時降級、暫存留言依序送出、嚴重與其他問題分流、PR 回貼連結,以及相依 API 失敗不阻斷流程。這些分支牽涉多次外部呼叫與狀態變化,未經測試容易出現 issue 未建立卻存取 `issue.number`、留言遺失或呼叫順序錯誤。",
"reason": "Paladin:可排除(重複)。歷史 finding 已涵蓋建問題模式的 issue 建立條件、標籤降級、暫存留言、問題分流、PR 回貼及相依 API 失敗等核心分支缺少測試。"
},
{
"addedAt": "2026/07/20 16:03:44",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/gitrepo.js",
"startLine": 103,
"endLine": 151,
"problem": "`resolveMergeBase` 新增多階段 fetch 復原與錯誤診斷,但沒有測試覆蓋淺層與失敗路徑。尚未驗證 unshallow 成功後會立即停止、fetch 失敗會繼續下一策略、非淺層 repo 不會執行 unshallow,以及所有策略失敗時的錯誤與 `cause` 是否正確;這類 git 邊界通常只會在 CI 的 shallow checkout 才暴露。",
"reason": "Paladin:可排除(重複)。歷史 finding 已針對 `resolveMergeBase` 的淺層與非淺層分支、多階段 fetch、停止條件及最終錯誤資訊缺少測試提出相同問題。"
},
{
"addedAt": "2026/07/20 16:03:44",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/gitrepo.js",
"startLine": 270,
"endLine": 313,
"problem": "新增的 PAT 推送與憑證注入路徑沒有對應測試。尚未驗證有 `pushToken` 時必須略過 origin、無 `pushToken` 時只有 origin 失敗才使用一般 token、Authorization 僅透過環境變數傳入,以及推送失敗時不會把 token、遠端 URL或原始命令帶入錯誤。這些未驗證行為同時影響 CI 是否重觸發與失敗路徑的機密保護。",
"reason": "Paladin:可排除(重複)。歷史 finding 已明確記錄 pushToken、origin 與一般 token 的兩套推送策略、認證資訊遮蔽及失敗路徑缺少測試。"
},
{
"addedAt": "2026/07/20 16:03:44",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/review.js",
"startLine": 16,
"endLine": 80,
"problem": "新增的失敗診斷與機密遮罩會處理不可信的 stderr/stdout,但沒有測試驗證邊界與失敗格式。特別是換行控制字元、Authorization、URL 帳密、各種 token 格式、超長輸出截斷,以及 `ACTIONS_STEP_DEBUG` 開關;任何漏測都可能造成除錯模式洩漏機密或產生可偽造的多行 CI 日誌。",
"reason": "Paladin:可排除(重複)。歷史 finding 已涵蓋 `redactSecrets``agentFailureDetail` 對控制字元、各類憑證、URL 帳密、截斷及 debug 開關等邊界缺少測試。"
},
{
"addedAt": "2026/07/20 16:03:44",
"prNumber": 6,
"reviewer": "Rogue",
"severity": "警告",
"file": "src/index.js",
"startLine": 224,
"endLine": 226,
"problem": "`issueBuffer` 內每則留言都逐一 `await` 遠端 API,總耗時為 O(n × API RTT)。目前固定情境留言也會累加多次網路往返;若日後增加階段,等待時間會線性成長。",
"reason": "Paladin:可排除(命中已知排除事項)。逐筆 `await` 是為維持暫存留言的 FIFO 發布順序,留言數量有限;現有證據不足以證明延遲構成缺陷,而並行發送會增加順序不確定及 API 限流風險。"
},
{
"addedAt": "2026/07/20 16:20:39",
"prNumber": 6,
"reviewer": "Assassin",
"severity": "嚴重",
"file": "src/lib/review.js",
"startLine": 73,
"endLine": 74,
"problem": "攻擊者可在 PR diff 中植入不符合現有正規表示式的機密或 PII,再誘使 AI CLI 失敗並將提示內容回顯至 stderr;此處預設把前 500 字寫入 CI log。`redactSecrets` 僅是樣式黑名單,無法遮蔽電子郵件、短 token、含特殊符號的憑證或原始碼敏感資料,會形成可長期讀取的資料外洩通道。",
"reason": "Paladin:可排除(重複)。歷史 finding 已針對除錯模式輸出 AI CLI stderr/stdout、黑名單式遮罩可繞過,以及敏感內容或 PII 外洩提出相同問題。"
},
{
"addedAt": "2026/07/20 16:20:39",
"prNumber": 6,
"reviewer": "Bard",
"severity": "建議",
"file": "src/index.js",
"startLine": 179,
"endLine": 232,
"problem": "`main()` 新增了 `issueBuffer`、可變的 `issue`,以及兩個捕捉外部狀態的區域函式,使原本已相當冗長的流程編排同時承擔留言路由、緩衝、issue 建立與緩衝區清空等細節。尤其 `ensureIssueCreated` 這個名稱暗示可重複安全呼叫,實作卻會無條件建立新 issue,名稱與行為並不押韻。",
"reason": "Paladin:可排除(重複)。歷史 findings 已分別涵蓋 main() 承擔留言路由與 issue 狀態管理,以及 ensureIssueCreated 名稱暗示冪等、實際卻建立新 issue 的問題。"
},
{
"addedAt": "2026/07/20 16:20:39",
"prNumber": 6,
"reviewer": "Bard",
"severity": "建議",
"file": "action.yml",
"startLine": 47,
"endLine": 58,
"problem": "`push-token` 周圍的註解重複敘述 PAT、CI 再觸發、步驟 1 快速回報與空值退回行為,且 `description` 又把同一段旋律再奏一次。Action manifest 因實作細節過密而難以快速掃讀,也與其他 input 較精簡的註解密度不一致。",
"reason": "Paladin:可排除(重複)。歷史 finding 與已知排除事項已記錄 push-token 在註解、description、required 與 default 說明中重複敘述相同資訊。"
},
{
"addedAt": "2026/07/20 16:20:39",
"prNumber": 6,
"reviewer": "Leo",
"severity": "警告",
"file": "src/index.js",
"startLine": 181,
"endLine": 231,
"problem": "`main()` 新增以 `issueBuffer`、`issue` 及兩個閉包管理追蹤 issue,後續又在主流程內負責挑標籤、建立 issue、排空留言、發布各類問題、回貼 PR 與設定相依關係。建問題模式的狀態與發布規則因此散落於整個超長函式;未來新增留言種類或調整建立時機時,維護者必須同步追蹤多處 `ctx.createIssue` 分支與可變閉包狀態,容易漏改,也難以獨立單元測試部分失敗及重試行為。",
"reason": "Paladin:可排除(命中已知排除事項且重複)。既有紀錄已涵蓋 main() 內留言路由、issue 生命週期、緩衝佇列及發布職責耦合,並提出相同的發布器抽離方向。"
},
{
"addedAt": "2026/07/20 16:20:39",
"prNumber": 6,
"reviewer": "Mage",
"severity": "嚴重",
"file": "src/index.js",
"startLine": 345,
"endLine": 347,
"problem": "舊留言在新問題留言真正發布成功前就被標記為過時。最小重現:`resolveOldComments` 成功後,步驟 9 的 `postSevereComments` 或步驟 10 的 `postComment` 因暫時性 API 錯誤失敗;本次流程以例外結束,但舊審查結果已被清除,PR 上只剩工具/角色等情境留言,沒有任何有效 finding。這仍違反此次延後清理所宣稱的「成功產生結果後才執行」語義。",
"reason": "Paladin:可排除(命中已知排除事項)。維護者已明確裁示舊留言應刻意在本回合結果發布前標記為過時,以免舊資訊持續誤導審查人員。"
},
{
"addedAt": "2026/07/20 16:20:39",
"prNumber": 6,
"reviewer": "Mage",
"severity": "警告",
"file": "src/index.js",
"startLine": 219,
"endLine": 229,
"problem": "建立追蹤 issue 與寫入暫存留言不是可恢復的原子流程。最小重現:`createIssue` 成功,但寫入第 2 則 `issueBuffer` 留言時 API 失敗;流程中止後已留下內容不完整且沒有 PR 回鏈的 issue,下次重跑又會建立另一個 issue,造成重複追蹤與狀態分歧。後續 PR 回鏈、相依設定或 commit/push 失敗也有相同的重跑問題。",
"reason": "Paladin:可排除(命中已知排除事項且重複)。建立 issue 後留言或後續步驟失敗、重跑無法沿用既有 issue 而產生孤兒或重複 issue,已由多筆既有紀錄完整涵蓋。"
},
{
"addedAt": "2026/07/20 16:20:39",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/gitrepo.js",
"startLine": 105,
"endLine": 157,
"problem": "`resolveMergeBase` 新增多階段 fetchmerge-base 復原流程,但本次變更沒有對應測試。淺層與非淺層儲存庫、fetch 失敗後繼續、任一策略成功即停止,以及全部失敗時的診斷與 `cause` 都是新增行為;沒有驗證就可能在 runner 的 shallow checkout 上才暴露錯誤或多餘 fetch。",
"reason": "Paladin:可排除(重複)。歷史 finding 已記錄 resolveMergeBase 多階段 fetch 在淺層、非淺層、策略停止、降級與最終失敗診斷等路徑缺少測試。"
},
{
"addedAt": "2026/07/20 16:20:39",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/gitrepo.js",
"startLine": 247,
"endLine": 311,
"problem": "新增 `pushToken` 與 `pushWithCredential` 後,推送分支及失敗路徑未見測試覆蓋。尚未驗證有 PAT 時確實略過 origin、無 PAT 時先推 origin 再以 `token` 降級、認證只進環境變數,以及失敗錯誤不帶 token/遠端 URL;這些都是本次新增且直接影響結果 commit 能否推送的行為。",
"reason": "Paladin:可排除(重複)。歷史 finding 已涵蓋 pushToken、origin 與一般 token 的推送策略、呼叫順序、認證遮蔽及失敗路徑缺少測試。"
},
{
"addedAt": "2026/07/20 16:20:39",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/index.js",
"startLine": 309,
"endLine": 386,
"problem": "建問題模式改成「有保留問題才建 issue」、緩衝留言、逐類發布、回貼 PR 與設定相依關係,但本次沒有流程測試驗證這組新增分支。尤其 `kept` 為空、只有嚴重問題、只有警告/建議、標籤挑選失敗,以及相依 API 失敗降級等路徑,若接線錯誤可能造成漏留言、對 `null` issue 取值,或非預期中斷審查。",
"reason": "Paladin:可排除(重複)。歷史 findings 已涵蓋建問題模式的 issue 建立條件、暫存留言、問題分流、標籤降級、PR 回貼及相依 API 失敗等核心分支缺少測試。"
},
{
"addedAt": "2026/07/20 16:20:39",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/review.js",
"startLine": 16,
"endLine": 85,
"problem": "新增的失敗診斷與機密遮罩沒有對應測試,尚未驗證空值、控制字元、多種 token 格式、URL 內嵌帳密、5002000 字截斷邊界,以及 `ACTIONS_STEP_DEBUG` 開關。這段程式會處理失敗路徑中的非可信 CLI 輸出;若正規表示式或截斷順序退化,測試無法及時發現機密殘留或假日誌換行。",
"reason": "Paladin:可排除(重複)。歷史 finding 已逐項記錄失敗診斷與遮罩對空值、控制字元、各類憑證、URL 帳密、截斷及 ACTIONS_STEP_DEBUG 開關缺少測試。"
},
{
"addedAt": "2026/07/20 16:20:39",
"prNumber": 6,
"reviewer": "Maya",
"severity": "建議",
"file": "src/lib/gitea.js",
"startLine": 171,
"endLine": 181,
"problem": "新 API `addIssueDependency` 未見測試驗證 endpoint 與 IssueMeta payload。`issueNumber` 與 `dependency` 的方向一旦顛倒,請求仍可能成功,卻會建立相反的阻擋關係;只靠主流程成功測試不容易察覺。",
"reason": "Paladin:可排除(重複)。歷史 finding 已指出 addIssueDependency 缺少 endpoint、HTTP method、payload 與相依方向的測試,與本條指控相同。"
},
{
"addedAt": "2026/07/20 16:39:40",
"prNumber": 6,
"reviewer": "Assassin",
"severity": "嚴重",
"file": "src/lib/review.js",
"startLine": 74,
"endLine": 77,
"problem": "攻擊者可在 PR diff 中植入機密或個資,誘使 AI CLI 在失敗時原樣回顯;此處卻預設把 stderr 與 stdout 寫入長期保存的 CI log。`redactSecrets()` 只是可繞過的黑名單,例如 `Authorization: Bearer <憑證>` 只會遮掉 `Bearer`,後方憑證仍會留下,且電子郵件、姓名、短 token 與未知格式完全不會被遮罩,違反回應不得含 PII 的規範。",
"reason": "Paladin:可排除(重複)。歷史 finding 已指出除錯模式輸出 AI CLI stderr/stdout、黑名單式遮罩可繞過,以及機密或個資外洩的相同問題。"
},
{
"addedAt": "2026/07/20 16:39:40",
"prNumber": 6,
"reviewer": "Bard",
"severity": "建議",
"file": "src/index.js",
"startLine": 183,
"endLine": 229,
"problem": "新增的 `postComment`、`ensureIssueCreated`、`issueBuffer` 與可變的 `issue` 全部嵌在本就冗長的 `main()` 中,且第二個函式透過閉包同時讀寫多個外部狀態。讀者要在主流程、留言路由與 issue 生命週期三條旋律間來回切換,主流程輪廓因此被大量細節淹沒。",
"reason": "Paladin:可排除(重複)。與 F005 及歷史 finding 指涉相同的 main() 職責膨脹、閉包狀態與 issue 發布流程耦合問題。"
},
{
"addedAt": "2026/07/20 16:39:40",
"prNumber": 6,
"reviewer": "Leo",
"severity": "警告",
"file": "src/index.js",
"startLine": 181,
"endLine": 229,
"problem": "`main()` 新增了 `issueBuffer`、`issue`、`postComment` 與 `ensureIssueCreated` 等可變狀態及閉包,並在後續流程散落多個 `ctx.createIssue` 分支。留言路由、issue 建立、緩衝區清空與主審查編排因此緊密耦合;半年後新增第三種發布方式或調整 issue 建立時機時,維護者必須同時追蹤整個 `main()` 的狀態轉移,也很難獨立單元測試發布行為。",
"reason": "Paladin:可排除(命中已知排除事項且重複)。既有紀錄已涵蓋 main() 內留言路由、issue 狀態、緩衝佇列與發布職責耦合的問題。"
},
{
"addedAt": "2026/07/20 16:39:40",
"prNumber": 6,
"reviewer": "Leo",
"severity": "警告",
"file": "src/index.js",
"startLine": 344,
"endLine": 382,
"problem": "一般模式在嚴重問題與彙整留言發布前就呼叫 `resolveOldComments`。若後續 `postSevereComments` 或 `postComment` 因 API 暫時失敗而中斷,舊的完整審查結果已被標成過時,新回合卻只留下工具、diff、角色等情境留言。這與本次變更宣稱的「成功產生結果後才清舊留言」保證不一致,也讓未來維護者難以判斷何時才算發布完成。",
"reason": "Paladin:可排除(命中已知排除事項)。維護者已明確裁示舊留言須刻意在本回合結果發布前標記為過時,以免舊資訊繼續誤導審查人員。"
},
{
"addedAt": "2026/07/20 16:39:40",
"prNumber": 6,
"reviewer": "Mage",
"severity": "嚴重",
"file": "src/index.js",
"startLine": 213,
"endLine": 225,
"problem": "建立追蹤 issue 與寫入暫存留言不是原子操作。最小重現:`gitea.createIssue` 成功後,第 2 則 `createCommentOnIssue` 因暫時性 API 錯誤失敗;主流程會中止,但遠端已留下內容不完整的 issue。工作重跑時沒有查找或續寫既有 issue 的機制,因此會再建立一張重複 issue,且先前已成功寫入的留言也可能重複。",
"reason": "Paladin:可排除(命中已知排除事項且重複)。建立 issue 後沖刷暫存留言失敗、重跑產生孤兒或重複 issue,已由多筆既有紀錄完整涵蓋。"
},
{
"addedAt": "2026/07/20 16:39:40",
"prNumber": 6,
"reviewer": "Mage",
"severity": "嚴重",
"file": "src/index.js",
"startLine": 342,
"endLine": 344,
"problem": "舊審查留言仍在新結果完整發布前被標記為過時。最小重現:防守方裁決與 findings 寫檔成功後,`resolveOldComments` 先清除舊結果;接著 `postSevereComments`、`postComment` 或最後的 commit/push 任一步失敗,流程便以失敗結束,PR 上只剩工具/角色等情境留言,既有問題已過時、新問題卻未完整發布。這仍違反本次改動宣稱的「失敗時保留舊結果」語義。",
"reason": "Paladin:可排除(命中已知排除事項且與 F006 重複)。維護者已裁示不得將舊留言清理延後至新結果完整發布之後。"
},
{
"addedAt": "2026/07/20 16:39:40",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/gitrepo.js",
"startLine": 105,
"endLine": 159,
"problem": "新增的 merge-base 補抓流程沒有對應測試驗證。尚未確認非淺層/淺層 repository、首次 fetch 失敗、unshallow 成功、deepen base 或 HEAD 才成功,以及所有策略失敗時的診斷與 `cause`;這些分支會直接決定送審 diff 的基準,未經試煉仍可能漏審或錯審。",
"reason": "Paladin:可排除(重複)。歷史 finding 已記錄 resolveMergeBase 多階段 fetch 在淺層、非淺層、停止條件、降級與最終失敗診斷等路徑缺少測試。"
},
{
"addedAt": "2026/07/20 16:39:40",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/gitrepo.js",
"startLine": 267,
"endLine": 308,
"problem": "新增的 `pushToken` 推送分流與 `pushWithCredential` 失敗降級沒有測試覆蓋。尚未驗證有 PAT 時確實略過 origin、無 PAT 時 origin 成功不重試、origin 失敗才使用一般 token,以及認證環境變數與固定錯誤訊息不會帶出 token;這是本次 CI 再觸發機制的核心行為。",
"reason": "Paladin:可排除(重複)。歷史 finding 已涵蓋 pushToken、origin 與一般 token 的推送策略、呼叫順序、認證遮蔽及失敗路徑缺少測試。"
},
{
"addedAt": "2026/07/20 16:39:40",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/index.js",
"startLine": 309,
"endLine": 387,
"problem": "建問題模式被大幅改寫,但 diff 中沒有測試驗證各分支的外部行為。尤其 `kept` 為空時必須不建 issue、不碰 PR 留言;有問題時必須依序建立 issue、沖出暫存留言、發布各類 finding、回貼 PR 連結;標籤挑選與相依 API 失敗又必須降級而不中斷。這些成功與失敗路徑目前都未被驗證。",
"reason": "Paladin:可排除(重複)。歷史 findings 已涵蓋建問題模式的 issue 建立條件、暫存留言、問題分流、標籤降級、PR 回貼及相依 API 失敗等核心分支缺少測試。"
},
{
"addedAt": "2026/07/20 16:39:40",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/review.js",
"startLine": 16,
"endLine": 82,
"problem": "新增的失敗診斷與機密遮罩邏輯沒有測試驗證邊界。尚未確認 Authorization、token/password/secret、URL 內嵌帳密、GitHub 樣式 token、長字串、控制字元,以及機密剛好跨越 2,000 字截斷邊界時是否仍會被完整遮蔽;也未驗證 timeout、數字/字串 code、signal 與空輸出的摘要。",
"reason": "Paladin:可排除(重複)。歷史 finding 已涵蓋失敗診斷與遮罩對空值、控制字元、各類憑證、URL 帳密、截斷及退出狀態等邊界缺少測試。"
},
{
"addedAt": "2026/07/20 16:39:40",
"prNumber": 6,
"reviewer": "Maya",
"severity": "建議",
"file": "src/lib/gitea.js",
"startLine": 171,
"endLine": 195,
"problem": "新加入的 `addIssueDependency` API 封裝沒有契約測試,尚未驗證 URL 中使用相依方 PR 編號,而 request body 的 `index` 使用阻擋來源 issue 編號;兩者若對調,請求可能仍是合法格式,卻會建立反向的相依關係。",
"reason": "Paladin:可排除(重複)。歷史 finding 已指出 addIssueDependency 缺少 endpoint、HTTP method、payload 與相依方向的契約測試。"
},
{
"addedAt": "2026/07/20 17:21:16",
"prNumber": 6,
"reviewer": "Assassin",
"severity": "嚴重",
"file": "src/lib/review.js",
"startLine": 70,
"endLine": 73,
"problem": "攻擊者可以把惡意內容塞進 PR diff 或 AI 工具輸出,誘使 AI CLI 在失敗時把環境變數、原始碼片段、token、PR 內容或 PII 印到 stdout/stderr;這裡預設把 stdout/stderr 前 500 字寫進 CI log。`redactSecrets` 只是黑名單式遮罩,擋不住 Gitea PAT、JWT、雲端金鑰、短 token、帶標點的密碼或一般 PII。尤其本 PR 又新增 `push-token` PAT,失敗診斷變成一條可被 prompt injection 利用的外洩通道。",
"reason": "Paladin:可排除(重複)。歷史 finding 已針對 debug/失敗診斷輸出 AI CLI stdout/stderr、黑名單式遮罩可繞過,以及機密或個資外洩提出相同問題。"
},
{
"addedAt": "2026/07/20 17:21:16",
"prNumber": 6,
"reviewer": "Leo",
"severity": "警告",
"file": "src/index.js",
"startLine": 180,
"endLine": 365,
"problem": "`main()` 這次把「留言目的地切換、issue 暫存與 flush、標籤挑選、PR 回貼、issue dependency、舊留言清理時機」全部塞進同一段流程。半年後要改建問題模式時,維護者必須同時理解 `ctx.createIssue`、`issue`、`issueBuffer`、`currentRunCommentIds` 這幾個閉包狀態的互動,任何一個留言新增在錯誤位置,都可能變成被暫存後丟棄、發錯地方,或被舊留言清理誤處理。這不是單純長度問題,而是 orchestration 和 delivery policy 已經耦合在一起。",
"reason": "Paladin:可排除(命中已知排除事項且重複)。既有紀錄已涵蓋 main() 內留言路由、issue 狀態、緩衝佇列與發布職責耦合的問題;本條只是擴充描述同一設計負擔。"
},
{
"addedAt": "2026/07/20 17:21:16",
"prNumber": 6,
"reviewer": "Leo",
"severity": "建議",
"file": "src/lib/review.js",
"startLine": 30,
"endLine": 39,
"problem": "`agentFailureDetail()` 的說明文字前後不一致:開頭說「原始輸出預設隱藏」,下一段又說失敗時預設附上遮罩後的 stderr/stdout 片段。這種註解矛盾會讓未來維護者不確定目前政策到底是偏向保守隱藏,還是偏向可診斷輸出,尤其這段又是多個 AI CLI 失敗路徑共用的行為。",
"reason": "Paladin:可排除(列表內重複)。與 F002 指涉同一段 agentFailureDetail 註解前後政策描述不一致的問題。"
},
{
"addedAt": "2026/07/20 17:21:16",
"prNumber": 6,
"reviewer": "Mage",
"severity": "警告",
"file": "src/index.js",
"startLine": 213,
"endLine": 224,
"problem": "`ensureIssueCreated` 先建立追蹤 issue,再逐則寫入 `issueBuffer`。只要 issue 建立成功後任一 buffered comment 發生暫時性 API 失敗,例外會往上拋出,action 以失敗結束,但已建立的 issue 不會回滾,也沒有被記錄成可重用狀態。\n\n最小重現情境:`create-issue=true`、有保留問題;`gitea.createIssue` 成功建立 #10;第一則 `createCommentOnIssue` timeout。這次 run 失敗;下次重跑又建立 #11,造成重複追蹤 issue,且 PR 可能沒有任何連結指向第一次建立的 issue。",
"reason": "Paladin:可排除(命中已知排除事項且重複)。issue 建立成功後 buffered comment 失敗、重跑產生重複追蹤 issue,正是既有排除事項與歷史 finding 已裁定涵蓋的同一問題。"
},
{
"addedAt": "2026/07/20 17:21:16",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/index.js",
"startLine": 309,
"endLine": 381,
"problem": "建問題模式這次改了主要行為:有保留問題時才建 issue、先暫存工具/diff/角色留言、之後逐條留言到 issue、再回貼 PR 連結並建立 dependency;但 diff 沒看到對應測試。這條路徑牽涉多個外部 API 呼叫與順序,沒有測試就無法驗證「PR 只留連結、issue 收到完整內容、無保留問題時靜默通過」這些新契約。",
"reason": "Paladin:可排除(重複)。歷史 findings 已涵蓋建問題模式有 finding 才建 issue、暫存留言 flush、PR 只回貼連結、dependency 失敗降級等核心分支缺少測試。"
},
{
"addedAt": "2026/07/20 17:21:16",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/gitrepo.js",
"startLine": 102,
"endLine": 146,
"problem": "`resolveMergeBase` 新增了多段 fetch fallback(明確更新 base、淺層時 unshallow、deepen base、deepen HEAD)以及失敗診斷,但沒有看到測試覆蓋這些邊界與失敗路徑。這段是 diff 基準來源;只要淺層 checkout 或 fetch 策略順序沒被驗證,審查範圍可能整個錯掉。",
"reason": "Paladin:可排除(重複)。歷史 findings 已指出 resolveMergeBase 多階段 fetch、淺層與非淺層路徑、停止條件及最終失敗診斷缺少測試。"
},
{
"addedAt": "2026/07/20 17:21:16",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/gitrepo.js",
"startLine": 267,
"endLine": 324,
"problem": "`push-token` 與 `pushWithCredential` 是新的提交推送行為,但 diff 沒有對應測試驗證分支選擇與失敗處理。尤其 `pushToken` 存在時會跳過 origin、未提供時才 fallback,這些都是會影響 CI 是否重新觸發的關鍵行為。",
"reason": "Paladin:可排除(重複)。歷史 findings 已涵蓋 pushToken、origin fallback、認證傳遞與推送失敗遮蔽等分支缺少測試。"
},
{
"addedAt": "2026/07/20 17:21:16",
"prNumber": 6,
"reviewer": "Maya",
"severity": "建議",
"file": "src/lib/review.js",
"startLine": 13,
"endLine": 72,
"problem": "`redactSecrets` / `agentFailureDetail` 新增了輸出 stderr/stdout 診斷的行為,但沒有測試驗證遮罩規則與限長。這不是單純格式調整;一旦正規式或順序被改壞,失敗 log 可能變得不可診斷,或把控制字元與憑證樣式原樣輸出。",
"reason": "Paladin:可排除(重複)。歷史 findings 已針對 redactSecretsagentFailureDetail 的控制字元、憑證樣式、URL 帳密、截斷與 debug 開關缺少測試提出相同問題。"
},
{
"addedAt": "2026/07/20 17:27:30",
"prNumber": 6,
"reviewer": "Assassin",
"severity": "嚴重",
"file": "src/lib/review.js",
"startLine": 74,
"endLine": 77,
"problem": "攻擊者只要讓 AI CLI 失敗,這裡就會把 stderr/stdout 片段寫進 CI log。那些輸出可能包含 prompt、diff 內容、環境診斷、第三方 CLI 錯誤訊息,甚至 token、API key、JWT、email 或其他 PII`redactSecrets` 只是樣式比對,漏掉未列舉格式時,秘密會被永久留在多人可讀的建置紀錄裡。",
"reason": "Paladin:可排除(重複)。歷史 finding 已針對 AI CLI stderr/stdout 寫入 CI log、黑名單式遮罩可繞過,以及 token/PII 外洩風險提出相同問題。"
},
{
"addedAt": "2026/07/20 17:27:30",
"prNumber": 6,
"reviewer": "Bard",
"severity": "建議",
"file": "src/index.js",
"startLine": 206,
"endLine": 217,
"problem": "`ensureIssueCreated` 這個名字唱的是「確保存在」,但實作每次呼叫都會直接建立新 issue;名稱與行為不同拍,日後重用時很容易誤讀。",
"reason": "Paladin:可排除(重複)。歷史 finding 已明確指出 `ensureIssueCreated` 名稱暗示冪等沿用,實作卻會建立新 issue,與本條指控相同。"
},
{
"addedAt": "2026/07/20 17:27:30",
"prNumber": 6,
"reviewer": "Leo",
"severity": "警告",
"file": "src/index.js",
"startLine": 176,
"endLine": 363,
"problem": "建問題模式把「留言目的地切換、issue 延後建立、標籤挑選、嚴重/非嚴重發布、PR 回貼連結、相依設定」全部塞進 `main()`,讓主流程同時承擔流程編排與發布策略。六個月後要改任何一種輸出模式時,很容易漏改其中一個 `ctx.createIssue` 分支,或讓一般模式與建問題模式的行為逐步分岔。",
"reason": "Paladin:可排除(命中已知排除事項且重複)。既有紀錄已涵蓋 `main()` 內留言路由、issue 生命週期、標籤、相依設定與發布職責耦合的問題。"
},
{
"addedAt": "2026/07/20 17:27:30",
"prNumber": 6,
"reviewer": "Leo",
"severity": "建議",
"file": "src/lib/review.js",
"startLine": 31,
"endLine": 53,
"problem": "`agentFailureDetail` 的說明提到「需要原始輸出診斷時,於 workflow 設定 secret `ACTIONS_STEP_DEBUG=true` 再重跑」,但實作其實不看 `ACTIONS_STEP_DEBUG`,預設就會輸出遮罩後的 stderr/stdout 片段。註解與行為不一致會讓未來維護者誤判這段診斷的暴露條件。",
"reason": "Paladin:可排除(與 F001 重複)。本條同樣指向 `agentFailureDetail` 預設輸出 stderr/stdout 片段、與 debug 暴露條件不一致的同一行為;F001 已保留其核心風險。"
},
{
"addedAt": "2026/07/20 17:27:30",
"prNumber": 6,
"reviewer": "Mage",
"severity": "警告",
"file": "src/index.js",
"startLine": 219,
"endLine": 228,
"problem": "`ensureIssueCreated` 先建立 issue,再逐則寫入暫存留言;任一留言 API 在中途失敗時,流程會直接丟出例外結束,但已建立的 issue 不會回滾,也沒有可重用的識別。最小情境:issue 建立成功,寫入第 2 則 `issueBuffer` 留言時 Gitea 暫時回 500;本次 action 失敗,下一次重跑會再建立一個新 issue,留下重複且內容不完整的追蹤 issue。",
"reason": "Paladin:可排除(命中已知排除事項且重複)。建立 issue 後沖刷暫存留言失敗、重跑又建立重複 issue,正是既有排除事項與多筆歷史 finding 已涵蓋的問題。"
},
{
"addedAt": "2026/07/20 17:27:30",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/index.js",
"startLine": 312,
"endLine": 383,
"problem": "建問題模式的核心流程被大幅改寫,但這段新增行為還沒看到對應測試驗證:`kept.length > 0` 才建 issue、標籤挑選失敗要降級、嚴重與非嚴重問題要改發到 issue、最後還要回貼 PR 並嘗試建立 issue dependency。這些都是跨 API 的分支與失敗路徑,沒有測試時很容易只跑到快樂路徑,漏掉「沒有保留問題」「標籤 API 失敗」「dependency API 不支援」這類實際會發生的情境。",
"reason": "Paladin:可排除(重複)。歷史 findings 已涵蓋建問題模式的 issue 建立條件、標籤降級、問題分流、PR 回貼與 dependency 失敗路徑缺少測試。"
},
{
"addedAt": "2026/07/20 17:27:30",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/gitrepo.js",
"startLine": 102,
"endLine": 151,
"problem": "`resolveMergeBase` 新增了淺層 checkout 修復策略與多段 fallback,但邊界與失敗路徑還沒被驗證:初次 fetch 成功但 merge-base 失敗、`--unshallow` 成功後立即成功、`deepen base` 成功、`deepen HEAD` 成功,以及所有策略都失敗時錯誤訊息要包含診斷。這段是 review diff 的基準點,沒測到 fallback 行為就等於沒有確認淺層 checkout 的修復真的可用。",
"reason": "Paladin:可排除(重複)。歷史 findings 已針對 `resolveMergeBase` 多階段 fetch、淺層/非淺層分支、停止條件與最終診斷缺少測試提出相同問題。"
},
{
"addedAt": "2026/07/20 17:27:30",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/gitrepo.js",
"startLine": 266,
"endLine": 314,
"problem": "push 行為從「先 origin、失敗才帶 token URL 重試」改成一律透過 `pushWithCredential` 用環境變數注入 Basic header,但新增的認證與錯誤遮蔽行為沒有測試驗證。這裡的失敗路徑如果沒測,很容易在 push 失敗時回歸成洩漏 argv/token,或 refspec/remoteUrl 組錯卻直到 CI 才發現。",
"reason": "Paladin:可排除(重複)。歷史 finding 已涵蓋 `pushToken`、origin 與 credential push 策略、認證遮蔽及 push 失敗路徑缺少測試。"
},
{
"addedAt": "2026/07/20 17:27:30",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/review.js",
"startLine": 14,
"endLine": 73,
"problem": "`agentFailureDetail` 現在會把 AI CLI 的 stderr/stdout 片段寫進 log,並依賴 `redactSecrets` 做遮罩與單行化;但這段新增的失敗診斷路徑沒有看到測試覆蓋。這不只是快樂路徑問題,邊界包含空輸出、只有 stdout、逾時 killed、換行控制字元、Authorization/token/URL credentials/長 token 等格式,任何一個漏掉都會讓診斷品質或遮罩行為失真。",
"reason": "Paladin:可排除(重複)。歷史 finding 已記錄 `agentFailureDetail``redactSecrets` 對空輸出、控制字元、憑證格式、URL 帳密、截斷與 debug 開關缺少測試。"
},
{
"addedAt": "2026/07/20 17:32:00",
"prNumber": 6,
"reviewer": "Assassin",
"severity": "警告",
"file": "src/lib/review.js",
"startLine": 52,
"endLine": 69,
"problem": "AI CLI 失敗時會把 stdout/stderr 片段預設寫進 CI log。攻擊者只要讓 CLI 失敗,並讓錯誤輸出夾帶 prompt、diff、環境診斷、原始碼片段或不符合目前 regex 的 token/PII,就能把本應留在審查沙箱內的內容長期落到多人可讀的 workflow log。`redactSecrets` 是黑名單式遮罩,擋不住未知格式憑證、中文個資、內部 URL、客戶資料或模型/CLI 回顯的任意文字。",
"reason": "Paladin:可排除(重複)。歷史 finding 已針對 AI CLI 失敗輸出 stdout/stderr、黑名單式遮罩可繞過,以及機密或個資落入 CI log 的風險提出相同問題。"
},
{
"addedAt": "2026/07/20 17:32:00",
"prNumber": 6,
"reviewer": "Bard",
"severity": "建議",
"file": "src/index.js",
"startLine": 178,
"endLine": 235,
"problem": "`main()` 裡新加入的兩個閉包與大段 JSDoc 讓主流程開場變得過於厚重。這些說明本身有價值,但它們插在流程步驟之前,讓讀者要先穿過一整段留言派送與建 issue 細節,才聽見真正的 10 步驟主旋律。",
"reason": "Paladin:可排除(重複)。歷史 finding 已涵蓋 main() 承擔留言路由、issue 狀態、緩衝佇列與發布職責耦合,並提出抽離 helper/發布器的方向。"
},
{
"addedAt": "2026/07/20 17:32:00",
"prNumber": 6,
"reviewer": "Leo",
"severity": "警告",
"file": "src/index.js",
"startLine": 177,
"endLine": 378,
"problem": "`main()` 這次把「一般模式」與「建問題模式」的留言路由、issue 建立、暫存 buffer、標籤挑選、相依關係、舊留言清理全部塞進同一個流程函式。六個月後要改任一個發佈規則時,維護者必須同時理解 `ctx.createIssue`、`issue` 閉包狀態、`issueBuffer`、`currentRunCommentIds` 與步驟順序,控制流已經變成隱含狀態機,測試也很難只針對「留言目的地」或「issue 收束」單獨驗證。",
"reason": "Paladin:可排除(重複)。此條與歷史 Leo finding 同樣指向 main() 內一般模式/建問題模式發布規則、issueBuffer、issue 閉包狀態與 ctx.createIssue 分支耦合。"
},
{
"addedAt": "2026/07/20 17:32:00",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/index.js",
"startLine": 177,
"endLine": 390,
"problem": "建問題模式這次新增了大量可觀察行為,但 diff 沒看到對應測試:留言先暫存再寫入 issue、無保留問題時靜默通過、有嚴重問題才加 PR 相依、只有警告/建議時不阻擋合併,以及一般模式才延後 resolve 舊留言。這些都是很容易在分支條件中漏掉的流程行為,現在還沒有被試煉過。",
"reason": "Paladin:可排除(重複)。歷史 Maya findings 已涵蓋建問題模式的暫存留言、靜默通過、嚴重/非嚴重分流、PR 相依與一般模式舊留言清理等核心分支缺少測試。"
},
{
"addedAt": "2026/07/20 17:32:00",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/gitrepo.js",
"startLine": 102,
"endLine": 158,
"problem": "`resolveMergeBase` 新增了多段 fetch 補救策略與錯誤診斷,但沒有看到測試驗證邊界與失敗路徑:首次 merge-base 成功、淺層 repo 走 `--unshallow`、unshallow 失敗後 deepen base/head、所有策略都失敗時要拋出含診斷且保留 `cause` 的錯誤。這段若沒測,很容易在淺層 checkout 才暴露審查整段中斷。",
"reason": "Paladin:可排除(重複)。歷史 findings 已針對 resolveMergeBase 多階段 fetch、淺層與非淺層分支、停止條件、降級及最終錯誤診斷缺少測試提出相同問題。"
},
{
"addedAt": "2026/07/20 17:32:00",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/gitrepo.js",
"startLine": 266,
"endLine": 306,
"problem": "`commitAndPushFindings` 改成一律透過 `pushWithCredential` 使用 token 推送,且 `pushWithCredential` 要保證 token 不進 argv、失敗錯誤被固定訊息取代;但 diff 沒有對這些失敗與遮蔽保證新增測試。這條路徑失敗時會直接影響 findings commit,也可能讓敏感資訊出現在測不到的例外訊息中。",
"reason": "Paladin:可排除(重複)。歷史 finding 已涵蓋 pushTokenpushWithCredential 推送策略、認證遮蔽與失敗路徑缺少測試。"
},
{
"addedAt": "2026/07/20 17:32:00",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/review.js",
"startLine": 13,
"endLine": 72,
"problem": "`agentFailureDetail` 現在會把 stderr/stdout 片段寫進 CI log,雖然有 `redactSecrets`,但沒有看到測試驗證遮罩規則與截斷邊界。這不是快樂路徑;一旦 AI CLI 失敗,未驗證的遮罩就會變成長期保存的 log 風險。",
"reason": "Paladin:可排除(重複)。歷史 finding 已涵蓋 redactSecretsagentFailureDetail 對 Authorization、token、URL 帳密、控制字元、截斷與空輸出等邊界缺少測試。"
},
{
"addedAt": "2026/07/20 17:36:21",
"prNumber": 6,
"reviewer": "Assassin",
"severity": "嚴重",
"file": "src/lib/review.js",
"startLine": 72,
"endLine": 75,
"problem": "這裡把 AI CLI 的 stderr/stdout 片段預設寫進 CI log。攻擊者可以讓 CLI 失敗並把 prompt、diff、環境診斷、token、JWT、內部 URL 或 PR 內容中的敏感資料噴到 stdout/stderr`redactSecrets` 只是正規表示式盡力遮罩,漏掉格式外的憑證或 PII 時,機密就被長期保存到多人可讀的 CI log。",
"reason": "Paladin:可排除(重複)。歷史 finding 已針對 debug/失敗診斷輸出 AI CLI stderr/stdout、黑名單式遮罩可繞過,以及機密或個資外洩提出相同問題。"
},
{
"addedAt": "2026/07/20 17:36:21",
"prNumber": 6,
"reviewer": "Bard",
"severity": "建議",
"file": "src/index.js",
"startLine": 180,
"endLine": 235,
"problem": "`main()` 裡新增了兩個閉包 helper,再各自搭配整段 JSDoc,像把副歌、橋段與註腳全塞進同一小節。這些註解本身不差,但放在主流程中間會稀釋流程主線,讓讀者在真正開始步驟 3 前先穿過一大段實作細節。",
"reason": "Paladin:可排除(重複)。歷史 findings 已涵蓋 `main()` 內留言路由、issue 建立、緩衝佇列與閉包 helper 造成主流程職責混雜,並提出抽出發布協作者的相同方向。"
},
{
"addedAt": "2026/07/20 17:36:21",
"prNumber": 6,
"reviewer": "Leo",
"severity": "警告",
"file": "src/index.js",
"startLine": 180,
"endLine": 234,
"problem": "`main()` 這次被塞進建問題模式的留言路由、issue 暫存佇列、issue 建立流程與標籤套用邏輯。未來只要要調整「留言要發到 PR 還是 issue」、「何時 flush 暫存留言」、「哪些模式要靜默通過」,維護者都必須在主流程裡追閉包狀態(`issueBuffer`、`issue`、`currentRunCommentIds`),主流程會越來越像狀態機但沒有清楚邊界。",
"reason": "Paladin:可排除(命中已知排除事項且重複)。既有紀錄已涵蓋 `main()` 中 issue 狀態、`issueBuffer`、留言路由與發布狀態機職責耦合的同一問題。"
},
{
"addedAt": "2026/07/20 17:36:21",
"prNumber": 6,
"reviewer": "Leo",
"severity": "警告",
"file": "src/index.js",
"startLine": 309,
"endLine": 390,
"problem": "建問題模式的收束流程散在多段 `if (ctx.createIssue)` 分支中:建立 issue、選標籤、嚴重問題留言、其他問題留言、PR 回貼連結、設定 dependency 都在 `main()` 裡交錯。這讓「建問題模式」沒有單一可讀入口,未來維護者要確認模式行為時必須跨多個區塊拼湊流程,尤其容易漏掉 `issue` 只在 `kept.length > 0` 後才存在的隱含前提。",
"reason": "Paladin:可排除(重複)。歷史 findings 已指出建問題模式的 issue 建立、留言分流、PR 回貼與 dependency 等流程散落在 `main()`,同屬發布流程邊界不清。"
},
{
"addedAt": "2026/07/20 17:36:21",
"prNumber": 6,
"reviewer": "Leo",
"severity": "建議",
"file": "src/lib/review.js",
"startLine": 30,
"endLine": 44,
"problem": "`agentFailureDetail` 的文件先說「原始輸出預設隱藏」,後面又說預設附上遮罩後的 stderr/stdout 片段。這種註解與實作語意互相打架,未來維護者很容易誤判 CI log 會不會包含 CLI 輸出,進而在調整遮罩或除錯策略時做錯取捨。",
"reason": "Paladin:可排除(重複)。與 F003 指涉同一段 `agentFailureDetail` 文件,問題同為「預設隱藏原始輸出」與「預設輸出遮罩片段」語意互相衝突。"
},
{
"addedAt": "2026/07/20 17:36:21",
"prNumber": 6,
"reviewer": "Mage",
"severity": "嚴重",
"file": "src/index.js",
"startLine": 397,
"endLine": 415,
"problem": "在 `create-issue=true` 且本輪有保留的嚴重問題、但 `excluded` 為空時,`exclusionsChanged` 會是 `false`,建問題模式又不 commit findings,因此收尾會「略過 commit/push」後直接 `return 0`。最小重現:PR 只有 1 條嚴重 finding、沒有任何誤判排除、問題相依 API 未啟用或設定失敗;流程會建立 issue、相依設定被 catch 成 WRN,沒有 `[failure]` 結果 commit,也沒有下一輪步驟 1 可回報失敗,最後 CI 成功通過。",
"reason": "Paladin:可排除(重複)。與 F001 指涉同一個嚴重 finding gate 依賴後續 commit/push 或 dependency side effect、而本輪可能直接回傳 0 的問題。"
},
{
"addedAt": "2026/07/20 17:36:21",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/index.js",
"startLine": 180,
"endLine": 409,
"problem": "建問題模式的流程被大幅改寫,但 diff 沒看到對應測試驗證這些新分支:留言先暫存到 `issueBuffer`、`kept.length > 0` 才建立 issue、無保留問題/無可審查變更時靜默通過、PR 回貼 issue 連結,以及只有嚴重問題才呼叫 `addIssueDependency`。這些都是使用者可觀察行為,沒有測試就很容易在之後調整流程時被改壞。",
"reason": "Paladin:可排除(重複)。歷史 findings 已涵蓋建問題模式的暫存留言、有 finding 才建 issue、靜默通過、PR 回貼、嚴重問題與 dependency 等核心分支缺少測試。"
},
{
"addedAt": "2026/07/20 17:36:21",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/gitrepo.js",
"startLine": 102,
"endLine": 159,
"problem": "`resolveMergeBase` 新增了多段 fetchunshallowdeepen fallback 與錯誤診斷,但沒有看到針對淺層 checkout、fetch 失敗、merge-base 首次失敗後成功、所有策略失敗等邊界的測試。這段決定送審 diff 的基準,一旦 fallback 順序或錯誤處理壞掉,審查可能漏看或多看變更。",
"reason": "Paladin:可排除(重複)。歷史 findings 已針對 `resolveMergeBase` 多階段 fetch、淺層 checkout、成功停止條件與全部失敗診斷缺少測試提出相同問題。"
},
{
"addedAt": "2026/07/20 17:36:21",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/gitrepo.js",
"startLine": 266,
"endLine": 297,
"problem": "push 行為改成一律走 `pushWithCredential`,並宣稱 token 不進 argv、失敗時隱藏 URL/認證資訊,但沒有測試覆蓋成功與失敗路徑。這裡一旦 regression,可能導致結果 commit 推不上去,或失敗訊息洩漏認證材料。",
"reason": "Paladin:可排除(重複)。歷史 findings 已涵蓋 pushTokenpushWithCredential 的推送策略、認證環境變數、失敗遮蔽與成功失敗路徑缺少測試。"
},
{
"addedAt": "2026/07/20 17:36:21",
"prNumber": 6,
"reviewer": "Maya",
"severity": "警告",
"file": "src/lib/review.js",
"startLine": 13,
"endLine": 84,
"problem": "`agentFailureDetail` 現在會把 AI CLI 的 stderr/stdout 片段寫進 CI log,並依賴 `redactSecrets` 遮罩機密;但新增的遮罩規則與截斷規則沒有測試。這是典型失敗路徑,平常快樂路徑不會跑到,沒測過就無法相信它真的能處理 Authorization、token、URL 帳密、控制字元與長金鑰。",
"reason": "Paladin:可排除(重複)。歷史 findings 已涵蓋 `redactSecrets``agentFailureDetail` 對 Authorization、token、URL 帳密、控制字元、長輸出與空輸出等邊界缺少測試。"
}
]