@namewta/speculo 0.7.3 → 0.7.4

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 (43) hide show
  1. package/dist/src/migrations.js +190 -39
  2. package/dist/src/migrations.js.map +1 -1
  3. package/package.json +1 -1
  4. package/template/canonical/canonical-specdev-engineering-cognitive-mentor.md +51 -15
  5. package/template/canonical/canonical-specdev-goal-plan.md +183 -116
  6. package/template/canonical/canonical-specdev-grill-with-docs.md +51 -15
  7. package/template/canonical/canonical-specdev-spec.md +61 -21
  8. package/template/canonical/canonical-specdev-tickets.md +83 -43
  9. package/template/canonical/canonical-specdev-wayfinder.md +51 -15
  10. package/template/skills/migrate-runtime-state/references/migration-contract.md +3 -3
  11. package/template/skills/migrate-runtime-state/scripts/migrate-runtime-state.mjs +94 -12
  12. package/template/workflows/specdev/I-implement/I-implement.md +27 -26
  13. package/template/workflows/specdev/I-implement/evidence-template.md +18 -12
  14. package/template/workflows/specdev/I-implement/execution-preflight.md +11 -9
  15. package/template/workflows/specdev/I-init-setup/I-init-setup.md +2 -2
  16. package/template/workflows/specdev/I-init-setup/change-status-template.json +3 -3
  17. package/template/workflows/specdev/I-init-setup/config-template.json +5 -2
  18. package/template/workflows/specdev/INDEX.md +6 -6
  19. package/template/workflows/specdev/P-goal-plan/P-goal-plan.md +16 -16
  20. package/template/workflows/specdev/P-goal-plan/completion-control.md +8 -8
  21. package/template/workflows/specdev/P-goal-plan/goal-plan-template.md +20 -14
  22. package/template/workflows/specdev/P-goal-plan/lead-orchestration.md +5 -5
  23. package/template/workflows/specdev/P-goal-plan/orchestration-protocol.md +13 -13
  24. package/template/workflows/specdev/P-goal-plan/planning-modes.md +27 -15
  25. package/template/workflows/specdev/P-prototype/ui-prototype.md +1 -1
  26. package/template/workflows/specdev/T-tickets/T-tickets.md +4 -4
  27. package/template/workflows/specdev/T-tickets/ticket-readiness.md +3 -3
  28. package/template/workflows/specdev/T-tickets/ticket-template.md +6 -6
  29. package/template/workflows/specdev/T-tickets/tickets-map-template.md +2 -2
  30. package/template/workflows/specdev/common/README.md +1 -1
  31. package/template/workflows/specdev/common/rules/change-completion.md +2 -2
  32. package/template/workflows/specdev/common/rules/evidence-and-verification.md +10 -6
  33. package/template/workflows/specdev/common/rules/path-ownership.md +4 -4
  34. package/template/workflows/specdev/common/schemas/change-status.schema.json +31 -4
  35. package/template/workflows/specdev/common/schemas/config.schema.json +12 -6
  36. package/template/workflows/specdev/common/schemas/goal-plan.schema.json +15 -6
  37. package/template/workflows/specdev/common/skills/dev-worktree/SKILL.md +3 -3
  38. package/template/workflows/specdev/common/skills/dev-worktree/references/finalize.md +1 -1
  39. package/template/workflows/specdev/common/skills/subagent-delivery/SKILL.md +4 -4
  40. package/template/workflows/specdev/common/skills/subagent-delivery/references/external-web-subagent.md +1 -1
  41. package/template/workflows/specdev/common/skills/subagent-delivery/references/native-subagent.md +4 -4
  42. package/template/workflows/specdev/common/tools/README.md +2 -1
  43. package/template/workflows/specdev/common/tools/validate-specdev.mjs +261 -66
@@ -115,8 +115,8 @@ Ticket 是**决策完备的微型执行计划**:它消除执行者在目标、
115
115
  - 有序执行路线和安全落点;
116
116
  - expected、writable、read-only、shared 路径;
117
117
  - 正常、失败和回归验证矩阵;
118
- - 每个 Ticket 的 source-worktree E2E 检查、父分支 candidate 集成出口,以及按实际跨边界风险判定的 E2E disposition;
119
- - 每个实现 Ticket 的独立 worktree、implementation commit 与父分支合并完成条件;
118
+ - 每个 Ticket 按 Goal Plan workspace 策略定义 current-workspace/direct-parent source-worktree/parent-candidate 检查,以及按实际跨边界风险判定的 E2E disposition;
119
+ - 每个实现 Ticket implementation commit 与对应父分支完成条件;仅 required 模式创建独立 worktree;
120
120
  - Deep 的迁移、兼容窗口、监控、回滚和不可逆批准点;
121
121
  - 可判定验收标准。
122
122
 
@@ -144,8 +144,8 @@ Ticket 是**决策完备的微型执行计划**:它消除执行者在目标、
144
144
  - 依赖缺失或 DAG 有环;
145
145
  - 可写路径不明确或并行所有权冲突;
146
146
  - 验证方法不能执行且没有批准的替代证据;
