@jstn-sdk/ma 0.1.13 → 0.14.1

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 (259) hide show
  1. package/.agents/plugins/marketplace.json +0 -0
  2. package/.codex/agents/Architect.toml +1 -0
  3. package/.codex/agents/Auditor.toml +1 -0
  4. package/.codex/agents/Builder.toml +1 -0
  5. package/.codex/agents/Flow.toml +1 -0
  6. package/.codex/agents/Sage.toml +1 -0
  7. package/.codex/agents/Vibe.toml +1 -0
  8. package/.codex/hooks.json +12 -2
  9. package/.codex/prompts/enforcement.md +0 -0
  10. package/.codex/prompts/onboarding.md +6 -1
  11. package/.codex/prompts/release-rules.md +0 -0
  12. package/.codex/prompts/skill-contract.md +0 -0
  13. package/COVERAGE.md +9 -9
  14. package/DEMO.md +15 -6
  15. package/LICENSE +0 -0
  16. package/README.md +127 -784
  17. package/bin/ma.js +591 -105
  18. package/data/clone-data.ledger.json +0 -0
  19. package/data/clone-data.proof.json +0 -0
  20. package/data/clone-data.rvf +0 -0
  21. package/docs/README.md +8 -2
  22. package/docs/assets/banner.png +0 -0
  23. package/docs/autonomous-tasks.md +46 -0
  24. package/docs/codex-integration.md +16 -0
  25. package/docs/getting-started.md +32 -8
  26. package/docs/installed-sdk.md +0 -0
  27. package/docs/mcp-setup.md +30 -1
  28. package/docs/qa/{release-issue-gates-0.1.13.json → release-issue-gates-0.14.1.json} +77 -77
  29. package/docs/qa/release-readiness-0.1.5.md +0 -0
  30. package/docs/qa/{release-readiness-0.1.13.md → release-readiness-0.14.1.md} +12 -12
  31. package/docs/quality.md +24 -0
  32. package/docs/reference/native-engineering-patterns.md +0 -0
  33. package/docs/reference/native-security-playbooks.md +0 -0
  34. package/docs/reference/native-source-selection.md +0 -0
  35. package/docs/reference/native-style-and-deslop.md +0 -0
  36. package/docs/release-spec.md +27 -14
  37. package/docs/skills.md +1 -1
  38. package/docs/vendor-plugin-publishing.md +49 -0
  39. package/index.js +73 -0
  40. package/mcp/collections.json +0 -0
  41. package/mcp/fallback.json +0 -0
  42. package/mcp/local/code-intel.js +185 -41
  43. package/mcp/local/context.js +180 -0
  44. package/mcp/local/memory.js +17 -6
  45. package/mcp/local/playbooks.js +0 -0
  46. package/mcp/local/quality.js +39 -0
  47. package/mcp/local/state.js +7 -3
  48. package/mcp/local/team-run.js +8 -3
  49. package/mcp/local/trace.js +0 -0
  50. package/mcp/local-capabilities.json +9 -0
  51. package/mcp/native-playbooks.json +0 -0
  52. package/mcp/servers.json +0 -0
  53. package/package.json +37 -6
  54. package/plugins/meta-architect/.app.json +1 -1
  55. package/plugins/meta-architect/.claude-plugin/plugin.json +12 -0
  56. package/plugins/meta-architect/.codex-plugin/plugin.json +1 -1
  57. package/plugins/meta-architect/.mcp.json +1 -1
  58. package/plugins/meta-architect/README.md +14 -2
  59. package/plugins/meta-architect/obsidian/main.js +137 -4
  60. package/plugins/meta-architect/obsidian/manifest.json +1 -1
  61. package/plugins/meta-architect/obsidian/styles.css +0 -0
  62. package/plugins/meta-architect/skills/align/SKILL.md +0 -0
  63. package/plugins/meta-architect/skills/align/agents/openai.yaml +0 -0
  64. package/plugins/meta-architect/skills/align/references/shared-language.md +0 -0
  65. package/plugins/meta-architect/skills/arch/SKILL.md +0 -0
  66. package/plugins/meta-architect/skills/arch/agents/openai.yaml +0 -0
  67. package/plugins/meta-architect/skills/build/SKILL.md +0 -0
  68. package/plugins/meta-architect/skills/build/agents/openai.yaml +0 -0
  69. package/plugins/meta-architect/skills/cleanup/SKILL.md +0 -0
  70. package/plugins/meta-architect/skills/cleanup/agents/openai.yaml +0 -0
  71. package/plugins/meta-architect/skills/cleanup/references/style-and-deslop.md +0 -0
  72. package/plugins/meta-architect/skills/diagnose/SKILL.md +0 -0
  73. package/plugins/meta-architect/skills/diagnose/agents/openai.yaml +0 -0
  74. package/plugins/meta-architect/skills/flow/SKILL.md +0 -0
  75. package/plugins/meta-architect/skills/flow/agents/openai.yaml +0 -0
  76. package/plugins/meta-architect/skills/maestro/SKILL.md +17 -1
  77. package/plugins/meta-architect/skills/maestro/agents/openai.yaml +0 -0
  78. package/plugins/meta-architect/skills/maestro/references/core-release-rules.md +2 -2
  79. package/plugins/meta-architect/skills/maestro/references/native-ingest-map.md +0 -0
  80. package/plugins/meta-architect/skills/sage/SKILL.md +0 -0
  81. package/plugins/meta-architect/skills/sage/agents/openai.yaml +0 -0
  82. package/plugins/meta-architect/skills/sage/references/source-selection.md +0 -0
  83. package/plugins/meta-architect/skills/tdd/SKILL.md +0 -0
  84. package/plugins/meta-architect/skills/tdd/agents/openai.yaml +0 -0
  85. package/plugins/meta-architect/skills/vet/SKILL.md +0 -0
  86. package/plugins/meta-architect/skills/vet/agents/openai.yaml +0 -0
  87. package/plugins/meta-architect/skills/vet/references/security-playbooks.md +0 -0
  88. package/plugins/meta-architect/skills/vibe/SKILL.md +0 -0
  89. package/plugins/meta-architect/skills/vibe/agents/openai.yaml +0 -0
  90. package/schemas/autonomous-task-queue.schema.json +58 -0
  91. package/schemas/handoff-packet.schema.json +36 -0
  92. package/schemas/setup-receipt.schema.json +28 -0
  93. package/schemas/skill-frontmatter.schema.json +20 -0
  94. package/schemas/support-bundle.schema.json +37 -0
  95. package/schemas/task-contract.schema.json +31 -0
  96. package/scripts/active-autonomy-hook.mjs +141 -11
  97. package/scripts/biome-staged.js +0 -0
  98. package/scripts/build-linux-packages.mjs +7 -3
  99. package/scripts/cleanup-test-fixtures.sh +55 -0
  100. package/scripts/context-hydration-hook.mjs +89 -0
  101. package/scripts/demo-smoke.js +285 -0
  102. package/scripts/doctor.js +10 -8
  103. package/scripts/install.sh +33 -4
  104. package/scripts/install.sh.sha256 +1 -0
  105. package/scripts/linux-package-lib.mjs +0 -0
  106. package/scripts/linux-package-smoke.mjs +2 -2
  107. package/scripts/package-size-check.mjs +26 -0
  108. package/scripts/plugin-build.js +314 -0
  109. package/scripts/plugin-publish.js +77 -0
  110. package/scripts/plugin-sync.js +83 -17
  111. package/scripts/prepack.js +9 -0
  112. package/scripts/ralph/prompt.md +0 -0
  113. package/scripts/release-metadata.js +0 -0
  114. package/scripts/release-sync.js +83 -7
  115. package/scripts/release-verify.js +131 -7
  116. package/scripts/setup-npmrc.js +48 -23
  117. package/scripts/skills-install.js +9 -2
  118. package/scripts/skills-manifest.js +2 -21
  119. package/scripts/skills-pack.js +2 -2
  120. package/scripts/skills-validate.js +5 -55
  121. package/skills/align/SKILL.md +0 -0
  122. package/skills/align/agents/openai.yaml +0 -0
  123. package/skills/align/references/shared-language.md +0 -0
  124. package/skills/arch/SKILL.md +0 -0
  125. package/skills/arch/agents/openai.yaml +0 -0
  126. package/skills/build/SKILL.md +0 -0
  127. package/skills/build/agents/openai.yaml +0 -0
  128. package/skills/cleanup/SKILL.md +0 -0
  129. package/skills/cleanup/agents/openai.yaml +0 -0
  130. package/skills/cleanup/references/style-and-deslop.md +0 -0
  131. package/skills/diagnose/SKILL.md +0 -0
  132. package/skills/diagnose/agents/openai.yaml +0 -0
  133. package/skills/flow/SKILL.md +0 -0
  134. package/skills/flow/agents/openai.yaml +0 -0
  135. package/skills/index.json +0 -0
  136. package/skills/maestro/SKILL.md +17 -1
  137. package/skills/maestro/agents/openai.yaml +0 -0
  138. package/skills/maestro/references/core-release-rules.md +2 -2
  139. package/skills/maestro/references/native-ingest-map.md +0 -0
  140. package/skills/sage/SKILL.md +0 -0
  141. package/skills/sage/agents/openai.yaml +0 -0
  142. package/skills/sage/references/source-selection.md +0 -0
  143. package/skills/tdd/SKILL.md +0 -0
  144. package/skills/tdd/agents/openai.yaml +0 -0
  145. package/skills/vet/SKILL.md +0 -0
  146. package/skills/vet/agents/openai.yaml +0 -0
  147. package/skills/vet/references/security-playbooks.md +0 -0
  148. package/skills/vibe/SKILL.md +0 -0
  149. package/skills/vibe/agents/openai.yaml +0 -0
  150. package/sprint/00-idea.md +0 -0
  151. package/sprint/01-architecture.md +0 -0
  152. package/sprint/02-oss-evidence.md +0 -0
  153. package/sprint/03-logic.md +0 -0
  154. package/sprint/04-security.md +0 -0
  155. package/sprint/05-dx-ux.md +0 -0
  156. package/sprint/06-build-plan.md +0 -0
  157. package/sprint/07-release.md +2 -2
  158. package/src/agents.js +281 -0
  159. package/src/bootstrap.js +272 -65
  160. package/src/build-gate.js +0 -0
  161. package/src/codex-app-server.js +291 -0
  162. package/src/decision-log.js +0 -0
  163. package/src/fs-utils.js +175 -4
  164. package/src/launcher.js +26 -23
  165. package/src/mcp-config.js +9 -1
  166. package/src/mcp-live-client.js +141 -8
  167. package/src/paths.js +6 -1
  168. package/src/policy.js +2 -2
  169. package/src/prelaunch.js +223 -0
  170. package/src/process-utils.js +62 -0
  171. package/src/quality/ai-quality-orchestrator.js +328 -0
  172. package/src/release-issue-gates.js +62 -0
  173. package/src/release-operations.js +72 -0
  174. package/src/release-state.js +0 -0
  175. package/src/runtime/active-autonomy-core.js +0 -0
  176. package/src/runtime/agent-compat.js +31 -0
  177. package/src/runtime/alignment-sentinel.js +0 -0
  178. package/src/runtime/architect-review.js +249 -11
  179. package/src/runtime/autonomous-tasks.js +585 -0
  180. package/src/runtime/build-readiness.js +0 -0
  181. package/src/runtime/code-graph-rehearse.js +0 -0
  182. package/src/runtime/codeburn-core.js +118 -0
  183. package/src/runtime/context-authority.js +40 -0
  184. package/src/runtime/context-economy-core.js +40 -0
  185. package/src/runtime/continuity-graph.js +201 -0
  186. package/src/runtime/continuity-notes.js +71 -26
  187. package/src/runtime/core-source-ingest.js +2 -2
  188. package/src/runtime/detached-provider.js +90 -13
  189. package/src/runtime/doctor-report.js +18 -0
  190. package/src/runtime/environment-awareness-core.js +0 -0
  191. package/src/runtime/exposure-catalog.js +0 -0
  192. package/src/runtime/graphify-core.js +167 -0
  193. package/src/runtime/guidance-stack.js +9 -2
  194. package/src/runtime/handoff-packets.js +92 -0
  195. package/src/runtime/headroom-core.js +104 -0
  196. package/src/runtime/helper-orchestration-core.js +0 -0
  197. package/src/runtime/hook-profiles.js +20 -0
  198. package/src/runtime/learning-loop-core.js +110 -4
  199. package/src/runtime/live-agent-verification.js +122 -0
  200. package/src/runtime/maestro-events.js +0 -0
  201. package/src/runtime/maestro-manager.js +0 -0
  202. package/src/runtime/maestro-output.js +58 -0
  203. package/src/runtime/maestro-state.js +0 -0
  204. package/src/runtime/managed-markdown.js +29 -0
  205. package/src/runtime/mcp-authority.js +147 -0
  206. package/src/runtime/mcp-policy.js +0 -0
  207. package/src/runtime/obsidian-integration-core.js +255 -17
  208. package/src/runtime/obsidian-plugin-bridge.js +344 -38
  209. package/src/runtime/orchestrator.js +0 -0
  210. package/src/runtime/pi-maestro-core.js +89 -0
  211. package/src/runtime/preferences.js +79 -0
  212. package/src/runtime/project-context.js +636 -0
  213. package/src/runtime/prompt-strategy-core.js +0 -0
  214. package/src/runtime/quorum-review.js +0 -0
  215. package/src/runtime/ralph-execution-core.js +0 -0
  216. package/src/runtime/redaction-gateway.js +218 -19
  217. package/src/runtime/runtime-state.js +94 -2
  218. package/src/runtime/schema-migrations.js +162 -0
  219. package/src/runtime/semantic-recording-core.js +0 -0
  220. package/src/runtime/signal-hooks.js +13 -0
  221. package/src/runtime/skills-registry-export.js +96 -8
  222. package/src/runtime/startup-path.js +0 -0
  223. package/src/runtime/task-contracts.js +83 -0
  224. package/src/runtime/universal-plugin-broker-core.js +373 -50
  225. package/src/runtime/workspace-intelligence-runtime.js +0 -0
  226. package/src/runtime/workspace-virtualizer.js +0 -0
  227. package/src/runtime/workspaces.js +0 -0
  228. package/src/runtime-artifacts.js +0 -0
  229. package/src/setup-lifecycle.js +359 -0
  230. package/src/skill-frontmatter.js +78 -0
  231. package/src/skill-installer.js +226 -71
  232. package/src/skills.js +309 -31
  233. package/src/state-sync.js +0 -0
  234. package/src/test-fixtures.js +543 -0
  235. package/src/tui/grid.js +67 -0
  236. package/src/tui/status-grid.js +23 -0
  237. package/support-bundle.json +114 -0
  238. package/templates/AGENTS.md +6 -2
  239. package/templates/catalog-manifest.json +0 -0
  240. package/templates/model-instructions/core.md +0 -0
  241. package/templates/model-instructions/release.md +0 -0
  242. package/templates/model-instructions/security.md +0 -0
  243. package/templates/quality/ai-quality-rules.yml +37 -0
  244. package/docs/assets/image/Screenshot(1).png +0 -0
  245. package/docs/assets/image/Screenshot(2).png +0 -0
  246. package/docs/assets/image/Screenshot(3).png +0 -0
  247. package/docs/assets/image/Screenshot(4).png +0 -0
  248. package/docs/assets/image/Screenshot(5).png +0 -0
  249. package/docs/assets/image/Screenshot(6).png +0 -0
  250. package/docs/assets/image/Screenshot(7).png +0 -0
  251. package/docs/assets/image/Screenshot(8).png +0 -0
  252. package/docs/assets/image/Screenshot(9).png +0 -0
  253. package/docs/assets/meta-architect-logo.png +0 -0
  254. package/docs/assets/meta-architect-logo.svg +0 -8
  255. package/docs/onboarding.md +0 -81
  256. package/docs/prompt-guidance-contract.md +0 -17
  257. package/docs/prompt-guidance-fragments/active-autonomy-core.md +0 -7
  258. package/docs/skills-publishing.md +0 -255
  259. package/scripts/postinstall.js +0 -23
