@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
@@ -0,0 +1,276 @@
1
+ import path from "node:path";
2
+ import { readJson } from "../fs-utils.js";
3
+ import { getMcpLocalCapabilitiesPath, getMcpServersPath, getRepoRoot } from "../paths.js";
4
+ import { validateRuntimeMcpPolicyFile } from "./mcp-policy.js";
5
+
6
+ const advisoryCatalog = [
7
+ {
8
+ ecosystem: "npm",
9
+ packageName: "tar",
10
+ vulnerableBelow: "6.2.1",
11
+ severity: "critical",
12
+ confidence: "high",
13
+ diagnostic: "tar < 6.2.1 allows arbitrary file overwrite.",
14
+ recommendedAction: "Upgrade tar to 6.2.1 or newer in the lockfile and reverify.",
15
+ advisoryReference: "advisory-2026-0042",
16
+ },
17
+ ];
18
+
19
+ function normalizePackageNameFromLockPath(lockPath) {
20
+ const marker = "node_modules/";
21
+ const markerIndex = lockPath.lastIndexOf(marker);
22
+ if (markerIndex === -1) {
23
+ return null;
24
+ }
25
+
26
+ return lockPath.slice(markerIndex + marker.length);
27
+ }
28
+
29
+ function compareSemver(a, b) {
30
+ const parse = (value) =>
31
+ `${value}`.split(".").map((part) => Number.parseInt(part.replace(/[^0-9].*$/, ""), 10) || 0);
32
+ const left = parse(a);
33
+ const right = parse(b);
34
+ const maxLength = Math.max(left.length, right.length);
35
+
36
+ for (let index = 0; index < maxLength; index += 1) {
37
+ const leftValue = left[index] ?? 0;
38
+ const rightValue = right[index] ?? 0;
39
+ if (leftValue > rightValue) {
40
+ return 1;
41
+ }
42
+ if (leftValue < rightValue) {
43
+ return -1;
44
+ }
45
+ }
46
+
47
+ return 0;
48
+ }
49
+
50
+ function normalizeManifestVersion(value) {
51
+ const match = `${value}`.match(/\d+(?:\.\d+){0,2}/);
52
+ return match ? match[0] : null;
53
+ }
54
+
55
+ export async function scanLockfilePackageExposure() {
56
+ const lockfilePath = path.join(getRepoRoot(), "package-lock.json");
57
+ let lockfile;
58
+ try {
59
+ lockfile = await readJson(lockfilePath);
60
+ } catch (error) {
61
+ if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
62
+ return [];
63
+ }
64
+
65
+ throw error;
66
+ }
67
+
68
+ return scanPackageExposureFromLockfile(lockfile, {
69
+ sourcePath: lockfilePath,
70
+ catalog: advisoryCatalog,
71
+ });
72
+ }
73
+
74
+ export function scanPackageExposureFromLockfile(
75
+ lockfile,
76
+ { sourcePath = "package-lock.json", catalog = advisoryCatalog } = {},
77
+ ) {
78
+ const packages = lockfile?.packages ?? {};
79
+ const findings = [];
80
+
81
+ for (const [lockPath, entry] of Object.entries(packages)) {
82
+ if (!lockPath || lockPath === "" || !entry?.version) {
83
+ continue;
84
+ }
85
+
86
+ const packageName = normalizePackageNameFromLockPath(lockPath);
87
+ if (!packageName) {
88
+ continue;
89
+ }
90
+
91
+ for (const advisory of catalog) {
92
+ if (packageName !== advisory.packageName) {
93
+ continue;
94
+ }
95
+
96
+ if (compareSemver(entry.version, advisory.vulnerableBelow) >= 0) {
97
+ continue;
98
+ }
99
+
100
+ findings.push({
101
+ record_type: "finding:package_exposure",
102
+ severity: advisory.severity,
103
+ confidence: advisory.confidence,
104
+ ecosystem: advisory.ecosystem,
105
+ package_name: packageName,
106
+ package_version: entry.version,
107
+ source_path: sourcePath,
108
+ evidence_kind: "lockfile-version-match",
109
+ diagnostic: advisory.diagnostic,
110
+ recommended_action: advisory.recommendedAction,
111
+ advisory_reference: advisory.advisoryReference,
112
+ });
113
+ }
114
+ }
115
+
116
+ return findings;
117
+ }
118
+
119
+ export function scanPackageExposureFromManifest(
120
+ manifest,
121
+ { sourcePath = "package.json", catalog = advisoryCatalog } = {},
122
+ ) {
123
+ const dependencyGroups = [
124
+ "dependencies",
125
+ "devDependencies",
126
+ "optionalDependencies",
127
+ "peerDependencies",
128
+ ];
129
+ const findings = [];
130
+
131
+ for (const group of dependencyGroups) {
132
+ for (const [packageName, versionRange] of Object.entries(manifest?.[group] ?? {})) {
133
+ const normalizedVersion = normalizeManifestVersion(versionRange);
134
+ if (!normalizedVersion) {
135
+ continue;
136
+ }
137
+
138
+ for (const advisory of catalog) {
139
+ if (packageName !== advisory.packageName) {
140
+ continue;
141
+ }
142
+ if (compareSemver(normalizedVersion, advisory.vulnerableBelow) >= 0) {
143
+ continue;
144
+ }
145
+
146
+ findings.push({
147
+ record_type: "finding:package_exposure",
148
+ severity: advisory.severity,
149
+ confidence: "medium",
150
+ ecosystem: advisory.ecosystem,
151
+ package_name: packageName,
152
+ package_version: versionRange,
153
+ normalized_version: normalizedVersion,
154
+ source_path: sourcePath,
155
+ evidence_kind: "manifest-version-range-match",
156
+ dependency_group: group,
157
+ diagnostic: advisory.diagnostic,
158
+ recommended_action: advisory.recommendedAction,
159
+ advisory_reference: advisory.advisoryReference,
160
+ });
161
+ }
162
+ }
163
+ }
164
+
165
+ return findings;
166
+ }
167
+
168
+ export async function validateMcpPolicyExposure({ activeProfile = "project" } = {}) {
169
+ const findings = [];
170
+
171
+ try {
172
+ const localCapabilities = await readJson(getMcpLocalCapabilitiesPath());
173
+ for (const capability of localCapabilities.capabilities ?? []) {
174
+ if (
175
+ typeof capability.module === "string" &&
176
+ !capability.module.startsWith("./local/") &&
177
+ capability.kind === "local-capability"
178
+ ) {
179
+ findings.push({
180
+ record_type: "policy:mcp_validation",
181
+ severity: "warning",
182
+ confidence: "high",
183
+ diagnostic: `Local capability module '${capability.module}' escapes the expected ./local/ namespace.`,
184
+ source_path: getMcpLocalCapabilitiesPath(),
185
+ recommended_action:
186
+ "Keep packaged local capability modules inside the ./local/ namespace or document the exception explicitly.",
187
+ });
188
+ }
189
+ }
190
+ } catch (error) {
191
+ if (!(error && typeof error === "object" && "code" in error && error.code === "ENOENT")) {
192
+ throw error;
193
+ }
194
+ }
195
+
196
+ try {
197
+ const servers = await readJson(getMcpServersPath());
198
+ for (const server of servers.servers ?? []) {
199
+ if (typeof server.endpoint === "string" && server.endpoint === "https://gitmcp.io/docs") {
200
+ findings.push({
201
+ record_type: "policy:mcp_validation",
202
+ severity: "warning",
203
+ confidence: "high",
204
+ diagnostic: "Fallback docs endpoint is configured as an approved evidence source.",
205
+ source_path: getMcpServersPath(),
206
+ recommended_action:
207
+ "Use exact repo-form GitMCP endpoints in mcp/servers.json instead of the docs fallback endpoint.",
208
+ });
209
+ }
210
+ }
211
+ } catch (error) {
212
+ if (!(error && typeof error === "object" && "code" in error && error.code === "ENOENT")) {
213
+ throw error;
214
+ }
215
+ }
216
+
217
+ findings.push(...(await validateRuntimeMcpPolicyFile({ activeProfile })));
218
+
219
+ return findings;
220
+ }
221
+
222
+ export async function scanExposureProfile(profile = "baseline") {
223
+ const allowedProfiles = new Set(["baseline", "project", "deep"]);
224
+ if (!allowedProfiles.has(profile)) {
225
+ throw new Error(`Unsupported exposure scan profile: ${profile}`);
226
+ }
227
+
228
+ const lockfileFindings = await scanLockfilePackageExposure();
229
+ let manifestFindings = [];
230
+ if (profile !== "baseline") {
231
+ try {
232
+ const manifestPath = path.join(getRepoRoot(), "package.json");
233
+ manifestFindings = scanPackageExposureFromManifest(await readJson(manifestPath), {
234
+ sourcePath: manifestPath,
235
+ catalog: advisoryCatalog,
236
+ });
237
+ } catch (error) {
238
+ if (!(error && typeof error === "object" && "code" in error && error.code === "ENOENT")) {
239
+ throw error;
240
+ }
241
+ }
242
+ }
243
+ const policyFindings =
244
+ profile === "baseline" ? [] : await validateMcpPolicyExposure({ activeProfile: profile });
245
+ const findings = [...lockfileFindings, ...manifestFindings, ...policyFindings];
246
+
247
+ return {
248
+ record_type: "exposure_profile_report",
249
+ profile,
250
+ read_only: true,
251
+ mutates_release_state: false,
252
+ findings,
253
+ blocker_count: findings.filter((finding) =>
254
+ ["critical", "high"].includes(`${finding.severity}`.toLowerCase()),
255
+ ).length,
256
+ scanned_surfaces:
257
+ profile === "baseline"
258
+ ? ["package-lock.json"]
259
+ : profile === "project"
260
+ ? [
261
+ "package-lock.json",
262
+ "package.json",
263
+ "mcp/local-capabilities.json",
264
+ "mcp/servers.json",
265
+ ".ma/.mcp.json",
266
+ ]
267
+ : [
268
+ "package-lock.json",
269
+ "package.json",
270
+ "mcp/local-capabilities.json",
271
+ "mcp/servers.json",
272
+ ".ma/.mcp.json",
273
+ "policy",
274
+ ],
275
+ };
276
+ }
File without changes
@@ -0,0 +1,307 @@
1
+ import { ensureDir, readJson, writeFileIfMissing } from "../fs-utils.js";
2
+ import { getRuntimeSubsystemPath } from "../paths.js";
3
+
4
+ export const helperOrchestrationSchemaVersion = "0.1.0";
5
+ export const helperSkillNames = ["$align", "$diagnose", "$tdd", "$cleanup"];
6
+
7
+ const helperContracts = [
8
+ {
9
+ skill: "$align",
10
+ semantic_role: "scope_alignment",
11
+ activates_when: [
12
+ "ambiguous_scope",
13
+ "terminology_drift",
14
+ "lane_handoff_needs_shared_language",
15
+ "docs_or_prompt_contract_needs_tightening",
16
+ ],
17
+ outputs: [
18
+ "current_ambiguity_or_mismatch",
19
+ "normalized_terminology",
20
+ "scope_boundary_and_exclusions",
21
+ "acceptance_checks_or_rewritten_prompts",
22
+ "exact_next_trigger",
23
+ ],
24
+ supports: ["$maestro", "$arch", "$sage", "$flow", "$vet", "$vibe", "$build"],
25
+ records_as: "helper_alignment_receipt",
26
+ },
27
+ {
28
+ skill: "$diagnose",
29
+ semantic_role: "blocked_lane_diagnosis",
30
+ activates_when: [
31
+ "lane_blocked",
32
+ "vague_symptom",
33
+ "runtime_artifact_invalid",
34
+ "missing_evidence_or_reproduction_boundary",
35
+ ],
36
+ outputs: [
37
+ "observed_symptom",
38
+ "likely_failure_slices",
39
+ "missing_evidence_or_repro_steps",
40
+ "smallest_next_probe",
41
+ "exact_next_trigger",
42
+ ],
43
+ supports: ["$maestro", "$flow", "$vet", "$build", "verifier_roles", "debugger_roles"],
44
+ records_as: "helper_diagnosis_receipt",
45
+ },
46
+ {
47
+ skill: "$tdd",
48
+ semantic_role: "regression_first_boundary",
49
+ activates_when: [
50
+ "implementation_expanding",
51
+ "cleanup_requires_behavior_lock",
52
+ "bounded_build_slice_needs_test_shape",
53
+ "regression_risk_before_refactor",
54
+ ],
55
+ outputs: [
56
+ "behavior_to_lock",
57
+ "minimal_regression_or_failing_test_shape",
58
+ "implementation_boundary",
59
+ "proof_test_belongs_to_change",
60
+ "exact_next_trigger",
61
+ ],
62
+ supports: ["$maestro", "$build", "executor_roles", "test_engineer_roles", "$cleanup"],
63
+ records_as: "helper_tdd_receipt",
64
+ },
65
+ {
66
+ skill: "$cleanup",
67
+ semantic_role: "contract_preserving_simplification",
68
+ activates_when: [
69
+ "artifact_is_noisy_after_decision",
70
+ "anti_slop_pass_needed",
71
+ "docs_need_product_native_wording",
72
+ "code_or_plan_can_be_simplified_without_behavior_change",
73
+ ],
74
+ outputs: [
75
+ "removable_complexity_or_noisy_wording",
76
+ "behavior_preserving_simplifications",
77
+ "residual_risks_after_cleanup",
78
+ "exact_next_trigger",
79
+ ],
80
+ supports: ["$maestro", "$arch", "$sage", "$flow", "$vet", "$vibe", "$build", "writer_roles"],
81
+ records_as: "helper_cleanup_receipt",
82
+ },
83
+ ];
84
+
85
+ export function getHelperOrchestrationCorePath() {
86
+ return getRuntimeSubsystemPath("context", "helper-orchestration-core.json");
87
+ }
88
+
89
+ export function createDefaultHelperOrchestrationCore() {
90
+ return {
91
+ schemaVersion: helperOrchestrationSchemaVersion,
92
+ product: "Meta-Architect",
93
+ purpose:
94
+ "Defines how $align, $diagnose, $tdd, and $cleanup work together as core non-gating helper capabilities across MA lanes, roles, workers, and exported host payloads.",
95
+ helper_contracts: helperContracts,
96
+ composition_rules: {
97
+ non_gating: true,
98
+ release_state_mutation_allowed: false,
99
+ may_create_parallel_release_gate: false,
100
+ authority_returns_to: "$maestro_or_owning_lane",
101
+ can_run_before_lane: true,
102
+ can_run_between_lanes: true,
103
+ can_run_after_lane: true,
104
+ records_as: "helper_receipt",
105
+ never_records_as: "gate_approval",
106
+ },
107
+ role_application: {
108
+ all_roles_may_consume_helper_receipts: true,
109
+ planner_roles: ["$align", "$diagnose"],
110
+ architect_roles: ["$align", "$diagnose", "$cleanup"],
111
+ executor_roles: ["$tdd", "$cleanup", "$diagnose"],
112
+ verifier_roles: ["$diagnose", "$tdd", "$cleanup"],
113
+ writer_roles: ["$align", "$cleanup"],
114
+ team_workers: ["$align", "$diagnose", "$tdd", "$cleanup"],
115
+ exported_host_payloads: ["$align", "$diagnose", "$tdd", "$cleanup"],
116
+ },
117
+ handoff_contract: {
118
+ required_fields: [
119
+ "skill",
120
+ "semantic_role",
121
+ "objective",
122
+ "observed_context",
123
+ "result",
124
+ "does_not_unlock",
125
+ "next_trigger",
126
+ ],
127
+ does_not_unlock: [
128
+ "release_state_transition",
129
+ "build_gate",
130
+ "merge_gate",
131
+ "production_release",
132
+ ],
133
+ },
134
+ };
135
+ }
136
+
137
+ export function validateHelperOrchestrationCore(value) {
138
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
139
+ throw new Error("helper orchestration core must be an object");
140
+ }
141
+ if (value.schemaVersion !== helperOrchestrationSchemaVersion) {
142
+ throw new Error(`Unsupported helper orchestration schemaVersion: ${value.schemaVersion}`);
143
+ }
144
+ if (!Array.isArray(value.helper_contracts)) {
145
+ throw new Error("helper orchestration core requires helper_contracts");
146
+ }
147
+ const found = value.helper_contracts.map((contract) => contract.skill).sort();
148
+ const expected = [...helperSkillNames].sort();
149
+ if (JSON.stringify(found) !== JSON.stringify(expected)) {
150
+ throw new Error("helper orchestration core must define all four helper skills exactly once");
151
+ }
152
+ for (const contract of value.helper_contracts) {
153
+ if (
154
+ typeof contract.semantic_role !== "string" ||
155
+ !Array.isArray(contract.activates_when) ||
156
+ !Array.isArray(contract.outputs) ||
157
+ !Array.isArray(contract.supports) ||
158
+ typeof contract.records_as !== "string"
159
+ ) {
160
+ throw new Error(
161
+ "helper contracts require semantic_role, activates_when, outputs, supports, records_as",
162
+ );
163
+ }
164
+ }
165
+ if (value.composition_rules?.release_state_mutation_allowed !== false) {
166
+ throw new Error("helper orchestration core must not allow release-state mutation");
167
+ }
168
+ if (value.composition_rules?.never_records_as !== "gate_approval") {
169
+ throw new Error("helper orchestration core must never record as gate approval");
170
+ }
171
+ return value;
172
+ }
173
+
174
+ export function resolveHelperContract(skill, core = createDefaultHelperOrchestrationCore()) {
175
+ const document = validateHelperOrchestrationCore(core);
176
+ const contract = document.helper_contracts.find((entry) => entry.skill === skill);
177
+ if (!contract) {
178
+ throw new Error(`Unknown helper skill: ${skill}`);
179
+ }
180
+ return contract;
181
+ }
182
+
183
+ export function chooseHelperRoute({
184
+ releaseState = {},
185
+ runtimeSummary = {},
186
+ taskIntent = "",
187
+ } = {}) {
188
+ const intent = taskIntent.toLowerCase();
189
+ const helpers = [];
190
+ const add = (skill, reason) => {
191
+ if (!helpers.some((entry) => entry.skill === skill)) {
192
+ helpers.push({ skill, reason });
193
+ }
194
+ };
195
+
196
+ if (
197
+ releaseState.idea_status !== "CLEAR" ||
198
+ releaseState.architecture_status !== "APPROVED" ||
199
+ intent.includes("scope") ||
200
+ intent.includes("terminology") ||
201
+ intent.includes("prompt")
202
+ ) {
203
+ add("$align", "Normalize scope, shared language, and the next owning lane.");
204
+ }
205
+ if (
206
+ releaseState.logic_status === "RED" ||
207
+ releaseState.security_status === "RED" ||
208
+ runtimeSummary.pendingMailboxCount > 0 ||
209
+ runtimeSummary.invalidArtifacts?.length > 0 ||
210
+ intent.includes("blocked") ||
211
+ intent.includes("failure")
212
+ ) {
213
+ add("$diagnose", "Decompose blockers into reproducible slices and next probes.");
214
+ }
215
+ if (
216
+ ["READY", "RUNNING"].includes(releaseState.build_status) ||
217
+ intent.includes("test") ||
218
+ intent.includes("regression") ||
219
+ intent.includes("refactor")
220
+ ) {
221
+ add("$tdd", "Lock behavior before implementation expands or cleanup changes code.");
222
+ }
223
+ if (
224
+ releaseState.build_status === "DONE" ||
225
+ intent.includes("cleanup") ||
226
+ intent.includes("polish") ||
227
+ intent.includes("slop") ||
228
+ intent.includes("docs")
229
+ ) {
230
+ add("$cleanup", "Simplify artifacts without changing the owning lane decision.");
231
+ }
232
+
233
+ return {
234
+ record_type: "helper_route_recommendation",
235
+ helpers,
236
+ helper_count: helpers.length,
237
+ non_gating: true,
238
+ release_state_mutation_allowed: false,
239
+ next_owner:
240
+ helpers.length === 0
241
+ ? "$maestro_or_owning_lane"
242
+ : helpers.at(-1).skill === "$cleanup"
243
+ ? "$maestro_or_release_verification"
244
+ : "$maestro_or_owning_lane",
245
+ };
246
+ }
247
+
248
+ export function createHelperReceipt({
249
+ skill,
250
+ objective,
251
+ observedContext,
252
+ result,
253
+ nextTrigger,
254
+ core = createDefaultHelperOrchestrationCore(),
255
+ }) {
256
+ const contract = resolveHelperContract(skill, core);
257
+ if (!objective || !observedContext || !result || !nextTrigger) {
258
+ throw new Error("helper receipt requires objective, observedContext, result, and nextTrigger");
259
+ }
260
+ return {
261
+ record_type: "helper_receipt",
262
+ skill,
263
+ semantic_role: contract.semantic_role,
264
+ objective,
265
+ observed_context: observedContext,
266
+ result,
267
+ records_as: contract.records_as,
268
+ does_not_unlock: ["release_state_transition", "build_gate", "merge_gate", "production_release"],
269
+ next_trigger: nextTrigger,
270
+ authority: "$maestro_or_owning_lane",
271
+ created_at: new Date().toISOString(),
272
+ };
273
+ }
274
+
275
+ export function evaluateHelperCoreCoverage(core = createDefaultHelperOrchestrationCore()) {
276
+ const document = validateHelperOrchestrationCore(core);
277
+ const supportedRoles = new Set();
278
+ for (const contract of document.helper_contracts) {
279
+ for (const support of contract.supports) {
280
+ supportedRoles.add(support);
281
+ }
282
+ }
283
+ return {
284
+ record_type: "helper_core_coverage",
285
+ helper_count: document.helper_contracts.length,
286
+ helper_skills: document.helper_contracts.map((contract) => contract.skill),
287
+ supported_surface_count: supportedRoles.size,
288
+ non_gating: document.composition_rules.non_gating === true,
289
+ release_state_mutation_allowed:
290
+ document.composition_rules.release_state_mutation_allowed === true,
291
+ all_helpers_defined: helperSkillNames.every((skill) =>
292
+ document.helper_contracts.some((contract) => contract.skill === skill),
293
+ ),
294
+ };
295
+ }
296
+
297
+ export async function seedHelperOrchestrationCoreArtifacts() {
298
+ await ensureDir(getRuntimeSubsystemPath("context"));
299
+ await writeFileIfMissing(
300
+ getHelperOrchestrationCorePath(),
301
+ `${JSON.stringify(createDefaultHelperOrchestrationCore(), null, 2)}\n`,
302
+ );
303
+ }
304
+
305
+ export async function loadHelperOrchestrationCore() {
306
+ return validateHelperOrchestrationCore(await readJson(getHelperOrchestrationCorePath()));
307
+ }