diff --git a/plugins/waypoint/CHANGELOG.md b/plugins/waypoint/CHANGELOG.md index 530a20d..30a446e 100644 --- a/plugins/waypoint/CHANGELOG.md +++ b/plugins/waypoint/CHANGELOG.md @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ## [Unreleased] +### Changed + +- `project-navigator`: a work order now has two layers. The goal, the decisions needed, what is out of scope, and the scope are hard constraints; every other detail (data formats, paths, specific instances, implementation routes) is a working assumption. When an assumption does not match reality, the executor follows reality and records the correction in the new "事实修正" (fact corrections) table of the receipt instead of ending as blocked. The reviewer checks each correction for evidence and for overstepping under the new "修正核对" (correction check) item, and the review report lists them. Before, a mismatched detail was a specification problem, so exploratory work such as reverse engineering sent the same order back and forth. +- `project-navigator`: the order section "前提假设" is renamed "工作假设" (working assumptions) and the receipt section "前提核对" is renamed "假设核对"; the blocked type "前提不符" becomes "目标不可达" (goal unreachable). Orders and receipts already written keep working. + ## [1.4.0] - 2026-11-12 ### Added diff --git a/plugins/waypoint/agents/navigator-executor.md b/plugins/waypoint/agents/navigator-executor.md index fcd299e..153a785 100644 --- a/plugins/waypoint/agents/navigator-executor.md +++ b/plugins/waypoint/agents/navigator-executor.md @@ -8,7 +8,8 @@ description: project-navigator 的执行子代理, 只由编排会话按 exec-br ## 立场 - 委派提示词中的规则与交回格式是硬性要求; 细节以执行手册 (`project-navigator ref executor`) 与工单为准. -- 只做工单 "工作范围" 中要做的事. 范围之外的改动, 规格歧义, 需要用户提供的账号或操作, 都写进回执, 以受阻结束, 不自行变通. +- 只做工单 "工作范围" 中要做的事. 范围之外的改动, 任务目标达不成, 需要用户决定的事, 都写进回执, 以受阻结束, 不自行变通. +- 工单中的细节 (数据格式, 路径, 具体实例, 实现途径) 与实际不符时, 取得证据后以实际为准继续做, 在回执 "事实修正" 中逐条记录, 不算受阻. 任务目标与工作范围不能借修正改动. - 不提交, 不推送, 不运行改变编排状态的插件命令. 守卫拒绝的写入按拒绝理由调整, 不换写法重试. ## 交回 diff --git a/plugins/waypoint/docs/project-navigator-maintaining.en.md b/plugins/waypoint/docs/project-navigator-maintaining.en.md index 3b82c01..6ff542f 100644 --- a/plugins/waypoint/docs/project-navigator-maintaining.en.md +++ b/plugins/waypoint/docs/project-navigator-maintaining.en.md @@ -64,6 +64,7 @@ Each entry states the decision, the reason, and what happens if it is changed. - **A work order needs two user decisions: publish it in "工单审阅" (order review), and accept and commit it in "验收报告" (review report).** The review card lists only the "审阅要点" (review points: goal, decisions needed, out of scope, sizing reason) and the order file path, prefilled by `reply approve` from the order file. Approval is still bound to the digest of the order file (the hook records the digest when the review reply ends and the choice when the user answers), so a shorter display does not weaken the binding. 0.x quoted five sections of the order verbatim; users could not read it in a few seconds, and most details were beyond their judgment anyway. If changed: the review becomes a formality, or users read every order in full. - **A checker subagent checks each work order once before the review.** The orchestrator writes orders from the records it already has; when a concrete fact in one (a file path, an id in the data, the release form or license of an external resource) does not hold, the executor finds out halfway through. In the same project all 5 blocked rounds of implementation orders were of this kind, and the orchestrator had read almost no project files before writing those orders. `precheck-brief` generates the prompt; `waypoint:navigator-checker` checks read-only and returns the items that do not hold or cannot be checked; the orchestrator fixes the order and runs `order precheck`. Without that mark, `reply approve` and `order set issued` refuse a drafting order. The mark records only that the check ran once and is not bound to the order content: changes made from the findings, or after a block, need no second check, otherwise every edit costs another subagent run. The findings are not stored in a file of their own; they end up in the corrected order. If changed: mistakes in an order surface during execution again, one round trip per mistake. +- **A work order has two layers, hard constraints and working assumptions, and the executor may correct the second.** The hard constraints are the goal, the decisions needed, and what is out of scope under "审阅要点" (review points), plus "工作范围" (scope). Every other detail is a working assumption: the order's "工作假设" (working assumptions) section, and the data formats, paths, specific instances, and implementation routes written in the guidelines and criteria. When an assumption does not match reality, the executor gets evidence, follows reality, and records one row per correction in the receipt's "事实修正" (fact corrections) table; this is not blocked. The "修正核对" (correction check) item of the review prompt checks each row for evidence and for overstepping: a valid correction means the criteria are judged against the corrected fact, an invalid one fails them; the review report lists every correction. Up to 1.4.0 an order was treated as a contract and a mismatched detail was a specification problem: for reverse engineering and integration with external systems, details are known only after doing the work, and one order went back and forth repeatedly. The precheck only catches mistakes that can be looked up. There is no separate order kind; this applies to all orders, because ordinary projects meet mismatched details too and another kind is another judgement to make. The line against pending criteria: if another detail that matches the facts satisfies the criterion, it is a correction; if the facts make it impossible, it is pending. If changed: every detail found in exploratory work costs another review and issue, or the executor builds something that contradicts the facts in order to match the order. - **When a few criteria cannot be met, the executor finishes the rest and lists them as pending.** The receipt's "偏差记录" (deviations) has a "待定判据" (pending criteria) item, and the status is still completed. The reviewer confirms the stated reason and marks those criteria unverified with evidence starting with "待定:" (pending); they go through the existing option set 3 of "验收报告", where the user accepts as is or issues a follow-up order. No new status or option set. In the same project, 3 blocked receipts said the rest of the work was already done and only one criterion was stuck. If the user's decision would change how the rest is done, the order is still blocked. If changed: the wording of one criterion costs the whole order another review and issue. - **Test authorization is gone.** The executor does not run tests with external effects and lists them under "外部影响" (external effects) in the receipt's test record; the reviewer runs the code checks and the receipt's other test commands, not the external ones, and judges those from the receipt's output. MCP evidence tools are no longer registered; the reviewer makes read-only queries at the places named in the receipt's evidence record, with the constraint stated in the prompt and the subagent definition. If changed: every order with an external test costs one more user choice. - **Unverified criteria can be accepted explicitly by the user.** The third option group of "验收报告" (only unverified, nothing failed) lets the user accept as is and commit, via `order set accepted --accept-unverified`; the unverified criteria are recorded as risks. 0.x always failed the order, so criteria that depend on external evidence were rejected over and over. Failed criteria still cannot be accepted. If changed: orders cannot converge when external conditions are missing. @@ -297,17 +298,18 @@ In a temporary repository with `claude --plugin-dir ./plugins/waypoint`, confirm ### Work order round trip 1. After writing an order the orchestrator first sends the checker subagent (the Agent call carries `model: "sonnet"`), and the checker is refused when it tries to write a file; put a nonexistent file into a criterion on purpose, the findings point it out, and the orchestrator fixes the order and runs `order precheck`; `reply approve` without the precheck is refused. -2. The executor meets one criterion it cannot satisfy: it finishes the rest, the receipt lists the criterion as pending, and the review report uses option set 3 and describes that criterion. -3. On an analysis order the executor needs a user action: no receipt, the handback is "执行状态: 等待操作"; the orchestrator replies "等待操作" (no option block), the same subagent continues after the user replies "操作完成", and `status` shows the order as issued throughout. -4. After `model set executor sonnet --kind fix`, the next action of a fix order says `model 参数写 "sonnet"` while an implementation order still says not to pass it; after a resume (SendMessage) the subagent still uses its dispatch model. -5. "工单审阅" (order review) shows only the review points and the order file path, matching the order file; after B the order is changed and reviewed again; after A it is issued, an executor is dispatched in the background, and the reply is "工单执行" (order running); changing the order file after approval makes the issue fail. -6. While the executor works in the background, the user can keep talking to the orchestrator; when it finishes, the orchestrator runs `status` on its own and starts the review. -7. In the default permission mode, the executor's write prompts appear in the orchestrator session; after switching to Accept edits they stop. -8. The executor is blocked (for example it needs an account): the reply is "受阻处理" (blocked handling); after the user acts, no new review is needed and the original subagent continues through SendMessage. -9. "工单执行" has no option block; replying "停止执行" (stop) during execution: the subagent stops, the order goes back to drafting, and it is reviewed again after changes. -10. The reviewer returns verdicts and evidence and is denied when it tries to write files; it does not run tests the receipt lists as external effects. -11. After a passing review, A commits and B commits and pushes; with unverified criteria the third group is used, and A accepts the order and records risks; with failures a follow-up order is issued, and for an implementation order the orchestrator first judges whether it was too large. -12. The executor's writes to records other than its order's receipt and `artifacts/` are denied; the orchestrator's business file writes are denied. +2. Write one wrong detail into the order's "工作假设" on purpose (for example a function name that does not exist): the executor is not blocked, finishes according to the facts, and the receipt's "事实修正" has one row; "修正核对" in the review report describes the correction. Then make a correction cross "明确不做" (out of scope): the review fails the related criterion. +3. The executor meets one criterion it cannot satisfy: it finishes the rest, the receipt lists the criterion as pending, and the review report uses option set 3 and describes that criterion. +4. On an analysis order the executor needs a user action: no receipt, the handback is "执行状态: 等待操作"; the orchestrator replies "等待操作" (no option block), the same subagent continues after the user replies "操作完成", and `status` shows the order as issued throughout. +5. After `model set executor sonnet --kind fix`, the next action of a fix order says `model 参数写 "sonnet"` while an implementation order still says not to pass it; after a resume (SendMessage) the subagent still uses its dispatch model. +6. "工单审阅" (order review) shows only the review points and the order file path, matching the order file; after B the order is changed and reviewed again; after A it is issued, an executor is dispatched in the background, and the reply is "工单执行" (order running); changing the order file after approval makes the issue fail. +7. While the executor works in the background, the user can keep talking to the orchestrator; when it finishes, the orchestrator runs `status` on its own and starts the review. +8. In the default permission mode, the executor's write prompts appear in the orchestrator session; after switching to Accept edits they stop. +9. The executor is blocked (for example it needs an account): the reply is "受阻处理" (blocked handling); after the user acts, no new review is needed and the original subagent continues through SendMessage. +10. "工单执行" has no option block; replying "停止执行" (stop) during execution: the subagent stops, the order goes back to drafting, and it is reviewed again after changes. +11. The reviewer returns verdicts and evidence and is denied when it tries to write files; it does not run tests the receipt lists as external effects. +12. After a passing review, A commits and B commits and pushes; with unverified criteria the third group is used, and A accepts the order and records risks; with failures a follow-up order is issued, and for an implementation order the orchestrator first judges whether it was too large. +13. The executor's writes to records other than its order's receipt and `artifacts/` are denied; the orchestrator's business file writes are denied. ### Changes, milestone reviews, and anomalies @@ -326,6 +328,7 @@ In a temporary repository with `claude --plugin-dir ./plugins/waypoint`, confirm - Recognizing the orchestrator depends on the marker in the transcript, whose format is internal to Claude Code; when the transcript cannot be read, rule 4 does not apply (the write is allowed). - The executor subagent belongs to the session that started it; closing that session interrupts its work, and a new session continues according to whether the receipt was written. - A background subagent's write prompt does not name the subagent; users can infer it only from the "工单执行" (order running) reply and the task list. +- Fact corrections are kept in check by the reviewer and the user: no script can tell when corrections add up to a changed goal; that shows only in the "修正核对" item of the review report. The line between hard constraints and working assumptions is written in the rules; when the executor misjudges it, it either blocks once more than needed or oversteps and fails the review. - The precheck records only that it ran, not whether the orchestrator changed the order accordingly; the checker examines only the facts written in the order and cannot find unstated assumptions. - The subagent model is only a parameter written in the "next action"; no hook checks that the orchestrator passes it. - While waiting for a user action the order status does not change, and the original executor is lost with the session; a newly dispatched one can continue only from the documents under `artifacts/`. diff --git a/plugins/waypoint/docs/project-navigator-maintaining.md b/plugins/waypoint/docs/project-navigator-maintaining.md index a4b95d4..81b37ad 100644 --- a/plugins/waypoint/docs/project-navigator-maintaining.md +++ b/plugins/waypoint/docs/project-navigator-maintaining.md @@ -64,6 +64,7 @@ - **一张工单只要用户做两次决定: 工单审阅中发布, 验收报告中通过并提交.** 审阅卡片只列 "审阅要点" (任务目标, 需要决定, 明确不做, 粒度依据) 与工单文件路径, 由 `reply approve` 从工单文件预填. 认可仍按工单文件的摘要绑定 (hook 在回复工单审阅时记下摘要, 用户回答时记下选择), 展示的内容变短不影响绑定. 0.x 原样摘录工单五节, 用户三秒内读不完, 而且多数细节用户判断不了. 改掉的后果: 审阅变成走过场, 或用户每张工单都要读完整工单. - **工单在审阅之前由核对子代理核对一次.** 编排会话凭已有的记录写工单, 其中的具体事实 (文件路径, 数据中的编号, 外部资源的发布形式与许可) 不成立时, 执行子代理做到一半才发现. 在同一个项目中, 实现工单的 5 轮受阻都属于这种情况, 而写这几张工单之前编排会话几乎没有读项目文件. `precheck-brief` 生成提示词, `waypoint:navigator-checker` 只读核对并交回不成立与无法核对的条目, 编排会话改好工单后运行 `order precheck`; 起草中的工单没有这个标记时, `reply approve` 与 `order set issued` 拒绝. 标记只记做过一次, 不绑定工单内容: 按核对结果修改, 或受阻后修改, 都不用再核对, 否则每改一次就多一轮子代理. 核对结果不另存文件, 落在改好的工单里. 改掉的后果: 工单中的错误回到执行阶段才暴露, 每个错误一轮往返. +- **工单分硬约束与工作假设两层, 执行子代理可以按实际修正后一层.** 硬约束是 "审阅要点" 的任务目标, 需要决定, 明确不做, 以及 "工作范围"; 其余细节 (工单的 "工作假设" 一节, 以及守则与判据中的数据格式, 路径, 具体实例, 实现途径) 都是工作假设. 假设与实际不符时, 执行子代理取得证据后以实际为准, 在回执 "事实修正" 表中逐行记录, 不算受阻; 验收提示词的 "修正核对" 逐行核对证据与是否越界, 成立的修正按修正后的事实判判据, 不成立的判不通过; 验收报告列出全部修正. 1.4.0 及之前把工单当合同, 细节不符就是规格问题: 逆向与对接外部系统的任务, 细节做了才知道, 同一张工单反复往返. 发布前核对只能拦住查得到的错. 不单设工单类型, 所有工单适用: 普通项目同样会遇到细节不符, 多一种类型多一处判断. 与待定判据的界线: 换一个符合事实的细节就能满足的是修正, 按事实根本做不出来的才是待定. 改掉的后果: 探索性的任务每发现一个细节就多一轮审阅与发布, 或执行子代理为了符合工单做出与事实不符的东西. - **个别判据做不到时, 执行子代理做完其余部分, 把这几条列为待定.** 回执 "偏差记录" 有 "待定判据" 一项, 执行状态仍写完成; 验收子代理核对原因属实后把这几条判为未验证, 证据以 "待定:" 开头, 走已有的 "验收报告" 第 3 组, 由用户接受现状或发补正工单. 没有新增状态与选项组. 同一项目中有 3 轮受阻的回执写明 "其余工作已全部完成", 只卡在一条判据上. 用户的决定会改变其余部分的做法时仍然受阻. 改掉的后果: 一条判据的措辞问题让整张工单多走一轮审阅与发布. - **测试授权去掉.** 执行子代理不运行有外部影响的测试, 写进回执 "测试记录" 的 "外部影响"; 验收子代理运行代码检查与回执中其它测试命令, 不重跑外部影响的命令, 按回执输出判断. MCP 取证工具不再登记, 验收子代理按回执 "取证记录" 做只读查询, 约束写在提示词与子代理定义中. 改掉的后果: 每张带外部测试的工单多一次用户选择. - **未验证的判据可以由用户明确接受.** "验收报告" 第 3 组 (只有未验证, 没有不通过) 由用户选择接受现状并提交, 对应 `order set accepted --accept-unverified`, 未验证的判据登记为风险. 0.x 一律判不通过, 依赖外部取证的判据反复被拒. 不通过的判据仍然不能接受. 改掉的后果: 外部条件不足时工单无法收敛. @@ -297,17 +298,18 @@ ### 工单往返 1. 写好工单后编排会话先派核对子代理 (Agent 调用带 `model: "sonnet"`), 核对子代理尝试写文件时被拒; 故意在判据里写一个不存在的文件, 核对结果指出来, 编排会话改好后运行 `order precheck`; 跳过核对直接 `reply approve` 被拒. -2. 执行子代理遇到一条做不到的判据: 做完其余部分, 回执列为待定, 验收报告用第 3 组并写明这条判据的情况. -3. 分析工单中执行子代理需要用户操作: 不写回执, 交回 "执行状态: 等待操作"; 编排会话回复 "等待操作" (没有选项块), 用户回复 "操作完成" 后原子代理继续, `status` 的工单状态一直是 issued. -4. `model set executor sonnet --kind fix` 之后, 修复工单的下一动作写 `model 参数写 "sonnet"`, 实现工单仍写不传; 续接 (SendMessage) 之后子代理仍用派出时的模型. -5. "工单审阅" 只有审阅要点与工单文件路径, 与工单文件一致; 选 B 后修改再审阅; 选 A 后发布并在后台派出执行子代理, 回复 "工单执行"; 认可之后改工单文件, 发布被拒. -6. 执行子代理在后台工作时, 能继续与编排会话对话; 子代理结束后编排会话自动运行 status 并进入验收. -7. 默认权限模式下, 执行子代理的写入确认弹在编排会话中; 切到 Accept edits 后不再弹出. -8. 执行子代理受阻 (例如需要用户提供账号): 回复 "受阻处理"; 用户完成操作后不需要重新审阅, 原子代理用 SendMessage 继续. -9. "工单执行" 没有选项块; 执行期间回复 "停止执行": 子代理停止, 工单撤回为起草中, 修改后重新审阅. -10. 验收子代理交回结论与证据, 它尝试写文件时被拒绝; 回执中列为外部影响的测试它不运行. -11. 验收通过选 A 提交, 选 B 提交并推送; 有未验证判据时用第 3 组, 选 A 后工单通过并登记风险; 有不通过时补正, 实现工单先判断是否太大. -12. 执行子代理写本工单回执与 `artifacts/` 之外的编排记录被拒; 编排会话写业务文件被拒. +2. 工单的 "工作假设" 故意写错一个细节 (例如一个不存在的函数名): 执行子代理不受阻, 按实际做完, 回执 "事实修正" 有一行; 验收报告的 "修正核对" 写出这项修正. 再让修正越过 "明确不做": 验收判相关判据不通过. +3. 执行子代理遇到一条做不到的判据: 做完其余部分, 回执列为待定, 验收报告用第 3 组并写明这条判据的情况. +4. 分析工单中执行子代理需要用户操作: 不写回执, 交回 "执行状态: 等待操作"; 编排会话回复 "等待操作" (没有选项块), 用户回复 "操作完成" 后原子代理继续, `status` 的工单状态一直是 issued. +5. `model set executor sonnet --kind fix` 之后, 修复工单的下一动作写 `model 参数写 "sonnet"`, 实现工单仍写不传; 续接 (SendMessage) 之后子代理仍用派出时的模型. +6. "工单审阅" 只有审阅要点与工单文件路径, 与工单文件一致; 选 B 后修改再审阅; 选 A 后发布并在后台派出执行子代理, 回复 "工单执行"; 认可之后改工单文件, 发布被拒. +7. 执行子代理在后台工作时, 能继续与编排会话对话; 子代理结束后编排会话自动运行 status 并进入验收. +8. 默认权限模式下, 执行子代理的写入确认弹在编排会话中; 切到 Accept edits 后不再弹出. +9. 执行子代理受阻 (例如需要用户提供账号): 回复 "受阻处理"; 用户完成操作后不需要重新审阅, 原子代理用 SendMessage 继续. +10. "工单执行" 没有选项块; 执行期间回复 "停止执行": 子代理停止, 工单撤回为起草中, 修改后重新审阅. +11. 验收子代理交回结论与证据, 它尝试写文件时被拒绝; 回执中列为外部影响的测试它不运行. +12. 验收通过选 A 提交, 选 B 提交并推送; 有未验证判据时用第 3 组, 选 A 后工单通过并登记风险; 有不通过时补正, 实现工单先判断是否太大. +13. 执行子代理写本工单回执与 `artifacts/` 之外的编排记录被拒; 编排会话写业务文件被拒. ### 变更, 复查与异常 @@ -326,6 +328,7 @@ - 编排会话的认定依赖转录中的标记, 转录格式是 Claude Code 的内部格式; 读不到转录时规则 4 不生效 (放行). - 执行子代理属于启动它的会话, 会话关闭后子代理的工作中断; 新会话按回执是否写入继续. - 后台子代理的写入确认不写明是子代理, 用户只能从 "工单执行" 回复与任务列表推断. +- 事实修正靠验收子代理与用户把关: 修正多到任务目标实际变了的情况, 脚本判断不了, 只能从验收报告的 "修正核对" 看出来. 硬约束与工作假设的界线写在规则里, 执行子代理判断错时, 要么多受阻一次, 要么越界后被验收判不通过. - 发布前核对只记是否做过, 不核对编排会话是否按结果改了工单; 核对子代理只查工单中写出来的事实, 没写出来的隐含假设查不到. - 子代理模型只是写在 "下一动作" 里的参数, hook 不核对编排会话是否照传. - 等待操作期间工单状态不变, 原执行子代理随会话结束而丢失; 新派出的子代理只能靠 `artifacts/` 下的文档接着做. diff --git a/plugins/waypoint/docs/project-navigator.en.md b/plugins/waypoint/docs/project-navigator.en.md index 4534825..16e89a7 100644 --- a/plugins/waypoint/docs/project-navigator.en.md +++ b/plugins/waypoint/docs/project-navigator.en.md @@ -155,12 +155,13 @@ A requirement change can be inserted at any stage, and the work returns to where 2. **Review.** The orchestrator replies with "工单审阅" (work order review), listing only the review points and the order file path. The order can be issued only after you choose A; if the order changes after that, it is reviewed again. 3. **Execution.** The orchestrator dispatches an executor subagent in the background and replies with "工单执行" (order running). The executor checks the commit and assumptions, plans, implements, checks itself, and writes the receipt. "工单执行" needs no choice from you, so it has no option block; to stop and change the order midway, reply "停止执行" (stop). 4. **Waiting for your action.** When the order is fine and the executor only needs you to do something by hand (for example, one action in the program being debugged), it writes no receipt and hands back midway; the orchestrator replies with "等待操作" (waiting for your action) and lists the steps. Reply "操作完成" (done) with what you actually did, and the executor continues. This can repeat; the order status does not change. -5. **Blocked.** When the executor hits a specification problem, or needs a decision from you, it explains in the receipt and stops. The orchestrator replies with "受阻处理" (blocked handling); once you have handled it and the order does not need to change, the same executor continues without a new review. When only a few criteria cannot be met as written and the rest is unaffected, this is not blocked: the executor finishes the rest and lists those criteria as pending in the receipt, for you to decide at acceptance. -6. **Review of the work.** The orchestrator sends the reviewer subagent to check each criterion; the only verdicts are pass, fail, and unverified. While the reviewer works in the background, the orchestrator first replies with "工单验收" (order under review, no option block), then with "验收报告" (review report) when the result is back; its recommendation goes only in the "处理建议" (recommendation) section. In "验收报告": +5. **Fact corrections.** The details in a work order (data formats, paths, specific instances, the way to implement something) are judgements made before the work started. When the executor finds one that does not match reality, it follows reality and keeps going, recording the original text, the actual facts, the evidence, and what it did instead in the receipt; it does not stop to ask you. The goal, the scope, what is out of scope, and the decisions reserved for you are not details, and it cannot change them. The reviewer checks each correction for evidence and for overstepping; "修正核对" (correction check) in the review report lists them all, so you read them once at acceptance. +6. **Blocked.** When the executor finds the goal cannot be reached, needs to go beyond the scope, or needs a decision from you, it explains in the receipt and stops. The orchestrator replies with "受阻处理" (blocked handling); once you have handled it and the order does not need to change, the same executor continues without a new review. When only a few criteria cannot be met as written and the rest is unaffected, this is not blocked: the executor finishes the rest and lists those criteria as pending in the receipt, for you to decide at acceptance. +7. **Review of the work.** The orchestrator sends the reviewer subagent to check each criterion; the only verdicts are pass, fail, and unverified. While the reviewer works in the background, the orchestrator first replies with "工单验收" (order under review, no option block), then with "验收报告" (review report) when the result is back; its recommendation goes only in the "处理建议" (recommendation) section. In "验收报告": - Everything passes: you may verify by hand following the "人工验收" (manual verification) steps, then choose to commit, or commit and push. - Something fails: the orchestrator first judges why; an order that was too large is split, otherwise a fix order follows. - Only unverified criteria remain: you decide to accept as is and commit, or to follow up; accepted unverified criteria are recorded as risks. Criteria the receipt lists as pending are handled here too; "处理建议" (recommendation) states the facts and the options for each. -7. **Commit.** After acceptance, the orchestrator calls commit-message, and the business changes and records of the round become one commit. Changes outside the receipt are listed for you to decide. +8. **Commit.** After acceptance, the orchestrator calls commit-message, and the business changes and records of the round become one commit. Changes outside the receipt are listed for you to decide. Work orders run strictly one after another. The orchestrator sizes each order by four limits (one executor run can finish it, one review can check it, it runs afterwards, risky parts are separate), one slice per order by default, and states the reason in the review points. diff --git a/plugins/waypoint/docs/project-navigator.md b/plugins/waypoint/docs/project-navigator.md index ff68cb7..979e040 100644 --- a/plugins/waypoint/docs/project-navigator.md +++ b/plugins/waypoint/docs/project-navigator.md @@ -153,12 +153,13 @@ project-navigator model set executor sonnet --kind fix 2. **审阅.** 编排会话回复 "工单审阅", 只列审阅要点与工单文件路径. 你选 A 后工单才能发布; 选 A 之后工单再有改动, 要再审阅一次. 3. **执行.** 编排会话在后台派出执行子代理, 回复 "工单执行". 执行子代理核对提交与前提, 做计划, 实施, 自检, 写回执. "工单执行" 不需要你选择, 所以没有选项块; 中途想停下改工单时, 回复 "停止执行". 4. **等待操作.** 工单没有问题, 只是要你亲手做一件事才能继续时 (例如在被调试的程序中操作一次), 执行子代理不写回执, 中途交回; 编排会话回复 "等待操作", 列出操作步骤. 你做完后回复 "操作完成" 并写明做了什么, 子代理接着做. 这一步可以重复多次, 工单状态不变. -5. **受阻.** 执行子代理遇到规格问题, 或需要你做决定时, 写回执说明并停下. 编排会话回复 "受阻处理"; 你处理完而工单不用改时, 原来的子代理接着做, 不需要重新审阅. 只有个别判据照原文做不到, 其余部分不受影响时, 不算受阻: 执行子代理把其余工作做完, 这几条判据在回执中列为待定, 由你在验收时决定. -6. **验收.** 编排会话派验收子代理逐条核对判据, 结论只有通过, 不通过, 未验证三种. 验收子代理在后台核对时, 编排会话先回复 "工单验收" (没有选项块), 结果回来后回复 "验收报告"; 编排会话的建议只写在其中的 "处理建议" 一节. 回复 "验收报告" 时: +5. **事实修正.** 工单里的细节 (数据格式, 路径, 具体实例, 实现途径) 是动手前的判断. 执行子代理发现与实际不符时, 以实际为准继续做, 在回执中逐条记录原文, 实际情况, 证据与处理办法, 不停下来问你. 任务目标, 工作范围, 明确不做与需要你决定的事不在此列, 这些它不能改. 验收子代理逐条核对修正是否属实, 是否越界; "验收报告" 的 "修正核对" 列出全部修正, 你在验收时一次看完. +6. **受阻.** 执行子代理发现任务目标达不成, 要超出范围, 或需要你做决定时, 写回执说明并停下. 编排会话回复 "受阻处理"; 你处理完而工单不用改时, 原来的子代理接着做, 不需要重新审阅. 只有个别判据照原文做不到, 其余部分不受影响时, 不算受阻: 执行子代理把其余工作做完, 这几条判据在回执中列为待定, 由你在验收时决定. +7. **验收.** 编排会话派验收子代理逐条核对判据, 结论只有通过, 不通过, 未验证三种. 验收子代理在后台核对时, 编排会话先回复 "工单验收" (没有选项块), 结果回来后回复 "验收报告"; 编排会话的建议只写在其中的 "处理建议" 一节. 回复 "验收报告" 时: - 全部通过: 你可以按 "人工验收" 的步骤亲手验证, 然后选择提交, 或提交并推送. - 有不通过: 编排会话先判断原因, 工单太大就拆小, 否则发修复工单. - 只有未验证: 由你决定接受现状并提交, 或补正; 接受的未验证判据登记为风险. 回执列为待定的判据也在这里处理, "处理建议" 中写明每条的实际情况与可选做法. -7. **提交.** 验收通过后, 编排会话调用 commit-message, 本轮业务改动与记录合成一条提交. 有回执之外的改动时, commit-message 会列出来问你是否纳入. +8. **提交.** 验收通过后, 编排会话调用 commit-message, 本轮业务改动与记录合成一条提交. 有回执之外的改动时, commit-message 会列出来问你是否纳入. 工单严格一张接一张. 工单的大小由编排会话按 "执行一次能做完, 验收能看清, 做完能运行, 高风险部分单独成工单" 判断, 默认一个切片一张, 审阅要点中写明划分依据. diff --git a/plugins/waypoint/skills/project-navigator/guide/executor.md b/plugins/waypoint/skills/project-navigator/guide/executor.md index 8472e1d..3c6b78c 100644 --- a/plugins/waypoint/skills/project-navigator/guide/executor.md +++ b/plugins/waypoint/skills/project-navigator/guide/executor.md @@ -15,7 +15,7 @@ ## 执行流程 1. 对账: 运行 `git status` 与 `git log -1`. 当前提交应等于工单概况中的 "基准提交", 工作区不应有与本工单无关的改动. 不一致时不动手, 写回执, 执行状态写 "受阻", 受阻类型写 "对账不符". -2. 核对前提: 逐条检查工单 "前提假设" 是否成立, 读代码与配置核实, 不凭记忆. 不成立时以受阻结束, 受阻类型写 "前提不符"; 只影响个别判据时按下方 "待定判据" 处理. +2. 核对假设: 逐条检查工单 "工作假设" 是否成立, 读代码与配置核实, 不凭记忆, 结果写进回执 "假设核对". 不成立的假设以实际为准, 按下方 "事实修正" 处理, 不因此停下. 3. 做计划: 先定模块划分, 写法见下方 "模块划分"; 再列出完成每条验收判据的步骤与验证方式. 计划不需要用户确认, 但要写进回执的 "模块划分" 与 "判据自检". 4. 实施: 只做工单 "工作范围" 中要做的事; 遵守工单 "执行守则" 与项目规范 `.claude/rules/engineering.md`. 5. 自检: 逐条核对验收判据, 运行代码检查与测试. 需要真实账号, 会产生费用或外部副作用的测试不要运行, 把命令写进回执 "测试记录" 的 "外部影响", 由用户决定. @@ -44,24 +44,42 @@ - 工单要求接线 Claude Code hook 时, 可以改 `.claude/settings.json` 的 `hooks` 字段与 `.claude/` 下项目自己的文件 (例如 `.claude/hooks/` 中的脚本). - 不改 `.claude/settings.json` 的 `permissions` 字段中本技能的放行规则 (以 `project-navigator` 或 `.navigator/` 开头的规则), 不改 `.claude/rules/engineering.md`: 前者由 init 管理, 后者由编排会话的 `standards` 命令写入. 需要调整时写进回执的 "需要操作". +## 事实修正 + +工单由编排会话在动手之前写成, 其中的细节只是当时的判断. 逆向, 对接外部系统这类任务, 很多事实做了才知道. 工单的内容因此分两层: + +- 硬约束: "审阅要点" 的任务目标, 需要决定, 明确不做, 以及 "工作范围". 这些是用户认可过的, 你不能改. +- 工作假设: 其余的细节, 包括 "工作假设" 一节, 以及 "执行守则" 与 "验收判据" 中写到的数据格式, 字段含义, 路径, 接口名, 具体实例与实现途径. + +工作假设与实际不符时, 以实际为准继续做, 不算受阻: + +- 先取得证据 (文件路径与行号, 命令输出, 取证记录, 或 `artifacts/` 下的脚本), 再按实际情况实现. 不为了符合工单而做出与事实不符的东西. +- 在回执 "事实修正" 表中每项修正写一行: "工单原文" 摘录原句并写明所在的节; "实际情况" 写查到的事实; "证据位置" 写能复核的位置; "处理办法" 写你改成了怎么做. 没有修正时只留表头. +- 判据引用了被修正的细节时, 按修正后的事实自检, "判据自检" 中写明 "按事实修正第 N 行". +- 修正之后任务目标仍要达成, 改动仍在工作范围之内. + +以下情况不属于事实修正, 仍按受阻处理: 按实际情况任务目标达不成; 要做 "明确不做" 的事或超出 "工作范围"; 有几种做法而取舍会影响用户 (例如许可, 费用, 对外行为); 工单 "需要决定" 中写的事. 拿不准时按受阻处理. + ## 受阻情形 -遇到以下情况立即停下, 写回执, 执行状态写 "受阻", 不自行变通. 两种情况例外, 先看下方 "待定判据" 与 "等待操作": +遇到以下情况立即停下, 写回执, 执行状态写 "受阻", 不自行变通. 细节与实际不符不在其列, 见上方 "事实修正"; 另有两种例外, 见下方 "待定判据" 与 "等待操作": -- 对账不符, 或工单前提不成立. -- 规格有歧义, 或判据之间互相矛盾. +- 对账不符. +- 按实际情况, 任务目标达不成. +- 规格有歧义而几种理解会做出不同的结果, 或判据之间互相矛盾. - 需要超出工作范围的改动, 例如改其它模块的公共接口. - 需要用户操作或决定, 例如提供账号, 密钥, 安装软件, 或在几种做法中选一种. - 按选型守则找不到满足需求的方案. -回执 "偏差记录" 的 "受阻详情" 写受阻类型 (对账不符, 前提不符, 规格问题, 范围过大, 需要用户操作, 需要用户决定), 规格原文, 实际情况与证据位置. 用户处理后, 编排会话可能让你接着做: 收到继续的消息时, 先运行 `git status` 核对工作区, 再从受阻处继续, 最后重写回执. +回执 "偏差记录" 的 "受阻详情" 写受阻类型 (对账不符, 目标不可达, 规格问题, 范围过大, 需要用户操作, 需要用户决定), 规格原文, 实际情况与证据位置. 用户处理后, 编排会话可能让你接着做: 收到继续的消息时, 先运行 `git status` 核对工作区, 再从受阻处继续, 最后重写回执. ## 待定判据 工单的其余部分不受影响, 只有个别判据照原文做不到时, 不以受阻结束: 把其余工作做完, 这几条判据留作待定, 由用户在验收时决定. 这样用户只决定一次, 不用整张工单往返一轮. -- 适用情形: 判据点名的实例不存在或不带所要求的特征; 判据依赖的事实不成立; 判据要用户在两种说法中选一种, 而选哪种都不改变已经完成的工作. -- 不适用: 用户的决定会改变其余部分的做法 (例如随包带哪种格式的文件); 前提不成立导致主要工作无法进行; 要改动工作范围之外的文件. 这些情况仍按受阻处理. +- 与事实修正的界线: 判据换一个符合事实的细节就能满足时 (例如点名的实例不存在, 另一个实例带有同样的特征), 属于事实修正, 照做并记录. 判据要求的东西按事实根本做不出来, 或要用户在两种说法中选一种时, 才留作待定. +- 适用情形: 判据要求的特征在实际数据中不存在; 判据要用户在两种说法中选一种, 而选哪种都不改变已经完成的工作. +- 不适用: 用户的决定会改变其余部分的做法 (例如随包带哪种格式的文件); 任务目标达不成; 要改动工作范围之外的文件. 这些情况仍按受阻处理. - 写法: 回执 "执行状态" 写 "完成"; "偏差记录" 的 "待定判据" 逐条写判据编号, 规格原文, 实际情况与证据位置, 以及可选的处理办法 (例如 "改用实例 X 核对" 或 "以单元测试代替"). "判据自检" 中这几条写 "待定". 没有待定判据时写 "无". - 不替用户选: 不按自己选的办法改写判据后写 "通过". @@ -99,8 +117,8 @@ 回执以 "# 工单回执" 开头, 第一节为 "## 当前进展". 之后各节: -- 实现类工单 (`--option 1`): 回执概况 (执行状态, 基准提交, 完成时间); 前提核对; 模块划分 (新增模块, 改动模块, 入口改动); 判据自检; 改动清单; 测试记录 (测试命令, 测试结果, 测试改动, 外部影响, 取证记录); 运行方式 (启动命令, 验证步骤); 偏差记录 (实现决定, 需要操作, 发现风险, 待定判据, 受阻详情) -- 选型类工单 (`--option 2`): 回执概况 (执行状态, 基准提交, 完成时间); 前提核对; 现有能力; 候选方案; 需求核对 (表格, 列为 需求, 结论, 依据, "结论" 只能填 能/不能); 能力核实 (表格, 列为 能力, 仓库, 版本, 路径, 行号, 说明); 选型结论; 一致检查; 改动清单; 偏差记录 (实现决定, 需要操作, 发现风险, 受阻详情) +- 实现类工单 (`--option 1`): 回执概况 (执行状态, 基准提交, 完成时间); 假设核对; 事实修正 (表格, 列为 工单原文, 实际情况, 证据位置, 处理办法); 模块划分 (新增模块, 改动模块, 入口改动); 判据自检; 改动清单; 测试记录 (测试命令, 测试结果, 测试改动, 外部影响, 取证记录); 运行方式 (启动命令, 验证步骤); 偏差记录 (实现决定, 需要操作, 发现风险, 待定判据, 受阻详情) +- 选型类工单 (`--option 2`): 回执概况 (执行状态, 基准提交, 完成时间); 假设核对; 现有能力; 候选方案; 需求核对 (表格, 列为 需求, 结论, 依据, "结论" 只能填 能/不能); 能力核实 (表格, 列为 能力, 仓库, 版本, 路径, 行号, 说明); 选型结论; 一致检查; 改动清单; 偏差记录 (实现决定, 需要操作, 发现风险, 受阻详情) 括号中是键名. 键值节中每个键只占一行 "- 键名: 值", 值写在同一行, 节中不加其它行, 列表, 表格或段落, 编排会话的脚本按键值行读取回执. 表格与多行内容写进没有键名的节, 完整输出放进证据文件后在值中写出路径. diff --git a/plugins/waypoint/skills/project-navigator/references/files.md b/plugins/waypoint/skills/project-navigator/references/files.md index f501f1b..456bbad 100644 --- a/plugins/waypoint/skills/project-navigator/references/files.md +++ b/plugins/waypoint/skills/project-navigator/references/files.md @@ -9,22 +9,22 @@ - 种类: `order` - 路径: `.navigator/orders/*/order.md` - 当前进展: 有 -- 固定节: 审阅要点 (任务目标, 需要决定, 明确不做, 粒度依据); 工单概况 (背景原因, 完成标志, 基准提交, 回执路径); 执行守则; 前提假设; 工作范围 (要做的事, 不做的事); 验收判据; 相关材料 +- 固定节: 审阅要点 (任务目标, 需要决定, 明确不做, 粒度依据); 工单概况 (背景原因, 完成标志, 基准提交, 回执路径); 执行守则; 工作假设; 工作范围 (要做的事, 不做的事); 验收判据; 相关材料 ## 工单回执 - 种类: `receipt` - 路径: `.navigator/orders/*/receipt.md` - 当前进展: 有 -- 固定节 (结构 1): 回执概况 (执行状态, 基准提交, 完成时间); 前提核对; 模块划分 (新增模块, 改动模块, 入口改动); 判据自检; 改动清单; 测试记录 (测试命令, 测试结果, 测试改动, 外部影响, 取证记录); 运行方式 (启动命令, 验证步骤); 偏差记录 (实现决定, 需要操作, 发现风险, 待定判据, 受阻详情) -- 固定节 (结构 2): 回执概况 (执行状态, 基准提交, 完成时间); 前提核对; 现有能力; 候选方案; 需求核对 (表格, 列为 需求, 结论, 依据, "结论" 只能填 能/不能); 能力核实 (表格, 列为 能力, 仓库, 版本, 路径, 行号, 说明); 选型结论; 一致检查; 改动清单; 偏差记录 (实现决定, 需要操作, 发现风险, 受阻详情) +- 固定节 (结构 1): 回执概况 (执行状态, 基准提交, 完成时间); 假设核对; 事实修正 (表格, 列为 工单原文, 实际情况, 证据位置, 处理办法); 模块划分 (新增模块, 改动模块, 入口改动); 判据自检; 改动清单; 测试记录 (测试命令, 测试结果, 测试改动, 外部影响, 取证记录); 运行方式 (启动命令, 验证步骤); 偏差记录 (实现决定, 需要操作, 发现风险, 待定判据, 受阻详情) +- 固定节 (结构 2): 回执概况 (执行状态, 基准提交, 完成时间); 假设核对; 现有能力; 候选方案; 需求核对 (表格, 列为 需求, 结论, 依据, "结论" 只能填 能/不能); 能力核实 (表格, 列为 能力, 仓库, 版本, 路径, 行号, 说明); 选型结论; 一致检查; 改动清单; 偏差记录 (实现决定, 需要操作, 发现风险, 受阻详情) ## 验收记录 - 种类: `review` - 路径: `.navigator/orders/*/review*.md` - 当前进展: 有 -- 固定节: 验收结论 (总体结论, 判据通过, 回执来源, 验收轮次, 验收时间); 判据核对 (表格, 列为 判据, 结论, 证据, "结论" 只能填 通过/不通过/未验证); 专项检查 (回执一致, 接线核查, 范围核查, 测试改动, 测试运行, 规范核查); 人工验收 (验收步骤, 用户结论 [骨架预填: 待用户确认]) +- 固定节: 验收结论 (总体结论, 判据通过, 回执来源, 验收轮次, 验收时间); 判据核对 (表格, 列为 判据, 结论, 证据, "结论" 只能填 通过/不通过/未验证); 专项检查 (回执一致, 接线核查, 范围核查, 测试改动, 测试运行, 修正核对, 规范核查); 人工验收 (验收步骤, 用户结论 [骨架预填: 待用户确认]) ## 项目简报 diff --git a/plugins/waypoint/skills/project-navigator/references/order-loop.md b/plugins/waypoint/skills/project-navigator/references/order-loop.md index 97288d1..980b034 100644 --- a/plugins/waypoint/skills/project-navigator/references/order-loop.md +++ b/plugins/waypoint/skills/project-navigator/references/order-loop.md @@ -54,12 +54,19 @@ | 基准提交 | 骨架已预填当前提交的完整哈希, 原样保留; 写好工单后仓库又有新提交时, 改为新的当前提交 (`git rev-parse HEAD`), 审阅与发布都会核对 | | 回执路径 | 同一文件夹中的 `receipt.md` | | 执行守则 | 本工单特有的约束, 例如 "不改 `src/api/` 的公共接口"; 手册与项目规范中已有的规则不重复. 要留存抓包原文, 复现脚本等证据时, 写明放在本工单文件夹的 `artifacts/` 下 | -| 前提假设 | 执行子代理动手前要核对的事实, 每条都能验证 | +| 工作假设 | 你对细节的判断: 数据格式, 字段含义, 已有的接口与文件, 实现途径. 每条写明依据 (查证过的写出处, 推测的写 "推测"). 与实际不符时执行子代理以实际为准, 不算受阻 | | 工作范围 | 要做的事与不做的事 | | 验收判据 | 编号列出, 每条只验证一件事, 写出验证方式: 命令, 操作步骤或文件位置; 要用 MCP 工具核对的写 "取证工具: <工具名>, 按回执取证记录核对". 实现与修复工单的第一条是骨架预填的代码检查判据, 原样保留 | | 相关材料 | 简报, 决策, 主线流程中相关条目的路径 | -执行子代理工作期间不能向用户提问, 所以工单要写到不用追问就能动手: 前提假设可以核对, 判据可以验证, 需要用户决定的事在审阅时就问清. +执行子代理工作期间不能向用户提问, 所以工单要写到不用追问就能动手: 判据可以验证, 需要用户决定的事在审阅时就问清. + +工单的内容分两层, 写的时候分清: + +- 硬约束: "审阅要点" 的任务目标, 需要决定, 明确不做, 以及 "工作范围". 用户认可的是这些, 执行子代理不能改; 做不到时受阻. +- 工作假设: 其余的细节. 执行子代理发现与实际不符时以实际为准, 在回执 "事实修正" 中逐条记录, 验收子代理核对每条修正的证据与是否越界. 逆向, 对接外部系统这类做了才知道细节的任务, 靠这一层避免反复往返. + +所以不能让步的要求写进硬约束, 不要埋在 "执行守则" 里; 判据写要达到的结果, 少写达到结果的途径. 途径写得越死, 修正越多. 工单中的具体事实只写查证过的: 文件路径, 接口名, 数据中的编号或实例, 引用的记录中的结论, 外部资源的发布形式与许可. 凭记忆写下的事实不成立时, 执行子代理要做到一半才发现. 判据尽量写要满足的特征 (例如 "任选一条带附件的记录"), 只在实例本身是要求时才点名实例. 发布前核对会逐条核对这些事实, 但核对子代理只报告, 改工单仍由你完成. @@ -84,12 +91,12 @@ - 回执是否写入, 执行状态是什么, 以 `status` 输出的 "工单状态" 一行为准. - 执行状态为受阻: 读回执, 运行 `order set blocked`, 回复 "受阻处理", 按受阻类型选择选项组: -| 受阻类型 | 选项组 | -| ---------------------------------------- | ------- | -| 规格问题: 对账不符, 前提不符, 歧义, 矛盾 | 第 1 组 | -| 范围过大 | 第 2 组 | -| 需要用户操作 | 第 3 组 | -| 需要用户决定, 或执行子代理提出问题 | 第 4 组 | +| 受阻类型 | 选项组 | +| ------------------------------------------ | ------- | +| 规格问题: 对账不符, 目标不可达, 歧义, 矛盾 | 第 1 组 | +| 范围过大 | 第 2 组 | +| 需要用户操作 | 第 3 组 | +| 需要用户决定, 或执行子代理提出问题 | 第 4 组 | - 用户完成所需操作, 或回答了问题而工单内容不用改: 运行 `order set issued` (内容没有改动时不需要重新审阅), 用 SendMessage 让原执行子代理继续, 说明用户做了什么或回答了什么; 找不到原子代理时运行 `exec-brief` 重新派出. 然后回复 "工单执行". - 需要修改工单: 改好工单文件后回复 "工单审阅"; 用户选 A 后发布并重新派出执行子代理. 旧回执在发布时自动改名归档. @@ -101,12 +108,13 @@ 1. 运行 `order set reviewing`. 2. 运行 `review-brief`, 把输出原样作为提示词派 `waypoint:navigator-reviewer`. 回执 "测试记录" 中列为 "外部影响" 的命令, 验收子代理不运行, 按回执中的输出判断. 子代理在后台运行, 本轮要先结束时回复 "工单验收": "验收方式" 写 "后台验收子代理", "核对重点" 只列执行子代理提请核对的事项, 没有时写 "无"; 不写其它说明. 3. 运行 `template review`, 用子代理交回的结果写 `review.md`. "判据核对" 表的结论照抄子代理的结论, 只能是 通过, 不通过, 未验证 之一. "用户结论" 保留骨架预填的 "待用户确认", 用户选择之后再改写. "人工验收" 写出用户可以亲手验证的步骤, 命令只取自回执; 没有时写 "无". -4. 回复 "验收报告", 按判据结论选择选项组 (`reply review --option <组号>` 会核对). 建议只写在 "处理建议" 一节: "建议选项" 写选项字母, "主要依据" 写一句话; 选项块之前不另加说明: +4. 回执 "事实修正" 表不为空时, `review.md` 与 "验收报告" 的 "修正核对" 逐条写出每项修正: 工单原来怎么写, 实际是什么, 是否成立. 用户靠这一项知道做出来的东西与审阅时的工单有哪些不同, 不能只写 "均成立". 修正成立的细节, 下一张工单直接按修正后的事实写. +5. 回复 "验收报告", 按判据结论选择选项组 (`reply review --option <组号>` 会核对). 建议只写在 "处理建议" 一节: "建议选项" 写选项字母, "主要依据" 写一句话; 选项块之前不另加说明: - 全部通过: 第 1 组. 用户选 A 或 B: 在 `review.md` 写 "用户结论", 运行 `order set accepted`, 按输出调用 `waypoint:commit-message` 提交 (B 同时推送). 用户选 C: 把用户描述的现象写进 `review.md`, 运行 `order set rejected`, 按输出用第 2 组再回复 "验收报告". - 有判据不通过: 运行 `order set rejected`, 按输出使用第 2 组. - 没有不通过, 但有未验证的判据: 第 3 组. 其中有回执列为待定的判据时 (证据以 "待定:" 开头), "处理建议" 的 "主要依据" 写明每条待定判据的实际情况与可选的处理办法: 用户选 A 表示按现状接受, 选 B 表示发补正工单. 用户选 A (接受现状): 在 `review.md` 写 "用户结论", 运行 `order set accepted --accept-unverified`, 按输出提交; 未验证的判据用 `risk add` 各登记一条风险. 用户选 B: 运行 `order set rejected`, 按输出新建补正工单. - 选型工单: 第 4 组, 见 `ref selection`. -5. 第 2 组用户选 A: 按 `order set rejected` 输出的命令新建补正工单, 判据写明要补正的问题. 实现与修复工单补正时先判断原因: 工单太大就拆小, 否则发修复工单 (`--kind fix`); 运行检查与分析工单补正时重发同类工单. +6. 第 2 组用户选 A: 按 `order set rejected` 输出的命令新建补正工单, 判据写明要补正的问题. 实现与修复工单补正时先判断原因: 工单太大就拆小, 否则发修复工单 (`--kind fix`); 运行检查与分析工单补正时重发同类工单. ### 提交 diff --git a/plugins/waypoint/skills/project-navigator/references/replies.md b/plugins/waypoint/skills/project-navigator/references/replies.md index 794c104..9e8c74b 100644 --- a/plugins/waypoint/skills/project-navigator/references/replies.md +++ b/plugins/waypoint/skills/project-navigator/references/replies.md @@ -98,7 +98,7 @@ ## 验收报告 - 编号: `review` -- 各节: 验收结论 (总体结论, 判据通过, 回执来源); 判据核对; 专项检查 (回执一致, 接线核查, 范围核查, 测试改动, 测试运行, 规范核查); 人工验收; 处理建议 (建议选项, 主要依据) +- 各节: 验收结论 (总体结论, 判据通过, 回执来源); 判据核对; 专项检查 (回执一致, 接线核查, 范围核查, 测试改动, 测试运行, 修正核对, 规范核查); 人工验收; 处理建议 (建议选项, 主要依据) - 选项: - 第 1 组 [验收结论]: A. 通过验收, 提交改动. B. 通过验收, 提交推送. C. 发现问题, 描述现象. - 第 2 组 [如何处理]: A. 补正工单, 立即发布. B. 暂不修复, 说明原因. diff --git a/plugins/waypoint/skills/project-navigator/runtime/lib/briefs.mjs b/plugins/waypoint/skills/project-navigator/runtime/lib/briefs.mjs index 3dfa0a8..acfcc05 100644 --- a/plugins/waypoint/skills/project-navigator/runtime/lib/briefs.mjs +++ b/plugins/waypoint/skills/project-navigator/runtime/lib/briefs.mjs @@ -49,6 +49,19 @@ export const PAUSED_HANDBACK = "执行状态: 等待操作"; */ export const PENDING_CRITERIA_KEY = "待定判据"; +/** + * 工单中写编排会话对细节的判断的节, 与规格 files.order 一致. 这一节与实际不符时, + * 执行子代理以实际为准, 不算受阻. + * @type {string} + */ +export const ASSUMPTIONS_SECTION = "工作假设"; + +/** + * 回执中逐条记录事实修正的节, 与规格 files.receipt 一致. + * @type {string} + */ +export const CORRECTIONS_SECTION = "事实修正"; + /** * 问题域调研提示词的固定框架; 编排会话只在其后填写调研问题. * @type {string} @@ -107,7 +120,7 @@ export function buildPrecheckBrief({ projectRoot, order }) { "", "## 核对要求", "", - '1. 前提假设: 逐条核对工单 "前提假设", 读代码, 配置与数据核实.', + `1. 工作假设: 逐条核对工单 "${ASSUMPTIONS_SECTION}", 读代码, 配置与数据核实.`, '2. 具体事实: 找出 "执行守则", "工作范围" 与 "验收判据" 中的每个具体事实, 逐个核对: 文件与目录路径, 函数与接口名, 命令, 数据中的编号或实例, 引用的记录中的结论, 外部资源的地址, 发布形式与许可. 判据点名某个实例时, 核对这个实例存在, 并且带有判据要求的特征.', '3. 判据可验证: 逐条看 "验证方式" 能否照做: 命令是否存在, 需要的数据, 工具与环境是否具备.', '4. 遗漏的决定: 列出执行中必须由用户决定, 而工单 "需要决定" 没有写的事, 例如许可条款的解释, 要改动仓库之外的文件, 几种做法的取舍.', @@ -210,13 +223,14 @@ export function buildReviewBrief({ '6. 测试运行: 运行 "代码检查" 中的命令, 以及回执 "测试记录" 中 "测试命令" 列出的命令, 原样记录结果; "外部影响" 中列出的命令 (需要真实账号, 会产生费用或外部副作用) 不运行, 按回执中的输出判断, 证据写明 "依据回执输出".', `7. 取证核对: 判据要用 MCP 工具核对时, 按回执 "取证记录" 给出的工具与位置查看, 只做查询类的只读调用, 不发请求, 不清空或修改记录. 证据写工具名, 参数与返回内容摘录; 工具不可用或按位置找不到记录时, 该判据为 ${unverified}.`, '8. 证据文件: "证据文件目录" 存在时, 其中是执行子代理留下的产物, 例如抓包原文与复现脚本. 回执或判据引用这些文件时, 按路径读取核对, 证据写文件路径与行号. 目录不存在时跳过本项.', - `9. 规范核查: 对照 ${ENGINEERING_RULES_FILE} 检查文档注释, 函数体内注释, 模块边界 (回执 "模块划分" 是否与实际改动一致, 新功能是否迫使多个已有模块改动内部实现), 单一数据源, 魔法值.`, - `10. 选型工单另查: 核对范围只是工单列出的每条需求, 判据核对表中每条需求单独一行. 对照回执 "${REQUIREMENT_SECTION}" 表: 依据是源码的, 运行\`${EVIDENCE_COMMAND}\` 从原仓库按版本取回 "${EVIDENCE_SECTION}" 表引用的源码行, 判断是否支持该需求的结论; 依据是测试的, 运行回执写明的测试命令, 按输出判断. 依据支持结论的为 ${pass}, 不支持的为 ${fail}, 取不到源码或测试无法运行的为 ${unverified}; 需求在表中没有对应行的也为 ${unverified}. 回执其它内容不核对, 不用其它方式获取源码.`, + `9. 修正核对: 回执 "${CORRECTIONS_SECTION}" 表中的每一行, 是执行子代理发现工单写的细节与实际不符, 按实际做了. 逐行核对: "实际情况" 有没有证据支持; "处理办法" 有没有改变工单的任务目标, 超出 "工作范围", 做了 "明确不做" 的事, 或替用户做了 "需要决定" 的事. 两项都没有问题的修正成立: 判据引用了被修正的细节时, 按修正后的事实判断. 证据不支持或越界的修正不成立: 相关判据为 ${fail}. 表为空时写 "无修正".`, + `10. 规范核查: 对照 ${ENGINEERING_RULES_FILE} 检查文档注释, 函数体内注释, 模块边界 (回执 "模块划分" 是否与实际改动一致, 新功能是否迫使多个已有模块改动内部实现), 单一数据源, 魔法值.`, + `11. 选型工单另查: 核对范围只是工单列出的每条需求, 判据核对表中每条需求单独一行. 对照回执 "${REQUIREMENT_SECTION}" 表: 依据是源码的, 运行\`${EVIDENCE_COMMAND}\` 从原仓库按版本取回 "${EVIDENCE_SECTION}" 表引用的源码行, 判断是否支持该需求的结论; 依据是测试的, 运行回执写明的测试命令, 按输出判断. 依据支持结论的为 ${pass}, 不支持的为 ${fail}, 取不到源码或测试无法运行的为 ${unverified}; 需求在表中没有对应行的也为 ${unverified}. 回执其它内容不核对, 不用其它方式获取源码.`, "", "## 交回格式", "", `1. 判据核对: 表格, 列为 ${criteriaTable.columns.join(", ")}.`, - "2. 专项检查: 依次写 回执一致, 接线核查, 范围核查, 测试改动, 测试运行, 规范核查, 每项一行结论加证据.", + "2. 专项检查: 依次写 回执一致, 接线核查, 范围核查, 测试改动, 测试运行, 修正核对, 规范核查, 每项一行结论加证据; 修正核对逐条写每项修正是否成立.", '3. 人工验收: 需要用户亲手运行才能确认的判据, 写成逐步操作, 命令原样取自回执; 回执中没有这样的命令时写 "无".', ].join("\n"); } diff --git a/plugins/waypoint/skills/project-navigator/spec/templates.json b/plugins/waypoint/skills/project-navigator/spec/templates.json index 0c16edc..1ca6de4 100644 --- a/plugins/waypoint/skills/project-navigator/spec/templates.json +++ b/plugins/waypoint/skills/project-navigator/spec/templates.json @@ -349,6 +349,7 @@ "范围核查", "测试改动", "测试运行", + "修正核对", "规范核查" ] }, @@ -562,7 +563,7 @@ "keys": ["背景原因", "完成标志", "基准提交", "回执路径"] }, { "title": "执行守则" }, - { "title": "前提假设" }, + { "title": "工作假设" }, { "title": "工作范围", "keys": ["要做的事", "不做的事"] }, { "title": "验收判据" }, { "title": "相关材料" } @@ -578,7 +579,14 @@ "title": "回执概况", "keys": ["执行状态", "基准提交", "完成时间"] }, - { "title": "前提核对" }, + { "title": "假设核对" }, + { + "title": "事实修正", + "table": { + "columns": ["工单原文", "实际情况", "证据位置", "处理办法"], + "allowEmpty": true + } + }, { "title": "模块划分", "keys": ["新增模块", "改动模块", "入口改动"] }, { "title": "判据自检" }, { "title": "改动清单" }, @@ -597,7 +605,7 @@ "title": "回执概况", "keys": ["执行状态", "基准提交", "完成时间"] }, - { "title": "前提核对" }, + { "title": "假设核对" }, { "title": "现有能力" }, { "title": "候选方案" }, { @@ -648,6 +656,7 @@ "范围核查", "测试改动", "测试运行", + "修正核对", "规范核查" ] }, diff --git a/scripts/navigator-docs/executor-guide.md b/scripts/navigator-docs/executor-guide.md index 9a155a6..b16654a 100644 --- a/scripts/navigator-docs/executor-guide.md +++ b/scripts/navigator-docs/executor-guide.md @@ -13,7 +13,7 @@ ## 执行流程 1. 对账: 运行 `git status` 与 `git log -1`. 当前提交应等于工单概况中的 "基准提交", 工作区不应有与本工单无关的改动. 不一致时不动手, 写回执, 执行状态写 "受阻", 受阻类型写 "对账不符". -2. 核对前提: 逐条检查工单 "前提假设" 是否成立, 读代码与配置核实, 不凭记忆. 不成立时以受阻结束, 受阻类型写 "前提不符"; 只影响个别判据时按下方 "待定判据" 处理. +2. 核对假设: 逐条检查工单 "工作假设" 是否成立, 读代码与配置核实, 不凭记忆, 结果写进回执 "假设核对". 不成立的假设以实际为准, 按下方 "事实修正" 处理, 不因此停下. 3. 做计划: 先定模块划分, 写法见下方 "模块划分"; 再列出完成每条验收判据的步骤与验证方式. 计划不需要用户确认, 但要写进回执的 "模块划分" 与 "判据自检". 4. 实施: 只做工单 "工作范围" 中要做的事; 遵守工单 "执行守则" 与项目规范 `.claude/rules/engineering.md`. 5. 自检: 逐条核对验收判据, 运行代码检查与测试. 需要真实账号, 会产生费用或外部副作用的测试不要运行, 把命令写进回执 "测试记录" 的 "外部影响", 由用户决定. @@ -42,24 +42,42 @@ - 工单要求接线 Claude Code hook 时, 可以改 `.claude/settings.json` 的 `hooks` 字段与 `.claude/` 下项目自己的文件 (例如 `.claude/hooks/` 中的脚本). - 不改 `.claude/settings.json` 的 `permissions` 字段中本技能的放行规则 (以 `project-navigator` 或 `.navigator/` 开头的规则), 不改 `.claude/rules/engineering.md`: 前者由 init 管理, 后者由编排会话的 `standards` 命令写入. 需要调整时写进回执的 "需要操作". +## 事实修正 + +工单由编排会话在动手之前写成, 其中的细节只是当时的判断. 逆向, 对接外部系统这类任务, 很多事实做了才知道. 工单的内容因此分两层: + +- 硬约束: "审阅要点" 的任务目标, 需要决定, 明确不做, 以及 "工作范围". 这些是用户认可过的, 你不能改. +- 工作假设: 其余的细节, 包括 "工作假设" 一节, 以及 "执行守则" 与 "验收判据" 中写到的数据格式, 字段含义, 路径, 接口名, 具体实例与实现途径. + +工作假设与实际不符时, 以实际为准继续做, 不算受阻: + +- 先取得证据 (文件路径与行号, 命令输出, 取证记录, 或 `artifacts/` 下的脚本), 再按实际情况实现. 不为了符合工单而做出与事实不符的东西. +- 在回执 "事实修正" 表中每项修正写一行: "工单原文" 摘录原句并写明所在的节; "实际情况" 写查到的事实; "证据位置" 写能复核的位置; "处理办法" 写你改成了怎么做. 没有修正时只留表头. +- 判据引用了被修正的细节时, 按修正后的事实自检, "判据自检" 中写明 "按事实修正第 N 行". +- 修正之后任务目标仍要达成, 改动仍在工作范围之内. + +以下情况不属于事实修正, 仍按受阻处理: 按实际情况任务目标达不成; 要做 "明确不做" 的事或超出 "工作范围"; 有几种做法而取舍会影响用户 (例如许可, 费用, 对外行为); 工单 "需要决定" 中写的事. 拿不准时按受阻处理. + ## 受阻情形 -遇到以下情况立即停下, 写回执, 执行状态写 "受阻", 不自行变通. 两种情况例外, 先看下方 "待定判据" 与 "等待操作": +遇到以下情况立即停下, 写回执, 执行状态写 "受阻", 不自行变通. 细节与实际不符不在其列, 见上方 "事实修正"; 另有两种例外, 见下方 "待定判据" 与 "等待操作": -- 对账不符, 或工单前提不成立. -- 规格有歧义, 或判据之间互相矛盾. +- 对账不符. +- 按实际情况, 任务目标达不成. +- 规格有歧义而几种理解会做出不同的结果, 或判据之间互相矛盾. - 需要超出工作范围的改动, 例如改其它模块的公共接口. - 需要用户操作或决定, 例如提供账号, 密钥, 安装软件, 或在几种做法中选一种. - 按选型守则找不到满足需求的方案. -回执 "偏差记录" 的 "受阻详情" 写受阻类型 (对账不符, 前提不符, 规格问题, 范围过大, 需要用户操作, 需要用户决定), 规格原文, 实际情况与证据位置. 用户处理后, 编排会话可能让你接着做: 收到继续的消息时, 先运行 `git status` 核对工作区, 再从受阻处继续, 最后重写回执. +回执 "偏差记录" 的 "受阻详情" 写受阻类型 (对账不符, 目标不可达, 规格问题, 范围过大, 需要用户操作, 需要用户决定), 规格原文, 实际情况与证据位置. 用户处理后, 编排会话可能让你接着做: 收到继续的消息时, 先运行 `git status` 核对工作区, 再从受阻处继续, 最后重写回执. ## 待定判据 工单的其余部分不受影响, 只有个别判据照原文做不到时, 不以受阻结束: 把其余工作做完, 这几条判据留作待定, 由用户在验收时决定. 这样用户只决定一次, 不用整张工单往返一轮. -- 适用情形: 判据点名的实例不存在或不带所要求的特征; 判据依赖的事实不成立; 判据要用户在两种说法中选一种, 而选哪种都不改变已经完成的工作. -- 不适用: 用户的决定会改变其余部分的做法 (例如随包带哪种格式的文件); 前提不成立导致主要工作无法进行; 要改动工作范围之外的文件. 这些情况仍按受阻处理. +- 与事实修正的界线: 判据换一个符合事实的细节就能满足时 (例如点名的实例不存在, 另一个实例带有同样的特征), 属于事实修正, 照做并记录. 判据要求的东西按事实根本做不出来, 或要用户在两种说法中选一种时, 才留作待定. +- 适用情形: 判据要求的特征在实际数据中不存在; 判据要用户在两种说法中选一种, 而选哪种都不改变已经完成的工作. +- 不适用: 用户的决定会改变其余部分的做法 (例如随包带哪种格式的文件); 任务目标达不成; 要改动工作范围之外的文件. 这些情况仍按受阻处理. - 写法: 回执 "执行状态" 写 "完成"; "偏差记录" 的 "待定判据" 逐条写判据编号, 规格原文, 实际情况与证据位置, 以及可选的处理办法 (例如 "改用实例 X 核对" 或 "以单元测试代替"). "判据自检" 中这几条写 "待定". 没有待定判据时写 "无". - 不替用户选: 不按自己选的办法改写判据后写 "通过". diff --git a/tests/project-navigator/file-checks.test.mjs b/tests/project-navigator/file-checks.test.mjs index 5f02266..6586830 100644 --- a/tests/project-navigator/file-checks.test.mjs +++ b/tests/project-navigator/file-checks.test.mjs @@ -129,7 +129,7 @@ test("文件: 回执的填写要求写明键值节每个键只占一行, 多行 }).join("\n"); assert.ok(guide.includes(KEY_SECTION_RULE)); assert.match(guide, /"测试记录"/u); - assert.match(guide, /表格与多行内容写进没有键名的节 \("前提核对"/u); + assert.match(guide, /表格与多行内容写进没有键名的节 \("假设核对"/u); assert.match(guide, /project-navigator check <文件路径>/u); }); diff --git a/tests/project-navigator/flow.test.mjs b/tests/project-navigator/flow.test.mjs index 0423b48..abaeef8 100644 --- a/tests/project-navigator/flow.test.mjs +++ b/tests/project-navigator/flow.test.mjs @@ -357,10 +357,14 @@ test("工单往返: 审阅发布, 执行子代理写回执, 验收通过, 输出 project(["reply", "paused"]).stdout, /· 工单 0001 \(待你操作\)\n[\s\S]*- 完成之后: 回复 "操作完成"/u, ); + const receiptSkeleton = project(["template", "receipt"]).stdout; + assert.match(receiptSkeleton, /- 待定判据: <待填写>/u); assert.match( - project(["template", "receipt"]).stdout, - /- 待定判据: <待填写>/u, + receiptSkeleton, + /## 事实修正\n\n\| 工单原文 \| 实际情况 \| 证据位置 \| 处理办法 \|/u, ); + assert.match(project(["template", "order"]).stdout, /## 工作假设\n/u); + assert.match(project(["reply", "review"]).stdout, /- 修正核对: /u); assert.match( project(["model", "set", "reviewer", "inherit"]).stdout, /验收 跟随会话/u, diff --git a/tests/project-navigator/workflow.test.mjs b/tests/project-navigator/workflow.test.mjs index 6e68138..b030823 100644 --- a/tests/project-navigator/workflow.test.mjs +++ b/tests/project-navigator/workflow.test.mjs @@ -388,6 +388,11 @@ test("委派: 验收提示词写明代码检查, 不重跑外部影响的测试, assert.match(brief, /"外部影响" 中列出的命令.+不运行/u); assert.match(brief, /只读调用/u); assert.match(brief, /从程序入口追到本工单的新代码/u); + assert.match( + brief, + /修正核对: 回执 "事实修正" 表中的每一行.+越界的修正不成立: 相关判据为 不通过/u, + ); + assert.match(brief, /专项检查: 依次写 .+测试运行, 修正核对, 规范核查/u); const runcheck = buildReviewBrief({ projectRoot: "/项目", order: { ...order, kind: "runcheck" }, @@ -511,6 +516,7 @@ test("委派: 核对提示词写明工单路径与三种结论; 执行提示词 assert.match(precheck, /^# 发布前核对 0001/u); assert.match(precheck, /order\.md/u); assert.match(precheck, /成立, 不成立, 无法核对 之一/u); + assert.match(precheck, /逐条核对工单 "工作假设"/u); assert.match( buildExecutorBrief({ projectRoot: "/项目", order }), /第一行写 "执行状态: 等待操作"/u,