@@ -1,4 +1,5 @@
1
1
  const { MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting } = require("obsidian");
2
+ const { createHash, randomUUID } = require("node:crypto");
2
3
 
3
4
  const DEFAULT_SETTINGS = {
4
5
  projectName: "Meta-Architect",
@@ -6,13 +7,29 @@ const DEFAULT_SETTINGS = {
6
7
  queuePath: "Meta-Architect/Plugin Requests/request-queue.json",
7
8
  attachmentDir: "Meta-Architect/Attachments",
8
9
  sourceWorkspace: "",
10
+ protocolToken: "",
9
11
  };
10
12
 
11
13
  const FORBIDDEN_TARGETS = [".ma/release.json", ".ma/decisions.json", ".ma/plans/", ".ma/specs/"];
14
+ const MAX_ATTACHMENT_BYTES = 1_048_576;
15
+ const ALLOWED_ATTACHMENT_TYPES = new Set([
16
+ "application/octet-stream",
17
+ "application/json",
18
+ "text/plain",
19
+ "text/markdown",
20
+ "image/png",
21
+ "image/jpeg",
22
+ "image/webp",
23
+ ]);
12
24
 
13
25
  module.exports = class MetaArchitectPlugin extends Plugin {
14
26
  async onload() {
15
27
  this.settings = Object.assign({}, DEFAULT_SETTINGS, (await this.loadData()) || {});
28
+ this.queueBusy = Promise.resolve();
29
+ if (!this.settings.protocolToken) {
30
+ this.settings.protocolToken = randomUUID();
31
+ await this.saveSettings();
32
+ }
16
33
  this.addRibbonIcon("network", "Send current note/selection to MA", async () => {
17
34
  await this.captureActiveNote();
18
35
  });
@@ -164,9 +181,15 @@ ${JSON.stringify(context.pane_state || {}, null, 2)}
164
181
  return;
165
182
  }
166
183
  if (params.action === "capture" || params.open === "active") {
184
+ if (!hasProtocolAuthority(params, this.settings)) {
185
+ throw new Error("obsidian_protocol_authority_required");
186
+ }
167
187
  await this.captureActiveNote();
168
188
  return;
169
189
  }
190
+ if (!hasProtocolAuthority(params, this.settings)) {
191
+ throw new Error("obsidian_protocol_authority_required");
192
+ }
170
193
  await this.openNote(params.path || "Meta-Architect/Map of Content.md");
171
194
  });
