feat(sdlc): 工作包隔離、留言取得共識後再修、盯 PR 到合併與每任務一筆日誌 #29

Merged
admin merged 5 commits from feat/sdlc-flow-rules/implement-worklog-and-pr-watch into feat/sdlc-flow-rules/main 2026-08-27 03:26:33 +00:00
Member

摘要

  • 需求描述:落實「SDLC 執行流程」規則群裡由 jsc-sdlc 執行的四條。每完成一個任務(一個工作包、一輪 PR 留言修正、一個獨立的修正提交)就立刻寫工作日誌;工作包隔離,以分析頁的工作包編號認定歸屬,查無歸屬就放行;等待合併改用 pr-watch.sh 輪詢,預設 60 秒、不自動退場;PR 留言的修正先走 jsc-ask:ask 決策樹取得共識才動手。另外把分支階梯的收場處理接進實作階段。決策紀錄在 wiki 存取庫 knowledges/QUESTION 的 QUESTION_FB8DF0B5,2026-08-27 那一節。
  • 計畫名稱:無
  • 計畫頁:無
  • 分析頁:無

變更內容

檔案 為什麼改
tools/wp-gate.sh 平行進行的工作包各有各的 PR,但閘門原本看不出某支 PR 是誰的。新增 claim 登錄領取、owns 比對歸屬,lock 加 --wp 把 PR 掛到工作包名下,check 判定已合併時一併交回領取紀錄
skills/implement/SKILL.md 留言原本直接開修(等於自行解讀審查者的一句話)、別包的 PR 沒人擋、等 PR 合併沒有統一做法、日誌等到階段結束才補。四件事各補上一步:owns、決策樹共識、pr-watch.sh、每個任務一筆日誌
skills/maintain/SKILL.md 一次跑好幾個專案卻只在收尾補一筆日誌,各專案的時間與困難全混在一起。改成 PR 一開好就寫,下一個專案開工前寫完
references/branch.md 新增「分支階梯與 base 推導」與「工作包隔離」兩節:前者只寫拿到 base-branch.sh --derive 各種回應後要做什麼,後者寫歸屬依據與狀態檔欄位
references/stage-report.md 日誌改成一個任務一筆之後,做完事情的階段本來就有日誌可連。暫存那一節改為只適用「還沒完成任何任務就停下」的階段,並補一句「暫存不等於已寫入」
README.md 工具表、兩支技能說明、參考文件表與相依技能清單同步更新
plugin.json、.claude-plugin/plugin.json、.codex-plugin/plugin.json 行為變更要 bump 版本;三份同步升到 0.1.9

設計重點

  • 歸屬只認分析頁上的工作包代號,不看分支名、不看 worktree 目錄名——那兩個都可能被改,改了也沒有徵兆。WP-03、WP-3、3 視為同一包。
  • 查無歸屬就放行,只提醒。沒有分析頁、查不到代號、領取檔不存在、工作包還沒掛上 PR,一律 unowned 並回 0。這與閘門既有的「查不到就擋」不衝突:那條講的是查得到卻查失敗,這條講的是根本還沒有歸屬可查,拿不存在的歸屬擋人會讓沒登錄過的工作包全部動不了。
  • 狀態檔一律由 jsc-hooks 的 sdlc-gate.sh 寫,wp-gate.sh 只讀不寫。兩邊各拼各的檔案,格式一改就對不上,而且誰寫壞了看不出來。
  • 留言絕不自動修。同一句審查意見常常允許兩種改法,自己挑一種等於多賭一輪審查;決策樹每一則留言一組選項,各自寫明影響範圍(動到哪些檔案、會不會改到這一包的待辦),使用者答完才動檔案。
  • 等待合併只有一種做法:pr-watch.sh 的退出碼 10 回頭跑同一套留言流程,跑完再盯一次,審查者要幾輪就幾輪;0 之後仍要用 wp-gate.sh check 分辨已合併與被關掉沒合併,後者回報後停下,不算完成;2 與 3 一律回報後停下,不准改用肉眼看 PR 頁面就當成已合併。
  • 日誌粒度寫成硬規則:一個任務一筆,下一個任務開始前寫完,同一頁 LOG_{HASH} 附加。一包跑五輪留言修正就是五筆,--pending-file 暫存的內容併進同一次寫入、寫成功才清除,暫存過的內容不算日誌。
  • 階梯表與狀態檔格式都不抄第二份:階梯的唯一來源在 jsc-meta 的 references/guidelines.md,格式的唯一來源在 jsc-hooks,本庫只寫「拿到回應之後要做什麼」。