147
- - Ticket 未声明 E2E required/not-required 及理由,或把 E2E 安排到 source worktree;
148
- - 无法形成实现 commit 与 candidate-merge 父分支出口;
147
+ - Ticket 未声明 E2E required/not-required 及理由,或在 required 模式把 E2E 安排到 source worktree;
148
+ - 无法形成实现 commit 与 Goal Plan 所选 direct-parent/candidate-merge 父分支出口;
149
149
  - 单个新上下文无法完成;
150
150
  - Standard/Deep 缺少有序执行路线;
151
151
  - Deep 缺少迁移、兼容、监控、回滚或批准点。
@@ -314,8 +314,8 @@ node Speculo Node 校验器 \
314
314
  - [ ] 每个 shared path 在 `shared_path_owners` 中有唯一 owner。
315
315
  - [ ] 正常、失败和回归至少各有一条验证,或有可信的不适用原因。
316
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。
317
+ - [ ] 按 Goal Plan 策略定义 current-workspace 或 source-worktree 的非 E2E 检查;E2E owner 固定为 Lead,运行环境分别为 current-workspace 或 parent-candidate。
318
+ - [ ] Ticket 完成合同包含 implementation commit、direct-parent 或 candidate-merge、父分支 result SHA 和 Lead Evidence;仅 required 模式需要独立 worktree
319
319
  - [ ] Evidence 位置明确为 `specdev/changes/{change}/evidence/T-NN.md`。
320
320
  - [ ] 单个全新上下文能够完成;否则已拆分。
321
321
  - [ ] 所有内部文件与目录引用使用本文约定的逻辑路径。
@@ -331,7 +331,7 @@ node Speculo Node 校验器 \
331
331
 
332
332
  - [ ] 迁移顺序、兼容窗口、监控、回滚或前向恢复、收缩条件和批准点完整。
333
333
  - [ ] 安全、隐私、资金或数据完整性风险有缓解与验证。
334
- - [ ] 跨 implementation owner 的路径所有权和 parent-candidate 集成 Gate 明确。
334
+ - [ ] 跨 implementation owner 的路径所有权和所选 direct-parent/parent-candidate 集成 Gate 明确。
335
335
  - [ ] expand-contract 的收缩条件可通过扫描、指标、查询或测试证明。
336
336
 
337
337
  ## Ready 状态
@@ -457,12 +457,12 @@ shared_path_owners: []
457
457
 
458
458
  不适用的关键风险类别必须写“不适用:原因”。
459
459
 
460
- - **Source-worktree checks:** 单元、组件、静态、类型、lint/build 等适用非 E2E 检查。
460
+ - **Workspace checks:** 按 Goal Plan 在 current workspace 或 source worktree 运行单元、组件、静态、类型、lint/build 等适用非 E2E 检查。
461
461
  - **E2E disposition:** required / not-required:原因。
462
- - **E2E owner/environment:** Lead / parent-candidate;required 时写明场景、接缝与预期。
463
- - **Integration evidence:** source commit、parent beforecandidate/result SHA 和父分支包含关系。
462
+ - **E2E owner/environment:** Lead / current-workspace 或 parent-candidate;required 时写明场景、接缝与预期。
463
+ - **Integration evidence:** implementation/source commit、parent before、适用 candidate/result SHA 和父分支包含关系。
464
464
 
465
- E2E 由实际跨边界行为与风险决定,不限于 UI;不得在 Ticket source worktree 运行或声明通过。
465
+ E2E 由实际跨边界行为与风险决定,不限于 UI;required 模式不得在 Ticket source worktree 运行或声明通过。
466
466
 
467
467
  ## 9. 发布、迁移与恢复
468
468
 
@@ -480,8 +480,8 @@ E2E 由实际跨边界行为与风险决定,不限于 UI;不得在 Ticket so
480
480
  - [ ] `AC-001`:<可判定结果>。
481
481
  - [ ] 验证矩阵全部执行并记录到 `specdev/changes/{change}/evidence/T-01.md`。
482
482
  - [ ] 实际项目修改未超出 `writable_paths`,shared path 由指定 owner 修改。
483
- - [ ] Ticket 来源 worktree 已形成非空实现 commit,candidate 验证通过且父分支 result 包含 source commit。
484
- - [ ] E2E disposition 已执行;required E2E 在 parent-candidate 由 Lead 完成。
483
+ - [ ] Ticket 已按 Goal Plan 策略形成非空 implementation/source commit,direct-parent 或 candidate 验证通过且父分支 result 已记录。
484
+ - [ ] E2E disposition 已执行;required 模式 E2E 在 parent-candidate、current 模式在 current workspace 由 Lead 完成。
485
485
  - [ ] 未发生未批准的范围、契约或发布偏差。
486
486
  - [ ] Ticket、Tickets Map 和 Evidence 状态一致。
487
487
 
@@ -541,11 +541,11 @@ T-01 [READY]
541
541
 
542
542
  ## 5. 并行与路径所有权
543
543
 
544
- - implementation subagent 上限来自 `specdev/config.json`,不得超过三个且不含 Lead。
544
+ - implementation subagent 上限来自 `specdev/config.json`,Goal Plan 可进一步降低且不含 Lead。
545
545
  - review/research/test-observation agent 不设 SpecDev 数字上限,但保持只读。
