From 6e0c5c35fc7b3f173878484742f32be845dff8b8 Mon Sep 17 00:00:00 2001 From: yuxuanhui Date: Mon, 3 Aug 2026 16:17:16 +0800 Subject: [PATCH] Add documentation for the three-stage development workflow and CLI management strategy; create a new notes file for additional insights. --- .obsidian/workspace.json | 28 +- AGENTS.md.md | 1 + ...0260725-extend-tracker-skill-additively.md | 84 ++ .../20260725-feishu-cli-base-wiki-tracker.md | 96 +++ ...3-usercenter-react-directory-convention.md | 129 +++ .../40-workflows/trellis-matt/CN/AGENTS.md | 6 +- .../40-workflows/trellis-matt/CN/workflow.md | 48 +- .../40-workflows/trellis-matt/EN/AGENTS.md | 7 +- .../40-workflows/trellis-matt/EN/workflow.md | 48 +- docs/Matt 工作流 × 飞书 CLI 全流程总结.md | 520 ++++++++++++ ...µ� × 飞书 Skills × Trellis Coding 闭环总结.md | 759 +++++++++++++++++ docs/Trellis × 飞书实现闭环初步方案.md | 763 ++++++++++++++++++ ...˜¶段研发工作流产物链路与飞书 CLI 管理方案.md | 694 ++++++++++++++++ notes/工作流整理.md | 0 14 files changed, 3122 insertions(+), 61 deletions(-) create mode 100644 AI Coding/inbox/20260725-extend-tracker-skill-additively.md create mode 100644 AI Coding/inbox/20260725-feishu-cli-base-wiki-tracker.md create mode 100644 AI Coding/inbox/20260803-usercenter-react-directory-convention.md create mode 100644 docs/Matt 工作流 × 飞书 CLI 全流程总结.md create mode 100644 docs/Matt 工作流 × 飞书 Skills × Trellis Coding 闭环总结.md create mode 100644 docs/Trellis × 飞书实现闭环初步方案.md create mode 100644 docs/三阶段研发工作流产物链路与飞书 CLI 管理方案.md create mode 100644 notes/工作流整理.md diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index 69ecc44..dcf27e8 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -8,17 +8,17 @@ "type": "tabs", "children": [ { - "id": "06ba3753fa958e03", + "id": "8b8d7a02c4ac5b2d", "type": "leaf", "state": { "type": "markdown", "state": { - "file": "AI-RD-Workflow/40-workflows/ai-development-workflow.md", + "file": "notes/工作流整理.md", "mode": "source", "source": false }, "icon": "lucide-file", - "title": "ai-development-workflow" + "title": "工作流整理" } } ] @@ -180,9 +180,19 @@ "bases:新建数据库": false } }, - "active": "81dfd388c3bb5590", + "active": "8b8d7a02c4ac5b2d", "lastOpenFiles": [ + "docs/Matt 工作流 × 飞书 CLI 全流程总结.md", + "notes/工作流整理.md", + "AGENTS.md.md", + "TODO.md.md", + "docs/Matt 工作流 × 飞书 Skills × Trellis Coding 闭环总结.md", + "docs/三阶段研发工作流产物链路与飞书 CLI 管理方案.md", "docs/MonoProxy订阅信息获取工作流.md", + "docs/MidScene 配置.md", + "docs/Trellis × 飞书实现闭环初步方案.md", + "AI-RD-Workflow/index.md", + "AI-RD-Workflow/40-workflows/ai-development-workflow.md", "AI-RD-Workflow/40-workflows/pm-workflow.md", "AI-RD-Workflow/40-workflows/rd-workflow.md", "AI-RD-Workflow/40-workflows/se-workflow.md", @@ -199,16 +209,6 @@ "AI-RD-Workflow/10-standards/lifecycle.md", "AI-RD-Workflow/00-meta/roadmap.md", "AI-RD-Workflow/30-templates/intake.md", - "AI-RD-Workflow/30-templates/ds.md", - "AI-RD-Workflow/30-templates/dr.md", - "AI Coding/inbox/20260627-cloud-runtime-project-root.md", - "AI Coding/inbox/20260715-codegraph-before-impact-analysis.md", - "AI Coding/inbox/20260715-codegraph-first-for-cross-file-analysis.md", - "AI Coding/inbox/20260625-central-compounding-brain.md", - "AI Coding/inbox/index.md", - "docs/MidScene 配置.md", - "AI Coding/assets/index.md", - "AI Coding/learnings/index.md", "docs", "notes", "projects", diff --git a/AGENTS.md.md b/AGENTS.md.md index 70706ce..4426577 100644 --- a/AGENTS.md.md +++ b/AGENTS.md.md @@ -3,3 +3,4 @@ - 准确地把待办事项、人员、项目、每日总结和草稿分类放好。 - 把做过的决定、遇到的卡点、负责人、日期和有用的链接好好保存下来。 - 如果没有什么实质性的新进展,不要随意修改知识库里的文件。 +- \ No newline at end of file diff --git a/AI Coding/inbox/20260725-extend-tracker-skill-additively.md b/AI Coding/inbox/20260725-extend-tracker-skill-additively.md new file mode 100644 index 0000000..945f576 --- /dev/null +++ b/AI Coding/inbox/20260725-extend-tracker-skill-additively.md @@ -0,0 +1,84 @@ +--- +id: 20260725-extend-tracker-skill-additively +title: 扩展 Issue Tracker Skill 时保留完整基线并做最小增量 +created: 2026-07-25 +updated: 2026-07-25 +status: validated +scope: global +category: skill-design +confidence: high +last_verified: 2026-07-25 +promotion_target: none +projects: + - matt-pocock-skills-feishu +tags: + - skill + - issue-tracker + - progressive-disclosure + - regression-prevention +--- + +# 扩展 Issue Tracker Skill 时保留完整基线并做最小增量 + +## Trigger + +当用户要求“在现有 setup skill 基础上增加一个 tracker/provider 选项”,并期望新 skill 保留原工作流和原模板行为时,召回这条经验。 + +## Context + +第一次实现把飞书版 skill 写成了一个压缩后的独立工作流,并通过相邻路径引用原 setup skill。它在概念上覆盖了原流程,但没有完整保留原 `SKILL.md` 的文字约束和五个 seed 文件。用户明确纠正:新 skill 应先完整对齐原 Matt skill,再增加 `references/issue-tracker-feishu.md`,并把原来的三个正式 tracker 模板扩展为第四个飞书选项。 + +最终实现以原 skill 整个目录为基线,保持 GitHub、GitLab、local、triage labels 和 domain 模板不变,仅在 `SKILL.md` 的 tracker 介绍、选择、确认、写入和完成验证处加入飞书条件分支,并把飞书细节放入一层 reference。 + +同日的第二个扩展场景把该原则应用到三个运行期 skill:`to-spec-feishu`、`to-tickets-feishu`、`triage-feishu`。每个新 skill 以对应原 Matt skill 的完整正文为基线,只增加一条必须读取 `references/feishu.md` 的接缝;`triage` 的 `AGENT-BRIEF.md` 和 `OUT-OF-SCOPE.md` 保持逐字节一致。飞书的发布顺序、查重、两遍关系写入、时间门禁和 Wiki 降级策略全部留在 reference 中。 + +## Evidence + +- 用户在 2026-07-25 两次指出结构要求:保留 `issue-tracker-feishu.md`;新 skill 必须完整对齐 `/Users/yuxuanhui/.agents/skills/setup-matt-pocock-skills` 后再补充飞书。 +- 最终目录中的 `issue-tracker-github.md`、`issue-tracker-gitlab.md`、`issue-tracker-local.md`、`triage-labels.md`、`domain.md` 与原 skill 逐字节一致。 +- `SKILL.md` 的 diff 只包含名称/描述兼容调整和飞书在 Section A、确认、模板、完成验证中的增量。 +- `quick_validate.py` 输出 `Skill is valid!`,且目录无 `TODO` 占位符。 +- 原 skill 使用的旧 frontmatter 字段 `disable-model-invocation` 被当前 validator 拒绝;新 skill 通过 `agents/openai.yaml` 的 `policy.allow_implicit_invocation: false` 保留等价行为。 +- `to-spec-feishu`、`to-tickets-feishu`、`triage-feishu` 均通过 `quick_validate.py`,无 `TODO`;三个 `agents/openai.yaml` 均显式禁止隐式调用。 +- 三个原 Matt skills 未修改;新 skill 主正文只新增飞书 reference 读取接缝,原有交互门禁、测试 seam、拆票确认和分诊角色语义保留。 +- `triage-feishu/AGENT-BRIEF.md` 与原文件、`triage-feishu/OUT-OF-SCOPE.md` 与原文件分别通过字节级比较。 +- 真实 POC 验证 reference 不是静态说明:Spec 发布、Ticket 两遍关系写入、Triage `needs-info → feedback → ready-for-agent` 均按新 reference 执行并回读;独立 Wiki 新建受平台限制时,降级和未满足项也按 reference 记录。 + +## Root cause + +已验证:把“在原 skill 基础上增加”理解为“运行时引用原 skill 并重写一个更短版本”,会丢失用户期望的文本级约束、配套模板和可独立运行性。概念等价不等于产物级对齐。 + +推断:tracker 是一个可变适配点,但 setup 的探索、交互顺序、文件选择和消费者契约属于稳定基线。若同时重写两者,未来很难区分是 provider 变化还是基础流程回归。 + +已验证:同一“完整基线 + 单一 provider 接缝 + provider reference”结构不仅适用于 setup,也适用于依赖 tracker 的运行期 skills。这样可以分别验证 Matt 核心语义和外部系统副作用,而不把 CLI 细节散落到主流程。 + +## Failed approaches + +- 将飞书操作链全部塞进主 `SKILL.md`:主文件偏离原 setup,且 provider 细节挤占上下文。 +- 让新 skill 只读取相邻原 skill:减少了重复,但不满足用户要求的完整基线和独立配套资源。 +- 手工重述原流程:即使语义接近,也会产生措辞、边界和模板缺失。 + +## Preferred action + +1. 先复制原 skill 的完整目录作为新 skill 基线,包括主文件和全部 seed/template 文件。 +2. 对不属于新 skill 身份的 metadata 做最小兼容调整;若旧字段被当前 validator 拒绝,用当前受支持的等价配置替代并记录原因。 +3. 只在明确的变体接缝增加 provider:选项列表、provider 输入、写前草稿、模板路由和 provider 专属完成门槛。 +4. 把长篇 CLI 命令、schema、状态机、已知版本边界放进 `references/.md`;在 `SKILL.md` 中明确何时必须完整读取它。 +5. 保留 `Other` 作为自由格式兜底,不把它误算为正式模板。原三个正式模板加飞书等于四个受支持模板。 +6. 用三类检查防止回归: + - `diff`:确认主 skill 只改了预期接缝; + - `cmp`:确认原 seed 文件逐字节一致; + - `quick_validate.py` 与占位符搜索:确认结构有效且无残留模板内容。 +7. 对带附属模板的 skill,再对每个模板做字节级比较;不要只比较 `SKILL.md`。 +8. 用一个最小真实 POC 验证 reference 中的外部副作用顺序。校验器通过只能证明结构有效,不能证明 provider 工作流可运行。 + +## Boundaries + +- 当用户明确接受依赖式组合、且基线 skill 会持续独立升级时,可以只引用基线 skill;不要默认复制。 +- 当 provider 需要改变基础探索、交互顺序或消费者语义时,不能强行维持最小 diff,应先确认这是新工作流还是原工作流的变体。 +- 不要为了“完整对齐”复制当前校验器明确拒绝的旧 metadata;应保留行为等价性并记录兼容差异。 +- provider reference 可以定义外部系统的失败降级,但不能削弱原 skill 的用户确认门禁,也不能把未完成的外部产物描述为成功。 + +## Promotion record + +- Not promoted. 该原则已在 setup 与三个运行期 tracker skills 两类场景落地并通过真实 POC,学习状态提升为 validated;尚未扩展第二种 provider,因此暂不写入全局 skill-creator guardrail。 diff --git a/AI Coding/inbox/20260725-feishu-cli-base-wiki-tracker.md b/AI Coding/inbox/20260725-feishu-cli-base-wiki-tracker.md new file mode 100644 index 0000000..9fafbdf --- /dev/null +++ b/AI Coding/inbox/20260725-feishu-cli-base-wiki-tracker.md @@ -0,0 +1,96 @@ +--- +id: 20260725-feishu-cli-base-wiki-tracker +title: 用飞书 CLI 将 Base 与 Wiki 组合为可验证的 Issue Tracker +created: 2026-07-25 +updated: 2026-07-25 +status: validated +scope: global +category: workflow +confidence: high +last_verified: 2026-07-25 +promotion_target: none +projects: + - matt-pocock-skills-feishu +tags: + - feishu + - lark-cli + - issue-tracker + - base + - wiki +--- + +# 用飞书 CLI 将 Base 与 Wiki 组合为可验证的 Issue Tracker + +## Trigger + +当工作流要用飞书多维表格管理 Issue、任务或产物状态,同时用飞书知识库承载 PRD、Spec、Map、研究、诊断、ADR 等长文档时,召回这条经验。 + +## Context + +两轮真实 POC 使用 `lark-cli` 连接同一 Base 表格和 Wiki 根节点。第一轮完成 setup、字段骨架、工作流文档和单条验收记录;第二轮分别运行 Spec、Ticket 依赖图和 Triage 时间状态机。关键不是“命令返回成功”,而是形成从身份验证、资源解析、增量写入到逐层回读的闭环,并保留平台限制导致的降级证据。 + +Base 适合保存一行一个产物及其可查询状态;Wiki/Docs 适合保存长文本。两者通过 Base 中的规范文档链接字段关联。CLI 命令和资源坐标可以进入工作流文档,但凭证、访问令牌和不必要的组织数据不能进入知识库。 + +## Evidence + +- 2026-07-25,在 `lark-cli 1.0.76` 上完成用户身份验证、Base URL 解析、表/视图/字段回读和 Wiki 根节点解析。 +- 在不删除或转换原字段的前提下,将目标表验证为共 23 个字段,包含状态、类型、负责人、进度、证据、父项和依赖等工作流字段。 +- 创建并分段追加 Wiki Docx,最终回读 revision 6,确认写入内容可取回。 +- 创建 Base POC 记录并用真实 record ID 回读,确认标题、文档链接、状态、完成度、验收标准和验证证据。 +- 执行经验固化位置:`/Users/yuxuanhui/.agents/skills/setup-matt-pocock-skills-feishu/references/issue-tracker-feishu.md`。 +- 已省略实际 Base/Wiki URL、token、record ID 和组织信息;这些值只属于目标环境,不属于通用经验。 +- 第二轮将原文本字段原地重命名为“产物文档”,保持同一 field ID、`text/plain` 类型和既有链接值;新增来源链接、外部编号、报告人、最后反馈时间、最后分诊时间后,完整字段回读为 28。 +- 第二轮创建并回读 1 条 Spec、2 条 Ticket 和 1 条 Issue;Ticket 采用“两遍写入”,先建所有记录,再写父项和 blocker,逐条确认链接字段。 +- Triage POC 保存 `needs-info` 阶段的时间快照,完整 `record-list` 返回 `has_more=false`,证明报告人反馈晚于上一轮分诊;随后发布 Agent Brief,并把最终再分诊时间推进到反馈之后。 +- 并行执行同一 Base 的四个 `record-search` 时,三个请求返回 `800004135 OpenAPISearchRecord limited`;改为串行查询或一次完整 `record-list` 后客户端分组。 +- `wiki +node-create` 返回 `131001 rpc fail`;`docs +create`(含正文与空文档两种)均返回 `10071 Document version limit reached`。搜索确认没有孤儿文档后,在已获授权的既有 Wiki 文档中追加独立 Spec/Triage 章节并回读,且明确记录该降级不等同于“新文档创建成功”。 + +## Root cause + +已验证:飞书 CLI 集成最容易出现的可靠性缺口不是单条 API 调用,而是把“命令成功”误当成“工作流已配置”。若没有先解析真实资源、只创建缺失字段、搜索业务键防重、使用 ID 回读记录,并 fetch Wiki 文档,最终状态可能与预期不一致。 + +已验证:`+record-upsert` 不应被当作按业务标题自动去重。创建前必须搜索真实主字段;更新必须使用真实 record ID。 + +已验证:在 `lark-cli 1.0.76` 中,同表双向链接可能返回未独立出现在字段列表中的反向 ID。自动化应以正向 `所属父项` 和 `前置依赖` 为事实来源,除非当前版本回读证明反向字段可单独操作。 + +已验证:同一 Base 上并行发起多次 `record-search` 会触发搜索接口限流。查重和队列读取默认串行;小表可以一次完整分页读取后在客户端精确匹配,但必须检查 `has_more`。 + +已验证:Wiki 节点创建失败与 Docs 文档创建配额/版本限制是两个不同失败层。只有 `docs +create` 成功后才能尝试 `wiki +move`;若创建本身返回 10071,不应删除用户文档或宣称已创建,只能在授权范围内使用既有文档章节降级,或请求管理员解除限制。 + +## Preferred action + +按以下顺序配置和验收: + +1. 用 `lark-cli auth status --json --verify` 验证用户身份,不在文档中保存凭证。 +2. 从用户给出的 Base table/view URL 和 Wiki root URL 解析真实 Base token、table ID、view ID、主字段、space ID、node token 和对象类型;不要按名称猜资源。 +3. 在写入前完整读取 Base、table、view 和 field list,计算“仅缺失字段”的增量草稿,并让用户确认外部写入范围。 +4. 串行执行 `base +field-create --json ...`。遵循每次响应中的 `field_get_recommended` 和 `next_step`,最后重新读取完整 field list。已明确授权的字段改名先用完整字段定义 `field-update --dry-run`,再以 `--yes` 写入,最后同时回读字段 ID、类型和既有单元格值。 +5. 用 `wiki +node-create` 在已解析根节点下创建空白 Docx;失败时可以尝试 `docs +create` 后 `wiki +move`。若 `docs +create` 返回文档限制错误,停止创建路径,不做清理;只有既有文档更新也在授权范围内时,才使用独立章节降级。写入后用 `docs +fetch --detail with-ids` 回读内容和 revision,不对已有文档使用 `overwrite`。 +6. 创建 Base 记录前,按真实主字段串行精确搜索标题。零个匹配才创建;已有记录只用真实 record ID 更新。小表改用完整 `record-list` 时必须分页到底并在客户端精确比较,不能把“第一页无匹配”当作不存在。 +7. 关系图采用两遍写入:第一遍创建所有节点,第二遍使用真实 record ID 写父项和依赖,最后逐条 `record-get` 验证边。Triage 时间比较保留“反馈前的最后分诊时间”快照,最终处理后再更新最后分诊时间。 +8. 创建关联 Wiki 文档的 POC 记录,包含明确验收标准和验证证据,再用 `record-get` 回读关键字段。身份字段无法可靠表达时留空并报告,不伪造用户值。 +9. 只有在身份、资源、字段、Wiki 内容、POC 记录和生成的 repo 配置全部回读成功后,才宣布对应部分完成。验证被阻塞或使用降级时明确写出未满足项和原因。 +10. 将实际执行过的命令写入 Wiki 工作流文档,删除凭证;保留有诊断价值的失败命令及修正版本。 + +建议使用的命令族: + +```text +lark-cli auth status --json --verify +lark-cli base +url-resolve / +base-get / +table-get / +view-get / +field-list +lark-cli base +field-create / +field-get +lark-cli wiki +node-get / +node-create +lark-cli docs +update / +fetch +lark-cli base +record-search / +record-upsert / +record-get +``` + +## Boundaries + +- 这条经验适用于 Base 作为结构化状态表、Wiki/Docs 作为长文档库的组合,不等同于飞书审批、项目或任务产品的通用集成方案。 +- 字段 JSON、用户字段值、链接字段属性和命令参数必须以当前安装版本的 skill reference、`lark-cli --help` 和当前文档为准。 +- 资源 token 和 ID 可能不是凭证,但仍应按最小披露原则处理;中央知识库只保留通用证据。 +- 外部写入、删除、覆盖、权限调整和发布仍需遵守当前授权边界。 +- “既有 Wiki 文档中的独立章节”能验证 Docs 写入和 Base 链接,但不能替代“成功新建独立 Wiki 文档”的验收证据。 + +## Promotion record + +- Not promoted. Setup POC 与 Spec/Ticket/Triage POC 已提供两轮独立流程证据,学习状态提升为 validated;仍未跨第二个 Base/租户验证,因此暂不提升为全局执行规则。 diff --git a/AI Coding/inbox/20260803-usercenter-react-directory-convention.md b/AI Coding/inbox/20260803-usercenter-react-directory-convention.md new file mode 100644 index 0000000..3f031fd --- /dev/null +++ b/AI Coding/inbox/20260803-usercenter-react-directory-convention.md @@ -0,0 +1,129 @@ +--- +id: 20260803-usercenter-react-directory-convention +title: React 管理后台按应用组装、路由、业务切片与共享能力分目录 +created: 2026-08-03 +updated: 2026-08-03 +status: candidate +scope: repository +category: frontend-architecture +confidence: high +last_verified: 2026-08-03 +promotion_target: none +projects: + - usercenter-react +tags: + - react + - directory-structure + - feature-module + - module-boundary + - admin-scaffold + - tanstack-query + - zustand + - server-state + - client-state +--- + +# React 管理后台按应用组装、路由、业务切片与共享能力分目录 + +## Trigger + +在 `usercenter-react` 中新增、生成或移动 React 页面、业务模块、路由、请求、表单、表格或跨业务组件,需要判断文件应放在 `src/app`、`src/routes`、`src/features`、`src/pages`、`src/shared` 还是 `src/styles`;或者发现业务代码开始散落在顶层 `pages`、通用 `components` 和请求工具中。 + +## Context + +这个项目的目录结构不是按 React 文件类型全局分组,而是先区分应用组装、路由、业务切片和横向共享能力,再在每个业务切片内按 API、组件、页面、Schema 和资源规格分层。这样既让单个业务模块的改动保持局部化,也让路由、权限、表格、表单、认证和国际化等公共契约有明确归属,并允许资源校验器检查生成式 CRUD 模块的完整性。 + +当前约定的核心结构是: + +```txt +src/ +├── app/ # 应用组装:Providers、QueryClient、Router 实例、Route Catalog +├── routes/ # 手写路由树、路由元数据类型与路由副作用 +├── features// # 业务垂直切片 +│ ├── api/ +│ ├── components/ +│ ├── pages/ +│ ├── schemas/ +│ └── specs/ +├── pages/ # 非资源型系统页、设置页和可运行示例页 +├── shared/ # 跨业务复用的技术能力与业务无关 UI 组合 +├── styles/ # 全局 reset、tokens 和全局样式入口 +└── main.tsx # 浏览器入口,只负责全局样式/运行时初始化和挂载 App +``` + +状态与请求管理遵循“服务端状态和客户端 UI 状态分离”的技术栈: + +- `@tanstack/react-query ^5.90.12` 管理服务端状态,包括查询缓存、loading/error 状态、mutation、缓存更新与失效。全局 `QueryClient` 位于 `src/app/query-client.ts`,具体 query 和 mutation hooks 位于各 feature 的 `api/` 目录。 +- `zustand ^5.0.9` 管理不来自服务端的全局 UI 状态。当前 `src/shared/config/ui-store.ts` 负责主题、语言、侧边栏折叠和命令面板开关,并按需要同步到 `localStorage` 或 i18next。 +- 请求链保持 `page/component -> TanStack Query hook -> typed feature API adapter -> shared request helper -> native fetch`。JSON、二进制下载和 multipart 上传分别通过 `requestJson`、`requestBlob`、`requestMultipart` 进入统一传输边界,页面和组件不直接发送 HTTP 请求。 + +## Evidence + +- 2026-08-03:检查 `usercenter-react` 当前项目文档、`src` 目录、导入关系、资源校验器和 CodeGraph 索引;中央知识库搜索“React 目录 / feature module / src/features / module boundary”未发现同根因条目。 +- `usercenter-react/AGENTS.md:18-26`:明确应用代码只放在 `src`,路由使用手写 TanStack Router 路由树和 Route Catalog,服务端状态使用 TanStack Query 与 feature API adapter,共享 CRUD 模式放在共享层,运行时 AI 与根目录 `specs/`、`skills/` 分离。 +- `usercenter-react/specs/feature-module.spec.md:3-15`:明确业务模块位于 `src/features/`,标准子目录为 `api/`、`components/`、`pages/`、`schemas/`、`specs/`,表格、表单、权限、认证、i18n 和布局等共享能力位于 feature 外部。 +- `usercenter-react/specs/api.spec.md:3-14`:定义 `page/component -> query or mutation hook -> typed feature API -> mock or real adapter` 数据访问链,并禁止组件直接访问 `fetch`、`axios` 或 mock store。 +- `usercenter-react/specs/route.spec.md:3-11`、`src/app/router.tsx`、`src/routes/route-tree.tsx`:路由实例和路由树分离;路由树负责懒加载 `src/pages` 的系统页与 `src/features/*/pages` 的业务页,元数据不放进页面组件。 +- `usercenter-react/src/main.tsx:1-20`:入口仅加载 Semi React 19 适配、全局样式、i18n,并挂载 `src/app/app.tsx`,没有承载业务逻辑。 +- `usercenter-react/src/features/products`:完整 CRUD 样例按 API、组件、页面、Schema 和资源规格垂直聚合;文件名使用 `.api.ts`、`.query.ts`、`.mutation.ts`、`.types.ts`、`.schema.ts`、`-page.tsx`、`-table.tsx` 等职责后缀。 +- `usercenter-react/src/features/market-management`:在标准目录之外按业务需要增加 `policies/` 和 `routes/`,说明标准结构是稳定基线,不是禁止扩展的封闭清单。 +- `usercenter-react/src/shared`:按 `api`、`auth`、`config`、`form`、`i18n`、`layout`、`list-templates`、`menu`、`permission`、`table`、`utils` 等横向能力组织,不按具体资源命名。 +- `usercenter-react/package.json:22,35`:服务端状态依赖为 `@tanstack/react-query ^5.90.12`,客户端状态依赖为 `zustand ^5.0.9`。 +- `usercenter-react/src/app/query-client.ts` 与 `src/app/providers.tsx`:应用集中创建并注入 QueryClient;默认 query 配置包含 `staleTime: 30_000`、`retry: 1` 和 `refetchOnWindowFocus: false`。 +- `usercenter-react/src/features/products/api/products.query.ts`、`products.mutation.ts`:feature 使用 `useQuery`、`useMutation` 和 `useQueryClient` 管理读取、提交、详情缓存更新与列表缓存失效。 +- `usercenter-react/src/shared/config/ui-store.ts`:使用 Zustand 集中管理主题、语言、侧边栏折叠和命令面板状态;这些状态不进入 TanStack Query 缓存。 +- `usercenter-react/src/shared/api/json-request.ts`、`binary-request.ts`:共享请求层基于原生 `fetch` 封装 JSON、Blob 和 multipart 请求;feature API adapter 使用这些请求 helper,而不是让页面或组件直接访问传输层。 +- `usercenter-react/tsconfig.json:18-21` 与 `vite.config.ts`:`@/*` 统一映射到 `src/*`,源码使用稳定的根路径导入,避免跨目录相对路径漂移。 +- `usercenter-react/packages/registry/src/resource-module-verifier.mjs:37-65`:生成式资源模块校验器会定位 `src/features/`,并检查 API adapter、类型、mock、query/mutation hooks、Schema、表格、表单、详情组件、CRUD 页面和资源规格的文件职责与命名。 +- 2026-08-03 运行 `pnpm validate:resources`:`products.resource.json` Schema 校验和 `src/features/products` 模块结构验证均通过。 +- 2026-08-03 运行 `codegraph status`:索引覆盖 131 个文件、1491 个节点和 3631 条边,但存在 1 个 pending modified file;因此目录结论以当前源码和规范直接检查为准,没有把未同步图谱当成唯一证据。 + +## Root cause + +已验证:项目同时服务人工开发和 AI 生成,需要让业务模块的输入规格、类型、数据访问、UI、路由入口和验证规则可发现、可组合、可检查。若按全局 `components/`、`hooks/`、`services/` 平铺,单一资源会跨多个顶层目录分散,资源校验器也难以围绕 `src/features/` 做完整性验证。 + +已验证:应用组装和路由元数据具有全局生命周期,资源业务代码具有按功能演进的生命周期,共享表格、表单、权限、认证、i18n 和布局具有跨功能演进的生命周期。按变化原因划分目录,比仅按文件技术类型划分更符合当前代码和规范。 + +已验证:远程数据与本地 UI 状态拥有不同生命周期。服务端状态需要请求去重、缓存、失效和 mutation 协调,项目由 TanStack Query 负责;主题、语言和界面开关只在浏览器内变化,项目由 Zustand 负责。请求传输细节则下沉到共享 fetch helper 和 feature API adapter,不进入组件。 + +推断:把“业务垂直切片 + 横向共享能力 + 集中应用/路由组装”作为新增代码的默认落点,可以减少跨目录修改、重复抽象和 AI 生成时的放置歧义;但是否需要新增 feature 子目录仍应由真实职责决定。 + +## Preferred action + +1. 运行时代码统一放在 `src`;根目录 `specs/`、`skills/`、`packages/registry` 等属于 AI Harness、规范或工具链,不要导入浏览器运行时。 +2. 保持 `src/main.tsx` 薄:只做全局样式和运行时初始化、DOM 根节点检查及 `` 挂载。Providers、认证启动边界、QueryClient、Router 实例和 Route Catalog 放在 `src/app`。 +3. 手写路由树、路由元数据类型和路由副作用放在 `src/routes`;路由组件可以懒加载 feature page 或顶层 system/example page,但不要把路由元数据散落到页面组件。 +4. 资源或业务能力默认建立 `src/features/` 垂直切片。完整单资源 CRUD 使用 `api/`、`components/`、`pages/`、`schemas/`、`specs/`;只有出现明确职责时再增加 `policies/`、`routes/` 等子目录,不提前创建空的通用层。 +5. feature 内按职责命名文件:数据边界用 `*.api.ts`、`*.types.ts`、`*.query.ts`、`*.mutation.ts`、必要时 `*.mock.ts` 和 `*.serializers.ts`;校验与 URL search shape 用 `*.schema.ts`;页面用 `*-page.tsx`;复杂表格拆成 `*-table.tsx`、`*-table-columns.tsx`、`*-table-toolbar.tsx` 和 `*-row-actions.tsx`。 +6. 服务端状态使用 TanStack Query:query/mutation hooks 放在 feature 的 `api/` 目录,query keys 使用共享工厂集中管理,mutation 成功后显式更新或失效相关缓存。不要把远程数据复制进 Zustand。 +7. 全局客户端 UI 状态使用 Zustand:只存放主题、语言、界面开关等浏览器状态。局部组件状态继续使用 React 本地 state,不因使用 Zustand 而集中所有交互状态。 +8. feature API adapter 负责端点、参数、响应和业务类型;共享 `requestJson`、`requestBlob`、`requestMultipart` 负责 URL、请求选项和统一传输行为。页面和组件只调用 query/mutation hooks,不直接调用 `fetch`。 +9. 非资源型的 dashboard、403/404、外观设置和模板演示页放在 `src/pages`。一旦页面属于具体业务资源,应放回对应 feature 的 `pages/`,不要把业务页长期堆在顶层 `pages`。 +10. 跨业务复用且不拥有具体资源语义的能力放在 `src/shared`,按能力域继续分目录。共享表格、表单和列表模板只拥有布局与交互壳;筛选状态、导航、API 调用和 mutation 保留在 feature。 +11. 全局 reset、token 和应用级样式入口放在 `src/styles`;只服务单一组件的 CSS 可与组件同目录。UI 原语直接使用 Semi Design,只有出现重复的项目工作流时才建立项目自有共享抽象。 +12. 源码跨目录导入使用 `@/` 别名。判断归属时先问“谁拥有这项业务语义、它与谁一起变化”,再决定目录,不以“它是组件/Hook/工具”作为唯一依据。 +13. 新增或生成完整资源模块后运行 `pnpm validate:resources`;涉及共享 API、类型或跨目录影响时,再按项目规则使用 CodeGraph、源码搜索、类型检查和针对性测试核对影响范围。 + +## Boundaries + +- 这是 `usercenter-react` 的仓库级规范,不是所有 React 项目的通用目录标准;其他仓库需要先读取其路由、状态管理、生成器和模块边界约定。 +- `api/components/pages/schemas/specs` 是完整单资源 CRUD 的标准结构,不要求轻量 feature 为了形式完整而创建所有目录。`current-user` 只拥有 API 与 Schema,`market-management` 还拥有 `policies` 和 feature-local `routes`,都是当前结构允许的变体。 +- 顶层 `src/pages` 适合无独立资源归属的系统页和示例页,不代表所有路由页面都应放在那里。 +- `src/shared` 的目标是跨业务复用和资源语义中立,但当前 `shared/auth/auth-context.tsx` 会组合 `features/current-user`。这说明仓库尚未建立可由 lint 强制的绝对无环分层;不要把本记录扩大成“shared 永远不能引用 feature”的新规则,除非另行设计并验证迁移方案。 +- 空目录或历史遗留目录不是规范证据;优先以 `AGENTS.md`、`specs/`、当前有效导入关系和可执行校验器为准。 +- TanStack Query 只负责远程/服务端状态,不用来保存纯界面开关;Zustand 只负责客户端状态,不作为请求缓存或远程数据副本。 +- 局部、短生命周期且只由一个组件树消费的交互状态不必放入 Zustand;优先保留为 React 本地 state。 +- `pnpm validate:resources` 只验证带 Resource Spec 的生成式资源模块,不能替代整个应用的类型检查、lint、构建或业务测试。 + +## Failed approaches + +- 按全局 `components/`、`hooks/`、`services/` 平铺所有业务代码:同一资源的修改会散落到多个顶层目录,资源规格与生成结果也难以成组验证。 +- 把可复用性未验证的业务组件提前放入 `shared`:会把具体资源语义伪装成公共抽象,增加依赖和后续拆分成本。 +- 看到 `feature-module.spec.md` 的目录清单就机械创建空目录:轻量 feature 和复杂 feature 的真实职责不同,空层级不会提高可发现性。 +- 把请求结果同时存进 TanStack Query 和 Zustand:会产生两个数据源、重复失效逻辑和状态不同步问题。 +- 页面组件直接调用 `fetch`:会绕过 feature API adapter、统一错误处理和 TanStack Query 缓存生命周期。 +- 仅凭 CodeGraph 或目录名推断边界:索引可能未同步,目录也可能存在历史空壳;必须回到当前源码、项目规范和校验器核对。 + +## Promotion record + +- Not promoted. 当前规范已经由 `usercenter-react/AGENTS.md`、`specs/` 和资源校验器共同承载;本记录先作为仓库级 candidate,待在另一个 React 管理后台独立复用并验证后,再考虑提炼为跨项目 pattern 或目录审计脚本。 diff --git a/AI-RD-Workflow/40-workflows/trellis-matt/CN/AGENTS.md b/AI-RD-Workflow/40-workflows/trellis-matt/CN/AGENTS.md index a83abaa..534a105 100644 --- a/AI-RD-Workflow/40-workflows/trellis-matt/CN/AGENTS.md +++ b/AI-RD-Workflow/40-workflows/trellis-matt/CN/AGENTS.md @@ -49,7 +49,7 @@ - Trellis 只管理 task 状态、planning artifacts、research、checkpoint、跨会话恢复和 archive。 - Matt 只提供当前阶段的工程方法;一个阶段只保留一个 method owner。 -- Phase 1 不使用 `trellis-brainstorm`:主会话先基于证据形成 task artifacts,再用 `grill-with-docs` review spec。 +- Phase 1 不使用 `trellis-brainstorm`:主会话先基于证据形成 task artifacts。普通 task 用 `grill-with-docs` review spec;已绑定并审批过的 Feishu Spec/Tickets 先做 source snapshot 一致性检查,只对 task 新增的 decision-bearing delta 使用 `grill-with-docs`。 - Phase 2 不使用原生 `trellis-implement`:由 `trellis-matt-implement` sub-agent 按已记录的 `standard|tdd` mode 执行;agent 不可用时由主会话按同一 mode fallback。 - Trellis 详细 phase、breadcrumb、恢复和归档命令以项目 `.trellis/workflow.md` 为准。 - 简单工作不建 task;项目没有 `.trellis/` 时不主动初始化,除非用户明确要求长期记录或初始化。 @@ -58,9 +58,11 @@ - Trellis task 的 `prd.md`、条件性的 `design.md` 和 `implement.md` 是 task-level spec source of truth。 - Planning artifacts 初稿应来自代码、测试、配置、文档和 task history 等证据。 +- Feishu-bound task 的 Wiki Spec/Base Tickets 继续拥有产品需求、验收和关系事实;Trellis artifacts 只是执行 snapshot 与 task-local planning,不得成为第二份业务 Spec。 - 每个 Trellis implementation task 在 `prd.md` 的 `Testing Strategy` 记录 `Implementation Mode: standard|tdd`;默认 `standard`。 - 用户要求 `/tdd`、test-first、red-green-refactor、integration tests 或 reviewed spec 明确要求 TDD 时记录 `tdd`,并在进入执行前确认公开测试 seam。 -- 使用 `grill-with-docs` 逐项 review 产品、范围、UX、兼容、风险、验收和关键设计决策。 +- 未绑定外部已审批 Spec 时,使用 `grill-with-docs` 逐项 review 产品、范围、UX、兼容、风险、验收和关键设计决策。 +- Feishu-bound task 若 snapshot 与已审批来源一致且没有新增决策,只做机械一致性检查;若 task-local planning 新增兼容、迁移、rollout/rollback、安全或执行顺序等决策,只 review delta;若改变产品需求、验收、Ticket 身份或 blocker 语义,先回写并重新批准 owning Feishu artifact。 - 一次只问一个问题;先查环境事实,只把真正属于用户的决策交给用户。 - 每个答案确认后立即同步回 owning Trellis artifact。 - `CONTEXT.md` 只保存稳定领域术语;ADR 只保存难以逆转、反直觉且经过真实取舍的决策,不复制 task spec。 diff --git a/AI-RD-Workflow/40-workflows/trellis-matt/CN/workflow.md b/AI-RD-Workflow/40-workflows/trellis-matt/CN/workflow.md index 2ac69d5..89c91a4 100644 --- a/AI-RD-Workflow/40-workflows/trellis-matt/CN/workflow.md +++ b/AI-RD-Workflow/40-workflows/trellis-matt/CN/workflow.md @@ -28,7 +28,7 @@ Trellis 是控制面,不替代工程方法;Matt 是方法层,不拥有 tas - 全局 `AGENTS.md` 与本文共同拥有任务分流权;Trellis bundled skill 不得覆盖二者。 - `trellis-start` 只用于加载 context、phase 和 spec indexes;忽略其中旧的 task-consent 与固定 skill route。 -- 不调用 `trellis-brainstorm` 和原生 `trellis-implement`。Planning 使用 `grill-with-docs`;Trellis Phase 2 使用 `trellis-matt-implement` 执行本工作流适配后的 Matt implementation contract。 +- 不调用 `trellis-brainstorm` 和原生 `trellis-implement`。普通 Planning 使用 `grill-with-docs`;Feishu-bound task 先做 approved-source snapshot 检查,只对 decision-bearing delta 使用 `grill-with-docs`。Trellis Phase 2 使用 `trellis-matt-implement` 执行本工作流适配后的 Matt implementation contract。 - 不依赖 `trellis-continue` 的旧 route table;恢复逻辑以本文 `Active Task Routing` 为准。 - 不调用 `trellis-finish-work` 的旧 commit-first 流程;直接运行本文 3.5 的 `--no-commit` 命令。 - 即使 Codex hook 的 `` banner 显示 Trellis sub-agent 默认值,本文对 planning/implementation 方法的明确选择优先:不得派发原生 `trellis-implement`。 @@ -95,7 +95,7 @@ Trellis 是控制面,不替代工程方法;Matt 是方法层,不拥有 tas Trellis 生命周期内有两个固定替换: -- Phase 1 不使用 `trellis-brainstorm`;先由主会话基于证据形成 planning artifacts,再用 `grill-with-docs` review 和压实 spec。 +- Phase 1 不使用 `trellis-brainstorm`;先由主会话基于证据形成 planning artifacts。普通 task 再用 `grill-with-docs` review 和压实 spec;已审批的 Feishu-bound task 先验证 source snapshot,只 review 新增 delta。 - Phase 2 不使用原生 `trellis-implement`;派发 `trellis-matt-implement` 按已经 review 的 artifacts 执行适配后的 Matt implementation contract。 其他意图不要在本文件复制一份会过期的 Matt skill 清单。按以下顺序路由: @@ -152,6 +152,8 @@ python3 ./.trellis/scripts/task.py list-archive `prd.md` 不放详细技术设计和执行 checklist。`design.md` 解释技术形状与取舍。`implement.md` 记录有序步骤、验证命令、风险、rollback point 和当前 checkpoint。 +Feishu-bound task 的 Wiki Spec/Base Tickets 继续拥有产品需求、验收、身份和关系事实。Trellis `prd.md`/`implement.md`保存可恢复的执行 snapshot 与 task-local planning:必须记录稳定 record IDs、来源更新时间/Wiki revision(可用时)、Ticket 集合和关系。它们不得静默覆盖飞书来源,也不得要求用户仅因内容被复制到 Trellis 就再次全文审批。 + 每个 Trellis implementation task 在 `prd.md` 中维护: ```markdown @@ -214,7 +216,7 @@ Phase 3: Finish → verify, evaluate knowledge, optionally use VCS, archive and | 简单、局部、根因明确 | Inline;不创建 task | | 非简单但单会话可完成 | 按当前 skill `description` 选择 Matt 方法 | | 明确 `/tdd`、test-first、red-green-refactor 或 integration tests | `/tdd`;Trellis task 先记录 mode 并确认公开 seam | -| Trellis planning artifact review | `grill-with-docs`;不用 `trellis-brainstorm` | +| Trellis planning artifact review | 普通 task 用 `grill-with-docs`;Feishu-bound task 做 snapshot check,只对 delta 用 `grill-with-docs`;不用 `trellis-brainstorm` | | Trellis reviewed spec implementation | `trellis-matt-implement`;不用原生 `trellis-implement`;不可用时主会话执行 Matt fallback | | 诊断、review、架构、research | 按当前 skill `description` 选择最窄匹配 | | Trellis 状态、恢复、归档 | 本文 Phase、Active Task Routing 与 `.trellis/scripts/` | @@ -224,7 +226,7 @@ Phase 3: Finish → verify, evaluate knowledge, optionally use VCS, archive and - 1.0 Create or resume task `[required · once]` - 1.1 Draft planning artifacts from evidence `[required · repeatable]` - 1.2 Research / prototype / design inquiry `[optional · repeatable]` -- 1.3 Review spec with `grill-with-docs` `[required · once]` +- 1.3 Review spec or source delta `[required · once]` - 1.4 Activate or stop at planning boundary `[required · once]` - 1.5 Planning completion criteria @@ -237,11 +239,11 @@ Route by `AGENTS.md`; keep simple work inline. Main session is default. Create a [/workflow-state:no_task-inline] [workflow-state:planning] -Do not use `trellis-brainstorm`. Draft task artifacts, record `standard|tdd`, confirm public TDD seams when required, review with `grill-with-docs`, then route by the user's original intent. +Do not use `trellis-brainstorm`. Draft task artifacts, record `standard|tdd`, confirm public TDD seams when required, then review the full spec or only the approved-source delta as applicable before routing by the user's original intent. [/workflow-state:planning] [workflow-state:planning-inline] -Draft task artifacts, record `standard|tdd`, confirm public TDD seams when required, review with `grill-with-docs`, and sync decisions. Trellis artifacts remain task-level truth. +Draft task artifacts, record `standard|tdd`, confirm public TDD seams when required, and review the full spec or only the approved-source delta as applicable. Feishu-bound artifacts remain execution snapshots; unbound Trellis artifacts remain task-level truth. [/workflow-state:planning-inline] ### Phase 2 summary @@ -312,6 +314,7 @@ python3 ./.trellis/scripts/task.py create "" --slug 6. 若实现 agent 需要固定读取某些 spec/research,把真实条目加入 `implement.jsonl`;不登记产品代码。没有额外 context 时允许保留 seed,由 agent 自行发现相关规范。 7. 每次重要结论形成后立即更新 owning artifact,避免只留在聊天里。 8. 暂不使用 `trellis-brainstorm`;开放决策和 TDD seam 留给 1.3 的 `grill-with-docs` 逐项 review。 +9. Feishu-bound task 读取并记录最新 Spec/Ticket record IDs、更新时间、Wiki revision(可用时)、验收和 blocker 集,作为后续 snapshot/delta 比较基线;不把 copied source 当成新 Spec。 `prd.md` 至少包含:Goal、Background/Evidence、In Scope、Out of Scope、Requirements、Acceptance Criteria、Constraints、Open Decisions、Testing Strategy。 @@ -331,21 +334,24 @@ Research 规则: Prototype 规则:代码从一开始就视为 throwaway;保留答案,不把原型未经重新设计直接并入产品实现。 -#### 1.3 Review spec with `grill-with-docs` `[required · once]` +#### 1.3 Review spec or source delta `[required · once]` -显式加载 `grill-with-docs`,用它 review `prd.md`、条件性的 `design.md` 和 `implement.md`: +先判断 task 是否绑定已经过审批的 Feishu Spec/Tickets: + +- **普通 task**:显式加载 `grill-with-docs`,review `prd.md`、条件性的 `design.md` 和 `implement.md`。 +- **Feishu-bound,snapshot-only**:比较稳定 IDs、Base 更新时间、Wiki revision(可用时)、完整 Ticket 集、parent/blocker、验收和 task-local 文本。完全一致且没有新增决策时,只记录 `snapshot-only / No decision-bearing delta`,不重复全文 grilling。 +- **Feishu-bound,delta-reviewed**:只把 task-local planning 新增或改变的兼容、迁移、rollout/rollback、安全、seam 或执行顺序等 decision-bearing delta 交给 `grill-with-docs`,确认后记录 delta 和来源版本。 +- **source-revision-required**:若 task-local planning 改变产品行为、范围、验收、Ticket 身份、parent 或 blocker 语义,停止激活;先修订并批准 owning Wiki Spec/Base Tickets,再刷新 snapshot。 + +Review 时遵守: 1. 先由环境证据回答事实问题,不把仓库可查事实反问用户。 -2. 对产品、范围、UX、兼容、风险、验收和关键设计决策逐项 grilling。 -3. 一次只问一个问题,每个问题提供推荐答案和不同选择的取舍。 -4. 每个答案确认后立即同步到 owning Trellis artifact。 -5. `Implementation Mode: tdd` 时,按 `/tdd` 契约确认要观察的公开 interface/seam;未确认前不写测试、不进入 Phase 2。`standard` 不询问 TDD seam。 -6. `CONTEXT.md` 只记录稳定领域术语;ADR 只记录难以逆转、反直觉且经过真实取舍的决策。 -7. Trellis artifacts 始终是当前 task 的 spec source of truth;不要让 glossary/ADR 复制任务细节。 +2. 一次只问一个决定性问题,每题提供推荐答案和选择取舍。 +3. 每个答案确认后立即同步到 owning artifact;产品/验收写回飞书来源,执行决策写入 Trellis。 +4. `Implementation Mode: tdd` 时,按 `/tdd` 契约确认公开 interface/seam;未确认前不写测试、不进入 Phase 2。`standard` 不询问 TDD seam。 +5. `CONTEXT.md` 只记录稳定领域术语;ADR 只记录难以逆转、反直觉且经过真实取舍的决策。 -`grill-with-docs` 在平台上不可直接加载时,使用其等价组合:`grilling` + `domain-modeling`。 - -当用户确认已经达到 shared understanding 时,本步骤完成。这个确认是 spec review 的完成条件,不再额外增加一层 Trellis implementation approval。 +`grill-with-docs` 在平台上不可直接加载时,使用其等价组合:`grilling` + `domain-modeling`。普通 task 在 shared understanding 后完成本步骤;Feishu-bound task 在 snapshot/delta disposition 已记录且无 unresolved delta 后完成。两者都不再增加额外的 Trellis implementation approval。 #### 1.4 Activate or stop at planning boundary `[required · once]` @@ -365,7 +371,7 @@ Prototype 规则:代码从一开始就视为 throwaway;保留答案,不把 python3 ./.trellis/scripts/task.py start ``` -原始实现请求加上 1.3 的 shared-understanding 确认已经构成实现授权;不再额外增加 Trellis planning approval。 +原始实现请求加上 1.3 的 review completion(普通 task 的 shared understanding,或 Feishu-bound task 的有效 snapshot/delta disposition)已经构成实现授权;不再额外增加 Trellis planning approval。 Planning-only task 的 planning 产物本身就是交付物;完成并验证后可直接进入 3.5 归档,不必为了走形式而把它切到 `in_progress`。 @@ -381,7 +387,7 @@ Planning-only task 的 planning 产物本身就是交付物;完成并验证后 | research 结论已持久化(如有) | ✅ | | `Testing Strategy` 已记录 `standard` 或 `tdd` | ✅ | | `tdd` 模式的公开测试 seam 已由用户确认 | 条件性 ✅ | -| `grill-with-docs` review 已达到 shared understanding | ✅ | +| 普通 task 已达到 shared understanding;Feishu-bound task 已记录有效 snapshot/delta disposition | ✅ | | 当前动作仍处于用户授权范围 | ✅ | ## Phase 2: Execute @@ -540,8 +546,8 @@ Active task 存在时,先读取 `task.json`、artifacts 和 Current Checkpoint | --- | --- | | `planning`,`prd.md` 未收敛 | 1.1 | | `planning`,存在技术未知项 | 1.2 | -| `planning`,artifacts 尚未通过 `grill-with-docs` review | 1.3 | -| `planning`,shared understanding 已确认 | 1.4;按用户原始意图 start 或停在 planning boundary | +| `planning`,普通 artifacts 尚未 review,或 Feishu snapshot/delta disposition 缺失/已失效 | 1.3 | +| `planning`,1.3 review completion 已满足 | 1.4;按用户原始意图 start 或停在 planning boundary | | `in_progress`,checkpoint 指向未完成实现/诊断/review | 2.1 | | `in_progress`,执行完成但缺 full-scope evidence | 2.2 | | `in_progress`,acceptance 已验证 | 3.3 → 条件性 3.4 → 3.5 | diff --git a/AI-RD-Workflow/40-workflows/trellis-matt/EN/AGENTS.md b/AI-RD-Workflow/40-workflows/trellis-matt/EN/AGENTS.md index 67acbbd..b2f3f06 100644 --- a/AI-RD-Workflow/40-workflows/trellis-matt/EN/AGENTS.md +++ b/AI-RD-Workflow/40-workflows/trellis-matt/EN/AGENTS.md @@ -49,18 +49,19 @@ Handle the following directly without creating a Trellis task: - Trellis manages only task state, planning artifacts, research, checkpoints, cross-session recovery, and archiving. - Matt provides only the engineering method for the current phase. Keep exactly one method owner per phase. -- Do not use `trellis-brainstorm` in Phase 1. The main session first drafts task artifacts from evidence, then reviews the spec with `grill-with-docs`. +- Do not use `trellis-brainstorm` in Phase 1. The main session first drafts task artifacts from evidence. Review a normal task's spec with `grill-with-docs`; for an approved Feishu-bound Spec/Ticket set, verify source-snapshot equivalence and use `grill-with-docs` only for decision-bearing task-local deltas. - Do not use the native `trellis-implement` in Phase 2. The `trellis-matt-implement` sub-agent executes the recorded `standard|tdd` mode; if the agent is unavailable, the main session falls back using the same mode. - Follow the project's `.trellis/workflow.md` for detailed phases, breadcrumbs, recovery, and archive commands. - Do not create a task for simple work. If the project has no `.trellis/`, do not initialize it unless the user explicitly asks for durable records or initialization. ## Planning Method -- A Trellis task's `prd.md` and conditional `design.md` and `implement.md` are the task-level source of truth for the spec. +- A Trellis task's `prd.md` and conditional `design.md` and `implement.md` are the task-level source of truth for an unbound task. For a Feishu-bound task, approved Wiki/Base artifacts remain the business source while Trellis stores an execution snapshot and task-local planning. - Initial planning artifacts should come from evidence in code, tests, configuration, documentation, and task history. - Every Trellis implementation task records `Implementation Mode: standard|tdd` under `Testing Strategy` in `prd.md`; `standard` is the default. - Record `tdd` when the user requests `/tdd`, test-first, red-green-refactor, or integration tests, or when the reviewed spec explicitly requires TDD, and confirm public test seams before execution. -- Use `grill-with-docs` to review product, scope, UX, compatibility, risk, acceptance, and key design decisions one by one. +- When there is no approved external Spec, use `grill-with-docs` to review product, scope, UX, compatibility, risk, acceptance, and key design decisions one by one. +- If a Feishu-bound snapshot matches the approved sources and adds no decision, perform only a mechanical consistency check. Review only task-local compatibility, migration, rollout/rollback, security, or sequencing deltas. If planning changes product requirements, acceptance, Ticket identity, or blocker semantics, revise and re-approve the owning Feishu artifact first. - Ask one question at a time. Investigate environmental facts first and ask the user only for decisions that genuinely belong to them. - After each answer is confirmed, immediately synchronize it back to the owning Trellis artifact. - `CONTEXT.md` stores only durable domain terminology. ADRs store only decisions that are hard to reverse, counterintuitive, and based on a real tradeoff; they must not duplicate the task spec. diff --git a/AI-RD-Workflow/40-workflows/trellis-matt/EN/workflow.md b/AI-RD-Workflow/40-workflows/trellis-matt/EN/workflow.md index 6bb57f3..bc1ddd5 100644 --- a/AI-RD-Workflow/40-workflows/trellis-matt/EN/workflow.md +++ b/AI-RD-Workflow/40-workflows/trellis-matt/EN/workflow.md @@ -28,7 +28,7 @@ At project level, this setup overrides `.trellis/workflow.md` and adds `.codex/a - Global `AGENTS.md` and this document jointly own task routing. Trellis bundled skills must not override either one. - Use `trellis-start` only to load context, phase, and spec indexes. Ignore its legacy task-consent and fixed skill routing. -- Do not call `trellis-brainstorm` or the native `trellis-implement`. Planning uses `grill-with-docs`; Trellis Phase 2 uses `trellis-matt-implement` to execute the Matt implementation contract adapted by this workflow. +- Do not call `trellis-brainstorm` or the native `trellis-implement`. Normal planning uses `grill-with-docs`; a Feishu-bound task first checks its approved-source snapshot and uses `grill-with-docs` only for decision-bearing deltas. Trellis Phase 2 uses `trellis-matt-implement` to execute the Matt implementation contract adapted by this workflow. - Do not depend on the legacy route table in `trellis-continue`. Use this document's `Active Task Routing`. - Do not call the legacy commit-first flow in `trellis-finish-work`. Run the `--no-commit` commands in section 3.5 directly. - Even if a Codex hook's `` banner shows Trellis sub-agent defaults, the explicit planning and implementation method selected here takes precedence. Never dispatch the native `trellis-implement`. @@ -95,7 +95,7 @@ When the boundary is uncertain, prefer Matt in a single session first. Upgrade t The Trellis lifecycle has two fixed substitutions: -- Phase 1 does not use `trellis-brainstorm`. The main session first drafts planning artifacts from evidence, then uses `grill-with-docs` to review and tighten the spec. +- Phase 1 does not use `trellis-brainstorm`. The main session first drafts planning artifacts from evidence. It then reviews and tightens a normal task's spec with `grill-with-docs`; an approved Feishu-bound task verifies its source snapshot and reviews only new deltas. - Phase 2 does not use the native `trellis-implement`. Dispatch `trellis-matt-implement` to execute the adapted Matt implementation contract from the reviewed artifacts. For other intents, do not copy a Matt skill list into this file where it can become stale. Route in this order: @@ -152,6 +152,8 @@ python3 ./.trellis/scripts/task.py list-archive Do not put detailed technical design or an execution checklist in `prd.md`. `design.md` explains the technical shape and tradeoffs. `implement.md` records ordered steps, verification commands, risks, rollback points, and the current checkpoint. +For a Feishu-bound task, the Wiki Spec/Base Tickets remain authoritative for product requirements, acceptance, identity, and relationships. Trellis `prd.md`/`implement.md` hold a recoverable execution snapshot and task-local planning: record stable record IDs, source update times/Wiki revision when available, the Ticket set, and relationships. They must not silently overwrite the Feishu sources or require a second full approval merely because approved content was copied into Trellis. + Every Trellis implementation task maintains this in `prd.md`: ```markdown @@ -214,7 +216,7 @@ Phase 3: Finish → verify, evaluate knowledge, optionally use VCS, archive and | Simple, local, root cause known | Inline; no task | | Not simple but completable in one session | Select a Matt method from current skill `description` values | | Explicit `/tdd`, test-first, red-green-refactor, or integration tests | `/tdd`; for Trellis, first record the mode and confirm public seams | -| Trellis planning artifact review | `grill-with-docs`; do not use `trellis-brainstorm` | +| Trellis planning artifact review | Normal task: `grill-with-docs`; Feishu-bound task: snapshot check and `grill-with-docs` only for deltas; do not use `trellis-brainstorm` | | Trellis reviewed-spec implementation | `trellis-matt-implement`; do not use the native `trellis-implement`; use the main-session Matt fallback when unavailable | | Diagnosis, review, architecture, or research | Select the narrowest match from current skill `description` values | | Trellis state, recovery, or archive | This document's phases, `Active Task Routing`, and `.trellis/scripts/` | @@ -224,7 +226,7 @@ Phase 3: Finish → verify, evaluate knowledge, optionally use VCS, archive and - 1.0 Create or resume task `[required · once]` - 1.1 Draft planning artifacts from evidence `[required · repeatable]` - 1.2 Research / prototype / design inquiry `[optional · repeatable]` -- 1.3 Review spec with `grill-with-docs` `[required · once]` +- 1.3 Review spec or source delta `[required · once]` - 1.4 Activate or stop at planning boundary `[required · once]` - 1.5 Planning completion criteria @@ -237,11 +239,11 @@ Route by `AGENTS.md`; keep simple work inline. Main session is default. Create a [/workflow-state:no_task-inline] [workflow-state:planning] -Do not use `trellis-brainstorm`. Draft task artifacts, record `standard|tdd`, confirm public TDD seams when required, review with `grill-with-docs`, then route by the user's original intent. +Do not use `trellis-brainstorm`. Draft task artifacts, record `standard|tdd`, confirm public TDD seams when required, then review the full spec or only the approved-source delta as applicable before routing by the user's original intent. [/workflow-state:planning] [workflow-state:planning-inline] -Draft task artifacts, record `standard|tdd`, confirm public TDD seams when required, review with `grill-with-docs`, and sync decisions. Trellis artifacts remain task-level truth. +Draft task artifacts, record `standard|tdd`, confirm public TDD seams when required, and review the full spec or only the approved-source delta as applicable. Feishu-bound artifacts remain execution snapshots; unbound Trellis artifacts remain task-level truth. [/workflow-state:planning-inline] ### Phase 2 summary @@ -312,6 +314,7 @@ If one request contains multiple independently verifiable deliverables, first cr 6. If the implementation agent must read specific specs or research, add real entries to `implement.jsonl`; do not register product code. When no extra context is needed, the seed may remain and the agent discovers relevant standards itself. 7. After every important conclusion, immediately update the owning artifact so that it does not live only in the conversation. 8. Do not use `trellis-brainstorm`. Leave open decisions and TDD seams for item-by-item review with `grill-with-docs` in step 1.3. +9. For a Feishu-bound task, record the latest Spec/Ticket record IDs, update times, Wiki revision when available, acceptance, and blocker set as the baseline for later snapshot/delta comparison. Do not treat copied source content as a new Spec. At minimum, `prd.md` contains: Goal, Background/Evidence, In Scope, Out of Scope, Requirements, Acceptance Criteria, Constraints, Open Decisions, and Testing Strategy. @@ -331,21 +334,24 @@ Research rules: Prototype rule: treat prototype code as throwaway from the beginning. Keep the answer, but do not merge the prototype into the product implementation without redesigning it. -#### 1.3 Review spec with `grill-with-docs` `[required · once]` +#### 1.3 Review spec or source delta `[required · once]` -Explicitly load `grill-with-docs` and use it to review `prd.md` plus conditional `design.md` and `implement.md`: +First determine whether the task is bound to an already approved Feishu Spec/Ticket set: -1. Answer factual questions from environmental evidence first. Do not ask the user for facts that can be found in the repository. -2. Grill product, scope, UX, compatibility, risk, acceptance, and key design decisions one by one. -3. Ask one question at a time. Each question includes a recommended answer and the tradeoffs of alternative choices. -4. After each answer is confirmed, immediately synchronize it to the owning Trellis artifact. -5. When `Implementation Mode: tdd`, use the `/tdd` contract to confirm the public interface/seam to observe. Do not write tests or enter Phase 2 before confirmation. Do not ask about TDD seams in `standard` mode. -6. `CONTEXT.md` records only durable domain terminology. An ADR records only a decision that is hard to reverse, counterintuitive, and based on a real tradeoff. -7. Trellis artifacts remain the source of truth for the current task spec. Do not duplicate task details in the glossary or ADRs. +- **Normal task**: explicitly load `grill-with-docs` and review `prd.md` plus conditional `design.md` and `implement.md`. +- **Feishu-bound, snapshot-only**: compare stable IDs, Base update times, Wiki revision when available, the complete Ticket set, parent/blocker relationships, acceptance, and task-local text. If they match and add no decision, record `snapshot-only / No decision-bearing delta`; do not repeat full-text grilling. +- **Feishu-bound, delta-reviewed**: give `grill-with-docs` only the decision-bearing compatibility, migration, rollout/rollback, security, seam, or sequencing text that task-local planning added or changed. Record the confirmed delta and source version. +- **source-revision-required**: if task-local planning changes product behavior, scope, acceptance, Ticket identity, parent, or blocker semantics, stop activation. Revise and approve the owning Wiki Spec/Base Tickets first, then refresh the snapshot. -If `grill-with-docs` cannot be loaded directly on the platform, use the equivalent combination `grilling` + `domain-modeling`. +During review: -This step is complete when the user confirms shared understanding. That confirmation completes the spec review; do not add another Trellis implementation-approval layer. +1. Answer factual questions from environment evidence rather than asking the user. +2. Ask one decision-bearing question at a time and provide a recommended answer plus tradeoffs. +3. Sync each confirmed answer into the owning artifact immediately: product/acceptance decisions go back to Feishu; execution decisions go to Trellis. +4. When `Implementation Mode: tdd`, confirm the public interface/seam according to the `/tdd` contract. Do not write tests or enter Phase 2 before confirmation. `standard` does not ask for a TDD seam. +5. `CONTEXT.md` stores only stable domain vocabulary. ADRs store only decisions that are hard to reverse, surprising, and the result of a real tradeoff. + +If `grill-with-docs` cannot be loaded directly on the platform, use the equivalent combination `grilling` + `domain-modeling`. A normal task completes this step at shared understanding; a Feishu-bound task completes it when the snapshot/delta disposition is recorded and no unresolved delta remains. Neither path adds another Trellis implementation approval. #### 1.4 Activate or stop at planning boundary `[required · once]` @@ -365,7 +371,7 @@ Start command: python3 ./.trellis/scripts/task.py start ``` -The original implementation request plus the shared-understanding confirmation in step 1.3 constitutes implementation authorization. Do not add another Trellis planning approval. +The original implementation request plus step 1.3 review completion—shared understanding for a normal task, or a valid snapshot/delta disposition for a Feishu-bound task—constitutes implementation authorization. Do not add another Trellis planning approval. For a planning-only task, the planning artifacts are themselves the deliverable. Once completed and verified, the task may go directly to archive in step 3.5 without being moved to `in_progress` merely for formality. @@ -381,7 +387,7 @@ For a planning-only task, the planning artifacts are themselves the deliverable. | Research conclusions have been persisted, if any | ✅ | | `Testing Strategy` records `standard` or `tdd` | ✅ | | Public test seams have been confirmed by the user in `tdd` mode | Conditional ✅ | -| `grill-with-docs` review reached shared understanding | ✅ | +| Normal task reached shared understanding; Feishu-bound task has a valid recorded snapshot/delta disposition | ✅ | | The current action remains within user authorization | ✅ | ## Phase 2: Execute @@ -540,8 +546,8 @@ When an active task exists, first read `task.json`, its artifacts, and Current C | --- | --- | | `planning`, `prd.md` has not converged | 1.1 | | `planning`, technical unknowns remain | 1.2 | -| `planning`, artifacts have not passed `grill-with-docs` review | 1.3 | -| `planning`, shared understanding has been confirmed | 1.4; start or stop at the planning boundary according to the user's original intent | +| `planning`, normal artifacts are unreviewed, or the Feishu snapshot/delta disposition is missing/stale | 1.3 | +| `planning`, step 1.3 review completion is satisfied | 1.4; start or stop at the planning boundary according to the user's original intent | | `in_progress`, checkpoint points to unfinished implementation/diagnosis/review | 2.1 | | `in_progress`, execution is complete but full-scope evidence is missing | 2.2 | | `in_progress`, acceptance has been verified | 3.3 → conditional 3.4 → 3.5 | diff --git a/docs/Matt 工作流 × 飞书 CLI 全流程总结.md b/docs/Matt 工作流 × 飞书 CLI 全流程总结.md new file mode 100644 index 0000000..e1d2b39 --- /dev/null +++ b/docs/Matt 工作流 × 飞书 CLI 全流程总结.md @@ -0,0 +1,520 @@ +# Matt 工作流 × 飞书 CLI 全流程总结 + +> 状态:已通过真实 Feishu Base / Wiki POC 验证 +> 更新时间:2026-07-26 +> 覆盖范围:`setup-matt-pocock-skills-feishu`、`to-spec-feishu`、`to-tickets-feishu`、`triage-feishu` + +## 1. 结论 + +本次工作把 Matt Pocock 的工程工作流接入了飞书,并保持原 Matt skills 的规划、规格、垂直切片和分诊语义不变: + +- **Feishu Base 是状态、关系和查询的事实来源**:每个 Issue、Spec、Ticket 或其他产物对应一条记录。 +- **Feishu Wiki / Docs 是长文档事实来源**:保存 Spec、Triage Notes、Agent Brief、Human Brief 等叙述性产物。 +- **仓库仍保存代码侧事实**:代码、测试、ADR、`CONTEXT.md` 和被拒绝 enhancement 的 `.out-of-scope/` 决定不会复制成第二份事实来源。 +- **所有 Feishu API 操作使用应用身份**:`--as bot --format json`,不回退到 user 身份或其他文档位置。 +- **每次 Base 记录创建或更新都记录真实发起用户**:调用者是 bot,“最后更新人”保存当前 CLI 人类用户;“负责人”仍只表示执行责任人。 +- **所有写入都需要回读验证**:API 返回 `ok:true` 只是第一层证据,Wiki 用 `docs +fetch`,Base 用 `record-get` 或完整分页查询复核。 + +## 2. 当前资源与身份 + +| 项目 | 当前值 | +| ---------- | -------------------------------------------------------------------------------------------------------------------- | +| Base | [Matt 工作流多维表格](https://oppeinlink.feishu.cn/wiki/Cq6Kw9mrGi0KXDkBJJpcW57Lnmd?table=tblFvlnVuWhmvQKC&view=vewwNwcwaf) | +| Base token | `HXzGbaFIAaHEpBsMMrfc0z1lnnb` | +| 数据表 | `数据表` / `tblFvlnVuWhmvQKC` | +| 主字段 | `文本` / `fldzLHLTca` | +| 视图 | `表格` / `vewwNwcwaf`,29 个字段全部可见 | +| Wiki 根节点 | [开发智能体文档仓库](https://oppeinlink.feishu.cn/wiki/RG7bwmoP0i6DJikbHqWcY959nLd) | +| Wiki space | `7493342321238130707` | +| 工作流文档 | [Matt 工作流 × 飞书 CLI:文档与进度管理工作流](https://oppeinlink.feishu.cn/wiki/L2qFwzIMAipZqlkbwoXc6Pofnxe) | +| API 执行身份 | bot `迷迭香` / `ou_967b892ae067fd2e24d369a289a5b01e` | +| 当前归因用户 | `于选辉` / `ou_aed469c8168cd31341fa94bf2d89bddd` | +| 已验证 CLI | `lark-cli 1.0.76` | + +## 3. 系统架构 + +```mermaid +flowchart LR + Human["真实用户 / 维护者"] --> Conversation["对话确认与 Matt 工作流"] + Conversation --> Auth["auth status --verify"] + Auth -->|"验证 bot"| Bot["应用身份:迷迭香"] + Auth -->|"冻结 user openId"| Attribution["业务归因:最后更新人"] + + Bot -->|"--as bot"| Base["Feishu Base\n状态、关系、查询"] + Bot -->|"--as bot"| Wiki["Feishu Wiki / Docs\n长文档与叙述"] + Attribution -->|"每次 record create / update"| Base + + Repo["代码仓库\n代码、测试、CONTEXT、ADR、out-of-scope"] --> Conversation + Base -->|"产物文档"| Wiki + Base -->|"代码引用"| Repo + + Base --> Verify["record-get / 完整分页回读"] + Wiki --> VerifyDoc["docs +fetch 回读"] + Verify --> Evidence["验证证据"] + VerifyDoc --> Evidence +``` + +关键边界: + +1. bot 是 API 调用者,不自动等于“负责人”或“最后更新人”。 +2. “最后更新人”由工作流显式写入当前已验证用户的 open ID。 +3. “负责人”是工作执行责任,不因 CLI 操作而被覆盖。 +4. Wiki 节点必须创建在配置的根节点下;失败时报告完整错误和 `x-tt-logid`,不切换身份或位置重试。 + +## 4. 四个 Feishu skill + +| Skill | 何时使用 | 核心输入 | 核心产物 | Base / Wiki 策略 | +|---|---|---|---|---| +| `setup-matt-pocock-skills-feishu` | 仓库接入或切换到飞书 tracker | Base 表格/视图 URL、Wiki 根节点 URL、Setup 模式 | repo tracker 合约;Bootstrap 另含 Base schema、Wiki setup 文档、POC 记录 | 默认 Reuse 只读复核既有设施;Bootstrap 才初始化并验证写路径 | +| `to-spec-feishu` | 把已澄清的对话转成可执行 Spec | 对话、代码库上下文、测试 seam、可选来源 Issue | 完整 Wiki Spec + 一条 Base Spec | Wiki 保存完整规格;Base 保存身份、状态、摘要、验收和父项 | +| `to-tickets-feishu` | 把 Spec / 计划拆成 tracer-bullet Tickets | 已确认 Spec、垂直切片、依赖图 | 每个切片一条 Base Ticket | V1 不创建 Ticket Wiki;通过父 Spec 取得文档;两遍写入关系 | +| `triage-feishu` | 处理 Issue / PR 的分类、澄清和委派 | Issue/PR、代码验证、维护者决定、报告人反馈 | Base Issue 状态 + 可选 Triage Wiki dossier | Base 保存当前状态;Wiki 追加 Notes / Brief;拒绝决定以 repo 为准 | + +这些 skill 的 `来源技能`仍使用逻辑流程名,例如 `setup-matt-pocock-skills`、`to-spec`、`to-tickets`、`triage`;不会把适配器名称写成新的业务枚举。 + +## 5. 端到端工作流 + +```mermaid +flowchart TD + Setup["setup-matt-pocock-skills-feishu\n建立 repo 合约;按模式复用或初始化飞书资源"] --> Intake{"工作从哪里进入?"} + + Intake -->|"想法 / 已澄清对话"| SpecDraft["to-spec-feishu"] + Intake -->|"外部 Issue / PR / 表单"| Triage["triage-feishu"] + + Triage --> NeedsInfo["needs-info\n等待报告人"] + NeedsInfo -->|"最后反馈时间 > 最后分诊时间"| Triage + Triage --> ReadyAgent["ready-for-agent"] + Triage --> ReadyHuman["ready-for-human"] + Triage --> Wontfix["wontfix / out-of-scope"] + + ReadyAgent --> Complexity{"是否需要正式 Spec?"} + Complexity -->|"跨模块、需要设计决策"| SpecDraft + Complexity -->|"范围已足够小且明确"| Implement["implement / tdd"] + + SpecDraft --> SpecArtifacts["Wiki Spec + Base Spec\n状态 ready-for-agent"] + SpecArtifacts --> Ticketing["to-tickets-feishu"] + Ticketing --> TicketGraph["Base Ticket 依赖图\nfrontier = 无未完成 blocker"] + TicketGraph --> Implement + + Implement --> Review["code-review / 验证"] + Review --> Done["已完成 + 验证证据"] + Implement --> Blocked["阻塞 + 阻塞原因 + 下一步"] + Blocked --> Implement + + ReadyHuman --> HumanWork["人类处理:判断、权限、设计或手工验证"] + Wontfix --> Memory["Wiki 关闭说明;必要时 repo .out-of-scope/"] +``` + +本次新增的硬依赖飞书适配止于 setup、Spec、Tickets 和 Triage;`implement`、`tdd`、`code-review` 等下游流程通过生成的 `docs/agents/issue-tracker.md` 公共合约继续消费同一 Base。 + +## 6. Setup:一次性建立公共契约 + +```mermaid +flowchart TD + Start["探索仓库"] --> Detect["检查 AGENTS/CLAUDE、docs/agents、domain docs、triage、monorepo"] + Detect --> Tracker{"选择 issue tracker"} + Tracker -->|"Feishu"| Inputs["只接受两个用户输入\nBase URL + Wiki 根 URL"] + Inputs --> ReadSkills["读取 lark-shared / base / wiki / doc 规则"] + ReadSkills --> Mode{"选择 Setup 模式\n默认 Reuse"} + Mode -->|"Reuse:复用已配置资源"| Identity["验证 bot + user;冻结当前 user openId"] + Mode -->|"Bootstrap:新建或显式重验"| Identity + Identity --> Resolve["bot 解析 Base、table、view、Wiki root"] + Resolve --> Diff["完整 field-list;按精确字段名计算缺失项"] + Diff --> ReuseCheck{"选择的是 Reuse?"} + ReuseCheck -->|"是,schema 完整"| ReuseDraft["展示 repo 文件与只读验证证据\n明确不会写 Base / Wiki"] + ReuseCheck -->|"是,但发现 drift"| ReuseStop["停止;询问切换 Bootstrap\n或单独授权 schema repair"] + ReuseCheck -->|"否"| BootstrapDraft["展示 repo 文件、缺失字段、Wiki 标题、POC 标题"] + ReuseDraft --> ReuseConfirm{"用户确认 repo 文件?"} + ReuseConfirm -->|"否"| ReuseDraft + ReuseConfirm -->|"是"| RepoContract["生成 docs/agents/issue-tracker.md\n以及 triage/domain 合约"] + BootstrapDraft --> BootstrapConfirm{"用户确认 Bootstrap 写入?"} + BootstrapConfirm -->|"否"| BootstrapDraft + BootstrapConfirm -->|"是"| Schema["只创建缺失字段;不静默转换冲突字段"] + Schema --> WikiSetup["根节点下创建 Wiki setup 文档;append + fetch"] + WikiSetup --> POC["创建 POC Base 记录;record-get"] + POC --> RepoContract + RepoContract --> Gate{"验证门通过?"} + Gate -->|"否"| Report["报告具体错误、未运行项和边界"] + Gate -->|"是"| Ready["其他 Matt skills 可开始消费"] +``` + +### Setup 产物 + +- `AGENTS.md` 或 `CLAUDE.md` 中唯一的 `## Agent skills` 区块。 +- `docs/agents/issue-tracker.md`:真实 Base/Wiki 坐标、命令、字段与身份合约。 +- `docs/agents/triage-labels.md`:仅当 triage 已安装时生成。 +- `docs/agents/domain.md`:单 context 或多 context 的领域文档规则。 +- Reuse 模式不创建 Base 字段/记录或 Wiki 文档;只读验证既有资源并生成 repo-local 合约。 +- Bootstrap 模式额外创建一份 Wiki setup 文档,记录实际命令、字段、状态机、失败与修正、验证证据。 +- Bootstrap 模式额外创建一条 setup POC Base 记录,链接 Wiki 文档并证明写路径闭环;它不是每个项目的必跑步骤。 + +## 7. to-spec:从对话到可执行规格 + +```mermaid +flowchart TD + Context["对话 + 代码库 + Domain / ADR"] --> Seam["选择尽可能高的测试 seam"] + Seam --> SeamConfirm{"用户确认 seam?"} + SeamConfirm -->|"调整"| Seam + SeamConfirm -->|"确认"| Draft["生成完整 Matt Spec"] + Draft --> Search["按真实主字段精确查重"] + Search --> Match{"精确匹配数量"} + Match -->|"多个"| Disambiguate["停止并消歧"] + Match -->|"一个,未明确修订"| Duplicate["停止并报告重复"] + Match -->|"零个或明确修订"| CreateWiki["bot 在配置根节点下创建 Spec — 标题"] + CreateWiki --> Append["append 完整 XML Spec"] + Append --> Fetch{"docs +fetch 完整?"} + Fetch -->|"否"| Stop["停止,不创建 Base"] + Fetch -->|"是"| BaseSpec["创建或明确更新 Base Spec"] + BaseSpec --> Parent["有来源 Issue 时写入所属父项"] + Parent --> Readback["record-get 验证所有字段和最后更新人"] +``` + +### Spec 产物契约 + +Wiki 文档标题为 `Spec — <标题>`,正文包含:Problem Statement、Solution、完整 User Stories、Implementation Decisions、Testing Decisions、Out of Scope 和 Further Notes。 + +对应 Base 记录至少包含: + +| 字段 | 值 | +|---|---| +| `产物类型` | `PRD/Spec` | +| `来源技能` | `to-spec` | +| `工作流阶段` | `规格` | +| `状态` | `ready-for-agent` | +| `协作模式` | `AFK` | +| `产物文档` | Wiki Spec 链接 | +| `结论/摘要` | Problem + Solution 摘要 | +| `验收标准` | 可执行、可验证条件 | +| `所属父项` | 可选的来源 Issue record ID | +| `最后更新人` | 当前已验证 CLI 用户 | + +## 8. to-tickets:从 Spec 到垂直切片依赖图 + +```mermaid +flowchart TD + Spec["已确认 Spec / 计划"] --> Explore["可选:探索代码、prefactor 机会"] + Explore --> Slice["拆成单上下文可完成的 tracer-bullet 垂直切片"] + Slice --> Edges["为每张票声明真实 blocker"] + Edges --> Quiz["用户确认粒度、合并/拆分和依赖边"] + Quiz -->|"调整"| Slice + Quiz -->|"批准"| ResolveParent["解析真实父 Spec record ID"] + ResolveParent --> Search["逐标题查重;歧义时停止"] + Search --> Pass1["第一遍:按依赖顺序创建全部 Ticket\n暂不写 blocker"] + Pass1 --> IDs["保留每个返回的 record ID"] + IDs --> Pass2["第二遍:写所属父项 + 前置依赖"] + Pass2 --> Readback["逐条 record-get 验证父项、精确 blocker 集合、最后更新人"] + Readback --> Frontier["frontier:所有 blocker 均完成且尚未认领的 Ticket"] +``` + +每个 Ticket 是一条 Base 记录;V1 不创建独立 Wiki 文档。Ticket 的 `产物文档`留空,实现者沿 `所属父项`找到父 Spec,再取得其 Wiki 文档。 + +### 普通垂直切片 + +```mermaid +flowchart LR + A["Ticket A\n完整可验证切片\n无 blocker"] -->|"解锁"| B["Ticket B\n消费 A 的稳定输出"] + B -->|"解锁"| C["Ticket C\n继续扩展端到端行为"] +``` + +### Wide refactor 的 expand–migrate–contract + +```mermaid +flowchart LR + Expand["Expand\n新旧形式并存"] --> M1["Migrate batch 1"] + Expand --> M2["Migrate batch 2"] + Expand --> M3["Migrate batch N"] + M1 --> Contract["Contract\n删除旧形式"] + M2 --> Contract + M3 --> Contract + M1 --> Integrate["可选:integrate-and-verify"] + M2 --> Integrate + M3 --> Integrate +``` + +## 9. triage:Issue / PR 分诊与可恢复上下文 + +### 关注队列 + +每次“显示需要关注的事项”都必须完整分页,并按创建时间从旧到新汇总三类: + +1. `状态`为空或`待分诊`。 +2. `状态=needs-triage`。 +3. `状态=needs-info`且本地比较得到`最后反馈时间 > 最后分诊时间`。 + +不能用单页查询宣称“没有待处理事项”。报告人活动只更新时间,不直接改变状态;后续 triage run 再根据时间门禁重启分诊。 + +### Triage 状态机 + +```mermaid +stateDiagram-v2 + [*] --> 待分诊 + 待分诊 --> NeedsTriage: 初次进入维护者评估 + state "needs-triage" as NeedsTriage + state "needs-info" as NeedsInfo + state "ready-for-agent" as ReadyAgent + state "ready-for-human" as ReadyHuman + + NeedsTriage --> NeedsInfo: 信息不足 + NeedsInfo --> NeedsTriage: 报告人有新反馈\n且反馈时间晚于分诊时间 + NeedsTriage --> ReadyAgent: 事实充分且可委派 + NeedsTriage --> ReadyHuman: 需要人类判断、权限或手工工作 + NeedsTriage --> wontfix: 不实施 + + ReadyAgent --> 进行中: Agent 认领 + ReadyHuman --> 进行中: 人类认领 + 进行中 --> 待评审 + 待评审 --> 已完成 + wontfix --> [*] + 已完成 --> [*] +``` + +每个已分诊项必须恰好拥有: + +- 一个`类别`:`bug`或`enhancement`。 +- 一个 canonical triage `状态`。 + +推荐阶段只读、不写飞书;维护者确认后才更新类别、状态、时间、摘要、证据和下一步。 + +### Outcome 与叙述产物 + +```mermaid +flowchart TD + Outcome{"维护者确认的 outcome"} + Outcome -->|"needs-info"| Notes["Wiki 追加 Triage Notes\n已确认事实 + 具体问题"] + Outcome -->|"ready-for-agent"| Agent["Wiki 追加完整 Agent Brief"] + Outcome -->|"ready-for-human"| Human["Wiki 追加 Human Brief\n注明不能委派原因"] + Outcome -->|"wontfix"| Close["Wiki 追加关闭原因"] + + Notes --> Fetch["fetch 最新 section"] + Agent --> Fetch + Human --> Fetch + Close --> Fetch + Fetch --> BasePatch["更新 Base 状态、产物文档、证据、下一步、时间、最后更新人"] + + Outcome -->|"拒绝 enhancement"| OOS["repo .out-of-scope/.md\n唯一决定事实来源"] + OOS --> CodeRef["Base 代码引用保存 repo 路径"] + Outcome -->|"已实现请求或拒绝 bug"| NoOOS["不写 .out-of-scope/"] +``` + +所有 AI 生成的 triage 文档 section 必须带免责声明。一个 Issue 只复用一份 `Triage — <标题>` dossier,后续 append,不为每个状态新建文档,也不覆盖历史。 + +## 10. 主执行状态机 + +```mermaid +stateDiagram-v2 + [*] --> 草拟中 + 草拟中 --> 待确认 + 待确认 --> ReadyAgent: 可由 Agent 独立执行 + 待确认 --> ReadyHuman: 需要人类处理 + state "ready-for-agent" as ReadyAgent + state "ready-for-human" as ReadyHuman + + ReadyAgent --> 进行中: 设置负责人并认领 + ReadyHuman --> 进行中: 人类认领 + 进行中 --> 阻塞: 出现 blocker + 阻塞 --> 进行中: blocker 已解除 + 进行中 --> 待评审 + 待评审 --> 进行中: 评审要求修改 + 待评审 --> 已完成: 验证证据充分 + + 草拟中 --> 已取代: POC 或被新方案替代 + 待确认 --> 已取代 + ReadyAgent --> 已取代 + 进行中 --> 已取代 + + 已完成 --> [*] + 已取代 --> [*] +``` + +状态一致性规则: + +- `状态=阻塞`时,`阻塞原因`和`下一步`必须非空。 +- 设置`已完成`前必须有具体`验证证据`;无法验证时写“未运行”及原因。 +- POC、废弃版本和超越记录进入`已取代`,不删除审计证据。 +- `完成度`、`下一步`和`阻塞原因`必须与`状态`一致。 + +## 11. 产物与关系模型 + +```mermaid +flowchart LR + External["外部 Issue / PR / 表单"] -->|"来源链接、外部编号、报告人"| Issue["Base:需求/Issue"] + Issue -->|"产物文档"| TriageDoc["Wiki:Triage dossier"] + + Spec["Base:PRD/Spec"] -->|"所属父项"| Issue + Spec -->|"产物文档"| SpecDoc["Wiki:Spec — 标题"] + + TicketA["Base:实现 Ticket A"] -->|"所属父项"| Spec + TicketB["Base:实现 Ticket B"] -->|"所属父项"| Spec + TicketB -->|"前置依赖"| TicketA + + TicketA -.->|"沿父项取得文档"| SpecDoc + TicketB -.->|"沿父项取得文档"| SpecDoc + + Issue -->|"代码引用"| RepoDecision["Repo:代码 / ADR / .out-of-scope/"] + TicketA -->|"代码引用、验证证据"| Code["分支 / commit / PR / 测试"] + TicketB -->|"代码引用、验证证据"| Code +``` + +### 哪个系统保存什么 + +| 信息 | 事实来源 | 原因 | +|---|---|---| +| 当前状态、类别、负责人、进度、时间 | Base | 可筛选、排序、聚合和自动化 | +| 父子关系、阻塞关系 | Base link 字段 | 可计算 frontier,不依赖文字解析 | +| Spec、Triage Notes、Agent/Human Brief | Wiki / Docs | 长文档可读、可追加、可审计 | +| 实现代码、测试、ADR、领域上下文 | repo | 与版本控制一致 | +| 被拒绝 enhancement 的持久决定 | repo `.out-of-scope/` | 避免 Wiki 与 repo 产生两份决定事实 | +| 命令、测试结果、回读事实 | Base `验证证据`,必要时 Wiki 详述 | 完成状态必须可核验 | + +## 12. 身份与“最后更新人” + +```mermaid +sequenceDiagram + participant H as 真实用户 + participant C as Codex / 工作流 + participant A as lark-cli auth + participant B as Feishu bot + participant T as Base record + + H->>C: 确认外部写入 + C->>A: auth status --json --verify + A-->>C: bot verified + user verified + user.openId + C->>C: 冻结 CURRENT_USER_OPEN_ID + C->>B: --as bot 创建或更新记录 + B->>T: payload 包含最后更新人 = user.openId + T-->>C: ok:true + record ID + C->>T: record-get 回读 + T-->>C: 最后更新人显示真实用户 +``` + +这是一条业务审计契约,而不是飞书 UI 的系统“最后操作者”字段: + +- 写入执行者:bot。 +- CLI 工作流真实发起者:`最后更新人`。 +- 当前工作责任人:`负责人`。 +- 每一次 Base create/update 都刷新`最后更新人`,包括仅修改状态、时间、关系、文档链接、证据或终态的 patch。 +- schema、view 和纯读操作没有行级归因目标,不写该字段。 + +## 13. Base 完整字段字典(29 个) + +以下内容来自 2026-07-26 的实时 `field-list` 回读。 + +| # | 字段 | Field ID | 类型 / 取值 | 含义与使用规则 | +|---:|---|---|---|---| +| 1 | 文本 | `fldzLHLTca` | text,主字段 | 记录的业务标题;Spec/Ticket 查重使用真实主字段精确匹配。 | +| 2 | 产物类型 | `fldlwQ46Ks` | single select:需求/Issue、PRD/Spec、实现 Ticket、Wayfinder Map、决策 Ticket、原型、研究、Handoff、ADR、领域词汇、Bug 诊断、代码评审、架构候选、教学资产 | 标识这条记录代表哪一种 Matt 工作流核心产物。 | +| 3 | 来源技能 | `fldUMyVtoS` | multi-select:setup-matt-pocock-skills、grill-with-docs、grill-me、triage、diagnosing-bugs、wayfinder、to-spec、to-tickets、implement、tdd、code-review、improve-codebase-architecture、domain-modeling、prototype、research、handoff、teach | 记录创建或推进该产物的逻辑 Matt skills;使用逻辑流程名,不使用 Feishu 适配器后缀。 | +| 4 | 工作流阶段 | `fldjAkNPqD` | single select:探索/澄清、决策、规格、拆票/规划、实现、验证/评审、交付、维护/学习、分诊 | 产物当前处于端到端流程的哪个阶段;与状态是两个维度。 | +| 5 | 状态 | `fldHjFrlwJ` | single select:草拟中、待确认、待分诊、needs-triage、needs-info、ready-for-agent、ready-for-human、进行中、阻塞、待评审、已完成、wontfix、out-of-scope、已取代 | 全流程统一状态机;英文值保留 Matt triage canonical role 名称。 | +| 6 | 类别 | `fldQWuceDX` | single select:bug、enhancement | Triage category role;每个被分诊项必须且只能有一个。 | +| 7 | 决策票类型 | `fldFpkeDkj` | single select:research、prototype、grilling、task | Wayfinder 子决策票的处理方式;非决策票通常留空。 | +| 8 | 协作模式 | `fldVwgWNRU` | single select:HITL、AFK | HITL 表示人类需要实时参与;AFK 表示 Agent 可独立推进。 | +| 9 | 优先级 | `fldJv2ts2l` | single select:P0、P1、P2、P3 | 表示业务/执行优先级;与依赖 frontier 分开管理。 | +| 10 | 负责人 | `fldGlPa1B1` | user,单值 | 当前直接执行责任人;必须使用真实飞书用户,不用纯文本姓名或 bot 代替。 | +| 11 | 最后更新人 | `fld6nvDu18` | user,单值 | 最近一次通过 lark-cli 创建或更新该记录的真实人类用户;不代表飞书 UI 的 API 操作者。 | +| 12 | 完成度 | `fldqNJjr0g` | number/progress,0–100% | 执行进度;需与当前状态保持一致。 | +| 13 | 产物文档 | `fldorpkrbf` | text/plain | 该记录的 canonical Wiki/长文档链接;Spec 和 Triage dossier 使用,V1 Ticket 留空。 | +| 14 | 验收标准 | `fldwbSY2pq` | text | 可验证完成条件;实现 Ticket 必填,Spec 保存主要测试/验收条件。 | +| 15 | 验证证据 | `fldIQ0NQPO` | text | 实际命令、测试结果、复现、评审或 read-back 事实;终态的重要门禁。 | +| 16 | 结论/摘要 | `fldmdDUJHh` | text | 决策结论、规格摘要、诊断根因、研究摘要或交付结果;长分析放 Wiki。 | +| 17 | 阻塞原因 | `fldUsFDsTS` | text | 仅`阻塞`或`needs-info`时填写;说明当前为何不能继续。 | +| 18 | 下一步 | `fldMY6XATm` | text | 解除阻塞或进入下一阶段所需的最小、直接动作。 | +| 19 | 代码引用 | `fldNylIQ5y` | text | 分支、commit、PR、文件路径、review fixed point 或 `.out-of-scope/` 路径。 | +| 20 | 截止时间 | `fldZP6Cm30` | datetime,`yyyy-MM-dd HH:mm` | 人工承诺的截止时间;不是自动推算时间。 | +| 21 | 创建时间 | `fldnPF52hP` | created_at,只读 | 飞书自动记录的行创建时间;关注队列按此从旧到新排序。 | +| 22 | 更新时间 | `fldd3rTk0I` | updated_at,只读 | 飞书自动记录的行更新时间;与业务归因字段不同。 | +| 23 | 所属父项 | `flduS0iiPy` | self-link,双向 | Spec 指向来源 Issue、Ticket 指向父 Spec、决策 Ticket 指向 Wayfinder Map;写入真实 record ID。 | +| 24 | 前置依赖 | `fldYkwZVu1` | self-link,双向 | 指向阻塞当前项的记录;所有依赖完成后当前项才进入 frontier。 | +| 25 | 来源链接 | `fldp4F1S6m` | text/url | 原始 Issue、PR、表单或外部系统 URL。 | +| 26 | 外部编号 | `fldpv8O5OW` | text | 原始外部系统编号;不能当作 Base record ID 使用。 | +| 27 | 报告人 | `fld37AxlZf` | text | 报告人显示名或外部标识;兼容报告人不是飞书用户的场景。 | +| 28 | 最后反馈时间 | `fldTwNj5Uz` | datetime,`yyyy-MM-dd HH:mm` | 报告人或外部来源最近一次新增反馈的时间。 | +| 29 | 最后分诊时间 | `fldNy9eAgM` | datetime,`yyyy-MM-dd HH:mm` | 维护者最近一次确认并写回分诊结果的时间;与反馈时间比较决定 needs-info 是否重入队列。 | + +### Link 字段边界 + +`所属父项`和`前置依赖`是自动化写入的正向事实来源。`lark-cli 1.0.76`可能返回同表双向关系的反向 field ID,但反向字段不一定能独立列出;在 CLI 明确回读证明前,不假设反向字段可以直接寻址。 + +## 14. 关键 CLI 操作模式 + +```bash +# 身份门禁 +lark-cli auth status --json --verify + +# Schema 与记录 +lark-cli base +field-list --base-token --table-id --limit 200 --as bot --format json +lark-cli base +record-search --base-token --table-id --keyword "" --search-field <PRIMARY_FIELD> --as bot --format json +lark-cli base +record-upsert --base-token <BASE_TOKEN> --table-id <TABLE_ID> --json '<FIELD_MAP>' --as bot --format json +lark-cli base +record-upsert --base-token <BASE_TOKEN> --table-id <TABLE_ID> --record-id <RECORD_ID> --json '<PATCH>' --as bot --format json +lark-cli base +record-get --base-token <BASE_TOKEN> --table-id <TABLE_ID> --record-id <RECORD_ID> --as bot --format json + +# Wiki / Docs +lark-cli wiki +node-create --space-id <SPACE_ID> --parent-node-token <ROOT_NODE_TOKEN> --obj-type docx --title "<TITLE>" --as bot --format json +lark-cli docs +update --doc <OBJ_TOKEN> --command append --content @artifact.xml --doc-format xml --as bot --format json +lark-cli docs +fetch --doc <OBJ_TOKEN> --detail with-ids --as bot --format json +``` + +共同约束: + +- `record-upsert`不会按业务标题自动去重;创建前必须查重。 +- link CellValue 必须使用真实 record ID,不能填标题或 Ticket 编号。 +- 文档先成功 fetch,再把 Wiki 链接和相应状态写入 Base。 +- 所有记录 create/update payload 都包含`最后更新人`。 +- 失败后不改用 user 身份,也不改到 Drive 或其他 Wiki 位置。 + +## 15. 已完成的真实 POC + +### 应用身份全流程 POC + +- bot 成功在指定 Wiki 根节点下创建独立 Spec 与 Triage 文档。 +- Wiki 创建结果返回正确的`parent_node_token`、`space_id`和自动用户权限。 +- Base 成功创建 Spec、两张 Ticket 和一条 Issue。 +- Ticket 父项和 blocker 边可回读。 +- Issue 完成`needs-info → reporter feedback → ready-for-agent`时间门禁。 +- 四条 POC Base 记录验收后均标记为`已取代`,Wiki 文档保留审计证据。 + +### 最后更新人 POC + +| 产物 | Base record ID | 最终验证 | +|---|---|---| +| Spec | `recvqrDi2D3ky9` | bot 创建;`最后更新人=于选辉`;状态`已取代` | +| Ticket A | `recvqrDoAyemKF` | 父项指向 Spec;归因正确;状态`已取代` | +| Ticket B | `recvqrDoAyBBZB` | 父项指向 Spec;前置依赖仅指向 Ticket A;归因正确;状态`已取代` | +| Issue | `recvqrDxnqoNUJ` | 完整 triage 状态流、时间门禁、Wiki Agent Brief、归因均通过;状态`已取代` | + +相关文档: + +- [Spec — 最后更新人全流程验证](https://oppeinlink.feishu.cn/wiki/Cu10w5D5CiWetKk6dVfcT52YnNJ) +- [Triage — 状态归因闭环](https://oppeinlink.feishu.cn/wiki/IvpowYL0si7JbVk0TzocQ5yvnPf) +- [Spec — 应用身份全流程验证](https://oppeinlink.feishu.cn/wiki/MacgwbOOpibGaEkH901cZ56AnCe) +- [Triage — 应用身份反馈闭环](https://oppeinlink.feishu.cn/wiki/R9s0whJvGimchUkhnjlcM1wcnkd) + +## 16. 当前验证状态与边界 + +- Base schema 实时回读:29 个字段,`产物文档`唯一存在。 +- Wiki 根节点完整分页:5 个直属子文档,`has_more=false`。 +- 双身份验证:bot 和 user 均为 verified。 +- 四个新 skill 均有`agents/openai.yaml`;受影响 skill 已通过`quick_validate.py`。 +- 所有相关本地 skill、Wiki 文档和当前 vault 中,已移除被替换字段名的旧引用。 +- Ticket V1 有意不创建 Wiki 文档;其长上下文来自父 Spec。 +- `负责人`若无法解析为真实飞书用户就留空并报告,不能填 bot 或伪造数据。 +- 未验证的命令、状态或产物不能写成“已完成”;需明确标记“未运行”及原因。 + +## 17. 最小心智模型 + +```mermaid +flowchart LR + Issue["Issue\n要解决什么"] --> Spec["Spec\n为什么与验收边界"] + Spec --> Tickets["Tickets\n可独立交付的垂直切片"] + Tickets --> Work["实现 / 测试 / 评审"] + Work --> Evidence["验证证据"] + Evidence --> Done["已完成"] + + Base["Base"] -.->|"管理状态、关系、责任、时间"| Issue + Base -.-> Spec + Base -.-> Tickets + Wiki["Wiki"] -.->|"保存 Spec 与 Triage 叙述"| Spec + Repo["Repo"] -.->|"保存代码、测试、ADR、决定"| Work +``` + +一句话总结:**Base 回答“现在是什么状态、由谁负责、依赖谁”,Wiki 回答“为什么这样做、具体要求是什么”,repo 回答“实现和验证事实是什么”;四个 Feishu skills 负责在三者之间建立可回读、可审计的连接。** diff --git a/docs/Matt 工作流 × 飞书 Skills × Trellis Coding 闭环总结.md b/docs/Matt 工作流 × 飞书 Skills × Trellis Coding 闭环总结.md new file mode 100644 index 0000000..d7f886c --- /dev/null +++ b/docs/Matt 工作流 × 飞书 Skills × Trellis Coding 闭环总结.md @@ -0,0 +1,759 @@ +# Matt 工作流 × 飞书 Skills × Trellis Coding 闭环总结 + +> 状态:六个 Feishu workflow skills 已落地;Coding 入队、Trellis 映射、Ticket 部分收口和 Spec 最终收口已通过真实 Base POC。 +> 更新时间:2026-07-27 +> 实际验证项目:`/Users/yuxuanhui/Documents/ai-workflow/project/经销商政策` +> 范围:工作进入、需求澄清、Spec、Tickets、Triage、Inline/Trellis Coding 路由、实现证据、部分收口、归档和最终对账。具体编码规范仍由目标项目自己的 Trellis specs 和 coding skills 决定。 + +## 1. 最终结论 + +这次工作补齐了 Matt 工作流在飞书上的实现侧闭环。现在不只是把需求和计划放进 Base/Wiki,还可以从 Base 选择当前用户负责的工作,路由到 Inline 或 Trellis,实现后按 Ticket 逐步验收,最后在严格门禁下关闭父 Spec。 + +当前完整模型是: + +- **Feishu Base** 管业务状态、责任人、父子关系、依赖、进度和可查询队列。 +- **Feishu Wiki / Docs** 管 Spec、Triage Notes、Agent Brief、Human Brief 等长文档。 +- **Trellis** 管复杂开发的本地任务生命周期、规划产物、执行快照、checkpoint、归档和 journal。 +- **repo** 管代码、测试、commit、ADR、领域知识和可回放的实现证据。 +- **用户** 决定开始哪项工作,并对每张 Ticket 和最终 Spec 分别执行人类 review。 +- **Agent** 负责查询、分析、路由、组织证据和提出精确 patch,但不能绕过人类 review 决定终态。 +- **lark-cli bot** 执行 API;当前已验证人类用户写入 `最后更新人`;`负责人`始终表示工作责任,不被 bot 或操作归因覆盖。 + +```mermaid +flowchart LR + U["用户<br/>选择、review、确认外部写入"] --> Skills["六个 Feishu workflow skills<br/>流程编排与门禁"] + Skills --> Auth["lark-cli 身份门禁<br/>bot + user verified"] + + Auth -->|"--as bot"| Base["Feishu Base<br/>状态、关系、队列、责任"] + Auth -->|"--as bot"| Wiki["Feishu Wiki / Docs<br/>Spec 与长叙述"] + Skills --> Trellis["Trellis<br/>复杂任务生命周期与本地上下文"] + Skills --> Repo["Repository<br/>代码、测试、commit、ADR"] + + Wiki -->|"产物文档"| Base + Base -->|"record IDs + 验收边界"| Trellis + Base -->|"Tickets / frontier"| Trellis + Trellis -->|"checkpoint / archive"| Skills + Repo -->|"验证证据 / 代码引用"| Skills + Skills -->|"最小 patch + 回读"| Base +``` + +## 2. 六个 Feishu workflow skills + +六个 skills 都是全局 skill,source of truth 位于 `~/.agents/skills/<skill-name>/`。它们都配置了 `policy.allow_implicit_invocation: false`,因此涉及真实飞书读写时要求显式调用,不靠模糊意图静默修改外部系统。 + +| Skill | 负责的阶段 | 主要输入 | 主要产物 | 明确不负责 | +|---|---|---|---|---| +| `setup-matt-pocock-skills-feishu` | 仓库接入 | Base URL、Wiki 根 URL、Reuse/Bootstrap 选择 | repo tracker 合约;Bootstrap 时创建 schema、setup Wiki 文档和 POC 记录 | 不在 Reuse 模式修 schema;不猜资源地址 | +| `to-spec-feishu` | 对话 → 可执行规格 | 已澄清对话、代码库、领域词汇、测试 seam | 一份 Wiki Spec + 一条 Base `PRD/Spec` | 不采访式重新澄清;不在 Wiki 未回读前创建 Base Spec | +| `to-tickets-feishu` | Spec → 垂直切片 | 已批准 Spec、Ticket 粒度、依赖边 | 每个切片一条 Base `实现 Ticket` | V1 不为 Ticket 创建 Wiki;不关闭或修改父 Spec | +| `triage-feishu` | Issue/PR 分诊 | 外部请求、代码验证、维护者决定、报告人反馈 | Base Issue 状态 + 可选 Wiki Triage dossier | 不在推荐阶段写状态;不重复创建 dossier | +| `start-work-feishu` | Coding 入队 | 当前用户、Spec/Ticket 队列、用户选择、路由确认 | Inline 会话绑定,或 `1 Spec = 1 task` 的 Trellis mapping;Base `进行中`回写 | 不实现代码;不初始化 Trellis;不启动 sibling Tickets | +| `close-work-feishu` | Coding 收口 | Spec/Tickets、repo/Trellis 证据、人类 review、确认 patch | Ticket 部分收口、Spec 最终收口、失败后的幂等对账 | 不根据测试或 archive 自动完成;不替用户选择完成项 | + +### 2.1 Skill 之间的调用关系 + +```mermaid +flowchart TD + Setup["setup-matt-pocock-skills-feishu<br/>建立项目级 tracker 合约"] --> Intake{"工作从哪里进入?"} + + Intake -->|"已澄清想法 / 对话"| Spec["to-spec-feishu<br/>Wiki Spec + Base Spec"] + Intake -->|"Issue / PR / 表单"| Triage["triage-feishu<br/>分类、验证、澄清、Brief"] + + Triage -->|"needs-info"| Feedback["等待报告人反馈"] + Feedback -->|"最后反馈时间 > 最后分诊时间"| Triage + Triage -->|"ready-for-agent 且需要正式规格"| Spec + Triage -->|"ready-for-agent 且已足够明确"| Start + Triage -->|"ready-for-human"| Human["人类处理"] + Triage -->|"wontfix / out-of-scope"| Stop["保留关闭原因与审计记录"] + + Spec --> Tickets["to-tickets-feishu<br/>Base Ticket 依赖图"] + Spec --> Start["start-work-feishu<br/>选择并开始"] + Tickets --> Start + + Start --> Coding["Inline 或 Trellis Coding"] + Coding --> Close["close-work-feishu<br/>部分 / 最终 / 对账"] + Close -->|"仍有未完成 Ticket"| Coding + Close -->|"全部门禁满足"| Done["Base Spec 已完成<br/>工作流闭环"] +``` + +## 3. 端到端工作流总图 + +下面这张图把需求侧、规划侧、实现侧和收口侧放在同一条链路中。 + +```mermaid +flowchart TD + A["仓库首次接入"] --> B["Setup:验证 Base/Wiki、生成 docs/agents 合约"] + B --> C{"请求入口"} + + C -->|"外部 Issue / PR / 表单"| D["Triage:验证事实与分类"] + D --> D1{"维护者 outcome"} + D1 -->|"needs-info"| D2["Wiki Triage Notes<br/>等待反馈"] + D2 --> D + D1 -->|"ready-for-human"| D3["Human Brief / 人类处理"] + D1 -->|"wontfix"| D4["关闭说明<br/>必要时 repo .out-of-scope"] + D1 -->|"ready-for-agent"| E{"是否需要正式 Spec?"} + + C -->|"已澄清对话"| F["to-spec:确认测试 seam"] + E -->|"是"| F + E -->|"否,范围足够小"| J + + F --> G["Wiki Spec 写入并 fetch 回读"] + G --> H["Base Spec:ready-for-agent"] + H --> I{"是否需要拆 Ticket?"} + I -->|"是"| I1["to-tickets:垂直切片 + blocker 图"] + I -->|"否,简单 Spec"| J["start-work:工作队列"] + I1 --> J + + J --> K["用户选择 record ID"] + K --> L["写前重读:负责人、状态、父项、依赖、更新时间"] + L --> M{"Inline 还是 Trellis?"} + + M -->|"Inline"| N["冻结当前会话 record IDs"] + M -->|"Trellis"| O["查找/创建唯一 task<br/>持久化 mapping 与 artifacts"] + N --> P["用户确认选择、路由和开始 patch"] + O --> P + P --> Q["Base 写进行中 + 实现 + 最后更新人"] + Q --> R["record-get 回读"] + R -->|"Trellis 新任务"| S["task.py start → in_progress"] + R -->|"Inline"| T["Coding 与验证"] + S --> T + + T --> U["收集 diff、测试、浏览器验收、未运行项、代码引用"] + U --> V["close-work:逐 Ticket 验收映射"] + V --> W["人类 review 并选择可关闭 Ticket IDs"] + W --> X["Ticket 最小 patch + 逐条回读"] + X --> Y{"所有子 Tickets 已完成?"} + Y -->|"否"| T + + Y -->|"是"| Z{"最终 Spec 门禁"} + Z -->|"Inline:Spec 证据 + 人类最终 review"| Z1["展示 Spec-only patch"] + Z -->|"Trellis:再加 archive + status=completed"| Z1 + Z1 --> Z2["用户第二次确认 Spec patch"] + Z2 --> Z3["更新 Spec + record-get 回读"] + Z3 --> End["最终闭环完成"] +``` + +## 4. 四类事实源与产物关系 + +### 4.1 产物关系总图 + +```mermaid +flowchart LR + External["外部 Issue / PR / 表单"] -->|"来源链接 / 外部编号 / 报告人"| Issue["Base:需求/Issue"] + Issue -->|"产物文档"| TriageDoc["Wiki:Triage — 标题"] + + Spec["Base:PRD/Spec"] -->|"所属父项"| Issue + Spec -->|"产物文档"| SpecDoc["Wiki:Spec — 标题"] + + Ticket1["Base:实现 Ticket A"] -->|"所属父项"| Spec + Ticket2["Base:实现 Ticket B"] -->|"所属父项"| Spec + Ticket2 -->|"前置依赖"| Ticket1 + + Spec -->|"specRecordId,一对一"| Task["Trellis task"] + Ticket1 -.->|"ticketRecordIds / snapshot"| Task + Ticket2 -.->|"ticketRecordIds / snapshot"| Task + + Task --> PRD["prd.md<br/>Spec 来源与验收边界"] + Task --> Design["design.md<br/>复杂任务技术设计"] + Task --> Impl["implement.md<br/>Ticket frontier + checkpoint"] + Task --> JSONL["implement.jsonl / check.jsonl<br/>必要 spec / research 清单"] + Task --> Archive["archive task.json<br/>status=completed"] + + Repo["repo:代码 / 测试 / ADR / commits"] -->|"验证证据 / 代码引用"| Ticket1 + Repo -->|"验证证据 / 代码引用"| Ticket2 + Archive -->|"最终生命周期门禁"| Spec + Ticket1 -->|"全部严格已完成"| Spec + Ticket2 -->|"全部严格已完成"| Spec +``` + +### 4.2 哪个系统保存什么 + +| 信息 | 事实来源 | 说明 | +|---|---|---| +| 当前业务状态、负责人、完成度、优先级、时间 | Base | 面向队列、筛选、自动化和团队可见性 | +| 父子层级和 blocker 边 | Base `所属父项`、`前置依赖` | 使用真实 record ID;用于计算 frontier | +| Spec 与 Triage 长叙述 | Wiki / Docs | 可读、可追加、可审计 | +| 复杂任务的本地生命周期 | Trellis | planning、in_progress、archive、journal | +| 当前复杂任务的执行快照 | Trellis `prd.md`、`implement.md` | 可从 Base/Wiki 刷新,不反向覆盖 Base 业务事实 | +| 代码、测试、commit、ADR、领域知识 | repo | 版本控制事实来源 | +| 完成证明 | Base `验证证据` + `代码引用` | 内容来自 repo、真实命令、浏览器验收和 Trellis checkpoint | +| 被拒绝 enhancement 的持久决定 | repo `.out-of-scope/` | Wiki 只记录 outcome/link,不复制第二份 canonical decision | + +## 5. Setup、Spec、Tickets 与 Triage 的逻辑 + +### 5.1 Setup:建立可执行 tracker 合约 + +```mermaid +flowchart TD + A["读取仓库现状"] --> B["用户提供 Base URL + Wiki 根 URL"] + B --> C{"Setup 模式"} + C -->|"Reuse,推荐"| D["只读验证身份、资源和完整 schema"] + C -->|"Bootstrap"| E["展示缺失字段、Wiki setup 标题、POC 标题"] + D --> F{"29 字段兼容?"} + F -->|"否"| G["停止;询问切换 Bootstrap 或单独 repair 授权"] + F -->|"是"| H["展示 repo-local 合约草案"] + E --> I["用户确认外部写入"] + I --> J["只创建缺失字段"] + J --> K["创建 Wiki setup 文档并 fetch"] + K --> L["创建 POC Base 记录并 record-get"] + L --> H + H --> M["生成 AGENTS/CLAUDE Agent skills 区块"] + M --> N["生成 docs/agents/issue-tracker.md"] + N --> O["生成 domain / triage 合约"] +``` + +Setup 的关键产物是项目级 `docs/agents/issue-tracker.md`。后续所有 Feishu skills 必须先读它,从中取得真实 Base、table、view、主字段、Wiki root、字段取值、身份和完成门禁,不能从别的项目或相似标题推断资源。 + +### 5.2 to-spec:一份长规格 + 一条可查询记录 + +```mermaid +sequenceDiagram + participant U as 用户 + participant S as to-spec-feishu + participant W as Wiki / Docs + participant B as Base + + S->>S: 读取对话、代码库、领域词汇和 ADR + S-->>U: 提议最高可用测试 seam + U->>S: 确认 seam + S->>B: 按真实主字段精确查重 + S->>W: 创建 Spec — 标题 + S->>W: append 完整 Spec XML + S->>W: docs +fetch + alt Wiki 内容完整 + S->>B: 创建 PRD/Spec 记录 + S->>B: record-get 回读全部字段 + else Wiki 写入或 fetch 不完整 + S-->>U: 停止,不创建 Base Spec + end +``` + +Wiki Spec 包含 Problem Statement、Solution、User Stories、Implementation Decisions、Testing Decisions、Out of Scope 和 Further Notes。Base Spec 保存 `ready-for-agent`、Wiki 链接、摘要、验收标准和可选来源 Issue。 + +### 5.3 to-tickets:两遍发布依赖图 + +```mermaid +flowchart TD + Spec["已批准 Spec"] --> Slice["拆成单上下文可验证的 tracer-bullet"] + Slice --> Edge["声明真实 blocker"] + Edge --> Quiz["用户确认粒度、拆分、合并和依赖"] + Quiz -->|"调整"| Slice + Quiz -->|"批准"| Parent["解析父 Spec record ID"] + Parent --> Search["逐标题查重"] + Search --> Pass1["Pass 1:按依赖顺序创建 Ticket<br/>暂不写 blocker"] + Pass1 --> IDs["冻结返回的 record IDs"] + IDs --> Pass2["Pass 2:写所属父项 + 前置依赖"] + Pass2 --> Verify["逐条回读父项、blocker 集、验收和最后更新人"] + Verify --> Frontier["frontier = 状态可开始<br/>且每个 blocker 恰好为已完成"] +``` + +Ticket V1 不创建 Wiki 文档,`产物文档`留空。实现者通过 `所属父项`找到父 Spec,再从父 Spec 的 `产物文档`取得完整规格。 + +### 5.4 triage:请求进入工程流程的 on-ramp + +```mermaid +stateDiagram-v2 + [*] --> 待分诊 + 待分诊 --> NeedsTriage: 维护者开始评估 + state "needs-triage" as NeedsTriage + state "needs-info" as NeedsInfo + state "ready-for-agent" as ReadyAgent + state "ready-for-human" as ReadyHuman + + NeedsTriage --> NeedsInfo: 信息不足,写 Triage Notes + NeedsInfo --> NeedsTriage: 最后反馈时间晚于最后分诊时间 + NeedsTriage --> ReadyAgent: 事实与验收足够,可委派 + NeedsTriage --> ReadyHuman: 需要判断、权限或手工工作 + NeedsTriage --> wontfix: 不实施 + + ReadyAgent --> 进行中: 被 start-work 认领 + ReadyHuman --> 进行中: 人类认领 + wontfix --> [*] +``` + +Triage 的推荐与验证阶段只读。维护者确认 outcome 后,才写唯一 `类别`、唯一 canonical `状态`、`最后分诊时间`、摘要、证据、下一步和 `最后更新人`。需要长叙述时,一个 Issue 只创建并持续 append 一份 `Triage — <标题>` Wiki dossier。 + +## 6. `start-work-feishu`:Coding 入队与路由 + +### 6.1 队列口径 + +Skill 会冻结当前已验证用户的 open ID,然后分别完整分页查询: + +- Spec:`产物类型=PRD/Spec`,且 **Spec 自身** `负责人=当前用户`。 +- Ticket:`产物类型=实现 Ticket`,且 **Ticket 自身** `负责人=当前用户`。 + +子 Ticket 归当前用户不会让父 Spec 自动进入 Spec 队列。父 Spec 只作为 Ticket 的上下文展示。 + +| 分组 | 条件 | 是否可选择 | +|---|---|---| +| 可恢复 | `进行中`或`阻塞` | 可以,但阻塞项必须展示原因,不暗示已解除 | +| 可开始 | `ready-for-agent`;Ticket 无 blocker 或所有 blocker 都恰好为`已完成` | 可以 | +| 待收口 | `待评审` | 不重新开始,转 `close-work-feishu` | +| 被阻塞 | `ready-for-agent`,但任一 blocker 不是`已完成` | 不可开始 | +| 排除 | 草拟、triage、人类专属和终态记录 | 不进入 coding queue | + +`wontfix`、`out-of-scope`、`已取代`虽然是终态,但不能自动证明依赖要求已交付,因此不算满足 blocker。 + +### 6.2 Start skill 内部逻辑 + +```mermaid +flowchart TD + A["显式调用 start-work-feishu"] --> B["读取项目 tracker 合约与 Trellis workflow"] + B --> C["验证 bot + user,冻结当前 user open ID"] + C --> D["field-list 验证 29 字段和枚举"] + D --> E["完整分页查询 Spec 队列"] + E --> F["完整分页查询 Ticket 队列"] + F --> G["按 record ID 读取父项与 blocker"] + G --> H["计算可恢复 / 可开始 / 待收口 / 被阻塞"] + H --> I["用户选择 number 或 record ID"] + I --> J["重读选中项、父 Spec、全部子 Tickets、blockers"] + J --> K{"负责人、状态、关系或更新时间漂移?"} + K -->|"是"| H + K -->|"否"| L{"建议路由"} + + L -->|"小、明确、单上下文"| M["Inline:冻结本会话 IDs 与快照"] + L -->|"跨模块、多会话、长验收链"| N["Trellis:扫描现有 mapping"] + N --> O{"匹配 task 数量"} + O -->|"多个"| Stop["停止,报告冲突"] + O -->|"一个"| Resume["恢复已有 task"] + O -->|"零个"| Create["task.py create --no-start"] + Resume --> Persist["刷新 prd / implement / mapping"] + Create --> Persist + Persist --> ReadMap["回读完整 meta.feishuTracker"] + + M --> Confirm["一次确认:工作项 + 路由 + Base patch"] + ReadMap --> Confirm + Confirm --> Patch["按 record ID 写进行中 / 实现 / 最后更新人"] + Patch --> ReadBase["逐条 record-get 回读"] + ReadBase --> Route{"路由"} + Route -->|"Inline"| Coding["交给当前会话实现"] + Route -->|"新建或 planning task"| Start["task.py start"] + Start --> VerifyTask["回读 task.json status=in_progress"] +``` + +### 6.3 Inline 与 Trellis 的判断 + +| 路由 | 适用情况 | 本地持久化 | +|---|---|---| +| Inline | 范围窄、方案已知、一个健康上下文可完成、最低验证可在当前会话完成 | 只在当前对话冻结 record IDs,不创建 mapping 文件 | +| Trellis | 跨模块、多阶段、多个稳定决策、durable research、多会话或验收链较长 | 创建或恢复唯一 task,持久化 Spec mapping、规划产物和 Ticket snapshot | + +这里的 Inline 是“完全不创建 Trellis task”。它和 Trellis 内部 Codex `dispatch_mode=inline`不是同一概念;后者仍然已经处在 Trellis task 内。 + +### 6.4 `1 Spec = 1 Trellis task` mapping + +```json +{ + "meta": { + "feishuTracker": { + "schemaVersion": 1, + "specRecordId": "rec_xxx", + "ticketRecordIds": ["rec_aaa", "rec_bbb"], + "selectedRecordIds": ["rec_aaa"], + "specWikiUrl": "https://...", + "trackerContractPath": "docs/agents/issue-tracker.md", + "boundAt": "ISO-8601", + "lastRefreshAt": "ISO-8601" + } + } +} +``` + +- `specRecordId` 是一对一绑定的稳定键。 +- `ticketRecordIds` 是刷新时全部子 Tickets 的排序去重快照,不是 Base 的替代事实源。 +- `selectedRecordIds` 是这次用户直接选择的 Spec 或 Ticket。 +- `boundAt` 首次绑定后不变;`lastRefreshAt` 随成功刷新更新。 +- mapping 不保存 Base token、凭证或固定个人 open ID。 +- 只更新 `meta.feishuTracker`,保留 `task.json`其他字段和未知未来键。 + +### 6.5 开始 patch + +```json +{ + "状态": "进行中", + "工作流阶段": "实现", + "最后更新人": [{"id": "<CURRENT_USER_OPEN_ID>"}] +} +``` + +- 选择 Spec:只写 Spec。 +- 选择 Ticket:写选中的 Ticket 和它的父 Spec。 +- 不修改`负责人`、`完成度`、sibling Tickets、证据、blocker 或下一步。 +- Trellis 新任务只有在 mapping 持久化成功、Base 写入成功且回读一致后才执行 `task.py start`。 + +## 7. Trellis Coding 生命周期 + +```mermaid +stateDiagram-v2 + [*] --> planning: task.py create --no-start + planning --> in_progress: task.py start + in_progress --> in_progress: implement / check / update-spec / commit + in_progress --> Detached: task.py finish + state "session detached\n任务未完成" as Detached + Detached --> in_progress: 其他 session 可继续 + in_progress --> completed: task.py archive + completed --> Archived: 移入 archive tree + state "archive/task.json\nstatus=completed" as Archived +``` + +关键边界: + +- `task.py finish`只清除当前 session 的任务指针,不能作为 Base 完成信号。 +- 复杂任务通常经历 `implement → check → update-spec → 工作 commit → finish-work/archive → journal`。 +- `after_archive`最多作为提醒或待对账信号;显式 `close-work-feishu`才有资格在回读后声称 Base 已闭环。 +- Ticket 部分收口不要求 archive;父 Spec 最终收口才要求归档 task 且`status=completed`。 + +## 8. `close-work-feishu`:部分收口、最终收口与对账 + +### 8.1 三个内部 routing + +| Routing | 进入条件 | 结果 | +|---|---|---| +| 部分收口 | 有一个或多个 Ticket 已有直接证据,并完成对应人类 review | 只关闭用户选中的 Ticket;Spec 保持`进行中` | +| 最终收口 | 全部 Ticket 已完成,Spec 验收有证据,人类完成最终 review;Trellis 路径还必须 archive | 用户再次确认 Spec-only patch 后关闭 Spec | +| 对账重放 | 上次写入部分成功、回读失败或记录已在目标终态 | 只补差异;证据完整时返回`already synchronized`,不重复追加 | + +### 8.2 Close skill 完整逻辑 + +```mermaid +flowchart TD + A["显式调用 close-work-feishu"] --> B["用 active/archived mapping 或 Inline 会话定位 Spec ID"] + B --> C["验证身份、schema、Spec 类型"] + C --> D["按父 Spec 完整分页查询全部子 Tickets"] + D --> E["比较 live Ticket 集与 Trellis snapshot"] + E --> F["汇总验收标准、repo diff、测试、浏览器验收、未运行项、代码引用、checkpoint"] + F --> G["逐 Ticket 映射验收证据"] + G --> H{"分类"} + H --> H1["建议可收口"] + H --> H2["待补证 / 待验证"] + H --> H3["明确未完成 / 阻塞"] + + H1 --> I["展示精确 Ticket patch"] + H2 --> Wait["保持原状态,说明最小下一步"] + H3 --> Wait + I --> J["用户声明已完成人类 review<br/>并选择允许关闭的 record IDs"] + J --> K["写前逐条重读,检查 owner、状态、父项、依赖、验收、证据、更新时间"] + K --> L{"是否漂移?"} + L -->|"是"| I + L -->|"否"| M["批量最小 patch,最多 200 条且串行"] + M --> N["逐条 record-get 回读"] + N --> O{"失败 / ignored / mismatch?"} + O -->|"是"| Reconcile["输出成功、失败、待对账清单<br/>禁止关闭 Spec"] + O -->|"否"| P["重新完整查询所有子 Tickets"] + P --> Q{"是否全部严格为已完成?"} + Q -->|"否"| Partial["部分收口完成<br/>Spec 保持进行中"] + Q -->|"是"| R{"Spec 级最终门禁"} + R -->|"未满足"| Hold["Spec 不变,报告缺失门禁"] + R -->|"满足"| S["展示独立 Spec-only patch"] + S --> T["用户第二次确认"] + T --> U["立即重读 Spec;漂移则确认失效"] + U --> V["写 Spec + record-get 回读"] + V --> Done["最终收口回执"] +``` + +### 8.3 Ticket 完成 patch + +```json +{ + "状态": "已完成", + "工作流阶段": "交付", + "完成度": 1, + "验证证据": "<保留旧内容并追加一次 Ticket 专属 closure section>", + "代码引用": "<保留并去重的真实引用>", + "阻塞原因": null, + "下一步": null, + "最后更新人": [{"id": "<CURRENT_USER_OPEN_ID>"}] +} +``` + +每个 closure section 至少记录:人类 review、验收到证据的映射、真实验证命令和结果、明确未运行项及原因。不能用 Agent review、测试通过、Trellis `finish`或 archive 单独替代人类 review。 + +### 8.4 Spec 最终门禁 + +```mermaid +flowchart LR + A["全部子 Tickets<br/>状态恰好为已完成"] --> Gate{"Spec 最终门禁"} + B["Spec 每条验收标准<br/>都有直接证据"] --> Gate + C["用户完成 Spec<br/>最终代码/功能 review"] --> Gate + D["Trellis 路径:task 位于 archive<br/>且 status=completed"] --> Gate + E["不存在 Ticket write/read-back 失败"] --> Gate + Gate -->|"全部满足"| Patch["展示 Spec-only patch"] + Patch --> Confirm["用户单独确认"] + Confirm --> Done["写入 + 回读后才算闭环"] +``` + +`wontfix`、`out-of-scope`、`已取代`不自动算作“全部 Ticket 已完成”。无 Ticket 的简单 Spec 可以跳过 Ticket 门禁,但仍需 Spec 验收证据、人类最终 review,以及适用的 Trellis archive 门禁。 + +## 9. 身份、确认与写后回读协议 + +```mermaid +sequenceDiagram + participant U as 用户 + participant S as Feishu skill + participant A as lark-cli auth + participant B as Feishu Base + + U->>S: 显式调用 skill + S->>A: auth status --json --verify + A-->>S: bot verified + user verified + user.openId + S->>S: 冻结 CURRENT_USER_OPEN_ID + S->>B: --as bot 读取 schema / records + B-->>S: 当前快照 + S-->>U: 展示稳定 record IDs 与精确 patch + U->>S: 明确确认外部写入 + S->>B: 写前按 record ID 重读 + B-->>S: 无漂移 + S->>B: --as bot 最小 patch<br/>最后更新人=user.openId + B-->>S: ok:true + S->>B: record-get / 完整分页回读 + B-->>S: 字段与关系符合预期 + S-->>U: 完成回执 +``` + +统一规则: + +1. 每条 Base read/write 都使用 `--as bot --format json`,失败后不降级为 user。 +2. `负责人`是 assignee;`最后更新人`是最近一次通过 CLI 推进记录的真实人类;bot 只是 API caller。 +3. 标题是展示文本,record ID 才是更新键。 +4. 写前展示目标记录和精确 patch;写后必须回读。 +5. `ok:true`不证明 record 存在或字段已生效;`ignored_fields`和 read-back mismatch 都算失败。 +6. schema、视图和只读操作没有行级归因目标,不写`最后更新人`。 + +## 10. Base 主状态机与 Trellis 映射 + +### 10.1 Base 主状态机 + +```mermaid +stateDiagram-v2 + [*] --> 草拟中 + 草拟中 --> 待确认 + 待确认 --> ReadyAgent: 可由 Agent 执行 + 待确认 --> ReadyHuman: 需要人类执行 + state "ready-for-agent" as ReadyAgent + state "ready-for-human" as ReadyHuman + + ReadyAgent --> 进行中: start-work 确认并回写 + ReadyHuman --> 进行中: 人类认领 + 进行中 --> 阻塞: 发生 blocker + 阻塞 --> 进行中: blocker 解除 + 进行中 --> 待评审: 进入 review + 待评审 --> 进行中: review 要求修改 + 待评审 --> 已完成: 人类 review + 直接证据 + + 草拟中 --> 已取代 + 待确认 --> 已取代 + ReadyAgent --> 已取代 + 进行中 --> 已取代 + ReadyAgent --> OutOfScope: 范围外 + state "out-of-scope" as OutOfScope + + 已完成 --> [*] + 已取代 --> [*] + OutOfScope --> [*] +``` + +### 10.2 Trellis 事件到 Base 的业务含义 + +| Trellis / 本地事件 | Base 动作 | 原因 | +|---|---|---| +| 只读列队、用户未选择 | 不写 | 浏览队列不是认领 | +| mapping 保存成功,用户确认“选择并开始” | Spec 或 Ticket/父 Spec → `进行中`、`实现` | 表示进入规划/执行,不猜完成度 | +| `planning` / `after_start` | 通常不重复写 | Start skill 已完成开始回写 | +| 发生外部 blocker | `阻塞`,并填写`阻塞原因`和`下一步` | 状态与解释必须一致 | +| Agent 建议可收口但无人类 review | 保持原状态 | Agent 只能推荐 | +| 部分收口 | 仅用户选中的 Tickets → `已完成` | 父 Spec 保持`进行中` | +| `task.py finish` / `after_finish` | 不写完成态 | 只代表 session detach | +| `archive` / `after_archive` | 不自动写完成态 | 只满足 Spec 生命周期门禁之一 | +| 全 Ticket 完成 + Spec 验收 + 人类最终 review + archive | Spec → `已完成`、`交付`、`完成度=1` | 最终聚合收口 | +| Base 同步失败 | 保留真实现状并输出待对账 | 代码/Trellis 完成与外部同步分开报告 | + +## 11. Base 完整字段字典(29 个) + +以下字段来自“经销商政策”项目配置的真实 Base `field-list`回读。`文本`是当前表的主字段。 + +| # | 字段 | Field ID | 类型 / 当前取值 | 含义与规则 | +|---:|---|---|---|---| +| 1 | 文本 | `fldzLHLTca` | text,主字段 | 记录的业务标题。标题可用于创建前精确查重,但更新必须使用 record ID。 | +| 2 | 产物类型 | `fldlwQ46Ks` | single select:需求/Issue、PRD/Spec、实现 Ticket、Wayfinder Map、决策 Ticket、原型、研究、Handoff、ADR、领域词汇、Bug 诊断、代码评审、架构候选、教学资产 | 说明该记录代表哪类工作流产物。 | +| 3 | 来源技能 | `fldUMyVtoS` | multi-select:setup-matt-pocock-skills、setup-matt-pocock-skills-feishu、grill-with-docs、grill-me、triage、diagnosing-bugs、wayfinder、to-spec、to-tickets、implement、tdd、code-review、improve-codebase-architecture、domain-modeling、prototype、research、handoff、teach | 记录创建或推进产物的逻辑流程。业务记录通常写逻辑 skill 名;当前表也保留 setup 的 Feishu 适配器选项。 | +| 4 | 工作流阶段 | `fldjAkNPqD` | single select:探索/澄清、决策、规格、拆票/规划、实现、验证/评审、交付、维护/学习、分诊 | 表示产物处于端到端流程哪一阶段;与`状态`是不同维度。 | +| 5 | 状态 | `fldHjFrlwJ` | single select:草拟中、待确认、待分诊、needs-triage、needs-info、ready-for-agent、ready-for-human、进行中、阻塞、待评审、已完成、wontfix、out-of-scope、已取代 | 统一业务状态机。英文值保留 Matt triage canonical role。 | +| 6 | 类别 | `fldQWuceDX` | single select:bug、enhancement | Triage 分类;每个已分诊项必须恰好一个。 | +| 7 | 决策票类型 | `fldFpkeDkj` | single select:research、prototype、grilling、task | Wayfinder 子决策票的解决方式;非决策票通常留空。 | +| 8 | 协作模式 | `fldVwgWNRU` | single select:HITL、AFK | HITL 需要人类实时参与;AFK 表示 Agent 可以独立推进到下一个门禁。 | +| 9 | 优先级 | `fldJv2ts2l` | single select:P0、P1、P2、P3 | 业务/执行优先级;不替代 blocker frontier。 | +| 10 | 负责人 | `fldGlPa1B1` | user,单值 | 当前直接执行责任人。必须是真实飞书用户;Start/Close skills 不覆盖它。 | +| 11 | 最后更新人 | `fld6nvDu18` | user,单值 | 最近一次通过 lark-cli 创建或更新记录的真实人类用户;不是 bot,也不是飞书系统更新时间。 | +| 12 | 完成度 | `fldqNJjr0g` | number/progress,0–1 | 业务进度。Base 显示为百分比;最终完成写 JSON number `1`。 | +| 13 | 产物文档 | `fldorpkrbf` | text/plain | canonical Wiki 或长文档链接。Spec/Triage 使用;V1 Ticket 留空并沿父 Spec 取文档。 | +| 14 | 验收标准 | `fldwbSY2pq` | text | 可验证的完成条件。实现 Ticket 必填;Spec 保存聚合验收边界。 | +| 15 | 验证证据 | `fldIQ0NQPO` | text | 真实命令、测试结果、浏览器验收、review、read-back 事实和未运行原因。没有具体证据不能完成。 | +| 16 | 结论/摘要 | `fldmdDUJHh` | text | Problem/Solution 摘要、决策结论、诊断根因、研究摘要或交付结果;长分析放 Wiki。 | +| 17 | 阻塞原因 | `fldUsFDsTS` | text | 仅`阻塞`或`needs-info`等无法继续的状态使用;说明为什么不能推进。 | +| 18 | 下一步 | `fldMY6XATm` | text | 解除阻塞或进入下一阶段的最小动作;完成态清空。 | +| 19 | 代码引用 | `fldNylIQ5y` | text | 分支、commit、PR、文件:行号、Trellis checkpoint、review fixed point 或`.out-of-scope/`路径。只写真实存在的引用。 | +| 20 | 截止时间 | `fldZP6Cm30` | datetime,`yyyy-MM-dd HH:mm` | 人工承诺的截止时间,不由 Agent 自动推算。 | +| 21 | 创建时间 | `fldnPF52hP` | created_at,只读 | Base 自动记录的创建时间;Triage 关注队列按它从旧到新排序。 | +| 22 | 更新时间 | `fldd3rTk0I` | updated_at,只读 | Base 自动记录的行更新时间;用于竞态检测,不等于`最后更新人`。 | +| 23 | 所属父项 | `flduS0iiPy` | self-link,双向 | Spec 指向来源 Issue;Ticket 指向父 Spec;决策 Ticket 指向 Wayfinder Map。写真实 record ID。 | +| 24 | 前置依赖 | `fldYkwZVu1` | self-link,双向 | 指向阻塞当前项的记录。只有所有 blocker 都恰好为`已完成`时 Ticket 才进入 frontier。 | +| 25 | 来源链接 | `fldp4F1S6m` | text/url | 原始 Issue、PR、表单或外部系统 URL。 | +| 26 | 外部编号 | `fldpv8O5OW` | text | 外部系统编号。它不是 Base record ID,不能用作更新键或 link CellValue。 | +| 27 | 报告人 | `fld37AxlZf` | text | 报告人的显示名或外部标识;兼容报告人不是飞书用户。 | +| 28 | 最后反馈时间 | `fldTwNj5Uz` | datetime,`yyyy-MM-dd HH:mm` | 报告人或外部来源最近一次新增反馈时间。只更新时间,不自动改状态。 | +| 29 | 最后分诊时间 | `fldNy9eAgM` | datetime,`yyyy-MM-dd HH:mm` | 维护者最近一次确认并写回分诊结果的时间。`最后反馈时间 > 最后分诊时间`时,needs-info 重新进入关注队列。 | + +### 11.1 Link 字段边界 + +`所属父项`和`前置依赖`的正向字段是自动化 source of truth。`lark-cli 1.0.76`可能返回同表双向关系的 reverse field ID,但 reverse 字段不一定独立出现在`field-list`,因此当前实现不依赖反向字段寻址。 + +## 12. 真实 POC:经销商政策项目 + +### 12.1 POC 对象 + +| 产物 | Record ID / 路径 | 最终状态 | +|---|---|---| +| Spec:历史报告多条件检索 | `recvquNpDDOafu` | `已完成 / 交付 / 1` | +| Ticket A:按事业部和分析类型筛选历史报告 | `recvquNtBMcQ2V` | `已完成 / 交付 / 1` | +| Ticket B:按关键词搜索并完善筛选反馈 | `recvquNxjmWwth` | `已完成 / 交付 / 1` | +| Trellis task | `.trellis/tasks/archive/2026-07/07-27-feishu-recvqunpddoafu` | archive 中,`task.json.status=completed` | +| 工作 commit | `e7270cf` | `feat: 支持历史报告多条件检索` | +| 规范 commit | `1f00f51` | `docs: 沉淀报告检索状态同步契约` | +| 归档 commit | `30b9c8f` | `chore(task): archive 07-27-feishu-recvqunpddoafu` | +| journal commit | `3e91199` | `chore: record journal` | + +### 12.2 真实执行时序 + +```mermaid +sequenceDiagram + participant U as 于选辉 + participant S as start-work-feishu + participant B as Feishu Base + participant T as Trellis + participant C as Coding / Check + participant X as close-work-feishu + + U->>S: 选择历史报告多条件检索工作 + S->>B: 查询 Spec、Tickets、父项和 blocker + S->>T: 创建并保存 1 Spec = 1 task mapping + S->>B: 写 Spec/Ticket 进行中并回读 + S->>T: task.py start + + T->>C: 实现 Ticket A + C-->>U: 代码、测试和构建证据 + U->>X: 已完成 Ticket A 人类 review + X->>B: 关闭 recvquNtBMcQ2V 并回读 + B-->>X: Ticket A 已完成,Ticket B blocker 解锁 + + T->>C: 实现 Ticket B + C-->>U: API、前端、构建、真实浏览器与竞态证据 + U->>X: 已完成 Ticket B 人类 review + X->>B: 关闭 recvquNxjmWwth 并回读 + B-->>X: 两张 Ticket 全部已完成 + + C->>T: update-spec + commits + U->>T: 授权 finish-work + T->>T: archive task + journal + U->>X: 已完成 Spec 最终 review + X->>B: 重新查询全部 Tickets 与 Spec + X-->>U: 展示 Spec-only 精确 patch + U->>X: 第二次确认最终 patch + X->>B: 更新 Spec 已完成并 record-get + B-->>X: 已完成 / 交付 / 1,负责人和验收保持不变 +``` + +### 12.3 实现与验证结果 + +本次 Spec 实现了:事业部、分析类型、标题/文件名关键词组合检索;条件使用 AND 语义;关键词去除首尾空白并对拉丁字符大小写不敏感;无筛选兼容旧行为;筛选后详情与列表保持一致;区分空仓库和筛选无结果;支持一键清空;旧请求不能覆盖新筛选结果。 + +真实验证证据: + +- `pytest -q tests/test_api.py -k reports`:`9 passed, 11 deselected`。 +- 可执行后端回归:`37 passed, 1 deselected`。 +- 前端 `npm test`:`4 passed`。 +- 前端 `npm run build`:通过,仅保留既有 large-chunk advisory。 +- Trellis task validation:通过。 +- `git diff --check`:通过。 +- 真实浏览器验收:文件名关键词、大小写不敏感三条件组合、当前条件/结果数反馈、筛选无结果、详情清空与恢复、一键清空全部通过。 +- 受控请求竞态:较早的延迟响应未覆盖较新的筛选结果。 +- 浏览器 console 仅出现与本功能无关的 `favicon.ico` 404。 +- 完整 pytest 未运行成功的原因被明确保留:既有缺失模块/import collection errors,以及本次 diff 外的`policy_data` 404;没有把未运行项伪报为通过。 + +### 12.4 POC 证明了什么 + +```mermaid +flowchart LR + A["当前用户负责人过滤"] --> Proof["真实 POC 通过"] + B["Ticket blocker frontier"] --> Proof + C["稳定 record ID 与 Trellis mapping"] --> Proof + D["1 Spec = 1 task"] --> Proof + E["Ticket 逐张人类 review"] --> Proof + F["部分收口不关闭 Spec"] --> Proof + G["archive 不是自动完成授权"] --> Proof + H["Spec 第二次确认"] --> Proof + I["写前重读 + 写后回读"] --> Proof + J["最后更新人归因"] --> Proof + K["未运行项显式记录"] --> Proof +``` + +本次 demo POC 仅对“planning artifacts 必须经人类 review 后才能 `task.py start`”放宽了一次;Ticket review、Spec 最终 review、外部写入确认和回读门禁均未放宽。最终 Spec 的 Base 回读时间为 `2026-07-27 10:04:12`,`负责人`和`最后更新人`均为于选辉,验收标准和关联字段保持不变。未执行 push。 + +## 13. 失败处理与幂等对账 + +```mermaid +flowchart TD + A["任一步失败"] --> B{"失败位置"} + B -->|"身份 / schema / 查询"| C["不做任何本地或外部写入"] + B -->|"选择后发生漂移"| D["旧确认失效,重新展示队列或 patch"] + B -->|"task / artifact / mapping"| E["不写 Base,保留明确失败原因"] + B -->|"Base 开始写失败"| F["task 保持 planning<br/>报告 mapping 已保存但未同步"] + B -->|"Base 成功,Trellis start 失败"| G["Base 已认领<br/>Trellis 待启动,不自动回滚"] + B -->|"Ticket batch 部分失败"| H["保留逐条成功/失败<br/>禁止关闭 Spec"] + B -->|"write ok 但回读 mismatch"| I["标记 mismatched,不宣称完成"] + B -->|"记录已完整同步"| J["already synchronized<br/>不重复追加证据"] + H --> K["下次对账只补仍有差异的记录"] + I --> K +``` + +核心原则:外部系统的部分成功不能被一个总体`ok:true`遮蔽;也不能因为 Base 同步失败就篡改已经完成的代码/Trellis事实。回执必须把“代码完成”“Trellis lifecycle 完成”“Base 同步完成”分开报告。 + +## 14. 当前边界与后续演进 + +V1 当前边界: + +- 两个 Coding 闭环 skills 已实现并通过真实 POC。 +- 直接编排项目内`.trellis/scripts/task.py`和`lark-cli`,没有新增 helper CLI。 +- 没有修改 Trellis workflow、hooks 或 Base schema。 +- 不自动 commit、push 或创建 PR;Git 写操作继续遵守用户授权边界。 +- 不把 coding sub-agent 设为 Base 状态决策者;外部选择、review、确认和回读都留在主会话。 + +建议的后续顺序: + +1. 在第二个真实项目重放一次 Inline 路径,验证跨会话时按 record ID 重选的体验。 +2. 演练一次故意的 Base batch 部分失败,验证对账 routing 的逐条补偿。 +3. 演练一次 mapping 冲突和记录竞态,验证确认失效路径。 +4. 稳定后再考虑抽取共享分页/frontier/helper;在两个 skills 尚未形成稳定重复前不提前封装。 +5. 如果接入 lifecycle hook,`after_archive`只提醒或生成不含凭证的 pending 标记,不直接写 Base 完成态。 + +## 15. 一句话心智模型 + +```mermaid +flowchart LR + Issue["Issue<br/>要解决什么"] --> Spec["Spec<br/>为什么做、验收边界"] + Spec --> Tickets["Tickets<br/>可独立交付的垂直切片与依赖"] + Tickets --> Start["Start<br/>选择、路由、认领"] + Start --> Coding["Coding<br/>Inline 或 1 Spec = 1 Trellis task"] + Coding --> Evidence["Evidence<br/>代码、测试、浏览器、review"] + Evidence --> Close["Close<br/>Ticket 部分收口 → Spec 最终收口"] + Close --> Done["Done<br/>写后回读的 Base 闭环"] +``` + +**Base 回答“现在是什么状态、由谁负责、依赖谁”;Wiki 回答“为什么做、具体要求是什么”;Trellis 回答“复杂工作如何规划、执行和归档”;repo 回答“到底实现了什么、验证过什么”;六个 Feishu skills 负责把这些事实源连接成一条可确认、可回读、可重放的工作流。** + +## 16. 相关资料 + +- [Matt 工作流 × 飞书 CLI 全流程总结](<./Matt 工作流 × 飞书 CLI 全流程总结.md>) +- [Trellis × 飞书实现闭环初步方案](<./Trellis × 飞书实现闭环初步方案.md>) +- 经销商政策项目 tracker 合约:`/Users/yuxuanhui/Documents/ai-workflow/project/经销商政策/docs/agents/issue-tracker.md` +- 真实 POC 归档任务:`/Users/yuxuanhui/Documents/ai-workflow/project/经销商政策/.trellis/tasks/archive/2026-07/07-27-feishu-recvqunpddoafu` +- Trellis 官方文档:[架构](https://docs.trytrellis.app/zh/advanced/architecture)、[自定义 Workflow](https://docs.trytrellis.app/zh/advanced/custom-workflow)、[自定义 Skills](https://docs.trytrellis.app/zh/advanced/custom-skills)、[自定义 Agents](https://docs.trytrellis.app/zh/advanced/custom-agents)、[配置](https://docs.trytrellis.app/zh/advanced/configuration) diff --git a/docs/Trellis × 飞书实现闭环初步方案.md b/docs/Trellis × 飞书实现闭环初步方案.md new file mode 100644 index 0000000..4010d2b --- /dev/null +++ b/docs/Trellis × 飞书实现闭环初步方案.md @@ -0,0 +1,763 @@ +# Trellis × 飞书实现闭环初步方案 + +> 状态:V1 两个全局 skill 已实现并完成本地结构、契约 fixture 与独立前向验证;真实 Base POC 尚未运行 +> 更新时间:2026-07-26 +> 范围:只讨论“如何发现待实现工作、如何在 Inline / Trellis 之间路由、如何在完成后回写飞书”;不展开具体 coding 规则。 +> 证据分层:文中明确区分「Trellis 官方文档事实」、「现有 Matt 文档提取」和「本文推导 / 推荐」。 + +> 版本注意:本机 `trellis --version` 已核对为 `0.6.8`,本次在线文档导航显示 `0.6.9`。两者在个别配置名称 / 默认值上可能有差异;真实项目 POC 必须以目标项目实际生成的 `.trellis/` 文件、本地脚本和安装版本为准。 + +## 1. 结论先行 + +目前已确认把实现侧闭环定义为: + +1. **飞书 Base 管“待做什么、由谁做、依赖谁、当前业务状态”**,是 Spec / Ticket 队列和对外状态的事实源。 +2. **Trellis 管复杂工作的本地执行上下文**:任务、PRD、技术设计、实施计划、检查上下文、归档和 journal。 +3. **repo 管实现与验证事实**:代码、测试、ADR、差异和可回放的验证结果。 +4. **普通小功能继续 Inline**,不为了状态同步强行创建 Trellis 任务;**复杂功能严格使用“1 Spec = 1 Trellis task”**,Ticket 只作为该 task 内可刷新的实施计划和验收单元,不再映射为 Trellis child task。 +5. 已实现两个职责分离的全局显式 skill: + - **`start-work-feishu`**:识别当前飞书用户,列出其负责的 Spec / Ticket,让用户选择,然后路由到 Inline 或 Trellis。 + - **`close-work-feishu`**:承担“部分收口、最终收口、对账重放”。它按 Spec 查找全部子 Tickets,分析可收口项并交给用户 review / 确认;只有被确认的 Tickets 或 Spec 才写入 `已完成`。 +6. **Trellis 路径的 Spec 最终收口必须以归档事件为准,不能以 `finish` 事件为准**。官方明确:`after_finish` 只表示当前 session 解除任务指针,任务可能仍在其他 session 继续;外部系统 done 应接 `after_archive`。Ticket 的部分收口可提前进行,但不得因此关闭 Spec。[官方:架构全景](https://docs.trytrellis.app/zh/advanced/architecture) +7. **不把 lifecycle hook 当成唯一保障**。官方规定 hook 失败只警告、不阻断主任务操作;因此必须由显式 close skill 完成飞书写入与回读。本方案中 hook 至多记录可重放的 pending / outbox 事件。[官方:`config.yaml` 配置](https://docs.trytrellis.app/zh/advanced/configuration) +8. **所有完成态都以人类 review 为必要门禁**。Agent 可以分析哪些 Ticket 已满足验收,但不能自行将它们或父 Spec 置为 `已完成`。 + +## 2. 本文如何区分事实与方案 + +| 标签 | 含义 | 能否当成已存在能力 | +|---|---|---| +| **[官方事实]** | 来自用户给出的 5 篇 Trellis 官方文档 | 可,但仍应以项目当前生成文件和安装版本为准 | +| **[Matt 提取]** | 来自已完成的《Matt 工作流 × 飞书 CLI 全流程总结》 | 可作为当前飞书 POC 和工作流合约 | +| **[推导 / 推荐]** | 基于上述事实对新闭环的设计 | 未标记实现时不能当成已有能力 | +| **[V1 已实现]** | 已写入全局 skill 并完成本地验证的合约 | 可用于 fixture;真实 Base 能力仍需目标项目 POC | + +本文不会把本方案的 skill、字段、任务元数据或 CLI 语法误写成 Trellis 内置能力。 + +## 3. Trellis 官方文档事实整理 + +### 3.1 定位与事实源 + +**[官方事实]** Trellis 将自己定位为“Team-level Agent Harness with built-in LLM wiki”: + +- Agent Harness 管 workflow state、hook、skill、sub-agent 和平台适配。 +- LLM wiki 把 spec、task、research、journal 放在仓库文件里。 +- workflow、spec、task 受 Git 跟踪;workspace memory 按 developer 隔离。 +- 它的核心思路是把 AI coding 当成“工作流 + 知识管理”,而不是一次性聊天。 + +来源:[官方:架构全景](https://docs.trytrellis.app/zh/advanced/architecture) + +Trellis 本地内容的职责边界如下: + +| 内容 | 位置 | 职责 | +|---|---|---| +| Workflow 合约 | `.trellis/workflow.md` | Plan → Execute → Finish、skill 路由和每轮 next action | +| 团队稳定规范 | `.trellis/spec/` | 可跨任务复用的团队知识 | +| 任务事实 | `.trellis/tasks/<task>/` | PRD、设计、实施计划、research、实现 / 检查 context manifest | +| 开发者记忆 | `.trellis/workspace/<developer>/` | 开发者 journal 和索引 | +| 当前任务指针 | `.trellis/.runtime/sessions/<session-key>.json` | 把一个 AI session / 窗口指向一个任务 | + +来源:[官方:架构全景](https://docs.trytrellis.app/zh/advanced/architecture) + +### 3.2 任务结构和上下文加载 + +**[官方事实]** 典型任务目录包含: + +```text +.trellis/tasks/<task>/ +├── task.json +├── prd.md +├── design.md +├── implement.md +├── implement.jsonl +├── check.jsonl +└── research/ +``` + +- `task.json` 承载状态、优先级、负责人、分支、PR URL、父子关系和扩展元数据。 +- `prd.md` 承载需求、约束、验收标准和 out-of-scope。 +- 复杂任务使用 `design.md` 和 `implement.md`。 +- `implement.jsonl` / `check.jsonl` 分别列实现与检查所需的 spec / research 文件。 +- 实现 / 检查的标准读取顺序是“JSONL entries → `prd.md` → 可选 `design.md` → 可选 `implement.md`”。 + +来源:[官方:架构全景](https://docs.trytrellis.app/zh/advanced/architecture) + +### 3.3 任务状态与生命周期 + +**[官方事实]** 默认状态是: + +```mermaid +flowchart LR + NoTask["no_task\n当前 session 无 active task"] -->|create| Planning["planning\n需求与规划"] + Planning -->|start| Progress["in_progress\n实现、验收、收尾"] + Progress -->|archive| Completed["completed\n归档前写入"] + Progress -.->|finish| Detached["只清除当前 session 指针\n不等于任务完成"] +``` + +- `no_task` 由 hook 在没有 active task 时合成。 +- 创建任务后是 `planning`,启动后是 `in_progress`。 +- `completed` 由 archive 在归档前写入,正常不会作为 live breadcrumb 长时存在。 +- active task 按 session 隔离;同一仓库的不同窗口可以做不同任务。 + +来源:[官方:架构全景](https://docs.trytrellis.app/zh/advanced/architecture) + +**[官方事实]** 任务 lifecycle hook 是“命令事件”,不是通用 status watcher: + +| 事件 | 确切含义 | 是否可作为外部 done 判定信号 | +|---|---|---| +| `after_create` | 任务目录已创建 | 否 | +| `after_start` | 任务进入 `in_progress` | 可用于写“进行中” | +| `after_finish` | 当前 AI session 已解除任务指针;任务可能在其他 session 继续 | **否** | +| `after_archive` | 任务已归档 | **是,官方指定的完成事件;但它不证明外部写入已成功** | + +来源:[官方:架构全景](https://docs.trytrellis.app/zh/advanced/architecture) + +### 3.4 Finish 边界 + +**[官方事实]** Trellis 把实现、工作 commit 和收尾记账分开: + +1. implement / check 产出通过检查的 diff。 +2. 主会话做最终验证并更新 spec。 +3. 工作 commit 先发生。 +4. `/trellis:finish-work` 如果发现当前任务改动未提交会停止,之后才归档任务并写 workspace journal。 + +`/trellis:finish-work` 不是提交功能代码的命令。 + +来源:[官方:架构全景](https://docs.trytrellis.app/zh/advanced/architecture) + +本文之后所说的“`finish-work` 之后收口”,统一解释为:**目标项目已按它的 workflow 完成最终验证,且对应 task 已真正 archive**。它绝不等同于底层 `task.py finish`,后者只是 session detach。官方 native `finish-work` 与本地 Trellis × Matt 的 `archive --no-commit` 收尾也不同;实现 skill 不猜测用户输入的名称,而是回读 archived task 证明这个门禁。 + +### 3.5 Workflow 的可定制点和不可随意更改的边界 + +**[官方事实]** `.trellis/workflow.md` 集中定义: + +- Phase 和分步说明。 +- Skill Routing,即“用户意图 → auto-trigger skill”。 +- `[workflow-state:STATUS]` 每轮面包屑。 +- `task.py` 命令参考。 + +可添加自定义状态、新 Phase、Plan 分支或新 skill 路由,但有三类约定受脚本依赖: + +- `[workflow-state:STATUS]...[/workflow-state:STATUS]` 标签格式。 +- `## Phase X` + `#### X.Y` 标题层级。 +- 真实 `task.py` 子命令名。只改 Markdown 不会改变 CLI。 + +面包屑文本下一条用户消息生效;Phase / step 正文和 skill routing 下一个 session 生效。 + +来源:[官方:定制 Workflow](https://docs.trytrellis.app/zh/advanced/custom-workflow) + +### 3.6 Skill 与 sub-agent 的选型 + +**[官方事实]** 三种扩展点的职责不同: + +| 扩展点 | 适合的问题 | 本闭环中的判断 | +|---|---|---| +| Command | 用户显式决定进入的会话边界 | 可作为手动补偿入口,但本文不预设具体命令 | +| Sub-agent | 需要隔离 prompt / 角色约束的子进程 | 不是 Spec / Ticket 选择和飞书状态回写的必需条件 | +| Skill | 根据意图自动触发、能力或阶段级的可复用工作流 | **适合本闭环的主要扩展点** | + +Skill 的 `description` 应该写“什么情况下触发”,正文应再做触发自检、列明动手前必读文件、给出固定输出格式。Codex 的项目级 skill 在 `.codex/skills/{name}/SKILL.md`,官方同时使用 `.agents/skills/` 作为跨平台共享层。 + +来源:[官方:定制 Skill](https://docs.trytrellis.app/zh/advanced/custom-skills) + +**[官方事实]** Trellis 原生提供 `trellis-implement`、`trellis-check`、`trellis-research` 三个 sub-agent。Codex 也可使用 inline 模式,由主会话通过 skill 读取同一批 task artifacts;自定义 sub-agent 若要拿到同类上下文,要约定 task-local JSONL 并遵守相同读取顺序。 + +来源:[官方:定制 Sub-agent](https://docs.trytrellis.app/zh/advanced/custom-agents) + +### 3.7 `config.yaml` 和 lifecycle hook + +**[官方事实]** `.trellis/config.yaml` 是应跟仓库提交的项目级共享配置,控制 session journal commit、任务 lifecycle hook、package 映射和 Codex 派发模式。 + +- 不应把机器身份、token、API key 或机器绝对路径放进该文件。 +- 开发者身份放 `.trellis/.developer`;凭证放环境变量或常规密钥管理。 +- `hooks` 支持 `after_create`、`after_start`、`after_finish`、`after_archive`,命令会收到指向当前 `task.json` 的 `TASK_JSON_PATH`。 +- Hook 失败只打印警告,不会阻断任务操作。 +- 在当前在线配置文档中,`codex.dispatch_mode` 记为默认 `inline`,`sub-agent` 用于选择旧派发模式。但这一点存在明确的本地版本差异,见 3.8;本方案不应依赖该默认值。 +- `session_auto_commit` 默认为 `true`。若团队希望手动 review / commit Trellis 记账改动,可设为 `false`。 + +来源:[官方:`config.yaml` 配置](https://docs.trytrellis.app/zh/advanced/configuration) + +### 3.8 在线文档与本机可执行事实的版本边界 + +**[本机验证]** 2026-07-26 实际执行: + +```text +trellis --version -> 0.6.8 +lark-cli --version -> 1.0.76 +``` + +在线 Trellis 文档导航已显示 `v0.6.9` changelog;本机 0.6.8 已安装模板中,`codex.dispatch_mode` 的默认值是 `auto`,`inline` 是显式退出 sub-agent 派发,`sub-agent` 只是 `auto` 的兼容别名。这与当前在线配置页的描述不一致。 + +因此: + +- 本文只依赖稳定的 task / artifact / lifecycle 语义,不把 `dispatch_mode` 当成飞书闭环的主集成点。 +- 真正实现时,以目标项目的 `trellis --version`、`.trellis/config.yaml`、已生成 agent / skill 文件和 `python3 ./.trellis/scripts/task.py --help` 为可执行事实源。 +- `trellis update` 后必须检查本地 workflow 覆盖和 `.new` / migration 差异,不直接假设在线文档与目标项目已同步。 + +## 4. 从现有 Matt 文档提取的“实现管理” + +本节只提取实际开发时的管理思想,不扩展 implement / tdd / code-review 的编码规则。本节来源均为[本地文档:《Matt 工作流 × 飞书 CLI 全流程总结》](<./Matt 工作流 × 飞书 CLI 全流程总结.md>)。 + +### 4.1 三类事实源不重叠 + +**[Matt 提取]** + +| 系统 | 管理内容 | +|---|---| +| Feishu Base | 当前状态、类别、负责人、进度、时间、父子关系和阻塞关系 | +| Feishu Wiki / Docs | Spec、Triage Notes、Agent / Human Brief 等长文档 | +| repo | 代码、测试、ADR、领域上下文和被拒绝 enhancement 的决定 | + +直接含义是:新闭环不应该在 Trellis 中复制一份“飞书当前业务状态”,也不应该把完整 Wiki Spec 长期复制为第二份权威文档。 + +### 4.2 Spec 和 Ticket 的管理含义 + +**[Matt 提取]** + +- Spec 是“问题、方案、验收边界”的聚合产物;完整内容在 Wiki,Base 保存可查询摘要和状态。 +- Ticket 是 tracer-bullet 垂直切片;每张 Ticket 是 Base 记录,V1 不建独立 Wiki,而是沿 `所属父项` 找到父 Spec 和完整文档。 +- Ticket 的 `前置依赖` 使用真实 Base record ID 建图。 +- 当一张 Ticket 所有 blocker 都已完成且它尚未认领时,它才是可执行 frontier。 + +因此,“当前用户的 Ticket”不能只做 `负责人 = 当前用户` 的扫描;列表还应该区分“可开始、可恢复、被阻塞”。 + +### 4.3 实现状态机和完成门禁 + +**[Matt 提取]** 主执行流包含: + +```text +ready-for-agent / ready-for-human + → 进行中 + → 阻塞 ⇄ 进行中 + → 待评审 ⇄ 进行中 + → 已完成 +``` + +关键一致性规则: + +- `状态=阻塞` 时,`阻塞原因` 和 `下一步` 必须非空。 +- 设置 `已完成` 前必须有具体 `验证证据`;无法验证时要写“未运行”和原因,不能伪装完成。 +- `完成度`、`下一步`、`阻塞原因` 需与状态一致。 +- Base create / update 后必须 `record-get` 或完整分页回读,`ok:true` 本身不是最终证据。 + +### 4.4 身份和责任分离 + +**[Matt 提取]** + +- API 执行者是 bot。 +- CLI 工作流真实发起人写入 `最后更新人`。 +- `负责人` 是当前执行责任人,不因 bot 执行 API 而被覆盖。 +- 每次 Base create / update 都刷新 `最后更新人`。 + +这意味着“当前用户”应从已验证的 Feishu CLI 用户身份取得,不能将 macOS 用户名、Trellis `.developer` 文本或 bot 身份直接当成飞书 `负责人`。 + +### 4.5 当前已完成与未闭环的部分 + +**[Matt 提取]** 当前飞书硬依赖适配已覆盖 setup、Spec、Tickets 和 Triage;`implement`、`tdd`、`code-review` 等下游流程只是通过公共 issue-tracker 合约消费同一 Base。 + +所以当前真正的缺口不是“再建一套开发规范”,而是: + +1. 实现前如何从 Base 得到当前用户可执行的工作。 +2. 如何将选中的 Spec / Ticket 和 Inline 会话或 Trellis task 稳定关联。 +3. 实现结束后如何把实际验证证据、代码引用和终态回写 Base。 +4. 外部回写失败时如何可见、可重试,而不是把任务误报为已闭环。 + +### 4.6 本地 Trellis × Matt 覆盖层的实现管理原则 + +**[Matt 提取]** 本仓库现有 [Trellis × Matt 工作流](<../AI-RD-Workflow/40-workflows/trellis-matt/CN/workflow.md>) 已经把实际开发分成三种模式: + +| 模式 | 管理含义 | +|---|---| +| Inline | 简单、局部、根因明确且一个上下文可完成;不创建 Trellis task | +| Matt without Trellis | 不属于 Inline,但仍可单会话完成;用最匹配的工程方法,不为“看起来正式”创建 task | +| Trellis + Matt | 跨会话、多项稳定决策、多交付物或 durable research;Trellis 管生命周期,Matt 管当前阶段方法 | + +与本闭环直接相关的管理原则是: + +- **一个 lifecycle owner,一个 method owner**:Trellis 管 task 状态与恢复;实现方法不再自建第二套任务状态。 +- `prd.md`、条件性的 `design.md` / `implement.md` 是 task-level 执行事实;跨会话任务用 `Current Checkpoint` 记录已完成、证据、下一步和 blocker。 +- 实现 agent 不修改 Trellis 状态、requirements 或 acceptance criteria,不执行 Git 写操作;主会话负责完整 diff、最终验收、checkpoint 和用户沟通。 +- 飞书的选择、外部写入确认和状态回读也应归主会话,不下放给 coding sub-agent。 +- 本地覆盖不使用旧的 commit-first `trellis-finish-work`,而是以 `archive --no-commit` + `add_session.py --no-commit` 记账;commit / push / PR 仍只由用户明确授权。 + +这里有一个必须在设计中显式消歧的术语冲突: + +- 你说的 **Inline 开发** = 不创建 Trellis task。 +- Trellis 的 **Codex `dispatch_mode: inline`** = 已经处在 Trellis task 里,只是由主 Codex agent 直接实现。 + +两者不能共用一个判断条件。 + +## 5. 设计思考:五个关键问题及已确认解法 + +以下是可对外审查的设计推理,不是把内部思维过程当成事实。 + +### 5.1 Spec、Ticket 和 Trellis task 不是同一层概念 + +| 概念 | 回答的问题 | 推荐角色 | +|---|---|---| +| Spec | “为什么做、做到什么程度才算完成” | 复杂开发的业务聚合根 | +| Ticket | “按什么可验证切片推进,哪些切片已解锁” | 可刷新的实施计划 / 验收单元 | +| Trellis task | “本地这次复杂执行需要什么上下文和生命周期” | 本地执行容器 | + +**[已确认]** 严格使用 `1 Spec = 1 Trellis task`。Ticket 只作为该 task 的动态执行计划、frontier 和验收单元,不映射为 Trellis child task。这样只保留一个 task lifecycle,避免 Trellis 任务树和 Base Ticket 依赖图双轨漂移。 + +### 5.2 两套状态机必须指定单向事实源 + +**[推荐]** 不做“两边任意修改、互相最后写入覆盖”的双向同步。 + +| 事实 | 权威来源 | 另一侧如何使用 | +|---|---|---| +| 负责人、优先级、Spec/Ticket 关系、前置依赖 | Feishu Base | Trellis 启动 / 恢复时读取快照 | +| Spec 长文档 | Feishu Wiki | Trellis task 保存链接和执行所需的摘要,不另建权威副本 | +| 当前 session 的 active task、本地 plan / check 上下文 | Trellis | 必要的节点摘要回写 Base | +| 代码、测试、commit / PR 引用 | repo | Base 仅保存 `代码引用` 和 `验证证据` | +| 对外工作状态 | Feishu Base | Trellis lifecycle 作为触发事件,不取代 Base | + +### 5.3 需要稳定的关联 ID,不能靠标题回猜 + +**[推荐]** 用 Feishu Base `record_id` 作为 Spec / Ticket 的稳定关联键。标题只用于展示和启动前查重,不用于收口时反向查找。 + +Trellis 官方架构文档说 `task.json` 支持“扩展元数据”。**[本机验证]** Trellis 0.6.8 的 task 初始结构实际包含 `meta: {}`,archive 后 `after_archive` 收到的 `TASK_JSON_PATH` 指向已移入 archive 的 `task.json`。因此初步推荐用 `task.json.meta.feishuTracker`保存关联,但实现时仍要在目标项目回读 schema 并跑 archive POC。 + +候选合约(方案定义,非 Trellis 内置字段): + +```json +{ + "meta": { + "feishuTracker": { + "schemaVersion": 1, + "specRecordId": "rec_xxx", + "ticketRecordIds": ["rec_aaa", "rec_bbb"], + "selectedRecordIds": ["rec_aaa"], + "specWikiUrl": "https://...", + "trackerContractPath": "docs/agents/issue-tracker.md", + "boundAt": "2026-07-26T00:00:00+08:00", + "lastRefreshAt": "2026-07-26T00:00:00+08:00" + } + } +} +``` + +不将 Base token、API token、密钥或固定个人 open ID 写入 task 元数据。Base / table 坐标继续由 repo tracker contract 提供;当次人类用户每次通过 `lark-cli auth status --json --verify` 重新验证。 + +关联基数保持为: + +```text +Trellis task + ↔ 1 个 Feishu Spec record_id + ↔ 0..N 个 Feishu Ticket record_id + ↔ Spec Wiki URL +``` + +Inline 路径不为了保存 mapping 而初始化 Trellis。同会话收口时使用用户已选的 record IDs;若跨会话恢复,收口 skill 重新完整查询“负责人 = 当前用户 且 状态 = 进行中 / 待评审 / 阻塞”的记录,让用户按 record ID 重选,不用标题猜测。 + +### 5.4 “任务归档”只是 Spec 最终完成的必要条件,不是充分条件 + +**[已确认]** Ticket 可在 task 进行中通过部分收口逐张完成;`after_archive` 只解决“何时允许尝试 Spec 最终收口”。它不能单独证明每张 Ticket 均已验收。Spec 完成回写仍必须同时满足: + +- 对应验收标准已核对。 +- 真实验证命令 / 结果已采集;未运行项已明示。 +- 需要的 check 已通过,且人类已完成最终 review。 +- 要更新的每个 Ticket 都有对应证据,不因父 Spec 任务归档而批量猜测“全部完成”。 + +### 5.5 Inline 和 Trellis 应共用收口协议 + +**[推荐]** Inline 和 Trellis 的区别只是“是否需要持久的本地任务容器”,不应导致两套飞书状态规则。 + +```mermaid +flowchart TD + Queue["当前用户的 Spec / Ticket 队列"] --> Select["用户选择工作项"] + Select --> Route{"是否需要持久的复杂任务上下文?"} + Route -->|"No"| Inline["Inline 实现"] + Route -->|"Yes"| Task["1 Spec ↔ 1 Trellis task\nTickets 作为计划 / 验收单元"] + Inline --> Verify["共用验证与 Base 回写协议"] + Task --> Archive["Trellis 最终验证 + 归档"] + Archive --> Verify + Verify --> Readback["Base 回读 + 收口回执"] +``` + +## 6. 初步方案 + +### 6.1 总体架构 + +**[推荐]** 把新能力分成三层: + +| 层 | 职责 | 不应负责的事 | +|---|---|---| +| Skill 编排层 | 身份门禁、列表、用户选择、路由、收口规则、结果汇报 | 不把 API 返回的 `ok:true` 当最终证据 | +| CLI 读写层 | 调用已验证的 `lark-cli`,查询 / patch / record-get | 不负责决定应将哪张 Ticket 置为完成 | +| Trellis lifecycle 集成层 | 提供 task 关联、start / archive 事件和归档上下文 | 不替代 Base 作为业务状态事实源 | + +**[本机验证]** `lark-cli 1.0.76` 已提供 V1 所需的基础原语: + +- `auth status --json --verify`:验证 bot / user 身份。 +- `base +record-list`:结构化 filter、sort、字段投影、`offset` 和单页最大 `limit=200`;skill 必须自行循环到完整结果。 +- `base +record-batch-update`:单次最多 200 条的差异化 patch,响应不保证 record ID 存在。 +- `base +record-get`:按稳定 record ID 回读,所以 batch update 后仍需逐条或分批验证。 + +V1 可直接由 skill 编排这些 `lark-cli` 命令;先不为了包装而新建 CLI。只有当分页、frontier 计算、幂等 patch 在两个 skill 中形成重复且已经 POC 验证时,再提取 repo-local helper。 + +### 6.2 Skill A:工作入队与路由 + +**[V1 已实现]** 全局显式 skill 名为 `start-work-feishu`,source of truth 位于 `~/.agents/skills/start-work-feishu/`;它不是 Trellis 内置命令。 + +触发条件: + +- 用户表示“开始开发、看我的待办、选一个 Spec / Ticket 实现”。 +- 当前无 active Trellis task,或用户明确要恢复已认领工作。 + +建议流程: + +1. 运行已验证的 Feishu 身份检查,冻结当前人类用户 open ID;不把 bot 当用户。 +2. 分别完整分页查询两类记录: + - Spec 队列:`产物类型 = PRD/Spec` 且 **Spec 自身** `负责人 = 当前用户`。不因“它的子 Ticket 由当前用户负责”而把该 Spec 追加到 Spec 队列。 + - Ticket 队列:`产物类型 = 实现 Ticket` 且 Ticket 自身 `负责人 = 当前用户`。展示时可附带父 Spec 上下文,但不改变 Spec 队列口径。 +3. 分组展示: + - **恢复执行**:`进行中` / `阻塞`。 + - **现在可开始**:`ready-for-agent` 且 blocker 都已完成的 Ticket,以及符合条件的 Spec。 + - **尚未解锁**:存在未完成 blocker 的 Ticket,只展示原因,不默认推荐开工。 +4. 每行至少展示:标题、产物类型、Base record ID、状态、优先级、父 Spec、阻塞项、更新时间和建议路由。 +5. 用户选择后,用 record ID 重新取得最新记录,防止列表与实际状态之间竞态。 +6. 如选 Ticket,沿 `所属父项` 取父 Spec 和 Wiki;如选 Spec,同时取子 Tickets 和依赖图。 +7. 根据既有约定路由: + - 范围小、根因 / 方案已知、当前上下文可以完成:Inline。 + - 跨模块、需持久计划、多会话、多人 / 多 Agent 或验收链较长:Trellis task。 +8. 列表本身只读。用户选择后,skill 一次性展示“工作项 + Inline / Trellis 路由 + 拟写 Base patch”;用户确认“开始”后,同时构成任务路由决定和这一次外部写入授权,不再追加一个纯流程性的“是否创建 Trellis task”问题。 +9. 官方 native `no_task` breadcrumb 要求任务创建同意,但本地 Trellis × Matt workflow 明确覆盖为“满足 durable 条件时直接创建,不问 task-consent”。本方案用上一步的“选择并开始”统一两者,不改 Trellis CLI 语义。 +10. 当 record ID 关联已成功保存且用户确认开始时,将选中的聚合工作项更新为 `进行中`。选 Spec 时先只写 Spec,其他 Tickets 保持原状态;选 Ticket 时写该 Ticket,并将其父 Spec 写为 `进行中`(如尚未进入),其他 Tickets 不动。这里的语义是“已认领并开始规划 / 执行”,不声称代码已写。 +11. 每次写入都带 `最后更新人 = 当前人类用户`,并立即回读核对。 + +建议列表形式: + +| 序号 | 可执行性 | 类型 | 标题 | 状态 | 优先级 | 父 Spec | 阻塞 | 建议路由 | +|---:|---|---|---|---|---|---|---|---| +| 1 | 可恢复 | Spec | … | 进行中 | P1 | — | — | Trellis | +| 2 | 可开始 | Ticket | … | ready-for-agent | P2 | Spec A | 无 | Inline | +| 3 | 被阻塞 | Ticket | … | ready-for-agent | P2 | Spec B | Ticket X | 暂不开工 | + +### 6.3 复杂开发的映射规则 + +**[推荐]** + +```text +Feishu Spec record_id + ↔ Trellis task + ├── prd.md:Spec 链接、必要摘要、验收边界 + ├── implement.md:按 Ticket frontier 生成 / 刷新的执行计划 + ├── implement.jsonl / check.jsonl:只收录必要的本地 spec / research + └── task.json.meta.feishuTracker:Spec record_id + Ticket record_ids +``` + +约束: + +- 同一 Spec 同时最多对应一个 active Trellis task。创建前先扫描 active task 的 `meta.feishuTracker.specRecordId`;已存在时恢复原 task,不按标题再建一个。 +- Feishu Wiki Spec 仍是长规格事实源;Trellis `prd.md` 是本地执行上下文,应显式记录来源 record ID / URL 和取得时间。 +- Ticket 状态和依赖仍以 Base 为准;`implement.md` 是可执行快照,恢复开发时先检查 Base 是否已变化。 +- 每次恢复 Trellis task 时,按 `specRecordId` 重取 Spec、子 Tickets、依赖与 `更新时间`,与 `lastRefreshAt` 快照比较。新增 Ticket 可追加为新计划项;验收、范围或依赖发生实质变化时,先向用户展示 diff,不静默改写已 review 的 task artifacts。 +- `implement.md` 保存本地 checkpoint,Base Ticket 保存对外状态。二者的重合内容是可重建快照,不形成双向最后写入覆盖。 +- Ticket 不映射成 Trellis child task;所有 Tickets 都通过同一 Spec task 的 `implement.md` / checkpoint 管理。 +- 不把完整业务文档塞进 JSONL;Trellis 官方建议 JSONL 只列当前任务需要的 spec / research。[官方:架构全景](https://docs.trytrellis.app/zh/advanced/architecture) + +### 6.4 Skill B:验证与飞书收口 + +**[V1 已实现]** 全局显式 skill 名为 `close-work-feishu`,source of truth 位于 `~/.agents/skills/close-work-feishu/`;它不是 Trellis 内置命令。 + +这个 skill 支持三个 routing,而不是只能在整个 Spec 完成后运行: + +| Routing | 何时调用 | 允许写入的终态 | +|---|---|---| +| **部分收口** | Inline 或 Trellis task 还在进行中,用户希望先结算已完成切片 | 只能关闭经人类 review 确认的 Tickets;Spec 继续保持 `进行中` | +| **最终收口** | 全部 Ticket 已结算,Spec 验收已完成;Trellis 路径的 task 还必须已 archive | 先确认漏网 Tickets,最后才允许关闭 Spec | +| **对账重放** | 上次写入部分成功、回读失败或记录已处于目标终态 | 只补齐仍有差异的记录;证据完整时返回“已同步”,不重复追加 | + +Inline 不等待 Trellis 事件。Trellis 的部分收口可在 active task 期间运行;最终收口才要求 archive。`after_archive` 仍只负责提醒或标记“待对账”,不直接代表 Base 已写回。 + +共享步骤: + +1. 先确定唯一父 Spec。Trellis 从 active / archived task 的 `meta.feishuTracker.specRecordId` 取得;Inline 从当会话选择或一次用户重选取得。不用标题反查。 +2. **按 Spec 回读所有未完成 Tickets**,不只分析当前 mapping 快照中的 Ticket IDs。同时重取验收标准、负责人、状态、前置依赖和更新时间,避免漏掉开发中新增或变更的 Tickets。 +3. 汇总 repo diff、真实验证命令与结果、未运行项及原因、review 证据、代码引用和 Trellis checkpoint,并逐张映射 Ticket 验收标准。 +4. 对未完成 Tickets 分类: + - **建议可收口**:验收条件和直接证据充分,可交给人类 review。 + - **待补证 / 待验证**:实现看似已有,但证据或验收映射不足,不建议完成。 + - **明确未完成 / 阻塞**:仍有实现项、未满足 blocker 或需要新决策。 +5. 向用户展示逐 Ticket 分析:标题、record ID、验收结论、证据、风险、建议动作和拟写 patch。Agent 只推荐,不自行选择终态。 +6. **人类 review 是每张 Ticket 写入 `已完成` 的必要条件**。用户可确认全部建议项,也可只选其中一部分;未被确认的 Ticket 不写终态。 +7. 对用户确认的 Tickets 构造最小 patch,写入状态、完成度、Ticket 专属的验证证据、代码引用和 `最后更新人`,清理终态不应保留的阻塞字段。不覆盖无关新写入。 +8. 先更新 Tickets 并逐条回读。部分收口在此结束:父 Spec 保持 `进行中`,未完成 Tickets 保持原状态,回执中列出最小下一步。 +9. 最终收口在 Ticket 回读后重新查询全部子 Tickets。只有当全部 Tickets 已完成、Spec 级验收充分、Trellis task 已 archive(若适用)且人类完成最终 review,才展示 Spec 终态 patch 并再取得一次确认。 +10. 更新 Spec 后回读,最终输出收口回执:已更新记录、未收口记录及原因、失败记录、人类 review 结论和回读证据。 + +```mermaid +flowchart TD + Invoke["用户执行收口 skill"] --> Spec["定位 Spec record ID"] + Spec --> Fetch["取全部未完成 Tickets"] + Fetch --> Analyze["逐 Ticket 分析验收与证据"] + Analyze --> Review["人类 review 并选择可收口 Tickets"] + Review --> CloseTickets["更新 Tickets + 逐条回读"] + CloseTickets --> Remaining{"仍有未完成 Ticket?"} + Remaining -->|"Yes"| Partial["部分收口完成\nSpec 保持进行中"] + Remaining -->|"No"| FinalGate{"Spec 验收 + 人类最终 review\n+ Trellis archive 如适用?"} + FinalGate -->|"No"| Wait["保持 Spec 进行中 / 待评审"] + FinalGate -->|"Yes"| CloseSpec["用户确认 Spec patch"] + CloseSpec --> Done["更新 Spec + 回读"] +``` + +推荐的完成 patch 语义,不是未验证的 CLI 命令: + +| 字段 | 目标值 / 规则 | +|---|---| +| `工作流阶段` | 已完成实现和验收后进入交付,或按团队最终确定的阶段映射 | +| `状态` | `已完成` | +| `完成度` | 100 | +| `验证证据` | 真实命令 + 结果摘要 + 未运行项 | +| `代码引用` | 任务路径、分支、commit、PR 或关键文件,只写真实存在的引用 | +| `阻塞原因` | 清空 | +| `下一步` | 清空,或按团队终态规则写明后续交付动作 | +| `最后更新人` | 当前已验证 CLI 人类用户 | + +### 6.5 Trellis 与 Base 状态映射 + +**[推荐]** + +| Trellis / 本地事件 | Base 候选状态 | 备注 | +|---|---|---| +| 已列表、用户未选择 | 不写 | 只读查询不应该改状态 | +| 用户确认“选择并开始”,mapping 保存成功 | `进行中` | 表示已认领并进入 planning / execution;不猜测完成度 | +| Trellis `planning` / `after_start` | 通常不再重复写 | 由入队 skill 完成开始回写;hook 可做对账,不必二次 patch | +| 外部 blocker 出现 | `阻塞` | `阻塞原因` + `下一步` 必填 | +| Agent 分析 Ticket “建议可收口”,尚未人类 review | 保持原状态,或经确认写 `待评审` | 绝不自动写 `已完成` | +| 部分收口:人类 review 并确认部分 Tickets | 被选 Tickets → `已完成` | 其他 Tickets 不动,Spec 保持 `进行中` | +| `after_finish` | 不写 | 只是 session detach | +| `after_archive` | 不直接写 done | 只生成收口提醒 / 待对账信号 | +| 全部 Tickets 完成 + Spec 验收 + 人类最终 review + archive(如适用) | Spec → `已完成` | 最终收口的聚合门禁;任一条不满足都不关 Spec | +| 同步失败 | 保留原状态 | 本地报告“代码 / Trellis 已完成,Base 待对账”,不伪报闭环 | + +该映射要在 POC 后才能固化进 skill;特别是 `工作流阶段` 和 Spec 聚合完成语义,需再确认业务预期。 + +### 6.6 Hook 怎么用:事件触发,不是唯一保障 + +**[推荐]** 分三阶段导入: + +#### V1:skill 显式闭环 + +- 由工作入队 skill 负责选择、路由和开始状态回写。 +- Inline / Trellis 进行中都可显式执行收口 skill 的“部分收口”routing,只关闭经人类 review 确认的 Tickets。 +- Inline 整体验收完成,或 Trellis 最终验证和归档后,显式执行“最终收口”routing,才可能关闭 Spec。 +- 先证明字段映射、回读和幂等性,不先扩大到全自动 hook。 + +#### V1.5:Workflow routing 固化入口 + +- 在 `.trellis/workflow.md` 的 Skill Routing 中加入“开始飞书工作”与“实现完成后闭环飞书”的意图路由。 +- 在 Finish 阶段明确“archive 成功后运行飞书收口 / 对账”。 +- 保持 Trellis 解析器依赖的 block 标签、Phase / step 标题层级和真实命令名不变。[官方:定制 Workflow](https://docs.trytrellis.app/zh/advanced/custom-workflow) + +#### V2:lifecycle hook + 可重放对账 + +- `after_start` 可选用于检查绑定工作项是否已是 `进行中`,不与入队 skill 重复 patch。 +- `after_archive` 只输出明确提醒,或写一个不含凭证的本地待对账标记;后续仍由用户显式运行收口 skill。 +- `after_finish` 不更新 Base 完成态。 +- Hook 里不放 Base token、user open ID 或机器绝对路径;`.trellis/config.yaml` 只保存团队共享的相对命令。[官方:`config.yaml` 配置](https://docs.trytrellis.app/zh/advanced/configuration) +- 收口 skill 扫描已 archive 任务的 `meta.feishuTracker`,并回读 Base 判断是否待同步;不需要依赖 hook 的“成功标记”。 +- 由于 hook 失败不阻断 archive,同一收口核心必须支持手动重放 / 对账;skill 作为唯一声称“Base 已闭环”的入口。 + +### 6.7 幂等、竞态和失败处理 + +**[推荐]** 收口设计必须包含: + +1. **稳定键**:只按 record ID 更新。 +2. **写前回读**:责任人、状态或父子关系已变更时停止并报告,不强制覆盖。 +3. **最小 patch**:只写当前状态转移需要的字段。 +4. **幂等重放**:目标已是相同终态且证据一致时,结果为“已同步”,不再创建新记录或重复附加证据。 +5. **部分成功可见**:返回逐条成功 / 失败列表,不用一个总体 `ok` 遮蔽部分失败。 +6. **回读才是成功**:只有回读字段符合预期才报告“Base 已闭环”。 +7. **外部失败不篡改本地事实**:代码 / Trellis 已完成与 Base 同步失败必须分开汇报。 + +### 6.8 为什么暂不需要新 sub-agent + +**[推荐]** Spec / Ticket 选择、外部写入确认和收口回执都依赖当前主会话,并不需要隔离的编码角色。Trellis 支持由主会话通过 skill 读取任务上下文,而本地 Trellis × Matt 覆盖已把 lifecycle、最终验收和用户沟通明确交给主会话。[官方:定制 Sub-agent](https://docs.trytrellis.app/zh/advanced/custom-agents) + +可以继续使用 Trellis 原生 implement / check / research 角色处理各自的执行职责,但不应该让它们各自直接决定 Base 终态。 + +## 7. 建议的端到端时序 + +### 7.1 Inline 路径 + +```mermaid +sequenceDiagram + participant U as 用户 + participant S as 工作入队 skill + participant F as Feishu Base / Wiki + participant C as Coding Agent + participant X as 工作收口 skill + + U->>S: 显示我的可实现工作 + S->>F: 验证身份 + 完整查询 + F-->>S: Spec / Ticket + 关系 + 状态 + S-->>U: 可恢复 / 可开始 / 被阻塞列表 + U->>S: 选择工作项 + S-->>U: 展示 Inline 路由 + Base 开始 patch + U->>S: 确认选择并开始 + S->>F: 重读后写进行中,再回读 + S->>C: record IDs + Spec + Tickets + 验收边界 + C->>C: Inline 实现与验证 + C->>X: 完成证据 + 代码引用 + X-->>U: 展示逐 Ticket / Spec patch + U->>X: 确认外部写入 + X->>F: 按 record ID 最小 patch + X->>F: 逐条回读 + X-->>U: 收口回执 +``` + +### 7.2 Trellis 路径 + +```mermaid +sequenceDiagram + participant U as 用户 + participant S as 工作入队 skill + participant F as Feishu Base / Wiki + participant T as Trellis + participant X as 工作收口 / 对账 + + U->>S: 选择复杂 Spec / Ticket + S->>F: 取最新 Spec、Tickets、依赖 + S-->>U: 展示 1 Spec ↔ 1 task 路由 + Base 开始 patch + U->>S: 确认选择并开始 + S->>T: 建立 task 与 Base record IDs 的稳定关联 + S->>F: 写进行中 + 最后更新人,再回读 + T->>T: planning + T->>T: start → in_progress + T->>T: implement → check → update-spec → 最终验证 + U->>T: 按目标项目合约执行 finish-work / archive + T->>T: archive + journal + T-->>X: after_archive 提醒 + archived TASK_JSON_PATH + U->>X: 显式运行收口 skill + X-->>U: 展示逐 Ticket / Spec patch + U->>X: 确认外部写入 + X->>F: 按逐 Ticket 证据幂等收口,Spec 最后写 + X->>F: 回读 + X-->>U: 收口成功,或 Base 待对账 +``` + +图中 `after_archive` 和 `TASK_JSON_PATH` 是 Trellis 官方已有事实;它们只触发提醒,不绕过用户确认直接写飞书。具体收口 skill 和 Feishu CLI payload 是本方案待实现部分。[官方:架构全景](https://docs.trytrellis.app/zh/advanced/architecture) [官方:`config.yaml` 配置](https://docs.trytrellis.app/zh/advanced/configuration) + +## 8. 建议的最小 POC + +本文推荐先不改完整 Trellis workflow,用一个真实但可回收的 Spec + 两张 Ticket 验证下列最小闭环: + +1. 当前 Feishu CLI 人类用户可被准确解析。 +2. 能完整列出“Spec 自身负责人 = 当前用户”的 Spec,不因子 Ticket 归属扩张 Spec 列表;同时独立列出当前用户负责的 Tickets,并正确计算依赖 frontier。 +3. 用户选定后,Trellis 路径能把 Spec / Ticket record IDs 保存到 `task.json.meta.feishuTracker`,且 archive 后仍可读取。 +4. 同一个候选工作能分别跑通 Inline 和 Trellis 两条路径。 +5. Trellis 的 `after_finish` 不触发 done;`after_archive` 只触发收口提醒,显式 skill 才尝试写 done。 +6. 在 task 未 archive 时执行部分收口,skill 能按 Spec 取得全部未完成 Tickets,给出“建议可收口 / 待补证 / 未完成”分析,并只关闭用户 review 后确认的 Tickets。 +7. 部分收口后 Spec 仍为 `进行中`;未被用户确认的 Tickets 不被误关闭。 +8. 最终收口只在全部 Tickets 完成、Spec 验收通过、人类最终 review 通过且 Trellis task 已 archive(如适用)时关闭 Spec。 +9. 重复执行部分 / 最终收口不会创建重复记录、重复证据或错误状态。 +10. 刻意让一次 hook 失败,archive 仍成功,收口 skill 仍能通过 archive task mapping + Base 回读发现待同步工作。 +11. 刻意让一次 Base batch update 部分失败,skill 能保留逐条成功 / 失败证据并幂等重放,不误关父 Spec。 +12. 所有 Base 更新都显示 `最后更新人 = 当前真实用户`,且已逐条回读。 +13. POC 验收后将测试记录标记为 `已取代`,保留审计证据,不删除。 + +POC 前先仅定义读取和预演模式,展示将修改的 record IDs 和字段;真实写飞书应在用户确认后进行。 + +## 9. 导入顺序建议 + +### 阶段 A:只读队列 + +- 实现身份验证、完整分页、负责人过滤、状态分组和 frontier 计算。 +- 不改 Base、不建 Trellis task。 +- 验收:列表与 Base UI 人工核对一致。 + +### 阶段 B:选择与开始同步 + +- 用户选择后重读 record。 +- 实现 Inline / Trellis 路由和稳定 ID 绑定。 +- 用户一次确认“选择并开始”后,写 `进行中`并回读;Trellis `after_start` 只做可选对账。 + +### 阶段 C:显式收口 + +- Inline 和 Trellis 共用一个收口核心。 +- 先做“部分收口”:按 Spec 分析所有未完成 Tickets,人类 review 后选择收口集合。 +- 再做“最终收口”:验证全 Ticket 完成、Spec 聚合验收、人类最终 review 和幂等重放。 + +### 阶段 D:Workflow 与 hook 集成 + +- 把 skill 意图写入 `.trellis/workflow.md` Skill Routing。 +- 再接 `after_start` / `after_archive` 的对账 / 提醒能力,不在 hook 中无确认写飞书。 +- 保留手动对账入口,并演练 hook 失败。 + +## 10. 已确认的设计决策 + +| # | 已确认决策 | 对实现的直接约束 | +|---:|---|---| +| 1 | 使用两个 skill:入队 skill + 收口 skill | 对账重放是收口 skill 的 routing,不新增第三个 skill | +| 2 | 严格 `1 Spec = 1 Trellis task` | Ticket 不建 Trellis task / child task,只作为同一 task 内的动态计划和验收单元 | +| 3 | 用户确认“选择并开始”且 mapping 保存后,立即写 `进行中` | 不新增“规划中”状态;`after_start` 不重复 patch | +| 4 | 必须人类 review 才能完成 | Agent check、测试通过和 archive 都只是证据,不能单独产生 Ticket / Spec 终态 | +| 5 | 收口 skill 支持部分收口 | 每次按 Spec 重取所有未完成 Tickets,分析可收口集合,用户 review / 选择后只关闭被确认 Tickets;Spec 保持进行中,直到最终聚合门禁通过 | +| 6 | 采用本文推荐的 mapping | 使用 `task.json.meta.feishuTracker`,不写 token、密钥或固定个人 open ID | +| 7 | Hook 按本文推荐边界 | `after_archive` 只提醒 / 待对账,不直接写 Feishu;显式收口 skill 才能声称 Base 闭环 | +| 8 | Spec 队列只列 Spec 自身负责人 = 当前用户 | 不因子 Ticket 归属扩张 Spec 队列;当前用户负责的 Tickets 仍作为独立 Ticket 队列展示 | + +## 11. 风险与非目标 + +### 当前风险 + +- **状态双写风险**:若 Base 和 Trellis 都被当成业务状态权威源,会出现覆盖与逆向跳转。 +- **误用 `after_finish`**:会在其他 session 仍工作时提前完成 Base。 +- **hook 假成功**:archive 成功不代表 hook 成功,必须有重放 / 对账。 +- **Spec 批量误关闭**:父 task 归档不能无证据地把所有 Ticket 置为已完成。 +- **用标题做关联**:改名、重名和模糊查询会导致更新错记录。 +- **身份混淆**:bot、`负责人`、`最后更新人` 和 Trellis developer 是不同概念。 +- **敏感信息进仓**:不能把 token / API key / 个人 open ID 硬编码进 `.trellis/config.yaml`。 + +### 非目标 + +- 本文不设计新的 coding / TDD / review 规则。 +- V1 已实现两个显式 skill,但不实现 hook、CLI wrapper、helper script 或 Trellis workflow 定制。 +- 本文不修改飞书 Base schema 或真实业务记录。 +- 本文不把本地结构 / fixture 验证等同于真实 Base POC。 + +## 12. 资料索引 + +### Trellis 官方一手资料 + +1. [架构全景](https://docs.trytrellis.app/zh/advanced/architecture) +2. [定制 Workflow](https://docs.trytrellis.app/zh/advanced/custom-workflow) +3. [定制 Skill](https://docs.trytrellis.app/zh/advanced/custom-skills) +4. [定制 Sub-agent](https://docs.trytrellis.app/zh/advanced/custom-agents) +5. [配置 `.trellis/config.yaml`](https://docs.trytrellis.app/zh/advanced/configuration) + +### 本地已验证资料 + +- [Matt 工作流 × 飞书 CLI 全流程总结](<./Matt 工作流 × 飞书 CLI 全流程总结.md>) +- [Trellis × Matt 全局 Agent 规则](<../AI-RD-Workflow/40-workflows/trellis-matt/CN/AGENTS.md>) +- [Trellis × Matt 项目 Workflow](<../AI-RD-Workflow/40-workflows/trellis-matt/CN/workflow.md>) +- 本机命令验证:`trellis 0.6.8`、`lark-cli 1.0.76`、本机 Trellis 0.6.8 已安装 task / config 模板。 + +## 13. V1 实现状态与下一步 + +### 13.1 已实现 + +- `~/.agents/skills/start-work-feishu/`:`SKILL.md`、`references/feishu.md`、`agents/openai.yaml`。 +- `~/.agents/skills/close-work-feishu/`:`SKILL.md`、`references/feishu.md`、`agents/openai.yaml`。 +- 两个 skill 均设置 `policy.allow_implicit_invocation: false`,只允许用户显式调用。 +- V1 直接编排项目内 Trellis 脚本与 `lark-cli`,没有新增 helper、hook、workflow 修改或 Base schema 写入。 + +### 13.2 已完成的本地验证 + +- 两个目录均通过 `skill-creator/scripts/quick_validate.py`。 +- `agents/openai.yaml` 已解析并确认显式调用策略及 `$skill-name` 默认提示。 +- 暂存目录与全局安装目录逐字节一致,无 `TODO` / 模板占位残留。 +- 契约 fixture 覆盖 11 类场景:负责人过滤、父 Spec 上下文、完整 frontier、非完成终态、待评审分流、重复 task mapping、部分收口、缺失证据、`finish` 非 archive、Spec 最终门禁和幂等回读规则。 +- 独立前向测试只使用脱敏 fixture,未调用 `lark-cli`、未写 Base;验证结果见本次实施回执。 + +### 13.3 尚未运行与后续顺序 + +当前机器没有发现任何项目级 `docs/agents/issue-tracker.md`,因此不能安全定位真实 Base,真实只读 POC 标记为 `未运行`。后续按以下顺序继续: + +1. 用户指定一个已配置飞书 tracker contract 的 Trellis 项目。 +2. 运行 `start-work-feishu` 只读队列 POC,与 Base UI 人工核对负责人、分页和 frontier。 +3. 单独展示 record IDs 与开始 patch,经确认后验证 mapping、`进行中` 写入和回读。 +4. 依次验证部分收口、最终收口和对账重放;每批真实写入仍单独确认。 +5. V1 真实 POC 稳定后,再讨论是否抽取 helper,以及是否进入 workflow / hook 提醒集成。 diff --git a/docs/三阶段研发工作流产物链路与飞书 CLI 管理方案.md b/docs/三阶段研发工作流产物链路与飞书 CLI 管理方案.md new file mode 100644 index 0000000..3f7c0a0 --- /dev/null +++ b/docs/三阶段研发工作流产物链路与飞书 CLI 管理方案.md @@ -0,0 +1,694 @@ +# 三阶段研发工作流:产物链路、Skill 组合与飞书 CLI 管理方案 + +> 状态:研究与方案评审 +> +> 日期:2026-07-28 +> +> 范围:需求探索 → 需求转化 → 开发收口;Matt skills、Feishu Base/Wiki、`lark-cli` 与 Trellis 的产物衔接。 +> +> 结论先行:三阶段方向成立,`Spec → Tickets → Start → Inline/Trellis → Close` 已有真实 POC 支撑;当前主要断点是探索阶段没有正式发布出口、`ready-for-agent` 与负责人分派之间断链、开发阶段缺少显式实现方法,以及 Wiki Spec 与 Trellis `prd.md` 的事实源边界尚未完全统一。来源 Issue 的后续状态由人类在 Base 中自行检查,不纳入自动化范围。 + +## 1. 研究问题与判断 + +本研究回答五个问题: + +1. 三个阶段中每个 skill 实际负责什么,不负责什么? +2. 每个阶段必须产出什么,才能被下一阶段稳定消费? +3. 当前流程中的 `handoff`、原型、Spec、Tickets、Trellis artifacts 是否形成了单一、可追踪的链路? +4. 哪些环节已经经过真实 Feishu/Trellis POC,哪些仍是建议? +5. 如何在不把所有内容都复制进飞书的前提下,用 `lark-cli` 提升可查询性、恢复能力和审计性? + +核心判断如下: + +- `handoff` 是临时会话运输层,不是需求事实源,也不应是每一步必经的业务状态。 +- `grill-me` 只负责消除决策歧义,不会自动生成需求文档;第一阶段缺少一个正式的“探索结论发布”动作。 +- `prototype` 产出的是“回答一个问题的可运行原型”,不保证是 HTML。UI 问题可能产出浏览器多变体,逻辑问题应产出 TUI/状态模型。 +- 第一阶段的文档应叫 **Discovery Brief(需求探索结论)**;第二阶段的 `to-spec` 才产出 **Engineering Spec(工程执行规格)**。二者不能都叫 PRD 并同时声称权威。 +- `to-spec-feishu` 和 `to-tickets-feishu` 当前都不写 `负责人`,而 `start-work-feishu` 只查询当前用户负责的记录,存在明确的 Dispatch Gate 断链。 +- `start-work-feishu` 只负责选择、路由、绑定和开始状态;`close-work-feishu` 只负责证据收口。中间必须存在 `standard implement`、`tdd`、诊断或评审等明确的方法 owner。 +- 复杂探索更适合使用 `wayfinder` 的 Map + Decision Tickets,而不是用多份临时 `handoff` 串成长链。 +- 飞书适合继续做管理控制面,不应复制完整 Trellis task 或 repo 内容。 + +## 2. 证据范围 + +### 2.1 本仓库总结文档 + +本研究以以下两篇总结为主: + +- [Matt 工作流 × 飞书 CLI 全流程总结](<./Matt 工作流 × 飞书 CLI 全流程总结.md>):覆盖 Setup、Spec、Tickets、Triage、29 字段、身份和 CLI 写后回读。 +- [Matt 工作流 × 飞书 Skills × Trellis Coding 闭环总结](<./Matt 工作流 × 飞书 Skills × Trellis Coding 闭环总结.md>):覆盖 Start、Inline/Trellis 路由、`1 Spec = 1 task`、Ticket 部分收口、Spec 最终收口和真实 POC。 + +两篇总结共同确认的事实源分工是: + +| 事实 | 事实源 | +|---|---| +| 当前状态、负责人、父子、依赖、队列 | Feishu Base | +| Discovery、Spec、Triage 等长文档 | Feishu Wiki / Docs | +| 复杂开发的 planning、checkpoint、archive | Trellis | +| 代码、测试、ADR、领域词汇、实现证据 | repo | +| 选择、产品决策、Ticket review、Spec 最终 review | 人类 | + +### 2.2 Skill 一手定义 + +本研究逐一核对了以下本地定义: + +- `/Users/yuxuanhui/.agents/skills/grilling/SKILL.md` +- `/Users/yuxuanhui/.agents/skills/grill-me/SKILL.md` +- `/Users/yuxuanhui/.agents/skills/grill-with-docs/SKILL.md` +- `/Users/yuxuanhui/.agents/skills/domain-modeling/SKILL.md` +- `/Users/yuxuanhui/.agents/skills/handoff/SKILL.md` +- `/Users/yuxuanhui/.agents/skills/prototype/SKILL.md` +- `/Users/yuxuanhui/.agents/skills/prototype/LOGIC.md` +- `/Users/yuxuanhui/.agents/skills/prototype/UI.md` +- `/Users/yuxuanhui/.agents/skills/to-spec/SKILL.md` +- `/Users/yuxuanhui/.agents/skills/to-spec-feishu/SKILL.md` +- `/Users/yuxuanhui/.agents/skills/to-tickets/SKILL.md` +- `/Users/yuxuanhui/.agents/skills/to-tickets-feishu/SKILL.md` +- `/Users/yuxuanhui/.agents/skills/start-work-feishu/SKILL.md` +- `/Users/yuxuanhui/.agents/skills/close-work-feishu/SKILL.md` +- `/Users/yuxuanhui/.agents/skills/wayfinder/SKILL.md` +- `/Users/yuxuanhui/.agents/skills/implement/SKILL.md` +- `/Users/yuxuanhui/.agents/skills/tdd/SKILL.md` +- `/Users/yuxuanhui/.agents/skills/code-review/SKILL.md` + +同时核对了飞书 tracker 的一手适配约定: + +- `/Users/yuxuanhui/.agents/skills/setup-matt-pocock-skills-feishu/references/issue-tracker-feishu.md` +- `/Users/yuxuanhui/.agents/skills/to-spec-feishu/references/feishu.md` +- `/Users/yuxuanhui/.agents/skills/to-tickets-feishu/references/feishu.md` + +### 2.3 Trellis 与 CLI 证据 + +Trellis 路由和产物规则来自: + +- [Trellis × Matt 全局规则](<../AI-RD-Workflow/40-workflows/trellis-matt/CN/AGENTS.md>) +- [Trellis × Matt workflow](<../AI-RD-Workflow/40-workflows/trellis-matt/CN/workflow.md>) + +本机只读验证: + +```text +lark-cli --version +→ lark-cli version 1.0.76 +``` + +当前 CLI 的 `base --help` 明确提供 Base records、views、dashboard、workflow、record history 和 data query;`docs --help`、`wiki --help`提供文档内容和知识库节点操作。`record-history-list` 是单条记录历史,不是整表审计;Workflow 创建后默认 disabled,启用应是单独动作。 + +Context7 命中的官方一手来源为 [`/larksuite/cli`](https://github.com/larksuite/cli),其 README 确认 Lark CLI 采用 shortcut、API command、Universal API 三层调用,并为 Base、Docs、Wiki 等域提供版本匹配的 agent skills。 + +本研究没有写入 Feishu,也没有重新执行已有业务 POC。实际闭环证据沿用两篇总结中记录的“经销商政策”项目验证。 + +## 3. 推荐的总产物图 + +```mermaid +flowchart TD + Issue["Base 需求/Issue<br/>稳定业务根 ID"] --> Discovery["Wiki Discovery Brief<br/>探索结论"] + Issue --> Prototype["原型资产/结论<br/>HTML、应用路由或逻辑 TUI"] + Issue --> Wayfinder["可选:Wayfinder Map"] + Wayfinder --> Decision["Decision Tickets<br/>grilling / prototype / research / task"] + + Spec["Base PRD/Spec"] -->|"所属父项"| Issue + Spec --> SpecDoc["Wiki Engineering Spec"] + Tickets["Base 实现 Tickets"] -->|"所属父项"| Spec + Tickets -->|"前置依赖"| Tickets + + Start["start-work-feishu"] --> Inline["Inline<br/>会话内冻结 IDs"] + Start --> Trellis["Trellis task<br/>1 Spec = 1 task"] + Spec --> Start + Tickets --> Start + + Inline --> Repo["repo 代码 / 测试 / review 证据"] + Trellis --> Repo + Repo --> Close["close-work-feishu"] + Close -->|"部分收口"| Tickets + Close -->|"最终收口"| Spec +``` + +关系方向必须明确: + +- Spec 的 `所属父项`指向来源 Issue。 +- Ticket 的 `所属父项`指向 Spec。 +- Decision Ticket 的 `所属父项`指向 Wayfinder Map。 +- `前置依赖`保存真实 Base record ID,不保存标题或文本编号。 + +## 4. 第一阶段:需求探索 + +用户原设想: + +```text +grill-me → handoff → prototype → handoff → grill-me +=> 需求文档 + HTML 一次性原型 +``` + +方向合理,但需要把固定流水线改成按问题选路。 + +### 4.1 每个 skill 的实际作用 + +| Skill | 作用 | 直接产物 | 不负责 | +|---|---|---|---| +| `grill-me` | 包装 `grilling`;一次问一个产品/范围决策,并给推荐答案 | 当前会话中的共同理解 | 自动写 PRD、自动发布飞书、替用户做决策 | +| `handoff` | 跨 session/agent 传递恢复所需指针和下一步 | OS 临时目录中的 Markdown | 长期事实源、需求审批、业务状态 | +| `prototype` | 用一次性代码回答一个 UI、状态或数据形状问题 | UI 多变体,或逻辑 TUI/纯模块;运行方式;问题与 verdict | 默认 HTML、生产实现、完整需求文档 | +| 第二次 `grill-me` | 针对使用原型后出现的新冲突,确认 winner 和边界 | Prototype verdict、修订后的产品决策 | 从头重做采访、自动综合文档 | + +`grilling` 明确要求环境可查的事实应直接查,不应反问用户;属于用户的决策才逐项确认。`handoff` 明确写到 OS 临时目录,并要求引用已有 artifacts,不复制其正文。这两点决定了 handoff 只能是运输层。 + +### 4.2 Prototype 不应等同于 HTML + +`prototype` 有两个完全不同的分支: + +| 需要回答的问题 | 原型形态 | +|---|---| +| “这个页面应该长什么样?” | UI 分支:同一路由的 3 个左右结构差异明显的变体,使用 `?variant=`切换 | +| “这个状态模型/业务逻辑合理吗?” | Logic 分支:小型 TUI 驱动纯 reducer、state machine 或函数集合 | + +因此第一阶段的正式产物名称应是“可运行一次性原型”,而不是无条件要求 HTML。 + +还有一个 brownfield 边界:UI skill 强烈偏好把变体嵌入现有页面,复用真实数据、auth、header/sidebar 和信息密度。如果是已有产品,完全不读代码库就制作独立 HTML,容易得到在真页面中不成立的方案。建议: + +- greenfield 或纯概念演示:第一阶段可以制作独立 HTML。 +- brownfield UI:第一阶段允许只读代码库并嵌入真实页面;或把 UI prototype 推迟到第二阶段。 +- 逻辑/状态问题:不要为了满足“HTML”形式而绕过 Logic prototype。 + +### 4.3 三种合理组合 + +#### 简单探索:同一会话 + +```text +grill-me →(必要时 prototype)→ targeted verdict review → Discovery Brief +``` + +没有会话切换时省略两个 `handoff`。 + +#### 跨会话探索 + +```text +grill-me +→ 更新 canonical Discovery dossier +→ handoff(只带 record ID / URL / path / next question) +→ prototype +→ 更新 prototype question、asset、verdict +→ handoff +→ targeted verdict review +→ Discovery Gate +``` + +临时 handoff 即使丢失,也可以从 Base/Wiki/repo 指针恢复。 + +#### 多条相互依赖的不确定性 + +```text +Wayfinder Map:Destination = 通过 Discovery Gate + ├─ grilling ticket(HITL) + ├─ prototype ticket(HITL) + ├─ research ticket(AFK) + └─ task ticket(HITL / AFK) +``` + +Wayfinder 原生提供 Map、Decision Tickets、blocker、frontier 和 fog of war,更适合多会话探索。现有 29 字段已包含 `Wayfinder Map`、`决策 Ticket`和四种`决策票类型`,但 Wayfinder 尚不在六个已完成真实 Feishu POC 的 workflow skills 中;正式默认采用前应补一次 create/update/read-back POC。 + +### 4.4 第一阶段最终产物 + +第一阶段不建议产出第二份 PRD,建议产出: + +#### A. Wiki `Discovery Brief — <标题>` + +至少包含: + +1. Problem、目标用户和期望结果。 +2. 已确认的产品规则与用户决策。 +3. 假设、证据、开放问题和明确延期问题。 +4. 原型要回答的精确问题。 +5. 原型运行方式、变体键或逻辑操作方式。 +6. Prototype verdict:选了什么、为什么、拒绝什么。 +7. 初步可观察验收语言,但不写模块、文件和实现设计。 +8. Out of scope。 +9. 来源 Issue、Prototype、Research、Wayfinder record IDs/URLs。 +10. 人类确认时间和当前版本。 + +#### B. Base 根记录 + +```text +产物类型 = 需求/Issue +来源技能 = grill-me / prototype / research(按实际追加) +工作流阶段 = 探索/澄清 +状态 = 草拟中 → 待确认 → ready-for-agent +产物文档 = Discovery Wiki URL +结论/摘要 = 一段式探索结论 +验收标准 = Discovery Gate +下一步 = grill-with-docs / to-spec +``` + +#### C. 原型资产 + +- 简单探索:`原型` Base child record 指向 Issue,保存问题、运行方式、path/URL 和 verdict。 +- Wayfinder 路径:优先把 prototype 作为 Decision Ticket 的 asset,避免再创建一份重复 Base 记录。 +- 需要长期复现时,保存 `repo@commit:path`。commit/branch/发布都需要独立用户授权。 +- 未获 Git 授权时,可以保存本地路径和内容 hash,但必须标注“仅同机可恢复”。 +- 只有跨团队、需要独立审计的移交才创建 `Handoff` Base 记录;普通 session handoff 不进入业务表。 + +### 4.5 Discovery Gate + +只有以下条件同时满足,第一阶段才可交给第二阶段: + +- 问题、目标用户和期望结果明确。 +- In scope / Out of scope 明确。 +- 原型问题有 verdict,或明确记录“不需要原型”。 +- 阻塞性产品决策为空。 +- 开放风险已显式列出并有 owner/next step。 +- 用户确认 Discovery Brief 代表当前共同理解。 +- Base/Wiki 写入如已执行,已经 read-back。 + +## 5. 第二阶段:需求转化 + +用户原设想: + +```text +grill-with-docs → to-spec → to-tickets +``` + +这条序列基本正确,但每一步应有不同问题域,避免第二次采访。 + +### 5.1 Skill 作用与产物 + +| Skill | 输入 | 作用 | 产物 | +|---|---|---|---| +| `grill-with-docs` | Discovery Brief、prototype verdict、代码库、现有 glossary/ADR | 只处理探索结论与现有代码/领域模型的碰撞;校正术语;确认难逆技术决策 | `CONTEXT.md` 术语更新;少量 ADR;已确认工程约束 | +| `to-spec-feishu` | 已澄清上下文、代码库、领域词汇、ADR、来源 Issue、原型决策 | 不再采访;确认最高可用测试 seam;综合并发布 | Wiki `Spec — 标题` + Base `PRD/Spec`,状态 `ready-for-agent` | +| `to-tickets-feishu` | 已批准 Spec、代码库、切片和依赖 | 拆 tracer-bullet 垂直切片;让用户确认粒度与 blocker;两遍发布关系 | N 个 Base `实现 Ticket`,父项和依赖完整回读 | + +`domain-modeling` 的边界需要保留: + +- `CONTEXT.md`只保存稳定领域词汇,不复制 Spec。 +- ADR 只用于难逆、反直觉且经过真实取舍的决策。 +- 普通 task 细节继续留在 Discovery/Spec/Trellis,而不是推广成长期知识。 + +### 5.2 第一阶段如何成为第二阶段输入 + +建议 `to-spec-feishu` 的输入 manifest 至少包含: + +```text +requestRecordId +discoveryWikiUrl +prototypeRefs[] +researchRefs[] +wayfinderMapRecordId(可选) +repositoryRef +discoveryUpdatedAt / digest +``` + +现有 `to-spec` 已允许把原型中最能表达决策的 state machine、reducer、schema 或 type shape 精简后写入 Spec。工作 Demo 本身不应复制进 Spec。 + +当前 adapter 允许 Spec 关联来源 Issue,但没有强制读取 Issue 的 Discovery Wiki 和全部 prototype/research children。建议把“按来源 Issue 读取并核对探索包”加入 precondition,并在 Spec 的 Sources/Further Notes 中保存稳定 record IDs/URLs。 + +### 5.3 第二阶段最终产物 + +- repo:更新后的领域词汇和必要 ADR。 +- Wiki:唯一 Engineering Spec 长文档。 +- Base:一个 Spec record、N 个 Ticket records、完整 parent/blocker 图。 +- 人类确认:测试 seam、Spec 内容、Ticket 粒度和依赖。 +- 分派信息:owner、priority、collaboration mode,或明确进入“待分派”队列。 + +### 5.4 明确断点:Dispatch Gate + +一手适配契约显示: + +- `to-spec-feishu/references/feishu.md` 的 Spec 字段表没有`负责人`。 +- `to-tickets-feishu/references/feishu.md` 的 Ticket 字段表也没有`负责人`。 +- `start-work-feishu` 只查询`负责人=当前用户`的 Spec/Ticket,并要求保持 owner 不变。 + +因此: + +```text +ready-for-agent ≠ 已分派 ≠ 可被 start-work 查询 +``` + +当前最小方案: + +1. 建立 Base “待分派”视图:`状态=ready-for-agent AND 负责人为空`。 +2. 人类在 Base UI 分派 owner、priority 和 collaboration mode。 +3. `start-work-feishu` 只消费已分派队列。 + +CLI 化的两个可选演进: + +- 新增轻量 `dispatch-work-feishu`:列出未分派 frontier,用户选择 owner,精确 patch 并 read-back。 +- 扩展 `start-work-feishu` 支持“未分派且无 blocker”的自助认领,在同一次“选择并开始”确认中原子写 owner + in-progress;它不能认领已分派给他人的工作。 + +管理者分派和开发者自助认领都需要,不能只实现其中一种。 + +### 5.5 Spec Gate 与 Ticket Gate + +Spec Gate: + +- Discovery 来源完整。 +- 测试 seam 已确认。 +- Wiki 内容 fetch 完整。 +- Base Spec 的 type/status/parent/link/acceptance 已 read-back。 + +Ticket Gate: + +- 每张 Ticket 是单上下文可验证的垂直切片。 +- 用户确认粒度、拆合和依赖。 +- 父项与精确 blocker set 已逐条 read-back。 +- 无 orphan Ticket。 +- 进入 Dispatch Gate,而不是假设已经能 Start。 + +## 6. 第三阶段:开发与收口 + +用户原设想: + +```text +start work → trellis / inline → close work +``` + +建议展开为: + +```text +Dispatch Gate +→ start-work-feishu + ├─ Inline + │ → standard implement / tdd / diagnose + │ → full-diff review + acceptance evidence + │ → Ticket partial close ↔ continue + │ → Spec final close + └─ Trellis + → bind/create planning task + → snapshot/delta review + → Base start patch + read-back + → task.py start + → standard implement / tdd + → checkpoint + full-diff review + → Ticket partial close ↔ continue + → archive + status=completed + → Spec final close +``` + +### 6.1 各角色的边界 + +| 角色/skill | 负责 | 不负责 | +|---|---|---| +| `start-work-feishu` | 查询、选择、刷新、路由、Inline 冻结或 Trellis mapping、开始 patch | 实现代码、完成 Ticket、初始化不存在的 Trellis | +| Inline | 小、明确、单上下文的生命周期选择 | 具体工程方法 | +| Trellis | 跨会话 planning、checkpoint、archive、`1 Spec = 1 task` | 替代 Spec、决定 Ticket 已完成 | +| `standard implement` / `tdd` | 实际编码和验证方法 | Base 状态和最终业务授权 | +| `code-review` / 主会话 acceptance check | 对完整 diff 做 Standards/Spec 检查 | 替代人类产品 review | +| `close-work-feishu` | 证据映射、Ticket 部分收口、Spec 最终收口、幂等对账 | 实现缺失代码、代替用户 review、代替 archive | + +`implement` 原 skill 中的无条件 commit 与当前本机规则冲突;在 Trellis × Matt workflow 中已经被覆盖。commit、push、PR 仍分别需要用户明确授权。 + +### 6.2 Trellis 与 Wiki Spec 的事实源冲突 + +当前总结把 Wiki Spec 定义为叙述事实源,而 Trellis workflow 又把 `prd.md`称为 task-level spec source of truth。如果不分层,实施中修改 Trellis `prd.md`可能产生第二份业务 Spec。 + +建议统一为: + +| 范围 | 权威来源 | +|---|---| +| 已批准的产品需求与验收 | Wiki Engineering Spec | +| 当前业务状态和关系 | Base | +| 当前实现批次的执行基线、技术计划和 checkpoint | Trellis `prd/design/implement` | +| 实现结果 | repo | + +Trellis mapping 应增加或明确维护 `specUpdatedAt`/digest。发现 Wiki/Base Spec 变化时: + +1. 停止使用旧 snapshot。 +2. 重新读取并确认变更。 +3. 刷新 Trellis artifacts。 +4. 只 review delta。 + +不要让 Trellis 反向静默覆盖 Wiki,也不要双向自动同步长文档。 + +### 6.3 Trellis planning review 不应重复审全文 + +Trellis workflow 要求 planning artifacts 在 `task.py start` 前完成 review,而现有 `start-work-feishu` 在 artifact persistence 后可以直接写 Base 并 start;总结中的真实 POC还记录了一次 planning review 豁免。 + +更高效的门禁是: + +- Feishu Spec/Tickets 已经完成用户 review,Trellis 只是忠实 snapshot:做自动一致性检查和 start confirmation,不重新 grill 全文。 +- Trellis 新增了 Spec 中没有的技术决策、兼容策略、rollout/rollback 或重大执行取舍:只对新增 delta 做 `grill-with-docs` review,再 start。 +- Artifact persistence 或 mapping read-back 失败:不写 Base。 + +这既关闭了 workflow 规则缺口,也避免重复审批。 + +### 6.4 Close 实际是循环,不是一次动作 + +`close-work-feishu` 有三个 route: + +1. Ticket 部分收口。 +2. Spec 最终收口。 +3. 失败后的幂等对账。 + +Ticket 可以在 Trellis task 尚未 archive 时逐张完成。父 Spec 只有在以下门禁全部通过后才能完成: + +- 所有 child Tickets 恰好为`已完成`。 +- 每条 Spec acceptance 都有直接证据。 +- 用户完成 Spec 最终 review。 +- Trellis 路径的 task 已 archive 且 `status=completed`。 +- 没有 Ticket write/read-back failure。 +- 用户单独确认 Spec-only patch。 + +`task.py finish`只解除当前 session 指针,不能替代 archive 或 Base closure。 + +### 6.5 第三阶段最终产物 + +- repo:代码、测试、必要文档、真实命令结果、完整 diff review。 +- Inline:冻结的 Spec/Ticket IDs 和当前会话证据;跨会话时必须重新按 ID 选择。 +- Trellis:mapping、planning artifacts、checkpoint、archive task。 +- Base Tickets:每张 Ticket 的验收映射、验证证据、代码引用和终态 read-back。 +- Base Spec:最终验收证据、最终人类 review、终态 read-back。 +- 来源 Issue:保留与 Spec 的父子关系供人类追踪;其状态由人类在 Base 中按需检查。 + +当前 `close-work-feishu` 关闭到 Spec 为止,不自动关闭或报告来源 Issue。此边界视为有意设计,不作为自动化断点。 + +## 7. 跨阶段传递性总表 + +| 阶段 | 最终产物 | 稳定身份/位置 | 下阶段如何消费 | 当前成熟度 | +|---|---|---|---|---| +| Setup(一次性) | tracker contract | repo `docs/agents/issue-tracker.md` | 所有 Feishu skills 读取 | 已验证 | +| 探索 | Base Issue + Wiki Discovery Brief | Issue record ID + Wiki URL | `grill-with-docs`、`to-spec` | 缺正式探索发布 adapter | +| 原型决策 | Prototype record/decision ticket + asset + verdict | record ID、path/branch/URL | Spec 的 Decisions/Sources | schema 已支持,发布 POC 待补 | +| 复杂探索 | Wayfinder Map + Decision Tickets | Map/Ticket record IDs | Discovery Gate 汇总 | skill 已有,Feishu POC 待补 | +| 领域转化 | `CONTEXT.md` + 必要 ADR | repo path/commit(如获授权) | Spec 使用词汇与决策 | 已有 skill | +| 工程规格 | Wiki Spec + Base Spec | Spec record ID + Wiki URL;parent=Issue | Tickets、Start、Trellis snapshot | 已真实 POC | +| 实施计划 | Base Tickets + dependency graph | Ticket IDs;parent=Spec;blocker IDs | Start 计算 frontier;Close 逐票验收 | 已真实 POC | +| 分派 | owner/priority/mode | Base fields | 进入当前用户 Start 队列 | **当前断点** | +| Inline 执行 | 会话冻结 IDs + repo 证据 | record IDs、diff/test refs | Close | 已设计;跨会话需重选 | +| Trellis 执行 | mapping + artifacts + checkpoint | task path + `meta.feishuTracker` | Close 解析 Spec、证据和 archive | 已真实 POC | +| Ticket 收口 | evidence/code refs + terminal read-back | Ticket record ID | 解锁下一 frontier | 已真实 POC | +| Spec 收口 | 全 Ticket、acceptance、review、archive、read-back | Spec record ID | 阶段交付完成;来源 Issue 由人类按需处理 | 已真实 POC | + +## 8. 组合场景建议 + +| 场景 | 推荐组合 | +|---|---| +| 简单、无重大不确定性的需求 | `grill-me → Discovery Brief → grill-with-docs → to-spec → 少量 Tickets/直接 Start` | +| Greenfield UI 探索 | `grill-me → 静态 HTML 多变体 → verdict review → Discovery Brief` | +| Brownfield 页面调整 | `grill-me → 只读代码库 → 在真实路由做 UI variants → verdict → to-spec` | +| 状态机/业务逻辑不确定 | `grill-me → Logic TUI prototype → verdict → Spec 中吸收 decision-rich 状态模型` | +| 多会话、多条互相依赖的不确定性 | `Wayfinder Map → grilling/prototype/research/task frontier → Discovery Gate` | +| 外部 Issue/PR 进入 | `triage → needs-info/ready-for-agent → 必要时 Discovery/Spec → Tickets` | +| 小型已明确实现 | `start-work → Inline → standard implement → review → close` | +| 跨模块、长验收链 | `start-work → Trellis → delta review → implement/checkpoint → partial close → archive → final close` | +| 用户明确要求 test-first | `to-spec 确认公开 seam → TDD mode → vertical red/green slices → review → close` | + +## 9. 更好的飞书 CLI 管理方案 + +### 9.1 保留四事实源,不做大一统同步 + +应继续坚持: + +- Base 管“是什么状态、谁负责、依赖谁”。 +- Wiki 管“为什么做、达成了什么共同理解”。 +- Trellis 管“复杂执行如何恢复和归档”。 +- repo 管“实际上实现和验证了什么”。 + +同步只传稳定 ID、版本、摘要、验收边界和证据指针。不要在 Base 复制全文,不要在 Trellis 复制业务状态,不要让 Wiki 保存一份代码侧事实副本。 + +### 9.2 现有 29 字段足以做 P0 + +P0 不建议先加字段。可以直接使用: + +- `产物类型` +- `来源技能` +- `工作流阶段` +- `状态` +- `负责人` +- `最后更新人` +- `产物文档` +- `结论/摘要` +- `验收标准` +- `验证证据` +- `下一步` +- `代码引用` +- `所属父项` +- `前置依赖` + +只有多个真实查询场景证明有价值时,才考虑新增多值`来源产物`或显式 version/digest 字段。 + +### 9.3 建议的 Base 视图/报告 + +| 视图/报告 | 条件或用途 | +|---|---| +| 探索中 | Issue/Wayfinder;阶段=探索/决策;状态=草拟/待确认 | +| 决策 frontier | Decision Ticket 未完成、未阻塞、未认领 | +| 待分派 | `ready-for-agent`且 owner 为空 | +| 我的可开始 | owner=当前用户且 blockers 全部恰好`已完成` | +| 进行中/阻塞 | 阻塞项必须有`阻塞原因`和`下一步` | +| 待评审 | Ticket 和 Spec 分组显示 | +| 待对账 | 写失败、read-back mismatch、Trellis archived 但 Base 未闭环 | +| 一致性异常 | 完成无证据、Ticket 无父项、Spec 完成但 child 未全完成、进行中但 owner 为空 | + +Frontier 和一致性判断应由 CLI 完整分页后计算,不依赖第一页或肉眼判断。 + +### 9.4 Base Workflow 只做提醒,不做完成决策 + +当前 `lark-cli 1.0.76`支持 Base Workflow、views、record history 和 data query。推荐的自动化边界: + +- 可以:状态变为待确认/待评审时通知 owner;未分派 ready item 超时提醒;阻塞项定期提醒。 +- 不可以:因为测试通过、Trellis archive 或所有可见 Tickets 看似完成,就自动把 Spec 设为已完成。 +- 不可以:用 Workflow 取代人类 review、写前重读和写后回读。 +- Workflow 新建后保持 disabled;经过 dry-run/定义检查和用户确认后再单独 enable。 + +### 9.5 增加机器可读 tracker contract + +当前 `docs/agents/issue-tracker.md`适合人读,但自动化需要解析自然语言。建议 Setup 稳定后同时生成: + +```text +docs/agents/issue-tracker.md +docs/agents/issue-tracker.json +``` + +JSON 建议保存: + +```text +schemaVersion +baseToken / tableId / viewIds / wikiRoot +semantic field key → field ID +enum values +completion gates +``` + +不保存 API credentials,也不保存固定个人 open ID;操作者身份仍在每次运行时通过 verified auth 解析。 + +### 9.6 抽机械 helper,不抽业务判断 + +六个 Feishu skills 已重复使用身份门禁、schema 验证、完整分页、record-ID patch、写前重读、写后回读、ignored-fields 检测和 batch reconciliation。可以在更多 POC 后抽取薄 helper: + +```text +tracker auth-check +tracker contract-validate +tracker list-all +tracker patch-and-verify +tracker batch-patch-and-reconcile +tracker wiki-append-and-fetch +``` + +Helper 只包装当前 `lark-cli`并输出结构化 JSON/exit code。以下判断必须继续留在人类和 skill: + +- 该问哪个产品问题。 +- 谁应该负责。 +- Inline 还是 Trellis。 +- Ticket 是否满足验收。 +- 是否允许关闭 Spec/Issue。 + +不要构建会自行推进全部状态的“大一统 Agent workflow”。 + +### 9.7 统一外部写入协议 + +所有 Feishu 记录写入继续遵守: + +1. 读取 tracker contract。 +2. 验证 bot 与当前人类 user,冻结本轮 user open ID。 +3. 完整查询并用 record ID 定位。 +4. 展示稳定 IDs 和精确 patch。 +5. 用户确认外部写入。 +6. 写前按 record ID 重读,发生漂移则确认失效。 +7. 最小 patch;`负责人`和`最后更新人`语义分离。 +8. 写后 `record-get`/完整分页回读。 +9. 分别报告 updated、already synchronized、failed、mismatched。 + +Base record history 可用于单记录审计,但不能替代应用侧的全表一致性报告。 + +## 10. 推荐的 V2 主流程 + +```mermaid +flowchart TD + Setup["一次性 Setup<br/>tracker contract"] --> Intake["创建/接收 Base Issue"] + Intake --> Explore{"探索复杂度"} + Explore -->|"简单"| Grill["grill-me"] + Explore -->|"多会话/多决策"| Map["Wayfinder Map + Decision Tickets"] + Grill --> Proto{"需要可运行反馈?"} + Map --> Proto + Proto -->|"UI"| UI["HTML / 真实路由多变体"] + Proto -->|"Logic"| Logic["TUI / state model"] + Proto -->|"否"| Brief + UI --> Verdict["targeted verdict review"] + Logic --> Verdict + Verdict --> Brief["Discovery Brief + Discovery Gate"] + + Brief --> GWD["grill-with-docs<br/>只处理代码库碰撞与 durable decisions"] + GWD --> Spec["to-spec-feishu<br/>Wiki Spec + Base Spec"] + Spec --> Tickets["to-tickets-feishu<br/>vertical Tickets + blockers"] + Tickets --> Dispatch["Dispatch Gate<br/>owner / priority / mode"] + + Dispatch --> Start["start-work-feishu"] + Start -->|"Inline"| Impl["standard / tdd implementation"] + Start -->|"Trellis"| Bind["bind + snapshot/delta review"] + Bind --> Impl + Impl --> Review["full-diff review + evidence"] + Review --> Partial["close-work:Ticket 部分收口"] + Partial -->|"仍有开放 Ticket"| Impl + Partial -->|"全部完成"| Archive{"Trellis?"} + Archive -->|"是"| TArchive["archive + status=completed"] + Archive -->|"否"| Final + TArchive --> Final["close-work:Spec 最终收口"] +``` + +流程不是不可逆直线: + +- 第二阶段发现产品结论与代码事实冲突:回到 Discovery Brief,重新确认受影响决策。 +- 开发中发现 Spec/acceptance 错误:回第二阶段修订 Spec/Tickets并重新 read-back。 +- 只在实现偏离而需求正确时留在第三阶段修代码。 +- 任何回退都更新 owning artifact,不依赖聊天摘要。 + +## 11. 落地优先级 + +### P0:先补断链,不改大架构 + +> 决策(2026-07-28):实施以下 1–5;不增加来源 Issue 状态报告或聚合关闭,由人类在 Base 中自行检查。 + +1. 明确第一阶段产物叫 Discovery Brief,不叫第二份 PRD。 +2. 把 `handoff` 从必经节点改成“发生 session 边界时才使用”。 +3. 建立 Base “待分派”视图,补 Dispatch Gate。 +4. 让 `to-spec-feishu` 显式读取来源 Issue、Discovery Wiki 和 prototype/research refs。 +5. 为 Feishu-bound Trellis task 定义 snapshot/delta review,消除重复全文审批。 + +### P1:让复杂探索可管理 + +1. 为 Discovery/Prototype/Wayfinder 做一次真实 Base/Wiki create/update/read-back POC。 +2. 增加 CLI 分派或 start self-claim 能力。 +3. 建立探索、决策 frontier、待分派、待对账和一致性异常视图。 + +### P2:稳定后工程化 + +1. 生成机器可读 tracker JSON contract。 +2. 抽取 `lark-cli` 机械 helper。 +3. 多个真实查询证明需要后,再扩展`来源产物`或 version/digest schema。 +4. 仅把提醒类流程沉淀为 Base Workflow,不自动做完成决策。 + +## 12. 最终评价 + +这套方案不需要推翻。它已经有一个很好的骨架: + +```text +Issue → Spec → Tickets → Start → Inline/Trellis → Evidence → Partial/Final Close +``` + +真正需要调整的是五个语义: + +1. `handoff` 是会话运输,不是业务产物。 +2. Discovery Brief 是产品探索结论,不是 Engineering Spec。 +3. 可运行原型不必然是 HTML。 +4. `ready-for-agent` 不等于已分派,也不等于可以被 Start 查询。 +5. Trellis 是执行基线和生命周期,不应成为第二份业务 Spec。 + +补上 Discovery 发布、Dispatch Gate、明确 implementation owner 和 Trellis delta review 后,三个阶段的产物就能形成可追踪、可恢复、可审计的闭环;来源 Issue 的后续状态继续由人类管理。 diff --git a/notes/工作流整理.md b/notes/工作流整理.md new file mode 100644 index 0000000..e69de29