測試結果

  • sh -n tools/wp-gate.sh:語法檢查通過。
  • 用暫時的 $JSC_HOME 走過三條歸屬路徑,結果全部符合預期:領取 WP-03 並把第 12 號 PR 掛上去之後,owns jsc/demo 12 --wp 3 回 status=owned(退出碼 0,且證明補零與否視為同一包);owns jsc/demo 9 --wp WP-03 回 status=foreign(退出碼 1),訊息指出第 9 號掛在 WP-01 名下;沒有領取紀錄的存取庫回 status=unowned(退出碼 0)並說明放行原因。
  • 對應的 hook 端一併驗過:sdlc-gate.sh wp-report 印出的第四欄工作包代號可被 wp-gate.sh 讀取比對,舊格式單行 TSV 鎖檔照樣讀得動且判為查無歸屬。
  • ste100-lint.sh .:全庫零命中。
  • 三份 manifest 以 JSON 解析器讀過,格式正確且版本一致為 0.1.9。
  • 未測:check、check-deps 與 claim 的實際 Gitea 往返,以及 implement、maintain 兩支技能跑完一輪的端到端流程。兩者都要可連線的 Gitea 與一份真實分析頁,本次在沒有 Gitea 存取的環境進行。

前置 Push Request

## 摘要 - 需求描述:落實「SDLC 執行流程」規則群裡由 `jsc-sdlc` 執行的四條。每完成一個任務(一個工作包、一輪 PR 留言修正、一個獨立的修正提交)就立刻寫工作日誌;工作包隔離,以分析頁的工作包編號認定歸屬,查無歸屬就放行;等待合併改用 `pr-watch.sh` 輪詢,預設 60 秒、不自動退場;PR 留言的修正先走 `jsc-ask:ask` 決策樹取得共識才動手。另外把分支階梯的收場處理接進實作階段。決策紀錄在 wiki 存取庫 `knowledges/QUESTION` 的 `QUESTION_FB8DF0B5`,2026-08-27 那一節。 - 計畫名稱:無 - 計畫頁:無 - 分析頁:無 ## 變更內容 | 檔案 | 為什麼改 | | --- | --- | | `tools/wp-gate.sh` | 平行進行的工作包各有各的 PR,但閘門原本看不出某支 PR 是誰的。新增 `claim` 登錄領取、`owns` 比對歸屬,`lock` 加 `--wp` 把 PR 掛到工作包名下,`check` 判定已合併時一併交回領取紀錄 | | `skills/implement/SKILL.md` | 留言原本直接開修(等於自行解讀審查者的一句話)、別包的 PR 沒人擋、等 PR 合併沒有統一做法、日誌等到階段結束才補。四件事各補上一步:`owns`、決策樹共識、`pr-watch.sh`、每個任務一筆日誌 | | `skills/maintain/SKILL.md` | 一次跑好幾個專案卻只在收尾補一筆日誌,各專案的時間與困難全混在一起。改成 PR 一開好就寫,下一個專案開工前寫完 | | `references/branch.md` | 新增「分支階梯與 base 推導」與「工作包隔離」兩節:前者只寫拿到 `base-branch.sh --derive` 各種回應後要做什麼,後者寫歸屬依據與狀態檔欄位 | | `references/stage-report.md` | 日誌改成一個任務一筆之後,做完事情的階段本來就有日誌可連。暫存那一節改為只適用「還沒完成任何任務就停下」的階段,並補一句「暫存不等於已寫入」 | | `README.md` | 工具表、兩支技能說明、參考文件表與相依技能清單同步更新 | | `plugin.json`、`.claude-plugin/plugin.json`、`.codex-plugin/plugin.json` | 行為變更要 bump 版本;三份同步升到 0.1.9 | ## 設計重點 - 歸屬只認分析頁上的工作包代號,不看分支名、不看 worktree 目錄名——那兩個都可能被改,改了也沒有徵兆。`WP-03`、`WP-3`、`3` 視為同一包。 - 查無歸屬就放行,只提醒。沒有分析頁、查不到代號、領取檔不存在、工作包還沒掛上 PR,一律 `unowned` 並回 `0`。這與閘門既有的「查不到就擋」不衝突:那條講的是查得到卻查失敗,這條講的是根本還沒有歸屬可查,拿不存在的歸屬擋人會讓沒登錄過的工作包全部動不了。 - 狀態檔一律由 `jsc-hooks` 的 `sdlc-gate.sh` 寫,`wp-gate.sh` 只讀不寫。兩邊各拼各的檔案,格式一改就對不上,而且誰寫壞了看不出來。 - 留言絕不自動修。同一句審查意見常常允許兩種改法,自己挑一種等於多賭一輪審查;決策樹每一則留言一組選項,各自寫明影響範圍(動到哪些檔案、會不會改到這一包的待辦),使用者答完才動檔案。 - 等待合併只有一種做法:`pr-watch.sh` 的退出碼 `10` 回頭跑同一套留言流程,跑完再盯一次,審查者要幾輪就幾輪;`0` 之後仍要用 `wp-gate.sh check` 分辨已合併與被關掉沒合併,後者回報後停下,不算完成;`2` 與 `3` 一律回報後停下,不准改用肉眼看 PR 頁面就當成已合併。 - 日誌粒度寫成硬規則:一個任務一筆,下一個任務開始前寫完,同一頁 `LOG_{HASH}` 附加。一包跑五輪留言修正就是五筆,`--pending-file` 暫存的內容併進同一次寫入、寫成功才清除,暫存過的內容不算日誌。 - 階梯表與狀態檔格式都不抄第二份:階梯的唯一來源在 `jsc-meta` 的 `references/guidelines.md`,格式的唯一來源在 `jsc-hooks`,本庫只寫「拿到回應之後要做什麼」。 ## 測試結果 - `sh -n tools/wp-gate.sh`:語法檢查通過。 - 用暫時的 `$JSC_HOME` 走過三條歸屬路徑,結果全部符合預期:領取 `WP-03` 並把第 12 號 PR 掛上去之後,`owns jsc/demo 12 --wp 3` 回 `status=owned`(退出碼 `0`,且證明補零與否視為同一包);`owns jsc/demo 9 --wp WP-03` 回 `status=foreign`(退出碼 `1`),訊息指出第 9 號掛在 `WP-01` 名下;沒有領取紀錄的存取庫回 `status=unowned`(退出碼 `0`)並說明放行原因。 - 對應的 hook 端一併驗過:`sdlc-gate.sh wp-report` 印出的第四欄工作包代號可被 `wp-gate.sh` 讀取比對,舊格式單行 TSV 鎖檔照樣讀得動且判為查無歸屬。 - `ste100-lint.sh .`:全庫零命中。 - 三份 manifest 以 JSON 解析器讀過,格式正確且版本一致為 0.1.9。 - 未測:`check`、`check-deps` 與 `claim` 的實際 Gitea 往返,以及 `implement`、`maintain` 兩支技能跑完一輪的端到端流程。兩者都要可連線的 Gitea 與一份真實分析頁,本次在沒有 Gitea 存取的環境進行。 ## 前置 Push Request - plugins/gitea#22 https://gitea.jsc.idv.tw/plugins/gitea/pulls/22(`pr-watch.sh`) - plugins/hooks#30 https://gitea.jsc.idv.tw/plugins/hooks/pulls/30(`wp-claim`、`wp-lock --wp`、`wp-unclaim`) - plugins/log#16 https://gitea.jsc.idv.tw/plugins/log/pulls/16(`worklog-pending.sh` 的 merge、commit、abort) - plugins/meta#22 https://gitea.jsc.idv.tw/plugins/meta/pulls/22(`guidelines.md` 的「PR 分支階梯」段落)
jiantw83 added 5 commits 2026-08-27 03:21:24 +00:00
What:`tools/wp-gate.sh` 新增 `claim {owner}/{repo} {wp-number} [--analyze {分析頁頁名}]` 登錄領取、`owns {owner}/{repo} {index} [--wp {wp-number}]` 比對某支 PR 是不是自己這一包的;`lock` 新增 `--wp` 把 PR 掛到工作包名下;`check` 判定已合併時一併交回領取紀錄。新增狀態 `claimed`、`owned`、`foreign`、`unowned`,`foreign` 回 `1`,`owned` 與 `unowned` 回 `0`。

