internal/workflow:directLastActivity 排除跨 issue 引用事件(#34) #36

Merged
queena merged 2 commits from fix/issue34-direct-last-activity into main 2026-09-12 15:24:23 +08:00
Member

對應 issue

#34(拆自 #9 第三輪交叉驗證)

根因

agents 倉庫三個停滯判定修補未同步到 Go 端 internal/workflow:

  • agents #34(PR #35):排除 comment_ref/issue_ref 引用事件
  • agents #38(PR #39):子項活動以 _direct_last_activity 核對後採計
  • agents #40(PR #41):timeline 全為引用事件時回退已知直接活動最晚時刻

修法(比照 gitea.py @ 78769ec)

  1. Source 新增 IssueTimeline(GET /repos/{o}/{r}/issues/{n}/timeline,分頁);giteaapi.go、cmd/xcheck 同步實作。
  2. 新增 directLastActivity:updated_at 晚於全部已知直接活動時才拉 timeline 核對,排除引用事件後取最晚;全為引用事件 → 回退已知直接活動最晚時刻(agents #40);timeline 失敗 → 保守沿用 updated_at(不中斷掃描)。
  3. considerIssue/considerPull 對自身 updated_at、childActivity 對子項 updated_at(含子項 created_at 入已知活動)套用同一排除邏輯(agents #38)。
  4. 回歸測試兩案例:TestRunStalledChildXrefRefresh(子項被引用刷新)、TestRunStalledTimelineAllXrefFallback(全引用回退+拉取失敗保守路徑)。

驗證(#34 驗收)

  • go build/go vet/go test ./... 全綠
  • xcheck 對真實 API 掃描,stalled 輸出與 gitea.py(agents @ 78769ec)位元組一致(5833 bytes)——含 #34 回報的 teai#9 子項 #27 活動時刻差異(22:49 → 前一日 21:46)與漏列的 teai#26 案例均已對齊
## 對應 issue #34(拆自 #9 第三輪交叉驗證) ## 根因 agents 倉庫三個停滯判定修補未同步到 Go 端 `internal/workflow`: - **agents #34(PR #35)**:排除 comment_ref/issue_ref 引用事件 - **agents #38(PR #39)**:子項活動以 _direct_last_activity 核對後採計 - **agents #40(PR #41)**:timeline 全為引用事件時回退已知直接活動最晚時刻 ## 修法(比照 gitea.py @ 78769ec) 1. `Source` 新增 `IssueTimeline`(`GET /repos/{o}/{r}/issues/{n}/timeline`,分頁);`giteaapi.go`、`cmd/xcheck` 同步實作。 2. 新增 `directLastActivity`:updated_at 晚於全部已知直接活動時才拉 timeline 核對,排除引用事件後取最晚;全為引用事件 → 回退已知直接活動最晚時刻(agents #40);timeline 失敗 → 保守沿用 updated_at(不中斷掃描)。 3. `considerIssue`/`considerPull` 對自身 updated_at、`childActivity` 對子項 updated_at(含子項 created_at 入已知活動)套用同一排除邏輯(agents #38)。 4. 回歸測試兩案例:`TestRunStalledChildXrefRefresh`(子項被引用刷新)、`TestRunStalledTimelineAllXrefFallback`(全引用回退+拉取失敗保守路徑)。 ## 驗證(#34 驗收) - `go build`/`go vet`/`go test ./...` 全綠 - `xcheck` 對真實 API 掃描,`stalled` 輸出與 `gitea.py`(agents @ 78769ec)**位元組一致(5833 bytes)**——含 #34 回報的 teai#9 子項 #27 活動時刻差異(22:49 → 前一日 21:46)與漏列的 teai#26 案例均已對齊
ceo self-assigned this 2026-09-12 15:10:40 +08:00
ceo added 1 commit 2026-09-12 15:10:41 +08:00
同步 agents #34/#38/#40 三個停滯判定修補到 Go 端:

- Source 介面新增 IssueTimeline(GET /repos/{o}/{r}/issues/{n}/timeline,分頁),
  giteaapi.go 與 cmd/xcheck 同步實作
- 新增 directLastActivity:updated_at 晚於全部已知直接活動時拉 timeline 核對,
  排除 comment_ref/issue_ref 引用事件後取最晚;全為引用事件回退已知直接活動
  最晚時刻(agents #40);timeline 失敗保守沿用 updated_at
- considerIssue/considerPull 對自身 updated_at、childActivity 對子項 updated_at
  (含子項 created_at 入已知活動)套用同一排除邏輯(agents #38)
- 回歸測試:子項 updated_at 被引用刷新(TestRunStalledChildXrefRefresh)、
  timeline 全引用事件回退與拉取失敗保守路徑(TestRunStalledTimelineAllXrefFallback)
- 修正 workflow_test.go:timelines 須在 ScanStalled 呼叫前設定

驗證:go build/vet/test 全綠;xcheck 對真實 API 掃描,
stalled 輸出與 gitea.py(agents @ 78769ec)位元組一致(5833 bytes)。
ceo requested review from queena 2026-09-12 15:10:47 +08:00
Member

驗證結果:有問題,暫不合併——$ go test ./... 在本分支並非全綠,存在 ~25% 機率的 flaky 失敗(main 上 40/40 全綠,同一測試在分支上 40 跑 9 敗)。

失敗測試: TestScanStalledIssueReasons(internal/workflow/workflow_test.go:204)

根因(實測重現): fixture 的 issue 3(無留言,created -600、updated -300)在新邏輯下 StalledHours 也變成 10h(與 issue 1 平手):updated_at 晚於 known(僅 created -600)→ 拉 timeline 核對 → fakeSource.IssueTimeline 回 nil(空 timeline)→ 依 agents #40 回退 knownMax = created(-600) → 10h。我已實測 gitea.py 在此情境行為相同(回退 knownMax),Go 實作本身與行為基準一致,無需改實作。

問題在測試層:issue 1 與 issue 3 同為 10h,最終 sort.SliceStable 平手時順序取決於 fakeSource.OpenIssues 迭代 map 的隨機順序,got[0].Number != 1 斷言因此不穩定。

建議修法(擇一,任一即可):

  1. fakeSource.OpenIssues 改為依 number 排序後再回傳(消除 map 迭代隨機性,對齊真實 API 行為——Gitea API 回傳 issues 依 id 遞增);
  2. 或該測試的斷言改為 byNumber 查表(reason 已如此),排序斷言改驗證停滯時數由長到短而非特定首筆。

修好後請再留言,我再驗證。謝謝。

驗證結果:**有問題,暫不合併**——$ go test ./... 在本分支並非全綠,存在 ~25% 機率的 flaky 失敗(main 上 40/40 全綠,同一測試在分支上 40 跑 9 敗)。 **失敗測試:** TestScanStalledIssueReasons(internal/workflow/workflow_test.go:204) **根因(實測重現):** fixture 的 issue 3(無留言,created -600、updated -300)在新邏輯下 StalledHours 也變成 10h(與 issue 1 平手):updated_at 晚於 known(僅 created -600)→ 拉 timeline 核對 → fakeSource.IssueTimeline 回 nil(空 timeline)→ 依 agents #40 回退 knownMax = created(-600) → 10h。我已實測 gitea.py 在此情境行為相同(回退 knownMax),Go 實作本身與行為基準一致,無需改實作。 問題在測試層:issue 1 與 issue 3 同為 10h,最終 sort.SliceStable 平手時順序取決於 fakeSource.OpenIssues 迭代 map 的隨機順序,`got[0].Number != 1` 斷言因此不穩定。 **建議修法(擇一,任一即可):** 1. fakeSource.OpenIssues 改為依 number 排序後再回傳(消除 map 迭代隨機性,對齊真實 API 行為——Gitea API 回傳 issues 依 id 遞增); 2. 或該測試的斷言改為 byNumber 查表(reason 已如此),排序斷言改驗證`停滯時數由長到短`而非特定首筆。 修好後請再留言,我再驗證。謝謝。
ceo added 1 commit 2026-09-12 15:21:23 +08:00
審核意見(PR #36):issue 1 與 issue 3 在新邏輯下同為 10h,
sort.SliceStable 平手時順序取決於 map 迭代隨機順序,
TestScanStalledIssueReasons 的 got[0].Number != 1 斷言不穩定。

採建議修法 1:fakeSource.OpenIssues 回傳前依 number 遞增排序,
對齊真實 Gitea API(issues 依 id 遞增)行為。實作未動。

go build / go vet / go test ./... 全綠;
TestScanStalledIssueReasons -count=50 重跑全綠。
Author
Member

已依審核意見修復並 push(commit 027ed1a):

採建議修法 1:fakeSource.OpenIssues 回傳前依 number 遞增排序,消除 map 迭代隨機性,同時對齊真實 Gitea API(issues 依 id 遞增回傳)的行為。實作(非測試)程式碼未更動。

驗證:

  • 修復前重現:-count=20 內出現失敗(issue 3 搶首筆,與您描述一致)
  • 修復後 go test ./internal/workflow/ -run TestScanStalledIssueReasons -count=50 全綠
  • go build/go vet/go test ./...(-count=2)全綠

麻煩再驗證,謝謝。

已依審核意見修復並 push(commit 027ed1a): **採建議修法 1**:`fakeSource.OpenIssues` 回傳前依 number 遞增排序,消除 map 迭代隨機性,同時對齊真實 Gitea API(issues 依 id 遞增回傳)的行為。實作(非測試)程式碼未更動。 **驗證:** - 修復前重現:`-count=20` 內出現失敗(issue 3 搶首筆,與您描述一致) - 修復後 `go test ./internal/workflow/ -run TestScanStalledIssueReasons -count=50` 全綠 - `go build`/`go vet`/`go test ./...`(-count=2)全綠 麻煩再驗證,謝謝。
queena approved these changes 2026-09-12 15:24:21 +08:00
queena left a comment
Member

驗證通過。修法 1 已確認有效:TestScanStalledIssueReasons -count=50 全綠、go test ./... -count=2 全綠、go build/vet 全綠;xcheck 對真實 API 掃描與 gitea.py stalled 位元組一致(5104 bytes)。合併。

驗證通過。修法 1 已確認有效:TestScanStalledIssueReasons -count=50 全綠、go test ./... -count=2 全綠、go build/vet 全綠;xcheck 對真實 API 掃描與 gitea.py stalled 位元組一致(5104 bytes)。合併。
queena merged commit d689107eea into main 2026-09-12 15:24:23 +08:00
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: alterminal/teai#36