546
546
  - shared owner 为专用 Ticket;Lead 是 SpecDev 状态与父分支 integration owner。
547
547
  - 项目路径契约以 Ticket frontmatter 为准。
548
- - 每个实现 Ticket 使用独立 worktree,不以是否派遣 Agent 或是否并行为条件;只读调查不进入 I-implement Ticket。
548
+ - 每个实现 Ticket workspace Goal Plan 选择;current 模式串行使用当前 workspace,required 模式使用独立 worktree;只读调查不进入 I-implement Ticket。
549
549
 
550
550
  | Ticket A | Ticket B | Writable 交集 | 真实依赖 | 处理 |
551
551
  |---|---|---|---|---|
@@ -789,15 +789,15 @@ Ticket 只有同时满足以下适用条件才可设置 `ready: true`:
789
789
  5. 越界前停止并按 deviation control 提出 ownership change;不得先改后报。
790
790
  6. 上游 Ticket 改变目录/合同后,下游基于已集成父分支重新解析路径和 preflight。
791
791
 
792
- ## 3. Ticket worktree
792
+ ## 3. Ticket workspace strategy
793
793
 
794
- 每个进入 I-implement Ticket 都使用唯一来源 worktree `specdev-worktree/<ticket-id>`,无论是否并行、是否派遣 subagent。Ticket 切片是隔离依据;Agent Team 不是 worktree 触发器。没有 Ticket 的获批 Direct Spec 可由 current workspace 唯一 owner 执行;只读调查不创建实现 worktree。
794
+ Goal Plan 创建时选择 Ticket workspace strategy,默认 `current`。`current` 模式的 Ticket 使用当前分支、当前 workspace 和严格串行执行;允许一个 implementation subagent 写入当前 workspace,但前一 Ticket 必须完成 commit、Lead 验收和 direct-parent 验证后才能开始下一个。`required` 模式每个 Ticket 使用唯一来源 worktree `specdev-worktree/<ticket-id>`,并通过 candidate-merge 集成。没有 Ticket 的获批 Direct Spec 继续由 current workspace 唯一 owner 执行;只读调查不创建实现 worktree。
795
795
 
796
- workspace/implementation owner 可以是 Lead 或动态 implementation subagent;integration owner 固定为 Lead。只有 Lead SpecDev 状态、建立 parent-candidate、运行适用 E2E 并推进父分支。生命周期由 下方 `<dev-worktree>` 标签 管理。
796
+ workspace/implementation owner 可以是 Lead 或动态 implementation subagent;integration owner 固定为 Lead。current 模式 Lead 在父分支直接验收和推进,required 模式 Lead 建立 parent-candidate、运行适用 E2E 并推进父分支。required 生命周期由 下方 `<dev-worktree>` 标签 管理,current 生命周期由 I-implement 的 direct-parent 规则管理。
797
797
 
798
798
  ## 4. 并发
799
799
 
800
- implementation subagent 同时最多三个,Lead 不计入;实际上限取 Goal Plan、config 和平台能力最小值。review/research/test-observation agent 不设置 SpecDev 数字上限,但 Lead 必须避免重复工作与可变环境争用。
800
+ required 模式 implementation subagent 上限取 Goal Plan、config 和平台能力共同约束,Lead 不计入。current 模式保持单 writer 串行安全不变量,Ticket 严格串行。review/research/test-observation agent 不设置 SpecDev 数字上限,但 Lead 必须避免重复工作与可变环境争用。
801
801
 
802
802
  **完成标准**:每个项目写入映射到唯一 Ticket、owner 和来源 worktree;shared 与父分支写入 owner 唯一。
803
803
 
@@ -815,19 +815,23 @@ implementation subagent 同时最多三个,Lead 不计入;实际上限取 Go
815
815
 
816
816
  | 行为或风险 | 接缝 | 命令/方法 | 环境 | 预期 | Evidence |
817
817
  |---|---|---|---|---|---|
818
- | 正常/失败路径 | 公共接口或稳定接缝 | 定向测试 | source-worktree | 合同成立 | Ticket Evidence |
819
- | 跨模块回归 | 集成接缝 | 回归命令 | parent-candidate | 组合状态成立 | Ticket Evidence |
820
- | E2E required | 真实端到端边界 | 场景步骤 | parent-candidate | 外部行为成立 | Ticket Evidence |
818
+ | 正常/失败路径 | 公共接口或稳定接缝 | 定向测试 | current-workspace 或 source-worktree | 合同成立 | Ticket Evidence |
819
+ | 跨模块回归 | 集成接缝 | 回归命令 | current-workspace 或 parent-candidate | 组合状态成立 | Ticket Evidence |
820
+ | E2E required | 真实端到端边界 | 场景步骤 | current-workspace 或 parent-candidate | 外部行为成立 | Ticket Evidence |
821
821
 
822
822
  ## 2. 两层验证
823
823
 
824
+ ### Current workspace
825
+
826
+ current 模式的 implementation owner 在当前父分支和当前 workspace 工作。Ticket 必须严格串行,workspace clean 后形成非空 implementation commit;Lead 在同一 workspace 执行适用集成/回归和 E2E,并在父 HEAD 未漂移时将 Ticket commit 记录为 result SHA。
827
+
824
828
  ### Source-worktree
