paseo-req-kit 1.14.0-beta.4 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/bin/req.mjs +6 -0
  3. package/contracts/notifier-event.md +1 -1
  4. package/contracts/spec.md +1 -0
  5. package/contracts/state.md +3 -1
  6. package/contracts/usage-record.md +16 -2
  7. package/docs/guide//344/275/277/347/224/250/350/200/205/346/214/207/345/215/227.md +3 -1
  8. package/docs/guide//351/241/271/347/233/256/345/256/232/345/210/266/344/270/216/350/277/220/350/241/214/350/247/204/345/210/231.md +17 -1
  9. package/engine/prompts/00-shared-context.md +3 -2
  10. package/engine/src/activity.ts +21 -0
  11. package/engine/src/api.ts +30 -5
  12. package/engine/src/code-review.ts +3 -0
  13. package/engine/src/config-view.ts +10 -0
  14. package/engine/src/config.ts +27 -0
  15. package/engine/src/danger-guard.ts +180 -0
  16. package/engine/src/features.ts +1 -1
  17. package/engine/src/messages.ts +29 -0
  18. package/engine/src/outcomes.ts +145 -0
  19. package/engine/src/paseo-runtime.ts +9 -1
  20. package/engine/src/pipeline.ts +135 -6
  21. package/engine/src/records.ts +71 -0
  22. package/engine/src/reply.ts +30 -11
  23. package/engine/src/review.ts +15 -1
  24. package/engine/src/runtime.ts +2 -0
  25. package/engine/src/secret-scan.ts +177 -0
  26. package/engine/src/state.ts +30 -0
  27. package/engine/src/stats.ts +143 -9
  28. package/engine/src/watchdog.ts +38 -4
  29. package/package.json +1 -1
  30. package/paseo-plugin/client/stats.tsx +15 -0
  31. package/paseo-plugin/package.json +1 -1
  32. package/paseo-plugin/shared/contracts.ts +7 -0
  33. package/site-dist/404.html +2 -2
  34. package/site-dist/assets/{app.Cp7WwPWE.js → app.VQ-QxRPH.js} +1 -1
  35. package/site-dist/assets/changelog.md.CIKYJXpF.js +1 -0
  36. package/site-dist/assets/{changelog.md.Zi-_3Rjh.lean.js → changelog.md.CIKYJXpF.lean.js} +1 -1
  37. package/site-dist/assets/chunks/@localSearchIndexroot.h7oQE_np.js +1 -0
  38. package/site-dist/assets/chunks/{VPLocalSearchBox.CMTXQK-Q.js → VPLocalSearchBox.CT4Vlj76.js} +1 -1
  39. package/site-dist/assets/chunks/{theme.DvVUfKr3.js → theme.B_UmHHou.js} +2 -2
  40. package/site-dist/assets/{guide_getting-started.md.D8XlIQOg.js → guide_getting-started.md.CZM53rO_.js} +1 -1
  41. package/site-dist/assets/{guide_project.md.Csi5wiyt.js → guide_project.md.DIjDRoAq.js} +1 -1
  42. package/site-dist/assets/{guide_project.md.Csi5wiyt.lean.js → guide_project.md.DIjDRoAq.lean.js} +1 -1
  43. package/site-dist/assets/{guide_user.md.B4N9ywmr.js → guide_user.md.UV0WxdJa.js} +1 -1
  44. package/site-dist/assets/{guide_user.md.B4N9ywmr.lean.js → guide_user.md.UV0WxdJa.lean.js} +1 -1
  45. package/site-dist/assets/{reference_contracts_notifier-event.md.CCfrkm_A.js → reference_contracts_notifier-event.md.B9WqeZdO.js} +1 -1
  46. package/site-dist/assets/{reference_contracts_notifier-event.md.CCfrkm_A.lean.js → reference_contracts_notifier-event.md.B9WqeZdO.lean.js} +1 -1
  47. package/site-dist/assets/{reference_contracts_spec.md.BwwS0L_j.js → reference_contracts_spec.md.Dh5XczZL.js} +2 -2
  48. package/site-dist/assets/{reference_contracts_spec.md.BwwS0L_j.lean.js → reference_contracts_spec.md.Dh5XczZL.lean.js} +2 -2
  49. package/site-dist/assets/reference_contracts_state.md.STlqkPPS.js +1 -0
  50. package/site-dist/assets/{reference_contracts_usage-record.md.D5krNLW7.lean.js → reference_contracts_usage-record.md.MjVps4CA.js} +2 -2
  51. package/site-dist/assets/{reference_contracts_usage-record.md.D5krNLW7.js → reference_contracts_usage-record.md.MjVps4CA.lean.js} +2 -2
  52. package/site-dist/changelog.html +5 -5
  53. package/site-dist/guide/getting-started.html +5 -5
  54. package/site-dist/guide/how-it-works.html +4 -4
  55. package/site-dist/guide/index.html +4 -4
  56. package/site-dist/guide/install.html +4 -4
  57. package/site-dist/guide/maintainer.html +4 -4
  58. package/site-dist/guide/phases.html +4 -4
  59. package/site-dist/guide/project.html +6 -6
  60. package/site-dist/guide/user.html +5 -5
  61. package/site-dist/hashmap.json +1 -1
  62. package/site-dist/index.html +4 -4
  63. package/site-dist/reference/adr/0001-step-agents-under-origin-chat.html +4 -4
  64. package/site-dist/reference/adr/0002-no-directory-switch-in-chat.html +4 -4
  65. package/site-dist/reference/adr/0003-script-engine-not-hub.html +4 -4
  66. package/site-dist/reference/adr/0004-result-files.html +4 -4
  67. package/site-dist/reference/adr/0005-no-default-branch-local-commits-only.html +4 -4
  68. package/site-dist/reference/adr/0006-skill-install-targets.html +4 -4
  69. package/site-dist/reference/adr/0007-own-interview-skill.html +4 -4
  70. package/site-dist/reference/adr/0008-entries-do-not-call-entries.html +4 -4
  71. package/site-dist/reference/adr/0009-versioned-install-layout.html +4 -4
  72. package/site-dist/reference/adr/0010-generated-feature-overview.html +4 -4
  73. package/site-dist/reference/adr/0011-resume-after-completion.html +4 -4
  74. package/site-dist/reference/adr/0012-review-panel.html +4 -4
  75. package/site-dist/reference/adr/0013-no-release-tooling.html +4 -4
  76. package/site-dist/reference/adr/0014-notifier-slot.html +4 -4
  77. package/site-dist/reference/adr/0015-incremental-continue.html +4 -4
  78. package/site-dist/reference/adr/0016-upgrade-from-tags.html +4 -4
  79. package/site-dist/reference/adr/0017-use-paseo-capabilities.html +4 -4
  80. package/site-dist/reference/adr/0018-own-worktree-option.html +4 -4
  81. package/site-dist/reference/adr/0019-parallel-orchestration.html +4 -4
  82. package/site-dist/reference/adr/0020-scheduling-through-the-chat.html +4 -4
  83. package/site-dist/reference/adr/0021-npm-version-manager.html +4 -4
  84. package/site-dist/reference/adr/0022-develop-and-verify-phases.html +4 -4
  85. package/site-dist/reference/adr/0023-types-gate-slices.html +4 -4
  86. package/site-dist/reference/adr/0024-confirm-early-review-axes.html +4 -4
  87. package/site-dist/reference/adr/0025-joint-requirements.html +4 -4
  88. package/site-dist/reference/adr/0026-machine-records-and-api.html +4 -4
  89. package/site-dist/reference/adr/0027-paseo-plugin.html +4 -4
  90. package/site-dist/reference/adr/0028-external-integrations.html +4 -4
  91. package/site-dist/reference/adr/0029-requirements-from-cards.html +4 -4
  92. package/site-dist/reference/adr/0030-card-intake-process.html +4 -4
  93. package/site-dist/reference/adr/0031-fewer-interventions.html +4 -4
  94. package/site-dist/reference/adr/0032-npm-only-install.html +4 -4
  95. package/site-dist/reference/adr/0033-prototype-review-and-ui-check.html +4 -4
  96. package/site-dist/reference/adr/index.html +4 -4
  97. package/site-dist/reference/commands.html +4 -4
  98. package/site-dist/reference/config.html +4 -4
  99. package/site-dist/reference/contracts/cli-json.html +4 -4
  100. package/site-dist/reference/contracts/feature-files.html +4 -4
  101. package/site-dist/reference/contracts/index.html +4 -4
  102. package/site-dist/reference/contracts/notifier-event.html +6 -6
  103. package/site-dist/reference/contracts/result-file.html +4 -4
  104. package/site-dist/reference/contracts/spec.html +6 -6
  105. package/site-dist/reference/contracts/state.html +5 -5
  106. package/site-dist/reference/contracts/usage-record.html +6 -6
  107. package/site-dist/reference/contracts/verify.html +4 -4
  108. package/site-dist/reference/scope.html +4 -4
  109. package/skills/req/SKILL.md +1 -0
  110. package/skills/req/playbooks/incident.md +1 -1
  111. package/skills/spec-writing/SKILL.md +2 -1
  112. package/site-dist/assets/changelog.md.Zi-_3Rjh.js +0 -1
  113. package/site-dist/assets/chunks/@localSearchIndexroot.COxp5Rrc.js +0 -1
  114. package/site-dist/assets/reference_contracts_state.md.EEBd_l2P.js +0 -1
  115. /package/site-dist/assets/{guide_getting-started.md.D8XlIQOg.lean.js → guide_getting-started.md.CZM53rO_.lean.js} +0 -0
  116. /package/site-dist/assets/{reference_contracts_state.md.EEBd_l2P.lean.js → reference_contracts_state.md.STlqkPPS.lean.js} +0 -0
@@ -74,4 +74,4 @@ import{_ as e,o as n,c as a,j as l,a as i}from"./chunks/framework.B9qR_F1m.js";c
74
74
  `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"name"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"安全视角"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"provider"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"codex/<模型 ID>"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"modeId"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"full-access"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"focus"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"重点检查权限、输入校验和数据安全"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," },")]),i(`
75
75
  `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"name"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"可维护性"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"provider"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"opencode/anthropic/<模型 ID>"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"modeId"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"build"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"featureValues"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"auto_accept"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"true"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," } }")]),i(`
76
76
  `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," ]")]),i(`
