feat(sdlc): 工作包隔離、留言取得共識後再修、盯 PR 到合併與每任務一筆日誌 #29
+25
-12
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: implement
|
||||
description: SDLC implementation stage. Gate on capability tags enforced in code by sdlc-gate (implement requires coding), then confirm the analysis page's source branch - it is both the worktree base and the PR target. Every already-open work package's PR comments get triaged via tools/wp-gate.sh check (sub agents fix them in that package's own worktree), but that never blocks a different, unrelated package - independent work packages can proceed in parallel. Picking a candidate is gated per-candidate in code by tools/wp-gate.sh check-deps, which re-reads the analysis page's WBS dependency column and queries Gitea itself: only a candidate whose own declared dependencies are merged may be claimed. Claim a ready work package from ANALYZE_CONTENTS with a work ticket, confirm a delivery package's content type, then complete its TDD todos one at a time inside a worktree built from origin/{source-branch}, updating the wiki after every item, closing with jsc-review code-review, one PR back to the source branch, the chosen delivery document, an optional MAINTAIN_CONTENTS entry, and a tools/stage-report.sh report covering the model tag verdict, the worklog link, every wiki link written, the worktree and the three branches. 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), then confirm the analysis page's source branch - it is both the worktree base and the PR target. Every already-open work package's PR comments get triaged via tools/wp-gate.sh check and fixed by sub agents only after jsc-ask consensus, never blocking an unrelated package; picking a candidate is gated per-candidate in code by tools/wp-gate.sh check-deps, and claiming it records the package number via tools/wp-gate.sh claim so tools/wp-gate.sh owns keeps every session on its own package's PR. Claim a ready work package from ANALYZE_CONTENTS with a work ticket, confirm a delivery package's content type, then complete its TDD todos one at a time inside a worktree built from origin/{source-branch}, updating the wiki after every item, closing with jsc-review code-review, one PR back to the source branch, a jsc-gitea pr-watch.sh poll that holds until that PR merges, a jsc-log:worklog entry per finished task, the chosen delivery document, an optional MAINTAIN_CONTENTS entry, and a tools/stage-report.sh report covering the model tag verdict, the worklog link, every wiki link written, the worktree and the three branches. Use when analysis is done and code must be written; not for planning or analysis.
|
||||
---
|
||||
|
||||
# implement
|
||||
@@ -20,17 +20,22 @@ All wiki reads and writes go through `jsc-gitea:wiki`.
|
||||
4. **Settle every already-open work-package PR's comments — this keeps existing PRs moving, but does not by itself decide which new package may start (that's step 6)**:
|
||||
1. Read the analysis page's PR column. For every work package holding a PR that is not marked merged, run `jsc-sdlc/tools/wp-gate.sh check {owner}/{repo} {index} --since {the comment timestamp recorded in that PR column}`. Drop `--since` when that package has no recorded timestamp yet.
|
||||
2. Exit 0 (`status=merged`) clears that package: remove its worktree (`references/branch.md`) and mark the package done on the analysis page.
|
||||
3. Exit 1 (`status=open` or `status=closed-unmerged`) means that package's own PR is not settled yet. Fix every comment the script printed — issue comments, review verdicts and inline comments alike. **Each round of fixes MUST run as a sub agent** inside that package's own worktree, pushing to the same work branch, so the PR updates itself. Never open a second PR for the same package, and never ask whether to fix or wait: the gate already decided. **This does not block picking a different, unrelated work package** — SDLC implementation can run several independent packages in parallel; an unmerged PR only holds back packages that depend on it (step 6 checks that specifically), never the whole analysis page.
|
||||
4. Give every printed comment an outcome — fixed, no fix needed, or cannot fix. Ignore what you cannot fix, plus pure discussion and praise: do not reply on the PR and do not stop the flow, and list each ignored comment with its reason in your final report.
|
||||
5. Write the script's `latest=` value into that work package's PR column, appended after the existing PR link as `#{index} 已處理留言 {ISO time}`, and save the page back to the wiki. Next run passes it as `--since`, so handled comments stay handled. Reuse the existing PR column; the analysis page's columns belong to `analyze`.
|
||||
6. Exit 3 means the gate could not decide (a missing dependency, or the PR could not be found). Report it and stop — an undecidable gate never counts as merged.
|
||||
7. Completion condition: every work package holding an unmerged PR has had this run's comments triaged (fixed, no fix needed, or cannot fix) and reported; a package left unmerged after this does not block step 5/6 for packages that do not depend on it.
|
||||
3. Exit 1 (`status=open` or `status=closed-unmerged`) means that package's own PR is not settled yet. **This does not block picking a different, unrelated work package** — SDLC implementation can run several independent packages in parallel; an unmerged PR only holds back packages that depend on it (step 6 checks that specifically), never the whole analysis page. Sub-steps 4.4 to 4.9 are the one comment round this skill owns; step 11.5 runs the same sub-steps for the PR it just opened.
|
||||
4. **The PR has to be yours before you touch it.** Run `jsc-sdlc/tools/wp-gate.sh owns {owner}/{repo} {index} --wp {the work package number that PR column belongs to}`. `status=owned` → carry on. `status=foreign` (exit 1) → leave that PR alone, name the work package the script says holds it, and let that package's own session handle it. `status=unowned` (exit 0) → carry on, and report that ownership could not be determined. Completion condition: the script has run for that PR and its verdict is reported.
|
||||
5. **Agree on the fix before making it.** Run the `jsc-ask:ask` decision tree over the comments the script printed — issue comments, review verdicts and inline comments alike — one option set per comment, each option stating its impact scope (which files it touches, whether it changes the package's TDD todos). **Never fix a comment automatically**: a reviewer's wording often allows two different fixes, and picking one silently costs another review round. Completion condition: the user has said how each comment is handled before any file is edited.
|
||||
6. **Each round of fixes MUST run as a sub agent** inside that package's own worktree, pushing to the same work branch, so the PR updates itself. Hand the sub agent the agreed decisions and let the comment text stay inside it — the main agent keeps only the decisions and the bookkeeping. Never open a second PR for the same package.
|
||||
7. Give every printed comment an outcome — fixed, no fix needed, or cannot fix. Ignore what you cannot fix, plus pure discussion and praise: do not reply on the PR and do not stop the flow, and list each ignored comment with its reason in your final report.
|
||||
8. Write the script's `latest=` value into that work package's PR column, appended after the existing PR link as `#{index} 已處理留言 {ISO time}`, and save the page back to the wiki. Next run passes it as `--since`, so handled comments stay handled. Reuse the existing PR column and add no new column; the analysis page's columns belong to `analyze`.
|
||||
9. **One round of comment fixes is one finished task — call `jsc-log:worklog` now**, under the Rules section's one-task-one-entry rule. Completion condition: the entry for this round is saved on `LOG_{HASH}` before the next round starts.
|
||||
10. Exit 3 means the gate could not decide (a missing dependency, or the PR could not be found). Report it and stop — an undecidable gate never counts as merged.
|
||||
11. Completion condition: every work package holding an unmerged PR has had this run's comments triaged (fixed, no fix needed, or cannot fix), logged and reported; a package left unmerged after this does not block step 5/6 for packages that do not depend on it.
|
||||
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, not holding a work ticket, and — verified by step 6's `wp-gate.sh check-deps`, never by eyeballing the 相依 column yourself — dependency-free or all dependencies merged**. Completion condition: you have listed every selectable work package, or reported that none is selectable and stopped.
|
||||
6. **Before picking, the candidate's own dependencies decide — the gate lives in code, not in this text, and it is scoped to that one candidate, never to every open PR on the page**:
|
||||
1. For the candidate work package the user is about to choose, run `jsc-sdlc/tools/wp-gate.sh check-deps {owner}/{repo} {wp-number}`. It re-reads the analysis page and queries Gitea itself — it does not trust anything you already read or concluded.
|
||||
2. Exit 0 (`status=ready`) → eligible; proceed to claim it. Exit 1 (`status=blocked`) → not eligible; report which dependency work package's PR is not merged yet, and offer the user the other eligible candidates instead of this one. Exit 3 (`status=missing-dep`) is an undecidable gate — report it and stop; never treat an undecidable result as either ready or blocked.
|
||||
3. A dependency phrased as text pointing outside this analysis page (another plan, another analysis) cannot be checked by the script; it comes back listed separately as needing manual confirmation. Confirm it with the user before proceeding — an unchecked cross-page dependency is not the same as a cleared one.
|
||||
4. Let the user pick per `jsc-ask:ask` rules from the eligible candidates only (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. Completion condition: `check-deps` returned `status=ready` for the picked candidate (any cross-page dependency confirmed with the user), the ticket is saved on the wiki; only then may you proceed.
|
||||
4. Let the user pick per `jsc-ask:ask` rules from the eligible candidates only (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.
|
||||
5. **Record the claim in code, so later steps can tell this package's PR from any other package's**: run `jsc-sdlc/tools/wp-gate.sh claim {owner}/{repo} {wp-number} --analyze ANALYZE_{HASH}`, with the number read off the analysis page — the work package number is the only thing ownership is judged by (`references/branch.md`). One repository holds one claim at a time; `wp-gate.sh check` hands it back once the PR merges. Completion condition: `check-deps` returned `status=ready` for the picked candidate (any cross-page dependency confirmed with the user), the ticket is saved on the wiki, and `claim` returned `status=claimed`; only then may you proceed.
|
||||
7. **A delivery/handover package confirms its content before its first todo**:
|
||||
1. Ask per `jsc-ask:ask` rules what this delivery must contain. The options are fixed: **1. API 文件** and **2. 由使用者輸入**. State the impact scope on each. **Never assume the type, and never skip this — the answer decides what the whole package produces.**
|
||||
2. Required fields, sample-data order and the new-versus-existing parameter marking: `references/deliver-formats.md`.
|
||||
@@ -42,11 +47,18 @@ All wiki reads and writes go through `jsc-gitea:wiki`.
|
||||
3. **A code comment states why the code is written this way; it never states where the work is documented.** The tracking numbers this stage always holds — the work package number, the analysis page number, the TDD todo number, the source branch name and the PR number — stay out of every code comment; write the reason itself into the comment instead. Full list and the allowed exceptions: `jsc-review/references/comment-scope.md`. `jsc-hooks/hooks/comment-scope.sh` compares each file after it is written and prints a warning; fix the flagged line at once, then carry on with the same item. Completion condition: the item's own diff holds no comment line carrying any of those numbers, and every warning the hook printed for this item is fixed.
|
||||
4. Completion condition: every item of the package shows `[x]` on the saved analysis page, and each save happened before the next item's sub agent started.
|
||||
10. When all items are done, sweep the work package's whole diff for the comment rule of step 9.3, then call `jsc-review:code-review` and wait for the verdict. Each round of fixes **MUST run as a sub agent** inside the same worktree. Completion condition: the review passes, and the diff handed to it holds no comment line carrying the work package number, the analysis page number, a TDD todo number, the source branch name or a PR number (full list: `jsc-review/references/comment-scope.md`).
|
||||
11. **One work package finished → commit, push, PR back to the source branch. Then stop and wait for that PR**:
|
||||
1. Call `jsc-git:pr` from inside the worktree, **passing `{source-branch}` as the base branch**. One package, one PR; the branch rules behind that are in `references/branch.md`.
|
||||
11. **One work package finished → commit, push, PR back to the source branch, then hold on that PR until it merges**:
|
||||
1. Call `jsc-git:pr` from inside the worktree, **passing `{source-branch}` as the base branch**. One package, one PR; the branch ladder and how the base is derived are in `references/branch.md`.
|
||||
2. 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).
|
||||
3. Run `jsc-sdlc/tools/wp-gate.sh lock {owner}/{repo} {index}`. The lock is what makes step 4's gate hold across work sessions — a new session starts blocked until that PR merges.
|
||||
4. **Do not start another work package.** Completion condition: the PR exists, its URL is saved on the analysis page and reported to the user, the lock exists (`status=locked`), and the skill has stopped.
|
||||
3. Run `jsc-sdlc/tools/wp-gate.sh lock {owner}/{repo} {index} --wp {wp-number}`. The lock is what makes step 4's gate hold across work sessions — a new session starts blocked until that PR merges — and `--wp` is what hangs this PR on the claim from step 6.5, so `owns` can keep other sessions off it. Leave `--wp` out and every session is free to touch this PR. Completion condition: the script printed `status=locked` and named the work package.
|
||||
4. **The work package is finished the moment its PR is open — call `jsc-log:worklog` now**, under the Rules section's one-task-one-entry rule. Completion condition: the entry is saved on `LOG_{HASH}` before the wait starts.
|
||||
5. **Wait for the merge with `jsc-gitea/tools/pr-watch.sh {owner}/{repo} {index}`** — it polls every 60 seconds (`JSC_PR_WATCH_INTERVAL` overrides), never times out, and never repeats a comment it already reported. Branch on its exit code:
|
||||
- `0` — the PR merged or was closed. Run `jsc-sdlc/tools/wp-gate.sh check {owner}/{repo} {index}` to tell merged from closed-unmerged, release the lock and hand the claim back. `status=merged` → remove the worktree (`references/branch.md`) and mark the package done on the analysis page; `status=closed-unmerged` → report it and stop, closed without merging is not finished. Comments printed in that final round still get an outcome per step 4.5 to 4.9.
|
||||
- `10` — new comments are waiting. Run step 4.4 to 4.9 over them (ownership, consensus, sub agent fixes, outcomes, timestamp, work log), then run `pr-watch.sh` again. Repeat for as many rounds as the reviewer needs.
|
||||
- `3` — the PR could not be found. Report and stop; a PR nobody can find never counts as merged.
|
||||
- `2` — bad arguments, or Gitea was unreachable on the very first poll. Fix the arguments or the environment and run it again; never fall back to eyeballing the PR page and calling it merged.
|
||||
6. **Do not start another work package in this session.** An unrelated package can still proceed, but in its own session with its own worktree; packages that depend on this one stay blocked until step 4 or step 11.5 sees it merged.
|
||||
7. Completion condition: the PR exists, its URL is saved on the analysis page and reported to the user, the lock existed (`status=locked`), the work log entry is saved, and `pr-watch.sh` has returned `0` with `wp-gate.sh check` confirming `status=merged` — or the run stopped on a reported `2`, `3` or `status=closed-unmerged`.
|
||||
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. Sample values and personal-data handling: `references/deliver-formats.md`.
|
||||
@@ -56,13 +68,14 @@ All wiki reads and writes go through `jsc-gitea:wiki`.
|
||||
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. Completion condition: the user has answered, and a chosen registration is saved on the wiki.
|
||||
14. **Stage report — the last thing this stage does, including every early stop** (the work package gate blocked, no work package was selectable, the source branch was missing from the remote). Run `tools/stage-report.sh implement` with:
|
||||
- one `--page TYPE:{page}` per wiki page this run wrote — `ANALYZE_{HASH}`, `DELIVER_{HASH}` and `DELIVER_CONTENTS`, `MAINTAIN_CONTENTS`;
|
||||
- `--worklog` and `--worklog-heading` when a work log entry exists; otherwise write this stage's log content to a file and pass `--pending-file {file} --log-hash {HASH}`, which holds it for the next `jsc-log:worklog` run;
|
||||
- `--worklog` and `--worklog-heading` pointing at the entry step 11.4 wrote — following the Rules section's one-task-one-entry rule, a stage that finished anything already has one. `--pending-file {file} --log-hash {HASH}` is the fallback for a stage that stopped before any task finished: it holds the content for the next `jsc-log:worklog` run, and held content is not a written log;
|
||||
- `--worktree {path} --source-branch {name} --work-branch {name} --pr {url}` — the script reads the commit count, the push state and whether the source branch exists on the remote by itself, so pass the names, not your own count.
|
||||
|
||||
Rules and exit codes: `references/stage-report.md`. Exit 1 is a warning, never a block. Completion condition: the script's output is reported to the user verbatim, and it names the worktree, all three branches and every wiki page this run wrote.
|
||||
|
||||
## Rules
|
||||
|
||||
- **One finished task, one work log entry.** A task is one of three things: one work package, one round of PR-comment fixes, or one standalone fix commit. Call `jsc-log:worklog` the moment one of them finishes — never let a stage end and then write a single catch-up entry, because by then the elapsed time, the token counts and the difficulties are gone. Every entry appends to the same `LOG_{HASH}` page, so one package that took five comment rounds leaves five entries. Content parked earlier by `tools/stage-report.sh --pending-file` is merged into that same write and cleared only once the write succeeds; parked content is not a written log.
|
||||
- The work ticket is a mutex: always skip work packages that already hold a ticket; never take one over.
|
||||
- Never batch wiki updates across items; one item, one update.
|
||||
- Sample data written into code or fixtures follows the analysis page's 資料來源 column, under the rules in `references/deliver-formats.md`.
|
||||
|
||||
Reference in New Issue
Block a user