@namewta/speculo 0.7.1 → 0.7.3

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 (57) hide show
  1. package/README.md +2 -1
  2. package/dist/src/migrations.js +604 -23
  3. package/dist/src/migrations.js.map +1 -1
  4. package/package.json +1 -1
  5. package/template/canonical/canonical-specdev-engineering-cognitive-mentor.md +171 -277
  6. package/template/canonical/canonical-specdev-goal-plan.md +714 -833
  7. package/template/canonical/canonical-specdev-grill-with-docs.md +172 -278
  8. package/template/canonical/canonical-specdev-spec.md +199 -315
  9. package/template/canonical/canonical-specdev-tickets.md +405 -398
  10. package/template/canonical/canonical-specdev-wayfinder.md +170 -276
  11. package/template/skills/migrate-runtime-state/SKILL.md +6 -6
  12. package/template/skills/migrate-runtime-state/references/migration-contract.md +9 -3
  13. package/template/skills/migrate-runtime-state/scripts/migrate-runtime-state.mjs +322 -33
  14. package/template/skills/optimize-codex-config/SKILL.md +81 -0
  15. package/template/skills/optimize-codex-config/references/configuration-contract.md +103 -0
  16. package/template/skills/optimize-codex-config/references/troubleshooting.md +79 -0
  17. package/template/skills/optimize-codex-config/scripts/audit-codex-config.mjs +747 -0
  18. package/template/workflows/specdev/I-implement/I-implement.md +97 -142
  19. package/template/workflows/specdev/I-implement/evidence-template.md +60 -48
  20. package/template/workflows/specdev/I-implement/execution-preflight.md +29 -19
  21. package/template/workflows/specdev/I-implement/merge-conflict-protocol.md +12 -11
  22. package/template/workflows/specdev/I-init-setup/I-init-setup.md +4 -5
  23. package/template/workflows/specdev/I-init-setup/change-status-template.json +14 -1
  24. package/template/workflows/specdev/I-init-setup/config-template.json +3 -5
  25. package/template/workflows/specdev/I-init-setup/status-template.json +1 -1
  26. package/template/workflows/specdev/INDEX.md +12 -8
  27. package/template/workflows/specdev/P-goal-plan/P-goal-plan.md +76 -93
  28. package/template/workflows/specdev/P-goal-plan/completion-control.md +26 -44
  29. package/template/workflows/specdev/P-goal-plan/goal-plan-template.md +43 -31
  30. package/template/workflows/specdev/P-goal-plan/lead-orchestration.md +34 -0
  31. package/template/workflows/specdev/P-goal-plan/orchestration-protocol.md +31 -42
  32. package/template/workflows/specdev/P-goal-plan/planning-modes.md +42 -61
  33. package/template/workflows/specdev/T-tickets/T-tickets.md +6 -3
  34. package/template/workflows/specdev/T-tickets/ticket-readiness.md +5 -3
  35. package/template/workflows/specdev/T-tickets/ticket-template.md +8 -1
  36. package/template/workflows/specdev/T-tickets/tickets-map-template.md +5 -4
  37. package/template/workflows/specdev/_state/status.json +1 -1
  38. package/template/workflows/specdev/common/README.md +2 -2
  39. package/template/workflows/specdev/common/rules/change-completion.md +17 -19
  40. package/template/workflows/specdev/common/rules/deviation-control.md +1 -1
  41. package/template/workflows/specdev/common/rules/evidence-and-verification.md +27 -37
  42. package/template/workflows/specdev/common/rules/path-ownership.md +21 -23
  43. package/template/workflows/specdev/common/rules/readiness-and-depth.md +1 -1
  44. package/template/workflows/specdev/common/schemas/change-status.schema.json +136 -195
  45. package/template/workflows/specdev/common/schemas/config.schema.json +9 -11
  46. package/template/workflows/specdev/common/schemas/goal-plan.schema.json +24 -6
  47. package/template/workflows/specdev/common/schemas/status.schema.json +7 -63
  48. package/template/workflows/specdev/common/skills/dev-worktree/SKILL.md +42 -21
  49. package/template/workflows/specdev/common/skills/dev-worktree/references/create.md +48 -18
  50. package/template/workflows/specdev/common/skills/dev-worktree/references/finalize.md +47 -12
  51. package/template/workflows/specdev/common/skills/subagent-delivery/SKILL.md +34 -30
  52. package/template/workflows/specdev/common/skills/subagent-delivery/references/external-web-subagent.md +10 -23
  53. package/template/workflows/specdev/common/skills/subagent-delivery/references/native-subagent.md +14 -25
  54. package/template/workflows/specdev/common/tools/validate-specdev.mjs +507 -117
  55. package/template/workflows/specdev/I-implement/delegated-evidence-template.md +0 -11
  56. package/template/workflows/specdev/P-goal-plan/delegated-execution-template.md +0 -33
  57. package/template/workflows/specdev/P-goal-plan/delegated-execution.md +0 -53
@@ -98,7 +98,7 @@ Ticket 是**决策完备的微型执行计划**:它消除执行者在目标、
98
98
 
99
99
  - `lite`:局部、可逆、沿用既有模式、无公共契约或迁移影响;
100
100
  - `standard`:大多数多文件或跨层垂直切片;
101
- - `deep`:公共 API/schema、数据迁移、安全/隐私/资金、不可逆操作、expand-contract、共享核心路径、多 Agent 或高事故半径。
101
+ - `deep`:公共 API/schema、数据迁移、安全/隐私/资金、不可逆操作、expand-contract、共享核心路径、多个 implementation owner 的跨 Ticket 写入协调或高事故半径。
102
102
 
103
103
  规划深度不是优先级,也不是 Gate。每个 Ticket 必须记录触发该深度的原因。
104
104
 
@@ -115,7 +115,8 @@ Ticket 是**决策完备的微型执行计划**:它消除执行者在目标、
115
115
  - 有序执行路线和安全落点;
116
116
  - expected、writable、read-only、shared 路径;
117
117
  - 正常、失败和回归验证矩阵;
118
- - 用户界面交互受影响时的 E2E Gate 与执行 owner;后续委派 Goal Plan 可以显式把该 Gate 转交 Lead
118
+ - 每个 Ticket source-worktree E2E 检查、父分支 candidate 集成出口,以及按实际跨边界风险判定的 E2E disposition
119
+ - 每个实现 Ticket 的独立 worktree、implementation commit 与父分支合并完成条件;
119
120
  - Deep 的迁移、兼容窗口、监控、回滚和不可逆批准点;
120
121
  - 可判定验收标准。
121
122
 
@@ -143,6 +144,8 @@ Ticket 是**决策完备的微型执行计划**:它消除执行者在目标、
143
144
  - 依赖缺失或 DAG 有环;
144
145
  - 可写路径不明确或并行所有权冲突;
145
146
  - 验证方法不能执行且没有批准的替代证据;
147
+ - Ticket 未声明 E2E required/not-required 及理由,或把 E2E 安排到 source worktree;
148
+ - 无法形成实现 commit 与 candidate-merge 父分支出口;
146
149
  - 单个新上下文无法完成;
147
150
  - Standard/Deep 缺少有序执行路线;
148
151
  - Deep 缺少迁移、兼容、监控、回滚或批准点。
@@ -223,7 +226,7 @@ node Speculo Node 校验器 \
223
226
 
224
227
  ## 下一步
225
228
 
226
- 满足任一情况时建议运行 “目标规划阶段”:Ticket 数量达到或超过 10、存在多 Agent 并行、Deep Ticket、迁移、共享契约、多个 Gate 或高风险发布。少量线性 Ready Ticket 可直接进入 “实现阶段”。
229
+ 满足任一情况时建议运行 “目标规划阶段”:Ticket 数量达到或超过 10、存在多个 implementation owner 的并行写入协调、Deep Ticket、迁移、共享契约、多个 Gate 或高风险发布。只读 review/research 并行本身不触发 Goal Plan;少量线性 Ready Ticket 可直接进入 “实现阶段”。
227
230
 
228
231
  ---
229
232
 
@@ -307,10 +310,12 @@ node Speculo Node 校验器 \
307
310
  - [ ] 高影响未决问题为零。
308
311
  - [ ] `blocked_by` 指向存在的 Ticket,DAG 无环。
309
312
  - [ ] `expected_changes`、`writable_paths`、`read_only_paths` 和 `shared_paths` 中的项目路径都使用项目根相对路径。
310
- - [ ] `writable_paths` 非空,或明确为仅文档、调查或无代码变更。
313
+ - [ ] `writable_paths` 非空;纯 review/research 不伪装成 I-implement Ticket。
311
314
  - [ ] 每个 shared path 在 `shared_path_owners` 中有唯一 owner。
312
315
  - [ ] 正常、失败和回归至少各有一条验证,或有可信的不适用原因。