825
829
 
826
830
  implementation owner 运行最接近目标行为的单元/组件测试、静态分析、类型、lint/build 等适用非 E2E 检查。来源实现必须在 clean worktree 形成 commit。任何 source-worktree E2E pass 声明无效。
827
831
 
828
832
  ### Parent-candidate
829
833
 
830
- Lead 在最新父分支与 source commit 的 candidate 状态运行受影响集成/回归、项目父状态检查和适用 E2E。E2E 由实际跨边界风险决定,不限于 UI;not-required 必须写理由。required E2E 未运行或失败时不得推进父分支。
834
+ required 模式下,Lead 在最新父分支与 source commit 的 candidate 状态运行受影响集成/回归、项目父状态检查和适用 E2E。E2E 由实际跨边界风险决定,不限于 UI;not-required 必须写理由。required E2E 未运行或失败时不得推进父分支。
831
835
 
832
836
  ### Direct Spec
833
837
 
@@ -847,9 +851,9 @@ subagent 只返回候选命令与结果,不写 Evidence。Lead 重读 workspac
847
851
 
848
852
  ## 5. Evidence 最低内容
849
853
 
850
- 每个 Ticket Evidence 至少包含:Lead、Dispatch/返回(若有)、base/source/candidate/result SHA、来源 worktree、实际路径、每条命令/环境/退出状态、合同映射、双轴审查、E2E disposition、未运行项、失败分类、偏差、残余风险和父分支重读结果。
854
+ 每个 Ticket Evidence 至少包含:Lead、Dispatch/返回(若有)、workspace 策略、base/source/result SHA、candidate 字段(required 模式适用,current 模式明确不适用)、实际路径、每条命令/环境/退出状态、合同映射、双轴审查、E2E disposition、未运行项、失败分类、偏差、残余风险和父分支重读结果。
851
855
 
852
- Ticket Done 必须有 source commit、通过 candidate、父分支 result 与 Lead Evidence。无法运行 required 验证、存在未批准偏差、父分支未包含 source commit 或 Evidence 不完整时不得 Done。
856
+ required Ticket Done 必须有 source commit、通过 candidate、父分支 result 与 Lead Evidence;current Ticket Done 必须有 implementation commit、通过 direct-parent 验证、父分支 result 与 Lead Evidence。无法运行 required 验证、存在未批准偏差、父分支未包含 Ticket commit 或 Evidence 不完整时不得 Done。
853
857
 
854
858
  Direct Spec Evidence 至少包含:用户批准与轻量合同、Lead、实施前/最终 checkpoint、实际路径、定向/回归/E2E 命令及环境、验收映射、未运行项、偏差、残余风险和提交授权状态。
855
859
 
@@ -962,7 +966,7 @@ Direct Spec Evidence 至少包含:用户批准与轻量合同、Lead、实施
962
966
 
963
967
  # Dev Worktree
964
968
 
965
- 本 Skill 由 T-tickets/P-goal-plan/I-implement 和 P-prototype 复用。`purpose=ticket` 使用完整 source → candidate → parent 状态机;`purpose=prototype` 只使用调用方批准的临时生命周期。
969
+ 本 Skill 由 T-tickets/P-goal-plan/I-implement 和 P-prototype 复用。`purpose=ticket` 仅在 Goal Plan 选择 `required` 时使用完整 source → candidate → parent 状态机;`current` Ticket 不调用本 Skill。`purpose=prototype` 只使用调用方批准的临时生命周期。
966
970
 
967
971
  ## 输入
968
972
 
@@ -972,7 +976,7 @@ Direct Spec Evidence 至少包含:用户批准与轻量合同、Lead、实施
972
976
  - workspace、implementation 和 integration owner;
973
977
  - 允许动作、路径合同、验证合同、调用方状态记录位置。
974
978
 
975
- Ticket 还必须提供 Ready Ticket、Goal Plan(若存在)、Evidence 路径、implementation commit 与本地 candidate integration/父分支更新授权。缺失时返回 blocked,不使用 current workspace 代替。
979
+ required Ticket 还必须提供 Ready Ticket、Goal Plan(若存在)、Evidence 路径、implementation commit 与本地 candidate integration/父分支更新授权。缺失时返回 blockedcurrent Ticket 应按 I-implement 的 direct-parent 规则执行。
976
980
 
977
981
  ## 1. 创建或恢复
978
982
 
@@ -1115,7 +1119,7 @@ Prototype 只要求调用方已记录本次临时 branch/worktree 授权、问
1115
1119
  - 项目要求的 typecheck/lint/build 或其他父状态检查;
1116
1120
  - 仅当 Ticket/Goal Plan `e2e.required=true` 时运行对应 E2E。
1117
1121
 
1118
- 每条命令记录运行环境 `parent-candidate`、退出码与摘要。E2E required 未运行或失败时 integration `verification=failed`、`status=failed`;父分支保持 `parent_before_sha`。可由既有合同机械修正的失败最多处理三轮;不得放宽断言、删除检查或发明行为。
1122
+ 每条命令记录运行环境 `parent-candidate`、退出码与摘要。E2E required 未运行或失败时 integration `verification=failed`、`status=failed`;父分支保持 `parent_before_sha`。机械修正次数不得超过 Goal Plan 快照的 `integration_attempt_limit`;不得放宽断言、删除检查或发明行为。
1119
1123
 