172
195
  }
@@ -196,14 +219,22 @@ ${JSON.stringify(context.pane_state || {}, null, 2)}
196
219
  }
197
220
 
198
221
  async queueRequest(params) {
222
+ return this.withQueueLock(() => this.queueRequestUnlocked(params));
223
+ }
224
+
225
+ async queueRequestUnlocked(params) {
226
+ if (!hasProtocolAuthority(params, this.settings)) {
227
+ throw new Error("obsidian_protocol_queue_authority_required");
228
+ }
199
229
  await this.ensureFolder(this.pathParent(this.settings.queuePath));
200
230
  const file = this.app.vault.getAbstractFileByPath(this.settings.queuePath);
201
231
  const queue = file ? JSON.parse(await this.app.vault.read(file)) : [];
202
232
  queue.push({
203
- ...params,
233
+ ...Object.fromEntries(Object.entries(params).filter(([key]) => key !== "protocol_token")),
204
234
  id: params.id || `ma-${Date.now()}`,
205
235
  queued_at: new Date().toISOString(),
206
236
  records_as: "vault_context",
237
+ protocol_token_hash: params.protocol_token_hash || tokenHash(params.protocol_token),
207
238
  });
208
239
  const payload = `${JSON.stringify(queue, null, 2)}\n`;
209
240
  if (file) await this.app.vault.modify(file, payload);
@@ -211,12 +242,29 @@ ${JSON.stringify(context.pane_state || {}, null, 2)}
211
242
  }
