intentdna 1.5.5 → 1.5.6
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.
|
@@ -42,7 +42,7 @@ export function compileWorkflowToSkill(plan, roles, ir, variables) {
|
|
|
42
42
|
lines.push("</Purpose>");
|
|
43
43
|
lines.push("");
|
|
44
44
|
}
|
|
45
|
-
// Steps
|
|
45
|
+
// Steps — each step MUST be executed via Agent() tool call
|
|
46
46
|
const usedRoles = new Set(plan.steps.map((s) => s.role));
|
|
47
47
|
lines.push("<Steps>");
|
|
48
48
|
let stepNumber = 0;
|
|
@@ -51,24 +51,44 @@ export function compileWorkflowToSkill(plan, roles, ir, variables) {
|
|
|
51
51
|
for (const stepId of group.step_ids) {
|
|
52
52
|
stepNumber++;
|
|
53
53
|
const step = plan.steps.find((s) => s.id === stepId);
|
|
54
|
-
const
|
|
55
|
-
const runIf = step.run_if ?
|
|
54
|
+
const agentType = `dna-${toKebabCase(step.role)}`;
|
|
55
|
+
const runIf = step.run_if ? `\n **Condition**: ${step.run_if}` : "";
|
|
56
56
|
const optional = step.optional ? " (optional)" : "";
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
// Build agent prompt: anti-recursion + role identity + task
|
|
58
|
+
const promptParts = [
|
|
59
|
+
"Do NOT spawn sub-agents.",
|
|
60
|
+
`You are the ${agentType} agent.`,
|
|
61
|
+
step.prompt || step.description,
|
|
62
|
+
];
|
|
63
|
+
const agentPrompt = escapePrompt(promptParts.join(" "));
|
|
64
|
+
lines.push(`${stepNumber}. **${step.id}**${optional}`);
|
|
65
|
+
lines.push(` ${step.description}${runIf}`);
|
|
66
|
+
lines.push("");
|
|
67
|
+
lines.push(` Execute with Agent tool — DO NOT perform this work yourself:`);
|
|
68
|
+
lines.push(` \`\`\``);
|
|
69
|
+
lines.push(` Agent(`);
|
|
70
|
+
lines.push(` subagent_type="${agentType}",`);
|
|
71
|
+
lines.push(` prompt="${agentPrompt}"`);
|
|
72
|
+
lines.push(` )`);
|
|
73
|
+
lines.push(` \`\`\``);
|
|
74
|
+
lines.push(` Wait for agent to complete. Read the output before proceeding.`);
|
|
75
|
+
if (step.handoff?.produces && step.handoff.produces.length > 0) {
|
|
76
|
+
const artifacts = step.handoff.produces.map(p => p.description).join(", ");
|
|
77
|
+
lines.push(` Verify produced artifacts: ${artifacts}`);
|
|
61
78
|
}
|
|
79
|
+
lines.push("");
|
|
62
80
|
}
|
|
63
81
|
}
|
|
64
82
|
lines.push("</Steps>");
|
|
65
83
|
lines.push("");
|
|
66
|
-
// Execution Policy — force
|
|
84
|
+
// Execution Policy — force Agent dispatch
|
|
67
85
|
lines.push("<Execution_Policy>");
|
|
86
|
+
lines.push("- **CRITICAL**: Each step MUST be executed by spawning an Agent using the Agent tool with the specified subagent_type. DO NOT perform any step's work directly in the main session.");
|
|
68
87
|
lines.push("- Use TodoWrite to track each step as pending/in_progress/completed.");
|
|
69
88
|
lines.push("- After completing each step, immediately proceed to the next — do not stop, summarize, or wait for confirmation.");
|
|
70
89
|
lines.push("- If a step fails, mark it as failed in TodoWrite, log the error, and continue to the next non-dependent step.");
|
|
71
90
|
lines.push("- Do not ask the user for permission between steps — the workflow is pre-approved.");
|
|
91
|
+
lines.push("- Wait for each Agent to complete and read its output before proceeding to the next step.");
|
|
72
92
|
lines.push("</Execution_Policy>");
|
|
73
93
|
lines.push("");
|
|
74
94
|
// Tool_Usage — only if roles have permissions or scope
|
|
@@ -232,3 +252,11 @@ export async function removeSkillFiles(outputDir) {
|
|
|
232
252
|
function escapeYaml(s) {
|
|
233
253
|
return s.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
234
254
|
}
|
|
255
|
+
/** Escape prompt text for Agent() call template inside markdown code block. */
|
|
256
|
+
function escapePrompt(s) {
|
|
257
|
+
return s
|
|
258
|
+
.replace(/\\/g, "\\\\")
|
|
259
|
+
.replace(/"/g, '\\"')
|
|
260
|
+
.replace(/`{3,}/g, "` ` `")
|
|
261
|
+
.replace(/\n/g, "\\n");
|
|
262
|
+
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Spec: F5 Agent 调度漏洞修复
|
|
2
|
+
|
|
3
|
+
## 问题(架构级)
|
|
4
|
+
|
|
5
|
+
DNA 的 skill-adapter.ts 生成的 SKILL.md 用文字提示调度 agent:
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
1. **scan** → @dna-frw-scanner
|
|
9
|
+
Prompt: ...
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
LLM 把这当成建议,选择自己做而非 spawn agent。导致:
|
|
13
|
+
|
|
14
|
+
- agent_type 为空 → role scope 不生效
|
|
15
|
+
- tool_permissions deny 不生效(scanner 能写文件)
|
|
16
|
+
- review/verify 步骤在主 session 做 → 自己审自己
|
|
17
|
+
- handoff chain 无意义(没有跨 agent artifact 传递)
|
|
18
|
+
- agent MD 文件从未被加载
|
|
19
|
+
- 所有 role-based 治理形同虚设
|
|
20
|
+
|
|
21
|
+
## 影响范围
|
|
22
|
+
|
|
23
|
+
**以下交付物全部不生效:**
|
|
24
|
+
|
|
25
|
+
| 功能 | 依赖 | 当前状态 |
|
|
26
|
+
|------|------|---------|
|
|
27
|
+
| Role scope (read/write 范围) | agent_type 匹配 | 不生效 |
|
|
28
|
+
| tool_permissions deny | agent_type 匹配 | 不生效 |
|
|
29
|
+
| review 步骤只读约束 | investigator agent spawn | 不生效 |
|
|
30
|
+
| verify 步骤独立验证 | 独立 agent context | 不生效 |
|
|
31
|
+
| merge-time scope gate | worktree + agent 隔离 | 不生效 |
|
|
32
|
+
| handoff consumes/produces | 跨 agent artifact | 不生效 |
|
|
33
|
+
| step enforce rules (G4) | workflow state + agent_type | 不生效 |
|
|
34
|
+
| agent MD 文件加载 | agent spawn 时 CC 自动加载 | 从未加载 |
|
|
35
|
+
|
|
36
|
+
## 根因
|
|
37
|
+
|
|
38
|
+
OMC 用 Claude Code 原生 `Task(subagent_type=...)` API 强制 spawn agent:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
Task(subagent_type="oh-my-claudecode:executor", prompt="implement caching")
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
这是 API 级调用,LLM 无法绕过。spawn 的 agent 有独立 context、独立 agent_type,hooks 能识别和 enforce。
|
|
45
|
+
|
|
46
|
+
DNA 的 SKILL.md 只是文字提示,不是 API 调用。
|
|
47
|
+
|
|
48
|
+
## 修复方案
|
|
49
|
+
|
|
50
|
+
### skill-adapter.ts 改动
|
|
51
|
+
|
|
52
|
+
生成的 SKILL.md `<Steps>` 部分从:
|
|
53
|
+
|
|
54
|
+
```markdown
|
|
55
|
+
1. **scan** → @dna-frw-scanner
|
|
56
|
+
Prompt: Scan module...
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
改为:
|
|
60
|
+
|
|
61
|
+
```markdown
|
|
62
|
+
1. **scan**
|
|
63
|
+
Execute with Agent tool — DO NOT perform this work in the main session:
|
|
64
|
+
```
|
|
65
|
+
Agent(subagent_type="dna-frw-scanner", prompt="Scan module '$ARGUMENTS' in common/lib/. ...")
|
|
66
|
+
```
|
|
67
|
+
Wait for agent to complete. Read the agent's output before proceeding.
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 关键设计要点
|
|
71
|
+
|
|
72
|
+
1. **每步必须是 Agent() 调用**,不是文字描述
|
|
73
|
+
2. **明确禁止主 session 做 agent 的工作**:"DO NOT perform this work in the main session"
|
|
74
|
+
3. **Agent 输出要读取**:Agent 完成后读取其 output,作为下一步的 handoff
|
|
75
|
+
4. **Agent 工具参数完整**:subagent_type 用 DNA 编译的 agent 名称,prompt 用编译的步骤 prompt
|
|
76
|
+
5. **参考 OMC 的 preamble 模式**:spawn 的 agent 不应再 spawn 子 agent("Do NOT spawn sub-agents")
|
|
77
|
+
|
|
78
|
+
### 生成模板
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
// skill-adapter.ts — 每个 workflow step 生成:
|
|
82
|
+
function generateStepExecution(step, roleName, prompt) {
|
|
83
|
+
return `
|
|
84
|
+
### Step: ${step.id}
|
|
85
|
+
|
|
86
|
+
Execute with Agent tool — DO NOT perform this work yourself:
|
|
87
|
+
|
|
88
|
+
\`\`\`
|
|
89
|
+
Agent(
|
|
90
|
+
subagent_type="dna-${toKebabCase(roleName)}",
|
|
91
|
+
prompt="${escapePrompt(prompt)}"
|
|
92
|
+
)
|
|
93
|
+
\`\`\`
|
|
94
|
+
|
|
95
|
+
Wait for agent to complete. Read the output.
|
|
96
|
+
${step.handoff?.produces ? `Verify produced artifacts: ${step.handoff.produces.map(p => p.description).join(', ')}` : ''}
|
|
97
|
+
`;
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 验证方式
|
|
102
|
+
|
|
103
|
+
修复后跑 behavior-lock(home),检查 trace:
|
|
104
|
+
- agent_type 应该有值(dna-frw-scanner, dna-frw-test-writer)
|
|
105
|
+
- 不应该全是 "-"
|
|
106
|
+
|
|
107
|
+
## Acceptance Criteria
|
|
108
|
+
|
|
109
|
+
- [ ] skill-adapter.ts 生成强制 Agent() 调用格式
|
|
110
|
+
- [ ] 每步明确禁止主 session 直接执行
|
|
111
|
+
- [ ] Agent subagent_type 使用编译后的 role 名称
|
|
112
|
+
- [ ] Agent prompt 包含完整步骤 prompt + variables 替换
|
|
113
|
+
- [ ] spawn 的 agent 包含 "Do NOT spawn sub-agents" 约束
|
|
114
|
+
- [ ] handoff produces 在 Agent 完成后验证
|
|
115
|
+
- [ ] 测试:生成的 SKILL.md 包含 Agent() 调用模板
|
|
116
|
+
- [ ] 实战验证:trace 中 agent_type 有值
|