@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
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
- 若本地项目提供 Speculo Node 校验器,可运行它补充结构校验;纯网页环境按本文内联的 schema、Ready 清单和完成标准逐项核对,并明确记录未运行的自动校验。
|
|
14
14
|
- 提交、推送、合并、部署、发布、归档移动和不可逆迁移仍需用户明确授权。
|
|
15
15
|
|
|
16
|
-
Goal Plan
|
|
16
|
+
Goal Plan 只拥有单个 Ticket 无法独立决定的事情:整体 Outcome、跨 Ticket 顺序与并发、共享所有权、里程碑 Gate、动态派单边界、父分支集成、迁移/发布顺序、偏差升级和恢复。Ticket 继续拥有局部实现合同。
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
每次 Goal Plan 都采用 `lead-directed`:当前主会话是唯一 Lead,负责计划、SpecDev 状态、Evidence、派单、验收、父分支推进和最终回复。形成 Goal Plan 时必须询问是否开启 worktree 开发,默认不开启;选择写入当前 Goal Plan,不修改全局配置。不开启时 Ticket 严格串行,允许动态派遣 implementation subagent,但同一时间只有一个 implementation owner 可写当前 workspace;开启时沿用每 Ticket 独立 worktree 与 candidate-merge。
|
|
19
19
|
|
|
20
20
|
产物写入 `specdev/changes/{change}/goal-plan.md`。
|
|
21
21
|
|
|
@@ -25,12 +25,12 @@ Goal Plan 只解决单个 Ticket 无法独立决定的事情:跨 Ticket 顺序
|
|
|
25
25
|
|
|
26
26
|
- 多个 Ticket 可以或需要并行;
|
|
27
27
|
- 存在 shared path、共享合同或集中 owner;
|
|
28
|
-
- 存在 Deep Ticket、expand-contract
|
|
29
|
-
-
|
|
30
|
-
- Ticket DAG
|
|
28
|
+
- 存在 Deep Ticket、expand-contract、迁移、兼容窗口或不可逆步骤;
|
|
29
|
+
- 存在多个 Gate、外部审批、发布窗口或高事故半径;
|
|
30
|
+
- Ticket DAG 的关键路径、汇合点或恢复策略无法由 Tickets Map 安全表达;
|
|
31
31
|
- 用户明确要求正式跨 Ticket Plan。
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
少量、线性、低风险的 Ready Tickets 可以跳过本 work,由 I-implement 按当前 Goal Plan 的 workspace 策略执行。没有 Ticket 的获批小型 Direct Spec 不受 Ticket workspace 合同约束;一旦需要切片,先运行 T-tickets。
|
|
34
34
|
|
|
35
35
|
## 输入
|
|
36
36
|
|
|
@@ -43,97 +43,78 @@ Goal Plan 只解决单个 Ticket 无法独立决定的事情:跨 Ticket 顺序
|
|
|
43
43
|
|
|
44
44
|
按存在情况读取:
|
|
45
45
|
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
-
|
|
46
|
+
- 当前 change 架构决策:`specdev/changes/{change}/ADR.md`
|
|
47
|
+
- 当前 change 领域上下文:`specdev/changes/{change}/CONTEXT.md`
|
|
48
|
+
- 当前 change 设计日志:`specdev/changes/{change}/LOG.md`
|
|
49
|
+
- 当前 change 诊断:`specdev/changes/{change}/diagnosis.md`
|
|
50
|
+
- 永久架构决策:`specdev/adr/`
|
|
51
|
+
- 永久领域上下文:`specdev/context/`
|
|
52
|
+
- 用户提供的合同、标准、参考实现、环境限制、发布窗口和批准策略。
|
|
52
53
|
|
|
53
|
-
Spec 或 Tickets Map
|
|
54
|
+
永久目录可以为空,静默继续。缺少 Spec 或 Tickets Map 时返回 “编写 Spec 阶段” 或 “拆分 Tickets 阶段”;当前 ADR/CONTEXT 缺失且规划依赖对应决定时返回 “设计访谈能力”,不在 Goal Plan 中补造上游权威。
|
|
54
55
|
|
|
55
56
|
## 流程
|
|
56
57
|
|
|
57
|
-
### 1.
|
|
58
|
+
### 1. 验证上游与执行边界
|
|
58
59
|
|
|
59
60
|
加载 下方 `<planning-modes>` 标签:
|
|
60
61
|
|
|
61
|
-
1. 验证 Spec
|
|
62
|
-
2.
|
|
63
|
-
3. 识别
|
|
64
|
-
4.
|
|
65
|
-
5.
|
|
66
|
-
6.
|
|
67
|
-
7. 只对无法发现且会改变 Gate、Wave、owner、迁移、批准点或隔离策略的问题继续提问;
|
|
68
|
-
8. 不熟悉的外部标准或依赖使用 下方 `<research>` 标签。
|
|
62
|
+
1. 验证 Spec、Tickets、合同覆盖、DAG、路径所有权和 Deep Ticket 完整性;
|
|
63
|
+
2. 只读探索影响调度的代码与项目事实;
|
|
64
|
+
3. 识别 migration、high-assurance、reference-conformance、release-coordination 等适用模式;
|
|
65
|
+
4. 从 config 读取 `max_implementation_agents` 与 `max_integration_attempts`,将实际值快照到 `implementation_agent_limit` 与 `integration_attempt_limit`;本计划可以降低但不得超过 config 或平台能力,Lead 不计入;
|
|
66
|
+
5. 根据 workspace 策略确认实现 commit 与 direct-parent/candidate integration 已获授权;缺一项则计划保持 blocked;
|
|
67
|
+
6. 只询问无法发现且会改变 Gate、Wave、owner、迁移、批准或验收的问题。
|
|
69
68
|
|
|
70
|
-
|
|
69
|
+
**完成标准**:所有计划内 Ticket Ready;Lead、授权、实现并发上限和父分支可判定;没有用 Goal Plan 掩盖上游缺口。
|
|
71
70
|
|
|
72
|
-
### 2.
|
|
71
|
+
### 2. 构建 Outcome、DAG、Wave 与 Gate
|
|
73
72
|
|
|
74
73
|
加载 下方 `<orchestration-protocol>` 标签:
|
|
75
74
|
|
|
76
|
-
1.
|
|
77
|
-
2.
|
|
78
|
-
3. 为 shared path
|
|
79
|
-
4.
|
|
80
|
-
5.
|
|
81
|
-
6.
|
|
82
|
-
7. 只有存在允许的隔离触发条件时才规划 worktree,并固定 workspace owner、integration owner、父分支和结束动作。
|
|
75
|
+
1. 压缩 Outcome、成功/伪完成、非目标和权威来源;
|
|
76
|
+
2. 从 Ticket frontmatter 构建 DAG、关键路径、扇出与汇合点;
|
|
77
|
+
3. 为 shared path、共享合同和集中修改指定唯一 owner;
|
|
78
|
+
4. 将依赖满足且项目写路径不相交的 Ticket 分入 Wave;current 模式仍按依赖顺序串行执行,不得把 Wave 当作并发授权;
|
|
79
|
+
5. 为合同稳定、垂直路径、迁移完成、发布就绪等状态定义 Gate;
|
|
80
|
+
6. 为每个 Ticket 记录开始条件、workspace 策略、验证层级、Evidence 目标、集成顺序和失败恢复。
|
|
83
81
|
|
|
84
|
-
**完成标准**:DAG、Wave、Gate 与 Tickets Map
|
|
82
|
+
**完成标准**:DAG、Wave、Gate 与 Tickets Map 一致;每个 Ticket 有唯一项目写 owner、worktree 合同和可验证集成出口。
|
|
85
83
|
|
|
86
|
-
### 3.
|
|
84
|
+
### 3. 固定 Lead 编排与动态派单合同
|
|
87
85
|
|
|
88
|
-
|
|
86
|
+
加载 下方 `<lead-orchestration>` 标签,并以 `operation=plan` 调用 下方 `<subagent-delivery>` 标签:
|
|
89
87
|
|
|
90
|
-
1.
|
|
91
|
-
2.
|
|
92
|
-
3.
|
|
88
|
+
1. 固定 Lead 的可恢复 owner/session locator;
|
|
89
|
+
2. 声明 implementation subagent 的 config/平台约束上限,Lead 不计入;
|
|
90
|
+
3. 不为只读 review/research/test-observation agent 写 SpecDev 数字上限;
|
|
91
|
+
4. current 模式固定只有一个 implementation writer 写项目路径,Lead 仍是唯一 SpecDev 工件与状态写入者;required 模式 implementation owner 写自己的 Ticket worktree;
|
|
92
|
+
5. 定义执行期动态 Dispatch Packet、候选返回和 Lead 验收;
|
|
93
|
+
6. provider、模型和具体派单在 Ticket 开始时按事实选择,不在 Goal Plan 中预分配。
|
|
93
94
|
|
|
94
|
-
|
|
95
|
+
**完成标准**:Lead 可以在恢复后重建派单边界;任何 subagent 都不能成为第二个 SpecDev 状态写入者或父分支 integration owner。
|
|
95
96
|
|
|
96
|
-
|
|
97
|
-
2. 以 `operation=plan` 调用 下方 `<subagent-delivery>` 标签;
|
|
98
|
-
3. 固定唯一 Lead、native/external provider、不可变 checkpoint、可恢复 locator、逐动作授权和修正上限;
|
|
99
|
-
4. 生成里程碑 Delivery Contract 与每个 Ticket 的独立 Dispatch Packet;
|
|
100
|
-
5. 为每个派单标记 `lead-write | worker-write | read-only`;`worker-write` 必须引用隔离 workspace 分配。
|
|
101
|
-
|
|
102
|
-
`single-session` 跳过委派能力,但仍可加载独立 workspace 附录;`lead-team` 在没有隔离触发条件时也不得制造 worktree。
|
|
103
|
-
|
|
104
|
-
### 4. 定义整体完成、证据与恢复
|
|
97
|
+
### 4. 定义完成、证据与恢复
|
|
105
98
|
|
|
106
99
|
加载 下方 `<completion-control>` 标签:
|
|
107
100
|
|
|
108
|
-
1.
|
|
109
|
-
2.
|
|
110
|
-
3.
|
|
111
|
-
4.
|
|
112
|
-
5.
|
|
113
|
-
6.
|
|
114
|
-
|
|
115
|
-
**完成标准**:所有完成声明能映射到实际命令、代码状态、Evidence 或人工批准;没有自报即通过的门禁。
|
|
116
|
-
|
|
117
|
-
### 5. 写入自适应 Goal Plan
|
|
118
|
-
|
|
119
|
-
使用 下方 `<goal-plan-template>` 标签 写入 `specdev/changes/{change}/goal-plan.md`。
|
|
101
|
+
1. 定义整体 Definition of Done 和每个 Gate 的关闭证据;
|
|
102
|
+
2. 固化不可协商约束与允许的局部实现自由;
|
|
103
|
+
3. 按 workspace 策略为每个 Ticket 明确 current-workspace/direct-parent 检查或 source-worktree/parent-candidate 检查;
|
|
104
|
+
4. E2E 按 Ticket 实际跨边界风险标记 required 或 not-required;
|
|
105
|
+
5. 定义 direct-parent 验证失败、candidate 冲突/失败、父 HEAD 漂移、偏差、暂停、批准和恢复动作;
|
|
106
|
+
6. 定义 change 完成、远程 reconcile、残余风险和回滚要求。
|
|
120
107
|
|
|
121
|
-
|
|
108
|
+
**完成标准**:每个完成声明映射到不可变 commit、候选/父分支 SHA、命令、Evidence 或人工批准。
|
|
122
109
|
|
|
123
|
-
|
|
124
|
-
2. Execution Graph;
|
|
125
|
-
3. Gates and Completion Evidence;
|
|
126
|
-
4. Execution and Integration Protocol;
|
|
127
|
-
5. Constraints, Risk and Recovery;
|
|
128
|
-
6. Progress and Decisions。
|
|
110
|
+
### 5. 写入、同步与验证
|
|
129
111
|
|
|
130
|
-
|
|
112
|
+
使用 下方 `<goal-plan-template>` 标签 写入 Goal Plan:
|
|
131
113
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
3. 运行:
|
|
114
|
+
1. 只保留适用 planning modes,不创建条件性 topology addendum;
|
|
115
|
+
2. 将 Wave、Gate 和 owner 投影同步到 Tickets Map;
|
|
116
|
+
3. 对照 下方 `<goal-plan-schema>` 标签;
|
|
117
|
+
4. 运行:
|
|
137
118
|
|
|
138
119
|
```bash
|
|
139
120
|
node Speculo Node 校验器 \
|
|
@@ -141,47 +122,40 @@ node Speculo Node 校验器 \
|
|
|
141
122
|
specdev/changes/{change}
|
|
142
123
|
```
|
|
143
124
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
6. 向用户汇报规划模式、协作方式、workspace 分配、关键路径、Wave、Gate、shared owner、迁移策略、主要风险和 Ready 状态;Lead Team 再汇报交付通道与 Lead;
|
|
125
|
+
5. 原子更新 Goal Plan、Tickets Map、全局/current change 状态并重新读取;
|
|
126
|
+
6. 向用户报告 Outcome、关键路径、Wave/Gate、Lead、实现 agent 上限、shared owner、E2E disposition、迁移与主要风险;
|
|
147
127
|
7. 未经用户要求,不自动进入实现。
|
|
148
128
|
|
|
149
129
|
## 决策完备标准
|
|
150
130
|
|
|
151
|
-
每份 Goal Plan
|
|
152
|
-
|
|
153
|
-
- 跨 Ticket 先后、并发 Wave 和关键汇合点;
|
|
154
|
-
- shared path 与共享合同的 owner;
|
|
155
|
-
- Gate 开启、关闭和证据;
|
|
156
|
-
- 迁移、兼容、收缩、发布和回滚顺序;
|
|
157
|
-
- Evidence 返回、集成、偏差、暂停和批准路径。
|
|
131
|
+
每份 Goal Plan 必须让 Lead 无需重新决定:
|
|
158
132
|
|
|
159
|
-
|
|
133
|
+
- Outcome、权威来源和整体完成;
|
|
134
|
+
- 跨 Ticket 先后、Wave、Gate 和关键汇合点;
|
|
135
|
+
- shared path 与共享合同 owner;
|
|
136
|
+
- implementation subagent 上限及动态派单边界;
|
|
137
|
+
- 每 Ticket workspace、implementation commit、对应验证和父分支推进规则;
|
|
138
|
+
- E2E disposition、偏差、暂停、批准和恢复路径。
|
|
160
139
|
|
|
161
|
-
Goal Plan
|
|
140
|
+
Goal Plan 不复制 Ticket 的局部施工路线、全部文件预测或逐项验收清单。
|
|
162
141
|
|
|
163
142
|
## 完成标准
|
|
164
143
|
|
|
165
|
-
- `
|
|
166
|
-
-
|
|
167
|
-
-
|
|
168
|
-
-
|
|
169
|
-
-
|
|
170
|
-
- Tickets Map
|
|
171
|
-
- 无未批准高影响假设或硬停止问题;
|
|
172
|
-
- 结构校验无 error;纯网页环境的人工核对结果已记录;
|
|
173
|
-
- 用户收到摘要和下一步选择。
|
|
144
|
+
- Goal Plan schema v6 且 `ready_for_execution` 与状态一致;
|
|
145
|
+
- Lead 唯一,implementation subagent 上限来自 config/平台能力,review/research agent 不受 SpecDev 数字限制;
|
|
146
|
+
- 每个实现 Ticket 都有 workspace、commit、对应 integration gate 和 Evidence 出口;
|
|
147
|
+
- current 模式不创建 source/candidate worktree,适用 E2E 由 Lead 在 current workspace 运行;required 模式保持 source/parent-candidate 边界;
|
|
148
|
+
- 计划只保留当前固定 Lead 与选定 workspace/integration 合同;
|
|
149
|
+
- validator 无 error,Tickets Map 投影同步,用户收到下一步选择。
|
|
174
150
|
|
|
175
151
|
## 子文件引用
|
|
176
152
|
|
|
177
153
|
- 规划模式与输入门禁:下方 `<planning-modes>` 标签
|
|
178
|
-
- DAG、Wave、Gate
|
|
179
|
-
-
|
|
180
|
-
-
|
|
181
|
-
- Goal Plan
|
|
182
|
-
-
|
|
183
|
-
- 委派附录模板:下方 `<delegated-execution-template>` 标签,仅用户选择委派时加载
|
|
184
|
-
- Agent 交付合同:下方 `<subagent-delivery>` 标签,仅用户选择委派时调用
|
|
154
|
+
- DAG、Wave、Gate 与集成队列:下方 `<orchestration-protocol>` 标签
|
|
155
|
+
- Lead 与动态派单:下方 `<lead-orchestration>` 标签
|
|
156
|
+
- 完成、证据与恢复:下方 `<completion-control>` 标签
|
|
157
|
+
- Goal Plan 模板:下方 `<goal-plan-template>` 标签
|
|
158
|
+
- Agent 交付合同:下方 `<subagent-delivery>` 标签
|
|
185
159
|
|
|
186
160
|
---
|
|
187
161
|
|
|
@@ -193,95 +167,73 @@ Goal Plan 不应重复 Ticket 的局部执行路线、全部文件预测、局
|
|
|
193
167
|
|
|
194
168
|
# Goal Plan 规划模式与输入门禁
|
|
195
169
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
## 1. 必需输入门禁
|
|
199
|
-
|
|
200
|
-
- [ ] `specdev/changes/{change}/spec.md` 设置 `ready_for_tickets: true`,或存在用户明确批准的等价权威目标。
|
|
201
|
-
- [ ] `specdev/changes/{change}/tickets-map.md` 与全部 Ticket 一致。
|
|
202
|
-
- [ ] 所有计划执行的 Ticket 设置 `ready: true`。
|
|
203
|
-
- [ ] Ticket ID、具体 `specdev/changes/{change}/ticket/NN-<ticket-name>.md` 和 Map 行一致。
|
|
204
|
-
- [ ] `blocked_by` 引用存在,DAG 无环。
|
|
205
|
-
- [ ] Spec 验收合同全部 covered,或 deferred 项有批准、原因和后续归属。
|
|
206
|
-
- [ ] 可能并行的 Ticket 项目写路径不相交,或已有 shared owner 与排序方案。
|
|
207
|
-
- [ ] Deep Ticket 具备迁移、兼容、监控、回滚、收缩条件和批准点。
|
|
208
|
-
- [ ] Ticket 与 Spec、ADR、代码事实不存在未处理冲突。
|
|
209
|
-
- [ ] 项目声明的验证命令真实存在且能观察目标行为;不可运行项有替代证据或明确 blocker。
|
|
210
|
-
- [ ] 当前源码基线、工作区状态和外部合同版本已实测,而非使用浮动的“最新”描述。
|
|
170
|
+
规划模式描述 Goal Plan 需要额外解决的工程问题。Goal Plan 创建时单独询问 Ticket 是否开启 worktree,默认使用当前 workspace;worktree 与 direct-parent/candidate-merge 由该次 Goal Plan 固定。
|
|
211
171
|
|
|
212
|
-
##
|
|
172
|
+
## 1. 输入门禁
|
|
213
173
|
|
|
214
|
-
|
|
174
|
+
开始规划前穷尽检查:
|
|
215
175
|
|
|
216
|
-
-
|
|
217
|
-
- DAG
|
|
218
|
-
-
|
|
219
|
-
-
|
|
220
|
-
-
|
|
221
|
-
-
|
|
222
|
-
- Deep Ticket
|
|
223
|
-
-
|
|
224
|
-
-
|
|
225
|
-
-
|
|
226
|
-
-
|
|
227
|
-
- `lead-team + current` 中存在 `worker-write`,或 current workspace 出现多个项目/状态写入 owner;
|
|
228
|
-
- 用户要求的远程或生产动作没有逐动作授权。
|
|
176
|
+
- Spec `ready_for_tickets: true`,或上游工件已等价覆盖范围、合同与验收;
|
|
177
|
+
- Tickets Map 与全部 Ticket 存在、Ready、DAG 无环;
|
|
178
|
+
- 每个验收合同被 Ticket 覆盖;
|
|
179
|
+
- writable/shared path 有唯一 owner,Wave 候选无写冲突;
|
|
180
|
+
- config schema v5,`max_implementation_agents` 与 `max_integration_attempts` 为正整数;原型变体范围读取 planning 配置;
|
|
181
|
+
- 父分支可定位,implementation commit 与本地 integration 已获授权;
|
|
182
|
+
- Deep Ticket 的迁移、兼容、监控、恢复和不可逆批准点完整。
|
|
183
|
+
- Ticket 与 `specdev/changes/{change}/spec.md`、`specdev/changes/{change}/ADR.md`、`specdev/adr/`、`specdev/context/` 和当前代码事实不存在未处理冲突;
|
|
184
|
+
- 项目声明的验证命令真实存在,并能观察目标行为;不可运行项有替代证据或明确 blocker;
|
|
185
|
+
- 当前源码基线、父分支、工作区状态和现有用户改动已经实测;
|
|
186
|
+
- 外部合同、标准、参考实现或依赖版本已经固定,不使用浮动的“最新”描述。
|
|
229
187
|
|
|
230
|
-
|
|
188
|
+
缺失上游事实返回其 owner;非 v5 Goal Plan 必须按当前合同重新规划,不能只修改版本号。
|
|
231
189
|
|
|
232
|
-
##
|
|
190
|
+
## 2. 可组合模式
|
|
233
191
|
|
|
234
|
-
-
|
|
235
|
-
-
|
|
236
|
-
-
|
|
237
|
-
-
|
|
238
|
-
- **release-coordination**:发布窗口、跨团队依赖、部署顺序或运营交接;重点是环境前置条件、Gate、观察期和回退。
|
|
192
|
+
- `migration`:存在 expand-contract、数据/协议迁移、兼容窗口或收缩条件;
|
|
193
|
+
- `high-assurance`:涉及安全、隐私、资金、数据完整性、法规、关键基础设施、不可逆操作或高事故半径;
|
|
194
|
+
- `reference-conformance`:必须逐项符合外部标准、协议、设计或参考实现;
|
|
195
|
+
- `release-coordination`:存在发布窗口、跨团队依赖、外部批准、阶段部署、观察期、运营交接或远程 reconcile。
|
|
239
196
|
|
|
240
|
-
|
|
197
|
+
没有适用模式时 `modes: []`。模式只增加对应 Gate、证据和恢复,不改变 Lead、worktree 或集成基本合同。
|
|
241
198
|
|
|
242
|
-
##
|
|
199
|
+
## 3. Goal Plan 工作区选择
|
|
243
200
|
|
|
244
|
-
|
|
201
|
+
- 创建 Goal Plan 时询问“是否开启 worktree 开发?”,默认 `否`;
|
|
202
|
+
- 用户选择 `否` 时写入 `ticket_workspace_policy: current` 与 `integration_gate: direct-parent`;
|
|
203
|
+
- 用户选择 `是` 时写入 `ticket_workspace_policy: required` 与 `integration_gate: candidate-merge`;
|
|
204
|
+
- 该选择只作用于当前 Goal Plan,不读取或修改全局配置;
|
|
205
|
+
- `current` 模式下所有 Ticket 必须串行,并持有唯一 implementation writer 锁;
|
|
206
|
+
- `required` 模式继续使用每 Ticket source worktree 和 Lead-owned candidate integration;
|
|
207
|
+
- `orchestration` 固定为 `lead-directed`;implementation agent 与 integration attempt 上限读取 config,并可在本计划中进一步降低。
|
|
245
208
|
|
|
246
|
-
|
|
247
|
-
- `workspace_strategy: current | worktree | mixed`。
|
|
209
|
+
## 4. Ready 停止条件
|
|
248
210
|
|
|
249
|
-
|
|
211
|
+
存在以下任一情况时 `ready_for_execution: false`:
|
|
250
212
|
|
|
251
|
-
|
|
213
|
+
- Goal Plan 工作区选择未记录;
|
|
214
|
+
- `current` 模式下 Ticket 无法串行排序或当前 workspace 不是唯一项目写入 owner;
|
|
215
|
+
- `required` 模式下 Ticket 无法建立独立 worktree 或父分支不明确;
|
|
216
|
+
- 当前模式所需的 implementation commit 或 direct-parent/candidate integration 授权缺失;
|
|
217
|
+
- shared path 没有唯一 owner;
|
|
218
|
+
- E2E 是否需要会改变验收结论但尚未确定;
|
|
219
|
+
- 项目验证命令不能执行或无法观察目标行为,且没有批准的替代证据;
|
|
220
|
+
- 当前源码/工作区基线未实测,或外部合同版本仍然浮动;
|
|
221
|
+
- Ticket 与 Spec、ADR、`specdev/adr/`、`specdev/context/` 或代码事实存在未处理冲突;
|
|
222
|
+
- 迁移、发布、不可逆动作或恢复存在高影响未知项;
|
|
223
|
+
- 实现 agent 或 integration attempt 上限超过 config 或平台能力。
|
|
252
224
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
| Coordination | Workspace | 写入约束 |
|
|
256
|
-
|---|---|---|
|
|
257
|
-
| single-session | current | 主会话唯一写入 |
|
|
258
|
-
| single-session | worktree/mixed | 主会话管理并集成隔离写入 |
|
|
259
|
-
| lead-team | current | Lead 唯一写入,Worker 只读 |
|
|
260
|
-
| lead-team | worktree/mixed | `worker-write` 每项绑定独立 workspace,Lead 默认承担 integration owner |
|
|
261
|
-
|
|
262
|
-
选择 Lead Team 后固定 Lead、provider、repository、不可变 `base_sha` 或等价基线、源码交付方式、`max_correction_rounds` 和逐动作授权。选择 worktree/mixed 后固定每项的 trigger、workspace owner、integration owner、父分支、locator、来源 checkpoint 策略和结束动作。认证秘密和机器绝对路径不得进入 Goal Plan。
|
|
263
|
-
|
|
264
|
-
## 5. 规划摘要
|
|
265
|
-
|
|
266
|
-
写入前形成核心摘要:
|
|
267
|
-
|
|
268
|
-
```text
|
|
269
|
-
modes=<mode-list>
|
|
270
|
-
coordination_mode=single-session|lead-team
|
|
271
|
-
workspace_strategy=current|worktree|mixed
|
|
272
|
-
tickets=<count>
|
|
273
|
-
critical_path=<ticket-list>
|
|
274
|
-
parallel_capacity=<n>
|
|
275
|
-
shared_owners=<owner-map>
|
|
276
|
-
gates=<gate-list>
|
|
277
|
-
authorization=<action-summary>
|
|
278
|
-
hard_stops=<none-or-list>
|
|
279
|
-
adopted_assumptions=<low-impact-only>
|
|
280
|
-
```
|
|
225
|
+
## 5. 固定执行拓扑
|
|
281
226
|
|
|
282
|
-
|
|
227
|
+
- `orchestration: lead-directed`;
|
|
228
|
+
- `ticket_workspace_policy: current | required`;
|
|
229
|
+
- `integration_gate: direct-parent | candidate-merge`;
|
|
230
|
+
- `current` 与 `direct-parent` 必须成对;`required` 与 `candidate-merge` 必须成对;
|
|
231
|
+
- `implementation_agent_limit` 不大于 config 与平台能力;`integration_attempt_limit` 不大于 config;current 模式保持单 writer 串行安全不变量;
|
|
232
|
+
- Lead 不计入 implementation subagent 数量;
|
|
233
|
+
- review/research/test-observation agent 无 SpecDev 固定数字上限,但必须保持只读且不竞争同一可变环境;
|
|
234
|
+
- provider 与派单在执行期决定,不成为 Goal Plan 的静态枚举。
|
|
283
235
|
|
|
284
|
-
|
|
236
|
+
**完成标准**:所有固定字段、适用模式、授权、Lead、父分支和阻塞均可验证;没有替代编排模型或空占位。
|
|
285
237
|
|
|
286
238
|
</planning-modes>
|
|
287
239
|
|
|
@@ -289,202 +241,144 @@ Lead Team 额外形成 `execution_model`、`lead`、`provider`、`checkpoint`、
|
|
|
289
241
|
|
|
290
242
|
# Goal Plan 核心编排协议
|
|
291
243
|
|
|
292
|
-
|
|
244
|
+
本文件定义 DAG、Wave、Gate、路径所有权、Ticket workspace 策略、Evidence 返回和父分支集成队列。
|
|
293
245
|
|
|
294
246
|
## 1. DAG 与关键路径
|
|
295
247
|
|
|
296
|
-
- 依赖权威来自
|
|
297
|
-
- `specdev/changes/{change}/tickets-map.md` 是投影,不是第二套依赖真相;
|
|
248
|
+
- 依赖权威来自 Ticket frontmatter 的 `blocked_by`;Tickets Map 是投影;
|
|
298
249
|
- 计算根节点、扇出、汇合点、关键路径、共享合同 owner 和最终收缩点;
|
|
299
|
-
-
|
|
300
|
-
-
|
|
250
|
+
- 依赖只表示真实开始条件,不表达偏好、Agent 交接或“最好先做”;
|
|
251
|
+
- 无法独立保持可验证状态的迁移批次必须有明确 Gate 和恢复策略。
|
|
301
252
|
|
|
302
|
-
## 2. Wave
|
|
253
|
+
## 2. Wave 与实现并发
|
|
303
254
|
|
|
304
|
-
Wave 内 Ticket
|
|
255
|
+
required 模式的 Wave 内 Ticket 必须 Ready、依赖 Evidence 完整、项目写路径不相交、shared owner 已稳定、适用 Gate 已打开且基线一致。current 模式即使 DAG 存在可并行节点,也强制一次只执行一个 Ticket。
|
|
305
256
|
|
|
306
|
-
-
|
|
307
|
-
- 所有依赖已完成并有 Evidence;
|
|
308
|
-
- 项目写路径不相交;
|
|
309
|
-
- shared path 已由 owner 稳定;
|
|
310
|
-
- 适用 Gate 已打开;
|
|
311
|
-
- 源码基线和外部合同版本一致。
|
|
312
|
-
|
|
313
|
-
最大并发从 `specdev/config.json` 读取。并发上限是资源约束,不是必须填满的目标;Wave 也不意味着必须使用多个 Agent。
|
|
314
|
-
|
|
315
|
-
Wave、Agent Team 和 worktree 是三个不同概念。Wave 只表达依赖上可并发;是否委派由 coordination mode 决定,是否隔离写入由 workspace strategy 决定。只读并行不需要 worktree;同一 current workspace 只能有一个项目与状态写入 owner。
|
|
257
|
+
Lead 根据当前事实决定自行实现或派单。required 模式同时活跃的 implementation subagent 不得超过 Goal Plan、config 与平台能力的共同上限;current 模式保持单 writer 串行安全不变量。Lead 不计入。Wave 是可并发性,不是必须填满的目标。只读 review/research/test-observation agent 不写固定数字上限,但不得写项目或 SpecDev 状态,也不得争用同一可变测试环境。
|
|
316
258
|
|
|
317
259
|
## 3. Gate
|
|
318
260
|
|
|
319
|
-
Gate
|
|
320
|
-
|
|
321
|
-
常见 Gate 包括共享合同稳定、首条垂直路径通过、迁移完成、旧调用点归零、发布就绪和观察期结束。名称按项目语义自定义。
|
|
322
|
-
|
|
323
|
-
## 4. Shared path 与共享合同
|
|
261
|
+
Gate 用可验证状态定义,必须写明:工程/业务状态、开启条件、关闭证据、阻塞范围、Lead/批准人和失败恢复。常见 Gate 包括共享合同稳定、首条垂直路径、迁移完成、旧调用点归零、候选合并通过、发布就绪和观察期结束。
|
|
324
262
|
|
|
325
|
-
|
|
263
|
+
## 4. Shared path 与合同
|
|
326
264
|
|
|
327
|
-
|
|
328
|
-
2. 形成可验证稳定基线;
|
|
329
|
-
3. 下游消费者在新基线上重新运行 preflight;
|
|
330
|
-
4. 才允许扇出或继续后续 Ticket;
|
|
331
|
-
5. 共享契约需要变化时暂停消费者并修订上游,不通过多个执行者同时修改解决。
|
|
265
|
+
遵循 下方 `<path-ownership>` 标签:
|
|
332
266
|
|
|
333
|
-
|
|
267
|
+
1. 专用 owner Ticket 修改共享路径;
|
|
268
|
+
2. required 模式在其 source worktree 形成 commit 与非 E2E 证据;current 模式在当前 workspace 形成 commit 与证据;
|
|
269
|
+
3. required 模式通过 Lead candidate-merge 进入父分支;current 模式由 Lead 在父分支 direct-parent 验证并推进;
|
|
270
|
+
4. required 模式下游 Ticket 基于新的父分支 checkpoint 创建或刷新 worktree;current 模式仅在前一 Ticket 完成后开始下一个;
|
|
271
|
+
5. 共享合同变化时暂停消费者并修订上游,不让多个执行者竞争写入。
|
|
334
272
|
|
|
335
|
-
|
|
273
|
+
## 5. 每 Ticket workspace 记录
|
|
336
274
|
|
|
337
|
-
|
|
338
|
-
2. **migrate**:按可独立验证的影响范围分批迁移;
|
|
339
|
-
3. **observe**:扫描旧调用点、旧数据或旧协议使用量;
|
|
340
|
-
4. **contract**:收缩条件有证据后删除旧形式;
|
|
341
|
-
5. **verify**:运行兼容、数据、回归、监控和回滚检查。
|
|
275
|
+
每个进入 I-implement 的 Ticket 建立唯一记录。current 模式使用 `workspace_ref=current`、`branch=parent_branch`,记录 implementation/source/result SHA 与 direct-parent 验证;required 模式使用唯一 `specdev-worktree/<ticket-id>`,记录 source/candidate/result SHA 与验证状态。Lead 自行实现或派 subagent 不改变所选策略。
|
|
342
276
|
|
|
343
|
-
|
|
277
|
+
required 模式同一 Ticket 在 candidate 验证失败后保留来源 worktree 并继续修正。新的 source commit 替换当前 `source_checkpoint`,旧 commit 继续由 Git/Evidence 可追溯。成功集成不自动清理 branch/worktree。
|
|
344
278
|
|
|
345
|
-
## 6.
|
|
279
|
+
## 6. 父分支集成队列
|
|
346
280
|
|
|
347
|
-
|
|
281
|
+
required 模式 Lead 串行集成 Ready 候选:
|
|
348
282
|
|
|
349
|
-
|
|
283
|
+
1. 冻结最新 `parent_before_sha`;
|
|
284
|
+
2. 在 Lead-owned parent integration checkout 组合父分支与 `source_checkpoint`;
|
|
285
|
+
3. 生成可定位的 `candidate_sha`;
|
|
286
|
+
4. 在 candidate 状态运行集成检查和适用 E2E;
|
|
287
|
+
5. 重读父 HEAD;若变化,将候选标记 `stale` 并重建;
|
|
288
|
+
6. 检查通过且父 HEAD 未变时,父分支 fast-forward 到 candidate;
|
|
289
|
+
7. 重读父 HEAD/tree,写入 `result_sha` 后才允许 Ticket Done。
|
|
350
290
|
|
|
351
|
-
|
|
291
|
+
父分支是 source checkpoint 的祖先时 candidate/result 可等于 source SHA,方法为 `fast-forward`;否则 candidate 必须是独立 merge commit。候选失败时父分支保持不变,Ticket 回到 `in_progress` 或 `blocked`。current 模式跳过候选 checkout,Lead 在 current workspace 核对 implementation commit、运行集成检查并记录 `method=direct-parent`;失败时父 HEAD 不推进。
|
|
352
292
|
|
|
353
|
-
|
|
354
|
-
2. 同步 Ticket、Tickets Map、Goal Plan 和 change 状态;
|
|
355
|
-
3. 检查依赖、路径所有权、合同覆盖和适用 Gate;
|
|
356
|
-
4. 返回 Ticket 状态、Evidence 路径、代码引用、未验证项和恢复条件。
|
|
293
|
+
## 7. Expand-contract
|
|
357
294
|
|
|
358
|
-
|
|
295
|
+
标准顺序为 expand → migrate → observe → contract → verify。每批迁移独立 commit、按所选策略验证和父分支集成;收缩依据旧调用/数据/协议归零证据,不依据 Ticket 数量推断。
|
|
359
296
|
|
|
360
|
-
|
|
297
|
+
**完成标准**:每个 Ticket 从父基线、implementation/source commit、对应 integration 到 result 都可恢复;父分支只包含已通过所选门禁的 Ticket。
|
|
361
298
|
|
|
362
299
|
</orchestration-protocol>
|
|
363
300
|
|
|
364
|
-
<
|
|
365
|
-
|
|
366
|
-
# Goal Plan 委派执行协议
|
|
367
|
-
|
|
368
|
-
只有用户在本次 P-goal-plan 运行中明确选择 `coordination_mode: lead-team` 时加载。该分支启用唯一 Lead 与 native/external Worker,但不决定 workspace strategy;Agent Team 可以只做只读分工,也可以与独立 worktree 组合。
|
|
369
|
-
|
|
370
|
-
## 1. Lead 与 Delivery Contract
|
|
371
|
-
|
|
372
|
-
Lead 负责源码基线、DAG、Wave、shared owner、Gate、权限、Evidence 汇总和最终验收;已派发写入 Ticket 的实现由对应执行者负责,Lead 不制造双重 owner。只有 workspace addendum 将 Lead 指定为 integration owner 时,Lead 才拥有对应 Git 集成。
|
|
301
|
+
<lead-orchestration>
|
|
373
302
|
|
|
374
|
-
|
|
303
|
+
# Lead 编排与动态派单协议
|
|
375
304
|
|
|
376
|
-
|
|
305
|
+
## 1. 唯一 Lead
|
|
377
306
|
|
|
378
|
-
|
|
379
|
-
- repository、branch、不可变 checkpoint 与源码交付方式;
|
|
380
|
-
- 最大并发和默认 3 轮的 `max_correction_rounds`;
|
|
381
|
-
- 标准轴、规范轴、Lead 独立验证和条件性 E2E;
|
|
382
|
-
- local changes、commit、push、PR、merge、deploy、migration 和生产动作的逐项授权;
|
|
383
|
-
- 完成、阻塞、偏差、恢复和返回协议。
|
|
307
|
+
Lead 是主会话中的唯一编排 owner,保留需求解释、DAG/Wave/Gate、路径分配、权限、SpecDev 状态、Evidence、候选验收、父分支集成和最终回复责任。恢复时以 Goal Plan 的 `lead` locator 和权威工件继续;更换会话只转移 Lead 身份,不产生第二写入者。
|
|
384
308
|
|
|
385
|
-
|
|
309
|
+
## 2. 派单类型
|
|
386
310
|
|
|
387
|
-
-
|
|
388
|
-
-
|
|
389
|
-
-
|
|
311
|
+
- **implementation**:写入 Goal Plan 选择的 current workspace 或 Ticket worktree 的授权项目路径,运行非 E2E 检查并返回 implementation/source commit;
|
|
312
|
+
- **review**:只读审查固定 checkpoint,返回 findings;
|
|
313
|
+
- **research**:只读收集代码或外部事实,返回来源与结论;
|
|
314
|
+
- **test-observation**:只读运行或观察已授权检查,返回命令与结果,不拥有 E2E Gate。
|
|
390
315
|
|
|
391
|
-
|
|
316
|
+
Lead 在 Ticket 可以独立执行、写路径不冲突、上下文足够且平台支持时派单。派单是执行期决定,不写回 Goal Plan 作为固定拓扑。
|
|
392
317
|
|
|
393
|
-
##
|
|
318
|
+
## 3. 并发
|
|
394
319
|
|
|
395
|
-
|
|
320
|
+
required 模式 implementation subagent 上限取 Goal Plan、config 与平台能力的最小值;current 模式保持单 writer 串行安全不变量;Lead 不计入。review/research/test-observation agent 不设置 SpecDev 数字上限,但 Lead 必须避免测试资源冲突、重复工作和上下文失控。
|
|
396
321
|
|
|
397
|
-
|
|
398
|
-
2. “实现阶段” 与具体 Ticket;
|
|
399
|
-
3. 相关 Spec 合同、ADR/CONTEXT 条目、Wave、Gate 和不可协商约束;
|
|
400
|
-
4. 已完成依赖及其 Evidence;
|
|
401
|
-
5. 项目 writable/read-only/shared 路径与唯一 shared owner;
|
|
402
|
-
6. mutation role、workspace allocation、`base_sha`、workspace/session locator 和 source package hash;
|
|
403
|
-
7. 必跑验证、基线、反向验证和明确不适用项;
|
|
404
|
-
8. 当前授权、偏差升级、修正上限、Evidence 路径和返回字段。
|
|
322
|
+
## 4. 写入边界
|
|
405
323
|
|
|
406
|
-
|
|
324
|
+
implementation subagent 只写分配的 current workspace 或 worktree 中的项目路径和其 Git commit,不写 Ticket、Map、Goal Plan、Evidence、change status 或父分支。current 模式 commit 直接落在 parent branch;required 模式 commit 落在 source branch。其他 subagent 全部只读。Lead 接收返回后独立核对,再写所有 SpecDev 状态。
|
|
407
325
|
|
|
408
|
-
##
|
|
326
|
+
## 5. 动态 Dispatch Packet
|
|
409
327
|
|
|
410
|
-
|
|
328
|
+
每次派单必须绑定 Ticket、Goal Plan、依赖 Evidence、不可变 `base_sha`、branch/workspace locator、workspace strategy、writable/read-only/shared paths、provider、允许动作、非 E2E 验证、停止条件和返回格式。provider 或模型按当次能力与授权选择;外部 provider 需要独立的数据发送授权。
|
|
411
329
|
|
|
412
|
-
|
|
330
|
+
implementation 返回至少包含:Ticket ID、workspace locator、最终 commit、dirty 状态、修改路径、检查命令/结果、未验证项、冲突与阻塞。review/research 返回固定输入、findings、来源和未验证声明。
|
|
413
331
|
|
|
414
|
-
|
|
415
|
-
2. 检查 checkpoint、附件 hash、路径授权、依赖和敏感信息边界;
|
|
416
|
-
3. 按 mutation role 和 workspace allocation 核对交付,在声明基线上复跑定向验证和受影响回归;
|
|
417
|
-
4. 仅当 UI 交互受影响时运行最小 E2E;
|
|
418
|
-
5. provider 声明、模拟结果和静态推断在独立证据前保持 `unverified`;
|
|
419
|
-
6. 验证通过后接受候选交付;存在 `terminal_action=integrate` 的 workspace 时交给其 integration owner 自动本地集成,否则按 current workspace 或 retain 合同继续;
|
|
420
|
-
7. 同步 Ticket、Map、Evidence 和 Goal Plan,检查 Gate 是否可关闭。
|
|
332
|
+
## 6. Lead 验收
|
|
421
333
|
|
|
422
|
-
|
|
334
|
+
Lead 核对基线、路径、commit、dirty 状态、项目事实与非 E2E 结果;不接受 subagent 自报的 Evidence 或 E2E pass。required implementation 候选进入 dev-worktree candidate-merge;current implementation 由 Lead 在同一 parent branch/current workspace 做 direct-parent 验证。read-only 结果由 Lead 复核后写入对应权威工件。失败返回同一 workspace/worktree 修正或标记 blocked。
|
|
423
335
|
|
|
424
|
-
|
|
336
|
+
**完成标准**:每次写入只有一个 Ticket/owner/worktree;所有 SpecDev 状态由 Lead 落盘;派单和返回可从 Evidence 恢复。
|
|
425
337
|
|
|
426
|
-
</
|
|
338
|
+
</lead-orchestration>
|
|
427
339
|
|
|
428
340
|
<completion-control>
|
|
429
341
|
|
|
430
|
-
# Goal Plan
|
|
342
|
+
# Goal Plan 完成、证据与恢复
|
|
431
343
|
|
|
432
|
-
## 1.
|
|
433
|
-
|
|
434
|
-
Goal Plan 用紧凑摘要表达业务目标、受众、所有 Ticket 完成后的可观察终态、关键约束、非目标、权威来源、冲突规则和伪完成判据,不复制 Spec 的完整用户故事。
|
|
435
|
-
|
|
436
|
-
## 2. 整体 Definition of Done
|
|
437
|
-
|
|
438
|
-
整体完成至少覆盖:
|
|
344
|
+
## 1. 整体 Definition of Done
|
|
439
345
|
|
|
440
|
-
|
|
441
|
-
- 所有 Spec 验收合同和外部符合性要求有 Evidence;
|
|
442
|
-
- 项目类型检查、静态检查、测试、lint、构建、适用 CI 和受影响 E2E 完成,基线没有未经批准的退化;
|
|
443
|
-
- 可静默失效的关键门禁完成受控反向验证并恢复绿色;
|
|
444
|
-
- 迁移、兼容、调用点清零、监控、回滚和不可逆批准完成;
|
|
445
|
-
- 无未批准偏差、未处置高风险残余问题或伪装成通过的 `unverified` 声明;
|
|
446
|
-
- Ticket、Map、Goal Plan、Evidence、代码事实和状态一致。
|
|
346
|
+
至少要求:
|
|
447
347
|
|
|
448
|
-
|
|
348
|
+
- Spec 验收合同全部有通过 Evidence 或明确批准的 deferred;
|
|
349
|
+
- current 模式的非 cancelled Ticket 都有 implementation commit、通过的 direct-parent 验证和父分支 result SHA;required 模式都有 source commit、通过的 candidate 和父分支 result SHA;
|
|
350
|
+
- shared path、接口、数据、兼容、迁移、调用点与回滚合同闭合;
|
|
351
|
+
- 项目定向检查、受影响回归、类型检查、lint/build 和适用 E2E 无未经批准退化;
|
|
352
|
+
- change 状态、Ticket、Map、Goal Plan、Evidence 与实际 Git 状态一致;
|
|
353
|
+
- 没有未集成 implementation/source checkpoint、活动 integration candidate 或未决高影响偏差。
|
|
449
354
|
|
|
450
|
-
|
|
355
|
+
无需改动的 Ticket 必须转为 `cancelled` 并记录来源事实;不得用 Evidence-only Done 或 empty commit 关闭。
|
|
451
356
|
|
|
452
|
-
|
|
357
|
+
## 2. 两层验证
|
|
453
358
|
|
|
454
|
-
- `
|
|
455
|
-
- `
|
|
359
|
+
- `current-workspace`:current 模式 implementation owner 运行 Ticket 要求的检查,Lead 在同一 workspace 运行受影响集成/回归和适用 E2E;
|
|
360
|
+
- `source-worktree`/`parent-candidate`:required 模式由 implementation owner 和 Lead 分别运行非 E2E 与集成/E2E 检查。
|
|
456
361
|
|
|
457
|
-
|
|
362
|
+
Evidence 必须记录命令运行环境。required 模式任何在 source worktree 声称的 E2E pass 都无效;subagent 返回的测试结果在 Lead 核对前保持候选状态。
|
|
458
363
|
|
|
459
|
-
##
|
|
364
|
+
## 3. Gate 关闭
|
|
460
365
|
|
|
461
|
-
|
|
366
|
+
Lead 在每个 Gate 汇总覆盖 Evidence、接口/数据/兼容状态、candidate/result SHA、适用 E2E、反向验证、偏差、风险和批准。Gate 不以“完成若干 Ticket”作为唯一关闭条件。
|
|
462
367
|
|
|
463
|
-
##
|
|
368
|
+
## 4. 失败与恢复
|
|
464
369
|
|
|
465
|
-
|
|
370
|
+
- current/source 检查失败:保留当前 workspace 或 source worktree,继续当前 Ticket;
|
|
371
|
+
- direct-parent/candidate 冲突或检查失败:父分支不动,integration 记 `failed`,Ticket 回到 `in_progress`/`blocked`;
|
|
372
|
+
- 父 HEAD 漂移:integration 记 `stale`,从最新父分支重建并重跑;
|
|
373
|
+
- E2E required 失败:父分支不动,保留失败命令、适用 checkpoint 和恢复条件;
|
|
374
|
+
- 命中当次 Dispatch Packet/候选协议的停止条件、继续修正已无合理收益或需要新产品决定:停止受影响 Wave,按 deviation control 返回契约 owner;
|
|
375
|
+
- Lead 会话变化:读取 Goal Plan、Ticket、change worktree 状态与最新 Evidence,从最后不可变 checkpoint 恢复。
|
|
466
376
|
|
|
467
|
-
##
|
|
377
|
+
## 5. Change 完成 owner
|
|
468
378
|
|
|
469
|
-
|
|
379
|
+
Lead 是 Goal Plan change 的唯一完成 owner。没有 Goal Plan 的单 Ticket/Direct Spec 由当前 I-implement owner 按 change completion 规则完成。Archive 不补造完成证据。
|
|
470
380
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
## 7. 进度与决策回报
|
|
474
|
-
|
|
475
|
-
使用可核验状态,不使用主观百分比:
|
|
476
|
-
|
|
477
|
-
```text
|
|
478
|
-
WAVE_STATUS wave=<n> ready=<ids> active=<ids> done=<ids> blocked=<ids>
|
|
479
|
-
GATE_STATUS gate=<name> state=open|closed evidence=<paths> risks=<summary>
|
|
480
|
-
TICKET_STATUS id=<id> state=<state> evidence=<path> deviation=<none|id>
|
|
481
|
-
BLOCKER id=<id> owner=<owner> needed=<decision-or-input> impact=<scope>
|
|
482
|
-
DECISION id=<id> owner=<owner> status=pending|approved|rejected impact=<scope>
|
|
483
|
-
```
|
|
484
|
-
|
|
485
|
-
Lead Team 的交付状态格式由委派协议提供,不加入 single-session Goal Plan。
|
|
486
|
-
|
|
487
|
-
**完成标准**:进度可由权威工件恢复;普通计划由最后一个 Implement 完成,委派计划由 Lead 完成;所有通过、阻塞和未验证声明均能定位到具体 Evidence 与代码事实。
|
|
381
|
+
**完成标准**:所有通过、阻塞、取消和未验证声明均定位到权威工件、命令与 Git checkpoint;失败不会推进父分支或 Done。
|
|
488
382
|
|
|
489
383
|
</completion-control>
|
|
490
384
|
|
|
@@ -495,13 +389,17 @@ Lead Team 的交付状态格式由委派协议提供,不加入 single-session
|
|
|
495
389
|
生成该工件时,将以下字段写在文档开头的 YAML frontmatter 中:
|
|
496
390
|
|
|
497
391
|
```yaml
|
|
498
|
-
schema_version:
|
|
392
|
+
schema_version: 6
|
|
499
393
|
artifact: goal-plan
|
|
500
394
|
change: <YYYY-MM-DD-topic>
|
|
501
395
|
status: draft
|
|
502
|
-
modes: [
|
|
503
|
-
|
|
504
|
-
|
|
396
|
+
modes: []
|
|
397
|
+
orchestration: lead-directed
|
|
398
|
+
lead: <owner-or-session-locator>
|
|
399
|
+
implementation_agent_limit: 3
|
|
400
|
+
integration_attempt_limit: 3
|
|
401
|
+
ticket_workspace_policy: current
|
|
402
|
+
integration_gate: direct-parent
|
|
505
403
|
ready_for_execution: false
|
|
506
404
|
```
|
|
507
405
|
|
|
@@ -526,10 +424,11 @@ ready_for_execution: false
|
|
|
526
424
|
| 优先级 | 来源 | 负责内容 | 冲突处理 |
|
|
527
425
|
|---|---|---|---|
|
|
528
426
|
| 1 | 用户最新明确决定 | 产品取舍与批准 | 更新真正拥有该决策的工件 |
|
|
529
|
-
| 2 | `specdev/changes/{change}/ADR.md` | 当前 change
|
|
530
|
-
| 3 | `specdev/changes/{change}/
|
|
531
|
-
| 4 | `specdev/changes/{change}/
|
|
532
|
-
| 5 |
|
|
427
|
+
| 2 | `specdev/changes/{change}/ADR.md` 与 `specdev/changes/{change}/CONTEXT.md` | 当前 change 架构决定与领域语义 | 返回 “设计访谈能力” 更新真正 owner |
|
|
428
|
+
| 3 | `specdev/adr/` 与 `specdev/context/` | 已毕业的永久决定与领域知识 | 当前 change 替代时在 `specdev/changes/{change}/ADR.md` 与 `specdev/changes/{change}/LOG.md` 明示 |
|
|
429
|
+
| 4 | `specdev/changes/{change}/spec.md` | 外部行为、范围与验收 | 下游不得改写 |
|
|
430
|
+
| 5 | `specdev/changes/{change}/ticket/` | 单 Ticket 契约 | Goal Plan 只编排 |
|
|
431
|
+
| 6 | `specdev/changes/{change}/diagnosis.md` 与当前代码/运行事实 | 已验证根因、现状与可行性 | 冲突时触发偏差并返回真正 owner |
|
|
533
432
|
|
|
534
433
|
## 2. Execution Graph
|
|
535
434
|
|
|
@@ -541,14 +440,14 @@ ready_for_execution: false
|
|
|
541
440
|
|
|
542
441
|
### Waves and Ownership
|
|
543
442
|
|
|
544
|
-
| Wave | Ticket | 前置条件 | 项目写路径 | Shared owner |
|
|
443
|
+
| Wave | Ticket | 前置条件 | 项目写路径 | Shared owner | Gate/集成序号 |
|
|
545
444
|
|---|---|---|---|---|---|
|
|
546
445
|
|
|
547
446
|
### Ticket Quick Reference
|
|
548
447
|
|
|
549
|
-
| ID |
|
|
550
|
-
|
|
551
|
-
| T-01 | `specdev
|
|
448
|
+
| ID | 可观察产出 | Dependencies | Workspace | Implementation owner | E2E disposition | Evidence |
|
|
449
|
+
|---|---|---|---|---|---|---|
|
|
450
|
+
| T-01 | ... | — | `current`(required 模式为 `specdev-worktree/<change>/T-01`) | Lead / dynamic dispatch | required / not-required: reason | `specdev/changes/{change}/evidence/T-01.md` |
|
|
552
451
|
|
|
553
452
|
## 3. Gates and Completion Evidence
|
|
554
453
|
|
|
@@ -556,7 +455,7 @@ ready_for_execution: false
|
|
|
556
455
|
|
|
557
456
|
### Gates
|
|
558
457
|
|
|
559
|
-
| Gate | 开启条件 | 关闭证据 | 阻塞范围 |
|
|
458
|
+
| Gate | 开启条件 | 关闭证据 | 阻塞范围 | Lead/批准人 | 失败恢复 |
|
|
560
459
|
|---|---|---|---|---|---|
|
|
561
460
|
|
|
562
461
|
### Contract and Reference Coverage
|
|
@@ -566,41 +465,49 @@ ready_for_execution: false
|
|
|
566
465
|
|
|
567
466
|
## 4. Execution and Integration Protocol
|
|
568
467
|
|
|
569
|
-
###
|
|
468
|
+
### Lead Orchestration
|
|
570
469
|
|
|
571
|
-
|
|
|
470
|
+
| 项目 | 决定 | 事实依据 |
|
|
572
471
|
|---|---|---|
|
|
573
|
-
|
|
|
574
|
-
|
|
|
472
|
+
| Lead | `<owner-or-session-locator>` | 唯一 SpecDev 状态、Evidence 与父分支 owner |
|
|
473
|
+
| Implementation subagents | `<implementation_agent_limit>`,Lead 不计入 | Goal Plan 快照、依赖和平台能力的最小值 |
|
|
474
|
+
| Integration attempts | `<integration_attempt_limit>` | Goal Plan 创建时从 config 快照 |
|
|
475
|
+
| Read-only agents | 无 SpecDev 数字上限 | review/research/test-observation,不写状态 |
|
|
476
|
+
| Dispatch | execution-time dynamic | provider/模型/派单按 Ticket 事实选择 |
|
|
575
477
|
|
|
576
|
-
### Ticket
|
|
478
|
+
### Ticket Workspace and Integration
|
|
577
479
|
|
|
578
|
-
| Ticket |
|
|
579
|
-
|
|
480
|
+
| Ticket | Parent/base | Workspace/branch | Source checks | Implementation commit | Integration checks/E2E | Parent result |
|
|
481
|
+
|---|---|---|---|---|---|---|
|
|
482
|
+
|
|
483
|
+
当 `ticket_workspace_policy: current` 时,Ticket 必须严格串行。Lead 每次只允许一个 implementation owner 写入当前 workspace;完成非 E2E 检查并形成 commit 后,Lead 在同一父分支/current workspace 运行适用集成检查和 E2E,验证通过后将该 Ticket 的 `result_sha` 记录为其 implementation commit,再开始下一个 Ticket。不得创建 source/candidate worktree。
|
|
484
|
+
|
|
485
|
+
当 `ticket_workspace_policy: required` 时,Ticket 使用独立 source worktree;source worktree 不运行 E2E,Lead 在最新父分支的 candidate 状态运行集成检查和适用 E2E,通过且父 HEAD 未漂移后才推进父分支。
|
|
580
486
|
|
|
581
487
|
### Authorization Matrix
|
|
582
488
|
|
|
583
489
|
| 动作 | 状态 | 目标与条件 |
|
|
584
490
|
|---|---|---|
|
|
585
|
-
|
|
|
586
|
-
|
|
|
587
|
-
|
|
|
588
|
-
|
|
|
589
|
-
|
|
|
491
|
+
| Current workspace Ticket changes | allowed / not-authorized | 仅 current 模式;严格串行,单一 implementation writer |
|
|
492
|
+
| Ticket worktree local changes | allowed / not-authorized | 仅 required 模式;限 writable/shared owner 合同 |
|
|
493
|
+
| Implementation commit | allowed / not-authorized | 每 Ticket 必需;缺失则 Plan blocked |
|
|
494
|
+
| Local direct-parent verification and parent update | allowed / not-authorized | 仅 current 模式;Lead 核对 Ticket commit 后继续 |
|
|
495
|
+
| Local candidate integration and parent update | allowed / not-authorized | 仅 required 模式;Lead-only;缺失则 Plan blocked |
|
|
496
|
+
| Push / PR / remote merge | allowed / not-authorized | 不从本计划本地授权继承 |
|
|
497
|
+
| Branch/worktree cleanup | allowed / not-authorized | 成功集成不自动继承 |
|
|
498
|
+
| Deploy / migration / production actions | allowed / not-authorized | 逐动作、目标和条件 |
|
|
590
499
|
|
|
591
|
-
### Evidence Return
|
|
500
|
+
### Evidence Return
|
|
592
501
|
|
|
593
|
-
|
|
502
|
+
subagent 只返回候选事实与 commit;Lead 独立核对并写 Evidence、状态和最终验收。
|
|
594
503
|
|
|
595
504
|
## 5. Constraints, Risk and Recovery
|
|
596
505
|
|
|
597
506
|
### Non-negotiable Constraints
|
|
598
507
|
|
|
599
|
-
每条包含来源和违反后果;局部实现自由进入 Guidance。
|
|
600
|
-
|
|
601
508
|
### Verification Integrity
|
|
602
509
|
|
|
603
|
-
|
|
510
|
+
记录判卷接缝、基线、禁止的伪绿色方式,以及 current/direct-parent 或 source/candidate 两层验证边界。
|
|
604
511
|
|
|
605
512
|
### Migration or Release Sequence
|
|
606
513
|
|
|
@@ -614,93 +521,20 @@ ready_for_execution: false
|
|
|
614
521
|
|
|
615
522
|
### Current Status
|
|
616
523
|
|
|
617
|
-
记录 Wave/Gate、Ticket
|
|
524
|
+
记录 Wave/Gate、Ticket、implementation/source、适用 candidate 和 result SHA、最近验证和未验证项;不使用主观百分比。
|
|
618
525
|
|
|
619
526
|
### Pending Decisions and Blockers
|
|
620
527
|
|
|
621
|
-
记录失败命令、已通过行为、owner 和恢复条件。
|
|
622
|
-
|
|
623
528
|
### Resume Protocol
|
|
624
529
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
### Reporting Format
|
|
530
|
+
恢复时读取 Goal Plan、当前 Ticket、change workspace 状态和最新 Evidence;从最后通过的父分支 result 或待修正 implementation/source checkpoint 继续。
|
|
628
531
|
|
|
629
532
|
## Assumptions
|
|
630
533
|
|
|
631
|
-
|
|
534
|
+
只记录低影响且可验证的假设。存在高影响假设时 `ready_for_execution` 必须为 `false`。
|
|
632
535
|
|
|
633
536
|
</goal-plan-template>
|
|
634
537
|
|
|
635
|
-
<workspace-execution-template>
|
|
636
|
-
|
|
637
|
-
## Isolated Workspace Addendum
|
|
638
|
-
|
|
639
|
-
只在 `workspace_strategy: worktree` 或 `workspace_strategy: mixed` 时加入。它独立于 Agent Team:单会话和 Lead Team 都可加载本附录。
|
|
640
|
-
|
|
641
|
-
### Workspace Decision
|
|
642
|
-
|
|
643
|
-
| 字段 | 值 |
|
|
644
|
-
|---|---|
|
|
645
|
-
| Strategy | worktree / mixed |
|
|
646
|
-
| Trigger | parallel-write / protect-local-state / disposable-experiment / background-resume / provider-requirement / user-requested |
|
|
647
|
-
| Current-workspace writer | `<primary-session-or-lead>` |
|
|
648
|
-
| Integration serialization | 每次只允许一个 integration owner 修改目标父分支 |
|
|
649
|
-
|
|
650
|
-
### Per-Ticket Workspace Allocation
|
|
651
|
-
|
|
652
|
-
| Ticket | Trigger and evidence | Implementation owner | Integration owner | Provider | Base SHA | Parent branch | Branch / workspace ref | Terminal action |
|
|
653
|
-
|---|---|---|---|---|---|---|---|---|
|
|
654
|
-
| T-01 | `<allowed-trigger>: <observed-fact>` | `<owner>` | `<owner>` | git / native / external | `<immutable-sha>` | `<parent-branch>` | `<branch>` / `<portable-locator>` | integrate / retain |
|
|
655
|
-
|
|
656
|
-
### Local Integration Authorization
|
|
657
|
-
|
|
658
|
-
`terminal_action=integrate` 持久授权 integration owner 执行本 Ticket 的本地 fast-forward,或在分叉时完成 `git add`、`git merge --continue` 和一次集成专用 merge commit。普通实现提交、push、PR、远端 merge、部署、迁移以及删除 branch/worktree 不从该授权继承。
|
|
659
|
-
|
|
660
|
-
来源 checkpoint、路径审计和验证通过后才可从 `review` 进入 `integrating`。集成成功写入 result SHA 与 Evidence;失败时中止正在进行的 merge、保留来源 workspace,并记录 blocker 和恢复条件。
|
|
661
|
-
|
|
662
|
-
</workspace-execution-template>
|
|
663
|
-
|
|
664
|
-
<delegated-execution-template>
|
|
665
|
-
|
|
666
|
-
## Delegated Execution Addendum
|
|
667
|
-
|
|
668
|
-
### Delivery Contract
|
|
669
|
-
|
|
670
|
-
| 字段 | 值 |
|
|
671
|
-
|---|---|
|
|
672
|
-
| Execution model | native-subagent / external-web-subagent |
|
|
673
|
-
| Lead / Provider | `<owner>` / `<provider>` |
|
|
674
|
-
| Repository / Source baseline | `<repository-or-local>` / `<immutable-checkpoint>` |
|
|
675
|
-
| Checkpoint policy | immutable SHA / equivalent fixed baseline |
|
|
676
|
-
| Source delivery | repository-url / source-package / combination |
|
|
677
|
-
| Max concurrency / corrections | `<n>` / `3` |
|
|
678
|
-
| Review | standards + spec + Lead verification + conditional E2E |
|
|
679
|
-
| Mutation policy | read-only / lead-write / worker-write;worker-write 必须引用隔离 workspace |
|
|
680
|
-
|
|
681
|
-
### Per-Ticket Dispatch Packets
|
|
682
|
-
|
|
683
|
-
#### Dispatch: T-01
|
|
684
|
-
|
|
685
|
-
- **Goal / observable result:**
|
|
686
|
-
- **Priority on conflict:** correctness > contract completeness > speed,或当前项目裁决
|
|
687
|
-
- **Implement / Ticket:** “实现阶段”;`specdev/changes/{change}/ticket/01-<name>.md`
|
|
688
|
-
- **Authority / dependencies:** 相关合同、ADR/CONTEXT、已完成依赖 Evidence
|
|
689
|
-
- **Wave / Gate / hard constraints:**
|
|
690
|
-
- **Writable / read-only / shared owner:**
|
|
691
|
-
- **Mutation role / workspace allocation:** read-only / lead-write / worker-write;current 或对应 isolated allocation
|
|
692
|
-
- **Baseline / workspace or session locator / package hash:**
|
|
693
|
-
- **Preflight receipt:** 在 `specdev/changes/{change}/evidence/T-01.md` 记录目标、顺序、最大风险和基线差异,不超过 10 行
|
|
694
|
-
- **Verification / baseline / reverse check:**
|
|
695
|
-
- **Authorization / deviation / correction limit:**
|
|
696
|
-
- **Return:** 状态、Evidence、locator、最终 checkpoint、commit/PR、未验证项、待 Lead E2E
|
|
697
|
-
|
|
698
|
-
### Candidate Delivery Return and Lead Acceptance
|
|
699
|
-
|
|
700
|
-
Worker 将 Ticket 推进到 `review` 并返回候选交付;Lead 负责独立验证、适用 E2E、候选验收和 Gate 判断。Git 集成只在独立 workspace 合同指定 Lead 为 integration owner 时发生;达到修正上限时保留最后可信 checkpoint、失败命令、已通过行为和恢复条件。
|
|
701
|
-
|
|
702
|
-
</delegated-execution-template>
|
|
703
|
-
|
|
704
538
|
<artifact-contract>
|
|
705
539
|
|
|
706
540
|
# 工件职责与权威裁决
|
|
@@ -783,39 +617,37 @@ Change CONTEXT/ADR 是 active change 内的执行权威,不是 workflow 级永
|
|
|
783
617
|
|
|
784
618
|
# 路径所有权与并发规则
|
|
785
619
|
|
|
786
|
-
|
|
620
|
+
路径所有权是逻辑写入边界;worktree 是物理隔离边界,两者不能互相替代。
|
|
787
621
|
|
|
788
622
|
## 1. 四类路径
|
|
789
623
|
|
|
790
|
-
- `expected_changes
|
|
791
|
-
- `writable_paths
|
|
792
|
-
- `read_only_paths
|
|
793
|
-
- `shared_paths`:多个 Ticket
|
|
624
|
+
- `expected_changes`:导航预测;
|
|
625
|
+
- `writable_paths`:当前 Ticket implementation owner 可写的硬边界;
|
|
626
|
+
- `read_only_paths`:只读上下文;
|
|
627
|
+
- `shared_paths`:多个 Ticket 可能触达且必须有唯一 owner 的项目路径。
|
|
794
628
|
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
```yaml
|
|
798
|
-
expected_changes: ["src/auth/session.ts"]
|
|
799
|
-
writable_paths: ["src/auth/**"]
|
|
800
|
-
read_only_paths: ["src/users/**"]
|
|
801
|
-
shared_paths: ["package.json"]
|
|
802
|
-
```
|
|
629
|
+
所有项目路径使用项目根相对路径。根依赖清单、锁文件、根导出、共享 schema、迁移索引、全局路由和跨 Ticket 合同默认视为 shared。
|
|
803
630
|
|
|
804
631
|
## 2. 所有权规则
|
|
805
632
|
|
|
806
|
-
1. 可能并行的 Ticket,其
|
|
807
|
-
2.
|
|
808
|
-
3.
|
|
809
|
-
4.
|
|
810
|
-
5.
|
|
811
|
-
6.
|
|
812
|
-
|
|
633
|
+
1. 可能并行的 Ticket,其 writable paths 不得相交;glob 按覆盖关系判断。
|
|
634
|
+
2. shared path 只由专用 owner Ticket 修改;消费者 Ticket 只读。Lead 负责集成,不以冲突解决替代 shared owner。
|
|
635
|
+
3. implementation subagent 只写其 Packet 与 Ticket 授权路径;Lead 自行实现也受同一边界约束。
|
|
636
|
+
4. review/research/test-observation agent 只读项目与 SpecDev 工件。
|
|
637
|
+
5. 越界前停止并按 deviation control 提出 ownership change;不得先改后报。
|
|
638
|
+
6. 上游 Ticket 改变目录/合同后,下游基于已集成父分支重新解析路径和 preflight。
|
|
639
|
+
|
|
640
|
+
## 3. Ticket workspace strategy
|
|
641
|
+
|
|
642
|
+
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。
|
|
813
643
|
|
|
814
|
-
|
|
644
|
+
workspace/implementation owner 可以是 Lead 或动态 implementation subagent;integration owner 固定为 Lead。current 模式 Lead 在父分支直接验收和推进,required 模式 Lead 建立 parent-candidate、运行适用 E2E 并推进父分支。required 生命周期由 下方 `<dev-worktree>` 标签 管理,current 生命周期由 I-implement 的 direct-parent 规则管理。
|
|
815
645
|
|
|
816
|
-
|
|
646
|
+
## 4. 并发
|
|
817
647
|
|
|
818
|
-
|
|
648
|
+
required 模式 implementation subagent 上限取 Goal Plan、config 和平台能力共同约束,Lead 不计入。current 模式保持单 writer 串行安全不变量,Ticket 严格串行。review/research/test-observation agent 不设置 SpecDev 数字上限,但 Lead 必须避免重复工作与可变环境争用。
|
|
649
|
+
|
|
650
|
+
**完成标准**:每个项目写入映射到唯一 Ticket、owner 和来源 worktree;shared 与父分支写入 owner 唯一。
|
|
819
651
|
|
|
820
652
|
</path-ownership>
|
|
821
653
|
|
|
@@ -823,61 +655,55 @@ Worktree 只在存在可观察隔离需求时使用:并行写入、保护当
|
|
|
823
655
|
|
|
824
656
|
# 证据与验证规范
|
|
825
657
|
|
|
826
|
-
|
|
658
|
+
验证回答“怎样证明”,Evidence 记录“实际运行了什么、在哪个状态运行、结果和残余风险是什么”。
|
|
827
659
|
|
|
828
660
|
## 1. 验证矩阵
|
|
829
661
|
|
|
830
|
-
|
|
662
|
+
每行绑定行为、合同或风险,并标记环境:
|
|
831
663
|
|
|
832
|
-
| 行为或风险 |
|
|
833
|
-
|
|
834
|
-
|
|
|
835
|
-
|
|
|
836
|
-
|
|
|
664
|
+
| 行为或风险 | 接缝 | 命令/方法 | 环境 | 预期 | Evidence |
|
|
665
|
+
|---|---|---|---|---|---|
|
|
666
|
+
| 正常/失败路径 | 公共接口或稳定接缝 | 定向测试 | current-workspace 或 source-worktree | 合同成立 | Ticket Evidence |
|
|
667
|
+
| 跨模块回归 | 集成接缝 | 回归命令 | current-workspace 或 parent-candidate | 组合状态成立 | Ticket Evidence |
|
|
668
|
+
| E2E required | 真实端到端边界 | 场景步骤 | current-workspace 或 parent-candidate | 外部行为成立 | Ticket Evidence |
|
|
669
|
+
|
|
670
|
+
## 2. 两层验证
|
|
671
|
+
|
|
672
|
+
### Current workspace
|
|
673
|
+
|
|
674
|
+
current 模式的 implementation owner 在当前父分支和当前 workspace 工作。Ticket 必须严格串行,workspace clean 后形成非空 implementation commit;Lead 在同一 workspace 执行适用集成/回归和 E2E,并在父 HEAD 未漂移时将 Ticket commit 记录为 result SHA。
|
|
837
675
|
|
|
838
|
-
|
|
676
|
+
### Source-worktree
|
|
839
677
|
|
|
840
|
-
|
|
678
|
+
implementation owner 运行最接近目标行为的单元/组件测试、静态分析、类型、lint/build 等适用非 E2E 检查。来源实现必须在 clean worktree 形成 commit。任何 source-worktree E2E pass 声明无效。
|
|
841
679
|
|
|
842
|
-
|
|
680
|
+
### Parent-candidate
|
|
843
681
|
|
|
844
|
-
|
|
845
|
-
2. 稳定接缝上的单元测试;
|
|
846
|
-
3. 类型检查、静态分析、lint 和构建;
|
|
847
|
-
4. 可重复手动步骤、截图或查询结果;
|
|
848
|
-
5. 代码阅读推断。
|
|
682
|
+
required 模式下,Lead 在最新父分支与 source commit 的 candidate 状态运行受影响集成/回归、项目父状态检查和适用 E2E。E2E 由实际跨边界风险决定,不限于 UI;not-required 必须写理由。required E2E 未运行或失败时不得推进父分支。
|
|
849
683
|
|
|
850
|
-
|
|
684
|
+
### Direct Spec
|
|
851
685
|
|
|
852
|
-
|
|
686
|
+
获批 Direct Spec 不创建 Ticket worktree 或 candidate。Lead 在 current workspace 记录实施前基线,运行轻量合同要求的定向检查、适用回归与 E2E,并记录最终 checkpoint、dirty 状态、运行环境、命令、退出状态和未运行原因。E2E 仍只由 Lead 执行;不得为套用两层验证而伪造 Ticket、source/candidate/result 或父分支推进证据。
|
|
853
687
|
|
|
854
|
-
|
|
688
|
+
低层证据不能替代明确要求的外部行为证据。高风险迁移还需要 dry-run、调用点扫描、数据核对、监控或恢复演练。
|
|
855
689
|
|
|
856
|
-
|
|
690
|
+
## 3. Agent 声明
|
|
857
691
|
|
|
858
|
-
-
|
|
859
|
-
- 基线已存在的失败;
|
|
860
|
-
- 环境、权限或基础设施失败;
|
|
861
|
-
- 验证本身无效或无法观察目标行为。
|
|
692
|
+
subagent 只返回候选命令与结果,不写 Evidence。Lead 重读 workspace/Git、必要时复跑或核对输出后落盘;外部 provider 自报、截图、模拟和推断在此之前标记 `unverified`。review/research/test-observation agent 不拥有 E2E Gate。
|
|
862
693
|
|
|
863
|
-
|
|
694
|
+
## 4. 失败分类与完整性
|
|
864
695
|
|
|
865
|
-
|
|
696
|
+
失败分类为本 Ticket 新失败、基线既有失败、环境/权限/基础设施失败、无效验证或 candidate stale。不得通过跳过、放宽断言、吞错、删除用例或迁移验证位置制造绿色。
|
|
866
697
|
|
|
867
|
-
|
|
698
|
+
受控反向验证只用于可能静默通过的关键门禁:证明检查能在目标风险出现时失败,再恢复并重跑。普通测试不为形式执行破坏性操作。
|
|
868
699
|
|
|
869
|
-
|
|
870
|
-
- 实际修改的项目路径;
|
|
871
|
-
- 每条命令、退出状态和结果摘要;
|
|
872
|
-
- 每条验收合同的证据映射;
|
|
873
|
-
- 未运行项与原因;
|
|
874
|
-
- 新失败、既有失败和环境失败;
|
|
875
|
-
- 偏差及批准;
|
|
876
|
-
- 残余风险;
|
|
877
|
-
- worktree、提交或 PR 引用;
|
|
878
|
-
- 最终结论。
|
|
700
|
+
## 5. Evidence 最低内容
|
|
879
701
|
|
|
880
|
-
|
|
702
|
+
每个 Ticket Evidence 至少包含:Lead、Dispatch/返回(若有)、workspace 策略、base/source/result SHA、candidate 字段(required 模式适用,current 模式明确不适用)、实际路径、每条命令/环境/退出状态、合同映射、双轴审查、E2E disposition、未运行项、失败分类、偏差、残余风险和父分支重读结果。
|
|
703
|
+
|
|
704
|
+
required Ticket Done 必须有 source commit、通过 candidate、父分支 result 与 Lead Evidence;current Ticket Done 必须有 implementation commit、通过 direct-parent 验证、父分支 result 与 Lead Evidence。无法运行 required 验证、存在未批准偏差、父分支未包含 Ticket commit 或 Evidence 不完整时不得 Done。
|
|
705
|
+
|
|
706
|
+
Direct Spec Evidence 至少包含:用户批准与轻量合同、Lead、实施前/最终 checkpoint、实际路径、定向/回归/E2E 命令及环境、验收映射、未运行项、偏差、残余风险和提交授权状态。
|
|
881
707
|
|
|
882
708
|
</evidence-and-verification>
|
|
883
709
|
|
|
@@ -925,7 +751,7 @@ E2E 仅在变更影响用户界面交互时加入验证矩阵。普通执行由
|
|
|
925
751
|
|
|
926
752
|
- 未批准的 ticket、spec、architecture 或 release 偏差不得继续实现。
|
|
927
753
|
- 不得通过扩大 `writable_paths`、删除测试、降低断言或把风险改写成“已知限制”来绕过停止。
|
|
928
|
-
-
|
|
754
|
+
- 偏差影响并行执行、source checkpoint 或 candidate 集成时,Lead 必须暂停受影响 Wave,重新计算路径所有权、依赖、Gate 与父分支顺序;任何 subagent 都不能自行改写上层合同。
|
|
929
755
|
|
|
930
756
|
</deviation-control>
|
|
931
757
|
|
|
@@ -933,38 +759,35 @@ E2E 仅在变更影响用户界面交互时加入验证矩阵。普通执行由
|
|
|
933
759
|
|
|
934
760
|
# Change Completion
|
|
935
761
|
|
|
936
|
-
本规则是 change 从 active/blocked 转为 completed
|
|
762
|
+
本规则是 change 从 active/blocked 转为 completed 的唯一合同。
|
|
937
763
|
|
|
938
764
|
## 完成门
|
|
939
765
|
|
|
940
|
-
一个 change
|
|
766
|
+
一个 change 只有同时满足以下条件才能 completed:
|
|
941
767
|
|
|
942
|
-
1. 所有计划内 Ticket 为
|
|
943
|
-
2.
|
|
944
|
-
3.
|
|
945
|
-
4.
|
|
946
|
-
5.
|
|
947
|
-
6.
|
|
768
|
+
1. 所有计划内 Ticket 为 done,或因权威事实无需改动而记录为 cancelled;Direct Spec/非实现流程有等价验收。
|
|
769
|
+
2. required Ticket 有 source commit、passed candidate、父分支 result SHA,且父分支包含 source commit;current Ticket 有 implementation commit、passed direct-parent 验证和父分支 result SHA;对应 workspace 记录均为完成状态。
|
|
770
|
+
3. 每个行为有 Lead Evidence,全部 Spec 合同与 Goal Gate 可定位。
|
|
771
|
+
4. current Ticket 的 current-workspace 检查/回归和适用 E2E,或 required Ticket 的 source-worktree 非 E2E 检查、parent-candidate 集成/回归和 required E2E 已通过;not-required 有理由。
|
|
772
|
+
5. 迁移、发布、监控、恢复和不可逆批准已完成或明确不适用。
|
|
773
|
+
6. 没有未批准 deviation、blocker、unverified、活动 candidate 或未集成 source checkpoint。
|
|
774
|
+
7. Ticket、Map、Goal Plan、Evidence、change status 与实际 Git 一致。
|
|
775
|
+
|
|
776
|
+
Evidence-only Done 和 empty commit 不满足完成门。
|
|
948
777
|
|
|
949
778
|
## 转换 Owner
|
|
950
779
|
|
|
951
|
-
- Goal Plan
|
|
952
|
-
-
|
|
953
|
-
-
|
|
954
|
-
- 非实现型终点:最后一个拥有最终验收工件的 Work 使用本规则完成转换。
|
|
780
|
+
- 有 Goal Plan:其唯一 Lead 在关闭最后 Gate 后拥有转换;
|
|
781
|
+
- 无 Goal Plan 的 Ticket/Direct Spec:当前 I-implement 主会话 owner 拥有转换;
|
|
782
|
+
- 非实现型终点:最终验收工件 owner 使用本规则。
|
|
955
783
|
|
|
956
|
-
Owner 原子更新 `specdev/changes/{change}/.status.json` 的 `change_status`、`completed_at`、`updated_at` 和 `current_work
|
|
784
|
+
Owner 原子更新 `specdev/changes/{change}/.status.json` 的 `change_status`、`completed_at`、`updated_at` 和 `current_work`,然后重读。全局 status 只维护 active/archived 索引。
|
|
957
785
|
|
|
958
786
|
## 远程来源与归档
|
|
959
787
|
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
## 完成标准
|
|
788
|
+
远程动作不参与本地完成判定。Triage 为 `pending-close`/`close-failed` 时先 reconcile;`closed`、`waived` 或 `not-applicable` 才允许 Archive。归档后工件只读。
|
|
963
789
|
|
|
964
|
-
|
|
965
|
-
- 当前 change 只有一个条件命中的转换 owner;
|
|
966
|
-
- 远程失败不会把 completed 改回 active;
|
|
967
|
-
- Archive 不接收尚未 reconcile 或 waive 的远程来源。
|
|
790
|
+
**完成标准**:完成声明可由本地工件、Git 与验证重建;只有一个 owner 命中;失败 candidate 不污染父分支。
|
|
968
791
|
|
|
969
792
|
</change-completion>
|
|
970
793
|
|
|
@@ -1025,77 +848,107 @@ Owner 原子更新 `specdev/changes/{change}/.status.json` 的 `change_status`
|
|
|
1025
848
|
|
|
1026
849
|
<dev-worktree>
|
|
1027
850
|
|
|
1028
|
-
#
|
|
851
|
+
# Dev Worktree
|
|
852
|
+
|
|
853
|
+
本 Skill 由 T-tickets/P-goal-plan/I-implement 和 P-prototype 复用。`purpose=ticket` 仅在 Goal Plan 选择 `required` 时使用完整 source → candidate → parent 状态机;`current` Ticket 不调用本 Skill。`purpose=prototype` 只使用调用方批准的临时生命周期。
|
|
854
|
+
|
|
855
|
+
## 输入
|
|
1029
856
|
|
|
1030
|
-
|
|
857
|
+
- `operation=create | restore | finalize | remove`;
|
|
858
|
+
- `purpose=ticket | prototype`;
|
|
859
|
+
- repository、父分支、`base_sha`、branch、portable workspace locator;
|
|
860
|
+
- workspace、implementation 和 integration owner;
|
|
861
|
+
- 允许动作、路径合同、验证合同、调用方状态记录位置。
|
|
1031
862
|
|
|
1032
|
-
|
|
1033
|
-
- 只读调查、Agent Team 本身和没有其他隔离事实的顺序执行默认共用当前工作区。
|
|
1034
|
-
- 调用方必须明确 trigger、workspace owner、implementation owner、integration owner、固定基线、父分支、工作项 ID、持久化 owner 和允许的结束动作。
|
|
1035
|
-
- Coordination 与 workspace 正交:`single-session` 可以使用本 Skill;`lead-team` 不自动使用。Current workspace 下 Worker 只读;Worker 写入必须绑定本 Skill 创建的独立 workspace。
|
|
1036
|
-
- 平台原生 worktree 优先;不可用时使用 Git worktree。
|
|
863
|
+
required Ticket 还必须提供 Ready Ticket、Goal Plan(若存在)、Evidence 路径、implementation commit 与本地 candidate integration/父分支更新授权。缺失时返回 blocked;current Ticket 应按 I-implement 的 direct-parent 规则执行。
|
|
1037
864
|
|
|
1038
|
-
##
|
|
865
|
+
## 1. 创建或恢复
|
|
1039
866
|
|
|
1040
|
-
|
|
1041
|
-
2. implementation owner 完成后返回工作项状态、Evidence/record 路径、`workspace_ref`、不可变 source checkpoint、commit 或 PR 引用和未验证项;Ticket worktree 从 `active` 更新为 `review`。
|
|
1042
|
-
3. `terminal_action=integrate` 时 integration owner 自动加载 下方 `<dev-worktree-finalize>` 标签;`retain` 保持 review。一次性原型只评估和清理,不合入生产分支。
|
|
867
|
+
`operation=create` 时加载 下方 `<dev-worktree-create>` 标签。Ticket 使用 `specdev-worktree/<ticket-id>`;同一 Ticket 只存在一个来源 worktree。`operation=restore` 时重读实际 Git worktree/branch/tip/dirty 状态并与调用方记录核对,漂移时停止。
|
|
1043
868
|
|
|
1044
|
-
|
|
869
|
+
**完成标准**:来源基线、branch、locator、owners 和实际 Git 状态一致;现有用户改动未被覆盖。
|
|
1045
870
|
|
|
1046
|
-
##
|
|
871
|
+
## 2. 来源实现门
|
|
1047
872
|
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
873
|
+
implementation owner 只在来源 worktree 修改授权项目路径,运行 Ticket 要求的单元、组件、静态、类型、lint/build 等非 E2E 检查。进入 `review` 前,worktree 必须 clean,branch tip 必须是已授权的 `source_checkpoint` commit,实际 diff 必须符合路径合同。
|
|
874
|
+
|
|
875
|
+
**完成标准**:source checkpoint 不可变且可达;来源 worktree 没有 E2E pass 声明。
|
|
876
|
+
|
|
877
|
+
## 3. 候选合并与父分支推进
|
|
878
|
+
|
|
879
|
+
`operation=finalize` 仅由 Lead/integration owner 调用,并加载 下方 `<dev-worktree-finalize>` 标签。Lead 在独立 parent-candidate checkout 组合最新父分支与 source checkpoint,运行集成检查和适用 E2E,通过后才推进父分支。
|
|
880
|
+
|
|
881
|
+
本地 candidate checkout/branch 的创建、重建和回收属于已授权 local candidate integration;来源 branch/worktree 的删除仍需要独立 cleanup 授权。push、PR、remote merge、deploy、migration 和生产动作不从本 Skill 继承。
|
|
882
|
+
|
|
883
|
+
**完成标准**:Ticket `integrated` 时父 HEAD 精确等于记录的 result SHA,并包含 source checkpoint;失败或 stale 时父分支未变化。后续 `removed` 只表示来源 branch/worktree 已清理,不撤销该集成事实。
|
|
884
|
+
|
|
885
|
+
## 4. 移除
|
|
886
|
+
|
|
887
|
+
`operation=remove` 先验证 Ticket 已 `integrated` 或 prototype 已结束、目标 worktree clean、checkpoint 可恢复且删除目标精确。只有明确 cleanup 授权时删除来源 branch/worktree;强制删除需要单独确认。删除后重读 `git worktree list` 与 refs,并只把调用方生命周期状态更新为 `removed`;`base_sha`、source checkpoint、candidate/result、验证、E2E 与 Evidence 字段必须原样保留。
|
|
888
|
+
|
|
889
|
+
**完成标准**:只删除精确授权目标;失败保留现场与恢复命令。
|
|
890
|
+
|
|
891
|
+
## 固定规则
|
|
892
|
+
|
|
893
|
+
- Agent Team 不决定 worktree;Ticket 切片本身决定来源 worktree;
|
|
894
|
+
- Ticket E2E 只在 Lead-owned parent-candidate checkout 运行;
|
|
895
|
+
- 每个 Done Ticket 必须有 source commit 与父分支 result,worktree 状态为 `integrated` 或其清理后终态 `removed`;
|
|
896
|
+
- candidate 失败保留来源 worktree 修正,父分支不动;
|
|
897
|
+
- 成功集成不自动清理来源 branch/worktree。
|
|
1054
898
|
|
|
1055
899
|
</dev-worktree>
|
|
1056
900
|
|
|
1057
901
|
<dev-worktree-create>
|
|
1058
902
|
|
|
1059
|
-
#
|
|
903
|
+
# Create Or Restore Worktree
|
|
904
|
+
|
|
905
|
+
## Ticket 前置条件
|
|
906
|
+
|
|
907
|
+
- Ticket Ready,项目根是有效 Git repository,父分支和 `base_sha` 可解析;
|
|
908
|
+
- implementation commit 与 local candidate integration/父分支更新已授权;
|
|
909
|
+
- workspace、implementation、integration owner 唯一;integration owner 必须为 Lead;
|
|
910
|
+
- `specdev-worktree/` 已由 Speculo init 加入项目 `.gitignore`;
|
|
911
|
+
- 目标 branch/worktree 不覆盖现有用户 workspace,路径合同无冲突。
|
|
1060
912
|
|
|
1061
|
-
|
|
913
|
+
Prototype 只要求调用方已记录本次临时 branch/worktree 授权、问题、owner、locator 和清理策略;它不写 Ticket worktree 状态。
|
|
1062
914
|
|
|
1063
|
-
|
|
1064
|
-
- 调用方已记录允许的 trigger 及其事实。`parallel-write` 还要求 `specdev/config.json` 中 `git.worktree_for_parallel: true`;一次性原型要求 P-prototype 已取得本次临时 worktree 授权。
|
|
1065
|
-
- 调用方已指定 workspace owner、implementation owner、integration owner、父分支、工作项 ID、持久化 owner、`integrate | retain`,并固定 `base_sha`;并行 Ticket 共用同一基线。
|
|
915
|
+
## 创建 Ticket 来源 worktree
|
|
1066
916
|
|
|
1067
|
-
|
|
917
|
+
1. 重读父分支 HEAD、工作树、现有 worktrees 与 refs;父 HEAD 与计划基线不一致时由 Lead决定更新 `base_sha` 或阻塞;
|
|
918
|
+
2. 固定 branch `speculo/<change>/<ticket-id>` 与 locator `specdev-worktree/<ticket-id>`;
|
|
919
|
+
3. 确认目标 branch/path 不存在,或其实际记录精确匹配当前 Ticket;
|
|
920
|
+
4. 从 `base_sha` 创建 Git worktree,不复用其他 Ticket/原型目录;
|
|
921
|
+
5. 在来源 worktree 读取项目 Agent 指令、依赖、构建与路径合同;
|
|
922
|
+
6. 安装实际需要的依赖,运行最小非 E2E 基线;
|
|
923
|
+
7. Lead 写入 `specdev/changes/{change}/.status.json`,状态为 `active`。
|
|
1068
924
|
|
|
1069
|
-
|
|
1070
|
-
2. 读取调用方拥有的持久化记录:Ticket 使用 `specdev/changes/{change}/.status.json` 的 `worktrees`;原型使用 `specdev/changes/{change}/prototypes/{prototype-id}/record.md`。若已有可恢复记录,Git provider 必须在 `git worktree list --porcelain` 中匹配固定路径、分支与 `base_sha`;native/external 由对应 provider 解析 opaque locator。一致则恢复,任一不一致停止。
|
|
1071
|
-
3. 否则优先调用平台原生 worktree 能力。使用 native/external 时保存 provider 返回的可迁移 locator;不可用时进入 Git fallback。
|
|
1072
|
-
4. Git fallback 前确认项目根 `.gitignore` 已包含 `specdev-worktree/` 或等价根模式。缺失时停止并提示重新运行当前版本 `speculo init`,不在本 Skill 内修改 `.gitignore`。
|
|
1073
|
-
5. Git fallback 固定 `physical_path = <project-root>/specdev-worktree/<work-item-id>`、`workspace_ref = specdev-worktree/<work-item-id>`,从 `base_sha` 执行 `git worktree add -b <work-item-branch> <physical-path> <base-sha>`。已存在但未与同一记录和 Git 注册匹配的目标路径一律阻塞。
|
|
1074
|
-
6. 分支使用 `speculo/<change>/<work-item-id>`;现有分支未能匹配记录时停止。
|
|
1075
|
-
7. 安装项目所需依赖,运行最小基线检查。E2E 不属于 implementation owner 的创建基线。
|
|
1076
|
-
8. Ticket 将记录写入 `worktrees`;`owner` 保持 implementation owner 的兼容含义:
|
|
925
|
+
初始记录:
|
|
1077
926
|
|
|
1078
927
|
```json
|
|
1079
928
|
{
|
|
1080
929
|
"ticket_id": "T-01",
|
|
1081
|
-
"owner": "
|
|
1082
|
-
"
|
|
930
|
+
"owner": "lead",
|
|
931
|
+
"implementation_owner": "lead-or-dynamic-agent",
|
|
932
|
+
"integration_owner": "lead",
|
|
1083
933
|
"provider": "git",
|
|
1084
|
-
"base_sha": "<sha>",
|
|
934
|
+
"base_sha": "<immutable-sha>",
|
|
1085
935
|
"parent_branch": "<parent-branch>",
|
|
1086
936
|
"branch": "speculo/<change>/T-01",
|
|
1087
937
|
"workspace_ref": "specdev-worktree/T-01",
|
|
1088
|
-
"terminal_action": "integrate",
|
|
1089
938
|
"source_checkpoint": null,
|
|
1090
939
|
"integration": {
|
|
1091
940
|
"status": "pending",
|
|
1092
941
|
"parent_before_sha": null,
|
|
1093
942
|
"source_sha": null,
|
|
943
|
+
"candidate_sha": null,
|
|
944
|
+
"candidate_branch": null,
|
|
945
|
+
"candidate_workspace_ref": null,
|
|
1094
946
|
"result_sha": null,
|
|
1095
947
|
"method": null,
|
|
1096
948
|
"conflict_paths": [],
|
|
1097
949
|
"verification": "pending",
|
|
1098
|
-
"
|
|
950
|
+
"e2e": {"required": false, "status": "not-required", "evidence": null},
|
|
951
|
+
"evidence": "specdev/changes/<change>/evidence/T-01.md",
|
|
1099
952
|
"attempts": 0
|
|
1100
953
|
},
|
|
1101
954
|
"status": "active",
|
|
@@ -1103,39 +956,73 @@ Ticket worktree 状态依次为 `planned → active → review → integrating
|
|
|
1103
956
|
}
|
|
1104
957
|
```
|
|
1105
958
|
|
|
1106
|
-
|
|
959
|
+
`e2e.required` 与 Ticket/Goal Plan disposition 一致;required 时初始 status 为 `pending`。
|
|
1107
960
|
|
|
1108
|
-
|
|
961
|
+
## 恢复
|
|
962
|
+
|
|
963
|
+
恢复时核对 repository、branch、locator、`base_sha`、实际 HEAD、dirty 状态和 owner。状态记录与 Git 不一致、branch 被其他 worktree 占用或出现越界修改时停止;Lead 写 blocker,不重建覆盖。
|
|
964
|
+
|
|
965
|
+
进入 `review` 前必须由 implementation owner 创建最终 commit;Lead 重读 branch tip、diff 与 `git status`,把精确 SHA 写入 `source_checkpoint`。
|
|
966
|
+
|
|
967
|
+
**完成标准**:来源 worktree 可定位且唯一;基线、记录与 Git 一致;source 检查不含 E2E;失败时保留现场。
|
|
1109
968
|
|
|
1110
969
|
</dev-worktree-create>
|
|
1111
970
|
|
|
1112
971
|
<dev-worktree-finalize>
|
|
1113
972
|
|
|
1114
|
-
#
|
|
973
|
+
# Candidate Merge And Parent Integration
|
|
974
|
+
|
|
975
|
+
仅由 Lead/integration owner 对状态为 `review` 的 Ticket 调用。
|
|
1115
976
|
|
|
1116
|
-
##
|
|
977
|
+
## 1. 接收 source checkpoint
|
|
1117
978
|
|
|
1118
|
-
|
|
979
|
+
1. 核对 Ticket、Goal Plan、Evidence 目标、owner 与本地 integration 授权;
|
|
980
|
+
2. 验证来源 worktree clean,branch tip 精确等于 `source_checkpoint`,commit 从 `base_sha` 可达;
|
|
981
|
+
3. 审计实际 diff 未越过 writable/shared owner 合同;
|
|
982
|
+
4. 确认 source-worktree 必跑非 E2E 检查已执行,且没有把 E2E 自报为通过;
|
|
983
|
+
5. 重读父分支 checkout clean、HEAD 与 remote/本地约定,记录 `parent_before_sha`。
|
|
1119
984
|
|
|
1120
|
-
|
|
1121
|
-
2. 确认目标 checkout 正位于 `parent_branch`、index 与项目 working tree 干净,并把当前 HEAD 固定为 `parent_before_sha`。目标不干净、父分支不匹配、其他记录已在同一父分支 `integrating` 或 HEAD 在集成期间变化时停止,不覆盖用户工作。
|
|
1122
|
-
3. 将记录原子更新为 `integrating`,设置 `integration.status=running`、`parent_before_sha`、`source_sha` 并递增 `attempts`。中断恢复时先核对记录、Git `MERGE_HEAD` 和当前 HEAD,不重复开始第二次集成。
|
|
1123
|
-
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 现场。
|
|
1124
|
-
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 步骤。
|
|
1125
|
-
6. 若双方已分叉,从干净目标 checkout 执行 `git merge --no-ff --no-commit <source_checkpoint>`。出现冲突时加载 下方 `<merge-conflict-protocol>` 标签,并将本记录作为持久授权来源;不为 `git add`、继续 merge 或集成提交重复请求确认。
|
|
1126
|
-
7. 在未提交的合并结果上运行 Ticket 定向验证、受影响回归、项目 typecheck/lint/build 和适用最小 E2E。可由既有意图机械修正的失败最多处理 3 轮;不得放宽断言、删除检查或引入未批准行为。
|
|
1127
|
-
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`。
|
|
1128
|
-
9. 冲突需要新产品/架构/安全/迁移决定、修改越过授权路径、验证无法通过、目标状态漂移或提交 hook 无法安全完成时,执行 `git merge --abort`(仅限本流程从干净目标开始的 merge),设置 worktree 与 integration 为 `blocked`,记录最小失败、已通过行为和恢复条件,并保留来源 worktree。
|
|
985
|
+
失败时保持 `review`/`blocked`,不开始候选合并。
|
|
1129
986
|
|
|
1130
|
-
|
|
987
|
+
## 2. 建立 parent-candidate checkout
|
|
1131
988
|
|
|
1132
|
-
|
|
989
|
+
1. 使用 branch `speculo/integration/<change>/<ticket-id>` 和 locator `specdev-worktree/.integration/<ticket-id>`,从最新 `parent_before_sha` 建立 Lead-owned integration worktree;
|
|
990
|
+
2. 如果父 SHA 是 source checkpoint 的祖先,在 candidate checkout 执行 `git merge --ff-only <source_checkpoint>`,`method=fast-forward`;
|
|
991
|
+
3. 否则执行 `git merge --no-ff --no-commit <source_checkpoint>`;
|
|
992
|
+
4. 冲突按 下方 `<merge-conflict-protocol>` 标签 处理。需要新产品决定时执行 `git merge --abort`,记录 blocker 并返回来源 worktree;
|
|
993
|
+
5. 对分叉结果创建一次 Lead-owned candidate merge commit,`method=merge-commit`;
|
|
994
|
+
6. 记录 candidate branch/locator、`candidate_sha`、`source_sha`、冲突路径与 attempts,worktree 状态改为 `integrating`、integration 状态改为 `candidate`。
|
|
1133
995
|
|
|
1134
|
-
|
|
1135
|
-
2. Git provider 从 project root 解析 `specdev-worktree/<work-item-id>`,重验无路径逃逸且与 `git worktree list --porcelain` 的记录一致,再从主工作树移除;native/external 通过对应 provider 管理入口移除。
|
|
1136
|
-
3. 确认 worktree 不再注册且工作项目录不存在后删除对应分支。Ticket 将状态更新为 `removed`;原型把 `cleanup_status` 更新为 `clean`。保留项目根 `specdev-worktree/` 统一目录及 `.gitignore` 条目。
|
|
996
|
+
重试前从最新父分支重建 candidate branch/worktree;旧 candidate SHA 保存在 Evidence。候选生命周期的重建/回收包含在 local candidate integration 授权中。
|
|
1137
997
|
|
|
1138
|
-
|
|
998
|
+
## 3. 在候选父状态验证
|
|
999
|
+
|
|
1000
|
+
在 candidate checkout 运行:
|
|
1001
|
+
|
|
1002
|
+
- Ticket 受影响集成与回归;
|
|
1003
|
+
- 项目要求的 typecheck/lint/build 或其他父状态检查;
|
|
1004
|
+
- 仅当 Ticket/Goal Plan `e2e.required=true` 时运行对应 E2E。
|
|
1005
|
+
|
|
1006
|
+
每条命令记录运行环境 `parent-candidate`、退出码与摘要。E2E required 未运行或失败时 integration `verification=failed`、`status=failed`;父分支保持 `parent_before_sha`。机械修正次数不得超过 Goal Plan 快照的 `integration_attempt_limit`;不得放宽断言、删除检查或发明行为。
|
|
1007
|
+
|
|
1008
|
+
## 4. 推进父分支
|
|
1009
|
+
|
|
1010
|
+
全部 required 检查通过后:
|
|
1011
|
+
|
|
1012
|
+
1. 重读父分支 HEAD;不等于 `parent_before_sha` 时将 candidate 标记 `stale`,不推进父分支并从步骤 2 重建;
|
|
1013
|
+
2. 在父分支 checkout 执行 `git merge --ff-only <candidate_sha>`;候选 merge commit 本身已以父 SHA 为第一祖先,因此不再创建第二个 merge commit;
|
|
1014
|
+
3. 重读父 HEAD、tree 与 ancestor 关系,确认 HEAD 精确等于 candidate SHA 且包含 source checkpoint;
|
|
1015
|
+
4. 写入 `result_sha=candidate_sha`、`verification=passed`、E2E 最终状态和 Evidence;
|
|
1016
|
+
5. integration/status 改为 `passed`/`integrated`,再由 Lead 标记 Ticket Done。
|
|
1017
|
+
|
|
1018
|
+
## 5. 失败、清理与恢复
|
|
1019
|
+
|
|
1020
|
+
- candidate 检查失败:父分支不动,Ticket 回 `in_progress` 或 `blocked`,来源 worktree 保留;
|
|
1021
|
+
- 父 HEAD 漂移:旧 candidate 记 `stale`,完整重建并重跑;
|
|
1022
|
+
- 成功后可按 candidate integration 授权回收 transient integration worktree/branch;来源 branch/worktree 不自动清理。获得独立 cleanup 授权并清理后,只将生命周期状态改为 `removed`,完整保留已经通过的集成与 E2E 证据;
|
|
1023
|
+
- push、PR、remote merge、deploy、migration 和生产动作仍需各自授权。
|
|
1024
|
+
|
|
1025
|
+
**完成标准**:passed 时父 HEAD=result/candidate SHA 且包含 source commit;failed/stale 时父 HEAD 仍为开始该轮记录的父状态或更新后的外部事实,没有本轮候选污染。
|
|
1139
1026
|
|
|
1140
1027
|
</dev-worktree-finalize>
|
|
1141
1028
|
|
|
@@ -1143,161 +1030,141 @@ PR、`terminal_action=retain` 或暂缓集成时保留 worktree。成功集成
|
|
|
1143
1030
|
|
|
1144
1031
|
# Merge / Rebase Conflict Protocol
|
|
1145
1032
|
|
|
1146
|
-
只在 `git status` 证明仓库正处于 merge
|
|
1033
|
+
只在 `git status` 证明仓库正处于 merge/rebase 冲突时加载。
|
|
1147
1034
|
|
|
1148
1035
|
## 流程
|
|
1149
1036
|
|
|
1150
|
-
1. 读取 Git
|
|
1151
|
-
2.
|
|
1152
|
-
3.
|
|
1153
|
-
4.
|
|
1154
|
-
5.
|
|
1155
|
-
6.
|
|
1156
|
-
7. 重读 Git 状态、parents
|
|
1037
|
+
1. 读取 Git 状态、操作类型、冲突路径、base/ours/theirs SHA、Ticket/Evidence 与匹配的 candidate integration 记录。
|
|
1038
|
+
2. 从 commit、source、Spec、Ticket、ADR、测试和调用者追溯双方意图;信息不足时不猜产品行为。
|
|
1039
|
+
3. 对每个 hunk 写出双方意图、共同约束和唯一可推导结果;需要新行为或上层决定时停止并登记 deviation。
|
|
1040
|
+
4. 在授权路径内解决文本,运行受影响的非 E2E 检查;candidate checkout 中按 finalize 合同运行父状态检查/E2E。
|
|
1041
|
+
5. 匹配的 local candidate integration 授权包含 `git add`、candidate merge commit、必要的 `git merge --abort` 和 transient candidate checkout/branch 生命周期;不扩展到来源 branch/worktree cleanup 或远端动作。
|
|
1042
|
+
6. 需要改变 Spec/ADR、安全/迁移决定、越过 owner 或无法同时保持既有意图时,在 Lead-created candidate 中执行 `git merge --abort`,记录 blocker 并保留来源 worktree;未知普通冲突现场不擅自 abort。
|
|
1043
|
+
7. 重读 Git 状态、parents 与 diff,确认无 marker、无未声明路径、双方合同及验证仍成立。
|
|
1157
1044
|
|
|
1158
1045
|
## 完成标准
|
|
1159
1046
|
|
|
1160
|
-
- 每个 hunk
|
|
1047
|
+
- 每个 hunk 可追溯到既有意图;
|
|
1161
1048
|
- 新产品决定没有藏在冲突解决中;
|
|
1162
|
-
-
|
|
1163
|
-
- Git
|
|
1164
|
-
-
|
|
1049
|
+
- 验证记录命令、运行环境、退出码和摘要;
|
|
1050
|
+
- Git 副作用来自明确的 candidate integration 或其他逐动作授权;
|
|
1051
|
+
- 完成/暂停可以从 Git、change status 和 Evidence 恢复。
|
|
1165
1052
|
|
|
1166
1053
|
</merge-conflict-protocol>
|
|
1167
1054
|
|
|
1168
1055
|
<subagent-delivery>
|
|
1169
1056
|
|
|
1170
|
-
#
|
|
1057
|
+
# Subagent Delivery
|
|
1171
1058
|
|
|
1172
|
-
本 Skill
|
|
1059
|
+
本 Skill 被 P-goal-plan 与 I-implement 调用。它不选择是否使用 Lead 模式:Lead 是固定外层 owner;本 Skill 只保证每次动态派单可恢复、可验收且不产生第二个 SpecDev 状态写入者。
|
|
1173
1060
|
|
|
1174
1061
|
## 输入
|
|
1175
1062
|
|
|
1176
|
-
|
|
1177
|
-
- `execution_model`:`native-subagent` 或 `external-web-subagent`;
|
|
1178
|
-
- mutation role:`read-only`、`lead-write` 或 `worker-write`,以及独立确定的 workspace allocation;
|
|
1179
|
-
- Lead、Ticket、Goal Plan、Spec、适用 ADR/CONTEXT、Wave/Gate 和依赖 Evidence;
|
|
1180
|
-
- 项目写、只读和 shared 路径,验证矩阵与当前源码基线;
|
|
1181
|
-
- provider、会话或 workspace locator、源码交付方式,以及用户当前明确授权。
|
|
1182
|
-
|
|
1183
|
-
`single-session` Goal Plan 和缺失 Goal Plan 的 Ticket 直接由 “实现阶段” 执行,不调用本 Skill;只读辅助 Agent 由对应 research/review 能力管理。Lead Team 输入缺失时返回调用方补齐,不猜测 checkpoint、权限或验收结果。
|
|
1184
|
-
|
|
1185
|
-
## 流程
|
|
1186
|
-
|
|
1187
|
-
### 1. 固定 Lead、模型与权限
|
|
1063
|
+
所有调用都必须提供 `operation=plan | dispatch | accept` 与 Lead owner/session locator。其余输入按 operation 判定,不得把后续阶段事实反向要求给 `plan`:
|
|
1188
1064
|
|
|
1189
|
-
|
|
1065
|
+
- `operation=plan`:提供允许的 `task_kind` 集合、implementation subagent 上限、Lead/SpecDev/父分支/E2E 所有权和通用授权边界;Goal Plan 此时可以尚未写入,不要求 Ticket、provider、checkpoint 或 workspace;
|
|
1066
|
+
- `operation=dispatch`:提供 `task_kind=implementation | review | research | test-observation`、已存在 Goal Plan(若有)、Ticket/固定审查目标、依赖 Evidence、适用合同、repository、不可变 checkpoint、项目 Agent 指令、workspace/session locator、provider、允许动作、路径边界、检查、停止条件与返回格式;
|
|
1067
|
+
- `operation=accept`:提供原 Dispatch Packet、subagent 返回、当前 repository/workspace、预期与实际 checkpoint,以及 Lead 可用于独立核对的 Git/命令事实。
|
|
1190
1068
|
|
|
1191
|
-
|
|
1069
|
+
`operation=dispatch` 且 `task_kind=implementation` 时,必须提供 Goal Plan 的 workspace strategy、branch、`base_sha`、writable/shared owner、implementation commit 授权与对应检查。`required` 必须提供独立 Ticket worktree 和 source-worktree 非 E2E 检查;`current` 必须提供 `workspace_ref=current`、parent branch 和 current-workspace 串行锁。缺失时返回 blocked,不推断策略或并发权限。
|
|
1192
1070
|
|
|
1193
|
-
|
|
1071
|
+
## 1. 固定 Lead 与任务类型
|
|
1194
1072
|
|
|
1195
|
-
|
|
1073
|
+
Lead 保留需求解释、DAG/Wave/Gate、shared owner、权限、SpecDev 工件、Evidence、candidate-merge、父分支和最终回复。subagent 不写 Ticket、Map、Goal Plan、Evidence、change status 或父分支。
|
|
1196
1074
|
|
|
1197
|
-
|
|
1075
|
+
- implementation 可以在 required 模式写唯一 Ticket worktree,或在 current 模式按串行锁写当前 workspace,并在授权时创建实现 commit;
|
|
1076
|
+
- review/research/test-observation 只读,返回 findings、来源或命令观察;
|
|
1077
|
+
- E2E Gate 永远由 Lead 拥有,不能派给 implementation 或只读 agent;required Ticket E2E 在 parent-candidate 状态执行,current Ticket 和 Direct Spec E2E 在 Lead-owned current workspace 执行。
|
|
1198
1078
|
|
|
1199
|
-
|
|
1079
|
+
**完成标准**:Lead、task kind、写入边界和 E2E owner 唯一。
|
|
1200
1080
|
|
|
1201
|
-
|
|
1081
|
+
## 2. 锁定基线、provider 与授权
|
|
1202
1082
|
|
|
1203
|
-
|
|
1083
|
+
记录 repository、branch、`base_sha`/固定审查 SHA、workspace/session locator 和 provider。GitHub 是源码事实来源时加载 下方 `<subagent-delivery-github-checkpoints>` 标签;需要向外部 provider 发送附件或私有上下文时,取得发送授权后加载 下方 `<subagent-delivery-source-package>` 标签。
|
|
1204
1084
|
|
|
1205
|
-
|
|
1206
|
-
- `external-web-subagent`:加载 下方 `<subagent-delivery-external-web>` 标签,完成能力探测、会话恢复、候选交付与修正。
|
|
1085
|
+
授权逐动作记录:worktree local changes、implementation commit、外部内容发送、push、PR、remote merge、deploy、migration 和 production actions。Goal Plan 的本地 commit/integration 授权不扩展到远端、清理或生产动作。
|
|
1207
1086
|
|
|
1208
|
-
|
|
1087
|
+
**完成标准**:每个可变输入绑定 checkpoint;provider 只接收已授权范围;未授权动作不可执行。
|
|
1209
1088
|
|
|
1210
|
-
|
|
1089
|
+
## 3. 生成动态 Dispatch Packet
|
|
1211
1090
|
|
|
1212
|
-
`operation=plan`
|
|
1091
|
+
`operation=plan` 时只返回通用 Lead delivery contract,不读取尚未生成的 Goal Plan,也不为 Ticket 预分配 agent/provider。
|
|
1213
1092
|
|
|
1214
|
-
`operation=
|
|
1093
|
+
`operation=dispatch` 时为单次任务生成 Packet:目标、IN/OUT、已锁定决定、固定输入、workspace、writable/read-only/shared paths、允许动作、必跑检查、禁止在 source worktree 运行 E2E、停止条件和返回字段。
|
|
1215
1094
|
|
|
1216
|
-
|
|
1095
|
+
- 原生 Agent:加载 下方 `<subagent-delivery-native>` 标签;
|
|
1096
|
+
- 外部网页 Agent:加载 下方 `<subagent-delivery-external-web>` 标签。
|
|
1217
1097
|
|
|
1218
|
-
|
|
1098
|
+
implementation Packet 必须适合一个上下文独立完成;required 模式多个 implementation subagent 由 Lead 控制在 Goal Plan、config 与平台能力共同上限内,current 模式保持单 writer 串行。只读 agent 不设置 SpecDev 数字上限,但不得争用可变环境。
|
|
1219
1099
|
|
|
1220
|
-
|
|
1100
|
+
**完成标准**:Packet 可独立投递;目标、checkpoint、路径、权限、检查和返回均可判定。
|
|
1221
1101
|
|
|
1222
|
-
|
|
1102
|
+
## 4. 接收与验收候选
|
|
1223
1103
|
|
|
1224
|
-
|
|
1104
|
+
`operation=accept` 时,Lead 核对 Packet、当前父/来源基线、实际路径、dirty 状态、commit 可达性、命令输出和未验证项。外部声明、截图、provider 自报测试和推断保持 `unverified`,直到 Lead 在本地复核。
|
|
1225
1105
|
|
|
1226
|
-
|
|
1106
|
+
implementation 返回必须包含 Ticket ID、workspace locator、最终 commit、dirty 状态、修改路径、非 E2E 检查、失败/未运行项和恢复条件。review/research/test-observation 返回固定输入、findings、来源、命令与未验证声明。Lead 把验收结果写入调用方拥有的 Evidence/状态。
|
|
1227
1107
|
|
|
1228
|
-
|
|
1108
|
+
**完成标准**:每个 pass 有 Lead 可复查事实;candidate 未被误写为 Done 或父分支结果。
|
|
1229
1109
|
|
|
1230
|
-
|
|
1110
|
+
## 5. 修正与恢复
|
|
1231
1111
|
|
|
1232
|
-
|
|
1112
|
+
修正继续使用同一 Ticket 与 worktree,基于最后 source checkpoint 生成新 commit。基线或父分支漂移时由 Lead 暂停派单、重算影响并更新 Packet;契约冲突返回拥有该决定的工件。Lead 可以按当次风险在 Dispatch Packet 中定义停止条件,但 SpecDev 不推断全局修正次数;继续修正已无合理收益或需要上游决定时,返回 blocked、最后可信 checkpoint、失败命令和恢复条件。
|
|
1233
1113
|
|
|
1234
|
-
|
|
1114
|
+
**完成标准**:恢复不重新决定已锁定事项;每次候选都有唯一 checkpoint 和明确 owner。
|
|
1235
1115
|
|
|
1236
|
-
|
|
1116
|
+
</subagent-delivery>
|
|
1237
1117
|
|
|
1238
|
-
|
|
1239
|
-
DISPATCH ticket=<id> wave=<wave> gate=<gate>
|
|
1240
|
-
baseline=<sha> branch=<branch> workspace=<workspace-ref>
|
|
1241
|
-
ticket_path=<full-ticket-path> evidence_path=<full-evidence-path>
|
|
1242
|
-
```
|
|
1118
|
+
<subagent-delivery-native>
|
|
1243
1119
|
|
|
1244
|
-
|
|
1120
|
+
# Native Subagent
|
|
1245
1121
|
|
|
1246
|
-
|
|
1122
|
+
Lead 可以直接创建和管理隔离 Agent 时加载。
|
|
1247
1123
|
|
|
1248
|
-
##
|
|
1124
|
+
## 派单
|
|
1249
1125
|
|
|
1250
|
-
|
|
1126
|
+
Lead 为每个 Agent 发送一个完整 Dispatch Packet。implementation Agent 只进入 Goal Plan 指定的 current workspace 或 Ticket worktree;review/research/test-observation Agent 只读取固定输入。并行前核对 Ticket 依赖与 writable/shared path,不以“不同 Agent”代替路径隔离。
|
|
1251
1127
|
|
|
1252
|
-
|
|
1253
|
-
- 规范轴:Spec、ADR、Ticket、Goal Plan、路径合同和验收映射;
|
|
1254
|
-
- Lead 复跑的定向验证与适用回归;
|
|
1255
|
-
- 对可能静默失效的门禁执行一次受控反向验证,并恢复绿色基线。
|
|
1128
|
+
Packet 对 implementation 明确:
|
|
1256
1129
|
|
|
1257
|
-
|
|
1130
|
+
- Ticket、Goal Plan、依赖 Evidence 与 `base_sha`;
|
|
1131
|
+
- branch、portable `workspace_ref`、writable/read-only/shared paths;
|
|
1132
|
+
- 允许当前策略下的 workspace changes 与 implementation commit;
|
|
1133
|
+
- 单元、组件、静态、类型、lint/build 等适用非 E2E 检查;
|
|
1134
|
+
- E2E 由 Lead 在 current workspace 或 parent-candidate 状态执行;
|
|
1135
|
+
- 越界、合同冲突、基线漂移和无法提交时立即停止。
|
|
1258
1136
|
|
|
1259
1137
|
## 返回
|
|
1260
1138
|
|
|
1261
|
-
Agent 返回 Ticket
|
|
1139
|
+
implementation Agent 返回 Ticket ID、workspace locator、最终 commit、`git status`、修改路径、命令/结果、未运行项、冲突和恢复条件,不写 SpecDev Evidence。只读 Agent 返回固定 checkpoint、findings、来源、命令观察和未验证项。
|
|
1140
|
+
|
|
1141
|
+
Lead 重读 workspace、验证 commit 可达且 tip 一致、检查实际 diff 与路径合同,再决定接受、修正或 blocked。接受的 implementation 结果按 Goal Plan 进入 direct-parent 或 candidate-merge;只读结论由 Lead 写入对应权威工件。
|
|
1262
1142
|
|
|
1263
|
-
|
|
1143
|
+
**完成标准**:原生 Agent 的写入与返回均绑定一个 Packet;Lead 可以独立复现其事实声明。
|
|
1264
1144
|
|
|
1265
1145
|
</subagent-delivery-native>
|
|
1266
1146
|
|
|
1267
1147
|
<subagent-delivery-external-web>
|
|
1268
1148
|
|
|
1269
|
-
#
|
|
1270
|
-
|
|
1271
|
-
用户或已批准 Goal Plan 明确选择网页模型时加载;原生能力不足本身不授权向外部 provider 发送上下文。外部输出是候选交付,Lead 的本地核对决定验收状态。
|
|
1272
|
-
|
|
1273
|
-
## 能力探测与会话
|
|
1274
|
-
|
|
1275
|
-
首次使用或界面变化时实测并记录:provider、稳定 session locator、仓库访问、附件上传与返回、长任务状态和认证交接。Provider 名称只是标识;只有能力差异改变交付路径时才产生分支。
|
|
1276
|
-
|
|
1277
|
-
登录、账号选择、密码、验证码、Passkey、两步验证、恢复码和 CAPTCHA 由用户在界面内完成。认证秘密不进入派单、源码包、Goal Plan 或 Evidence;发送仓库链接、源码或附件前还必须确认 provider 和内容范围已获授权。
|
|
1149
|
+
# External Web Subagent
|
|
1278
1150
|
|
|
1279
|
-
|
|
1151
|
+
用户已授权目标 provider 与发送内容范围,且外部网页模型能为当前任务提供实际价值时加载。外部会话永远返回候选,不拥有本地 worktree、commit、SpecDev 状态或 E2E Gate。
|
|
1280
1152
|
|
|
1281
|
-
##
|
|
1153
|
+
## 能力与数据门
|
|
1282
1154
|
|
|
1283
|
-
|
|
1155
|
+
先确认 provider 能接收的文件、大小、会话恢复、输出格式和数据保留边界。需要源码包时加载 source-package reference,排除凭据、真实用户数据、运行时状态和无关代码;记录 locator、hash 与 checkpoint。能力或授权不足时改用原生/Lead 执行,不降低合同。
|
|
1284
1156
|
|
|
1285
|
-
|
|
1286
|
-
2. 用户结果、里程碑位置、相关模块、公共契约和领域不变量;
|
|
1287
|
-
3. allowed/read-only/shared 路径、保留行为和依赖策略;
|
|
1288
|
-
4. 需要返回的方案、修改清单、patch/源码、测试、实际命令和风险;
|
|
1289
|
-
5. mutation role、workspace allocation、当前授权矩阵与逐项验收标准;
|
|
1290
|
-
6. 未实际运行的检查必须标记 `unverified`。
|
|
1157
|
+
## 投递与返回
|
|
1291
1158
|
|
|
1292
|
-
|
|
1159
|
+
Packet 固定目标、范围、合同、checkpoint、路径边界、非 E2E 验证要求和停止条件。外部 provider 返回 patch/文件、修改清单、推理摘要、模拟或自报测试、未验证项和会话 locator。
|
|
1293
1160
|
|
|
1294
|
-
|
|
1161
|
+
Lead 在 Goal Plan 指定的 current workspace 或 Ticket worktree 中核对附件 hash、应用候选、检查 diff、依赖与锁文件、运行本地非 E2E 检查并创建 implementation commit。外部自报结果、截图或模拟保持 `unverified`;适用 E2E 由 Lead 在 current workspace 或 parent-candidate 状态运行。
|
|
1295
1162
|
|
|
1296
|
-
|
|
1163
|
+
## 修正与恢复
|
|
1297
1164
|
|
|
1298
|
-
|
|
1165
|
+
修正轮绑定新的源码 checkpoint 或 candidate hash,不覆盖旧附件。会话无法恢复、输出越界或 contract 冲突时停止并保留最后可信包、失败证据和恢复条件。
|
|
1299
1166
|
|
|
1300
|
-
|
|
1167
|
+
**完成标准**:发送范围有授权且可审计;本地 commit 与验收完全由 Lead 拥有;外部声明不被当作通过证据。
|
|
1301
1168
|
|
|
1302
1169
|
</subagent-delivery-external-web>
|
|
1303
1170
|
|
|
@@ -1355,16 +1222,15 @@ Manifest 至少记录 repository、branch、checkpoint、工作区状态、包 l
|
|
|
1355
1222
|
|
|
1356
1223
|
```json
|
|
1357
1224
|
{
|
|
1358
|
-
"schema_version":
|
|
1225
|
+
"schema_version": 5,
|
|
1359
1226
|
"interaction_language": "zh-CN",
|
|
1360
1227
|
"artifact_language": "zh-CN",
|
|
1361
1228
|
"git": {
|
|
1362
|
-
"
|
|
1363
|
-
"default_branch": null,
|
|
1364
|
-
"worktree_for_parallel": true
|
|
1229
|
+
"default_branch": null
|
|
1365
1230
|
},
|
|
1366
1231
|
"execution": {
|
|
1367
|
-
"
|
|
1232
|
+
"max_implementation_agents": 3,
|
|
1233
|
+
"max_integration_attempts": 3,
|
|
1368
1234
|
"deep_ticket_human_approval": true,
|
|
1369
1235
|
"shared_path_owner": "explicit"
|
|
1370
1236
|
},
|
|
@@ -1377,7 +1243,9 @@ Manifest 至少记录 repository、branch、checkpoint、工作区状态、包 l
|
|
|
1377
1243
|
"planning": {
|
|
1378
1244
|
"default_depth": "standard",
|
|
1379
1245
|
"require_ready_gate": true,
|
|
1380
|
-
"require_evidence": true
|
|
1246
|
+
"require_evidence": true,
|
|
1247
|
+
"ui_prototype_default_variants": 3,
|
|
1248
|
+
"ui_prototype_max_variants": 5
|
|
1381
1249
|
}
|
|
1382
1250
|
}
|
|
1383
1251
|
```
|
|
@@ -1389,33 +1257,32 @@ Manifest 至少记录 repository、branch、checkpoint、工作区状态、包 l
|
|
|
1389
1257
|
```json
|
|
1390
1258
|
{
|
|
1391
1259
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
1392
|
-
"$id": "urn:speculo:specdev:config:
|
|
1260
|
+
"$id": "urn:speculo:specdev:config:v5",
|
|
1393
1261
|
"title": "SpecDev Configuration",
|
|
1394
1262
|
"type": "object",
|
|
1395
1263
|
"required": ["schema_version", "interaction_language", "artifact_language", "git", "execution", "verification", "planning"],
|
|
1396
1264
|
"properties": {
|
|
1397
|
-
"schema_version": {"const":
|
|
1265
|
+
"schema_version": {"const": 5},
|
|
1398
1266
|
"interaction_language": {"type": "string", "minLength": 1},
|
|
1399
1267
|
"artifact_language": {"type": "string", "minLength": 1},
|
|
1400
1268
|
"git": {
|
|
1401
1269
|
"type": "object",
|
|
1402
|
-
"required": ["
|
|
1270
|
+
"required": ["default_branch"],
|
|
1403
1271
|
"properties": {
|
|
1404
|
-
"
|
|
1405
|
-
"default_branch": {"type": ["string", "null"]},
|
|
1406
|
-
"worktree_for_parallel": {"type": "boolean"}
|
|
1272
|
+
"default_branch": {"type": ["string", "null"]}
|
|
1407
1273
|
},
|
|
1408
|
-
"additionalProperties":
|
|
1274
|
+
"additionalProperties": false
|
|
1409
1275
|
},
|
|
1410
1276
|
"execution": {
|
|
1411
1277
|
"type": "object",
|
|
1412
|
-
"required": ["
|
|
1278
|
+
"required": ["max_implementation_agents", "max_integration_attempts", "deep_ticket_human_approval", "shared_path_owner"],
|
|
1413
1279
|
"properties": {
|
|
1414
|
-
"
|
|
1280
|
+
"max_implementation_agents": {"type": "integer", "minimum": 1},
|
|
1281
|
+
"max_integration_attempts": {"type": "integer", "minimum": 1},
|
|
1415
1282
|
"deep_ticket_human_approval": {"type": "boolean"},
|
|
1416
1283
|
"shared_path_owner": {"type": "string", "minLength": 1}
|
|
1417
1284
|
},
|
|
1418
|
-
"additionalProperties":
|
|
1285
|
+
"additionalProperties": false
|
|
1419
1286
|
},
|
|
1420
1287
|
"verification": {
|
|
1421
1288
|
"type": "object",
|
|
@@ -1430,16 +1297,21 @@ Manifest 至少记录 repository、branch、checkpoint、工作区状态、包 l
|
|
|
1430
1297
|
},
|
|
1431
1298
|
"planning": {
|
|
1432
1299
|
"type": "object",
|
|
1433
|
-
"required": ["default_depth", "require_ready_gate", "require_evidence"],
|
|
1300
|
+
"required": ["default_depth", "require_ready_gate", "require_evidence", "ui_prototype_default_variants", "ui_prototype_max_variants"],
|
|
1434
1301
|
"properties": {
|
|
1435
1302
|
"default_depth": {"enum": ["lite", "standard", "deep"]},
|
|
1436
1303
|
"require_ready_gate": {"type": "boolean"},
|
|
1437
|
-
"require_evidence": {"type": "boolean"}
|
|
1304
|
+
"require_evidence": {"type": "boolean"},
|
|
1305
|
+
"ui_prototype_default_variants": {"type": "integer", "minimum": 1},
|
|
1306
|
+
"ui_prototype_max_variants": {"type": "integer", "minimum": 1}
|
|
1438
1307
|
},
|
|
1439
1308
|
"additionalProperties": true
|
|
1440
1309
|
}
|
|
1441
1310
|
},
|
|
1442
|
-
"
|
|
1311
|
+
"allOf": [{
|
|
1312
|
+
"$comment": "ui_prototype_default_variants <= ui_prototype_max_variants is enforced by validate-specdev.mjs because JSON Schema cannot compare sibling numeric values."
|
|
1313
|
+
}],
|
|
1314
|
+
"additionalProperties": false
|
|
1443
1315
|
}
|
|
1444
1316
|
```
|
|
1445
1317
|
|
|
@@ -1449,7 +1321,7 @@ Manifest 至少记录 repository、branch、checkpoint、工作区状态、包 l
|
|
|
1449
1321
|
|
|
1450
1322
|
```json
|
|
1451
1323
|
{
|
|
1452
|
-
"schema_version":
|
|
1324
|
+
"schema_version": 5,
|
|
1453
1325
|
"workflow": "specdev",
|
|
1454
1326
|
"active": [],
|
|
1455
1327
|
"archived": []
|
|
@@ -1463,83 +1335,27 @@ Manifest 至少记录 repository、branch、checkpoint、工作区状态、包 l
|
|
|
1463
1335
|
```json
|
|
1464
1336
|
{
|
|
1465
1337
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
1466
|
-
"$id": "urn:speculo:specdev:status:
|
|
1338
|
+
"$id": "urn:speculo:specdev:status:v5",
|
|
1467
1339
|
"title": "SpecDev Global Status",
|
|
1468
1340
|
"type": "object",
|
|
1469
|
-
"required": [
|
|
1470
|
-
"schema_version",
|
|
1471
|
-
"workflow",
|
|
1472
|
-
"active",
|
|
1473
|
-
"archived"
|
|
1474
|
-
],
|
|
1341
|
+
"required": ["schema_version", "workflow", "active", "archived"],
|
|
1475
1342
|
"properties": {
|
|
1476
|
-
"schema_version": {
|
|
1477
|
-
|
|
1478
|
-
},
|
|
1479
|
-
"workflow": {
|
|
1480
|
-
"const": "specdev"
|
|
1481
|
-
},
|
|
1343
|
+
"schema_version": {"const": 5},
|
|
1344
|
+
"workflow": {"const": "specdev"},
|
|
1482
1345
|
"active": {
|
|
1483
1346
|
"type": "array",
|
|
1484
1347
|
"items": {
|
|
1485
1348
|
"type": "object",
|
|
1486
|
-
"required": [
|
|
1487
|
-
"change",
|
|
1488
|
-
"current_work",
|
|
1489
|
-
"works_run"
|
|
1490
|
-
],
|
|
1349
|
+
"required": ["change"],
|
|
1491
1350
|
"properties": {
|
|
1492
1351
|
"change": {
|
|
1493
1352
|
"type": "string",
|
|
1494
1353
|
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*$"
|
|
1495
|
-
},
|
|
1496
|
-
"current_work": {
|
|
1497
|
-
"type": [
|
|
1498
|
-
"string",
|
|
1499
|
-
"null"
|
|
1500
|
-
],
|
|
1501
|
-
"pattern": "^specdev/"
|
|
1502
|
-
},
|
|
1503
|
-
"works_run": {
|
|
1504
|
-
"type": "array",
|
|
1505
|
-
"items": {
|
|
1506
|
-
"type": "string",
|
|
1507
|
-
"pattern": "^specdev/"
|
|
1508
|
-
},
|
|
1509
|
-
"uniqueItems": true
|
|
1510
|
-
},
|
|
1511
|
-
"claimed_investigations": {
|
|
1512
|
-
"type": "array",
|
|
1513
|
-
"items": {
|
|
1514
|
-
"type": "object",
|
|
1515
|
-
"required": [
|
|
1516
|
-
"id",
|
|
1517
|
-
"owner",
|
|
1518
|
-
"claimed_at"
|
|
1519
|
-
],
|
|
1520
|
-
"properties": {
|
|
1521
|
-
"id": {
|
|
1522
|
-
"type": "string"
|
|
1523
|
-
},
|
|
1524
|
-
"owner": {
|
|
1525
|
-
"type": "string"
|
|
1526
|
-
},
|
|
1527
|
-
"session": {
|
|
1528
|
-
"type": [
|
|
1529
|
-
"string",
|
|
1530
|
-
"null"
|
|
1531
|
-
]
|
|
1532
|
-
},
|
|
1533
|
-
"claimed_at": {
|
|
1534
|
-
"type": "string"
|
|
1535
|
-
}
|
|
1536
|
-
},
|
|
1537
|
-
"additionalProperties": false
|
|
1538
|
-
}
|
|
1539
1354
|
}
|
|
1540
1355
|
},
|
|
1541
1356
|
"additionalProperties": false
|
|
1542
|
-
}
|
|
1357
|
+
},
|
|
1358
|
+
"uniqueItems": true
|
|
1543
1359
|
},
|
|
1544
1360
|
"archived": {
|
|
1545
1361
|
"type": "array",
|
|
@@ -1560,11 +1376,24 @@ Manifest 至少记录 repository、branch、checkpoint、工作区状态、包 l
|
|
|
1560
1376
|
|
|
1561
1377
|
```json
|
|
1562
1378
|
{
|
|
1563
|
-
"schema_version":
|
|
1379
|
+
"schema_version": 6,
|
|
1564
1380
|
"artifact": "change-status",
|
|
1565
1381
|
"change": "<YYYY-MM-DD-topic>",
|
|
1566
1382
|
"change_status": "active",
|
|
1567
1383
|
"current_work": null,
|
|
1384
|
+
"works_run": [],
|
|
1385
|
+
"claimed_investigations": [],
|
|
1386
|
+
"execution_authorization": {
|
|
1387
|
+
"implementation_commit": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Ticket implementation commits"},
|
|
1388
|
+
"local_candidate_integration": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Lead-owned local direct-parent or candidate integration and parent update"},
|
|
1389
|
+
"source_cleanup": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Source worktree and branch cleanup"}
|
|
1390
|
+
},
|
|
1391
|
+
"leadership": {
|
|
1392
|
+
"current": "<owner-or-session-locator>",
|
|
1393
|
+
"epoch": 1,
|
|
1394
|
+
"assigned_at": "<ISO-8601>",
|
|
1395
|
+
"history": []
|
|
1396
|
+
},
|
|
1568
1397
|
"created_at": "<ISO-8601>",
|
|
1569
1398
|
"updated_at": "<ISO-8601>",
|
|
1570
1399
|
"completed_at": null,
|
|
@@ -1583,394 +1412,184 @@ Manifest 至少记录 repository、branch、checkpoint、工作区状态、包 l
|
|
|
1583
1412
|
```json
|
|
1584
1413
|
{
|
|
1585
1414
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
1586
|
-
"$id": "urn:speculo:specdev:change-status:
|
|
1415
|
+
"$id": "urn:speculo:specdev:change-status:v6",
|
|
1587
1416
|
"title": "SpecDev Change Status",
|
|
1588
1417
|
"type": "object",
|
|
1589
1418
|
"required": [
|
|
1590
|
-
"schema_version",
|
|
1591
|
-
"
|
|
1592
|
-
"
|
|
1593
|
-
"change_status",
|
|
1594
|
-
"current_work",
|
|
1595
|
-
"created_at",
|
|
1596
|
-
"updated_at",
|
|
1597
|
-
"completed_at",
|
|
1598
|
-
"archived",
|
|
1599
|
-
"archive_path",
|
|
1600
|
-
"blockers",
|
|
1601
|
-
"deviations"
|
|
1419
|
+
"schema_version", "artifact", "change", "change_status", "current_work", "works_run",
|
|
1420
|
+
"claimed_investigations", "execution_authorization", "leadership", "created_at", "updated_at",
|
|
1421
|
+
"completed_at", "archived", "archive_path", "blockers", "deviations", "worktrees"
|
|
1602
1422
|
],
|
|
1603
1423
|
"properties": {
|
|
1604
|
-
"schema_version": {
|
|
1605
|
-
|
|
1606
|
-
},
|
|
1607
|
-
"
|
|
1608
|
-
|
|
1609
|
-
},
|
|
1610
|
-
"
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
},
|
|
1614
|
-
"
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1424
|
+
"schema_version": {"const": 6},
|
|
1425
|
+
"artifact": {"const": "change-status"},
|
|
1426
|
+
"change": {"type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*$"},
|
|
1427
|
+
"change_status": {"enum": ["active", "blocked", "completed", "archived"]},
|
|
1428
|
+
"current_work": {"type": ["string", "null"], "pattern": "^specdev/"},
|
|
1429
|
+
"works_run": {"type": "array", "items": {"type": "string", "pattern": "^specdev/"}, "uniqueItems": true},
|
|
1430
|
+
"claimed_investigations": {"type": "array", "items": {"$ref": "#/$defs/claim"}},
|
|
1431
|
+
"execution_authorization": {"$ref": "#/$defs/authorization"},
|
|
1432
|
+
"leadership": {"$ref": "#/$defs/leadership"},
|
|
1433
|
+
"created_at": {"type": "string", "minLength": 1},
|
|
1434
|
+
"updated_at": {"type": "string", "minLength": 1},
|
|
1435
|
+
"completed_at": {"type": ["string", "null"]},
|
|
1436
|
+
"archived": {"type": "boolean"},
|
|
1437
|
+
"archive_path": {"anyOf": [{"type": "null"}, {"type": "string", "pattern": "^specdev/archive/[0-9]{4}-[0-9]{2}/.+/$"}]},
|
|
1438
|
+
"blockers": {"type": "array", "items": {"type": "string"}},
|
|
1439
|
+
"deviations": {"type": "array", "items": {"type": "string"}},
|
|
1440
|
+
"worktrees": {"type": "array", "items": {"$ref": "#/$defs/worktree"}}
|
|
1441
|
+
},
|
|
1442
|
+
"$defs": {
|
|
1443
|
+
"claim": {
|
|
1444
|
+
"type": "object",
|
|
1445
|
+
"required": ["id", "owner", "session", "claimed_at"],
|
|
1446
|
+
"properties": {
|
|
1447
|
+
"id": {"type": "string", "minLength": 1},
|
|
1448
|
+
"owner": {"type": "string", "minLength": 1},
|
|
1449
|
+
"session": {"type": ["string", "null"]},
|
|
1450
|
+
"claimed_at": {"type": "string", "minLength": 1}
|
|
1451
|
+
},
|
|
1452
|
+
"additionalProperties": false
|
|
1621
1453
|
},
|
|
1622
|
-
"
|
|
1623
|
-
"type":
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1454
|
+
"authorization-entry": {
|
|
1455
|
+
"type": "object",
|
|
1456
|
+
"required": ["status", "source", "granted_at", "scope"],
|
|
1457
|
+
"properties": {
|
|
1458
|
+
"status": {"enum": ["authorized", "not-authorized", "revoked"]},
|
|
1459
|
+
"source": {"type": ["string", "null"]},
|
|
1460
|
+
"granted_at": {"type": ["string", "null"]},
|
|
1461
|
+
"scope": {"type": "string", "minLength": 1}
|
|
1462
|
+
},
|
|
1463
|
+
"allOf": [{
|
|
1464
|
+
"if": {"properties": {"status": {"const": "authorized"}}, "required": ["status"]},
|
|
1465
|
+
"then": {"properties": {"source": {"type": "string", "minLength": 1}, "granted_at": {"type": "string", "minLength": 1}}}
|
|
1466
|
+
}],
|
|
1467
|
+
"additionalProperties": false
|
|
1627
1468
|
},
|
|
1628
|
-
"
|
|
1629
|
-
"type": "
|
|
1630
|
-
"
|
|
1469
|
+
"authorization": {
|
|
1470
|
+
"type": "object",
|
|
1471
|
+
"required": ["implementation_commit", "local_candidate_integration", "source_cleanup"],
|
|
1472
|
+
"properties": {
|
|
1473
|
+
"implementation_commit": {"$ref": "#/$defs/authorization-entry"},
|
|
1474
|
+
"local_candidate_integration": {"$ref": "#/$defs/authorization-entry"},
|
|
1475
|
+
"source_cleanup": {"$ref": "#/$defs/authorization-entry"}
|
|
1476
|
+
},
|
|
1477
|
+
"additionalProperties": false
|
|
1631
1478
|
},
|
|
1632
|
-
"
|
|
1633
|
-
"type": "
|
|
1634
|
-
"
|
|
1479
|
+
"leadership-history": {
|
|
1480
|
+
"type": "object",
|
|
1481
|
+
"required": ["owner", "epoch", "assigned_at", "ended_at"],
|
|
1482
|
+
"properties": {
|
|
1483
|
+
"owner": {"type": "string", "minLength": 1},
|
|
1484
|
+
"epoch": {"type": "integer", "minimum": 1},
|
|
1485
|
+
"assigned_at": {"type": "string", "minLength": 1},
|
|
1486
|
+
"ended_at": {"type": "string", "minLength": 1}
|
|
1487
|
+
},
|
|
1488
|
+
"additionalProperties": false
|
|
1635
1489
|
},
|
|
1636
|
-
"
|
|
1637
|
-
"type":
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1490
|
+
"leadership": {
|
|
1491
|
+
"type": "object",
|
|
1492
|
+
"required": ["current", "epoch", "assigned_at", "history"],
|
|
1493
|
+
"properties": {
|
|
1494
|
+
"current": {"type": "string", "minLength": 1},
|
|
1495
|
+
"epoch": {"type": "integer", "minimum": 1},
|
|
1496
|
+
"assigned_at": {"type": "string", "minLength": 1},
|
|
1497
|
+
"history": {"type": "array", "items": {"$ref": "#/$defs/leadership-history"}}
|
|
1498
|
+
},
|
|
1499
|
+
"additionalProperties": false
|
|
1641
1500
|
},
|
|
1642
|
-
"
|
|
1643
|
-
"type": "
|
|
1501
|
+
"full-suite": {
|
|
1502
|
+
"type": "object",
|
|
1503
|
+
"required": ["required", "status", "reason", "evidence"],
|
|
1504
|
+
"properties": {
|
|
1505
|
+
"required": {"type": "boolean"},
|
|
1506
|
+
"status": {"enum": ["not-required", "pending", "passed", "failed"]},
|
|
1507
|
+
"reason": {"type": ["string", "null"]},
|
|
1508
|
+
"evidence": {"type": ["string", "null"]}
|
|
1509
|
+
},
|
|
1510
|
+
"allOf": [{
|
|
1511
|
+
"if": {"properties": {"required": {"const": false}}, "required": ["required"]},
|
|
1512
|
+
"then": {"properties": {"status": {"const": "not-required"}, "reason": {"type": "string", "minLength": 1}}}
|
|
1513
|
+
}],
|
|
1514
|
+
"additionalProperties": false
|
|
1644
1515
|
},
|
|
1645
|
-
"
|
|
1646
|
-
"
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
},
|
|
1516
|
+
"worktree": {
|
|
1517
|
+
"type": "object",
|
|
1518
|
+
"required": ["ticket_id", "owner", "implementation_owner", "integration_owner", "provider", "base_sha", "parent_branch", "branch", "workspace_ref", "source_checkpoint", "integration", "status", "updated_at"],
|
|
1519
|
+
"properties": {
|
|
1520
|
+
"ticket_id": {"type": "string", "pattern": "^T-[0-9]{2,}$"},
|
|
1521
|
+
"owner": {"type": "string", "minLength": 1},
|
|
1522
|
+
"implementation_owner": {"type": "string", "minLength": 1},
|
|
1523
|
+
"integration_owner": {"type": "string", "minLength": 1},
|
|
1524
|
+
"provider": {"const": "git"},
|
|
1525
|
+
"base_sha": {"type": "string", "minLength": 1},
|
|
1526
|
+
"parent_branch": {"type": "string", "minLength": 1},
|
|
1527
|
+
"branch": {"type": "string", "minLength": 1},
|
|
1528
|
+
"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,})$"},
|
|
1529
|
+
"source_checkpoint": {"type": ["string", "null"]},
|
|
1530
|
+
"integration": {"$ref": "#/$defs/integration"},
|
|
1531
|
+
"status": {"enum": ["planned", "active", "review", "integrating", "integrated", "removed", "blocked"]},
|
|
1532
|
+
"updated_at": {"type": "string", "minLength": 1}
|
|
1533
|
+
},
|
|
1534
|
+
"allOf": [
|
|
1650
1535
|
{
|
|
1651
|
-
"
|
|
1652
|
-
"
|
|
1653
|
-
}
|
|
1654
|
-
]
|
|
1655
|
-
},
|
|
1656
|
-
"blockers": {
|
|
1657
|
-
"type": "array",
|
|
1658
|
-
"items": {
|
|
1659
|
-
"type": "string"
|
|
1660
|
-
}
|
|
1661
|
-
},
|
|
1662
|
-
"deviations": {
|
|
1663
|
-
"type": "array",
|
|
1664
|
-
"items": {
|
|
1665
|
-
"type": "string"
|
|
1666
|
-
}
|
|
1667
|
-
},
|
|
1668
|
-
"worktrees": {
|
|
1669
|
-
"type": "array",
|
|
1670
|
-
"items": {
|
|
1671
|
-
"type": "object",
|
|
1672
|
-
"required": [
|
|
1673
|
-
"ticket_id",
|
|
1674
|
-
"owner",
|
|
1675
|
-
"provider",
|
|
1676
|
-
"base_sha",
|
|
1677
|
-
"branch",
|
|
1678
|
-
"workspace_ref",
|
|
1679
|
-
"status",
|
|
1680
|
-
"updated_at"
|
|
1681
|
-
],
|
|
1682
|
-
"properties": {
|
|
1683
|
-
"ticket_id": {
|
|
1684
|
-
"type": "string",
|
|
1685
|
-
"pattern": "^T-[0-9]{2,}$"
|
|
1686
|
-
},
|
|
1687
|
-
"owner": {
|
|
1688
|
-
"type": "string",
|
|
1689
|
-
"minLength": 1
|
|
1690
|
-
},
|
|
1691
|
-
"integration_owner": {
|
|
1692
|
-
"type": "string",
|
|
1693
|
-
"minLength": 1
|
|
1694
|
-
},
|
|
1695
|
-
"provider": {
|
|
1696
|
-
"enum": [
|
|
1697
|
-
"native",
|
|
1698
|
-
"git",
|
|
1699
|
-
"external"
|
|
1700
|
-
]
|
|
1701
|
-
},
|
|
1702
|
-
"base_sha": {
|
|
1703
|
-
"type": "string",
|
|
1704
|
-
"minLength": 1
|
|
1705
|
-
},
|
|
1706
|
-
"parent_branch": {
|
|
1707
|
-
"type": "string",
|
|
1708
|
-
"minLength": 1
|
|
1709
|
-
},
|
|
1710
|
-
"branch": {
|
|
1711
|
-
"type": "string",
|
|
1712
|
-
"minLength": 1
|
|
1713
|
-
},
|
|
1714
|
-
"workspace_ref": {
|
|
1715
|
-
"type": "string",
|
|
1716
|
-
"minLength": 1,
|
|
1717
|
-
"pattern": "^(?!/)(?![A-Za-z]:[\\\\/]).+"
|
|
1718
|
-
},
|
|
1719
|
-
"terminal_action": {
|
|
1720
|
-
"enum": [
|
|
1721
|
-
"integrate",
|
|
1722
|
-
"retain"
|
|
1723
|
-
]
|
|
1724
|
-
},
|
|
1725
|
-
"source_checkpoint": {
|
|
1726
|
-
"type": [
|
|
1727
|
-
"string",
|
|
1728
|
-
"null"
|
|
1729
|
-
]
|
|
1730
|
-
},
|
|
1731
|
-
"integration": {
|
|
1732
|
-
"type": "object",
|
|
1733
|
-
"required": [
|
|
1734
|
-
"status",
|
|
1735
|
-
"parent_before_sha",
|
|
1736
|
-
"source_sha",
|
|
1737
|
-
"result_sha",
|
|
1738
|
-
"method",
|
|
1739
|
-
"conflict_paths",
|
|
1740
|
-
"verification",
|
|
1741
|
-
"evidence",
|
|
1742
|
-
"attempts"
|
|
1743
|
-
],
|
|
1536
|
+
"if": {"properties": {"workspace_ref": {"const": "current"}}, "required": ["workspace_ref"]},
|
|
1537
|
+
"then": {
|
|
1744
1538
|
"properties": {
|
|
1745
|
-
"
|
|
1746
|
-
"
|
|
1747
|
-
"pending",
|
|
1748
|
-
"running",
|
|
1749
|
-
"passed",
|
|
1750
|
-
"blocked"
|
|
1751
|
-
]
|
|
1752
|
-
},
|
|
1753
|
-
"parent_before_sha": {
|
|
1754
|
-
"type": ["string", "null"]
|
|
1755
|
-
},
|
|
1756
|
-
"source_sha": {
|
|
1757
|
-
"type": ["string", "null"]
|
|
1758
|
-
},
|
|
1759
|
-
"result_sha": {
|
|
1760
|
-
"type": ["string", "null"]
|
|
1761
|
-
},
|
|
1762
|
-
"method": {
|
|
1763
|
-
"enum": [null, "fast-forward", "merge-commit"]
|
|
1764
|
-
},
|
|
1765
|
-
"conflict_paths": {
|
|
1766
|
-
"type": "array",
|
|
1767
|
-
"items": {"type": "string"}
|
|
1768
|
-
},
|
|
1769
|
-
"verification": {
|
|
1770
|
-
"enum": ["pending", "passed", "failed"]
|
|
1771
|
-
},
|
|
1772
|
-
"evidence": {
|
|
1773
|
-
"type": "string",
|
|
1774
|
-
"pattern": "^\\{roots\\.state\\}/specdev/changes/[^<]+/evidence/T-[0-9]{2,}\\.md$"
|
|
1775
|
-
},
|
|
1776
|
-
"attempts": {
|
|
1777
|
-
"type": "integer",
|
|
1778
|
-
"minimum": 0
|
|
1779
|
-
}
|
|
1780
|
-
},
|
|
1781
|
-
"additionalProperties": true
|
|
1782
|
-
},
|
|
1783
|
-
"status": {
|
|
1784
|
-
"enum": [
|
|
1785
|
-
"planned",
|
|
1786
|
-
"active",
|
|
1787
|
-
"review",
|
|
1788
|
-
"integrating",
|
|
1789
|
-
"integrated",
|
|
1790
|
-
"removed",
|
|
1791
|
-
"blocked"
|
|
1792
|
-
]
|
|
1793
|
-
},
|
|
1794
|
-
"updated_at": {
|
|
1795
|
-
"type": "string",
|
|
1796
|
-
"minLength": 1
|
|
1797
|
-
}
|
|
1798
|
-
},
|
|
1799
|
-
"dependentRequired": {
|
|
1800
|
-
"terminal_action": [
|
|
1801
|
-
"integration_owner",
|
|
1802
|
-
"parent_branch",
|
|
1803
|
-
"source_checkpoint",
|
|
1804
|
-
"integration"
|
|
1805
|
-
]
|
|
1806
|
-
},
|
|
1807
|
-
"allOf": [
|
|
1808
|
-
{
|
|
1809
|
-
"if": {
|
|
1810
|
-
"properties": {
|
|
1811
|
-
"status": {"const": "integrating"}
|
|
1812
|
-
},
|
|
1813
|
-
"required": ["status"]
|
|
1814
|
-
},
|
|
1815
|
-
"then": {
|
|
1816
|
-
"required": [
|
|
1817
|
-
"terminal_action",
|
|
1818
|
-
"integration_owner",
|
|
1819
|
-
"parent_branch",
|
|
1820
|
-
"source_checkpoint",
|
|
1821
|
-
"integration"
|
|
1822
|
-
],
|
|
1823
|
-
"properties": {
|
|
1824
|
-
"terminal_action": {"const": "integrate"}
|
|
1825
|
-
}
|
|
1826
|
-
}
|
|
1827
|
-
},
|
|
1828
|
-
{
|
|
1829
|
-
"if": {
|
|
1830
|
-
"properties": {
|
|
1831
|
-
"status": {"enum": ["integrating", "integrated"]},
|
|
1832
|
-
"terminal_action": {"const": "integrate"}
|
|
1833
|
-
},
|
|
1834
|
-
"required": ["status", "terminal_action"]
|
|
1835
|
-
},
|
|
1836
|
-
"then": {
|
|
1837
|
-
"properties": {
|
|
1838
|
-
"source_checkpoint": {"type": "string", "minLength": 1},
|
|
1839
|
-
"integration": {
|
|
1539
|
+
"integration": {
|
|
1540
|
+
"allOf": [{
|
|
1840
1541
|
"properties": {
|
|
1841
|
-
"
|
|
1842
|
-
"
|
|
1843
|
-
"
|
|
1542
|
+
"candidate_sha": {"const": null},
|
|
1543
|
+
"candidate_tree_sha": {"const": null},
|
|
1544
|
+
"candidate_branch": {"const": null},
|
|
1545
|
+
"candidate_workspace_ref": {"const": null},
|
|
1546
|
+
"method": {"enum": [null, "direct-parent"]}
|
|
1844
1547
|
}
|
|
1845
|
-
}
|
|
1548
|
+
}]
|
|
1846
1549
|
}
|
|
1847
1550
|
}
|
|
1848
1551
|
},
|
|
1849
|
-
{
|
|
1850
|
-
"
|
|
1851
|
-
"
|
|
1852
|
-
"
|
|
1853
|
-
"terminal_action": {"const": "integrate"}
|
|
1854
|
-
},
|
|
1855
|
-
"required": ["status", "terminal_action"]
|
|
1856
|
-
},
|
|
1857
|
-
"then": {
|
|
1858
|
-
"properties": {
|
|
1859
|
-
"integration": {
|
|
1860
|
-
"properties": {
|
|
1861
|
-
"status": {"const": "running"}
|
|
1862
|
-
}
|
|
1863
|
-
}
|
|
1864
|
-
}
|
|
1865
|
-
}
|
|
1866
|
-
},
|
|
1867
|
-
{
|
|
1868
|
-
"if": {
|
|
1869
|
-
"properties": {
|
|
1870
|
-
"status": {"const": "integrated"},
|
|
1871
|
-
"terminal_action": {"const": "integrate"}
|
|
1872
|
-
},
|
|
1873
|
-
"required": ["status", "terminal_action"]
|
|
1874
|
-
},
|
|
1875
|
-
"then": {
|
|
1876
|
-
"properties": {
|
|
1877
|
-
"integration": {
|
|
1878
|
-
"properties": {
|
|
1879
|
-
"status": {"const": "passed"},
|
|
1880
|
-
"result_sha": {"type": "string", "minLength": 1},
|
|
1881
|
-
"method": {"enum": ["fast-forward", "merge-commit"]},
|
|
1882
|
-
"verification": {"const": "passed"}
|
|
1883
|
-
}
|
|
1884
|
-
}
|
|
1885
|
-
}
|
|
1886
|
-
}
|
|
1887
|
-
},
|
|
1888
|
-
{
|
|
1889
|
-
"if": {
|
|
1890
|
-
"properties": {
|
|
1891
|
-
"terminal_action": {"const": "retain"}
|
|
1892
|
-
},
|
|
1893
|
-
"required": ["terminal_action"]
|
|
1894
|
-
},
|
|
1895
|
-
"then": {
|
|
1896
|
-
"properties": {
|
|
1897
|
-
"status": {
|
|
1898
|
-
"not": {"enum": ["integrating", "integrated"]}
|
|
1899
|
-
}
|
|
1900
|
-
}
|
|
1901
|
-
}
|
|
1902
|
-
}
|
|
1903
|
-
],
|
|
1904
|
-
"additionalProperties": true
|
|
1905
|
-
}
|
|
1906
|
-
}
|
|
1907
|
-
},
|
|
1908
|
-
"allOf": [
|
|
1909
|
-
{
|
|
1910
|
-
"if": {
|
|
1911
|
-
"properties": {
|
|
1912
|
-
"worktrees": {
|
|
1913
|
-
"contains": {
|
|
1914
|
-
"properties": {
|
|
1915
|
-
"provider": {
|
|
1916
|
-
"const": "git"
|
|
1917
|
-
}
|
|
1918
|
-
},
|
|
1919
|
-
"required": [
|
|
1920
|
-
"provider"
|
|
1921
|
-
]
|
|
1922
|
-
}
|
|
1923
|
-
}
|
|
1924
|
-
}
|
|
1925
|
-
},
|
|
1926
|
-
"then": {
|
|
1927
|
-
"properties": {
|
|
1928
|
-
"worktrees": {
|
|
1929
|
-
"items": {
|
|
1930
|
-
"if": {
|
|
1931
|
-
"properties": {
|
|
1932
|
-
"provider": {
|
|
1933
|
-
"const": "git"
|
|
1934
|
-
}
|
|
1935
|
-
},
|
|
1936
|
-
"required": [
|
|
1937
|
-
"provider"
|
|
1938
|
-
]
|
|
1939
|
-
},
|
|
1940
|
-
"then": {
|
|
1941
|
-
"properties": {
|
|
1942
|
-
"workspace_ref": {
|
|
1943
|
-
"pattern": "^specdev-worktree/T-[0-9]{2,}$"
|
|
1944
|
-
}
|
|
1945
|
-
}
|
|
1552
|
+
"else": {
|
|
1553
|
+
"properties": {
|
|
1554
|
+
"integration": {
|
|
1555
|
+
"allOf": [{"properties": {"method": {"enum": [null, "fast-forward", "merge-commit"]}}}]
|
|
1946
1556
|
}
|
|
1947
1557
|
}
|
|
1948
1558
|
}
|
|
1949
1559
|
}
|
|
1950
|
-
|
|
1560
|
+
],
|
|
1561
|
+
"additionalProperties": false
|
|
1951
1562
|
},
|
|
1952
|
-
{
|
|
1953
|
-
"
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
}
|
|
1563
|
+
"integration": {
|
|
1564
|
+
"type": "object",
|
|
1565
|
+
"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"],
|
|
1566
|
+
"properties": {
|
|
1567
|
+
"status": {"enum": ["pending", "candidate", "passed", "failed", "stale"]},
|
|
1568
|
+
"parent_ref": {"type": ["string", "null"]},
|
|
1569
|
+
"parent_before_sha": {"type": ["string", "null"]},
|
|
1570
|
+
"source_sha": {"type": ["string", "null"]},
|
|
1571
|
+
"candidate_sha": {"type": ["string", "null"]},
|
|
1572
|
+
"candidate_tree_sha": {"type": ["string", "null"]},
|
|
1573
|
+
"candidate_branch": {"type": ["string", "null"]},
|
|
1574
|
+
"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,}$"}]},
|
|
1575
|
+
"result_sha": {"type": ["string", "null"]},
|
|
1576
|
+
"method": {"enum": [null, "direct-parent", "fast-forward", "merge-commit"]},
|
|
1577
|
+
"conflict_paths": {"type": "array", "items": {"type": "string"}},
|
|
1578
|
+
"verification": {"enum": ["pending", "passed", "failed"]},
|
|
1579
|
+
"full_suite": {"$ref": "#/$defs/full-suite"},
|
|
1580
|
+
"e2e": {"$ref": "#/$defs/full-suite"},
|
|
1581
|
+
"evidence": {"type": "string", "pattern": "^\\{roots\\.state\\}/specdev/changes/[^<]+/evidence/T-[0-9]{2,}\\.md$"},
|
|
1582
|
+
"attempts": {"type": "integer", "minimum": 0},
|
|
1583
|
+
"promotion_status": {"enum": ["pending", "applying", "applied", "failed", "stale"]}
|
|
1959
1584
|
},
|
|
1960
|
-
"
|
|
1961
|
-
"properties": {
|
|
1962
|
-
"archived": {
|
|
1963
|
-
"const": true
|
|
1964
|
-
},
|
|
1965
|
-
"archive_path": {
|
|
1966
|
-
"type": "string",
|
|
1967
|
-
"pattern": "^specdev/archive/[0-9]{4}-[0-9]{2}/.+/$"
|
|
1968
|
-
}
|
|
1969
|
-
}
|
|
1970
|
-
}
|
|
1585
|
+
"additionalProperties": false
|
|
1971
1586
|
}
|
|
1972
|
-
|
|
1973
|
-
"
|
|
1587
|
+
},
|
|
1588
|
+
"allOf": [{
|
|
1589
|
+
"if": {"properties": {"change_status": {"const": "archived"}}, "required": ["change_status"]},
|
|
1590
|
+
"then": {"properties": {"archived": {"const": true}, "archive_path": {"type": "string", "pattern": "^specdev/archive/[0-9]{4}-[0-9]{2}/.+/$"}}}
|
|
1591
|
+
}],
|
|
1592
|
+
"additionalProperties": false
|
|
1974
1593
|
}
|
|
1975
1594
|
```
|
|
1976
1595
|
|
|
@@ -1981,34 +1600,51 @@ Manifest 至少记录 repository、branch、checkpoint、工作区状态、包 l
|
|
|
1981
1600
|
```json
|
|
1982
1601
|
{
|
|
1983
1602
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
1984
|
-
"$id": "urn:speculo:specdev:goal-plan:
|
|
1603
|
+
"$id": "urn:speculo:specdev:goal-plan:v6",
|
|
1985
1604
|
"title": "SpecDev Goal Plan Frontmatter",
|
|
1986
1605
|
"type": "object",
|
|
1987
|
-
"required": [
|
|
1606
|
+
"required": [
|
|
1607
|
+
"schema_version", "artifact", "change", "status", "modes", "orchestration",
|
|
1608
|
+
"lead", "implementation_agent_limit", "integration_attempt_limit", "ticket_workspace_policy", "integration_gate",
|
|
1609
|
+
"ready_for_execution"
|
|
1610
|
+
],
|
|
1988
1611
|
"properties": {
|
|
1989
|
-
"schema_version": {"const":
|
|
1612
|
+
"schema_version": {"const": 6},
|
|
1990
1613
|
"artifact": {"const": "goal-plan"},
|
|
1991
1614
|
"change": {"type": "string", "minLength": 1},
|
|
1992
1615
|
"status": {"enum": ["draft", "ready", "in_progress", "completed", "blocked"]},
|
|
1993
1616
|
"modes": {
|
|
1994
1617
|
"type": "array",
|
|
1995
|
-
"items": {"enum": ["
|
|
1996
|
-
"minItems": 1,
|
|
1618
|
+
"items": {"enum": ["migration", "high-assurance", "reference-conformance", "release-coordination"]},
|
|
1997
1619
|
"uniqueItems": true
|
|
1998
1620
|
},
|
|
1999
|
-
"
|
|
2000
|
-
|
|
2001
|
-
},
|
|
2002
|
-
"
|
|
2003
|
-
|
|
2004
|
-
},
|
|
1621
|
+
"orchestration": {"const": "lead-directed"},
|
|
1622
|
+
"lead": {"type": "string", "minLength": 1},
|
|
1623
|
+
"implementation_agent_limit": {"type": "integer", "minimum": 1},
|
|
1624
|
+
"integration_attempt_limit": {"type": "integer", "minimum": 1},
|
|
1625
|
+
"ticket_workspace_policy": {"enum": ["current", "required"]},
|
|
1626
|
+
"integration_gate": {"enum": ["direct-parent", "candidate-merge"]},
|
|
2005
1627
|
"ready_for_execution": {"type": "boolean"}
|
|
2006
1628
|
},
|
|
2007
|
-
"
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
1629
|
+
"allOf": [
|
|
1630
|
+
{
|
|
1631
|
+
"if": {"properties": {"ticket_workspace_policy": {"const": "current"}}, "required": ["ticket_workspace_policy"]},
|
|
1632
|
+
"then": {"properties": {"integration_gate": {"const": "direct-parent"}}}
|
|
1633
|
+
},
|
|
1634
|
+
{
|
|
1635
|
+
"if": {"properties": {"ticket_workspace_policy": {"const": "required"}}, "required": ["ticket_workspace_policy"]},
|
|
1636
|
+
"then": {"properties": {"integration_gate": {"const": "candidate-merge"}}}
|
|
1637
|
+
},
|
|
1638
|
+
{
|
|
1639
|
+
"if": {"properties": {"status": {"enum": ["draft", "blocked", "completed"]}}, "required": ["status"]},
|
|
1640
|
+
"then": {"properties": {"ready_for_execution": {"const": false}}}
|
|
1641
|
+
},
|
|
1642
|
+
{
|
|
1643
|
+
"if": {"properties": {"status": {"enum": ["ready", "in_progress"]}}, "required": ["status"]},
|
|
1644
|
+
"then": {"properties": {"ready_for_execution": {"const": true}}}
|
|
1645
|
+
}
|
|
1646
|
+
],
|
|
1647
|
+
"additionalProperties": false
|
|
2012
1648
|
}
|
|
2013
1649
|
```
|
|
2014
1650
|
|