What:`references/guidelines.md` 新增「PR 分支階梯」一節,列出兩種型別的階梯、多層子功能的組法、base 一律由 `jsc-git/tools/base-branch.sh --derive` 推導、功能主幹自動建立,以及最後一級不能省;環境變數表補上 `JSC_PR_WATCH_INTERVAL`;稽核檢查清單新增一項「PR 的 base 符合 PR 分支階梯,沒有越級」。 Why:階梯要對所有存取庫成立,就必須有一份正本。放在技能準則裡,各 domain 的 README 與參考文件才能只寫摘要並指回來,不會養出好幾份互相打架的規則;稽核清單少了這一項,越級開的 PR 也沒有任何一關會發現。 How:階梯只寫表與六條說明,不寫實作細節,推導行為的正本仍在 `jsc-git/tools/base-branch.sh`。特別寫明第 4 條「推不出唯一合法基底就中止並詢問使用者,不猜,也不退回 `develop`」與第 6 條「`develop` 併進 `master` 才會生效」——marketplace 與 `version-guard.sh` 讀的都是存取庫的預設分支,階梯最後一級省掉就等於沒有發布。 Who:所有 jsc domain 存取庫的 PR,以及跑 `jsc-meta:skill-check` 稽核的人。
14 KiB
JSC 技能準則
本文件是 jsc 技能組的唯一準則來源。skill-new、skill-update、skill-delete 與技能審核都必須依此檢查。
命名
- Plugin 名稱:
jsc-{domain},domain 用一個簡短的英文代表詞(例:ask、sdlc、gitea)。 - Marketplace 統一為
jsc,正本在https://gitea.jsc.idv.tw/plugins/meta.git;安裝 token 一律jsc-{domain}@jsc。每個 domain 存取庫都帶同一份 marketplace 檔(.claude-plugin/marketplace.json與.agents/plugins/marketplace.json,內容與正本完全一致),所以任何一個 repo 都能當註冊入口,互相覆蓋沒關係。 - Skill 名稱:小寫、數字、連字號(
-),最長 64 字元。名稱即指令(/jsc-{domain}:{name})。 - 每個 domain 是一個獨立存取庫
https://gitea.jsc.idv.tw/plugins/{domain}.git。新 domain 必須依https://gitea.jsc.idv.tw/plugins/template的結構建立新存取庫(三份 plugin manifest、skills/、README.md、AGENTS.md),並把 plugin 條目(URL 來源指向新存取庫)加入plugins/meta正本的兩份 marketplace 檔,再把更新後的檔案同步到所有 domain 存取庫(含新存取庫自己)。 - Git 分支名只允許 ASCII(
a-z0-9與/、-);中文需求或標題先翻譯成英文短語再 slug 化。 - Manifest 版本號從
0.0.1開始,三份 manifest 同步 bump;minor與patch不得超過9,滿9就往左進位,major可以超過9。
PR 分支階梯
所有存取庫的 PR 一律照階梯逐級上推,禁止越級。
| 類型 | 階梯 |
|---|---|
feat、docs、style、refactor、perf、test、chore、revert |
{類型}/{子功能} → {類型}/{功能}/main → develop → master |
fix |
fix/{修改} → develop → master |
{子功能}={功能}/{子功能內容中文簡述},可以多層,例如{A}/{A的子功能B}/{B的子功能C}/{C的子功能}。{功能}= 功能內容中文簡述;{修改}= 修改內容中文簡述。- 中文簡述先交給
jsc-git/tools/slugify.sh轉成 ASCII slug,再組成分支名;分支名本身的字元限制見「命名」第 5 條。 - base 一律由
jsc-git/tools/base-branch.sh --derive推導。推不出唯一合法基底就中止並詢問使用者,不猜,也不退回develop。 - 功能主幹
{類型}/{功能}/main不在 origin 上時,自動從develop建立並推上去,收尾要回報建立了哪一條分支。 - 階梯最後一級不能省:
develop併進master才會生效,marketplace 與version-guard.sh都讀存取庫的預設分支。
Description 規則
- frontmatter 的
description為一行英文,不超過 5 句或 5 個步驟——兩個上限滿足任一個就算通過,句數與步驟數都超過才要精簡。 - 使用專有名詞、概念或指引詞(例:WBS、TDD、decision tree、STE100)取代解釋。
- 必須寫清楚觸發時機(何時用、何時不用),這是各 CLI 自動載入的唯一依據。
- 複雜流程透過組合其他技能實現,不在單一 description 裡塞流程。
強制力層級
- 規則的實現優先順序:hook > prompt。凡是可以由 hook 強制的規則(語言、計時、統計),一律下放 hook,SKILL.md 只保留 hook 無法涵蓋的指引。
- 有標準輸入與輸出的流程一律下放到
tools/腳本,SKILL.md 只描述何時呼叫與參數。 - 主 agent 不需要處理細節的流程,SKILL.md 必須明確要求建立 sub agent 處理(關鍵字:「必須以 sub agent 執行」)。
Hook 規則
- 所有 hook 專屬存放於
jsc-hooks,不可散落在其他 domain。 - Hook 腳本實作優先順序:shell > nodejs > python。
- Hook 必須適用於 claude / codex / copilot / antigravity / kiro 五種 CLI:
- 腳本同時支援 stdin JSON(Claude 格式)與環境變數輸入,缺欄位時安靜降級(exit 0)。
- 各 CLI 的接線方式由
jsc-hooks:hooks-install技能處理。
技能設計
- 每個技能必須有單一明確目標,不可與既有技能重複;能複用就複用(呼叫其他技能或工具)。
- 需要操作 gitea 且輸入輸出明確的技能,一律透過
jsc-gitea/tools/gitea.sh(curl +GITEA_TOKEN)或teaCLI,不可自行拼 API 呼叫。gitea.sh 在 token 未設定或收到 401/403 時,會自動改用 tea 的登入金鑰重試一次。 - 需要問使用者的技能,一律透過
jsc-ask:ask的決策樹規則:選項式提問、每個選項標明影響範圍、問到沒有疑慮為止、已有紀錄的答案不再問。
語言
- 所有非程式碼輸出一律 STE100 繁體中文、UTF-8、無亂碼、無簡體字,帶擬人台灣感:短句、一句一指令、主動語態、術語一致、台灣用語、全形標點、去 AI 味、直接講重點。範圍涵蓋程式碼註解、commit 訊息、PR 描述、wiki 頁、對使用者的回報、README 與各種文件;程式碼本身(識別字、關鍵字、API 名稱)不受此規則限制。完整適用範圍表、編碼要求與替換表的唯一來源:
references/ste100.md。 - 技能文件(SKILL.md)整份為英文:frontmatter 與內文都是。風格比照 STE100:短句、祈使句、術語一致。
- 技能文件裡「要原樣輸出的繁中字面內容」保留繁中:wiki 狀態字串(例:已分析、未完成)、hook 注入文字、要寫進 wiki 或 commit 的文案。技能執行時產生的 commit 訊息、PR 描述、wiki 頁內容仍依第 1 條輸出繁中。
- README、AGENTS.md、
templates/、references/為 STE100 繁體中文。中文並列項用頓號「、」,不用半形「/」;英文項目的並列(CLI 名、頁名前綴)可用「/」。
撰寫規範(SKILL.md 內文)
- 每個步驟以可檢核的完成條件結尾(例:「成功標上工作證才可以進入下一步」),不用模糊語(「理解後」「適當地」)。
- 用正向敘述寫目標行為;禁止句只留給無法正向表達的硬性護欄。
- 每個意義只有單一真實來源:環境可查的資訊(指令、設定、目錄結構)不要抄進技能,只寫環境查不到的慣例、原因與陷阱。
- 漸進揭露:所有分支都需要的內容留在 SKILL.md;只有部分分支需要的參考資料下放
references/,以一行指引指過去。 - 善用引導詞(WBS、CPM、TDD、seam、STE100 等既有概念)取代整段解釋。
環境變數
| 變數 | 用途 | 未設定時 |
|---|---|---|
GITEA_HOST |
Gitea 站台(例:https://gitea.jsc.idv.tw) |
詢問使用者 |
GITEA_TOKEN |
Gitea API token | 改用 tea 登入金鑰(tea login list);tea 也沒有才詢問使用者 |
JSC_WIKI_REPO_QUESTION |
QUESTION_CONTENTS、QUESTION_{HASH} 所在的 {owner}/{repo} |
退回 JSC_WIKI_REPO |
JSC_WIKI_REPO_PLAN |
PLAN_CONTENTS、PLAN_{HASH} 所在的 {owner}/{repo} |
退回 JSC_WIKI_REPO |
JSC_WIKI_REPO_ANALYZE |
ANALYZE_CONTENTS、ANALYZE_{HASH} 所在的 {owner}/{repo} |
退回 JSC_WIKI_REPO |
JSC_WIKI_REPO_DELIVER |
DELIVER_CONTENTS、DELIVER_{HASH} 所在的 {owner}/{repo} |
退回 JSC_WIKI_REPO |
JSC_WIKI_REPO_MAINTAIN |
MAINTAIN_CONTENTS、MAINTAIN_{HASH} 所在的 {owner}/{repo} |
退回 JSC_WIKI_REPO |
JSC_WIKI_REPO_REPO |
REPO_CONTENTS、REPO_{HASH} 所在的 {owner}/{repo} |
退回 JSC_WIKI_REPO |
JSC_WIKI_REPO_LOG |
LOG_CONTENTS、LOG_{HASH} 所在的 {owner}/{repo} |
退回 JSC_WIKI_REPO |
JSC_WIKI_REPO_LEARN |
LEARN_CONTENTS、LEARN_{HASH} 所在的 {owner}/{repo} |
退回 JSC_WIKI_REPO |
JSC_WIKI_REPO_ERROR |
ERROR_CONTENTS、ERROR_{HASH} 所在的 {owner}/{repo} |
退回 JSC_WIKI_REPO |
JSC_WIKI_REPO_CHECK |
CHECK_CONTENTS、CHECK_{HASH} 所在的 {owner}/{repo} |
退回 JSC_WIKI_REPO |
JSC_WIKI_REPO_REPORT |
REPORT_CONTENTS、REPORT_{HASH} 所在的 {owner}/{repo} |
退回 JSC_WIKI_REPO |
JSC_WIKI_REPO |
未逐類設定時的共用 wiki {owner}/{repo} |
詢問使用者 |
JSC_HOME |
Hook 資料目錄 | 預設 ~/.jsc |
JSC_PR_WATCH_INTERVAL |
jsc-gitea/tools/pr-watch.sh 輪詢 PR 狀態的間隔秒數 |
預設 60 |
頁面類型只讀自己的 JSC_WIKI_REPO_{TYPE}。只有該變數未設定時,才退回 JSC_WIKI_REPO。不得跨類型代用。
版本前置檢查
技能組的每一支技能在被呼叫前都要確認本機版本沒有落後遠端發佈版本。判定在程式層,由 jsc-hooks 的 version-guard.sh(PreToolUse,matcher Skill)執行,不靠技能內文自我約束——寫在內文的規則,模型可以無視。
這道檢查只擋「確定落後」一種情況。查不到任何一項基礎資訊就安靜放行(exit 0),不要求先修好環境:五支 CLI 只有 claude 讀得到本機載入版本,fail-closed 會把另外四支整批鎖死。
| 項目 | 規則 |
|---|---|
| 比對對象 | 遠端發佈版本(存取庫預設分支的 plugin.json,經 jsc-gitea/tools/gitea.sh 讀取,不寫死分支名)對本機實際載入版本 |
| 實際載入版本 | 只認 installed_plugins.json 的 installPath 底下那份 plugin.json。註冊在 installed_plugins.json 的 version 欄位不當備援——註冊值可能比實際載入的版本新,拿它來比對會放過真正被載入的舊版 |
| 落後 | 擋下該次技能呼叫(exit 2),並印出更新指令。只有這一種情況會擋 |
| 相等或超前 | 放行。開發技能組時本機本來就會超前預設分支,擋下去維護者自己動不了 |
| 查不到本機載入版本 | 放行(exit 0,安靜降級)。讀不到 installed_plugins.json、裡面沒有該 plugin 的條目、取不到 installPath、installPath 底下那份 plugin.json 讀不到,四種都算這一列,不退回註冊欄位 |
| 解不出 Gitea 站台 | 放行(exit 0,安靜降級) |
| 查不到遠端版本 | 放行(exit 0,安靜降級)。缺基礎設施不等於落後,擋下去會把四支非 Claude CLI 整批鎖死 |
| 逃生門 | JSC_VERSION_GUARD=off(離線工作用),快取秒數 JSC_VERSION_TTL(預設 600) |
豁免清單(永遠放行,改動前想清楚後果):
| 技能 | 為什麼不能擋 |
|---|---|
jsc-cli:deploy |
更新整組技能的入口。擋了就沒有任何方法更新,形成死鎖 |
jsc-hooks:hooks-install |
更新後要重新接線,擋了會讓更新做一半卡住 |
jsc-cli:models |
SDLC 階段閘門依賴它產生 model-tags.tsv |
jsc-meta:* |
開發技能組本身的工具,擋了就修不了技能組 |
沒有 pre-tool hook 的 CLI 接不上這道檢查,hooks-install 要據實回報,不得暗示每個 CLI 都有保護。
Wiki 頁命名總表
所有 wiki 頁面一律採雙層命名:
| 類型 | 目錄頁 | 內容頁 | 用途 | 擁有者 |
|---|---|---|---|---|
QUESTION |
QUESTION_CONTENTS |
QUESTION_{HASH} |
問詢目錄、單一存取庫的問詢紀錄 | jsc-ask |
PLAN |
PLAN_CONTENTS |
PLAN_{HASH} |
計畫目錄、計畫頁 | jsc-sdlc |
ANALYZE |
ANALYZE_CONTENTS |
ANALYZE_{HASH} |
分析目錄、分析頁 | jsc-sdlc |
DELIVER |
DELIVER_CONTENTS |
DELIVER_{HASH} |
交付目錄、工作包交付文件 | jsc-sdlc |
MAINTAIN |
MAINTAIN_CONTENTS |
MAINTAIN_{HASH} |
維護目錄、維護頁 | jsc-sdlc |
REPO |
REPO_CONTENTS |
REPO_{HASH} |
盤點目錄、存取庫盤點頁 | jsc-sdlc |
LOG |
LOG_CONTENTS |
LOG_{HASH} |
日誌目錄、工作日誌頁 | jsc-log |
LEARN |
LEARN_CONTENTS |
LEARN_{HASH} |
教訓目錄、技能教訓頁 | jsc-log |
ERROR |
ERROR_CONTENTS |
ERROR_{HASH} |
異常目錄、異常頁 | jsc-hooks |
CHECK |
CHECK_CONTENTS |
CHECK_{HASH} |
體檢目錄、執行環境體檢頁 | jsc-cli |
REPORT |
REPORT_CONTENTS |
REPORT_{HASH} |
報表目錄、工作報表頁(年、月、週、日各一頁) | jsc-log |
{HASH} 一律為 {owner}/{repo}(必要時加上主題字串)的 SHA-1 前 8 碼,大寫。
若第一碼是 0-9、A、B、C,就改成 H 加上原 SHA-1 前 7 碼,總長仍維持 8 碼。
同一規則套用到所有目錄頁與內容頁。
REPORT 用得到那個主題字串:雜湊來源為 {owner}/{repo}/{期間},期間是 daily、weekly、monthly、yearly 其中之一。
年、月、週、日各自一頁,每頁內依期間累積分節。
CHECK 是唯一例外:它記的是一台執行環境,不是一個存取庫,所以雜湊來源為 {主機名}/{登入帳號}。
8 碼與 H 前綴的算法完全相同,由同一支 jsc-gitea/tools/hash-id 產生。
在沒有存取庫的目錄也跑得出體檢,是這個例外存在的原因。
審核檢查清單
新增或更新技能後逐項檢查,任一不符就修正:
- 名稱符合命名規則,且與既有技能目標不重複
- description 為英文、≤ 5 句或 ≤ 5 步驟(滿足任一即通過)、含觸發時機(何時用、何時不用)
- 可 hook 的規則已下放 jsc-hooks;可工具化的流程已下放 tools/;SKILL.md 沒有保留可由標準輸入輸出執行的細節流程
- 細節流程已標示 MUST run as a sub agent
- gitea 操作透過 gitea.sh 或 tea
- wiki repo 與 Gitea 認證先讀目前 shell 繼承的環境變數;只有缺值或無法解析時才詢問;頁面類型不得跨用其他
JSC_WIKI_REPO_{TYPE} - 問詢透過 jsc-ask 決策樹規則
- SKILL.md 整份為英文(要原樣輸出的繁中字面除外);README、AGENTS、templates、references 為 STE100 繁中;UTF-8 無亂碼
- 所有非程式碼輸出(程式碼註解、commit 訊息、PR 描述、wiki 頁、回報、文件)為繁體中文、UTF-8、無亂碼、無簡體字,且
tools/ste100-lint.sh對該 domain 全綠 - 已同步更新該 domain 的 README「Skills 目錄」與三份 manifest 的 version
- PR 的 base 符合「PR 分支階梯」,沒有越級