关于 sync-pstack
用于在多个项目中设置和同步 pstack 的技能,并将共享覆盖规则与项目专属规则分开。它提供应用更新、检查偏差、验证引用和测试技能路由的命令。
主要功能
- 01安装共享 pstack 配置
- 02固定并同步上游版本
- 03检查项目偏差和待更新内容
- 04验证引用与命令历史
- 05冒烟测试技能路由
适用场景
- 01在项目中设置 pstack
- 02更新多个受管理项目的 pstack
- 03查找配置存在偏差的项目
- 04检查技能与 playbook 引用
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ udecode/ dotai --skill sync-pstack安装后在 Claude Code 中输入/sync-pstack确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlassets/block.mdassets/pstack/checkout.mjscodex-browser.mjscodex-build.mdcodex-isolation.mjscross.mjscua-steps.mjsdecisions-check.mjsfreeze.mjsguard.mjshead.mjsland.mjslead.mjslevels.mjsmutate.mjspage-stop.mjsplan-open.mjsplan-page.mjsproof.mjsreply.mjsreread.mjsreview.mjsassets/pstack/rules/browser.mdchips.mdclose.mdcodex.mdfast.mdland.mdlinked.md详细介绍
Sync pstack
一个技能可在项目中设置 pstack,并让每个已设置的项目始终与上游 pstack 及一套共享覆盖内容保持同步。项目专属规则不会同步。
设置过程会引入共享层:插件固定版本、覆盖内容区块、辅助工具、为已退役控制器保留的类型化入口、路由表和一个验证技能。它不会引入项目自己的知识,例如其源代码权威、领域规则或评审场景;这些仍由项目自行处理,领域技能也会在设置过程中保持原样。
分层
| 层 | 所在位置 | 修改方式 |
|---|---|---|
| 上游 | 每个项目的 .claude/settings.json、用户的 ~/.claude/settings.json 和用户的 Codex 市场中的 pstack@pstack-claude 插件固定标签版本 | 使用 sync --tag 和 user-pin。绝不编辑 pstack 本身。 |
| 共享 | assets/block.md,渲染到每个项目的 AGENTS.md 中 pstack:begin 和 pstack:end 标记之间;以及 assets/pstack/ 中复制到 .agents/pstack/ 的辅助工具,还有 assets/pstack/rules/ 中的规则文件,这些文件会像区块一样渲染到 .agents/pstack/rules/ 中 | 修改 dotai 检出目录中的此技能源文件,然后执行同步 |
| 项目 | .agents/pstack.json,用于保存访谈的答案;项目操作手册位于 .agents/playbooks/,并由区块列出;以及区块外的所有规则,它们的优先级高于区块中的规则 | 由项目手动修改或通过设置流程修改 |
运行脚本
可从任意目录运行 node <skill>/scripts/sync-pstack.mjs <command>。
| 命令 | 作用 |
|---|---|
discover <project> | 以 JSON 格式打印访谈所需的信息。只读。 |
status [project...] | 显示最新的上游标签(以及领先于该标签的上游 VERSION)、用户固定版本,以及每个项目的固定版本、偏离情况、供应商副本和最近的源修订。未指定项目路径时,它会从 ~/.agents/config.json 中的仓库集合、其父目录以及每个 --root <dir> 查找本地 pstack 项目。跳过已链接的 git 工作树,因为每个工作树都会通过其检出的分支获取同步。未指定项目路径时,sync 会同步同一组项目。只读。 |
apply <project> | 根据项目配置写入区块、辅助工具和项目固定版本。--tag 会先固定标签,打印 pstack 在两个标签之间对每个被覆盖内容或项目操作手册引用的文件所做的差异;如果 pstack 不再包含其中任一文件引用的文本,则拒绝该标签。--dry-run 会显示区块差异并列出其他写入内容。--force 会覆盖已编辑的区块或辅助工具,或从早于项目上次同步的源进行渲染;它绝不会跳过锚点。对于克隆配置了 pstack.delivery 的 trunk 项目,它拒绝写入主检出目录;此类项目会在工作树中同步并提交结果。 |
check <project> | 如果 apply 会更改任何内容,则以状态码 1 退出。只读。 |
verify <project> | 如果此项目历史记录中输入过的命令或参数提示模式不再解析(除非 dropped 列出了它)、项目技能中有指向技能树的失效链接、规则引用了已弃用的技能、文档告知用户安装的技能依赖此项目的工作流文件、check 会更改任何内容,或固定标签中的 pstack 缺少被覆盖内容或项目操作手册引用的文本,则以状态码 1 退出。只读;只有在某项技能或模式自 HEAD 起被删减时才会读取聊天历史,这需要几分钟,因此请在最后一次 apply 后于后台运行一次,并将输出写入文件。 |
sync --tag <tag> [project...] | 对指定项目运行 apply --tag;如果未指定项目,则对每个受管理项目运行,并列出未受管理的项目。除非使用 --allow-dirty,否则如果检出不在项目分支上,或待写入文件有未提交的修改,则拒绝执行;即使某个项目失败,也会继续处理其他项目。 |
playbook <project> <name> | 在项目固定版本下,打印 .agents/playbooks/<name>.md 扩展的每个 pstack 操作手册的编号步骤,并按顺序应用其中的更改。不在步骤内的文本(例如 Reply 行)会被省略。只读。 |
smoke <project> <prompt>... | 从项目根目录并行运行只读 Claude Code Opus 会话和只读 Codex gpt-6.1-sol 会话,分别处理每个提示词,并打印每个运行时的最终回答。其回答只能证明路由有效;请根据设置第 6 步进行判断。Claude Code 会话是在计划模式下运行的 CLI,不包含桌面应用的会话工具。 |
corpus [project...] | 运行项目已安装的 decisions-check.mjs 和此技能的副本(包含未提交的修改),检查项目账本以及自首次提交以来新增的决策日志行(--all、chips、chips stale),并打印差异。两个 chips 运行会读取同一份账本副本。每次 --all 运行都会读取实时日志,因此,如果其他会话可能在两次运行之间写入了日志,请重新运行 corpus,再相信日志中的差异。未指定项目路径时,会对 status 找到的每个受管理项目运行。--session <id> 会将此会话的 ID 传给 chips,--installed <dir> 会从某项目辅助工具的已保存副本读取旧版本,--out <dir> 还会将每一侧的完整输出写入该目录。只读。 |
user-pin --tag <tag> | 固定用户范围的 Claude Code marketplace,并打印刷新命令。每次都会打印 Codex 的命令;只有用户设置声明了 pstack marketplace 时才会打印 Claude Code 的命令。 |
latest | 打印最新的上游标签。 |
node <skill>/scripts/audit.mjs <project> [--json] [--min <score>] 会打印 审计模式评估的事实;--min 用于设置句子对所需的重合度分数,默认值为 0.5。只读。 |
锚点检查会从脚本首次使用时在 ~/.cache/sync-pstack/ 中创建的裸克隆读取 pstack;SYNC_PSTACK_UPSTREAM 可将其指向其他克隆或 URL。如果 dotai 检出中存在副本,请运行该副本;此检出的 origin 为 udecode/dotai。其中的 assets/ 是事实来源。apply 和 sync 会打印其渲染所用的源,并在 synced.source 中记录渲染所用的共享提交。有了这条记录,拒绝操作时会准确显示项目修改了哪些内容;如果副本早于项目上次同步的版本,则会拒绝覆盖。即使 dotai 检出中包含本次运行未写入的编辑,也要从该检出运行 check,因为 dotai 的 AGENTS.md 会将这些编辑与本次运行一并提交。
选择模式
| 请求 | 模式 |
|---|---|
| 在项目中设置 pstack,或在此处安装 pstack | 设置 |
| 在此处或所有地方同步、升级或更新 pstack | 同步 |
| 比较设置,或列出哪些项目使用 pstack 或存在偏差 | 比较,只读 |
| 审计项目的技能与 pstack 的偏差,或确定要移除哪些技能 | 审计,在所有者做出选择前为只读 |
| “从现在起,让 运行 <architect、评审小组或竞技场>”,或停止运行其中一项 | 评审 |
| 改变共享规则的经验教训或更正 | 经验教训 |
| 添加或修改项目自己的手册 | 项目手册 |
共享源发生更改时,会同步所有受管理的项目,并在每个项目中安装所有新增或更改的 dotai 技能,包括其 .claude/skills/<name> 链接(所有者原话,2026-10-09)。设置、固定版本升级或评审更改只影响请求中指定的项目;如果请求涵盖所有项目,则影响所有受管理的项目。~/.agents/config.json 中的仓库集合用于列出候选项目,并不代表已获授权。
设置
- **发现。**运行
discover <project>,然后完整阅读AGENTS.md及其指向的工作流规则。此时尚未写入任何内容。 - **访谈。**这是用户看到的第一步。遵循访谈:根据证据做好准备,始终询问交付方式,除非项目证据另有说明,否则推荐参考答案;已经确定的答案绝不重复询问。
- 记录答案到
.agents/pstack.json,并从latest获取tag。 - **适配。**按照适配调整项目。移除 vendored 的 pstack 副本,处理孤立的技能和分叉的规则,确保格式化工具不会修改同步文件,重写与该区块重复或矛盾的项目规则,将指向已移除技能的引用重新指向别处,写入已确认的路由表;没有 proof 技能时创建一个,并根据规则重新生成技能。
- **应用。**运行
apply <project> --dry-run,阅读差异,然后运行apply <project>。 - 验证。
discover报告没有 vendored 副本,且status <project>显示用户固定版本为该 tag。否则运行user-pin及其命令。- 每个运行时的模型清单都存在,分别为
~/.claude/pstack-models.md和~/.codex/pstack-models.md,并列出该区块的 Panel review 规则使用的席位。否则,在冒烟测试前运行/pstack:setup-pstack,因为没有清单的会话会运行 pstack 的默认模型。 - 使用
smoke <project> "<prompt>"对两个运行时进行冒烟测试,提示词应是提及真实功能的普通请求:“模拟任务,不要编辑任何内容,也不要运行会写入的命令: 在 后会重置。用不超过十行的简短内容,按顺序说明你会怎么做:先列出你会打开的待办项,然后说明完成的工作如何交付。”评判每个运行时会采取什么行动,而不只是它提到哪个 playbook。评审员为答案打分时,必须先根据已更改的指令文本写下每个运行时预期的行为,再让评审员查看任何答案,并引用要求各项行为的规则行。只有当会话显示技能已加载时,对已更改技能进行的冒烟测试才算数;只读冒烟测试只能证明路由,不能证明实际行动。首先检查测试夹具是否处于提示词所暗示的状态,例如,你说已获批准的计划不能处于 Done 状态。预期使用 poteto-mode 的 Bug fix playbook(以及扩展它的项目 playbook)、不使用 worktree,并给出交付方式的答案。在每个提示词末尾,要求运行时以编号列表列出它发现的所有规则冲突;阅读完整答案,并为每个编号记录一种处理方式。此更改涉及的规则之间若有冲突,即为失败:修复后重新测试失败的运行时。测试框架造成的限制,是指只读模式带来的限制,而真实会话没有这种限制,例如计划模式阻止写入临时文件,或无头会话缺少某个连接器;记录下来,并将任何依赖该限制的声明表述为“在该测试框架下成立”;记录即可结案。Claude Code 冒烟测试使用处于计划模式的 CLI,因此,计划模式下“什么都不编辑”始终属于此类限制;CLI 不具备桌面应用的会话工具,例如get_session、list_events、search_session_transcripts或start_session。需要使用其中某个工具的规则,必须由负责人在桌面会话中实际使用一次来证明,并记录该会话的 id,绝不能用冒烟测试证明;没有桌面会话时,应在 Needs you 下记录为gap。其他所有编号的冲突,包括更改前就存在的冲突,都必须以下列三种方式之一处理:在本次更改中修复;通过项目的 Suggested tasks 规则或跟踪系统提出任务;或说明理由后予以驳回。仅记录冲突不能结案。运行时之间存在差异即为失败,除非更改后的规则本身规定了这种差异,例如草稿场景中一个运行时拒绝发送;或者运行时因项目规则无法改变的原因拒绝执行更改所承诺的操作。此时应将规则和提交说明缩小到会执行操作的运行时,或为规则提供两个运行时都会遵循的备用方案。如果答案称无法读取正在测试的文件,则该文件相关步骤的测试结论为不确定;记录为partial。在第二个提示词中询问子 Agent 使用哪个模型运行。切勿在提示词中提及 playbook、停止点或步骤,也不要用规则自身的措辞提及该规则的触发条件,因为这样测试证明的只是查找,而非路由。要测试新增或更改的关卡(例如审查),应发送足以触发关卡的普通请求,只要求待办列表及交还工作的回复;只有关卡在未提示的情况下出现,冒烟测试才算通过。这些测试会触发项目的钩子,因此会暂存文件的 Stop 钩子也会暂存设置所做的更改。 - 对已更改的代码文件运行项目的
lintFix,然后最后运行verify <project>,以便及时发现已删减的类型化命令、失效链接、弃用名称、相互依赖的公共技能,或格式化工具对同步文件的改写。交付前修复它列出的所有问题。
- **交付。**按照项目的交付方式作答。对于
trunk,只有在访谈中对直接推送的回答为“是”时,才在所有者的克隆中运行git config pstack.delivery push;该配置绝不会写入仓库,其他所有克隆都通过 PR 提交。当创建提交时,提交说明正文应写明哪些运行时以及项目中的哪些提交者获得或失去什么;每个运行时的说法取自该运行时自己的冒烟测试答案;在user模式下,对于所有者的提交,回复中应写明这一点。结尾应列出答案、已应用的确定默认设置、已移除和保留的技能,以及验证输出。
Sync
- 运行
status,查看受管项目、它们的固定版本、偏差和上次来源,以及最新标签。只有latest打印出的标签才能固定。合并 VERSION 更新并不代表发布,直到推送其标签;当上游的 VERSION 超前于最新标签时,status会说明这一点。 - 存在更新的标签时,读取 pstack-claude 在新标签下的
CHANGES.md(gh api 'repos/michael-denyer/pstack-claude/contents/CHANGES.md?ref=<tag>' -H 'Accept: application/vnd.github.raw'),从已固定的标签一路查到新标签。逐项对照每个变更与区块的内容:剧本步骤、技能、原则或钩子,只要被某项覆盖规则点名,就要检查。上游现在可能已实现覆盖规则的作用;建议移除该覆盖规则。上游也可能更改了覆盖规则所反驳的文本;建议重写覆盖规则。然后,对于CHANGES.md新增或变更的每项技能、Agent 或剧本步骤,判断范围内的每个项目是否应采用。阅读项目的剧本和区块之外的规则,并在这些位置运行git grep搜索技能名称,然后再判定该技能未接入。每个项目给出一个结论:已接入,并注明对应行;接入,注明它加入或替换的步骤或规则,以及弥补的缺口,例如没有其他门禁审查的路径;仅手动执行,注明自动化会与之冲突的规则;或不采用,注明已有何种机制能更好地完成其工作。评估时要结合项目现有的门禁和升级处理机制,而不是只看技能自身的说明。同步交接时附上此表;若项目规则通过计划页交接,则将表放在计划页上。向用户展示每项建议,包括接入建议,并且只有在用户明确同意后才实施。对区块的变更通过 Lesson 进行;对单个项目剧本的变更通过 Project playbooks 进行。 - 对范围内的项目运行
sync --tag <tag> --dry-run,并阅读它打印的每个文件的 pstack 差异,这些文件由区块或项目剧本中的锚点引用,因为即使引用文本保留,步骤也可能已变更。然后不带--dry-run再运行一次。只有当请求涵盖所有受管项目时,才省略项目列表。若列出未受管项目,为每个项目提供 Setup。 - 解决每项拒绝。
- 区块或辅助文件已编辑。 拒绝信息会显示项目的编辑内容。将通用编辑通过 Lesson 移入模板,将仅适用于项目的编辑移到区块之外。这样不会丢失任何内容,然后使用
--force重新运行。若不先移出,只有所有者明确表示可以丢弃该编辑时,才能使用--force。 - 分支不匹配或存在未提交编辑。 切换到项目分支,或等待所有者提交。只有当未提交编辑是本次运行所做的,或项目规则要求仅提交本次运行的代码片段、同时保留另一个会话的其他未提交更改时,才能使用
--allow-dirty。 - 来源较旧。 更新 dotai 检出,并从中重新运行;若存在未提交编辑,请按照 Lesson 的第 2 步操作。当本次运行修改或变基了项目已经同步过的提交时,确认
apply --dry-run的整个区块内差异仅包含已提交模板中的行,然后使用--force重新运行。 - 共享编辑未提交。 项目上次同步自尚未有人提交的共享编辑,使用干净来源会丢弃这些编辑。dotai 的检查通过后,按照 dotai 的
AGENTS.md要求提交并推送这些编辑,然后重新运行;只有所有者明确表示可以丢弃时,才能使用--force。如果这些编辑是本次运行所做的,且此后已以修订形式提交,拒绝仍会触发。运行apply --dry-run,确认其区块内差异仅包含已提交模板中的行,解释任何与此相矛盾的诊断,然后使用--force重新运行。 - pstack 锚点。 新标签中的 pstack 不再包含区块或项目剧本所依赖的文本,拒绝信息会显示 pstack 的差异。依据新文本,通过 Lesson 重写覆盖规则,或在对应项目中更改剧本,然后重新运行。如果上游现在已实现原先的功能,则移除该更改。
- 错误。 模板无法渲染某项配置。修正配置,然后为该项目重新运行。
- 区块或辅助文件已编辑。 拒绝信息会显示项目的编辑内容。将通用编辑通过 Lesson 移入模板,将仅适用于项目的编辑移到区块之外。这样不会丢失任何内容,然后使用
- 运行
user-pin --tag <tag>,然后从主目录运行打印出的命令。如果 Codex 检测到其文件已更改,会再次询问是否信任 pstack 钩子。 - 对每个已同步项目运行
verify进行验证,并按照 Setup 第 6 步所述,对每种正在使用的交付模式各选择一个项目进行冒烟测试。每个when或步骤已变更的剧本都用一个普通提示词测试;每个裁剪后的入口点各测试一次;每个新增或变更的门禁各测试一次,不使用固定测试集。当CHANGES.md新增或变更技能或原则时,还要对每个已同步项目运行 Audit,该流程会读取新固定版本中的 pstack。首先评估项目级和用户范围内、工作内容由该技能覆盖的技能。 - 根据各项目自身的交付方式,在其分支上交付。只提交同步写入的文件。
push项目提交并推送同步结果;user项目将更改留给所有者;pr项目直接将同步结果提交并推送到<branch>,不创建 PR(所有者决定,2026-10-20);trunk项目从origin/<branch>创建工作树来运行同步,并使用land.mjs合并。在推送push或pr项目的更改前,检查在该分支上运行的每个工作流的on: push过滤器。当此次推送携带的路径会触发某个工作流时,无论是通过匹配该路径的paths列表、未排除该路径的paths-ignore列表,还是没有过滤器,都要修改该工作流的过滤器,使该路径不再触发它,并在头部提交信息中加入[skip ci],因为工作流的修改本身也会触发 CI。当同步基于更早的同步分支时,使用--no-ff合并项目分支,而不是变基,这样 GitHub 才会将这些分支上的 PR 标记为已合并。根据 Setup 第 7 步的要求,每条提交说明正文都要写明哪些运行环境和提交者获得或失去了什么。
比较
运行 status。对于每个使用 pstack 的非托管项目,阅读其说明,并将每项覆盖规则映射为以下类别之一:已覆盖、项目适配、明确的策略差异、偏离或未解决。只有在阅读项目中区块以外的 AGENTS.md 及其设置计划的处置表,并且使用不止一种表述搜索过相关行为后,才能认定规则已丢失,因为设置过程可能会迁移规则并改写措辞。报告每项差异时,列出两种行为、各自的源路径,以及最小化的协调方案。建议进行设置或同步;未经请求,不得应用任何更改。
审计
当技能复制了 pstack 或区块已经负责的规则,或仍保留了 pstack 现在负责的工作时,就会偏离 pstack。本模式会找出这些偏离,让所有者移除它们。
- 如果存在 dotai 检出目录,从中运行
node <skill>/scripts/audit.mjs <project>。它会打印:- 每项项目级和用户范围技能的来源、输入计数、入站路由和过时的已安装副本;
- 没有
overrides注记或adds标记的区块规则; - 重复 pstack、区块或项目中其他文件内容的句子。 输入计数只统计人类编写的内容:跳过 Agent、任务通知和无头记录,以及粘贴的区块;对于长度超过 2,000 的请求,忽略首 200 个字符之后的匹配项。用户范围技能的计数涵盖所有项目的会话。
- 根据审计简报中的意图以及移除、折叠或保留标准来评估报告。只有当区块的 Panel 审查规则允许无需询问即可运行
/pstack:interrogate,或所有者说“panel”时,才对报告运行该命令;否则由负责人评估,并在结论表中将负责人列为评估者。每项技能只能有一个结论:若 pstack 或区块已能完成其工作,或无人使用该技能,则移除;若保留其领域知识但移除流程文本,则折叠;若包含 pstack 无法提供的领域知识,则保留。每项移除结论都必须说明由什么取代。 - 使用
AskUserQuestion将结论表交给所有者,按项目归类移除项,并将推荐项排在前面。每个移除选项都显示其全历史输入计数,以及经验证可在当前设置中使用的替代方案。若某个选项会删除文件,则按规则、经验、数字和理由分别计数,并分别显示其中有多少已存在于其他位置、多少仍需保留,以及多少会被丢弃。不得将 git 历史作为安全保障,因为没有任何工作流会读取已删除的文件。选项中的事实性陈述(例如“从未输入过”)必须注明其依据的检查。若某个选项会移动或移除关卡,须在其标签中注明该关卡。只有所有者选择移除后,某条已输入命令才会失去其入口点;该移除项须在项目配置的dropped下列出该命令。 - 根据区块的 Plans and trails 和 Panel review 规则,将所选项目作为计划执行。若移除操作依据使用计数,则在操作前立即重新运行计数,因为计划移除目标期间,并行会话仍可能继续使用它。在移除、折叠或重建之前,按照 adapt 的处置表,列出旧文本中的每条规则、检查和仍然成立的经验,并注明其新归属位置,或记录为丢弃。首次编辑目标位置前,冻结每一行的源引用和适用条件。由未编辑目标位置的审阅者检查每一行:若其归属位置原本就存在、引用在编辑后发生变化,或该行由脚本生成,都必须检查。将此表与计划一同提交。项目的
AGENTS.md指定的每份工作流指南都必须设置更新关卡,如 Lesson 第 1 步所示。移除 dotai 技能后,搜索所有受管理项目,查找其路径,并在交付移除操作前运行每个项目的文档检查。在主目录中运行npx --yes skills remove <names> -g -y卸载用户范围技能;在项目目录中运行npx --yes skills remove <names> -y卸载项目技能。
审核
每个项目的 .agents/pstack.json 中的审核列表,列出了运行评审组、architect 或竞技场的工作;对于每个已默认要求其中之一的 pstack 步骤,无需再逐一询问。用户说的“评审组”“竞技场”或“完整审核”,则会在其他任何地方运行。
- 完整阅读工具的技能说明,然后列出项目固定版本中每个默认调用该工具的 pstack 手册步骤和技能,例如 Feature 的设计步骤会调用
architect。在计划的“默认项”中,为每个调用位置各列一行,说明该位置会如何处理,以及撤销该处理的关键词;在构建之前完成。 - 将用户的句子拆成每个涉及项目各一行:使用 kebab-case 的
id,并写一句话的rule,说明工作内容、工具和阶段,例如{ "id": "api-design", "rule": "best-api 设计在选定目标之前会调用 architect。" }。如果已有行涵盖该工作,就改写该行,不要另加一行;如果用户要撤销某行,就删除该行。 - 当项目手册为该工作调用工具时,在相应位置引用该行,格式为
(reviews: <id>);从任何未被行覆盖的手册步骤中移除该工具。 - 运行
apply,然后运行verify。它会标记未在同一行附上有效引用却提及pstack:interrogate、pstack:arena或pstack:architect的手册行,以及仍设置了bigWork、risk或reviewPr的配置。 - 试运行一个该行涵盖的普通请求,以及一个该行未涵盖的请求;后者取自项目最常见的工作,并按照 Setup 的第 6 步进行判断。如果未涵盖的请求最终仍落入某个已覆盖的行中,就告知用户,因为该行涵盖的范围超出了他们的要求。然后按照每个项目的交付答复进行交付。
经验教训
来自 /pstack:reflect 的经验教训,或某个项目中的修正,只有在适用于所有项目时,才会修改共享层。仅适用于一个项目的经验教训应放在该项目块之外。若要更改计划页面的结构,需执行这些步骤;plan-page 技能的 Change 模式会将渲染器的具体要求补充到第 2、3、4 步中。只有一个项目会编写的部分应放在该项目手册的 frontmatter 中,绝不能放在渲染器中。
- 打开一个待办列表,逐字引用用户提出的每项要求,然后在最后一次行为编辑之后,按顺序执行这些关卡:对 helper 执行
deslop和no-comments,对 block 和 skill 文案执行unslop,运行测试和corpus,检查 helper panel,在从未提交的 dotai 树渲染出的最终 block 上运行 pre-push render 和整套 smoke;在任何试运行之前,为每个反向经验写一个具名提示词,写入 Setup 第 6 步所述的预期行为文件;接着执行 dotai push、apply、verify,然后在有决策轨迹审查时进行审查。若规则变更重新定义了什么算作证据,就要为该规则评判的决策添加一个提示词,例如,为 cut 规则添加一个 cut,而不只是添加一个会演练写入其结果的路径的提示词。本次运行在 smoke 之后对该项目 smoke 读取的任何指令文件所做的编辑,包括 block、项目规则、playbook 和工作流指南,都必须重新运行该项目的整套检查;重跑必须在该项目交付前完成,Close 必须列出轨迹审查所涵盖的 commit。项目的AGENTS.md点名的每份工作流指南都要有一个更新关卡。向用户复述设计时,每个状态或触发条件都沿用用户自己的用词。对于所有者要求保留的规则,也要同样处理:负责人比较所有者的触发条件与规则中的触发条件,然后重写规则,并将所有适用位置中 Agent 会加载的每份副本都改为符合所有者的范围。若计划变更某个关卡,就必须遵循计划启动时生效的关卡:计划的建议和 Defaults 应应用当前规则;若某个选项会跳过当前规则要求的关卡,就必须说明这一点。 - 在首次编辑之前以及再次在第 5 步的 smoke 之前,获取并快进 dotai checkout;按照 dotai 的
AGENTS.md要求,直接在其中编辑。根据 block 的 Other sessions 规则处理其他会话;该规则不围绕其他会话制定计划,只有当冲突造成阻碍时才处理冲突。若本次运行未提交的编辑阻碍快进,则跳过快进,直到这些编辑提交。若随后 push 被拒绝,则运行git pull --rebase,变基到已落地的更改之上,解决本次运行自身代码块中的任何冲突,重新运行检查并再次 push。列出并入已同步项目的每个上游 commit。负责人绝不还原本次运行未编写的编辑。只要 dotai 的检查通过,负责人就会按照 dotai 的AGENTS.md要求,在自己的编辑之后提交并推送其他会话对 dotai 的编辑或本地 commit;按照第 5 步的要求,这些编辑要单独放在一个 commit 中。若生成的workflow-manifest.json发生冲突,使用git checkout HEAD -- workflow-manifest.json解决,然后运行node scripts/build-workflow.mjs;若某个文件的工作树副本已被替换,则在对该文件运行git apply -3之前先检出HEAD,因为否则apply -3会拒绝执行。 - 编辑 dotai checkout 中的
assets/block.md或 helper。不要在其中写入项目名称、路径和命令。每个因项目而异的值都改为配置字段和占位符。优先使用位于 `` 内的可选字段,因为新增必填字段会导致所有缺少该字段的配置在面试补齐之前都无法渲染。若 block 文本称某个 helper 会拒绝某项内容,就要明确说明其检查的具体谓词以及会跳过什么。若拒绝操作需要从自由文本内容推断状态转换,则至少比较两种谓词设计后再实现。当一轮修复在该谓词上引出了新的 critical 后,下一轮修复要以显式输入取代推断,例如由状态转换写入的标记或记录下来的基准 commit。若 helper 开始拒绝旧配置格式,则必须在同一次apply写入中附带迁移,并以迁移的前置条件为门槛。若所有者表示将继续迭代某条共享规则,就将其移入独立 skill,block 只保留其权威规则和指向该 skill 的引用。若变更废弃或收窄某条规则,或为其添加例外,则必须运行 adapt 的 retired-policy 搜索,并在首次 smoke 前修复所有命中项。若变更添加了上限或边界,还要搜索每个 section 中会重新启动该循环的指令,例如 rerun、again 或 until,并为每项指令加上边界。在编辑共享规则前,对其变更的条款运行git log -S '<clause>' -- assets/block.md;若该条款是由某个经验教训添加的,就将此次编辑记录为对该经验教训的反向修订;其反向修订行要引用第 1 步中用于针对新文本 smoke 该经验教训案例的提示词。若 block 规则开始抑制某个 pstack 步骤,则按照 Template grammar 的要求,为每个步骤添加一条# overrides注释。 - 对每个受管理项目运行
apply <project> --dry-run进行预览。若变更涉及 helper 或检查,还要让新旧副本分别处理每个受管理项目中它们会判定的所有产物,并对失败项做 diff;对于 ledger helper,即运行corpus --session <id> --out <run directory>;对于 renderer,还要对渲染出的正文做 diff。若运行时的 session 工具提供了本次会话的 id,就传入该 id,因为chips只有在获得该 id 时才会打印其 started-session 检查结果。依据处理该行的 skill 或规则步骤,逐行审阅 diff 中新增或删除的内容,例如 pass 标题下处理 Do-list 行的步骤,因为仅有数量变化不能证明任何事。在 dotai commit 之前,负责人还要打开每个受管理项目实际渲染页面中已更改的区域,因为退出状态和打印出的路径都无法展示内容。若某项发现指向真实产物,则只能通过检查该产物来关闭,不能只检查 fixture。引出问题的真实产物必须始终是一个必须拒绝的案例,并在每轮修复后重新运行检查。新增或扩大的检查只判定尚未关闭的产物;其近似案例必须涵盖它可能扮演的每种角色中的一个已关闭产物,以及对已关闭产物所引用文件的重命名或删除。检查要在每个填充到受其约束状态的模板上运行,以确保它能够通过。对于每个会拒绝内容的谓词,都要运行一个必须通过的近似案例、一个必须拒绝的近似案例,以及一个反向状态转换案例,例如重新打开的计划。存在失败,或没有任何符合新检查所约束状态的实例时,记录为partial或gap,绝不能记录为verified。若新失败的文件由另一个会话持有未提交更改,则保持其失败状态,并按照 block 的 Delivery 规则标明其所有者。记录任何关于某个文件的声明之前,都要重新读取该文件。commit 正文要列出每个项目新增失败的数量。若 helper 会针对用户的全局配置打印或运行命令,则必须先在一个临时HOME下端到端验证;该HOME中应存放该配置的副本,并同时运行对照测试,然后才能发布。 - 首次 dotai commit 之前,对涉及 helper 或检查的变更,要用
/pstack:interrogate对其 diff 进行一轮审查;负责人修复该 panel 接受的问题,因为 smoke 轮次审查较慢且不完整。已接受的修复必须在 smoke 之前重新运行写入流程、测试和corpus。然后从未提交的树中运行 smoke,因为apply会从该树渲染。对于每个受管理项目,将其.agents/pstack复制到运行目录,作为corpus --installed基准,并在其实际 checkout 上运行基准 smoke。然后使用sync --tag <its pinned tag> <project>从未提交的树渲染该项目;其 preflight 会拒绝不在项目分支上,或写入文件存在未提交编辑的 checkout。将 dotai 项目中每个新增或更改的 skill 复制到其 skill 目录中,替代重新安装;从本地 checkout 使用-g安装每个已更改的用户范围 skill;然后按照 Setup 第 6 步所述的方式进行判定,运行成对 smoke。若sync拒绝某个项目,则从导出副本运行 smoke。在所有 git checkout 之外提取git archive HEAD,在其中运行git init并提交,这样 Codex 才会在仓库中运行,且不会读取任何父目录中的AGENTS.md;使用apply --force渲染新的 block。基准运行应读取变更前的指令文件,并将其复制到自己的导出副本中,因此两组之间只有编辑内容不同。渲染记录不会记录共享源,而第 6 步的apply会记录最后一次触及assets/的 commit,同时其输出保持不变。若 smoke 指出冲突,就在树中修复并再次运行 smoke,确保变更通过一次 push 进入 dotai。在 dotai 中,运行node scripts/build-workflow.mjs,然后运行node --test skills/sync-pstack/scripts/sync-pstack.test.mjs和scripts/validate-skills,后者会检查生成的目录;每项命令都可能超出前台命令的时限,因此要在后台运行,并将输出和退出状态写入日志。使用git add -- <new paths>暂存本次运行的新文件,并使用git commit --only -- <paths>提交本次运行的文件;此 commit 绝不使用git add -A。若某个指定路径也包含其他会话的代码块,则这些代码块也会一并提交,并在正文中说明。由于 dotai 的AGENTS.md要求提交所有内容,如果还有其他会话留下的编辑,就将其与workflow-manifest.json一起放入第二个 commit;若没有剩余的此类编辑,则将 manifest 放在第一个 commit 中,然后推送两个 commit。若所有者持有 push,则不要提交或推送。编辑留在 dotai checkout 中,并将其git diff保存为运行目录中的补丁;计划的 Open work item 要写明补丁、只有在其落地后才成立的每项声明,以及每个项目尚未执行的第 5 步渲染;这些项目的下一次apply会在编辑落地前拒绝执行。 - 若项目已从某个 commit 同步,则使用新的 commit 修复,绝不 amend 或 rebase,因为项目会将该 commit 记录为其源。从已推送的 commit 同步每个受管理项目,并在每个项目即将运行
apply之前,对其实际树运行corpus <project> --installed <its step 5 baseline> --session <id>,因为会话可能会在运行中途添加文件。若第 5 步已渲染的项目因未提交的共享编辑而被拒绝,这是本次运行自身的编辑导致的;按照 Sync 第 4 步处理。安装 block 点名的每个新增或更改的 skill,或此次变更编辑的每个 skill,然后运行 Sync 第 6 步的verify;若有决策轨迹审查,则随后进行审查。若本次apply写入的内容超出.agents/pstack.json,或者 smoke 之后的 commit 或编辑更改了其读取的指令文件的字节内容,则该项目不能仅凭第 5 步的 smoke 通过,必须在交付前再次运行成对 smoke。smoke 在变更所触及规则中指出的冲突,必须在任何项目交付之前作为新的 dotai commit 落地。使用npx --yes skills add udecode/dotai --skill <name> --agent codex claude-code -y重新安装每个新增或更改的项目 skill,以便 lock 记录远程源。从 home 目录使用npx --yes skills add udecode/dotai --skill <name> --agent codex claude-code -g -y刷新已更改的用户范围 skill,然后用diff -q将其已安装的SKILL.md与 dotai 副本比较。然后对每个项目运行 Sync 第 7 步。
项目工作手册
项目通过在 pstack 的工作手册之上添加自身的生命周期来实现,而不是只放在用户才能调用的技能中,这样普通请求就会通过 poteto-mode 触达它。每个 .agents/playbooks/<name>.md 都遵循 poteto-mode 中的 Project playbooks 段落,其中定义了 extends 和 when 前置元数据,以及基于 pstack 某个步骤原文引用片段所做的更改。sync-pstack 会添加:
- 可选的
page-lead、page-pairs和page-require行,用于命名计划所写入的审查章节,具体说明见plan-page技能。 - 区块会列出每本工作手册及其
when句子,因此添加或编辑工作手册后,必须再次运行apply渲染区块,否则check会失败。 - 当 pstack 工作手册不会停止而本项目工作手册会停止时,其停止点。
**In** 表示在步骤内添加工作,**Replace** 表示替换项目已确定的步骤,**Before** 表示在步骤之前执行。因此,实现某项更改的工作应放在基础工作手册的实现步骤 **In** 中,绝不能放在设计或固定步骤的 **Before** 中。**In**、**Before** 和 **After** 会添加行并保留基础步骤的所有原文,因此如果某个步骤的内容与区块或项目规则相矛盾(委派、提交、快照、额外的撰写环节),就需要使用 **Replace**。限制后续步骤的规则,例如谁可以提交、推送或回复,应放在其限制的第一个步骤的 **Before**,因为 Agent 会按顺序将渲染后的步骤复制到待办事项中。锚点检查匹配文本,不检查顺序。每次编辑后,运行 playbook <project> <name>,它会按顺序打印应用更改后的每个基础工作手册的步骤,然后阅读输出。如果某本工作手册扩展了两个基础工作手册,就要针对每个基础工作手册分别重述各项更改。
将项目知识保留在技能和项目规则中;工作手册只负责安排工作顺序。过去用于运行生命周期的类型化命令,应继续作为指向相应工作手册的入口。
模板语法
assets/block.md 和 assets/pstack/rules/ 中的每个规则文件都是带行指令的 Markdown。区块会保留典型任务所需的所有规则,并为每个规则文件保留一行指向说明,其中注明触发 Agent 阅读该文件的条件;如果规则内容移至规则文件,则须在其指向说明上方保留 overrides 注释。
,,和用于打开区域;当项目配置满足条件时,这些区域会被渲染。- `` 用于打开一个区域;如果配置在
skip下列出id,该区域就会被移除。 - `` 关闭最内层区域。区域可以嵌套。
{{key}}插入配置值。渲染行所需的值缺失时,渲染会失败;skip条目引用了不存在的章节时也会失败。- 以
开头的行用于指定下一条覆盖规则要替换的 pstack 文本,其中 `<path>` 相对于 pstack 的 `plugins/pstack/skills/`;如果该文本不存在,`apply --tag` 和 `verify` 就会失败。每条覆盖规则都要为其替换的每个 pstack 步骤添加一条注释,因此扩大覆盖范围时,也要为每个新涵盖的步骤添加注释。仅扩展 pstack 规则的规则应改用;verify会标记既没有此指令也没有覆盖说明的规则。 - 缩进行会续接上方的列表项,因此条件句可以补充规则。渲染后,内容会接在该列表项所在行,除非它以嵌套列表项开头,或跟在嵌套列表项之后。
边界
- 切勿编辑 pstack 自身的文件。通过区块或项目规则更改其行为。
- 未经所有者同意,切勿覆盖被拒绝的区块或辅助工具,除非其编辑已移至模板或区块之外。
- 设置和同步只能按照项目的交付答复进行。它们绝不会推送受保护分支、强制推送,也不会创建答复未要求的 PR;同步完全不会创建 PR,正如同步步骤 7 所述。对于
pr项目,同步将更改推送到其分支,这是它们唯一会进行的受保护推送,即使规则集要求创建 PR 也不例外,因为所有者已将其作为长期要求提出(所有者同意,2026-10-20);这也算作用户已提出的请求,因此项目禁止推送main的规则需要作相应处理。 - 访谈中已确定的答复归所有者所有。只有当项目证据与其中某项答复矛盾时,才再次询问。
- 设置和同步绝不会精简、合并或改写领域技能的方法。精简应作为单独的衡量步骤:先衡量各文件之间的重叠,再进行删减,并保留任何没有其他负责方的规则。
资源
- 访谈:问题、问题的证据和建议,以及配置字段。
- 适配:供应商副本、孤立技能、规则分支、Codex 席位、格式化工具,以及围绕区块改写项目规则。
assets/block.md:共享区块。assets/pstack/:Plans 规则运行的计划和决策日志辅助工具,以及cross.mjs。它会在指定模型和工作量下,在另一种运行环境中运行提示词;对于smoke,以只读方式运行;对于面板的 Codex 席位,则使用--reach,这些席位会加载所有者的配置和网络,并且只写入临时目录;或者使用--bypass,作为 Codex 工作进程使用所有者自己的 Codex 配置且不启用沙盒运行。还有seats.mjs,它会通过cross.mjs在一个进程中运行面板回合的各个席位,使该回合只需唤醒一次会话。scripts/sync-pstack.mjs,其测试位于scripts/sync-pstack.test.mjs。