313
- - [ ] 仅当用户界面交互受影响时定义 E2E 与当前执行 owner;Ticket 不预设 Lead/Worker,委派 Goal Plan 可以显式改由 Lead 集成。
316
+ - [ ] 明确 `E2E disposition: required | not-required: reason`;required 场景、预期和接缝可执行。
317
+ - [ ] Source-worktree 验证只包含单元、组件、静态、类型、lint/build 等非 E2E 检查;E2E owner 固定为 Lead,运行环境固定为 parent-candidate。
318
+ - [ ] Ticket 完成合同包含独立 worktree、implementation commit、candidate-merge、父分支 result SHA 和 Lead Evidence。
314
319
  - [ ] Evidence 位置明确为 `specdev/changes/{change}/evidence/T-NN.md`。
315
320
  - [ ] 单个全新上下文能够完成;否则已拆分。
316
321
  - [ ] 所有内部文件与目录引用使用本文约定的逻辑路径。
@@ -326,7 +331,7 @@ node Speculo Node 校验器 \
326
331
 
327
332
  - [ ] 迁移顺序、兼容窗口、监控、回滚或前向恢复、收缩条件和批准点完整。
328
333
  - [ ] 安全、隐私、资金或数据完整性风险有缓解与验证。
329
- - [ ] 跨 Agent 路径所有权和集成 Gate 明确。
334
+ - [ ] 跨 implementation owner 的路径所有权和 parent-candidate 集成 Gate 明确。
330
335
  - [ ] expand-contract 的收缩条件可通过扫描、指标、查询或测试证明。
331
336
 
332
337
  ## Ready 状态
@@ -452,7 +457,12 @@ shared_path_owners: []
452
457
 
453
458
  不适用的关键风险类别必须写“不适用:原因”。
454
459
 
455
- 仅当用户界面交互受影响时增加 E2E 行并指定当前执行 owner。若后续 Goal Plan 含委派附录,再由该计划显式转交 Lead;Ticket 不预设 Lead/Worker 角色。
460
+ - **Source-worktree checks:** 单元、组件、静态、类型、lint/build 等适用非 E2E 检查。
461
+ - **E2E disposition:** required / not-required:原因。
462
+ - **E2E owner/environment:** Lead / parent-candidate;required 时写明场景、接缝与预期。
463
+ - **Integration evidence:** source commit、parent before、candidate/result SHA 和父分支包含关系。
464
+
465
+ E2E 由实际跨边界行为与风险决定,不限于 UI;不得在 Ticket source worktree 运行或声明通过。
456
466
 
457
467
  ## 9. 发布、迁移与恢复
458
468
 
@@ -470,6 +480,8 @@ shared_path_owners: []
470
480
  - [ ] `AC-001`:<可判定结果>。
471
481
  - [ ] 验证矩阵全部执行并记录到 `specdev/changes/{change}/evidence/T-01.md`。
472
482
  - [ ] 实际项目修改未超出 `writable_paths`,shared path 由指定 owner 修改。
483
+ - [ ] Ticket 来源 worktree 已形成非空实现 commit,candidate 验证通过且父分支 result 包含 source commit。
484
+ - [ ] E2E disposition 已执行;required E2E 在 parent-candidate 由 Lead 完成。
473
485
  - [ ] 未发生未批准的范围、契约或发布偏差。
474
486
  - [ ] Ticket、Tickets Map 和 Evidence 状态一致。
475
487
 
@@ -529,10 +541,11 @@ T-01 [READY]
529
541
 
530
542
  ## 5. 并行与路径所有权
531
543
 
532
- - 最大并发来自 `specdev/config.json`。
533
- - shared owner 为专用 Ticket 或明确的集成 owner;只有委派 Goal Plan 才使用 Lead 角色。
544
+ - implementation subagent 上限来自 `specdev/config.json`,不得超过三个且不含 Lead。
545
+ - review/research/test-observation agent 不设 SpecDev 数字上限,但保持只读。
546
+ - shared owner 为专用 Ticket;Lead 是 SpecDev 状态与父分支 integration owner。
534
547
  - 项目路径契约以 Ticket frontmatter 为准。
535
- - 并行写代码的 Ticket 使用独立 worktree;只读调查不需要。
548
+ - 每个实现 Ticket 使用独立 worktree,不以是否派遣 Agent 或是否并行为条件;只读调查不进入 I-implement Ticket。
536
549
 
537
550
  | Ticket A | Ticket B | Writable 交集 | 真实依赖 | 处理 |
538
551
  |---|---|---|---|---|
@@ -540,7 +553,7 @@ T-01 [READY]
540
553
 
541
554
  ## 6. Gate、Wave 与集成点
542
555
 
543
- T-tickets 可以标注候选 Wave 和行为里程碑。需要正式跨 Ticket 编排时,由 “目标规划阶段” 完成 Gate、Wave、owner、发布与恢复,并把结果投影回本 Map。
556
+ T-tickets 可以标注候选 Wave、E2E disposition 和行为里程碑。需要正式跨 Ticket 编排时,由 “目标规划阶段” 完成 Gate、Wave、Lead、动态派单边界、candidate 集成顺序、发布与恢复,并把结果投影回本 Map。
544
557
 
545
558
  ## 7. 横切契约与风险
546
559
 
@@ -716,7 +729,7 @@ Change CONTEXT/ADR 是 active change 内的执行权威,不是 workflow 级永
716
729
 
717
730
  ### Deep
718
731
 
719
- 任一条件触发:公共 API、schema、wire format、数据迁移、认证授权、隐私、资金、不可逆操作、expand-contract、共享核心路径、多 Agent 复杂协作、多个实质架构方案或高事故半径。
732
+ 任一条件触发:公共 API、schema、wire format、数据迁移、认证授权、隐私、资金、不可逆操作、expand-contract、共享核心路径、多个 implementation owner 的跨 Ticket 写入协调、多个实质架构方案或高事故半径。
720
733
 
721
734
  额外要求:数据流或状态转换、兼容窗口、迁移顺序、可观测性、回滚、风险缓解、收缩条件和人工批准点。
722
735
 
@@ -756,39 +769,37 @@ Ticket 只有同时满足以下适用条件才可设置 `ready: true`:
756
769
 
757
770
  # 路径所有权与并发规则
758
771
 
759
- 路径所有权是并行执行的硬边界,不是文件预测清单。
772
+ 路径所有权是逻辑写入边界;worktree 是物理隔离边界,两者不能互相替代。
760
773
 
761
774
  ## 1. 四类路径
762
775
 
763
- - `expected_changes`:预计修改的项目路径,仅用于导航;每项写成项目根相对路径。
764
- - `writable_paths`:实现者获准修改的项目路径或 glob,是硬约束。
765
- - `read_only_paths`:建立上下文但不得修改的项目路径。
766
- - `shared_paths`:多个 Ticket 可能需要修改的项目路径,必须指定唯一 owner
776
+ - `expected_changes`:导航预测;
777
+ - `writable_paths`:当前 Ticket implementation owner 可写的硬边界;
778
+ - `read_only_paths`:只读上下文;
779
+ - `shared_paths`:多个 Ticket 可能触达且必须有唯一 owner 的项目路径。
767
780
 
768
- 示例:
769
-
770
- ```yaml
771
- expected_changes: ["src/auth/session.ts"]
772
- writable_paths: ["src/auth/**"]
773
- read_only_paths: ["src/users/**"]
774
- shared_paths: ["package.json"]
775
- ```
781
+ 所有项目路径使用项目根相对路径。根依赖清单、锁文件、根导出、共享 schema、迁移索引、全局路由和跨 Ticket 合同默认视为 shared。
776
782
 
777
783
  ## 2. 所有权规则
778
784
 
779
- 1. 可能并行的 Ticket,其 `writable_paths` 不得相交。
780
- 2. glob 与具体路径按覆盖关系判断,不得只比较字符串。
781
- 3. 根依赖清单、锁文件、根导出、共享 schema、迁移索引、全局路由和跨 Ticket 合同文件默认视为 shared。
782
- 4. shared path 只能由专用 owner Ticket 或 Goal Plan 明确指定的唯一集成 owner 修改;消费者 Ticket 只读。委派 Goal Plan 可以把该 owner 指定为 Lead,但普通计划不预设角色。
783
- 5. 需要越界时先停止,按 下方 `<deviation-control>` 标签 提出 ownership change;不得先改后报。
784
- 6. 前置 Ticket 改变目录结构后,后续 Ticket 开始前重新解析项目路径;若授权范围语义未改变,可只更新导航路径。
785
- 7. 不得把“最后解决合并冲突”当作所有权方案。
785
+ 1. 可能并行的 Ticket,其 writable paths 不得相交;glob 按覆盖关系判断。
786
+ 2. shared path 只由专用 owner Ticket 修改;消费者 Ticket 只读。Lead 负责集成,不以冲突解决替代 shared owner。
787
+ 3. implementation subagent 只写其 Packet 与 Ticket 授权路径;Lead 自行实现也受同一边界约束。
788
+ 4. review/research/test-observation agent 只读项目与 SpecDev 工件。
789
+ 5. 越界前停止并按 deviation control 提出 ownership change;不得先改后报。
790
+ 6. 上游 Ticket 改变目录/合同后,下游基于已集成父分支重新解析路径和 preflight。
791
+
792
+ ## 3. Ticket worktree
786
793
 
