@chllming/wave-orchestration 0.5.4 → 0.6.0
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 +46 -3
- package/README.md +33 -5
- package/docs/README.md +18 -4
- package/docs/agents/wave-cont-eval-role.md +36 -0
- package/docs/agents/{wave-evaluator-role.md → wave-cont-qa-role.md} +14 -11
- package/docs/agents/wave-documentation-role.md +1 -1
- package/docs/agents/wave-infra-role.md +1 -1
- package/docs/agents/wave-integration-role.md +3 -3
- package/docs/agents/wave-launcher-role.md +4 -3
- package/docs/agents/wave-security-role.md +40 -0
- package/docs/concepts/context7-vs-skills.md +1 -1
- package/docs/concepts/what-is-a-wave.md +56 -6
- package/docs/evals/README.md +166 -0
- package/docs/evals/benchmark-catalog.json +663 -0
- package/docs/guides/author-and-run-waves.md +135 -0
- package/docs/guides/planner.md +5 -0
- package/docs/guides/terminal-surfaces.md +2 -0
- package/docs/plans/component-cutover-matrix.json +1 -1
- package/docs/plans/component-cutover-matrix.md +1 -1
- package/docs/plans/current-state.md +19 -1
- package/docs/plans/examples/wave-example-live-proof.md +435 -0
- package/docs/plans/migration.md +42 -0
- package/docs/plans/wave-orchestrator.md +46 -7
- package/docs/plans/waves/wave-0.md +4 -4
- package/docs/reference/live-proof-waves.md +177 -0
- package/docs/reference/migration-0.2-to-0.5.md +26 -19
- package/docs/reference/npmjs-trusted-publishing.md +6 -5
- package/docs/reference/runtime-config/README.md +13 -3
- package/docs/reference/sample-waves.md +87 -0
- package/docs/reference/skills.md +110 -42
- package/docs/research/agent-context-sources.md +130 -11
- package/docs/research/coordination-failure-review.md +266 -0
- package/docs/roadmap.md +6 -2
- package/package.json +2 -2
- package/releases/manifest.json +20 -2
- package/scripts/research/agent-context-archive.mjs +83 -1
- package/scripts/research/manifests/agent-context-expanded-2026-03-22.mjs +811 -0
- package/scripts/wave-orchestrator/adhoc.mjs +1331 -0
- package/scripts/wave-orchestrator/agent-state.mjs +358 -6
- package/scripts/wave-orchestrator/artifact-schemas.mjs +173 -0
- package/scripts/wave-orchestrator/clarification-triage.mjs +10 -3
- package/scripts/wave-orchestrator/config.mjs +48 -12
- package/scripts/wave-orchestrator/context7.mjs +2 -0
- package/scripts/wave-orchestrator/coord-cli.mjs +51 -19
- package/scripts/wave-orchestrator/coordination-store.mjs +26 -4
- package/scripts/wave-orchestrator/coordination.mjs +83 -9
- package/scripts/wave-orchestrator/dashboard-state.mjs +20 -8
- package/scripts/wave-orchestrator/dep-cli.mjs +5 -2
- package/scripts/wave-orchestrator/docs-queue.mjs +8 -2
- package/scripts/wave-orchestrator/evals.mjs +451 -0
- package/scripts/wave-orchestrator/feedback.mjs +15 -1
- package/scripts/wave-orchestrator/install.mjs +32 -9
- package/scripts/wave-orchestrator/launcher-closure.mjs +281 -0
- package/scripts/wave-orchestrator/launcher-runtime.mjs +334 -0
- package/scripts/wave-orchestrator/launcher.mjs +709 -601
- package/scripts/wave-orchestrator/ledger.mjs +123 -20
- package/scripts/wave-orchestrator/local-executor.mjs +99 -12
- package/scripts/wave-orchestrator/planner.mjs +177 -42
- package/scripts/wave-orchestrator/replay.mjs +6 -3
- package/scripts/wave-orchestrator/role-helpers.mjs +84 -0
- package/scripts/wave-orchestrator/shared.mjs +75 -11
- package/scripts/wave-orchestrator/skills.mjs +637 -106
- package/scripts/wave-orchestrator/traces.mjs +71 -48
- package/scripts/wave-orchestrator/wave-files.mjs +947 -101
- package/scripts/wave.mjs +9 -0
- package/skills/README.md +202 -0
- package/skills/provider-aws/SKILL.md +111 -0
- package/skills/provider-aws/adapters/claude.md +1 -0
- package/skills/provider-aws/adapters/codex.md +1 -0
- package/skills/provider-aws/references/service-verification.md +39 -0
- package/skills/provider-aws/skill.json +50 -1
- package/skills/provider-custom-deploy/SKILL.md +59 -0
- package/skills/provider-custom-deploy/skill.json +46 -1
- package/skills/provider-docker-compose/SKILL.md +90 -0
- package/skills/provider-docker-compose/adapters/local.md +1 -0
- package/skills/provider-docker-compose/skill.json +49 -1
- package/skills/provider-github-release/SKILL.md +116 -1
- package/skills/provider-github-release/adapters/claude.md +1 -0
- package/skills/provider-github-release/adapters/codex.md +1 -0
- package/skills/provider-github-release/skill.json +51 -1
- package/skills/provider-kubernetes/SKILL.md +137 -0
- package/skills/provider-kubernetes/adapters/claude.md +1 -0
- package/skills/provider-kubernetes/adapters/codex.md +1 -0
- package/skills/provider-kubernetes/references/kubectl-patterns.md +58 -0
- package/skills/provider-kubernetes/skill.json +48 -1
- package/skills/provider-railway/SKILL.md +118 -1
- package/skills/provider-railway/references/verification-commands.md +39 -0
- package/skills/provider-railway/skill.json +67 -1
- package/skills/provider-ssh-manual/SKILL.md +91 -0
- package/skills/provider-ssh-manual/skill.json +50 -1
- package/skills/repo-coding-rules/SKILL.md +84 -0
- package/skills/repo-coding-rules/skill.json +30 -1
- package/skills/role-cont-eval/SKILL.md +90 -0
- package/skills/role-cont-eval/adapters/codex.md +1 -0
- package/skills/role-cont-eval/skill.json +36 -0
- package/skills/role-cont-qa/SKILL.md +93 -0
- package/skills/role-cont-qa/adapters/claude.md +1 -0
- package/skills/role-cont-qa/skill.json +36 -0
- package/skills/role-deploy/SKILL.md +90 -0
- package/skills/role-deploy/skill.json +32 -1
- package/skills/role-documentation/SKILL.md +66 -0
- package/skills/role-documentation/skill.json +32 -1
- package/skills/role-implementation/SKILL.md +62 -0
- package/skills/role-implementation/skill.json +32 -1
- package/skills/role-infra/SKILL.md +74 -0
- package/skills/role-infra/skill.json +32 -1
- package/skills/role-integration/SKILL.md +79 -1
- package/skills/role-integration/skill.json +32 -1
- package/skills/role-research/SKILL.md +58 -0
- package/skills/role-research/skill.json +32 -1
- package/skills/role-security/SKILL.md +60 -0
- package/skills/role-security/skill.json +36 -0
- package/skills/runtime-claude/SKILL.md +60 -1
- package/skills/runtime-claude/skill.json +32 -1
- package/skills/runtime-codex/SKILL.md +52 -1
- package/skills/runtime-codex/skill.json +32 -1
- package/skills/runtime-local/SKILL.md +39 -0
- package/skills/runtime-local/skill.json +32 -1
- package/skills/runtime-opencode/SKILL.md +51 -0
- package/skills/runtime-opencode/skill.json +32 -1
- package/skills/wave-core/SKILL.md +107 -0
- package/skills/wave-core/references/marker-syntax.md +62 -0
- package/skills/wave-core/skill.json +31 -1
- package/wave.config.json +35 -6
- package/skills/role-evaluator/SKILL.md +0 -6
- package/skills/role-evaluator/skill.json +0 -5
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
|
+
DEFAULT_CONT_EVAL_AGENT_ID,
|
|
2
3
|
DEFAULT_DOCUMENTATION_AGENT_ID,
|
|
3
|
-
|
|
4
|
+
DEFAULT_CONT_QA_AGENT_ID,
|
|
4
5
|
DEFAULT_INTEGRATION_AGENT_ID,
|
|
5
6
|
} from "./config.mjs";
|
|
6
7
|
import {
|
|
8
|
+
validateContEvalSummary,
|
|
7
9
|
validateDocumentationClosureSummary,
|
|
8
|
-
|
|
10
|
+
validateContQaSummary,
|
|
9
11
|
validateImplementationSummary,
|
|
12
|
+
validateSecuritySummary,
|
|
10
13
|
} from "./agent-state.mjs";
|
|
14
|
+
import {
|
|
15
|
+
isContEvalImplementationOwningAgent,
|
|
16
|
+
isSecurityReviewAgent,
|
|
17
|
+
} from "./role-helpers.mjs";
|
|
11
18
|
import { openClarificationLinkedRequests } from "./coordination-store.mjs";
|
|
12
19
|
import { buildHelperTasks } from "./routing-state.mjs";
|
|
13
20
|
import { readJsonOrNull, toIsoTimestamp, writeJsonAtomic } from "./shared.mjs";
|
|
@@ -40,19 +47,24 @@ function openClarifications(state) {
|
|
|
40
47
|
export function buildSeedWaveLedger({
|
|
41
48
|
lane,
|
|
42
49
|
wave,
|
|
43
|
-
|
|
50
|
+
contQaAgentId = DEFAULT_CONT_QA_AGENT_ID,
|
|
51
|
+
contEvalAgentId = DEFAULT_CONT_EVAL_AGENT_ID,
|
|
44
52
|
integrationAgentId = DEFAULT_INTEGRATION_AGENT_ID,
|
|
45
53
|
documentationAgentId = DEFAULT_DOCUMENTATION_AGENT_ID,
|
|
46
54
|
}) {
|
|
47
55
|
const tasks = [];
|
|
48
56
|
for (const agent of wave.agents) {
|
|
49
57
|
const kind =
|
|
50
|
-
agent.agentId ===
|
|
51
|
-
? "
|
|
58
|
+
agent.agentId === contQaAgentId
|
|
59
|
+
? "cont-qa"
|
|
60
|
+
: agent.agentId === contEvalAgentId
|
|
61
|
+
? "cont-eval"
|
|
52
62
|
: agent.agentId === integrationAgentId
|
|
53
63
|
? "integration"
|
|
54
|
-
|
|
64
|
+
: agent.agentId === documentationAgentId
|
|
55
65
|
? "documentation"
|
|
66
|
+
: isSecurityReviewAgent(agent)
|
|
67
|
+
? "security"
|
|
56
68
|
: "implementation";
|
|
57
69
|
tasks.push({
|
|
58
70
|
id: taskId(kind, agent.agentId),
|
|
@@ -73,6 +85,8 @@ export function buildSeedWaveLedger({
|
|
|
73
85
|
role: agent.executorResolved.role,
|
|
74
86
|
profile: agent.executorResolved.profile,
|
|
75
87
|
selectedBy: agent.executorResolved.selectedBy,
|
|
88
|
+
retryPolicy: agent.executorResolved.retryPolicy || null,
|
|
89
|
+
allowFallbackOnRetry: agent.executorResolved.allowFallbackOnRetry !== false,
|
|
76
90
|
fallbacks: agent.executorResolved.fallbacks || [],
|
|
77
91
|
fallbackUsed: agent.executorResolved.fallbackUsed === true,
|
|
78
92
|
}
|
|
@@ -107,9 +121,11 @@ export function buildSeedWaveLedger({
|
|
|
107
121
|
clarificationLinkedRequests: [],
|
|
108
122
|
humanFeedback: [],
|
|
109
123
|
humanEscalations: [],
|
|
124
|
+
contEvalState: "pending",
|
|
125
|
+
securityState: "pending",
|
|
110
126
|
integrationState: "pending",
|
|
111
127
|
docClosureState: "pending",
|
|
112
|
-
|
|
128
|
+
contQaState: "pending",
|
|
113
129
|
updatedAt: toIsoTimestamp(),
|
|
114
130
|
};
|
|
115
131
|
}
|
|
@@ -117,8 +133,10 @@ export function buildSeedWaveLedger({
|
|
|
117
133
|
function derivePhase({
|
|
118
134
|
tasks,
|
|
119
135
|
integrationSummary,
|
|
136
|
+
contEvalValidation,
|
|
137
|
+
securityValidation,
|
|
120
138
|
docValidation,
|
|
121
|
-
|
|
139
|
+
contQaValidation,
|
|
122
140
|
state,
|
|
123
141
|
dependencySnapshot = null,
|
|
124
142
|
}) {
|
|
@@ -149,14 +167,20 @@ function derivePhase({
|
|
|
149
167
|
if (!allImplementationDone) {
|
|
150
168
|
return "running";
|
|
151
169
|
}
|
|
170
|
+
if (tasks.some((task) => task.kind === "cont-eval") && !contEvalValidation?.ok) {
|
|
171
|
+
return "cont-eval";
|
|
172
|
+
}
|
|
173
|
+
if (tasks.some((task) => task.kind === "security") && !securityValidation?.ok) {
|
|
174
|
+
return "security-review";
|
|
175
|
+
}
|
|
152
176
|
if (integrationSummary?.recommendation !== "ready-for-doc-closure") {
|
|
153
177
|
return "integrating";
|
|
154
178
|
}
|
|
155
179
|
if (!docValidation?.ok) {
|
|
156
180
|
return "docs-closure";
|
|
157
181
|
}
|
|
158
|
-
if (!
|
|
159
|
-
return "
|
|
182
|
+
if (!contQaValidation?.ok) {
|
|
183
|
+
return "cont-qa-closure";
|
|
160
184
|
}
|
|
161
185
|
return "completed";
|
|
162
186
|
}
|
|
@@ -169,16 +193,19 @@ export function deriveWaveLedger({
|
|
|
169
193
|
integrationSummary = null,
|
|
170
194
|
docsQueue = null,
|
|
171
195
|
attempt = 0,
|
|
172
|
-
|
|
196
|
+
contQaAgentId = DEFAULT_CONT_QA_AGENT_ID,
|
|
197
|
+
contEvalAgentId = DEFAULT_CONT_EVAL_AGENT_ID,
|
|
173
198
|
integrationAgentId = DEFAULT_INTEGRATION_AGENT_ID,
|
|
174
199
|
documentationAgentId = DEFAULT_DOCUMENTATION_AGENT_ID,
|
|
200
|
+
benchmarkCatalogPath = null,
|
|
175
201
|
capabilityAssignments = [],
|
|
176
202
|
dependencySnapshot = null,
|
|
177
203
|
}) {
|
|
178
204
|
const seed = buildSeedWaveLedger({
|
|
179
205
|
lane,
|
|
180
206
|
wave,
|
|
181
|
-
|
|
207
|
+
contQaAgentId,
|
|
208
|
+
contEvalAgentId,
|
|
182
209
|
integrationAgentId,
|
|
183
210
|
documentationAgentId,
|
|
184
211
|
});
|
|
@@ -203,8 +230,38 @@ export function deriveWaveLedger({
|
|
|
203
230
|
docState: validation.ok ? "closed" : "open",
|
|
204
231
|
};
|
|
205
232
|
}
|
|
206
|
-
if (task.kind === "
|
|
207
|
-
const
|
|
233
|
+
if (task.kind === "cont-eval" && agent) {
|
|
234
|
+
const evalValidation = validateContEvalSummary(agent, summary, {
|
|
235
|
+
mode: "live",
|
|
236
|
+
evalTargets: wave.evalTargets,
|
|
237
|
+
benchmarkCatalogPath,
|
|
238
|
+
});
|
|
239
|
+
const implementationValidation = isContEvalImplementationOwningAgent(agent, {
|
|
240
|
+
contEvalAgentId,
|
|
241
|
+
})
|
|
242
|
+
? validateImplementationSummary(agent, summary)
|
|
243
|
+
: { ok: true, statusCode: "pass", detail: "cont-EVAL is report-only." };
|
|
244
|
+
const validation = !evalValidation.ok ? evalValidation : implementationValidation;
|
|
245
|
+
return {
|
|
246
|
+
...task,
|
|
247
|
+
state: taskStateFromValidation(validation),
|
|
248
|
+
proofState: validation.ok ? "met" : "gap",
|
|
249
|
+
docState: "n/a",
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
if (task.kind === "cont-qa" && agent) {
|
|
253
|
+
const validation = validateContQaSummary(agent, summary, {
|
|
254
|
+
mode: "live",
|
|
255
|
+
});
|
|
256
|
+
return {
|
|
257
|
+
...task,
|
|
258
|
+
state: taskStateFromValidation(validation),
|
|
259
|
+
proofState: validation.ok ? "met" : "gap",
|
|
260
|
+
docState: "n/a",
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
if (task.kind === "security" && agent) {
|
|
264
|
+
const validation = validateSecuritySummary(agent, summary);
|
|
208
265
|
return {
|
|
209
266
|
...task,
|
|
210
267
|
state: taskStateFromValidation(validation),
|
|
@@ -255,12 +312,54 @@ export function deriveWaveLedger({
|
|
|
255
312
|
});
|
|
256
313
|
const tasks = [...primaryTasks, ...helperTasks];
|
|
257
314
|
const docAgent = wave.agents.find((agent) => agent.agentId === documentationAgentId);
|
|
258
|
-
const
|
|
315
|
+
const contEvalAgent = wave.agents.find((agent) => agent.agentId === contEvalAgentId);
|
|
316
|
+
const contQaAgent = wave.agents.find((agent) => agent.agentId === contQaAgentId);
|
|
317
|
+
const securityAgents = (wave.agents || []).filter((agent) => isSecurityReviewAgent(agent));
|
|
318
|
+
const contEvalValidation = (() => {
|
|
319
|
+
if (!contEvalAgent) {
|
|
320
|
+
return { ok: true };
|
|
321
|
+
}
|
|
322
|
+
const summary = summariesByAgentId[contEvalAgentId];
|
|
323
|
+
const evalValidation = validateContEvalSummary(contEvalAgent, summary, {
|
|
324
|
+
mode: "live",
|
|
325
|
+
evalTargets: wave.evalTargets,
|
|
326
|
+
benchmarkCatalogPath,
|
|
327
|
+
});
|
|
328
|
+
if (!evalValidation.ok) {
|
|
329
|
+
return evalValidation;
|
|
330
|
+
}
|
|
331
|
+
if (
|
|
332
|
+
isContEvalImplementationOwningAgent(contEvalAgent, {
|
|
333
|
+
contEvalAgentId,
|
|
334
|
+
})
|
|
335
|
+
) {
|
|
336
|
+
return validateImplementationSummary(contEvalAgent, summary);
|
|
337
|
+
}
|
|
338
|
+
return evalValidation;
|
|
339
|
+
})();
|
|
259
340
|
const docValidation = docAgent
|
|
260
341
|
? validateDocumentationClosureSummary(docAgent, summariesByAgentId[documentationAgentId])
|
|
261
342
|
: { ok: true };
|
|
262
|
-
const
|
|
263
|
-
|
|
343
|
+
const securityValidation = (() => {
|
|
344
|
+
if (securityAgents.length === 0) {
|
|
345
|
+
return { ok: true, statusCode: "pass" };
|
|
346
|
+
}
|
|
347
|
+
for (const agent of securityAgents) {
|
|
348
|
+
const validation = validateSecuritySummary(agent, summariesByAgentId[agent.agentId]);
|
|
349
|
+
if (!validation.ok) {
|
|
350
|
+
return validation;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return securityAgents.some(
|
|
354
|
+
(agent) => summariesByAgentId[agent.agentId]?.security?.state === "concerns",
|
|
355
|
+
)
|
|
356
|
+
? { ok: true, statusCode: "security-concerns" }
|
|
357
|
+
: { ok: true, statusCode: "pass" };
|
|
358
|
+
})();
|
|
359
|
+
const contQaValidation = contQaAgent
|
|
360
|
+
? validateContQaSummary(contQaAgent, summariesByAgentId[contQaAgentId], {
|
|
361
|
+
mode: "live",
|
|
362
|
+
})
|
|
264
363
|
: { ok: true };
|
|
265
364
|
return {
|
|
266
365
|
wave: wave.wave,
|
|
@@ -269,8 +368,10 @@ export function deriveWaveLedger({
|
|
|
269
368
|
phase: derivePhase({
|
|
270
369
|
tasks,
|
|
271
370
|
integrationSummary,
|
|
371
|
+
contEvalValidation,
|
|
372
|
+
securityValidation,
|
|
272
373
|
docValidation,
|
|
273
|
-
|
|
374
|
+
contQaValidation,
|
|
274
375
|
state: coordinationState,
|
|
275
376
|
dependencySnapshot,
|
|
276
377
|
}),
|
|
@@ -311,14 +412,16 @@ export function deriveWaveLedger({
|
|
|
311
412
|
.map((record) => record.id),
|
|
312
413
|
...(coordinationState?.humanEscalations || [])
|
|
313
414
|
.filter((record) => ["open", "acknowledged", "in_progress"].includes(record.status))
|
|
314
|
-
|
|
415
|
+
.map((record) => record.id),
|
|
315
416
|
],
|
|
316
417
|
humanEscalations: (coordinationState?.humanEscalations || [])
|
|
317
418
|
.filter((record) => ["open", "acknowledged", "in_progress"].includes(record.status))
|
|
318
419
|
.map((record) => record.id),
|
|
420
|
+
contEvalState: contEvalValidation.ok ? "pass" : "open",
|
|
421
|
+
securityState: securityValidation.ok ? securityValidation.statusCode || "pass" : "open",
|
|
319
422
|
integrationState: integrationSummary?.recommendation || "pending",
|
|
320
423
|
docClosureState: docValidation.ok ? "closed" : "open",
|
|
321
|
-
|
|
424
|
+
contQaState: contQaValidation.ok ? "pass" : "open",
|
|
322
425
|
updatedAt: toIsoTimestamp(),
|
|
323
426
|
};
|
|
324
427
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { REPO_ROOT, ensureDirectory } from "./shared.mjs";
|
|
4
|
+
import { isContEvalReportPath } from "./role-helpers.mjs";
|
|
4
5
|
|
|
5
6
|
function titleFromPath(relPath) {
|
|
6
7
|
return path
|
|
@@ -22,7 +23,8 @@ function extractAgentId(rawPrompt) {
|
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
function extractRoleAgentIds(rawPrompt) {
|
|
25
|
-
const
|
|
26
|
+
const contQaMatch = String(rawPrompt || "").match(/- cont-QA agent id:\s*([A-Za-z0-9.]+)/);
|
|
27
|
+
const contEvalMatch = String(rawPrompt || "").match(/- cont-EVAL agent id:\s*([A-Za-z0-9.]+)/);
|
|
26
28
|
const integrationMatch = String(rawPrompt || "").match(
|
|
27
29
|
/- Integration steward agent id:\s*([A-Za-z0-9.]+)/,
|
|
28
30
|
);
|
|
@@ -30,7 +32,8 @@ function extractRoleAgentIds(rawPrompt) {
|
|
|
30
32
|
/- Documentation steward agent id:\s*([A-Za-z0-9.]+)/,
|
|
31
33
|
);
|
|
32
34
|
return {
|
|
33
|
-
|
|
35
|
+
contQaAgentId: contQaMatch ? contQaMatch[1].trim() : "A0",
|
|
36
|
+
contEvalAgentId: contEvalMatch ? contEvalMatch[1].trim() : "E0",
|
|
34
37
|
integrationAgentId: integrationMatch ? integrationMatch[1].trim() : "A8",
|
|
35
38
|
documentationAgentId: documentationMatch ? documentationMatch[1].trim() : "A9",
|
|
36
39
|
};
|
|
@@ -114,6 +117,62 @@ function extractDeliverables(rawPrompt, promptText) {
|
|
|
114
117
|
return Array.from(new Set(out));
|
|
115
118
|
}
|
|
116
119
|
|
|
120
|
+
function extractFileOwnershipPaths(promptText) {
|
|
121
|
+
return Array.from(
|
|
122
|
+
new Set(extractDeliverablesFromList(promptText, /^\s*File ownership\b/i)),
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function extractEvalMarkerPayload(rawPrompt) {
|
|
127
|
+
const lines = String(rawPrompt || "").split(/\r?\n/);
|
|
128
|
+
const targetIds = [];
|
|
129
|
+
const benchmarkIds = [];
|
|
130
|
+
let inTargets = false;
|
|
131
|
+
for (const line of lines) {
|
|
132
|
+
if (/^\s*Eval targets for this wave:\s*$/i.test(line)) {
|
|
133
|
+
inTargets = true;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (inTargets && !line.trim()) {
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
if (!inTargets) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const match = line.match(/^\s*-\s+([a-z0-9._-]+):\s+(.+)\s*$/i);
|
|
143
|
+
if (!match) {
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
targetIds.push(match[1].toLowerCase());
|
|
147
|
+
const payload = match[2];
|
|
148
|
+
const benchmarkMatch =
|
|
149
|
+
payload.match(/\bbenchmarks=([a-z0-9._\-,\s]+)/i) ||
|
|
150
|
+
payload.match(/\ballowed-benchmarks=([a-z0-9._\-,\s]+)/i);
|
|
151
|
+
if (!benchmarkMatch) {
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
for (const benchmarkId of benchmarkMatch[1].split(",")) {
|
|
155
|
+
const normalized = benchmarkId.trim().toLowerCase();
|
|
156
|
+
if (normalized) {
|
|
157
|
+
benchmarkIds.push(normalized);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
targetIds: Array.from(new Set(targetIds)).sort(),
|
|
163
|
+
benchmarkIds: Array.from(new Set(benchmarkIds)).sort(),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function formatWaveEvalLine(evalMarker, detail) {
|
|
168
|
+
const targetIds = Array.isArray(evalMarker?.targetIds) ? evalMarker.targetIds : [];
|
|
169
|
+
const benchmarkIds = Array.isArray(evalMarker?.benchmarkIds) ? evalMarker.benchmarkIds : [];
|
|
170
|
+
const targetIdSegment = targetIds.length > 0 ? ` target_ids=${targetIds.join(",")}` : "";
|
|
171
|
+
const benchmarkIdSegment =
|
|
172
|
+
benchmarkIds.length > 0 ? ` benchmark_ids=${benchmarkIds.join(",")}` : "";
|
|
173
|
+
return `[wave-eval] state=satisfied targets=${targetIds.length} benchmarks=${benchmarkIds.length} regressions=0${targetIdSegment}${benchmarkIdSegment} detail=${detail}`;
|
|
174
|
+
}
|
|
175
|
+
|
|
117
176
|
export function resolveRepoOwnedDeliverablePath(relPath) {
|
|
118
177
|
if (!relPath || path.isAbsolute(relPath)) {
|
|
119
178
|
throw new Error(`Unsafe deliverable path: ${String(relPath || "")}`);
|
|
@@ -146,7 +205,7 @@ function markdownTemplate(relPath, promptText, options = {}) {
|
|
|
146
205
|
? requirements.map((item) => `- ${item}`)
|
|
147
206
|
: ["- Derived from assigned wave prompt."]),
|
|
148
207
|
"",
|
|
149
|
-
...(options.
|
|
208
|
+
...(options.contQaReport ? ["## Verdict", "Verdict: PASS", ""] : []),
|
|
150
209
|
"## Note",
|
|
151
210
|
"- Replace this placeholder with real implementation work before relying on it.",
|
|
152
211
|
"",
|
|
@@ -170,12 +229,12 @@ function writeDeliverable(relPath, promptText, options = {}) {
|
|
|
170
229
|
return "exists";
|
|
171
230
|
}
|
|
172
231
|
if (/\.(md|mdx)$/i.test(absPath)) {
|
|
173
|
-
const
|
|
174
|
-
options.
|
|
175
|
-
/(?:^|\/)(?:reviews?|.*
|
|
232
|
+
const contQaReport =
|
|
233
|
+
options.contQaAgent === true &&
|
|
234
|
+
/(?:^|\/)(?:reviews?|.*cont[-_]?qa).*\.(md|mdx)$/i.test(relPath);
|
|
176
235
|
fs.writeFileSync(
|
|
177
236
|
absPath,
|
|
178
|
-
`${markdownTemplate(relPath, promptText, {
|
|
237
|
+
`${markdownTemplate(relPath, promptText, { contQaReport })}\n`,
|
|
179
238
|
"utf8",
|
|
180
239
|
);
|
|
181
240
|
return "created";
|
|
@@ -213,19 +272,34 @@ export function runLocalExecutorCli(argv) {
|
|
|
213
272
|
}
|
|
214
273
|
const rawPrompt = fs.readFileSync(options.promptFile, "utf8");
|
|
215
274
|
const agentId = extractAgentId(rawPrompt);
|
|
216
|
-
const {
|
|
217
|
-
|
|
275
|
+
const { contQaAgentId, contEvalAgentId, integrationAgentId, documentationAgentId } =
|
|
276
|
+
extractRoleAgentIds(rawPrompt);
|
|
277
|
+
const contQaAgent = agentId === contQaAgentId;
|
|
278
|
+
const contEvalAgent = agentId === contEvalAgentId;
|
|
218
279
|
const integrationAgent = agentId === integrationAgentId;
|
|
219
280
|
const ownedComponents = extractOwnedComponents(rawPrompt);
|
|
220
281
|
const assignedPrompt = extractAssignedPrompt(rawPrompt);
|
|
282
|
+
const ownedPaths = extractFileOwnershipPaths(assignedPrompt);
|
|
221
283
|
const deliverables = extractDeliverables(rawPrompt, assignedPrompt);
|
|
284
|
+
const evalMarker = extractEvalMarkerPayload(rawPrompt);
|
|
285
|
+
const contEvalImplementationOwning =
|
|
286
|
+
contEvalAgent &&
|
|
287
|
+
ownedPaths.some((ownedPath) => !isContEvalReportPath(ownedPath));
|
|
222
288
|
if (deliverables.length === 0) {
|
|
223
289
|
console.log("[local-executor] no deliverables detected; nothing to do.");
|
|
224
|
-
if (
|
|
290
|
+
if (contQaAgent) {
|
|
225
291
|
console.log(
|
|
226
292
|
"[wave-gate] architecture=pass integration=pass durability=pass live=pass docs=pass detail=local-executor-no-deliverables",
|
|
227
293
|
);
|
|
228
294
|
console.log("[wave-verdict] pass detail=local-executor-no-deliverables");
|
|
295
|
+
} else if (contEvalAgent) {
|
|
296
|
+
console.log(formatWaveEvalLine(evalMarker, "local-executor-no-deliverables"));
|
|
297
|
+
if (contEvalImplementationOwning) {
|
|
298
|
+
console.log(
|
|
299
|
+
"[wave-proof] completion=contract durability=none proof=unit state=met detail=local-executor-no-deliverables",
|
|
300
|
+
);
|
|
301
|
+
console.log("[wave-doc-delta] state=none detail=local-executor-no-deliverables");
|
|
302
|
+
}
|
|
229
303
|
} else if (integrationAgent) {
|
|
230
304
|
console.log(
|
|
231
305
|
"[wave-integration] state=ready-for-doc-closure claims=0 conflicts=0 blockers=0 detail=local-executor-no-deliverables",
|
|
@@ -249,14 +323,27 @@ export function runLocalExecutorCli(argv) {
|
|
|
249
323
|
console.log(`[local-executor] deliverables=${deliverables.join(", ")}`);
|
|
250
324
|
for (const deliverable of deliverables) {
|
|
251
325
|
console.log(
|
|
252
|
-
`[local-executor] ${writeDeliverable(deliverable, assignedPrompt, {
|
|
326
|
+
`[local-executor] ${writeDeliverable(deliverable, assignedPrompt, { contQaAgent })}: ${deliverable}`,
|
|
253
327
|
);
|
|
254
328
|
}
|
|
255
|
-
if (
|
|
329
|
+
if (contQaAgent) {
|
|
256
330
|
console.log(
|
|
257
331
|
"[wave-gate] architecture=pass integration=pass durability=pass live=pass docs=pass detail=local-executor-smoke",
|
|
258
332
|
);
|
|
259
333
|
console.log("[wave-verdict] pass detail=local-executor-smoke");
|
|
334
|
+
} else if (contEvalAgent) {
|
|
335
|
+
console.log(formatWaveEvalLine(evalMarker, "local-executor-smoke"));
|
|
336
|
+
if (contEvalImplementationOwning) {
|
|
337
|
+
console.log(
|
|
338
|
+
"[wave-proof] completion=contract durability=none proof=unit state=met detail=local-executor-smoke",
|
|
339
|
+
);
|
|
340
|
+
console.log("[wave-doc-delta] state=none detail=local-executor-smoke");
|
|
341
|
+
for (const component of ownedComponents) {
|
|
342
|
+
console.log(
|
|
343
|
+
`[wave-component] component=${component.componentId} level=${component.level || "repo-landed"} state=met detail=local-executor-smoke`,
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
260
347
|
} else if (integrationAgent) {
|
|
261
348
|
console.log(
|
|
262
349
|
"[wave-integration] state=ready-for-doc-closure claims=0 conflicts=0 blockers=0 detail=local-executor-smoke",
|