@guanlin4924/devflow-pi 0.1.14 → 0.1.16
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/package.json +1 -1
- package/plugins/devflow-core/extensions/devflow-core.ts +179 -54
- package/plugins/devflow-core/skills/workflow-orchestrator/SKILL.md +4 -4
- package/plugins/devflow-core/skills/workflow-orchestrator/scripts/execution_contract.rb +93 -0
- package/plugins/devflow-core/skills/workflow-orchestrator/scripts/init_state.rb +2 -1
- package/plugins/devflow-core/skills/workflow-orchestrator/scripts/machine_evidence.rb +111 -0
- package/plugins/devflow-core/skills/workflow-orchestrator/scripts/requirement_graph.rb +471 -0
- package/plugins/devflow-core/skills/workflow-orchestrator/scripts/traceability_check.py +160 -0
- package/plugins/devflow-core/skills/workflow-orchestrator/scripts/validate_state.rb +85 -0
- package/plugins/devflow-core/skills/workflow-orchestrator/templates/feature-development.yaml +59 -3
- package/plugins/devflow-core/skills/workflow-orchestrator/templates/traceability.json +23 -0
- package/plugins/devflow-design/skills/workflow-api-contract/SKILL.md +4 -1
- package/plugins/devflow-design/skills/workflow-backend-tech-spec/SKILL.md +4 -0
- package/plugins/devflow-design/skills/workflow-frontend-tech-spec/SKILL.md +4 -0
- package/plugins/devflow-design/skills/workflow-integration-verify/SKILL.md +10 -0
- package/plugins/devflow-implementation/skills/workflow-change-plan/SKILL.md +8 -0
- package/plugins/devflow-requirements/skills/requirement-feasibility-review/SKILL.md +4 -0
- package/plugins/devflow-requirements/skills/workflow-domain-modeling/SKILL.md +4 -0
- package/plugins/devflow-requirements/skills/workflow-requirement-baseline/SKILL.md +13 -0
- package/plugins/devflow-requirements/skills/workflow-requirement-triage/SKILL.md +4 -0
- package/src/cli.ts +2 -1
- package/src/runtime.ts +2 -1
|
@@ -6,6 +6,7 @@ require "optparse"
|
|
|
6
6
|
require "yaml"
|
|
7
7
|
require_relative "control_io"
|
|
8
8
|
require_relative "phase_ownership"
|
|
9
|
+
require_relative "requirement_graph"
|
|
9
10
|
|
|
10
11
|
module WorkflowStateValidator
|
|
11
12
|
REQUIRED_STATE_FIELDS = %w[
|
|
@@ -76,6 +77,26 @@ module WorkflowStateValidator
|
|
|
76
77
|
validate_completed_outputs(issues, root, state, step_by_id, completed_ids, artifact_by_path, strict_artifact_status)
|
|
77
78
|
validate_waiting_checkpoint(issues, root, state, step_by_id, artifact_by_path, strict_artifact_status)
|
|
78
79
|
validate_current_in_progress_output_drift(issues, root, state, step_by_id, artifact_by_path)
|
|
80
|
+
graph_gate = workflow.dig("governance", "requirement_graph_gate").to_s
|
|
81
|
+
governed_steps = %w[requirement-baseline api-contract integration-verify change-plan execute verify]
|
|
82
|
+
# A historical completed state is never rolled back solely because it has
|
|
83
|
+
# no v2 graph/evidence. Its first new governed step, however, must satisfy
|
|
84
|
+
# the new contract before it can advance.
|
|
85
|
+
strict_requirement_graph = graph_gate == "enforced" && (governed_steps.include?(state["current_step"]) || completed_ids.any? { |id| governed_steps.include?(id) })
|
|
86
|
+
observe_requirement_graph(issues, root, state, strict: strict_requirement_graph)
|
|
87
|
+
# Migration is intentionally non-destructive: pre-v2 completed steps are
|
|
88
|
+
# visible as unattested, never rewritten, rolled back, or auto-rerun.
|
|
89
|
+
if state["governance_started_revision"].nil?
|
|
90
|
+
legacy_steps = completed_ids.select { |id| governed_steps.include?(id) }
|
|
91
|
+
if legacy_steps.any?
|
|
92
|
+
issues << issue(
|
|
93
|
+
"warning",
|
|
94
|
+
"legacy_unattested",
|
|
95
|
+
"Historical governed steps predate Evidence Pack v2 and are report-only",
|
|
96
|
+
steps: legacy_steps
|
|
97
|
+
)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
79
100
|
|
|
80
101
|
ok = issues.none? { |entry| entry["severity"] == "error" }
|
|
81
102
|
result(ok, state_path, workflow_path, registry_path, issues)
|
|
@@ -263,6 +284,43 @@ module WorkflowStateValidator
|
|
|
263
284
|
end
|
|
264
285
|
end
|
|
265
286
|
|
|
287
|
+
# P1 observation mode: existing projects must not become invalid merely
|
|
288
|
+
# because they predate governance graphs. Once a graph exists, surface its
|
|
289
|
+
# structural failures through state inspection so operators can fix them
|
|
290
|
+
# before the corresponding checkpoint is upgraded to fail-closed.
|
|
291
|
+
def observe_requirement_graph(issues, root, state, strict: false)
|
|
292
|
+
path, relative = RequirementGraph.graph_path(root, state["current_feature"])
|
|
293
|
+
unless File.exist?(path)
|
|
294
|
+
issues << issue(strict ? "error" : "warning", "requirement_graph_missing", "Requirement governance graph is missing", path: relative) if strict
|
|
295
|
+
return
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
graph, = RequirementGraph.load_graph(root, state["current_feature"])
|
|
299
|
+
errors = RequirementGraph.validate(graph)
|
|
300
|
+
if errors.any?
|
|
301
|
+
issues << issue(
|
|
302
|
+
strict ? "error" : "warning",
|
|
303
|
+
"requirement_graph_observe_failed",
|
|
304
|
+
"Requirement governance graph has structural gaps (observation mode)",
|
|
305
|
+
path: relative,
|
|
306
|
+
graph_revision: graph["revision"],
|
|
307
|
+
errors: errors
|
|
308
|
+
)
|
|
309
|
+
end
|
|
310
|
+
return if Array(graph["stale"]).empty?
|
|
311
|
+
|
|
312
|
+
issues << issue(
|
|
313
|
+
strict ? "error" : "warning",
|
|
314
|
+
"requirement_graph_needs_recheck",
|
|
315
|
+
"Requirement governance graph has downstream nodes awaiting recheck (observation mode)",
|
|
316
|
+
path: relative,
|
|
317
|
+
graph_revision: graph["revision"],
|
|
318
|
+
stale: graph["stale"]
|
|
319
|
+
)
|
|
320
|
+
rescue ArgumentError => error
|
|
321
|
+
issues << issue("warning", "requirement_graph_observe_failed", error.message)
|
|
322
|
+
end
|
|
323
|
+
|
|
266
324
|
def validate_step_outputs(issues, root, state, step, artifact_by_path, strict_artifact_status, waiting_checkpoint)
|
|
267
325
|
Array(step["outputs"]).each do |output|
|
|
268
326
|
next unless output["required"]
|
|
@@ -324,6 +382,7 @@ module WorkflowStateValidator
|
|
|
324
382
|
validate_frontend_tech_spec_gate(issues, step, data)
|
|
325
383
|
validate_api_supplement_gate(issues, step, data)
|
|
326
384
|
validate_integration_merge_gate(issues, step, data)
|
|
385
|
+
validate_change_plan_gate(issues, step, data)
|
|
327
386
|
validate_verification_gate(issues, step, data)
|
|
328
387
|
rescue JSON::ParserError => e
|
|
329
388
|
issues << issue("error", "invalid_meta_json", e.message, step: step["id"], path: path)
|
|
@@ -423,6 +482,10 @@ module WorkflowStateValidator
|
|
|
423
482
|
|
|
424
483
|
issues << issue("error", "baseline_blocking_counter_nonzero", "Requirement baseline has a non-zero blocking counter", step: step["id"], field: field, count: data[field])
|
|
425
484
|
end
|
|
485
|
+
|
|
486
|
+
if data["traceability_status"] != "passed"
|
|
487
|
+
issues << issue("error", "baseline_traceability_not_passed", "Requirement traceability must pass before technical design", step: step["id"], status: data["traceability_status"])
|
|
488
|
+
end
|
|
426
489
|
end
|
|
427
490
|
|
|
428
491
|
def validate_api_contract_gate(issues, step, data)
|
|
@@ -436,6 +499,10 @@ module WorkflowStateValidator
|
|
|
436
499
|
issues << issue("error", "api_contract_pending_items", "API contract has unresolved pending contract items", step: step["id"], count: data["pending_contract_count"])
|
|
437
500
|
end
|
|
438
501
|
|
|
502
|
+
if data["traceability_status"] != "passed"
|
|
503
|
+
issues << issue("error", "api_contract_traceability_not_passed", "API contract must retain complete requirement traceability", step: step["id"], status: data["traceability_status"])
|
|
504
|
+
end
|
|
505
|
+
|
|
439
506
|
api_required = data["api_required"]
|
|
440
507
|
endpoint_count = data["endpoint_count"].to_i
|
|
441
508
|
if api_required == false && endpoint_count.positive?
|
|
@@ -515,6 +582,10 @@ module WorkflowStateValidator
|
|
|
515
582
|
issues << issue("error", "merge_gate_not_passed", "Integration merge gate status is not passed", step: step["id"], status: data["merge_gate_status"])
|
|
516
583
|
end
|
|
517
584
|
|
|
585
|
+
if data["traceability_status"] != "passed"
|
|
586
|
+
issues << issue("error", "integration_traceability_not_passed", "Integration gate requires complete requirement-to-design traceability", step: step["id"], status: data["traceability_status"])
|
|
587
|
+
end
|
|
588
|
+
|
|
518
589
|
%w[
|
|
519
590
|
contract_backend_mismatch_count
|
|
520
591
|
contract_frontend_mismatch_count
|
|
@@ -527,6 +598,20 @@ module WorkflowStateValidator
|
|
|
527
598
|
end
|
|
528
599
|
end
|
|
529
600
|
|
|
601
|
+
def validate_change_plan_gate(issues, step, data)
|
|
602
|
+
return unless step["id"] == "change-plan"
|
|
603
|
+
|
|
604
|
+
if data["traceability_status"] != "passed"
|
|
605
|
+
issues << issue("error", "change_plan_traceability_not_passed", "Change plan requires complete requirement-to-task traceability", step: step["id"], status: data["traceability_status"])
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
%w[uncovered_requirement_count orphan_task_count].each do |field|
|
|
609
|
+
next if data[field].to_i.zero?
|
|
610
|
+
|
|
611
|
+
issues << issue("error", "change_plan_traceability_counter_nonzero", "Change plan has unresolved traceability coverage", step: step["id"], field: field, count: data[field])
|
|
612
|
+
end
|
|
613
|
+
end
|
|
614
|
+
|
|
530
615
|
def validate_verification_gate(issues, step, data)
|
|
531
616
|
return unless step["id"] == "verify"
|
|
532
617
|
|
package/plugins/devflow-core/skills/workflow-orchestrator/templates/feature-development.yaml
CHANGED
|
@@ -13,6 +13,40 @@ phase_scope:
|
|
|
13
13
|
failure_branch_enabled: true
|
|
14
14
|
parallel_window_enabled: true
|
|
15
15
|
|
|
16
|
+
# P2 preset: new work fail-closes at the defined checkpoints. Existing STATE
|
|
17
|
+
# files without governance_started_revision remain legacy_unattested and are
|
|
18
|
+
# only reported until their next newly-started governed step.
|
|
19
|
+
governance:
|
|
20
|
+
requirement_graph_gate: enforced
|
|
21
|
+
enforced_checkpoints:
|
|
22
|
+
- CP-1
|
|
23
|
+
- CP-API
|
|
24
|
+
- CP-2
|
|
25
|
+
- CP-3
|
|
26
|
+
step_checkers:
|
|
27
|
+
requirement-baseline:
|
|
28
|
+
- requirement-graph-check
|
|
29
|
+
- slice-independence-check
|
|
30
|
+
- acceptance-coverage-check
|
|
31
|
+
- change-impact-check
|
|
32
|
+
api-contract:
|
|
33
|
+
- requirement-graph-check
|
|
34
|
+
- contract-coverage-check
|
|
35
|
+
- change-impact-check
|
|
36
|
+
integration-verify:
|
|
37
|
+
- requirement-graph-check
|
|
38
|
+
- slice-independence-check
|
|
39
|
+
- contract-coverage-check
|
|
40
|
+
- change-impact-check
|
|
41
|
+
change-plan:
|
|
42
|
+
- requirement-graph-check
|
|
43
|
+
- slice-independence-check
|
|
44
|
+
- contract-coverage-check
|
|
45
|
+
- change-impact-check
|
|
46
|
+
verify:
|
|
47
|
+
- acceptance-coverage-check
|
|
48
|
+
- change-impact-check
|
|
49
|
+
|
|
16
50
|
artifact_registry:
|
|
17
51
|
source: ".planning/artifacts/index.yaml"
|
|
18
52
|
path_key: path
|
|
@@ -126,6 +160,7 @@ checkpoints:
|
|
|
126
160
|
producing_step: requirement-baseline
|
|
127
161
|
required_outputs:
|
|
128
162
|
- ".planning/requirements/baseline.md"
|
|
163
|
+
- ".planning/requirements/{feature}/traceability.json"
|
|
129
164
|
required_meta_output: ".planning/requirements/baseline.meta.json"
|
|
130
165
|
required_meta_fields:
|
|
131
166
|
- review_status
|
|
@@ -138,6 +173,7 @@ checkpoints:
|
|
|
138
173
|
- code_reality_missing_count
|
|
139
174
|
- current_feature
|
|
140
175
|
- depends_on_count
|
|
176
|
+
- traceability_status
|
|
141
177
|
summary_fields:
|
|
142
178
|
- fp_count
|
|
143
179
|
- br_count
|
|
@@ -146,9 +182,10 @@ checkpoints:
|
|
|
146
182
|
- critical_image_missing_count
|
|
147
183
|
- challenge_pending_count
|
|
148
184
|
- code_reality_missing_count
|
|
185
|
+
- traceability_status
|
|
149
186
|
- key_decisions
|
|
150
187
|
- risks
|
|
151
|
-
prompt: "
|
|
188
|
+
prompt: "确认需求基线和需求追溯清单均完整;每个 REQ 都有六维验收定义,并允许进入 UI/功能拆解和技术方案阶段。"
|
|
152
189
|
confirm_options:
|
|
153
190
|
- approve
|
|
154
191
|
- needs_fix
|
|
@@ -196,6 +233,7 @@ checkpoints:
|
|
|
196
233
|
- contract_frontend_mismatch_count
|
|
197
234
|
- unhandled_api_supplement_count
|
|
198
235
|
- blocking_issue_count
|
|
236
|
+
- traceability_status
|
|
199
237
|
summary_fields:
|
|
200
238
|
- merge_gate_status
|
|
201
239
|
- api_required
|
|
@@ -203,7 +241,8 @@ checkpoints:
|
|
|
203
241
|
- contract_frontend_mismatch_count
|
|
204
242
|
- unhandled_api_supplement_count
|
|
205
243
|
- blocking_issue_count
|
|
206
|
-
|
|
244
|
+
- traceability_status
|
|
245
|
+
prompt: "确认 API 契约、后端方案、前端调用三方一致,且所有 REQ 都已有设计覆盖,并允许进入变更清单。"
|
|
207
246
|
confirm_options:
|
|
208
247
|
- approve
|
|
209
248
|
- needs_fix
|
|
@@ -215,13 +254,19 @@ checkpoints:
|
|
|
215
254
|
producing_step: change-plan
|
|
216
255
|
required_outputs:
|
|
217
256
|
- ".planning/features/{feature}/变更清单.md"
|
|
257
|
+
- ".planning/features/{feature}/变更清单.meta.json"
|
|
258
|
+
required_meta_output: ".planning/features/{feature}/变更清单.meta.json"
|
|
259
|
+
required_meta_fields:
|
|
260
|
+
- traceability_status
|
|
261
|
+
- uncovered_requirement_count
|
|
262
|
+
- orphan_task_count
|
|
218
263
|
summary_fields:
|
|
219
264
|
- task_count
|
|
220
265
|
- ddl_count
|
|
221
266
|
- migration_steps
|
|
222
267
|
- verification_steps
|
|
223
268
|
- risks
|
|
224
|
-
prompt: "确认变更清单中的 DDL
|
|
269
|
+
prompt: "确认变更清单中的 DDL、代码任务、上线步骤和验收标准可执行;每项 REQ 都有任务、每项任务都有 REQ 来源,并允许进入代码执行。"
|
|
225
270
|
confirm_options:
|
|
226
271
|
- approve
|
|
227
272
|
- needs_fix
|
|
@@ -379,6 +424,9 @@ steps:
|
|
|
379
424
|
- path: ".planning/requirements/baseline.md"
|
|
380
425
|
type: requirement-baseline
|
|
381
426
|
required: true
|
|
427
|
+
- path: ".planning/requirements/{feature}/traceability.json"
|
|
428
|
+
type: requirement-traceability
|
|
429
|
+
required: true
|
|
382
430
|
meta_output:
|
|
383
431
|
path: ".planning/requirements/baseline.meta.json"
|
|
384
432
|
fields:
|
|
@@ -395,6 +443,7 @@ steps:
|
|
|
395
443
|
pending_items: { type: array, required: false }
|
|
396
444
|
risks: { type: array, required: false }
|
|
397
445
|
key_decisions: { type: array, max: 5, required: false }
|
|
446
|
+
traceability_status: { type: string, required: true }
|
|
398
447
|
checkpoint: CP-1
|
|
399
448
|
|
|
400
449
|
- id: api-contract
|
|
@@ -420,6 +469,7 @@ steps:
|
|
|
420
469
|
breaking_change_count: { type: integer, required: true }
|
|
421
470
|
permission_rule_count: { type: integer, required: true }
|
|
422
471
|
error_case_count: { type: integer, required: true }
|
|
472
|
+
traceability_status: { type: string, required: true }
|
|
423
473
|
checkpoint: CP-API
|
|
424
474
|
|
|
425
475
|
- id: ui-spec
|
|
@@ -587,6 +637,12 @@ steps:
|
|
|
587
637
|
- path: ".planning/features/{feature}/变更清单.md"
|
|
588
638
|
type: change-plan
|
|
589
639
|
required: true
|
|
640
|
+
meta_output:
|
|
641
|
+
path: ".planning/features/{feature}/变更清单.meta.json"
|
|
642
|
+
fields:
|
|
643
|
+
traceability_status: { type: string, required: true }
|
|
644
|
+
uncovered_requirement_count: { type: integer, required: true }
|
|
645
|
+
orphan_task_count: { type: integer, required: true }
|
|
590
646
|
checkpoint: CP-3
|
|
591
647
|
|
|
592
648
|
- id: phase-structure
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": 1,
|
|
3
|
+
"feature": "{feature}",
|
|
4
|
+
"requirements": [
|
|
5
|
+
{
|
|
6
|
+
"id": "REQ-001",
|
|
7
|
+
"title": "原子且可验收的需求",
|
|
8
|
+
"status": "confirmed",
|
|
9
|
+
"scope": "in",
|
|
10
|
+
"dimensions": {
|
|
11
|
+
"input": "输入、前置条件与参数",
|
|
12
|
+
"output": "输出、持久化或界面结果",
|
|
13
|
+
"behavior": "正常业务语义",
|
|
14
|
+
"orchestration": "遍历、触发、顺序、并发或调度;无则写 N/A",
|
|
15
|
+
"failure": "异常、兼容、幂等、资源限制;无则写 N/A",
|
|
16
|
+
"verification": "可执行的验收证据"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"designs": [],
|
|
21
|
+
"tasks": [],
|
|
22
|
+
"verification": []
|
|
23
|
+
}
|
|
@@ -27,11 +27,14 @@ description: "Use after requirement-baseline, before dual-track fork. Defines sh
|
|
|
27
27
|
- `.planning/features/{功能名}/api-contract.md`
|
|
28
28
|
- `.planning/features/{功能名}/api-contract.meta.json`
|
|
29
29
|
|
|
30
|
+
The meta file must also set `traceability_status: "passed"` only after every API design has been written to `traceability.json.designs` and `traceability_check.py --stage design` succeeds; otherwise set `failed` and do not advance.
|
|
31
|
+
|
|
30
32
|
## 输入
|
|
31
33
|
|
|
32
34
|
- `.planning/requirements/baseline.md` — 需求基线(FP/BR/BC)
|
|
33
35
|
- `.planning/navigation/INDEX.md` 和相关 codebase navigation — 粗定位已有接口
|
|
34
36
|
- `.planning/code-index/`(如存在)— 查询已有 route/handler/API symbol 与 `routes_to` / `calls` 关系,确认接口复用和冲突
|
|
37
|
+
- `.planning/requirements/{feature}/traceability.json` — 每个接口必须回指它的 `REQ-*`,不能只写 FP 标题
|
|
35
38
|
|
|
36
39
|
使用 code-index 时,必须回读 `evidence_path:evidence_line` 附近源码后再把既有接口写入契约;不得只凭 Markdown navigation 或 relation 摘要判断。
|
|
37
40
|
|
|
@@ -39,7 +42,7 @@ description: "Use after requirement-baseline, before dual-track fork. Defines sh
|
|
|
39
42
|
|
|
40
43
|
1. **只定义接口契约,不谈实现细节** — 不写数据表结构、不写具体代码、不写业务流程内部逻辑
|
|
41
44
|
2. **分叉后不变更** — 一旦确定,Track A/B 都基于此契约工作。变更走 `api-supplement` 异常路径
|
|
42
|
-
3. **接口签名必须完整** — 包括 endpoint、method
|
|
45
|
+
3. **接口签名必须完整** — 包括 endpoint、method、请求参数(含类型约束)、响应结构(含状态码)、错误契约与行为语义(过滤、排序、权限、幂等/兼容规则)
|
|
43
46
|
4. **数据模型共享** — 核心业务实体定义在这里,前后端共用一个数据模型
|
|
44
47
|
5. **切片对齐** — 若 baseline 包含 `SL-*`,先读取 `skill://workflow-pipeline/references/slice-safety-guide.md`,只为当前执行切片定义 API。后置切片接口不得提前进入契约。
|
|
45
48
|
6. **既有接口优先查事实索引** — 当 `.planning/code-index/` 存在时,先用 Symbol/Relation 定位候选接口、调用方和处理器,再读取源码证据;缺失或过期时再按 navigation 和 `rg` 兜底。
|
|
@@ -42,6 +42,10 @@ allowed-tools:
|
|
|
42
42
|
|
|
43
43
|
# 后端技术方案生成器
|
|
44
44
|
|
|
45
|
+
## 需求追溯硬约束
|
|
46
|
+
|
|
47
|
+
读取 `.planning/requirements/{feature}/traceability.json`。每个设计章节必须列 `覆盖 REQ: REQ-*`;定时任务、批处理、导入和通知至少拆为“编排(扫描/触发/锁/重试)”与“业务算法(判定/计算/写入)”两个可独立验证的小节。不得把遍历全部活跃组织、发送通知、文件解析等编排事实藏在算法描述中。
|
|
48
|
+
|
|
45
49
|
根据需求基线和项目现有代码,生成聚焦于影响分析的后端技术方案。
|
|
46
50
|
|
|
47
51
|
## 核心原则
|
|
@@ -34,6 +34,7 @@ description: "Use after both Track A (api-call-guide) and Track B (frontend-tech
|
|
|
34
34
|
{
|
|
35
35
|
"api_required": true,
|
|
36
36
|
"merge_gate_status": "passed",
|
|
37
|
+
"traceability_status": "passed",
|
|
37
38
|
"contract_backend_mismatch_count": 0,
|
|
38
39
|
"contract_frontend_mismatch_count": 0,
|
|
39
40
|
"unhandled_api_supplement_count": 0,
|
|
@@ -50,6 +51,7 @@ description: "Use after both Track A (api-call-guide) and Track B (frontend-tech
|
|
|
50
51
|
- `.planning/features/{功能名}/后端技术方案.md` — Track A 产出的后端方案
|
|
51
52
|
- `.planning/features/{功能名}/api-supplement-requests.md` —(可选)Track B 提交的 API 补充需求
|
|
52
53
|
- `.planning/code-index/`(如存在)— 用于抽查 API route/handler、frontend API calls、imports/calls 关系,并回读源码 evidence
|
|
54
|
+
- `.planning/requirements/{feature}/traceability.json` — 原子 REQ 的唯一追溯源
|
|
53
55
|
|
|
54
56
|
## 核心原则
|
|
55
57
|
|
|
@@ -107,6 +109,13 @@ description: "Use after both Track A (api-call-guide) and Track B (frontend-tech
|
|
|
107
109
|
- 可以用已有接口拼吗?
|
|
108
110
|
- 必须新增的对 Track A 影响多大?
|
|
109
111
|
|
|
112
|
+
### Step 5:需求→设计闭环(不可跳过)
|
|
113
|
+
|
|
114
|
+
1. 将后端、前端、UI、API 契约中的设计项写入 `traceability.json.designs`,每项以 `requirements: ["REQ-…"]` 回指来源。
|
|
115
|
+
2. 所有 API 类型设计必须在 `contract` 中同时写 `request`、`response`、`errors`、`behavior`;禁止只对齐响应字段。
|
|
116
|
+
3. 执行 `python3 <workflow-orchestrator>/scripts/traceability_check.py --file .planning/requirements/{feature}/traceability.json --stage design`。
|
|
117
|
+
4. 结果不为 passed 时,`merge_gate_status` 必须为 failed,`blocking_issue_count` 必须大于 0,回到对应方案修复;不得进入变更清单。
|
|
118
|
+
|
|
110
119
|
## 产出模板
|
|
111
120
|
|
|
112
121
|
```
|
|
@@ -169,4 +178,5 @@ description: "Use after both Track A (api-call-guide) and Track B (frontend-tech
|
|
|
169
178
|
- [ ] 验证结论已写入报告
|
|
170
179
|
- [ ] meta.json 中 `merge_gate_status` 为 `passed`
|
|
171
180
|
- [ ] meta.json 中所有 mismatch / supplement / blocking 计数均为 0
|
|
181
|
+
- [ ] `traceability_check.py --stage design` 通过,且 meta.json 的 `traceability_status` 为 `passed`
|
|
172
182
|
- [ ] 无 API 变更时生成 no-op meta,`api_required` 为 false,`merge_gate_status` 为 `skipped`
|
|
@@ -58,6 +58,7 @@ description: "Use after workflow-integration-verify has passed or produced an ap
|
|
|
58
58
|
5. 读取功能点梳理(如存在)→ 确认 FP 覆盖完整性
|
|
59
59
|
6. 读取 baseline.md 的审查结论和风险标记
|
|
60
60
|
7. 若输入包含 `SL-*` 切片计划,读取 `skill://workflow-pipeline/references/slice-safety-guide.md`,只生成当前执行切片的任务。后置切片只能写入风险/后续范围,不得生成实现任务。
|
|
61
|
+
8. 读取 `.planning/requirements/{feature}/traceability.json`;它是任务覆盖判断的唯一 REQ 清单,不能仅凭技术方案标题推断覆盖。
|
|
61
62
|
|
|
62
63
|
### 第二阶段:扫描项目上下文
|
|
63
64
|
|
|
@@ -70,6 +71,8 @@ description: "Use after workflow-integration-verify has passed or produced an ap
|
|
|
70
71
|
|
|
71
72
|
输出到 `.planning/features/{feature}/变更清单.md`。
|
|
72
73
|
|
|
74
|
+
同时输出 `.planning/features/{feature}/变更清单.meta.json`。只有 `traceability_check.py --stage change-plan` 成功时才允许写入 `traceability_status: "passed"`;`uncovered_requirement_count` 和 `orphan_task_count` 必须为 0。
|
|
75
|
+
|
|
73
76
|
## 输出结构
|
|
74
77
|
|
|
75
78
|
```markdown
|
|
@@ -109,6 +112,7 @@ description: "Use after workflow-integration-verify has passed or produced an ap
|
|
|
109
112
|
- **参考实现**:`path/to/similar/file.py:line`(有则填写)
|
|
110
113
|
- **Code Index 证据**:相关 symbol/relation/evidence(有 `.planning/code-index/` 时填写;无则写"未使用:原因")
|
|
111
114
|
- **需求来源**:FP-001 / BR-001 / 技术方案第X章
|
|
115
|
+
- **REQ 覆盖**:`REQ-001`(必须是 traceability.json 中的原子 ID;无来源任务必须显式标为获批技术债)
|
|
112
116
|
- **Slice**:SL-001
|
|
113
117
|
- **适用规范**:`.context/spec/backend/service.md` 等(有则填写)
|
|
114
118
|
- **相关经验教训**:lesson ID 或"无"
|
|
@@ -119,6 +123,7 @@ description: "Use after workflow-integration-verify has passed or produced an ap
|
|
|
119
123
|
- **完成标准**:(每条必须使用 `- [ ]` checkbox 格式,可被 code_review 门禁自动验证)
|
|
120
124
|
- [ ] 具体可验证的检查项(可映射到代码中具体元素)
|
|
121
125
|
- [ ] 另一条检查项(可映射到验证命令)
|
|
126
|
+
- **六维验收**:输入、输出、行为、编排、失败、验证各写一条可验证结论;算法与遍历/调度等编排必须分列,不能相互替代。
|
|
122
127
|
- **验证命令**:`pytest tests/test_xxx.py -k test_yyy`
|
|
123
128
|
|
|
124
129
|
## 四、配置变更
|
|
@@ -158,3 +163,6 @@ graph TD
|
|
|
158
163
|
- [ ] 若 `.planning/code-index/` 存在,涉及已有代码的任务已标注相关 symbol/relation/evidence 或说明未使用原因
|
|
159
164
|
- [ ] 每个任务包含审查要求、适用规范、需求来源字段(至少标注"无")
|
|
160
165
|
- [ ] 文件路径与技术方案一致
|
|
166
|
+
- [ ] 变更清单任务同步写入 `traceability.json.tasks`,每项包含 `id`、`requirements` 和六维 `acceptance`
|
|
167
|
+
- [ ] 执行 `traceability_check.py --stage change-plan` 通过;没有漏 REQ,也没有无 REQ 来源的任务
|
|
168
|
+
- [ ] 输出 `变更清单.meta.json`,至少包含 `traceability_status: passed`、`uncovered_requirement_count: 0`、`orphan_task_count: 0`
|
|
@@ -204,6 +204,10 @@ Before accepting the rebuttal or retracting the finding, re-open the cited raw s
|
|
|
204
204
|
|
|
205
205
|
## Quality Bar
|
|
206
206
|
|
|
207
|
+
## Governance Graph Candidate
|
|
208
|
+
|
|
209
|
+
Submit `risk` and `decision` candidates through `devflow_requirement_graph`, and add missing `behavior` candidates only when backed by a cited source. A `pass` review cannot promote candidates, clear stale nodes, or claim machine validation; it supplies structured candidates and evidence for the Core gate and human checkpoint.
|
|
210
|
+
|
|
207
211
|
The review must make it easy to trace every conclusion back to evidence. Include:
|
|
208
212
|
|
|
209
213
|
- flow inventory and critical capability chains;
|
|
@@ -130,6 +130,10 @@ Accepted
|
|
|
130
130
|
|
|
131
131
|
## Meta Output
|
|
132
132
|
|
|
133
|
+
## Governance Graph Candidate
|
|
134
|
+
|
|
135
|
+
Submit bounded candidates through `devflow_requirement_graph`: use `term` for shared language and `behavior` for actor, precondition, state transition, invariant, writes, side effects, failure, and recovery. Link candidates only with returned IDs. Never directly edit the canonical graph or mark a node confirmed; unresolved ownership remains a candidate and is reported in metadata.
|
|
136
|
+
|
|
133
137
|
`领域模型记录.meta.json` minimum fields:
|
|
134
138
|
|
|
135
139
|
```json
|
|
@@ -107,6 +107,15 @@ Always create or update:
|
|
|
107
107
|
|
|
108
108
|
- `.planning/requirements/baseline.md` — unified requirement baseline
|
|
109
109
|
- `.planning/requirements/baseline.meta.json` — structured metadata. Schema defined in `feature-development.yaml` under `steps[requirement-baseline].meta_output.fields`: `review_status`, `fp_count`, `br_count`, `bc_count`, `blocking_pending_count`, `critical_image_missing_count`, `challenge_pending_count`, `code_reality_missing_count`, `current_feature`, `depends_on_count`, plus optional `pending_items`, `risks`, and `key_decisions`.
|
|
110
|
+
- `.planning/requirements/{feature}/traceability.json` — copy the orchestrator `templates/traceability.json` schema and create one atomic `REQ-*` record for every confirmed in-scope requirement. Every record must define `input`、`output`、`behavior`、`orchestration`、`failure`、`verification`; use `N/A` only with a reason when a dimension truly does not apply.
|
|
111
|
+
|
|
112
|
+
Before the CP-1 result is reported, run:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
python3 <workflow-orchestrator>/scripts/traceability_check.py --file .planning/requirements/{feature}/traceability.json --stage baseline
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Set `baseline.meta.json.traceability_status` to `passed` only when that command succeeds. A failed traceability check is a blocking baseline defect, not a deferred documentation suggestion.
|
|
110
119
|
|
|
111
120
|
Do not create by default:
|
|
112
121
|
|
|
@@ -718,6 +727,10 @@ Completion gate: baseline and baseline.meta.json are written and contain no unre
|
|
|
718
727
|
|
|
719
728
|
### 7.4 产物完整性检查
|
|
720
729
|
|
|
730
|
+
### 7.4.1 Governance Graph Candidate
|
|
731
|
+
|
|
732
|
+
Before claiming baseline readiness, submit `requirement`、`rule`、`boundary`、`slice` and `acceptance` candidates through `devflow_requirement_graph`. Each requirement candidate must cite source IDs and reference behavior/acceptance IDs returned by the writer. Run `devflow_requirement_graph(action="validate")` and record its result in baseline metadata. Do not directly create `governance.json`, allocate IDs, or set candidate status to `confirmed`.
|
|
733
|
+
|
|
721
734
|
```markdown
|
|
722
735
|
- [ ] 每个原始需求映射到 FP-*/BR-*/BC-* 或 out-of-scope
|
|
723
736
|
- [ ] 追溯表完整,来源→FP 映射可验证
|
|
@@ -191,6 +191,10 @@ Ask at most one question, only when route cannot be decided without it. If the n
|
|
|
191
191
|
|
|
192
192
|
## Completion Rule
|
|
193
193
|
|
|
194
|
+
## Governance Graph Candidate
|
|
195
|
+
|
|
196
|
+
Before completion, inspect `devflow_requirement_graph` for the current feature. Submit only `source` or `code` candidate deltas for source material and repository facts discovered here. Read the returned graph revision after every accepted delta. Do not invent stable IDs, set a candidate to `confirmed`, or write `governance.json` directly.
|
|
197
|
+
|
|
194
198
|
Only tell `workflow-orchestrator` to complete `requirement-triage` after writing:
|
|
195
199
|
|
|
196
200
|
```json
|
package/src/cli.ts
CHANGED
|
@@ -14,7 +14,7 @@ function usage(): string {
|
|
|
14
14
|
" devflow-pi init [project]",
|
|
15
15
|
" devflow-pi doctor [project]",
|
|
16
16
|
" devflow-pi usage [project]",
|
|
17
|
-
" devflow-pi [project] [--resume [session-id]] [--prompt <text>] [--mcp]",
|
|
17
|
+
" devflow-pi [project] [--resume [session-id]] [--prompt <text>] [--mcp] [--yolo]",
|
|
18
18
|
].join("\n");
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -76,6 +76,7 @@ async function main(): Promise<void> {
|
|
|
76
76
|
originalOmpAgentDir,
|
|
77
77
|
resume: optionalOption(args, "--resume"),
|
|
78
78
|
enableMCP: args.includes("--mcp"),
|
|
79
|
+
approvalMode: args.includes("--yolo") ? "yolo" : "write",
|
|
79
80
|
});
|
|
80
81
|
}
|
|
81
82
|
|
package/src/runtime.ts
CHANGED
|
@@ -13,6 +13,7 @@ export interface RuntimeOptions {
|
|
|
13
13
|
hasUI?: boolean;
|
|
14
14
|
enableMCP?: boolean;
|
|
15
15
|
enableLsp?: boolean;
|
|
16
|
+
approvalMode?: "write" | "yolo";
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
const MANAGED_SETTINGS: Record<string, unknown> = {
|
|
@@ -54,7 +55,6 @@ const MANAGED_SETTINGS: Record<string, unknown> = {
|
|
|
54
55
|
"lsp.enabled": true,
|
|
55
56
|
"lsp.lazy": true,
|
|
56
57
|
"lsp.diagnosticsOnWrite": true,
|
|
57
|
-
"tools.approvalMode": "write",
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
export async function createEmbeddedRuntime(project: ProjectContext, options: RuntimeOptions = {}) {
|
|
@@ -92,6 +92,7 @@ export async function createEmbeddedRuntime(project: ProjectContext, options: Ru
|
|
|
92
92
|
agentDir: productAgentDir,
|
|
93
93
|
overrides: {
|
|
94
94
|
...MANAGED_SETTINGS,
|
|
95
|
+
"tools.approvalMode": options.approvalMode ?? "write",
|
|
95
96
|
// OMP 17.2.7 classifies extension-package skills behind the generic
|
|
96
97
|
// third-party toggle. Explicit custom roots keep ambient providers off
|
|
97
98
|
// while guaranteeing the packaged Devflow skills are present.
|