787
- ## 3. Worktree 与分支
794
+ 每个进入 I-implement Ticket 都使用唯一来源 worktree `specdev-worktree/<ticket-id>`,无论是否并行、是否派遣 subagent。Ticket 切片是隔离依据;Agent Team 不是 worktree 触发器。没有 Ticket 的获批 Direct Spec 可由 current workspace 唯一 owner 执行;只读调查不创建实现 worktree。
788
795
 
789
- 需要并行或临时隔离项目写入时使用独立 worktree;只读调查和顺序执行默认共用当前工作区。Worktree 防止工作区污染,路径所有权防止逻辑冲突,两者不能互相替代。
796
+ workspace/implementation owner 可以是 Lead 或动态 implementation subagent;integration owner 固定为 Lead。只有 Lead 写 SpecDev 状态、建立 parent-candidate、运行适用 E2E 并推进父分支。生命周期由 下方 `<dev-worktree>` 标签 管理。
790
797
 
791
- 生命周期由调用方明确的 workspace owner 按 下方 `<dev-worktree>` 标签 管理。普通 Goal Plan 由当前执行或集成 owner 负责;委派 Goal Plan 才把 workspace owner 映射为 Lead。编排规则位于 “目标规划阶段的核心编排规则”。
798
+ ## 4. 并发
799
+
800
+ implementation subagent 同时最多三个,Lead 不计入;实际上限取 Goal Plan、config 和平台能力最小值。review/research/test-observation agent 不设置 SpecDev 数字上限,但 Lead 必须避免重复工作与可变环境争用。
801
+
802
+ **完成标准**:每个项目写入映射到唯一 Ticket、owner 和来源 worktree;shared 与父分支写入 owner 唯一。
792
803
 
793
804
  </path-ownership>
794
805
 
@@ -796,61 +807,51 @@ shared_paths: ["package.json"]
796
807
 
797
808
  # 证据与验证规范
798
809
 
799
- 验证回答“怎样证明行为已经正确发生”,Evidence 回答“实际运行了什么、结果是什么、仍有什么风险”。
810
+ 验证回答“怎样证明”,Evidence 记录“实际运行了什么、在哪个状态运行、结果和残余风险是什么”。
800
811
 
801
812
  ## 1. 验证矩阵
802
813
 
803
- 每一行绑定一个行为、合同或风险:
814
+ 每行绑定行为、合同或风险,并标记环境:
804
815
 
805
- | 行为或风险 | 验证接缝 | 方法或命令 | 预期结果 | Evidence |
806
- |---|---|---|---|---|
807
- | 正常路径 | 公共接口 | 项目定向测试 | 指定外部行为成立 | `specdev/changes/{change}/evidence/T-NN.md` |
808
- | 无效输入 | schema 或公共接口 | 定向失败测试 | 稳定错误行为成立 | `specdev/changes/{change}/evidence/T-NN.md` |
809
- | 回归 | 现有测试套件 | 项目回归命令 | 相关既有行为保持 | `specdev/changes/{change}/evidence/T-NN.md` |
816
+ | 行为或风险 | 接缝 | 命令/方法 | 环境 | 预期 | Evidence |
817
+ |---|---|---|---|---|---|
818
+ | 正常/失败路径 | 公共接口或稳定接缝 | 定向测试 | source-worktree | 合同成立 | Ticket Evidence |
819
+ | 跨模块回归 | 集成接缝 | 回归命令 | parent-candidate | 组合状态成立 | Ticket Evidence |
820
+ | E2E required | 真实端到端边界 | 场景步骤 | parent-candidate | 外部行为成立 | Ticket Evidence |
821
+
822
+ ## 2. 两层验证
823
+
824
+ ### Source-worktree
810
825
 
811
- 命令引用项目脚本时,项目文件路径使用项目根相对路径,例如 `package.json` `Makefile`。
826
+ implementation owner 运行最接近目标行为的单元/组件测试、静态分析、类型、lint/build 等适用非 E2E 检查。来源实现必须在 clean worktree 形成 commit。任何 source-worktree E2E pass 声明无效。
812
827
 
813
- ## 2. 最小充分验证
828
+ ### Parent-candidate
814
829
 
815
- 选择最接近目标行为的稳定接缝:
830
+ Lead 在最新父分支与 source commit 的 candidate 状态运行受影响集成/回归、项目父状态检查和适用 E2E。E2E 由实际跨边界风险决定,不限于 UI;not-required 必须写理由。required E2E 未运行或失败时不得推进父分支。
816
831
 
817
- 1. 公共接口或契约集成测试;
818
- 2. 稳定接缝上的单元测试;
819
- 3. 类型检查、静态分析、lint 和构建;
820
- 4. 可重复手动步骤、截图或查询结果;
821
- 5. 代码阅读推断。
832
+ ### Direct Spec
822
833
 
823
- E2E 仅在变更影响用户界面交互时加入验证矩阵。普通执行由当前实现或集成 owner 运行;委派执行中 Worker 只记录场景、预期结果和待执行状态,由 Lead 在集成阶段运行。APICLI、后端、库或数据变更默认使用其稳定接缝,不追加 E2E
834
+ 获批 Direct Spec 不创建 Ticket worktree 或 candidate。Lead 在 current workspace 记录实施前基线,运行轻量合同要求的定向检查、适用回归与 E2E,并记录最终 checkpointdirty 状态、运行环境、命令、退出状态和未运行原因。E2E 仍只由 Lead 执行;不得为套用两层验证而伪造 Ticket、source/candidate/result 或父分支推进证据。
824
835
 
825
- 低层证据不能替代明确要求的用户行为证据。高风险迁移还需要 dry-run、调用点扫描、数据核对、监控信号或回滚演练。
836
+ 低层证据不能替代明确要求的外部行为证据。高风险迁移还需要 dry-run、调用点扫描、数据核对、监控或恢复演练。
826
837
 
827
- ## 3. 失败分类
838
+ ## 3. Agent 声明
828
839
 
829
- 每个失败必须分类为:
840
+ subagent 只返回候选命令与结果,不写 Evidence。Lead 重读 workspace/Git、必要时复跑或核对输出后落盘;外部 provider 自报、截图、模拟和推断在此之前标记 `unverified`。review/research/test-observation agent 不拥有 E2E Gate。
830
841
 
831
- - Ticket 引入的新失败;
832
- - 基线已存在的失败;
833
- - 环境、权限或基础设施失败;
834
- - 验证本身无效或无法观察目标行为。
842
+ ## 4. 失败分类与完整性
835
843
 
836
- 不得通过跳过测试、放宽断言、吞错、删除用例或把命令移出验证矩阵来制造绿色。
844
+ 失败分类为本 Ticket 新失败、基线既有失败、环境/权限/基础设施失败、无效验证或 candidate stale。不得通过跳过、放宽断言、吞错、删除用例或迁移验证位置制造绿色。
837
845
 
838
- ## 4. Evidence 最低内容
846
+ 受控反向验证只用于可能静默通过的关键门禁:证明检查能在目标风险出现时失败,再恢复并重跑。普通测试不为形式执行破坏性操作。
839
847
 
840
- 每个完成 Ticket `specdev/changes/{change}/evidence/T-NN.md` 记录:
848
+ ## 5. Evidence 最低内容
841
849
 
842
- - 基线、分支或 worktree
843
- - 实际修改的项目路径;
844
- - 每条命令、退出状态和结果摘要;
845
- - 每条验收合同的证据映射;
846
- - 未运行项与原因;
847
- - 新失败、既有失败和环境失败;
848
- - 偏差及批准;
849
- - 残余风险;
850
- - worktree、提交或 PR 引用;
851
- - 最终结论。
850
+ 每个 Ticket Evidence 至少包含:Lead、Dispatch/返回(若有)、base/source/candidate/result SHA、来源 worktree、实际路径、每条命令/环境/退出状态、合同映射、双轴审查、E2E disposition、未运行项、失败分类、偏差、残余风险和父分支重读结果。
852
851
 
853
- 无法运行关键验证、存在未批准偏差或 Evidence 不完整时,Ticket 不得标为 `done`。
852
+ Ticket Done 必须有 source commit、通过 candidate、父分支 result 与 Lead Evidence。无法运行 required 验证、存在未批准偏差、父分支未包含 source commit 或 Evidence 不完整时不得 Done。
853
+
854
+ Direct Spec Evidence 至少包含:用户批准与轻量合同、Lead、实施前/最终 checkpoint、实际路径、定向/回归/E2E 命令及环境、验收映射、未运行项、偏差、残余风险和提交授权状态。
854
855
 
855
856
  </evidence-and-verification>
856
857
 
