
planning-with-files 计划文件锁定/plan-attest 与 SHA-256 防篡改证明机制深度解析【免费下载链接】planning-with-filesPersistent file-based planning for AI coding agents and long-running tasks. Crash-proof markdown plans, session recovery after /clear and compaction, per-turn re-injection against context rot, deterministic completion gate. Manus-style. Install from npm, the Claude Code plugin marketplace, or npx skills. Codex, Cursor, OpenCode, 60 agents.项目地址: https://gitcode.com/GitHub_Trending/pl/planning-with-filesplan-attest 是 planning-with-files 中负责锁定计划文件的核心命令它将当前task_plan.md的内容计算为 SHA-256 摘要并落盘保存此后每一次 hook 注入计划内容前都会重新比对摘要一旦发现文件被静默改动立即停止注入并抛出[PLAN TAMPERED — injection blocked]警告。本文以 commands/plan-attest.md 为骨架结合 scripts/attest-plan.sh、scripts/inject-plan.sh 与 tests/test_plan_attestation.py 的源码实现完整讲解该命令的解析顺序、三种工作模式、hook 校验链路、原子写入与并发安全以及并行会话下的推荐用法。读完本文你将能够熟练使用/plan-attest锁定与解锁计划、正确理解证明的信任边界并在多会话并行场景下落地安全的计划管理流程。为什么要锁定计划文件防篡改的动机planning-with-files 的核心机制是逐轮将计划文件内容重新注入模型上下文。这意味着模型每一轮实际看到的task_plan.md内容直接决定了它接下来会执行什么。如果task_plan.md在未经人工确认的情况下被悄悄改写——例如外部工具写入、脚本误操作、会话恢复时合并出错——那么注入给模型的就是一份未经批准的新计划可能把整个任务带偏甚至让 Agent 执行攻击者注入的指令。plan-attest 解决的就是这个问题先把已批准的计划内容用 SHA-256 固定下来之后 hook 在每次注入前都做一次当前内容 vs 已批准摘要的比对。内容变了就拒绝注入。这一设计是该项目防上下文腐烂context rot与防注入injection体系中的重要一环相关背景还可参考 docs/attestation-locking.md 与 docs/agent-forgets-plan-after-clear.md。命令速览能力、可用性与调用边界/plan-attest的命令定义位于 commands/plan-attest.md其 frontmatter 明确记录了关键信息能力描述锁定当前task_plan.md的内容SHA-256 证明。hook 若发现文件摘要与已存证明不一致将拒绝注入计划内容从而阻断静默篡改--show用于打印已存摘要--clear用于移除证明。可用版本自 v2.37.0 起提供README 与 CHANGELOG.md 可查证。disable-model-invocation: true该命令不允许模型自行调用必须由用户在 Bash 中手动执行——这本身就是一道人工确认闸门防止 Agent 自我背书。allowed-tools: Bash命令经由 Bash 工具执行。运行一次/plan-attest的标准操作序列原文档定义解析活动计划依次优先使用${PLAN_ID}环境变量、.planning/.active_plan文件、最新的.planning/dir/目录若当前目录本身就是合法的.planning/slug/目录则直接使用其中的task_plan.md否则回退到遗留模式的./task_plan.md。计算摘要对解析到的task_plan.md计算 SHA-256。写入证明将十六进制摘要写入.planning/active-plan/.attestation并行计划模式或./.plan-attestation遗留模式。向用户确认打印摘要前 12 位短哈希与存储路径。关键安全约束显式指定的${PLAN_ID}或${PWF_PLAN_ROOT}若无法解析命令将以错误退出绝不回退到其他计划。计划解析五级优先级与绑定即不回退原则解析逻辑完整实现在 scripts/attest-plan.sh 的resolve_plan_file()第 44-74 行中顺序如下${PLAN_ID}环境变量 →./.planning/$PLAN_ID/./.planning/.active_plan指向的计划目录按 mtime 最新的./.planning/dir/当前目录本身是合法的.planning/valid-slug/由resolve_from_slug_cwd()与slug_is_valid()校验第 25-42 行遗留模式项目根目录的./task_plan.md。两个值得注意的实现细节slug 合法性校验slug_is_valid()只允许A-Za-z0-9._-字符拒绝空字符串防止路径注入或指向任意目录。显式选择器是绑定而非提示如果共享解析器resolve-plan-dir.sh拒绝了显式选择器attest-plan.sh会直接返回失败第 54-58 行而不是通过 cwd 回退去证明另一个计划。脚本针对这种情况给出了带原因的报错信息第 116-123 行PLAN_IDxxx names no plan directory under .planning...或PWF_PLAN_ROOTxxx did not resolve to a project root...。这样做的历史原因写在源码注释里在修复之前一个拼错的PLAN_ID会以 rc0 错误地证明另一个计划。证明存储位置并行模式与遗留模式的差异存储路径由attestation_path_for()决定scripts/attest-plan.sh遗留模式计划文件在项目根目录即task_plan.md的父目录为.摘要写入./.plan-attestation并行计划模式.planning/slug/下的计划摘要写入该计划目录内的.attestation。测试 tests/test_plan_attestation.py 中的test_parallel_plan_attest_writes_into_plan_dir明确断言当存在活动计划目录时必须写入计划目录内的.attestation且不得在根目录残留遗留的.plan-attestation文件test_attest_from_inside_plan_dir_updates_slug_attestation进一步验证了从 slug 目录内部直接调用也不会创建遗留文件。三种工作模式attest / --show / --clear命令参数解析位于 scripts/attest-plan.sh支持三种模式模式触发方式行为attest默认无参数计算task_plan.md的 SHA-256 并原子写入证明文件随后打印前 12 位短哈希与存储路径show--show打印当前存储的完整摘要、计划文件路径、证明文件路径若存在.nonce会话随机数一并打印clear--clear删除证明文件重新解锁计划以允许编辑show查看当前锁定状态--show分支第 128-145 行输出Plan: task_plan.md Attestation: ./.plan-attestation SHA-256: 64 位十六进制摘要 Nonce: 若存在其中 Nonce 来自init-session为每个计划生成的.nonce文件源码注释将其标注为安全项 A1.4hook 会用它构造带碰撞保护的 BEGIN/END 分隔符show 仅作信息展示。若尚未设置证明命令输出No attestation set for ...并以非零码退出。clear解除锁定--clear分支第 146-153 行删除证明文件。这通常在有意编辑并重新批准计划之前使用——先解锁、编辑、再用/plan-attest重新锁定。测试test_clear_removes_attestation验证了清除后文件确实消失。attest核心锁定流程默认模式第 154-251 行包含四个关键环节下面分别展开。摘要计算与 Hook 校验链路TAMPERED 是如何触发的摘要计算compute_hash()scripts/attest-plan.sh优先使用sha256sum否则回退shasum -a 256两者都不可用时明确报错退出。Hook 侧校验锁定之后真正执行注入前比对的是 scripts/inject-plan.sh。每次 UserPromptSubmit 与 PreToolUse hook 触发时确定证明文件遗留模式取${PLAN_PREFIX}.plan-attestation第 532 行并行模式取${RESOLVED}/.attestation第 539 行重算当前摘要对计划文件实时计算 SHA-256并去掉 GNU coreutils 可能添加的转义反斜杠前缀第 1100-1106 行。实现注释特别强调mtime 与缓存摘要都不是可信信号因为文件可以在保持两者不变的情况下被改写所以每次触发都全量重算比对并分支PreToolUse 场景第 1137-1138 行与 UserPromptSubmit 场景第 1163-1169 行都会输出[planning-with-files] [PLAN TAMPERED — injection blocked]在用户提示词场景下还会附上expected存储摘要与actual实际摘要供排障并提示Run /plan-attest to re-approve current contents, or restore the file from git.也就是说每次有意编辑并重新批准计划后都要重新运行/plan-attest——这正是原文档结尾给出的操作准则。防检查-使用竞态的快照机制校验并非先读文件再比较的朴素实现。scripts/inject-plan.sh 先把计划文件复制成私有快照证明校验针对快照的精确字节进行之后所有输出也只读快照。即使攻击者在读后恢复原始 mtime也无法制造 check-then-use 的时间窗口快照复制本身通过 O_NOFOLLOW 等受限描述符完成safe_snapshot()第 600-619 行。信任边界证明 ≠ 签名必须清醒认识docs/attestation-locking.md 明确划定了这一机制的信任边界引用时务必如实传达存储的值只是本地普通摘要不是密钥签名也不是人类已批准的证明它仅在摘要本身保持可信的前提下才能检测计划变更。一个能同时改写task_plan.md及其证明文件的进程可以让新内容顺利通过校验。初始化过程中的自动证明记录的是生成时的字节不包含独立的人工复核步骤。证明不意味着计划内容可以无条件服从即使文件与摘要匹配从工具、网站或其他外部来源复制进来的指令仍应视为不可信内容。若要抵御能控制整个计划目录的写入者需要独立的信任边界例如用权限保护审批记录。这是整个 attestation 设计中诚实且安全的关键部分它防的是静默篡改不是万能防篡改。写入路径的原子性与并发安全证明文件的写入不是简单重定向而是临时文件 原子重命名 可选 flockscripts/attest-plan.sh先将摘要写入临时文件attestation_file.tmp.$$若有flock在flock -w 5内执行mv -f锁文件为证明文件同目录下的.attestation.lock否则直接原子重命名读回校验写入完成后读取磁盘上的证明文件与期望摘要比对第 233-244 行。不一致即报错并以非零码退出杜绝宣称已锁定、实际未落盘的陈旧证明被信任失败回退若首次重命名失败跨设备、权限等会通过第二次原子重命名补齐绝不裸重定向到活文件那会让并发校验者读到撕裂的中间状态。原子重命名是正确性保证——读者永远不会看到半截摘要flock 只是协同并发写入者的合作闸门。这个设计对应 v2.40 的一个真实回归并发遗留模式会话曾因非原子 file重定向产生截断的证明文件导致 hook 误报 TAMPERED。回归测试test_concurrent_attest_writes_do_not_corrupt_filetests/test_plan_attestation.py并发拉起 8 个 attest 进程断言最终文件始终是完整的 64 位十六进制摘要且与计划内容一致。另外attest 分支还会检测遗留模式下证明文件在 30 秒内被其他进程改写过并给出提示建议并行会话改用 slug 模式第 169-192 行。跨平台行为与 Windows 实现flock的可用性随平台而异docs/attestation-locking.md 给出了对照平台flock可用性行为Linux通常可用原子重命名 协同flock守卫macOS默认未安装原子重命名仍保证正确性Windows Git Bash通常缺失原子重命名仍保证正确性WSL通常可用与 Linux 相同Windows 原生安装使用 PowerShell 实现 scripts/attest-plan.ps1要求 PowerShell 5.0通过-Show/-Clear开关对应--show/--clear。其实现值得注意它内嵌了 Win32 P/InvokePwfAttestationNative第 38-60 行以受限句柄完成无跟随no-follow的文件操作并在非 Windows 主机上直接抛错要求改用attest-plan.sh。命令的完整调用方式原文档给出的实现路径# Linux/macOS/Git Bash插件安装 sh ${CLAUDE_PLUGIN_ROOT}/scripts/attest-plan.sh # Windows PowerShell插件安装 $env:CLAUDE_PLUGIN_ROOT\scripts\attest-plan.ps1 # Windows PowerShell独立安装 $env:USERPROFILE\.claude\skills\planning-with-files\scripts\attest-plan.ps1v3 模式下的强制证明autonomous / gatedattestation 在遗留模式无.mode文件是可选的但在 v3 的autonomous与gated模式下是强制的。scripts/inject-plan.sh 中的逻辑安全项 security-major-4说明在无人值守的循环中计划体会在每一轮注入模型仅靠 nonce 分隔符无法防御分隔符混淆注入——因为.nonce与task_plan.md处于同一信任域能写计划的人就能读到 nonce 并伪造 END 分隔符。因此证明才是真正的防线若autonomous/gated模式下不存在证明ATTEST为空计划体不得注入只输出一行提示[planning-with-files] v3 mode requires attested plan; run attest-planPreToolUse 与 UserPromptSubmit 两个上下文都执行该强制检查。并行会话的最佳实践slug 模式 PLAN_ID 固定遗留模式./task_plan.md./.plan-attestation下多个会话共享同一份计划与证明文件原子重命名虽能保证证明文件有效却无法让共享计划文件成为安全的并行工作区。docs/attestation-locking.md 推荐的并行方案是 slug 模式./scripts/init-session.sh Backend Refactor ./scripts/init-session.sh Incident Investigation每个 slug 拥有完全隔离的文件.planning/2026-01-10-backend-refactor/task_plan.md .planning/2026-01-10-backend-refactor/.attestation .planning/2026-01-10-incident-investigation/task_plan.md .planning/2026-01-10-incident-investigation/.attestation需要把某个终端固定到指定计划时导出PLAN_ID再执行证明export PLAN_ID2026-01-10-backend-refactor sh scripts/attest-plan.shslug 模式通过每会话独立task_plan.md 独立.attestation从根本上避免同文件竞争。测试如何保障行为契约tests/test_plan_attestation.py 是一份完整的契约清单可用于自行复现验证跳过逻辑平台无sh时跳过测试用例验证点test_legacy_attest_writes_root_attestation遗留模式将摘要写入根目录.plan-attestation且与task_plan.md的 SHA-256 完全一致test_show_prints_stored_hash--show输出中包含完整摘要test_clear_removes_attestation--clear删除证明文件test_tamper_changes_hash篡改计划内容后新摘要与已存摘要必然不同hook 闸门能触发的必要条件test_parallel_plan_attest_writes_into_plan_dir活动计划存在时写入 slug 目录内的.attestation不写遗留文件test_attest_from_inside_plan_dir_updates_slug_attestation从 slug 目录内调用可更新该 slug 的证明且不创建遗留文件test_failed_explicit_selector_does_not_fallback_inside_slugPLAN_ID/PWF_PLAN_ROOT指向缺失计划时非零退出且不产生任何证明文件不静默证明其他计划test_no_plan_exits_nonzero无计划时非零退出test_concurrent_attest_writes_do_not_corrupt_file8 个并发 attest 后证明文件始终是完整 64 位十六进制摘要实操总结完整生命周期把以上内容串成一份可直接落地的操作流程创建计划/plan生成task_plan.md、findings.md、progress.md人工审阅并批准确认计划内容符合预期锁定执行/plan-attest或sh scripts/attest-plan.sh确认输出的短哈希与存储路径并行场景下先export PLAN_IDslug或用init-session.sh建号正常推进每次 UserPromptSubmit / PreToolUsehook 自动比对摘要一旦看到[PLAN TAMPERED — injection blocked]说明计划被非预期改动——先--show查看已存摘要再决定是git还原还是重新批准有意修改计划先/plan-attest --clear解锁 → 编辑 → 重新审阅 → 再次/plan-attest锁定v3 模式autonomous/gated未证明的计划不会被注入提示v3 mode requires attested plan; run attest-plan。记住信任边界attestation 防的是静默篡改不是防一切。把它与PWF_PLAN_ROOT/PLAN_ID的绑定式选择器、slug 并行隔离、原子写入与读回校验组合使用就是当前仓库给出的最完整、可审计的计划完整性方案。【免费下载链接】planning-with-filesPersistent file-based planning for AI coding agents and long-running tasks. Crash-proof markdown plans, session recovery after /clear and compaction, per-turn re-injection against context rot, deterministic completion gate. Manus-style. Install from npm, the Claude Code plugin marketplace, or npx skills. Codex, Cursor, OpenCode, 60 agents.项目地址: https://gitcode.com/GitHub_Trending/pl/planning-with-files创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考