1120
1124
  ## 4. 推进父分支
1121
1125
 
@@ -1168,7 +1172,7 @@ Prototype 只要求调用方已记录本次临时 branch/worktree 授权、问
1168
1172
 
1169
1173
  ```json
1170
1174
  {
1171
- "schema_version": 4,
1175
+ "schema_version": 5,
1172
1176
  "interaction_language": "zh-CN",
1173
1177
  "artifact_language": "zh-CN",
1174
1178
  "git": {
@@ -1176,6 +1180,7 @@ Prototype 只要求调用方已记录本次临时 branch/worktree 授权、问
1176
1180
  },
1177
1181
  "execution": {
1178
1182
  "max_implementation_agents": 3,
1183
+ "max_integration_attempts": 3,
1179
1184
  "deep_ticket_human_approval": true,
1180
1185
  "shared_path_owner": "explicit"
1181
1186
  },
@@ -1188,7 +1193,9 @@ Prototype 只要求调用方已记录本次临时 branch/worktree 授权、问
1188
1193
  "planning": {
1189
1194
  "default_depth": "standard",
1190
1195
  "require_ready_gate": true,
1191
- "require_evidence": true
1196
+ "require_evidence": true,
1197
+ "ui_prototype_default_variants": 3,
1198
+ "ui_prototype_max_variants": 5
1192
1199
  }
1193
1200
  }
1194
1201
  ```
@@ -1200,12 +1207,12 @@ Prototype 只要求调用方已记录本次临时 branch/worktree 授权、问
1200
1207
  ```json
1201
1208
  {
1202
1209
  "$schema": "https://json-schema.org/draft/2020-12/schema",
1203
- "$id": "urn:speculo:specdev:config:v4",
1210
+ "$id": "urn:speculo:specdev:config:v5",
1204
1211
  "title": "SpecDev Configuration",
1205
1212
  "type": "object",
1206
1213
  "required": ["schema_version", "interaction_language", "artifact_language", "git", "execution", "verification", "planning"],
1207
1214
  "properties": {
1208
- "schema_version": {"const": 4},
1215
+ "schema_version": {"const": 5},
1209
1216
  "interaction_language": {"type": "string", "minLength": 1},
1210
1217
  "artifact_language": {"type": "string", "minLength": 1},
1211
1218
  "git": {
@@ -1218,9 +1225,10 @@ Prototype 只要求调用方已记录本次临时 branch/worktree 授权、问
1218
1225
  },
1219
1226
  "execution": {
1220
1227
  "type": "object",
1221
- "required": ["max_implementation_agents", "deep_ticket_human_approval", "shared_path_owner"],
1228
+ "required": ["max_implementation_agents", "max_integration_attempts", "deep_ticket_human_approval", "shared_path_owner"],
1222
1229
  "properties": {
1223
- "max_implementation_agents": {"type": "integer", "minimum": 1, "maximum": 3},
1230
+ "max_implementation_agents": {"type": "integer", "minimum": 1},
1231
+ "max_integration_attempts": {"type": "integer", "minimum": 1},
1224
1232
  "deep_ticket_human_approval": {"type": "boolean"},
1225
1233
  "shared_path_owner": {"type": "string", "minLength": 1}
1226
1234
  },
@@ -1239,15 +1247,20 @@ Prototype 只要求调用方已记录本次临时 branch/worktree 授权、问
1239
1247
  },
1240
1248
  "planning": {
1241
1249
  "type": "object",
1242
- "required": ["default_depth", "require_ready_gate", "require_evidence"],
1250
+ "required": ["default_depth", "require_ready_gate", "require_evidence", "ui_prototype_default_variants", "ui_prototype_max_variants"],
1243
1251
  "properties": {
1244
1252
  "default_depth": {"enum": ["lite", "standard", "deep"]},
1245
1253
  "require_ready_gate": {"type": "boolean"},
1246
- "require_evidence": {"type": "boolean"}
1254
+ "require_evidence": {"type": "boolean"},
1255
+ "ui_prototype_default_variants": {"type": "integer", "minimum": 1},
1256
+ "ui_prototype_max_variants": {"type": "integer", "minimum": 1}
1247
1257
  },
1248
1258
  "additionalProperties": true
1249
1259
  }
1250
1260
  },
1261
+ "allOf": [{
1262
+ "$comment": "ui_prototype_default_variants <= ui_prototype_max_variants is enforced by validate-specdev.mjs because JSON Schema cannot compare sibling numeric values."
1263
+ }],
1251
1264
  "additionalProperties": false
1252
1265
  }
1253
1266
  ```
@@ -1313,7 +1326,7 @@ Prototype 只要求调用方已记录本次临时 branch/worktree 授权、问
1313
1326
 