@@ -898,7 +899,7 @@ E2E 仅在变更影响用户界面交互时加入验证矩阵。普通执行由
898
899
 
899
900
  - 未批准的 ticket、spec、architecture 或 release 偏差不得继续实现。
900
901
  - 不得通过扩大 `writable_paths`、删除测试、降低断言或把风险改写成“已知限制”来绕过停止。
901
- - 偏差影响普通并行执行时,当前集成 owner 必须暂停受影响 Wave,重新计算路径所有权、依赖和 Gate;委派执行由 Lead 承担同一责任。
902
+ - 偏差影响并行执行、source checkpoint 或 candidate 集成时,Lead 必须暂停受影响 Wave,重新计算路径所有权、依赖、Gate 与父分支顺序;任何 subagent 都不能自行改写上层合同。
902
903
 
903
904
  </deviation-control>
904
905
 
@@ -959,112 +960,222 @@ E2E 仅在变更影响用户界面交互时加入验证矩阵。普通执行由
959
960
 
960
961
  <dev-worktree>
961
962
 
962
- # SpecDev Dev Worktree
963
+ # Dev Worktree
964
+
965
+ 本 Skill 由 T-tickets/P-goal-plan/I-implement 和 P-prototype 复用。`purpose=ticket` 使用完整 source → candidate → parent 状态机;`purpose=prototype` 只使用调用方批准的临时生命周期。
966
+
967
+ ## 输入
968
+
969
+ - `operation=create | restore | finalize | remove`;
970
+ - `purpose=ticket | prototype`;
971
+ - repository、父分支、`base_sha`、branch、portable workspace locator;
972
+ - workspace、implementation 和 integration owner;
973
+ - 允许动作、路径合同、验证合同、调用方状态记录位置。
974
+
975
+ Ticket 还必须提供 Ready Ticket、Goal Plan(若存在)、Evidence 路径、implementation commit 与本地 candidate integration/父分支更新授权。缺失时返回 blocked,不使用 current workspace 代替。
976
+
977
+ ## 1. 创建或恢复
978
+
979
+ `operation=create` 时加载 下方 `<dev-worktree-create>` 标签。Ticket 使用 `specdev-worktree/<ticket-id>`;同一 Ticket 只存在一个来源 worktree。`operation=restore` 时重读实际 Git worktree/branch/tip/dirty 状态并与调用方记录核对,漂移时停止。
980
+
981
+ **完成标准**:来源基线、branch、locator、owners 和实际 Git 状态一致;现有用户改动未被覆盖。
963
982
 
964
- ## 适用范围
983
+ ## 2. 来源实现门
965
984
 
966
- - 用于并行写代码且路径所有权不冲突的 Ready Ticket,或明确要求临时隔离的一次性原型。
967
- - 只读调查和顺序执行默认共用当前工作区。
968
- - 调用方必须明确 workspace owner、implementation owner、固定基线、工作项 ID、持久化 owner 和允许的结束动作。
969
- - 普通执行不建立额外角色;委派 Goal Plan 才把 workspace owner/implementation owner 分别映射为 Lead/Worker。
970
- - 平台原生 worktree 优先;不可用时使用 Git worktree。
985
+ implementation owner 只在来源 worktree 修改授权项目路径,运行 Ticket 要求的单元、组件、静态、类型、lint/build 等非 E2E 检查。进入 `review` 前,worktree 必须 clean,branch tip 必须是已授权的 `source_checkpoint` commit,实际 diff 必须符合路径合同。
971
986
 
972
- ## 生命周期
987
+ **完成标准**:source checkpoint 不可变且可达;来源 worktree 没有 E2E pass 声明。
973
988
 
974
- 1. 创建或恢复时加载 下方 `<dev-worktree-create>` 标签。
975
- 2. implementation owner 完成后返回工作项状态、Evidence/record 路径、`workspace_ref`、checkpoint、commit 或 PR 引用和未验证项;Ticket worktree 从 `active` 更新为 `review`。
976
- 3. workspace owner 集成或清理时加载 下方 `<dev-worktree-finalize>` 标签;一次性原型只评估和清理,不合入生产分支。
989
+ ## 3. 候选合并与父分支推进
977
990
 
978
- Ticket worktree 状态依次为 `planned active review integrated removed`;失败进入 `blocked`,记录写入 `specdev/changes/{change}/.status.json` `worktrees`。原型的 branch、`workspace_ref` 和清理结果只写入 `specdev/changes/{change}/prototypes/{prototype-id}/record.md`,不伪造 Ticket worktree 记录。
991
+ `operation=finalize` 仅由 Lead/integration owner 调用,并加载 下方 `<dev-worktree-finalize>` 标签。Lead 在独立 parent-candidate checkout 组合最新父分支与 source checkpoint,运行集成检查和适用 E2E,通过后才推进父分支。
979
992
 
980
- ## 边界
993
+ 本地 candidate checkout/branch 的创建、重建和回收属于已授权 local candidate integration;来源 branch/worktree 的删除仍需要独立 cleanup 授权。push、PR、remote merge、deploy、migration 和生产动作不从本 Skill 继承。
981
994
 
982
- - 每个并行 Ticket 使用独立 worktree、分支和相同 `base_sha`;每个原型使用独立 worktree 和分支。
983
- - Git provider 固定使用 `<project-root>/specdev-worktree/<work-item-id>/`,持久化 `workspace_ref: specdev-worktree/<work-item-id>`;`<project-root>` 由 `workspace.json#path_base: project-root` 解析。
984
- - native/external provider 保留其可迁移 opaque locator;所有 provider 都不保存机器绝对路径、认证秘密或真实用户数据。
985
- - 项目根 `.gitignore` 的 `specdev-worktree/` 条目由 `speculo init` 单一维护;缺失时创建流程阻塞并提示重新运行 init。
986
- - E2E 仅适用于用户界面交互受影响的变更。普通执行由当前集成 owner 运行;委派执行由 Lead 在集成阶段运行。
987
- - 合并、推送、PR、删除分支或 worktree 仍需用户授权。
995
+ **完成标准**:Ticket `integrated` 时父 HEAD 精确等于记录的 result SHA,并包含 source checkpoint;失败或 stale 时父分支未变化。后续 `removed` 只表示来源 branch/worktree 已清理,不撤销该集成事实。
996
+
997
+ ## 4. 移除
998
+
999
+ `operation=remove` 先验证 Ticket `integrated` prototype 已结束、目标 worktree clean、checkpoint 可恢复且删除目标精确。只有明确 cleanup 授权时删除来源 branch/worktree;强制删除需要单独确认。删除后重读 `git worktree list` 与 refs,并只把调用方生命周期状态更新为 `removed`;`base_sha`、source checkpoint、candidate/result、验证、E2E 与 Evidence 字段必须原样保留。
1000
+
1001
+ **完成标准**:只删除精确授权目标;失败保留现场与恢复命令。
1002
+
1003
+ ## 固定规则
1004
+
1005
+ - Agent Team 不决定 worktree;Ticket 切片本身决定来源 worktree;
1006
+ - Ticket E2E 只在 Lead-owned parent-candidate checkout 运行;
1007
+ - 每个 Done Ticket 必须有 source commit 与父分支 result,worktree 状态为 `integrated` 或其清理后终态 `removed`;
1008
+ - candidate 失败保留来源 worktree 修正,父分支不动;
1009
+ - 成功集成不自动清理来源 branch/worktree。
988
1010
 
989
1011
  </dev-worktree>
990
1012
 
991
1013
  <dev-worktree-create>
992
1014
 
993
- # 创建或恢复工作项 Worktree
1015
+ # Create Or Restore Worktree
994
1016
 
995
- ## 前置
1017
+ ## Ticket 前置条件
996
1018
 
997
- - Ticket `ready: true` 且依赖完成,或原型问题与临时写入范围已锁定;项目写路径无冲突。
998
- - 并行 Ticket 要求 `specdev/config.json` `git.worktree_for_parallel: true`;一次性原型要求 P-prototype 已取得本次临时 worktree 授权。
999
- - 调用方已指定 workspace owner、implementation owner、工作项 ID、持久化 owner,并固定 `base_sha`;并行 Ticket 共用同一基线。
1019
+ - Ticket Ready,项目根是有效 Git repository,父分支和 `base_sha` 可解析;
1020
+ - implementation commit local candidate integration/父分支更新已授权;
1021
+ - workspace、implementation、integration owner 唯一;integration owner 必须为 Lead;
1022
+ - `specdev-worktree/` 已由 Speculo init 加入项目 `.gitignore`;
1023
+ - 目标 branch/worktree 不覆盖现有用户 workspace,路径合同无冲突。
1000
1024
 
1001
- ## 创建
1025
+ Prototype 只要求调用方已记录本次临时 branch/worktree 授权、问题、owner、locator 和清理策略;它不写 Ticket worktree 状态。
1002
1026
 
