会议纪要、行动项与自动提醒工程手册
“会上已经说过”为什么没有变成一次交付
接口联调会结束后,后端口头承诺补幂等键,客户端承诺重试时复用请求 ID,测试准备增加断网恢复用例。下一轮联调仍然失败:聊天记录里能找到三句承诺,却没有一个可查询的 owner、期限或验收证据;纪要中的复选框已经勾选,但代码、测试和发布记录都没有回链。团队不是忘记开会,而是把“讨论内容”和“可执行工作”误写成了同一个对象。
一条可靠链路至少包含两类事实。会议纪要保存议题、上下文、结论和异议,是一次会议的不可变快照;行动项保存要改变什么、由谁负责、何时检查、处于什么状态以及怎样证明完成,是持续变化的工作对象。把行动项只留成纪要里的普通文本,提醒系统无法查询它,工单系统无法流转它,人员离开后也无法重新分派。
“不可变快照”不是说页面从此不能编辑,而是每次改变结论都产生新修订,并保留旧修订的身份。会议开始时先固定输入:源需求或事故 ID、候选提交或文档版本、议题清单、决策角色;结束时再固定输出:结论、异议、未决问题和行动项 ID。会后补充错字可以留编辑历史,改变结论则必须写明替代了哪个修订并重新通知受影响角色。否则后来上传的新方案会悄悄借用旧会议的同意。
先认清六个对象
| 对象 | 稳定身份 | 应保存的事实 | 不应冒充的事实 |
|---|---|---|---|
| 会议 | 纪要工单或页面 ID | 议题、参会角色、输入、结论、未决问题 | 行动项的实时状态 |
| 结论 | 纪要内锚点或决策 ID | 选择、理由、反对意见、触发复审的条件 | 实现已经完成 |
| 行动项 | 独立工单 ID | owner、deadline、状态、验收标准 | 一句“后续跟进” |
| 关系 | 工单链接 | 源纪要、实现 PR、发布、故障或 ADR | 复制粘贴的标题 |
| 提醒 | 自动化执行 ID | 查询条件、目标、发送结果 | 任务一定被处理 |
| 证据 | URL、提交或检查运行 ID | 测试、变更、日志、截图或批准记录 | owner 的口头确认 |
这里的 owner 是对结果负责并更新状态的人,不是被抄送的人;deadline 是下一次必须发生状态变化的时间,不等于一定上线的承诺;“完成”表示验收标准已经有证据,不表示复选框被点击。
owner、deadline、evidence 与 escalation 要形成一条连续约束。owner 到检查点前要么提交证据,要么声明阻塞;声明阻塞时必须给出依赖 owner 与下一检查点;检查点已过且两者都没有时,系统升级给项目 owner,而不是继续给原 owner 重复发同一条提醒。升级只改变响应路径,不自动改变任务优先级,也不替代项目负责人对取舍的判断。
从仓库原生入口跑通一条链
小团队可以先使用代码仓库已有的 Issues 和 Projects,不必部署新的协作服务器。GitHub CLI 的安装、登录与升级入口以 GitHub CLI 官方说明 为准;运行 gh auth status 应显示当前主机、账号和授权方式。不要把 gh auth token 的输出粘进纪要、终端截图或 CI 日志。
仓库管理员先创建标签:
gh label create meeting-note --color 1D76DB --description "Meeting record" --force
gh label create action-item --color FBCA04 --description "Trackable follow-up" --force
gh label create action:blocked --color B60205 --description "Waiting on a dependency" --force随后在 .github/ISSUE_TEMPLATE/meeting-note.yml 保存纪要入口。GitHub 要求 Issue Form 位于 .github/ISSUE_TEMPLATE,支持必填校验、默认标签和负责人;该能力仍可能调整,启用前应查看 Issue Forms 语法与预览状态。
name: Meeting record
description: Record decisions and link follow-up issues
title: "[Meeting] "
labels: ["meeting-note"]
body:
- type: textarea
id: trigger
attributes:
label: Trigger and evidence
description: What failure, change, metric, or conflict caused this meeting?
validations:
required: true
- type: textarea
id: conclusions
attributes:
label: Conclusions and dissent
description: Record the selected result, reason, and unresolved objections.
validations:
required: true
- type: input
id: input_version
attributes:
label: Reviewed input
description: Commit, document revision, incident ID, or other stable input identity.
validations:
required: true
- type: textarea
id: actions
attributes:
label: Linked action issues
description: Add one issue reference per action, for example #123.
value: "- "
validations:
required: true
- type: textarea
id: evidence
attributes:
label: Source evidence
description: Link sanitized design, trace, incident, or test evidence.
validations:
required: true行动项使用另一个表单,保存为 .github/ISSUE_TEMPLATE/action-item.yml:
name: Action item
description: Create one owned and verifiable follow-up
title: "[Action] "
labels: ["action-item"]
body:
- type: input
id: source
attributes:
label: Source record
description: Meeting issue, review issue, incident, or decision ID.
placeholder: "#123"
validations:
required: true
- type: input
id: deadline
attributes:
label: Target checkpoint
description: Use the project date field as truth; repeat it here for export readability.
placeholder: "T+2d or project Target date field"
validations:
required: true
- type: textarea
id: acceptance
attributes:
label: Acceptance evidence
description: State the observable result and where evidence will be linked.
validations:
required: true
- type: textarea
id: rollback
attributes:
label: Failure and rollback
description: State what blocks completion and how a partial change is reverted.
validations:
required: true
- type: textarea
id: escalation
attributes:
label: Escalation route
description: Name the project owner, dependency owner, and the event that triggers escalation.
validations:
required: true表单不能强制提交者选择真实 assignee,也不能直接填充 GitHub Project 的自定义字段。行动项创建后必须再做三步:把 assignee 设为唯一主 owner;加入团队 Project;填写 Status 与 Target date。Project 的日期、单选和 PR 关联字段定义见 GitHub Projects 字段说明。若提交者没有 Project 写权限,表单的 projects 字段可能无法完成加入;更稳妥的是启用 Project auto-add 工作流,并按实际套餐核对自动加入工作流数量限制。
正向实验:让承诺变成可查询的行动项
先通过网页表单创建会议纪要,再为“补充幂等测试”创建独立行动项。也可以用 CLI 创建实验数据,但要注意 API/CLI 可以绕过表单必填校验:
gh issue create \
--title "[Action] Add idempotency retry test" \
--label action-item \
--assignee @me \
--body $'### Source record\n#123\n\n### Target checkpoint\nT+2d\n\n### Acceptance evidence\nA retry test passes and its pull request links this issue.\n\n### Failure and rollback\nRevert the fixture change if it alters unrelated cases.'命令应返回新 Issue URL。把该编号回填到会议纪要,并在实现 PR 的正文写 Closes #<action-id>;GitHub 支持用 closing keyword 建立 PR 到 Issue 的关系,并在默认分支合并后关闭工单,具体语义见 Issue 与 PR 关键字说明。验证查询为:
gh issue list --label action-item --state open \
--json number,title,assignees,url \
--jq '.[] | {number,title,owners:[.assignees[].login],url}'预期能看到行动项编号、标题、一个 owner 和 URL。Project 视图中还应出现非空 Status、Target date 与 linked pull request。测试合并后,Issue 时间线应保留关闭它的 PR;先把状态推进到 InReview,由验收者打开测试运行并核对断言,再进入 Done。若 PR 只改了测试名称或运行链接无权访问,验收者应退回 InProgress,这能证明状态由证据驱动,而不是由合并事件直接驱动。
会议纪要此时仍保留原始结论和行动项编号,不复制行动项的当前状态。查询实时进度时打开行动项;追问“当时基于什么输入作出承诺”时打开纪要修订。一个对象保存历史快照,一个对象承载流转,避免双写。
反向实验:故意制造一个无人负责的“完成”
在会议纪要里增加 - [x] 补充超时测试,但不创建行动项;再用 CLI 创建一个没有 assignee 的工单:
gh issue create \
--title "[Action] Verify timeout behavior" \
--label action-item \
--body "Created without source, owner, deadline, or acceptance evidence."
gh issue list --label action-item --state open \
--json number,title,assignees,body \
--jq '.[] | select((.assignees|length)==0 or (.body|contains("### Source record")|not))'预期第二条命令返回这条坏数据。它证明两个失效点:Markdown 复选框可以制造“看起来完成”的假象;Issue Form 的网页校验不是数据层约束,CLI、API、迁移工具和自动化身份仍能写入残缺对象。项目必须用定时查询或 CI 再检查不变量,而不能把模板存在当成治理完成。
自动提醒要有查询、去重和死亡证据
提醒系统的输入应是结构化行动项,而不是扫描整篇纪要。一个最小规则可以表达为:
candidate = type == action-item
AND status NOT IN (Done, Cancelled)
AND target_date <= now + reminder_window
AND owner IS NOT EMPTY
dedupe_key = action_id + target_date + reminder_stage
escalate = target_date < now
AND evidence IS EMPTY
AND blocked_dependency IS EMPTYdedupe_key 防止定时任务每次运行都刷屏。提醒发送后写回 last_reminded_at 或追加带执行 ID 的机器人评论;目标日期、owner 或状态变化时,旧去重键失效。满足 escalate 时创建一次升级事件,目标是项目 owner,并引用原行动项、原 owner、错过的检查点和最近一次成功提醒。通知失败不能把行动项改成已提醒,应记录 delivery_failed、目标通道、HTTP 状态或平台执行 ID,并通知自动化 owner。
Jira Cloud 可以在项目自动化中建立 Scheduled trigger,用 JQL 查询临近到期且未完成的行动项,再发送通知或评论。定时触发器、连续失败后的停用行为见 Jira Automation triggers;规则的 scope、owner、actor 与错误通知设置见 创建自动化规则。示例查询思路是:
labels = action-item
AND assignee IS NOT EMPTY
AND due <= 2d
AND statusCategory != Done
ORDER BY due ASC先把规则限制在试点项目并使用只拥有浏览、评论和必要编辑权限的专用 actor。手动运行一次,预期审计日志显示查询命中的工单、执行分支和发送结果。随后把通知目标改成无效通道,反向运行应在 Automation audit log 中留下失败步骤;如果只有聊天里“没收到”,还不足以区分规则未触发、查询为空、权限拒绝、通道失败或收件人静音。
自动化执行量、并发、查询条数和处理时间存在服务限制,规则还可能因持续失败而停用。实施前按租户套餐查看 Atlassian automation service limits,不要写死价格或把试用环境行为当作长期承诺。GitHub Projects 的字段、自动加入和 API 也受产品与套餐边界影响;规模扩大前应用目标组织的设置页和官方计划页重新确认。
状态不能替代证据
建议把行动项状态压缩为少量可解释状态:
Blocked 必须同时写阻塞对象、依赖 owner 和下一检查点,否则只是把超期换了颜色。Escalated 表示响应契约失效,必须记录升级事件与重新分派结果,不能作为长期停车场。Done 需要验收者能打开的证据;Cancelled 需要有权角色、原因和替代工单或结论。聊天中的“我接了”不自动进入 InProgress,代码提交也不自动进入 Done。状态由事件推动,证据解释事件为什么成立。
工单状态不反映真实进度时,先按下面顺序取证:
| 现象 | 第一证据 | 常见原因 | 修复后再验证 |
|---|---|---|---|
| owner 收不到提醒 | 自动化执行日志与收件目标 | 查询未命中、actor 无权、通知被限流 | 手动触发并看到成功执行 ID |
| 工单已关闭但代码未上线 | Issue 时间线、PR 与发布记录 | closing keyword 在合并时提前关闭 | 增加发布状态或把验收动作拆为后继工单 |
| Project 没有行动项 | auto-add 过滤器与权限 | 标签不匹配、提交者无 Project 权限 | 新建匹配工单并确认自动加入 |
| 状态长期停在进行中 | 最后更新时间、阻塞关系、owner 活跃状态 | owner 离开、任务过大、依赖未建模 | 重分派或拆分后更新检查点 |
| 行动项已经超期却无人升级 | 目标日期、升级事件、规则审计日志 | 规则只发提醒、项目 owner 为空、去重键误吞升级 | 补齐升级路由并用过期测试项确认只升级一次 |
| 同一人收到重复提醒 | 机器人评论与去重键 | 多条规则重叠、目标日期变化未重算 | 同一阶段只留下一个执行记录 |
会议工具接入项目的正确位置
会议不是新的事实源。需求和缺陷仍归工单;实现归提交与 PR;发布归流水线;长期架构选择归 ADR;纪要只保存这些对象在某次讨论中的输入与结论。项目模板应要求纪要回链源工单,行动项回链纪要,PR 回链行动项,发布或故障记录再回链实现。任意一环用复制文本代替稳定 ID,后续更新就会产生多个版本。
Confluence Cloud 的 action item 可以通过 [] 创建并 @ 指派,受指派者会在任务入口和通知中看到它,真实行为见 Confluence action items 与 mentions。这适合轻量跟进,但涉及代码交付、跨项目状态、期限查询和发布证据时,仍应创建工单并从页面链接过去。知识库任务和工单同时可编辑时,明确工单是状态事实源,页面只渲染或引用,否则会出现一边勾选、一边仍开放的双写冲突。
权限、凭证和敏感数据从会议输入开始控制
纪要常包含客户名称、事故时间线、漏洞路径、内部拓扑、录屏和聊天导出。广泛可读的纪要只保存脱敏结论和受控证据编号;原始日志、录音、客户数据和安全细节进入权限更窄、留存策略明确的系统。不要因为工单是私有仓库就粘贴令牌、Cookie、预签名 URL 或生产连接串,仓库导出、通知邮件和第三方机器人都会扩大数据流。
自动化身份只授予读取行动项、写评论或更新目标字段所需权限。仓库内 Issue 评论可使用 GITHUB_TOKEN 并在 workflow 中显式声明最小 issues 权限;该令牌的资源边界仍是当前仓库。更新组织级 Projects 时,改用被组织批准、明确授予 Projects 权限的 GitHub App 安装令牌,并把可访问仓库压到实际集合,不要虚构一个 workflow projects 权限键,也不用成员个人 PAT。Jira 规则的 actor 与 owner 分开:actor 决定执行权限,owner 接收失败并维护规则。离职时先转移开放行动项和规则 owner,再撤销账号与凭证,并检查最近执行日志是否出现权限拒绝。
容量和成本首先消耗的是注意力
行动项规模增长会同时消耗工单席位、Project 字段、自动化执行量、API 配额、附件存储、通知通道和评审时间。不要以“每天发更多提醒”解决积压;观察开放行动项数量、无 owner 数量、超期年龄分布、重复提醒率、自动化失败率和从 InReview 退回的比例。阈值应由团队交付节奏与风险确定,示例数字不能替代基线测量。
架构上可按规模选择三种形态:
单仓库 Issue + Project:身份与代码天然相邻,接入成本低;跨仓库汇总、复杂期限自动化和权限分层较弱。Jira 等中心工单 + 代码托管:字段、工作流、查询和自动化更强;链接同步、席位、管理员能力和迁移成本更高。知识库纪要 + 中心工单 + 代码平台:适合多角色与高敏附件;必须指定每类事实的唯一写入端,并监控同步失败。
选型时比较对象是否能稳定导出、API 是否能读取 owner/deadline/status/link、自动化是否有审计与限额、账号能否最小授权、停用后历史链接是否仍可解析。编辑器好不好看排在这些问题之后。
清理、回滚和长期治理
试点失败时,先禁用提醒规则并导出规则配置与执行日志,避免继续骚扰;把开放行动项迁回原工单系统,保留旧 ID 到新 ID 的映射;撤销机器人凭证和外部 webhook;最后移除表单入口。已经参与发布、事故或审计的纪要和行动项不要批量删除,改为只读归档并保留重定向。
模板升级先在测试仓库创建一条好数据和一条坏数据,确认网页校验、API 绕过检测、Project 自动加入、提醒审计和清理都符合预期,再推广到其他仓库。长期 owner 需要定期查找无负责人、无期限、无源记录、关闭但无证据、超期但无升级事件以及规则持续失败的对象;还要抽样确认纪要修订绑定的输入没有被新文档静默替换。趋势回到稳定基线,比“每场会都有纪要”更能证明协作链仍在工作。
当一次承诺能够从纪要追到独立行动项、owner、期限、状态变化、实现、发布和验收证据,并且提醒失败也能留下机器证据时,会议才真正进入研发交付系统。
