Theme / v0.9.56

Graphify

Codebase 知識圖譜

實戰範例

實戰範例 006:用 graphify prs --triage 在 PR 流程做衝突預警

把 reviewer 從『看 PR 數字排順序』昇級成『依 graph impact + community 重疊排優先度與 merge 順序』,每天省下排程的心力

背景

中型團隊的日常:早上進公司,看到 8 個 open PR 等 review。問題不是「review 哪個」,而是:

  • 哪個 PR 的改動風險最高,要先看?
  • 哪兩個 PR 會衝突,要排 merge 順序?
  • 哪個 PR 是孤島,可以無腦先 merge?

傳統排程靠數字:diff 行數、改幾個檔、CI 紅綠。但這些都看不到圖譜層級的衝突。兩個 PR 改的檔案不重疊,卻都動到同一個 god node 或同一個 community,merge 後一樣會炸。

graphify 的 prs --triageprs --conflicts 用 graph impact 來排優先度跟找隱性衝突。reviewer 拿到的是「按社群重疊跟 god node 觸動排出的清單」,不是按檔案行數排的。

⚠️ 與範例 002 差異:002 示範 3 個 PR 的衝突分析。本範例聚焦在日常 reviewer 的工作流:每天早上的 triage routine、CI 整合、團隊紀律。


適用情境

  • 一天有 5 個以上 open PR 的團隊
  • reviewer 輪值,需要快速决定今天看哪幾個
  • 多個 feature branch 平行開發,預期會有 graph-level 衝突
  • 想把 graph-impact 整合進 CI,讓每個 PR 自動帶影響半徑標籤

完整流程

步驟 1:確保 repo 是 graphify-ready

triage 的前提是圖譜反映 main branch 的現況,而且 hook 已裝:

cd ~/team-monorepo

uv tool install graphifyy && graphify install
graphify extract . --code-only
graphify hook install
graphify hook status

hook status 應該顯示 post-commit / post-checkout / merge driver 都已安裝。沒裝好,後面 triage 的圖譜會跟實際 branch 脫鉤。

步驟 2:早上 routine 第一行:triage

進公司、開終端,第一行指令就是 triage:

graphify prs --triage

graphify 收集所有 open PR,比對各自的 diff 跟當前圖譜,輸出按風險排序的清單:

Triage ranking (8 open PRs):
1. #58 (HIGH) billing refactor
   - 3 god nodes touched in Community 3 (billing)
   - 12 modified files, CI failing
   - Suggested reviewer: domain owner (Alice)
2. #52 (MED) export endpoint
   - Community 3 (billing) overlap with #58
   - 3 files, CI passing
3. #61 (MED) auth rate limiter
   - 1 god node touched in Community 1 (auth)
   - 5 files, CI pending
4. #41 (LOW) typo fix in README
   - No graph impact
   - 1 file, CI passing
... (4 more)

reviewer 看一眼就知道:今天優先看 #58,因為它動到 3 個 god node、CI 又紅了。

步驟 3:找隱性衝突配對

接著跑衝突配對:

graphify prs --conflicts

graphify 比對所有 PR 兩兩之間的 community 重疊:

Conflict pairs (graph-level):
  PR #52 ↔ #58  shared community: billing (Community 3)
    → merge order: #58 first, rebase #52 after
  PR #61 ↔ #67  shared god node: AuthMiddleware.verify
    → merge order: queue serially, do not parallel merge
  PR #41 ↔ (none)  isolated

這份清單看不到檔案層級的 diff 重疊,但 graph 重疊才是真正的風險。#52 跟 #58 改的檔案可能完全不重疊,但都動到 billing community 的 god node,先 merge 誰、後 rebase 誰會决定後續 PR 多乾淨。

步驟 4:决定 merge 順序

基於步驟 2 跟 3 的輸出,今天的 merge 計畫:

1. 先 merge #41(孤島,無風險)
2. 再 merge #58(HIGH,先解 CI)
3. rebase #52 onto main(因為跟 #58 共用 billing community)
4. 處理 #61 跟 #67 序列合併(共用 god node)

這個順序保證:高風險先處理,後續每個 rebase 都對著已穩定的 main 做,不會反覆處理同一條 community 的 conflict。

步驟 5:CI 自動貼 triage 標籤

把 triage 整合進 GitHub Actions,每個 PR 自動帶 graph-impact 標籤:

.github/workflows/pr-graph-impact.yml:

name: PR Graph Impact
on:
  pull_request:
    types: [opened, synchronize, reopened]
jobs:
  triage:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install graphify
        run: pipx install graphifyy
      - name: Build main branch graph
        run: graphify extract . --code-only
      - name: Run triage
        run: graphify prs --triage > triage.md
      - name: Run conflict check
        run: graphify prs --conflicts > conflicts.md
      - uses: actions/upload-artifact@v4
        with:
          name: graphify-triage
          path: |
            triage.md
            conflicts.md

