107 lines
6.7 KiB
Markdown
107 lines
6.7 KiB
Markdown
# ACK 飞书多维表格 Bug 收件箱
|
||
|
||
## 目标
|
||
|
||
让用户在飞书多维表格中跨设备记录文字和截图,由 ACK Coordinator 在同一记录补全并
|
||
反复修订修复逻辑与验收标准。用户明确审核通过后,才将批准版本整理为独立、可验收、
|
||
可幂等追踪的 ACK 任务并启动三角色闭环。
|
||
|
||
## 非目标
|
||
|
||
- 不用 Skill 承担人工记录入口。
|
||
- 不抓取公开网页或依赖浏览器登录态。
|
||
- 不把 App Secret、access token 或飞书用户凭据写入项目。
|
||
- 不在审核前把草案写入 `tasks.yaml`,也不把 ACK 执行状态持续双向同步到飞书。
|
||
- 不把多条互不相关的 Bug 合成一次 Developer 派发。
|
||
|
||
## 项目配置契约
|
||
|
||
可选配置位于 `docs/ack/tasks.yaml` 的 `project.bugIntake`。未配置时 ACK 保持现有行为。
|
||
配置存在时必须包含:
|
||
|
||
| 字段 | 约束 |
|
||
|------|------|
|
||
| `provider` | 固定为 `feishu-base` |
|
||
| `workflow` | 审核前协作固定为 `reviewed-writeback-v1`;缺省表示旧只读模式 |
|
||
| `profile` | `lark-cli` profile 名称;每次命令显式传入 |
|
||
| `baseToken` | 飞书 Base token |
|
||
| `tableId` | 数据表 ID |
|
||
| `viewId` | 只包含可导入记录的 `ACK Ready` 视图 ID |
|
||
| `fields` | 逻辑字段到飞书字段 ID/名称的映射 |
|
||
|
||
`fields` 必须映射 `title`、`actual`、`expected`、`stepsToReproduce`、
|
||
`acceptance`、`priority`、`attachments`、`updatedAt`。启用审核前协作时还必须映射
|
||
`fixLogic`。字段值只作为单个 argv 传给 `lark-cli`,不经过 shell。
|
||
|
||
## CLI 契约
|
||
|
||
- 可执行文件固定为可信路径中的 `lark-cli`。
|
||
- 允许官方 npm 包生成且 package/bin 映射校验通过的 `run.js` wrapper,并解析到包内
|
||
native binary 执行;拒绝缺少 native binary 或其它同名软链接目标。
|
||
- profile 由项目显式选择;不得执行 `profile use` 或读取 active profile作为回退。
|
||
- 子进程使用最小环境,不继承可能覆盖 profile/config/凭据或注入运行时的环境变量。
|
||
- 记录读取使用 `base +record-list`、JSON 输出、指定 Base/table/view 和投影字段。
|
||
- 草案写回只通过读取器的 `write-draft` 子命令调用 `base +record-upsert`,并且只允许修改
|
||
配置映射的 `fixLogic` 与 `acceptance`。
|
||
- 批准后只通过 `import-approved` 生成规范任务字段和可重算的 `approvedPayloadHash`;任务
|
||
校验器拒绝审核字段与该 hash 不一致的 reviewed task。
|
||
- 记录超过一页时按 offset/limit 继续读取,并设置总页数/记录数上限。
|
||
- 附件仅通过 `base +record-download-attachment` 下载到调用者显式提供的临时目录。
|
||
- 附件数量、单文件大小、批次总大小和子进程文件写入均有硬上限;落盘大小必须与
|
||
元数据一致。
|
||
- 标准输出必须是单一 JSON;CLI stderr 只作为错误摘要,不把可能的凭据写入结果。
|
||
|
||
## 标准化结果
|
||
|
||
读取器输出批次元数据和 `records`。每条记录至少包含:
|
||
|
||
- `sourceRef`:对 provider、profile、Base、table、record ID 做域隔离 SHA-256
|
||
后得到的稳定匿名引用;原始 profile、Base token 与 record ID 不拼入引用文本;
|
||
- `recordId` 与 `updatedAt`;
|
||
- 绑定来源事实、附件元数据和审核字段的 `draftRevision`;
|
||
- title、actual、expected、steps、可选 fixLogic、acceptance、priority;
|
||
- `enrichmentRequired`:缺失但允许 Coordinator 整理的 steps、fixLogic、acceptance、priority;
|
||
- 附件的 name/type/size 与可选本地临时路径;附件 token 只在下载命令内部使用;
|
||
- 原始字段中无法映射但不影响导入的警告。
|
||
|
||
输出不得包含 App ID、App Secret、Base token、附件 file token、tenant/user access
|
||
token 或 CLI 配置文件内容。
|
||
|
||
## Coordinator 整理规则
|
||
|
||
1. 先运行读取器 `check` 确认 `lark-cli` 和项目 profile,再单独核对 app 已获得所需读写
|
||
scope;`check` 不把用户 token 状态当作 app/bot scope 证明。
|
||
2. 运行读取器 `plan` 读取 `ACK Ready` 视图并生成 create/refresh/unchanged/drift
|
||
整理动作;需要看截图时使用临时下载目录。
|
||
3. 将记录分类并在飞书补全 `fixLogic` 与 `acceptance`;用户反馈时继续写回同一记录。
|
||
4. 用户必须明确批准当前 `draftRevision`;通过前不写 `tasks.yaml`、不派发角色、不修改
|
||
应用代码。通过后每条导入任务保存 `source.kind=feishu-base`、`source.ref`、
|
||
`source.recordId`、`source.updatedAt`、`source.workflow`、`source.approvedRevision`、
|
||
`source.approvedPayloadHash`,并把截图观察转成文字证据。
|
||
5. 导入前扫描已有任务的 `source.ref`。相同来源不得新建第二条任务。
|
||
6. 来源更新但任务尚为 `open` 时可由 Coordinator刷新描述;任务已派发或进入终态时只报告漂移,由用户决定是否新开任务。
|
||
7. 飞书记录删除、不可访问或 CLI 暂时失败时保留已有 ACK 任务,不反向删除。
|
||
8. title、actual、expected、updatedAt 是不可推断的来源事实,部分缺失时 fail closed;
|
||
steps、fixLogic、acceptance、priority 缺失时由 Coordinator 根据来源事实和项目上下文
|
||
补齐并写回飞书。只有批准后的最终版本才导入任务板。
|
||
9. 没有附件且所有 Bug 内容字段均为空的误建行跳过并输出 `blank_record_skipped`;带部分
|
||
来源事实的残缺行不得静默跳过。
|
||
|
||
## 可观测验收信号
|
||
|
||
1. 两个假租户 profile 同时存在时,项目指定 `tenant-b`,所有记录和附件命令都显式包含 `--profile tenant-b`,不会读取 active 的 `tenant-a`。
|
||
2. 只读取配置的 `ACK Ready` view ID,并投影配置字段;不查询整张表或其它视图。
|
||
3. 一条含截图附件的假记录被标准化为稳定 `sourceRef`、完整文字字段和本地附件路径,输出中不存在任何 secret/token 凭据。
|
||
4. CLI 缺失、profile 缺失、畸形 JSON、错位矩阵、分页越界、路径穿越或附件下载失败均返回非零退出码且不输出伪成功结果。
|
||
5. ACK 文档明确要求按 `source.ref` 幂等整理;同一读取结果重复提交不会生成第二个来源任务。
|
||
6. 现有无 `bugIntake` 的 ACK 项目仍能通过任务板校验并按原流程工作。
|
||
7. 缺少 steps、acceptance、priority 的记录仍生成 create/refresh 计划并列出
|
||
`enrichmentRequired`;全空误建行被跳过,缺 title/actual/expected 的部分记录失败。
|
||
|
||
## 最脆弱假设与降级
|
||
|
||
本设计假设官方 `lark-cli` 的 Base JSON 输出保持 `fields`、`record_id_list` 与行矩阵
|
||
对应关系。读取器必须校验三者长度和字段映射;若上游输出契约变化,立即失败并提示
|
||
升级适配器,不能错列生成 Bug。飞书或 CLI 不可用时,只停止新的同步,已经进入
|
||
`tasks.yaml` 的任务继续按 ACK 闭环执行。
|