1003
- 1. Speculo 工作区声明的 `path_base: project-root` 解析 `<project-root>`。若记录的 provider 为 `git`,要求 `workspace_ref` 精确为 `specdev-worktree/<work-item-id>`,拼接后仍位于 project root,且 `specdev-worktree/` 不是逃逸到外部的符号链接。
1004
- 2. 读取调用方拥有的持久化记录:Ticket 使用 `specdev/changes/{change}/.status.json` 的 `worktrees`;原型使用 `specdev/changes/{change}/prototypes/{prototype-id}/record.md`。若已有可恢复记录,Git provider 必须在 `git worktree list --porcelain` 中匹配固定路径、分支与 `base_sha`;native/external 由对应 provider 解析 opaque locator。一致则恢复,任一不一致停止。
1005
- 3. 否则优先调用平台原生 worktree 能力。使用 native/external 时保存 provider 返回的可迁移 locator;不可用时进入 Git fallback。
1006
- 4. Git fallback 前确认项目根 `.gitignore` 已包含 `specdev-worktree/` 或等价根模式。缺失时停止并提示重新运行当前版本 `speculo init`,不在本 Skill 内修改 `.gitignore`。
1007
- 5. Git fallback 固定 `physical_path = <project-root>/specdev-worktree/<work-item-id>`、`workspace_ref = specdev-worktree/<work-item-id>`,从 `base_sha` 执行 `git worktree add -b <work-item-branch> <physical-path> <base-sha>`。已存在但未与同一记录和 Git 注册匹配的目标路径一律阻塞。
1008
- 6. 分支使用 `speculo/<change>/<work-item-id>`;现有分支未能匹配记录时停止。
1009
- 7. 安装项目所需依赖,运行最小基线检查。E2E 不属于 implementation owner 的创建基线。
1010
- 8. Ticket 将记录写入 `worktrees`:
1027
+ ## 创建 Ticket 来源 worktree
1028
+
1029
+ 1. 重读父分支 HEAD、工作树、现有 worktrees refs;父 HEAD 与计划基线不一致时由 Lead决定更新 `base_sha` 或阻塞;
1030
+ 2. 固定 branch `speculo/<change>/<ticket-id>` locator `specdev-worktree/<ticket-id>`;
1031
+ 3. 确认目标 branch/path 不存在,或其实际记录精确匹配当前 Ticket;
1032
+ 4. `base_sha` 创建 Git worktree,不复用其他 Ticket/原型目录;
1033
+ 5. 在来源 worktree 读取项目 Agent 指令、依赖、构建与路径合同;
1034
+ 6. 安装实际需要的依赖,运行最小非 E2E 基线;
1035
+ 7. Lead 写入 `specdev/changes/{change}/.status.json`,状态为 `active`。
1036
+
1037
+ 初始记录:
1011
1038
 
1012
1039
  ```json
1013
1040
  {
1014
1041
  "ticket_id": "T-01",
1015
- "owner": "<implementation-owner>",
1042
+ "owner": "lead",
1043
+ "implementation_owner": "lead-or-dynamic-agent",
1044
+ "integration_owner": "lead",
1016
1045
  "provider": "git",
1017
- "base_sha": "<sha>",
1046
+ "base_sha": "<immutable-sha>",
1047
+ "parent_branch": "<parent-branch>",
1018
1048
  "branch": "speculo/<change>/T-01",
1019
1049
  "workspace_ref": "specdev-worktree/T-01",
1050
+ "source_checkpoint": null,
1051
+ "integration": {
1052
+ "status": "pending",
1053
+ "parent_before_sha": null,
1054
+ "source_sha": null,
1055
+ "candidate_sha": null,
1056
+ "candidate_branch": null,
1057
+ "candidate_workspace_ref": null,
1058
+ "result_sha": null,
1059
+ "method": null,
1060
+ "conflict_paths": [],
1061
+ "verification": "pending",
1062
+ "e2e": {"required": false, "status": "not-required", "evidence": null},
1063
+ "evidence": "specdev/changes/<change>/evidence/T-01.md",
1064
+ "attempts": 0
1065
+ },
1020
1066
  "status": "active",
1021
1067
  "updated_at": "<ISO-8601>"
1022
1068
  }
1023
1069
  ```
1024
1070
 
1025
- native/external provider 将示例中的 provider 与 `workspace_ref` 换为对应可迁移 locator,不套用 Git 物理路径。原型不使用本 JSON 结构,只在 record Run and Assets 中记录源码 branch/commit,并在 frontmatter 写入 `workspace_ref` 与清理状态。
1071
+ `e2e.required` Ticket/Goal Plan disposition 一致;required 时初始 status `pending`。
1072
+
1073
+ ## 恢复
1074
+
1075
+ 恢复时核对 repository、branch、locator、`base_sha`、实际 HEAD、dirty 状态和 owner。状态记录与 Git 不一致、branch 被其他 worktree 占用或出现越界修改时停止;Lead 写 blocker,不重建覆盖。
1026
1076
 
1027
- 完成条件:工作区可定位、基线可用、调用方记录与实际 provider、分支和 checkpoint 一致;Git provider 的引用与工作项 ID 完全一致。失败时在调用方拥有的记录中设为 `blocked` 并保留现场。
1077
+ 进入 `review` 前必须由 implementation owner 创建最终 commit;Lead 重读 branch tip、diff 与 `git status`,把精确 SHA 写入 `source_checkpoint`。
1078
+
1079
+ **完成标准**:来源 worktree 可定位且唯一;基线、记录与 Git 一致;source 检查不含 E2E;失败时保留现场。
1028
1080
 
1029
1081
  </dev-worktree-create>
1030
1082
 
1031
1083
  <dev-worktree-finalize>
1032
1084
 
1033
- # 集成与清理工作项 Worktree
1085
+ # Candidate Merge And Parent Integration
1086
+
1087
+ 仅由 Lead/integration owner 对状态为 `review` 的 Ticket 调用。
1088
+
1089
+ ## 1. 接收 source checkpoint
1090
+
1091
+ 1. 核对 Ticket、Goal Plan、Evidence 目标、owner 与本地 integration 授权;
1092
+ 2. 验证来源 worktree clean,branch tip 精确等于 `source_checkpoint`,commit 从 `base_sha` 可达;
1093
+ 3. 审计实际 diff 未越过 writable/shared owner 合同;
1094
+ 4. 确认 source-worktree 必跑非 E2E 检查已执行,且没有把 E2E 自报为通过;
1095
+ 5. 重读父分支 checkout clean、HEAD 与 remote/本地约定,记录 `parent_before_sha`。
1096
+
1097
+ 失败时保持 `review`/`blocked`,不开始候选合并。
1098
+
1099
+ ## 2. 建立 parent-candidate checkout
1100
+
1101
+ 1. 使用 branch `speculo/integration/<change>/<ticket-id>` 和 locator `specdev-worktree/.integration/<ticket-id>`,从最新 `parent_before_sha` 建立 Lead-owned integration worktree;
1102
+ 2. 如果父 SHA 是 source checkpoint 的祖先,在 candidate checkout 执行 `git merge --ff-only <source_checkpoint>`,`method=fast-forward`;
1103
+ 3. 否则执行 `git merge --no-ff --no-commit <source_checkpoint>`;
1104
+ 4. 冲突按 下方 `<merge-conflict-protocol>` 标签 处理。需要新产品决定时执行 `git merge --abort`,记录 blocker 并返回来源 worktree;
1105
+ 5. 对分叉结果创建一次 Lead-owned candidate merge commit,`method=merge-commit`;
1106
+ 6. 记录 candidate branch/locator、`candidate_sha`、`source_sha`、冲突路径与 attempts,worktree 状态改为 `integrating`、integration 状态改为 `candidate`。
1107
+
1108
+ 重试前从最新父分支重建 candidate branch/worktree;旧 candidate SHA 保存在 Evidence。候选生命周期的重建/回收包含在 local candidate integration 授权中。
1109
+
1110
+ ## 3. 在候选父状态验证
1034
1111
 
1035
- ## 集成
1112
+ candidate checkout 运行:
1036
1113
 
1037
- 仅生产 Ticket 进入本段;一次性原型不得合入生产分支。
1114
+ - Ticket 受影响集成与回归;
1115
+ - 项目要求的 typecheck/lint/build 或其他父状态检查;
1116
+ - 仅当 Ticket/Goal Plan `e2e.required=true` 时运行对应 E2E。
1038
1117
 
1039
- 1. workspace owner 确认记录为 `review`,读取 implementation owner 的 Evidence,实际修改未越过路径契约。
1040
- 2. 在目标集成基线上应用变更并运行受影响的定向与回归验证。
1041
- 3. 仅当变更影响用户界面交互时,由当前集成 owner 运行验收所需的最小 E2E;委派执行中 implementation owner 只提供场景和预期结果,Lead 负责运行。
1042
- 4. 验证通过后将记录更新为 `integrated`;冲突或失败时设为 `blocked` 并保留 worktree。
1118
+ 每条命令记录运行环境 `parent-candidate`、退出码与摘要。E2E required 未运行或失败时 integration `verification=failed`、`status=failed`;父分支保持 `parent_before_sha`。可由既有合同机械修正的失败最多处理三轮;不得放宽断言、删除检查或发明行为。
1043
1119
 
