Files
obsidian-vault/docs/Matt 工作流 × 飞书 CLI 全流程总结.md
T
yuxuanhui dcd6d44960 feat: add Feishu user authorization flow documentation and update frontend guidelines
- Added new documentation for the Feishu user authorization flow, detailing the backend protocol, authorization initiation, callback handling, and token management.
- Updated frontend index to link to the new authorization flow documentation for better accessibility and guidance on UI design consistency.
2026-08-31 09:18:03 +08:00

521 lines
29 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Matt 工作流 × 飞书 CLI 全流程总结
> 状态:已通过真实 Feishu Base / Wiki POC 验证
> 更新时间:2026-07-26
> 覆盖范围:`setup-workflow-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-workflow-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-workflow-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/<concept>.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 <BASE_TOKEN> --table-id <TABLE_ID> --limit 200 --as bot --format json
lark-cli base +record-search --base-token <BASE_TOKEN> --table-id <TABLE_ID> --keyword "<TITLE>" --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 负责在三者之间建立可回读、可审计的连接。**