每個 PR 自動 attach 兩份報告:triage 排序跟衝突清單。reviewer 不必親自跑指令。

步驟 6:在 PR 討論串用 triage 結果

reviewer 看 PR 時,先看 triage 標籤决定深度:

  • LOW:skimmable review,看個 5 分鐘就 approve
  • MED:聚焦 review,重點看 community 重疊處
  • HIGH:找 domain owner 配對 review,CI 必過才 merge

對 PR 作者也一樣:作者開 PR 前可以先 graphify prs --conflicts 預查自己會跟誰衝突,提前 rebase 或先跟對方溝通。


真實輸出範例

$ graphify prs --triage
Triage ranking (8 open PRs):
1. #58 (HIGH) billing refactor
   - 3 god nodes touched in Community 3 (billing)
   - 12 modified files, CI failing
   - Suggested reviewer: domain owner (Alice)
2. #52 (MED) export endpoint
   - Community 3 (billing) overlap with #58
   - 3 files, CI passing
3. #61 (MED) auth rate limiter
   - 1 god node touched in Community 1 (auth)
   - 5 files, CI pending
4. #41 (LOW) typo fix in README
   - No graph impact
   - 1 file, CI passing
5. #43 (LOW) bump deps
6. #44 (LOW) docs: add architecture diagram
7. #45 (LOW) chore: extract util function
8. #47 (LOW) test: add coverage for notifier

$ graphify prs --conflicts
Conflict pairs (graph-level):
  PR #52 ↔ #58  shared community: billing (Community 3)
    → merge order: #58 first, rebase #52 after
  PR #61 ↔ #67  shared god node: AuthMiddleware.verify
    → merge order: queue serially, do not parallel merge
  PR #41 ↔ (none)  isolated
  PR #43 ↔ (none)  isolated
  PR #44 ↔ (none)  isolated

對比傳統 PR 流程

任務 傳統(檔案 diff + CI) graphify triage
排 review 優先度 看檔案數、行數、CI 紅綠 加上 graph impact 跟 god node 觸動
找衝突 等 git conflict marker prs --conflicts 在 merge 前預警
决定 merge 順序 憑感覺或看 PR 號 依 community / god node 重疊排
找孤島 PR 要自己過濾 triage 直接標 LOW / isolated
跨檔隱性衝突 完全看不到 graph-level 才看得到

graph-level 衝突的價值在於:兩個 PR 改的檔案不重疊、git 不會報 conflict,但都動到同一個 god node,後 merge 的那個其實是建立在過時的圖譜假設上。prs --conflicts 提前抓出來。


失敗處理

情境 排查
prsgh not authenticated 在本地跑 gh auth login;在 CI 設 GITHUB_TOKEN(建議用 pull-requests: read 權限的 GITHUB_TOKEN,不要塞 PAT)
prs --triage 結果沒排序 沒設語意後端,graphify auto-detect 失敗。手動設 GRAPHIFY_TRIAGE_BACKEND=kimi(或 claude / openai / gemini
衝突結果為空但實際會衝突 圖譜過時。確認 graphify hook status 顯示 hook 跑過,或手動 graphify update
CI 裡 graphify extract 失敗 CI runner 記憶體不夠,或某個檔 AST parse 失敗。加 --code-only 跟排除 .graphifyignore 範圍
triage 把無關 PR 排成 HIGH 某個 god node 被誤判。看該 PR 的 Communities impacted,如果是誤判,可能是 --code-only 沒抓到 dynamic dispatch
兩 PR diff 完全一樣卻沒被標衝突 graphify 是 graph-level,不是檔案層級。檔案相同但 community 不重疊就不會標。若要找檔案層級衝突,加 git 工具(例如 gh pr view --json files

內部連結


下一步

  1. PR 審查 + 團隊共享 graphify-out(團隊層級的 graph 共享與 HTTP MCP server)
  2. 大型 monorepo 重購(triage 之外的重購影響分析)

關鍵學習點

  • triage 排程依 graph impact 而不是 diff 行數。god node 觸動才是真正的風險訊號。
  • prs --conflicts 抓的是 graph-level 衝突,比 git conflict marker 更早預警。兩 PR 檔案不重疊仍可能 community 重疊。
  • 標準早上 routine 兩行:先 prs --triage 排優先度,再 prs --conflicts 找配對。5 分鐘决定今天的 review 與 merge 計畫。
  • CI 整合讓每個 PR 自動帶 triage 報告,reviewer 不必親自跑。這是把 graphify 從個人工具昇級成團隊紀律的關鍵步驟。
  • triage 需要語意後端(GRAPHIFY_TRIAGE_BACKEND),沒設會退化成沒排序的清單。團隊統一設一個,避免結果不一致。