1044
- ## 清理
1120
+ ## 4. 推进父分支
1045
1121
 
1046
- 1. 取得用户对删除 worktree 和分支的授权。
1047
- 2. Git provider 从 project root 解析 `specdev-worktree/<work-item-id>`,重验无路径逃逸且与 `git worktree list --porcelain` 的记录一致,再从主工作树移除;native/external 通过对应 provider 管理入口移除。
1048
- 3. 确认 worktree 不再注册且工作项目录不存在后删除对应分支。Ticket 将状态更新为 `removed`;原型把 `cleanup_status` 更新为 `clean`。保留项目根 `specdev-worktree/` 统一目录及 `.gitignore` 条目。
1122
+ 全部 required 检查通过后:
1049
1123
 
1050
- PR 或暂缓集成时保留 worktree。清理失败时停止;仅在用户明确要求时使用强制删除。
1124
+ 1. 重读父分支 HEAD;不等于 `parent_before_sha` 时将 candidate 标记 `stale`,不推进父分支并从步骤 2 重建;
1125
+ 2. 在父分支 checkout 执行 `git merge --ff-only <candidate_sha>`;候选 merge commit 本身已以父 SHA 为第一祖先,因此不再创建第二个 merge commit;
1126
+ 3. 重读父 HEAD、tree 与 ancestor 关系,确认 HEAD 精确等于 candidate SHA 且包含 source checkpoint;
1127
+ 4. 写入 `result_sha=candidate_sha`、`verification=passed`、E2E 最终状态和 Evidence;
1128
+ 5. integration/status 改为 `passed`/`integrated`,再由 Lead 标记 Ticket Done。
1129
+
1130
+ ## 5. 失败、清理与恢复
1131
+
1132
+ - candidate 检查失败:父分支不动,Ticket 回 `in_progress` 或 `blocked`,来源 worktree 保留;
1133
+ - 父 HEAD 漂移:旧 candidate 记 `stale`,完整重建并重跑;
1134
+ - 成功后可按 candidate integration 授权回收 transient integration worktree/branch;来源 branch/worktree 不自动清理。获得独立 cleanup 授权并清理后,只将生命周期状态改为 `removed`,完整保留已经通过的集成与 E2E 证据;
1135
+ - push、PR、remote merge、deploy、migration 和生产动作仍需各自授权。
1136
+
1137
+ **完成标准**:passed 时父 HEAD=result/candidate SHA 且包含 source commit;failed/stale 时父 HEAD 仍为开始该轮记录的父状态或更新后的外部事实,没有本轮候选污染。
1051
1138
 
1052
1139
  </dev-worktree-finalize>
1053
1140
 
1141
+ <merge-conflict-protocol>
1142
+
1143
+ # Merge / Rebase Conflict Protocol
1144
+
1145
+ 只在 `git status` 证明仓库正处于 merge/rebase 冲突时加载。
1146
+
1147
+ ## 流程
1148
+
1149
+ 1. 读取 Git 状态、操作类型、冲突路径、base/ours/theirs SHA、Ticket/Evidence 与匹配的 candidate integration 记录。
1150
+ 2. 从 commit、source、Spec、Ticket、ADR、测试和调用者追溯双方意图;信息不足时不猜产品行为。
1151
+ 3. 对每个 hunk 写出双方意图、共同约束和唯一可推导结果;需要新行为或上层决定时停止并登记 deviation。
1152
+ 4. 在授权路径内解决文本,运行受影响的非 E2E 检查;candidate checkout 中按 finalize 合同运行父状态检查/E2E。
1153
+ 5. 匹配的 local candidate integration 授权包含 `git add`、candidate merge commit、必要的 `git merge --abort` 和 transient candidate checkout/branch 生命周期;不扩展到来源 branch/worktree cleanup 或远端动作。
1154
+ 6. 需要改变 Spec/ADR、安全/迁移决定、越过 owner 或无法同时保持既有意图时,在 Lead-created candidate 中执行 `git merge --abort`,记录 blocker 并保留来源 worktree;未知普通冲突现场不擅自 abort。
1155
+ 7. 重读 Git 状态、parents 与 diff,确认无 marker、无未声明路径、双方合同及验证仍成立。
1156
+
1157
+ ## 完成标准
1158
+
1159
+ - 每个 hunk 可追溯到既有意图;
1160
+ - 新产品决定没有藏在冲突解决中;
1161
+ - 验证记录命令、运行环境、退出码和摘要;
1162
+ - Git 副作用来自明确的 candidate integration 或其他逐动作授权;
1163
+ - 完成/暂停可以从 Git、change status 和 Evidence 恢复。
1164
+
1165
+ </merge-conflict-protocol>
1166
+
1054
1167
  <config-template>
1055
1168
 
1056
1169
  ```json
1057
1170
  {
1058
- "schema_version": 3,
1171
+ "schema_version": 4,
1059
1172
  "interaction_language": "zh-CN",
1060
1173
  "artifact_language": "zh-CN",
1061
1174
  "git": {
1062
- "auto_commit": false,
1063
- "default_branch": null,
1064
- "worktree_for_parallel": true
1175
+ "default_branch": null
1065
1176
  },
1066
1177
  "execution": {
1067
- "max_parallel": 3,
1178
+ "max_implementation_agents": 3,
1068
1179
  "deep_ticket_human_approval": true,
1069
1180
  "shared_path_owner": "explicit"
1070
1181
  },
@@ -1089,33 +1200,31 @@ PR 或暂缓集成时保留 worktree。清理失败时停止;仅在用户明
1089
1200
  ```json
1090
1201
  {
1091
1202
  "$schema": "https://json-schema.org/draft/2020-12/schema",
1092
- "$id": "urn:speculo:specdev:config:v3",
1203
+ "$id": "urn:speculo:specdev:config:v4",
1093
1204
  "title": "SpecDev Configuration",
1094
1205
  "type": "object",
1095
1206
  "required": ["schema_version", "interaction_language", "artifact_language", "git", "execution", "verification", "planning"],
1096
1207
  "properties": {
1097
- "schema_version": {"const": 3},
1208
+ "schema_version": {"const": 4},
1098
1209
  "interaction_language": {"type": "string", "minLength": 1},
1099
1210
  "artifact_language": {"type": "string", "minLength": 1},
1100
1211
  "git": {
1101
1212
  "type": "object",
1102
- "required": ["auto_commit", "default_branch", "worktree_for_parallel"],
1213
+ "required": ["default_branch"],
1103
1214
  "properties": {
1104
- "auto_commit": {"type": "boolean"},
1105
- "default_branch": {"type": ["string", "null"]},
1106
- "worktree_for_parallel": {"type": "boolean"}
1215
+ "default_branch": {"type": ["string", "null"]}
1107
1216
  },
1108
- "additionalProperties": true
1217
+ "additionalProperties": false
1109
1218
  },
1110
1219
  "execution": {
1111
1220
  "type": "object",
1112
- "required": ["max_parallel", "deep_ticket_human_approval", "shared_path_owner"],
1221
+ "required": ["max_implementation_agents", "deep_ticket_human_approval", "shared_path_owner"],
1113
1222
  "properties": {
1114
- "max_parallel": {"type": "integer", "minimum": 1},
1223
+ "max_implementation_agents": {"type": "integer", "minimum": 1, "maximum": 3},
1115
1224
  "deep_ticket_human_approval": {"type": "boolean"},
1116
1225
  "shared_path_owner": {"type": "string", "minLength": 1}
1117
1226
  },
1118
- "additionalProperties": true
1227
+ "additionalProperties": false
1119
1228
  },
1120
1229
  "verification": {
1121
1230
  "type": "object",
@@ -1139,7 +1248,7 @@ PR 或暂缓集成时保留 worktree。清理失败时停止;仅在用户明
1139
1248
  "additionalProperties": true
1140
1249
  }
1141
1250
  },
1142
- "additionalProperties": true
1251
+ "additionalProperties": false
1143
1252
  }
1144
1253
  ```
1145
1254
 
@@ -1149,7 +1258,7 @@ PR 或暂缓集成时保留 worktree。清理失败时停止;仅在用户明
1149
1258
 
1150
1259
  ```json
