760 lines
40 KiB
Markdown
760 lines
40 KiB
Markdown
# 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-workflow-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-workflow-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-workflow-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)
|