77
- `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"}")])])])]),l("ul",null,[l("li",null,[i("成员并行运行,在同一个目录里只读代码、写各自的意见文件("),l("code",null,"<功能目录>/review-panel/"),i("),不提交,不改文件。")]),l("li",null,"某位成员失败时,只汇总完成的成员;全部失败时该步骤失败。"),l("li",null,"成本:每次启用的评审多出 N 个 agent 的用量,所以默认只用于标准档的第一轮。"),l("li",null,[i("成员的模型和模式会在 "),l("code",null,"/req-doctor"),i(" 中一并检查。")])]),l("h2",{id:"需求总览、决策记录、变更与验收记录",tabindex:"-1"},[i("需求总览、决策记录、变更与验收记录 "),l("a",{class:"header-anchor",href:"#需求总览、决策记录、变更与验收记录","aria-label":'Permalink to "需求总览、决策记录、变更与验收记录"'},"​")]),l("ul",null,[l("li",null,[l("strong",null,"需求总览"),i(":"),l("code",null,"node <req-kit>/bin/start-pipeline.mjs --list"),i(" 列出这个仓库所有 worktree 中的需求和各自的阶段(对齐中、开发中、待验收、已验收等)。总览现场生成,不提交到仓库,避免各分支合并时冲突。")]),l("li",null,[l("strong",null,"决策记录"),i(),l("code",null,"decisions.tsv"),i(":各步骤把不显而易见的选择(假设、取舍、偏离方案、驳回的评审意见、决定不修的问题)各记一行。会影响结果的标为 "),l("code",null,"needs_human=yes"),i(',完成报告把它们列入"需要你确认的决定"。')]),l("li",null,[l("strong",null,"变更记录"),i(),l("code",null,"changes.md"),i(':每次修改需求(包括方案审核提出问题、验收发现问题)记一节,spec 头部的"版本"随之加 1。')]),l("li",null,[l("strong",null,"验收记录"),i(),l("code",null,"acceptance.md"),i(":由 "),l("code",null,"/req"),i(" 的验收手册写,逐条记录验收结果和结论。")])]),l("p",null,[i("格式见 "),l("code",null,"contracts/feature-files.md"),i("。")]),l("h2",{id:"运行规则",tabindex:"-1"},[i("运行规则 "),l("a",{class:"header-anchor",href:"#运行规则","aria-label":'Permalink to "运行规则"'},"​")]),l("p",null,[l("strong",null,"步骤和轮数"),i("(轮数按档位,在配置的 "),l("code",null,"profiles"),i(" 中调整;下面是标准档的默认值):")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"环节"),l("th",null,"规则")])]),l("tbody",null,[l("tr",null,[l("td",null,"评审小组(可选)"),l("td",null,"开启时,标准档的方案审核和代码评审第一轮先由小组成员并行评审,再由评审者核实汇总")]),l("tr",null,[l("td",null,"方案审核 ⇄ 方案修订"),l("td",null,'最多 2 轮审核。判定"阻塞"时暂停并请需求方决定;最后一轮仍要求修改时,修订后直接进入实现')]),l("tr",null,[l("td",null,"代码评审 ⇄ 评审问题修复"),l("td",null,"最多 3 轮评审,通过即止;轮数用完时修复后进入下一阶段")]),l("tr",null,[l("td",null,"提测说明"),l("td",null,[i("代码评审之后执行,写 "),l("code",null,"handoff.md"),i("。分阶段执行时研发阶段到此结束")])]),l("tr",null,[l("td",null,"服务启动验证"),l("td",null,[i("方案设计判断项目有常驻服务、且档位开启了 "),l("code",null,"serviceStart"),i(" 时才执行(在已部署的测试环境中验证时不执行)")])]),l("tr",null,[l("td",null,"缺陷修复 ⇄ 复验"),l("td",null,[i("功能验证发现缺陷时执行,最多 3 轮,复验通过即止("),l("code",null,"phases.verify.defects"),i(" 为 "),l("code",null,"handback"),i(" 或 "),l("code",null,"report"),i(' 时见上文"执行方式")')])]),l("tr",null,[l("td",null,"完成报告"),l("td",null,"只要没有暂停或中断就一定执行,遗留问题写进报告")]),l("tr",null,[l("td",null,"完成后继续"),l("td",null,[i("完成后 spec.md 被修改过(需求变更、验收发现问题),"),l("code",null,"--resume"),i(" 从方案设计开始,各步骤在已有方案和代码的基础上只处理变化的部分;没改过则拒绝。"),l("code",null,"--restart"),i(" 则完全从零开始")])]),l("tr",null,[l("td",null,"增量继续"),l("td",null,[i('需求变更、回答了方案审核的问题后继续时:方案在原文末尾追加"第 N 次尝试"一节;实现只改需要改的;代码评审只看本次开始以来的改动;验证重新验证变化涉及的验收标准,其余的至少跑一遍现有测试;报告说明是第几次。做法写在 '),l("code",null,"engine/prompts/incremental.md"),i(",可以用 "),l("code",null,"prompts.local/"),i(" 替换")])])])]),l("p",null,[l("strong",null,"结果文件"),i(":每步必须写一个 JSON 结果文件,流水线只看它,不看 agent 的回复文字。文件缺失或格式不对时,会在同一个会话里提醒 agent 补写,最多 2 次,仍不对则判定该步骤失败。")]),l("p",null,[l("strong",null,"等待与超时"),i(":每步有总时限("),l("code",null,"stepTimeoutMinutes"),i(")。到时 agent 还在做时,先再给它同样长的时间("),l("code",null,"selfHeal"),i(",见下);仍未完成才判定失败,但不停止 agent。继续("),l("code",null,"--resume"),i("、自动重试)时先看这一步上一次的 agent:已经做完、结果文件有效就直接用它的结果;还在做就接着等它一轮(这一轮不再额外延长);第二次仍超时才停止它、另起一个 agent。需求改过、开始了新一次尝试时,上一次留下的 agent 直接停掉,不接手(1.12.1)。同一步不会有两个 agent 同时在做(它们会改同样的文件、在同一个工作区提交、写同一个结果文件)。连续读不到 agent 状态时同样处理。等待被拆成每段 10 分钟(打开 "),l("code",null,"scanGuard"),i(" 时每段 1 分钟,以便查看正在运行的命令),连接断开时自动重试。agent 等待权限批准时,同一个请求只通知一次,然后继续等待。")]),l("p",null,[l("strong",null,"临时错误自动重试"),i(":步骤因限流(429)、服务暂时不可用(502/503/504/529、overloaded)、网络中断等临时错误失败时,等待后用新的 agent 重做这一步,并告诉它工作区里可能留有上一次没做完的改动。默认最多重试 2 次,分别等 1 分钟和 5 分钟:")]),l("div",{class:"language-json vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"json"),l("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[l("code",null,[l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"retry"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"attempts"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"2"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"backoffSeconds"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": ["),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"60"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"300"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"] }")])])])]),l("p",null,[l("code",null,"attempts"),i(" 设为 0 关闭;"),l("code",null,"backoffSeconds"),i(" 的个数少于重试次数时,后面的重试使用最后一个值。超时、结果文件不合格、agent 自己判定失败等不是临时错误,不按这里重试。重试用完仍失败时,中断通知会注明已重试的次数。")]),l("p",null,[l("strong",null,"自愈"),i("(1.12,"),l("code",null,"selfHeal"),i(",默认 "),l("code",null,"true"),i("):能安全自动处理的中断不再等人。")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"情况"),l("th",null,"自动处理")])]),l("tbody",null,[l("tr",null,[l("td",null,"步骤超时,agent 还在做"),l("td",null,"不打断它,再等同样长的时间;仍未完成才中断")]),l("tr",null,[l("td",null,"agent 报错(不是临时错误)"),l("td",null,"新开一个 agent 重做这一步一次;配置了备用模型时用备用模型")]),l("tr",null,[l("td",null,"提醒后仍没有有效的结果文件"),l("td",null,"新开一个 agent 重做这一步一次")]),l("tr",null,[l("td",null,"限流、额度用完,重试用完"),l("td",null,[i("配置了备用模型时,用备用模型再做一次;仍不行就中断,并按 Paseo 显示的额度恢复时间预约自动继续(恢复后 5 分钟;没有恢复时间时按 "),l("code",null,"autoResumeMinutes"),i(")")])]),l("tr",null,[l("td",null,"方案审核说需要需求方决定"),l("td",null,[i("先请 builder 从代码、文档和需求说明中找答案("),l("code",null,"answerQuestionsFirst"),i(",默认 "),l("code",null,"true"),i("),只把真正的业务取舍连同推荐答案交给需求方;都能回答时不停下。最后一轮审核的问题被自答时,再加一轮审核复核这些答案(1.12.1)")])])])]),l("p",null,[l("strong",null,"备用模型"),i("(1.12,可选):"),l("code",null,"agents.fallback"),i(",写法同 builder、reviewer,可以用 "),l("code",null,"paseoProfile"),i("。"),l("code",null,"req configure"),i(' 和插件的"模型"设置页会推荐一个与主模型不同厂商的模型。')]),l("div",{class:"language-json vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"json"),l("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[l("code",null,[l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"agents"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"builder"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),l("span",{style:{"--shiki-light":"#B31D28","--shiki-light-font-style":"italic","--shiki-dark":"#FDAEB7","--shiki-dark-font-style":"italic"}},"…"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," }, "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"reviewer"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),l("span",{style:{"--shiki-light":"#B31D28","--shiki-light-font-style":"italic","--shiki-dark":"#FDAEB7","--shiki-dark-font-style":"italic"}},"…"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," }, "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"fallback"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"provider"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"opencode/<模型 ID>"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," } }")])])])]),l("p",null,[i("自动处理的每一次都记在进度日志、状态文件的 "),l("code",null,"recoveries"),i(" 和使用记录中,"),l("code",null,"req stats"),i(' 的"人工介入"一节汇总:停下等人的原因、自动处理了多少次、到达提测的需求中没有非必要介入的比例。')]),l("p",null,[l("strong",null,"打断大目录搜索"),i("(1.13,"),l("code",null,"scanGuard"),i(",默认开):步骤 agent 有时为了找一个类或一个包,去搜索整个磁盘、用户目录、Maven 本地仓库("),l("code",null,"~/.m2"),i(")、Gradle 缓存、全局 "),l("code",null,"node_modules"),i(" 或整个 "),l("code",null,"node_modules"),i(",一次就是几十分钟,这一步迟迟做不完。步骤运行时,流水线大约每分钟看一次 agent 正在运行的命令:搜索这类大目录的命令运行超过 1 分钟、或者任何搜索命令运行超过 "),l("code",null,"minutes"),i(" 分钟,就打断它,并告诉 agent 改用什么办法(在仓库里用 "),l("code",null,"git grep"),i(";按 "),l("code",null,"pom.xml"),i(" 里的坐标直接打开那一个依赖目录、用 "),l("code",null,"unzip -l"),i(" 看那一个 jar;"),l("code",null,"mvn dependency:tree"),i(';找不到就写进"假设"继续)。构建和测试命令('),l("code",null,"mvn"),i("、"),l("code",null,"gradle"),i("、"),l("code",null,"npm test"),i(" 等)不打断;只搜具体的子目录(如 "),l("code",null,"~/.m2/repository/com/acme/foo"),i(")或排除了 "),l("code",null,"node_modules"),i(" 的搜索也不算。同一个命令只打断一次,每轮最多打断 5 次;每次都记在进度日志和 "),l("code",null,"recoveries"),i("("),l("code",null,"stop_scan"),i(")中。各步骤的提示词里也写明了只在仓库里搜索。")]),l("div",{class:"language-json vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"json"),l("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[l("code",null,[l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"scanGuard"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"enabled"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"true"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"minutes"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"5"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"paths"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": ["),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"D:/share"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"] }")])])])]),l("p",null,[l("code",null,"paths"),i(":另外不允许整个搜索的目录(例如共享盘);"),l("code",null,"enabled: false"),i(" 关闭。")]),l("p",null,[l("strong",null,"同一个目录一次只运行一条流水线"),i(",因为各步骤都在这个目录中修改和提交。需要并行时,为每个需求使用单独的 worktree 工作区。")]),l("h2",{id:"注意事项",tabindex:"-1"},[i("注意事项 "),l("a",{class:"header-anchor",href:"#注意事项","aria-label":'Permalink to "注意事项"'},"​")]),l("ul",null,[l("li",null,[l("strong",null,"发起流水线的聊天 agent 需要能访问本机网络。"),i(" 流水线进程继承它的运行环境,需要连接 "),l("code",null,"ws://127.0.0.1:6767"),i("。用 Codex 做聊天 agent 时,请使用 "),l("code",null,"full-access"),i(" 模式;沙箱模式可能禁止网络。")]),l("li",null,[l("strong",null,"必须在仓库对应的项目对话中发起,对话过程中不要切换工作目录。"),i(" 步骤 agent 一律作为子 agent 挂在发起的对话下,而 Paseo 会让子 agent 使用父 agent 的工作目录,所以仓库目录必须就是这个对话的工作目录。在对话中启动时,"),l("code",null,"--repo"),i(" 默认就取对话的工作目录;两者不一致、或发起的对话已不存在时,流水线拒绝启动并说明原因。")]),l("li",null,[l("strong",null,"步骤 agent 以免确认模式运行"),i(",在本机拥有执行命令的权限。提示词禁止了危险操作,但这不是安全边界。请让仓库目录中不包含生产环境凭据。")]),l("li",null,[l("strong",null,"聊天被归档时"),i(",挂在它下面的步骤 agent 也会被归档;通知会发送失败,但流水线会继续运行到结束,结果仍可在 "),l("code",null,"report.md"),i(" 和日志中查看。")]),l("li",null,[l("strong",null,"daemon 重启"),i("会中断正在运行的步骤 agent。流水线会在连续 5 次无法获取状态后判定该步骤失败,之后可以用 "),l("code",null,"--resume"),i(" 继续。")])])],-1),l("p",{class:"source-note"},[i("本页由仓库中的 "),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/docs/guide/项目定制与运行规则.md"},"docs/guide/项目定制与运行规则.md"),i(" 生成。"),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/docs/guide/项目定制与运行规则.md"},"在 GitHub 上编辑")],-1)])])}const c=e(t,[["render",h]]);export{p as __pageData,c as default};
77
+ `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"}")])])])]),l("ul",null,[l("li",null,[i("成员并行运行,在同一个目录里只读代码、写各自的意见文件("),l("code",null,"<功能目录>/review-panel/"),i("),不提交,不改文件。")]),l("li",null,"某位成员失败时,只汇总完成的成员;全部失败时该步骤失败。"),l("li",null,"成本:每次启用的评审多出 N 个 agent 的用量,所以默认只用于标准档的第一轮。"),l("li",null,[i("成员的模型和模式会在 "),l("code",null,"/req-doctor"),i(" 中一并检查。")])]),l("h2",{id:"需求总览、决策记录、变更与验收记录",tabindex:"-1"},[i("需求总览、决策记录、变更与验收记录 "),l("a",{class:"header-anchor",href:"#需求总览、决策记录、变更与验收记录","aria-label":'Permalink to "需求总览、决策记录、变更与验收记录"'},"​")]),l("ul",null,[l("li",null,[l("strong",null,"需求总览"),i(":"),l("code",null,"node <req-kit>/bin/start-pipeline.mjs --list"),i(" 列出这个仓库所有 worktree 中的需求和各自的阶段(对齐中、开发中、待验收、已验收等)。总览现场生成,不提交到仓库,避免各分支合并时冲突。")]),l("li",null,[l("strong",null,"决策记录"),i(),l("code",null,"decisions.tsv"),i(":各步骤把不显而易见的选择(假设、取舍、偏离方案、驳回的评审意见、决定不修的问题)各记一行。会影响结果的标为 "),l("code",null,"needs_human=yes"),i(',完成报告把它们列入"需要你确认的决定"。')]),l("li",null,[l("strong",null,"变更记录"),i(),l("code",null,"changes.md"),i(':每次修改需求(包括方案审核提出问题、验收发现问题)记一节,spec 头部的"版本"随之加 1。')]),l("li",null,[l("strong",null,"验收记录"),i(),l("code",null,"acceptance.md"),i(":由 "),l("code",null,"/req"),i(" 的验收手册写,逐条记录验收结果和结论。")])]),l("p",null,[i("格式见 "),l("code",null,"contracts/feature-files.md"),i("。")]),l("h2",{id:"运行规则",tabindex:"-1"},[i("运行规则 "),l("a",{class:"header-anchor",href:"#运行规则","aria-label":'Permalink to "运行规则"'},"​")]),l("p",null,[l("strong",null,"步骤和轮数"),i("(轮数按档位,在配置的 "),l("code",null,"profiles"),i(" 中调整;下面是标准档的默认值):")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"环节"),l("th",null,"规则")])]),l("tbody",null,[l("tr",null,[l("td",null,"评审小组(可选)"),l("td",null,"开启时,标准档的方案审核和代码评审第一轮先由小组成员并行评审,再由评审者核实汇总")]),l("tr",null,[l("td",null,"方案审核 ⇄ 方案修订"),l("td",null,'最多 2 轮审核。判定"阻塞"时暂停并请需求方决定;最后一轮仍要求修改时,修订后直接进入实现')]),l("tr",null,[l("td",null,"代码评审 ⇄ 评审问题修复"),l("td",null,"最多 3 轮评审,通过即止;轮数用完时修复后进入下一阶段")]),l("tr",null,[l("td",null,"提测说明"),l("td",null,[i("代码评审之后执行,写 "),l("code",null,"handoff.md"),i("。分阶段执行时研发阶段到此结束")])]),l("tr",null,[l("td",null,"服务启动验证"),l("td",null,[i("方案设计判断项目有常驻服务、且档位开启了 "),l("code",null,"serviceStart"),i(" 时才执行(在已部署的测试环境中验证时不执行)")])]),l("tr",null,[l("td",null,"缺陷修复 ⇄ 复验"),l("td",null,[i("功能验证发现缺陷时执行,最多 3 轮,复验通过即止("),l("code",null,"phases.verify.defects"),i(" 为 "),l("code",null,"handback"),i(" 或 "),l("code",null,"report"),i(' 时见上文"执行方式")')])]),l("tr",null,[l("td",null,"完成报告"),l("td",null,"只要没有暂停或中断就一定执行,遗留问题写进报告")]),l("tr",null,[l("td",null,"完成后继续"),l("td",null,[i("完成后 spec.md 被修改过(需求变更、验收发现问题),"),l("code",null,"--resume"),i(" 从方案设计开始,各步骤在已有方案和代码的基础上只处理变化的部分;没改过则拒绝。"),l("code",null,"--restart"),i(" 则完全从零开始")])]),l("tr",null,[l("td",null,"增量继续"),l("td",null,[i('需求变更、回答了方案审核的问题后继续时:方案在原文末尾追加"第 N 次尝试"一节;实现只改需要改的;代码评审只看本次开始以来的改动;验证重新验证变化涉及的验收标准,其余的至少跑一遍现有测试;报告说明是第几次。做法写在 '),l("code",null,"engine/prompts/incremental.md"),i(",可以用 "),l("code",null,"prompts.local/"),i(" 替换")])])])]),l("p",null,[l("strong",null,"结果文件"),i(":每步必须写一个 JSON 结果文件,流水线只看它,不看 agent 的回复文字。文件缺失或格式不对时,会在同一个会话里提醒 agent 补写,最多 2 次,仍不对则判定该步骤失败。")]),l("p",null,[l("strong",null,"等待与超时"),i(":每步有总时限("),l("code",null,"stepTimeoutMinutes"),i(")。到时 agent 还在做时,先再给它同样长的时间("),l("code",null,"selfHeal"),i(",见下);仍未完成才判定失败,但不停止 agent。继续("),l("code",null,"--resume"),i("、自动重试)时先看这一步上一次的 agent:已经做完、结果文件有效就直接用它的结果;还在做就接着等它一轮(这一轮不再额外延长);第二次仍超时才停止它、另起一个 agent。需求改过、开始了新一次尝试时,上一次留下的 agent 直接停掉,不接手(1.12.1)。同一步不会有两个 agent 同时在做(它们会改同样的文件、在同一个工作区提交、写同一个结果文件)。连续读不到 agent 状态时同样处理。等待被拆成每段 10 分钟(打开 "),l("code",null,"scanGuard"),i(" 时每段 1 分钟、打开 "),l("code",null,"dangerGuard"),i(" 时每段 15 秒,以便查看正在运行的命令;只是读取状态,不占模型 token),连接断开时自动重试。agent 等待权限批准时,同一个请求只通知一次,然后继续等待。")]),l("p",null,[l("strong",null,"临时错误自动重试"),i(":步骤因限流(429)、服务暂时不可用(502/503/504/529、overloaded)、网络中断等临时错误失败时,等待后用新的 agent 重做这一步,并告诉它工作区里可能留有上一次没做完的改动。默认最多重试 2 次,分别等 1 分钟和 5 分钟:")]),l("div",{class:"language-json vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"json"),l("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[l("code",null,[l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"retry"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"attempts"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"2"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"backoffSeconds"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": ["),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"60"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"300"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"] }")])])])]),l("p",null,[l("code",null,"attempts"),i(" 设为 0 关闭;"),l("code",null,"backoffSeconds"),i(" 的个数少于重试次数时,后面的重试使用最后一个值。超时、结果文件不合格、agent 自己判定失败等不是临时错误,不按这里重试。重试用完仍失败时,中断通知会注明已重试的次数。")]),l("p",null,[l("strong",null,"自愈"),i("(1.12,"),l("code",null,"selfHeal"),i(",默认 "),l("code",null,"true"),i("):能安全自动处理的中断不再等人。")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"情况"),l("th",null,"自动处理")])]),l("tbody",null,[l("tr",null,[l("td",null,"步骤超时,agent 还在做"),l("td",null,"不打断它,再等同样长的时间;仍未完成才中断")]),l("tr",null,[l("td",null,"agent 报错(不是临时错误)"),l("td",null,"新开一个 agent 重做这一步一次;配置了备用模型时用备用模型")]),l("tr",null,[l("td",null,"提醒后仍没有有效的结果文件"),l("td",null,"新开一个 agent 重做这一步一次")]),l("tr",null,[l("td",null,"限流、额度用完,重试用完"),l("td",null,[i("配置了备用模型时,用备用模型再做一次;仍不行就中断,并按 Paseo 显示的额度恢复时间预约自动继续(恢复后 5 分钟;没有恢复时间时按 "),l("code",null,"autoResumeMinutes"),i(")")])]),l("tr",null,[l("td",null,"方案审核说需要需求方决定"),l("td",null,[i("先请 builder 从代码、文档和需求说明中找答案("),l("code",null,"answerQuestionsFirst"),i(",默认 "),l("code",null,"true"),i("),只把真正的业务取舍连同推荐答案交给需求方;都能回答时不停下。最后一轮审核的问题被自答时,再加一轮审核复核这些答案(1.12.1)")])])])]),l("p",null,[l("strong",null,"备用模型"),i("(1.12,可选):"),l("code",null,"agents.fallback"),i(",写法同 builder、reviewer,可以用 "),l("code",null,"paseoProfile"),i("。"),l("code",null,"req configure"),i(' 和插件的"模型"设置页会推荐一个与主模型不同厂商的模型。')]),l("div",{class:"language-json vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"json"),l("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[l("code",null,[l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"agents"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"builder"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),l("span",{style:{"--shiki-light":"#B31D28","--shiki-light-font-style":"italic","--shiki-dark":"#FDAEB7","--shiki-dark-font-style":"italic"}},"…"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," }, "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"reviewer"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),l("span",{style:{"--shiki-light":"#B31D28","--shiki-light-font-style":"italic","--shiki-dark":"#FDAEB7","--shiki-dark-font-style":"italic"}},"…"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," }, "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"fallback"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"provider"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"opencode/<模型 ID>"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," } }")])])])]),l("p",null,[i("自动处理的每一次都记在进度日志、状态文件的 "),l("code",null,"recoveries"),i(" 和使用记录中,"),l("code",null,"req stats"),i(' 的"人工介入"一节汇总:停下等人的原因、自动处理了多少次、到达提测的需求中没有非必要介入的比例。')]),l("p",null,[l("strong",null,"打断大目录搜索"),i("(1.13,"),l("code",null,"scanGuard"),i(",默认开):步骤 agent 有时为了找一个类或一个包,去搜索整个磁盘、用户目录、Maven 本地仓库("),l("code",null,"~/.m2"),i(")、Gradle 缓存、全局 "),l("code",null,"node_modules"),i(" 或整个 "),l("code",null,"node_modules"),i(",一次就是几十分钟,这一步迟迟做不完。步骤运行时,流水线大约每分钟看一次 agent 正在运行的命令:搜索这类大目录的命令运行超过 1 分钟、或者任何搜索命令运行超过 "),l("code",null,"minutes"),i(" 分钟,就打断它,并告诉 agent 改用什么办法(在仓库里用 "),l("code",null,"git grep"),i(";按 "),l("code",null,"pom.xml"),i(" 里的坐标直接打开那一个依赖目录、用 "),l("code",null,"unzip -l"),i(" 看那一个 jar;"),l("code",null,"mvn dependency:tree"),i(';找不到就写进"假设"继续)。构建和测试命令('),l("code",null,"mvn"),i("、"),l("code",null,"gradle"),i("、"),l("code",null,"npm test"),i(" 等)不打断;只搜具体的子目录(如 "),l("code",null,"~/.m2/repository/com/acme/foo"),i(")或排除了 "),l("code",null,"node_modules"),i(" 的搜索也不算。同一个命令只打断一次,每轮最多打断 5 次;每次都记在进度日志和 "),l("code",null,"recoveries"),i("("),l("code",null,"stop_scan"),i(")中。各步骤的提示词里也写明了只在仓库里搜索。")]),l("div",{class:"language-json vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"json"),l("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[l("code",null,[l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"scanGuard"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"enabled"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"true"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"minutes"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"5"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"paths"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": ["),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"D:/share"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"] }")])])])]),l("p",null,[l("code",null,"paths"),i(":另外不允许整个搜索的目录(例如共享盘);"),l("code",null,"enabled: false"),i(" 关闭。")]),l("p",null,[l("strong",null,"拦截危险命令"),i("(1.14,"),l("code",null,"dangerGuard"),i(',默认开):步骤 agent 通常以免确认模式运行命令,"只做本地提交、不碰生产"以前只写在提示词里。现在步骤运行时,流水线每 15 秒看一次 agent 运行过和正在运行的命令(读 Paseo 的记录,不用模型)。下面这些会被处理:推送('),l("code",null,"git push"),i(",强推、删除远程分支单独标出)、改远程地址;发布制品("),l("code",null,"npm publish"),i("、"),l("code",null,"mvn deploy"),i("、"),l("code",null,"gradle publish"),i("、"),l("code",null,"docker push"),i(" 等);改动集群和基础设施("),l("code",null,"kubectl apply/delete/exec…"),i("、"),l("code",null,"helm install/upgrade…"),i("、"),l("code",null,"terraform apply/destroy"),i("、"),l("code",null,"ansible-playbook"),i(");连接其他机器上的数据库("),l("code",null,"mysql -h <带点的主机名或地址>"),i(" 等,"),l("code",null,"localhost"),i(" 和 docker compose 里的服务名如 "),l("code",null,"db"),i(" 不算);登录或复制到其他机器("),l("code",null,"ssh"),i("、"),l("code",null,"scp"),i("、"),l("code",null,"rsync"),i(","),l("code",null,"git@"),i(" 不算);删除仓库以外的目录("),l("code",null,"rm -rf ~"),i("、"),l("code",null,"/"),i("、"),l("code",null,".."),i("、仓库外的绝对路径,临时目录除外);下载脚本直接执行("),l("code",null,"curl … | sh"),i(");关机、格式化等系统级操作;以及命令里出现 "),l("code",null,"production"),i(" 中任何一项(生产环境的主机名、地址、库名)。还在运行的命令立即打断,告诉 agent 不要再做、把需要人做的写进产物;已经运行完的也会告诉它。每次都通知需求的对话(和外部通知的 "),l("code",null,"alert"),i(" 事件,"),l("code",null,"details.kind"),i(" 为 "),l("code",null,"danger"),i("),记在状态文件的 "),l("code",null,"dangers"),i(" 里,并写进完成报告。这是按命令文字的检查,能拦住常见的情况,不是沙箱。")]),l("div",{class:"language-json vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"json"),l("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[l("code",null,[l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"dangerGuard"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"enabled"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"true"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"production"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": ["),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"prod.example.com"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"10.8.0."'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"], "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"allow"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": ["),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"^ssh test-box"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"] }")])])])]),l("p",null,[l("code",null,"production"),i(":生产环境的标记(出现在命令或访问的地址里就拦),建议团队配置里写上;"),l("code",null,"allow"),i(":放行的命令(正则表达式),例如测试机的登录;"),l("code",null,"enabled: false"),i(" 关闭。")]),l("p",null,[l("strong",null,"密钥扫描"),i("(1.14,"),l("code",null,"secretScan"),i(",默认开):每个改代码的步骤之后(和质量门一起),流水线检查本需求新增的内容:从这次尝试开始时的提交以来,每次提交加进来的行、还没提交的改动和新文件。常见格式的密钥(私钥、AWS、GitHub、GitLab、Slack、模型服务的 API 密钥、JWT、地址里带的口令)在任何文件里都算;"),l("code",null,'password = "…"'),i("、"),l("code",null,"token: …"),i(" 这样的赋值只在代码和配置里算,测试和文档不算,值是占位符("),l("code",null,"${…}"),i("、"),l("code",null,"<your-token>"),i("、"),l("code",null,"changeme"),i(")或从环境变量读取的也不算。发现了就交回这一步的 agent:改成从配置或环境变量读取;已经写进本需求提交的,用 "),l("code",null,"git commit --fixup"),i(" 和非交互的 "),l("code",null,"git rebase --autosquash"),i(" 从这些还没推送的提交里去掉;确实不是密钥的,在那一行加注释 "),l("code",null,"req-kit:allow-secret"),i("。最多要求 "),l("code",null,"qualityGate.fixAttempts"),i(" 次,仍有的通知需求的对话、写进代码评审和完成报告;配置了 "),l("code",null,"push"),i(" 的需求"),l("strong",null,"不会推送"),i("有疑似密钥的分支。")]),l("div",{class:"language-json vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"json"),l("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[l("code",null,[l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"secretScan"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"enabled"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"true"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"allow"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": ["),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"test/fixtures/**"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"] }")])])])]),l("p",null,[l("code",null,"allow"),i(":不扫描的文件(路径或通配符);"),l("code",null,"enabled: false"),i(" 关闭。")]),l("p",null,[l("strong",null,"同一个目录一次只运行一条流水线"),i(",因为各步骤都在这个目录中修改和提交。需要并行时,为每个需求使用单独的 worktree 工作区。")]),l("h2",{id:"注意事项",tabindex:"-1"},[i("注意事项 "),l("a",{class:"header-anchor",href:"#注意事项","aria-label":'Permalink to "注意事项"'},"​")]),l("ul",null,[l("li",null,[l("strong",null,"发起流水线的聊天 agent 需要能访问本机网络。"),i(" 流水线进程继承它的运行环境,需要连接 "),l("code",null,"ws://127.0.0.1:6767"),i("。用 Codex 做聊天 agent 时,请使用 "),l("code",null,"full-access"),i(" 模式;沙箱模式可能禁止网络。")]),l("li",null,[l("strong",null,"必须在仓库对应的项目对话中发起,对话过程中不要切换工作目录。"),i(" 步骤 agent 一律作为子 agent 挂在发起的对话下,而 Paseo 会让子 agent 使用父 agent 的工作目录,所以仓库目录必须就是这个对话的工作目录。在对话中启动时,"),l("code",null,"--repo"),i(" 默认就取对话的工作目录;两者不一致、或发起的对话已不存在时,流水线拒绝启动并说明原因。")]),l("li",null,[l("strong",null,"步骤 agent 以免确认模式运行"),i(",在本机拥有执行命令的权限。提示词禁止了危险操作,但这不是安全边界。请让仓库目录中不包含生产环境凭据。")]),l("li",null,[l("strong",null,"聊天被归档时"),i(",挂在它下面的步骤 agent 也会被归档;通知会发送失败,但流水线会继续运行到结束,结果仍可在 "),l("code",null,"report.md"),i(" 和日志中查看。")]),l("li",null,[l("strong",null,"daemon 重启"),i("会中断正在运行的步骤 agent。流水线会在连续 5 次无法获取状态后判定该步骤失败,之后可以用 "),l("code",null,"--resume"),i(" 继续。")])])],-1),l("p",{class:"source-note"},[i("本页由仓库中的 "),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/docs/guide/项目定制与运行规则.md"},"docs/guide/项目定制与运行规则.md"),i(" 生成。"),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/docs/guide/项目定制与运行规则.md"},"在 GitHub 上编辑")],-1)])])}const c=e(t,[["render",h]]);export{p as __pageData,c as default};
@@ -1 +1 @@
1
- import{_ as o,o as e,c as r,a3 as d}from"./chunks/framework.B9qR_F1m.js";const g=JSON.parse('{"title":"使用者指南","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"guide/user.md","filePath":"guide/user.md","lastUpdated":null}'),u={name:"guide/user.md"};function q(s,t,l,i,a,n){return e(),r("div",null,[...t[0]||(t[0]=[d('<div><h1 id="使用者指南" tabindex="-1">使用者指南 <a class="header-anchor" href="#使用者指南" aria-label="Permalink to &quot;使用者指南&quot;">​</a></h1><p>req-kit 帮你把一个需求从&quot;我想要……&quot;做到&quot;可以验收&quot;:你在 Paseo 的对话里把需求讲清楚、确认一份需求说明,之后的方案设计、写代码、评审、测试和报告由一组 AI agent 在后台完成,结果发回同一个对话。</p><p>适合测试、产品经理、项目经理等不写代码、但熟悉需求和测试的同事。你不需要读代码,但可以随时查看每一步的产物,也可以亲自执行测试命令核对结果。</p><h2 id="第一次使用之前" tabindex="-1">第一次使用之前 <a class="header-anchor" href="#第一次使用之前" aria-label="Permalink to &quot;第一次使用之前&quot;">​</a></h2><p>请开发同事确认这台机器已经装好 req-kit(<code>/req-doctor</code> 全部正常),并且项目已经接入:在项目根目录的对话中运行过 <code>/req-setup</code>,生成了项目说明和验证方法。测试同事熟悉项目的话,也可以自己运行 <code>/req-setup</code>。</p><h2 id="提一个需求" tabindex="-1">提一个需求 <a class="header-anchor" href="#提一个需求" aria-label="Permalink to &quot;提一个需求&quot;">​</a></h2><ol><li><strong>准备工作区</strong>:每个需求最好有自己的 worktree 工作区,几个需求可以同时进行,互不影响。两种方式任选: <ul><li>直接在项目的对话里开始,AI 问到时选&quot;开发时自动新建工作区&quot;:照常谈需求,启动开发时流水线会自动新建工作区并在那里开发,这个对话不用动。</li><li>自己新建:在 Paseo 中点 <strong>New workspace</strong> → 选择项目 → <strong>Isolation</strong> 选 <strong>New worktree</strong> → 起点选主分支,然后在新工作区的对话里开始。</li></ul></li><li><strong>输入 <code>/req</code> 和一句话</strong>:例如 <code>/req 登录页增加短信验证码登录</code>。用 Pi 时输入 <code>/skill:req ……</code>。</li><li><strong>回答问题</strong>:AI 会先复述它的理解,然后一次问一个问题,给出选项和推荐。它会问到异常情况、权限、已有数据、测试数据和验证环境,这些往往是你最清楚的。拿不准时可以说&quot;你定&quot;,它会采用推荐项并记为假设,最后请你过目。</li><li><strong>独立审阅</strong>(标准档):确认之前,AI 会请另一个模型把需求说明独立审一遍,几分钟后把发现的问题(歧义、遗漏、没法验证的验收标准)逐个问你。这一步常常能省掉开发之后的返工。</li><li><strong>确认需求说明</strong>:AI 给出一份 10 行以内的摘要,完整的需求说明在 <code>docs/features/&lt;日期&gt;-&lt;名称&gt;/spec.md</code>。确认后它会问是否开始开发。</li><li><strong>等待</strong>:开发在后台进行,通常需要几个小时,不需要盯着。期间你会收到几句进展(方案定了、开始验证等)。</li></ol><p>小改动(改文案、样式、一个配置项)会走快速流程:只问 2–3 个问题,开发环节各做一轮。</p><p><strong>需求的类型</strong>:AI 复述时会和你确认这是哪一类,流水线按类型走不同的做法:</p><table tabindex="0"><thead><tr><th>类型</th><th>说法举例</th><th>流水线怎么做</th><th>你需要讲清楚的</th></tr></thead><tbody><tr><td>新需求</td><td>&quot;加一个……&quot;</td><td>方案、实现、评审、验证</td><td>要什么、怎么算做对</td></tr><tr><td>缺陷</td><td>&quot;……不对&quot;&quot;报错了&quot;</td><td>先复现、找到原因再修;复现不了会回来问你</td><td>复现步骤:环境、账号或数据、操作、看到的、应有的</td></tr><tr><td>重构</td><td>&quot;整理一下……&quot;&quot;升级依赖&quot;</td><td>先用测试锁住现有行为,再小步改,确认行为没变</td><td>改进目标,以及哪些行为必须保持不变</td></tr><tr><td>评估</td><td>&quot;能不能做……&quot;&quot;影响多大&quot;</td><td>只调研、写评估报告,由另一个模型审阅,不写代码</td><td>要回答的问题,结论用来做什么决定</td></tr></tbody></table><p>评估做完后,可以直接说&quot;按评估结果提一个新需求&quot;。</p><p><strong>前端和后端都要改</strong>:另一个仓库已经由开发同事登记过(<code>/req-setup</code> 时登记)的,AI 会问是否作为联合需求一起做:流水线先设计整体方案和双方的接口约定,再在每个仓库各开一个工作区同时开发,最后一起验证,报告里写明每个仓库的分支和合并顺序。</p><p><strong>验收标准带例子</strong>:AI 写验收标准时会给每条配上具体的数据(&quot;输入 13800000000,60 秒内再点发送,提示&#39;请 45 秒后重试&#39;&quot;)。请认真看这些例子:它们会直接变成测试检查的期望值,你确认的就是测试会检查的东西。</p><p><strong>开工前先看一眼&quot;做完后会看到什么&quot;</strong>(标准档的界面改动):方案审核通过后、写代码之前,流水线会停下来,AI 把 <code>preview.md</code> 的要点讲给你听:会看到什么变化、有哪些需要你确认的假设;界面改动还会有静态的原型页面(功能目录的 <code>prototype/</code> 中),可以在浏览器里打开看。说&quot;可以&quot;就开始写代码;想改的直接说,AI 会更新需求说明,方案调整后再请你看一次。这时调整的成本最低。</p><p><strong>研发和测试分开做</strong>(标准档,确定档位时 AI 会问,团队配置里定好了就不问):</p><ul><li><strong>连续</strong>(默认):研发完成后流水线接着做测试验证,一次跑完。</li><li><strong>分阶段</strong>:研发完成、写好提测说明(<code>handoff.md</code>)后停下来通知你:&quot;研发完成,可以提测&quot;。你或测试同事准备好之后说&quot;开始测试验证&quot;,AI 会讲一遍提测说明,问清在哪里测(本地,或已部署的测试环境)、发现缺陷怎么办(当场修复、退回研发修复后再提测,或只记录),然后开始;也可以预约时间。用&quot;开发时自动新建工作区&quot;开发的需求,测试同事可以在自己的对话里输入 <code>/req 开始测试验证 &lt;需求名称&gt;</code> 接手。</li><li><strong>只做研发</strong>:做到提测说明和研发报告为止,测试由人完成,验收时 AI 会按提测说明带你逐条测试。</li></ul><h2 id="过程中" tabindex="-1">过程中 <a class="header-anchor" href="#过程中" aria-label="Permalink to &quot;过程中&quot;">​</a></h2><table tabindex="0"><thead><tr><th>你想做的</th><th>在对话里说</th></tr></thead><tbody><tr><td>看进度</td><td>&quot;做到哪了&quot;(会说明当前在哪一步、agent 最近在做什么,例如正在运行测试)</td></tr><tr><td>暂停</td><td>&quot;先停一下&quot;(当前步骤做到一半的工作不保留,已完成的步骤保留)</td></tr><tr><td>继续</td><td>&quot;继续开发&quot;</td></tr><tr><td>确认方案</td><td>收到&quot;请确认方案&quot;时,看过之后说&quot;可以,按这个做&quot;,或者说要改哪里</td></tr><tr><td>改需求</td><td>&quot;我想改一下……&quot;:先暂停,谈清变化的部分,更新需求说明(版本加 1,记入 <code>changes.md</code>)后继续,开发会在已有方案和代码的基础上只处理变化的部分。开发已经完成的也可以改</td></tr><tr><td>看看项目里有哪些需求</td><td>&quot;现在有哪些需求&quot;:列出所有工作区中的需求和各自的阶段</td></tr><tr><td>研发完成后提测</td><td>&quot;开始测试验证&quot;(分阶段执行时);想晚点开始就说&quot;等测试环境部署好,明早 9 点开始测试&quot;</td></tr><tr><td>晚点再开始</td><td>确认需求后说&quot;今晚 10 点开始&quot;&quot;明天早上开始&quot;:到时会在这个对话里自动开始,说&quot;先停一下&quot;可以取消</td></tr><tr><td>接手别人的需求</td><td>&quot;这个需求之前是同事提的,现在什么情况&quot;:讲清现状、待决事项和下一步</td></tr></tbody></table><p>也可以不进对话,在终端里用 <code>req</code> 命令(需要开发同事装好并加入 PATH,见 <a href="./install">安装与升级</a>):在项目目录中 <code>req list</code> 看所有需求,<code>req status</code> 看进度(多个需求时写名称的一部分,如 <code>req status sms-login</code>),<code>req stop</code>、<code>req resume</code> 暂停和继续。</p><p>装了 req-kit 插件的话(见 <a href="./install">安装与升级</a> 第 13 节),在 Paseo 侧边栏点&quot;需求&quot;:本机所有项目的需求一页看完,&quot;需要你处理&quot;的排在最前;点开一个需求能看到每一步的进度和用时、读需求说明、方案、确认预览和完成报告,也可以直接确认方案、停止、继续或开始测试验证。网页端、桌面版和手机上都能用。</p><p>1.14 起,需求从开始谈的时候就出现在插件里(状态&quot;对齐中&quot;);需求说明确认了却还没开始开发(超过 30 分钟),或者上次启动没成功的,会出现在&quot;等你处理&quot;里,点&quot;开始开发&quot;就能开始,进展照常发回谈需求的那个对话。</p><p>1.12 起,首页最上面是&quot;等你处理&quot;:所有等你确认方案、回答问题、中断了的需求,等得最久的在前,每条写明要做什么、等了多久。方案可以直接确认,也可以写修改意见;方案审核的问题可以直接写回答,插件会转给这个需求的对话,效果和在对话里回答一样。首页的&quot;配置&quot;列出 req-kit 的全部设置:每一项是什么、现在的值、来自本机、团队还是项目的配置文件,可以按项目查看、搜索、只看改过的。</p><p><strong>在原型上提意见(1.13 起)。</strong> 界面改动的需求,在请你确认方案时会有一份界面原型。在插件首页的&quot;等你处理&quot;或需求页面最上面,点**&quot;审查原型并确认方案&quot;**按钮(终端里是 <code>req review &lt;需求&gt;</code>),原型审查页就在 Paseo 里打开(手机上会在浏览器中打开;嫌窗口小时点右上角&quot;在新窗口打开&quot;):</p><ul><li>标着 ①②③ 的是这次要改的地方,右边写着各自对应的验收标准,顺着看就不会漏。</li><li>想改哪里就<strong>点哪里</strong>,选一种改法(文字改成…、大一点、换颜色、换位置、删掉、这里加东西……),再用自己的话补一句。不用想专业词汇,你点的是哪个按钮、原来是什么颜色和大小,页面会自动记下来交给 AI。</li><li>想换文字就<strong>双击文字</strong>,直接改成你想要的字。</li><li>正常、出错、空数据这些状态,以及电脑、手机宽度,在页面上方切换。</li><li>写的意见会自动保存。看完后点&quot;提交修改意见&quot;,需求会话会据此改需求说明,改好后请你再确认;改过的原型再打开时,会用绿色框标出这一版改了哪里。没有要改的,点&quot;同意开始写代码&quot;。</li></ul><p><strong>还要多久(1.13 起)。</strong> 本机做完过 3 个以上同档位的需求后,开始开发时会告诉你这类需求通常要多久、用多少 token;问&quot;做到哪了&quot;或在插件的需求页面里,会看到&quot;预计还要约多久&quot;(不含等人确认的时间)。</p><p>每个步骤都会出现在这个对话的子 agent 列表里(名字形如&quot;[20261012-sms-login] 6-代码评审 第2轮&quot;),点开可以看到它在做什么。功能目录下的 <code>progress.md</code> 按时间记录了每一步的结果。</p><p>可能收到的通知(团队接入了企业 IM 的话,这些通知也会发到 IM):</p><ul><li><strong>需要你决定</strong>:方案审核发现只有你能回答的问题。AI 会逐个问你,然后继续。一天没有回答的话,会在对话里提醒一次。</li><li><strong>研发完成,可以提测</strong>(分阶段执行时):代码已写完并通过评审,提测说明在 <code>handoff.md</code>。一天没有开始测试验证的话,会在对话里提醒一次。</li><li><strong>等待批准</strong>:某一步在等权限批准,按提示打开对应的 agent 处理,或请开发同事处理。1.13 起插件的&quot;等你处理&quot;里也会显示,列出要批准的操作,点&quot;打开这个 agent&quot;直接去处理。</li><li><strong>token 用量提醒</strong>(团队设了 token 预算时):用到预算的一定比例时告知一次,开发照常进行;用完时做完当前步骤就停下,AI 会告诉你用了多少、问你是否继续。继续会再给一份预算。</li><li><strong>中断</strong>:限流、网络中断这类临时问题会先自动等待重试,仍然不行才中断,并预约半小时后自动继续(说&quot;先停一下&quot;可以取消)。AI 会说明原因和日志位置。环境类问题(例如测试服务没启动)你可以自己处理;涉及配置或代码的请开发同事处理。处理后说&quot;继续开发&quot;。</li></ul><h2 id="验收" tabindex="-1">验收 <a class="header-anchor" href="#验收" aria-label="Permalink to &quot;验收&quot;">​</a></h2><p>完成后你会收到结论和摘要,完整报告在功能目录的 <code>report.md</code>:</p><ul><li><strong>验收对照表</strong>:每条验收标准的结果,以及是怎么确认的(运行了什么命令、看到了什么、截图在哪里)。</li><li><strong>需要你确认的决定</strong>:开发过程中替你做的假设和取舍,以及被驳回的评审意见里会影响结果的那些。请逐条表态。</li><li><strong>遗留问题</strong>和<strong>需要你做的事</strong>。</li><li><strong>用时与用量</strong>:各步骤 agent 合计用了多长时间、多少 token、大约多少费用,便于估算后续需求的成本。</li></ul><p>然后说&quot;我要验收&quot;。AI 会按验收标准一条一条带你核对:告诉你怎么操作、应该看到什么;能用命令验证的给出命令,你可以自己执行。每条结果记入功能目录的 <code>acceptance.md</code>。</p><p><strong>代码审查(1.14 起,给开发同事和评审人)。</strong> 需求页面上点**&quot;代码审查&quot;**(终端里是 <code>req code-review &lt;需求&gt;</code>),代码审查页在 Paseo 里打开:</p><ul><li>列出这次改动的全部文件(相对需求分支的起点,需求文档排在最后、默认折叠),上面是提测说明里&quot;这次改了什么&quot;。</li><li>AI 代码评审的每条意见放在它说的那一行旁边,标着级别(阻塞 / 重要 / 建议)和修复步骤的处理结果(已修复、判为不成立、决定不修复);可以标<strong>要改</strong>或<strong>不用改</strong>,补一句话。</li><li>点任意一行代码写意见;最下面可以写总体意见。</li><li><strong>审核人</strong>默认取自仓库的 <code>CODEOWNERS</code>(按改动的文件),提交前可以改;以后建合并请求时会用它。</li><li><strong>退回修改</strong>:意见写进 <code>code-review.md</code> 的&quot;人工评审&quot;一节(HR-1 起)和 <code>changes.md</code>,流水线随即开始新的一次尝试,需求说明不变,从方案设计开始只处理这些意见,改完再经过 AI 代码评审和验证,进展发回需求的对话。<strong>评审通过</strong>:记下评审人和审核人;之后代码又有改动时,页面会提示需要重新评审。</li></ul><p><strong>在插件里自己验收(1.14 起)。</strong> 需求页面上点**&quot;验收清单(可一键试用)&quot;**(终端里是 <code>req checklist &lt;需求&gt;</code>),验收清单在 Paseo 里打开:</p><ul><li><p>每条验收标准写着前置条件、怎么操作、应该看到什么,以及流水线的验证结果;流水线没验证或没通过的排在最前面,报告里&quot;需要你确认的决定&quot;也列在后面请你表态。</p></li><li><p>右上角**&quot;把它跑起来试用&quot;**(终端里是 <code>req try &lt;需求&gt;</code>):用项目的 Paseo 服务脚本(<code>paseo.json</code>)在这个需求自己的工作区里把它启动起来,给出访问地址和提测说明里的测试账号、数据;用完点&quot;停止试用&quot;。项目没有服务脚本时,会给出提测说明里写的启动方法,也可以在需求的对话里说&quot;帮我把它跑起来&quot;。</p></li><li><p>每条点&quot;通过&quot;、&quot;不对&quot;(写下看到了什么)或&quot;先不验&quot;,进度自动保存。必须验的都核对完才能提交&quot;通过&quot;;有&quot;不对&quot;的就提交&quot;不通过&quot;。</p></li><li><p>提交后写成 <code>acceptance.md</code> 并提交。不通过时,不对的地方会转给这个需求的对话,它会和你一起确定怎么处理。</p></li><li><p><strong>全部通过</strong>:请开发同事审阅代码并合并上线。流水线只做本地提交,不会自己合并或上线。</p></li><li><p><strong>有不通过的</strong>:逐项决定怎么处理:做得不对的,补进需求说明后继续开发;发现想要的不是这样的,按改需求处理;也可以接受现状并记下理由。</p></li></ul><p>测试同事可以把验收标准直接转成测试用例:每条都写成了&quot;前置条件 / 操作 / 预期结果&quot;。</p><h2 id="上线后发现问题" tabindex="-1">上线后发现问题 <a class="header-anchor" href="#上线后发现问题" aria-label="Permalink to &quot;上线后发现问题&quot;">​</a></h2><p>说&quot;线上发现……不对&quot;。AI 会先问这个问题是否正在影响真实用户:是的话,请马上联系开发同事或值班人员处理线上情况(req-kit 不碰生产环境)。然后它会问清现象、复现步骤、影响范围,关联到原来的需求,生成一份缺陷说明,按快速流程修复,修复后照常验收。</p><h2 id="注意" tabindex="-1">注意 <a class="header-anchor" href="#注意" aria-label="Permalink to &quot;注意&quot;">​</a></h2><ul><li>一个对话只谈一个需求;对话过程中不要切换工作目录。</li><li>需求属于另一个项目时,到那个项目里新开对话。</li><li>遇到&quot;未启动&quot;或其他看不懂的情况,输入 <code>/req-doctor</code> 做一次体检,或请开发同事看一下。</li></ul></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/docs/guide/使用者指南.md">docs/guide/使用者指南.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/docs/guide/使用者指南.md">在 GitHub 上编辑</a></p>',2)])])}const p=o(u,[["render",q]]);export{g as __pageData,p as default};
1
+ import{_ as o,o as e,c as d,a3 as r}from"./chunks/framework.B9qR_F1m.js";const g=JSON.parse('{"title":"使用者指南","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"guide/user.md","filePath":"guide/user.md","lastUpdated":null}'),u={name:"guide/user.md"};function q(s,t,l,i,a,n){return e(),d("div",null,[...t[0]||(t[0]=[r('<div><h1 id="使用者指南" tabindex="-1">使用者指南 <a class="header-anchor" href="#使用者指南" aria-label="Permalink to &quot;使用者指南&quot;">​</a></h1><p>req-kit 帮你把一个需求从&quot;我想要……&quot;做到&quot;可以验收&quot;:你在 Paseo 的对话里把需求讲清楚、确认一份需求说明,之后的方案设计、写代码、评审、测试和报告由一组 AI agent 在后台完成,结果发回同一个对话。</p><p>适合测试、产品经理、项目经理等不写代码、但熟悉需求和测试的同事。你不需要读代码,但可以随时查看每一步的产物,也可以亲自执行测试命令核对结果。</p><h2 id="第一次使用之前" tabindex="-1">第一次使用之前 <a class="header-anchor" href="#第一次使用之前" aria-label="Permalink to &quot;第一次使用之前&quot;">​</a></h2><p>请开发同事确认这台机器已经装好 req-kit(<code>/req-doctor</code> 全部正常),并且项目已经接入:在项目根目录的对话中运行过 <code>/req-setup</code>,生成了项目说明和验证方法。测试同事熟悉项目的话,也可以自己运行 <code>/req-setup</code>。</p><h2 id="提一个需求" tabindex="-1">提一个需求 <a class="header-anchor" href="#提一个需求" aria-label="Permalink to &quot;提一个需求&quot;">​</a></h2><ol><li><strong>准备工作区</strong>:每个需求最好有自己的 worktree 工作区,几个需求可以同时进行,互不影响。两种方式任选: <ul><li>直接在项目的对话里开始,AI 问到时选&quot;开发时自动新建工作区&quot;:照常谈需求,启动开发时流水线会自动新建工作区并在那里开发,这个对话不用动。</li><li>自己新建:在 Paseo 中点 <strong>New workspace</strong> → 选择项目 → <strong>Isolation</strong> 选 <strong>New worktree</strong> → 起点选主分支,然后在新工作区的对话里开始。</li></ul></li><li><strong>输入 <code>/req</code> 和一句话</strong>:例如 <code>/req 登录页增加短信验证码登录</code>。用 Pi 时输入 <code>/skill:req ……</code>。</li><li><strong>回答问题</strong>:AI 会先复述它的理解,然后一次问一个问题,给出选项和推荐。它会问到异常情况、权限、已有数据、测试数据和验证环境,这些往往是你最清楚的。拿不准时可以说&quot;你定&quot;,它会采用推荐项并记为假设,最后请你过目。</li><li><strong>独立审阅</strong>(标准档):确认之前,AI 会请另一个模型把需求说明独立审一遍,几分钟后把发现的问题(歧义、遗漏、没法验证的验收标准)逐个问你。这一步常常能省掉开发之后的返工。</li><li><strong>确认需求说明</strong>:AI 给出一份 10 行以内的摘要,完整的需求说明在 <code>docs/features/&lt;日期&gt;-&lt;名称&gt;/spec.md</code>。确认后它会问是否开始开发。</li><li><strong>等待</strong>:开发在后台进行,通常需要几个小时,不需要盯着。期间你会收到几句进展(方案定了、开始验证等)。</li></ol><p>小改动(改文案、样式、一个配置项)会走快速流程:只问 2–3 个问题,开发环节各做一轮。</p><p><strong>需求的类型</strong>:AI 复述时会和你确认这是哪一类,流水线按类型走不同的做法:</p><table tabindex="0"><thead><tr><th>类型</th><th>说法举例</th><th>流水线怎么做</th><th>你需要讲清楚的</th></tr></thead><tbody><tr><td>新需求</td><td>&quot;加一个……&quot;</td><td>方案、实现、评审、验证</td><td>要什么、怎么算做对</td></tr><tr><td>缺陷</td><td>&quot;……不对&quot;&quot;报错了&quot;</td><td>先复现、找到原因再修;复现不了会回来问你</td><td>复现步骤:环境、账号或数据、操作、看到的、应有的</td></tr><tr><td>重构</td><td>&quot;整理一下……&quot;&quot;升级依赖&quot;</td><td>先用测试锁住现有行为,再小步改,确认行为没变</td><td>改进目标,以及哪些行为必须保持不变</td></tr><tr><td>评估</td><td>&quot;能不能做……&quot;&quot;影响多大&quot;</td><td>只调研、写评估报告,由另一个模型审阅,不写代码</td><td>要回答的问题,结论用来做什么决定</td></tr></tbody></table><p>评估做完后,可以直接说&quot;按评估结果提一个新需求&quot;。</p><p><strong>前端和后端都要改</strong>:另一个仓库已经由开发同事登记过(<code>/req-setup</code> 时登记)的,AI 会问是否作为联合需求一起做:流水线先设计整体方案和双方的接口约定,再在每个仓库各开一个工作区同时开发,最后一起验证,报告里写明每个仓库的分支和合并顺序。</p><p><strong>验收标准带例子</strong>:AI 写验收标准时会给每条配上具体的数据(&quot;输入 13800000000,60 秒内再点发送,提示&#39;请 45 秒后重试&#39;&quot;)。请认真看这些例子:它们会直接变成测试检查的期望值,你确认的就是测试会检查的东西。</p><p><strong>开工前先看一眼&quot;做完后会看到什么&quot;</strong>(标准档的界面改动):方案审核通过后、写代码之前,流水线会停下来,AI 把 <code>preview.md</code> 的要点讲给你听:会看到什么变化、有哪些需要你确认的假设;界面改动还会有静态的原型页面(功能目录的 <code>prototype/</code> 中),可以在浏览器里打开看。说&quot;可以&quot;就开始写代码;想改的直接说,AI 会更新需求说明,方案调整后再请你看一次。这时调整的成本最低。</p><p><strong>研发和测试分开做</strong>(标准档,确定档位时 AI 会问,团队配置里定好了就不问):</p><ul><li><strong>连续</strong>(默认):研发完成后流水线接着做测试验证,一次跑完。</li><li><strong>分阶段</strong>:研发完成、写好提测说明(<code>handoff.md</code>)后停下来通知你:&quot;研发完成,可以提测&quot;。你或测试同事准备好之后说&quot;开始测试验证&quot;,AI 会讲一遍提测说明,问清在哪里测(本地,或已部署的测试环境)、发现缺陷怎么办(当场修复、退回研发修复后再提测,或只记录),然后开始;也可以预约时间。用&quot;开发时自动新建工作区&quot;开发的需求,测试同事可以在自己的对话里输入 <code>/req 开始测试验证 &lt;需求名称&gt;</code> 接手。</li><li><strong>只做研发</strong>:做到提测说明和研发报告为止,测试由人完成,验收时 AI 会按提测说明带你逐条测试。</li></ul><h2 id="过程中" tabindex="-1">过程中 <a class="header-anchor" href="#过程中" aria-label="Permalink to &quot;过程中&quot;">​</a></h2><table tabindex="0"><thead><tr><th>你想做的</th><th>在对话里说</th></tr></thead><tbody><tr><td>看进度</td><td>&quot;做到哪了&quot;(会说明当前在哪一步、agent 最近在做什么,例如正在运行测试)</td></tr><tr><td>暂停</td><td>&quot;先停一下&quot;(当前步骤做到一半的工作不保留,已完成的步骤保留)</td></tr><tr><td>继续</td><td>&quot;继续开发&quot;</td></tr><tr><td>确认方案</td><td>收到&quot;请确认方案&quot;时,看过之后说&quot;可以,按这个做&quot;,或者说要改哪里</td></tr><tr><td>改需求</td><td>&quot;我想改一下……&quot;:先暂停,谈清变化的部分,更新需求说明(版本加 1,记入 <code>changes.md</code>)后继续,开发会在已有方案和代码的基础上只处理变化的部分。开发已经完成的也可以改</td></tr><tr><td>看看项目里有哪些需求</td><td>&quot;现在有哪些需求&quot;:列出所有工作区中的需求和各自的阶段</td></tr><tr><td>研发完成后提测</td><td>&quot;开始测试验证&quot;(分阶段执行时);想晚点开始就说&quot;等测试环境部署好,明早 9 点开始测试&quot;</td></tr><tr><td>晚点再开始</td><td>确认需求后说&quot;今晚 10 点开始&quot;&quot;明天早上开始&quot;:到时会在这个对话里自动开始,说&quot;先停一下&quot;可以取消</td></tr><tr><td>接手别人的需求</td><td>&quot;这个需求之前是同事提的,现在什么情况&quot;:讲清现状、待决事项和下一步</td></tr></tbody></table><p>也可以不进对话,在终端里用 <code>req</code> 命令(需要开发同事装好并加入 PATH,见 <a href="./install">安装与升级</a>):在项目目录中 <code>req list</code> 看所有需求,<code>req status</code> 看进度(多个需求时写名称的一部分,如 <code>req status sms-login</code>),<code>req stop</code>、<code>req resume</code> 暂停和继续。</p><p>装了 req-kit 插件的话(见 <a href="./install">安装与升级</a> 第 13 节),在 Paseo 侧边栏点&quot;需求&quot;:本机所有项目的需求一页看完,&quot;需要你处理&quot;的排在最前;点开一个需求能看到每一步的进度和用时、读需求说明、方案、确认预览和完成报告,也可以直接确认方案、停止、继续或开始测试验证。网页端、桌面版和手机上都能用。</p><p>1.14 起,需求从开始谈的时候就出现在插件里(状态&quot;对齐中&quot;);需求说明确认了却还没开始开发(超过 30 分钟),或者上次启动没成功的,会出现在&quot;等你处理&quot;里,点&quot;开始开发&quot;就能开始,进展照常发回谈需求的那个对话。</p><p>1.12 起,首页最上面是&quot;等你处理&quot;:所有等你确认方案、回答问题、中断了的需求,等得最久的在前,每条写明要做什么、等了多久。方案可以直接确认,也可以写修改意见;方案审核的问题可以直接写回答,插件会转给这个需求的对话,效果和在对话里回答一样。首页的&quot;配置&quot;列出 req-kit 的全部设置:每一项是什么、现在的值、来自本机、团队还是项目的配置文件,可以按项目查看、搜索、只看改过的。</p><p><strong>在原型上提意见(1.13 起)。</strong> 界面改动的需求,在请你确认方案时会有一份界面原型。在插件首页的&quot;等你处理&quot;或需求页面最上面,点**&quot;审查原型并确认方案&quot;**按钮(终端里是 <code>req review &lt;需求&gt;</code>),原型审查页就在 Paseo 里打开(手机上会在浏览器中打开;嫌窗口小时点右上角&quot;在新窗口打开&quot;):</p><ul><li>标着 ①②③ 的是这次要改的地方,右边写着各自对应的验收标准,顺着看就不会漏。</li><li>想改哪里就<strong>点哪里</strong>,选一种改法(文字改成…、大一点、换颜色、换位置、删掉、这里加东西……),再用自己的话补一句。不用想专业词汇,你点的是哪个按钮、原来是什么颜色和大小,页面会自动记下来交给 AI。</li><li>想换文字就<strong>双击文字</strong>,直接改成你想要的字。</li><li>正常、出错、空数据这些状态,以及电脑、手机宽度,在页面上方切换。</li><li>写的意见会自动保存。看完后点&quot;提交修改意见&quot;,需求会话会据此改需求说明,改好后请你再确认;改过的原型再打开时,会用绿色框标出这一版改了哪里。没有要改的,点&quot;同意开始写代码&quot;。</li></ul><p><strong>还要多久(1.13 起)。</strong> 本机做完过 3 个以上同档位的需求后,开始开发时会告诉你这类需求通常要多久、用多少 token;问&quot;做到哪了&quot;或在插件的需求页面里,会看到&quot;预计还要约多久&quot;(不含等人确认的时间)。</p><p>每个步骤都会出现在这个对话的子 agent 列表里(名字形如&quot;[20261012-sms-login] 6-代码评审 第2轮&quot;),点开可以看到它在做什么。功能目录下的 <code>progress.md</code> 按时间记录了每一步的结果。</p><p>可能收到的通知(团队接入了企业 IM 的话,这些通知也会发到 IM):</p><ul><li><strong>需要你决定</strong>:方案审核发现只有你能回答的问题。AI 会逐个问你,然后继续。一天没有回答的话,会在对话里提醒一次。</li><li><strong>研发完成,可以提测</strong>(分阶段执行时):代码已写完并通过评审,提测说明在 <code>handoff.md</code>。一天没有开始测试验证的话,会在对话里提醒一次。</li><li><strong>等待批准</strong>:某一步在等权限批准,按提示打开对应的 agent 处理,或请开发同事处理。1.13 起插件的&quot;等你处理&quot;里也会显示,列出要批准的操作,点&quot;打开这个 agent&quot;直接去处理。</li><li><strong>token 用量提醒</strong>(团队设了 token 预算时):用到预算的一定比例时告知一次,开发照常进行;用完时做完当前步骤就停下,AI 会告诉你用了多少、问你是否继续。继续会再给一份预算。</li><li><strong>中断</strong>:限流、网络中断这类临时问题会先自动等待重试,仍然不行才中断,并预约半小时后自动继续(说&quot;先停一下&quot;可以取消)。AI 会说明原因和日志位置。环境类问题(例如测试服务没启动)你可以自己处理;涉及配置或代码的请开发同事处理。处理后说&quot;继续开发&quot;。</li></ul><h2 id="验收" tabindex="-1">验收 <a class="header-anchor" href="#验收" aria-label="Permalink to &quot;验收&quot;">​</a></h2><p>完成后你会收到结论和摘要,完整报告在功能目录的 <code>report.md</code>:</p><ul><li><strong>验收对照表</strong>:每条验收标准的结果,以及是怎么确认的(运行了什么命令、看到了什么、截图在哪里)。</li><li><strong>需要你确认的决定</strong>:开发过程中替你做的假设和取舍,以及被驳回的评审意见里会影响结果的那些。请逐条表态。</li><li><strong>遗留问题</strong>和<strong>需要你做的事</strong>。</li><li><strong>用时与用量</strong>:各步骤 agent 合计用了多长时间、多少 token、大约多少费用,便于估算后续需求的成本。</li></ul><p>然后说&quot;我要验收&quot;。AI 会按验收标准一条一条带你核对:告诉你怎么操作、应该看到什么;能用命令验证的给出命令,你可以自己执行。每条结果记入功能目录的 <code>acceptance.md</code>。</p><p><strong>代码审查(1.14 起,给开发同事和评审人)。</strong> 需求页面上点**&quot;代码审查&quot;**(终端里是 <code>req code-review &lt;需求&gt;</code>),代码审查页在 Paseo 里打开:</p><ul><li>列出这次改动的全部文件(相对需求分支的起点,需求文档排在最后、默认折叠),上面是提测说明里&quot;这次改了什么&quot;。</li><li>AI 代码评审的每条意见放在它说的那一行旁边,标着级别(阻塞 / 重要 / 建议)和修复步骤的处理结果(已修复、判为不成立、决定不修复);可以标<strong>要改</strong>或<strong>不用改</strong>,补一句话。</li><li>点任意一行代码写意见;最下面可以写总体意见。</li><li><strong>审核人</strong>默认取自仓库的 <code>CODEOWNERS</code>(按改动的文件),提交前可以改;以后建合并请求时会用它。</li><li><strong>退回修改</strong>:意见写进 <code>code-review.md</code> 的&quot;人工评审&quot;一节(HR-1 起)和 <code>changes.md</code>,流水线随即开始新的一次尝试,需求说明不变,从方案设计开始只处理这些意见,改完再经过 AI 代码评审和验证,进展发回需求的对话。<strong>评审通过</strong>:记下评审人和审核人;之后代码又有改动时,页面会提示需要重新评审。</li></ul><p><strong>在插件里自己验收(1.14 起)。</strong> 需求页面上点**&quot;验收清单(可一键试用)&quot;**(终端里是 <code>req checklist &lt;需求&gt;</code>),验收清单在 Paseo 里打开:</p><ul><li><p>每条验收标准写着前置条件、怎么操作、应该看到什么,以及流水线的验证结果;流水线没验证或没通过的排在最前面,报告里&quot;需要你确认的决定&quot;也列在后面请你表态。</p></li><li><p>右上角**&quot;把它跑起来试用&quot;**(终端里是 <code>req try &lt;需求&gt;</code>):用项目的 Paseo 服务脚本(<code>paseo.json</code>)在这个需求自己的工作区里把它启动起来,给出访问地址和提测说明里的测试账号、数据;用完点&quot;停止试用&quot;。项目没有服务脚本时,会给出提测说明里写的启动方法,也可以在需求的对话里说&quot;帮我把它跑起来&quot;。</p></li><li><p>每条点&quot;通过&quot;、&quot;不对&quot;(写下看到了什么)或&quot;先不验&quot;,进度自动保存。必须验的都核对完才能提交&quot;通过&quot;;有&quot;不对&quot;的就提交&quot;不通过&quot;。</p></li><li><p>提交后写成 <code>acceptance.md</code> 并提交。不通过时,不对的地方会转给这个需求的对话,它会和你一起确定怎么处理。</p></li><li><p><strong>全部通过</strong>:请开发同事审阅代码并合并上线。流水线只做本地提交,不会自己合并或上线。</p></li><li><p><strong>有不通过的</strong>:逐项决定怎么处理:做得不对的,补进需求说明后继续开发;发现想要的不是这样的,按改需求处理;也可以接受现状并记下理由。</p></li></ul><p>测试同事可以把验收标准直接转成测试用例:每条都写成了&quot;前置条件 / 操作 / 预期结果&quot;。</p><p><strong>记录会留下来(1.14 起)。</strong> 代码审查和验收的结论、评审人、每条意见都写在需求目录的 <code>code-review.md</code>、<code>acceptance.md</code>(退回修改的原因在 <code>changes.md</code>)里,随需求分支提交,合并后在主干上也能查。结论和数量另外记在本机的使用记录里,<code>req stats</code> 能看到人工评审退回了几次、验收通过率、合并进主干的需求和合并后发现的问题。</p><h2 id="上线后发现问题" tabindex="-1">上线后发现问题 <a class="header-anchor" href="#上线后发现问题" aria-label="Permalink to &quot;上线后发现问题&quot;">​</a></h2><p>说&quot;线上发现……不对&quot;。AI 会先问这个问题是否正在影响真实用户:是的话,请马上联系开发同事或值班人员处理线上情况(req-kit 不碰生产环境)。然后它会问清现象、复现步骤、影响范围,关联到原来的需求,生成一份缺陷说明,按快速流程修复,修复后照常验收。缺陷说明里写明是哪个需求引入的问题,<code>req stats</code> 会把它算作那个需求&quot;合并后发现的问题&quot;;也可以在终端里手动记一笔:<code>req outcome &lt;需求&gt; --issue &quot;&lt;问题&gt;&quot;</code>。</p><h2 id="注意" tabindex="-1">注意 <a class="header-anchor" href="#注意" aria-label="Permalink to &quot;注意&quot;">​</a></h2><ul><li>一个对话只谈一个需求;对话过程中不要切换工作目录。</li><li>需求属于另一个项目时,到那个项目里新开对话。</li><li>遇到&quot;未启动&quot;或其他看不懂的情况,输入 <code>/req-doctor</code> 做一次体检,或请开发同事看一下。</li></ul></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/docs/guide/使用者指南.md">docs/guide/使用者指南.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/docs/guide/使用者指南.md">在 GitHub 上编辑</a></p>',2)])])}const p=o(u,[["render",q]]);export{g as __pageData,p as default};
@@ -1 +1 @@
1
- import{_ as o,o as e,c as r,a3 as d}from"./chunks/framework.B9qR_F1m.js";const g=JSON.parse('{"title":"使用者指南","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"guide/user.md","filePath":"guide/user.md","lastUpdated":null}'),u={name:"guide/user.md"};function q(s,t,l,i,a,n){return e(),r("div",null,[...t[0]||(t[0]=[d("",2)])])}const p=o(u,[["render",q]]);export{g as __pageData,p as default};
1
+ import{_ as o,o as e,c as d,a3 as r}from"./chunks/framework.B9qR_F1m.js";const g=JSON.parse('{"title":"使用者指南","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"guide/user.md","filePath":"guide/user.md","lastUpdated":null}'),u={name:"guide/user.md"};function q(s,t,l,i,a,n){return e(),d("div",null,[...t[0]||(t[0]=[r("",2)])])}const p=o(u,[["render",q]]);export{g as __pageData,p as default};
@@ -21,4 +21,4 @@ import{_ as e,o as t,c as n,j as i,a as s}from"./chunks/framework.B9qR_F1m.js";c
21
21
  `),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "requester"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"张广祥"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
22
22
  `),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "card"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"system"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"ALM"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"id"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"CMASTER-BUSINESS#9902"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"url"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"null"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," },")]),s(`
23
23
  `),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "recipients"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": [{ "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"name"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"张广祥"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"accounts"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"um"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"ZHANGGX001"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," } }]")]),s(`
24
- `),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"}")])])])]),i("ul",null,[i("li",null,[i("code",null,"audience"),s(":"),i("code",null,"requester"),s(" 表示这件事要需求方处理或是给他的结果("),i("code",null,"blocked"),s("、"),i("code",null,"approval"),s("、"),i("code",null,"phase_done"),s("、"),i("code",null,"completed"),s(",而且需求从卡片开始、知道提出人);其余为 "),i("code",null,"team"),s(",发到群里即可。")]),i("li",null,[i("code",null,"requester"),s("、"),i("code",null,"card"),s(":从卡片开始的需求的提出人和卡片;其他需求为 null。")]),i("li",null,[i("code",null,"recipients"),s(":"),i("code",null,"audience"),s(" 为 "),i("code",null,"requester"),s(" 时是需求方本人;"),i("code",null,"accounts"),s(" 来自本机或团队配置的 "),i("code",null,"people"),s("(姓名 → 各种账号),没有写时为 "),i("code",null,"{}"),s(",模块可以改发到群。")])]),i("table",{tabindex:"0"},[i("thead",null,[i("tr",null,[i("th",null,"type"),i("th",null,"什么时候"),i("th",null,"details")])]),i("tbody",null,[i("tr",null,[i("td",null,[i("code",null,"milestone")]),i("td",null,[s("方案确定、开始验证、开始修复缺陷(配置 "),i("code",null,"notifyMilestones"),s(" 为 true 时,每次尝试各一次)")]),i("td",null,[i("code",null,"milestone"),s(":"),i("code",null,"design-settled"),s("、"),i("code",null,"code-reviewed"),s("、"),i("code",null,"fixing-defects"),s("、"),i("code",null,"handback-<n>"),s("(1.7.0 起,测试验证第 n 次把缺陷退回研发)")])]),i("tr",null,[i("td",null,[i("code",null,"blocked")]),i("td",null,"方案审核发现需要需求方决定的问题,流水线已暂停"),i("td",null,[i("code",null,"questions"),s("(字符串数组)、"),i("code",null,"resumeCommand")])]),i("tr",null,[i("td",null,[i("code",null,"permission")]),i("td",null,"步骤 agent 在等待权限批准"),i("td",null,[i("code",null,"stepTitle"),s("、"),i("code",null,"agentTitle"),s("、"),i("code",null,"requests"),s("(字符串数组)")])]),i("tr",null,[i("td",null,[i("code",null,"failed")]),i("td",null,"流水线因错误中断(已自动重试过的临时错误除外)"),i("td",null,[i("code",null,"stepTitle"),s("、"),i("code",null,"reason"),s("、"),i("code",null,"logPath"),s("、"),i("code",null,"resumeCommand")])]),i("tr",null,[i("td",null,[i("code",null,"completed")]),i("td",null,"流水线结束,报告已生成"),i("td",null,[i("code",null,"outcome"),s("("),i("code",null,"completed"),s("、"),i("code",null,"completed_with_issues"),s("、"),i("code",null,"not_completed"),s(")、"),i("code",null,"summary"),s("、"),i("code",null,"reportPath"),s('。"只做研发"时另有 '),i("code",null,"mode"),s("("),i("code",null,"develop-only"),s(")和 "),i("code",null,"handoffPath"),s(",报告是研发报告,需要人工测试")])]),i("tr",null,[i("td",null,[i("code",null,"approval")]),i("td",null,[s("1.8.0 起。方案确认点("),i("code",null,"designApproval"),s('):方案已通过审核,等待需求方确认"做完后会看到什么",还没有开始写代码')]),i("td",null,[i("code",null,"previewPath"),s("(要确认的内容)、"),i("code",null,"approveCommand"),s("(确认后继续的命令)、"),i("code",null,"resumeCommand"),s("(修改需求后继续的命令),都在发起的对话中执行")])]),i("tr",null,[i("td",null,[i("code",null,"phase_done")]),i("td",null,"1.7.0 起。分阶段执行时研发阶段已完成(代码已通过评审、提测说明已写好),流水线停在闸口等待测试验证。测试退回后再次修完也会发"),i("td",null,[i("code",null,"handoffPath"),s("(提测说明)、"),i("code",null,"mode"),s("("),i("code",null,"gated"),s(")、"),i("code",null,"verifyCommand"),s("(开始测试验证的命令,在发起的对话中执行)、"),i("code",null,"verifyAt"),s("(预约的开始时间,ISO 格式,没有为 null)、"),i("code",null,"handbacks"),s("(已退回的次数)")])]),i("tr",null,[i("td",null,[i("code",null,"alert")]),i("td",null,[s("1.12 起。接单器("),i("code",null,"req factory"),s(")自检没有通过(Paseo 连不上、agent 没有登录、额度用完、需求管理系统的命令不可用),暂停接新卡片;或者恢复正常。同样的问题只发一次。"),i("code",null,"feature.title"),s(' 为"接单器",'),i("code",null,"feature.dir"),s("、"),i("code",null,"repo"),s(" 为空")]),i("td",null,[i("code",null,"source"),s("("),i("code",null,"factory"),s(")、"),i("code",null,"machine"),s("、"),i("code",null,"problems"),s("(字符串数组,恢复时为空)、"),i("code",null,"recovered")])]),i("tr",null,[i("td",null,[i("code",null,"digest")]),i("td",null,[i("code",null,"req digest --notify"),s("(或由 "),i("code",null,"req digest --schedule"),s(" 创建的 Paseo 定时任务)发送项目的需求总览,1.6.0 起。"),i("code",null,"feature.title"),s(' 为"<项目> 需求总览",'),i("code",null,"text"),s(" 是完整的多行总览")]),i("td",null,[i("code",null,"features"),s(":每个需求的 "),i("code",null,"name"),s("、"),i("code",null,"title"),s("、"),i("code",null,"stage"),s("、"),i("code",null,"branch"),s("、"),i("code",null,"updatedAt"),s("、"),i("code",null,"usage"),s(";"),i("code",null,"recurringLessons"),s("(1.8.0 起):在两个以上需求的 "),i("code",null,"lessons.tsv"),s(" 中出现的问题类别,每项 "),i("code",null,"category"),s("、"),i("code",null,"features"),s("、"),i("code",null,"rules")])])])]),i("h2",{id:"兼容性",tabindex:"-1"},[s("兼容性 "),i("a",{class:"header-anchor",href:"#兼容性","aria-label":'Permalink to "兼容性"'},"​")]),i("ul",null,[i("li",null,[s("同一 "),i("code",null,"schema"),s(" 内只增加字段,不删除、不改含义;模块应忽略不认识的字段和事件类型。")]),i("li",null,[s("不兼容的变化会提升 "),i("code",null,"schema"),s(",并在 "),i("code",null,"CHANGELOG.md"),s(' 的"升级须知"中说明。')])])],-1),i("p",{class:"source-note"},[s("本页由仓库中的 "),i("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/notifier-event.md"},"contracts/notifier-event.md"),s(" 生成。"),i("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/notifier-event.md"},"在 GitHub 上编辑")],-1)])])}const c=e(a,[["render",h]]);export{u as __pageData,c as default};
24
+ `),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"}")])])])]),i("ul",null,[i("li",null,[i("code",null,"audience"),s(":"),i("code",null,"requester"),s(" 表示这件事要需求方处理或是给他的结果("),i("code",null,"blocked"),s("、"),i("code",null,"approval"),s("、"),i("code",null,"phase_done"),s("、"),i("code",null,"completed"),s(",而且需求从卡片开始、知道提出人);其余为 "),i("code",null,"team"),s(",发到群里即可。")]),i("li",null,[i("code",null,"requester"),s("、"),i("code",null,"card"),s(":从卡片开始的需求的提出人和卡片;其他需求为 null。")]),i("li",null,[i("code",null,"recipients"),s(":"),i("code",null,"audience"),s(" 为 "),i("code",null,"requester"),s(" 时是需求方本人;"),i("code",null,"accounts"),s(" 来自本机或团队配置的 "),i("code",null,"people"),s("(姓名 → 各种账号),没有写时为 "),i("code",null,"{}"),s(",模块可以改发到群。")])]),i("table",{tabindex:"0"},[i("thead",null,[i("tr",null,[i("th",null,"type"),i("th",null,"什么时候"),i("th",null,"details")])]),i("tbody",null,[i("tr",null,[i("td",null,[i("code",null,"milestone")]),i("td",null,[s("方案确定、开始验证、开始修复缺陷(配置 "),i("code",null,"notifyMilestones"),s(" 为 true 时,每次尝试各一次)")]),i("td",null,[i("code",null,"milestone"),s(":"),i("code",null,"design-settled"),s("、"),i("code",null,"code-reviewed"),s("、"),i("code",null,"fixing-defects"),s("、"),i("code",null,"handback-<n>"),s("(1.7.0 起,测试验证第 n 次把缺陷退回研发)")])]),i("tr",null,[i("td",null,[i("code",null,"blocked")]),i("td",null,"方案审核发现需要需求方决定的问题,流水线已暂停"),i("td",null,[i("code",null,"questions"),s("(字符串数组)、"),i("code",null,"resumeCommand")])]),i("tr",null,[i("td",null,[i("code",null,"permission")]),i("td",null,"步骤 agent 在等待权限批准"),i("td",null,[i("code",null,"stepTitle"),s("、"),i("code",null,"agentTitle"),s("、"),i("code",null,"requests"),s("(字符串数组)")])]),i("tr",null,[i("td",null,[i("code",null,"failed")]),i("td",null,"流水线因错误中断(已自动重试过的临时错误除外)"),i("td",null,[i("code",null,"stepTitle"),s("、"),i("code",null,"reason"),s("、"),i("code",null,"logPath"),s("、"),i("code",null,"resumeCommand")])]),i("tr",null,[i("td",null,[i("code",null,"completed")]),i("td",null,"流水线结束,报告已生成"),i("td",null,[i("code",null,"outcome"),s("("),i("code",null,"completed"),s("、"),i("code",null,"completed_with_issues"),s("、"),i("code",null,"not_completed"),s(")、"),i("code",null,"summary"),s("、"),i("code",null,"reportPath"),s('。"只做研发"时另有 '),i("code",null,"mode"),s("("),i("code",null,"develop-only"),s(")和 "),i("code",null,"handoffPath"),s(",报告是研发报告,需要人工测试")])]),i("tr",null,[i("td",null,[i("code",null,"approval")]),i("td",null,[s("1.8.0 起。方案确认点("),i("code",null,"designApproval"),s('):方案已通过审核,等待需求方确认"做完后会看到什么",还没有开始写代码')]),i("td",null,[i("code",null,"previewPath"),s("(要确认的内容)、"),i("code",null,"approveCommand"),s("(确认后继续的命令)、"),i("code",null,"resumeCommand"),s("(修改需求后继续的命令),都在发起的对话中执行")])]),i("tr",null,[i("td",null,[i("code",null,"phase_done")]),i("td",null,"1.7.0 起。分阶段执行时研发阶段已完成(代码已通过评审、提测说明已写好),流水线停在闸口等待测试验证。测试退回后再次修完也会发"),i("td",null,[i("code",null,"handoffPath"),s("(提测说明)、"),i("code",null,"mode"),s("("),i("code",null,"gated"),s(")、"),i("code",null,"verifyCommand"),s("(开始测试验证的命令,在发起的对话中执行)、"),i("code",null,"verifyAt"),s("(预约的开始时间,ISO 格式,没有为 null)、"),i("code",null,"handbacks"),s("(已退回的次数)")])]),i("tr",null,[i("td",null,[i("code",null,"alert")]),i("td",null,[s("1.12 起。接单器("),i("code",null,"req factory"),s(")自检没有通过(Paseo 连不上、agent 没有登录、额度用完、需求管理系统的命令不可用),暂停接新卡片;或者恢复正常。同样的问题只发一次。"),i("code",null,"feature.title"),s(' 为"接单器",'),i("code",null,"feature.dir"),s("、"),i("code",null,"repo"),s(" 为空")]),i("td",null,[i("code",null,"source"),s("("),i("code",null,"factory"),s(")、"),i("code",null,"machine"),s("、"),i("code",null,"problems"),s("(字符串数组,恢复时为空)、"),i("code",null,"recovered"),s("。1.14 起,步骤 agent 运行或开始运行危险命令("),i("code",null,"dangerGuard"),s(")时也发:"),i("code",null,"details.kind"),s(" 为 "),i("code",null,"danger"),s(",另有 "),i("code",null,"stepTitle"),s("、"),i("code",null,"command"),s("、"),i("code",null,"label"),s("、"),i("code",null,"ran"),s(";这时 "),i("code",null,"feature"),s("、"),i("code",null,"repo"),s(" 是那个需求的")])]),i("tr",null,[i("td",null,[i("code",null,"digest")]),i("td",null,[i("code",null,"req digest --notify"),s("(或由 "),i("code",null,"req digest --schedule"),s(" 创建的 Paseo 定时任务)发送项目的需求总览,1.6.0 起。"),i("code",null,"feature.title"),s(' 为"<项目> 需求总览",'),i("code",null,"text"),s(" 是完整的多行总览")]),i("td",null,[i("code",null,"features"),s(":每个需求的 "),i("code",null,"name"),s("、"),i("code",null,"title"),s("、"),i("code",null,"stage"),s("、"),i("code",null,"branch"),s("、"),i("code",null,"updatedAt"),s("、"),i("code",null,"usage"),s(";"),i("code",null,"recurringLessons"),s("(1.8.0 起):在两个以上需求的 "),i("code",null,"lessons.tsv"),s(" 中出现的问题类别,每项 "),i("code",null,"category"),s("、"),i("code",null,"features"),s("、"),i("code",null,"rules")])])])]),i("h2",{id:"兼容性",tabindex:"-1"},[s("兼容性 "),i("a",{class:"header-anchor",href:"#兼容性","aria-label":'Permalink to "兼容性"'},"​")]),i("ul",null,[i("li",null,[s("同一 "),i("code",null,"schema"),s(" 内只增加字段,不删除、不改含义;模块应忽略不认识的字段和事件类型。")]),i("li",null,[s("不兼容的变化会提升 "),i("code",null,"schema"),s(",并在 "),i("code",null,"CHANGELOG.md"),s(' 的"升级须知"中说明。')])])],-1),i("p",{class:"source-note"},[s("本页由仓库中的 "),i("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/notifier-event.md"},"contracts/notifier-event.md"),s(" 生成。"),i("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/notifier-event.md"},"在 GitHub 上编辑")],-1)])])}const c=e(a,[["render",h]]);export{u as __pageData,c as default};
@@ -21,4 +21,4 @@ import{_ as e,o as t,c as n,j as i,a as s}from"./chunks/framework.B9qR_F1m.js";c
21
21
  `),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "requester"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"张广祥"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
