Documentation Index
Fetch the complete documentation index at: https://docs.trytrellis.app/llms.txt
Use this file to discover all available pages before exploring further.
1. 命令与 Skill 参考
0.5.0 开始 Trellis 走 skill-first:大部分能力都做成 auto-trigger skill,平台自己根据上下文触发,不用你记命令。只保留会话边界入口:agent-capable 平台暴露 finish-work 和 continue;没有自动会话注入的平台额外暴露 start。
1.1 总览
| 类型 | 名称 | 触发 | 用途 |
|---|
| Command | /trellis:start | 手动(支持 hook 的平台会自动注入) | 开启会话、加载上下文、任务分类 |
| Command | /trellis:continue | 手动 | 当前任务内推进下一步工作流,用户不用记 workflow(详见 1.2.2 小节) |
| Command | /trellis:finish-work | 手动,在 Phase 3.4 commit 落地之后 | 归档 task + 写入 session journal |
| Skill | trellis-brainstorm | 用户描述需求 / bug / 模糊诉求时自动触发 | 把请求转成 task + prd.md |
| Skill | trellis-before-dev | task 中动手改代码前自动触发 | 先读相关 spec 再写代码 |
| Skill | trellis-check | 实现完成后自动触发;也被 sub-agent 调用 | 验证 + 自修复循环 |
| Skill | trellis-update-spec | 有值得沉淀的知识时自动触发 | 把经验固化进 .trellis/spec/ |
| Skill | trellis-break-loop | 修完棘手 bug 后自动触发 | 根因分析 + 预防机制 |
只有 3 个 slash 命令:start、continue、finish-work。以前的 /before-backend-dev、/check-backend、/record-session、/onboard 等等都已经被折叠进 skill/sub-agent 或直接移除。
1.2 命令
1.2.1 /trellis:start:开启会话
如果平台不自动注入上下文就手动跑一下。Hook 或 extension 可用的平台(Claude Code、Cursor、OpenCode、Gemini、Qoder、CodeBuddy、Copilot、Droid、Pi Agent,以及开了 features.hooks = true 的 Codex —— 旧版用 codex_hooks = true)有 SessionStart hook 或 extension,打开终端就自动执行,所以通常不会安装用户可见的 start 命令。
行为:
- 读
.trellis/workflow.md,让 AI 清楚工作流契约。
- 跑
get_context.py 拿到开发者身份、git 状态、活跃任务。
- 读 spec 索引(monorepo 场景下按 package 读)。
- 汇报上下文并询问你想做什么。
AI 做的任务分类:
| 类型 | 判断依据 | 流程 |
|---|
| 问答 | 问代码 / 架构相关问题 | 直接回答 |
| 小修 | typo / 单行修改 / 约 5 分钟以内 | 直接改 |
| 开发任务 | 逻辑变更、新功能、多文件修改 | 任务工作流(brainstorm skill) |
拿不准就走任务工作流,它能保证 sub-agent 拿到正确的 spec 注入。
1.2.2 /trellis:continue:当前任务内推进下一步
continue 是单个任务内的 continue,不是跨任务的 continue。AI 根据当前 task 的 task.json.status 和每轮 hook 注入的 workflow-state breadcrumb,对照 workflow.md 判断当前在哪个 phase/step,然后推进到下一步。
典型一次 task 的对话:
- 你用自然语言描述需求 →
trellis-brainstorm auto-trigger → 创建 task、起草 prd.md。
- PRD 跟你确认完,你输入
continue → 它知道下一步是填 implement.jsonl / check.jsonl(给 sub-agent 的 context 索引)。
- 填完再跟你确认,你输入
continue → 它知道下一步是 spawn trellis-implement 和 trellis-check sub-agent。
- sub-agent 跑完你再
continue → 它知道该走 trellis-update-spec,最后 finish-work。
以前你得自己学 workflow、记住每个阶段该调哪个 slash command 让 AI 干对应的事;现在一路自然对话 + continue,几乎零学习成本就能跑完整个 trellis 工作流。
1.2.3 /trellis:finish-work:收尾 + 归档
前提:代码已经 commit。AI 在 workflow Phase 3.4(见 .trellis/workflow.md)里主导批量 commit —— 起草本次 session 改动的 commit 计划、参考 git log --oneline -5 学习 repo 的 commit message 风格、一次性展示计划让用户 confirm、确认后逐批 git commit。/finish-work 自身只做 archive + journal,工作区还有未提交代码改动时拒绝执行,保证 bookkeeping commit 永远在 work commit 之后。
步骤:
- 跑
get_context.py --mode record,列出 active tasks、git status 和 recent commits。用这一步发现除了当前 task 之外是否还有其它已完成但未归档的 task,并拿到 Step 4 要用的 work-commit hash。
- 跑
git status --porcelain,排除 .trellis/workspace/ 和 .trellis/tasks/(这两个路径由脚本 auto-commit 管理)。其它路径有 dirty 文件就拒绝执行,引导用户回到 Phase 3.4。
- 用
task.py archive <name> 归档当前 active task(产生 chore(task): archive ... commit)。如果 Step 1 暴露出其它已完成 task 且用户确认了清理,本轮一并归档。
- 用
add_session.py --title … --commit … 追加一条 journal(产生 chore: record journal commit)。
最终 git log 顺序:<3.4 阶段的 work commits> → chore(task): archive ...(可能多条)→ chore: record journal。把本次经验沉淀进 trellis-update-spec 属于 workflow Phase 3.3 在 commit 之前的事,不在这个 skill 的职责里。
1.3 Auto-trigger Skills
Skill 不需要显式命令,平台根据用户意图自动匹配。匹配不中时手动触发就行(/skill trellis-brainstorm 之类)。
1.3.1 trellis-brainstorm
把模糊的用户请求转成具体任务:
- 产出任务名和 slug。
- 按 assumption / requirement / acceptance 模板起草
prd.md。
- 请求依赖调研时(现有代码、外部 API、库文档),并行 spawn
trellis-research sub-agent。
- 通过
task.py create 建任务。
1.3.2 trellis-before-dev
编码前触发。读受影响 package 的 spec 索引,再读 Pre-Development Checklist 里引用的具体 guideline 文件。确保 AI 在动手前就知道约定,而不是之后。
1.3.3 trellis-check
实现完之后触发:
git diff --name-only HEAD 找变更。
- 确认哪些 spec 层适用。
- 对照每层 index 的 quality checklist 比对代码。
- 为受影响 package 跑
pnpm lint / pnpm typecheck / pnpm test(或等价命令)。
- 在有限循环内自修复违规,然后汇报修了什么、还剩什么。
trellis-check sub-agent 把这个 skill 包了一层,主会话把验证这事丢给它就行。sub-agent 自己有重试循环,不再需要外面套 Ralph Loop。
1.3.4 trellis-update-spec
把经验沉淀为 .trellis/spec/ 里的可执行契约。调试完、踩坑后、做了非显而易见的设计决策时用。会挑对应的 spec 文件,做一次聚焦更新(decision / convention / pattern / anti-pattern / gotcha),必要时更新索引。
1.3.5 trellis-break-loop
修完难 bug 后触发。产出 5 维分析:
- 根因分类(缺 spec / 契约违反 / 变更传播失败 / 测试缺口 / 隐式假设)。
- 之前修复尝试失败的原因。
- 预防机制(更新 spec、类型约束、lint 规则、测试、CR 清单、文档)。
- 系统化扩散:其他具备同样模式的地方。
- 知识固化:结果走
trellis-update-spec。
调试的价值不是修掉 这个 bug,而是确保这一类 bug 不再发生。
1.4 Sub-agents
Sub-agent 是独立的 AI 子进程,各自有 prompt 和(视平台而定)各自的 tool / hook 挂接。上下文通过 task 目录下的 JSONL 文件注入。
| Sub-agent | 约束 | 主会话何时 spawn |
|---|
trellis-research | 只读 | 代码搜索 / 模式发现 / 文档查阅 |
trellis-implement | 写代码,不 commit | 需求 + 计划就绪后的编码阶段 |
trellis-check | 可写(修复) | 验证阶段;内部自带自修复循环 |
在 Claude Code、Cursor、OpenCode、CodeBuddy、Droid、Pi Agent 上,这些 sub-agent 启动前会自动拿到对应 JSONL(implement.jsonl、check.jsonl、research.jsonl)。Pi 走 extension,不是 Python hook。其他平台由主会话自行读 JSONL 并把相关内容传给 sub-agent。
2. 任务管理全流程
2.1 任务生命周期
create → curate jsonl → start → implement/check → finish → archive
create: 任务目录 + task.json + seed jsonl
curate jsonl: AI 填 implement/check/research 上下文
start: 写入当前 AI 会话/窗口的任务
implement/check:开发与验证循环
finish: 清除当前 AI 会话/窗口的任务
archive: 把完成任务移动到 archive/
task.py create 在检测到 sub-agent 平台(Claude / Cursor / Codex / Kiro / Pi 等)时会 seed 出 implement.jsonl + check.jsonl;agent-less 平台(Kilo / Antigravity / Windsurf)跳过 seed,改由 Phase 2 的 trellis-before-dev skill 加载 spec。
2.2 task.py 子命令
2.2.1 创建任务
# 创建任务
TASK_DIR=$(./.trellis/scripts/task.py create "新增用户登录" \
--slug user-login \ # 目录名后缀(可选,不写自动生成)
--assignee alice \ # 负责人(可选)
--priority P1 \ # 优先级:P0/P1/P2/P3(可选,默认 P2)
--description "实现 JWT 登录") # 描述(可选)
# 创建的目录:.trellis/tasks/02-27-user-login/
# 创建的文件:task.json
2.2.2 上下文配置
# sub-agent 平台上 implement.jsonl + check.jsonl 已在 task.py create 时
# seed 好了——每个文件起手一行自描述 {"_example": "..."},可保留也可删除。
# curate 条目:在编辑器里改 jsonl,或用 add-context:
./.trellis/scripts/task.py add-context "$TASK_DIR" implement \
".trellis/spec/backend/index.md" "后端开发指南"
./.trellis/scripts/task.py add-context "$TASK_DIR" check \
".trellis/spec/cli/unit-test/conventions.md" "单测约定"
# target:implement | check(自动补 .jsonl)
# path:文件或目录路径——add-context 自动识别,目录会 type="directory"
#
# jsonl 里放什么:任务相关的 spec 文件(.trellis/spec/**/*.md)和 research
# 文件($TASK_DIR/research/*.md)。不要放代码路径——代码在 Phase 2 实现时
# 读,不在这里预注册。
# 看有哪些 spec 可选
./.trellis/scripts/get_context.py --mode packages
# 可选:--package PACKAGE (monorepo 必填,选 spec/<pkg>/ 根)
# 追加额外的上下文条目
./.trellis/scripts/task.py add-context "$TASK_DIR" implement \
"src/services/auth.ts" "现有 auth 模式"
# file 参数:implement | check(简写,自动补 .jsonl)
# path 参数:文件 or 目录路径,add-context 自动识别目录并设 type="directory"
# 校验 implement.jsonl + check.jsonl 里引用的文件都存在
./.trellis/scripts/task.py validate "$TASK_DIR"
# 查看所有 JSONL 条目
./.trellis/scripts/task.py list-context "$TASK_DIR"
research.jsonl 不由 task.py add-context 管(由 trellis-research sub-agent
读)。add-context 只写 implement.jsonl / check.jsonl,要自定义 research 上下文手动编辑
research.jsonl 即可。
2.2.3 任务控制
# 设为当前 AI 会话/窗口的任务
# 写入 .trellis/.runtime/sessions/<session-key>.json
./.trellis/scripts/task.py start "$TASK_DIR"
# 清除当前 AI 会话/窗口的任务
./.trellis/scripts/task.py finish
# 设置 Git 分支名
./.trellis/scripts/task.py set-branch "$TASK_DIR" "feature/user-login"
# 设置 PR 目标分支
./.trellis/scripts/task.py set-base-branch "$TASK_DIR" "main"
# 设置 scope(用在 commit message:feat(scope): ...)
./.trellis/scripts/task.py set-scope "$TASK_DIR" "auth"
2.2.4 父子任务(subtasks)
一个任务可以有子任务。子任务是磁盘上独立的任务目录——有自己的 prd.md、JSONL 文件、status;父任务只是引用它们做分组。
# 方式 A:在父任务下直接建子任务
./.trellis/scripts/task.py create "JWT middleware" \
--slug jwt-middleware \
--parent 02-27-user-login
# 方式 B:把两个已有任务链起来
./.trellis/scripts/task.py add-subtask \
02-27-user-login \ # 父任务目录
02-28-jwt-middleware # 子任务目录
# 解除关联(不会删除任何任务)
./.trellis/scripts/task.py remove-subtask \
02-27-user-login 02-28-jwt-middleware
对 task.json 的影响:
- 父任务的
children: [<子任务目录名>, ...] 追加子任务名。
- 子任务的
parent: "<父任务目录名>" 被设置。
task.py list 把子任务缩进显示在父任务下面,同时打 [已完成/总数],方便一眼看进度。
父子关系走 parent 和 children 字段。task.json 里还有一个 subtasks
字段,和它们完全无关——subtasks 是单个任务内部的 todo checklist(name + status 对),主要由
bootstrap 任务使用。别混。
2.2.5 任务管理
# 列出活跃任务
./.trellis/scripts/task.py list
./.trellis/scripts/task.py list --mine # 只看自己的
./.trellis/scripts/task.py list --status review # 按状态过滤
# 归档完成的任务
./.trellis/scripts/task.py archive user-login
# 移动到 archive/2026-02/
# 列出归档任务
./.trellis/scripts/task.py list-archive
./.trellis/scripts/task.py list-archive 2026-02 # 按月过滤
2.3 task.json Schema
task.py create 当前实际写出的结构(详见 .trellis/scripts/common/task_store.py):
{
"id": "02-27-user-login",
"name": "user-login",
"title": "新增用户登录",
"description": "实现 JWT 登录流程",
"status": "planning",
"dev_type": null,
"scope": null,
"package": null,
"priority": "P1",
"creator": "alice",
"assignee": "alice",
"createdAt": "2026-02-27",
"completedAt": null,
"branch": null,
"base_branch": "main",
"worktree_path": null,
"commit": null,
"pr_url": null,
"subtasks": [],
"children": [],
"parent": null,
"relatedFiles": [],
"notes": "",
"meta": {}
}
字段会随任务进展被填上:
dev_type / scope / package → 通过 task.py set-scope 或直接编辑 task.json 写入;没有自动 setter
branch → task.py set-branch 设置
status → planning → in_progress → completed
completedAt → task.py archive 填上(archive 不回写 commit hash)
parent / children → task.py create --parent 或 add-subtask 设置
worktree_path / commit / pr_url 是 schema 占位字段,0.5 没有脚本主动写入。想记 commit 或 PR
URL,建议用 meta: {} 自定义键或写 after_archive hook 自己回写。
早期版本创建的任务可能少某些字段(如 package 支持前的任务没有 "package"),task.py 把缺失字段按 null 处理,不会出错。
状态流转:
task.py create → status: "planning"
task.py start → planning 自动改写成 in_progress(其他状态保留)
task.py archive → status: "completed" + 移到 archive/
planning / in_progress / completed 对应 workflow.md 的三个 Phase。task.py start 会自动把 planning 改写成 in_progress,其他状态不动(review 这类自定义状态重启不会被清零)。task.py list --status 还接受 review 作为过滤条件,如果你想要更多自定义状态,在 workflow.md 里加 [workflow-state:<name>] block 就行。
2.4 JSONL 上下文配置实战
2.4.1 create 时 seed,AI 在 Phase 1.3 curate
在 sub-agent 平台上,task.py create 会在两个 jsonl 里各写一行 seed:
# task.py create 刚跑完的 implement.jsonl
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line when done."}
这一行是给 AI 看的填写说明。它没有 file 字段,所有下游消费方(hook / prelude / validate / list-context)都会跳过,AI 读完就知道怎么填,在 Phase 1.3 把它替换成真实条目即可。
AI curate 之后的 implement.jsonl 样例(monorepo dev_type=backend):
{"file": ".trellis/spec/guides/index.md", "reason": "跨包思维指引"}
{"file": ".trellis/spec/cli/backend/index.md", "reason": "后端开发指南——本次改动涉及 Python 脚本"}
{"file": ".trellis/spec/cli/backend/script-conventions.md", "reason": "脚本规范"}
{"file": ".trellis/tasks/.../research/auth-library-comparison.md", "reason": "三方库选型依据"}
jsonl 该放什么:
- Spec 文件(
.trellis/spec/<pkg>/<layer>/index.md + 具体 guideline 文件):和任务相关的规范
- Research 文件(
{TASK_DIR}/research/*.md):sub-agent 要参考的调研产出
不该放什么:
- 代码文件(
src/**、packages/**/*.ts 等)——代码在 Phase 2 实现时读,不在这里预注册
- 即将要改的文件——同上
agent-less 平台(Kilo / Antigravity / Windsurf)上 task.py create 不 seed,改由 Phase 2.1 的 trellis-before-dev skill 加载 spec。
2.4.2 添加自定义上下文
# 把现有代码作为参考(文件)
./.trellis/scripts/task.py add-context "$TASK_DIR" implement \
"src/services/user.ts" "现有 user service 模式"
# 整个目录(自动读所有 .md)
./.trellis/scripts/task.py add-context "$TASK_DIR" implement \
"src/services/" "现有 service 模式"
# 自定义 check 上下文
./.trellis/scripts/task.py add-context "$TASK_DIR" check \
".trellis/spec/guides/cross-layer-thinking-guide.md" "跨层验证"
2.5 任务生命周期 Hook
你可以配置 shell 命令,在任务生命周期事件上自动跑。用于对接 Linear、发 Slack、触发 CI 等。
2.5.1 配置
在 .trellis/config.yaml 加 hooks 块:
hooks:
after_create:
- 'python3 .trellis/scripts/hooks/linear_sync.py create'
after_start:
- 'python3 .trellis/scripts/hooks/linear_sync.py start'
after_finish:
- "echo 'Task finished'"
after_archive:
- 'python3 .trellis/scripts/hooks/linear_sync.py archive'
默认 config.yaml 里 hooks 段是注释掉的。取消注释并编辑即可激活。
2.5.2 支持的事件
| 事件 | 触发时机 | 用途 |
|---|
after_create | task.py create 完成 | 在项目追踪工具里建 issue |
after_start | task.py start 设置当前会话任务 | 更新 issue 状态到 “In Progress” |
after_finish | task.py finish 清除当前会话任务 | 通知团队、触发 review |
after_archive | task.py archive 移动任务 | 标记 issue 为 “Done” |
2.5.3 环境变量
每个 hook 收到:
| 变量 | 值 |
|---|
TASK_JSON_PATH | 任务 task.json 的绝对路径 |
其他环境变量从父进程继承。
2.5.4 执行行为
- 工作目录:仓库根
- Shell:命令通过系统 shell 运行(
shell=True)
- 失败不阻断:失败的 hook 在 stderr 打印
[WARN],但不阻止任务操作完成
- 顺序:同一事件有多个 hook 按列表顺序执行;一个失败不跳过其他
- stdout 不显示:诊断输出用 stderr
after_archive hook 收到的 TASK_JSON_PATH 指向归档后位置(如
.trellis/tasks/archive/2026-03/task-name/task.json),不是原路径。
2.5.5 示例:Linear Sync Hook
Trellis 原生带有 .trellis/scripts/hooks/linear_sync.py 示例 hook,把任务生命周期事件同步到 Linear。
行为:
| 操作 | 触发 | 效果 |
|---|
create | after_create | 从 task.json 建 Linear issue(title、priority、assignee、parent) |
start | after_start | 把关联 issue 更新到 “In Progress” |
archive | after_archive | 把关联 issue 更新到 “Done” |
sync | 手动 | 把 prd.md 内容推到 Linear issue 描述 |
前置:
- 装
linearis CLI 并设置 LINEAR_API_KEY
- 创建
.trellis/hooks.local.json(gitignored)放团队配置:
{
"linear": {
"team": "ENG",
"project": "我的项目",
"assignees": {
"alice": "linear-user-id-for-alice"
}
}
}
Hook 把 Linear issue id 写回 task.json 的 meta.linear_issue(如 "ENG-123"),保证后续事件幂等。
3. 规范编写指南
3.1 Spec 目录结构和分层
3.1.1 trellis init 默认结构
trellis init 会写一个骨架:frontend/ + backend/ + guides/,里面全是空占位模板(标注 “(To be filled by the team)”)。这些模板原样注入 sub-agent 是没用的。
.trellis/spec/
├── frontend/ # 前端规范(占位)
│ ├── index.md # 索引:列出所有规范及状态
│ ├── component-guidelines.md # 组件规范
│ ├── hook-guidelines.md # Hook 规范
│ ├── state-management.md # 状态管理
│ ├── type-safety.md # 类型安全
│ ├── quality-guidelines.md # 质量指南
│ └── directory-structure.md # 目录结构
│
├── backend/ # 后端规范(占位)
│ ├── index.md
│ ├── database-guidelines.md
│ ├── error-handling.md
│ ├── logging-guidelines.md
│ ├── quality-guidelines.md
│ └── directory-structure.md
│
└── guides/ # 思维指南
├── index.md
├── cross-layer-thinking-guide.md
└── code-reuse-thinking-guide.md
trellis init 同时创建一个 bootstrap 任务(00-bootstrap-guidelines)。第一次 Trellis 会话里,AI 会认出它、调 trellis-research 读你的实际代码,然后把占位模板按真实项目(技术栈、约定、目录结构)填起来。跳过这个任务就是把空壳喂给每个 sub-agent——别跳。
3.1.2 这套结构只是约定
frontend/ 和 backend/ 没有任何魔法。Trellis 扫描 .trellis/spec/ 下的一级目录,只要目录里有 index.md 就把它当作一个 spec 层注册。你按项目实际怎么切就怎么命名——按运行时、按 package、按职责都行,每层有自己的 index.md 就够。
Trellis 本身用的是另一种结构(monorepo、按 package):
.trellis/spec/ # Trellis 自己的 spec 树
├── cli/ # Package: CLI
│ ├── backend/
│ │ └── index.md # ← 通过 index.md 注册为一层
│ └── unit-test/
│ └── index.md # ← 又一层
│
├── docs-site/ # Package: 文档站
│ └── docs/
│ └── index.md # ← 单层 package
│
└── guides/ # 跨 package 的思维指南
├── index.md
├── cross-layer-thinking-guide.md
├── cross-platform-thinking-guide.md
└── code-reuse-thinking-guide.md
顶层没有 frontend/ 或 backend/,因为仓库是按 package 切的。Trellis 唯一硬性约定就是”一层 = 带 index.md 的目录”,其他随你。
3.2 从空模板到完整规范
trellis init 会生成空模板,标记 “(To be filled by the team)“。填充步骤:
Step 1:从实际代码中提取模式
# 看看现有代码是怎么组织的
ls src/components/ # 组件结构
ls src/services/ # 服务结构
Step 2:写下你的约定
# Component Guidelines
## File Structure
- One component per file
- Use PascalCase for filenames: `UserProfile.tsx`
- Co-locate styles: `UserProfile.module.css`
- Co-locate tests: `UserProfile.test.tsx`
## Patterns
#### Required
- Functional components + hooks (no class components)
- TypeScript with explicit Props interface
- `export default` for page components, named export for shared
#### Forbidden
- No `any` type in Props
- No inline styles (use CSS Modules)
- No direct DOM manipulation
Step 3:添加代码示例
#### Good Example
```tsx
interface UserProfileProps {
userId: string;
onUpdate: (user: User) => void;
}
export function UserProfile({ userId, onUpdate }: UserProfileProps) {
// ...
}
```
#### Bad Example
```tsx
// Don't: no Props interface, using any
export default function UserProfile(props: any) {
// ...
}
```
Step 4:更新 index.md 状态
| Guideline | File | Status |
| -------------------- | ----------------------- | ---------- |
| Component Guidelines | component-guidelines.md | **Filled** |
| Hook Guidelines | hook-guidelines.md | To fill |
3.3 Spec 应该长什么样
trellis-update-spec skill 把 spec 当作可执行契约写,不是原则性文字。sub-agent 在 trellis-implement / trellis-check 时读到的每条都要能告诉它 怎样安全地实现——具体签名、契约、用例、测试。如果你写的只是”动手前该想到什么”,那东西属于 guides/。
3.3.1 Code-Spec vs Guide
| 类型 | 位置 | 用途 | 内容形态 |
|---|
| Code-Spec | <layer>/*.md(如 backend/、cli/backend/) | “如何安全地实现” | 签名、契约、验证矩阵、Good / Base / Bad 用例、必需测试 |
| Guide | guides/*.md | ”动手前该想到什么” | 思考清单、问题、指向具体 spec 的链接 |
如果你写的是”别忘了检查 X”——放 guide。如果你写的是”X 接受 {field: type, …},返回 {…},错误矩阵如下,必须覆盖这些测试”——放 code-spec。
3.3.2 选对更新形态
trellis-update-spec 原生带有几套模板,按你学到的是什么挑一个:
| 你学到了…… | 模板 | 关键字段 |
|---|
| 为什么选方案 X 而不是 Y | Design Decision | Context、Options Considered、Decision、Example、Extensibility |
| 本项目约定 X 这么做 | Convention | What、Why、Example、Related |
| 一种能复用的解法 | Pattern | Problem、Solution、Example(Good + Bad)、Why |
| 一种会出问题的做法 | Forbidden Pattern(Don't) | 错误片段、为什么糟、改成什么 |
| 容易犯的错 | Common Mistake | Symptom、Cause、Fix、Prevention |
| 非直觉的行为 | Gotcha | > Warning: 引用块,说明何时触发、怎么处理 |
3.3.3 基础设施 / 跨层改动的强制 7 段式
改动涉及 命令 / API 签名、跨层 request-response 契约、DB schema、或 基础设施接线(存储、队列、缓存、密钥、env)时,skill 强制 7 段:
- Scope / Trigger — 为什么要上 code-spec 深度
- Signatures — command / API / DB 签名
- Contracts — request 字段、response 字段、env key(名字、类型、约束)
- Validation & Error Matrix —
<条件> → <错误> 表
- Good / Base / Bad Cases — 例输入 + 预期结果
- Tests Required — unit / integration / e2e,带断言点
- Wrong vs Correct — 至少一组反正例
少一段 skill 会提示补;这就是”可执行契约”的底线。
3.3.4 对比示例
一条合格的 Convention(放在 backend/database-guidelines.md):
#### Convention:用 ORM batch 方法,别在循环里一条一条写 DB
**What**:对 N 条数据,调一次 ORM 的 batch 方法(`createMany` / `updateMany` / `deleteMany`)。不要把单行 `create` / `update` / `delete` 套进 `for` 或 `Promise.all`。
**Why**:每次 DB 调用都是一次 round-trip。线上接口里一个 200 条的循环就能把 p99 从 50ms 悄悄拖到 8s——这种坑已经在 code review 里抓到过两次(PR #312、#417)。Batch 方法把 N 次 round-trip 压成一次 SQL,DB 可以自己规划写入。
**Example**:
```ts
// ✅ 正确——一次 round-trip
await prisma.user.createMany({ data: users });
// ❌ 错误——N 次 round-trip
for (const user of users) {
await prisma.user.create({ data: user });
}
// ❌ 还是错——并发的 N 次 round-trip
await Promise.all(users.map((user) => prisma.user.create({ data: user })));
```
**Batch 不可用时**:把循环包进单事务(`prisma.$transaction`),至少是一个逻辑单元;加注释说明为什么 batch 用不了。
**Related**:`quality-guidelines.md#performance`、`error-handling.md#transactions`。
一条差的 spec——没签名、没示例、没 why、没测试点:
#### Database
- Use good query patterns
- Be careful with SQL
- Follow best practices
一条过度规范——机械规则、没有原因、扼杀判断:
#### Variable Naming
- All boolean variables must start with `is` or `has`
- All arrays must end with `List`
- All functions must be less than 20 lines
- All files must be less than 200 lines
底线:具体、可操作、带代码示例、说清 why;对 code-spec 而言,还要有足够的签名 / 契约细节让 sub-agent 不用追问就能照做。
3.4 Bootstrap 引导首次填充
trellis init 会同时建一个 bootstrap 任务(00-bootstrap-guidelines)。第一次 Trellis 会话里,AI 会认出它,调 trellis-research 扫一遍你的代码,然后把 frontend/ / backend/ / guides/ 下那堆空模板按你的真实项目填起来——技术栈、约定、目录结构都从代码里读出来。