1314
1327
  ```json
1315
1328
  {
1316
- "schema_version": 5,
1329
+ "schema_version": 6,
1317
1330
  "artifact": "change-status",
1318
1331
  "change": "<YYYY-MM-DD-topic>",
1319
1332
  "change_status": "active",
@@ -1321,8 +1334,8 @@ Prototype 只要求调用方已记录本次临时 branch/worktree 授权、问
1321
1334
  "works_run": [],
1322
1335
  "claimed_investigations": [],
1323
1336
  "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"},
1337
+ "implementation_commit": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Ticket implementation commits"},
1338
+ "local_candidate_integration": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Lead-owned local direct-parent or candidate integration and parent update"},
1326
1339
  "source_cleanup": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Source worktree and branch cleanup"}
1327
1340
  },
1328
1341
  "leadership": {
@@ -1349,7 +1362,7 @@ Prototype 只要求调用方已记录本次临时 branch/worktree 授权、问
1349
1362
  ```json
1350
1363
  {
1351
1364
  "$schema": "https://json-schema.org/draft/2020-12/schema",
1352
- "$id": "urn:speculo:specdev:change-status:v5",
1365
+ "$id": "urn:speculo:specdev:change-status:v6",
1353
1366
  "title": "SpecDev Change Status",
1354
1367
  "type": "object",
1355
1368
  "required": [
@@ -1358,7 +1371,7 @@ Prototype 只要求调用方已记录本次临时 branch/worktree 授权、问
1358
1371
  "completed_at", "archived", "archive_path", "blockers", "deviations", "worktrees"
1359
1372
  ],
1360
1373
  "properties": {
1361
- "schema_version": {"const": 5},
1374
+ "schema_version": {"const": 6},
1362
1375
  "artifact": {"const": "change-status"},
1363
1376
  "change": {"type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*$"},
1364
1377
  "change_status": {"enum": ["active", "blocked", "completed", "archived"]},
@@ -1462,12 +1475,39 @@ Prototype 只要求调用方已记录本次临时 branch/worktree 授权、问
1462
1475
  "base_sha": {"type": "string", "minLength": 1},
1463
1476
  "parent_branch": {"type": "string", "minLength": 1},
1464
1477
  "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,}$"},
1478
+ "workspace_ref": {"type": "string", "pattern": "^(?:current|specdev-worktree/[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*/T-[0-9]{2,})$"},
1466
1479
  "source_checkpoint": {"type": ["string", "null"]},
1467
1480
  "integration": {"$ref": "#/$defs/integration"},
1468
1481
  "status": {"enum": ["planned", "active", "review", "integrating", "integrated", "removed", "blocked"]},
1469
1482
  "updated_at": {"type": "string", "minLength": 1}
1470
1483
  },
1484
+ "allOf": [
1485
+ {
1486
+ "if": {"properties": {"workspace_ref": {"const": "current"}}, "required": ["workspace_ref"]},
1487
+ "then": {
1488
+ "properties": {
1489
+ "integration": {
1490
+ "allOf": [{
1491
+ "properties": {
1492
+ "candidate_sha": {"const": null},
1493
+ "candidate_tree_sha": {"const": null},
1494
+ "candidate_branch": {"const": null},
1495
+ "candidate_workspace_ref": {"const": null},
1496
+ "method": {"enum": [null, "direct-parent"]}
1497
+ }
1498
+ }]
1499
+ }
1500
+ }
1501
+ },
1502
+ "else": {
1503
+ "properties": {
1504
+ "integration": {
1505
+ "allOf": [{"properties": {"method": {"enum": [null, "fast-forward", "merge-commit"]}}}]
1506
+ }
1507
+ }
1508
+ }
1509
+ }
1510
+ ],
1471
1511
  "additionalProperties": false
1472
1512
  },
