@jstn-sdk/ma 0.1.12 → 0.1.13

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.
Files changed (177) hide show
  1. package/.agents/plugins/marketplace.json +0 -0
  2. package/.codex/agents/Architect.toml +0 -2
  3. package/.codex/agents/Auditor.toml +0 -2
  4. package/.codex/agents/Builder.toml +0 -2
  5. package/.codex/agents/Flow.toml +0 -2
  6. package/.codex/agents/Sage.toml +0 -2
  7. package/.codex/agents/Vibe.toml +0 -2
  8. package/.codex/hooks.json +14 -13
  9. package/.codex/prompts/enforcement.md +4 -0
  10. package/.codex/prompts/skill-contract.md +4 -0
  11. package/COVERAGE.md +211 -0
  12. package/DEMO.md +265 -0
  13. package/README.md +159 -16
  14. package/bin/ma.js +219 -14
  15. package/data/clone-data.ledger.json +41 -0
  16. package/data/clone-data.proof.json +50 -0
  17. package/data/clone-data.rvf +37 -0
  18. package/docs/README.md +4 -1
  19. package/docs/assets/image/Screenshot(1).png +0 -0
  20. package/docs/assets/image/Screenshot(2).png +0 -0
  21. package/docs/assets/image/Screenshot(3).png +0 -0
  22. package/docs/assets/image/Screenshot(4).png +0 -0
  23. package/docs/assets/image/Screenshot(5).png +0 -0
  24. package/docs/assets/image/Screenshot(6).png +0 -0
  25. package/docs/assets/image/Screenshot(7).png +0 -0
  26. package/docs/assets/image/Screenshot(8).png +0 -0
  27. package/docs/assets/image/Screenshot(9).png +0 -0
  28. package/docs/assets/meta-architect-logo.png +0 -0
  29. package/docs/assets/meta-architect-logo.svg +0 -0
  30. package/docs/getting-started.md +38 -22
  31. package/docs/installed-sdk.md +0 -0
  32. package/docs/mcp-setup.md +35 -0
  33. package/docs/onboarding.md +18 -2
  34. package/docs/prompt-guidance-contract.md +17 -0
  35. package/docs/prompt-guidance-fragments/active-autonomy-core.md +7 -0
  36. package/docs/qa/release-issue-gates-0.1.13.json +644 -0
  37. package/docs/qa/{release-readiness-0.1.12.md → release-readiness-0.1.13.md} +25 -9
  38. package/docs/qa/release-readiness-0.1.5.md +1 -1
  39. package/docs/reference/native-engineering-patterns.md +0 -0
  40. package/docs/reference/native-security-playbooks.md +6 -0
  41. package/docs/reference/native-source-selection.md +6 -0
  42. package/docs/reference/native-style-and-deslop.md +0 -0
  43. package/docs/release-spec.md +25 -9
  44. package/docs/skills.md +14 -1
  45. package/index.js +222 -2
  46. package/mcp/collections.json +23 -6
  47. package/mcp/local/code-intel.js +0 -0
  48. package/mcp/local/memory.js +0 -0
  49. package/mcp/local/playbooks.js +0 -0
  50. package/mcp/local/state.js +0 -0
  51. package/mcp/local/team-run.js +48 -1
  52. package/mcp/local/trace.js +0 -0
  53. package/mcp/local-capabilities.json +0 -0
  54. package/mcp/native-playbooks.json +0 -0
  55. package/mcp/servers.json +24 -0
  56. package/package.json +5 -2
  57. package/plugins/meta-architect/.app.json +1 -1
  58. package/plugins/meta-architect/.codex-plugin/plugin.json +1 -1
  59. package/plugins/meta-architect/.mcp.json +1 -1
  60. package/plugins/meta-architect/README.md +8 -1
  61. package/plugins/meta-architect/obsidian/main.js +401 -0
  62. package/plugins/meta-architect/obsidian/manifest.json +9 -0
  63. package/plugins/meta-architect/obsidian/styles.css +7 -0
  64. package/plugins/meta-architect/skills/align/SKILL.md +0 -0
  65. package/plugins/meta-architect/skills/align/agents/openai.yaml +0 -0
  66. package/plugins/meta-architect/skills/align/references/shared-language.md +0 -0
  67. package/plugins/meta-architect/skills/arch/SKILL.md +2 -0
  68. package/plugins/meta-architect/skills/arch/agents/openai.yaml +0 -0
  69. package/plugins/meta-architect/skills/build/SKILL.md +3 -0
  70. package/plugins/meta-architect/skills/build/agents/openai.yaml +0 -0
  71. package/plugins/meta-architect/skills/cleanup/SKILL.md +0 -0
  72. package/plugins/meta-architect/skills/cleanup/agents/openai.yaml +0 -0
  73. package/plugins/meta-architect/skills/cleanup/references/style-and-deslop.md +0 -0
  74. package/plugins/meta-architect/skills/diagnose/SKILL.md +0 -0
  75. package/plugins/meta-architect/skills/diagnose/agents/openai.yaml +0 -0
  76. package/plugins/meta-architect/skills/flow/SKILL.md +2 -0
  77. package/plugins/meta-architect/skills/flow/agents/openai.yaml +0 -0
  78. package/plugins/meta-architect/skills/maestro/SKILL.md +0 -0
  79. package/plugins/meta-architect/skills/maestro/agents/openai.yaml +0 -0
  80. package/plugins/meta-architect/skills/maestro/references/core-release-rules.md +0 -0
  81. package/plugins/meta-architect/skills/maestro/references/native-ingest-map.md +0 -0
  82. package/plugins/meta-architect/skills/sage/SKILL.md +2 -0
  83. package/plugins/meta-architect/skills/sage/agents/openai.yaml +0 -0
  84. package/plugins/meta-architect/skills/sage/references/source-selection.md +8 -0
  85. package/plugins/meta-architect/skills/tdd/SKILL.md +0 -0
  86. package/plugins/meta-architect/skills/tdd/agents/openai.yaml +0 -0
  87. package/plugins/meta-architect/skills/vet/SKILL.md +2 -0
  88. package/plugins/meta-architect/skills/vet/agents/openai.yaml +0 -0
  89. package/plugins/meta-architect/skills/vet/references/security-playbooks.md +7 -0
  90. package/plugins/meta-architect/skills/vibe/SKILL.md +2 -0
  91. package/plugins/meta-architect/skills/vibe/agents/openai.yaml +0 -0
  92. package/scripts/active-autonomy-hook.mjs +96 -0
  93. package/scripts/biome-staged.js +0 -0
  94. package/scripts/build-linux-packages.mjs +0 -0
  95. package/scripts/doctor.js +17 -4
  96. package/scripts/install.sh +28 -0
  97. package/scripts/linux-package-lib.mjs +0 -0
  98. package/scripts/linux-package-smoke.mjs +0 -0
  99. package/scripts/plugin-sync.js +0 -0
  100. package/scripts/postinstall.js +0 -0
  101. package/scripts/ralph/prompt.md +35 -0
  102. package/scripts/release-metadata.js +0 -0
  103. package/scripts/release-sync.js +0 -0
  104. package/scripts/release-verify.js +166 -1
  105. package/scripts/setup-npmrc.js +0 -0
  106. package/skills/align/SKILL.md +0 -0
  107. package/skills/align/agents/openai.yaml +0 -0
  108. package/skills/align/references/shared-language.md +0 -0
  109. package/skills/arch/SKILL.md +2 -0
  110. package/skills/arch/agents/openai.yaml +0 -0
  111. package/skills/build/SKILL.md +3 -0
  112. package/skills/build/agents/openai.yaml +0 -0
  113. package/skills/cleanup/SKILL.md +0 -0
  114. package/skills/cleanup/agents/openai.yaml +0 -0
  115. package/skills/cleanup/references/style-and-deslop.md +0 -0
  116. package/skills/diagnose/SKILL.md +0 -0
  117. package/skills/diagnose/agents/openai.yaml +0 -0
  118. package/skills/flow/SKILL.md +2 -0
  119. package/skills/flow/agents/openai.yaml +0 -0
  120. package/skills/maestro/SKILL.md +0 -0
  121. package/skills/maestro/agents/openai.yaml +0 -0
  122. package/skills/maestro/references/core-release-rules.md +0 -0
  123. package/skills/maestro/references/native-ingest-map.md +0 -0
  124. package/skills/sage/SKILL.md +2 -0
  125. package/skills/sage/agents/openai.yaml +0 -0
  126. package/skills/sage/references/source-selection.md +8 -0
  127. package/skills/tdd/SKILL.md +0 -0
  128. package/skills/tdd/agents/openai.yaml +0 -0
  129. package/skills/vet/SKILL.md +2 -0
  130. package/skills/vet/agents/openai.yaml +0 -0
  131. package/skills/vet/references/security-playbooks.md +7 -0
  132. package/skills/vibe/SKILL.md +2 -0
  133. package/skills/vibe/agents/openai.yaml +0 -0
  134. package/src/bootstrap.js +17 -0
  135. package/src/build-gate.js +2 -2
  136. package/src/launcher.js +4 -0
  137. package/src/mcp-live-client.js +289 -3
  138. package/src/paths.js +4 -0
  139. package/src/policy.js +1 -1
  140. package/src/release-issue-gates.js +190 -0
  141. package/src/runtime/active-autonomy-core.js +208 -0
  142. package/src/runtime/alignment-sentinel.js +165 -0
  143. package/src/runtime/architect-review.js +88 -0
  144. package/src/runtime/build-readiness.js +28 -4
  145. package/src/runtime/code-graph-rehearse.js +113 -0
  146. package/src/runtime/context-economy-core.js +276 -0
  147. package/src/runtime/continuity-notes.js +0 -0
  148. package/src/runtime/core-source-ingest.js +379 -0
  149. package/src/runtime/detached-provider.js +74 -0
  150. package/src/runtime/environment-awareness-core.js +460 -0
  151. package/src/runtime/exposure-catalog.js +276 -0
  152. package/src/runtime/guidance-stack.js +0 -0
  153. package/src/runtime/helper-orchestration-core.js +307 -0
  154. package/src/runtime/learning-loop-core.js +238 -0
  155. package/src/runtime/maestro-events.js +18 -0
  156. package/src/runtime/maestro-manager.js +19 -0
  157. package/src/runtime/maestro-state.js +125 -0
  158. package/src/runtime/mcp-policy.js +192 -0
  159. package/src/runtime/obsidian-integration-core.js +851 -0
  160. package/src/runtime/obsidian-plugin-bridge.js +739 -0
  161. package/src/runtime/orchestrator.js +0 -0
  162. package/src/runtime/prompt-strategy-core.js +230 -0
  163. package/src/runtime/quorum-review.js +90 -0
  164. package/src/runtime/ralph-execution-core.js +217 -0
  165. package/src/runtime/redaction-gateway.js +174 -0
  166. package/src/runtime/runtime-state.js +843 -2
  167. package/src/runtime/semantic-recording-core.js +147 -0
  168. package/src/runtime/signal-hooks.js +15 -0
  169. package/src/runtime/skills-registry-export.js +670 -0
  170. package/src/runtime/startup-path.js +0 -0
  171. package/src/runtime/universal-plugin-broker-core.js +575 -0
  172. package/src/runtime/workspace-intelligence-runtime.js +674 -0
  173. package/src/runtime/workspace-virtualizer.js +102 -0
  174. package/src/runtime/workspaces.js +0 -0
  175. package/src/runtime-artifacts.js +225 -62
  176. package/src/skill-installer.js +0 -0
  177. package/src/skills.js +876 -84
