feat(一包一 PR): 每個工作包完成即 commit、push、PR 回來源分支
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -25,13 +25,13 @@ SDLC 各階段引用的參考分支與來源分支,**一律指遠端的 `origi
|
|||||||
| 階段 | 要確認的分支 | 確認時機 |
|
| 階段 | 要確認的分支 | 確認時機 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `analyze` | **來源分支**——哪條分支的程式碼算現況 | 讀任何程式碼之前 |
|
| `analyze` | **來源分支**——哪條分支的程式碼算現況 | 讀任何程式碼之前 |
|
||||||
| `implement` | **目標分支**——這批工作要合併進哪條分支 | 寫任何檔案之前 |
|
| `implement` | **來源分支**——worktree 的基準,也是每個工作包的 PR 目標 | 寫任何檔案之前 |
|
||||||
|
|
||||||
確認方式:
|
確認方式:
|
||||||
|
|
||||||
1. 先 `git fetch --prune origin`,再把事實攤開:目前分支、工作區是否乾淨、遠端有哪些分支(`git branch -r`,不看本地)、下節判定出的遠端預設分支。
|
1. 先 `git fetch --prune origin`,再把事實攤開:目前分支、工作區是否乾淨、遠端有哪些分支(`git branch -r`,不看本地)、下節判定出的遠端預設分支。
|
||||||
2. 依 `jsc-ask:ask` 的決策樹詢問,每個選項都要標明影響範圍。分析錯分支會產出對不上程式碼的工作包;目標分支錯了則 PR 會開到錯的地方。
|
2. 依 `jsc-ask:ask` 的決策樹詢問,每個選項都要標明影響範圍。分析錯分支會產出對不上程式碼的工作包;來源分支錯了則 worktree 從錯的起點長出來,PR 也會開到錯的地方。
|
||||||
3. 把確認結果寫進產出(分析頁的來源分支欄、PR 的目標分支),後續步驟一律沿用同一個答案,不再自行改判。
|
3. 把確認結果寫進產出(分析頁的來源分支欄),後續步驟一律沿用同一個答案,不再自行改判。
|
||||||
4. 使用者沒回答就**不預設** `develop`/`master`;預設值只在使用者明確同意後才成立。
|
4. 使用者沒回答就**不預設** `develop`/`master`;預設值只在使用者明確同意後才成立。
|
||||||
|
|
||||||
## 判定遠端預設分支
|
## 判定遠端預設分支
|
||||||
@@ -52,8 +52,11 @@ SDLC 各階段引用的參考分支與來源分支,**一律指遠端的 `origi
|
|||||||
|
|
||||||
## 實作階段的分支選擇
|
## 實作階段的分支選擇
|
||||||
|
|
||||||
- 判斷同名與否,兩邊都用遠端的分支名(`origin/{來源分支}` 與 `origin/{目標分支}`)。
|
實作在 worktree 內進行,工作分支從 `origin/{來源分支}` 長出來,做完再 PR 回同一條來源分支。
|
||||||
- **只有來源分支與目標分支同名時才開新的工作分支**:同名就不可在該分支上直接 commit,改從已更新到最新的目標分支建立新工作分支,後續操作都以新分支為準。不同名就在目前分支處理。
|
|
||||||
|
- **一個工作包一個 PR**,目標一律是 `origin/{來源分支}`。不把兩個完成的工作包併成一個 PR,也不把完成的工作包留到下一包一起送——拆工作包的意義就是各自能獨立審查。
|
||||||
|
- 呼叫 `jsc-git:pr` 時**必須明確帶入來源分支當 base**。該 skill 在沒收到 base 時會自行退回 `develop`,那會讓單一工作包越過它所屬的功能分支直接進 develop。
|
||||||
|
- 來源分支整條後續要進 `develop` 時,那是另一個獨立的 PR,不在本階段範圍。
|
||||||
- 新分支名稱要可讀且不覆蓋既有分支;本地或遠端已存在同名分支時,換一個時間戳或短 hash。
|
- 新分支名稱要可讀且不覆蓋既有分支;本地或遠端已存在同名分支時,換一個時間戳或短 hash。
|
||||||
- 切換或建立分支屬不可忽略的狀態變更,要在輸出中講清楚原因與結果分支名稱。
|
- 切換或建立分支屬不可忽略的狀態變更,要在輸出中講清楚原因與結果分支名稱。
|
||||||
|
|
||||||
|
|||||||
+14
-12
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: implement
|
name: implement
|
||||||
description: SDLC implementation stage. Gate on capability tags enforced in code by sdlc-gate (implement requires coding), confirm the target branch before writing any file, then claim a ready work package from ANALYZE_CONTENTS with a work ticket, create a worktree from the analysis page's source branch under .worktree/{分析頁 HASH}/{repo}, and complete its TDD todos one by one inside it, updating the wiki after every item. A delivery package confirms its content type (API document or user-defined) before its first todo. Ends with jsc-review code-review, opens the PR and only then removes the worktree, asks which delivery-document format to produce (DELIVER_{HASH} wiki page or Gitea issue comment), and optionally registers the project in MAINTAIN_CONTENTS. Use when analysis is done and code must be written; not for planning or analysis.
|
description: SDLC implementation stage. Gate on capability tags enforced in code by sdlc-gate (implement requires coding), confirm the analysis page's source branch (which is both the worktree base and the PR target), claim a ready work package from ANALYZE_CONTENTS with a work ticket, create a worktree from origin/{來源分支} under .worktree/{分析頁 HASH}/{repo}, and complete its TDD todos one by one inside it, updating the wiki after every item. Every finished work package gets its own commit, push and PR back to the source branch, and its worktree is removed only after that PR exists. A delivery package confirms its content type (API document or user-defined) before its first todo, and at the end you ask which delivery-document format to produce (DELIVER_{HASH} wiki page or Gitea issue comment) before optionally registering the project in MAINTAIN_CONTENTS. Use when analysis is done and code must be written; not for planning or analysis.
|
||||||
---
|
---
|
||||||
|
|
||||||
# implement
|
# implement
|
||||||
@@ -15,12 +15,12 @@ All wiki reads and writes go through `jsc-gitea:wiki`.
|
|||||||
2. Run `jsc-hooks/hooks/sdlc-gate.sh lock implement`. The script reads the **actual** model id from the transcript, compares it against this stage's required tags (`coding`), and locks the stage only when they match.
|
2. Run `jsc-hooks/hooks/sdlc-gate.sh lock implement`. The script reads the **actual** model id from the transcript, compares it against this stage's required tags (`coding`), and locks the stage only when they match.
|
||||||
3. **Never claim a capability tag you have not verified with that script**, and never substitute your own judgement for its verdict. Non-zero exit = blocked: relay the script's message verbatim, stop the skill, do nothing else this turn. Do not run `unlock` to get past the gate; only the user may decide that.
|
3. **Never claim a capability tag you have not verified with that script**, and never substitute your own judgement for its verdict. Non-zero exit = blocked: relay the script's message verbatim, stop the skill, do nothing else this turn. Do not run `unlock` to get past the gate; only the user may decide that.
|
||||||
4. Exit 0 means the stage is locked. From now until the next stage's gate runs, the sdlc-gate hook blocks every prompt whose model stops satisfying the tags.
|
4. Exit 0 means the stage is locked. From now until the next stage's gate runs, the sdlc-gate hook blocks every prompt whose model stops satisfying the tags.
|
||||||
2. **Confirm the target branch** — do this **before writing any file**:
|
2. **Confirm the source branch — it is also this stage's PR target**:
|
||||||
1. Run `git fetch --prune origin` first — every `origin/...` reference is stale cache without it. Then report the current branch, whether the working tree is clean, which of `origin/develop` / `origin/master` exist, and the remote default branch resolved per `references/branch.md`. **Branches are always the remote ones; local branches are never the basis.**
|
1. Run `git fetch --prune origin` first — every `origin/...` reference is stale cache without it. Then read the source branch from the analysis page and report it, along with the current branch and whether the working tree is clean. **Branches are always the remote ones; local branches are never the basis.**
|
||||||
2. Ask per `jsc-ask:ask` rules which branch this work merges into; state the impact scope on every option (the answer decides the PR target and, when it collides with the current branch, forces a new working branch).
|
2. Ask per `jsc-ask:ask` rules to confirm that `origin/{來源分支}` is both the worktree's base and the PR target for every work package in this analysis. State the impact scope: each finished work package merges back into the source branch, and that branch as a whole reaches `develop` later as its own separate PR.
|
||||||
3. Uncommitted changes in the working tree → warn first and let the user commit or back them up; never discard them.
|
3. `origin/{來源分支}` does not exist on the remote → report and stop. Never fall back to `develop` silently.
|
||||||
4. Apply `references/branch.md` to the confirmed target: source branch and target branch sharing a name means creating a new working branch instead of committing on the target; report the resulting branch name.
|
4. Uncommitted changes in the main working directory → warn first and let the user commit or back them up; never discard them. Implementation happens in a worktree (step 7), so the main working directory stays untouched anyway.
|
||||||
5. Record the confirmed target branch on the analysis page next to the work ticket, and reuse it as the PR target in `jsc-git:pr`. Completion condition: the user has confirmed the target branch explicitly; never fall back to `develop` silently.
|
5. Record the confirmed source branch on the analysis page next to the work ticket. Completion condition: the user has confirmed it explicitly.
|
||||||
3. **Generate a work ticket**: format `TICKET_{yyyyMMdd}_{HHmmss}_{HASH}`. `{HASH}` = the shared wiki hash for `{owner}/{repo}`, computed by `jsc-gitea/tools/hash-id` (see `jsc-gitea:wiki`). Try to rename the current session to the ticket name (skip when the CLI does not support it).
|
3. **Generate a work ticket**: format `TICKET_{yyyyMMdd}_{HHmmss}_{HASH}`. `{HASH}` = the shared wiki hash for `{owner}/{repo}`, computed by `jsc-gitea/tools/hash-id` (see `jsc-gitea:wiki`). Try to rename the current session to the ticket name (skip when the CLI does not support it).
|
||||||
4. Read `ANALYZE_CONTENTS` via `jsc-gitea:wiki` and list what is unfinished: plan name, HASH, work package number, count of open items. A selectable work package must satisfy all three: **unfinished, dependency-free (or all dependencies done), and not holding a work ticket**.
|
4. Read `ANALYZE_CONTENTS` via `jsc-gitea:wiki` and list what is unfinished: plan name, HASH, work package number, count of open items. A selectable work package must satisfy all three: **unfinished, dependency-free (or all dependencies done), and not holding a work ticket**.
|
||||||
5. Let the user pick a work package per `jsc-ask:ask` rules (options state open-item count and estimated effort). **List delivery packages (交付 `是`) first** — the analysis page makes `WP-01` the standalone delivery package, so keep that order in the options. Write the ticket into that work package's ticket column (the zh-TW field 「工作證」) on the analysis page and save it back to the wiki. **Only after the ticket is saved successfully may you proceed.**
|
5. Let the user pick a work package per `jsc-ask:ask` rules (options state open-item count and estimated effort). **List delivery packages (交付 `是`) first** — the analysis page makes `WP-01` the standalone delivery package, so keep that order in the options. Write the ticket into that work package's ticket column (the zh-TW field 「工作證」) on the analysis page and save it back to the wiki. **Only after the ticket is saved successfully may you proceed.**
|
||||||
@@ -41,11 +41,13 @@ All wiki reads and writes go through `jsc-gitea:wiki`.
|
|||||||
- Follow the TDD loop: red before green, one slice at a time; rules and anti-patterns in `references/tdd.md` (refactoring belongs to the review stage).
|
- Follow the TDD loop: red before green, one slice at a time; rules and anti-patterns in `references/tdd.md` (refactoring belongs to the review stage).
|
||||||
- After each item, flip its `[ ]` to `[x]` on the analysis page and save to the wiki before starting the next item.
|
- After each item, flip its `[ ]` to `[x]` on the analysis page and save to the wiki before starting the next item.
|
||||||
9. When all items are done, call `jsc-review:code-review` and wait for the review; on failure, fix and re-review until it passes.
|
9. When all items are done, call `jsc-review:code-review` and wait for the review; on failure, fix and re-review until it passes.
|
||||||
10. **Open the PR, then remove the worktree** — in that order, never the reverse:
|
10. **One work package finished → commit, push, PR back to the source branch, then remove the worktree** — in that order, never the reverse:
|
||||||
1. Call `jsc-git:pr` with the target branch confirmed in step 2. Commits come from inside the worktree.
|
1. **One work package, one PR.** Never let two finished packages share a PR, and never carry a finished package over to the next one — the point of splitting packages is that each lands reviewable on its own.
|
||||||
2. **Only after `jsc-git:pr` reports the PR was created successfully**, run `git worktree remove {路徑}` for each worktree, then `git worktree prune`. PR creation failed → keep the worktree so the user can take over.
|
2. Call `jsc-git:pr` from inside the worktree, **passing `{來源分支}` as the base branch**. It commits everything (via `jsc-git:commit`), creates the working branch, pushes, and opens the PR. `jsc-git:pr` falls back to `develop` when no base is passed in, so passing it explicitly is what keeps a single work package from merging straight past its feature branch.
|
||||||
3. Uncommitted changes still inside a worktree → **do not remove it**; report and stop. Those changes never reached the PR, and removing would throw them away.
|
3. **Only after `jsc-git:pr` reports the PR was created successfully**, run `git worktree remove {路徑}` for each worktree of this package, then `git worktree prune`. PR creation failed → keep the worktree so the user can take over.
|
||||||
4. Once every worktree of this analysis is gone and `.worktree/{HASH}/` is empty, delete that directory too.
|
4. Uncommitted changes still inside a worktree → **do not remove it**; report and stop. Those changes never reached the PR, and removing would throw them away.
|
||||||
|
5. Once every worktree of this analysis is gone and `.worktree/{HASH}/` is empty, delete that directory too.
|
||||||
|
6. Report the PR URL and its base branch. Completion condition: the PR exists and points at `{來源分支}`.
|
||||||
11. **Delivery document** — a finished work package is a delivery, so **always ask before producing it; never pick a format silently and never skip this step**:
|
11. **Delivery document** — a finished work package is a delivery, so **always ask before producing it; never pick a format silently and never skip this step**:
|
||||||
1. Ask per `jsc-ask:ask` rules which format to produce. The options are fixed: **a `DELIVER_{HASH}` wiki page** or **a Gitea issue comment**. State the impact scope on each (the wiki page lives beside the plan and analysis pages; the issue comment reaches whoever follows that issue).
|
1. Ask per `jsc-ask:ask` rules which format to produce. The options are fixed: **a `DELIVER_{HASH}` wiki page** or **a Gitea issue comment**. State the impact scope on each (the wiki page lives beside the plan and analysis pages; the issue comment reaches whoever follows that issue).
|
||||||
2. Both formats use the same structure — `templates/deliver-page.md`, in Traditional Chinese. Only the destination differs.
|
2. Both formats use the same structure — `templates/deliver-page.md`, in Traditional Chinese. Only the destination differs.
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
- HASH:`{HASH}`
|
- HASH:`{HASH}`
|
||||||
- 對應分析:[ANALYZE_{HASH}]({ANALYZE 頁絕對網址})
|
- 對應分析:[ANALYZE_{HASH}]({ANALYZE 頁絕對網址})
|
||||||
- 存取庫:`{owner}/{repo}`
|
- 存取庫:`{owner}/{repo}`
|
||||||
- 目標分支:`{使用者確認的目標分支}`
|
- 來源分支(=PR 目標):`origin/{來源分支}`
|
||||||
- 工作證:`TICKET_{yyyyMMdd}_{HHmmss}_{HASH}`
|
- 工作證:`TICKET_{yyyyMMdd}_{HHmmss}_{HASH}`
|
||||||
- 交付工作包:是 <!-- 是 | 否 -->
|
- 交付工作包:是 <!-- 是 | 否 -->
|
||||||
- 交付型別:API 文件 <!-- API 文件 | 由使用者輸入:{說明} -->
|
- 交付型別:API 文件 <!-- API 文件 | 由使用者輸入:{說明} -->
|
||||||
|
|||||||
Reference in New Issue
Block a user