From 3cc5bb5cd2720022fab7f90fd581730854ae87e0 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Tue, 25 Aug 2026 12:08:11 +0800 Subject: [PATCH] =?UTF-8?q?feat(PR=20=E9=98=BB=E6=93=8B):=20PR=20=E6=9C=AA?= =?UTF-8?q?=E5=90=88=E4=BD=B5=E4=B8=8D=E9=96=8B=E4=B8=8B=E4=B8=80=E5=8C=85?= =?UTF-8?q?=EF=BC=8C=E6=AA=A2=E6=9F=A5=E6=99=82=E4=B8=80=E4=BD=B5=E8=AE=80?= =?UTF-8?q?=E7=95=99=E8=A8=80=E4=B8=A6=E8=A9=A2=E5=95=8F=E6=98=AF=E5=90=A6?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5 (1M context) --- references/branch.md | 16 +++++++++++++--- skills/implement/SKILL.md | 34 ++++++++++++++++++++-------------- templates/analyze-page.md | 11 ++++++----- 3 files changed, 39 insertions(+), 22 deletions(-) diff --git a/references/branch.md b/references/branch.md index 1b2c739..92e93f8 100644 --- a/references/branch.md +++ b/references/branch.md @@ -95,13 +95,23 @@ SDLC 各階段引用的參考分支與來源分支,**一律指遠端的 `origi ### 移除時機 -**PR 建立成功後自動移除**:`git worktree remove {路徑}`。 +**PR 合併之後才移除**:`git worktree remove {路徑}`,接著 `git worktree prune`。 -- 只有 `jsc-git:pr` 回報 PR 建立成功才移除;PR 失敗就保留,讓使用者能接手處理。 +不是 PR 建立後就移除——審查留言可能要求修改,而修改要回到同一個 worktree、推到同一條工作分支(PR 會自己更新,不開第二個 PR)。先移除就得為了改一行重建整個 worktree。 + +- PR 尚未合併 → 保留。PR 建立失敗 → 保留,讓使用者接手處理。 - worktree 內還有未提交變更時**不移除**,回報並停止——那些變更沒有進 PR,移除等於丟掉。 -- 移除後順手 `git worktree prune` 清掉殘留記錄。 - 同一份分析的多個 worktree 全部移除後,若 `.worktree/{HASH}/` 已空就一併刪掉那層目錄。 +### PR 未合併就不開下一個工作包 + +一個工作包的 PR 還沒合併,就不得開始下一包。每次要領工作包之前先確認: + +1. `gitea.sh pr-status {owner}/{repo} {index}` 看 `{state} {merged} {mergeable}`。 +2. 未合併 → **同時**用 `gitea.sh pr-comments {owner}/{repo} {index}` 讀留言(issue 留言、審查評語、行內留言,含沒有文字的 `APPROVED`/`REQUEST_CHANGES`),原文轉述給使用者。 +3. 依 `jsc-ask:ask` 詢問:依留言修正(回原 worktree 改、推同一條工作分支)或先等待。**不自行決定,也不為同一包開第二個 PR。** +4. 已關閉但未合併 → 回報並詢問,不得當成完成。 + ## 不破壞既有工作 - 工作區有未提交變更時,先提醒使用者 commit 或備份,**絕不**強制丟棄。 diff --git a/skills/implement/SKILL.md b/skills/implement/SKILL.md index 97ba4ee..b3e2013 100644 --- a/skills/implement/SKILL.md +++ b/skills/implement/SKILL.md @@ -1,6 +1,6 @@ --- name: implement -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. +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, then the stage stops: no further package may start until that PR merges, and each check of it also reads the PR comments and asks the user whether to fix accordingly. 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 @@ -22,14 +22,21 @@ All wiki reads and writes go through `jsc-gitea:wiki`. 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 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). -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.** -6. **When the package taken is a delivery/handover package, confirm its content before doing any of its todos**: +4. **Before picking anything, settle the previous work package's PR.** A work package whose PR is still open blocks the next one — no exceptions: + 1. Read the analysis page's PR column. Any work package holding a PR that is not merged → run `jsc-gitea/tools/gitea.sh pr-status {owner}/{repo} {index}` (prints `{state} {merged} {mergeable}`). + 2. `merged=true` → clear the block: remove that package's worktree (`git worktree remove {路徑}` then `git worktree prune`; `.worktree/{HASH}/` empty → delete it too), mark the package done on the analysis page, and continue. + 3. Not merged → **read the comments in the same breath**: `jsc-gitea/tools/gitea.sh pr-comments {owner}/{repo} {index}` returns issue comments, review verdicts (including `APPROVED` / `REQUEST_CHANGES` with no text) and inline code comments, sorted by time. Show them to the user verbatim — author, time, and what they said. + 4. Ask per `jsc-ask:ask` rules what to do, with the options: **fix per the comments** (go back into that package's worktree, implement the fix, push to the same working branch — the PR updates itself, no new PR), or **leave it and wait**. State the impact scope on each. **Never decide this yourself, and never open a second PR for the same package.** + 5. Closed but not merged → report it and ask the user how to proceed; do not silently treat it as done. + 6. **Only when no unmerged PR remains may you go on.** Stop here otherwise. +5. 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**. +6. 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.** +7. **When the package taken is a delivery/handover package, confirm its content before doing any of its todos**: 1. Ask per `jsc-ask:ask` rules what this delivery must contain. The default options are fixed: **1. API 文件** (endpoint path, **every** input parameter, **every** output parameter) and **2. 由使用者輸入** (the user states the content themselves). State the impact scope on each. **Never assume the type, and never skip this — the answer decides what the whole package produces.** 2. Chose API 文件 → follow `references/deliver-formats.md`: all parameters listed (not just the main ones), each with name, type, required flag, example, data source and new-versus-existing status; sample values take real sources first and are labelled `真實:{來源}` or `推論:無來源`; **an existing endpoint must mark new versus old parameters both ways** — the status column (🆕 新增 / ⚠️ 變更 / ❌ 移除 / blank for untouched) and a `diff` code block for colour. HTML `style` attributes get filtered by the wiki, so never rely on them. 3. Chose 由使用者輸入 → produce exactly what the user described; do not force the API document layout onto it. 4. Record the confirmed type in the analysis page's 交付型別 column and save it before starting the todos. -7. **Create the worktree — before touching any code**. Full rules in `references/branch.md`: +8. **Create the worktree — before touching any code**. Full rules in `references/branch.md`: 1. Run `git fetch --prune origin`, then read the **source branch** and the repositories involved from the analysis page. The worktree is built from `origin/{來源分支}` — **never from a local branch of the same name**, which may be behind, ahead or diverged. Every code change happens inside the worktree; the main working directory's branch and working tree stay untouched. 2. Path: `{工作目錄}/.worktree/{分析頁 HASH}/{repo}` — the HASH without the `ANALYZE_` prefix, the repo name without its owner. One worktree per repository, all under the same HASH directory. 3. **Ask per `jsc-ask:ask` rules how to handle the branch**, with the two fixed options: create a new working branch off the remote source branch (`git worktree add -b {工作分支} {路徑} "origin/{來源分支}"`), or check the source branch out with remote tracking (`git worktree add --track -b {來源分支} {路徑} "origin/{來源分支}"`). State the impact scope on each. **Never assume, never skip the question.** @@ -37,25 +44,24 @@ All wiki reads and writes go through `jsc-gitea:wiki`. 5. No local clone of that repository → stop and ask the user for its path; never clone on your own initiative and never guess the location. 6. Add `.worktree/` to that repository's `.git/info/exclude` — never edit the user's shared `.gitignore`. 7. Report the worktree path, the checked-out branch, the source branch and the commit sha `origin/{來源分支}` pointed at — that sha is this implementation's starting point and must stay traceable. Completion condition: every involved repository has a worktree and you have reported all of them. -8. List every open item of the work package and implement them **one at a time**, **inside the worktree**: +9. List every open item of the work package and implement them **one at a time**, **inside the worktree**: - 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. -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. **One work package finished → commit, push, PR back to the source branch, then remove the worktree** — in that order, never the reverse: +10. When all items are done, call `jsc-review:code-review` and wait for the review; on failure, fix and re-review until it passes. +11. **One work package finished → commit, push, PR back to the source branch. Then stop and wait for that PR**: 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. 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. **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. 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**: + 3. Write the PR URL and number into that work package's PR column on the analysis page and save it back to the wiki, so the next run of this skill can find it (step 4). + 4. **Keep the worktree.** It is removed only after the PR is merged — comments may ask for changes, and rebuilding a worktree to make them is wasted work. + 5. **Do not start another work package.** Report the PR URL and stop. The next run picks up at step 4, which checks whether this PR merged and reads its comments. +12. **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). 2. Both formats use the same structure — `templates/deliver-page.md`, in Traditional Chinese. Only the destination differs. 3. Wiki page: write `DELIVER_{HASH}` through `jsc-gitea:wiki`, where `{HASH}` comes from `jsc-gitea/tools/hash-id` over `{owner}/{repo}` plus the work package number (for example `plugins/sdlc#WP-01`), so each work package gets its own page instead of overwriting the previous one. A new page is added to `DELIVER_CONTENTS` per `templates/deliver-contents.md`. 4. Issue comment: confirm the issue number with the user (propose the one referenced by the work package or the PR; never guess), then post via `gitea/tools/gitea.sh api POST /repos/{owner}/{repo}/issues/{n}/comments` with the body passed in as a UTF-8 file — real newlines, never a literal `\n`. 5. Sample values follow the analysis page's 資料來源 column: `真實:{來源}` for real sources, `推論:無來源` for reasoned ones. Personal data never goes in — keep the field and format, drop the value. 6. Completion condition: the chosen format has actually been produced, and you have reported where it landed (wiki page name, or the comment URL). -12. Ask per `jsc-ask:ask` rules whether to register this project for maintenance: append to `MAINTAIN_CONTENTS` with `templates/maintain-contents.md`. Required: repository `{owner}/{repo}`, maintenance method, start date. Optional: end date (NULL = maintain forever), last-maintained time. +13. Ask per `jsc-ask:ask` rules whether to register this project for maintenance: append to `MAINTAIN_CONTENTS` with `templates/maintain-contents.md`. Required: repository `{owner}/{repo}`, maintenance method, start date. Optional: end date (NULL = maintain forever), last-maintained time. ## Rules diff --git a/templates/analyze-page.md b/templates/analyze-page.md index 5aa68bc..bec9345 100644 --- a/templates/analyze-page.md +++ b/templates/analyze-page.md @@ -30,12 +30,13 @@ `WP-01` 固定是交付/交接工作包,獨立成一包,不與實作合併;用到它規格的實作工作包相依於它。 交付型別於實作階段開工時確認(API 文件/由使用者輸入)。 資料來源欄記錄範例資料的出處:`真實:{來源}` 或 `推論:無來源`。 +PR 欄記錄該工作包的 PR 連結與編號;PR 未合併前不得開始下一個工作包。 -| 編號 | 工作包名稱 | 交付 | 交付型別 | 相依 | 工時(h) | 天數 | 資料來源 | 工作證 | 狀態 | -| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| WP-01 | {交付/交接:規格與介面定義} | 是 | API 文件 | - | {h} | {d} | 真實:{來源} | | 未完成 | -| WP-02 | {實作類名稱} | 否 | - | WP-01 | {h} | {d} | 真實:{來源} | | 未完成 | -| WP-03 | {實作類名稱} | 否 | - | WP-01 | {h} | {d} | 推論:無來源 | | 未完成 | +| 編號 | 工作包名稱 | 交付 | 交付型別 | 相依 | 工時(h) | 天數 | 資料來源 | 工作證 | PR | 狀態 | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| WP-01 | {交付/交接:規格與介面定義} | 是 | API 文件 | - | {h} | {d} | 真實:{來源} | | | 未完成 | +| WP-02 | {實作類名稱} | 否 | - | WP-01 | {h} | {d} | 真實:{來源} | | | 未完成 | +| WP-03 | {實作類名稱} | 否 | - | WP-01 | {h} | {d} | 推論:無來源 | | | 未完成 | - 關鍵路徑:{WP-01 → WP-02 → ⋯⋯},總天數 {d} - 實作候補:{WP-02、WP-03、⋯⋯}