From b78f7e8b3fc6a12db58d1881769724ab6600b78c Mon Sep 17 00:00:00 2001 From: Jeffery Date: Tue, 25 Aug 2026 14:58:54 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix(sdlc):=20=E8=A3=9C=E9=BD=8A=E7=A8=BD?= =?UTF-8?q?=E6=A0=B8=E7=BC=BA=E5=A4=B1=E4=B8=A6=E4=BF=AE=E6=8E=89=E8=AD=B7?= =?UTF-8?q?=E6=AC=84=E5=A4=B1=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What:依 jsc-meta:skill-check 的稽核結果修正技能與工具——補上每個步驟的可檢核完成條件、 把留在內文的標準輸入輸出流程下放 tools/、修正查表與退碼路由造成的誤判。 Why:稽核發現這些缺失會讓技能在實際執行時走錯分支或靜默通過。 完成條件缺漏是最常被違反的一項;退碼誤判與查表錯誤則會讓良性狀況被當成失敗。 How:逐項對照 references/guidelines.md 的審核檢查清單修正,新增的工具都有 documented exit codes,並以真實執行驗證每條路徑。 Who:jsc-meta:skill-check 例行稽核(2026-08-25)。 Co-Authored-By: Claude Opus 5 --- skills/analyze/SKILL.md | 51 ++++++++++-------------- skills/implement/SKILL.md | 82 ++++++++++++++------------------------- skills/maintain/SKILL.md | 23 +++++------ skills/plan/SKILL.md | 21 +++++----- 4 files changed, 70 insertions(+), 107 deletions(-) diff --git a/skills/analyze/SKILL.md b/skills/analyze/SKILL.md index 3bcb0fe..13fea7a 100644 --- a/skills/analyze/SKILL.md +++ b/skills/analyze/SKILL.md @@ -1,6 +1,6 @@ --- name: analyze -description: SDLC analysis stage. Gate on capability tags enforced in code by sdlc-gate (analyze requires reasoning-max, verified against the transcript's actual model id), confirm the source branch with the user, pick a plan from PLAN_CONTENTS, analyze user stories against the current state (working directory plus REPO_{HASH} inventory for reuse). Keep questioning until consensus per references/consensus.md, run WBS with the delivery/handover package as a standalone WP-01 that implementation packages depend on, estimate them with CPM, split each into TDD todos, and write wiki page ANALYZE_{HASH} with real sample data. Logic only - never write code or modify files. Use after planning and before implementation. +description: SDLC analysis stage. Gate on capability tags enforced in code by sdlc-gate (analyze requires reasoning-max), confirm the source branch, then pick a plan from PLAN_CONTENTS and question until consensus per references/consensus.md. Analyze its user stories against the current state (working directory plus REPO_{HASH} inventory for reuse), then run WBS with a standalone delivery/handover WP-01, CPM estimates and TDD todos. Write wiki page ANALYZE_{HASH} with real sample data; logic only - never write code or modify files. Use after planning and before implementation; not for writing code (that is implement), and not before a plan exists in PLAN_CONTENTS. --- # analyze @@ -13,51 +13,42 @@ All wiki reads and writes go through `jsc-gitea:wiki`. ## Steps -1. **Model gate and stage lock** (capability tags, enforced in code — never self-assessed): - 1. Run `jsc-cli/tools/model-tags.sh sync` to refresh `$JSC_HOME/model-tags.tsv` from `jsc-cli/references/model-tags.md`. - 2. Run `jsc-hooks/hooks/sdlc-gate.sh lock analyze`. The script reads the **actual** model id from the transcript, compares it against this stage's required tags (`reasoning-max`), 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. - 4. **Report the gate result to the user every time — whether it passed or blocked.** State the stage, the required tags, the actual model id the script read from the transcript, and the verdict. A silent pass looks identical to a skipped check, and the whole point of moving this into code was that a claimed check cannot be trusted. - 5. 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. +1. **Model gate and stage lock** — run `jsc-cli/tools/model-tags.sh sync`, then `jsc-hooks/hooks/sdlc-gate.sh lock analyze`. This stage requires the `reasoning-max` capability tag. Rules: `references/model-gate.md`. Completion condition: the script exited 0, and you have reported the stage, the required tag, the actual model id it read from the transcript, and the verdict. 2. **Confirm the source branch** — the branch whose code counts as the current state: 1. Run `git fetch --prune origin` first — without it, every `origin/...` reference is stale cache. Then report the working directory's current branch, the **remote** branches available (`git branch -r`; never `git branch`) and whether the working tree is clean. 2. Ask per `jsc-ask:ask` rules which branch the analysis reads from; state the impact scope on every option (analysing the wrong branch produces work packages for code that does not exist). - 3. **The current state is always the remote branch `origin/{來源分支}`, never the local one.** The working directory's HEAD must point at the same commit as `origin/{來源分支}`; behind, ahead or diverged all mean you would be analysing code that is not what the remote holds. Report the gap (`git rev-list --left-right --count origin/{來源分支}...HEAD`) and stop — this stage never switches branches, never stashes, never pulls and never touches the working tree. Rules in `references/branch.md`. - 4. Record the confirmed branch and the head sha **of `origin/{來源分支}`** on the analysis page. Completion condition: the user has confirmed the branch explicitly; never infer it from the current checkout alone. -3. Read `PLAN_CONTENTS` via `jsc-gitea:wiki` for plans whose status is the literal 「未分析」 (name and HASH), and read `ANALYZE_CONTENTS` for existing analyses. -4. Let the user choose per `jsc-ask:ask` rules: **extend an existing analysis** or **analyze a new plan**. State the impact scope on every option. + 3. **The current state is always the remote branch `origin/{source-branch}`, never the local one.** The working directory's HEAD must point at the same commit as `origin/{source-branch}`; behind, ahead or diverged all mean you would be analysing code that is not what the remote holds. Report the gap (`git rev-list --left-right --count origin/{source-branch}...HEAD`) and stop — this stage never switches branches, never stashes, never pulls and never touches the working tree. Rules in `references/branch.md`. + 4. Record the confirmed branch and the head sha **of `origin/{source-branch}`** on the analysis page. Completion condition: the user has confirmed the branch explicitly; never infer it from the current checkout alone. +3. Read `PLAN_CONTENTS` via `jsc-gitea:wiki` for plans whose status is the literal 「未分析」 (name and HASH), and read `ANALYZE_CONTENTS` for existing analyses. Completion condition: you have listed every 未分析 plan with its name and HASH plus every existing analysis, or reported that a list is empty. +4. Let the user choose per `jsc-ask:ask` rules: **extend an existing analysis** or **analyze a new plan**. State the impact scope on every option. Completion condition: the user has picked one option explicitly, and you have named the target — the existing `ANALYZE_{HASH}` page, or the plan the new analysis covers. 5. Analyze the plan page's user stories one by one against the **current state**, **questioning until consensus** per `references/consensus.md` (the single authority for both planning and analysis): every answer produces the next question, and consensus needs both no output-changing unknown **and** the user's explicit confirmation. Never assume a missing detail, and never start the WBS while any item is still open. Current state means: - 1. Every file in the working directory, at the commit `origin/{來源分支}` points to (verified in step 2). - 2. **Reuse existing methods and endpoints whenever possible**: + 1. Every file in the working directory, at the commit `origin/{source-branch}` points to (verified in step 2). + 2. **Reuse an existing method or endpoint unless its logic cannot satisfy the requirement**: - Check the `REPO_{HASH}` inventory page first. Re-inventory when the feature or endpoint is missing, or when the recorded commit sha differs from the current one. - Re-inventory **MUST run as a sub agent**: analyze the repository's features and endpoints, attach the current commit sha, write back to `REPO_{HASH}` with `templates/repo-page.md`, and update `REPO_CONTENTS` per `templates/repo-contents.md`. - - For each reuse candidate, confirm the file path and method name first, then analyze whether its logic fits the requirement. -6. Run a **Work Breakdown Structure (WBS)**: split the user stories into work packages, number them sequentially (`WP-01`, `WP-02`, ...) and mark dependencies. -7. **`WP-01` is always the delivery/handover work package** — see 「交付工作包最優先」 below. It stands alone, never merged into an implementation package, and every implementation package that consumes its spec depends on it. -8. Estimate every work package's effort in hours and days with the **Critical Path Method (CPM)**, and mark the critical path. -9. Split every work package into todos with **Test-Driven Development (TDD)**, formatted `[ ]` (open) / `[x]` (done). Each todo is one vertical slice: one seam, one test, one minimal implementation. Seams and anti-patterns: `references/tdd.md`. -10. Apply `templates/analyze-page.md` to create or update the analysis page and write it back via `jsc-gitea:wiki`. The page content is Traditional Chinese, exactly as the template dictates. -11. If the analysis page is new: add it to `ANALYZE_CONTENTS` per `templates/analyze-contents.md`, and flip the plan's status in `PLAN_CONTENTS` to the literal 「已分析」. + - For each reuse candidate, confirm the file path and method name first, then analyze whether its logic fits the requirement. Reject a candidate only for a stated reason, and record both the candidate and that reason in the analysis page's 複用決策 field. -## 交付工作包最優先(delivery package is WP-01) + Completion condition: every user story has reached consensus under both conditions of `references/consensus.md`, and every reuse decision — reused, or rejected with its reason — is recorded in 複用決策. +6. Run a **Work Breakdown Structure (WBS)**: split the user stories into work packages, number them sequentially (`WP-01`, `WP-02`, ...) and mark dependencies. Completion condition: every user story on the plan page maps to at least one numbered work package, and every dependency edge is recorded in the WBS table's 相依 column. +7. **`WP-01` is always the delivery/handover work package** — see "Delivery package is WP-01" below. It stands alone, never merged into an implementation package, and every implementation package that consumes its spec depends on it. Completion condition: `WP-01` is marked 交付 `是` and holds only spec-shaped items, and every implementation package that consumes its spec names `WP-01` in its 相依 column — or the no-handover case below is confirmed with the user and its reason is written on the page. +8. Estimate every work package's effort in hours and days with the **Critical Path Method (CPM)**, and mark the critical path. Completion condition: every work package carries an hours figure and a days figure, and the critical path plus its total days are written on the page. +9. Split every work package into todos with **Test-Driven Development (TDD)**, formatted `[ ]` (open) / `[x]` (done). Each todo is one vertical slice: one seam, one test, one minimal implementation. Seams and anti-patterns: `references/tdd.md`. Completion condition: every work package carries at least one `[ ]` todo, and every todo names its seam and the behaviour its test asserts. +10. Apply `templates/analyze-page.md` to create or update the analysis page and write it back via `jsc-gitea:wiki`. The page content is Traditional Chinese, exactly as the template dictates. Completion condition: the page is saved on the wiki and carries every section the template dictates, including the source branch, the head sha and the 未決項 section (「無」 when there is none). +11. If the analysis page is new: add it to `ANALYZE_CONTENTS` per `templates/analyze-contents.md`, and flip the plan's status in `PLAN_CONTENTS` to the literal 「已分析」. Completion condition: `ANALYZE_CONTENTS` shows the new row and `PLAN_CONTENTS` shows the literal 「已分析」, both saved on the wiki. + +## Delivery package is WP-01 A work package is a **delivery/handover package** when someone else — another person, another CLI, another team — has to act on its output. Interfaces, schemas, spec documents, acceptance criteria and sample payloads are delivery output; endpoint bodies and UI wiring are not. - **`WP-01` is the delivery/handover package, always first, always standalone.** Pull every spec-shaped item out of the implementation packages and put it here. Never merge a spec into the package that implements it — merging removes the ability to hand the spec over early, which is the whole point. -- **Implementation packages depend on `WP-01`** when they consume its spec, and they are the backup queue (實作候補): still numbered, still estimated, still on the page, just ranked after it. +- **Implementation packages depend on `WP-01`** when they consume its spec, and they are the backup queue: still numbered, still estimated, still on the page, just ranked after it. - Mark every work package as 交付 `是` / `否` in the WBS table, and record `WP-01`'s intended content type in the 交付型別 column when the user has already decided it (options in `references/deliver-formats.md`; the type is confirmed for real when `implement` starts that package). - Dependencies still win among the rest: never place a package before one it depends on. Within the same dependency level, delivery-shaped packages come first. - **When nothing is genuinely deliverable** (say, an internal refactor with no interface change), do not invent an empty `WP-01`: confirm with the user per `jsc-ask:ask` that this analysis has no handover output, then note the reason on the page and number the implementation packages from `WP-01`. -## 範例資料(sample data) +## Sample data -Every sample value on the analysis page — request and response payloads, field values, config snippets, test fixtures — follows this order: - -1. **Real data first.** Take values from an actual source: the database schema and rows, a real API response, an existing config or fixture file, logs. Record where each sample came from in the WBS table's 資料來源 column (for example `真實:dbo.Member`). -2. **Only when no source exists**, derive the value by reasoning from the surrounding logic — and label it as inferred (for example `推論:無來源`), so the receiving side knows it is unverified. -3. Never invent a plausible-looking value and present it as real, and never leave the origin of a sample unstated. -4. Real data goes on the page as **structure and format only**: field names, types, shapes. Never copy personal data onto the wiki — mask any personal identifier, and prefer describing the format over pasting the value. -5. When `WP-01`'s content type is an API document, the required fields and the new-versus-existing parameter marking are defined in `references/deliver-formats.md`; follow it rather than inventing a layout. +Every sample value on the analysis page — request and response payloads, field values, config snippets, test fixtures — follows `references/deliver-formats.md`, which owns the source order, the labelling and the API-document layout. Record each value's origin in the WBS table's 資料來源 column. Completion condition: every sample value on the page carries a 資料來源 label of either 「真實:{source}」 or 「推論:無來源」, and no sample value contains personal data. ## Hard limits diff --git a/skills/implement/SKILL.md b/skills/implement/SKILL.md index 7c5af1e..0643df3 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, 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. +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. 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 and closing with jsc-review code-review. One package, one PR back to the source branch, then stop until it merges, and finish with the chosen delivery document plus an optional MAINTAIN_CONTENTS entry. Use when analysis is done and code must be written; not for planning or analysis. --- # implement @@ -10,63 +10,41 @@ All wiki reads and writes go through `jsc-gitea:wiki`. ## Steps -1. **Model gate and stage lock** (capability tags, enforced in code — never self-assessed): - 1. Run `jsc-cli/tools/model-tags.sh sync` to refresh `$JSC_HOME/model-tags.tsv` from `jsc-cli/references/model-tags.md`. - 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. - 4. **Report the gate result to the user every time — whether it passed or blocked.** State the stage, the required tags, the actual model id the script read from the transcript, and the verdict. A silent pass looks identical to a skipped check, and the whole point of moving this into code was that a claimed check cannot be trusted. - 5. 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. +1. **Model gate and stage lock** — run `jsc-cli/tools/model-tags.sh sync`, then `jsc-hooks/hooks/sdlc-gate.sh lock implement`. This stage requires the `coding` capability tag. Rules: `references/model-gate.md`. Completion condition: the script exited 0, and you have reported the stage, the required tag, the actual model id it read from the transcript, and the verdict. 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 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 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. `origin/{來源分支}` does not exist on the remote → report and stop. Never fall back to `develop` silently. - 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. **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. -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.** - 4. **Quote every branch name and path**: source branches carry Chinese characters, spaces and multiple slashes (for example `feat/一址通/查地址/完整版/P2`), and an unquoted argument gets split. - 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. -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. -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. + 1. Run `git fetch --prune origin`, then read the source branch from the analysis page and report it, along with the current branch and whether the working tree is clean. + 2. Ask per `jsc-ask:ask` rules to confirm that `origin/{source-branch}` 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. **A source branch missing from the remote is a stop-and-report condition, never a silent fallback.** That rule (section 「來源分支在遠端找不到」), the remote-only basis and the uncommitted-changes rules: `references/branch.md`. + 4. Completion condition: the user has confirmed the source branch explicitly, and it is recorded on the analysis page next to the work ticket. +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`). Rename the current session to the ticket name; skip the rename only when the CLI exposes no rename command. Completion condition: the ticket string exists, and you have reported it together with which branch applied — renamed, or skipped because this CLI has no rename command. +4. **Settle the previous work package's PR before picking anything.** Read the analysis page's PR column; for every work package holding a PR that is not marked merged, run `jsc-gitea/tools/gitea.sh pr-status {owner}/{repo} {index}`, and when it is not merged run `jsc-gitea/tools/gitea.sh pr-comments {owner}/{repo} {index}` in the same breath, relay the comments verbatim, and ask per `jsc-ask:ask` rules whether to fix or wait. Fixes go back into the original worktree and push to the same work branch; never open a second PR for the same package. A PR that is closed but not merged does not count as done: report it and ask the same way. A merged PR clears the block: remove that package's worktree (`references/branch.md`) and mark the package done on the analysis page. Completion condition: no work package holds an unmerged PR; 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**. Completion condition: you have listed every selectable work package, or reported that none is selectable and stopped. +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. Completion condition: the ticket is saved on the wiki; 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`. + 3. Completion condition: the confirmed type is written into the analysis page's 交付型別 column and saved back to the wiki before the first todo starts. +8. **Create the worktree — before touching any code.** Run `git fetch --prune origin`, read the source branch and the repositories involved from the analysis page, then ask per `jsc-ask:ask` rules how to handle the branch. Path layout, the two `git worktree add` options, quoting, `.git/info/exclude` and the reporting duty: `references/branch.md`. Completion condition: every repository the analysis page names has a worktree built from `origin/{source-branch}`, and you have reported each worktree's path, checked-out branch, source branch and starting commit sha. +9. **Complete the work package's open items one at a time. Every item MUST run as a sub agent**, working inside the worktree: + 1. One sub agent takes one item and follows the TDD loop: red before green, one vertical slice. Rules and anti-patterns: `references/tdd.md` (refactoring belongs to the review stage). + 2. The main agent keeps only the wiki bookkeeping: when the sub agent reports the item done, flip its `[ ]` to `[x]` on the analysis page and save to the wiki. + 3. 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, 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. 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. 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. + 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`. + 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. **Do not start another work package.** Completion condition: the PR exists, its URL is saved on the analysis page and reported to the user, and the skill has stopped. 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). -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. + 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`. + 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 `jsc-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. Completion condition: the chosen format has actually been produced, and you have reported where it landed (wiki page name, or the comment URL). +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. ## Rules - 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: real data where a source exists, reasoned values labelled as inferred where none does. Never invent a value and present it as real, and never copy personal data into fixtures — keep the format, drop the identity. +- Sample data written into code or fixtures follows the analysis page's 資料來源 column, under the rules in `references/deliver-formats.md`. - Everything the skill writes out (wiki content, commit messages, PR descriptions) stays Traditional Chinese per the STE100 rule. diff --git a/skills/maintain/SKILL.md b/skills/maintain/SKILL.md index 9b943f2..5fb4b79 100644 --- a/skills/maintain/SKILL.md +++ b/skills/maintain/SKILL.md @@ -10,22 +10,19 @@ All wiki reads and writes go through `jsc-gitea:wiki`. ## Steps -1. **Model gate and stage lock** (capability tags, enforced in code — never self-assessed): - 1. Run `jsc-cli/tools/model-tags.sh sync` to refresh `$JSC_HOME/model-tags.tsv` from `jsc-cli/references/model-tags.md`. - 2. Run `jsc-hooks/hooks/sdlc-gate.sh lock maintain`. The script reads the **actual** model id from the transcript and checks it against this stage's required tags — maintenance requires no specific tag, so the gate passes as long as the actual model can be determined at all. - 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. **Report the gate result to the user every time — whether it passed or blocked.** State the stage, the required tags, the actual model id the script read from the transcript, and the verdict. A silent pass looks identical to a skipped check, and the whole point of moving this into code was that a claimed check cannot be trusted. - 5. Exit 0 means the stage is locked. Run this gate only when the stage changes; inside the maintenance stage the lock already covers every project, so never re-gate between projects. -2. Read `MAINTAIN_CONTENTS` via `jsc-gitea:wiki` and filter projects **still inside their maintenance window**: start date ≤ today, and (end date is NULL or ≥ today). -3. Every project **MUST run as a sub agent** with this flow: - 1. Run `git fetch --prune origin`, then switch the project to `develop`, falling back to `master`, and bring it up to `origin/{該分支}` — the remote is the basis, never the local branch. Local and remote diverged → report and skip that project; never `pull --rebase`, `reset` or discard anything on your own. - 2. Propose **at least five** maintenance methods and apply the ones that fit the project, for example: +1. **Model gate and stage lock** — run `jsc-cli/tools/model-tags.sh sync`, then `jsc-hooks/hooks/sdlc-gate.sh lock maintain`. This stage requires no specific capability tag; the gate passes as long as the script can determine the actual model id. Rules: `references/model-gate.md`. Completion condition: the script exited 0, and you have reported the stage, the required tag, the actual model id it read from the transcript, and the verdict. +2. Read `MAINTAIN_CONTENTS` via `jsc-gitea:wiki` and filter projects **still inside their maintenance window**: start date ≤ today, and (end date is NULL or ≥ today). Completion condition: you have listed every in-window project with its `{owner}/{repo}` and window dates, or reported that none is in window and stopped. +3. Every project **MUST run as a sub agent** with this flow. Completion condition: every project listed in step 2 has its sub agent finished, and each one ends in either a PR link or a recorded skip reason. + 1. Run `git fetch --prune origin`, then put the project on its maintenance branch and align it with `origin/{branch}`. Which branch that is, the remote-is-the-basis rule, the diverged case and the never-pull-never-reset rule all live in `references/branch.md`; never guess the branch name. Completion condition: the project's HEAD points at the same commit as `origin/{branch}`, or you have reported the gap and skipped this project. + 2. Propose **at least five** maintenance methods, then let the user pick per `jsc-ask:ask` rules — every option states its impact scope (which files it touches, whether it can break the build, how much review it costs). Candidates: - dependency updates (reuse `jsc-pkg:pkg-update`) - security vulnerability scan and patching - dead code and stale comment cleanup - test coverage reinforcement - docs and README synchronization - build warning elimination - 3. Commit the changes to a new branch per `jsc-git:commit`, push, then open a PR back to develop or master per `jsc-git:pr`. - 4. Update the project's last-maintained field (the zh-TW column 「前次維護時間」) in `MAINTAIN_CONTENTS` to today. -4. The main agent reports the summary: maintenance methods applied per project, PR links, and failure reasons. The report and all generated wiki content, commits, and PR descriptions stay Traditional Chinese per the STE100 rule. + + Completion condition: the user has picked the methods to apply, and every picked method is either applied or reported with the reason it could not be. + 3. Commit the changes to a new branch per `jsc-git:commit`, push, then open a PR per `jsc-git:pr` back to the branch of step 3.1, passing it explicitly as the base. Completion condition: the PR exists, and you have reported its URL and number. + 4. Update the project's last-maintained field (the zh-TW column 「前次維護時間」) in `MAINTAIN_CONTENTS` to today. Completion condition: `MAINTAIN_CONTENTS` shows today's date in 「前次維護時間」 for that project, saved on the wiki. +4. The main agent reports the summary: maintenance methods applied per project, PR links, and failure reasons. The report and all generated wiki content, commits, and PR descriptions stay Traditional Chinese per the STE100 rule. Completion condition: the summary names every project read in step 2, each with its applied methods and either a PR link or the reason it was skipped. diff --git a/skills/plan/SKILL.md b/skills/plan/SKILL.md index 52572d6..38205dc 100644 --- a/skills/plan/SKILL.md +++ b/skills/plan/SKILL.md @@ -13,23 +13,20 @@ All wiki reads and writes go through `jsc-gitea:wiki`. ## Steps -1. **Model gate and stage lock** (capability tags, enforced in code — never self-assessed): - 1. Run `jsc-cli/tools/model-tags.sh sync` to refresh `$JSC_HOME/model-tags.tsv` from `jsc-cli/references/model-tags.md`. - 2. Run `jsc-hooks/hooks/sdlc-gate.sh lock plan`. The script reads the **actual** model id from the transcript, compares it against this stage's required tags (`reasoning-max`), 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. - 4. **Report the gate result to the user every time — whether it passed or blocked.** State the stage, the required tags, the actual model id the script read from the transcript, and the verdict. A silent pass looks identical to a skipped check, and the whole point of moving this into code was that a claimed check cannot be trusted. - 5. 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. Read `PLAN_CONTENTS` via `jsc-gitea:wiki` and list the plans whose status is the literal 「未分析」 (not analyzed), with names and HASH. -3. Let the user choose per `jsc-ask:ask` rules: **extend an existing plan** (list the not-analyzed plans as options) or **create a new plan**. State the impact scope on every option. +1. **Model gate and stage lock** — run `jsc-cli/tools/model-tags.sh sync`, then `jsc-hooks/hooks/sdlc-gate.sh lock plan`. This stage requires the `reasoning-max` capability tag. Rules: `references/model-gate.md`. Completion condition: the script exited 0, and you have reported the stage, the required tag, the actual model id it read from the transcript, and the verdict. +2. Read `PLAN_CONTENTS` via `jsc-gitea:wiki` and list the plans whose status is the literal 「未分析」 (not analyzed), with names and HASH. Completion condition: you have listed every 未分析 plan with its name and HASH, or reported that none exists. +3. Let the user choose per `jsc-ask:ask` rules: **extend an existing plan** (list the not-analyzed plans as options) or **create a new plan**. State the impact scope on every option. Completion condition: the user has picked one option explicitly, and you have named the `PLAN_{HASH}` page this run writes to. 4. **Keep questioning until consensus** — rules in `references/consensus.md`, which is the single authority for both planning and analysis. Cover all three items: - Goal: the problem to solve and the criteria for success. - Scope: what is included, what is excluded, which repositories are involved. - Feasibility: whether the system architecture and data sources support the goal. - **One round is never enough**: every answer must produce the next question, derived from what that answer just exposed. Consensus needs both conditions from `references/consensus.md` — no remaining unknown that would change the output, **and** the user's explicit confirmation of the summary you read back. Never fill a gap with your own assumption, and never move on to user stories while any item is still open. -5. Turn the consensus into **user stories** (the zh-TW pattern 「身為⋯⋯我想要⋯⋯以便⋯⋯」), one per line. -6. Apply `templates/plan-page.md` to create or update the plan page, and write it back via `jsc-gitea:wiki`. The page content is Traditional Chinese, exactly as the template dictates. -7. If the plan page is new, add it to `PLAN_CONTENTS` using the entry format of `templates/plan-contents.md`, with status set to the literal 「未分析」. + **One round is never enough**: every answer must produce the next question, derived from what that answer just exposed. Never fill a gap with your own assumption, and never move on to user stories while any item is still open. + + Completion condition: all three items are settled under both conditions of `references/consensus.md` — no remaining unknown that would change the output, **and** the user's explicit confirmation of the summary you read back. +5. Turn the consensus into **user stories** (the zh-TW pattern 「身為⋯⋯我想要⋯⋯以便⋯⋯」), one per line. Completion condition: every consensus item is covered by at least one user story in that pattern, and no user story rests on an unanswered question. +6. Apply `templates/plan-page.md` to create or update the plan page, and write it back via `jsc-gitea:wiki`. The page content is Traditional Chinese, exactly as the template dictates. Completion condition: the page is saved on the wiki and carries every section the template dictates — goal, scope, feasibility, user stories and the consensus summary — with no placeholder left unfilled. +7. If the plan page is new, add it to `PLAN_CONTENTS` using the entry format of `templates/plan-contents.md`, with status set to the literal 「未分析」. Completion condition: `PLAN_CONTENTS` shows the plan's row with the literal 「未分析」, saved on the wiki. ## Hard limits From 821261ad9d6863babe53abf890ecbff61f3baf0c Mon Sep 17 00:00:00 2001 From: Jeffery Date: Tue, 25 Aug 2026 14:58:54 +0800 Subject: [PATCH 2/3] =?UTF-8?q?docs(sdlc):=20=E5=90=8C=E6=AD=A5=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E8=88=87=E5=8F=83=E8=80=83=E8=B3=87=E6=96=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What:更新 README、AGENTS.md、templates 與 references,讓文件敘述與實際行為一致。 Why:稽核發現多處文件與程式行為分歧,違反「每個意義只有單一真實來源」。 How:以實際程式行為為準改寫敘述,重複的規則收成單一來源並以一行指引指過去。 Who:jsc-meta:skill-check 例行稽核(2026-08-25)。 Co-Authored-By: Claude Opus 5 --- README.md | 12 ++++----- references/branch.md | 50 ++++++++++++++++++++--------------- references/deliver-formats.md | 6 ++--- references/model-gate.md | 28 ++++++++++++++++++++ templates/analyze-page.md | 16 +++++------ templates/deliver-contents.md | 2 +- templates/deliver-page.md | 8 +++--- templates/error-contents.md | 9 ------- templates/error-page.md | 33 ----------------------- templates/repo-page.md | 2 +- 10 files changed, 79 insertions(+), 87 deletions(-) create mode 100644 references/model-gate.md delete mode 100644 templates/error-contents.md delete mode 100644 templates/error-page.md diff --git a/README.md b/README.md index 8cd1a15..fd684fd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # jsc-sdlc — 開發生命週期 -jsc 技能組的 sdlc domain:規劃 → 分析 → 實作 → 維護四個階段,全程以 wiki 頁追蹤(`PLAN_CONTENTS`、`PLAN_{HASH}`、`ANALYZE_CONTENTS`、`ANALYZE_{HASH}`、`REPO_CONTENTS`、`REPO_{HASH}`、`DELIVER_CONTENTS`、`DELIVER_{HASH}`、`MAINTAIN_CONTENTS`)。工作包完成即交付:實作階段會詢問交付文件要產生成 `DELIVER_{HASH}` wiki 頁或 Gitea 議題留言。另有異常頁(`ERROR_CONTENTS`、`ERROR_{HASH}`)記錄 hook 或流程失敗。每次切換階段先過模型閘門:由 `jsc-hooks/hooks/sdlc-gate.sh lock {stage}` 從 transcript 讀出**實際**模型 id,比對該階段的必要能力標籤(plan、analyze 需 `reasoning-max`;implement 需 `coding`;maintain 任意),不符就拒絕上鎖、該階段不得執行。判定全在程式層,模型不得自評標籤,且**每次都要把閘門結果回報使用者**(階段、必要標籤、實際模型、判定),不論通過或阻擋。通過後鎖定到下一階段的閘門重新上鎖;同一階段內把模型換成不合格的,下一輪提示會被 hook 以 exit 2 擋下。分析前先與使用者確認來源分支;實作沿用同一條來源分支作為 worktree 基準與 PR 目標。**所有參考與來源分支一律取遠端的 `origin/{分支}`,動作前先 `git fetch --prune origin`;本地分支不可作為基準,本地與遠端不一致就停下回報。** +jsc 技能組的 sdlc domain:規劃 → 分析 → 實作 → 維護四個階段,全程以 wiki 頁追蹤(`PLAN_CONTENTS`、`PLAN_{HASH}`、`ANALYZE_CONTENTS`、`ANALYZE_{HASH}`、`REPO_CONTENTS`、`REPO_{HASH}`、`DELIVER_CONTENTS`、`DELIVER_{HASH}`、`MAINTAIN_CONTENTS`)。工作包完成即交付:實作階段會詢問交付文件要產生成 `DELIVER_{HASH}` wiki 頁或 Gitea 議題留言。hook 或流程失敗記在異常頁(`ERROR_CONTENTS`、`ERROR_{HASH}`),那組頁面與範本由 `jsc-hooks` 擁有,本 domain 不放副本。每次切換階段先過模型閘門,判定全在程式層,由 `jsc-hooks/hooks/sdlc-gate.sh lock {stage}` 執行;各階段必要標籤、阻擋與回報的鐵則見 `references/model-gate.md`。分析前先與使用者確認來源分支;實作沿用同一條來源分支作為 worktree 基準與 PR 目標。**所有參考與來源分支一律取遠端的 `origin/{branch}`,動作前先 `git fetch --prune origin`;本地分支不可作為基準,本地與遠端不一致就停下回報。** ## 安裝、更新、移除 @@ -30,15 +30,15 @@ Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/meta.git),安 ### `analyze` -分析:先確認來源分支 → 持續提問到達成共識(`references/consensus.md`)→ 搭配現況(工作目錄與 `REPO_{HASH}` 盤點複用)分析使用者故事 → WBS 產生編號工作包,`WP-01` 固定是獨立的交付/交接工作包、實作工作包相依於它 → CPM 估工時與天數 → TDD 拆待辦 → 寫回 `ANALYZE_{HASH}`。純邏輯,禁止程式碼與修改檔案。 +分析:先確認來源分支 → 持續提問到達成共識(`references/consensus.md`)→ 搭配現況(工作目錄與 `REPO_{HASH}` 盤點複用)分析使用者故事 → WBS 產生編號工作包,`WP-01` 固定是獨立的交付、交接工作包,實作工作包相依於它 → CPM 估工時與天數 → TDD 拆待辦 → 寫回 `ANALYZE_{HASH}`。純邏輯,禁止程式碼與修改檔案。 ### `implement` -實作:先確認來源分支(同時是 PR 目標)→ 產生工作證鎖定「未完成、無相依、無工作證」的工作包(交付工作包優先)→ 交付工作包開工前先確認交付內容(API 文件/由使用者輸入,見 `references/deliver-formats.md`)→ **動程式碼前先從 `origin/{分析頁來源分支}` 建立 worktree**(`.worktree/{分析頁 HASH}/{repo}`,分支處理依決策樹詢問)→ 在 worktree 內逐項 TDD 實作、每完成一項立即更新 wiki → 程式碼審查 → **每完成一個工作包就 commit、push、PR 回來源分支**(一包一 PR)→ **PR 未合併就不開下一包**;每次要領工作包前先查 PR 狀態並讀留言,依決策樹問使用者要修正還是等待;合併後才移除 worktree → 詢問交付文件格式(`DELIVER_{HASH}` wiki 頁或 Gitea 議題留言)並產出 → 詢問是否加入維護目錄。 +實作:先確認來源分支(同時是 PR 目標)→ 產生工作證鎖定「未完成、無相依、無工作證」的工作包(交付工作包優先)→ 交付工作包開工前先確認交付內容(API 文件、由使用者輸入,見 `references/deliver-formats.md`)→ **動程式碼前先從 `origin/{source-branch}` 建立 worktree**(`.worktree/{analysis-HASH}/{repo}`,分支處理依決策樹詢問)→ 在 worktree 內逐項 TDD 實作、每完成一項立即更新 wiki → 程式碼審查 → **每完成一個工作包就 commit、push、PR 回來源分支**(一包一 PR)→ **PR 未合併就不開下一包**;每次要領工作包前先查 PR 狀態並讀留言,依決策樹問使用者要修正還是等待;合併後才移除 worktree → 詢問交付文件格式(`DELIVER_{HASH}` wiki 頁或 Gitea 議題留言)並產出 → 詢問是否加入維護目錄。 ### `maintain` -維護:讀取維護期內的專案,每個專案一個 sub agent:fetch 後切 develop、master 並對齊 `origin/{該分支}` → 至少五種建議維護方法 → commit / push / PR → 更新前次維護時間。僅適用於維護期內已交付的專案;尚在實作中或未登記於 `MAINTAIN_CONTENTS` 的專案不適用。 +維護:讀取維護期內的專案,每個專案一個 sub agent:fetch 後切 develop、master 並對齊 `origin/{branch}` → 提出至少五種維護方法,依決策樹讓使用者挑要做哪些 → commit / push / PR → 更新前次維護時間。僅適用於維護期內已交付的專案;尚在實作中或未登記於 `MAINTAIN_CONTENTS` 的專案不適用。 @@ -49,11 +49,11 @@ Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/meta.git),安 | `templates/plan-page.md`、`templates/plan-contents.md` | 計畫頁與計畫目錄 | | `templates/analyze-page.md`、`templates/analyze-contents.md` | 分析頁(WBS、CPM、TDD 待辦)與分析目錄 | | `templates/repo-page.md`、`templates/repo-contents.md` | 存取庫盤點頁(功能與端點,附 commit sha)與盤點目錄 | -| `templates/error-page.md`、`templates/error-contents.md` | 異常頁與異常目錄 | | `templates/deliver-page.md`、`templates/deliver-contents.md` | 交付頁(API 文件、新舊參數標示、驗證方式)與交付目錄 | | `templates/maintain-contents.md` | 維護目錄(截止日 NULL = 永久維護) | +| `references/model-gate.md` | 模型閘門:執行順序、各階段必要標籤、阻擋與回報的鐵則 | | `references/tdd.md` | 接縫、紅綠循環規則、反模式 | -| `references/branch.md` | 分支規則:**一律以遠端 `origin/{分支}` 為準、動作前先 fetch**、分析前確認來源分支、實作沿用同一條來源分支作為 PR 目標(一包一 PR、PR 未合併不開下一包)、實作一律在 `.worktree/{HASH}/{repo}` 內進行(建立前問分支、PR 成功後移除)、判定遠端預設分支、不破壞未提交變更 | +| `references/branch.md` | 分支規則:**一律以遠端 `origin/{branch}` 為準、動作前先 fetch**、分析前確認來源分支、實作沿用同一條來源分支作為 PR 目標(一包一 PR、PR 未合併不開下一包)、實作一律在 `.worktree/{HASH}/{repo}` 內進行(建立前問分支、PR 合併後才移除)、判定遠端預設分支、不破壞未提交變更 | | `references/consensus.md` | 規劃與分析的提問規則:一輪不算問完、共識的兩個判定條件、未決項處理 | | `references/deliver-formats.md` | 交付內容型別:API 文件必備欄位、範例資料優先序、既有端點的新舊參數標示 | diff --git a/references/branch.md b/references/branch.md index 92e93f8..2bade1f 100644 --- a/references/branch.md +++ b/references/branch.md @@ -4,22 +4,30 @@ ## 總則:一律以遠端為準,不吃本地分支 -SDLC 各階段引用的參考分支與來源分支,**一律指遠端的 `origin/{分支}`**。本地分支不可作為基準。 +SDLC 各階段引用的參考分支與來源分支,**一律指遠端的 `origin/{branch}`**。本地分支不可作為基準。 理由:本地分支可能落後遠端、可能有沒推上去的 commit、也可能是別的工作留下的狀態。以本地為基準,分析會對著過時的程式碼做,實作會從錯誤的起點長出來,而且錯了不會有任何徵兆。 | 項目 | 規則 | | --- | --- | -| 動作之前 | 先 `git fetch --prune origin`。**沒 fetch 就用 `origin/{分支}` 等於用快取**,遠端追蹤參照可能已經過時,連分支被刪掉都看不出來 | +| 動作之前 | 先 `git fetch --prune origin`。**沒 fetch 就用 `origin/{branch}` 等於用快取**,遠端追蹤參照可能已經過時,連分支被刪掉都看不出來 | | 列分支 | `git branch -r`,不看 `git branch` | -| 基準與比對 | 一律寫 `origin/{分支}`,例如 `git rev-list --count origin/master..origin/develop` | -| 建立 worktree | 從 `origin/{來源分支}` 建,不從本地同名分支建 | +| 基準與比對 | 一律寫 `origin/{branch}`,例如 `git rev-list --count origin/master..origin/develop` | +| 建立 worktree | 從 `origin/{source-branch}` 建,不從本地同名分支建 | | 判定預設分支 | `refs/remotes/origin/HEAD`(見〔判定遠端預設分支〕) | **本地與遠端不一致時一律停下回報**,不自行 `pull`、不自行 `reset`、不自行切換。要不要同步是使用者的決定。 `origin` 以外的遠端名稱(例如 `upstream`):先問使用者以哪個遠端為準,不臆測。 +### 來源分支在遠端找不到:停下回報,不退回預設分支 + +已指定的來源分支,`origin/{source-branch}` 在遠端不存在時,**回報並停止**。不改用 `develop`、不改用 `master`、不套用任何後備分支,也不自行建立同名分支。這條沒有例外。 + +理由:來源分支是那份分析的功能分支。悄悄退回 `develop`,單一工作包就會越過自己的功能分支直接進 `develop`,而且沒有任何徵兆看得出來。 + +**這是停止條件,不是後備條件。**〔判定遠端預設分支〕那節的後備順序只用在「還沒有指定分支、要挑一條基準」的情況;指定過的來源分支找不到,一律套用本節。 + ## 先確認,再動工 | 階段 | 要確認的分支 | 確認時機 | @@ -40,21 +48,23 @@ SDLC 各階段引用的參考分支與來源分支,**一律指遠端的 `origi 2. 取不到時退而用 `git remote show origin`,找輸出中的 `HEAD branch:` 那行。 3. 兩者都取不到 → 回報並停止,**不臆測** `master`/`main`。 -需要基準或後備分支時(例如 PR 目標):`origin/develop` 存在就用 `develop`;否則 `origin/master` 存在就用 `master`;兩者皆無則回報並停止。 +還沒有指定分支、需要挑一條基準或後備分支時(例如維護階段要落腳的分支):`origin/develop` 存在就用 `develop`;否則 `origin/master` 存在就用 `master`;兩者皆無則回報並停止。 + +這條後備順序**不適用於已指定的來源分支**。指定過的來源分支在遠端找不到,一律回報並停止,見總則的〔來源分支在遠端找不到〕。 ## 只讀階段不動工作區 `analyze` 是 logic-only 階段: -- **工作目錄的 HEAD 必須與 `origin/{來源分支}` 指向同一個 commit**。落後、超前或分歧都代表讀到的不是遠端現況——停下來回報差距(`git rev-list --left-right --count origin/{來源分支}...HEAD`),請使用者自己處理。 +- **工作目錄的 HEAD 必須與 `origin/{source-branch}` 指向同一個 commit**。落後、超前或分歧都代表讀到的不是遠端現況——停下來回報差距(`git rev-list --left-right --count origin/{source-branch}...HEAD`),請使用者自己處理。 - 需要換分支才能讀到正確現況時,**停下來請使用者自己切換**。 - 不代為 `switch`、不 `stash`、不動工作區、不建分支。 ## 實作階段的分支選擇 -實作在 worktree 內進行,工作分支從 `origin/{來源分支}` 長出來,做完再 PR 回同一條來源分支。 +實作在 worktree 內進行,工作分支從 `origin/{source-branch}` 長出來,做完再 PR 回同一條來源分支。 -- **一個工作包一個 PR**,目標一律是 `origin/{來源分支}`。不把兩個完成的工作包併成一個 PR,也不把完成的工作包留到下一包一起送——拆工作包的意義就是各自能獨立審查。 +- **一個工作包一個 PR**,目標一律是 `origin/{source-branch}`。不把兩個完成的工作包併成一個 PR,也不把完成的工作包留到下一包一起送——拆工作包的意義就是各自能獨立審查。 - 呼叫 `jsc-git:pr` 時**必須明確帶入來源分支當 base**。該 skill 在沒收到 base 時會自行退回 `develop`,那會讓單一工作包越過它所屬的功能分支直接進 develop。 - 來源分支整條後續要進 `develop` 時,那是另一個獨立的 PR,不在本階段範圍。 - 新分支名稱要可讀且不覆蓋既有分支;本地或遠端已存在同名分支時,換一個時間戳或短 hash。 @@ -62,15 +72,15 @@ SDLC 各階段引用的參考分支與來源分支,**一律指遠端的 `origi ## 實作一律在 worktree 內進行 -`implement` 動任何程式碼之前,先 `git fetch --prune origin`,再從**分析頁記錄的來源分支的遠端版本**(`origin/{來源分支}`)建立 git worktree。所有修改都在 worktree 內,主工作目錄的分支與工作區完全不動。 +`implement` 動任何程式碼之前,先 `git fetch --prune origin`,再從**分析頁記錄的來源分支的遠端版本**(`origin/{source-branch}`)建立 git worktree。所有修改都在 worktree 內,主工作目錄的分支與工作區完全不動。 ### 路徑 ``` -{工作目錄}/.worktree/{分析頁 HASH}/{repo} +{cwd}/.worktree/{analysis-HASH}/{repo} ``` -- `{分析頁 HASH}`:`ANALYZE_{HASH}` 的 HASH 部分,不含 `ANALYZE_` 前綴。 +- `{analysis-HASH}`:`ANALYZE_{HASH}` 的 HASH 部分,不含 `ANALYZE_` 前綴。 - `{repo}`:存取庫名稱,不含 owner(`HP/WebService.Buy` → `WebService.Buy`)。不同 owner 的同名存取庫同時出現時,才改用 `{owner}-{repo}` 避免蓋掉,並在輸出中說明。 - 一份分析涉及多個存取庫時,每個存取庫各一個 worktree,並列在同一個 HASH 目錄下。 @@ -80,22 +90,23 @@ SDLC 各階段引用的參考分支與來源分支,**一律指遠端的 `origi | 選項 | 指令 | 影響 | | --- | --- | --- | -| 以來源分支為基準開新工作分支 | `git worktree add -b {工作分支} {路徑} "origin/{來源分支}"` | commit 落在新分支,來源分支不動 | -| 直接簽出來源分支 | `git worktree add --track -b {來源分支} {路徑} "origin/{來源分支}"` | 建立追蹤遠端的本地分支再簽出;本地已存在同名分支時指令會失敗,此時先確認它與遠端一致才可改用 `git worktree add {路徑} {來源分支}`,不一致就停下回報 | +| 以來源分支為基準開新工作分支 | `git worktree add -b {work-branch} {path} "origin/{source-branch}"` | commit 落在新分支,來源分支不動 | +| 直接簽出來源分支 | `git worktree add --track -b {source-branch} {path} "origin/{source-branch}"` | 建立追蹤遠端的本地分支再簽出;本地已存在同名分支時指令會失敗,此時先確認它與遠端一致才可改用 `git worktree add {path} {source-branch}`,不一致就停下回報 | **不得自行預設**,也不得跳過詢問。 ### 建立時的鐵則 -- **分支名與路徑一律加引號**:來源分支可能含中文、空白或多層斜線(例如 `feat/一址通/查地址/完整版/P2`),不加引號會被切斷。 +- **分支名與路徑一律加引號**:既有的來源分支可能含空白、多層斜線或非 ASCII 字元(例如 `feat/addr-lookup/query/full/P2` 這種多層命名,或更舊的分支帶空白),不加引號會被切斷。 +- **jsc 自己開的分支只用 ASCII**(`a-z0-9` 與 `/`、`-`)。中文標題先翻譯成英文短語,再 slug 化當分支名。 - 找不到該存取庫的本地 clone → **停下來問使用者路徑**,不自行 clone、不臆測位置。 - 目標路徑已存在 → 不覆蓋。先確認它是不是同一份工作的 worktree(`git worktree list`),是就沿用,不是就回報並停止。 - 把 `.worktree/` 加進該存取庫的 `.git/info/exclude`(不動使用者的 `.gitignore`,那是專案共用檔)。 -- 建立後在輸出中明確列出:worktree 路徑、簽出的分支、來源分支,以及 `origin/{來源分支}` 當下的 commit sha——那是這次實作的起點,要能事後追。 +- 建立後在輸出中明確列出:worktree 路徑、簽出的分支、來源分支,以及 `origin/{source-branch}` 當下的 commit sha——那是這次實作的起點,要能事後追。 ### 移除時機 -**PR 合併之後才移除**:`git worktree remove {路徑}`,接著 `git worktree prune`。 +**PR 合併之後才移除**:`git worktree remove {path}`,接著 `git worktree prune`。 不是 PR 建立後就移除——審查留言可能要求修改,而修改要回到同一個 worktree、推到同一條工作分支(PR 會自己更新,不開第二個 PR)。先移除就得為了改一行重建整個 worktree。 @@ -105,12 +116,9 @@ SDLC 各階段引用的參考分支與來源分支,**一律指遠端的 `origi ### PR 未合併就不開下一個工作包 -一個工作包的 PR 還沒合併,就不得開始下一包。每次要領工作包之前先確認: +一個工作包的 PR 還沒合併,就不得開始下一包。修正一律回原 worktree、推同一條工作分支,**不為同一包開第二個 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. 已關閉但未合併 → 回報並詢問,不得當成完成。 +查驗程序(查狀態、讀留言、詢問修正或等待、已關閉但未合併怎麼辦)由 `skills/implement/SKILL.md` 步驟 4 擁有,本檔不重複。 ## 不破壞既有工作 diff --git a/references/deliver-formats.md b/references/deliver-formats.md index ec78004..00a1ed9 100644 --- a/references/deliver-formats.md +++ b/references/deliver-formats.md @@ -1,14 +1,12 @@ # 交付內容型別 -交付/交接工作包開工時,先跟使用者確認這份交付要產出什麼內容。預設選項固定兩個,其餘由使用者輸入。 +詢問時機與鐵則(不得自行預設、不得跳過詢問)由 `skills/implement/SKILL.md` 步驟 7 擁有。本檔只定義每個選項要產出什麼內容。 | 選項 | 內容 | | --- | --- | | 1. API 文件 | 端點路徑、輸入參數(**全部**)、輸出參數(**全部**);見下節 | | 2. 由使用者輸入 | 使用者自己講要什麼內容;照使用者說的做,不套 API 文件格式 | -選項一律依 `jsc-ask:ask` 規則呈現,並標明影響範圍。**不得自行預設,也不得跳過詢問。** - ## API 文件 ### 必備欄位 @@ -23,7 +21,7 @@ ### 參數範例:真實資料優先 -1. 先找真實來源:資料庫欄位與實際資料列、實際 API 回應、既有設定檔或 fixture、日誌。標成 `真實:{來源}`。 +1. 先找真實來源:資料庫欄位與實際資料列、實際 API 回應、既有設定檔或 fixture、日誌。標成 `真實:{source}`(`{source}` 換成實際來源名稱)。 2. 找不到來源才由邏輯推理,標成 `推論:無來源`,讓接手者知道那個值還沒被驗證。 3. **不得**編一個看起來合理的值當成真實資料。 4. 範例只保留**結構與格式**。個資一律遮蔽或改寫成格式描述,不把真實個資寫進交付文件。 diff --git a/references/model-gate.md b/references/model-gate.md new file mode 100644 index 0000000..dc252c7 --- /dev/null +++ b/references/model-gate.md @@ -0,0 +1,28 @@ +# 模型閘門 — 各階段動工前的能力標籤判定 + +SDLC 每個階段動工前先過模型閘門。判定全在程式層,由 `jsc-hooks/hooks/sdlc-gate.sh` 執行;模型不得自評標籤。 + +## 執行順序 + +1. `jsc-cli/tools/model-tags.sh sync`:把 `jsc-cli/references/model-tags.md` 的標籤表同步到 `$JSC_HOME/model-tags.tsv`。 +2. `jsc-hooks/hooks/sdlc-gate.sh lock {stage}`:腳本從 transcript 讀出**實際**模型 id,比對該階段的必要標籤,相符才上鎖。 + +## 各階段必要標籤 + +| 階段 | 必要標籤 | +| --- | --- | +| `plan` | `reasoning-max` | +| `analyze` | `reasoning-max` | +| `implement` | `coding` | +| `maintain` | 無。實際模型 id 可判定就通過 | + +## 鐵則 + +| 項目 | 規則 | +| --- | --- | +| 標籤來源 | 只認腳本的判定。不得宣稱自己沒驗證過的標籤,也不得用自己的判斷取代腳本結論 | +| 非零退出 | 一律視為阻擋:原文轉述腳本訊息、停止該技能、該回合不做別的事 | +| `unlock` | 不得用來繞過閘門。要不要解鎖是使用者的決定 | +| 回報 | **每次都要回報**:階段、必要標籤、腳本從 transcript 讀到的實際模型 id、判定結果。通過與阻擋都要講——安靜通過看起來跟跳過檢查一樣,而判定搬進程式層的理由就是「宣稱有檢查」不可信 | +| 退出 0 | 該階段已上鎖。到下一階段的閘門重新上鎖之前,同一階段內把模型換成不合格的,下一輪提示會被 sdlc-gate hook 以 exit 2 擋下 | +| 上鎖時機 | 只在階段變換時上鎖。同一階段內逐項或逐專案跑時不重新上鎖 | diff --git a/templates/analyze-page.md b/templates/analyze-page.md index bec9345..d1763f8 100644 --- a/templates/analyze-page.md +++ b/templates/analyze-page.md @@ -15,7 +15,7 @@ - 工作目錄:{關鍵檔案與結構摘要} - 複用來源:[REPO_{HASH}]({REPO 頁絕對網址})(commit sha:`{sha}`) -- 複用決策:{複用哪些方法/端點、為什麼;不複用的原因} +- 複用決策:{複用哪些方法、端點、為什麼;不複用的原因} ## 未決項 @@ -27,15 +27,15 @@ ## 工作分解結構(WBS) -`WP-01` 固定是交付/交接工作包,獨立成一包,不與實作合併;用到它規格的實作工作包相依於它。 -交付型別於實作階段開工時確認(API 文件/由使用者輸入)。 -資料來源欄記錄範例資料的出處:`真實:{來源}` 或 `推論:無來源`。 +`WP-01` 固定是交付、交接工作包,獨立成一包,不與實作合併;用到它規格的實作工作包相依於它。 +交付型別於實作階段開工時確認(API 文件、由使用者輸入)。 +資料來源欄記錄範例資料的出處:`真實:{source}` 或 `推論:無來源`。 PR 欄記錄該工作包的 PR 連結與編號;PR 未合併前不得開始下一個工作包。 | 編號 | 工作包名稱 | 交付 | 交付型別 | 相依 | 工時(h) | 天數 | 資料來源 | 工作證 | PR | 狀態 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| WP-01 | {交付/交接:規格與介面定義} | 是 | API 文件 | - | {h} | {d} | 真實:{來源} | | | 未完成 | -| WP-02 | {實作類名稱} | 否 | - | WP-01 | {h} | {d} | 真實:{來源} | | | 未完成 | +| WP-01 | {交付、交接:規格與介面定義} | 是 | API 文件 | - | {h} | {d} | 真實:{source} | | | 未完成 | +| WP-02 | {實作類名稱} | 否 | - | WP-01 | {h} | {d} | 真實:{source} | | | 未完成 | | WP-03 | {實作類名稱} | 否 | - | WP-01 | {h} | {d} | 推論:無來源 | | | 未完成 | - 關鍵路徑:{WP-01 → WP-02 → ⋯⋯},總天數 {d} @@ -43,10 +43,10 @@ PR 欄記錄該工作包的 PR 連結與編號;PR 未合併前不得開始下 ## 待辦事項(TDD) -### WP-01 {交付/交接工作包名稱} +### WP-01 {交付、交接工作包名稱} - [ ] 盤點端點與參數:{對象} -- [ ] 產出規格與範例資料(標明真實/推論) +- [ ] 產出規格與範例資料(標明真實、推論) - [ ] 與使用者確認交付內容並產出交付文件 ### WP-02 {工作包名稱} diff --git a/templates/deliver-contents.md b/templates/deliver-contents.md index fd24150..be1aca8 100644 --- a/templates/deliver-contents.md +++ b/templates/deliver-contents.md @@ -1,6 +1,6 @@ # 交付目錄 - + | 計畫名稱 | 工作包 | 交付 | 交付型別 | 交付頁 | HASH | 存取庫 | 交付時間 | | --- | --- | --- | --- | --- | --- | --- | --- | diff --git a/templates/deliver-page.md b/templates/deliver-page.md index e8ccde4..8943b97 100644 --- a/templates/deliver-page.md +++ b/templates/deliver-page.md @@ -30,19 +30,19 @@ - 說明:{這個端點做什麼} 標示規則:🆕 **新增**、⚠️ **變更**、❌ **移除**(含淘汰時程)、既有參數留空。 -資料來源:`真實:{來源}` 或 `推論:無來源`。範例只留格式,個資不留值。 +資料來源:`真實:{source}` 或 `推論:無來源`。範例只留格式,個資不留值。 #### 輸入參數(全部) | 參數 | 位置 | 型別 | 必填 | 範例 | 資料來源 | 狀態 | | --- | --- | --- | --- | --- | --- | --- | -| {name} | path/query/header/body | {型別} | 是/否 | {值} | 真實:{來源} | 🆕 **新增** | +| {name} | path/query/header/body | {型別} | 是、否 | {值} | 真實:{source} | 🆕 **新增** | #### 輸出參數(全部) | 參數 | 型別 | 說明 | 範例 | 資料來源 | 狀態 | | --- | --- | --- | --- | --- | --- | -| {name} | {型別} | {說明} | {值} | 真實:{來源} | | +| {name} | {型別} | {說明} | {值} | 真實:{source} | | #### 錯誤回應 @@ -76,7 +76,7 @@ | 項目 | 指令或步驟 | 結果 | | --- | --- | --- | -| {測試} | `{指令}` | {通過/失敗} | +| {測試} | `{指令}` | {通過、失敗} | ## 已知限制 diff --git a/templates/error-contents.md b/templates/error-contents.md deleted file mode 100644 index 6e3dfbf..0000000 --- a/templates/error-contents.md +++ /dev/null @@ -1,9 +0,0 @@ -# 異常目錄 - -> 由失敗回報流程維護。新異常附加在文末,查問題時先看最新一筆。 - -## 異常清單 - -| 時間 | 頁名 | 存取庫名稱 | 觸發流程 | 退出碼 | 摘要 | -| --- | --- | --- | --- | --- | --- | -| {yyyy-MM-dd HH:mm:ss} | [[{error title}|ERROR_{HASH}]] | {owner}/{repo} | {hook_name} | {exit_code} | {error_summary} | diff --git a/templates/error-page.md b/templates/error-page.md deleted file mode 100644 index b00acb3..0000000 --- a/templates/error-page.md +++ /dev/null @@ -1,33 +0,0 @@ -# 異常紀錄:{error title} - -> 由失敗回報流程建立。這是一筆單次異常紀錄,不覆寫舊內容;同類失敗再發生時,請另開新頁。 - -- 頁名:`ERROR_{HASH}` -- HASH:`{HASH}` -- 發生時間:{yyyy-MM-dd HH:mm:ss} -- 存取庫名稱:{owner}/{repo} -- CLI:{cli} -- Session:{session_id} -- 觸發流程:{hook_name} -- 退出碼:{exit_code} -- 錯誤摘要:{error_summary} - -## 現象 - -- {現象描述} - -## 可能原因 - -- {可能原因} - -## 處理結果 - -- {處理方式} - -## 相關資訊 - -| 欄位 | 內容 | -| --- | --- | -| 訊息來源 | {stdin / env / command} | -| 相關輸出 | {stdout / stderr 摘要} | -| 關聯 ticket | `TICKET_{yyyyMMdd}_{HHmmss}_{HASH}` | diff --git a/templates/repo-page.md b/templates/repo-page.md index 6f828d0..f50827f 100644 --- a/templates/repo-page.md +++ b/templates/repo-page.md @@ -7,6 +7,6 @@ ## 功能與端點 -| 檔案路徑 | 方法/端點名稱 | 類型 | 邏輯摘要 | +| 檔案路徑 | 方法、端點名稱 | 類型 | 邏輯摘要 | | --- | --- | --- | --- | | {path} | {method 或 HTTP 動詞加路由} | 方法 \| 端點 | {做什麼、輸入輸出概要} | From 4dcf5a74014afcdaa389ab7830f95f56c4f0013a Mon Sep 17 00:00:00 2001 From: Jeffery Date: Tue, 25 Aug 2026 14:58:54 +0800 Subject: [PATCH 3/3] =?UTF-8?q?chore(sdlc):=20=E4=B8=89=E4=BB=BD=20manifes?= =?UTF-8?q?t=20=E5=90=8C=E6=AD=A5=E5=8D=87=E7=89=88=E4=B8=A6=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=20marketplace=20=E6=AD=A3=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What:三份 plugin manifest 版本同步 bump,兩份 marketplace 檔與 plugins/meta 正本對齊。 Why:準則要求技能異動必須同步升版;marketplace 副本必須與正本完全一致。 How:以 jsc-meta 的 tools/sync-skill-manifest.sh 升版,marketplace 檔由正本複製。 Who:jsc-meta:skill-check 例行稽核(2026-08-25)。 Co-Authored-By: Claude Opus 5 --- .agents/plugins/marketplace.json | 6 +++--- .claude-plugin/marketplace.json | 6 +++--- .claude-plugin/plugin.json | 4 ++-- .codex-plugin/plugin.json | 4 ++-- plugin.json | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.agents/plugins/marketplace.json b/.agents/plugins/marketplace.json index a9b4e66..8a2f91b 100644 --- a/.agents/plugins/marketplace.json +++ b/.agents/plugins/marketplace.json @@ -43,7 +43,7 @@ "source": "url", "url": "https://gitea.jsc.idv.tw/plugins/hooks.git" }, - "description": "跨 CLI hooks:STE100 語言強制、工時計時、技能用量記錄" + "description": "跨 CLI hooks:STE100 語言強制、工時計時、技能用量記錄、SDLC 模型鎖、版本前置檢查" }, { "name": "jsc-log", @@ -75,7 +75,7 @@ "source": "url", "url": "https://gitea.jsc.idv.tw/plugins/review.git" }, - "description": "程式碼審查:Refactoring 壞味道六組 + 註解規範 + 淺模組" + "description": "程式碼審查:Refactoring 壞味道六組、註解規範、淺模組" }, { "name": "jsc-sdlc", @@ -83,7 +83,7 @@ "source": "url", "url": "https://gitea.jsc.idv.tw/plugins/sdlc.git" }, - "description": "開發生命週期:規劃/分析/實作/維護(wiki 追蹤)" + "description": "開發生命週期:規劃、分析、實作、維護(wiki 追蹤)" } ] } diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index a9b4e66..8a2f91b 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -43,7 +43,7 @@ "source": "url", "url": "https://gitea.jsc.idv.tw/plugins/hooks.git" }, - "description": "跨 CLI hooks:STE100 語言強制、工時計時、技能用量記錄" + "description": "跨 CLI hooks:STE100 語言強制、工時計時、技能用量記錄、SDLC 模型鎖、版本前置檢查" }, { "name": "jsc-log", @@ -75,7 +75,7 @@ "source": "url", "url": "https://gitea.jsc.idv.tw/plugins/review.git" }, - "description": "程式碼審查:Refactoring 壞味道六組 + 註解規範 + 淺模組" + "description": "程式碼審查:Refactoring 壞味道六組、註解規範、淺模組" }, { "name": "jsc-sdlc", @@ -83,7 +83,7 @@ "source": "url", "url": "https://gitea.jsc.idv.tw/plugins/sdlc.git" }, - "description": "開發生命週期:規劃/分析/實作/維護(wiki 追蹤)" + "description": "開發生命週期:規劃、分析、實作、維護(wiki 追蹤)" } ] } diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 03af6d1..4a81976 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "jsc-sdlc", - "version": "0.1.2", - "description": "開發生命週期:規劃/分析/實作/維護(wiki 追蹤)", + "version": "0.1.4", + "description": "開發生命週期:規劃、分析、實作、維護(wiki 追蹤)", "skills": "./skills", "author": { "name": "JSC" diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index 1f02ebd..b343ffa 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-sdlc", - "version": "0.1.2", - "description": "開發生命週期:規劃/分析/實作/維護(wiki 追蹤)", + "version": "0.1.4", + "description": "開發生命週期:規劃、分析、實作、維護(wiki 追蹤)", "skills": "./skills" } diff --git a/plugin.json b/plugin.json index 4c02497..98db40c 100644 --- a/plugin.json +++ b/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-sdlc", - "version": "0.1.2", - "description": "開發生命週期:規劃/分析/實作/維護(wiki 追蹤)", + "version": "0.1.4", + "description": "開發生命週期:規劃、分析、實作、維護(wiki 追蹤)", "skills": "./skills/" }