1473
1513
  "integration": {
@@ -1483,7 +1523,7 @@ Prototype 只要求调用方已记录本次临时 branch/worktree 授权、问
1483
1523
  "candidate_branch": {"type": ["string", "null"]},
1484
1524
  "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
1525
  "result_sha": {"type": ["string", "null"]},
1486
- "method": {"enum": [null, "fast-forward", "merge-commit"]},
1526
+ "method": {"enum": [null, "direct-parent", "fast-forward", "merge-commit"]},
1487
1527
  "conflict_paths": {"type": "array", "items": {"type": "string"}},
1488
1528
  "verification": {"enum": ["pending", "passed", "failed"]},
1489
1529
  "full_suite": {"$ref": "#/$defs/full-suite"},
@@ -324,7 +324,7 @@ resolution: answered
324
324
 
325
325
  ```json
326
326
  {
327
- "schema_version": 4,
327
+ "schema_version": 5,
328
328
  "interaction_language": "zh-CN",
329
329
  "artifact_language": "zh-CN",
330
330
  "git": {
@@ -332,6 +332,7 @@ resolution: answered
332
332
  },
333
333
  "execution": {
334
334
  "max_implementation_agents": 3,
335
+ "max_integration_attempts": 3,
335
336
  "deep_ticket_human_approval": true,
336
337
  "shared_path_owner": "explicit"
337
338
  },
@@ -344,7 +345,9 @@ resolution: answered
344
345
  "planning": {
345
346
  "default_depth": "standard",
346
347
  "require_ready_gate": true,
347
- "require_evidence": true
348
+ "require_evidence": true,
349
+ "ui_prototype_default_variants": 3,
350
+ "ui_prototype_max_variants": 5
348
351
  }
349
352
  }
350
353
  ```
@@ -356,12 +359,12 @@ resolution: answered
356
359
  ```json
357
360
  {
358
361
  "$schema": "https://json-schema.org/draft/2020-12/schema",
359
- "$id": "urn:speculo:specdev:config:v4",
362
+ "$id": "urn:speculo:specdev:config:v5",
360
363
  "title": "SpecDev Configuration",
361
364
  "type": "object",
362
365
  "required": ["schema_version", "interaction_language", "artifact_language", "git", "execution", "verification", "planning"],
363
366
  "properties": {
364
- "schema_version": {"const": 4},
367
+ "schema_version": {"const": 5},
365
368
  "interaction_language": {"type": "string", "minLength": 1},
366
369
  "artifact_language": {"type": "string", "minLength": 1},
367
370
  "git": {
@@ -374,9 +377,10 @@ resolution: answered
374
377
  },
375
378
  "execution": {
376
379
  "type": "object",
377
- "required": ["max_implementation_agents", "deep_ticket_human_approval", "shared_path_owner"],
380
+ "required": ["max_implementation_agents", "max_integration_attempts", "deep_ticket_human_approval", "shared_path_owner"],
378
381
  "properties": {
379
- "max_implementation_agents": {"type": "integer", "minimum": 1, "maximum": 3},
382
+ "max_implementation_agents": {"type": "integer", "minimum": 1},
383
+ "max_integration_attempts": {"type": "integer", "minimum": 1},
380
384
  "deep_ticket_human_approval": {"type": "boolean"},
381
385
  "shared_path_owner": {"type": "string", "minLength": 1}
382
386
  },
@@ -395,15 +399,20 @@ resolution: answered
395
399
  },
396
400
  "planning": {
397
401
  "type": "object",
398
- "required": ["default_depth", "require_ready_gate", "require_evidence"],
402
+ "required": ["default_depth", "require_ready_gate", "require_evidence", "ui_prototype_default_variants", "ui_prototype_max_variants"],
399
403
  "properties": {
400
404
  "default_depth": {"enum": ["lite", "standard", "deep"]},
401
405
  "require_ready_gate": {"type": "boolean"},
402
- "require_evidence": {"type": "boolean"}
406
+ "require_evidence": {"type": "boolean"},
407
+ "ui_prototype_default_variants": {"type": "integer", "minimum": 1},
408
+ "ui_prototype_max_variants": {"type": "integer", "minimum": 1}
403
409
  },
404
410
  "additionalProperties": true
405
411
  }
406
412
  },
413
+ "allOf": [{
414
+ "$comment": "ui_prototype_default_variants <= ui_prototype_max_variants is enforced by validate-specdev.mjs because JSON Schema cannot compare sibling numeric values."
415
+ }],
407
416
  "additionalProperties": false
408
417
  }
409
418
  ```
@@ -469,7 +478,7 @@ resolution: answered
469
478
 
470
479
  ```json
471
480
  {
472
- "schema_version": 5,
481
+ "schema_version": 6,
473
482
  "artifact": "change-status",
474
483
  "change": "<YYYY-MM-DD-topic>",
475
484
  "change_status": "active",
@@ -477,8 +486,8 @@ resolution: answered
477
486
  "works_run": [],
478
487
  "claimed_investigations": [],
479
488
  "execution_authorization": {
480
- "implementation_commit": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Ticket source commits"},
481
- "local_candidate_integration": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Lead-owned local parent candidate integration and parent update"},
489
+ "implementation_commit": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Ticket implementation commits"},
490
+ "local_candidate_integration": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Lead-owned local direct-parent or candidate integration and parent update"},
482
491
  "source_cleanup": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Source worktree and branch cleanup"}
483
492
  },
484
493
  "leadership": {
@@ -505,7 +514,7 @@ resolution: answered
505
514
  ```json
506
515
  {
507
516
  "$schema": "https://json-schema.org/draft/2020-12/schema",
508
- "$id": "urn:speculo:specdev:change-status:v5",
517
+ "$id": "urn:speculo:specdev:change-status:v6",
509
518
  "title": "SpecDev Change Status",
510
519
  "type": "object",
511
520
  "required": [
@@ -514,7 +523,7 @@ resolution: answered
514
523
  "completed_at", "archived", "archive_path", "blockers", "deviations", "worktrees"
515
524
  ],
516
525
  "properties": {
517
- "schema_version": {"const": 5},
526
+ "schema_version": {"const": 6},
518
527
  "artifact": {"const": "change-status"},
519
528
  "change": {"type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*$"},
520
529
  "change_status": {"enum": ["active", "blocked", "completed", "archived"]},
@@ -618,12 +627,39 @@ resolution: answered
618
627
  "base_sha": {"type": "string", "minLength": 1},
619
628
  "parent_branch": {"type": "string", "minLength": 1},
620
629
  "branch": {"type": "string", "minLength": 1},
621
- "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,}$"},
630
+ "workspace_ref": {"type": "string", "pattern": "^(?:current|specdev-worktree/[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*/T-[0-9]{2,})$"},
622
631
  "source_checkpoint": {"type": ["string", "null"]},
623
632
  "integration": {"$ref": "#/$defs/integration"},
624
633
  "status": {"enum": ["planned", "active", "review", "integrating", "integrated", "removed", "blocked"]},
625
634
  "updated_at": {"type": "string", "minLength": 1}
626
635
  },
636
+ "allOf": [
637
+ {
638
+ "if": {"properties": {"workspace_ref": {"const": "current"}}, "required": ["workspace_ref"]},
639
+ "then": {
640
+ "properties": {
641
+ "integration": {
642
+ "allOf": [{
643
+ "properties": {
644
+ "candidate_sha": {"const": null},
645
+ "candidate_tree_sha": {"const": null},
646
+ "candidate_branch": {"const": null},
647
+ "candidate_workspace_ref": {"const": null},
648
+ "method": {"enum": [null, "direct-parent"]}
649
+ }
650
+ }]
651
+ }
652
+ }
653
+ },
654
+ "else": {
655
+ "properties": {
656
+ "integration": {
657
+ "allOf": [{"properties": {"method": {"enum": [null, "fast-forward", "merge-commit"]}}}]
658
+ }
659
+ }
660
+ }
661
+ }
662
+ ],
627
663
  "additionalProperties": false
628
664
  },
