@xenonbyte/da-vinci-workflow 0.1.26 → 0.2.1
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/CHANGELOG.md +14 -0
- package/README.md +17 -65
- package/README.zh-CN.md +17 -65
- package/commands/claude/dv/continue.md +5 -0
- package/commands/codex/prompts/dv-continue.md +6 -1
- package/commands/gemini/dv/continue.toml +5 -0
- package/commands/templates/dv-continue.shared.md +33 -0
- package/docs/dv-command-reference.md +31 -0
- package/docs/execution-chain-migration.md +46 -0
- package/docs/execution-chain-plan.md +125 -0
- package/docs/prompt-entrypoints.md +6 -0
- package/docs/workflow-examples.md +10 -0
- package/docs/workflow-overview.md +25 -0
- package/docs/zh-CN/dv-command-reference.md +31 -0
- package/docs/zh-CN/execution-chain-migration.md +46 -0
- package/docs/zh-CN/prompt-entrypoints.md +6 -0
- package/docs/zh-CN/workflow-examples.md +10 -0
- package/docs/zh-CN/workflow-overview.md +25 -0
- package/lib/artifact-parsers.js +120 -0
- package/lib/audit.js +61 -0
- package/lib/cli.js +328 -13
- package/lib/diff-spec.js +242 -0
- package/lib/execution-signals.js +136 -0
- package/lib/lint-bindings.js +143 -0
- package/lib/lint-spec.js +408 -0
- package/lib/lint-tasks.js +176 -0
- package/lib/planning-parsers.js +567 -0
- package/lib/scaffold.js +193 -0
- package/lib/scope-check.js +603 -0
- package/lib/sidecars.js +369 -0
- package/lib/supervisor-review.js +28 -3
- package/lib/utils.js +10 -2
- package/lib/verify.js +652 -0
- package/lib/workflow-contract.js +107 -0
- package/lib/workflow-persisted-state.js +297 -0
- package/lib/workflow-state.js +785 -0
- package/package.json +10 -2
- package/references/artifact-templates.md +26 -0
- package/references/checkpoints.md +14 -0
- package/references/modes.md +10 -0
|
@@ -39,6 +39,36 @@ Da Vinci 期望它们遵循工作流状态。
|
|
|
39
39
|
|
|
40
40
|
这些命令不会替代 `dv:` 选路,但能显著提升设计执行质量:
|
|
41
41
|
|
|
42
|
+
- `da-vinci workflow-status --project <path> [--change <id>] [--json]`
|
|
43
|
+
- 从工件和 checkpoint 真相推导当前 workflow 阶段
|
|
44
|
+
- 报告 blocker、warning、handoff gate 状态,以及主推荐路由
|
|
45
|
+
- 它和 `audit` 职责不同:它负责选路,不是终态审计真相
|
|
46
|
+
- `da-vinci next-step --project <path> [--change <id>] [--json]`
|
|
47
|
+
- 基于同一套 workflow-state 推导,给出 route-first 的续跑建议
|
|
48
|
+
- 在自由扫描工件之前,优先把它作为第一路由信号
|
|
49
|
+
- `da-vinci lint-spec --project <path> [--change <id>] [--strict] [--json]`
|
|
50
|
+
- 校验 Da Vinci 运行时 `spec.md` 的核心章节(`Behavior`、`States`、`Inputs`、`Outputs`、`Acceptance`、`Edge Cases`)
|
|
51
|
+
- 默认 advisory(有发现给 `WARN` 且不阻断);显式 `--strict` 才升级为阻断
|
|
52
|
+
- 不会把 OpenSpec 规划用的 `ADDED Requirements` 结构当成运行时 spec 合法结构
|
|
53
|
+
- `da-vinci scope-check --project <path> [--change <id>] [--strict] [--json]`
|
|
54
|
+
- 检查 proposal、page-map、运行时 spec、pencil-design 状态和 tasks 之间的 scope 传播一致性
|
|
55
|
+
- 输出页面与状态两条线的机器可读覆盖矩阵
|
|
56
|
+
- 默认 advisory(有发现给 `WARN` 且不阻断);显式 `--strict` 才升级为阻断
|
|
57
|
+
- `da-vinci lint-tasks --project <path> [--change <id>] [--strict] [--json]`
|
|
58
|
+
- 校验顶层 task groups、编号顺序、verification 动作和 behavior 覆盖提示
|
|
59
|
+
- 默认 advisory(有发现给 `WARN` 且不阻断);显式 `--strict` 才升级为阻断
|
|
60
|
+
- `da-vinci lint-bindings --project <path> [--change <id>] [--strict] [--json]`
|
|
61
|
+
- 校验实现到 Pencil 的映射是否可解析、source 形态是否合理、实现落点是否可定位
|
|
62
|
+
- 默认 advisory(有发现给 `WARN` 且不阻断);显式 `--strict` 才升级为阻断
|
|
63
|
+
- `da-vinci generate-sidecars --project <path> [--change <id>] [--json]`
|
|
64
|
+
- 显式生成确定性的 planning sidecars:`spec.index.json`、`tasks.index.json`、`page-map.index.json`、`bindings.index.json`
|
|
65
|
+
- sidecar 只允许通过这个命令写入;lint/status/verify 不应静默重写
|
|
66
|
+
- `da-vinci verify-bindings|verify-implementation|verify-structure|verify-coverage --project <path> [--change <id>] [--strict] [--json]`
|
|
67
|
+
- 校验代码落点、计划状态实现证据、以及绑定驱动的结构一致性
|
|
68
|
+
- `verify-structure` 会明确报告是 markup-backed 还是 heuristic fallback,并给出置信度
|
|
69
|
+
- `da-vinci diff-spec --project <path> [--change <id>] [--from <sidecars-dir>] [--json]`
|
|
70
|
+
- 比较规范化 planning sidecars,报告新增/删除/修改的规划项
|
|
71
|
+
- 在同一 surface 下提供 spec 差异以及 tasks/page-map/bindings 摘要差异
|
|
42
72
|
- `da-vinci icon-sync`
|
|
43
73
|
- 同步官方图标名(Material Symbols、Lucide、Feather、Phosphor)到 `~/.da-vinci/icon-catalog.json`
|
|
44
74
|
- 默认是用户级范围(当前 HOME),同一用户可跨项目复用
|
|
@@ -116,6 +146,7 @@ Da Vinci 期望它们遵循工作流状态。
|
|
|
116
146
|
|
|
117
147
|
重要规则:
|
|
118
148
|
|
|
149
|
+
- 有 shell 能力时,先跑 `da-vinci workflow-status --project <path> [--change <id>] --json`,再用 `da-vinci next-step --project <path> [--change <id>]` 作为第一选路信号
|
|
119
150
|
- 如果设计已经有了,但 `tasks.md` 还没有,`continue` 通常应该把你送到 `tasks`
|
|
120
151
|
- 这时候不应该把 `build` 当成同级主推荐
|
|
121
152
|
- 选路必须先基于工件和 checkpoint 真相,再参考 Context Delta
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Execution-Chain 升级迁移指南
|
|
2
|
+
|
|
3
|
+
当你要在已有项目上启用 execution-chain 升级能力时,使用这份指南。
|
|
4
|
+
|
|
5
|
+
## 1. Sidecar 生成生命周期
|
|
6
|
+
|
|
7
|
+
Planning sidecar 是显式工件,不是隐式副产物。
|
|
8
|
+
|
|
9
|
+
- 用 `da-vinci generate-sidecars --project <path> [--change <id>]` 生成
|
|
10
|
+
- sidecar 写入 `.da-vinci/changes/<change-id>/sidecars/`
|
|
11
|
+
- lint/status/verify 不应静默改写 sidecar
|
|
12
|
+
- proposal/spec/page-map/tasks/bindings 有实质改动后应重新生成
|
|
13
|
+
|
|
14
|
+
## 2. Advisory 与 Strict 推广策略
|
|
15
|
+
|
|
16
|
+
默认策略:
|
|
17
|
+
|
|
18
|
+
- `lint-spec`、`scope-check`、`lint-tasks`、`lint-bindings` 默认 advisory(`WARN` 不硬阻断)
|
|
19
|
+
- 传 `--strict` 才把 warning 升级为阻断退出
|
|
20
|
+
- 只有在 warning 基线稳定后,才在 CI 打开 strict
|
|
21
|
+
|
|
22
|
+
Audit 集成:
|
|
23
|
+
|
|
24
|
+
- integrity audit 把 planning-signal 的 `BLOCK` 当 warning 级信号
|
|
25
|
+
- completion audit 把 verification-signal 的 `BLOCK` 当 failure 级信号
|
|
26
|
+
|
|
27
|
+
## 3. 持久化工作流状态回退
|
|
28
|
+
|
|
29
|
+
`workflow-status` 只有在以下条件全部满足时才会使用 `.da-vinci/state/workflow.json`:
|
|
30
|
+
|
|
31
|
+
- schema 版本可识别
|
|
32
|
+
- change 条目存在
|
|
33
|
+
- 时间戳未过期
|
|
34
|
+
- 指纹与当前工件真相一致
|
|
35
|
+
|
|
36
|
+
任一条件不满足时,会自动回退到基于工件的派生状态,并记录 reconciliation 说明。
|
|
37
|
+
|
|
38
|
+
## 4. Scaffold 约束
|
|
39
|
+
|
|
40
|
+
`da-vinci scaffold` 是 MVP 脚手架能力,约束如下:
|
|
41
|
+
|
|
42
|
+
- 输出只用于 TODO 标记和人工审阅
|
|
43
|
+
- 不是最终代码生成
|
|
44
|
+
- MVP 不做多框架扩展
|
|
45
|
+
- scaffold 边界来自 `pencil-bindings.md` 映射
|
|
46
|
+
- 接受前需跑 `verify-bindings`、`verify-implementation`、`verify-structure`
|
|
@@ -65,6 +65,12 @@
|
|
|
65
65
|
|
|
66
66
|
继续规则优先级:
|
|
67
67
|
|
|
68
|
+
- 有 shell 能力时,先运行 `da-vinci workflow-status --project <path> [--change <id>] --json`
|
|
69
|
+
- 再用 `da-vinci next-step --project <path> [--change <id>]` 作为第一续跑路由信号
|
|
70
|
+
- 如果运行时 spec 质量还不确定,进入 `build` 前先运行 `da-vinci lint-spec --project <path> [--change <id>]`
|
|
71
|
+
- 如果页面或状态在规划工件中的传播关系不确定,进入 `build` 前先运行 `da-vinci scope-check --project <path> [--change <id>]`
|
|
72
|
+
- 进入终态前先运行 `da-vinci verify-bindings --project <path> [--change <id>]` 与 `da-vinci verify-coverage --project <path> [--change <id>]`
|
|
73
|
+
- 当规划切片有改动且需要恢复判断时,运行 `da-vinci diff-spec --project <path> [--change <id>]`
|
|
68
74
|
- 先根据工件和 checkpoint 真相决定路由
|
|
69
75
|
- Context Delta 只用于恢复和解释,不用于覆盖选路
|
|
70
76
|
- 如果 Context Delta 与当前工件冲突,选路时忽略冲突内容并标记冲突
|
|
@@ -19,6 +19,16 @@
|
|
|
19
19
|
- `continue` 选路先看工件/checkpoint 真相,再把 Context Delta 当作辅助恢复信息
|
|
20
20
|
- 如果 Context Delta 与当前工件冲突,选路时应忽略冲突内容并记录冲突
|
|
21
21
|
|
|
22
|
+
execution-chain 命令组合(终态前建议):
|
|
23
|
+
|
|
24
|
+
- `da-vinci workflow-status --project <path> [--change <id>] --json`
|
|
25
|
+
- `da-vinci next-step --project <path> [--change <id>]`
|
|
26
|
+
- `da-vinci lint-spec|lint-tasks|lint-bindings --project <path> [--change <id>]`
|
|
27
|
+
- `da-vinci scope-check --project <path> [--change <id>]`
|
|
28
|
+
- `da-vinci generate-sidecars --project <path> [--change <id>]`
|
|
29
|
+
- `da-vinci verify-bindings|verify-implementation|verify-structure|verify-coverage --project <path> [--change <id>]`
|
|
30
|
+
- `da-vinci diff-spec --project <path> [--change <id>]`
|
|
31
|
+
|
|
22
32
|
## 1. `greenfield-spec`
|
|
23
33
|
|
|
24
34
|
适用:
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
如果你想看 Pencil 渲染、持久化、门禁和审计的专门说明,请看 [pencil-rendering-workflow.md](/Users/xubo/x-skills/da-vinci/docs/zh-CN/pencil-rendering-workflow.md)。
|
|
16
16
|
如果你想看逐个 `dv:` 命令的职责、下一步推荐和 `verify` 回退规则,请看 [dv-command-reference.md](/Users/xubo/x-skills/da-vinci/docs/zh-CN/dv-command-reference.md)。
|
|
17
17
|
如果你想看约束文件总览(哪些字段是硬门禁、哪些是指导项),请看 [constraint-files.md](/Users/xubo/x-skills/da-vinci/docs/zh-CN/constraint-files.md)。
|
|
18
|
+
如果你想看 sidecar、enforcement、persisted-state 回退和 scaffold 约束,请看 [execution-chain-migration.md](/Users/xubo/x-skills/da-vinci/docs/zh-CN/execution-chain-migration.md)。
|
|
18
19
|
|
|
19
20
|
## 核心契约
|
|
20
21
|
|
|
@@ -42,6 +43,30 @@ Da Vinci 围绕一个固定契约工作:
|
|
|
42
43
|
8. 实现。
|
|
43
44
|
9. 验证需求漂移和设计漂移。
|
|
44
45
|
|
|
46
|
+
## Workflow-State 命令面
|
|
47
|
+
|
|
48
|
+
在选择下一步 `dv:` 路由前,可先使用这些命令判断当前阶段就绪度:
|
|
49
|
+
|
|
50
|
+
- `da-vinci workflow-status --project <path> [--change <id>] [--json]`
|
|
51
|
+
- 从工件真相和部分 audit 可见证据推导阶段、blocker、handoff gate 与路由建议
|
|
52
|
+
- `da-vinci next-step --project <path> [--change <id>] [--json]`
|
|
53
|
+
- 基于同一 workflow-state 模型,给出优先续跑动作
|
|
54
|
+
- `da-vinci lint-spec --project <path> [--change <id>] [--strict] [--json]`
|
|
55
|
+
- 在进入实现规划或实现前,校验运行时 `spec.md` 结构质量
|
|
56
|
+
- 默认 advisory;显式 `--strict` 才会把发现升级为阻断
|
|
57
|
+
- `da-vinci scope-check --project <path> [--change <id>] [--strict] [--json]`
|
|
58
|
+
- 校验 proposal、page-map、运行时 spec、pencil-design、tasks 之间页面/状态传播是否一致
|
|
59
|
+
- 输出页面和状态的机器可读覆盖矩阵,供后续 verify/status 消费
|
|
60
|
+
- `da-vinci generate-sidecars --project <path> [--change <id>] [--json]`
|
|
61
|
+
- 显式生成确定性的 planning sidecars,供 diff 和下游工具消费
|
|
62
|
+
- `da-vinci verify-bindings|verify-implementation|verify-structure|verify-coverage --project <path> [--change <id>] [--strict] [--json]`
|
|
63
|
+
- 校验从 bindings 到实现与结构覆盖的执行链证据
|
|
64
|
+
- `da-vinci diff-spec --project <path> [--change <id>] [--from <sidecars-dir>] [--json]`
|
|
65
|
+
- 报告 spec/tasks/page-map/bindings sidecars 的规范化差异,支持安全续跑
|
|
66
|
+
|
|
67
|
+
这些命令不替代 `da-vinci audit --mode integrity|completion`。
|
|
68
|
+
`audit` 仍是 integrity/completion 的正式真相面。
|
|
69
|
+
|
|
45
70
|
## 标准工件骨架
|
|
46
71
|
|
|
47
72
|
根据 mode 的不同,Da Vinci 一般会围绕这组工件推进:
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
const { getMarkdownSection, hasMarkdownHeading } = require("./audit-parsers");
|
|
2
|
+
|
|
3
|
+
const RUNTIME_SPEC_SECTION_DEFS = [
|
|
4
|
+
{
|
|
5
|
+
id: "capability",
|
|
6
|
+
heading: "Capability",
|
|
7
|
+
required: false
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
id: "behavior",
|
|
11
|
+
heading: "Behavior",
|
|
12
|
+
required: true
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: "states",
|
|
16
|
+
heading: "States",
|
|
17
|
+
required: true
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: "inputs",
|
|
21
|
+
heading: "Inputs",
|
|
22
|
+
required: true
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: "outputs",
|
|
26
|
+
heading: "Outputs",
|
|
27
|
+
required: true
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: "acceptance",
|
|
31
|
+
heading: "Acceptance",
|
|
32
|
+
required: true
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: "edgeCases",
|
|
36
|
+
heading: "Edge Cases",
|
|
37
|
+
required: true
|
|
38
|
+
}
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
const LIST_ITEM_PATTERN = /^\s*(?:[-*+]|\d+[.)])\s+(.+?)\s*$/;
|
|
42
|
+
|
|
43
|
+
function extractSectionItems(sectionText) {
|
|
44
|
+
const normalized = String(sectionText || "").replace(/\r\n?/g, "\n").trim();
|
|
45
|
+
if (!normalized) {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const lines = normalized.split("\n");
|
|
50
|
+
const listItems = [];
|
|
51
|
+
for (const line of lines) {
|
|
52
|
+
const match = line.match(LIST_ITEM_PATTERN);
|
|
53
|
+
if (!match) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const value = String(match[1] || "").trim();
|
|
57
|
+
if (value) {
|
|
58
|
+
listItems.push(value);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (listItems.length > 0) {
|
|
63
|
+
return listItems;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return normalized
|
|
67
|
+
.split(/\n\s*\n/g)
|
|
68
|
+
.map((item) => item.trim())
|
|
69
|
+
.filter(Boolean);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function parseRuntimeSpecMarkdown(markdownText) {
|
|
73
|
+
const source = String(markdownText || "");
|
|
74
|
+
const sections = {};
|
|
75
|
+
const missingSections = [];
|
|
76
|
+
const emptySections = [];
|
|
77
|
+
|
|
78
|
+
for (const sectionDef of RUNTIME_SPEC_SECTION_DEFS) {
|
|
79
|
+
const present = hasMarkdownHeading(source, sectionDef.heading, {
|
|
80
|
+
allowParentheticalSuffix: true
|
|
81
|
+
});
|
|
82
|
+
const raw = getMarkdownSection(source, sectionDef.heading, {
|
|
83
|
+
allowParentheticalSuffix: true
|
|
84
|
+
});
|
|
85
|
+
const empty = present && String(raw || "").trim() === "";
|
|
86
|
+
const items = extractSectionItems(raw);
|
|
87
|
+
|
|
88
|
+
sections[sectionDef.id] = {
|
|
89
|
+
heading: sectionDef.heading,
|
|
90
|
+
required: sectionDef.required,
|
|
91
|
+
present,
|
|
92
|
+
empty,
|
|
93
|
+
raw,
|
|
94
|
+
items
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
if (!sectionDef.required) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (!present) {
|
|
102
|
+
missingSections.push(sectionDef.heading);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (empty) {
|
|
106
|
+
emptySections.push(sectionDef.heading);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
sections,
|
|
112
|
+
missingSections,
|
|
113
|
+
emptySections
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
module.exports = {
|
|
118
|
+
RUNTIME_SPEC_SECTION_DEFS,
|
|
119
|
+
parseRuntimeSpecMarkdown
|
|
120
|
+
};
|
package/lib/audit.js
CHANGED
|
@@ -11,6 +11,7 @@ const { getSessionStatePath, readSessionState } = require("./pencil-session");
|
|
|
11
11
|
const { isPathInside, listFilesRecursiveSafe } = require("./fs-safety");
|
|
12
12
|
const { pathExists, readTextIfExists } = require("./utils");
|
|
13
13
|
const { runModuleExportInWorker } = require("./async-offload");
|
|
14
|
+
const { readExecutionSignals, summarizeSignalsBySurface } = require("./execution-signals");
|
|
14
15
|
const {
|
|
15
16
|
normalizeCheckpointLabel,
|
|
16
17
|
parseCheckpointStatusMap,
|
|
@@ -38,6 +39,13 @@ const EXPORT_SCAN_LIMITS = Object.freeze({
|
|
|
38
39
|
maxDepth: 4,
|
|
39
40
|
maxEntries: 1200
|
|
40
41
|
});
|
|
42
|
+
const PLANNING_SIGNAL_SURFACES = new Set(["lint-spec", "scope-check", "lint-tasks", "lint-bindings"]);
|
|
43
|
+
const VERIFICATION_SIGNAL_SURFACES = new Set([
|
|
44
|
+
"verify-bindings",
|
|
45
|
+
"verify-implementation",
|
|
46
|
+
"verify-structure",
|
|
47
|
+
"verify-coverage"
|
|
48
|
+
]);
|
|
41
49
|
|
|
42
50
|
function listFilesRecursive(rootDir, limits = {}) {
|
|
43
51
|
return listFilesRecursiveSafe(rootDir, {
|
|
@@ -253,6 +261,17 @@ function auditProject(projectPathInput, options = {}) {
|
|
|
253
261
|
|
|
254
262
|
if (!pathExists(daVinciDir)) {
|
|
255
263
|
failures.push("Missing `.da-vinci/` directory.");
|
|
264
|
+
addMissingArtifacts(projectRoot, [path.join(projectRoot, "DA-VINCI.md"), designsDir], failures);
|
|
265
|
+
const missingWorkflowArtifacts = [
|
|
266
|
+
path.join(daVinciDir, "project-inventory.md"),
|
|
267
|
+
path.join(daVinciDir, "page-map.md"),
|
|
268
|
+
designRegistryPath
|
|
269
|
+
];
|
|
270
|
+
if (mode === "completion") {
|
|
271
|
+
addMissingArtifacts(projectRoot, missingWorkflowArtifacts, failures);
|
|
272
|
+
} else {
|
|
273
|
+
addMissingArtifacts(projectRoot, missingWorkflowArtifacts, warnings);
|
|
274
|
+
}
|
|
256
275
|
notes.push(
|
|
257
276
|
`Hint: scaffold the required workflow files with \`${buildBootstrapCommand(projectRoot, mode, options.changeId || null)}\`.`
|
|
258
277
|
);
|
|
@@ -814,6 +833,48 @@ function auditProject(projectPathInput, options = {}) {
|
|
|
814
833
|
}
|
|
815
834
|
}
|
|
816
835
|
|
|
836
|
+
const signalSummary =
|
|
837
|
+
options && options.preloadedSignalSummary && typeof options.preloadedSignalSummary === "object"
|
|
838
|
+
? options.preloadedSignalSummary
|
|
839
|
+
: summarizeSignalsBySurface(
|
|
840
|
+
readExecutionSignals(projectRoot, {
|
|
841
|
+
changeId: options.changeId || ""
|
|
842
|
+
})
|
|
843
|
+
);
|
|
844
|
+
for (const [surface, signal] of Object.entries(signalSummary)) {
|
|
845
|
+
if (surface === "signal-file-parse") {
|
|
846
|
+
const warningMessage =
|
|
847
|
+
Array.isArray(signal.warnings) && signal.warnings[0]
|
|
848
|
+
? String(signal.warnings[0])
|
|
849
|
+
: "Malformed execution signal files were detected.";
|
|
850
|
+
pushUnique(warnings, warningMessage);
|
|
851
|
+
continue;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
if (mode === "integrity" && PLANNING_SIGNAL_SURFACES.has(surface)) {
|
|
855
|
+
if (signal.status === "BLOCK") {
|
|
856
|
+
pushUnique(warnings, `Planning signal ${surface} is BLOCK (advisory in integrity mode).`);
|
|
857
|
+
} else if (signal.status === "WARN") {
|
|
858
|
+
pushUnique(notes, `Planning signal ${surface} is WARN.`);
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
if (mode === "completion" && VERIFICATION_SIGNAL_SURFACES.has(surface)) {
|
|
863
|
+
if (signal.status === "BLOCK") {
|
|
864
|
+
failures.push(`Verification signal ${surface} is BLOCK.`);
|
|
865
|
+
} else if (signal.status === "WARN") {
|
|
866
|
+
pushUnique(warnings, `Verification signal ${surface} is WARN.`);
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
if (surface === "diff-spec" && signal.status !== "PASS") {
|
|
871
|
+
pushUnique(warnings, `Planning diff signal ${surface} reports ${signal.status}.`);
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
notes.push(
|
|
875
|
+
"Execution-chain signal integration uses advisory planning semantics in integrity mode and blocking verification semantics in completion mode."
|
|
876
|
+
);
|
|
877
|
+
|
|
817
878
|
const status = failures.length > 0 ? "FAIL" : warnings.length > 0 ? "WARN" : "PASS";
|
|
818
879
|
|
|
819
880
|
return {
|