22
22
  `),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "card"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"system"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"ALM"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"id"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"CMASTER-BUSINESS#9902"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"url"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"null"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," },")]),s(`
23
23
  `),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "recipients"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": [{ "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"name"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"张广祥"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"accounts"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"um"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"ZHANGGX001"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," } }]")]),s(`
24
- `),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"}")])])])]),i("ul",null,[i("li",null,[i("code",null,"audience"),s(":"),i("code",null,"requester"),s(" 表示这件事要需求方处理或是给他的结果("),i("code",null,"blocked"),s("、"),i("code",null,"approval"),s("、"),i("code",null,"phase_done"),s("、"),i("code",null,"completed"),s(",而且需求从卡片开始、知道提出人);其余为 "),i("code",null,"team"),s(",发到群里即可。")]),i("li",null,[i("code",null,"requester"),s("、"),i("code",null,"card"),s(":从卡片开始的需求的提出人和卡片;其他需求为 null。")]),i("li",null,[i("code",null,"recipients"),s(":"),i("code",null,"audience"),s(" 为 "),i("code",null,"requester"),s(" 时是需求方本人;"),i("code",null,"accounts"),s(" 来自本机或团队配置的 "),i("code",null,"people"),s("(姓名 → 各种账号),没有写时为 "),i("code",null,"{}"),s(",模块可以改发到群。")])]),i("table",{tabindex:"0"},[i("thead",null,[i("tr",null,[i("th",null,"type"),i("th",null,"什么时候"),i("th",null,"details")])]),i("tbody",null,[i("tr",null,[i("td",null,[i("code",null,"milestone")]),i("td",null,[s("方案确定、开始验证、开始修复缺陷(配置 "),i("code",null,"notifyMilestones"),s(" 为 true 时,每次尝试各一次)")]),i("td",null,[i("code",null,"milestone"),s(":"),i("code",null,"design-settled"),s("、"),i("code",null,"code-reviewed"),s("、"),i("code",null,"fixing-defects"),s("、"),i("code",null,"handback-<n>"),s("(1.7.0 起,测试验证第 n 次把缺陷退回研发)")])]),i("tr",null,[i("td",null,[i("code",null,"blocked")]),i("td",null,"方案审核发现需要需求方决定的问题,流水线已暂停"),i("td",null,[i("code",null,"questions"),s("(字符串数组)、"),i("code",null,"resumeCommand")])]),i("tr",null,[i("td",null,[i("code",null,"permission")]),i("td",null,"步骤 agent 在等待权限批准"),i("td",null,[i("code",null,"stepTitle"),s("、"),i("code",null,"agentTitle"),s("、"),i("code",null,"requests"),s("(字符串数组)")])]),i("tr",null,[i("td",null,[i("code",null,"failed")]),i("td",null,"流水线因错误中断(已自动重试过的临时错误除外)"),i("td",null,[i("code",null,"stepTitle"),s("、"),i("code",null,"reason"),s("、"),i("code",null,"logPath"),s("、"),i("code",null,"resumeCommand")])]),i("tr",null,[i("td",null,[i("code",null,"completed")]),i("td",null,"流水线结束,报告已生成"),i("td",null,[i("code",null,"outcome"),s("("),i("code",null,"completed"),s("、"),i("code",null,"completed_with_issues"),s("、"),i("code",null,"not_completed"),s(")、"),i("code",null,"summary"),s("、"),i("code",null,"reportPath"),s('。"只做研发"时另有 '),i("code",null,"mode"),s("("),i("code",null,"develop-only"),s(")和 "),i("code",null,"handoffPath"),s(",报告是研发报告,需要人工测试")])]),i("tr",null,[i("td",null,[i("code",null,"approval")]),i("td",null,[s("1.8.0 起。方案确认点("),i("code",null,"designApproval"),s('):方案已通过审核,等待需求方确认"做完后会看到什么",还没有开始写代码')]),i("td",null,[i("code",null,"previewPath"),s("(要确认的内容)、"),i("code",null,"approveCommand"),s("(确认后继续的命令)、"),i("code",null,"resumeCommand"),s("(修改需求后继续的命令),都在发起的对话中执行")])]),i("tr",null,[i("td",null,[i("code",null,"phase_done")]),i("td",null,"1.7.0 起。分阶段执行时研发阶段已完成(代码已通过评审、提测说明已写好),流水线停在闸口等待测试验证。测试退回后再次修完也会发"),i("td",null,[i("code",null,"handoffPath"),s("(提测说明)、"),i("code",null,"mode"),s("("),i("code",null,"gated"),s(")、"),i("code",null,"verifyCommand"),s("(开始测试验证的命令,在发起的对话中执行)、"),i("code",null,"verifyAt"),s("(预约的开始时间,ISO 格式,没有为 null)、"),i("code",null,"handbacks"),s("(已退回的次数)")])]),i("tr",null,[i("td",null,[i("code",null,"alert")]),i("td",null,[s("1.12 起。接单器("),i("code",null,"req factory"),s(")自检没有通过(Paseo 连不上、agent 没有登录、额度用完、需求管理系统的命令不可用),暂停接新卡片;或者恢复正常。同样的问题只发一次。"),i("code",null,"feature.title"),s(' 为"接单器",'),i("code",null,"feature.dir"),s("、"),i("code",null,"repo"),s(" 为空")]),i("td",null,[i("code",null,"source"),s("("),i("code",null,"factory"),s(")、"),i("code",null,"machine"),s("、"),i("code",null,"problems"),s("(字符串数组,恢复时为空)、"),i("code",null,"recovered")])]),i("tr",null,[i("td",null,[i("code",null,"digest")]),i("td",null,[i("code",null,"req digest --notify"),s("(或由 "),i("code",null,"req digest --schedule"),s(" 创建的 Paseo 定时任务)发送项目的需求总览,1.6.0 起。"),i("code",null,"feature.title"),s(' 为"<项目> 需求总览",'),i("code",null,"text"),s(" 是完整的多行总览")]),i("td",null,[i("code",null,"features"),s(":每个需求的 "),i("code",null,"name"),s("、"),i("code",null,"title"),s("、"),i("code",null,"stage"),s("、"),i("code",null,"branch"),s("、"),i("code",null,"updatedAt"),s("、"),i("code",null,"usage"),s(";"),i("code",null,"recurringLessons"),s("(1.8.0 起):在两个以上需求的 "),i("code",null,"lessons.tsv"),s(" 中出现的问题类别,每项 "),i("code",null,"category"),s("、"),i("code",null,"features"),s("、"),i("code",null,"rules")])])])]),i("h2",{id:"兼容性",tabindex:"-1"},[s("兼容性 "),i("a",{class:"header-anchor",href:"#兼容性","aria-label":'Permalink to "兼容性"'},"​")]),i("ul",null,[i("li",null,[s("同一 "),i("code",null,"schema"),s(" 内只增加字段,不删除、不改含义;模块应忽略不认识的字段和事件类型。")]),i("li",null,[s("不兼容的变化会提升 "),i("code",null,"schema"),s(",并在 "),i("code",null,"CHANGELOG.md"),s(' 的"升级须知"中说明。')])])],-1),i("p",{class:"source-note"},[s("本页由仓库中的 "),i("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/notifier-event.md"},"contracts/notifier-event.md"),s(" 生成。"),i("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/notifier-event.md"},"在 GitHub 上编辑")],-1)])])}const c=e(a,[["render",h]]);export{u as __pageData,c as default};
24
+ `),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"}")])])])]),i("ul",null,[i("li",null,[i("code",null,"audience"),s(":"),i("code",null,"requester"),s(" 表示这件事要需求方处理或是给他的结果("),i("code",null,"blocked"),s("、"),i("code",null,"approval"),s("、"),i("code",null,"phase_done"),s("、"),i("code",null,"completed"),s(",而且需求从卡片开始、知道提出人);其余为 "),i("code",null,"team"),s(",发到群里即可。")]),i("li",null,[i("code",null,"requester"),s("、"),i("code",null,"card"),s(":从卡片开始的需求的提出人和卡片;其他需求为 null。")]),i("li",null,[i("code",null,"recipients"),s(":"),i("code",null,"audience"),s(" 为 "),i("code",null,"requester"),s(" 时是需求方本人;"),i("code",null,"accounts"),s(" 来自本机或团队配置的 "),i("code",null,"people"),s("(姓名 → 各种账号),没有写时为 "),i("code",null,"{}"),s(",模块可以改发到群。")])]),i("table",{tabindex:"0"},[i("thead",null,[i("tr",null,[i("th",null,"type"),i("th",null,"什么时候"),i("th",null,"details")])]),i("tbody",null,[i("tr",null,[i("td",null,[i("code",null,"milestone")]),i("td",null,[s("方案确定、开始验证、开始修复缺陷(配置 "),i("code",null,"notifyMilestones"),s(" 为 true 时,每次尝试各一次)")]),i("td",null,[i("code",null,"milestone"),s(":"),i("code",null,"design-settled"),s("、"),i("code",null,"code-reviewed"),s("、"),i("code",null,"fixing-defects"),s("、"),i("code",null,"handback-<n>"),s("(1.7.0 起,测试验证第 n 次把缺陷退回研发)")])]),i("tr",null,[i("td",null,[i("code",null,"blocked")]),i("td",null,"方案审核发现需要需求方决定的问题,流水线已暂停"),i("td",null,[i("code",null,"questions"),s("(字符串数组)、"),i("code",null,"resumeCommand")])]),i("tr",null,[i("td",null,[i("code",null,"permission")]),i("td",null,"步骤 agent 在等待权限批准"),i("td",null,[i("code",null,"stepTitle"),s("、"),i("code",null,"agentTitle"),s("、"),i("code",null,"requests"),s("(字符串数组)")])]),i("tr",null,[i("td",null,[i("code",null,"failed")]),i("td",null,"流水线因错误中断(已自动重试过的临时错误除外)"),i("td",null,[i("code",null,"stepTitle"),s("、"),i("code",null,"reason"),s("、"),i("code",null,"logPath"),s("、"),i("code",null,"resumeCommand")])]),i("tr",null,[i("td",null,[i("code",null,"completed")]),i("td",null,"流水线结束,报告已生成"),i("td",null,[i("code",null,"outcome"),s("("),i("code",null,"completed"),s("、"),i("code",null,"completed_with_issues"),s("、"),i("code",null,"not_completed"),s(")、"),i("code",null,"summary"),s("、"),i("code",null,"reportPath"),s('。"只做研发"时另有 '),i("code",null,"mode"),s("("),i("code",null,"develop-only"),s(")和 "),i("code",null,"handoffPath"),s(",报告是研发报告,需要人工测试")])]),i("tr",null,[i("td",null,[i("code",null,"approval")]),i("td",null,[s("1.8.0 起。方案确认点("),i("code",null,"designApproval"),s('):方案已通过审核,等待需求方确认"做完后会看到什么",还没有开始写代码')]),i("td",null,[i("code",null,"previewPath"),s("(要确认的内容)、"),i("code",null,"approveCommand"),s("(确认后继续的命令)、"),i("code",null,"resumeCommand"),s("(修改需求后继续的命令),都在发起的对话中执行")])]),i("tr",null,[i("td",null,[i("code",null,"phase_done")]),i("td",null,"1.7.0 起。分阶段执行时研发阶段已完成(代码已通过评审、提测说明已写好),流水线停在闸口等待测试验证。测试退回后再次修完也会发"),i("td",null,[i("code",null,"handoffPath"),s("(提测说明)、"),i("code",null,"mode"),s("("),i("code",null,"gated"),s(")、"),i("code",null,"verifyCommand"),s("(开始测试验证的命令,在发起的对话中执行)、"),i("code",null,"verifyAt"),s("(预约的开始时间,ISO 格式,没有为 null)、"),i("code",null,"handbacks"),s("(已退回的次数)")])]),i("tr",null,[i("td",null,[i("code",null,"alert")]),i("td",null,[s("1.12 起。接单器("),i("code",null,"req factory"),s(")自检没有通过(Paseo 连不上、agent 没有登录、额度用完、需求管理系统的命令不可用),暂停接新卡片;或者恢复正常。同样的问题只发一次。"),i("code",null,"feature.title"),s(' 为"接单器",'),i("code",null,"feature.dir"),s("、"),i("code",null,"repo"),s(" 为空")]),i("td",null,[i("code",null,"source"),s("("),i("code",null,"factory"),s(")、"),i("code",null,"machine"),s("、"),i("code",null,"problems"),s("(字符串数组,恢复时为空)、"),i("code",null,"recovered"),s("。1.14 起,步骤 agent 运行或开始运行危险命令("),i("code",null,"dangerGuard"),s(")时也发:"),i("code",null,"details.kind"),s(" 为 "),i("code",null,"danger"),s(",另有 "),i("code",null,"stepTitle"),s("、"),i("code",null,"command"),s("、"),i("code",null,"label"),s("、"),i("code",null,"ran"),s(";这时 "),i("code",null,"feature"),s("、"),i("code",null,"repo"),s(" 是那个需求的")])]),i("tr",null,[i("td",null,[i("code",null,"digest")]),i("td",null,[i("code",null,"req digest --notify"),s("(或由 "),i("code",null,"req digest --schedule"),s(" 创建的 Paseo 定时任务)发送项目的需求总览,1.6.0 起。"),i("code",null,"feature.title"),s(' 为"<项目> 需求总览",'),i("code",null,"text"),s(" 是完整的多行总览")]),i("td",null,[i("code",null,"features"),s(":每个需求的 "),i("code",null,"name"),s("、"),i("code",null,"title"),s("、"),i("code",null,"stage"),s("、"),i("code",null,"branch"),s("、"),i("code",null,"updatedAt"),s("、"),i("code",null,"usage"),s(";"),i("code",null,"recurringLessons"),s("(1.8.0 起):在两个以上需求的 "),i("code",null,"lessons.tsv"),s(" 中出现的问题类别,每项 "),i("code",null,"category"),s("、"),i("code",null,"features"),s("、"),i("code",null,"rules")])])])]),i("h2",{id:"兼容性",tabindex:"-1"},[s("兼容性 "),i("a",{class:"header-anchor",href:"#兼容性","aria-label":'Permalink to "兼容性"'},"​")]),i("ul",null,[i("li",null,[s("同一 "),i("code",null,"schema"),s(" 内只增加字段,不删除、不改含义;模块应忽略不认识的字段和事件类型。")]),i("li",null,[s("不兼容的变化会提升 "),i("code",null,"schema"),s(",并在 "),i("code",null,"CHANGELOG.md"),s(' 的"升级须知"中说明。')])])],-1),i("p",{class:"source-note"},[s("本页由仓库中的 "),i("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/notifier-event.md"},"contracts/notifier-event.md"),s(" 生成。"),i("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/notifier-event.md"},"在 GitHub 上编辑")],-1)])])}const c=e(a,[["render",h]]);export{u as __pageData,c as default};
@@ -1,8 +1,8 @@
1
- import{_ as s,o as t,c as i,j as l,a as e}from"./chunks/framework.B9qR_F1m.js";const k=JSON.parse('{"title":"spec.md","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/spec.md","filePath":"reference/contracts/spec.md","lastUpdated":null}'),a={name:"reference/contracts/spec.md"};function d(c,n,r,u,o,h){return t(),i("div",null,[...n[0]||(n[0]=[l("div",null,[l("h1",{id:"spec-md",tabindex:"-1"},[e("spec.md "),l("a",{class:"header-anchor",href:"#spec-md","aria-label":'Permalink to "spec.md"'},"​")]),l("p",null,[e("需求说明,由 "),l("code",null,"/req"),e("("),l("code",null,"spec-writing"),e(" skill)按模板 "),l("code",null,"skills/spec-writing/spec-template.md"),e(" 写成,需求方确认后交给流水线。")]),l("h2",{id:"头部",tabindex:"-1"},[e("头部 "),l("a",{class:"header-anchor",href:"#头部","aria-label":'Permalink to "头部"'},"​")]),l("div",{class:"language-markdown vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"markdown"),l("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[l("code",null,[l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"# <需求名称>")]),e(`
1
+ import{_ as s,o as t,c as i,j as l,a as e}from"./chunks/framework.B9qR_F1m.js";const k=JSON.parse('{"title":"spec.md","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/spec.md","filePath":"reference/contracts/spec.md","lastUpdated":null}'),a={name:"reference/contracts/spec.md"};function d(c,n,u,r,o,h){return t(),i("div",null,[...n[0]||(n[0]=[l("div",null,[l("h1",{id:"spec-md",tabindex:"-1"},[e("spec.md "),l("a",{class:"header-anchor",href:"#spec-md","aria-label":'Permalink to "spec.md"'},"​")]),l("p",null,[e("需求说明,由 "),l("code",null,"/req"),e("("),l("code",null,"spec-writing"),e(" skill)按模板 "),l("code",null,"skills/spec-writing/spec-template.md"),e(" 写成,需求方确认后交给流水线。")]),l("h2",{id:"头部",tabindex:"-1"},[e("头部 "),l("a",{class:"header-anchor",href:"#头部","aria-label":'Permalink to "头部"'},"​")]),l("div",{class:"language-markdown vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"markdown"),l("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[l("code",null,[l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"# <需求名称>")]),e(`
2
2
  `),l("span",{class:"line"}),e(`
3
3
  `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 状态:已确认(2026-10-12)")]),e(`
4
4
  `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 档位:标准")]),e(`
5
5
  `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 执行方式:连续")]),e(`
6
6
  `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 类型:新需求")]),e(`
7
7
  `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 版本:1")]),e(`
8
- `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 格式:req-kit/spec@1")])])])]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"行"),l("th",null,"谁读"),l("th",null,"规则")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"- 状态:")]),l("td",null,"引擎"),l("td",null,[e('以"已确认"开头才能启动流水线。正则:'),l("code",null,"^\\s*-\\s*状态\\s*[::]\\s*已确认")])]),l("tr",null,[l("td",null,[l("code",null,"- 档位:")]),l("td",null,"引擎"),l("td",null,[e('"快速"或"标准"(也接受 '),l("code",null,"quick"),e(" / "),l("code",null,"standard"),e(")。没有时用配置中的 "),l("code",null,"defaultProfile")])]),l("tr",null,[l("td",null,[l("code",null,"- 执行方式:")]),l("td",null,"引擎"),l("td",null,[e('"连续"、"分阶段"或"只做研发"(也接受 '),l("code",null,"continuous"),e(" / "),l("code",null,"gated"),e(" / "),l("code",null,"develop-only"),e(")。可以没有;没有时用配置中的 "),l("code",null,"phases.mode"),e(",启动参数 "),l("code",null,"--phases"),e(" 优先(1.7 起)")])]),l("tr",null,[l("td",null,[l("code",null,"- 类型:")]),l("td",null,[e("引擎(1.8 起)、"),l("code",null,"/req")]),l("td",null,[e("新需求 / 小改动 / 缺陷 / 重构 / 评估(也接受 "),l("code",null,"defect"),e("、"),l("code",null,"bug"),e("、"),l("code",null,"refactor"),e("、"),l("code",null,"assessment"),e(';"技术改进"同重构,"调研"同评估)。缺陷、重构、评估按各自的做法运行('),l("code",null,"engine/prompts/types/"),e("),配置 "),l("code",null,"requirementTypes"),e(" 可以关掉某个类型;其他写法按新需求处理")])]),l("tr",null,[l("td",null,[l("code",null,"- 联合开发:")]),l("td",null,"引擎(1.8 起)"),l("td",null,[e("这个需求还要改的其他仓库,写项目配置 "),l("code",null,"relatedRepos"),e(" 中的名称,最多两个,用顿号分开。可以没有。见 ADR 0025")])]),l("tr",null,[l("td",null,[l("code",null,"- 版本:")]),l("td",null,[l("code",null,"/req")]),l("td",null,"从 1 开始,每次修改需求加 1")]),l("tr",null,[l("td",null,[l("code",null,"- 格式:")]),l("td",null,[l("code",null,"/req"),e("、引擎(将来)")]),l("td",null,[l("code",null,"req-kit/spec@<n>"),e("。没有这一行的旧 spec 按 "),l("code",null,"req-kit/spec@1"),e(" 处理")])])])]),l("h2",{id:"正文中被引用的编号",tabindex:"-1"},[e("正文中被引用的编号 "),l("a",{class:"header-anchor",href:"#正文中被引用的编号","aria-label":'Permalink to "正文中被引用的编号"'},"​")]),l("ul",null,[l("li",null,[e("功能需求 "),l("code",null,"FR-<n>"),e(",验收标准 "),l("code",null,"AC-<n>.<m>"),e(",规则 "),l("code",null,"BR-<n>"),e(",假设 "),l("code",null,"A-<n>"),e("。")]),l("li",null,[e("每条验收标准至少带一组具体的输入和期望输出(1.8 起由 "),l("code",null,"acceptance-criteria"),e("、需求说明审阅检查);方案的测试直接用这些例子作为期望值。")]),l("li",null,'流水线各步骤和最终报告按这些编号引用,编号一旦确认就不要重排;删除的需求保留编号并注明"已取消"。')]),l("h2",{id:"变更",tabindex:"-1"},[e("变更 "),l("a",{class:"header-anchor",href:"#变更","aria-label":'Permalink to "变更"'},"​")]),l("ul",null,[l("li",null,"spec 的内容哈希记录在状态文件中。spec 在流水线中断后被修改,续跑时从方案设计重新开始。")])],-1),l("p",{class:"source-note"},[e("本页由仓库中的 "),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/spec.md"},"contracts/spec.md"),e(" 生成。"),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/spec.md"},"在 GitHub 上编辑")],-1)])])}const m=s(a,[["render",d]]);export{k as __pageData,m as default};
8
+ `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 格式:req-kit/spec@1")])])])]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"行"),l("th",null,"谁读"),l("th",null,"规则")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"- 状态:")]),l("td",null,"引擎"),l("td",null,[e('以"已确认"开头才能启动流水线。正则:'),l("code",null,"^\\s*-\\s*状态\\s*[::]\\s*已确认")])]),l("tr",null,[l("td",null,[l("code",null,"- 档位:")]),l("td",null,"引擎"),l("td",null,[e('"快速"或"标准"(也接受 '),l("code",null,"quick"),e(" / "),l("code",null,"standard"),e(")。没有时用配置中的 "),l("code",null,"defaultProfile")])]),l("tr",null,[l("td",null,[l("code",null,"- 执行方式:")]),l("td",null,"引擎"),l("td",null,[e('"连续"、"分阶段"或"只做研发"(也接受 '),l("code",null,"continuous"),e(" / "),l("code",null,"gated"),e(" / "),l("code",null,"develop-only"),e(")。可以没有;没有时用配置中的 "),l("code",null,"phases.mode"),e(",启动参数 "),l("code",null,"--phases"),e(" 优先(1.7 起)")])]),l("tr",null,[l("td",null,[l("code",null,"- 类型:")]),l("td",null,[e("引擎(1.8 起)、"),l("code",null,"/req")]),l("td",null,[e("新需求 / 小改动 / 缺陷 / 重构 / 评估(也接受 "),l("code",null,"defect"),e("、"),l("code",null,"bug"),e("、"),l("code",null,"refactor"),e("、"),l("code",null,"assessment"),e(';"技术改进"同重构,"调研"同评估)。缺陷、重构、评估按各自的做法运行('),l("code",null,"engine/prompts/types/"),e("),配置 "),l("code",null,"requirementTypes"),e(" 可以关掉某个类型;其他写法按新需求处理")])]),l("tr",null,[l("td",null,[l("code",null,"- 联合开发:")]),l("td",null,"引擎(1.8 起)"),l("td",null,[e("这个需求还要改的其他仓库,写项目配置 "),l("code",null,"relatedRepos"),e(" 中的名称,最多两个,用顿号分开。可以没有。见 ADR 0025")])]),l("tr",null,[l("td",null,[l("code",null,"- 引入问题的需求:")]),l("td",null,[l("code",null,"req stats"),e("、"),l("code",null,"req outcome"),e("(1.14 起)")]),l("td",null,'缺陷需求才写:引入这个问题的需求的目录名(或功能目录、标题)。记为那个需求"合并后发现的问题"。可以没有')]),l("tr",null,[l("td",null,[l("code",null,"- 版本:")]),l("td",null,[l("code",null,"/req")]),l("td",null,"从 1 开始,每次修改需求加 1")]),l("tr",null,[l("td",null,[l("code",null,"- 格式:")]),l("td",null,[l("code",null,"/req"),e("、引擎(将来)")]),l("td",null,[l("code",null,"req-kit/spec@<n>"),e("。没有这一行的旧 spec 按 "),l("code",null,"req-kit/spec@1"),e(" 处理")])])])]),l("h2",{id:"正文中被引用的编号",tabindex:"-1"},[e("正文中被引用的编号 "),l("a",{class:"header-anchor",href:"#正文中被引用的编号","aria-label":'Permalink to "正文中被引用的编号"'},"​")]),l("ul",null,[l("li",null,[e("功能需求 "),l("code",null,"FR-<n>"),e(",验收标准 "),l("code",null,"AC-<n>.<m>"),e(",规则 "),l("code",null,"BR-<n>"),e(",假设 "),l("code",null,"A-<n>"),e("。")]),l("li",null,[e("每条验收标准至少带一组具体的输入和期望输出(1.8 起由 "),l("code",null,"acceptance-criteria"),e("、需求说明审阅检查);方案的测试直接用这些例子作为期望值。")]),l("li",null,'流水线各步骤和最终报告按这些编号引用,编号一旦确认就不要重排;删除的需求保留编号并注明"已取消"。')]),l("h2",{id:"变更",tabindex:"-1"},[e("变更 "),l("a",{class:"header-anchor",href:"#变更","aria-label":'Permalink to "变更"'},"​")]),l("ul",null,[l("li",null,"spec 的内容哈希记录在状态文件中。spec 在流水线中断后被修改,续跑时从方案设计重新开始。")])],-1),l("p",{class:"source-note"},[e("本页由仓库中的 "),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/spec.md"},"contracts/spec.md"),e(" 生成。"),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/spec.md"},"在 GitHub 上编辑")],-1)])])}const m=s(a,[["render",d]]);export{k as __pageData,m as default};
@@ -1,8 +1,8 @@
1
- import{_ as s,o as t,c as i,j as l,a as e}from"./chunks/framework.B9qR_F1m.js";const k=JSON.parse('{"title":"spec.md","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/spec.md","filePath":"reference/contracts/spec.md","lastUpdated":null}'),a={name:"reference/contracts/spec.md"};function d(c,n,r,u,o,h){return t(),i("div",null,[...n[0]||(n[0]=[l("div",null,[l("h1",{id:"spec-md",tabindex:"-1"},[e("spec.md "),l("a",{class:"header-anchor",href:"#spec-md","aria-label":'Permalink to "spec.md"'},"​")]),l("p",null,[e("需求说明,由 "),l("code",null,"/req"),e("("),l("code",null,"spec-writing"),e(" skill)按模板 "),l("code",null,"skills/spec-writing/spec-template.md"),e(" 写成,需求方确认后交给流水线。")]),l("h2",{id:"头部",tabindex:"-1"},[e("头部 "),l("a",{class:"header-anchor",href:"#头部","aria-label":'Permalink to "头部"'},"​")]),l("div",{class:"language-markdown vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"markdown"),l("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[l("code",null,[l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"# <需求名称>")]),e(`
1
+ import{_ as s,o as t,c as i,j as l,a as e}from"./chunks/framework.B9qR_F1m.js";const k=JSON.parse('{"title":"spec.md","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/spec.md","filePath":"reference/contracts/spec.md","lastUpdated":null}'),a={name:"reference/contracts/spec.md"};function d(c,n,u,r,o,h){return t(),i("div",null,[...n[0]||(n[0]=[l("div",null,[l("h1",{id:"spec-md",tabindex:"-1"},[e("spec.md "),l("a",{class:"header-anchor",href:"#spec-md","aria-label":'Permalink to "spec.md"'},"​")]),l("p",null,[e("需求说明,由 "),l("code",null,"/req"),e("("),l("code",null,"spec-writing"),e(" skill)按模板 "),l("code",null,"skills/spec-writing/spec-template.md"),e(" 写成,需求方确认后交给流水线。")]),l("h2",{id:"头部",tabindex:"-1"},[e("头部 "),l("a",{class:"header-anchor",href:"#头部","aria-label":'Permalink to "头部"'},"​")]),l("div",{class:"language-markdown vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"markdown"),l("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[l("code",null,[l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"# <需求名称>")]),e(`
2
2
  `),l("span",{class:"line"}),e(`
3
3
  `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 状态:已确认(2026-10-12)")]),e(`
4
4
  `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 档位:标准")]),e(`
5
5
  `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 执行方式:连续")]),e(`
6
6
  `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 类型:新需求")]),e(`
7
7
  `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 版本:1")]),e(`
8
- `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 格式:req-kit/spec@1")])])])]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"行"),l("th",null,"谁读"),l("th",null,"规则")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"- 状态:")]),l("td",null,"引擎"),l("td",null,[e('以"已确认"开头才能启动流水线。正则:'),l("code",null,"^\\s*-\\s*状态\\s*[::]\\s*已确认")])]),l("tr",null,[l("td",null,[l("code",null,"- 档位:")]),l("td",null,"引擎"),l("td",null,[e('"快速"或"标准"(也接受 '),l("code",null,"quick"),e(" / "),l("code",null,"standard"),e(")。没有时用配置中的 "),l("code",null,"defaultProfile")])]),l("tr",null,[l("td",null,[l("code",null,"- 执行方式:")]),l("td",null,"引擎"),l("td",null,[e('"连续"、"分阶段"或"只做研发"(也接受 '),l("code",null,"continuous"),e(" / "),l("code",null,"gated"),e(" / "),l("code",null,"develop-only"),e(")。可以没有;没有时用配置中的 "),l("code",null,"phases.mode"),e(",启动参数 "),l("code",null,"--phases"),e(" 优先(1.7 起)")])]),l("tr",null,[l("td",null,[l("code",null,"- 类型:")]),l("td",null,[e("引擎(1.8 起)、"),l("code",null,"/req")]),l("td",null,[e("新需求 / 小改动 / 缺陷 / 重构 / 评估(也接受 "),l("code",null,"defect"),e("、"),l("code",null,"bug"),e("、"),l("code",null,"refactor"),e("、"),l("code",null,"assessment"),e(';"技术改进"同重构,"调研"同评估)。缺陷、重构、评估按各自的做法运行('),l("code",null,"engine/prompts/types/"),e("),配置 "),l("code",null,"requirementTypes"),e(" 可以关掉某个类型;其他写法按新需求处理")])]),l("tr",null,[l("td",null,[l("code",null,"- 联合开发:")]),l("td",null,"引擎(1.8 起)"),l("td",null,[e("这个需求还要改的其他仓库,写项目配置 "),l("code",null,"relatedRepos"),e(" 中的名称,最多两个,用顿号分开。可以没有。见 ADR 0025")])]),l("tr",null,[l("td",null,[l("code",null,"- 版本:")]),l("td",null,[l("code",null,"/req")]),l("td",null,"从 1 开始,每次修改需求加 1")]),l("tr",null,[l("td",null,[l("code",null,"- 格式:")]),l("td",null,[l("code",null,"/req"),e("、引擎(将来)")]),l("td",null,[l("code",null,"req-kit/spec@<n>"),e("。没有这一行的旧 spec 按 "),l("code",null,"req-kit/spec@1"),e(" 处理")])])])]),l("h2",{id:"正文中被引用的编号",tabindex:"-1"},[e("正文中被引用的编号 "),l("a",{class:"header-anchor",href:"#正文中被引用的编号","aria-label":'Permalink to "正文中被引用的编号"'},"​")]),l("ul",null,[l("li",null,[e("功能需求 "),l("code",null,"FR-<n>"),e(",验收标准 "),l("code",null,"AC-<n>.<m>"),e(",规则 "),l("code",null,"BR-<n>"),e(",假设 "),l("code",null,"A-<n>"),e("。")]),l("li",null,[e("每条验收标准至少带一组具体的输入和期望输出(1.8 起由 "),l("code",null,"acceptance-criteria"),e("、需求说明审阅检查);方案的测试直接用这些例子作为期望值。")]),l("li",null,'流水线各步骤和最终报告按这些编号引用,编号一旦确认就不要重排;删除的需求保留编号并注明"已取消"。')]),l("h2",{id:"变更",tabindex:"-1"},[e("变更 "),l("a",{class:"header-anchor",href:"#变更","aria-label":'Permalink to "变更"'},"​")]),l("ul",null,[l("li",null,"spec 的内容哈希记录在状态文件中。spec 在流水线中断后被修改,续跑时从方案设计重新开始。")])],-1),l("p",{class:"source-note"},[e("本页由仓库中的 "),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/spec.md"},"contracts/spec.md"),e(" 生成。"),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/spec.md"},"在 GitHub 上编辑")],-1)])])}const m=s(a,[["render",d]]);export{k as __pageData,m as default};
8
+ `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 格式:req-kit/spec@1")])])])]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"行"),l("th",null,"谁读"),l("th",null,"规则")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"- 状态:")]),l("td",null,"引擎"),l("td",null,[e('以"已确认"开头才能启动流水线。正则:'),l("code",null,"^\\s*-\\s*状态\\s*[::]\\s*已确认")])]),l("tr",null,[l("td",null,[l("code",null,"- 档位:")]),l("td",null,"引擎"),l("td",null,[e('"快速"或"标准"(也接受 '),l("code",null,"quick"),e(" / "),l("code",null,"standard"),e(")。没有时用配置中的 "),l("code",null,"defaultProfile")])]),l("tr",null,[l("td",null,[l("code",null,"- 执行方式:")]),l("td",null,"引擎"),l("td",null,[e('"连续"、"分阶段"或"只做研发"(也接受 '),l("code",null,"continuous"),e(" / "),l("code",null,"gated"),e(" / "),l("code",null,"develop-only"),e(")。可以没有;没有时用配置中的 "),l("code",null,"phases.mode"),e(",启动参数 "),l("code",null,"--phases"),e(" 优先(1.7 起)")])]),l("tr",null,[l("td",null,[l("code",null,"- 类型:")]),l("td",null,[e("引擎(1.8 起)、"),l("code",null,"/req")]),l("td",null,[e("新需求 / 小改动 / 缺陷 / 重构 / 评估(也接受 "),l("code",null,"defect"),e("、"),l("code",null,"bug"),e("、"),l("code",null,"refactor"),e("、"),l("code",null,"assessment"),e(';"技术改进"同重构,"调研"同评估)。缺陷、重构、评估按各自的做法运行('),l("code",null,"engine/prompts/types/"),e("),配置 "),l("code",null,"requirementTypes"),e(" 可以关掉某个类型;其他写法按新需求处理")])]),l("tr",null,[l("td",null,[l("code",null,"- 联合开发:")]),l("td",null,"引擎(1.8 起)"),l("td",null,[e("这个需求还要改的其他仓库,写项目配置 "),l("code",null,"relatedRepos"),e(" 中的名称,最多两个,用顿号分开。可以没有。见 ADR 0025")])]),l("tr",null,[l("td",null,[l("code",null,"- 引入问题的需求:")]),l("td",null,[l("code",null,"req stats"),e("、"),l("code",null,"req outcome"),e("(1.14 起)")]),l("td",null,'缺陷需求才写:引入这个问题的需求的目录名(或功能目录、标题)。记为那个需求"合并后发现的问题"。可以没有')]),l("tr",null,[l("td",null,[l("code",null,"- 版本:")]),l("td",null,[l("code",null,"/req")]),l("td",null,"从 1 开始,每次修改需求加 1")]),l("tr",null,[l("td",null,[l("code",null,"- 格式:")]),l("td",null,[l("code",null,"/req"),e("、引擎(将来)")]),l("td",null,[l("code",null,"req-kit/spec@<n>"),e("。没有这一行的旧 spec 按 "),l("code",null,"req-kit/spec@1"),e(" 处理")])])])]),l("h2",{id:"正文中被引用的编号",tabindex:"-1"},[e("正文中被引用的编号 "),l("a",{class:"header-anchor",href:"#正文中被引用的编号","aria-label":'Permalink to "正文中被引用的编号"'},"​")]),l("ul",null,[l("li",null,[e("功能需求 "),l("code",null,"FR-<n>"),e(",验收标准 "),l("code",null,"AC-<n>.<m>"),e(",规则 "),l("code",null,"BR-<n>"),e(",假设 "),l("code",null,"A-<n>"),e("。")]),l("li",null,[e("每条验收标准至少带一组具体的输入和期望输出(1.8 起由 "),l("code",null,"acceptance-criteria"),e("、需求说明审阅检查);方案的测试直接用这些例子作为期望值。")]),l("li",null,'流水线各步骤和最终报告按这些编号引用,编号一旦确认就不要重排;删除的需求保留编号并注明"已取消"。')]),l("h2",{id:"变更",tabindex:"-1"},[e("变更 "),l("a",{class:"header-anchor",href:"#变更","aria-label":'Permalink to "变更"'},"​")]),l("ul",null,[l("li",null,"spec 的内容哈希记录在状态文件中。spec 在流水线中断后被修改,续跑时从方案设计重新开始。")])],-1),l("p",{class:"source-note"},[e("本页由仓库中的 "),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/spec.md"},"contracts/spec.md"),e(" 生成。"),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/spec.md"},"在 GitHub 上编辑")],-1)])])}const m=s(a,[["render",d]]);export{k as __pageData,m as default};
@@ -0,0 +1 @@
1
+ import{_ as d,o,c as t,a3 as c}from"./chunks/framework.B9qR_F1m.js";const m=JSON.parse('{"title":"state.json","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/state.md","filePath":"reference/contracts/state.md","lastUpdated":null}'),r={name:"reference/contracts/state.md"};function a(s,e,n,i,l,u){return o(),t("div",null,[...e[0]||(e[0]=[c('<div><h1 id="state-json" tabindex="-1">state.json <a class="header-anchor" href="#state-json" aria-label="Permalink to &quot;state.json&quot;">​</a></h1><p>流水线的运行状态,位于 <code>docs/features/&lt;目录&gt;/.pipeline/state.json</code>,只由引擎写入,不提交。</p><h2 id="当前格式-version-1" tabindex="-1">当前格式:version 1 <a class="header-anchor" href="#当前格式-version-1" aria-label="Permalink to &quot;当前格式:version 1&quot;">​</a></h2><table tabindex="0"><thead><tr><th>字段</th><th>类型</th><th>含义</th></tr></thead><tbody><tr><td><code>version</code></td><td>number</td><td>格式版本。没有这个字段的文件按 1 处理</td></tr><tr><td><code>repo</code></td><td>string</td><td>仓库目录(绝对路径)</td></tr><tr><td><code>featureDir</code></td><td>string</td><td>功能目录(相对路径,<code>/</code> 分隔)</td></tr><tr><td><code>status</code></td><td><code>running</code> | <code>waiting_for_business</code> | <code>failed</code> | <code>completed</code> | <code>phase_done</code> | <code>waiting_for_approval</code></td><td>当前状态。<code>waiting_for_business</code> 表示等待需求方决定;<code>phase_done</code>(1.7.0 起)表示研发阶段已完成、停在闸口等待测试验证;<code>waiting_for_approval</code>(1.8.0 起)表示方案已通过审核、等待需求方确认 <code>preview.md</code>,<code>--approve</code> 继续。旧引擎把不认识的状态当作可以继续的中断:<code>phase_done</code> 继续时直接做验证,<code>waiting_for_approval</code> 继续时不经确认直接写代码</td></tr><tr><td><code>attempt</code></td><td>number</td><td>第几次从方案设计开始</td></tr><tr><td><code>specHash</code></td><td>string</td><td>启动时 spec.md 的 sha256</td></tr><tr><td><code>originAgentId</code></td><td>string | null</td><td>发起对话的 agent,通知发往这里</td></tr><tr><td><code>pid</code></td><td>number</td><td>流水线进程</td></tr><tr><td><code>startedAt</code> / <code>updatedAt</code></td><td>ISO 时间</td><td></td></tr><tr><td><code>results</code></td><td>object</td><td>已完成步骤的结果,键为步骤键(如 <code>code_review-r2</code>)</td></tr><tr><td><code>history</code></td><td>array</td><td>每次步骤执行的记录:agent、起止时间、结果、错误;<code>usage</code>(可选,1.3.0 起)为 agent 报告的用量:<code>inputTokens</code>、<code>cachedInputTokens</code>、<code>outputTokens</code>、<code>totalCostUsd</code>,agent 没有报告时为 null 或缺少;<code>leftRunning</code>(可选,1.11 起)为 true 表示失败时 agent 可能还在运行,下一次运行这一步时先看它;<code>reattached</code>(可选,1.11 起)为接着等上一次 agent 的次数</td></tr><tr><td><code>stopReason</code> / <code>outcome</code></td><td>string | null</td><td>停止原因;最终结论</td></tr><tr><td><code>stopKind</code></td><td>string | null</td><td>可选,1.12 起。停下等人的原因代码:必要的决定 <code>approval</code>(确认方案)、<code>phase_gate</code>(研发完成,等待测试)、<code>business</code>(需求方决定)、<code>reproduce</code>(缺陷复现不了);中断 <code>timeout</code>、<code>agent_error</code>、<code>invalid_result</code>、<code>transient</code>、<code>stopped</code>、<code>process_exit</code>、<code>budget</code>(1.13,用完 token 预算)、<code>other</code>。运行中或完成时为 null</td></tr><tr><td><code>budget</code></td><td>object</td><td>可选,1.13 起,配置了 <code>budget.tokens</code> 时。<code>{ allowance, warnedAt }</code>:停下前允许用到的 tokens(预算,每次用完后继续再加一份);已经提醒过的那一档</td></tr><tr><td><code>waitingPermission</code></td><td>object | null</td><td>可选,1.13 起。步骤 agent 在等权限批准时:<code>{ agentId, stepTitle, requests, since }</code>;没有在等时为 null</td></tr><tr><td><code>recoveries</code></td><td>array</td><td>可选,1.12 起。流水线自己处理掉的问题(最多保留 200 条):<code>at</code>、<code>key</code>(步骤键)、<code>kind</code>(<code>retry</code> 重试 / <code>reattach</code> 接着等上一次的 agent / <code>reuse_result</code> 沿用上一次 agent 的结果 / <code>extend_timeout</code> 超时后多等一轮 / <code>redo</code> 新开 agent 重做 / <code>fallback</code> 换备用模型 / <code>auto_resume</code> 预约自动继续 / <code>quota_wait</code> 预约在额度恢复后继续 / <code>self_answer</code> 方案审核的问题由 builder 自答 / <code>stop_scan</code> 打断了搜索大目录的命令,1.13 起)、<code>detail</code></td></tr><tr><td><code>dangers</code></td><td>array</td><td>可选,1.14 起。步骤 agent 运行(或开始运行)的危险命令(<code>dangerGuard</code>,最多保留 50 条):<code>at</code>、<code>key</code>(步骤键)、<code>stepTitle</code>、<code>command</code>、<code>label</code>(如&quot;推送到远程仓库&quot;)、<code>ran</code>(发现时已经运行完为 true,正在运行、已打断为 false)、<code>agentId</code>、<code>callId</code>(同一个调用只处理一次)</td></tr><tr><td><code>secretScans</code></td><td>array</td><td>可选,1.14 起。改代码的步骤之后的密钥扫描(<code>secretScan</code>),每个步骤、每次尝试保留最新一次:<code>key</code>、<code>attempt</code>、<code>at</code>、<code>findings</code>(<code>{ file, line, commit, kind, preview }</code>,<code>preview</code> 里的值已遮住)、<code>fixRounds</code>、<code>passed</code></td></tr><tr><td><code>profile</code></td><td><code>quick</code> | <code>standard</code></td><td>档位</td></tr><tr><td><code>branch</code></td><td>string | null</td><td>工作分支,启动时确定</td></tr><tr><td><code>milestones</code></td><td>string[]</td><td>已发送的进展通知,续跑时不重复发送</td></tr><tr><td><code>incremental</code></td><td>object | null</td><td>可选,1.3.0 起。需求变更或回答问题后的继续:<code>fromAttempt</code>(接着哪一次)、<code>reason</code>、<code>baseCommit</code>(本次开始时的提交,评审看这之后的改动)、<code>hadImplementation</code>(上一次是否已写过代码)。第一次运行和 <code>--restart</code> 为 null</td></tr><tr><td><code>worktree</code></td><td>object | null</td><td>可选,1.5.0 起。用 <code>--worktree</code> 启动、在为需求新建的工作区中开发时:<code>workspaceId</code>(Paseo 工作区)、<code>sourceRepo</code>(对话所在的目录)。此时 <code>repo</code> 是新工作区的目录</td></tr><tr><td><code>schedules</code></td><td>array</td><td>可选,1.6.0 起。这次运行创建的 Paseo 定时任务:<code>id</code>、<code>kind</code>(<code>reminder</code> 提醒 / <code>auto-resume</code> 自动继续 / <code>watchdog</code> 定时检查)、<code>at</code>。下一次运行或暂停命令会取消它们</td></tr><tr><td><code>autoResumes</code></td><td>object | null</td><td>可选,1.6.0 起。<code>attempt</code>、<code>count</code>:这次尝试已经预约过几次自动继续</td></tr><tr><td><code>queuedSince</code></td><td>string | null</td><td>可选,1.6.0 起。正在排队(<code>maxConcurrentPipelines</code>)时为开始排队的时间</td></tr><tr><td><code>phases</code></td><td>object | null</td><td>可选,1.7.0 起。这次运行的执行方式:<code>mode</code>(<code>continuous</code> / <code>gated</code> / <code>develop-only</code>)、<code>environment</code>(<code>local</code> / <code>deployed</code>)、<code>defects</code>(<code>fix</code> / <code>handback</code> / <code>report</code>)。没有时按 <code>continuous</code>、<code>local</code>、<code>fix</code> 处理</td></tr><tr><td><code>phase</code></td><td><code>develop</code> | <code>verify</code></td><td>可选,1.7.0 起。当前阶段。用字符串而不是编号,以后增加阶段不用改格式</td></tr><tr><td><code>verifyAt</code></td><td>string | null</td><td>可选,1.7.0 起。<code>--verify-at</code>:研发完成后在这个时间开始测试验证</td></tr><tr><td><code>handbacks</code></td><td>number</td><td>可选,1.7.0 起。测试验证把缺陷退回研发阶段的次数(<code>defects</code> 为 <code>handback</code>),上限为档位的 <code>defectFix</code> 轮数</td></tr><tr><td><code>type</code></td><td><code>defect</code> | <code>refactor</code> | <code>assessment</code> | null</td><td>可选,1.8.0 起。spec 中&quot;类型&quot;对应的做法;新需求、小改动和配置关掉的类型为 null</td></tr><tr><td><code>codeBase</code></td><td>object | null</td><td>可选,1.8.0 起。<code>attempt</code>、<code>commit</code>:这次尝试在改动任何代码之前的提交,质量门的基线和范围检查从这里比较。尝试开始时就已经写过代码的旧记录为 <code>commit: null</code></td></tr><tr><td><code>joint</code></td><td>array | null</td><td>可选,1.8.0 起。联合需求(spec 的 <code>- 联合开发:</code>)中其他仓库的工作区:<code>name</code>(<code>relatedRepos</code> 中的名称)、<code>slug</code>(步骤键的后缀,如 <code>implement@backend</code>)、<code>sourceRepo</code>(切出工作区的那份检出)、<code>repo</code>(工作区目录)、<code>workspaceId</code>、<code>branch</code>、<code>specHash</code>(最近一次同步过去的 spec),以及这个仓库自己的 <code>codeBase</code> 和 <code>gate</code>(格式同顶层)。见 ADR 0025</td></tr><tr><td><code>approval</code></td><td>object | null</td><td>可选,1.8.0 起。方案确认点:<code>attempt</code>(哪一次尝试的方案)、<code>status</code>(<code>waiting</code> / <code>approved</code>)、<code>at</code>。需求变更后的新尝试需要重新确认</td></tr><tr><td><code>external</code></td><td>object | null</td><td>可选,1.9.0 起。外部系统中的卡片,按集成名称:<code>id</code>(卡片编号)、<code>url</code>、<code>status</code>(最近设置的状态)、<code>syncedAt</code>、<code>pending</code>(没有成功、等待补发的调用:<code>action</code> 为 <code>create</code> / <code>status</code>、<code>event</code>、<code>status</code>、<code>at</code>、<code>attempts</code>、<code>error</code>)。见 ADR 0028</td></tr><tr><td><code>pushed</code></td><td>array | null</td><td>可选,1.10 起。从卡片开始、配置了 <code>push</code> 的需求推送过的分支,每个仓库一条(主仓库在前):<code>repo</code>、<code>remote</code>、<code>branch</code>、<code>at</code>、<code>error</code>(成功时为 null;1.14 起,发现疑似密钥时不推送,<code>error</code> 写明原因)。见 ADR 0029</td></tr><tr><td><code>gate</code></td><td>object | null</td><td>可选,1.8.0 起。质量门:<code>baseline</code>(<code>attempt</code>、<code>commit</code>、<code>at</code>、<code>results</code>:每项检查改动前 <code>pass</code> / <code>fail</code>),<code>runs</code>(每次运行:<code>key</code> 步骤键、<code>attempt</code>、<code>at</code>、<code>checks</code>(<code>name</code>、<code>result</code>:<code>pass</code> / <code>fail</code> / <code>skipped</code>、<code>failedBefore</code>)、<code>newFailures</code>、<code>fixRounds</code>、<code>passed</code>)。各次运行的完整输出在 <code>.pipeline/checks/&lt;步骤键&gt;/</code></td></tr></tbody></table><p><code>schedules[].kind</code> 在 1.7.0 起还可能是 <code>verify-start</code>(<code>--verify-at</code> 预约的测试验证开始),1.8.0 起还可能是 <code>approval-continue</code>(方案确认超时后按方案继续,<code>designApproval.autoContinueHours</code>)。<code>history</code> 中每条步骤记录在 1.7.0 起有可选的 <code>phase</code>(<code>develop</code> / <code>verify</code>),用于按阶段统计用时与用量;没有时按研发阶段统计。</p><h2 id="迁移" tabindex="-1">迁移 <a class="header-anchor" href="#迁移" aria-label="Permalink to &quot;迁移&quot;">​</a></h2><p>只增加可选字段(缺少时按默认值处理,旧版本引擎读到也不出错)时不提升版本,以便回滚到旧版本后仍能继续已有的流水线;在上表中注明&quot;可选&quot;和起始版本即可。</p><p>引擎(<code>engine/src/state.ts</code>)中 <code>STATE_VERSION</code> 是当前版本,<code>STATE_MIGRATIONS[n]</code> 把第 n 版升级到第 n+1 版。增加必需字段或改变已有字段的含义时:</p><ol><li><code>STATE_VERSION</code> 加 1。</li><li>在 <code>STATE_MIGRATIONS</code> 中加一个从旧版本到新版本的函数,为旧文件补上默认值。</li><li>在 <code>engine/test/state.test.ts</code> 中加一条迁移测试,更新本文件。</li></ol></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/state.md">contracts/state.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/state.md">在 GitHub 上编辑</a></p>',2)])])}const h=d(r,[["render",a]]);export{m as __pageData,h as default};