212
243
 
213
244
  async drainRequestQueue() {
245
+ return this.withQueueLock(() => this.drainRequestQueueUnlocked());
246
+ }
247
+
248
+ async drainRequestQueueUnlocked() {
214
249
  const file = this.app.vault.getAbstractFileByPath(this.settings.queuePath);
215
250
  const queue = file ? JSON.parse(await this.app.vault.read(file)) : [];
216
251
  const processed = [];
217
252
  const refused = [];
253
+ const refusedQueueItems = [];
218
254
  for (const request of queue) {
219
255
  try {
256
+ const mutating = [
257
+ "capture_active_note",
258
+ "create_note",
259
+ "rename_note",
260
+ "write_attachment",
261
+ ].includes(request.action);
262
+ if (
263
+ (mutating && !hasProtocolAuthority(request, this.settings)) ||
264
+ (!mutating && !hasVaultContextAuthority(request, this.settings))
265
+ ) {
266
+ throw new Error("obsidian_queue_authority_required");
267
+ }
220
268
  const target = request.note_path || request.path || "";
221
269
  if (target) assertSafeVaultPath(target);
222
270
  if (request.action === "capture_active_note") {
@@ -224,6 +272,7 @@ ${JSON.stringify(context.pane_state || {}, null, 2)}
224
272
  } else if (request.action === "create_note") {
225
273
  processed.push(await this.writeVaultContextNote(target, request.content, true));
226
274
  } else if (request.action === "rename_note") {
275
+ assertSafeVaultPath(request.from);
227
276
  assertSafeVaultPath(request.to);
228
277
  const fileToRename = this.app.vault.getAbstractFileByPath(request.from);
229
278
  await this.app.fileManager.renameFile(fileToRename, request.to);
@@ -236,6 +285,7 @@ ${JSON.stringify(context.pane_state || {}, null, 2)}
236
285
  throw new Error(`unsupported_action:${request.action}`);
237
286
  }
238
287
  } catch (error) {
288
+ refusedQueueItems.push(request);
239
289
  refused.push({
240
290
  action: request?.action || null,
241
291
  reason: error.message,
@@ -244,7 +294,11 @@ ${JSON.stringify(context.pane_state || {}, null, 2)}
244
294
  });
245
295
  }
246
296
  }
247
- if (file && queue.length > 0) await this.app.vault.modify(file, "[]\n");
297
+ if (file && queue.length > 0) {
298
+ const nextQueue = `${JSON.stringify(refusedQueueItems, null, 2)}\n`;
299
+ const currentQueue = await this.app.vault.read(file);
300
+ if (currentQueue !== nextQueue) await this.app.vault.modify(file, nextQueue);
301
+ }
248
302
  return {
249
303
  record_type: "obsidian_plugin_queue_drain",
250
304
  records_as: "vault_context",
@@ -254,8 +308,18 @@ ${JSON.stringify(context.pane_state || {}, null, 2)}
254
308
  };
255
309
  }
