@namewta/speculo 0.7.2 → 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.
- package/dist/src/migrations.js +755 -23
- package/dist/src/migrations.js.map +1 -1
- package/package.json +1 -1
- package/template/canonical/canonical-specdev-engineering-cognitive-mentor.md +200 -448
- package/template/canonical/canonical-specdev-goal-plan.md +744 -1108
- package/template/canonical/canonical-specdev-grill-with-docs.md +201 -449
- package/template/canonical/canonical-specdev-spec.md +232 -486
- package/template/canonical/canonical-specdev-tickets.md +411 -590
- package/template/canonical/canonical-specdev-wayfinder.md +199 -447
- package/template/skills/migrate-runtime-state/SKILL.md +6 -6
- package/template/skills/migrate-runtime-state/references/migration-contract.md +9 -3
- package/template/skills/migrate-runtime-state/scripts/migrate-runtime-state.mjs +404 -33
- package/template/workflows/specdev/I-implement/I-implement.md +98 -143
- package/template/workflows/specdev/I-implement/evidence-template.md +66 -48
- package/template/workflows/specdev/I-implement/execution-preflight.md +31 -21
- package/template/workflows/specdev/I-implement/merge-conflict-protocol.md +12 -12
- package/template/workflows/specdev/I-init-setup/I-init-setup.md +4 -5
- package/template/workflows/specdev/I-init-setup/change-status-template.json +14 -1
- package/template/workflows/specdev/I-init-setup/config-template.json +7 -6
- package/template/workflows/specdev/I-init-setup/status-template.json +1 -1
- package/template/workflows/specdev/INDEX.md +11 -8
- package/template/workflows/specdev/P-goal-plan/P-goal-plan.md +76 -102
- package/template/workflows/specdev/P-goal-plan/completion-control.md +26 -44
- package/template/workflows/specdev/P-goal-plan/goal-plan-template.md +46 -37
- package/template/workflows/specdev/P-goal-plan/lead-orchestration.md +34 -0
- package/template/workflows/specdev/P-goal-plan/orchestration-protocol.md +31 -46
- package/template/workflows/specdev/P-goal-plan/planning-modes.md +67 -89
- package/template/workflows/specdev/P-prototype/ui-prototype.md +1 -1
- package/template/workflows/specdev/T-tickets/T-tickets.md +6 -3
- package/template/workflows/specdev/T-tickets/ticket-readiness.md +5 -3
- package/template/workflows/specdev/T-tickets/ticket-template.md +8 -1
- package/template/workflows/specdev/T-tickets/tickets-map-template.md +5 -4
- package/template/workflows/specdev/_state/status.json +1 -1
- package/template/workflows/specdev/common/README.md +2 -2
- package/template/workflows/specdev/common/rules/change-completion.md +17 -20
- package/template/workflows/specdev/common/rules/deviation-control.md +1 -1
- package/template/workflows/specdev/common/rules/evidence-and-verification.md +31 -37
- package/template/workflows/specdev/common/rules/path-ownership.md +21 -23
- package/template/workflows/specdev/common/rules/readiness-and-depth.md +1 -1
- package/template/workflows/specdev/common/schemas/change-status.schema.json +153 -363
- package/template/workflows/specdev/common/schemas/config.schema.json +17 -13
- package/template/workflows/specdev/common/schemas/goal-plan.schema.json +33 -16
- package/template/workflows/specdev/common/schemas/status.schema.json +7 -63
- package/template/workflows/specdev/common/skills/dev-worktree/SKILL.md +42 -21
- package/template/workflows/specdev/common/skills/dev-worktree/references/create.md +36 -21
- package/template/workflows/specdev/common/skills/dev-worktree/references/finalize.md +46 -18
- package/template/workflows/specdev/common/skills/subagent-delivery/SKILL.md +34 -31
- package/template/workflows/specdev/common/skills/subagent-delivery/references/external-web-subagent.md +10 -23
- package/template/workflows/specdev/common/skills/subagent-delivery/references/native-subagent.md +15 -25
- package/template/workflows/specdev/common/tools/README.md +2 -1
- package/template/workflows/specdev/common/tools/validate-specdev.mjs +591 -219
- package/template/workflows/specdev/I-implement/delegated-evidence-template.md +0 -12
- package/template/workflows/specdev/P-goal-plan/delegated-execution-template.md +0 -35
- package/template/workflows/specdev/P-goal-plan/delegated-execution.md +0 -59
- package/template/workflows/specdev/P-goal-plan/workspace-execution-template.md +0 -24
|
@@ -98,7 +98,7 @@ Ticket 是**决策完备的微型执行计划**:它消除执行者在目标、
|
|
|
98
98
|
|
|
99
99
|
- `lite`:局部、可逆、沿用既有模式、无公共契约或迁移影响;
|
|
100
100
|
- `standard`:大多数多文件或跨层垂直切片;
|
|
101
|
-
- `deep`:公共 API/schema、数据迁移、安全/隐私/资金、不可逆操作、expand-contract
|
|
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
|
-
-
|
|
118
|
+
- 每个 Ticket 按 Goal Plan 的 workspace 策略定义 current-workspace/direct-parent 或 source-worktree/parent-candidate 检查,以及按实际跨边界风险判定的 E2E disposition;
|
|
119
|
+
- 每个实现 Ticket 的 implementation commit 与对应父分支完成条件;仅 required 模式创建独立 worktree;
|
|
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 及理由,或在 required 模式把 E2E 安排到 source worktree;
|
|
148
|
+
- 无法形成实现 commit 与 Goal Plan 所选 direct-parent/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
|
|
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
|
-
- [ ]
|
|
316
|
+
- [ ] 明确 `E2E disposition: required | not-required: reason`;required 场景、预期和接缝可执行。
|
|
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。
|
|
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
|
-
- [ ] 跨
|
|
334
|
+
- [ ] 跨 implementation owner 的路径所有权和所选 direct-parent/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
|
-
|
|
460
|
+
- **Workspace checks:** 按 Goal Plan 在 current workspace 或 source worktree 运行单元、组件、静态、类型、lint/build 等适用非 E2E 检查。
|
|
461
|
+
- **E2E disposition:** required / not-required:原因。
|
|
462
|
+
- **E2E owner/environment:** Lead / current-workspace 或 parent-candidate;required 时写明场景、接缝与预期。
|
|
463
|
+
- **Integration evidence:** implementation/source commit、parent before、适用 candidate/result SHA 和父分支包含关系。
|
|
464
|
+
|
|
465
|
+
E2E 由实际跨边界行为与风险决定,不限于 UI;required 模式不得在 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 已按 Goal Plan 策略形成非空 implementation/source commit,direct-parent 或 candidate 验证通过且父分支 result 已记录。
|
|
484
|
+
- [ ] E2E disposition 已执行;required 模式 E2E 在 parent-candidate、current 模式在 current workspace 由 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
|
-
-
|
|
533
|
-
-
|
|
544
|
+
- implementation subagent 上限来自 `specdev/config.json`,Goal Plan 可进一步降低且不含 Lead。
|
|
545
|
+
- review/research/test-observation agent 不设 SpecDev 数字上限,但保持只读。
|
|
546
|
+
- shared owner 为专用 Ticket;Lead 是 SpecDev 状态与父分支 integration owner。
|
|
534
547
|
- 项目路径契约以 Ticket frontmatter 为准。
|
|
535
|
-
-
|
|
548
|
+
- 每个实现 Ticket 的 workspace 由 Goal Plan 选择;current 模式串行使用当前 workspace,required 模式使用独立 worktree;只读调查不进入 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、
|
|
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
|
|
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
|
|
765
|
-
- `read_only_paths
|
|
766
|
-
- `shared_paths`:多个 Ticket
|
|
767
|
-
|
|
768
|
-
示例:
|
|
776
|
+
- `expected_changes`:导航预测;
|
|
777
|
+
- `writable_paths`:当前 Ticket implementation owner 可写的硬边界;
|
|
778
|
+
- `read_only_paths`:只读上下文;
|
|
779
|
+
- `shared_paths`:多个 Ticket 可能触达且必须有唯一 owner 的项目路径。
|
|
769
780
|
|
|
770
|
-
|
|
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,其
|
|
780
|
-
2.
|
|
781
|
-
3.
|
|
782
|
-
4.
|
|
783
|
-
5.
|
|
784
|
-
6.
|
|
785
|
-
|
|
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 workspace strategy
|
|
793
|
+
|
|
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。
|
|
786
795
|
|
|
787
|
-
|
|
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 规则管理。
|
|
788
797
|
|
|
789
|
-
|
|
798
|
+
## 4. 并发
|
|
790
799
|
|
|
791
|
-
|
|
800
|
+
required 模式 implementation subagent 上限取 Goal Plan、config 和平台能力共同约束,Lead 不计入。current 模式保持单 writer 串行安全不变量,Ticket 严格串行。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,55 @@ Worktree 只在存在可观察隔离需求时使用:并行写入、保护当
|
|
|
796
807
|
|
|
797
808
|
# 证据与验证规范
|
|
798
809
|
|
|
799
|
-
|
|
810
|
+
验证回答“怎样证明”,Evidence 记录“实际运行了什么、在哪个状态运行、结果和残余风险是什么”。
|
|
800
811
|
|
|
801
812
|
## 1. 验证矩阵
|
|
802
813
|
|
|
803
|
-
|
|
814
|
+
每行绑定行为、合同或风险,并标记环境:
|
|
804
815
|
|
|
805
|
-
| 行为或风险 |
|
|
806
|
-
|
|
807
|
-
|
|
|
808
|
-
|
|
|
809
|
-
|
|
|
816
|
+
| 行为或风险 | 接缝 | 命令/方法 | 环境 | 预期 | Evidence |
|
|
817
|
+
|---|---|---|---|---|---|
|
|
818
|
+
| 正常/失败路径 | 公共接口或稳定接缝 | 定向测试 | current-workspace 或 source-worktree | 合同成立 | Ticket Evidence |
|
|
819
|
+
| 跨模块回归 | 集成接缝 | 回归命令 | current-workspace 或 parent-candidate | 组合状态成立 | Ticket Evidence |
|
|
820
|
+
| E2E required | 真实端到端边界 | 场景步骤 | current-workspace 或 parent-candidate | 外部行为成立 | Ticket Evidence |
|
|
821
|
+
|
|
822
|
+
## 2. 两层验证
|
|
823
|
+
|
|
824
|
+
### Current workspace
|
|
825
|
+
|
|
826
|
+
current 模式的 implementation owner 在当前父分支和当前 workspace 工作。Ticket 必须严格串行,workspace clean 后形成非空 implementation commit;Lead 在同一 workspace 执行适用集成/回归和 E2E,并在父 HEAD 未漂移时将 Ticket commit 记录为 result SHA。
|
|
827
|
+
|
|
828
|
+
### Source-worktree
|
|
810
829
|
|
|
811
|
-
|
|
830
|
+
implementation owner 运行最接近目标行为的单元/组件测试、静态分析、类型、lint/build 等适用非 E2E 检查。来源实现必须在 clean worktree 形成 commit。任何 source-worktree E2E pass 声明无效。
|
|
812
831
|
|
|
813
|
-
|
|
832
|
+
### Parent-candidate
|
|
814
833
|
|
|
815
|
-
|
|
834
|
+
required 模式下,Lead 在最新父分支与 source commit 的 candidate 状态运行受影响集成/回归、项目父状态检查和适用 E2E。E2E 由实际跨边界风险决定,不限于 UI;not-required 必须写理由。required E2E 未运行或失败时不得推进父分支。
|
|
816
835
|
|
|
817
|
-
|
|
818
|
-
2. 稳定接缝上的单元测试;
|
|
819
|
-
3. 类型检查、静态分析、lint 和构建;
|
|
820
|
-
4. 可重复手动步骤、截图或查询结果;
|
|
821
|
-
5. 代码阅读推断。
|
|
836
|
+
### Direct Spec
|
|
822
837
|
|
|
823
|
-
|
|
838
|
+
获批 Direct Spec 不创建 Ticket worktree 或 candidate。Lead 在 current workspace 记录实施前基线,运行轻量合同要求的定向检查、适用回归与 E2E,并记录最终 checkpoint、dirty 状态、运行环境、命令、退出状态和未运行原因。E2E 仍只由 Lead 执行;不得为套用两层验证而伪造 Ticket、source/candidate/result 或父分支推进证据。
|
|
824
839
|
|
|
825
|
-
|
|
840
|
+
低层证据不能替代明确要求的外部行为证据。高风险迁移还需要 dry-run、调用点扫描、数据核对、监控或恢复演练。
|
|
826
841
|
|
|
827
|
-
## 3.
|
|
842
|
+
## 3. Agent 声明
|
|
828
843
|
|
|
829
|
-
|
|
844
|
+
subagent 只返回候选命令与结果,不写 Evidence。Lead 重读 workspace/Git、必要时复跑或核对输出后落盘;外部 provider 自报、截图、模拟和推断在此之前标记 `unverified`。review/research/test-observation agent 不拥有 E2E Gate。
|
|
830
845
|
|
|
831
|
-
|
|
832
|
-
- 基线已存在的失败;
|
|
833
|
-
- 环境、权限或基础设施失败;
|
|
834
|
-
- 验证本身无效或无法观察目标行为。
|
|
846
|
+
## 4. 失败分类与完整性
|
|
835
847
|
|
|
836
|
-
|
|
848
|
+
失败分类为本 Ticket 新失败、基线既有失败、环境/权限/基础设施失败、无效验证或 candidate stale。不得通过跳过、放宽断言、吞错、删除用例或迁移验证位置制造绿色。
|
|
837
849
|
|
|
838
|
-
|
|
850
|
+
受控反向验证只用于可能静默通过的关键门禁:证明检查能在目标风险出现时失败,再恢复并重跑。普通测试不为形式执行破坏性操作。
|
|
839
851
|
|
|
840
|
-
|
|
852
|
+
## 5. Evidence 最低内容
|
|
841
853
|
|
|
842
|
-
|
|
843
|
-
- 实际修改的项目路径;
|
|
844
|
-
- 每条命令、退出状态和结果摘要;
|
|
845
|
-
- 每条验收合同的证据映射;
|
|
846
|
-
- 未运行项与原因;
|
|
847
|
-
- 新失败、既有失败和环境失败;
|
|
848
|
-
- 偏差及批准;
|
|
849
|
-
- 残余风险;
|
|
850
|
-
- worktree、提交或 PR 引用;
|
|
851
|
-
- 最终结论。
|
|
854
|
+
每个 Ticket Evidence 至少包含:Lead、Dispatch/返回(若有)、workspace 策略、base/source/result SHA、candidate 字段(required 模式适用,current 模式明确不适用)、实际路径、每条命令/环境/退出状态、合同映射、双轴审查、E2E disposition、未运行项、失败分类、偏差、残余风险和父分支重读结果。
|
|
852
855
|
|
|
853
|
-
|
|
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。
|
|
857
|
+
|
|
858
|
+
Direct Spec Evidence 至少包含:用户批准与轻量合同、Lead、实施前/最终 checkpoint、实际路径、定向/回归/E2E 命令及环境、验收映射、未运行项、偏差、残余风险和提交授权状态。
|
|
854
859
|
|
|
855
860
|
</evidence-and-verification>
|
|
856
861
|
|
|
@@ -898,7 +903,7 @@ E2E 仅在变更影响用户界面交互时加入验证矩阵。普通执行由
|
|
|
898
903
|
|
|
899
904
|
- 未批准的 ticket、spec、architecture 或 release 偏差不得继续实现。
|
|
900
905
|
- 不得通过扩大 `writable_paths`、删除测试、降低断言或把风险改写成“已知限制”来绕过停止。
|
|
901
|
-
-
|
|
906
|
+
- 偏差影响并行执行、source checkpoint 或 candidate 集成时,Lead 必须暂停受影响 Wave,重新计算路径所有权、依赖、Gate 与父分支顺序;任何 subagent 都不能自行改写上层合同。
|
|
902
907
|
|
|
903
908
|
</deviation-control>
|
|
904
909
|
|
|
@@ -959,77 +964,107 @@ E2E 仅在变更影响用户界面交互时加入验证矩阵。普通执行由
|
|
|
959
964
|
|
|
960
965
|
<dev-worktree>
|
|
961
966
|
|
|
962
|
-
#
|
|
967
|
+
# Dev Worktree
|
|
968
|
+
|
|
969
|
+
本 Skill 由 T-tickets/P-goal-plan/I-implement 和 P-prototype 复用。`purpose=ticket` 仅在 Goal Plan 选择 `required` 时使用完整 source → candidate → parent 状态机;`current` Ticket 不调用本 Skill。`purpose=prototype` 只使用调用方批准的临时生命周期。
|
|
970
|
+
|
|
971
|
+
## 输入
|
|
972
|
+
|
|
973
|
+
- `operation=create | restore | finalize | remove`;
|
|
974
|
+
- `purpose=ticket | prototype`;
|
|
975
|
+
- repository、父分支、`base_sha`、branch、portable workspace locator;
|
|
976
|
+
- workspace、implementation 和 integration owner;
|
|
977
|
+
- 允许动作、路径合同、验证合同、调用方状态记录位置。
|
|
978
|
+
|
|
979
|
+
required Ticket 还必须提供 Ready Ticket、Goal Plan(若存在)、Evidence 路径、implementation commit 与本地 candidate integration/父分支更新授权。缺失时返回 blocked;current Ticket 应按 I-implement 的 direct-parent 规则执行。
|
|
980
|
+
|
|
981
|
+
## 1. 创建或恢复
|
|
982
|
+
|
|
983
|
+
`operation=create` 时加载 下方 `<dev-worktree-create>` 标签。Ticket 使用 `specdev-worktree/<ticket-id>`;同一 Ticket 只存在一个来源 worktree。`operation=restore` 时重读实际 Git worktree/branch/tip/dirty 状态并与调用方记录核对,漂移时停止。
|
|
984
|
+
|
|
985
|
+
**完成标准**:来源基线、branch、locator、owners 和实际 Git 状态一致;现有用户改动未被覆盖。
|
|
986
|
+
|
|
987
|
+
## 2. 来源实现门
|
|
988
|
+
|
|
989
|
+
implementation owner 只在来源 worktree 修改授权项目路径,运行 Ticket 要求的单元、组件、静态、类型、lint/build 等非 E2E 检查。进入 `review` 前,worktree 必须 clean,branch tip 必须是已授权的 `source_checkpoint` commit,实际 diff 必须符合路径合同。
|
|
990
|
+
|
|
991
|
+
**完成标准**:source checkpoint 不可变且可达;来源 worktree 没有 E2E pass 声明。
|
|
963
992
|
|
|
964
|
-
##
|
|
993
|
+
## 3. 候选合并与父分支推进
|
|
965
994
|
|
|
966
|
-
|
|
967
|
-
- 只读调查、Agent Team 本身和没有其他隔离事实的顺序执行默认共用当前工作区。
|
|
968
|
-
- 调用方必须明确 trigger、workspace owner、implementation owner、integration owner、固定基线、父分支、工作项 ID、持久化 owner 和允许的结束动作。
|
|
969
|
-
- Coordination 与 workspace 正交:`single-session` 可以使用本 Skill;`lead-team` 不自动使用。Current workspace 下 Worker 只读;Worker 写入必须绑定本 Skill 创建的独立 workspace。
|
|
970
|
-
- 平台原生 worktree 优先;不可用时使用 Git worktree。
|
|
995
|
+
`operation=finalize` 仅由 Lead/integration owner 调用,并加载 下方 `<dev-worktree-finalize>` 标签。Lead 在独立 parent-candidate checkout 组合最新父分支与 source checkpoint,运行集成检查和适用 E2E,通过后才推进父分支。
|
|
971
996
|
|
|
972
|
-
|
|
997
|
+
本地 candidate checkout/branch 的创建、重建和回收属于已授权 local candidate integration;来源 branch/worktree 的删除仍需要独立 cleanup 授权。push、PR、remote merge、deploy、migration 和生产动作不从本 Skill 继承。
|
|
973
998
|
|
|
974
|
-
|
|
975
|
-
2. implementation owner 完成后返回工作项状态、Evidence/record 路径、`workspace_ref`、不可变 source checkpoint、commit 或 PR 引用和未验证项;Ticket worktree 从 `active` 更新为 `review`。
|
|
976
|
-
3. `terminal_action=integrate` 时 integration owner 自动加载 下方 `<dev-worktree-finalize>` 标签;`retain` 保持 review。一次性原型只评估和清理,不合入生产分支。
|
|
999
|
+
**完成标准**:Ticket `integrated` 时父 HEAD 精确等于记录的 result SHA,并包含 source checkpoint;失败或 stale 时父分支未变化。后续 `removed` 只表示来源 branch/worktree 已清理,不撤销该集成事实。
|
|
977
1000
|
|
|
978
|
-
|
|
1001
|
+
## 4. 移除
|
|
979
1002
|
|
|
980
|
-
|
|
1003
|
+
`operation=remove` 先验证 Ticket 已 `integrated` 或 prototype 已结束、目标 worktree clean、checkpoint 可恢复且删除目标精确。只有明确 cleanup 授权时删除来源 branch/worktree;强制删除需要单独确认。删除后重读 `git worktree list` 与 refs,并只把调用方生命周期状态更新为 `removed`;`base_sha`、source checkpoint、candidate/result、验证、E2E 与 Evidence 字段必须原样保留。
|
|
981
1004
|
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
-
|
|
987
|
-
-
|
|
1005
|
+
**完成标准**:只删除精确授权目标;失败保留现场与恢复命令。
|
|
1006
|
+
|
|
1007
|
+
## 固定规则
|
|
1008
|
+
|
|
1009
|
+
- Agent Team 不决定 worktree;Ticket 切片本身决定来源 worktree;
|
|
1010
|
+
- Ticket E2E 只在 Lead-owned parent-candidate checkout 运行;
|
|
1011
|
+
- 每个 Done Ticket 必须有 source commit 与父分支 result,worktree 状态为 `integrated` 或其清理后终态 `removed`;
|
|
1012
|
+
- candidate 失败保留来源 worktree 修正,父分支不动;
|
|
1013
|
+
- 成功集成不自动清理来源 branch/worktree。
|
|
988
1014
|
|
|
989
1015
|
</dev-worktree>
|
|
990
1016
|
|
|
991
1017
|
<dev-worktree-create>
|
|
992
1018
|
|
|
993
|
-
#
|
|
1019
|
+
# Create Or Restore Worktree
|
|
1020
|
+
|
|
1021
|
+
## Ticket 前置条件
|
|
994
1022
|
|
|
995
|
-
|
|
1023
|
+
- Ticket Ready,项目根是有效 Git repository,父分支和 `base_sha` 可解析;
|
|
1024
|
+
- implementation commit 与 local candidate integration/父分支更新已授权;
|
|
1025
|
+
- workspace、implementation、integration owner 唯一;integration owner 必须为 Lead;
|
|
1026
|
+
- `specdev-worktree/` 已由 Speculo init 加入项目 `.gitignore`;
|
|
1027
|
+
- 目标 branch/worktree 不覆盖现有用户 workspace,路径合同无冲突。
|
|
996
1028
|
|
|
997
|
-
|
|
998
|
-
- 调用方已记录允许的 trigger 及其事实。`parallel-write` 还要求 `specdev/config.json` 中 `git.worktree_for_parallel: true`;一次性原型要求 P-prototype 已取得本次临时 worktree 授权。
|
|
999
|
-
- 调用方已指定 workspace owner、implementation owner、integration owner、父分支、工作项 ID、持久化 owner、`integrate | retain`,并固定 `base_sha`;并行 Ticket 共用同一基线。
|
|
1029
|
+
Prototype 只要求调用方已记录本次临时 branch/worktree 授权、问题、owner、locator 和清理策略;它不写 Ticket worktree 状态。
|
|
1000
1030
|
|
|
1001
|
-
## 创建
|
|
1031
|
+
## 创建 Ticket 来源 worktree
|
|
1002
1032
|
|
|
1003
|
-
1.
|
|
1004
|
-
2.
|
|
1005
|
-
3.
|
|
1006
|
-
4.
|
|
1007
|
-
5.
|
|
1008
|
-
6.
|
|
1009
|
-
7.
|
|
1010
|
-
|
|
1033
|
+
1. 重读父分支 HEAD、工作树、现有 worktrees 与 refs;父 HEAD 与计划基线不一致时由 Lead决定更新 `base_sha` 或阻塞;
|
|
1034
|
+
2. 固定 branch `speculo/<change>/<ticket-id>` 与 locator `specdev-worktree/<ticket-id>`;
|
|
1035
|
+
3. 确认目标 branch/path 不存在,或其实际记录精确匹配当前 Ticket;
|
|
1036
|
+
4. 从 `base_sha` 创建 Git worktree,不复用其他 Ticket/原型目录;
|
|
1037
|
+
5. 在来源 worktree 读取项目 Agent 指令、依赖、构建与路径合同;
|
|
1038
|
+
6. 安装实际需要的依赖,运行最小非 E2E 基线;
|
|
1039
|
+
7. Lead 写入 `specdev/changes/{change}/.status.json`,状态为 `active`。
|
|
1040
|
+
|
|
1041
|
+
初始记录:
|
|
1011
1042
|
|
|
1012
1043
|
```json
|
|
1013
1044
|
{
|
|
1014
1045
|
"ticket_id": "T-01",
|
|
1015
|
-
"owner": "
|
|
1016
|
-
"
|
|
1046
|
+
"owner": "lead",
|
|
1047
|
+
"implementation_owner": "lead-or-dynamic-agent",
|
|
1048
|
+
"integration_owner": "lead",
|
|
1017
1049
|
"provider": "git",
|
|
1018
|
-
"base_sha": "<sha>",
|
|
1050
|
+
"base_sha": "<immutable-sha>",
|
|
1019
1051
|
"parent_branch": "<parent-branch>",
|
|
1020
1052
|
"branch": "speculo/<change>/T-01",
|
|
1021
1053
|
"workspace_ref": "specdev-worktree/T-01",
|
|
1022
|
-
"terminal_action": "integrate",
|
|
1023
1054
|
"source_checkpoint": null,
|
|
1024
1055
|
"integration": {
|
|
1025
1056
|
"status": "pending",
|
|
1026
1057
|
"parent_before_sha": null,
|
|
1027
1058
|
"source_sha": null,
|
|
1059
|
+
"candidate_sha": null,
|
|
1060
|
+
"candidate_branch": null,
|
|
1061
|
+
"candidate_workspace_ref": null,
|
|
1028
1062
|
"result_sha": null,
|
|
1029
1063
|
"method": null,
|
|
1030
1064
|
"conflict_paths": [],
|
|
1031
1065
|
"verification": "pending",
|
|
1032
|
-
"
|
|
1066
|
+
"e2e": {"required": false, "status": "not-required", "evidence": null},
|
|
1067
|
+
"evidence": "specdev/changes/<change>/evidence/T-01.md",
|
|
1033
1068
|
"attempts": 0
|
|
1034
1069
|
},
|
|
1035
1070
|
"status": "active",
|
|
@@ -1037,39 +1072,73 @@ Ticket worktree 状态依次为 `planned → active → review → integrating
|
|
|
1037
1072
|
}
|
|
1038
1073
|
```
|
|
1039
1074
|
|
|
1040
|
-
|
|
1075
|
+
`e2e.required` 与 Ticket/Goal Plan disposition 一致;required 时初始 status 为 `pending`。
|
|
1076
|
+
|
|
1077
|
+
## 恢复
|
|
1078
|
+
|
|
1079
|
+
恢复时核对 repository、branch、locator、`base_sha`、实际 HEAD、dirty 状态和 owner。状态记录与 Git 不一致、branch 被其他 worktree 占用或出现越界修改时停止;Lead 写 blocker,不重建覆盖。
|
|
1041
1080
|
|
|
1042
|
-
|
|
1081
|
+
进入 `review` 前必须由 implementation owner 创建最终 commit;Lead 重读 branch tip、diff 与 `git status`,把精确 SHA 写入 `source_checkpoint`。
|
|
1082
|
+
|
|
1083
|
+
**完成标准**:来源 worktree 可定位且唯一;基线、记录与 Git 一致;source 检查不含 E2E;失败时保留现场。
|
|
1043
1084
|
|
|
1044
1085
|
</dev-worktree-create>
|
|
1045
1086
|
|
|
1046
1087
|
<dev-worktree-finalize>
|
|
1047
1088
|
|
|
1048
|
-
#
|
|
1089
|
+
# Candidate Merge And Parent Integration
|
|
1090
|
+
|
|
1091
|
+
仅由 Lead/integration owner 对状态为 `review` 的 Ticket 调用。
|
|
1092
|
+
|
|
1093
|
+
## 1. 接收 source checkpoint
|
|
1094
|
+
|
|
1095
|
+
1. 核对 Ticket、Goal Plan、Evidence 目标、owner 与本地 integration 授权;
|
|
1096
|
+
2. 验证来源 worktree clean,branch tip 精确等于 `source_checkpoint`,commit 从 `base_sha` 可达;
|
|
1097
|
+
3. 审计实际 diff 未越过 writable/shared owner 合同;
|
|
1098
|
+
4. 确认 source-worktree 必跑非 E2E 检查已执行,且没有把 E2E 自报为通过;
|
|
1099
|
+
5. 重读父分支 checkout clean、HEAD 与 remote/本地约定,记录 `parent_before_sha`。
|
|
1100
|
+
|
|
1101
|
+
失败时保持 `review`/`blocked`,不开始候选合并。
|
|
1102
|
+
|
|
1103
|
+
## 2. 建立 parent-candidate checkout
|
|
1049
1104
|
|
|
1050
|
-
|
|
1105
|
+
1. 使用 branch `speculo/integration/<change>/<ticket-id>` 和 locator `specdev-worktree/.integration/<ticket-id>`,从最新 `parent_before_sha` 建立 Lead-owned integration worktree;
|
|
1106
|
+
2. 如果父 SHA 是 source checkpoint 的祖先,在 candidate checkout 执行 `git merge --ff-only <source_checkpoint>`,`method=fast-forward`;
|
|
1107
|
+
3. 否则执行 `git merge --no-ff --no-commit <source_checkpoint>`;
|
|
1108
|
+
4. 冲突按 下方 `<merge-conflict-protocol>` 标签 处理。需要新产品决定时执行 `git merge --abort`,记录 blocker 并返回来源 worktree;
|
|
1109
|
+
5. 对分叉结果创建一次 Lead-owned candidate merge commit,`method=merge-commit`;
|
|
1110
|
+
6. 记录 candidate branch/locator、`candidate_sha`、`source_sha`、冲突路径与 attempts,worktree 状态改为 `integrating`、integration 状态改为 `candidate`。
|
|
1051
1111
|
|
|
1052
|
-
|
|
1112
|
+
重试前从最新父分支重建 candidate branch/worktree;旧 candidate SHA 保存在 Evidence。候选生命周期的重建/回收包含在 local candidate integration 授权中。
|
|
1053
1113
|
|
|
1054
|
-
|
|
1055
|
-
2. 确认目标 checkout 正位于 `parent_branch`、index 与项目 working tree 干净,并把当前 HEAD 固定为 `parent_before_sha`。目标不干净、父分支不匹配、其他记录已在同一父分支 `integrating` 或 HEAD 在集成期间变化时停止,不覆盖用户工作。
|
|
1056
|
-
3. 将记录原子更新为 `integrating`,设置 `integration.status=running`、`parent_before_sha`、`source_sha` 并递增 `attempts`。中断恢复时先核对记录、Git `MERGE_HEAD` 和当前 HEAD,不重复开始第二次集成。
|
|
1057
|
-
4. 恢复已有 `integrating` 记录时只进入一个分支:HEAD 仍等于 `parent_before_sha` 且没有 `MERGE_HEAD` 时恢复同一次尝试;HEAD 已等于 `source_checkpoint`、没有 `MERGE_HEAD` 且 `parent_before_sha` 可达来源时,将其视为已完成但尚未落状态的 fast-forward;`MERGE_HEAD` 等于 `source_checkpoint` 时恢复未完成 merge。其他 HEAD、来源或 merge 状态漂移一律设为 `blocked`,不修改 Git 现场。
|
|
1058
|
-
5. 若 `parent_before_sha` 是 `source_checkpoint` 的祖先,先在来源 workspace 运行 Ticket 定向验证、受影响回归、项目 typecheck/lint/build 和适用最小 E2E,再从目标 checkout 执行 `git merge --ff-only <source_checkpoint>`。重读目标 HEAD、tree 和 Evidence,确认 HEAD 精确等于 `source_checkpoint` 后,记录 `method=fast-forward`、`result_sha=source_checkpoint`、空 `conflict_paths`、验证命令与结果、`verification=passed`、Evidence 和 `integration.status=passed`,再把 worktree 状态更新为 `integrated`。这是 fast-forward 的终态,不继续执行 merge-commit 步骤。
|
|
1059
|
-
6. 若双方已分叉,从干净目标 checkout 执行 `git merge --no-ff --no-commit <source_checkpoint>`。出现冲突时加载 下方 `<merge-conflict-protocol>` 标签,并将本记录作为持久授权来源;不为 `git add`、继续 merge 或集成提交重复请求确认。
|
|
1060
|
-
7. 在未提交的合并结果上运行 Ticket 定向验证、受影响回归、项目 typecheck/lint/build 和适用最小 E2E。可由既有意图机械修正的失败最多处理 3 轮;不得放宽断言、删除检查或引入未批准行为。
|
|
1061
|
-
8. 验证通过后完成一次集成专用 merge commit,重读 HEAD、parents、tree、diff 和 Evidence,确认父分支为第一 parent、`source_checkpoint` 为第二 parent,记录 `method=merge-commit`、`result_sha`、conflict paths、`verification=passed`、Evidence 与 `integration.status=passed`,再把 worktree 状态更新为 `integrated`。
|
|
1062
|
-
9. 冲突需要新产品/架构/安全/迁移决定、修改越过授权路径、验证无法通过、目标状态漂移或提交 hook 无法安全完成时,执行 `git merge --abort`(仅限本流程从干净目标开始的 merge),设置 worktree 与 integration 为 `blocked`,记录最小失败、已通过行为和恢复条件,并保留来源 worktree。
|
|
1114
|
+
## 3. 在候选父状态验证
|
|
1063
1115
|
|
|
1064
|
-
|
|
1116
|
+
在 candidate checkout 运行:
|
|
1065
1117
|
|
|
1066
|
-
|
|
1118
|
+
- Ticket 受影响集成与回归;
|
|
1119
|
+
- 项目要求的 typecheck/lint/build 或其他父状态检查;
|
|
1120
|
+
- 仅当 Ticket/Goal Plan `e2e.required=true` 时运行对应 E2E。
|
|
1067
1121
|
|
|
1068
|
-
|
|
1069
|
-
2. Git provider 从 project root 解析 `specdev-worktree/<work-item-id>`,重验无路径逃逸且与 `git worktree list --porcelain` 的记录一致,再从主工作树移除;native/external 通过对应 provider 管理入口移除。
|
|
1070
|
-
3. 确认 worktree 不再注册且工作项目录不存在后删除对应分支。Ticket 将状态更新为 `removed`;原型把 `cleanup_status` 更新为 `clean`。保留项目根 `specdev-worktree/` 统一目录及 `.gitignore` 条目。
|
|
1122
|
+
每条命令记录运行环境 `parent-candidate`、退出码与摘要。E2E required 未运行或失败时 integration `verification=failed`、`status=failed`;父分支保持 `parent_before_sha`。机械修正次数不得超过 Goal Plan 快照的 `integration_attempt_limit`;不得放宽断言、删除检查或发明行为。
|
|
1071
1123
|
|
|
1072
|
-
|
|
1124
|
+
## 4. 推进父分支
|
|
1125
|
+
|
|
1126
|
+
全部 required 检查通过后:
|
|
1127
|
+
|
|
1128
|
+
1. 重读父分支 HEAD;不等于 `parent_before_sha` 时将 candidate 标记 `stale`,不推进父分支并从步骤 2 重建;
|
|
1129
|
+
2. 在父分支 checkout 执行 `git merge --ff-only <candidate_sha>`;候选 merge commit 本身已以父 SHA 为第一祖先,因此不再创建第二个 merge commit;
|
|
1130
|
+
3. 重读父 HEAD、tree 与 ancestor 关系,确认 HEAD 精确等于 candidate SHA 且包含 source checkpoint;
|
|
1131
|
+
4. 写入 `result_sha=candidate_sha`、`verification=passed`、E2E 最终状态和 Evidence;
|
|
1132
|
+
5. integration/status 改为 `passed`/`integrated`,再由 Lead 标记 Ticket Done。
|
|
1133
|
+
|
|
1134
|
+
## 5. 失败、清理与恢复
|
|
1135
|
+
|
|
1136
|
+
- candidate 检查失败:父分支不动,Ticket 回 `in_progress` 或 `blocked`,来源 worktree 保留;
|
|
1137
|
+
- 父 HEAD 漂移:旧 candidate 记 `stale`,完整重建并重跑;
|
|
1138
|
+
- 成功后可按 candidate integration 授权回收 transient integration worktree/branch;来源 branch/worktree 不自动清理。获得独立 cleanup 授权并清理后,只将生命周期状态改为 `removed`,完整保留已经通过的集成与 E2E 证据;
|
|
1139
|
+
- push、PR、remote merge、deploy、migration 和生产动作仍需各自授权。
|
|
1140
|
+
|
|
1141
|
+
**完成标准**:passed 时父 HEAD=result/candidate SHA 且包含 source commit;failed/stale 时父 HEAD 仍为开始该轮记录的父状态或更新后的外部事实,没有本轮候选污染。
|
|
1073
1142
|
|
|
1074
1143
|
</dev-worktree-finalize>
|
|
1075
1144
|
|
|
@@ -1077,25 +1146,25 @@ PR、`terminal_action=retain` 或暂缓集成时保留 worktree。成功集成
|
|
|
1077
1146
|
|
|
1078
1147
|
# Merge / Rebase Conflict Protocol
|
|
1079
1148
|
|
|
1080
|
-
只在 `git status` 证明仓库正处于 merge
|
|
1149
|
+
只在 `git status` 证明仓库正处于 merge/rebase 冲突时加载。
|
|
1081
1150
|
|
|
1082
1151
|
## 流程
|
|
1083
1152
|
|
|
1084
|
-
1. 读取 Git
|
|
1085
|
-
2.
|
|
1086
|
-
3.
|
|
1087
|
-
4.
|
|
1088
|
-
5.
|
|
1089
|
-
6.
|
|
1090
|
-
7. 重读 Git 状态、parents
|
|
1153
|
+
1. 读取 Git 状态、操作类型、冲突路径、base/ours/theirs SHA、Ticket/Evidence 与匹配的 candidate integration 记录。
|
|
1154
|
+
2. 从 commit、source、Spec、Ticket、ADR、测试和调用者追溯双方意图;信息不足时不猜产品行为。
|
|
1155
|
+
3. 对每个 hunk 写出双方意图、共同约束和唯一可推导结果;需要新行为或上层决定时停止并登记 deviation。
|
|
1156
|
+
4. 在授权路径内解决文本,运行受影响的非 E2E 检查;candidate checkout 中按 finalize 合同运行父状态检查/E2E。
|
|
1157
|
+
5. 匹配的 local candidate integration 授权包含 `git add`、candidate merge commit、必要的 `git merge --abort` 和 transient candidate checkout/branch 生命周期;不扩展到来源 branch/worktree cleanup 或远端动作。
|
|
1158
|
+
6. 需要改变 Spec/ADR、安全/迁移决定、越过 owner 或无法同时保持既有意图时,在 Lead-created candidate 中执行 `git merge --abort`,记录 blocker 并保留来源 worktree;未知普通冲突现场不擅自 abort。
|
|
1159
|
+
7. 重读 Git 状态、parents 与 diff,确认无 marker、无未声明路径、双方合同及验证仍成立。
|
|
1091
1160
|
|
|
1092
1161
|
## 完成标准
|
|
1093
1162
|
|
|
1094
|
-
- 每个 hunk
|
|
1163
|
+
- 每个 hunk 可追溯到既有意图;
|
|
1095
1164
|
- 新产品决定没有藏在冲突解决中;
|
|
1096
|
-
-
|
|
1097
|
-
- Git
|
|
1098
|
-
-
|
|
1165
|
+
- 验证记录命令、运行环境、退出码和摘要;
|
|
1166
|
+
- Git 副作用来自明确的 candidate integration 或其他逐动作授权;
|
|
1167
|
+
- 完成/暂停可以从 Git、change status 和 Evidence 恢复。
|
|
1099
1168
|
|
|
1100
1169
|
</merge-conflict-protocol>
|
|
1101
1170
|
|
|
@@ -1103,16 +1172,15 @@ PR、`terminal_action=retain` 或暂缓集成时保留 worktree。成功集成
|
|
|
1103
1172
|
|
|
1104
1173
|
```json
|
|
1105
1174
|
{
|
|
1106
|
-
"schema_version":
|
|
1175
|
+
"schema_version": 5,
|
|
1107
1176
|
"interaction_language": "zh-CN",
|
|
1108
1177
|
"artifact_language": "zh-CN",
|
|
1109
1178
|
"git": {
|
|
1110
|
-
"
|
|
1111
|
-
"default_branch": null,
|
|
1112
|
-
"worktree_for_parallel": true
|
|
1179
|
+
"default_branch": null
|
|
1113
1180
|
},
|
|
1114
1181
|
"execution": {
|
|
1115
|
-
"
|
|
1182
|
+
"max_implementation_agents": 3,
|
|
1183
|
+
"max_integration_attempts": 3,
|
|
1116
1184
|
"deep_ticket_human_approval": true,
|
|
1117
1185
|
"shared_path_owner": "explicit"
|
|
1118
1186
|
},
|
|
@@ -1125,7 +1193,9 @@ PR、`terminal_action=retain` 或暂缓集成时保留 worktree。成功集成
|
|
|
1125
1193
|
"planning": {
|
|
1126
1194
|
"default_depth": "standard",
|
|
1127
1195
|
"require_ready_gate": true,
|
|
1128
|
-
"require_evidence": true
|
|
1196
|
+
"require_evidence": true,
|
|
1197
|
+
"ui_prototype_default_variants": 3,
|
|
1198
|
+
"ui_prototype_max_variants": 5
|
|
1129
1199
|
}
|
|
1130
1200
|
}
|
|
1131
1201
|
```
|
|
@@ -1137,33 +1207,32 @@ PR、`terminal_action=retain` 或暂缓集成时保留 worktree。成功集成
|
|
|
1137
1207
|
```json
|
|
1138
1208
|
{
|
|
1139
1209
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
1140
|
-
"$id": "urn:speculo:specdev:config:
|
|
1210
|
+
"$id": "urn:speculo:specdev:config:v5",
|
|
1141
1211
|
"title": "SpecDev Configuration",
|
|
1142
1212
|
"type": "object",
|
|
1143
1213
|
"required": ["schema_version", "interaction_language", "artifact_language", "git", "execution", "verification", "planning"],
|
|
1144
1214
|
"properties": {
|
|
1145
|
-
"schema_version": {"const":
|
|
1215
|
+
"schema_version": {"const": 5},
|
|
1146
1216
|
"interaction_language": {"type": "string", "minLength": 1},
|
|
1147
1217
|
"artifact_language": {"type": "string", "minLength": 1},
|
|
1148
1218
|
"git": {
|
|
1149
1219
|
"type": "object",
|
|
1150
|
-
"required": ["
|
|
1220
|
+
"required": ["default_branch"],
|
|
1151
1221
|
"properties": {
|
|
1152
|
-
"
|
|
1153
|
-
"default_branch": {"type": ["string", "null"]},
|
|
1154
|
-
"worktree_for_parallel": {"type": "boolean"}
|
|
1222
|
+
"default_branch": {"type": ["string", "null"]}
|
|
1155
1223
|
},
|
|
1156
|
-
"additionalProperties":
|
|
1224
|
+
"additionalProperties": false
|
|
1157
1225
|
},
|
|
1158
1226
|
"execution": {
|
|
1159
1227
|
"type": "object",
|
|
1160
|
-
"required": ["
|
|
1228
|
+
"required": ["max_implementation_agents", "max_integration_attempts", "deep_ticket_human_approval", "shared_path_owner"],
|
|
1161
1229
|
"properties": {
|
|
1162
|
-
"
|
|
1230
|
+
"max_implementation_agents": {"type": "integer", "minimum": 1},
|
|
1231
|
+
"max_integration_attempts": {"type": "integer", "minimum": 1},
|
|
1163
1232
|
"deep_ticket_human_approval": {"type": "boolean"},
|
|
1164
1233
|
"shared_path_owner": {"type": "string", "minLength": 1}
|
|
1165
1234
|
},
|
|
1166
|
-
"additionalProperties":
|
|
1235
|
+
"additionalProperties": false
|
|
1167
1236
|
},
|
|
1168
1237
|
"verification": {
|
|
1169
1238
|
"type": "object",
|
|
@@ -1178,16 +1247,21 @@ PR、`terminal_action=retain` 或暂缓集成时保留 worktree。成功集成
|
|
|
1178
1247
|
},
|
|
1179
1248
|
"planning": {
|
|
1180
1249
|
"type": "object",
|
|
1181
|
-
"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"],
|
|
1182
1251
|
"properties": {
|
|
1183
1252
|
"default_depth": {"enum": ["lite", "standard", "deep"]},
|
|
1184
1253
|
"require_ready_gate": {"type": "boolean"},
|
|
1185
|
-
"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}
|
|
1186
1257
|
},
|
|
1187
1258
|
"additionalProperties": true
|
|
1188
1259
|
}
|
|
1189
1260
|
},
|
|
1190
|
-
"
|
|
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
|
+
}],
|
|
1264
|
+
"additionalProperties": false
|
|
1191
1265
|
}
|
|
1192
1266
|
```
|
|
1193
1267
|
|
|
@@ -1197,7 +1271,7 @@ PR、`terminal_action=retain` 或暂缓集成时保留 worktree。成功集成
|
|
|
1197
1271
|
|
|
1198
1272
|
```json
|
|
1199
1273
|
{
|
|
1200
|
-
"schema_version":
|
|
1274
|
+
"schema_version": 5,
|
|
1201
1275
|
"workflow": "specdev",
|
|
1202
1276
|
"active": [],
|
|
1203
1277
|
"archived": []
|
|
@@ -1211,83 +1285,27 @@ PR、`terminal_action=retain` 或暂缓集成时保留 worktree。成功集成
|
|
|
1211
1285
|
```json
|
|
1212
1286
|
{
|
|
1213
1287
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
1214
|
-
"$id": "urn:speculo:specdev:status:
|
|
1288
|
+
"$id": "urn:speculo:specdev:status:v5",
|
|
1215
1289
|
"title": "SpecDev Global Status",
|
|
1216
1290
|
"type": "object",
|
|
1217
|
-
"required": [
|
|
1218
|
-
"schema_version",
|
|
1219
|
-
"workflow",
|
|
1220
|
-
"active",
|
|
1221
|
-
"archived"
|
|
1222
|
-
],
|
|
1291
|
+
"required": ["schema_version", "workflow", "active", "archived"],
|
|
1223
1292
|
"properties": {
|
|
1224
|
-
"schema_version": {
|
|
1225
|
-
|
|
1226
|
-
},
|
|
1227
|
-
"workflow": {
|
|
1228
|
-
"const": "specdev"
|
|
1229
|
-
},
|
|
1293
|
+
"schema_version": {"const": 5},
|
|
1294
|
+
"workflow": {"const": "specdev"},
|
|
1230
1295
|
"active": {
|
|
1231
1296
|
"type": "array",
|
|
1232
1297
|
"items": {
|
|
1233
1298
|
"type": "object",
|
|
1234
|
-
"required": [
|
|
1235
|
-
"change",
|
|
1236
|
-
"current_work",
|
|
1237
|
-
"works_run"
|
|
1238
|
-
],
|
|
1299
|
+
"required": ["change"],
|
|
1239
1300
|
"properties": {
|
|
1240
1301
|
"change": {
|
|
1241
1302
|
"type": "string",
|
|
1242
1303
|
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*$"
|
|
1243
|
-
},
|
|
1244
|
-
"current_work": {
|
|
1245
|
-
"type": [
|
|
1246
|
-
"string",
|
|
1247
|
-
"null"
|
|
1248
|
-
],
|
|
1249
|
-
"pattern": "^specdev/"
|
|
1250
|
-
},
|
|
1251
|
-
"works_run": {
|
|
1252
|
-
"type": "array",
|
|
1253
|
-
"items": {
|
|
1254
|
-
"type": "string",
|
|
1255
|
-
"pattern": "^specdev/"
|
|
1256
|
-
},
|
|
1257
|
-
"uniqueItems": true
|
|
1258
|
-
},
|
|
1259
|
-
"claimed_investigations": {
|
|
1260
|
-
"type": "array",
|
|
1261
|
-
"items": {
|
|
1262
|
-
"type": "object",
|
|
1263
|
-
"required": [
|
|
1264
|
-
"id",
|
|
1265
|
-
"owner",
|
|
1266
|
-
"claimed_at"
|
|
1267
|
-
],
|
|
1268
|
-
"properties": {
|
|
1269
|
-
"id": {
|
|
1270
|
-
"type": "string"
|
|
1271
|
-
},
|
|
1272
|
-
"owner": {
|
|
1273
|
-
"type": "string"
|
|
1274
|
-
},
|
|
1275
|
-
"session": {
|
|
1276
|
-
"type": [
|
|
1277
|
-
"string",
|
|
1278
|
-
"null"
|
|
1279
|
-
]
|
|
1280
|
-
},
|
|
1281
|
-
"claimed_at": {
|
|
1282
|
-
"type": "string"
|
|
1283
|
-
}
|
|
1284
|
-
},
|
|
1285
|
-
"additionalProperties": false
|
|
1286
|
-
}
|
|
1287
1304
|
}
|
|
1288
1305
|
},
|
|
1289
1306
|
"additionalProperties": false
|
|
1290
|
-
}
|
|
1307
|
+
},
|
|
1308
|
+
"uniqueItems": true
|
|
1291
1309
|
},
|
|
1292
1310
|
"archived": {
|
|
1293
1311
|
"type": "array",
|
|
@@ -1308,11 +1326,24 @@ PR、`terminal_action=retain` 或暂缓集成时保留 worktree。成功集成
|
|
|
1308
1326
|
|
|
1309
1327
|
```json
|
|
1310
1328
|
{
|
|
1311
|
-
"schema_version":
|
|
1329
|
+
"schema_version": 6,
|
|
1312
1330
|
"artifact": "change-status",
|
|
1313
1331
|
"change": "<YYYY-MM-DD-topic>",
|
|
1314
1332
|
"change_status": "active",
|
|
1315
1333
|
"current_work": null,
|
|
1334
|
+
"works_run": [],
|
|
1335
|
+
"claimed_investigations": [],
|
|
1336
|
+
"execution_authorization": {
|
|
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"},
|
|
1339
|
+
"source_cleanup": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Source worktree and branch cleanup"}
|
|
1340
|
+
},
|
|
1341
|
+
"leadership": {
|
|
1342
|
+
"current": "<owner-or-session-locator>",
|
|
1343
|
+
"epoch": 1,
|
|
1344
|
+
"assigned_at": "<ISO-8601>",
|
|
1345
|
+
"history": []
|
|
1346
|
+
},
|
|
1316
1347
|
"created_at": "<ISO-8601>",
|
|
1317
1348
|
"updated_at": "<ISO-8601>",
|
|
1318
1349
|
"completed_at": null,
|
|
@@ -1331,394 +1362,184 @@ PR、`terminal_action=retain` 或暂缓集成时保留 worktree。成功集成
|
|
|
1331
1362
|
```json
|
|
1332
1363
|
{
|
|
1333
1364
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
1334
|
-
"$id": "urn:speculo:specdev:change-status:
|
|
1365
|
+
"$id": "urn:speculo:specdev:change-status:v6",
|
|
1335
1366
|
"title": "SpecDev Change Status",
|
|
1336
1367
|
"type": "object",
|
|
1337
1368
|
"required": [
|
|
1338
|
-
"schema_version",
|
|
1339
|
-
"
|
|
1340
|
-
"
|
|
1341
|
-
"change_status",
|
|
1342
|
-
"current_work",
|
|
1343
|
-
"created_at",
|
|
1344
|
-
"updated_at",
|
|
1345
|
-
"completed_at",
|
|
1346
|
-
"archived",
|
|
1347
|
-
"archive_path",
|
|
1348
|
-
"blockers",
|
|
1349
|
-
"deviations"
|
|
1369
|
+
"schema_version", "artifact", "change", "change_status", "current_work", "works_run",
|
|
1370
|
+
"claimed_investigations", "execution_authorization", "leadership", "created_at", "updated_at",
|
|
1371
|
+
"completed_at", "archived", "archive_path", "blockers", "deviations", "worktrees"
|
|
1350
1372
|
],
|
|
1351
1373
|
"properties": {
|
|
1352
|
-
"schema_version": {
|
|
1353
|
-
|
|
1354
|
-
},
|
|
1355
|
-
"
|
|
1356
|
-
|
|
1357
|
-
},
|
|
1358
|
-
"
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
},
|
|
1362
|
-
"
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1374
|
+
"schema_version": {"const": 6},
|
|
1375
|
+
"artifact": {"const": "change-status"},
|
|
1376
|
+
"change": {"type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*$"},
|
|
1377
|
+
"change_status": {"enum": ["active", "blocked", "completed", "archived"]},
|
|
1378
|
+
"current_work": {"type": ["string", "null"], "pattern": "^specdev/"},
|
|
1379
|
+
"works_run": {"type": "array", "items": {"type": "string", "pattern": "^specdev/"}, "uniqueItems": true},
|
|
1380
|
+
"claimed_investigations": {"type": "array", "items": {"$ref": "#/$defs/claim"}},
|
|
1381
|
+
"execution_authorization": {"$ref": "#/$defs/authorization"},
|
|
1382
|
+
"leadership": {"$ref": "#/$defs/leadership"},
|
|
1383
|
+
"created_at": {"type": "string", "minLength": 1},
|
|
1384
|
+
"updated_at": {"type": "string", "minLength": 1},
|
|
1385
|
+
"completed_at": {"type": ["string", "null"]},
|
|
1386
|
+
"archived": {"type": "boolean"},
|
|
1387
|
+
"archive_path": {"anyOf": [{"type": "null"}, {"type": "string", "pattern": "^specdev/archive/[0-9]{4}-[0-9]{2}/.+/$"}]},
|
|
1388
|
+
"blockers": {"type": "array", "items": {"type": "string"}},
|
|
1389
|
+
"deviations": {"type": "array", "items": {"type": "string"}},
|
|
1390
|
+
"worktrees": {"type": "array", "items": {"$ref": "#/$defs/worktree"}}
|
|
1391
|
+
},
|
|
1392
|
+
"$defs": {
|
|
1393
|
+
"claim": {
|
|
1394
|
+
"type": "object",
|
|
1395
|
+
"required": ["id", "owner", "session", "claimed_at"],
|
|
1396
|
+
"properties": {
|
|
1397
|
+
"id": {"type": "string", "minLength": 1},
|
|
1398
|
+
"owner": {"type": "string", "minLength": 1},
|
|
1399
|
+
"session": {"type": ["string", "null"]},
|
|
1400
|
+
"claimed_at": {"type": "string", "minLength": 1}
|
|
1401
|
+
},
|
|
1402
|
+
"additionalProperties": false
|
|
1369
1403
|
},
|
|
1370
|
-
"
|
|
1371
|
-
"type":
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1404
|
+
"authorization-entry": {
|
|
1405
|
+
"type": "object",
|
|
1406
|
+
"required": ["status", "source", "granted_at", "scope"],
|
|
1407
|
+
"properties": {
|
|
1408
|
+
"status": {"enum": ["authorized", "not-authorized", "revoked"]},
|
|
1409
|
+
"source": {"type": ["string", "null"]},
|
|
1410
|
+
"granted_at": {"type": ["string", "null"]},
|
|
1411
|
+
"scope": {"type": "string", "minLength": 1}
|
|
1412
|
+
},
|
|
1413
|
+
"allOf": [{
|
|
1414
|
+
"if": {"properties": {"status": {"const": "authorized"}}, "required": ["status"]},
|
|
1415
|
+
"then": {"properties": {"source": {"type": "string", "minLength": 1}, "granted_at": {"type": "string", "minLength": 1}}}
|
|
1416
|
+
}],
|
|
1417
|
+
"additionalProperties": false
|
|
1375
1418
|
},
|
|
1376
|
-
"
|
|
1377
|
-
"type": "
|
|
1378
|
-
"
|
|
1419
|
+
"authorization": {
|
|
1420
|
+
"type": "object",
|
|
1421
|
+
"required": ["implementation_commit", "local_candidate_integration", "source_cleanup"],
|
|
1422
|
+
"properties": {
|
|
1423
|
+
"implementation_commit": {"$ref": "#/$defs/authorization-entry"},
|
|
1424
|
+
"local_candidate_integration": {"$ref": "#/$defs/authorization-entry"},
|
|
1425
|
+
"source_cleanup": {"$ref": "#/$defs/authorization-entry"}
|
|
1426
|
+
},
|
|
1427
|
+
"additionalProperties": false
|
|
1379
1428
|
},
|
|
1380
|
-
"
|
|
1381
|
-
"type": "
|
|
1382
|
-
"
|
|
1429
|
+
"leadership-history": {
|
|
1430
|
+
"type": "object",
|
|
1431
|
+
"required": ["owner", "epoch", "assigned_at", "ended_at"],
|
|
1432
|
+
"properties": {
|
|
1433
|
+
"owner": {"type": "string", "minLength": 1},
|
|
1434
|
+
"epoch": {"type": "integer", "minimum": 1},
|
|
1435
|
+
"assigned_at": {"type": "string", "minLength": 1},
|
|
1436
|
+
"ended_at": {"type": "string", "minLength": 1}
|
|
1437
|
+
},
|
|
1438
|
+
"additionalProperties": false
|
|
1383
1439
|
},
|
|
1384
|
-
"
|
|
1385
|
-
"type":
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1440
|
+
"leadership": {
|
|
1441
|
+
"type": "object",
|
|
1442
|
+
"required": ["current", "epoch", "assigned_at", "history"],
|
|
1443
|
+
"properties": {
|
|
1444
|
+
"current": {"type": "string", "minLength": 1},
|
|
1445
|
+
"epoch": {"type": "integer", "minimum": 1},
|
|
1446
|
+
"assigned_at": {"type": "string", "minLength": 1},
|
|
1447
|
+
"history": {"type": "array", "items": {"$ref": "#/$defs/leadership-history"}}
|
|
1448
|
+
},
|
|
1449
|
+
"additionalProperties": false
|
|
1389
1450
|
},
|
|
1390
|
-
"
|
|
1391
|
-
"type": "
|
|
1451
|
+
"full-suite": {
|
|
1452
|
+
"type": "object",
|
|
1453
|
+
"required": ["required", "status", "reason", "evidence"],
|
|
1454
|
+
"properties": {
|
|
1455
|
+
"required": {"type": "boolean"},
|
|
1456
|
+
"status": {"enum": ["not-required", "pending", "passed", "failed"]},
|
|
1457
|
+
"reason": {"type": ["string", "null"]},
|
|
1458
|
+
"evidence": {"type": ["string", "null"]}
|
|
1459
|
+
},
|
|
1460
|
+
"allOf": [{
|
|
1461
|
+
"if": {"properties": {"required": {"const": false}}, "required": ["required"]},
|
|
1462
|
+
"then": {"properties": {"status": {"const": "not-required"}, "reason": {"type": "string", "minLength": 1}}}
|
|
1463
|
+
}],
|
|
1464
|
+
"additionalProperties": false
|
|
1392
1465
|
},
|
|
1393
|
-
"
|
|
1394
|
-
"
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
},
|
|
1466
|
+
"worktree": {
|
|
1467
|
+
"type": "object",
|
|
1468
|
+
"required": ["ticket_id", "owner", "implementation_owner", "integration_owner", "provider", "base_sha", "parent_branch", "branch", "workspace_ref", "source_checkpoint", "integration", "status", "updated_at"],
|
|
1469
|
+
"properties": {
|
|
1470
|
+
"ticket_id": {"type": "string", "pattern": "^T-[0-9]{2,}$"},
|
|
1471
|
+
"owner": {"type": "string", "minLength": 1},
|
|
1472
|
+
"implementation_owner": {"type": "string", "minLength": 1},
|
|
1473
|
+
"integration_owner": {"type": "string", "minLength": 1},
|
|
1474
|
+
"provider": {"const": "git"},
|
|
1475
|
+
"base_sha": {"type": "string", "minLength": 1},
|
|
1476
|
+
"parent_branch": {"type": "string", "minLength": 1},
|
|
1477
|
+
"branch": {"type": "string", "minLength": 1},
|
|
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,})$"},
|
|
1479
|
+
"source_checkpoint": {"type": ["string", "null"]},
|
|
1480
|
+
"integration": {"$ref": "#/$defs/integration"},
|
|
1481
|
+
"status": {"enum": ["planned", "active", "review", "integrating", "integrated", "removed", "blocked"]},
|
|
1482
|
+
"updated_at": {"type": "string", "minLength": 1}
|
|
1483
|
+
},
|
|
1484
|
+
"allOf": [
|
|
1398
1485
|
{
|
|
1399
|
-
"
|
|
1400
|
-
"
|
|
1401
|
-
}
|
|
1402
|
-
]
|
|
1403
|
-
},
|
|
1404
|
-
"blockers": {
|
|
1405
|
-
"type": "array",
|
|
1406
|
-
"items": {
|
|
1407
|
-
"type": "string"
|
|
1408
|
-
}
|
|
1409
|
-
},
|
|
1410
|
-
"deviations": {
|
|
1411
|
-
"type": "array",
|
|
1412
|
-
"items": {
|
|
1413
|
-
"type": "string"
|
|
1414
|
-
}
|
|
1415
|
-
},
|
|
1416
|
-
"worktrees": {
|
|
1417
|
-
"type": "array",
|
|
1418
|
-
"items": {
|
|
1419
|
-
"type": "object",
|
|
1420
|
-
"required": [
|
|
1421
|
-
"ticket_id",
|
|
1422
|
-
"owner",
|
|
1423
|
-
"provider",
|
|
1424
|
-
"base_sha",
|
|
1425
|
-
"branch",
|
|
1426
|
-
"workspace_ref",
|
|
1427
|
-
"status",
|
|
1428
|
-
"updated_at"
|
|
1429
|
-
],
|
|
1430
|
-
"properties": {
|
|
1431
|
-
"ticket_id": {
|
|
1432
|
-
"type": "string",
|
|
1433
|
-
"pattern": "^T-[0-9]{2,}$"
|
|
1434
|
-
},
|
|
1435
|
-
"owner": {
|
|
1436
|
-
"type": "string",
|
|
1437
|
-
"minLength": 1
|
|
1438
|
-
},
|
|
1439
|
-
"integration_owner": {
|
|
1440
|
-
"type": "string",
|
|
1441
|
-
"minLength": 1
|
|
1442
|
-
},
|
|
1443
|
-
"provider": {
|
|
1444
|
-
"enum": [
|
|
1445
|
-
"native",
|
|
1446
|
-
"git",
|
|
1447
|
-
"external"
|
|
1448
|
-
]
|
|
1449
|
-
},
|
|
1450
|
-
"base_sha": {
|
|
1451
|
-
"type": "string",
|
|
1452
|
-
"minLength": 1
|
|
1453
|
-
},
|
|
1454
|
-
"parent_branch": {
|
|
1455
|
-
"type": "string",
|
|
1456
|
-
"minLength": 1
|
|
1457
|
-
},
|
|
1458
|
-
"branch": {
|
|
1459
|
-
"type": "string",
|
|
1460
|
-
"minLength": 1
|
|
1461
|
-
},
|
|
1462
|
-
"workspace_ref": {
|
|
1463
|
-
"type": "string",
|
|
1464
|
-
"minLength": 1,
|
|
1465
|
-
"pattern": "^(?!/)(?![A-Za-z]:[\\\\/]).+"
|
|
1466
|
-
},
|
|
1467
|
-
"terminal_action": {
|
|
1468
|
-
"enum": [
|
|
1469
|
-
"integrate",
|
|
1470
|
-
"retain"
|
|
1471
|
-
]
|
|
1472
|
-
},
|
|
1473
|
-
"source_checkpoint": {
|
|
1474
|
-
"type": [
|
|
1475
|
-
"string",
|
|
1476
|
-
"null"
|
|
1477
|
-
]
|
|
1478
|
-
},
|
|
1479
|
-
"integration": {
|
|
1480
|
-
"type": "object",
|
|
1481
|
-
"required": [
|
|
1482
|
-
"status",
|
|
1483
|
-
"parent_before_sha",
|
|
1484
|
-
"source_sha",
|
|
1485
|
-
"result_sha",
|
|
1486
|
-
"method",
|
|
1487
|
-
"conflict_paths",
|
|
1488
|
-
"verification",
|
|
1489
|
-
"evidence",
|
|
1490
|
-
"attempts"
|
|
1491
|
-
],
|
|
1486
|
+
"if": {"properties": {"workspace_ref": {"const": "current"}}, "required": ["workspace_ref"]},
|
|
1487
|
+
"then": {
|
|
1492
1488
|
"properties": {
|
|
1493
|
-
"
|
|
1494
|
-
"
|
|
1495
|
-
"pending",
|
|
1496
|
-
"running",
|
|
1497
|
-
"passed",
|
|
1498
|
-
"blocked"
|
|
1499
|
-
]
|
|
1500
|
-
},
|
|
1501
|
-
"parent_before_sha": {
|
|
1502
|
-
"type": ["string", "null"]
|
|
1503
|
-
},
|
|
1504
|
-
"source_sha": {
|
|
1505
|
-
"type": ["string", "null"]
|
|
1506
|
-
},
|
|
1507
|
-
"result_sha": {
|
|
1508
|
-
"type": ["string", "null"]
|
|
1509
|
-
},
|
|
1510
|
-
"method": {
|
|
1511
|
-
"enum": [null, "fast-forward", "merge-commit"]
|
|
1512
|
-
},
|
|
1513
|
-
"conflict_paths": {
|
|
1514
|
-
"type": "array",
|
|
1515
|
-
"items": {"type": "string"}
|
|
1516
|
-
},
|
|
1517
|
-
"verification": {
|
|
1518
|
-
"enum": ["pending", "passed", "failed"]
|
|
1519
|
-
},
|
|
1520
|
-
"evidence": {
|
|
1521
|
-
"type": "string",
|
|
1522
|
-
"pattern": "^\\{roots\\.state\\}/specdev/changes/[^<]+/evidence/T-[0-9]{2,}\\.md$"
|
|
1523
|
-
},
|
|
1524
|
-
"attempts": {
|
|
1525
|
-
"type": "integer",
|
|
1526
|
-
"minimum": 0
|
|
1527
|
-
}
|
|
1528
|
-
},
|
|
1529
|
-
"additionalProperties": true
|
|
1530
|
-
},
|
|
1531
|
-
"status": {
|
|
1532
|
-
"enum": [
|
|
1533
|
-
"planned",
|
|
1534
|
-
"active",
|
|
1535
|
-
"review",
|
|
1536
|
-
"integrating",
|
|
1537
|
-
"integrated",
|
|
1538
|
-
"removed",
|
|
1539
|
-
"blocked"
|
|
1540
|
-
]
|
|
1541
|
-
},
|
|
1542
|
-
"updated_at": {
|
|
1543
|
-
"type": "string",
|
|
1544
|
-
"minLength": 1
|
|
1545
|
-
}
|
|
1546
|
-
},
|
|
1547
|
-
"dependentRequired": {
|
|
1548
|
-
"terminal_action": [
|
|
1549
|
-
"integration_owner",
|
|
1550
|
-
"parent_branch",
|
|
1551
|
-
"source_checkpoint",
|
|
1552
|
-
"integration"
|
|
1553
|
-
]
|
|
1554
|
-
},
|
|
1555
|
-
"allOf": [
|
|
1556
|
-
{
|
|
1557
|
-
"if": {
|
|
1558
|
-
"properties": {
|
|
1559
|
-
"status": {"const": "integrating"}
|
|
1560
|
-
},
|
|
1561
|
-
"required": ["status"]
|
|
1562
|
-
},
|
|
1563
|
-
"then": {
|
|
1564
|
-
"required": [
|
|
1565
|
-
"terminal_action",
|
|
1566
|
-
"integration_owner",
|
|
1567
|
-
"parent_branch",
|
|
1568
|
-
"source_checkpoint",
|
|
1569
|
-
"integration"
|
|
1570
|
-
],
|
|
1571
|
-
"properties": {
|
|
1572
|
-
"terminal_action": {"const": "integrate"}
|
|
1573
|
-
}
|
|
1574
|
-
}
|
|
1575
|
-
},
|
|
1576
|
-
{
|
|
1577
|
-
"if": {
|
|
1578
|
-
"properties": {
|
|
1579
|
-
"status": {"enum": ["integrating", "integrated"]},
|
|
1580
|
-
"terminal_action": {"const": "integrate"}
|
|
1581
|
-
},
|
|
1582
|
-
"required": ["status", "terminal_action"]
|
|
1583
|
-
},
|
|
1584
|
-
"then": {
|
|
1585
|
-
"properties": {
|
|
1586
|
-
"source_checkpoint": {"type": "string", "minLength": 1},
|
|
1587
|
-
"integration": {
|
|
1489
|
+
"integration": {
|
|
1490
|
+
"allOf": [{
|
|
1588
1491
|
"properties": {
|
|
1589
|
-
"
|
|
1590
|
-
"
|
|
1591
|
-
"
|
|
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"]}
|
|
1592
1497
|
}
|
|
1593
|
-
}
|
|
1498
|
+
}]
|
|
1594
1499
|
}
|
|
1595
1500
|
}
|
|
1596
1501
|
},
|
|
1597
|
-
{
|
|
1598
|
-
"
|
|
1599
|
-
"
|
|
1600
|
-
"
|
|
1601
|
-
"terminal_action": {"const": "integrate"}
|
|
1602
|
-
},
|
|
1603
|
-
"required": ["status", "terminal_action"]
|
|
1604
|
-
},
|
|
1605
|
-
"then": {
|
|
1606
|
-
"properties": {
|
|
1607
|
-
"integration": {
|
|
1608
|
-
"properties": {
|
|
1609
|
-
"status": {"const": "running"}
|
|
1610
|
-
}
|
|
1611
|
-
}
|
|
1612
|
-
}
|
|
1613
|
-
}
|
|
1614
|
-
},
|
|
1615
|
-
{
|
|
1616
|
-
"if": {
|
|
1617
|
-
"properties": {
|
|
1618
|
-
"status": {"const": "integrated"},
|
|
1619
|
-
"terminal_action": {"const": "integrate"}
|
|
1620
|
-
},
|
|
1621
|
-
"required": ["status", "terminal_action"]
|
|
1622
|
-
},
|
|
1623
|
-
"then": {
|
|
1624
|
-
"properties": {
|
|
1625
|
-
"integration": {
|
|
1626
|
-
"properties": {
|
|
1627
|
-
"status": {"const": "passed"},
|
|
1628
|
-
"result_sha": {"type": "string", "minLength": 1},
|
|
1629
|
-
"method": {"enum": ["fast-forward", "merge-commit"]},
|
|
1630
|
-
"verification": {"const": "passed"}
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
}
|
|
1634
|
-
}
|
|
1635
|
-
},
|
|
1636
|
-
{
|
|
1637
|
-
"if": {
|
|
1638
|
-
"properties": {
|
|
1639
|
-
"terminal_action": {"const": "retain"}
|
|
1640
|
-
},
|
|
1641
|
-
"required": ["terminal_action"]
|
|
1642
|
-
},
|
|
1643
|
-
"then": {
|
|
1644
|
-
"properties": {
|
|
1645
|
-
"status": {
|
|
1646
|
-
"not": {"enum": ["integrating", "integrated"]}
|
|
1647
|
-
}
|
|
1648
|
-
}
|
|
1649
|
-
}
|
|
1650
|
-
}
|
|
1651
|
-
],
|
|
1652
|
-
"additionalProperties": true
|
|
1653
|
-
}
|
|
1654
|
-
}
|
|
1655
|
-
},
|
|
1656
|
-
"allOf": [
|
|
1657
|
-
{
|
|
1658
|
-
"if": {
|
|
1659
|
-
"properties": {
|
|
1660
|
-
"worktrees": {
|
|
1661
|
-
"contains": {
|
|
1662
|
-
"properties": {
|
|
1663
|
-
"provider": {
|
|
1664
|
-
"const": "git"
|
|
1665
|
-
}
|
|
1666
|
-
},
|
|
1667
|
-
"required": [
|
|
1668
|
-
"provider"
|
|
1669
|
-
]
|
|
1670
|
-
}
|
|
1671
|
-
}
|
|
1672
|
-
}
|
|
1673
|
-
},
|
|
1674
|
-
"then": {
|
|
1675
|
-
"properties": {
|
|
1676
|
-
"worktrees": {
|
|
1677
|
-
"items": {
|
|
1678
|
-
"if": {
|
|
1679
|
-
"properties": {
|
|
1680
|
-
"provider": {
|
|
1681
|
-
"const": "git"
|
|
1682
|
-
}
|
|
1683
|
-
},
|
|
1684
|
-
"required": [
|
|
1685
|
-
"provider"
|
|
1686
|
-
]
|
|
1687
|
-
},
|
|
1688
|
-
"then": {
|
|
1689
|
-
"properties": {
|
|
1690
|
-
"workspace_ref": {
|
|
1691
|
-
"pattern": "^specdev-worktree/T-[0-9]{2,}$"
|
|
1692
|
-
}
|
|
1693
|
-
}
|
|
1502
|
+
"else": {
|
|
1503
|
+
"properties": {
|
|
1504
|
+
"integration": {
|
|
1505
|
+
"allOf": [{"properties": {"method": {"enum": [null, "fast-forward", "merge-commit"]}}}]
|
|
1694
1506
|
}
|
|
1695
1507
|
}
|
|
1696
1508
|
}
|
|
1697
1509
|
}
|
|
1698
|
-
|
|
1510
|
+
],
|
|
1511
|
+
"additionalProperties": false
|
|
1699
1512
|
},
|
|
1700
|
-
{
|
|
1701
|
-
"
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
}
|
|
1513
|
+
"integration": {
|
|
1514
|
+
"type": "object",
|
|
1515
|
+
"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"],
|
|
1516
|
+
"properties": {
|
|
1517
|
+
"status": {"enum": ["pending", "candidate", "passed", "failed", "stale"]},
|
|
1518
|
+
"parent_ref": {"type": ["string", "null"]},
|
|
1519
|
+
"parent_before_sha": {"type": ["string", "null"]},
|
|
1520
|
+
"source_sha": {"type": ["string", "null"]},
|
|
1521
|
+
"candidate_sha": {"type": ["string", "null"]},
|
|
1522
|
+
"candidate_tree_sha": {"type": ["string", "null"]},
|
|
1523
|
+
"candidate_branch": {"type": ["string", "null"]},
|
|
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,}$"}]},
|
|
1525
|
+
"result_sha": {"type": ["string", "null"]},
|
|
1526
|
+
"method": {"enum": [null, "direct-parent", "fast-forward", "merge-commit"]},
|
|
1527
|
+
"conflict_paths": {"type": "array", "items": {"type": "string"}},
|
|
1528
|
+
"verification": {"enum": ["pending", "passed", "failed"]},
|
|
1529
|
+
"full_suite": {"$ref": "#/$defs/full-suite"},
|
|
1530
|
+
"e2e": {"$ref": "#/$defs/full-suite"},
|
|
1531
|
+
"evidence": {"type": "string", "pattern": "^\\{roots\\.state\\}/specdev/changes/[^<]+/evidence/T-[0-9]{2,}\\.md$"},
|
|
1532
|
+
"attempts": {"type": "integer", "minimum": 0},
|
|
1533
|
+
"promotion_status": {"enum": ["pending", "applying", "applied", "failed", "stale"]}
|
|
1707
1534
|
},
|
|
1708
|
-
"
|
|
1709
|
-
"properties": {
|
|
1710
|
-
"archived": {
|
|
1711
|
-
"const": true
|
|
1712
|
-
},
|
|
1713
|
-
"archive_path": {
|
|
1714
|
-
"type": "string",
|
|
1715
|
-
"pattern": "^specdev/archive/[0-9]{4}-[0-9]{2}/.+/$"
|
|
1716
|
-
}
|
|
1717
|
-
}
|
|
1718
|
-
}
|
|
1535
|
+
"additionalProperties": false
|
|
1719
1536
|
}
|
|
1720
|
-
|
|
1721
|
-
"
|
|
1537
|
+
},
|
|
1538
|
+
"allOf": [{
|
|
1539
|
+
"if": {"properties": {"change_status": {"const": "archived"}}, "required": ["change_status"]},
|
|
1540
|
+
"then": {"properties": {"archived": {"const": true}, "archive_path": {"type": "string", "pattern": "^specdev/archive/[0-9]{4}-[0-9]{2}/.+/$"}}}
|
|
1541
|
+
}],
|
|
1542
|
+
"additionalProperties": false
|
|
1722
1543
|
}
|
|
1723
1544
|
```
|
|
1724
1545
|
|