@jstn-sdk/ma 0.1.10 → 0.1.12
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/.agents/plugins/marketplace.json +0 -0
- package/README.md +136 -29
- package/bin/ma.js +23 -67
- package/docs/README.md +4 -1
- package/docs/assets/image/Screenshot(1).png +0 -0
- package/docs/assets/image/Screenshot(2).png +0 -0
- package/docs/assets/image/Screenshot(3).png +0 -0
- package/docs/assets/image/Screenshot(4).png +0 -0
- package/docs/assets/image/Screenshot(5).png +0 -0
- package/docs/assets/image/Screenshot(6).png +0 -0
- package/docs/assets/image/Screenshot(7).png +0 -0
- package/docs/assets/image/Screenshot(8).png +0 -0
- package/docs/assets/image/Screenshot(9).png +0 -0
- package/docs/assets/meta-architect-logo.png +0 -0
- package/docs/assets/meta-architect-logo.svg +0 -0
- package/docs/getting-started.md +74 -19
- package/docs/installed-sdk.md +23 -0
- package/docs/mcp-setup.md +30 -1
- package/docs/qa/{release-readiness-0.1.10.md → release-readiness-0.1.12.md} +29 -8
- package/docs/qa/release-readiness-0.1.5.md +0 -0
- package/docs/reference/native-engineering-patterns.md +35 -0
- package/docs/reference/native-security-playbooks.md +21 -0
- package/docs/reference/native-source-selection.md +21 -0
- package/docs/reference/native-style-and-deslop.md +20 -0
- package/docs/release-spec.md +21 -10
- package/docs/skills-publishing.md +25 -1
- package/docs/skills.md +24 -12
- package/mcp/local/code-intel.js +113 -0
- package/mcp/local/memory.js +46 -0
- package/mcp/local/playbooks.js +168 -0
- package/mcp/local/state.js +71 -0
- package/mcp/local/team-run.js +66 -0
- package/mcp/local/trace.js +60 -0
- package/mcp/local-capabilities.json +56 -0
- package/mcp/native-playbooks.json +117 -0
- package/mcp/servers.json +10 -0
- package/package.json +4 -1
- package/plugins/meta-architect/.app.json +1 -1
- package/plugins/meta-architect/.codex-plugin/plugin.json +4 -4
- package/plugins/meta-architect/.mcp.json +1 -1
- package/plugins/meta-architect/README.md +27 -1
- package/plugins/meta-architect/skills/align/SKILL.md +24 -0
- package/plugins/meta-architect/skills/align/agents/openai.yaml +4 -0
- package/plugins/meta-architect/skills/align/references/shared-language.md +24 -0
- package/plugins/meta-architect/skills/arch/SKILL.md +0 -0
- package/plugins/meta-architect/skills/arch/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/build/SKILL.md +0 -0
- package/plugins/meta-architect/skills/build/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/cleanup/SKILL.md +23 -0
- package/plugins/meta-architect/skills/cleanup/agents/openai.yaml +4 -0
- package/plugins/meta-architect/skills/cleanup/references/style-and-deslop.md +18 -0
- package/plugins/meta-architect/skills/diagnose/SKILL.md +24 -0
- package/plugins/meta-architect/skills/diagnose/agents/openai.yaml +4 -0
- package/plugins/meta-architect/skills/flow/SKILL.md +0 -0
- package/plugins/meta-architect/skills/flow/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/maestro/SKILL.md +36 -3
- package/plugins/meta-architect/skills/maestro/agents/openai.yaml +2 -2
- package/plugins/meta-architect/skills/{meta-architect → maestro}/references/core-release-rules.md +0 -0
- package/plugins/meta-architect/skills/maestro/references/native-ingest-map.md +44 -0
- package/plugins/meta-architect/skills/sage/SKILL.md +3 -1
- package/plugins/meta-architect/skills/sage/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/sage/references/source-selection.md +28 -0
- package/plugins/meta-architect/skills/tdd/SKILL.md +24 -0
- package/plugins/meta-architect/skills/tdd/agents/openai.yaml +4 -0
- package/plugins/meta-architect/skills/vet/SKILL.md +3 -1
- package/plugins/meta-architect/skills/vet/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/vet/references/security-playbooks.md +23 -0
- package/plugins/meta-architect/skills/vibe/SKILL.md +0 -0
- package/plugins/meta-architect/skills/vibe/agents/openai.yaml +0 -0
- package/scripts/biome-staged.js +0 -0
- package/scripts/build-linux-packages.mjs +328 -0
- package/scripts/doctor.js +19 -0
- package/scripts/linux-package-lib.mjs +40 -0
- package/scripts/linux-package-smoke.mjs +103 -0
- package/scripts/plugin-sync.js +0 -0
- package/scripts/postinstall.js +0 -0
- package/scripts/release-metadata.js +0 -0
- package/scripts/release-sync.js +13 -6
- package/scripts/release-verify.js +0 -0
- package/scripts/setup-npmrc.js +0 -0
- package/skills/align/SKILL.md +24 -0
- package/skills/align/agents/openai.yaml +4 -0
- package/skills/align/references/shared-language.md +24 -0
- package/skills/arch/SKILL.md +0 -0
- package/skills/arch/agents/openai.yaml +0 -0
- package/skills/build/SKILL.md +0 -0
- package/skills/build/agents/openai.yaml +0 -0
- package/skills/cleanup/SKILL.md +23 -0
- package/skills/cleanup/agents/openai.yaml +4 -0
- package/skills/cleanup/references/style-and-deslop.md +18 -0
- package/skills/diagnose/SKILL.md +24 -0
- package/skills/diagnose/agents/openai.yaml +4 -0
- package/skills/flow/SKILL.md +0 -0
- package/skills/flow/agents/openai.yaml +0 -0
- package/skills/index.json +21 -6
- package/skills/maestro/SKILL.md +36 -3
- package/skills/maestro/agents/openai.yaml +2 -2
- package/skills/{meta-architect → maestro}/references/core-release-rules.md +0 -0
- package/skills/maestro/references/native-ingest-map.md +44 -0
- package/skills/sage/SKILL.md +3 -1
- package/skills/sage/agents/openai.yaml +0 -0
- package/skills/sage/references/source-selection.md +28 -0
- package/skills/tdd/SKILL.md +24 -0
- package/skills/tdd/agents/openai.yaml +4 -0
- package/skills/vet/SKILL.md +3 -1
- package/skills/vet/agents/openai.yaml +0 -0
- package/skills/vet/references/security-playbooks.md +23 -0
- package/skills/vibe/SKILL.md +0 -0
- package/skills/vibe/agents/openai.yaml +0 -0
- package/src/bootstrap.js +124 -24
- package/src/decision-log.js +12 -9
- package/src/launcher.js +0 -0
- package/src/mcp-config.js +130 -8
- package/src/mcp-live-client.js +1 -1
- package/src/paths.js +33 -1
- package/src/release-state.js +30 -1
- package/src/runtime/build-readiness.js +38 -0
- package/src/runtime/continuity-notes.js +79 -0
- package/src/runtime/guidance-stack.js +42 -0
- package/src/runtime/maestro-manager.js +586 -0
- package/src/runtime/orchestrator.js +158 -0
- package/src/runtime/runtime-state.js +382 -0
- package/src/runtime/signal-hooks.js +52 -0
- package/src/runtime/startup-path.js +14 -0
- package/src/runtime/workspaces.js +25 -0
- package/src/runtime-artifacts.js +190 -30
- package/src/skill-installer.js +53 -5
- package/src/skills.js +633 -49
- package/src/state-sync.js +51 -8
- package/plugins/meta-architect/skills/meta-architect/SKILL.md +0 -32
- package/plugins/meta-architect/skills/meta-architect/agents/openai.yaml +0 -4
- package/skills/meta-architect/SKILL.md +0 -32
- package/skills/meta-architect/agents/openai.yaml +0 -4
package/src/skills.js
CHANGED
|
@@ -5,9 +5,25 @@ import { readJson, writeFileIfMissing, writeJson } from "./fs-utils.js";
|
|
|
5
5
|
import { validateMcpServers } from "./mcp-config.js";
|
|
6
6
|
import { McpSseClient } from "./mcp-live-client.js";
|
|
7
7
|
import { getRepoRoot, getRuntimeReadPath, getRuntimeWritePath, packageRoot } from "./paths.js";
|
|
8
|
+
import { evaluateRuntimeBuildReadiness } from "./runtime/build-readiness.js";
|
|
9
|
+
import {
|
|
10
|
+
buildHelperFailureMatrix,
|
|
11
|
+
chooseMaestroManagerAction,
|
|
12
|
+
createManagerRun,
|
|
13
|
+
getActiveManagerRun,
|
|
14
|
+
loadManagerRunRegistry,
|
|
15
|
+
saveManagerRunRegistry,
|
|
16
|
+
} from "./runtime/maestro-manager.js";
|
|
17
|
+
import { submitTask } from "./runtime/orchestrator.js";
|
|
18
|
+
import {
|
|
19
|
+
assertLeaderAuthority,
|
|
20
|
+
createRuntimeSummary,
|
|
21
|
+
loadRuntimeSnapshot,
|
|
22
|
+
} from "./runtime/runtime-state.js";
|
|
8
23
|
import {
|
|
9
24
|
seedRuntimeArtifacts,
|
|
10
25
|
writeArchitectureArtifacts,
|
|
26
|
+
writeBuildPlanArtifact,
|
|
11
27
|
writeEvidenceSpec,
|
|
12
28
|
writeExperienceSpec,
|
|
13
29
|
writeLogicSpec,
|
|
@@ -18,9 +34,10 @@ import {
|
|
|
18
34
|
import { syncStatusUpdates } from "./state-sync.js";
|
|
19
35
|
|
|
20
36
|
const skillNames = ["$maestro", "$arch", "$sage", "$flow", "$vet", "$vibe", "$build"];
|
|
37
|
+
const maestroWorkflowSequence = ["$arch", "$sage", "$flow", "$vet", "$vibe", "$build"];
|
|
21
38
|
const workflowTemplates = {
|
|
22
39
|
"maestro.skill.md":
|
|
23
|
-
"# `$maestro`\n\
|
|
40
|
+
"# `$maestro`\n\nThe singular Meta-Architect umbrella workflow. Inspect runtime state, execute bounded helper or gated work when it is safe, persist the manager-run control plane, and return the exact next trigger.\n",
|
|
24
41
|
"arch.skill.md":
|
|
25
42
|
"# `$arch`\n\nProduces blueprint architecture, stack rationale, subsystem design, and tradeoffs.\n",
|
|
26
43
|
"sage.skill.md":
|
|
@@ -30,6 +47,14 @@ const workflowTemplates = {
|
|
|
30
47
|
"vibe.skill.md":
|
|
31
48
|
"# `$vibe`\n\nReviews developer and user experience risks before build execution.\n",
|
|
32
49
|
"build.skill.md": "# `$build`\n\nChecks gates and plans bounded build execution.\n",
|
|
50
|
+
"align.skill.md":
|
|
51
|
+
"# `$align`\n\nHelper skill for scope alignment, shared language, and docs clarity. Non-gating.\n",
|
|
52
|
+
"diagnose.skill.md":
|
|
53
|
+
"# `$diagnose`\n\nHelper skill for blocked-lane diagnosis and root-cause slicing. Non-gating.\n",
|
|
54
|
+
"tdd.skill.md":
|
|
55
|
+
"# `$tdd`\n\nHelper skill for regression-first or test-first preparation. Non-gating.\n",
|
|
56
|
+
"cleanup.skill.md":
|
|
57
|
+
"# `$cleanup`\n\nHelper skill for simplification, anti-slop cleanup, and final-pass polish. Non-gating.\n",
|
|
33
58
|
"sync.skill.md":
|
|
34
59
|
"# `$sync`\n\nReserved for refreshing mapped MCP sources and availability records.\n",
|
|
35
60
|
};
|
|
@@ -38,7 +63,7 @@ export function listSkills() {
|
|
|
38
63
|
return skillNames;
|
|
39
64
|
}
|
|
40
65
|
|
|
41
|
-
function chooseMaestroRecommendation(releaseState, idea) {
|
|
66
|
+
function chooseMaestroRecommendation(releaseState, idea, buildReadiness = null) {
|
|
42
67
|
if (releaseState.idea_status !== "CLEAR") {
|
|
43
68
|
return {
|
|
44
69
|
nextStep: "Capture or refine the project brief before any design or validation lane starts.",
|
|
@@ -127,6 +152,21 @@ function chooseMaestroRecommendation(releaseState, idea) {
|
|
|
127
152
|
}
|
|
128
153
|
|
|
129
154
|
if (releaseState.build_status === "LOCKED") {
|
|
155
|
+
if (buildReadiness && buildReadiness.releaseBlockers.length === 0 && !buildReadiness.allowed) {
|
|
156
|
+
return {
|
|
157
|
+
nextStep: "Repair runtime artifacts before bounded build planning can unlock.",
|
|
158
|
+
why: "The release gates are green, but runtime artifacts or pending mailbox proposals are still blocking build readiness.",
|
|
159
|
+
primaryLane: "runtime repair",
|
|
160
|
+
supportLane: "$build",
|
|
161
|
+
assignments: [
|
|
162
|
+
"Repair the listed runtime blockers first.",
|
|
163
|
+
"Re-run $build only after runtime blockers are cleared.",
|
|
164
|
+
],
|
|
165
|
+
avoid: ["Do not unlock bounded implementation planning while runtime blockers remain."],
|
|
166
|
+
nextTrigger: "`repair runtime artifacts`",
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
130
170
|
return {
|
|
131
171
|
nextStep: "Unlock bounded implementation planning.",
|
|
132
172
|
why: "All upstream quality gates are green, so the workflow can now evaluate build readiness.",
|
|
@@ -188,7 +228,338 @@ async function readIdeaText() {
|
|
|
188
228
|
return ideaDecision?.idea ?? null;
|
|
189
229
|
}
|
|
190
230
|
|
|
231
|
+
async function readRuntimeSummary() {
|
|
232
|
+
const runtimeSnapshot = await loadRuntimeSnapshot();
|
|
233
|
+
return createRuntimeSummary(runtimeSnapshot);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function assertControlPlaneReady(runtimeSummary) {
|
|
237
|
+
const blockingInvalidArtifacts = runtimeSummary.invalidArtifacts.filter((artifact) =>
|
|
238
|
+
["runtime.release", "runtime.decisions"].includes(artifact),
|
|
239
|
+
);
|
|
240
|
+
const blockingMissingArtifacts = runtimeSummary.missingArtifacts.filter(
|
|
241
|
+
(artifact) => artifact === "runtime.decisions" || artifact === "runtime.release",
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
const blockingArtifacts = [...blockingInvalidArtifacts, ...blockingMissingArtifacts];
|
|
245
|
+
if (blockingArtifacts.length > 0) {
|
|
246
|
+
throw new Error(`Invalid runtime artifacts: ${blockingArtifacts.join(", ")}`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function getManagerDecisionStatus(managerRun) {
|
|
251
|
+
return managerRun.state.toUpperCase().replaceAll("-", "_");
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function stripBackticks(value) {
|
|
255
|
+
return value.replaceAll("`", "");
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export async function runBuildLane({ actor = null } = {}) {
|
|
259
|
+
const authority = await assertLeaderAuthority(actor);
|
|
260
|
+
const runtimeSnapshot = await loadRuntimeSnapshot();
|
|
261
|
+
const runtimeSummary = createRuntimeSummary(runtimeSnapshot);
|
|
262
|
+
const evaluation = evaluateRuntimeBuildReadiness(runtimeSnapshot.release, runtimeSummary);
|
|
263
|
+
|
|
264
|
+
if (evaluation.controlPlaneBlockers.length > 0) {
|
|
265
|
+
throw new Error(`Invalid runtime artifacts: ${evaluation.controlPlaneBlockers.join(", ")}`);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (!evaluation.allowed) {
|
|
269
|
+
await writeBuildPlanArtifact({
|
|
270
|
+
allowed: false,
|
|
271
|
+
blockers: evaluation.blockers,
|
|
272
|
+
nextTriggers: evaluation.nextTriggers,
|
|
273
|
+
runtimeSummary,
|
|
274
|
+
});
|
|
275
|
+
await appendDecision({
|
|
276
|
+
actor: authority.leaderActor,
|
|
277
|
+
kind: "skill",
|
|
278
|
+
skill: "$build",
|
|
279
|
+
decision: "Build execution remains locked under the current runtime and release state.",
|
|
280
|
+
status: "BLOCKED",
|
|
281
|
+
evidence: [{ kind: "runtime-summary", value: runtimeSummary }],
|
|
282
|
+
blockers: evaluation.blockers,
|
|
283
|
+
next_allowed_triggers: evaluation.nextTriggers,
|
|
284
|
+
});
|
|
285
|
+
return {
|
|
286
|
+
status: "BLOCKED",
|
|
287
|
+
nextTrigger: evaluation.nextTriggers[0] ?? "$build",
|
|
288
|
+
blockers: evaluation.blockers,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const suggestedBranches = ["feature/implementation", "feature/verification"];
|
|
293
|
+
await writeBuildPlanArtifact({
|
|
294
|
+
allowed: true,
|
|
295
|
+
blockers: [],
|
|
296
|
+
nextTriggers: ["$build"],
|
|
297
|
+
suggestedBranches,
|
|
298
|
+
runtimeSummary,
|
|
299
|
+
});
|
|
300
|
+
await appendDecision({
|
|
301
|
+
actor: authority.leaderActor,
|
|
302
|
+
kind: "skill",
|
|
303
|
+
skill: "$build",
|
|
304
|
+
decision: "Build gate ready",
|
|
305
|
+
status: "READY",
|
|
306
|
+
evidence: [
|
|
307
|
+
{ kind: "runtime-summary", value: runtimeSummary },
|
|
308
|
+
{ kind: "branches", value: suggestedBranches },
|
|
309
|
+
],
|
|
310
|
+
blockers: [],
|
|
311
|
+
next_allowed_triggers: ["$build"],
|
|
312
|
+
});
|
|
313
|
+
await syncStatusUpdates({ build_status: "READY" }, { actor: authority.leaderActor });
|
|
314
|
+
return {
|
|
315
|
+
status: "READY",
|
|
316
|
+
nextTrigger: "$build",
|
|
317
|
+
blockers: [],
|
|
318
|
+
suggestedBranches,
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
function getAutonomousGateRunners() {
|
|
323
|
+
return {
|
|
324
|
+
$arch: runArch,
|
|
325
|
+
$sage: runSage,
|
|
326
|
+
$flow: runFlow,
|
|
327
|
+
$vet: runVet,
|
|
328
|
+
$vibe: runVibe,
|
|
329
|
+
$build: runBuildLane,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function updateManagerRunTimestamps(managerRun, overrides = {}) {
|
|
334
|
+
const now = new Date().toISOString();
|
|
335
|
+
Object.assign(managerRun, overrides, { updatedAt: now });
|
|
336
|
+
if (["completed", "blocked", "failed", "cancelled"].includes(managerRun.state)) {
|
|
337
|
+
managerRun.completedAt ??= now;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function buildManagerDecisionEvidence(managerRun, recommendation) {
|
|
342
|
+
return [
|
|
343
|
+
{
|
|
344
|
+
runId: managerRun.id,
|
|
345
|
+
mode: managerRun.mode,
|
|
346
|
+
state: managerRun.state,
|
|
347
|
+
nextAction: managerRun.nextAction,
|
|
348
|
+
helperRuns: managerRun.helperRuns.map((helper) => ({
|
|
349
|
+
id: helper.id,
|
|
350
|
+
skill: helper.skill,
|
|
351
|
+
status: helper.status,
|
|
352
|
+
objective: helper.objective,
|
|
353
|
+
})),
|
|
354
|
+
dispatchPlan: {
|
|
355
|
+
helpers: managerRun.dispatchPlan.helpers.map((helper) => ({
|
|
356
|
+
skill: helper.skill,
|
|
357
|
+
objective: helper.objective,
|
|
358
|
+
})),
|
|
359
|
+
gated: managerRun.dispatchPlan.gated.map((gate) => ({
|
|
360
|
+
skill: gate.skill,
|
|
361
|
+
objective: gate.objective,
|
|
362
|
+
status: gate.status,
|
|
363
|
+
})),
|
|
364
|
+
team: managerRun.dispatchPlan.team
|
|
365
|
+
? {
|
|
366
|
+
title: managerRun.dispatchPlan.team.title,
|
|
367
|
+
createdTaskIds: managerRun.dispatchPlan.team.createdTaskIds,
|
|
368
|
+
}
|
|
369
|
+
: null,
|
|
370
|
+
},
|
|
371
|
+
},
|
|
372
|
+
recommendation,
|
|
373
|
+
];
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
function buildManagerDecisionBlockers(managerRun, runtimeSummary, buildReadiness) {
|
|
377
|
+
const blockers = [];
|
|
378
|
+
if (managerRun.state === "waiting-review" && managerRun.pendingReview.proposalPath) {
|
|
379
|
+
blockers.push(`Manager run is waiting for review at ${managerRun.pendingReview.proposalPath}.`);
|
|
380
|
+
}
|
|
381
|
+
if (managerRun.state === "blocked" && managerRun.retry.lastReason) {
|
|
382
|
+
blockers.push(managerRun.retry.lastReason);
|
|
383
|
+
}
|
|
384
|
+
if (
|
|
385
|
+
buildReadiness &&
|
|
386
|
+
!buildReadiness.allowed &&
|
|
387
|
+
buildReadiness.nextTriggers.includes("repair runtime artifacts")
|
|
388
|
+
) {
|
|
389
|
+
blockers.push(...buildReadiness.runtimeBlockers);
|
|
390
|
+
}
|
|
391
|
+
if (runtimeSummary.pendingMailboxCount > 0) {
|
|
392
|
+
blockers.push("Pending mailbox proposals require leader review.");
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
return [...new Set(blockers)];
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
function executeManagerHelper(helper, { releaseState, runtimeSummary, recommendation }) {
|
|
399
|
+
if (helper.skill === "$align") {
|
|
400
|
+
return {
|
|
401
|
+
helperId: helper.id,
|
|
402
|
+
kind: "alignment",
|
|
403
|
+
workflowSequence: maestroWorkflowSequence,
|
|
404
|
+
currentBuildStatus: releaseState.build_status,
|
|
405
|
+
recommendedNextTrigger: recommendation.nextTrigger,
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (helper.skill === "$diagnose") {
|
|
410
|
+
return {
|
|
411
|
+
helperId: helper.id,
|
|
412
|
+
kind: "diagnostic",
|
|
413
|
+
pendingMailboxCount: runtimeSummary.pendingMailboxCount,
|
|
414
|
+
invalidArtifacts: runtimeSummary.invalidArtifacts,
|
|
415
|
+
missingArtifacts: runtimeSummary.missingArtifacts,
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if (helper.skill === "$tdd") {
|
|
420
|
+
return {
|
|
421
|
+
helperId: helper.id,
|
|
422
|
+
kind: "test-first",
|
|
423
|
+
buildStatus: releaseState.build_status,
|
|
424
|
+
nextTrigger: recommendation.nextTrigger,
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if (helper.skill === "$cleanup") {
|
|
429
|
+
return {
|
|
430
|
+
helperId: helper.id,
|
|
431
|
+
kind: "cleanup",
|
|
432
|
+
mergeStatus: releaseState.merge_status,
|
|
433
|
+
releaseStatus: releaseState.release_status,
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
return {
|
|
438
|
+
helperId: helper.id,
|
|
439
|
+
kind: "manager-helper",
|
|
440
|
+
objective: helper.objective,
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
async function executeManagerHelpers({
|
|
445
|
+
registry,
|
|
446
|
+
managerRun,
|
|
447
|
+
releaseState,
|
|
448
|
+
runtimeSummary,
|
|
449
|
+
recommendation,
|
|
450
|
+
helperFailureMatrix,
|
|
451
|
+
}) {
|
|
452
|
+
const startedAt = new Date().toISOString();
|
|
453
|
+
updateManagerRunTimestamps(managerRun, { state: "running" });
|
|
454
|
+
for (const helperRun of managerRun.helperRuns) {
|
|
455
|
+
helperRun.status = "running";
|
|
456
|
+
helperRun.startedAt = startedAt;
|
|
457
|
+
}
|
|
458
|
+
await saveManagerRunRegistry(registry);
|
|
459
|
+
|
|
460
|
+
const results = await Promise.allSettled(
|
|
461
|
+
managerRun.helperRuns.map(async (helperRun) => {
|
|
462
|
+
const evidence = executeManagerHelper(helperRun, {
|
|
463
|
+
releaseState,
|
|
464
|
+
runtimeSummary,
|
|
465
|
+
recommendation,
|
|
466
|
+
});
|
|
467
|
+
return { helperRun, evidence };
|
|
468
|
+
}),
|
|
469
|
+
);
|
|
470
|
+
|
|
471
|
+
const continuedHelpers = [];
|
|
472
|
+
let hadFailure = false;
|
|
473
|
+
for (const result of results) {
|
|
474
|
+
const helperRun =
|
|
475
|
+
result.status === "fulfilled"
|
|
476
|
+
? result.value.helperRun
|
|
477
|
+
: managerRun.helperRuns[results.indexOf(result)];
|
|
478
|
+
|
|
479
|
+
if (result.status === "fulfilled") {
|
|
480
|
+
helperRun.status = "completed";
|
|
481
|
+
helperRun.evidence.push(result.value.evidence);
|
|
482
|
+
helperRun.completedAt = new Date().toISOString();
|
|
483
|
+
continuedHelpers.push(helperRun.skill);
|
|
484
|
+
continue;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
hadFailure = true;
|
|
488
|
+
const policy = helperFailureMatrix.helper_failed_but_manager_can_fall_back_to_safe_summary;
|
|
489
|
+
helperRun.status = "failed";
|
|
490
|
+
helperRun.errorClass = "helper_failed_but_manager_can_fall_back_to_safe_summary";
|
|
491
|
+
helperRun.errorMessage = result.reason?.message ?? String(result.reason);
|
|
492
|
+
helperRun.completedAt = new Date().toISOString();
|
|
493
|
+
helperRun.evidence.push({
|
|
494
|
+
runId: managerRun.id,
|
|
495
|
+
helperId: helperRun.id,
|
|
496
|
+
skill: helperRun.skill,
|
|
497
|
+
objective: helperRun.objective,
|
|
498
|
+
degradedReason: helperRun.errorMessage,
|
|
499
|
+
safeNextTrigger: recommendation.nextTrigger,
|
|
500
|
+
siblingHelperPolicy: policy.siblingHelperPolicy,
|
|
501
|
+
continuedHelpers,
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
if (hadFailure) {
|
|
506
|
+
updateManagerRunTimestamps(managerRun, {
|
|
507
|
+
state: "completed",
|
|
508
|
+
retry: {
|
|
509
|
+
count: managerRun.retry.count + 1,
|
|
510
|
+
lastReason: "One or more helper runs degraded to recommendation-only behavior.",
|
|
511
|
+
},
|
|
512
|
+
});
|
|
513
|
+
await saveManagerRunRegistry(registry);
|
|
514
|
+
return false;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
await saveManagerRunRegistry(registry);
|
|
518
|
+
return true;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
async function executeManagerTeamDispatch(registry, managerRun) {
|
|
522
|
+
const teamPlan = managerRun.dispatchPlan.team;
|
|
523
|
+
if (!teamPlan) {
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
const taskResult = await submitTask({
|
|
528
|
+
title: teamPlan.title,
|
|
529
|
+
owner: "leader",
|
|
530
|
+
metadata: {
|
|
531
|
+
classification: "durable-team-task",
|
|
532
|
+
managerOwner: "$maestro",
|
|
533
|
+
managerRunId: managerRun.id,
|
|
534
|
+
objective: teamPlan.objective,
|
|
535
|
+
verificationOwner: teamPlan.verificationOwner,
|
|
536
|
+
launchHints: teamPlan.launchHints,
|
|
537
|
+
staffing: teamPlan.staffing,
|
|
538
|
+
},
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
if (taskResult.proposed) {
|
|
542
|
+
updateManagerRunTimestamps(managerRun, {
|
|
543
|
+
state: "waiting-review",
|
|
544
|
+
pendingReview: {
|
|
545
|
+
proposalPath: taskResult.proposalPath,
|
|
546
|
+
mailboxOwner: "leader",
|
|
547
|
+
resumeTrigger: "Review the queued team task proposal, then rerun `$maestro`.",
|
|
548
|
+
},
|
|
549
|
+
});
|
|
550
|
+
await saveManagerRunRegistry(registry);
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
teamPlan.createdTaskIds.push(taskResult.task.id);
|
|
555
|
+
updateManagerRunTimestamps(managerRun, { state: "running" });
|
|
556
|
+
await saveManagerRunRegistry(registry);
|
|
557
|
+
}
|
|
558
|
+
|
|
191
559
|
export async function runIdea(idea) {
|
|
560
|
+
const runtimeSummary = await readRuntimeSummary();
|
|
561
|
+
assertControlPlaneReady(runtimeSummary);
|
|
562
|
+
await assertLeaderAuthority();
|
|
192
563
|
const trimmed = idea.trim();
|
|
193
564
|
if (!trimmed) {
|
|
194
565
|
throw new Error("Idea text is required");
|
|
@@ -203,25 +574,28 @@ export async function runIdea(idea) {
|
|
|
203
574
|
status: "CLEAR",
|
|
204
575
|
evidence: [{ kind: "user-input", value: trimmed }],
|
|
205
576
|
blockers: [],
|
|
206
|
-
next_allowed_triggers: ["$
|
|
577
|
+
next_allowed_triggers: ["$maestro"],
|
|
207
578
|
});
|
|
208
579
|
|
|
209
580
|
await syncStatusUpdates({ idea_status: "CLEAR" });
|
|
210
581
|
}
|
|
211
582
|
|
|
212
583
|
export async function runArch() {
|
|
584
|
+
await assertLeaderAuthority();
|
|
585
|
+
const runtimeSummary = await readRuntimeSummary();
|
|
586
|
+
assertControlPlaneReady(runtimeSummary);
|
|
213
587
|
const idea = await readIdeaText();
|
|
214
588
|
if (!idea) {
|
|
215
589
|
throw new Error("Cannot run $arch before ma idea captures a project brief");
|
|
216
590
|
}
|
|
217
591
|
|
|
218
592
|
const blueprint = {
|
|
219
|
-
summary: `Blueprint derived from idea: ${idea}
|
|
220
|
-
suggestedStack: ["Node.js", "MCP", "GitMCP", "Git worktree"],
|
|
221
|
-
outcome: "Produce a gated architecture and implementation plan",
|
|
593
|
+
summary: `Blueprint derived from idea: ${idea}. Runtime shell currently exposes ${runtimeSummary.workerCount} workers, ${runtimeSummary.workspaceCount} workspaces, and ${runtimeSummary.guidanceSourceCount} guidance sources.`,
|
|
594
|
+
suggestedStack: ["Node.js", "MCP", "GitMCP", "Git worktree", "File-backed runtime state"],
|
|
595
|
+
outcome: "Produce a gated architecture and implementation plan backed by runtime state.",
|
|
222
596
|
};
|
|
223
597
|
|
|
224
|
-
await writeArchitectureArtifacts({ idea, blueprint });
|
|
598
|
+
await writeArchitectureArtifacts({ idea, blueprint, runtimeSummary });
|
|
225
599
|
|
|
226
600
|
await appendDecision({
|
|
227
601
|
kind: "skill",
|
|
@@ -237,7 +611,10 @@ export async function runArch() {
|
|
|
237
611
|
}
|
|
238
612
|
|
|
239
613
|
export async function runSage() {
|
|
614
|
+
await assertLeaderAuthority();
|
|
240
615
|
const config = await validateMcpServers();
|
|
616
|
+
const runtimeSummary = await readRuntimeSummary();
|
|
617
|
+
assertControlPlaneReady(runtimeSummary);
|
|
241
618
|
const sourceEntries = config.servers.map((server) => ({
|
|
242
619
|
repo: server.repo,
|
|
243
620
|
endpoint: server.endpoint,
|
|
@@ -246,7 +623,6 @@ export async function runSage() {
|
|
|
246
623
|
const blockers = [];
|
|
247
624
|
const idea = (await readIdeaText()) ?? "software architecture";
|
|
248
625
|
const disableLiveProbe = process.env.MA_DISABLE_LIVE_MCP === "1";
|
|
249
|
-
const probeCandidates = sourceEntries.slice(0, 1);
|
|
250
626
|
let liveSuccessCount = 0;
|
|
251
627
|
|
|
252
628
|
for (const source of sourceEntries) {
|
|
@@ -258,14 +634,6 @@ export async function runSage() {
|
|
|
258
634
|
continue;
|
|
259
635
|
}
|
|
260
636
|
|
|
261
|
-
if (!probeCandidates.includes(source)) {
|
|
262
|
-
source.liveProbe = {
|
|
263
|
-
skipped: true,
|
|
264
|
-
reason: "Not selected for the live probe set in this run",
|
|
265
|
-
};
|
|
266
|
-
continue;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
637
|
const client = new McpSseClient(source.endpoint);
|
|
270
638
|
try {
|
|
271
639
|
const init = await client.connect();
|
|
@@ -313,13 +681,21 @@ export async function runSage() {
|
|
|
313
681
|
existing.items = sourceEntries;
|
|
314
682
|
await writeJson(getRuntimeWritePath("evidence", "sources.json"), existing);
|
|
315
683
|
|
|
316
|
-
const verified =
|
|
317
|
-
|
|
684
|
+
const verified =
|
|
685
|
+
sourceEntries.length > 0 && !disableLiveProbe && liveSuccessCount === sourceEntries.length;
|
|
686
|
+
if (sourceEntries.length > 0 && !verified && blockers.length === 0) {
|
|
687
|
+
blockers.push(
|
|
688
|
+
disableLiveProbe
|
|
689
|
+
? "Live MCP verification was skipped, so evidence remains unverified."
|
|
690
|
+
: "No live MCP verification succeeded, so evidence remains unverified.",
|
|
691
|
+
);
|
|
692
|
+
}
|
|
693
|
+
await writeEvidenceSpec({ idea, sourceEntries, verified, blockers, runtimeSummary });
|
|
318
694
|
await appendDecision({
|
|
319
695
|
kind: "skill",
|
|
320
696
|
skill: "$sage",
|
|
321
697
|
decision: "Bound architectural choices to approved GitMCP sources using live MCP queries",
|
|
322
|
-
status: verified ? "VERIFIED" : "
|
|
698
|
+
status: verified ? "VERIFIED" : sourceEntries.length > 0 ? "PARTIAL" : "MISSING",
|
|
323
699
|
evidence: sourceEntries,
|
|
324
700
|
blockers: sourceEntries.length > 0 ? blockers : ["No approved GitMCP sources configured"],
|
|
325
701
|
next_allowed_triggers: verified ? ["$flow"] : ["mcp/servers.json", "$sage"],
|
|
@@ -331,10 +707,37 @@ export async function runSage() {
|
|
|
331
707
|
}
|
|
332
708
|
|
|
333
709
|
export async function runFlow() {
|
|
710
|
+
await assertLeaderAuthority();
|
|
711
|
+
const runtimeSnapshot = await loadRuntimeSnapshot();
|
|
712
|
+
const runtimeSummary = createRuntimeSummary(runtimeSnapshot);
|
|
713
|
+
assertControlPlaneReady(runtimeSummary);
|
|
714
|
+
if (runtimeSnapshot.release.evidence_status !== "VERIFIED") {
|
|
715
|
+
throw new Error("Cannot run $flow before $sage reaches VERIFIED evidence_status");
|
|
716
|
+
}
|
|
717
|
+
const blockers = [];
|
|
718
|
+
if (runtimeSummary.missingArtifacts.length > 0) {
|
|
719
|
+
blockers.push(`Missing runtime artifacts: ${runtimeSummary.missingArtifacts.join(", ")}`);
|
|
720
|
+
}
|
|
721
|
+
if (runtimeSummary.invalidArtifacts.length > 0) {
|
|
722
|
+
blockers.push(`Invalid runtime artifacts: ${runtimeSummary.invalidArtifacts.join(", ")}`);
|
|
723
|
+
}
|
|
724
|
+
if (runtimeSummary.pendingMailboxCount > 0) {
|
|
725
|
+
blockers.push(
|
|
726
|
+
"Pending mailbox proposals require leader review before logic can be marked green.",
|
|
727
|
+
);
|
|
728
|
+
}
|
|
729
|
+
if (runtimeSummary.workerCount > 0 && runtimeSummary.workspaceCount === 0) {
|
|
730
|
+
blockers.push("Workers exist without registered workspaces.");
|
|
731
|
+
}
|
|
334
732
|
const logicMap = {
|
|
733
|
+
actors: ["leader", "worker", "guidance_stack", "hook_dispatcher", "workspace_manager"],
|
|
335
734
|
states: ["idea", "architecture", "evidence", "logic", "security", "experience", "build"],
|
|
336
|
-
|
|
735
|
+
runtimeSummary,
|
|
736
|
+
blockers,
|
|
737
|
+
nextTrigger: blockers.length === 0 ? "`$vet`" : "`$flow`",
|
|
337
738
|
};
|
|
739
|
+
const status = blockers.length === 0 ? "GREEN" : "RED";
|
|
740
|
+
const nextAllowedTriggers = blockers.length === 0 ? ["$vet"] : ["$flow"];
|
|
338
741
|
|
|
339
742
|
await writeLogicSpec(logicMap);
|
|
340
743
|
|
|
@@ -342,87 +745,253 @@ export async function runFlow() {
|
|
|
342
745
|
kind: "skill",
|
|
343
746
|
skill: "$flow",
|
|
344
747
|
decision: "Validated logic and state transitions",
|
|
345
|
-
status
|
|
748
|
+
status,
|
|
346
749
|
evidence: [logicMap],
|
|
347
|
-
blockers
|
|
348
|
-
next_allowed_triggers:
|
|
750
|
+
blockers,
|
|
751
|
+
next_allowed_triggers: nextAllowedTriggers,
|
|
349
752
|
});
|
|
350
753
|
|
|
351
|
-
await syncStatusUpdates({ logic_status:
|
|
754
|
+
await syncStatusUpdates({ logic_status: status });
|
|
352
755
|
}
|
|
353
756
|
|
|
354
757
|
export async function runVet() {
|
|
758
|
+
await assertLeaderAuthority();
|
|
759
|
+
const runtimeSummary = await readRuntimeSummary();
|
|
760
|
+
assertControlPlaneReady(runtimeSummary);
|
|
355
761
|
const auditLog = await readJson(getRuntimeWritePath("evidence", "audits.json"));
|
|
356
762
|
const cveLog = await readJson(getRuntimeWritePath("evidence", "cves.json"));
|
|
763
|
+
const reviewApproved =
|
|
764
|
+
auditLog.items.some((item) => item.source === "review" || item.approved === true) ||
|
|
765
|
+
cveLog.items.some((item) => item.source === "review" || item.approved === true);
|
|
357
766
|
const finding = {
|
|
358
767
|
severity: "INFO",
|
|
359
|
-
|
|
360
|
-
|
|
768
|
+
source: "placeholder",
|
|
769
|
+
summary: `Placeholder security review recorded; explicit security approval is still required after reviewing ${runtimeSummary.compatibilityHookCount} compatibility hooks and ${runtimeSummary.runtimeHookCount} runtime events.`,
|
|
770
|
+
unresolved: true,
|
|
361
771
|
};
|
|
362
772
|
auditLog.items.push(finding);
|
|
363
773
|
await writeJson(getRuntimeWritePath("evidence", "audits.json"), auditLog);
|
|
364
774
|
cveLog.items.push({
|
|
365
775
|
id: "baseline-review",
|
|
776
|
+
source: "placeholder",
|
|
366
777
|
severity: "INFO",
|
|
367
|
-
unresolved:
|
|
778
|
+
unresolved: true,
|
|
368
779
|
});
|
|
369
780
|
await writeJson(getRuntimeWritePath("evidence", "cves.json"), cveLog);
|
|
370
781
|
await writeSecuritySpec({
|
|
371
782
|
finding,
|
|
372
783
|
auditCount: auditLog.items.length,
|
|
373
784
|
cveCount: cveLog.items.length,
|
|
785
|
+
runtimeSummary,
|
|
786
|
+
nextTrigger: reviewApproved ? "`$vibe`" : "`$vet`",
|
|
374
787
|
});
|
|
788
|
+
const status = reviewApproved ? "GREEN" : "PENDING";
|
|
789
|
+
const blockers = reviewApproved
|
|
790
|
+
? []
|
|
791
|
+
: ["Security review evidence has not been explicitly approved yet."];
|
|
792
|
+
const nextAllowedTriggers = reviewApproved ? ["$vibe"] : ["$vet"];
|
|
375
793
|
|
|
376
794
|
await appendDecision({
|
|
377
795
|
kind: "skill",
|
|
378
796
|
skill: "$vet",
|
|
379
797
|
decision: "Reviewed security posture for the current implementation",
|
|
380
|
-
status
|
|
798
|
+
status,
|
|
381
799
|
evidence: [finding],
|
|
382
|
-
blockers
|
|
383
|
-
next_allowed_triggers:
|
|
800
|
+
blockers,
|
|
801
|
+
next_allowed_triggers: nextAllowedTriggers,
|
|
384
802
|
});
|
|
385
803
|
|
|
386
|
-
await syncStatusUpdates({ security_status:
|
|
804
|
+
await syncStatusUpdates({ security_status: status });
|
|
387
805
|
}
|
|
388
806
|
|
|
389
807
|
export async function runVibe() {
|
|
808
|
+
await assertLeaderAuthority();
|
|
809
|
+
const runtimeSummary = await readRuntimeSummary();
|
|
810
|
+
assertControlPlaneReady(runtimeSummary);
|
|
390
811
|
const outcomes = await readJson(getRuntimeWritePath("evidence", "outcomes.json"));
|
|
812
|
+
const reviewApproved = outcomes.items.some(
|
|
813
|
+
(item) => item.source === "review" || item.approved === true,
|
|
814
|
+
);
|
|
391
815
|
const note = {
|
|
392
816
|
area: "developer-experience",
|
|
393
|
-
|
|
817
|
+
source: "placeholder",
|
|
818
|
+
summary: `Placeholder DX/UX review recorded; explicit workflow approval is still required while the runtime tracks ${runtimeSummary.taskCount} tasks and ${runtimeSummary.workspaceCount} workspaces.`,
|
|
394
819
|
};
|
|
395
820
|
outcomes.items.push(note);
|
|
396
821
|
await writeJson(getRuntimeWritePath("evidence", "outcomes.json"), outcomes);
|
|
397
|
-
|
|
822
|
+
const status = reviewApproved ? "GREEN" : "PENDING";
|
|
823
|
+
const blockers = reviewApproved
|
|
824
|
+
? []
|
|
825
|
+
: ["DX/UX review evidence has not been explicitly approved yet."];
|
|
826
|
+
const nextAllowedTriggers = reviewApproved ? ["$build"] : ["$vibe"];
|
|
827
|
+
await writeExperienceSpec({
|
|
828
|
+
note,
|
|
829
|
+
outcomeCount: outcomes.items.length,
|
|
830
|
+
runtimeSummary,
|
|
831
|
+
nextTrigger: reviewApproved ? "`$build`" : "`$vibe`",
|
|
832
|
+
});
|
|
398
833
|
|
|
399
834
|
await appendDecision({
|
|
400
835
|
kind: "skill",
|
|
401
836
|
skill: "$vibe",
|
|
402
837
|
decision: "Recorded DX/UX review notes",
|
|
403
|
-
status
|
|
838
|
+
status,
|
|
404
839
|
evidence: [note],
|
|
405
|
-
blockers
|
|
406
|
-
next_allowed_triggers:
|
|
840
|
+
blockers,
|
|
841
|
+
next_allowed_triggers: nextAllowedTriggers,
|
|
407
842
|
});
|
|
408
843
|
|
|
409
|
-
await syncStatusUpdates({ experience_status:
|
|
844
|
+
await syncStatusUpdates({ experience_status: status });
|
|
410
845
|
}
|
|
411
846
|
|
|
412
847
|
export async function runMaestro() {
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
848
|
+
await assertLeaderAuthority();
|
|
849
|
+
let runtimeSnapshot = await loadRuntimeSnapshot();
|
|
850
|
+
let releaseState = runtimeSnapshot.release;
|
|
851
|
+
let runtimeSummary = createRuntimeSummary(runtimeSnapshot);
|
|
852
|
+
assertControlPlaneReady(runtimeSummary);
|
|
853
|
+
let idea = await readIdeaText();
|
|
854
|
+
let buildReadiness = evaluateRuntimeBuildReadiness(releaseState, runtimeSummary);
|
|
855
|
+
let recommendation = chooseMaestroRecommendation(releaseState, idea, buildReadiness);
|
|
856
|
+
const helperFailureMatrix = buildHelperFailureMatrix();
|
|
857
|
+
const registry = await loadManagerRunRegistry();
|
|
858
|
+
const activeRun = getActiveManagerRun(registry);
|
|
859
|
+
const managerAction = chooseMaestroManagerAction({
|
|
860
|
+
releaseState,
|
|
861
|
+
runtimeSummary,
|
|
862
|
+
buildReadiness,
|
|
863
|
+
recommendation,
|
|
864
|
+
activeRun,
|
|
865
|
+
});
|
|
866
|
+
|
|
867
|
+
if (activeRun?.state === "waiting-review" && managerAction.nextAction === "recommend") {
|
|
868
|
+
await writeMaestroPlan({
|
|
869
|
+
releaseState,
|
|
870
|
+
recommendation,
|
|
871
|
+
runtimeSummary,
|
|
872
|
+
workflowSequence: maestroWorkflowSequence,
|
|
873
|
+
managerRun: activeRun,
|
|
874
|
+
});
|
|
875
|
+
await appendDecision({
|
|
876
|
+
kind: "skill",
|
|
877
|
+
skill: "$maestro",
|
|
878
|
+
decision: "Held the manager in waiting-review until the pending proposal is resolved",
|
|
879
|
+
status: "WAITING_REVIEW",
|
|
880
|
+
evidence: buildManagerDecisionEvidence(activeRun, recommendation),
|
|
881
|
+
blockers: buildManagerDecisionBlockers(activeRun, runtimeSummary, buildReadiness),
|
|
882
|
+
next_allowed_triggers: [stripBackticks(recommendation.nextTrigger)],
|
|
883
|
+
});
|
|
884
|
+
return;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
const managerRun = createManagerRun({
|
|
888
|
+
parentRunId: activeRun?.id ?? null,
|
|
889
|
+
triggeredBy: "$maestro",
|
|
890
|
+
mode: managerAction.mode,
|
|
891
|
+
nextAction: managerAction.nextAction,
|
|
892
|
+
dispatchPlan: managerAction.dispatchPlan,
|
|
893
|
+
pendingReview: managerAction.pendingReview ?? null,
|
|
894
|
+
});
|
|
895
|
+
registry.runs.push(managerRun);
|
|
896
|
+
updateManagerRunTimestamps(managerRun);
|
|
897
|
+
await saveManagerRunRegistry(registry);
|
|
898
|
+
|
|
899
|
+
try {
|
|
900
|
+
updateManagerRunTimestamps(managerRun, { state: "dispatching" });
|
|
901
|
+
await saveManagerRunRegistry(registry);
|
|
902
|
+
|
|
903
|
+
if (managerRun.helperRuns.length > 0) {
|
|
904
|
+
const helpersCompleted = await executeManagerHelpers({
|
|
905
|
+
registry,
|
|
906
|
+
managerRun,
|
|
907
|
+
releaseState,
|
|
908
|
+
runtimeSummary,
|
|
909
|
+
recommendation,
|
|
910
|
+
helperFailureMatrix,
|
|
911
|
+
});
|
|
912
|
+
if (!helpersCompleted) {
|
|
913
|
+
runtimeSnapshot = await loadRuntimeSnapshot();
|
|
914
|
+
releaseState = runtimeSnapshot.release;
|
|
915
|
+
runtimeSummary = createRuntimeSummary(runtimeSnapshot);
|
|
916
|
+
buildReadiness = evaluateRuntimeBuildReadiness(releaseState, runtimeSummary);
|
|
917
|
+
recommendation = chooseMaestroRecommendation(releaseState, idea, buildReadiness);
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
if (managerRun.state !== "completed" && managerRun.nextAction === "dispatch-gated") {
|
|
922
|
+
const gateRunners = getAutonomousGateRunners();
|
|
923
|
+
for (const gate of managerRun.dispatchPlan.gated) {
|
|
924
|
+
const runner = gateRunners[gate.skill];
|
|
925
|
+
if (!runner) {
|
|
926
|
+
gate.status = "recommended";
|
|
927
|
+
continue;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
gate.status = "running";
|
|
931
|
+
updateManagerRunTimestamps(managerRun, { state: "running" });
|
|
932
|
+
await saveManagerRunRegistry(registry);
|
|
933
|
+
await runner();
|
|
934
|
+
gate.status = "completed";
|
|
935
|
+
await saveManagerRunRegistry(registry);
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
if (managerRun.state !== "completed" && managerRun.nextAction === "dispatch-team") {
|
|
940
|
+
await executeManagerTeamDispatch(registry, managerRun);
|
|
941
|
+
}
|
|
942
|
+
} catch (error) {
|
|
943
|
+
updateManagerRunTimestamps(managerRun, {
|
|
944
|
+
state: "failed",
|
|
945
|
+
retry: {
|
|
946
|
+
count: managerRun.retry.count + 1,
|
|
947
|
+
lastReason: error.message,
|
|
948
|
+
},
|
|
949
|
+
});
|
|
950
|
+
await saveManagerRunRegistry(registry);
|
|
951
|
+
throw error;
|
|
952
|
+
}
|
|
416
953
|
|
|
417
|
-
await
|
|
954
|
+
runtimeSnapshot = await loadRuntimeSnapshot();
|
|
955
|
+
releaseState = runtimeSnapshot.release;
|
|
956
|
+
runtimeSummary = createRuntimeSummary(runtimeSnapshot);
|
|
957
|
+
assertControlPlaneReady(runtimeSummary);
|
|
958
|
+
idea = await readIdeaText();
|
|
959
|
+
buildReadiness = evaluateRuntimeBuildReadiness(releaseState, runtimeSummary);
|
|
960
|
+
recommendation = chooseMaestroRecommendation(releaseState, idea, buildReadiness);
|
|
961
|
+
|
|
962
|
+
if (managerRun.state === "dispatching" || managerRun.state === "running") {
|
|
963
|
+
updateManagerRunTimestamps(managerRun, { state: "completed" });
|
|
964
|
+
await saveManagerRunRegistry(registry);
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
if (
|
|
968
|
+
buildReadiness.nextTriggers.includes("$build") ||
|
|
969
|
+
buildReadiness.nextTriggers.includes("repair runtime artifacts")
|
|
970
|
+
) {
|
|
971
|
+
await writeBuildPlanArtifact({
|
|
972
|
+
allowed: buildReadiness.allowed,
|
|
973
|
+
blockers: buildReadiness.blockers,
|
|
974
|
+
nextTriggers: buildReadiness.nextTriggers,
|
|
975
|
+
runtimeSummary,
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
await writeMaestroPlan({
|
|
980
|
+
releaseState,
|
|
981
|
+
recommendation,
|
|
982
|
+
runtimeSummary,
|
|
983
|
+
workflowSequence: maestroWorkflowSequence,
|
|
984
|
+
managerRun,
|
|
985
|
+
});
|
|
418
986
|
await appendDecision({
|
|
419
987
|
kind: "skill",
|
|
420
988
|
skill: "$maestro",
|
|
421
|
-
decision:
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
989
|
+
decision:
|
|
990
|
+
"Executed the autonomous Meta-Architect manager run and persisted the control-plane record",
|
|
991
|
+
status: getManagerDecisionStatus(managerRun),
|
|
992
|
+
evidence: buildManagerDecisionEvidence(managerRun, recommendation),
|
|
993
|
+
blockers: buildManagerDecisionBlockers(managerRun, runtimeSummary, buildReadiness),
|
|
994
|
+
next_allowed_triggers: [stripBackticks(recommendation.nextTrigger)],
|
|
426
995
|
});
|
|
427
996
|
}
|
|
428
997
|
|
|
@@ -433,6 +1002,12 @@ export async function runInit() {
|
|
|
433
1002
|
".codex/prompts",
|
|
434
1003
|
".ma/skills",
|
|
435
1004
|
".ma/evidence",
|
|
1005
|
+
".ma/guidance",
|
|
1006
|
+
".ma/memory",
|
|
1007
|
+
".ma/hooks",
|
|
1008
|
+
".ma/tasks",
|
|
1009
|
+
".ma/workspaces",
|
|
1010
|
+
".ma/state",
|
|
436
1011
|
".ma/context",
|
|
437
1012
|
".ma/specs",
|
|
438
1013
|
".ma/plans",
|
|
@@ -508,8 +1083,8 @@ export async function runInit() {
|
|
|
508
1083
|
path.join(getRepoRoot(), "docs", "release-spec.md"),
|
|
509
1084
|
],
|
|
510
1085
|
[
|
|
511
|
-
path.join(packageRoot, "docs", "qa", "release-readiness-0.1.
|
|
512
|
-
path.join(getRepoRoot(), "docs", "qa", "release-readiness-0.1.
|
|
1086
|
+
path.join(packageRoot, "docs", "qa", "release-readiness-0.1.12.md"),
|
|
1087
|
+
path.join(getRepoRoot(), "docs", "qa", "release-readiness-0.1.12.md"),
|
|
513
1088
|
],
|
|
514
1089
|
];
|
|
515
1090
|
|
|
@@ -531,7 +1106,12 @@ export async function runInit() {
|
|
|
531
1106
|
]);
|
|
532
1107
|
}
|
|
533
1108
|
|
|
534
|
-
for (const file of [
|
|
1109
|
+
for (const file of [
|
|
1110
|
+
"servers.json",
|
|
1111
|
+
"collections.json",
|
|
1112
|
+
"fallback.json",
|
|
1113
|
+
"local-capabilities.json",
|
|
1114
|
+
]) {
|
|
535
1115
|
templateCopies.push([
|
|
536
1116
|
path.join(packageRoot, "mcp", file),
|
|
537
1117
|
path.join(getRepoRoot(), "mcp", file),
|
|
@@ -599,6 +1179,10 @@ export async function runInit() {
|
|
|
599
1179
|
path.join(getRepoRoot(), "mcp", "servers.json"),
|
|
600
1180
|
`${JSON.stringify({ schemaVersion: "0.1.0", servers: [] }, null, 2)}\n`,
|
|
601
1181
|
);
|
|
1182
|
+
await writeFileIfMissing(
|
|
1183
|
+
path.join(getRepoRoot(), "mcp", "local-capabilities.json"),
|
|
1184
|
+
`${JSON.stringify({ schemaVersion: "0.1.0", capabilities: [] }, null, 2)}\n`,
|
|
1185
|
+
);
|
|
602
1186
|
await writeFileIfMissing(
|
|
603
1187
|
path.join(getRepoRoot(), "mcp", "collections.json"),
|
|
604
1188
|
`${JSON.stringify({ schemaVersion: "0.1.0", collections: {} }, null, 2)}\n`,
|