629
665
  "integration": {
@@ -639,7 +675,7 @@ resolution: answered
639
675
  "candidate_branch": {"type": ["string", "null"]},
640
676
  "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,}$"}]},
641
677
  "result_sha": {"type": ["string", "null"]},
642
- "method": {"enum": [null, "fast-forward", "merge-commit"]},
678
+ "method": {"enum": [null, "direct-parent", "fast-forward", "merge-commit"]},
643
679
  "conflict_paths": {"type": "array", "items": {"type": "string"}},
644
680
  "verification": {"enum": ["pending", "passed", "failed"]},
645
681
  "full_suite": {"$ref": "#/$defs/full-suite"},
@@ -26,9 +26,9 @@
26
26
  - `active` 从仍位于 `changes/` 且 change 状态为 active/blocked/completed 的真实目录核对;不得创建虚假 change。
27
27
  - `archived` 从 `archive/YYYY-MM/<change>/` 核对,active/archived 不得重叠。
28
28
  - `config.json` 保留语言、Git、执行、验证与规划偏好,并补入当前 schema 的必需默认值。
29
- - SpecDev config v3 升级为 v4 时,`execution.max_parallel` 只作为旧并发偏好的输入,收敛到 `execution.max_implementation_agents: 1..3`;删除旧的自动提交和条件 worktree 开关,不把它们解释为授权。
29
+ - SpecDev config v3/v4 升级为 v5 时,`execution.max_parallel` 只作为旧并发偏好的输入,保留为正整数的 `execution.max_implementation_agents`;补齐 `max_integration_attempts` 与 planning 原型变体配置。删除旧的自动提交和条件 worktree 开关,不把它们解释为授权。
30
30
  - change-status v3 只有在 `worktrees` 缺失或为空时才可确定性升级为 v4;存在旧 worktree 记录时,必须逐 Ticket 重建 implementation owner、source commit、candidate/result、E2E disposition 和父分支包含关系。v4 runtime 不得自动升级为 v5:旧状态无法可靠推断 execution authorization 或 Lead leadership,必须保持 pending 并显式对账。
31
- - active Goal Plan 不是 v5 时必须重新规划固定 Lead、Ticket worktree 和 candidate integration gate;不能只改 frontmatter 版本号。
31
+ - active Goal Plan 不是 v6 时必须重新规划 Lead、workspace integration gate;不能只改 frontmatter 版本号。
32
32
  - 已声明为 v4 的 SpecDev config,以及已声明为 v5 的 global status、change-status 和 Goal Plan,必须完整满足当前 schema:必需字段、类型、枚举、嵌套对象和 `additionalProperties` 边界都通过后才能自动保留。不得为不完整状态静默补默认值,也不得只扫描少量标记字段。
33
33
  - worktree `removed` 只接受为 `integrated` 后的清理终态;source checkpoint、passed candidate/result、验证、E2E disposition 和 Evidence 必须完整保留。
34
34
  - `.config/`、`adr/`、`context/`、`research/`、`changes/`、`archive/` 和声明的 sidecar 都是持久项。
@@ -59,6 +59,6 @@
59
59
  - action 后、删除 staged marker 前、原子替换后都递归拒绝 active runtime 中的 symlink;任何失败均恢复原 active 安装。
60
60
  - 所有迁移后 JSON 可解析。
61
61
  - workspace、install manifest、项目配置和已安装 workflow 全局状态满足当前版本。
62
- - SpecDev active/archive 索引与目录一致;SpecDev config 满足 v4 合同,global statuschange-status Goal Plan 满足 v5 合同;person 状态满足 schema v1。
62
+ - SpecDev active/archive 索引与目录一致;SpecDev config 满足 v5 合同,global status 满足 v5 合同,change-status 满足 v6 合同,Goal Plan 满足 v6 合同;person 状态满足 schema v1。
63
63
  - pending marker 只在全部验证通过后从 staged 安装删除。
64
64
  - 执行后 backup manifest 与内容 hash 不变。