@hoplogic/hopjit 0.1.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 (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +99 -0
  3. package/dist/act-body-interpreter.d.ts +24 -0
  4. package/dist/act-body-interpreter.js +159 -0
  5. package/dist/act-body-parser.d.ts +10 -0
  6. package/dist/act-body-parser.js +577 -0
  7. package/dist/act-builtins.d.ts +12 -0
  8. package/dist/act-builtins.js +104 -0
  9. package/dist/ast-helpers.d.ts +26 -0
  10. package/dist/ast-helpers.js +58 -0
  11. package/dist/ast-runtime.d.ts +49 -0
  12. package/dist/ast-runtime.js +224 -0
  13. package/dist/ast-types.d.ts +260 -0
  14. package/dist/ast-types.js +4 -0
  15. package/dist/cli-types.d.ts +190 -0
  16. package/dist/cli-types.js +4 -0
  17. package/dist/cli.d.ts +26 -0
  18. package/dist/cli.js +623 -0
  19. package/dist/dispatcher.d.ts +92 -0
  20. package/dist/dispatcher.js +692 -0
  21. package/dist/doc-ref.d.ts +41 -0
  22. package/dist/doc-ref.js +214 -0
  23. package/dist/engine-traverse.d.ts +37 -0
  24. package/dist/engine-traverse.js +385 -0
  25. package/dist/engine.d.ts +141 -0
  26. package/dist/engine.js +1792 -0
  27. package/dist/errors.d.ts +47 -0
  28. package/dist/errors.js +34 -0
  29. package/dist/hoplog.d.ts +120 -0
  30. package/dist/hoplog.js +501 -0
  31. package/dist/parser.d.ts +7 -0
  32. package/dist/parser.js +802 -0
  33. package/dist/persistence.d.ts +60 -0
  34. package/dist/persistence.js +208 -0
  35. package/dist/prompt.d.ts +130 -0
  36. package/dist/prompt.js +1014 -0
  37. package/dist/provider-types.d.ts +134 -0
  38. package/dist/provider-types.js +3 -0
  39. package/dist/runtime-types.d.ts +84 -0
  40. package/dist/runtime-types.js +4 -0
  41. package/dist/tools.d.ts +16 -0
  42. package/dist/tools.js +141 -0
  43. package/dist/validator.d.ts +23 -0
  44. package/dist/validator.js +959 -0
  45. package/driver/codex/AGENTS.md +54 -0
  46. package/driver/hopskill-build/SKILL.md +137 -0
  47. package/driver/hopskill-build/references/spec-skeleton.md +132 -0
  48. package/driver/hopskill-build/references/step-type-cheatsheet.md +56 -0
  49. package/driver/hopskill-build/references/three-focus-rules.md +148 -0
  50. package/driver/hopspec-skill.md +187 -0
  51. package/driver/references/cli-discovery.md +36 -0
  52. package/driver/references/discovery.md +45 -0
  53. package/driver/references/driver-subagent.md +50 -0
  54. package/driver/references/parallel-worker.md +50 -0
  55. package/driver/references/step-execution-rules.md +47 -0
  56. package/package.json +52 -0
@@ -0,0 +1,54 @@
1
+ %% @trace
2
+ id: hopspec-codex-driver
3
+ source: [[hopspec-driver-skill]]
4
+ source_id: hopspec-driver-skill
5
+ type: extend
6
+ last_sync: 2026-07-13T00:00+0800
7
+ note: Codex CLI 复用模式驱动指令(载体=AGENTS.md)。与 CC 版 driver/hopspec-skill.md 同构——同一套引擎/CLI/references、同一套 fanout 顾问 + subagent 编排,只换四处载体差异(问人/子agent工具/触发方式/act工具映射)。references(cli-discovery/driver-subagent/parallel-worker/step-execution-rules)载体中立,两家共享、不复制。厂商中立分析见 [[HopSpec-Codex复用模式对接分析]]。
8
+ %%
9
+
10
+ # HopSpec Codex 驱动指令(复用模式,载体 = Codex CLI)
11
+
12
+ > 本文件是 CC 版 `driver/hopspec-skill.md` 的 **Codex 载体等价物**。引擎/CLI/references **完全相同**(hopjit CLI 纯 JSON、agent 无关),编排逻辑同构——主 agent 只编排介入点、执行段外包 subagent、parallel 用 fanout 顾问 + 满额窗口。**唯一差异是四处载体原语映射**(下表)。CC 版正文的每条规则在 Codex 下等价成立,读 CC 版 `hopspec-skill.md` 的 §0–§3 为完整流程,本文件只列 Codex 的原语替换 + 骨架。
13
+
14
+ ## 🔴 载体原语映射(CC → Codex,这是唯一的差异面)
15
+
16
+ | 能力 | CC(hopspec-skill.md 写法) | Codex 等价 |
17
+ |---|---|---|
18
+ | **触发** | slash command `/hopspec run <spec>` | 自然语言任务("用 hopspec 跑这个 spec" / "驱动执行 <spec>");本 AGENTS.md 作为 Codex 项目指令常驻 |
19
+ | **起 subagent** | `Agent` 工具起 driver subagent / parallel worker | Codex 的 subagent 机制起子会话(本地,非 Codex Cloud)——每个 subagent 一个 child/执行段,one-shot 跑完返回。并发用 git worktree 隔离(见 [[HopSpec-Codex复用模式对接分析]] §5) |
20
+ | **问人(介入点)** | `AskUserQuestion` 工具 | 直接在主会话向用户自然语言提问,等用户回复——Codex 主会话即人机交互回路。references/discovery.md 与 CC 版 §2 里所有 `AskUserQuestion` 对 Codex = "主会话 NL 问用户" |
21
+ | **完成通知** | `task-notification`(后台 subagent 完成回调) | Codex subagent 返回即完成信号;无独立通知机制则主 agent 起 subagent 后等其返回(同步 join),或按 worktree 完成(`hopjit done` 落盘)轮询 `.hopstate`(分析 §6 方案 B) |
22
+ | **act 工具** | Bash / Read / Write 工具 | Codex 的 shell 执行 + 文件读写。`<CLI>` 命令用 shell 跑;act 步无 body 时用 shell/文件操作,操作范围受 spec SandboxConfig 约束(复用模式下 sandbox 退化为契约,见分析 §1) |
23
+
24
+ **除上表四处,其余一切与 CC 版一致**:`<CLI>`/`<PKG>` 自举探测([[cli-discovery]],四级探测,Codex 同样跑)、主 agent 不碰执行链、介入点归主 agent、执行段/worker 归 subagent、fanout-plan/fanout-next 顾问调度、work_zone 硬边界、submit 的 `--instance` 复合路径规则——**全部照 CC 版 references 执行,不重述**。
25
+
26
+ ## 前置条件
27
+
28
+ - `hopjit` CLI 可用(`npm i -g @hoplogic/...` 或本地)。启动最前跑 CLI 自举探测确定 `<CLI>`/`<PKG>`——算法见 `<PKG>/driver/references/cli-discovery.md`(载体中立,Codex 直接用)。
29
+ - standalone 模式才需 API key;复用模式(Codex 当推理 LLM)不需要。
30
+
31
+ ## 执行流程(同构 CC,原语按上表替换)
32
+
33
+ ### 0. 前置:定位 spec + 组装 params
34
+ 照 `<PKG>/driver/references/discovery.md`(spec 搜索 + recent-dirs + 读 `## Inputs` 推断参数)。其中 `AskUserQuestion` → Codex 主会话 NL 问用户确认。
35
+
36
+ ### 1. 启动 + 姿态
37
+ 主 agent 只编排,**全程不碰执行链**(不自己 run/submit 执行步——抢跑污染 hoplog)。起首个 driver subagent 从 `run` 起(模板见 `<PKG>/driver/references/driver-subagent.md`,载体中立),它跑到介入点/终态返回 JSON + instance_id。
38
+
39
+ ### 2. 主 agent 编排循环(按 status 分派,同 CC §2)
40
+ - **step_ready** → 起 driver subagent 跑执行段(Codex subagent),跑到介入点/终态返回。
41
+ - **paused(confirm/ask)** → **主会话 NL 问用户**(不替答;present_inputs 非空须先完整 dump 原文再问,同 CC 硬约束),拿到答复 `<CLI> submit_and_fetch_next <step_id> --answer ... --instance <id>`。
42
+ - **parallel_ready** → 主 agent 编排 fan-out:`<CLI> fanout-plan <pid>` 拿初始批 → 起 subagent worker(worktree 隔离)→ 每个完成 `<CLI> fanout-next <pid> --done <cid> --status <s>` 拿补位/join → 全终态 `join_parallel`。流程 + worker 模板见 `<PKG>/driver/references/parallel-worker.md`(载体中立)。
43
+ - **adaptive_needed** → 读失败上下文,生成新步骤 markdown,`<CLI> submit_and_fetch_next <subtask_id> --replan '...' --instance <id>`。
44
+ - **completed / failed** → 报终态结束。
45
+
46
+ ### 3. 异常处理 / 进度 / 约束
47
+ 同 CC 版 §3 + 输出纪律 + 约束节,逐条等价(`references/step-execution-rules.md` 载体中立,subagent 自引用)。
48
+
49
+ ## 厂商中立红线(Codex 特有,见 [[HopSpec-Codex复用模式对接分析]])
50
+
51
+ - subagent 并发只用 **git worktree(本地)**+ 进程/shell(L0 通用原语),**不碰 Codex Cloud**(唯一禁区,OpenAI 云容器)。
52
+ - worker 模型经 HopSpec `@model` 路由任意后端,不锁 GPT。
53
+ - 完成判据始终是 `.hopstate` 状态,不是 git commit。
54
+ - 换任何"多轮+shell+子agent"能力的开源 runtime,对接逻辑不变——这是中立性的终极检验。
@@ -0,0 +1,137 @@
1
+ ---
2
+ name: hopskill-build
3
+ description: >
4
+ 把一个自然语言(prose)skill 翻译成结构化的 HopSpec 规约(hopskill),
5
+ 用 HopSpec 的引擎强制取代 prose 里"靠 LLM 记住"的纪律。三个正确性焦点:
6
+ 循环遍历不漏(for-each)、审核不跳过(confirm 人审 + check 产出核验)、
7
+ 试错阶段不做 commit 等不可撤回操作(act 可逆 / commit 隔离)。
8
+ Trigger: "把 skill 转成 spec", "生成 hopskill", "skill 转 hopspec",
9
+ "translate skill to hopspec", "hopskill 构建", "/hopskill-build".
10
+ user_invocable: true
11
+ ---
12
+
13
+ %% @trace
14
+ id: hopskill-build-skill
15
+ type: intent
16
+ last_sync: 2026-07-05T15:02+0800
17
+ note: 把 prose skill 翻译成 HopSpec spec 的构建器(prose skill 形态,不自举)。输入=现有 prose skill 文件。三焦点=循环不漏(for-each)/审核不跳(confirm+check)/试错不 commit(act vs commit),一一对应概念层 ^anc-step-parallel / ^anc-step-confirm+^anc-exec-hitl-presentation+^anc-step-check / ^anc-step-act vs ^anc-step-commit。细则外置 references/(spec-skeleton / step-type-cheatsheet / three-focus-rules)。与 anchor-audit/hopspec 同层,纯 skill 层零引擎改动。2026-07-04 补三处(元翻译暴露的缺口):§4 忠实门加"功能一致性·行为映射表"第一关(prose 每行为↔spec 步骤逐一核对、无遗漏无杜撰、I/O 与控制流保留);§3 + spec-skeleton「知识抽取与 doc-ref」——大段 act/reason/check 判据外置成 <spec-id>-knowledge.md 陪伴文档、`>` 用 doc-ref 引、引擎运行期自动注入(照 anchor-audit 模式);知识文档必须与 spec 同住目标 skill 目录、doc-ref 目录内相对引用、禁引目录外(doc-ref 按 cwd 解析禁 `..`,跨目录 run 期必 P15 失败)。元翻译样本 hopskill-build.md 自身的 3/4/5.1 reason 步经此修正——原赌"执行 LLM 自带 V3 语法",改为 doc-ref 引 hopspec-v3-syntax.md(同 examples/ 目录),实测 doc_ref_context 真注入。2026-07-04 再修两处(作者校准):① commit 不是"必前置 confirm"——按概念层 ^anc-step-commit,commit 前序把关闸门三选一(confirm 人审 / 足够 check 验证 / 环境预授权),改遍全 skill+references+知识文件 7 处 + 补 check 把关生成模板 B;② 三焦点分别标注 + 生成后三个独立 subtask 逐关检查修正(作者定:做成引擎强制的 spec 结构)——§2 加 focus 标注要求、§4 拆成语法门→逐焦点三关独立检查→忠实门,样本 hopskill-build.md 把三关建模为三个带 check finally 的独立 subtask(引擎强制不能跳、失败 retry)。③ check 失败反馈走概念层「带反馈重跑」非前向引用(作者指出 5.1 等重跑步拿不到 syntax_issue;并纠正:L2c 是 prompt 组装层内部编号、非概念层,不该外露——概念层正式机制是 ^anc-exec-retry-adaptive 升级阶梯第 1 档"带反馈重跑",check text 槽即反馈源):失败说明自动注入重跑 context,重跑步不写 `← 说明槽`(前向引用违反 v1)、`>` 点明据带反馈重跑注入的失败说明定向修正;补 step-type-cheatsheet + hopspec-v3-syntax「check 失败反馈」段 + 样本四个重跑步 `>`,全部改用概念层"带反馈重跑"表述、去 L2c 黑话。2026-07-05 references 追平引擎两轮改造(resume scope 树 v2 + 变量 Python 化):spec-skeleton 节点体加 `= 初值` 语法、新增「变量语义与累加器」节(Python 自然保留 / 累加器 `+→ acc=初值` init 一次 / `=Null` 每轮重置 / 🔴 累加器更新步必放容器直接子步 DEBT-12 陷阱)、修 v2 规则去"当轮变量"旧术语;step-type-cheatsheet loop 行"延续变量"→"累加器+自然保留"。端到端验证:批量校验累加 error_log 场景,违规版(更新步在 case 内)实测 error_log 停初值 [](DEBT-12 咬人),合规版(更新步在 loop 直接子步)累积 ['err:bad1','err:bad2'] 正确——双向验证 warning 与正解。2026-07-05 显式错误反馈(作者指出 5.1"据错误修正"逻辑不显式、靠隐式带反馈重跑):先撞引擎真 bug(DEBT-13:check finally 更新模式回填祖先 last_err 时 retry 失效——failStep 无差别 null 化 check 输出误伤 last_err + check 失败不写输出),插桩定位根因后修引擎两处(failStep 跳过更新模式输出 + check 失败先写更新模式输出,^anc-exec-failstep-skip-update)。样本 §4-8 改用显式 last_err 通道:步骤4 init `last_err=""`,各 check finally 更新模式回填错误、各 reason 步 `← last_err` 定向修正。实跑验证 5.3 失败→5.1 重跑 inputs 含回填的 last_err("据错误修正"成 spec 数据流一等公民,不再靠隐式注入)。知识文件「check 失败反馈」段改教显式 last_err 通道。
18
+ %%
19
+
20
+ # /hopskill-build — 把 prose skill 翻译成 HopSpec 规约
21
+
22
+ 把一个自然语言写的 skill(prose SKILL.md)翻译成结构化的 **HopSpec 规约(hopskill)**,之后可用 `/hopspec run` 驱动执行。
23
+
24
+ **为什么要翻译**:prose skill 的纪律靠执行 LLM"读到并记住"——上下文压力下会漏遍历项、擅自跳过审核、试错期就做不可逆操作。翻成 hopskill 后,这些纪律由 **HopSpec 引擎结构化强制**,不再靠记忆。这正是本 skill 的三个正确性焦点。
25
+
26
+ ## 宪法级原则(三焦点不可降级,违反 = 翻译错误)
27
+
28
+ 翻译的正确性底线是这三条——不是风格偏好,违反即错误:
29
+
30
+ 1. **循环遍历不漏 → 必 for-each**:prose 里每个"对每一个/逐个/遍历"都必须翻成 `parallel + for-each` 容器(引擎按列表长度动态复制、全部完成才 join)。**禁止**翻成 act body 里的 `for` 循环或 reason"逐个分析"——那把遍历完整性又交回 LLM 记忆。
31
+
32
+ 2. **审核不跳过 → 必 confirm 或 check(两层)**:
33
+ - **人来把关**(审批/授权/"让用户确认")→ `confirm`(paused/HITL,driver 不得替答,reject 全局中止)。**禁止**翻成 reason"判断是否该批准"(架空外部决策者)。
34
+ - **产出核验**("验证达标"/"确保满足约束"/prose 的每条 Constraints)→ `check`,关键验收放 `subtask + check finally`(不可被 adaptive 跳过)。**禁止**丢失原 prose 里的任何约束验收。
35
+
36
+ 3. **试错不 commit → act 可逆 / commit 隔离**:不可逆操作(发送/支付/写生产/删除/提交)必翻成 `commit`,且其**前序须有把关闸门**——confirm(人审)**或**足够的 check(验证放行条件满足)**或**环境预授权(能执行到即已授权)三选一;试错/中间产物用 `act`(可安全重跑)。**禁止**把不可逆操作放进 act、让 commit **无任何前序把关**、或把 commit 塞进 retry 容器。
37
+
38
+ > 三条的概念层权威锚点、识别信号、生成模板、反例,全在 `<PKG>/driver/hopskill-build/references/three-focus-rules.md`——翻译时逐焦点对照。
39
+
40
+ **另两条原则**:
41
+ - **忠实翻译,不增删业务逻辑**:只做 prose→spec 的结构化映射,不擅自加/减工作流步骤(核心观点归原 skill 作者)。prose 意图不清 → §4 问作者,不臆断。
42
+ - **生成即校验**:产出的 spec 必须过 `validate`(语法)+ 作者过目(语义忠实),双门都过才交付。
43
+
44
+ ## 翻译流程
45
+
46
+ ### §0 前置:定位输入 prose skill
47
+
48
+ 用户给了路径就用;没给则列出 `.claude/skills/` 下的 prose skill 供选(跳过已有对应 spec 的)。读输入 skill **全文**——SKILL.md + 它引用的 references(若有)。
49
+
50
+ ### §1 骨架识别
51
+
52
+ 从 prose 抽出 HopSpec 骨架各部件:
53
+
54
+ | prose 里的 | → HopSpec |
55
+ |---|---|
56
+ | skill 的目的/一句话功能 | `Goal:` |
57
+ | 输入参数 / 触发时给的数据 | `Inputs:` |
58
+ | 最终交付物 | `Outputs:` |
59
+ | 硬约束、"必须"、"不可" | `Constraints:`(→ 多数应有对应 check)|
60
+ | 复用的复合数据结构 | `Types:` |
61
+ | 步骤序列 | `## Steps` |
62
+
63
+ 识别每个步骤的 step 类型用 `<PKG>/driver/hopskill-build/references/step-type-cheatsheet.md` 的「NL 措辞 → step 类型映射」表(分析→reason、机械执行→act、不可逆→commit、验证→check、审批→confirm、收数据→ask、遍历→for-each、循环→loop、业务分支→branch)。
64
+
65
+ ### §2 三焦点强制标注(核心,逐焦点过一遍)
66
+
67
+ 对 §1 的步骤草稿,**逐一过三关**(判据/模板/反例见 `<PKG>/driver/hopskill-build/references/three-focus-rules.md`):
68
+ - **① 遍历**:找出所有遍历点 → 全部改成 `parallel + for-each`(一个 child 模板,列表变量 `[T]`)。
69
+ - **② 审核**:找出所有把关点 → 人审→confirm(含 require_human 判断);产出核验→check(关键的 subtask+check finally)。逐条核对 prose 的 Constraints 都有 check 落地。
70
+ - **③ 不可逆**:找出所有有外部副作用的操作 → 可逆→act,不可逆→commit 且其前序有把关闸门(confirm 人审 / 足够 check 验证 / 环境预授权,三选一)。检查 commit 不在 retry 容器内。
71
+
72
+ **🔴 三焦点落点必须显式标注**(供 §4 逐关检查、供人审计):每个因三焦点而定型的步骤,在其 `>` 末尾加一行焦点标注注释——`> focus①:遍历不漏` / `> focus②:审核(confirm 人审 | check 核验)` / `> focus③:不可逆(把关=confirm/check/预授权)`。标注让"哪步为哪个焦点服务"从脑中判断变成 spec 里可核查的事实,不能混在普通步骤里靠人认。某焦点无触发则不标、并在报告里说明。
73
+
74
+ ### §3 生成 spec.md
75
+
76
+ 按 `<PKG>/driver/hopskill-build/references/spec-skeleton.md` 的骨架 + 语法,产出完整 spec.md 文本:
77
+ - 文件头(`# Spec:` / `Goal:` / `Inputs:` / `Outputs:` / `Constraints:` / `Types:`)。
78
+ - `## Steps`:每步 `[type]` + `- ←` 输入 + `+ →` 输出(首现标类型+说明)+ `>` 执行说明。
79
+ - act/commit 若是纯机械执行,配 ` ```hop_python ` body(无推理、无循环、确定性分支)。
80
+ - 变量流自查:每个 `←` 都能追到前序 `→` 或 `Inputs`(避免 validate v1 报错)。
81
+ - **大段判据知识外置**:当某个 act/reason/check 步的 `>` 承载**大段判据/评分规则/方法论/清单**(超几行、或含可复用的判定标准),**不要**全塞进 `>`——抽成陪伴 knowledge 文档、`>` 里用 doc-ref `[[knowledge文件#章节]]` 引,引擎运行期自动切片注入该步上下文。spec 只留编排骨架,判据沉于知识文档。判据与生成方法见 `spec-skeleton.md`「知识抽取与 doc-ref」。范本:`examples/anchor-audit.md`(判据全在 `anchor-audit-knowledge.md`,spec 各步 `[[anchor-audit-knowledge#…]]` 引)。
82
+ - **🔴 知识文档必须与 spec 同住目标 skill 目录**(硬约束):抽出的 knowledge 陪伴文档与生成的 spec **同置一处**(目标 skill 目录),doc-ref 用**目录内相对引用**(裸文件名,如 `[[xxx-knowledge#章节]]`)。**禁止引用 skill 目录外的文件**——doc-ref 按运行时 `workspace_dir`(cwd) 解析且**禁 `..`**,跨目录/向上引用运行期必 P15 失败(validate 未必拦得住,因它按 spec 所在目录校验,与运行 cwd 未必一致)。理由:hopskill + 其 knowledge 是**自包含可分发单元**,引用不依赖外部 cwd 猜测。
83
+
84
+ ### §4 自校验(语法门 → 逐焦点独立检查修正 → 忠实门)
85
+
86
+ 生成后**必须**依次过下述闸门,缺一不可——这一步本身就是"审核不跳"的现身说法,构建器自己也吃自己的狗粮:三关分别独立检查、不到位当场修正,而非一次性笼统过目。
87
+
88
+ 1. **语法门**:跑(`<CLI>` = hopjit 调用前缀,首次用前按 `<PKG>/driver/references/cli-discovery.md` 探测确定——可能是 `hopjit` 或 `node <abs>/cli.js`;`<PKG>` 同由探测得)
89
+ ```bash
90
+ <CLI> validate <生成的spec路径>
91
+ ```
92
+ 有 error 就回 §3 修正重跑,直到零 error。
93
+
94
+ 2. **逐焦点独立检查并修正(三关,分别独立)**:对生成的 spec,**三个焦点各自独立检查一遍**(据 §2 的 focus 标注 + `three-focus-rules.md` 判据),不到位就**当场回 §3 修正、重查该关**:
95
+ - **焦点① 检查**:原 prose 每个遍历点是否都成了 `for-each`?有无被误翻成 act body 循环 / reason 逐个分析?(无遍历则记"无触发")
96
+ - **焦点② 检查**:原 prose 每个人审是否都成了 `confirm`、每个产出核验/每条 Constraints 是否都有 `check`(关键的 check finally)?有无审核被误翻成普通 reason/act?
97
+ - **焦点③ 检查**:每个不可逆操作是否都成了 `commit` 且**前序有把关闸门**(confirm/足够 check/环境预授权,任一即可)?commit 有无落进 retry 容器?有无不可逆操作漏放进 act?
98
+ > hopskill-build 自身的 hopskill(`examples/hopskill-build.md`)把这三关建模为**三个带 `check finally` 的独立 subtask**(引擎强制三关都跑、不能跳、失败 retry 修正)——这是本条的"引擎强制"落地范本。
99
+
100
+ 3. **忠实门(问作者)**:三关都过后,用 `AskUserQuestion` 请作者做最终审阅,呈交:
101
+ - **① 功能一致性——行为映射表**:翻出的 hopskill 跑起来必须与原 prose **行为等价**。逐一列出原 prose 每个行为/步骤 → 对应 spec 步骤,核对无遗漏(每个 prose 行为都有步骤承接)、无杜撰(spec 没多出 prose 没有的业务步骤)、Inputs/Outputs 对得上、控制流保留。有行为找不到落点或步骤找不到来源 → 不一致,回 §1/§3 修。
102
+ - **② 三焦点落点报告**:据 focus 标注列出三焦点各落在哪些步骤 + 上一步三关检查结论;**某焦点无真实触发时如实说明**,不强造。
103
+ 连同任何拿不准的 prose 意图一并呈交。作者批准后才 §5。
104
+
105
+ ### §5 写盘 + 报告
106
+
107
+ 作者批准后写出 spec.md(位置与作者商定,缺省 `<PKG>/examples/` 或与原 skill 同域)。报告:三焦点各落在哪些步骤、validate 结果、后续可 `/hopspec run <生成的spec>` 执行。
108
+
109
+ ## Bash 纪律(硬约束)
110
+
111
+ - 每条 Bash 只做一件事,不链式(`&&`)、不管道(`|`)——管道触发 pipe_guard 弹框。
112
+ - validate 直接写完整命令 `<CLI> validate <spec>`,自己读 JSON 输出。
113
+
114
+ ## 约束
115
+
116
+ - **输入限现有 prose skill 文件**——不做任意自然语言需求→spec 的泛化。
117
+ - **不修改输入 skill 本身**——只读它、产出新 spec。
118
+ - **纯 skill 层,不碰引擎**——不改 `src/`、`design/`、概念层规范,只引用其锚点。
119
+ - **不自动写盘不问人**——§4 作者审阅是硬闸门。
120
+
121
+ ## 参考(细则外置)
122
+
123
+ (均在 `<PKG>/driver/hopskill-build/references/`)
124
+ - `three-focus-rules.md` — ⭐ 三焦点识别信号/生成模板/反例(翻译正确性核心)
125
+ - `step-type-cheatsheet.md` — 14 种 step 类型 + NL→step 选型映射
126
+ - `spec-skeleton.md` — HopSpec 文件骨架 + 语法速查 + 验证规则自查
127
+ - 活教材:`<PKG>/examples/anchor-audit.md`(anchor-audit prose skill 翻成的 hopskill,三焦点全含)
128
+
129
+ ## 示例
130
+
131
+ ```bash
132
+ # 翻译一个现有 prose skill
133
+ /hopskill-build .claude/skills/test-coverage-audit/SKILL.md
134
+
135
+ # 不给路径则列出可选
136
+ /hopskill-build
137
+ ```
@@ -0,0 +1,132 @@
1
+ # HopSpec 文件骨架 + 语法速查
2
+
3
+ > hopskill-build §3 生成 spec.md 时的骨架模板与语法参考。权威在概念层 HopSpec V3 核心规范文档(`^anc-ast-spec-structure` 文件结构、`^anc-rule-v3-all` 27 条验证规则)——本文件是速查,拿不准回权威。
4
+
5
+ ## 文件骨架
6
+
7
+ ```markdown
8
+ # Spec: <标题>
9
+ Id: <kebab-case-id> # 可选,供 call 引用;含 commit 的 spec 建议加 _commit 后缀
10
+ Goal: <一句话业务目标>
11
+ > <可选:多行补充说明,展开 Goal 的背景/流程概览>
12
+
13
+ Constraints: # 可选,不可违反的硬约束(→ 常映射为 check finally 验收门)
14
+ - <约束1>
15
+ - <约束2>
16
+
17
+ Types: # 可选,复用的复合类型(PascalCase,≥2 词)
18
+ - <TypeName>:
19
+ - <field>: <type> # 说明
20
+
21
+ Inputs: # 可选,Spec 级输入(供 call 传参 / run --params 注入)
22
+ - <name>: <type> # 说明
23
+
24
+ Outputs: # 可选,交付物契约(exit 必须全部交付)
25
+ - <name>: <type> # 说明
26
+
27
+ Config: # 可选
28
+ model: <service/model> # Spec 默认模型路由
29
+
30
+ ## Steps # 有 Steps=具体实现(≥1步);无 Steps=能力声明(仅 Goal+Outputs,交 HopJIT 有序思考生成)
31
+ <步骤列表>
32
+ ```
33
+
34
+ **必需**:`# Spec:` 标题 + `Goal:`。其余按需。有 `## Steps` 则至少 1 步。
35
+
36
+ ## 节点体三前缀
37
+
38
+ ```markdown
39
+ N. [type 修饰] 一句话任务描述
40
+ - ← <var> # 输入:只写变量名(类型/说明在源头已声明)
41
+ + → <var>: <type> # 说明 # 输出:首次声明标类型+说明,后续仅写变量名
42
+ + → <var>: <type> = <初值> # 说明 # 可选:带初值(累加器/每轮重置,见「变量语义与累加器」)
43
+ > <执行说明:角色视角 / 关注维度 / 方法论 / 约束>
44
+ > @model service/model # 可选:步骤级模型路由
45
+ > @knowledge 关键词 # 可选:模糊知识检索注入(KnowledgeProvider)
46
+ > [[文档路径#章节名]] # 可选:doc-ref 精确引用(作者钉死必读知识,加载期校验存在性)
47
+ ```
48
+
49
+ **编号**:顶层 `1. 2. 3.`;容器子步 `3.1. 3.2.`;再嵌 `3.1.1.`。缩进 2 空格/层。
50
+
51
+ ## act / commit 的 hop_python body
52
+
53
+ act / commit 步骤可带 ` ```hop_python ` 围栏(无推理编排:纯计算 + 工具调用 + 确定性分支,**禁 for/while 循环**、禁 LLM 判断分支):
54
+
55
+ ```markdown
56
+ 1. [act] 统计指标
57
+ - ← raw_data
58
+ + → profile: yaml
59
+ > 无推理计算:逐字段统计缺失率/异常
60
+ > ```hop_python
61
+ > total = len(raw_data)
62
+ > missing = count_nulls(data: raw_data)
63
+ > profile = build_profile(total: total, missing: missing)
64
+ > ```
65
+ ```
66
+
67
+ 无 body 时按 `>` 自然语言描述执行(用宿主工具)。循环必须升为 HopSpec `loop` 步骤,不写进 body。
68
+
69
+ ## 常用值类型
70
+
71
+ `line`(单行文本)· `text`(多行)· `markdown` · `yaml` · `bool` · `int` · `float` · `[T]`(列表,如 `[text]`)· 自定义 `Types:` 里的 PascalCase 类型。
72
+
73
+ ## 变量语义与累加器(Python 语义)
74
+
75
+ 权威:概念层 `HopSpec V3核心规范.md ^anc-exec-loop-var-scope`。翻译时凡涉及"跨迭代累积"或"每轮重置"必按此写。
76
+
77
+ - **自然保留**:变量一律跨迭代(loop)、跨重试(subtask retry)**自然保留**,引擎不自动清空——同 Python 循环体。某轮未产出某变量,`←` 读到的是它上一次的值(不是空)。
78
+ - **累加器**(逐轮追加,如 error_log / findings):在 **loop/subtask 容器节点**声明 `+ → acc: type = 初值`,初值在**容器进入时 init 一次**(非每轮);子步骤用**更新模式**(`← acc … + → acc`)累加:
79
+ ```markdown
80
+ 1. [loop max_iterations=N] 逐项处理
81
+ + → error_log: yaml = [] # 累加器:容器进入 init 一次为空列表
82
+ 1.1. [act] 处理并记录
83
+ - ← error_log
84
+ + → error_log # 更新模式:追加本轮记录(非重声明)
85
+ ```
86
+ - **显式重置**(每轮清零某变量):在**子步骤**声明 `+ → x: type = Null`——该步每次执行时写入初值,loop 内即每轮重置。不写 `= 初值` 则自然保留上轮值。
87
+ - **初值字面量**:`Null`/`None`→空值;`[]` 空列表;`{}` 空对象;`0`;`false`;`"文本"` 或裸文本→字符串。
88
+ - **🔴 累加器更新步必须放容器直接子步**(DEBT-12 陷阱):累加器 `acc` 声明在 loop/subtask 节点时,更新它的步骤(`← acc + → acc`)**必须是该 loop/subtask 的直接子步**——**不能放进 case/更深嵌套容器内**。否则更新写入落到就近容器 scope(如 case scope),累加器所在 scope 收不到,`acc` 停在初值。深层需累加时:在深层用当轮变量产出,提到直接子步再合并进 acc。
89
+
90
+ ## 高频验证规则(生成后自查,避免 validate 报 error)
91
+
92
+ - **v1**:步骤输入 `←` 必来自前序步骤 `→` 输出或 `Inputs:` 声明——不能凭空引用。
93
+ - **v2**:变量名全局唯一;同名再次 `+ →` 是**更新**(在现有值上重写)非重声明,不算重名。累加器更新模式(`← X` 且 `+ → X`)、带 `= 初值` 的重置声明均放行(不报遮蔽)。
94
+ - **c6**:`check` 必须在 subtask/case 容器内(失败才有 retry 兜底)。
95
+ - **c7**:`check finally` 必在 subtask/case **末尾**。
96
+ - **s10**:有 Steps 的 spec ≥1 步;无 Steps 的必有 Goal+Outputs。
97
+ - **p15**:doc-ref `[[文档#章节]]` 的文件与章节必须真实存在(加载期校验)。
98
+ - **exit**:Outputs 声明的变量必须都被交付(无输出显式写 none)。
99
+
100
+ 生成完跑 `<CLI> validate <spec>` 核验。
101
+
102
+ ## 知识抽取与 doc-ref(大段判据外置)
103
+
104
+ **问题**:富 prose skill 常在某步塞大段**判据知识**——评分规则、FLAG 清单、分类标准、方法论、报告模板。若原样全塞进 spec 步骤的 `>`,spec 会臃肿(编排骨架被判据淹没)、且判据无法复用。
105
+
106
+ **做法**(照 `examples/anchor-audit.md` 模式):把大段判据抽成**陪伴 knowledge 文档**,spec 步骤的 `>` 用 doc-ref `[[knowledge文件#章节名]]` 引用,**引擎运行期自动切片注入**该步 agent 上下文(小节内联,超阈值转 `$file` 指针)——spec 只留编排骨架,判据沉于知识文档、引用即注入。
107
+
108
+ **何时抽**(判据):某个 act/reason/check 步的 `>` 满足任一 → 抽:
109
+ - 承载**可复用判定规则**(如"应 FLAG / 不应 FLAG"清单、严重度分类标准、评分区间);
110
+ - 大段**方法论/执行协议**(分几步、读哪些文件、±行号范围);
111
+ - **报告/输出格式模板**(章节结构、统计表格式);
112
+ - 纯经验:`>` 超过约 5-6 行且非"这一步具体做什么"的一次性指令。
113
+
114
+ **🔴 目录约束(硬)**:knowledge 文档必须与 spec **同置目标 skill 目录**,doc-ref 用目录内相对引用(裸文件名)。**禁引用 skill 目录外文件**——doc-ref 按运行时 `workspace_dir`(cwd) 解析且禁 `..`,跨目录/向上引用运行期必 P15 失败(validate 按 spec 所在目录校验、与运行 cwd 未必一致,故可能 validate 过、run 挂)。hopskill + knowledge 是自包含可分发单元。
115
+
116
+ **怎么抽**:
117
+ 1. 建陪伴文档 `<spec-id>-knowledge.md`(**与 spec 同一 skill 目录**),按判据主题分 `## 章节`(章节名即 doc-ref 锚点,须真实存在——validate p15 会校验)。遵循渐进展开:一个章节一个自足判据块。
118
+ 2. spec 步骤 `>` 里保留**一句话意图** + doc-ref 引用:
119
+ ```markdown
120
+ 6. [reason] 审计 mock 质量
121
+ - ← mock_patterns
122
+ + → mock_audit: yaml
123
+ > 对每个 mock 按注入的判据判定应否 FLAG,产出审计结果。引擎已自动注入(doc-ref):
124
+ > [[test-coverage-audit-knowledge#mock FLAG 判据]]
125
+ ```
126
+ 3. Constraints 里也可引用(如"判据权威见 `[[…-knowledge#…]]`,禁止自创判据")。
127
+
128
+ **不抽的**:一次性的"这一步具体干什么"(如"用 Write 把 X 写入 Y")留 `>` 即可,别为抽而抽。
129
+
130
+ ## 活教材
131
+
132
+ 结构完整的真实 spec:`<PKG>/examples/anchor-audit.md`(含 Inputs/Outputs/Constraints/Types + subtask/for-each/confirm/ask/check finally/commit/loop/branch 全套)、`data-quality.md`(中等规模,act+reason+subtask+check finally)。
@@ -0,0 +1,56 @@
1
+ # Step 类型速查 + 选型判据
2
+
3
+ > hopskill-build §1 骨架识别 / §3 生成时的 step 选型参考。权威在概念层 HopSpec V3 核心规范文档(各 `^anc-step-*`)。三焦点相关的 for-each/confirm/check/act/commit 详规见 `three-focus-rules.md`。
4
+
5
+ ## 14 种 step 类型一览
6
+
7
+ ### 叶子步骤(做实事)
8
+
9
+ | 类型 | 一句话语义 | 关键身份约束 |
10
+ |---|---|---|
11
+ | **reason** | LLM 推理/分析/判断,产出新知识 | 唯一"动脑"的步;信息不足触发 lack_of_info 走错误链 |
12
+ | **act** | 无推理、无循环的确定性计算 + 工具调用 | **必无不可逆副作用、可安全重做**;分支须确定性可求值 |
13
+ | **commit** | 有不可逆外部副作用的计算 + 工具调用 | **不可重试、需幂等**;前面须有 confirm 把关;不能在 retry/adaptive 内 |
14
+ | **check** | 验证已有产出是否达标,固定输出 `bool + text` | **必在 subtask/case 内**;失败触发容器 retry |
15
+ | **check finally** | 不可被 adaptive 改写或跳过的验收门 | **必在 subtask/case 末尾**;Constraints 的可执行化身 |
16
+ | **confirm** | 纯审批闸门,等外部决策者 approve/reject | paused/HITL;driver 不得替答;reject **全局中止** |
17
+ | **ask** | 向 caller 收集业务数据值 | 与 confirm 正交;无 reject;支持 present_inputs 呈交 |
18
+ | **call** | 调用另一个 spec,传参 + 收交付物 | 跨调用层 confirm 直达有权者 |
19
+
20
+ ### 结构步骤(控制流容器 / 跳转)
21
+
22
+ | 类型 | 一句话语义 | 关键身份约束 |
23
+ |---|---|---|
24
+ | **subtask** | 顺序执行子步的容器 | `retry=N`(缺省 3);`adaptive` 允许重规划策略 |
25
+ | **parallel** | 并发执行 children,**全部完成才继续** | 支持 `for-each` 动态展开;children 间无数据依赖 |
26
+ | **loop** | 循环执行 children 直到退出条件 | 变量跨迭代自然保留(Python 语义);累加器用 `+→ acc=初值`(见 spec-skeleton「变量语义与累加器」);`max_iterations=N` |
27
+ | **branch** | 条件决策,children 必全是 case | 无匹配 case 静默跳过(输出 None) |
28
+ | **case** | branch 下的分支条件 | 执行语义同 subtask;`(cond == "x")` 或 `default` |
29
+ | **break / continue** | 跳出 loop / 跳过本轮 | 仅 loop 容器内 |
30
+ | **exit** | 结束 spec,标记交付变量 | Outputs 声明变量须全部交付 |
31
+
32
+ ## NL 措辞 → step 类型映射(骨架识别用)
33
+
34
+ 读 prose skill 时,按动词/意图识别:
35
+
36
+ | prose 里出现… | → step 类型 |
37
+ |---|---|
38
+ | "分析"、"判断"、"评估"、"决定策略"、"解读" | **reason** |
39
+ | "计算"、"统计"、"提取"、"运行脚本"、"读文件"、"生成文本"(可重跑、无外部副作用)| **act** |
40
+ | "写入生产库"、"发送"、"支付"、"删除"、"提交 git"、"调用写 API"(不可逆)| **commit**(前序须有把关:confirm / 足够 check / 环境预授权)|
41
+ | "验证…是否达标"、"检查…对不对"、"确保…满足" | **check**(关键验收→ subtask + **check finally**)|
42
+ | "让用户确认"、"人工审批"、"等批准"、"需授权" | **confirm** |
43
+ | "询问用户"、"让用户提供/选择/填写" | **ask**(呈交内容用 `present_inputs`)|
44
+ | "对每一个X"、"逐个"、"遍历"、"批量处理列表" | **parallel + for-each**(见 three-focus-rules §1)|
45
+ | "重复直到"、"反复…直到满足" | **loop** |
46
+ | "如果…否则…"(业务分支) | **branch + case** |
47
+ | "分几步完成"、"可能要重试" | **subtask**(含 retry/adaptive)|
48
+ | "调用另一个 skill/流程" | **call** |
49
+
50
+ ## 选型注意
51
+
52
+ - **reason vs act**:要"动脑判断"用 reason;纯机械执行(策略已定)用 act。同一件事的"定策略"和"执行策略"应拆成 reason→act 两步(见 data-quality.md 步骤 2→3.1)。
53
+ - **act vs commit**:唯一分界是**副作用可逆性**。拿不准"这个操作能不能安全重跑"→ 当作不可逆,用 commit(保守安全)。commit 前序须有把关闸门——人审用 confirm、条件验证用足够的 check、已由环境预授权则无需额外步(能执行到 commit 即已授权),三者取其一,不必都用 confirm。
54
+ - **check 必须有容器**:孤立的 check 会 validate 报错(c6)。验收逻辑要么进 subtask(失败可 retry),要么就是 reason 里的自然判断。
55
+ - **check 失败反馈走「带反馈重跑」、不走 `←`**:`subtask retry` 里 check 判 false 时,其 **text 说明槽**(如 `*_issue`)作失败说明,触发升级阶梯第 1 档「带反馈重跑」(概念层 `^anc-exec-retry-adaptive`)——**上次失败说明自动注入重跑步上下文**。故重跑/修正步**不要写 `← <说明槽>`**(说明槽由后面的 check 产出,`←` 引用=前向引用,违反 v1);重跑步 `>` 点明"依据带反馈重跑注入的上次失败说明定向修正"即可。check 说明槽命名要能承载"哪里不达标",供反馈有料。
56
+ - **for-each 只能一个 child 模板**:parallel 下写一个 child,引擎按列表长度复制 N 份。多个不同 child 用普通 parallel(非 for-each)。
@@ -0,0 +1,148 @@
1
+ # 三焦点翻译规则(hopskill-build 的正确性核心)
2
+
3
+ > hopskill-build §2 逐一过这三关。每焦点给:**识别信号**(prose 里怎么认出它)→ **生成模板**(翻成什么 HopSpec 结构)→ **反例**(翻错长什么样)。这三条是翻译正确性底线,违反 = 翻译错误,不是风格问题。概念层权威锚点在每节标注。
4
+
5
+ ---
6
+
7
+ ## 焦点① 循环遍历不漏 → for-each 容器
8
+
9
+ **概念层**:`^anc-step-parallel`(`HopSpec V3核心规范.md`)。引擎按列表长度**运行时动态复制 N 份 child**、**全部完成才 join**、同名输出自动收集为列表——遍历完整性由引擎屏障保证,不靠 LLM 记着"还有几个没处理"。
10
+
11
+ **识别信号**(prose 里):
12
+ - "对每一个 X…"、"逐个处理"、"遍历所有…"、"针对列表中每项…"、"批量地对每个…"
13
+ - 隐式循环:prose 说"处理这些文件/模块/记录"且数量运行时才定。
14
+
15
+ **生成模板**:
16
+ ```markdown
17
+ 5. [parallel] 逐项处理
18
+ - ← items # items 必须是 [T] 列表类型的已定义变量
19
+ + → item : for-each items # 单行:元素绑定名 item + 遍历列表 items
20
+ + → results: [text] # child 同名输出自动收集为列表
21
+
22
+ 5.1. [subtask retry=2] 处理单项
23
+ - ← item
24
+ + → results: text # 与上面 [text] 同名,聚合
25
+ > 对单个 item 做处理…
26
+ ```
27
+ 关键:**parallel 下只写一个 child 模板**(引擎复制展开);`item` 在 child 及后代可作输入引用;列表变量先由前序步骤产出 `[T]` 类型。
28
+
29
+ **反例(翻错)**:
30
+ - ❌ 翻成 `[act] 循环处理所有项` 并在 hop_python body 里写 `for item in items:` —— act body **禁止循环**,且把遍历塞进一步 = LLM 执行期可能漏项,正是要消除的失效。
31
+ - ❌ 翻成 `[reason] 逐个分析每项` —— 遍历完整性又交回 LLM 记忆,无引擎屏障。
32
+ - ❌ for-each 下写多个不同 child 模板 —— 只允许一个(引擎复制)。多种不同处理用普通 parallel 或 branch。
33
+
34
+ ---
35
+
36
+ ## 焦点② 审核不跳过(**两层**)→ confirm + check
37
+
38
+ 审核有两种,prose 里常混在一起说"审核/把关/确认",翻译时**必须分辨**:
39
+
40
+ ### 2a. 人来把关 → confirm
41
+
42
+ **概念层**:`^anc-step-confirm` + `^anc-exec-hitl-presentation`。confirm = paused 介入点,driver **必须**问外部决策者、**不得替答**;`require_human: true` 时必须真人;**reject 全局中止**(后续步骤全 skipped、终态 failed)——所以放在 commit 前的 confirm 是"拒绝即停、不可逆操作绝不发生"的硬闸门。
43
+
44
+ **识别信号**:"让用户确认"、"人工审批"、"等待批准"、"需要授权"、"经同意后再…"。
45
+
46
+ **生成模板**:
47
+ ```markdown
48
+ 6. [confirm require_human] 请批准执行修复
49
+ - ← fix_plan # 给决策者看的依据
50
+ + → approved: bool # approve→true;reject→全局中止
51
+ > 展示 fix_plan,请决策者批准是否执行。
52
+ ```
53
+ `require_human` 修饰:涉及不可逆/高风险 → 加(强制真人);一般确认 → 可省(允许上层 agent 代答,但默认倾向问人)。
54
+
55
+ ### 2b. 产出核验 → check / check finally
56
+
57
+ **概念层**:`^anc-step-check`。check 验证产出是否达标,固定输出 `bool + text`;失败触发容器 retry。**`check finally`** 位于 subtask/case 末尾、**不可被 adaptive 改写或跳过**——是 Constraints 的可执行化身,最强的"验收不能跳"保证。
58
+
59
+ **识别信号**:"验证…是否达标"、"检查…对不对"、"确保满足约束"、"质量达标才…"、prose 的 Constraints 里每条硬约束。
60
+
61
+ **生成模板**(关键验收):
62
+ ```markdown
63
+ 3. [subtask retry=2] 执行并验证
64
+ + → summary: text
65
+ 3.1. [act] 执行操作
66
+ - ← input
67
+ + → output: yaml
68
+ > …
69
+ 3.2. [check finally] 验证 output 满足约束 # 必在 subtask 末尾
70
+ - ← output, threshold
71
+ + → ok: bool # 判定槽
72
+ + → note: text # 说明槽(未达标时的缺口)
73
+ > 检查 output 是否达标,输出 true/false。
74
+ ```
75
+ Constraints 里每条可执行的硬约束,都应对应一个 check(关键的用 check finally)。
76
+
77
+ **反例(翻错)**:
78
+ - ❌ 人工审批翻成 `[reason] 判断是否该批准` —— reason 是 LLM 自己推理,**架空了外部决策者**,违反 CITL 语义。审批必须 confirm。
79
+ - ❌ 产出核验翻成 `[act] 检查质量` 且不放容器 —— 孤立 check 违反 c6;且 act 无 retry 兜底,达标失败无法重试。
80
+ - ❌ 关键验收用普通 check(非 finally)放 subtask 中间 —— 可能被 adaptive 跳过。硬约束验收用 **check finally** 钉在末尾。
81
+ - ❌ prose 里明明说"确保 X"却在 spec 里没有任何 check —— 约束丢失,翻译不忠实。
82
+
83
+ ---
84
+
85
+ ## 焦点③ 试错不 commit → act(可逆)vs commit(不可逆)
86
+
87
+ **概念层**:`^anc-step-act` vs `^anc-step-commit`。act **必无不可逆副作用、可安全重做**;commit 有不可逆副作用、**不可重试、需幂等**,且**能执行到 commit 说明授权/放行已在前序完成**——概念层原文:「前置 confirm 步骤 **或** 环境预授权」。即 commit 要的是**前序有把关闸门**,不是硬绑 confirm。把关闸门三选一:**confirm**(人来批)/**足够的 check**(验证放行条件已满足,如"质量达标才落库")/**环境预授权**(能跑到即已授权,无需额外步)。试错/探索阶段的所有操作都应是 act(可反复重跑不留后果),不可逆动作隔离到 commit。
88
+
89
+ **识别信号**(不可逆 → commit):
90
+ - "发送邮件/消息"、"支付/扣款"、"写入生产数据库"、"删除文件"、"提交 git"、"调用写语义的外部 API"、"发布"。
91
+ - 判据:**这个操作做完能不能安全地再做一遍 / 撤销?** 不能 → commit。
92
+
93
+ **生成模板 A(人审把关:confirm + commit)**——需人拍板放行时:
94
+ ```markdown
95
+ 7. [confirm require_human] 批准发送
96
+ - ← draft
97
+ + → approved: bool
98
+ > 展示 draft,请批准是否发送。
99
+
100
+ 8. [commit] 发送邮件
101
+ - ← draft, approved
102
+ + → sent: line
103
+ > 不可逆操作(发送后不可撤回,前序 confirm 已放行):调用邮件工具发送 draft。
104
+ > 幂等设计:按 message_id 去重,避免重复发送。
105
+ ```
106
+
107
+ **生成模板 B(验证把关:check + commit)**——放行条件可自动验证时(无需人):
108
+ ```markdown
109
+ 5. [subtask retry=2] 校验后落库
110
+ 5.1. [check finally] 校验记录满足入库约束
111
+ - ← record
112
+ + → valid: bool
113
+ + → valid_note: text
114
+ > 检查 record 满足入库约束(必填齐全、无冲突键),输出 true/false。
115
+ 5b. [commit] 写入生产库
116
+ - ← record, valid
117
+ > 不可逆操作(前序 check 已验证放行条件):valid 为 true 时按业务键 upsert record(幂等)。
118
+ ```
119
+ > 环境预授权场景则无需前序步——能执行到 commit 即已授权(如 CLI 已登录态下的 git commit)。
120
+
121
+ 试错/中间产物用 act:
122
+ ```markdown
123
+ 4. [act] 生成候选草稿 # 可反复重跑,不留外部后果
124
+ - ← input
125
+ + → draft: text
126
+ > 生成草稿,纯产出无副作用。
127
+ ```
128
+
129
+ **反例(翻错)**:
130
+ - ❌ 把"发送/写库/删除"翻成 `[act]` —— act 契约是"可安全重做",不可逆操作放 act = 崩溃重跑会重复扣款/重复发送。
131
+ - ❌ commit 前**无任何前序把关**(既无 confirm、也无验证 check、也非环境预授权)—— 不可逆操作无把关直接执行,违反"试错不 commit"精神。(有 confirm **或** 足够 check **或** 环境预授权,任一即可,不必都要 confirm。)
132
+ - ❌ commit 放进 `subtask retry` 内 —— commit 不可重试,retry 会重复副作用。
133
+ - ❌ 试错/探索步骤用 commit —— 试错就该可反复重来,用 act;commit 只留给"最终真的要落地"的那一下。
134
+
135
+ ---
136
+
137
+ ## 三焦点串起来的典型形态
138
+
139
+ 一个"遍历 + 审核 + 落地"流程翻完通常长这样:
140
+ ```
141
+ parallel for-each(① 遍历所有项,引擎保证不漏)
142
+ └ subtask
143
+ ├ act(试错/生成,可逆)
144
+ └ check finally(② 产出核验,不可跳)
145
+ confirm require_human(② 人工把关)
146
+ commit(③ 不可逆落地,前序有把关闸门:confirm / 足够 check / 环境预授权)
147
+ ```
148
+ 翻译完对照原 prose 自查:**每个遍历都成了 for-each?每个审核都落在 confirm 或 check?每个不可逆操作都成了 commit 且前序有把关闸门(confirm / 足够 check / 环境预授权,任一即可)?** 三问都 yes 才算忠实。