1151
1260
  {
1152
- "schema_version": 4,
1261
+ "schema_version": 5,
1153
1262
  "workflow": "specdev",
1154
1263
  "active": [],
1155
1264
  "archived": []
@@ -1163,83 +1272,27 @@ PR 或暂缓集成时保留 worktree。清理失败时停止;仅在用户明
1163
1272
  ```json
1164
1273
  {
1165
1274
  "$schema": "https://json-schema.org/draft/2020-12/schema",
1166
- "$id": "urn:speculo:specdev:status:v4",
1275
+ "$id": "urn:speculo:specdev:status:v5",
1167
1276
  "title": "SpecDev Global Status",
1168
1277
  "type": "object",
1169
- "required": [
1170
- "schema_version",
1171
- "workflow",
1172
- "active",
1173
- "archived"
1174
- ],
1278
+ "required": ["schema_version", "workflow", "active", "archived"],
1175
1279
  "properties": {
1176
- "schema_version": {
1177
- "const": 4
1178
- },
1179
- "workflow": {
1180
- "const": "specdev"
1181
- },
1280
+ "schema_version": {"const": 5},
1281
+ "workflow": {"const": "specdev"},
1182
1282
  "active": {
1183
1283
  "type": "array",
1184
1284
  "items": {
1185
1285
  "type": "object",
1186
- "required": [
1187
- "change",
1188
- "current_work",
1189
- "works_run"
1190
- ],
1286
+ "required": ["change"],
1191
1287
  "properties": {
1192
1288
  "change": {
1193
1289
  "type": "string",
1194
1290
  "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*$"
1195
- },
1196
- "current_work": {
1197
- "type": [
1198
- "string",
1199
- "null"
1200
- ],
1201
- "pattern": "^specdev/"
1202
- },
1203
- "works_run": {
1204
- "type": "array",
1205
- "items": {
1206
- "type": "string",
1207
- "pattern": "^specdev/"
1208
- },
1209
- "uniqueItems": true
1210
- },
1211
- "claimed_investigations": {
1212
- "type": "array",
1213
- "items": {
1214
- "type": "object",
1215
- "required": [
1216
- "id",
1217
- "owner",
1218
- "claimed_at"
1219
- ],
1220
- "properties": {
1221
- "id": {
1222
- "type": "string"
1223
- },
1224
- "owner": {
1225
- "type": "string"
1226
- },
1227
- "session": {
1228
- "type": [
1229
- "string",
1230
- "null"
1231
- ]
1232
- },
1233
- "claimed_at": {
1234
- "type": "string"
1235
- }
1236
- },
1237
- "additionalProperties": false
1238
- }
1239
1291
  }
1240
1292
  },
1241
1293
  "additionalProperties": false
1242
- }
1294
+ },
1295
+ "uniqueItems": true
1243
1296
  },
1244
1297
  "archived": {
1245
1298
  "type": "array",
@@ -1260,11 +1313,24 @@ PR 或暂缓集成时保留 worktree。清理失败时停止;仅在用户明
1260
1313
 
1261
1314
  ```json
1262
1315
  {
1263
- "schema_version": 3,
1316
+ "schema_version": 5,
1264
1317
  "artifact": "change-status",
1265
1318
  "change": "<YYYY-MM-DD-topic>",
1266
1319
  "change_status": "active",
1267
1320
  "current_work": null,
1321
+ "works_run": [],
1322
+ "claimed_investigations": [],
1323
+ "execution_authorization": {
1324
+ "implementation_commit": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Ticket source commits"},
1325
+ "local_candidate_integration": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Lead-owned local parent candidate integration and parent update"},
1326
+ "source_cleanup": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Source worktree and branch cleanup"}
1327
+ },
1328
+ "leadership": {
1329
+ "current": "<owner-or-session-locator>",
1330
+ "epoch": 1,
1331
+ "assigned_at": "<ISO-8601>",
1332
+ "history": []
1333
+ },
1268
1334
  "created_at": "<ISO-8601>",
1269
1335
  "updated_at": "<ISO-8601>",
1270
1336
  "completed_at": null,
@@ -1283,216 +1349,157 @@ PR 或暂缓集成时保留 worktree。清理失败时停止;仅在用户明
1283
1349
  ```json
1284
1350
  {
1285
1351
  "$schema": "https://json-schema.org/draft/2020-12/schema",
1286
- "$id": "urn:speculo:specdev:change-status:v3",
1352
+ "$id": "urn:speculo:specdev:change-status:v5",
1287
1353
  "title": "SpecDev Change Status",
1288
1354
  "type": "object",
1289
1355
  "required": [
1290
- "schema_version",
1291
- "artifact",
1292
- "change",
1293
- "change_status",
1294
- "current_work",
1295
- "created_at",
1296
- "updated_at",
1297
- "completed_at",
1298
- "archived",
1299
- "archive_path",
1300
- "blockers",
1301
- "deviations"
1356
+ "schema_version", "artifact", "change", "change_status", "current_work", "works_run",
1357
+ "claimed_investigations", "execution_authorization", "leadership", "created_at", "updated_at",
1358
+ "completed_at", "archived", "archive_path", "blockers", "deviations", "worktrees"
1302
1359
  ],
1303
1360
  "properties": {
1304
- "schema_version": {
1305
- "const": 3
1306
- },
1307
- "artifact": {
1308
- "const": "change-status"
1309
- },
1310
- "change": {
1311
- "type": "string",
1312
- "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*$"
1313
- },
1314
- "change_status": {
1315
- "enum": [
1316
- "active",
1317
- "blocked",
1318
- "completed",
1319
- "archived"
1320
- ]
1321
- },
1322
- "current_work": {
1323
- "type": [
1324
- "string",
1325
- "null"
1326
- ]
1327
- },
1328
- "created_at": {
1329
- "type": "string",
1330
- "minLength": 1
1331
- },
1332
- "updated_at": {
1333
- "type": "string",
1334
- "minLength": 1
1361
+ "schema_version": {"const": 5},
1362
+ "artifact": {"const": "change-status"},
1363
+ "change": {"type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*$"},
1364
+ "change_status": {"enum": ["active", "blocked", "completed", "archived"]},
1365
+ "current_work": {"type": ["string", "null"], "pattern": "^specdev/"},
1366
+ "works_run": {"type": "array", "items": {"type": "string", "pattern": "^specdev/"}, "uniqueItems": true},
1367
+ "claimed_investigations": {"type": "array", "items": {"$ref": "#/$defs/claim"}},
1368
+ "execution_authorization": {"$ref": "#/$defs/authorization"},
1369
+ "leadership": {"$ref": "#/$defs/leadership"},
1370
+ "created_at": {"type": "string", "minLength": 1},
1371
+ "updated_at": {"type": "string", "minLength": 1},
1372
+ "completed_at": {"type": ["string", "null"]},
1373
+ "archived": {"type": "boolean"},
1374
+ "archive_path": {"anyOf": [{"type": "null"}, {"type": "string", "pattern": "^specdev/archive/[0-9]{4}-[0-9]{2}/.+/$"}]},
1375
+ "blockers": {"type": "array", "items": {"type": "string"}},
1376
+ "deviations": {"type": "array", "items": {"type": "string"}},
1377
+ "worktrees": {"type": "array", "items": {"$ref": "#/$defs/worktree"}}
1378
+ },
1379
+ "$defs": {
1380
+ "claim": {
1381
+ "type": "object",
1382
+ "required": ["id", "owner", "session", "claimed_at"],
1383
+ "properties": {
1384
+ "id": {"type": "string", "minLength": 1},
1385
+ "owner": {"type": "string", "minLength": 1},
1386
+ "session": {"type": ["string", "null"]},
1387
+ "claimed_at": {"type": "string", "minLength": 1}
1388
+ },
1389
+ "additionalProperties": false
1335
1390
  },
1336
- "completed_at": {
1337
- "type": [
1338
- "string",
1339
- "null"
1340
- ]
1391
+ "authorization-entry": {
1392
+ "type": "object",
1393
+ "required": ["status", "source", "granted_at", "scope"],
1394
+ "properties": {
1395
+ "status": {"enum": ["authorized", "not-authorized", "revoked"]},
1396
+ "source": {"type": ["string", "null"]},
1397
+ "granted_at": {"type": ["string", "null"]},
1398
+ "scope": {"type": "string", "minLength": 1}
1399
+ },
1400
+ "allOf": [{
1401
+ "if": {"properties": {"status": {"const": "authorized"}}, "required": ["status"]},
1402
+ "then": {"properties": {"source": {"type": "string", "minLength": 1}, "granted_at": {"type": "string", "minLength": 1}}}
1403
+ }],
1404
+ "additionalProperties": false
1341
1405
  },
1342
- "archived": {
1343
- "type": "boolean"
1406
+ "authorization": {
1407
+ "type": "object",
1408
+ "required": ["implementation_commit", "local_candidate_integration", "source_cleanup"],
1409
+ "properties": {
1410
+ "implementation_commit": {"$ref": "#/$defs/authorization-entry"},
1411
+ "local_candidate_integration": {"$ref": "#/$defs/authorization-entry"},
1412
+ "source_cleanup": {"$ref": "#/$defs/authorization-entry"}
1413
+ },
1414
+ "additionalProperties": false
1344
1415
  },
1345
- "archive_path": {
1346
- "anyOf": [
1347
- {
1348
- "type": "null"
1349
- },
1350
- {
1351
- "type": "string",
1352
- "pattern": "^specdev/archive/[0-9]{4}-[0-9]{2}/.+/$"
1353
- }
1354
- ]
1416
+ "leadership-history": {
1417
+ "type": "object",
1418
+ "required": ["owner", "epoch", "assigned_at", "ended_at"],
1419
+ "properties": {
1420
+ "owner": {"type": "string", "minLength": 1},
1421
+ "epoch": {"type": "integer", "minimum": 1},
1422
+ "assigned_at": {"type": "string", "minLength": 1},
1423
+ "ended_at": {"type": "string", "minLength": 1}
1424
+ },
1425
+ "additionalProperties": false
1355
1426
  },
1356
- "blockers": {
1357
- "type": "array",
1358
- "items": {
1359
- "type": "string"
1360
- }
1427
+ "leadership": {
1428
+ "type": "object",
1429
+ "required": ["current", "epoch", "assigned_at", "history"],
1430
+ "properties": {
1431
+ "current": {"type": "string", "minLength": 1},
1432
+ "epoch": {"type": "integer", "minimum": 1},
1433
+ "assigned_at": {"type": "string", "minLength": 1},
1434
+ "history": {"type": "array", "items": {"$ref": "#/$defs/leadership-history"}}
1435
+ },
1436
+ "additionalProperties": false
1361
1437
  },
1362
- "deviations": {
1363
- "type": "array",
1364
- "items": {
1365
- "type": "string"
1366
- }
1438
+ "full-suite": {
1439
+ "type": "object",
1440
+ "required": ["required", "status", "reason", "evidence"],
1441
+ "properties": {
1442
+ "required": {"type": "boolean"},
1443
+ "status": {"enum": ["not-required", "pending", "passed", "failed"]},
1444
+ "reason": {"type": ["string", "null"]},
1445
+ "evidence": {"type": ["string", "null"]}
1446
+ },
1447
+ "allOf": [{
1448
+ "if": {"properties": {"required": {"const": false}}, "required": ["required"]},
1449
+ "then": {"properties": {"status": {"const": "not-required"}, "reason": {"type": "string", "minLength": 1}}}
1450
+ }],
1451
+ "additionalProperties": false
1367
1452
  },
1368
- "worktrees": {
1369
- "type": "array",
1370
- "items": {
1371
- "type": "object",
1372
- "required": [
1373
- "ticket_id",
1374
- "owner",
1375
- "provider",
1376
- "base_sha",
1377
- "branch",
1378
- "workspace_ref",
1379
- "status",
1380
- "updated_at"
1381
- ],
1382
- "properties": {
1383
- "ticket_id": {
1384
- "type": "string",
1385
- "pattern": "^T-[0-9]{2,}$"
1386
- },
1387
- "owner": {
1388
- "type": "string",
1389
- "minLength": 1
1390
- },
1391
- "provider": {
1392
- "enum": [
1393
- "native",
1394
- "git",
1395
- "external"
1396
- ]
1397
- },
1398
- "base_sha": {
1399
- "type": "string",
1400
- "minLength": 1
1401
- },
1402
- "branch": {
1403
- "type": "string",
1404
- "minLength": 1
1405
- },
1406
- "workspace_ref": {
1407
- "type": "string",
1408
- "minLength": 1,
1409
- "pattern": "^(?!/)(?![A-Za-z]:[\\\\/]).+"
1410
- },
1411
- "status": {
1412
- "enum": [
1413
- "planned",
1414
- "active",
1415
- "review",
1416
- "integrated",
1417
- "removed",
1418
- "blocked"
1419
- ]
1420
- },
1421
- "updated_at": {
1422
- "type": "string",
1423
- "minLength": 1
1424
- }
1425
- },
1426
- "additionalProperties": true
1427
- }
1428
- }
1429
- },
1430
- "allOf": [
1431
- {
1432
- "if": {
1433
- "properties": {
1434
- "worktrees": {
1435
- "contains": {
1436
- "properties": {
1437
- "provider": {
1438
- "const": "git"
1439
- }
1440
- },
1441
- "required": [
1442
- "provider"
1443
- ]
1444
- }
1445
- }
1446
- }
1453
+ "worktree": {
1454
+ "type": "object",
1455
+ "required": ["ticket_id", "owner", "implementation_owner", "integration_owner", "provider", "base_sha", "parent_branch", "branch", "workspace_ref", "source_checkpoint", "integration", "status", "updated_at"],
1456
+ "properties": {
1457
+ "ticket_id": {"type": "string", "pattern": "^T-[0-9]{2,}$"},
1458
+ "owner": {"type": "string", "minLength": 1},
1459
+ "implementation_owner": {"type": "string", "minLength": 1},
1460
+ "integration_owner": {"type": "string", "minLength": 1},
1461
+ "provider": {"const": "git"},
1462
+ "base_sha": {"type": "string", "minLength": 1},
1463
+ "parent_branch": {"type": "string", "minLength": 1},
1464
+ "branch": {"type": "string", "minLength": 1},
1465
+ "workspace_ref": {"type": "string", "pattern": "^specdev-worktree/[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*/T-[0-9]{2,}$"},
1466
+ "source_checkpoint": {"type": ["string", "null"]},
1467
+ "integration": {"$ref": "#/$defs/integration"},
1468
+ "status": {"enum": ["planned", "active", "review", "integrating", "integrated", "removed", "blocked"]},
1469
+ "updated_at": {"type": "string", "minLength": 1}
1447
1470
  },
1448
- "then": {
1449
- "properties": {
1450
- "worktrees": {
1451
- "items": {
1452
- "if": {
1453
- "properties": {
1454
- "provider": {
1455
- "const": "git"
1456
- }
1457
- },
1458
- "required": [
1459
- "provider"
1460
- ]
1461
- },
1462
- "then": {
1463
- "properties": {
1464
- "workspace_ref": {
1465
- "pattern": "^specdev-worktree/T-[0-9]{2,}$"
1466
- }
1467
- }
1468
- }
1469
- }
1470
- }
1471
- }
1472
- }
1471
+ "additionalProperties": false
1473
1472
  },
1474
- {
1475
- "if": {
1476
- "properties": {
1477
- "change_status": {
1478
- "const": "archived"
1479
- }
1480
- }
1473
+ "integration": {
1474
+ "type": "object",
1475
+ "required": ["status", "parent_ref", "parent_before_sha", "source_sha", "candidate_sha", "candidate_tree_sha", "candidate_branch", "candidate_workspace_ref", "result_sha", "method", "conflict_paths", "verification", "full_suite", "e2e", "evidence", "attempts", "promotion_status"],
1476
+ "properties": {
1477
+ "status": {"enum": ["pending", "candidate", "passed", "failed", "stale"]},
1478
+ "parent_ref": {"type": ["string", "null"]},
1479
+ "parent_before_sha": {"type": ["string", "null"]},
1480
+ "source_sha": {"type": ["string", "null"]},
1481
+ "candidate_sha": {"type": ["string", "null"]},
1482
+ "candidate_tree_sha": {"type": ["string", "null"]},
1483
+ "candidate_branch": {"type": ["string", "null"]},
1484
+ "candidate_workspace_ref": {"anyOf": [{"type": "null"}, {"type": "string", "pattern": "^specdev-worktree/\\.integration/[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*/T-[0-9]{2,}$"}]},
1485
+ "result_sha": {"type": ["string", "null"]},
1486
+ "method": {"enum": [null, "fast-forward", "merge-commit"]},
1487
+ "conflict_paths": {"type": "array", "items": {"type": "string"}},
1488
+ "verification": {"enum": ["pending", "passed", "failed"]},
1489
+ "full_suite": {"$ref": "#/$defs/full-suite"},
1490
+ "e2e": {"$ref": "#/$defs/full-suite"},
1491
+ "evidence": {"type": "string", "pattern": "^\\{roots\\.state\\}/specdev/changes/[^<]+/evidence/T-[0-9]{2,}\\.md$"},
1492
+ "attempts": {"type": "integer", "minimum": 0},
1493
+ "promotion_status": {"enum": ["pending", "applying", "applied", "failed", "stale"]}
1481
1494
  },
1482
- "then": {
1483
- "properties": {
1484
- "archived": {
1485
- "const": true
1486
- },
1487
- "archive_path": {
1488
- "type": "string",
1489
- "pattern": "^specdev/archive/[0-9]{4}-[0-9]{2}/.+/$"
1490
- }
1491
- }
1492
- }
1495
+ "additionalProperties": false
1493
1496
  }
1494
- ],
1495
- "additionalProperties": true
1497
+ },
1498
+ "allOf": [{
1499
+ "if": {"properties": {"change_status": {"const": "archived"}}, "required": ["change_status"]},
1500
+ "then": {"properties": {"archived": {"const": true}, "archive_path": {"type": "string", "pattern": "^specdev/archive/[0-9]{4}-[0-9]{2}/.+/$"}}}
1501
+ }],
1502
+ "additionalProperties": false
1496
1503
  }
1497
1504
  ```
1498
1505