Why:同一份分析常有好幾包平行進行,每包各自的 worktree 與 PR。動任何一支 PR 之前要先確認它是自己這一包的,靠的必須是狀態檔而不是記憶——記憶跨不了工作階段。

How:歸屬一律以分析頁的工作包代號為準,不看分支名、不看 worktree 目錄名,那兩個都可能被改,改了也沒有徵兆。`WP-03`、`WP-3`、`3` 比對前先正規化成 `WP-03`,不然同一包的兩種寫法會被當成兩包。狀態檔的寫入一律轉呼叫 `jsc-hooks` 的 `sdlc-gate.sh`,本檔只讀不寫:兩邊各拼各的檔案,格式一改就對不上。查無歸屬(沒有領取紀錄、工作包還沒掛上 PR)一律 `unowned` 並放行只提醒,這與「查不到就擋」不衝突——那條講的是查得到卻查失敗,這條講的是根本還沒有歸屬可查。擋人時要講得出對方是誰,所以 `foreign` 會指出那支 PR 掛在哪一包名下。合併後交回領取紀錄前先確認領取檔登記的正是這一包,中途改領別包時直接交回會把還在進行的那一包的歸屬清掉。

Who:`jsc-sdlc:implement` 領包、開 PR 與處理留言的每一步,以及跨工作階段接手同一份分析的人。
What:`implement` 步驟 4 的留言處理拆細:動手前先跑 `wp-gate.sh owns` 確認 PR 是自己這一包的,接著走 `jsc-ask:ask` 決策樹對每一則留言取得共識才修,一輪修完立刻寫一筆工作日誌。步驟 6 領到包就跑 `wp-gate.sh claim`,步驟 11 的 `lock` 帶 `--wp`,開完 PR 先寫日誌再用 `jsc-gitea/tools/pr-watch.sh` 盯到合併,並依退出碼 `0`、`10`、`3`、`2` 分四條路走。Rules 新增「一個任務一筆日誌」一條,步驟 14 的日誌參數改為指向步驟 11 寫的那一筆。

