Imported from zhanglunet/livepowers (
skills/oltp-action-safety/SKILL.md). Install upstream withnpx skills add zhanglunet/livepowers --skill oltp-action-safety. Copyright stays with the author.
写操作安全门禁
查数可以试错,生产操作不行。把概率性的写入变成确定性的写入,是固化收益最大的地方,也是风险最大的地方。
高风险闭环顺序
发现 → 诊断 → 仿真(本体孪生预演)→ 审批 → 执行 → 核验 → 补偿 / 回撤
执行前必须做场景预演;没有预演报告不进入审批。
八项检查(缺一项都不准执行或固化)
| # | 检查 | 要回答的问题 | 必备测试 |
|---|---|---|---|
| 1 | 状态前提 | 执行前对象必须处于什么状态?谁校验? | 前提不满足时拒绝 |
| 2 | 权限 | 执行人是否有权对该对象做该动作? | 无权限时拒绝且无副作用 |
| 3 | 事务 | 哪些写入必须同成同败? | 中途失败全部回滚 |
| 4 | 幂等 | 重复提交会不会重复生效?幂等键是什么? | 同一幂等键两次只生效一次 |
| 5 | 并发 | 两个执行者同时操作同一对象会怎样? | 并发修改时一方失败并可重试 |
| 6 | 审批 | 是否需要确认?确认覆盖哪些对象与参数? | 未审批不执行;审批后参数变化须重新审批 |
| 7 | 审计 | 留下什么证据(谁、何时、改了什么、依据、回执)? | 审计记录完整 |
| 8 | 补偿 | 外部调用(通知、计费、合同)失败怎么办? | 下游失败进入补偿 / 待重试 |
推荐实现模式
- 读—校验—写同一事务;乐观锁(版本号)或
SELECT ... FOR UPDATE。 - 通知等副作用写入同一事务中的 outbox 事件表,由独立投递器发送;通知失败不等于动作失败。
- 幂等键 = 业务动作 + 对象 ID + 业务日期(或客户端 UUID),唯一索引保证。
- 审批后重新检查权限、状态、最近相关事件与对象版本——审批只能覆盖已确认的对象与参数。
- 超时先查状态再决定重试,不要盲目重发。
- 所有写操作通过本体定义的原子行动或已有领域服务完成,禁止 Agent 拼接任意 UPDATE。
存量系统缺少事务或幂等时
原系统继续作为权威记录,写操作通过已有领域服务完成。原系统缺少事务或幂等能力时,适配层采用状态核验 + 补偿 + 人工处置,并在规格里写明可保证的执行范围,不要假装有保证。
探索阶段
- 只在隔离库、本体孪生或"事务 + 最终 ROLLBACK"中预演。
- 预演报告:影响哪些对象、多少条、哪些字段从什么变成什么、哪些外部调用会被触发。
执行阶段
- 读取对象当前状态,逐项核对前提。
- 汇总"将要发生的变更",在确认点等待确认(可免确认的须在规格中写明规则)。
- 带幂等键执行;保存真实回执;记录审计;
lp evidence add ... --writes-state。 - 报告结果与失败 / 补偿项。
固化时
八项检查全部写成测试,放进 --tests 指向的测试集;注册时加 --writes-state(lp 会拒绝没有测试的写操作能力)。独立验收至少覆盖:正常、越权、对象状态不符、重复提交、并发修改、审批后参数变化、下游超时。
回撤的边界
代码回退只控制后续执行;已提交的业务动作通过有记录的补偿行动纠正。