256
310
 
311
+ withQueueLock(task) {
312
+ const previous = this.queueBusy;
313
+ let release;
314
+ this.queueBusy = new Promise((resolve) => {
315
+ release = resolve;
316
+ });
317
+ return previous.then(task).finally(release);
318
+ }
319
+
257
320
  async writeVaultContextNote(notePath, content, overwrite) {
258
321
  assertSafeVaultPath(notePath);
322
+ assertMaOwnedPath(notePath, "Meta-Architect/");
259
323
  if (!content?.trim()) throw new Error("vault_context note content required");
260
324
  await this.ensureFolder(this.pathParent(notePath));
261
325
  const file = this.app.vault.getAbstractFileByPath(notePath);
@@ -273,8 +337,18 @@ ${JSON.stringify(context.pane_state || {}, null, 2)}
273
337
 
274
338
  async writeBinaryAttachment(attachmentPath, data, contentType) {
275
339
  assertSafeVaultPath(attachmentPath);
340
+ assertMaOwnedPath(attachmentPath, "Meta-Architect/Attachments/");
341
+ if (!ALLOWED_ATTACHMENT_TYPES.has(contentType)) {
342
+ throw new Error(`attachment_type_forbidden:${contentType}`);
343
+ }
276
344
  await this.ensureFolder(this.pathParent(attachmentPath));
277
345
  const bytes = new TextEncoder().encode(String(data || ""));
346
+ if (bytes.byteLength > MAX_ATTACHMENT_BYTES) {
347
+ throw new Error(`attachment_too_large:${attachmentPath}:${bytes.byteLength}`);
348
+ }
349
+ if (this.app.vault.getAbstractFileByPath(attachmentPath)) {
350
+ throw new Error(`attachment_exists:${attachmentPath}`);
351
+ }
278
352
  if (this.app.vault.createBinary) {
279
353
  await this.app.vault.createBinary(attachmentPath, bytes.buffer);
280
354
  } else {
@@ -369,7 +443,21 @@ class MetaArchitectSettingTab extends PluginSettingTab {
369
443
 
370
444
  function withVaultContextFrontmatter(content) {
371
445
  if (content.trimStart().startsWith("---")) {
372
- return content;
446
+ const start = content.indexOf("---");
447
+ const end = content.indexOf("\n---", start + 3);
448
+ if (end > start) {
449
+ let frontmatter = content.slice(start + 4, end);
450
+ for (const [key, value] of [
451
+ ["ma_records_as", "vault_context"],
452
+ ["ma_project", "Meta-Architect"],
453
+ ]) {
454
+ const pattern = new RegExp(`^${key}:.*$`, "m");
455
+ frontmatter = pattern.test(frontmatter)
456
+ ? frontmatter.replace(pattern, `${key}: ${value}`)
457
+ : `${key}: ${value}\n${frontmatter}`;
458
+ }
459
+ return `---\n${frontmatter}\n---${content.slice(end + 4)}`;
460
+ }
373
461
  }
374
462
  return `---
375
463
  ma_records_as: vault_context
@@ -382,9 +470,13 @@ ${content}`;
382
470
  }
383
471
 
384
472
  function assertSafeVaultPath(targetPath) {
385
- const normalized = String(targetPath || "")
473
+ const raw = String(targetPath || "")
386
474
  .replaceAll("\\", "/")
387
475
  .replace(/^\/+/, "");
476
+ if (raw === ".." || raw.startsWith("../") || raw.includes("/../")) {
477
+ throw new Error("path_traversal_forbidden");
478
+ }
479
+ const normalized = pathNormalize(raw);
388
480
  if (
389
481
  !normalized ||
390
482
  normalized === ".." ||
@@ -393,9 +485,50 @@ function assertSafeVaultPath(targetPath) {
393
485
  ) {
394
486
  throw new Error("path_traversal_forbidden");
395
487
  }
488
+ if ([".obsidian/", ".trash/", ".git/"].some((prefix) => normalized.startsWith(prefix))) {
489
+ throw new Error("vault_control_path_forbidden");
490
+ }
396
491
  for (const forbidden of FORBIDDEN_TARGETS) {
397
492
  if (normalized === forbidden || normalized.startsWith(forbidden)) {
398
493
  throw new Error(`forbidden_authoritative_mutation:${forbidden}`);
399
494
  }
400
495
  }
401
496
  }
497
+
498
+ function assertMaOwnedPath(targetPath, prefix) {
499
+ const normalized = pathNormalize(String(targetPath || "").replaceAll("\\", "/"));
500
+ if (!normalized.startsWith(prefix)) throw new Error(`ma_owned_path_required:${prefix}`);
501
+ }
502
+
503
+ function pathNormalize(value) {
504
+ const parts = [];
505
+ for (const part of value.split("/")) {
506
+ if (!part || part === ".") continue;
507
+ if (part === "..") {
508
+ parts.pop();
509
+ } else {
510
+ parts.push(part);
511
+ }
512
+ }
513
+ return parts.join("/");
514
+ }
515
+
516
+ function hasVaultContextAuthority(params, settings) {
517
+ const requiredAuthority = settings.protocolAuthority || "vault_context";
518
+ return params?.authority === requiredAuthority;
519
+ }
520
+
521
+ function tokenHash(value) {
522
+ return createHash("sha256")
523
+ .update(String(value || ""))
524
+ .digest("hex");
525
+ }
526
+
527
+ function hasProtocolAuthority(params, settings) {
528
+ return (
529
+ Boolean(settings.protocolToken) &&
530
+ (params?.protocol_token === settings.protocolToken ||
531
+ params?.protocol_token_hash === tokenHash(settings.protocolToken)) &&
532
+ hasVaultContextAuthority(params, settings)
533
+ );
534
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "meta-architect",
3
3
  "name": "Meta-Architect",
4
- "version": "0.1.13",
4
+ "version": "0.14.1",
5
5
  "minAppVersion": "1.5.0",
6
6
  "description": "Connects active Obsidian notes, selections, graph metadata, canvases, attachments, and request queues to Meta-Architect vault context.",
7
7
  "author": "JustineDevs",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -7,7 +7,7 @@ description: "Use when the user wants the singular Meta-Architect in-session aut
7
7
 
8
8
  ## Overview
9
9
 
10
- Use this skill inside Codex as the singular Meta-Architect umbrella surface and bounded autonomous manager. It inspects workflow state, chooses the smallest safe next step, manages the fixed gated design-and-review sequence one lane at a time, and routes helper handoffs when they are enough. There is no separate shipped `$meta-architect` skill.
10
+ Use this skill inside Codex as the singular Meta-Architect umbrella surface and persistent autonomous manager. It accepts one task or a durable batch, inspects workflow state, chooses the smallest safe next step, manages the fixed gated design-and-review sequence, and keeps resuming eligible work until each task is completed, blocked, cancelled, or failed. It never invents a second umbrella command. There is no separate shipped `$meta-architect` skill.
11
11
 
12
12
  ## Workflow
13
13
 
@@ -30,6 +30,19 @@ Use this skill inside Codex as the singular Meta-Architect umbrella surface and
30
30
  - `$build`
31
31
  5. End with a clear result shape: decision, evidence, blockers, the lane assignment if any, and the exact next trigger.
32
32
 
33
+ ## Autonomous task loop
34
+
35
+ For a task or batch, keep the manager loop active across turns:
36
+
37
+ 1. Normalize the request into the durable `.ma` task contract before dispatch.
38
+ 2. Discover the selected host, available skills, and required lane syntax without taking ownership of user-installed assets.
39
+ 3. Dispatch independent tasks with bounded concurrency and preserve dependency order for dependent tasks.
40
+ 4. Inspect, implement, test, review, repair, and verify. Route a failure back to its owning lane with the failure evidence attached.
41
+ 5. Persist checkpoints, receipts, and the next trigger after every transition so an interrupted process can resume safely.
42
+ 6. Continue unaffected batch tasks when one task is blocked, then return a batch summary with terminal states and unresolved blockers.
43
+
44
+ Routine local work continues without asking for another prompt. Stop only for credentials, destructive actions, production or external mutations, explicit approval gates, unsafe commands, unavailable required providers, or missing verification evidence.
45
+
33
46
  ## Output
34
47
 
35
48
  Produce:
@@ -43,6 +56,9 @@ Produce:
43
56
  ## Rules
44
57
 
45
58
  - Prefer the smallest next step that moves the workflow forward safely.
59
+ - Continue eligible work until the current task or batch reaches a terminal state; do not stop after a single successful lane.
60
+ - Treat persisted `.ma` state as the source for resume, deduplication, dependency ordering, cancellation, and bounded retries.
61
+ - Keep autonomous execution bounded by task dependencies, concurrency limits, deadlines, retry limits, and explicit safety gates.
46
62
  - Respect current gate state before recommending implementation or release work.
47
63
  - Be explicit when more evidence, planning, or validation is still needed.
48
64
  - Treat the in-session skill flow as primary. Use `ma ...` terminal helpers only when repo-local setup, inspection, or scripted state automation is explicitly the better support path.
@@ -8,6 +8,6 @@
8
8
  - `logic_status = GREEN`
9
9
  - `security_status = GREEN`
10
10
  - `experience_status = GREEN` or `WAIVED`
11
- - Feature work merges into `development`, never directly into `prod`.
12
- - Release promotion is allowed only from `development` or approved `release/*`.
11
+ - Feature work merges into `dev`, never directly into `main`.
12
+ - Release promotion is allowed only from `dev` or approved `release/*`.
13
13
  - Use the helper command path only when repo-local state automation is explicitly needed; otherwise stay inside Codex and carry the gate decisions in the session.
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,58 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://meta-architect.dev/schemas/autonomous-task-queue.schema.json",
4
+ "title": "Meta-Architect Autonomous Task Queue",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "record_type", "tasks"],
8
+ "properties": {
9
+ "schemaVersion": { "const": "0.1.0" },
10
+ "record_type": { "const": "autonomous_task_queue" },
11
+ "tasks": {
12
+ "type": "array",
13
+ "items": {
14
+ "type": "object",
15
+ "additionalProperties": false,
16
+ "required": [
17
+ "id",
18
+ "goal",
19
+ "priority",
20
+ "dependencies",
21
+ "labels",
22
+ "status",
23
+ "attempts",
24
+ "maxAttempts",
25
+ "contract",
26
+ "createdAt",
27
+ "updatedAt"
28
+ ],
29
+ "properties": {
30
+ "id": { "type": "string", "minLength": 1 },
31
+ "goal": { "type": "string", "minLength": 1 },
32
+ "priority": { "enum": ["low", "normal", "high", "critical"] },
33
+ "dependencies": { "type": "array", "items": { "type": "string" } },
34
+ "labels": { "type": "array", "items": { "type": "string" } },
35
+ "deadline": { "type": ["string", "null"], "format": "date-time" },
36
+ "status": {
37
+ "enum": ["queued", "running", "completed", "failed", "blocked", "cancelled"]
38
+ },
39
+ "attempts": { "type": "integer", "minimum": 0 },
40
+ "maxAttempts": { "type": "integer", "minimum": 1 },
41
+ "vendor": { "type": ["string", "null"] },
42
+ "contract": { "$ref": "task-contract.schema.json" },
43
+ "createdAt": { "type": "string", "format": "date-time" },
44
+ "updatedAt": { "type": "string", "format": "date-time" },
45
+ "startedAt": { "type": ["string", "null"], "format": "date-time" },
46
+ "completedAt": { "type": ["string", "null"], "format": "date-time" },
47
+ "error": { "type": ["string", "null"] },
48
+ "blocker": { "type": ["string", "null"] },
49
+ "runnerPid": { "type": ["integer", "null"], "minimum": 1 },
50
+ "runnerId": { "type": ["string", "null"], "minLength": 1 },
51
+ "evidence": { "type": "array", "items": {} },
52
+ "selectedCapabilities": { "type": "array", "items": { "type": "object" } },
53
+ "invocation": { "type": ["string", "null"] }
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://meta-architect.dev/schemas/handoff-packet.schema.json",
4
+ "title": "Meta-Architect Handoff Packet",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "schemaVersion",
9
+ "record_type",
10
+ "goal",
11
+ "current_state",
12
+ "context_used",
13
+ "decisions",
14
+ "blockers",
15
+ "risks",
16
+ "changed_files",
17
+ "verification",
18
+ "next_action",
19
+ "status"
20
+ ],
21
+ "properties": {
22
+ "schemaVersion": { "const": "0.1.0" },
23
+ "record_type": { "const": "handoff_packet" },
24
+ "goal": { "type": "string", "minLength": 1 },
25
+ "current_state": { "type": "string", "minLength": 1 },
26
+ "context_used": { "type": "array", "items": { "type": "string" } },
27
+ "decisions": { "type": "array", "items": { "type": "string" } },
28
+ "blockers": { "type": "array", "items": { "type": "string" } },
29
+ "risks": { "type": "array", "items": { "type": "string" } },
30
+ "changed_files": { "type": "array", "items": { "type": "string" } },
31
+ "verification": { "type": "array", "items": { "type": "string" } },
32
+ "next_action": { "type": "string", "minLength": 1 },
33
+ "status": { "enum": ["active", "blocked", "verified"] },
34
+ "created_at": { "type": "string", "format": "date-time" }
35
+ }
36
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "type": "object",
4
+ "required": ["schemaVersion", "record_type", "generatedAt", "managedBy", "artifacts"],
5
+ "properties": {
6
+ "schemaVersion": { "const": "0.1.0" },
7
+ "record_type": { "const": "setup_receipt" },
8
+ "generatedAt": { "type": "string", "format": "date-time" },
9
+ "managedBy": { "const": "@jstn-sdk/ma" },
10
+ "artifacts": {
11
+ "type": "array",
12
+ "items": {
13
+ "type": "object",
14
+ "required": ["path", "kind", "status", "created"],
15
+ "properties": {
16
+ "path": { "type": "string", "minLength": 1 },
17
+ "kind": { "enum": ["file", "directory"] },
18
+ "status": {
19
+ "enum": ["created", "existing", "refreshed", "skipped", "warning", "failed"]
20
+ },
21
+ "created": { "type": "boolean" }
22
+ },
23
+ "additionalProperties": true
24
+ }
25
+ }
26
+ },
27
+ "additionalProperties": true
28
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://meta-architect.jstn.site/schemas/skill-frontmatter.schema.json",
4
+ "$comment": "Schema version: 1.0.0",
5
+ "title": "Meta-Architect skill frontmatter",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["name", "description"],
9
+ "properties": {
10
+ "name": {
11
+ "type": "string",
12
+ "pattern": "^[a-z0-9-]+$",
13
+ "minLength": 1
14
+ },
15
+ "description": {
16
+ "type": "string",
17
+ "minLength": 10
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://meta-architect.dev/schemas/support-bundle.schema.json",
4
+ "type": "object",
5
+ "required": ["schemaVersion", "bundleVersion", "assets", "compatibility"],
6
+ "properties": {
7
+ "schemaVersion": { "const": "1.0.0" },
8
+ "bundleVersion": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" },
9
+ "compatibility": {
10
+ "type": "object",
11
+ "required": ["node", "managedBy"],
12
+ "properties": {
13
+ "node": { "type": "string", "minLength": 1 },
14
+ "managedBy": { "const": "@jstn-sdk/ma" }
15
+ },
16
+ "additionalProperties": false
17
+ },
18
+ "assets": {
19
+ "type": "array",
20
+ "minItems": 1,
21
+ "items": {
22
+ "type": "object",
23
+ "required": ["name", "class", "source", "destination", "type", "required"],
24
+ "properties": {
25
+ "name": { "type": "string", "pattern": "^[a-z0-9-]+$" },
26
+ "class": { "enum": ["runtime", "guidance", "plugin", "documentation"] },
27
+ "source": { "type": "string", "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$)).+" },
28
+ "destination": { "type": "string", "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$)).+" },
29
+ "type": { "enum": ["file", "directory"] },
30
+ "required": { "type": "boolean" }
31
+ },
32
+ "additionalProperties": false
33
+ }
34
+ }
35
+ },
36
+ "additionalProperties": false
37
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://meta-architect.dev/schemas/task-contract.schema.json",
4
+ "title": "Meta-Architect Task Contract",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "schemaVersion",
9
+ "record_type",
10
+ "goal",
11
+ "context_used",
12
+ "assumptions",
13
+ "constraints",
14
+ "risk",
15
+ "verification",
16
+ "stop_condition"
17
+ ],
18
+ "properties": {
19
+ "schemaVersion": { "const": "0.1.0" },
20
+ "record_type": { "const": "task_contract" },
21
+ "goal": { "type": "string", "minLength": 1 },
22
+ "context_used": { "type": "array", "items": { "type": "string" } },
23
+ "assumptions": { "type": "array", "items": { "type": "string" } },
24
+ "constraints": { "type": "array", "items": { "type": "string" } },
25
+ "risk": { "enum": ["low", "medium", "high"] },
26
+ "verification": { "type": "array", "items": { "type": "string" } },
27
+ "stop_condition": { "type": "string", "minLength": 1 },
28
+ "persist": { "type": "boolean" },
29
+ "created_at": { "type": "string", "format": "date-time" }
30
+ }
31
+ }