intentdna 1.5.16 → 1.5.17
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +72 -92
- package/dist/audit/index.d.ts +12 -3
- package/dist/cli/commands/feedback.d.ts +3 -0
- package/dist/cli/commands/feedback.js +33 -11
- package/dist/cli/commands/run.js +1 -1
- package/dist/cli/commands/sync.js +5 -5
- package/dist/compiler/cascade.d.ts +3 -1
- package/dist/compiler/cascade.js +86 -2
- package/dist/compiler/compile.js +93 -3
- package/dist/compiler/workflow.d.ts +1 -0
- package/dist/compiler/workflow.js +1 -0
- package/dist/evolution/trace-bridge.d.ts +4 -5
- package/dist/evolution/trace-bridge.js +31 -55
- package/dist/hooks/cli.d.ts +18 -1
- package/dist/hooks/cli.js +624 -24
- package/dist/hooks/enforce.js +3 -2
- package/dist/hooks/state.d.ts +20 -1
- package/dist/hooks/state.js +55 -0
- package/dist/runtime/settings-adapter.d.ts +3 -2
- package/dist/runtime/settings-adapter.js +26 -4
- package/dist/runtime/skill-adapter.js +49 -23
- package/dist/schema/types.d.ts +39 -0
- package/dist/schema/validate.js +143 -0
- package/dist/signals/index.d.ts +45 -0
- package/dist/signals/index.js +117 -0
- package/dist/templates/code-review-pipeline.dna.yaml +4 -0
- package/dist/templates/flutter-rewrite.dna.yaml +34 -11
- package/dist/templates/full-pipeline.dna.yaml +4 -0
- package/dist/templates/mobile-dev.dna.yaml +5 -0
- package/hooks/hooks.json +1 -1
- package/package.json +1 -1
- package/spec/control-plane-convergence-handoff-2026-04-24.md +432 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { extractGeneFromReason } from "../evolution/trace-bridge.js";
|
|
2
|
+
function toSignalEvidence(result) {
|
|
3
|
+
const payload = {
|
|
4
|
+
target: result.target,
|
|
5
|
+
evidence: result.evidence,
|
|
6
|
+
exit_code: result.exit_code,
|
|
7
|
+
artifact: result.artifact,
|
|
8
|
+
message: result.message,
|
|
9
|
+
};
|
|
10
|
+
return Object.values(payload).some((value) => value !== undefined) ? payload : undefined;
|
|
11
|
+
}
|
|
12
|
+
function normalizeExternalSignals(adapterName, payload) {
|
|
13
|
+
const items = Array.isArray(payload) ? payload : [payload];
|
|
14
|
+
return items.map((item, index) => {
|
|
15
|
+
const timestamp = item.timestamp ?? new Date().toISOString();
|
|
16
|
+
return {
|
|
17
|
+
id: item.id ?? `${adapterName}:${item.source}:${timestamp}:${index}`,
|
|
18
|
+
kind: "external",
|
|
19
|
+
status: item.status,
|
|
20
|
+
timestamp,
|
|
21
|
+
gene: item.gene,
|
|
22
|
+
source: item.source,
|
|
23
|
+
detail: item.detail ?? item.message ?? item.evidence,
|
|
24
|
+
adapter: adapterName,
|
|
25
|
+
evidence_payload: toSignalEvidence(item),
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
export const newapiSignalAdapter = {
|
|
30
|
+
name: "newapi",
|
|
31
|
+
adapt(payload) {
|
|
32
|
+
return normalizeExternalSignals("newapi", payload);
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
export const gatewaySignalAdapter = {
|
|
36
|
+
name: "gateway",
|
|
37
|
+
adapt(payload) {
|
|
38
|
+
return normalizeExternalSignals("gateway", payload);
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
export function adaptSignals(adapter, payload) {
|
|
42
|
+
return adapter.adapt(payload);
|
|
43
|
+
}
|
|
44
|
+
export function traceToSignals(traces) {
|
|
45
|
+
const signals = [];
|
|
46
|
+
for (const trace of traces) {
|
|
47
|
+
const gene = extractGeneFromReason(trace.reason);
|
|
48
|
+
if (!gene)
|
|
49
|
+
continue;
|
|
50
|
+
const status = trace.decision === "allow" ? "positive" : trace.decision === "warn" ? "neutral" : "negative";
|
|
51
|
+
signals.push({
|
|
52
|
+
id: trace.trace_id,
|
|
53
|
+
kind: "trace",
|
|
54
|
+
status,
|
|
55
|
+
timestamp: trace.timestamp,
|
|
56
|
+
gene,
|
|
57
|
+
source: trace.event,
|
|
58
|
+
detail: trace.reason,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return signals;
|
|
62
|
+
}
|
|
63
|
+
export function verifierResultsToSignals(results) {
|
|
64
|
+
const signals = [];
|
|
65
|
+
for (const result of results) {
|
|
66
|
+
const genes = result.source_genes && result.source_genes.length > 0 ? result.source_genes : [undefined];
|
|
67
|
+
const status = result.status === "pass" ? "positive" : result.severity === "warn" ? "neutral" : "negative";
|
|
68
|
+
for (const gene of genes) {
|
|
69
|
+
signals.push({
|
|
70
|
+
id: `${result.verifier_id}:${gene ?? "unknown"}:${result.timestamp}`,
|
|
71
|
+
kind: "verifier",
|
|
72
|
+
status,
|
|
73
|
+
timestamp: result.timestamp,
|
|
74
|
+
gene,
|
|
75
|
+
source: result.verifier_id,
|
|
76
|
+
detail: result.message ?? result.evidence,
|
|
77
|
+
evidence_payload: toSignalEvidence(result),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return signals;
|
|
82
|
+
}
|
|
83
|
+
export function signalsToOutcomes(signals, dnaId = "default") {
|
|
84
|
+
const feedbackByGene = new Map();
|
|
85
|
+
for (const signal of signals) {
|
|
86
|
+
if (!signal.gene)
|
|
87
|
+
continue;
|
|
88
|
+
const effect = signal.status === "positive"
|
|
89
|
+
? "helped"
|
|
90
|
+
: signal.status === "negative"
|
|
91
|
+
? "hindered"
|
|
92
|
+
: "neutral";
|
|
93
|
+
const existing = feedbackByGene.get(signal.gene) ?? [];
|
|
94
|
+
existing.push({
|
|
95
|
+
gene: signal.gene,
|
|
96
|
+
effect,
|
|
97
|
+
detail: signal.detail ?? signal.evidence_payload?.message ?? signal.source,
|
|
98
|
+
});
|
|
99
|
+
feedbackByGene.set(signal.gene, existing);
|
|
100
|
+
}
|
|
101
|
+
const outcomes = [];
|
|
102
|
+
for (const [gene, feedback] of feedbackByGene) {
|
|
103
|
+
const hindered = feedback.filter((item) => item.effect === "hindered").length;
|
|
104
|
+
const helped = feedback.filter((item) => item.effect === "helped").length;
|
|
105
|
+
outcomes.push({
|
|
106
|
+
id: `signal_${gene}_${feedback.length}`,
|
|
107
|
+
timestamp: new Date().toISOString(),
|
|
108
|
+
dna_id: dnaId,
|
|
109
|
+
action: `signals:${gene} helped=${helped} hindered=${hindered}`,
|
|
110
|
+
active_genes: [gene],
|
|
111
|
+
constraints_applied: [gene],
|
|
112
|
+
success: helped >= hindered,
|
|
113
|
+
constraint_feedback: feedback,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return outcomes;
|
|
117
|
+
}
|
|
@@ -137,6 +137,9 @@ context_files:
|
|
|
137
137
|
test_runner:
|
|
138
138
|
- "docs/behavior/{{ARGUMENTS}}.md"
|
|
139
139
|
|
|
140
|
+
verifier_policy:
|
|
141
|
+
allow_builtin_asserts:
|
|
142
|
+
- clean_working_tree
|
|
140
143
|
|
|
141
144
|
roles:
|
|
142
145
|
# ── Phase 0/3: behavior-lock 角色 ──
|
|
@@ -244,10 +247,13 @@ roles:
|
|
|
244
247
|
write: [".dna/specs/**"]
|
|
245
248
|
instructions:
|
|
246
249
|
- "REQUIRED FIRST: Read all context files listed in SKILL.md"
|
|
250
|
+
- "Treat docs/behavior/blocked_items.md as historical context only, never as the current run verdict"
|
|
247
251
|
- "For each failing, skipped, and hung test: read test code + v1 impl + v2 impl"
|
|
248
252
|
- "Classify each as BUG / UNIMPLEMENTED / INFRA / REMOVED / TEST_BUG (skipped tests are usually UNIMPLEMENTED)"
|
|
249
|
-
- "Output diagnosis spec with v1 code snippets + v2 current state"
|
|
250
|
-
- "
|
|
253
|
+
- "Output diagnosis spec with v1 code snippets + v2 current state + evidence paths"
|
|
254
|
+
- "If reanalyzing after REQUEST_REANALYSIS, update every reviewer sections_to_fix item and report sections_updated"
|
|
255
|
+
- "DO NOT include fix prescriptions, implementation order, call-site instructions, or Notes for Surgeon"
|
|
256
|
+
- "DO NOT run tests. DO NOT edit app code. Analysis only."
|
|
251
257
|
|
|
252
258
|
analysis_reviewer:
|
|
253
259
|
description: "Reviews analyzer output quality. Read-only."
|
|
@@ -261,7 +267,8 @@ roles:
|
|
|
261
267
|
- "REQUIRED FIRST: Read all context files listed in SKILL.md"
|
|
262
268
|
- "Verify analyzer spec: v1 references exist? Classifications sound?"
|
|
263
269
|
- "Check missing: any failing test not covered?"
|
|
264
|
-
- "
|
|
270
|
+
- "Verify diagnosis remains evidence-only: no fix prescriptions, implementation order, call-site instructions, or Notes for Surgeon"
|
|
271
|
+
- "Output a structured verdict block with verdict, artifact_reviewed, sections_to_fix, evidence_paths, confidence, and summary"
|
|
265
272
|
|
|
266
273
|
test_runner:
|
|
267
274
|
description: "Runs tests and reports progress delta."
|
|
@@ -517,16 +524,19 @@ workflows:
|
|
|
517
524
|
|
|
518
525
|
For module $ARGUMENTS, analyze failing tests in baseline:
|
|
519
526
|
1. Read behavior doc: docs/behavior/$ARGUMENTS.md
|
|
520
|
-
2. Read test results from last behavior-lock run
|
|
521
|
-
3.
|
|
527
|
+
2. Read test results from last behavior-lock run. If no structured baseline artifact exists, state exactly which file(s) you used as the baseline source.
|
|
528
|
+
3. Treat docs/behavior/blocked_items.md as historical context only. It must never be used as the current run verdict.
|
|
529
|
+
4. For each failing, skipped, and hung test:
|
|
522
530
|
a. Read test code (what behavior does it expect?)
|
|
523
531
|
b. Read v1 implementation (how did v1 do this?)
|
|
524
532
|
c. Read v2 current state (what's missing/wrong?)
|
|
525
533
|
d. Classify: BUG / UNIMPLEMENTED / INFRA / REMOVED / TEST_BUG
|
|
526
|
-
|
|
534
|
+
5. Write .dna/specs/diagnosis-$ARGUMENTS.md with:
|
|
527
535
|
- For each failure: v1 code snippet + v2 current state + classification
|
|
528
|
-
-
|
|
536
|
+
- Evidence paths for every classification
|
|
537
|
+
- NO fix prescriptions, implementation order, call-site instructions, or "Notes for Surgeon"
|
|
529
538
|
- NO running tests (analysis only)
|
|
539
|
+
6. If this is a reanalysis after REQUEST_REANALYSIS, read the reviewer verdict first, update every section listed in sections_to_fix plus the summary table, and report sections_updated in your final response. Reanalysis is not successful unless the spec artifact is rewritten.
|
|
530
540
|
handoff:
|
|
531
541
|
produces:
|
|
532
542
|
- type: file
|
|
@@ -545,10 +555,23 @@ workflows:
|
|
|
545
555
|
1. All failing tests from baseline covered?
|
|
546
556
|
2. v1 code references actually exist at claimed locations?
|
|
547
557
|
3. Classifications reasonable? (INFRA not mistaken for BUG)
|
|
548
|
-
4. Enough detail for surgeon to act?
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
558
|
+
4. Enough evidence detail for surgeon to act without adding fix prescriptions?
|
|
559
|
+
5. Diagnosis remains evidence-only: no implementation order, call-site instructions, or "Notes for Surgeon"?
|
|
560
|
+
|
|
561
|
+
Output exactly one structured verdict block:
|
|
562
|
+
```json
|
|
563
|
+
{
|
|
564
|
+
"verdict": "APPROVE" | "REQUEST_REANALYSIS",
|
|
565
|
+
"artifact_reviewed": ".dna/specs/diagnosis-$ARGUMENTS.md",
|
|
566
|
+
"sections_to_fix": ["section ids or titles; empty when approved"],
|
|
567
|
+
"evidence_paths": ["paths that justify the verdict"],
|
|
568
|
+
"confidence": "high" | "medium" | "low",
|
|
569
|
+
"summary": "brief reason"
|
|
570
|
+
}
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
APPROVE → diagnosis complete.
|
|
574
|
+
REQUEST_REANALYSIS → sections_to_fix must be passed back to analyze. docs/behavior/blocked_items.md is historical context only and must not be treated as the current run verdict.
|
|
552
575
|
handoff:
|
|
553
576
|
consumes:
|
|
554
577
|
- type: file
|
package/hooks/hooks.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"SubagentStop": [{ "matcher": "*", "hooks": [{ "type": "command", "command": "dna-hook SubagentStop", "timeout": 3 }] }],
|
|
7
7
|
"PreCompact": [{ "matcher": "*", "hooks": [{ "type": "command", "command": "dna-hook PreCompact", "timeout": 3 }] }],
|
|
8
8
|
"Notification": [{ "matcher": "*", "hooks": [{ "type": "command", "command": "dna-hook Notification", "timeout": 3 }] }],
|
|
9
|
-
"Stop": [{ "matcher": "*", "hooks": [{ "type": "command", "command": "dna-hook Stop", "timeout":
|
|
9
|
+
"Stop": [{ "matcher": "*", "hooks": [{ "type": "command", "command": "dna-hook Stop", "timeout": 45 }] }],
|
|
10
10
|
"SessionStart": [{ "matcher": "*", "hooks": [{ "type": "command", "command": "dna-hook SessionStart", "timeout": 5 }] }]
|
|
11
11
|
}
|
|
12
12
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
# Spec: Control Plane Convergence Handoff
|
|
2
|
+
|
|
3
|
+
## Metadata
|
|
4
|
+
- Date: 2026-04-24
|
|
5
|
+
- Status: 阶段性完成,可切新 session
|
|
6
|
+
- Scope: control-plane positioning + legibility assets + verifier contract + normalized local signals
|
|
7
|
+
- Note: `dna import` / harness reverse-parser 暂时不作为当前主线阻塞项
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 一、原始目标
|
|
12
|
+
|
|
13
|
+
本轮工作的核心目标不是继续扩概念,而是把 Intent DNA 的方向和实现收束成一条更明确的治理主线:
|
|
14
|
+
|
|
15
|
+
**legibility assets → verifiers → signals → evolution**
|
|
16
|
+
|
|
17
|
+
同时完成两件事:
|
|
18
|
+
|
|
19
|
+
1. 从项目叙事上明确:Intent DNA 是 **agent control plane / governance layer**,而不是业务系统执行平台。
|
|
20
|
+
2. 从代码上把现有零散能力收束成一套更像 control plane 的一等公民 runtime contract。
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 二、已完成的文档调整
|
|
25
|
+
|
|
26
|
+
### 1. 项目定位已重新收口
|
|
27
|
+
|
|
28
|
+
已修改:
|
|
29
|
+
- `README.md`
|
|
30
|
+
- `DESIGN.md`
|
|
31
|
+
- `ROADMAP.md`
|
|
32
|
+
|
|
33
|
+
### 2. 已完成的定位调整内容
|
|
34
|
+
|
|
35
|
+
#### README
|
|
36
|
+
- 明确 Intent DNA 是 **declarative control plane for AI agent behavior**
|
|
37
|
+
- 明确它治理的是运行在现有系统之上的 agent,而不是重写业务系统本体
|
|
38
|
+
- 新增更清晰的 design principles
|
|
39
|
+
- 收紧多框架表述,避免和 roadmap 冲突
|
|
40
|
+
|
|
41
|
+
#### DESIGN
|
|
42
|
+
- 新增 **边界定义**
|
|
43
|
+
- 业务系统是被操作对象
|
|
44
|
+
- agent 是执行者
|
|
45
|
+
- Intent DNA 是上层控制面
|
|
46
|
+
- 新增 **设计哲学**
|
|
47
|
+
- 先治理,后执行
|
|
48
|
+
- 先声明,后编译
|
|
49
|
+
- 先约束,后能力
|
|
50
|
+
- 先闭环,后规模
|
|
51
|
+
- 先可插拔,后绑定
|
|
52
|
+
- 把固定 Portkey 叙事收口为 **Gateway / Signal Layer**
|
|
53
|
+
- `.intentdna/` / `.dna/` 表述统一为 `.dna/`
|
|
54
|
+
|
|
55
|
+
#### ROADMAP
|
|
56
|
+
- 当前节点新增:
|
|
57
|
+
- 强化 agent 可见性
|
|
58
|
+
- verifier / validator 闭环
|
|
59
|
+
- signals 接口
|
|
60
|
+
- 让治理从“约束”走向“可验证闭环”
|
|
61
|
+
- 后续多框架 adapter wording 已和 README 对齐
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 三、已完成的代码调整
|
|
66
|
+
|
|
67
|
+
## Phase 1 — Legibility assets first-class
|
|
68
|
+
|
|
69
|
+
### 已完成内容
|
|
70
|
+
|
|
71
|
+
把“agent 在行动前必须理解什么”从散落在 `context_files` 中的约定,升级为 typed schema:
|
|
72
|
+
|
|
73
|
+
#### 新增 schema
|
|
74
|
+
文件:`src/schema/types.ts`
|
|
75
|
+
|
|
76
|
+
新增:
|
|
77
|
+
- `LegibilityAssetType`
|
|
78
|
+
- `required_read`
|
|
79
|
+
- `repo_map`
|
|
80
|
+
- `manifest`
|
|
81
|
+
- `artifact_index`
|
|
82
|
+
- `LegibilityAsset`
|
|
83
|
+
- `LegibilityAssetMap`
|
|
84
|
+
- `IntentDNA.legibility_assets`
|
|
85
|
+
- `ConstraintIR.legibility_assets`
|
|
86
|
+
|
|
87
|
+
#### 验证层
|
|
88
|
+
文件:`src/schema/validate.ts`
|
|
89
|
+
|
|
90
|
+
新增:
|
|
91
|
+
- `legibility_assets` 的结构验证
|
|
92
|
+
- role / workflow 引用校验
|
|
93
|
+
- 非法 asset type 校验
|
|
94
|
+
- `tags` 校验
|
|
95
|
+
|
|
96
|
+
#### 级联层
|
|
97
|
+
文件:`src/compiler/cascade.ts`
|
|
98
|
+
|
|
99
|
+
新增:
|
|
100
|
+
- `CascadedDNA.legibility_assets`
|
|
101
|
+
- 级联时高优先级 DNA 的 `legibility_assets` 覆盖低优先级
|
|
102
|
+
|
|
103
|
+
#### 编译层
|
|
104
|
+
文件:`src/compiler/compile.ts`
|
|
105
|
+
|
|
106
|
+
新增:
|
|
107
|
+
- 把 `legibility_assets` 编译进 IR
|
|
108
|
+
- 自动把 `required_read` 类型映射成兼容的 `context_files`
|
|
109
|
+
- 若已有旧 `context_files`,保持旧字段优先,确保兼容性
|
|
110
|
+
|
|
111
|
+
#### 运行时消费层
|
|
112
|
+
文件:
|
|
113
|
+
- `src/runtime/skill-adapter.ts`
|
|
114
|
+
- `src/hooks/cli.ts`
|
|
115
|
+
|
|
116
|
+
行为:
|
|
117
|
+
- `Required_Context` 输出优先读 `legibility_assets.required_read`
|
|
118
|
+
- `Context Gate` 也优先读 `legibility_assets.required_read`
|
|
119
|
+
- 如果没有 `legibility_assets`,自动 fallback 到旧 `context_files`
|
|
120
|
+
|
|
121
|
+
### 结果
|
|
122
|
+
|
|
123
|
+
现在项目已经有:
|
|
124
|
+
- typed legibility schema
|
|
125
|
+
- backward-compatible runtime behavior
|
|
126
|
+
- 不破坏旧模板/旧配置/旧 context gate 逻辑
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Phase 2 — Verifier contract
|
|
131
|
+
|
|
132
|
+
### 已完成内容
|
|
133
|
+
|
|
134
|
+
把 advisory validator 和真正可执行 verifier 分离。
|
|
135
|
+
|
|
136
|
+
#### 新增 schema
|
|
137
|
+
文件:`src/schema/types.ts`
|
|
138
|
+
|
|
139
|
+
新增:
|
|
140
|
+
- `VerifierWhen`
|
|
141
|
+
- `stop`
|
|
142
|
+
- `post_tool_use`
|
|
143
|
+
- `VerifierSeverity`
|
|
144
|
+
- `block`
|
|
145
|
+
- `warn`
|
|
146
|
+
- `VerifierKind`
|
|
147
|
+
- `checkpoint`
|
|
148
|
+
- `completion`
|
|
149
|
+
- `VerifierSpec`
|
|
150
|
+
- `ConstraintIR.verifier_specs`
|
|
151
|
+
|
|
152
|
+
#### 编译层
|
|
153
|
+
文件:`src/compiler/compile.ts`
|
|
154
|
+
|
|
155
|
+
已完成:
|
|
156
|
+
- 将 workflow step 的 `checkpoints` 编译为 `VerifierSpec(kind=checkpoint)`
|
|
157
|
+
- 将 workflow step 的 `completion` 编译为 `VerifierSpec(kind=completion)`
|
|
158
|
+
- `VerifierSpec` 中记录:
|
|
159
|
+
- workflow
|
|
160
|
+
- step
|
|
161
|
+
- role
|
|
162
|
+
- severity
|
|
163
|
+
- source
|
|
164
|
+
- source_genes(来自 role activates_genes 的 gene hint)
|
|
165
|
+
|
|
166
|
+
#### runtime state
|
|
167
|
+
文件:`src/hooks/state.ts`
|
|
168
|
+
|
|
169
|
+
新增:
|
|
170
|
+
- `VerifierResultEntry`
|
|
171
|
+
- `appendVerifierResult()`
|
|
172
|
+
- `readVerifierResults()`
|
|
173
|
+
- `writeVerifierResults()`
|
|
174
|
+
|
|
175
|
+
数据落在:
|
|
176
|
+
- `.dna/state/sessions/<session>/workflow/verifier-results.json`
|
|
177
|
+
|
|
178
|
+
并且现在 `readVerifierResults(projectDir)` 已支持跨 session 聚合读取。
|
|
179
|
+
|
|
180
|
+
#### Stop hook 执行
|
|
181
|
+
文件:`src/hooks/cli.ts`
|
|
182
|
+
|
|
183
|
+
新增:
|
|
184
|
+
- `runCheckpointVerifier()`
|
|
185
|
+
- `runStopVerifiers()`
|
|
186
|
+
- `clearBlockingVerifierCheckpoints()`
|
|
187
|
+
|
|
188
|
+
行为:
|
|
189
|
+
- Stop 时会执行 `verifier_specs.when === "stop"`
|
|
190
|
+
- 对 `completion` verifier 执行:
|
|
191
|
+
- `file_exists`
|
|
192
|
+
- `file_not_empty`
|
|
193
|
+
- `file_contains`
|
|
194
|
+
- `command_success`
|
|
195
|
+
- 对 `checkpoint` verifier 执行:
|
|
196
|
+
- `clean_working_tree`
|
|
197
|
+
- `no_test_regression`
|
|
198
|
+
- `lint_passing`
|
|
199
|
+
- `build_passing`
|
|
200
|
+
- 自定义 command
|
|
201
|
+
- 结果写入 verifier-results state
|
|
202
|
+
- 如果有 blocking verifier fail,会优先 block stop
|
|
203
|
+
- 然后把对应 blocking checkpoint 从 `enforceStop()` 的 legacy checkpoint 路径里剔除,避免双重阻断
|
|
204
|
+
|
|
205
|
+
#### hook 注册层
|
|
206
|
+
文件:`src/runtime/settings-adapter.ts`
|
|
207
|
+
|
|
208
|
+
已完成:
|
|
209
|
+
- `HookEventKey` 新增 `stop`
|
|
210
|
+
- `HOOK_EVENT_MAP` 新增 `Stop`
|
|
211
|
+
- `detectEnabledEvents()` 在存在:
|
|
212
|
+
- stop verifiers
|
|
213
|
+
- checkpoints
|
|
214
|
+
- handoffs
|
|
215
|
+
时会启用 `stop` hook
|
|
216
|
+
- 返回值去重
|
|
217
|
+
|
|
218
|
+
### 结果
|
|
219
|
+
|
|
220
|
+
现在 verifier 已不再只是“提示要验证”,而是:
|
|
221
|
+
- 可编译
|
|
222
|
+
- 可执行
|
|
223
|
+
- 可落状态
|
|
224
|
+
- 可参与 stop-time 阻断
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Phase 3 — Normalized local signals
|
|
229
|
+
|
|
230
|
+
### 已完成内容
|
|
231
|
+
|
|
232
|
+
#### 新增 signals 子系统
|
|
233
|
+
文件:`src/signals/index.ts`
|
|
234
|
+
|
|
235
|
+
新增:
|
|
236
|
+
- `SignalKind`
|
|
237
|
+
- `trace`
|
|
238
|
+
- `verifier`
|
|
239
|
+
- `SignalStatus`
|
|
240
|
+
- `positive`
|
|
241
|
+
- `negative`
|
|
242
|
+
- `neutral`
|
|
243
|
+
- `SignalEnvelope`
|
|
244
|
+
- `traceToSignals()`
|
|
245
|
+
- `verifierResultsToSignals()`
|
|
246
|
+
- `signalsToOutcomes()`
|
|
247
|
+
|
|
248
|
+
#### evolution bridge
|
|
249
|
+
文件:`src/evolution/trace-bridge.ts`
|
|
250
|
+
|
|
251
|
+
现在:
|
|
252
|
+
- `traceToOutcomes()` 已变成 normalized signals wrapper
|
|
253
|
+
- 新增:
|
|
254
|
+
- `verifierResultsToOutcomes()`
|
|
255
|
+
- `mergeOutcomes()`
|
|
256
|
+
|
|
257
|
+
也就是说,bridge 不再只理解 trace,而开始理解统一 signals。
|
|
258
|
+
|
|
259
|
+
#### feedback 命令
|
|
260
|
+
文件:`src/cli/commands/feedback.ts`
|
|
261
|
+
|
|
262
|
+
已完成:
|
|
263
|
+
- 读取 trace
|
|
264
|
+
- 读取 verifier results
|
|
265
|
+
- `--evolve` 时调用 `mergeOutcomes(traces, verifierResults)`
|
|
266
|
+
- 当没有 trace 但有 verifier results 时,也能进入 evolve 路径
|
|
267
|
+
- 错误提示从 only trace 改成 trace + verifier-aware
|
|
268
|
+
|
|
269
|
+
### 结果
|
|
270
|
+
|
|
271
|
+
现在 evolution 不再只盯着:
|
|
272
|
+
- block / warn trace
|
|
273
|
+
|
|
274
|
+
还开始吸收:
|
|
275
|
+
- verifier pass / fail
|
|
276
|
+
- positive / negative / neutral signal
|
|
277
|
+
|
|
278
|
+
这意味着 epigenetic loop 的输入开始变得完整,而不是只从 friction 学习。
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## 四、已修改文件清单
|
|
283
|
+
|
|
284
|
+
### 文档
|
|
285
|
+
- `README.md`
|
|
286
|
+
- `DESIGN.md`
|
|
287
|
+
- `ROADMAP.md`
|
|
288
|
+
|
|
289
|
+
### Memory
|
|
290
|
+
- `memory/project_signals_newapi_direction.md`
|
|
291
|
+
- `memory/project_ignore_import_feature_temporarily.md`
|
|
292
|
+
- `memory/MEMORY.md`
|
|
293
|
+
|
|
294
|
+
### 核心代码
|
|
295
|
+
- `src/schema/types.ts`
|
|
296
|
+
- `src/schema/validate.ts`
|
|
297
|
+
- `src/compiler/cascade.ts`
|
|
298
|
+
- `src/compiler/compile.ts`
|
|
299
|
+
- `src/runtime/skill-adapter.ts`
|
|
300
|
+
- `src/runtime/settings-adapter.ts`
|
|
301
|
+
- `src/hooks/state.ts`
|
|
302
|
+
- `src/hooks/cli.ts`
|
|
303
|
+
- `src/evolution/trace-bridge.ts`
|
|
304
|
+
- `src/cli/commands/feedback.ts`
|
|
305
|
+
- `src/signals/index.ts`
|
|
306
|
+
|
|
307
|
+
### 测试
|
|
308
|
+
- `test/schema.test.ts`
|
|
309
|
+
- `test/compiler.test.ts`
|
|
310
|
+
- `test/handoff.test.ts`
|
|
311
|
+
- `test/hooks-harness.test.ts`
|
|
312
|
+
- `test/checkpoint.test.ts`
|
|
313
|
+
- `test/completion-audit.test.ts`
|
|
314
|
+
- `test/hooks-cli.test.ts`
|
|
315
|
+
- `test/hooks-state.test.ts`
|
|
316
|
+
- `test/trace-bridge.test.ts`
|
|
317
|
+
- `test/feedback.test.ts`
|
|
318
|
+
- `test/signals.test.ts`
|
|
319
|
+
|
|
320
|
+
### 计划文件
|
|
321
|
+
- `/Users/samuel/.claude/plans/zippy-riding-wolf.md`
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## 五、验证结果
|
|
326
|
+
|
|
327
|
+
### 已通过
|
|
328
|
+
|
|
329
|
+
#### build
|
|
330
|
+
- `npm run build` ✅
|
|
331
|
+
|
|
332
|
+
#### 本轮主线定向测试
|
|
333
|
+
最后一次综合定向测试:
|
|
334
|
+
- 12 个 test files
|
|
335
|
+
- 280 passed
|
|
336
|
+
- 0 failed
|
|
337
|
+
|
|
338
|
+
#### 独立 verifier agent 结果
|
|
339
|
+
- PASS
|
|
340
|
+
- high confidence
|
|
341
|
+
- 0 blockers
|
|
342
|
+
|
|
343
|
+
它确认:
|
|
344
|
+
1. `legibility_assets` + `context_files` 兼容链路成立
|
|
345
|
+
2. `verifier_specs` 编译 / stop-time 执行 / state capture 成立
|
|
346
|
+
3. normalized signals + feedback/evolve 消费 traces + verifier results 成立
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## 六、当前未做 / 留给新 session 的内容
|
|
351
|
+
|
|
352
|
+
### 1. `dna import` / reverse-parser 暂时忽略
|
|
353
|
+
这条线不是当前 control-plane convergence 的主线。
|
|
354
|
+
`test/import.test.ts` 对应的是 reverse import / harness2dna,不作为当前阻塞项。
|
|
355
|
+
|
|
356
|
+
### 2. verifier 还没有继续扩到更多阶段
|
|
357
|
+
当前已完成的是:
|
|
358
|
+
- `when: stop`
|
|
359
|
+
|
|
360
|
+
还没继续做:
|
|
361
|
+
- `post_tool_use` verifier execution
|
|
362
|
+
- `pre_handoff` verifier execution
|
|
363
|
+
- `post_step` verifier execution
|
|
364
|
+
- 更强的 evidence schema
|
|
365
|
+
- verifier → audit event 更完整联动
|
|
366
|
+
|
|
367
|
+
### 3. signals 目前还是本地最小闭环
|
|
368
|
+
当前已完成:
|
|
369
|
+
- traces
|
|
370
|
+
- verifier results
|
|
371
|
+
- normalized signals
|
|
372
|
+
- feedback/evolve consumption
|
|
373
|
+
|
|
374
|
+
还没继续做:
|
|
375
|
+
- newapi / gateway adapter
|
|
376
|
+
- 外部 signal ingestion
|
|
377
|
+
- cost / latency / ROI / usage 指标接入
|
|
378
|
+
- richer signal taxonomy
|
|
379
|
+
|
|
380
|
+
### 4. 全量 `npm test` 还有既有仓库漂移问题
|
|
381
|
+
说明:
|
|
382
|
+
- 不是本轮 control-plane convergence 主线引入的阻塞
|
|
383
|
+
- 主要是 `test/import.test.ts` 和当前仓库实际 `.claude/agents/` 生成物不一致
|
|
384
|
+
- 当前 memory 已记录:这条线暂时忽略
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
## 七、建议的新 session 起点
|
|
389
|
+
|
|
390
|
+
如果开新 session,建议按下面顺序推进:
|
|
391
|
+
|
|
392
|
+
### 路线 A:继续 verifier 深化(推荐)
|
|
393
|
+
优先级最高。
|
|
394
|
+
|
|
395
|
+
建议下一步:
|
|
396
|
+
1. 把 `VerifierWhen` 扩展到:
|
|
397
|
+
- `post_tool_use`
|
|
398
|
+
- `pre_handoff`
|
|
399
|
+
- `post_step`
|
|
400
|
+
2. 让 verifier evidence 更结构化:
|
|
401
|
+
- target
|
|
402
|
+
- evidence
|
|
403
|
+
- exit code
|
|
404
|
+
- artifact path
|
|
405
|
+
- message
|
|
406
|
+
3. 把 verifier result 接入 audit event
|
|
407
|
+
4. 让 `settings-adapter` 继续自动启用必要 hook
|
|
408
|
+
|
|
409
|
+
### 路线 B:继续 signals 外部化
|
|
410
|
+
如果你先要做功能检查后接 newapi,这条线也适合。
|
|
411
|
+
|
|
412
|
+
建议下一步:
|
|
413
|
+
1. 给 `src/signals/` 增加 adapter boundary
|
|
414
|
+
2. 定义 newapi / gateway ingestion interface
|
|
415
|
+
3. 增加 metrics/cost/latency signal mapping
|
|
416
|
+
4. 让 normalized signals 不只服务 evolve,也能服务 dashboard / governance
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
## 八、给新 session 的一句话 handoff
|
|
421
|
+
|
|
422
|
+
这轮已经把 Intent DNA 从“约束 + hooks + feedback”推进成了更清晰的治理闭环骨架:
|
|
423
|
+
|
|
424
|
+
**legibility assets → verifiers → signals → evolution**
|
|
425
|
+
|
|
426
|
+
并且这三段最小可用实现已经落下、通过 build、通过定向测试、通过独立 verifier。
|
|
427
|
+
|
|
428
|
+
当前最值得继续推进的是:
|
|
429
|
+
- verifier 深化
|
|
430
|
+
- signals 外部化
|
|
431
|
+
|
|
432
|
+
`dna import` / reverse-parser 暂时忽略,不作为当前阻塞项。
|