feat/sdlc-flow-rules/main
develop
base-branch.sh
jsc-git:pr
本 PR 併入 5 個 commit,來自已合併的子功能 PR plugins/git#11。
tools/base-branch.sh
--derive
skills/pr/SKILL.md
skills/commit/SKILL.md
README.md
plugin.json
.claude-plugin/plugin.json
.codex-plugin/plugin.json
0.0.8
7
{類型}/{功能}/main
origin/develop
base-branch.sh "$SOURCE_BRANCH"
2
3
4
5
main
master
6
8
9
jsc-gitea
gitea.sh pr-get
pr-edit
slugify.sh
sh -n tools/base-branch.sh
jsc-meta/tools/ste100-lint.sh
base-branch.sh --derive
gitea.sh pr-depend
What:`tools/base-branch.sh` 新增 `--derive [分支]` 模式,從分支名推出唯一合法的上一階基底。`feat` 這一類走 `{類型}/{功能}/{子功能}` → `{類型}/{功能}/main` → `develop` → `master`,`fix` 走 `fix/{修改}` → `develop` → `master`。新增退出碼 `7`(推不出唯一合法基底)、`8`(推導出的基底不在遠端又不能自動建立)、`9`(自動建立功能主幹失敗)。既有的呼叫方模式一字未改。 Why:PR 階梯禁止越級,但基底原本靠呼叫端自己挑,挑錯就是把一個子功能直接併進 `develop`,中間那層功能主幹整個被跳過。判斷寫進程式,越級就不會發生在「這次剛好沒注意」的時候。 How:`{子功能}` 可以多層,推導一律把最後一段換成 `main`。推不出唯一合法基底就中止並回 `7`,由呼叫端問使用者,不猜、也不退回 `develop`——退回 `develop` 正是這支腳本要擋的那件事。功能主幹不在 origin 時,直接把 `origin/develop` 推成新分支自動補一條,不動本機工作區,再把建立了哪一條分支印到 stderr。分支名只收 ASCII 小寫、數字、連字號與斜線,中文簡述請先過 `tools/slugify.sh`。 Who:`jsc-git:pr` 決定 PR base 的那一步,以及所有經由它開 PR 的技能。
What:`pr` 技能新增「PR ladder」一節與階梯形狀的分支命名(`fix` 叫一次 `slugify.sh`,其餘型別叫兩次組出 `{類型}/{功能}/{子功能}`),base 一律由 `base-branch.sh --derive` 推導;新增步驟 6 查目標分支有沒有開啟中的 PR,有就跳到新的步驟 9 比對標題、描述、前置 PR 依賴三項,只有不一樣的那幾項才送 API。`commit` 技能新增步驟 5:認可完成後,目前分支已有 PR 就交給 `pr` 校準。 Why:越級開 PR 與「同一條分支重開第二支 PR」是同一個病灶的兩面——base 與 PR 現況都靠人記。改成先推導、先比對之後,base 由腳本決定,PR 只在真的有差時才更新。 How:呼叫方傳入的 base 仍然照收,但要與推導結果一致;不一致就當成越級擋下,說明正確階梯再問使用者,不會悄悄改目標。校準走 `jsc-gitea` 的 `pr-get` 讀現況、`pr-edit` 一次帶標題與描述、`pr-depend` 補依賴;三項都相同就什麼都不做——每一次多餘的編修都會通知所有審查者,安靜才是對的結果。 Who:`jsc-git:pr` 與 `jsc-git:commit` 兩支技能,以及呼叫它們的 `jsc-sdlc:implement`、`jsc-sdlc:maintain` 與 `jsc-meta` 各技能。
What:README 新增「PR 階梯」一節(兩種型別的階梯表、多層子功能的推導方式、推不出就回 `7` 中止、功能主幹自動建立),工具表補上 `base-branch.sh --derive` 與 `slugify.sh` 連叫兩次組多層分支名,`commit` 與 `pr` 兩段說明改寫成新行為。 Why:階梯與校準是這次的行為變更,README 是對外說明。說明沒跟上,使用者會照舊以為 base 可以自己挑、PR 要重開一支。 How:階梯表在 README 只寫一份摘要,唯一來源仍是 `jsc-meta` 的 `references/guidelines.md`。技能說明兩段各補上推導與校準兩件事,用詞與 SKILL.md 一致。 Who:讀 `jsc-git` 說明的人,以及要接 `base-branch.sh` 的其他 domain。
What:`plugin.json`、`.claude-plugin/plugin.json`、`.codex-plugin/plugin.json` 的 `version` 由 0.0.7 改為 0.0.8。 Why:本次改了 `base-branch.sh` 的介面與 `commit`、`pr` 兩支技能的步驟,屬於行為變更,版本要跟著往上走,各 CLI 才知道要更新。 How:三份只改 `version` 一個欄位,其餘內容不動,三份保持同一版號。 Who:`jsc-git` 外掛的套件描述檔。
Reviewed-on: #11
No dependencies set.
The note is not visible to the blocked user.
PR 描述
摘要
feat/sdlc-flow-rules/main累積的內容整批推上develop。本存取庫負責使用者 15 條規則第一群「SDLC 執行流程」裡的 R3 與 R2 的落地:R3 的分支階梯不能只寫在準則裡靠模型自律,要由base-branch.sh在程式層推導出來;R2 的「每次 commit 後校準 PR」則要讓jsc-git:pr遇到既有 PR 時改成比對三項、有差才改,而不是關掉重開。本 PR 併入 5 個 commit,來自已合併的子功能 PR plugins/git#11。
變更內容
tools/base-branch.sh--derive模式,從分支名推出唯一合法的上一階基底,並在功能主幹不存在時自動建立。階梯寫在準則裡是給人看的,寫在這裡才擋得住越級skills/pr/SKILL.mdskills/commit/SKILL.mdREADME.mdplugin.json、.claude-plugin/plugin.json、.codex-plugin/plugin.json0.0.8設計重點
--derive只推導唯一合法的上一階。推不出來就以退出碼7中止,由呼叫端問使用者,不猜、也不退回develop。退回develop就是預設允許越級,正是這支腳本要擋的事。{類型}/{功能}/main不在 origin 時,自動以origin/develop為起點建立並推上去,再把建立了哪一條分支印到 stderr。決策紀錄見 wiki QUESTION_FB8DF0B5 的 2026-08-27 那一節 Q3。自動建立配上明確回報,比每個新功能都多一輪問答來得省事。base-branch.sh "$SOURCE_BRANCH"而變數沒設定時,那是空字串、不是沒傳;當成沒傳就會悄悄退回develop,把單一工作包直接併進develop。2參數過多、3抓不到遠端、4指定的分支不在遠端、5develop與main與master都不在遠端、6傳入空字串、7推不出唯一合法基底、8推導出的基底不在遠端又不能自動建立、9自動建立功能主幹失敗。jsc-gitea的gitea.sh pr-get與pr-edit,不自行拼 API。slugify.sh轉成 slug,base-branch.sh本身不接受非 ASCII 分支名。測試結果
sh -n tools/base-branch.sh通過。jsc-meta/tools/ste100-lint.sh掃整個存取庫全綠。feat/sdlc-flow-rules/main全部由base-branch.sh --derive自動從develop建立並推上 origin,七次都印出建立訊息、退出碼 0;主幹已存在時再跑一次只印分支名,不重複建立。前置 Push Request
jsc-gitea的gitea.sh pr-get與pr-edit。該依賴已隨 plugins/gitea#22 合併進 gitea 的功能主幹,沒有未結清的前置 PR,不需要掛gitea.sh pr-depend。What:`tools/base-branch.sh` 新增 `--derive [分支]` 模式,從分支名推出唯一合法的上一階基底。`feat` 這一類走 `{類型}/{功能}/{子功能}` → `{類型}/{功能}/main` → `develop` → `master`,`fix` 走 `fix/{修改}` → `develop` → `master`。新增退出碼 `7`(推不出唯一合法基底)、`8`(推導出的基底不在遠端又不能自動建立)、`9`(自動建立功能主幹失敗)。既有的呼叫方模式一字未改。 Why:PR 階梯禁止越級,但基底原本靠呼叫端自己挑,挑錯就是把一個子功能直接併進 `develop`,中間那層功能主幹整個被跳過。判斷寫進程式,越級就不會發生在「這次剛好沒注意」的時候。 How:`{子功能}` 可以多層,推導一律把最後一段換成 `main`。推不出唯一合法基底就中止並回 `7`,由呼叫端問使用者,不猜、也不退回 `develop`——退回 `develop` 正是這支腳本要擋的那件事。功能主幹不在 origin 時,直接把 `origin/develop` 推成新分支自動補一條,不動本機工作區,再把建立了哪一條分支印到 stderr。分支名只收 ASCII 小寫、數字、連字號與斜線,中文簡述請先過 `tools/slugify.sh`。 Who:`jsc-git:pr` 決定 PR base 的那一步,以及所有經由它開 PR 的技能。What:`pr` 技能新增「PR ladder」一節與階梯形狀的分支命名(`fix` 叫一次 `slugify.sh`,其餘型別叫兩次組出 `{類型}/{功能}/{子功能}`),base 一律由 `base-branch.sh --derive` 推導;新增步驟 6 查目標分支有沒有開啟中的 PR,有就跳到新的步驟 9 比對標題、描述、前置 PR 依賴三項,只有不一樣的那幾項才送 API。`commit` 技能新增步驟 5:認可完成後,目前分支已有 PR 就交給 `pr` 校準。 Why:越級開 PR 與「同一條分支重開第二支 PR」是同一個病灶的兩面——base 與 PR 現況都靠人記。改成先推導、先比對之後,base 由腳本決定,PR 只在真的有差時才更新。 How:呼叫方傳入的 base 仍然照收,但要與推導結果一致;不一致就當成越級擋下,說明正確階梯再問使用者,不會悄悄改目標。校準走 `jsc-gitea` 的 `pr-get` 讀現況、`pr-edit` 一次帶標題與描述、`pr-depend` 補依賴;三項都相同就什麼都不做——每一次多餘的編修都會通知所有審查者,安靜才是對的結果。 Who:`jsc-git:pr` 與 `jsc-git:commit` 兩支技能,以及呼叫它們的 `jsc-sdlc:implement`、`jsc-sdlc:maintain` 與 `jsc-meta` 各技能。