package/src/skills.js CHANGED
@@ -3,9 +3,24 @@ import path from "node:path";
3
3
  import { appendDecision } from "./decision-log.js";
4
4
  import { readJson, writeFileIfMissing, writeJson } from "./fs-utils.js";
5
5
  import { validateMcpServers } from "./mcp-config.js";
6
- import { McpSseClient } from "./mcp-live-client.js";
6
+ import { createMcpLiveClient, hasConfiguredMcpRemoteBridge } from "./mcp-live-client.js";
7
7
  import { getRepoRoot, getRuntimeReadPath, getRuntimeWritePath, packageRoot } from "./paths.js";
8
+ import {
9
+ evaluateAlignmentDrift,
10
+ saveAlignmentSentinelReport,
11
+ } from "./runtime/alignment-sentinel.js";
8
12
  import { evaluateRuntimeBuildReadiness } from "./runtime/build-readiness.js";
13
+ import {
14
+ findIngestedCoreSourceForRepo,
15
+ loadCoreSourceIngest,
16
+ } from "./runtime/core-source-ingest.js";
17
+ import { launchDetachedTrack } from "./runtime/detached-provider.js";
18
+ import {
19
+ scanLockfilePackageExposure,
20
+ validateMcpPolicyExposure,
21
+ } from "./runtime/exposure-catalog.js";
22
+ import { createHelperReceipt } from "./runtime/helper-orchestration-core.js";
23
+ import { appendMaestroEvent } from "./runtime/maestro-events.js";
9
24
  import {
10
25
  buildHelperFailureMatrix,
11
26
  chooseMaestroManagerAction,
@@ -14,11 +29,24 @@ import {
14
29
  loadManagerRunRegistry,
15
30
  saveManagerRunRegistry,
16
31
  } from "./runtime/maestro-manager.js";
32
+ import {
33
+ beginMaestroOrchestration,
34
+ loadMaestroStateOrDefault,
35
+ saveMaestroState,
36
+ } from "./runtime/maestro-state.js";
17
37
  import { submitTask } from "./runtime/orchestrator.js";
38
+ import {
39
+ createQuorumReviewReceipt,
40
+ evaluateQuorumVotes,
41
+ quorumDecisions,
42
+ } from "./runtime/quorum-review.js";
43
+ import { writeRalphExecutionContract } from "./runtime/ralph-execution-core.js";
44
+ import { redactProviderBoundText, seedRedactionVault } from "./runtime/redaction-gateway.js";
18
45
  import {
19
46
  assertLeaderAuthority,
20
47
  createRuntimeSummary,
21
48
  loadRuntimeSnapshot,
49
+ repairRuntimeScratchpadArtifacts,
22
50
  } from "./runtime/runtime-state.js";
23
51
  import {
24
52
  seedRuntimeArtifacts,
@@ -33,7 +61,19 @@ import {
33
61
  } from "./runtime-artifacts.js";
34
62
  import { syncStatusUpdates } from "./state-sync.js";
35
63
 
36
- const skillNames = ["$maestro", "$arch", "$sage", "$flow", "$vet", "$vibe", "$build"];
64
+ const skillNames = [
65
+ "$maestro",
66
+ "$arch",
67
+ "$sage",
68
+ "$flow",
69
+ "$vet",
70
+ "$vibe",
71
+ "$build",
72
+ "$align",
73
+ "$diagnose",
74
+ "$tdd",
75
+ "$cleanup",
76
+ ];
37
77
  const maestroWorkflowSequence = ["$arch", "$sage", "$flow", "$vet", "$vibe", "$build"];
38
78
  const workflowTemplates = {
39
79
  "maestro.skill.md":
@@ -181,6 +221,35 @@ function chooseMaestroRecommendation(releaseState, idea, buildReadiness = null)
181
221
  };
182
222
  }
183
223
 
224
+ if (releaseState.build_status === "READY") {
225
+ return {
226
+ nextStep: "Start the bounded build execution substep.",
227
+ why: "The build lane has prepared a narrow slice and verification plan, and the next safe move is to begin that bounded substep.",
228
+ primaryLane: "$build",
229
+ supportLane: "implementation",
230
+ assignments: [
231
+ "Run $build again to move the bounded build slice into active execution.",
232
+ "Keep the slice reversible and lane-owned.",
233
+ ],
234
+ avoid: ["Do not merge or release before the bounded build slice is complete."],
235
+ nextTrigger: "`$build`",
236
+ };
237
+ }
238
+
239
+ if (releaseState.build_status === "RUNNING") {
240
+ return {
241
+ nextStep: "Finalize the bounded build execution substep.",
242
+ why: "The build lane is already running its bounded slice and now needs completion evidence before downstream promotion.",
243
+ primaryLane: "$build",
244
+ supportLane: "verification",
245
+ assignments: [
246
+ "Run $build again to finalize the bounded build substep and persist completion evidence.",
247
+ ],
248
+ avoid: ["Do not merge or release before the build lane records DONE."],
249
+ nextTrigger: "`$build`",
250
+ };
251
+ }
252
+
184
253
  if (releaseState.merge_status !== "MERGED_TO_DEVELOPMENT") {
185
254
  return {
186
255
  nextStep: "Finish the implementation slice and merge it into development.",
@@ -255,7 +324,144 @@ function stripBackticks(value) {
255
324
  return value.replaceAll("`", "");
256
325
  }
257
326
 
258
- export async function runBuildLane({ actor = null } = {}) {
327
+ function isGitMcpDocumentationTool(tool, action) {
328
+ if (!tool || typeof tool.name !== "string") {
329
+ return false;
330
+ }
331
+ if (!tool.name.startsWith(`${action}_`)) {
332
+ return false;
333
+ }
334
+ if (tool.name === "fetch_generic_url_content") {
335
+ return false;
336
+ }
337
+
338
+ const lowerName = tool.name.toLowerCase();
339
+ return (
340
+ lowerName.includes("_documentation") ||
341
+ lowerName.includes("_docs") ||
342
+ `${tool.description ?? ""}`.toLowerCase().includes("documentation")
343
+ );
344
+ }
345
+
346
+ function createBoundedBuildSlice() {
347
+ return [
348
+ "Create or confirm the bounded implementation and verification slice for the current release-ready state.",
349
+ "Keep the slice reversible and owned by the $build lane.",
350
+ ];
351
+ }
352
+
353
+ function createBuildVerificationPlan(nextTrigger = "$build") {
354
+ return [
355
+ "Confirm release gates and runtime control-plane artifacts are still green.",
356
+ `Use ${nextTrigger} as the bounded verification loop trigger for the current build slice.`,
357
+ ];
358
+ }
359
+
360
+ function createBuildRepairPath() {
361
+ return [
362
+ "If the bounded build slice becomes invalid without upstream gate regression, return to READY and rerun `$build`.",
363
+ "If runtime or upstream gates regress, fail closed and repair those blockers before resuming.",
364
+ ];
365
+ }
366
+
367
+ async function updateMaestroLedgerForBuild({
368
+ buildStatus,
369
+ runtimeSummary,
370
+ blockers,
371
+ nextTriggers,
372
+ gateState,
373
+ trackStatus,
374
+ completionEvidence = [],
375
+ }) {
376
+ let maestroState = await loadMaestroStateOrDefault();
377
+ maestroState = beginMaestroOrchestration(maestroState, {
378
+ globalStatus: gateState,
379
+ });
380
+ maestroState.runtime_tracks.track_0_sync = {
381
+ active_gate: "$build",
382
+ status: trackStatus,
383
+ pid: null,
384
+ execution_pane: null,
385
+ exit_code: trackStatus === "COMPLETED" ? 0 : null,
386
+ blockers,
387
+ next_triggers: nextTriggers,
388
+ completion_evidence: completionEvidence,
389
+ build_status: buildStatus,
390
+ updated_at: new Date().toISOString(),
391
+ runtime_summary: {
392
+ pendingMailboxCount: runtimeSummary.pendingMailboxCount,
393
+ invalidArtifacts: runtimeSummary.invalidArtifacts,
394
+ missingArtifacts: runtimeSummary.missingArtifacts,
395
+ },
396
+ };
397
+ maestroState.downstream_lock_table.$build = {
398
+ is_locked: buildStatus !== "DONE",
399
+ locked_by: buildStatus === "DONE" ? [] : ["$build"],
400
+ unlock_criteria: "build_status == 'DONE'",
401
+ };
402
+ maestroState.timestamp = new Date().toISOString();
403
+ maestroState.global_status = gateState;
404
+ await saveMaestroState(maestroState);
405
+ await appendMaestroEvent({
406
+ record_type: "runtime:track_status",
407
+ gate: "$build",
408
+ global_status: gateState,
409
+ track_status: trackStatus,
410
+ build_status: buildStatus,
411
+ next_triggers: nextTriggers,
412
+ blockers,
413
+ });
414
+ await appendMaestroEvent({
415
+ record_type: "lock:downstream_circuit_breaker",
416
+ target_gate: "$build",
417
+ is_locked: buildStatus !== "DONE",
418
+ locked_by: buildStatus === "DONE" ? [] : ["$build"],
419
+ unlock_criteria: "build_status == 'DONE'",
420
+ });
421
+ }
422
+
423
+ async function updateScratchpadTrackForLane({
424
+ gate,
425
+ trackStatus,
426
+ globalStatus,
427
+ blockers = [],
428
+ nextTriggers = [],
429
+ detached = null,
430
+ details = {},
431
+ }) {
432
+ let maestroState = await loadMaestroStateOrDefault();
433
+ maestroState = beginMaestroOrchestration(maestroState, {
434
+ globalStatus,
435
+ });
436
+ const trackKey = `track_${gate.replaceAll("$", "")}_sync`;
437
+ maestroState.runtime_tracks[trackKey] = {
438
+ active_gate: gate,
439
+ status: trackStatus,
440
+ pid: null,
441
+ execution_pane: detached?.executionPane ?? null,
442
+ provider: detached?.provider ?? "none",
443
+ log_path: detached?.logPath ?? null,
444
+ exit_code: trackStatus === "COMPLETED" ? 0 : null,
445
+ blockers,
446
+ next_triggers: nextTriggers,
447
+ updated_at: new Date().toISOString(),
448
+ ...details,
449
+ };
450
+ maestroState.timestamp = new Date().toISOString();
451
+ maestroState.global_status = globalStatus;
452
+ await saveMaestroState(maestroState);
453
+ await appendMaestroEvent({
454
+ record_type: "runtime:track_status",
455
+ gate,
456
+ global_status: globalStatus,
457
+ track_status: trackStatus,
458
+ next_triggers: nextTriggers,
459
+ blockers,
460
+ provider: detached?.provider ?? "none",
461
+ });
462
+ }
463
+
464
+ export async function runBuildLane({ actor = null, reviewMode = null, quorumVotes = [] } = {}) {
259
465
  const authority = await assertLeaderAuthority(actor);
260
466
  const runtimeSnapshot = await loadRuntimeSnapshot();
261
467
  const runtimeSummary = createRuntimeSummary(runtimeSnapshot);
@@ -268,10 +474,22 @@ export async function runBuildLane({ actor = null } = {}) {
268
474
  if (!evaluation.allowed) {
269
475
  await writeBuildPlanArtifact({
270
476
  allowed: false,
477
+ gateState: "LOCKED",
271
478
  blockers: evaluation.blockers,
272
479
  nextTriggers: evaluation.nextTriggers,
480
+ buildSlice: createBoundedBuildSlice(),
481
+ verificationPlan: createBuildVerificationPlan("`$build`"),
482
+ repairPath: createBuildRepairPath(),
273
483
  runtimeSummary,
274
484
  });
485
+ await updateMaestroLedgerForBuild({
486
+ buildStatus: runtimeSnapshot.release.build_status,
487
+ runtimeSummary,
488
+ blockers: evaluation.blockers,
489
+ nextTriggers: evaluation.nextTriggers,
490
+ gateState: "LOCKED",
491
+ trackStatus: "BLOCKED",
492
+ });
275
493
  await appendDecision({
276
494
  actor: authority.leaderActor,
277
495
  kind: "skill",
@@ -290,30 +508,205 @@ export async function runBuildLane({ actor = null } = {}) {
290
508
  }
291
509
 
292
510
  const suggestedBranches = ["feature/implementation", "feature/verification"];
511
+ const buildSlice = createBoundedBuildSlice();
512
+ const verificationPlan = createBuildVerificationPlan("`$build`");
513
+ const repairPath = createBuildRepairPath();
514
+ const ralphContract = await writeRalphExecutionContract({
515
+ buildSlice,
516
+ verificationPlan,
517
+ runtimeSummary,
518
+ });
519
+
520
+ if (runtimeSnapshot.release.build_status === "LOCKED") {
521
+ await writeBuildPlanArtifact({
522
+ allowed: true,
523
+ gateState: "READY",
524
+ blockers: [],
525
+ nextTriggers: ["$build"],
526
+ suggestedBranches,
527
+ buildSlice,
528
+ verificationPlan,
529
+ repairPath,
530
+ runtimeSummary,
531
+ });
532
+ await appendDecision({
533
+ actor: authority.leaderActor,
534
+ kind: "skill",
535
+ skill: "$build",
536
+ decision: "Build gate ready",
537
+ status: "READY",
538
+ evidence: [
539
+ { kind: "runtime-summary", value: runtimeSummary },
540
+ { kind: "branches", value: suggestedBranches },
541
+ { kind: "build-slice", value: buildSlice },
542
+ { kind: "ralph-prd", value: ralphContract.prdPath },
543
+ ],
544
+ blockers: [],
545
+ next_allowed_triggers: ["$build"],
546
+ });
547
+ await syncStatusUpdates({ build_status: "READY" }, { actor: authority.leaderActor });
548
+ await updateMaestroLedgerForBuild({
549
+ buildStatus: "READY",
550
+ runtimeSummary,
551
+ blockers: [],
552
+ nextTriggers: ["$build"],
553
+ gateState: "READY",
554
+ trackStatus: "READY",
555
+ });
556
+ return {
557
+ status: "READY",
558
+ nextTrigger: "$build",
559
+ blockers: [],
560
+ suggestedBranches,
561
+ };
562
+ }
563
+
564
+ if (runtimeSnapshot.release.build_status === "READY") {
565
+ await writeBuildPlanArtifact({
566
+ allowed: true,
567
+ gateState: "RUNNING",
568
+ blockers: [],
569
+ nextTriggers: ["$build"],
570
+ suggestedBranches,
571
+ buildSlice,
572
+ verificationPlan,
573
+ repairPath,
574
+ runtimeSummary,
575
+ });
576
+ await appendDecision({
577
+ actor: authority.leaderActor,
578
+ kind: "skill",
579
+ skill: "$build",
580
+ decision: "Started the bounded build execution substep",
581
+ status: "RUNNING",
582
+ evidence: [
583
+ { kind: "runtime-summary", value: runtimeSummary },
584
+ { kind: "build-slice", value: buildSlice },
585
+ { kind: "verification-plan", value: verificationPlan },
586
+ { kind: "ralph-prd", value: ralphContract.prdPath },
587
+ ],
588
+ blockers: [],
589
+ next_allowed_triggers: ["$build"],
590
+ });
591
+ await syncStatusUpdates({ build_status: "RUNNING" }, { actor: authority.leaderActor });
592
+ await updateMaestroLedgerForBuild({
593
+ buildStatus: "RUNNING",
594
+ runtimeSummary,
595
+ blockers: [],
596
+ nextTriggers: ["$build"],
597
+ gateState: "RUNNING",
598
+ trackStatus: "RUNNING",
599
+ });
600
+ return {
601
+ status: "RUNNING",
602
+ nextTrigger: "$build",
603
+ blockers: [],
604
+ suggestedBranches,
605
+ };
606
+ }
607
+
608
+ const completionEvidence = [
609
+ "Build slice remained release-ready through the bounded verification substep.",
610
+ "Runtime control-plane artifacts remained valid at completion.",
611
+ ];
612
+ if (reviewMode === "quorum") {
613
+ const quorum = evaluateQuorumVotes(quorumVotes);
614
+ const quorumReceipt = createQuorumReviewReceipt({ votes: quorumVotes, evaluation: quorum });
615
+ if (quorum.decision !== quorumDecisions.APPROVED) {
616
+ await writeBuildPlanArtifact({
617
+ allowed: true,
618
+ gateState: "READY",
619
+ blockers: quorum.blockers,
620
+ nextTriggers: ["$build"],
621
+ suggestedBranches,
622
+ buildSlice,
623
+ verificationPlan: [
624
+ ...verificationPlan,
625
+ "Resolve quorum disagreement or provide a compatible majority fingerprint before promotion.",
626
+ ],
627
+ repairPath,
628
+ runtimeSummary,
629
+ });
630
+ await appendDecision({
631
+ actor: authority.leaderActor,
632
+ kind: "skill",
633
+ skill: "$build",
634
+ decision: "Quorum review did not approve the current bounded build slice",
635
+ status: "READY",
636
+ evidence: [
637
+ { kind: "runtime-summary", value: runtimeSummary },
638
+ { kind: "quorum-votes", value: quorumVotes },
639
+ { kind: "quorum-decision", value: quorum },
640
+ { kind: "quorum-receipt", value: quorumReceipt },
641
+ { kind: "ralph-prd", value: ralphContract.prdPath },
642
+ ],
643
+ blockers: quorum.blockers,
644
+ next_allowed_triggers: ["$build"],
645
+ });
646
+ await syncStatusUpdates({ build_status: "READY" }, { actor: authority.leaderActor });
647
+ await updateMaestroLedgerForBuild({
648
+ buildStatus: "READY",
649
+ runtimeSummary,
650
+ blockers: quorum.blockers,
651
+ nextTriggers: ["$build"],
652
+ gateState: "READY",
653
+ trackStatus: "BLOCKED",
654
+ completionEvidence: ["Quorum review returned INDETERMINATE or non-approval."],
655
+ });
656
+ return {
657
+ status: "READY",
658
+ nextTrigger: "$build",
659
+ blockers: quorum.blockers,
660
+ suggestedBranches,
661
+ };
662
+ }
663
+ completionEvidence.push(
664
+ "Quorum review approved the bounded build slice with a majority-compatible fingerprint.",
665
+ );
666
+ completionEvidence.push(
667
+ `Quorum confidence receipt recorded with ${quorumReceipt.reviewer_count} reviewers.`,
668
+ );
669
+ }
293
670
  await writeBuildPlanArtifact({
294
671
  allowed: true,
672
+ gateState: "DONE",
295
673
  blockers: [],
296
- nextTriggers: ["$build"],
674
+ nextTriggers: ["ma merge <feature/*> development"],
297
675
  suggestedBranches,
676
+ buildSlice,
677
+ verificationPlan,
678
+ repairPath,
679
+ completionEvidence,
298
680
  runtimeSummary,
299
681
  });
300
682
  await appendDecision({
301
683
  actor: authority.leaderActor,
302
684
  kind: "skill",
303
685
  skill: "$build",
304
- decision: "Build gate ready",
305
- status: "READY",
686
+ decision: "Completed the bounded build execution substep",
687
+ status: "DONE",
306
688
  evidence: [
307
689
  { kind: "runtime-summary", value: runtimeSummary },
308
690
  { kind: "branches", value: suggestedBranches },
691
+ { kind: "completion-evidence", value: completionEvidence },
692
+ { kind: "ralph-prd", value: ralphContract.prdPath },
309
693
  ],
310
694
  blockers: [],
311
- next_allowed_triggers: ["$build"],
695
+ next_allowed_triggers: ["ma merge <feature/*> development"],
696
+ });
697
+ await syncStatusUpdates({ build_status: "DONE" }, { actor: authority.leaderActor });
698
+ await updateMaestroLedgerForBuild({
699
+ buildStatus: "DONE",
700
+ runtimeSummary,
701
+ blockers: [],
702
+ nextTriggers: ["ma merge <feature/*> development"],
703
+ gateState: "COMPLETED",
704
+ trackStatus: "COMPLETED",
705
+ completionEvidence,
312
706
  });
313
- await syncStatusUpdates({ build_status: "READY" }, { actor: authority.leaderActor });
314
707
  return {
315
- status: "READY",
316
- nextTrigger: "$build",
708
+ status: "DONE",
709
+ nextTrigger: "ma merge <feature/*> development",
317
710
  blockers: [],
318
711
  suggestedBranches,
319
712
  };
@@ -396,10 +789,23 @@ function buildManagerDecisionBlockers(managerRun, runtimeSummary, buildReadiness
396
789
  }
397
790
 
398
791
  function executeManagerHelper(helper, { releaseState, runtimeSummary, recommendation }) {
792
+ const baseReceipt = ({ observedContext, result, nextTrigger }) => ({
793
+ helperId: helper.id,
794
+ ...createHelperReceipt({
795
+ skill: helper.skill,
796
+ objective: helper.objective,
797
+ observedContext,
798
+ result,
799
+ nextTrigger: nextTrigger ?? recommendation.nextTrigger ?? "$maestro",
800
+ }),
801
+ });
802
+
399
803
  if (helper.skill === "$align") {
400
804
  return {
401
- helperId: helper.id,
402
- kind: "alignment",
805
+ ...baseReceipt({
806
+ observedContext: `build_status=${releaseState.build_status}; next=${recommendation.nextTrigger}`,
807
+ result: "Normalized the manager handoff around the current lane sequence and next trigger.",
808
+ }),
403
809
  workflowSequence: maestroWorkflowSequence,
404
810
  currentBuildStatus: releaseState.build_status,
405
811
  recommendedNextTrigger: recommendation.nextTrigger,
@@ -408,8 +814,10 @@ function executeManagerHelper(helper, { releaseState, runtimeSummary, recommenda
408
814
 
409
815
  if (helper.skill === "$diagnose") {
410
816
  return {
411
- helperId: helper.id,
412
- kind: "diagnostic",
817
+ ...baseReceipt({
818
+ observedContext: `pending_mailbox=${runtimeSummary.pendingMailboxCount}; invalid_artifacts=${runtimeSummary.invalidArtifacts.length}; missing_artifacts=${runtimeSummary.missingArtifacts.length}`,
819
+ result: "Captured the smallest blocker slices before the manager resumes gated work.",
820
+ }),
413
821
  pendingMailboxCount: runtimeSummary.pendingMailboxCount,
414
822
  invalidArtifacts: runtimeSummary.invalidArtifacts,
415
823
  missingArtifacts: runtimeSummary.missingArtifacts,
@@ -418,8 +826,10 @@ function executeManagerHelper(helper, { releaseState, runtimeSummary, recommenda
418
826
 
419
827
  if (helper.skill === "$tdd") {
420
828
  return {
421
- helperId: helper.id,
422
- kind: "test-first",
829
+ ...baseReceipt({
830
+ observedContext: `build_status=${releaseState.build_status}; next=${recommendation.nextTrigger}`,
831
+ result: "Defined the regression-first boundary for the owning implementation lane.",
832
+ }),
423
833
  buildStatus: releaseState.build_status,
424
834
  nextTrigger: recommendation.nextTrigger,
425
835
  };
@@ -427,8 +837,10 @@ function executeManagerHelper(helper, { releaseState, runtimeSummary, recommenda
427
837
 
428
838
  if (helper.skill === "$cleanup") {
429
839
  return {
430
- helperId: helper.id,
431
- kind: "cleanup",
840
+ ...baseReceipt({
841
+ observedContext: `merge_status=${releaseState.merge_status}; release_status=${releaseState.release_status}`,
842
+ result: "Prepared contract-preserving simplification without changing release authority.",
843
+ }),
432
844
  mergeStatus: releaseState.merge_status,
433
845
  releaseStatus: releaseState.release_status,
434
846
  };
@@ -590,8 +1002,25 @@ export async function runArch() {
590
1002
  }
591
1003
 
592
1004
  const blueprint = {
1005
+ decision: "Approve the first bounded architecture direction.",
1006
+ status: "APPROVED",
593
1007
  summary: `Blueprint derived from idea: ${idea}. Runtime shell currently exposes ${runtimeSummary.workerCount} workers, ${runtimeSummary.workspaceCount} workspaces, and ${runtimeSummary.guidanceSourceCount} guidance sources.`,
594
1008
  suggestedStack: ["Node.js", "MCP", "GitMCP", "Git worktree", "File-backed runtime state"],
1009
+ workloadAssumptions: [
1010
+ "single-repo operator workflow",
1011
+ "gate-driven release discipline",
1012
+ "file-backed runtime state",
1013
+ ],
1014
+ rejectedAlternatives: [
1015
+ "Standalone second umbrella runtime surface because it would weaken Meta-Architect ownership.",
1016
+ ],
1017
+ evidence: [
1018
+ `Workers detected: ${runtimeSummary.workerCount}`,
1019
+ `Workspaces detected: ${runtimeSummary.workspaceCount}`,
1020
+ `Guidance sources detected: ${runtimeSummary.guidanceSourceCount}`,
1021
+ ],
1022
+ blockers: [],
1023
+ nextAllowedTriggers: ["`$sage`"],
595
1024
  outcome: "Produce a gated architecture and implementation plan backed by runtime state.",
596
1025
  };
597
1026
 
@@ -608,6 +1037,16 @@ export async function runArch() {
608
1037
  });
609
1038
 
610
1039
  await syncStatusUpdates({ architecture_status: "APPROVED" });
1040
+ await updateScratchpadTrackForLane({
1041
+ gate: "$arch",
1042
+ trackStatus: "COMPLETED",
1043
+ globalStatus: "COMPLETED",
1044
+ nextTriggers: ["$sage"],
1045
+ details: {
1046
+ decision: blueprint.decision,
1047
+ rejected_alternatives: blueprint.rejectedAlternatives,
1048
+ },
1049
+ });
611
1050
  }
612
1051
 
613
1052
  export async function runSage() {
@@ -615,17 +1054,48 @@ export async function runSage() {
615
1054
  const config = await validateMcpServers();
616
1055
  const runtimeSummary = await readRuntimeSummary();
617
1056
  assertControlPlaneReady(runtimeSummary);
1057
+ await seedRedactionVault();
1058
+ const disableLiveProbe = process.env.MA_DISABLE_LIVE_MCP === "1";
618
1059
  const sourceEntries = config.servers.map((server) => ({
619
1060
  repo: server.repo,
620
1061
  endpoint: server.endpoint,
621
1062
  category: server.category,
1063
+ exactUpstreamMapping: server.repo,
1064
+ evidenceGrade: disableLiveProbe ? "PARTIAL" : "MISSING",
622
1065
  }));
623
1066
  const blockers = [];
624
1067
  const idea = (await readIdeaText()) ?? "software architecture";
625
- const disableLiveProbe = process.env.MA_DISABLE_LIVE_MCP === "1";
626
- let liveSuccessCount = 0;
1068
+ let verificationSuccessCount = 0;
1069
+ let coreSourceIngest = null;
1070
+ try {
1071
+ coreSourceIngest = await loadCoreSourceIngest();
1072
+ } catch {
1073
+ coreSourceIngest = null;
1074
+ }
627
1075
 
628
1076
  for (const source of sourceEntries) {
1077
+ const ingestedSource = findIngestedCoreSourceForRepo(coreSourceIngest, source.repo);
1078
+ if (ingestedSource) {
1079
+ source.localSourceSnapshot = {
1080
+ status: ingestedSource.status,
1081
+ localPath: ingestedSource.local_path,
1082
+ capability: ingestedSource.capability,
1083
+ semanticRole: ingestedSource.semantic_role,
1084
+ fileCount: ingestedSource.file_count,
1085
+ contentSha256: ingestedSource.content_sha256,
1086
+ gitCommit: ingestedSource.git_commit,
1087
+ sampledFiles: ingestedSource.sampled_files,
1088
+ };
1089
+ source.liveProbe = {
1090
+ transport: "local-core-source-ingest",
1091
+ queryMode: "local-snapshot",
1092
+ sampleText: ingestedSource.sample_text?.slice(0, 400) ?? null,
1093
+ };
1094
+ source.evidenceGrade = "VERIFIED";
1095
+ verificationSuccessCount += 1;
1096
+ continue;
1097
+ }
1098
+
629
1099
  if (disableLiveProbe) {
630
1100
  source.liveProbe = {
631
1101
  skipped: true,
@@ -634,43 +1104,76 @@ export async function runSage() {
634
1104
  continue;
635
1105
  }
636
1106
 
637
- const client = new McpSseClient(source.endpoint);
1107
+ const client = createMcpLiveClient(source.endpoint);
638
1108
  try {
639
1109
  const init = await client.connect();
640
1110
  const tools = await client.request("tools/list", {});
641
- const searchTool = tools.tools?.find(
642
- (tool) => tool.name.includes("search_") && tool.name.endsWith("_documentation"),
643
- );
644
- const fetchTool = tools.tools?.find(
645
- (tool) => tool.name.includes("fetch_") && tool.name.endsWith("_documentation"),
646
- );
1111
+ const searchTool = tools.tools?.find((tool) => isGitMcpDocumentationTool(tool, "search"));
1112
+ const fetchTool = tools.tools?.find((tool) => isGitMcpDocumentationTool(tool, "fetch"));
647
1113
 
648
1114
  let evidence = null;
649
- if (searchTool) {
650
- evidence = await client.request("tools/call", {
651
- name: searchTool.name,
652
- arguments: { query: idea },
653
- });
654
- } else if (fetchTool) {
655
- evidence = await client.request("tools/call", {
656
- name: fetchTool.name,
657
- arguments: {},
1115
+ let queryMode = "list-only";
1116
+ const callFailures = [];
1117
+ if (fetchTool) {
1118
+ try {
1119
+ evidence = await client.request("tools/call", {
1120
+ name: fetchTool.name,
1121
+ arguments: {},
1122
+ });
1123
+ queryMode = "fetch";
1124
+ } catch (error) {
1125
+ callFailures.push({
1126
+ tool: fetchTool.name,
1127
+ error: error.message,
1128
+ });
1129
+ }
1130
+ }
1131
+ if (!evidence && searchTool) {
1132
+ const redactedQuery = await redactProviderBoundText(idea, {
1133
+ kind: "sage-live-query",
1134
+ repo: source.repo,
658
1135
  });
1136
+ try {
1137
+ evidence = await client.request("tools/call", {
1138
+ name: searchTool.name,
1139
+ arguments: { query: redactedQuery.sanitizedText },
1140
+ });
1141
+ queryMode = "search";
1142
+ } catch (error) {
1143
+ callFailures.push({
1144
+ tool: searchTool.name,
1145
+ error: error.message,
1146
+ });
1147
+ }
1148
+ }
1149
+ if ((fetchTool || searchTool) && !evidence) {
1150
+ throw new Error(
1151
+ `No GitMCP documentation call succeeded: ${callFailures
1152
+ .map((failure) => `${failure.tool}: ${failure.error}`)
1153
+ .join("; ")}`,
1154
+ );
659
1155
  }
660
1156
 
661
1157
  source.liveProbe = {
1158
+ transport: hasConfiguredMcpRemoteBridge() ? "stdio-bridge" : "direct-sse",
662
1159
  serverName: init.serverInfo?.name ?? "unknown",
663
1160
  serverVersion: init.serverInfo?.version ?? "unknown",
664
1161
  toolsCount: tools.tools?.length ?? 0,
665
- queryMode: searchTool ? "search" : fetchTool ? "fetch" : "list-only",
1162
+ queryMode,
1163
+ callFailures,
666
1164
  sampleText:
667
1165
  evidence?.content?.find((item) => item.type === "text")?.text?.slice(0, 400) ?? null,
668
1166
  };
669
- liveSuccessCount += 1;
1167
+ source.evidenceGrade = "VERIFIED";
1168
+ source.exactUpstreamMapping = source.repo;
1169
+ verificationSuccessCount += 1;
670
1170
  } catch (error) {
671
1171
  source.liveProbe = {
1172
+ transport: hasConfiguredMcpRemoteBridge() ? "stdio-bridge" : "direct-sse",
672
1173
  error: error.message,
673
1174
  };
1175
+ source.evidenceGrade = "PARTIAL";
1176
+ source.exactUpstreamMapping = source.repo;
674
1177
  blockers.push(`Live MCP query failed for ${source.repo}: ${error.message}`);
675
1178
  } finally {
676
1179
  await client.close().catch(() => {});
@@ -681,8 +1184,7 @@ export async function runSage() {
681
1184
  existing.items = sourceEntries;
682
1185
  await writeJson(getRuntimeWritePath("evidence", "sources.json"), existing);
683
1186
 
684
- const verified =
685
- sourceEntries.length > 0 && !disableLiveProbe && liveSuccessCount === sourceEntries.length;
1187
+ const verified = sourceEntries.length > 0 && verificationSuccessCount === sourceEntries.length;
686
1188
  if (sourceEntries.length > 0 && !verified && blockers.length === 0) {
687
1189
  blockers.push(
688
1190
  disableLiveProbe
@@ -694,7 +1196,8 @@ export async function runSage() {
694
1196
  await appendDecision({
695
1197
  kind: "skill",
696
1198
  skill: "$sage",
697
- decision: "Bound architectural choices to approved GitMCP sources using live MCP queries",
1199
+ decision:
1200
+ "Bound architectural choices to approved sources using local core-source snapshots first, with GitMCP only as refresh/provenance fallback",
698
1201
  status: verified ? "VERIFIED" : sourceEntries.length > 0 ? "PARTIAL" : "MISSING",
699
1202
  evidence: sourceEntries,
700
1203
  blockers: sourceEntries.length > 0 ? blockers : ["No approved GitMCP sources configured"],
@@ -704,6 +1207,17 @@ export async function runSage() {
704
1207
  await syncStatusUpdates({
705
1208
  evidence_status: verified ? "VERIFIED" : sourceEntries.length > 0 ? "PARTIAL" : "MISSING",
706
1209
  });
1210
+ await updateScratchpadTrackForLane({
1211
+ gate: "$sage",
1212
+ trackStatus: verified ? "COMPLETED" : "BLOCKED",
1213
+ globalStatus: verified ? "COMPLETED" : "LOCKED",
1214
+ blockers: sourceEntries.length > 0 ? blockers : ["No approved GitMCP sources configured"],
1215
+ nextTriggers: verified ? ["$flow"] : ["$sage"],
1216
+ details: {
1217
+ evidence_grade: verified ? "VERIFIED" : sourceEntries.length > 0 ? "PARTIAL" : "MISSING",
1218
+ exact_upstream_mapping: sourceEntries.map((source) => source.repo),
1219
+ },
1220
+ });
707
1221
  }
708
1222
 
709
1223
  export async function runFlow() {
@@ -729,12 +1243,32 @@ export async function runFlow() {
729
1243
  if (runtimeSummary.workerCount > 0 && runtimeSummary.workspaceCount === 0) {
730
1244
  blockers.push("Workers exist without registered workspaces.");
731
1245
  }
1246
+ const actors = ["leader", "worker", "guidance_stack", "hook_dispatcher", "workspace_manager"];
732
1247
  const logicMap = {
733
- actors: ["leader", "worker", "guidance_stack", "hook_dispatcher", "workspace_manager"],
1248
+ actors,
1249
+ decision:
1250
+ blockers.length === 0
1251
+ ? "Approve the current behavioral model for downstream review."
1252
+ : "Behavioral model remains blocked until the identified logic/runtime issues are resolved.",
1253
+ status: blockers.length === 0 ? "GREEN" : "RED",
734
1254
  states: ["idea", "architecture", "evidence", "logic", "security", "experience", "build"],
1255
+ stateMap: [
1256
+ "idea -> architecture -> evidence -> logic -> security -> experience -> build",
1257
+ "logic review must stop if runtime artifacts are invalid or worker/workspace integrity breaks",
1258
+ ],
1259
+ failureFlows:
1260
+ blockers.length > 0
1261
+ ? blockers
1262
+ : ["No blocking failure flow detected in the current runtime snapshot."],
1263
+ evidence: [
1264
+ `actors observed: ${actors.length}`,
1265
+ `pending mailbox proposals: ${runtimeSummary.pendingMailboxCount}`,
1266
+ `registered workspaces: ${runtimeSummary.workspaceCount}`,
1267
+ ],
735
1268
  runtimeSummary,
736
1269
  blockers,
737
1270
  nextTrigger: blockers.length === 0 ? "`$vet`" : "`$flow`",
1271
+ nextAllowedTriggers: blockers.length === 0 ? ["`$vet`"] : ["`$flow`"],
738
1272
  };
739
1273
  const status = blockers.length === 0 ? "GREEN" : "RED";
740
1274
  const nextAllowedTriggers = blockers.length === 0 ? ["$vet"] : ["$flow"];
@@ -752,6 +1286,18 @@ export async function runFlow() {
752
1286
  });
753
1287
 
754
1288
  await syncStatusUpdates({ logic_status: status });
1289
+ await updateScratchpadTrackForLane({
1290
+ gate: "$flow",
1291
+ trackStatus: status === "GREEN" ? "COMPLETED" : "BLOCKED",
1292
+ globalStatus: status === "GREEN" ? "COMPLETED" : "LOCKED",
1293
+ blockers,
1294
+ nextTriggers: nextAllowedTriggers,
1295
+ details: {
1296
+ failure_flows: logicMap.failureFlows,
1297
+ state_map: logicMap.stateMap,
1298
+ hardening_mode: runtimeSummary.pendingMailboxCount > 0 ? "STRICT" : "STANDARD",
1299
+ },
1300
+ });
755
1301
  }
756
1302
 
757
1303
  export async function runVet() {
@@ -760,36 +1306,103 @@ export async function runVet() {
760
1306
  assertControlPlaneReady(runtimeSummary);
761
1307
  const auditLog = await readJson(getRuntimeWritePath("evidence", "audits.json"));
762
1308
  const cveLog = await readJson(getRuntimeWritePath("evidence", "cves.json"));
1309
+ const packageExposureFindings = await scanLockfilePackageExposure();
1310
+ const policyFindings = await validateMcpPolicyExposure();
1311
+ const criticalPackageExposure = packageExposureFindings.filter(
1312
+ (finding) => finding.severity === "critical",
1313
+ );
1314
+ const blockingPolicyFindings = policyFindings.filter((finding) =>
1315
+ ["critical", "high"].includes(`${finding.severity}`.toLowerCase()),
1316
+ );
763
1317
  const reviewApproved =
764
1318
  auditLog.items.some((item) => item.source === "review" || item.approved === true) ||
765
1319
  cveLog.items.some((item) => item.source === "review" || item.approved === true);
766
- const finding = {
767
- severity: "INFO",
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,
771
- };
772
- auditLog.items.push(finding);
1320
+ const scanApproved = criticalPackageExposure.length === 0 && blockingPolicyFindings.length === 0;
1321
+ const finding =
1322
+ criticalPackageExposure.length > 0
1323
+ ? {
1324
+ severity: criticalPackageExposure[0].severity.toUpperCase(),
1325
+ source: "package-exposure-scan",
1326
+ summary: criticalPackageExposure
1327
+ .map(
1328
+ (item) =>
1329
+ `${item.package_name}@${item.package_version}: ${item.diagnostic} (${item.advisory_reference})`,
1330
+ )
1331
+ .join(" "),
1332
+ unresolved: true,
1333
+ trustBoundaries: [
1334
+ "lockfile metadata vs provider-bound or build-unlocking execution",
1335
+ "repo-owned MCP config vs runtime-local scratchpad state",
1336
+ "published docs vs private `.ma` execution state",
1337
+ ],
1338
+ acceptedRisks: ["No accepted risk: blocking package exposure must be remediated."],
1339
+ }
1340
+ : {
1341
+ severity: policyFindings.length > 0 ? "WARNING" : "INFO",
1342
+ source: policyFindings.length > 0 ? "mcp-policy-validation" : "runtime-review",
1343
+ summary:
1344
+ policyFindings.length > 0
1345
+ ? policyFindings.map((item) => item.diagnostic).join(" ")
1346
+ : `No blocking package exposure was detected in the current bounded scan. Review still remains required after checking ${runtimeSummary.compatibilityHookCount} compatibility hooks and ${runtimeSummary.runtimeHookCount} runtime events.`,
1347
+ unresolved: !reviewApproved && !scanApproved,
1348
+ trustBoundaries: [
1349
+ "leader vs worker mutation authority",
1350
+ "repo-owned MCP config vs runtime-local scratchpad state",
1351
+ "published docs vs private `.ma` execution state",
1352
+ ],
1353
+ acceptedRisks: scanApproved
1354
+ ? ["No material unresolved risk remains for the current bounded step."]
1355
+ : [
1356
+ "Security evidence still requires explicit approval or remediation before promotion.",
1357
+ ],
1358
+ };
1359
+ auditLog.items.push(finding, ...packageExposureFindings, ...policyFindings);
773
1360
  await writeJson(getRuntimeWritePath("evidence", "audits.json"), auditLog);
774
- cveLog.items.push({
775
- id: "baseline-review",
776
- source: "placeholder",
777
- severity: "INFO",
778
- unresolved: true,
779
- });
1361
+ cveLog.items.push(
1362
+ ...packageExposureFindings.map((item) => ({
1363
+ id: item.advisory_reference ?? `${item.package_name}-${item.package_version}`,
1364
+ source: "package-exposure-scan",
1365
+ severity: item.severity.toUpperCase(),
1366
+ unresolved: true,
1367
+ package_name: item.package_name,
1368
+ package_version: item.package_version,
1369
+ })),
1370
+ {
1371
+ id: "baseline-review",
1372
+ source: packageExposureFindings.length > 0 ? "package-exposure-scan" : "runtime-review",
1373
+ severity: packageExposureFindings.length > 0 ? "CRITICAL" : "INFO",
1374
+ unresolved: !reviewApproved && !scanApproved,
1375
+ },
1376
+ );
780
1377
  await writeJson(getRuntimeWritePath("evidence", "cves.json"), cveLog);
1378
+ for (const exposureFinding of packageExposureFindings) {
1379
+ await appendMaestroEvent(exposureFinding);
1380
+ }
1381
+ for (const policyFinding of policyFindings) {
1382
+ await appendMaestroEvent(policyFinding);
1383
+ }
781
1384
  await writeSecuritySpec({
782
1385
  finding,
783
1386
  auditCount: auditLog.items.length,
784
1387
  cveCount: cveLog.items.length,
785
1388
  runtimeSummary,
786
- nextTrigger: reviewApproved ? "`$vibe`" : "`$vet`",
1389
+ nextTrigger: scanApproved ? "`$vibe`" : "`$vet`",
787
1390
  });
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"];
1391
+ const status = scanApproved ? "GREEN" : criticalPackageExposure.length > 0 ? "RED" : "PENDING";
1392
+ const blockers =
1393
+ criticalPackageExposure.length > 0
1394
+ ? criticalPackageExposure.map(
1395
+ (item) =>
1396
+ `${item.package_name}@${item.package_version}: ${item.diagnostic} (${item.advisory_reference})`,
1397
+ )
1398
+ : reviewApproved
1399
+ ? []
1400
+ : blockingPolicyFindings.map((finding) => finding.diagnostic);
1401
+ const nextAllowedTriggers = scanApproved
1402
+ ? ["$vibe"]
1403
+ : criticalPackageExposure.length > 0
1404
+ ? ["$vet"]
1405
+ : ["$vet"];
793
1406
 
794
1407
  await appendDecision({
795
1408
  kind: "skill",
@@ -802,6 +1415,25 @@ export async function runVet() {
802
1415
  });
803
1416
 
804
1417
  await syncStatusUpdates({ security_status: status });
1418
+ await updateScratchpadTrackForLane({
1419
+ gate: "$vet",
1420
+ trackStatus: status === "GREEN" ? "COMPLETED" : "BLOCKED",
1421
+ globalStatus:
1422
+ status === "GREEN" ? "COMPLETED" : status === "RED" ? "LOCKED" : "DEGRADED_HEALING",
1423
+ blockers,
1424
+ nextTriggers: nextAllowedTriggers,
1425
+ details: {
1426
+ trust_boundaries: finding.trustBoundaries,
1427
+ accepted_risks: finding.acceptedRisks,
1428
+ healing_ledger: reviewApproved
1429
+ ? null
1430
+ : {
1431
+ current_attempt: 0,
1432
+ strategy_assigned: "BOUNDED_DIAGNOSTIC_REVIEW",
1433
+ status: "PENDING_OPERATOR_APPROVAL",
1434
+ },
1435
+ },
1436
+ });
805
1437
  }
806
1438
 
807
1439
  export async function runVibe() {
@@ -812,23 +1444,34 @@ export async function runVibe() {
812
1444
  const reviewApproved = outcomes.items.some(
813
1445
  (item) => item.source === "review" || item.approved === true,
814
1446
  );
1447
+ const runtimeApproved = runtimeSummary.pendingMailboxCount === 0;
815
1448
  const note = {
816
1449
  area: "developer-experience",
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.`,
1450
+ source: "runtime-vibe-review",
1451
+ summary: `Runtime DX/UX review recorded from current coordination state: ${runtimeSummary.taskCount} tasks, ${runtimeSummary.workspaceCount} workspaces, and ${runtimeSummary.pendingMailboxCount} pending mailbox proposals.`,
1452
+ operatorFriction: [
1453
+ runtimeSummary.pendingMailboxCount > 0
1454
+ ? "Pending mailbox proposals increase operator coordination overhead."
1455
+ : "Operator flow is bounded and clear in the current runtime state.",
1456
+ ],
1457
+ userFriction: [
1458
+ "The gated sequence is explicit, but users still need clearer build-loop feedback once execution starts.",
1459
+ ],
1460
+ approved: reviewApproved || runtimeApproved,
819
1461
  };
820
1462
  outcomes.items.push(note);
821
1463
  await writeJson(getRuntimeWritePath("evidence", "outcomes.json"), outcomes);
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"];
1464
+ const status = reviewApproved || runtimeApproved ? "GREEN" : "PENDING";
1465
+ const blockers =
1466
+ status === "GREEN"
1467
+ ? []
1468
+ : ["Pending mailbox proposals must be resolved before DX/UX can be marked GREEN."];
1469
+ const nextAllowedTriggers = status === "GREEN" ? ["$build"] : ["$vibe"];
827
1470
  await writeExperienceSpec({
828
1471
  note,
829
1472
  outcomeCount: outcomes.items.length,
830
1473
  runtimeSummary,
831
- nextTrigger: reviewApproved ? "`$build`" : "`$vibe`",
1474
+ nextTrigger: status === "GREEN" ? "`$build`" : "`$vibe`",
832
1475
  });
833
1476
 
834
1477
  await appendDecision({
@@ -842,9 +1485,20 @@ export async function runVibe() {
842
1485
  });
843
1486
 
844
1487
  await syncStatusUpdates({ experience_status: status });
1488
+ await updateScratchpadTrackForLane({
1489
+ gate: "$vibe",
1490
+ trackStatus: status === "GREEN" ? "COMPLETED" : "BLOCKED",
1491
+ globalStatus: status === "GREEN" ? "COMPLETED" : "LOCKED",
1492
+ blockers,
1493
+ nextTriggers: nextAllowedTriggers,
1494
+ details: {
1495
+ operator_friction: note.operatorFriction,
1496
+ user_friction: note.userFriction,
1497
+ },
1498
+ });
845
1499
  }
846
1500
 
847
- export async function runMaestro() {
1501
+ export async function runMaestro({ autoHeal = false, parallel = false } = {}) {
848
1502
  await assertLeaderAuthority();
849
1503
  let runtimeSnapshot = await loadRuntimeSnapshot();
850
1504
  let releaseState = runtimeSnapshot.release;
@@ -854,6 +1508,133 @@ export async function runMaestro() {
854
1508
  let buildReadiness = evaluateRuntimeBuildReadiness(releaseState, runtimeSummary);
855
1509
  let recommendation = chooseMaestroRecommendation(releaseState, idea, buildReadiness);
856
1510
  const helperFailureMatrix = buildHelperFailureMatrix();
1511
+ const alignmentReport = {
1512
+ ...evaluateAlignmentDrift({
1513
+ releaseState,
1514
+ decisionLog: runtimeSnapshot.decisions,
1515
+ }),
1516
+ lastRunAt: new Date().toISOString(),
1517
+ baselineArtifacts: [
1518
+ ".ma/release.json",
1519
+ ".ma/decisions.json",
1520
+ ".ma/state/manager-runs.json",
1521
+ ".ma/state/maestro-state.json",
1522
+ ],
1523
+ };
1524
+ await saveAlignmentSentinelReport(alignmentReport);
1525
+ if (alignmentReport.driftStatus === "DRIFTED") {
1526
+ await updateScratchpadTrackForLane({
1527
+ gate: "$maestro",
1528
+ trackStatus: "BLOCKED",
1529
+ globalStatus: "LOCKED",
1530
+ blockers: alignmentReport.findings.map(
1531
+ (finding) =>
1532
+ `${finding.skill} expects ${finding.releaseField} to remain in ${finding.expectedReleaseValues.join(" or ")}, but the current value is ${finding.actualReleaseValue}.`,
1533
+ ),
1534
+ nextTriggers: ["$maestro"],
1535
+ details: {
1536
+ drift_status: alignmentReport.driftStatus,
1537
+ reboot_planned: alignmentReport.rebootPlanned,
1538
+ resume_trigger: alignmentReport.resumeTrigger,
1539
+ },
1540
+ });
1541
+ await appendMaestroEvent({
1542
+ record_type: "alignment:drift_detected",
1543
+ gate: "$maestro",
1544
+ findings: alignmentReport.findings,
1545
+ reboot_planned: alignmentReport.rebootPlanned,
1546
+ resume_trigger: alignmentReport.resumeTrigger,
1547
+ });
1548
+ const driftRecommendation = {
1549
+ nextStep: "Resolve alignment drift before manager dispatch continues.",
1550
+ why: alignmentReport.rebootReason,
1551
+ primaryLane: "$maestro",
1552
+ supportLane: "none",
1553
+ assignments: [
1554
+ "Review the persisted alignment report and conflicting lane-owned decisions.",
1555
+ "Rehydrate the next manager run from baseline `.ma/` artifacts after the conflicting state is repaired.",
1556
+ ],
1557
+ avoid: [
1558
+ "Do not continue autonomous dispatch while release state contradicts approved lane decisions.",
1559
+ ],
1560
+ nextTrigger: "`$maestro`",
1561
+ };
1562
+ await writeMaestroPlan({
1563
+ releaseState,
1564
+ recommendation: driftRecommendation,
1565
+ runtimeSummary,
1566
+ workflowSequence: maestroWorkflowSequence,
1567
+ managerRun: null,
1568
+ });
1569
+ await appendDecision({
1570
+ kind: "skill",
1571
+ skill: "$maestro",
1572
+ decision:
1573
+ "Alignment Sentinel blocked manager execution and requested a fresh worker rehydration path.",
1574
+ status: "BLOCKED",
1575
+ evidence: [alignmentReport],
1576
+ blockers: alignmentReport.findings.map(
1577
+ (finding) =>
1578
+ `${finding.skill} approved ${finding.expectedDecisionStatus}, but ${finding.releaseField} regressed to ${finding.actualReleaseValue}.`,
1579
+ ),
1580
+ next_allowed_triggers: ["$maestro"],
1581
+ });
1582
+ return;
1583
+ }
1584
+ if (
1585
+ autoHeal &&
1586
+ buildReadiness.releaseBlockers.length === 0 &&
1587
+ buildReadiness.nextTriggers.includes("repair runtime artifacts")
1588
+ ) {
1589
+ const repairedArtifacts = await repairRuntimeScratchpadArtifacts([
1590
+ ...runtimeSummary.invalidArtifacts,
1591
+ ...runtimeSummary.missingArtifacts,
1592
+ ]);
1593
+ if (repairedArtifacts.length > 0) {
1594
+ const detached = await launchDetachedTrack({
1595
+ trackId: "heal-sync",
1596
+ title: "Meta-Architect bounded diagnostic sidecar",
1597
+ command: "/bin/sh",
1598
+ args: [
1599
+ "-lc",
1600
+ `printf '%s\n' "Repaired scratchpad artifacts: ${repairedArtifacts.join(", ")}"`,
1601
+ ],
1602
+ });
1603
+ let maestroState = await loadMaestroStateOrDefault();
1604
+ maestroState = beginMaestroOrchestration(maestroState, {
1605
+ globalStatus: "DEGRADED_HEALING",
1606
+ configuration: {
1607
+ auto_heal: true,
1608
+ concurrency_limit: parallel ? 4 : 1,
1609
+ },
1610
+ });
1611
+ maestroState.runtime_tracks.track_heal_sync = {
1612
+ active_gate: "$maestro",
1613
+ status: "COMPLETED",
1614
+ pid: null,
1615
+ execution_pane: detached.executionPane,
1616
+ provider: detached.provider,
1617
+ log_path: detached.logPath,
1618
+ exit_code: 0,
1619
+ repaired_artifacts: repairedArtifacts,
1620
+ updated_at: new Date().toISOString(),
1621
+ };
1622
+ await saveMaestroState(maestroState);
1623
+ await appendMaestroEvent({
1624
+ record_type: "healing:attempt",
1625
+ gate: "$maestro",
1626
+ global_status: "DEGRADED_HEALING",
1627
+ track_status: "COMPLETED",
1628
+ repaired_artifacts: repairedArtifacts,
1629
+ repaired_count: repairedArtifacts.length,
1630
+ });
1631
+ runtimeSnapshot = await loadRuntimeSnapshot();
1632
+ releaseState = runtimeSnapshot.release;
1633
+ runtimeSummary = createRuntimeSummary(runtimeSnapshot);
1634
+ buildReadiness = evaluateRuntimeBuildReadiness(releaseState, runtimeSummary);
1635
+ recommendation = chooseMaestroRecommendation(releaseState, idea, buildReadiness);
1636
+ }
1637
+ }
857
1638
  const registry = await loadManagerRunRegistry();
858
1639
  const activeRun = getActiveManagerRun(registry);
859
1640
  const managerAction = chooseMaestroManagerAction({
@@ -927,9 +1708,28 @@ export async function runMaestro() {
927
1708
  continue;
928
1709
  }
929
1710
 
1711
+ const detached =
1712
+ parallel && ["$flow", "$vet", "$vibe", "$build"].includes(gate.skill)
1713
+ ? await launchDetachedTrack({
1714
+ trackId: `${managerRun.id}-${gate.skill.replaceAll("$", "")}`,
1715
+ title: `Meta-Architect detached track ${gate.skill}`,
1716
+ command: "/bin/sh",
1717
+ args: ["-lc", `printf '%s\n' "Detached scratchpad track for ${gate.skill}"`],
1718
+ })
1719
+ : null;
930
1720
  gate.status = "running";
931
1721
  updateManagerRunTimestamps(managerRun, { state: "running" });
932
1722
  await saveManagerRunRegistry(registry);
1723
+ await updateScratchpadTrackForLane({
1724
+ gate: gate.skill,
1725
+ trackStatus: "RUNNING",
1726
+ globalStatus: "RUNNING",
1727
+ nextTriggers: [gate.skill],
1728
+ detached,
1729
+ details: {
1730
+ objective: gate.objective,
1731
+ },
1732
+ });
933
1733
  await runner();
934
1734
  gate.status = "completed";
935
1735
  await saveManagerRunRegistry(registry);
@@ -964,18 +1764,6 @@ export async function runMaestro() {
964
1764
  await saveManagerRunRegistry(registry);
965
1765
  }
966
1766
 
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
1767
  await writeMaestroPlan({
980
1768
  releaseState,
981
1769
  recommendation,
@@ -1083,8 +1871,12 @@ export async function runInit() {
1083
1871
  path.join(getRepoRoot(), "docs", "release-spec.md"),
1084
1872
  ],
1085
1873
  [
1086
- path.join(packageRoot, "docs", "qa", "release-readiness-0.1.12.md"),
1087
- path.join(getRepoRoot(), "docs", "qa", "release-readiness-0.1.12.md"),
1874
+ path.join(packageRoot, "docs", "qa", "release-readiness-0.1.13.md"),
1875
+ path.join(getRepoRoot(), "docs", "qa", "release-readiness-0.1.13.md"),
1876
+ ],
1877
+ [
1878
+ path.join(packageRoot, "docs", "qa", "release-issue-gates-0.1.13.json"),
1879
+ path.join(getRepoRoot(), "docs", "qa", "release-issue-gates-0.1.13.json"),
1088
1880
  ],
1089
1881
  ];
1090
1882