JurisLM Repo 設定規範
Repo 分類
| 類型 | 適用 Repo | CI 平台 | release-type | Runtime | ESLint 基礎 |
|---|---|---|---|---|---|
| Next.js | Next.js web app repos | Drone | node |
Bun | eslint-config-next |
| Node/TS | Node/TypeScript service repos | Drone | node |
Bun | @eslint/js + typescript-eslint |
| Plugin | Content-first plugin repos | Drone | simple |
— | 無 TS 原始碼,不需要 ESLint |
| Monorepo | jurislm/entire(唯一已驗證 reference)及其他待驗收 monorepo |
Drone | node |
Bun | @entire/eslint-config 或目標 repo 的既有設定 |
自架 Drone(https://ci.jurislm.com)是唯一的 CI 與 release 平台,四種 repo 類型一律適用。
新 repo 直接建立 .drone.yml;既有 repo 若仍在其他平台,遷移與移除舊 workflow 屬同一次交付。
references/ci-workflow-templates.md 的模板以部署形態命名,對應關係是
Next.js → 模板 A(Coolify web app)、Monorepo → 模板 B、Node/TS → 模板 C(npm / MCP)、
Plugin → 模板 D。
⚠️ 上游 fork(例如 jurislm/firecrawl)保留上游自己的 workflow,不受本規範約束——
那些檔案是上游資產。本規範只涵蓋 JurisLM 自有的 repo。
Verified Reference 與導入目標
jurislm/entire是目前唯一已透過可觀測驗收證明的 release delivery 與 monorepo CI/CD reference。- 其他 repo 都是 adoption target;完成該 repo 自己的 CI、release、部署/發布與 readback 驗收前,不得標示為 verified reference,也不得把它的拓撲當成組織標準。
entire的 reference 範圍是可驗證的不變量(trusted main delivery、Turborepo 與安全 release contract),不是要複製它的 Runtime、Coolify 部署或 app 拓撲。- 從
entire提煉規則時,怎麼取證、哪些機制是可移植規則、哪些只是條件控制,見references/entire-delivery-design.md。
Agent 指引檔同步:AGENTS.md 讀取 CLAUDE.md
CLAUDE.md 是 JurisLM repo 的人機協作規範單一來源;AGENTS.md 只作為 Codex / agents 的入口轉接檔。
執行 /repo-standards 審查任一 repo 時,必須先檢查 repo 內是否存在 AGENTS.md:
- 若 repo 內沒有
AGENTS.md:不需要新增,除非使用者明確要求。 - 若 repo 內有一個或多個
AGENTS.md:逐一更新為讀取同層CLAUDE.md;若同層沒有CLAUDE.md,則讀取 repo 根目錄CLAUDE.md。 - 不要把
CLAUDE.md全文複製進AGENTS.md;避免兩份規範 drift。 - 若找不到可對應的
CLAUDE.md:先回報阻塞,不要產生空泛或過期規則。
標準 AGENTS.md 內容:
# AGENTS.md instructions
請先閱讀並遵守同目錄的 `CLAUDE.md`。
若本目錄沒有 `CLAUDE.md`,請改讀 repo 根目錄的 `CLAUDE.md`。
本檔只作為 agents 入口;實際 repo 規範以 `CLAUDE.md` 為準。
變更追蹤
預設以 Linear issue 作為需求、範圍、驗收標準與交付狀態的唯一紀錄,比照
jurislm-tools 根目錄 CLAUDE.md 的 Linear + Superpowers 交付鏈。不要建立、引用或
依賴 GitHub Issue。
標準變更影響其他 adoption target 時,用 Linear 的 project、issue 關聯與 blocks/blocked-by 記錄目標與相依關係。
⚠️ 前置條件:已連接的 Linear workspace(讀寫 issue 用)。spectra init 可以由目標
repo 自己跑起來,Linear 不行——沒有 workspace 就沒有預設路徑可走。目標 repo 未接
Linear 時,開始非瑣碎變更前先問使用者要用哪個追蹤容器,不要自行假設,也不要因此
略過追蹤。
只有使用者明確要求 Spectra/OpenSpec 時才改用它:那時先執行 spectra --version,
目標 repo 缺少 openspec/ 或 .spectra.yaml 就先在根目錄 spectra init,之後一律以
proposal → design → specs → tasks 作為該次交付的唯一紀錄。兩套不混用——一次交付
只屬於其中一個容器。
Git Worktree 規則
GitHub Flow 單段式:main worktree(根目錄)永遠保持在 main 分支,不做 feature commits;每個需求/功能直接從 main 建立獨立 feature worktree,沒有 develop 分支這一段。
分支結構
<repo>/ ← main worktree,永遠在 main 分支,不做 feature commits
<repo>/.claude/worktrees/
<change-name>/ ← feature worktree,需要時建立,直接基於 main
建立規則
# 確認現有 worktree 與分支
git worktree list
git branch --show-current # 根目錄必須顯示 main
# 建立 feature worktree(直接基於最新 main,不動主目錄)
git fetch origin main
git worktree add --no-track -b <change-name> .claude/worktrees/<change-name> origin/main
# ⚠️ <change-name> 若含 "/"(如 feature/auth),-b 後面用原始名稱,
# 但 .claude/worktrees/ 後面的目錄部分要換成 "-"(.claude/worktrees/feature-auth),
# 兩處不是同一個字串,見下方「強制規則」的完整範例
# ⚠️ start point 是 origin/main(remote-tracking ref),若省略 --no-track,
# git 預設會把新分支的 upstream 設成 origin/main(是否真的觸發依
# branch.autoSetupMerge 設定而定,不保證每個環境都一樣);--no-track 從一開始
# 就不建立這個 tracking,比事後用 git config --unset 解除更可靠——後者在
# upstream 其實沒被設定的環境會直接報錯(exit 5,key 不存在),不是穩妥的做法
git push -u origin <change-name> # 明確指定 upstream,不要裸 push
開發流程
.claude/worktrees/<change-name> → commit → push origin <change-name> → PR <change-name>→main → merge
強制規則
- main worktree 根目錄只能在
main分支,不可切換到其他分支 - 若發現根目錄不在 main:立即
git checkout main && git pull origin main - 嚴禁直接 push 到 main(main 連接 Coolify 自動部署 + Release Please)
- 沒有
develop分支:不建立、不維護、不預期存在——每個 feature worktree 直接從main分出,PR 一律直接<change-name> → main - feature worktree 目錄名稱必須與 branch 名稱一致(
.claude/worktrees/<change-name>↔<change-name>;branch 名稱含/時目錄以-替代,例:branch =feature/auth→ 目錄 =.claude/worktrees/feature-auth) .claude/worktrees/由 Claude Code runtime 透過本地.git/info/exclude自動排除,不要額外加進.gitignore;但.prettierignore/ESLint ignores/vitest.config.ts的exclude不會讀 git 的 exclude 規則,仍須各自手動加入.claude/worktrees/**
Runtime 規範:統一使用 Bun
所有 JavaScript/TypeScript repo 統一使用 Bun 作為 runtime 與 package manager。
package.json 標準設定
所有 repo 共用欄位:
{
"packageManager": "bun@1.3.14",
"engines": {
"bun": ">=1.1.0"
}
}
Node/TS repo(MCP server 等) 的 scripts:
{
"scripts": {
"dev": "bun --watch src/index.ts",
"start": "bun dist/index.js",
"build": "bun build src/index.ts --outdir dist --target bun",
"test": "bun run vitest",
"typecheck": "tsc --noEmit",
"lint": "eslint --max-warnings=0"
}
}
Next.js repo 的 scripts:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"test": "bun run vitest",
"typecheck": "tsc --noEmit",
"lint": "eslint --max-warnings=0"
}
}
命令對照
| 舊(Node.js/npm) | 新(Bun) |
|---|---|
npm install |
bun install |
npm run dev |
bun run dev |
node dist/index.js |
bun dist/index.js |
tsx watch src/index.ts |
bun --watch src/index.ts |
ts-node src/index.ts |
bun src/index.ts |
npm publish |
bun publish |
安裝必要套件
# 移除舊 Node.js 工具
bun remove tsx ts-node
# 加入 Bun 類型
bun add -d @types/bun
測試規範:統一使用 Vitest
所有 TypeScript repo 的單元測試統一使用 Vitest。
安裝
bun add -d vitest
package.json scripts
{
"scripts": {
"test": "bun run vitest",
"test:watch": "bun run vitest --watch",
"test:coverage": "bun run vitest --coverage"
}
}
vitest.config.ts 標準模板
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
globals: true,
environment: 'node',
exclude: [
'**/node_modules/**',
'.claude/worktrees/**',
],
},
})
測試寫法
import { describe, it, expect, vi, beforeEach } from 'vitest'
describe('MyModule', () => {
beforeEach(() => {
vi.clearAllMocks()
})
it('should do something', () => {
const spy = vi.fn().mockReturnValue('result')
expect(spy()).toBe('result')
})
})
關鍵 API:
- Mock:
vi.fn(),vi.spyOn(),vi.mock() - 環境變數:
vi.stubEnv('KEY', 'value')/vi.unstubAllEnvs() - 模組:
vi.mocked()取得 typed mock
三層測試分工
| 層級 | 工具 | 範疇 |
|---|---|---|
| 單元測試 | Vitest | 純函式、業務邏輯 |
| 整合測試 | Vitest + Testcontainers + MSW | API Route Handlers ↔ DB |
| E2E 測試 | Playwright | 完整使用者流程、頁面渲染 |
整合測試(Next.js repo)
整合測試驗證 Route Handlers 與資料庫互動(狀態碼、資料結構、錯誤路徑)。資料庫用 Testcontainers(Docker 隔離),外部 HTTP 用 MSW 攔截。
完整 vitest.config.ts 多 project 設定模板與安裝指令,見
references/testing-config-templates.md。
Release 設定
release-please 一律在 Drone 執行,四種 repo 類型皆同——Coolify web app /
npm-MCP / monorepo / plugin 都使用 repo 根目錄的 .drone.yml。標準順序是
先 github-release(cut 已合併 release PR),再 release-pr(維護下一個版本
PR)。完整模板與變體見 references/ci-workflow-templates.md。
.drone.yml 的 release-please pipeline(只在 push main 跑)
---
kind: pipeline
type: docker
name: release-please
trigger:
event: [push]
ref: [refs/heads/main]
steps:
- name: github-release
image: node:20-alpine
environment:
GITHUB_API_TOKEN: { from_secret: GITHUB_API_TOKEN }
commands:
- npx --yes release-please@<EXACT-RELEASE-PLEASE-VERSION> github-release --repo-url=https://github.com/jurislm/<REPO> --config-file=release-please-config.json --manifest-file=.release-please-manifest.json --token=$GITHUB_API_TOKEN
- name: release-pr
image: node:20-alpine
depends_on: [github-release]
environment:
GITHUB_API_TOKEN: { from_secret: GITHUB_API_TOKEN }
commands:
- npx --yes release-please@<EXACT-RELEASE-PLEASE-VERSION> release-pr --repo-url=https://github.com/jurislm/<REPO> --config-file=release-please-config.json --manifest-file=.release-please-manifest.json --token=$GITHUB_API_TOKEN
規則:
- 先
github-release(建 tag / release)再release-pr(維護下一個版本 PR),兩者皆冪等;若反過來,尚未 cut 的已合併 release PR 可能阻擋新 release PR。 - 所有會寫 GitHub 的 Release Please command 都必須使用
release-please@<EXACT-RELEASE-PLEASE-VERSION>;目標 repo 必須替換為經測試的精確版本,禁止 unpinned command。 GITHUB_API_TOKEN為 Drone repo-scope secret(Drone Web UI Settings → Secrets)。classic PAT 最小需求是repo一個 scope;workflow僅在該 repo 有.github/workflows/時才需要(實查七個 JurisLM repo 皆無)。⚠️ 現行那顆開了 21 個 scope,屬過度授權。 ⚠️ 它是跨 JurisLM 各 repo 共用的同一份憑證,且用途不只 release-please(release-pr-auto-merge、deploy也用它)。 輪替時必須同步更新每一個 repo 的同名 secret;fine-grained PAT 另需 Issues: Read and write(autorelease:label), 有release-pr-auto-merge的 repo 再加 Administration: Read(讀 branch protection)。release-type不可寫在 pipeline — 必須只放在release-please-config.json(否則 Release Please 會忽略 config 的extra-files,導致plugin.json/marketplace.json版本號不被更新)。--config-file+--manifest-file必填 — 明確引用 config,避免隱性 drift。- ⚠️ 合併 release PR 後須確認 push webhook 有觸發 build(GitHub 偶爾漏發 → release 卡住沒 cut)。若 trusted delivery 沒有建立,保留候選 PR,修復後由新的 trusted main delivery 重試;不得人工合併或手動執行 write command 繞過 validator。
Release PR 自動合併契約(所有採用 repo)
Release Please 在 trusted main delivery 完成後,必須由該 repo source-controlled 的 validator 自動處理候選 PR;不得保留人工合併 fallback。validator 必須:
- 綁定同一個 delivery commit
C,並確認 validate/release 前置 pipeline 都成功。 - 以 target-specific closed artifact contract 驗證精確檔案清單、版本欄位與內容;不得把另一個 repo 的檔案 allowlist 直接套用。
- 驗證官方 candidate identity(repository、base branch、head branch、作者、title/body marker)、base/head SHA、required-check clean 狀態與 mergeability。
- 在寫入前驗證 target branch protection/ruleset:candidate 必須受 latest-base required checks 約束,automation credential 不可繞過,且 release PR 不得要求人工 approval;legacy branch protection 需
strict: true且對 admin credential 啟用 enforcement。 - 只用 GitHub PR merge API 並傳入剛驗證的 head SHA;每個 target 必須先 readback target-compatible merge mode。採 Conventional Commit eligibility 的 target 預設 squash-only,並以已驗證 PR title 作 squash title;若沒有 candidate、candidate base 已由較新 delivery 接手、候選等待時 reread 證實 main 已改變,或 GitHub 拒絕 stale merge 後 reread 證實 main 已改變,成功 no-op 並交由較新 delivery 處理。
- 其他 identity、artifact、SHA、protection、required-check、API 或 mergeability mismatch 一律 fail closed;不得直接更新 main ref。
Release eligibility 的 Compare request 必須綁定 immutable DRONE_COMMIT,並從該 commit
沿 first-parent mainline 回到已發布 tag;Compare side branch 的中間提交不可當作 main
delivery subject。first-parent path 不完整時 fail closed。若須為既有 GitHub default merge
歷史做 recovery,僅能接受精確 default merge subject 與通過 Conventional Commit 驗證的
body title;未來 merge policy 不得依賴此相容性分支。
No candidate is a safe no-op;a candidate based on a newer delivery is a safe no-op;a waiting candidate or rejected protected merge that proves main changed is a safe no-op。其他狀態不得合併。
Validator 只能在 trusted main-delivery pipeline 執行。禁止 pull_request_target、candidate-head checkout/執行,以及把 write token 暴露給 PR workflow。
release-type 選擇
| 類型 | 適用條件 |
|---|---|
node |
有 package.json |
simple |
無 package.json(plugin repo),搭配 extra-files 同步版本號 |
標準 release-please-config.json
{
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
"packages": {
".": {
"release-type": "node",
"changelog-path": "CHANGELOG.md",
"bump-minor-pre-major": true,
"bump-patch-for-minor-pre-major": true,
"include-component-in-tag": false,
"include-v-in-tag": true,
"changelog-sections": [
{ "type": "feat", "section": "Features" },
{ "type": "fix", "section": "Bug Fixes" },
{ "type": "perf", "section": "Performance" },
{ "type": "docs", "section": "Documentation" },
{ "type": "refactor", "section": "Refactoring" },
{ "type": "style", "section": "Styles" },
{ "type": "test", "section": "Tests" },
{ "type": "chore", "section": "Maintenance", "hidden": true }
]
}
}
}
Plugin Repo 額外設定
Plugin repo(如 jurislm-tools)需加 extra-files 同步版本號:
"extra-files": [
{
"type": "json",
"path": "plugins/<repo-name>/.claude-plugin/plugin.json",
"jsonpath": "$.version"
},
{
"type": "json",
"path": ".claude-plugin/marketplace.json",
"jsonpath": "$.plugins[0].version"
}
]
⚠️ 重要:marketplace.json 用 $.plugins[0].version(index,非 filter),目標 plugin 必須是陣列第一個元素。
Plugin 類型的 release / 驗證
Plugin 類型的 .drone.yml 必須同時提供 PR / main 的 aggregate validation 與
main-only release pipeline。每個 plugin repo 仍須完成自己的 observable
acceptance,才算符合本標準。
repo 若另有與 CI/release 無關、具獨立語意的 workflow(例如發版後手動觸發的資料
同步),保留與否的判準見 references/ci-workflow-templates.md。
Monorepo CI/CD(Turborepo)
所有 JurisLM monorepo 必須在 repo root 提供 turbo.json,並以 Turborepo 定義 workspace task 與 cache。entire 是唯一已驗證 reference;其他 monorepo 只有完成自己的 observable acceptance 後,才能宣稱符合。
- 已知且固定的 workspace gate 使用
turbo run <task> --filter=<workspace>;--filter不是任意縮小檢查範圍的理由。 --affected只可在 trusted Git base/head 已明確建立、可重現且涵蓋目標 delivery 時使用。- 無法建立可信 Git 範圍或 affected query 不確定時,執行完整 validation/deploy,不得靜默跳過。
- Turbo cache inputs 必須包含 task 實際讀取的全部 source、config、test 與 lockfile 檔案;漏列會造成 false green,必須由 policy test 或等價 readback 證明。
- monorepo 的 deployment targets 仍依 repo 類型各自定義;不得因採用 Turborepo 而複製
entire的 Coolify topology 到 Plugin/npm repo。
ESLint 設定
所有 repo 統一使用 ESLint 9 flat config,搭配 --max-warnings=0。
統一規則
| 規則 | 設定 | 說明 |
|---|---|---|
@typescript-eslint/no-explicit-any |
error(test 檔案豁免) |
禁用 any |
@typescript-eslint/no-unused-vars |
error(_ 前綴豁免) |
未使用變數 |
| Prettier 整合 | eslint-config-prettier |
關閉與 Prettier 衝突的規則 |
.claude/worktrees/** |
ignores | 排除 feature worktree 內容 |
| lint script | eslint --max-warnings=0 |
warning 視同 error |
完整 config 模板見
references/eslint-templates.md。
必要套件
# Next.js repo
bun add -d eslint eslint-config-next eslint-config-prettier prettier
# Node/TS repo
bun add -d eslint @eslint/js typescript-eslint eslint-config-prettier globals prettier
.prettierignore 必含
# git worktrees
.claude/worktrees/
⚠️ 少了這行,prettier --write . 會掃到 feature worktree 內容(各自完整的 checkout),導致 pre-commit 失敗。
CI Workflow 設定(Drone CI)
lint / typecheck / test 一律在自架 Drone(https://ci.jurislm.com)執行——
四種 repo 類型都使用 repo 根目錄的 .drone.yml,validation 與 release 都由
Drone 擁有。大型 repo 可把檢查拆成多個 pipeline;小型 plugin repo 可用單一
aggregate validate pipeline。GitHub PR 顯示一個 aggregated check(drone/pr)。
完整模板(Coolify Web App / Monorepo / npm 套件 / Plugin 變體 + deploy + secrets)見
references/ci-workflow-templates.md。
核心規則:避免重複觸發(Drone 版)
用 trigger.event + trigger.ref(git ref glob)對齊「PR 任意分支 + push 限 main」:
trigger:
event: [push, pull_request]
ref:
- refs/heads/main # push main(post-merge safety net)
- refs/pull/*/head # PR(任意分支)
- Feature 分支只由
refs/pull/*/head(PR)觸發,push main只覆蓋 main 自己(繞過 PR 的 force-push / rebase / release-please commit safety net);兩者涵蓋範圍不重疊,避免同一次變更雙 build 競爭 runner(GitHub Actions 時代 Issue #82 的 duplicate-runs 教訓,Drone 用 ref glob 從設計上避免)。 - release-please commit 守衛:deploy / lint / test 在純版號 commit 上跳過(見下方 CD 章節)。
Audit 既存 Repo
# 逐 repo 解碼 .drone.yml 看 pipeline 與 trigger.ref(已過濾 archived repo)
for repo in $(gh repo list jurislm --limit 50 \
--json name,isArchived -q '.[] | select(.isArchived == false) | .name'); do
echo "=== $repo ==="
gh api "repos/jurislm/$repo/contents/.drone.yml" --jq '.content' 2>/dev/null \
| tr -d '\n' | base64 -d 2>/dev/null | grep -E '^name:|refs/heads' | head -15 \
|| echo "(no .drone.yml)"
done
單一平台原則:每個 repo 的 CI 與 release 只由 Drone 擁有。既有 repo 遷移時,舊平台上所有負責 CI、release 或版本檢查的 workflow 都必須和 Drone
設定在同一次交付中移除,避免雙跑。認定依用途,不依檔名——常見的是
.github/workflows/ 底下的 ci.yml、release.yml、version-check.yml,但實際檔名
由各 repo 自訂,audit 時要讀 workflow 內容而不是比對這份清單。與 CI/release 無關、
具獨立語意的 workflow 不在此列。
規範回填協議
當任一 repo 的 .drone.yml 發現新陷阱:在來源 repo 修復(PR 含 root cause)→ 同步回填 references/ci-workflow-templates.md + 本檔 → 在該次交付的追蹤紀錄裡登記其他 adoption target(Linear:issue 關聯;選用 Spectra 的 repo:proposal 的 Delivery Relations)。禁止只修單一 repo 不回填。
部署(CD)與避免重複部署
完整設定步驟、守衛邏輯、secret、收尾與踩坑見
references/ci-workflow-templates.md「CD 與避免重複部署」「部署收尾」章節。以下為核心規範。
Coolify auto-deploy 對每個 push main 都部署,包含 release-please 的純版號 commit → 同一份程式碼被部署兩次(feature 合併一次、release PR 合併再一次)。解法是把部署觸發移到 Drone 並關閉 auto-deploy:
.drone.yml加buildpipeline(pushmain + PR,一般 clone,跑bun run build)與deploypipeline(pushmain、depends_on涵蓋lint-typecheck/test/build;只有deploy用clone: { disable: true }——它只 curl Coolify API 不需要 repo 內容,build需要完整 clone 才能執行建置):curl Coolify deploy API,守衛跳過 release commit。- 守衛:
echo "$DRONE_COMMIT_MESSAGE" | grep -qE '^chore(\(.+\))?: release [0-9]'- grep 全訊息(勿加
head -1):merge commit 合併 release PR 時 HEAD subject 為Merge pull request #N from …release-please…、chore(main): release X.Y.Z落在 body;加head -1只看 subject 會漏判 → release commit 誤觸發部署(2026-06-02 entire #383 實證)。全訊息 grep 同時涵蓋 merge(body 命中)與 squash(subject 命中)。release [0-9]要求版號數字(排除chore: release notes …誤判)。
- grep 全訊息(勿加
- Drone repo-scope secret
COOLIFY_DEPLOY_TOKEN(pull_request: false)。 - 關閉每個部署 app 的 Coolify auto-deploy(
is_auto_deploy_enabled;先驗證 Drone→Coolify 接線可用再關,避免部署被靜默停止)。 - 加
release-pr-auto-mergepipeline,讓 Release Please 在 trusted main delivery 後自動合併(Coolify web app 的部署 pipeline 仍須依 repo 類型設定;release PR 不得以人工合併作 fallback)。validator 必須遵守上方「Release PR 自動合併契約」。
結果:單 app repo,feature 合併進 main = 部署 1 次。Multi-app monorepo 且未額外
導入受影響 target 判斷時,每個 app 的 deploy step 對每次 push main 都各自部署,不分
該次改動是否影響該 app——這是本規範預設,不虛構模板沒有的選擇性部署能力;需要依
dependency graph 只部署受影響 target 時,那是進階條件控制,見
references/entire-delivery-design.md 的「Production deploy」一列。
trusted release PR 自動合併進 main = 部署 0 次(守衛跳過,僅 release-please 建 tag)。
這同樣是簡化版——沒有選擇性部署系統時,release commit 完全不寫入。entire 自己
另外跑一層 --pin-only,只對已 caught up 到 release 父節點的 target 做已驗證的部署
狀態對齊,是條件控制而非本規範預設;見同檔「Release commit deploy」一列。
僅適用 Coolify-deployed repo(web app)。npm 套件 / MCP repo 不需要——它們 publish 到 npm,只在 release commit 發布一次,無重複問題。Monorepo(多 app)須為每個部署的 app 各設一個 deploy step。
⚠️ 合併任何 PR 進 main 後務必確認 push webhook 有觸發 build(GitHub 偶爾漏發 → release / deploy 卡住)。若 delivery 沒建立,保留 release candidate,修復後由新的 trusted main delivery 重試,不得人工合併或手動執行 write command 繞過 validator。
Code Review 設定
PR review 與 merge 的唯一操作契約是目標 repo 自身的 CLAUDE.md。目標 repo 缺少
## PR review and merge contract 時,先將本 skill 的
references/review-orchestration-template.md 複製進其 CLAUDE.md,再依 repo 的
required checks 與部署方式客製化。建立 PR 後必須 invoke
superpowers:requesting-code-review;收到 finding 時以
superpowers:receiving-code-review 逐項處置、修正或記錄具體拒絕理由,並 resolve
所有 review thread。合併前還必須符合 CI、mergeable=MERGEABLE、mergeStateStatus
為 CLEAN/UNSTABLE/HAS_HOOKS(不可為 BLOCKED/DIRTY/BEHIND;不要求
CLEAN——理由見 references/review-orchestration-template.md)、CodeRabbit gate。
目標 repo 使用 engineering-delivery 時,本地 review 由該 Skill invoke
superpowers:requesting-code-review 擁有;外部 review 交給 coderabbit:code-review
skill,不另起第二套審查機制。
repo 設定必須提供以下前置條件:
- CodeRabbit:
.coderabbit.yaml設定reviews.auto_review.enabled: false,每個 PR 只明確 request App 一次;CLI 只依 canonical contract 作為 App 無法產生有效 review 時的 fallback。 - Codex:屬帳號層級設定,是否自動審查、何時觸發依各貢獻者個人 Codex 帳號,repo 不做覆寫;不要主動 request 或等待其回應,平台自動貼出的 finding 仍逐項核實。
- 不設定自動 Claude PR review pipeline:不新增
claude-code-review.yml、claude.yml或 Droneclaude-review,也不需要CLAUDE_CODE_OAUTH_TOKEN。
完整的 consent、secret preflight、外部審查預算與 gate 細節只以 canonical contract 為準,避免在此複製而 drift。
新增 Repo Checklist
完整 checklist(AGENTS.md / Git Worktree / Runtime / 測試 / Release / ESLint / CI / CD / Code Review)見 references/new-repo-checklist.md。
快速概覽(各類別必做項):
- AGENTS.md:若 repo 內存在
AGENTS.md,更新為讀取同層或 repo 根目錄CLAUDE.md;不要複製 CLAUDE 全文 - 變更追蹤:預設用 Linear issue 記錄需求、範圍與驗收;跨 repo 目標用 Linear 的 project 與 issue 關聯表示。僅在使用者明確要求時改用 Spectra 四件套
- Worktree:feature worktree 直接從 main 建立於
.claude/worktrees/<change-name>,不建立 develop;.claude/worktrees/不進.gitignore(由 Claude Code runtime 本地排除) - Bun:
"packageManager": "bun@1.3.14",scripts 換成bun run vitest等 - Release:使用
main-only release pipeline,依序執行固定精確版本的github-release、release-pr;release-type放在 config,Plugin repo 加extra-files,secret 使用GITHUB_API_TOKEN,並由同一 trusted delivery 的 source-controlled validator 自動合併 release PR;無人工 fallback - Release 資格閘門:使用
release-type: simple的 Plugin repo 必須在release-pr前執行scripts/release-eligibility.mjs;只有 exit0才呼叫 Release Please,exit10成功跳過,其他錯誤 fail closed;完整模板見references/ci-workflow-templates.md - Delivery subject:資格閘門必須對 immutable
DRONE_COMMIT走 first-parent mainline;對 Conventional Commit target,GitHub merge setting 預設 readback 為 squash-only + pull-request title 作 squash title - Monorepo:所有 JurisLM monorepo 必須有 root
turbo.json;已知 workspace 用--filter,可信 Git base/head 才能用--affected,否則完整 validation/deploy,cache inputs 必須涵蓋 task 讀取的全部檔案 - ESLint:
eslint --max-warnings=0,.prettierignore加.claude/worktrees/ - CI:檢查 pipeline
trigger.ref只列refs/heads/main+refs/pull/*/head;既有 repo 遷移時,舊平台上所有 CI、release 與版本檢查用途的 workflow 在同一次交付移除(依用途認定,不依檔名) - CD(Coolify web app):
.drone.yml加build、deploy、release-pr-auto-merge三個 pipeline + release-commit 守衛 + 關閉 Coolify auto-deploy + secretCOOLIFY_DEPLOY_TOKEN(npm/MCP repo 不需要) - Code Review:將 packaged review contract 寫入目標
CLAUDE.md後,依其 invoke Skill-driven review;CodeRabbit 一次明確 App request、Codex 依個人帳號設定;無自動 Claude review