pi-todone

Todo 完成义务闸 + 证明点协议:todo 标 completed 必须附 evidence(格式闸),空闲时有 pending 注入证明义务(证明/继续/卡点),语义验证交给 subagent 系

Packages

Package details

extension

Install pi-todone from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:pi-todone
Package
pi-todone
Version
0.6.1
Published
Aug 15, 2026
Downloads
1,095/mo · 7/wk
Author
nuctori
License
MIT
Types
extension
Size
74.6 KB
Dependencies
0 dependencies · 1 peer
Pi manifest JSON
{
  "extensions": [
    "./src/index.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-todone

todo 状态机守护:完成义务闸 + 树完整性 + 证明点协议 + 并行建议。针对 AI 长自主任务偷懒(提前停、空转、随便 done、不拆任务、埋头苦等)的最小干预。

  • 格式闸todocompleted 必须附 metadata.evidence(JSON),格式不合规 → block(宽容归一化,无法归一化才 block);同一任务同一原因连续 block ≥2 次 → block 消息附强提示(停止重试同格式 / 标回 pending 逃生口),防模型反复重试同一违规烧工具预算
  • 树完整性:子节点挂到不存在的父 → block;父 completed 时子任务未完成 → block(目标不能假完成)
  • 证明点协议:agent 空闲且有 pending todo → 注入"证明本轮进展 | 说明卡点 | 继续";连续无进展 → 触发重新审视树结构
  • 创建义务:复杂任务(本单元 ≥200 次工具调用)但完全没拆 todo → 注入"请先拆 todo"(树形 + 粒度规范);小任务豁免
  • 并行建议:依赖未完成就开工 → 确认提示;subagent/长命令等待期间 → 提示推进无依赖任务
  • 验证义务:格式合规的完成项 → 注入"请 spawn fresh reviewer 独立验证",由 subagent 系 LLM 做语义判断
  • 硬门禁(gate 原语):create 时可声明 metadata.gate{"test":true} / "audit" / ["test","audit"]);test → 完成证据必须含 cmd 且 exit 显式为 0;audit → 必须含 review 交叉审计证据(agent+path);不满足 → block。声明即义务,防"忘了这个节点要特殊证明"(拦忘记/格式错,不拦谎报——真实性由验证义务的 fresh reviewer 复核)
  • 收尾强制(⑦):agent 收尾时(agent_settled)todo 未全部完成 → 顶回一轮强制交代(说明卡点或继续完成,triggerTurn 强制新回合);交代过一次即放行(防死循环),进展/用户介入后复位

插件只做确定性校验(零 LLM 成本、永不幻觉)。语义验证 → 独立 subagent(防共谋)。

设计哲学

一个工具做一件事

pi-todone 的语义边界只有一条:todo 的完成义务。围绕 todo 的其他职责刻意留在外面:

职责 语义 归属
todo 义务(evidence 格式、树完整性、空闲注入、停滞检测、并行建议) 机械、可判定 本插件(硬闸 + 建议)
结构规范(结果导向、依赖显式、卡点重规划) 语义、不可判定 pi-todone skill(规范层,AI 自觉)
目标理解(用户要什么、什么算达成) 语义 AI + 用户验收(不依赖任何其他插件)

边界原则:能强制的做进工具,不能强制的放规范层,语义理解留给 AI 与审计。把不可判定的结构/目标规则做成"门禁"是伪门禁——启发式必误报,真判定要 LLM(那就不是插件,是又一个审计 agent)。

证明义务在 AI 侧(burden of proof)

  • 插件不验证真实性,只校验格式:AI 必须提交证明才能 done,证明内容(path/cmd)由 AI 自己负责
  • 格式闸拦不住"格式合规的假证据"——语义真实性靠独立 subagent 验证(fresh context 隔离,防同模型共谋)
  • 宽容归一化:模型构造嵌套 JSON 参数能力弱,常见偏差(单对象、字符串、缺 kind、裸命令)自动修复;只有完全无法归一化才 block。教学循环不该退化成试错循环

缓存安全

  • 动态内容(任务 id、计数、时间)一律走消息通道(customType 注入),永不碰 system prompt——任何动态注入都会破坏缓存前缀
  • 注入消息带 customType 标记,静默/单元统计排除自身(防自反馈循环)

小任务豁免

完成义务只对"已创建的 todo"生效;创建义务只对复杂任务触发。避免两个极端:不列(数据:flash 仅 8% 单元用 todo)与噪音(每个小活都列)。

诚实边界

  • todo 状态是 AI 自报的——本插件管"完成义务",管不了"todo 之外的漏做"(那是声称审计的事)
  • effect 类是诚实出口:block 它没意义(模型会改编 state 证据更糟),给一条不编造的路径反而对
  • 卡点检测是"触发"不是"教学":停滞时要求 AI 重新审视结构,怎么重规划在 skill

三层知识架构(缓存安全)

通道 内容 缓存影响
L1 常驻 before_agent_startpromptGuidelines 追加编译期常量 2 行义务摘要 ✅ 静态字节 → 缓存命中
L2 按需 ~/.agents/skills/pi-todone/SKILL.md 完整规则:粒度判定、evidence 格式、结构三原则、验证流程 ✅ 不触发不加载
L3 强制 block reason + agent_end 注入(customType 消息,triggerTurn 自动继续) 违规时现场教 + 继续义务 ✅ 走消息通道,不碰 system prompt

安装

pi install npm:pi-todone

证明格式

todo 标 completed 时在 metadata.evidence 提交:

{ "kind": "state",    "evidence": [{"type": "file", "path": "src/a.ts", "op": "edit"}] }
{ "kind": "runnable", "evidence": [{"type": "cmd",  "cmd": "npm test", "exit": 0}] }
{ "kind": "effect",   "evidence": [] }
kind 含义 格式闸
state "X 文件已改" ≥1 条 file 证据(path 必填,op ∈ write/edit/delete)
runnable "测试通过/构建成功" ≥1 条 cmd 证据(cmd 必填,exit 可选数字)
effect "性能提升/更清晰" 不拦截,留人工验收
review 交叉审计(gate.audit 用) agent+path 必填;附于 state/runnable 时与 cmd/file 证据同附,单独出现须走 effect(仅声明,留人工验收)

常见偏差自动归一化:evidence 单对象、字符串 JSON、缺 kind(按条目推断)、裸命令文本、条目缺 type。只有完全无法归一化才 block(reason 含完整格式)。

硬门禁(gate 原语)

某些节点需要硬证明义务(必须跑通测试 / 必须交叉审计)时,create 时声明,完成时插件机械校验:

{ "action": "create", "subject": "实现 X", "metadata": { "gate": {"test": true, "audit": true} } }
gate 完成证据要求
test ≥1 条 cmd 证据且 exit 显式为 0(普通 runnable 只要求 exit 是数字,gate 加严)
audit ≥1 条 {"type":"review","agent":"<复核者>","path":"<评审产物>"}(与 cmd/file 同附于 state/runnable,或单独走 effect)
  • 不满足 → block(与 evidence 格式闸、树完整性叠加)
  • gate 节点完成 → 验证义务注入提升为必复核(点名硬门禁义务),由 fresh-context reviewer 核实测试/审计证据真实性
  • gate 与 blockedBy 正交:blockedBy 管顺序(依赖就绪),gate 管完成条件(证明义务)——组合即 todo 里的工作流
  • 防伪边界:gate 是机械校验,拦"忘记附证据/格式错",拦不住"谎报 exit 0"——真实性靠验证义务的独立复核兜底(插件从不验证真实性,见设计哲学)

收尾强制(⑦)

todo 未全部完成时,agent 不能直接收尾:agent_settled(Pi 不再自动继续的最终收尾点)时仍有未完成项 → 注入最后通牒 + triggerTurn 顶回一轮,二选一:

  1. 说明卡点(哪项卡住、原因、下一步)后收尾——合法出口,交代过即放行
  2. 继续完成剩余项后再收尾

防循环:通知过一次(settledForced)即静默放行,不反复顶;进展(未完成计数变化)或用户介入后复位。区别于 ⑤ 证明点(回合内软提示):⑦ 是收尾点强制,绕开"本回合已注入"守卫(turn_end 提示过也最后通牒)。⑦ 不走指数退避(最后通牒是收尾点最后手段,不参与 ⑤/⑥ 的退避调度),同文本去重仍生效(同一收尾内容不重复顶)。

防循环

  • 停滞检测:todo 计数连续 N 轮不变(默认 3)→ 注入重新审视树结构(终态通知,之后静默等用户介入或进展,不重复催促)
  • 指数退避:注入间隔 60s ×2ⁿ,上限 10min
  • 同文本去重:相同注入不重复
  • 交互静默:最近 2 分钟有用户消息时不注入(不打扰正常对话)
  • customType 排除:注入消息带 pi-todone 标记,静默/单元统计跳过自身(防自反馈循环)
  • 幂等注入:promptGuidelines 同文本不重复追加
  • block-storm 抑制:同一任务同一原因连续拦截计数,第 2 次起 block 消息前缀 [第 N 次拦截同一调用] + 逃生口(补 evidence 重试 / 标回 pending);任何非 block 的 update 复位计数

配置(环境变量)

变量 默认 含义
PI_TODONE_STALL_THRESHOLD 3 停滞几轮转卡点报告
PI_TODONE_QUIET_AFTER_MS 120000 最近用户消息距今小于此值则不注入(交互静默)
PI_TODONE_CREATE_THRESHOLD 200 本单元工具调用 ≥ 此值且未拆 todo 则注入创建义务
PI_TODONE_COOLDOWN_BASE_MS 60000 退避基数 60s×2ⁿ(上限 10min 写死)

验证义务开关(SEMANTIC_CHECK)是写死常量(要关改代码)。

测试

npm test    # demo 自检(84 断言)+ mock E2E(34 场景 102 断言,无模型依赖)

CI(GitHub Actions):test job 必跑;real-e2e job 需仓库变量 RUN_REAL_E2E=true + secret PI_E2E_API_KEY

设计边界(诚实说明)

  • 格式闸拦不住"格式合规的假证据"(编造的 file/cmd 也合规)——语义真实性靠 subagent 验证,这是分层的原因
  • 插件不能程序化调用 subagent 工具(pi 扩展 API 限制),验证义务通过注入交给主 agent spawn
  • todo 状态是 AI 自报的——本插件管"完成义务",管不了"todo 之外的漏做",那是声称审计的事
  • 创建义务只对"完全没拆过 todo 的复杂单元"注入;列了粗粒度 todo 的情况由 skill 粒度规范纠正(插件不判语义)
  • 结构规范(结果导向/依赖/重规划)在 skill 层,不在插件——见设计哲学"一个工具做一件事"

License

MIT