Why:三件事原本都靠模型自己記。留言直接開修,等於把審查者的一句話自行解讀成一種改法,猜錯就多一輪審查;別包的 PR 沒人擋,跨工作階段就會互相踩;日誌等到階段結束才補一次,那時花費時間、token 用量與困難都已經散掉了。

How:留言文本留在 sub agent 裡,主代理只留決策與帳務。`pr-watch.sh` 收到 `10` 就回頭跑同一套留言流程(歸屬、共識、sub agent 修正、逐則結果、時間戳、日誌),跑完再盯一次,審查者要幾輪就幾輪;收到 `0` 再用 `wp-gate.sh check` 分辨已合併與被關掉沒合併,後者回報後停下,不算完成。時間戳一律寫回分析頁**既有**的 PR 欄,不加新欄,分析頁的欄位屬於 `analyze`。日誌一律附加到同一頁 `LOG_{HASH}`,`--pending-file` 暫存的內容併進同一次寫入,寫成功才清除——暫存不等於已寫入。

Who:跑 SDLC 實作階段的每個工作階段,以及接手同一份分析的下一個人。
What:`maintain` 步驟 3 新增 3.5「一個專案的維護就是一個完成的任務」,PR 一開好就呼叫 `jsc-log:worklog` 寫一筆,原 3.5 順延為 3.6;步驟 5 的階段回報改成指向 3.5 寫的那幾筆,`--pending-file` 降級為「一個任務都沒完成就停下」時的備援。

Why:維護階段一次跑好幾個專案,原本整個階段結束才補一筆日誌。等到那時候,每個專案各自花掉多少時間、遇到什麼困難都已經混在一起,補出來的是一段概述而不是紀錄。

How:一個專案一筆,下一個專案的 sub agent 開工前要先寫完。條目一律附加到同一頁 `LOG_{HASH}`,`stage-report.sh --pending-file` 暫存的內容併進同一次寫入,寫成功才清除;暫存過的內容不算已寫入的日誌。

Who:跑 SDLC 維護階段的人,以及事後查某個專案上次維護做了什麼的人。
What:`references/branch.md` 新增「分支階梯與 base 推導」一節(只寫拿到 `jsc-git/tools/base-branch.sh --derive` 回應之後要做什麼)與「工作包隔離」一節(歸屬依據、狀態檔欄位、誰寫誰讀、查無歸屬放行、逃生門),閘門分工那一表補上 `claim`、`lock`、`owns`。`references/stage-report.md` 改寫暫存那一節,講明本節只適用於「還沒完成任何任務就停下」的階段。README 的工具表、`implement` 與 `maintain` 兩段說明、參考文件表與相依技能清單同步更新。

Why:階梯表與歸屬狀態檔的正本各有其處——階梯在 `jsc-meta` 的 `references/guidelines.md`,狀態檔格式在 `jsc-hooks`。抄第二份就會有兩份互相打架的規則,但完全不提又會讓實作階段不知道拿到 `7` 或「已建立功能主幹」時該做什麼。

How:兩節都只寫本階段要做的事,並把唯一來源用連結指出去。`branch.md` 的階梯那一節寫成一張「腳本回應 → 這個階段要做的事」對照表,`7` 明寫成「中止並問使用者,不退回 `develop`」。`stage-report.md` 補一句「暫存不等於已寫入」,因為日誌改成一個任務一筆之後,做完事情的階段本來就有日誌可連。

Who:讀 `jsc-sdlc` 參考文件與 README 的人,以及跑實作與維護兩階段的工作階段。
What:`plugin.json`、`.claude-plugin/plugin.json`、`.codex-plugin/plugin.json` 的 `version` 由 0.1.8 改為 0.1.9。

Why:本次為 `wp-gate.sh` 新增兩個子命令,並改了 `implement` 與 `maintain` 兩支技能的步驟,屬於行為變更,版本要跟著往上走,各 CLI 才知道要更新。

How:三份只改 `version` 一個欄位,其餘內容不動,三份保持同一版號。

Who:`jsc-sdlc` 外掛的套件描述檔。
admin merged commit ce8f2eb9af into feat/sdlc-flow-rules/main 2026-08-27 03:26:33 +00:00
admin deleted branch feat/sdlc-flow-rules/implement-worklog-and-pr-watch 2026-08-27 03:26:33 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Reference: plugins/sdlc#29