@neuroverseos/governance 0.3.0 → 0.3.3

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 (126) hide show
  1. package/.well-known/ai-plugin.json +34 -9
  2. package/AGENTS.md +72 -24
  3. package/README.md +352 -237
  4. package/dist/adapters/autoresearch.cjs +1152 -3
  5. package/dist/adapters/autoresearch.d.cts +11 -3
  6. package/dist/adapters/autoresearch.d.ts +11 -3
  7. package/dist/adapters/autoresearch.js +9 -4
  8. package/dist/adapters/deep-agents.cjs +1528 -0
  9. package/dist/adapters/deep-agents.d.cts +181 -0
  10. package/dist/adapters/deep-agents.d.ts +181 -0
  11. package/dist/adapters/deep-agents.js +17 -0
  12. package/dist/adapters/express.cjs +171 -32
  13. package/dist/adapters/express.d.cts +1 -1
  14. package/dist/adapters/express.d.ts +1 -1
  15. package/dist/adapters/express.js +5 -5
  16. package/dist/adapters/index.cjs +564 -121
  17. package/dist/adapters/index.d.cts +3 -1
  18. package/dist/adapters/index.d.ts +3 -1
  19. package/dist/adapters/index.js +38 -16
  20. package/dist/adapters/langchain.cjs +217 -57
  21. package/dist/adapters/langchain.d.cts +5 -5
  22. package/dist/adapters/langchain.d.ts +5 -5
  23. package/dist/adapters/langchain.js +6 -5
  24. package/dist/adapters/openai.cjs +219 -59
  25. package/dist/adapters/openai.d.cts +5 -5
  26. package/dist/adapters/openai.d.ts +5 -5
  27. package/dist/adapters/openai.js +6 -5
  28. package/dist/adapters/openclaw.cjs +217 -57
  29. package/dist/adapters/openclaw.d.cts +6 -6
  30. package/dist/adapters/openclaw.d.ts +6 -6
  31. package/dist/adapters/openclaw.js +6 -5
  32. package/dist/add-ROOZLU62.js +314 -0
  33. package/dist/behavioral-MJO34S6Q.js +118 -0
  34. package/dist/{bootstrap-GXVDZNF7.js → bootstrap-CQRZVOXK.js} +6 -4
  35. package/dist/bootstrap-emitter-Q7UIJZ2O.js +7 -0
  36. package/dist/bootstrap-parser-EEF36XDU.js +7 -0
  37. package/dist/browser.global.js +941 -0
  38. package/dist/{build-P42YFKQV.js → build-QKOBBC23.js} +7 -5
  39. package/dist/{chunk-COT5XS4V.js → chunk-3WQLXYTP.js} +17 -35
  40. package/dist/{chunk-ER62HNGF.js → chunk-4FLICVVA.js} +17 -37
  41. package/dist/chunk-5TPFNWRU.js +215 -0
  42. package/dist/chunk-5U2MQO5P.js +57 -0
  43. package/dist/{chunk-NF5POFCI.js → chunk-6S5CFQXY.js} +6 -4
  44. package/dist/{chunk-QPASI2BR.js → chunk-A7GKPPU7.js} +49 -10
  45. package/dist/{chunk-OGL7QXZS.js → chunk-B6OXJLJ5.js} +17 -3
  46. package/dist/{chunk-2PQU3VAN.js → chunk-BNKJPUPQ.js} +17 -35
  47. package/dist/chunk-BQZMOEML.js +43 -0
  48. package/dist/chunk-CNSO6XW5.js +207 -0
  49. package/dist/{chunk-JZPQGIKR.js → chunk-CTZHONLA.js} +65 -9
  50. package/dist/chunk-D2UCV5AK.js +326 -0
  51. package/dist/{chunk-XPDMYECO.js → chunk-EMQDLDAF.js} +1 -185
  52. package/dist/{chunk-GR6DGCZ2.js → chunk-F66BVUYB.js} +3 -3
  53. package/dist/{chunk-2NICNKOM.js → chunk-G7DJ6VOD.js} +5 -4
  54. package/dist/{chunk-4A7LISES.js → chunk-IS4WUH6Y.js} +45 -6
  55. package/dist/{chunk-MWDQ4MJB.js → chunk-MH7BT4VH.js} +5 -1
  56. package/dist/chunk-O5ABKEA7.js +304 -0
  57. package/dist/chunk-PVTQQS3Y.js +186 -0
  58. package/dist/{chunk-4QXB6PEO.js → chunk-QLPTHTVB.js} +37 -16
  59. package/dist/chunk-QWGCMQQD.js +16 -0
  60. package/dist/{chunk-T5EUJQE5.js → chunk-QXBFT7NI.js} +31 -2
  61. package/dist/{chunk-PDOZHZWL.js → chunk-TG6SEF24.js} +25 -4
  62. package/dist/chunk-U6U7EJZL.js +177 -0
  63. package/dist/{chunk-4JRYGIO7.js → chunk-W7LLXRGY.js} +110 -7
  64. package/dist/{chunk-BUWWN2NX.js → chunk-ZJTDUCC2.js} +9 -7
  65. package/dist/{chunk-FYS2CBUW.js → chunk-ZWI3NIXK.js} +10 -0
  66. package/dist/cli/neuroverse.cjs +5091 -2348
  67. package/dist/cli/neuroverse.js +52 -21
  68. package/dist/cli/plan.cjs +881 -41
  69. package/dist/cli/plan.js +7 -15
  70. package/dist/cli/run.cjs +289 -34
  71. package/dist/cli/run.js +4 -4
  72. package/dist/{configure-ai-TK67ZWZL.js → configure-ai-6TZ3MCSI.js} +1 -1
  73. package/dist/decision-flow-M63D47LO.js +61 -0
  74. package/dist/demo-G43RLCPK.js +469 -0
  75. package/dist/{derive-TLIV4OOU.js → derive-FJZVIPUZ.js} +5 -4
  76. package/dist/{doctor-XPDLEYXN.js → doctor-6BC6X2VO.js} +6 -4
  77. package/dist/equity-penalties-SG5IZQ7I.js +244 -0
  78. package/dist/{explain-IDCRWMPX.js → explain-RHBU2GBR.js} +6 -25
  79. package/dist/{guard-RV65TT4L.js → guard-AJCCGZMF.js} +8 -12
  80. package/dist/{guard-contract-WZx__PmU.d.cts → guard-contract-DqFcTScd.d.cts} +117 -5
  81. package/dist/{guard-contract-WZx__PmU.d.ts → guard-contract-DqFcTScd.d.ts} +117 -5
  82. package/dist/{guard-engine-JLTUARGU.js → guard-engine-PNR6MHCM.js} +3 -3
  83. package/dist/{impact-XPECYRLH.js → impact-3XVDSCBU.js} +5 -5
  84. package/dist/{improve-GPUBKTEA.js → improve-TQP4ECSY.js} +7 -26
  85. package/dist/index.cjs +5597 -4279
  86. package/dist/index.d.cts +597 -18
  87. package/dist/index.d.ts +597 -18
  88. package/dist/index.js +134 -41
  89. package/dist/{infer-world-7GVZWFX4.js → infer-world-IFXCACJ5.js} +1 -1
  90. package/dist/{init-PKPIYHYE.js → init-FYPV4SST.js} +1 -1
  91. package/dist/{init-world-VWMQZQC7.js → init-world-TI7ARHBT.js} +1 -1
  92. package/dist/mcp-server-5Y3ZM7TV.js +13 -0
  93. package/dist/{model-adapter-BB7G4MFI.js → model-adapter-VXEKB4LS.js} +1 -1
  94. package/dist/{playground-E664U4T6.js → playground-VZBNPPBO.js} +29 -19
  95. package/dist/{redteam-Z7WREJ44.js → redteam-MZPZD3EF.js} +4 -4
  96. package/dist/session-JYOARW54.js +15 -0
  97. package/dist/shared-7RLUHNMU.js +16 -0
  98. package/dist/shared-B8dvUUD8.d.cts +60 -0
  99. package/dist/shared-Dr5Wiay8.d.ts +60 -0
  100. package/dist/{simulate-VDOYQFRO.js → simulate-LJXYBC6M.js} +8 -33
  101. package/dist/{test-OGXJK4QU.js → test-BOOR4A5F.js} +4 -4
  102. package/dist/{trace-JVF67VR3.js → trace-PKV4KX56.js} +4 -4
  103. package/dist/{validate-LLBWVPGV.js → validate-RALX7CZS.js} +2 -2
  104. package/dist/{validate-engine-UIABSIHD.js → validate-engine-7ZXFVGF2.js} +1 -1
  105. package/dist/viz/assets/index-B8SaeJZZ.js +23 -0
  106. package/dist/viz/index.html +23 -0
  107. package/dist/{world-LAXO6DOX.js → world-BIP4GZBZ.js} +9 -11
  108. package/dist/world-loader-Y6HMQH2D.js +13 -0
  109. package/dist/worlds/coding-agent.nv-world.md +211 -0
  110. package/dist/worlds/research-agent.nv-world.md +169 -0
  111. package/dist/worlds/social-media.nv-world.md +198 -0
  112. package/dist/worlds/trading-agent.nv-world.md +218 -0
  113. package/examples/social-media-sim/bridge.py +209 -0
  114. package/examples/social-media-sim/simulation.py +927 -0
  115. package/package.json +30 -4
  116. package/policies/content-moderation-rules.txt +8 -0
  117. package/policies/marketing-rules.txt +8 -0
  118. package/policies/science-research-rules.txt +11 -0
  119. package/policies/social-media-rules.txt +7 -0
  120. package/policies/strict-rules.txt +8 -0
  121. package/policies/trading-rules.txt +8 -0
  122. package/simulate.html +1567 -0
  123. package/dist/chunk-YZFATT7X.js +0 -9
  124. package/dist/mcp-server-FPVSU32Z.js +0 -13
  125. package/dist/session-EKTRSR7C.js +0 -14
  126. package/dist/world-loader-HMPTOEA2.js +0 -9
@@ -0,0 +1,304 @@
1
+ import {
2
+ GovernanceBlockedError,
3
+ buildEngineOptions,
4
+ extractScope,
5
+ trackPlanProgress
6
+ } from "./chunk-5U2MQO5P.js";
7
+ import {
8
+ evaluateGuard
9
+ } from "./chunk-W7LLXRGY.js";
10
+ import {
11
+ loadWorld
12
+ } from "./chunk-CTZHONLA.js";
13
+
14
+ // src/engine/tool-classifier.ts
15
+ var TOOL_CATEGORY_MAP = {
16
+ // File operations
17
+ read_file: "file_read",
18
+ read: "file_read",
19
+ glob: "file_read",
20
+ grep: "file_read",
21
+ list_files: "file_read",
22
+ write_file: "file_write",
23
+ write: "file_write",
24
+ create_file: "file_write",
25
+ edit_file: "file_write",
26
+ edit: "file_write",
27
+ patch: "file_write",
28
+ delete_file: "file_delete",
29
+ remove_file: "file_delete",
30
+ // Shell
31
+ shell: "shell",
32
+ bash: "shell",
33
+ execute: "shell",
34
+ run_command: "shell",
35
+ terminal: "shell",
36
+ // Git
37
+ git: "git",
38
+ git_commit: "git",
39
+ git_push: "git",
40
+ git_checkout: "git",
41
+ // Network
42
+ http: "network",
43
+ fetch: "network",
44
+ curl: "network",
45
+ web_search: "network",
46
+ // Sub-agents
47
+ sub_agent: "sub_agent",
48
+ spawn_agent: "sub_agent",
49
+ delegate: "sub_agent",
50
+ // Context management
51
+ summarize: "context",
52
+ compress_context: "context"
53
+ };
54
+ function classifyTool(toolName) {
55
+ const normalized = toolName.toLowerCase().replace(/[-\s]/g, "_");
56
+ return TOOL_CATEGORY_MAP[normalized] ?? "unknown";
57
+ }
58
+ var DANGEROUS_SHELL_PATTERNS = [
59
+ { pattern: /rm\s+(-[a-zA-Z]*f[a-zA-Z]*\s+|.*-rf\s+|.*--force)/, label: "force-delete" },
60
+ { pattern: /rm\s+-[a-zA-Z]*r/, label: "recursive-delete" },
61
+ { pattern: />\s*\/dev\/sd/, label: "disk-overwrite" },
62
+ { pattern: /mkfs\./, label: "format-disk" },
63
+ { pattern: /dd\s+if=/, label: "disk-dump" },
64
+ { pattern: /chmod\s+(-R\s+)?777/, label: "world-writable" },
65
+ { pattern: /curl\s+.*\|\s*(bash|sh|zsh)/, label: "pipe-to-shell" },
66
+ { pattern: /wget\s+.*\|\s*(bash|sh|zsh)/, label: "pipe-to-shell" },
67
+ { pattern: /:(){ :\|:& };:/, label: "fork-bomb" },
68
+ { pattern: />\s*\/etc\//, label: "system-config-overwrite" },
69
+ { pattern: /shutdown|reboot|halt|poweroff/, label: "system-shutdown" },
70
+ { pattern: /kill\s+-9\s+1\b/, label: "kill-init" }
71
+ ];
72
+ var DANGEROUS_GIT_PATTERNS = [
73
+ { pattern: /push\s+.*--force/, label: "force-push" },
74
+ { pattern: /push\s+.*-f\b/, label: "force-push" },
75
+ { pattern: /push\s+(origin\s+)?main\b/, label: "push-main" },
76
+ { pattern: /push\s+(origin\s+)?master\b/, label: "push-master" },
77
+ { pattern: /reset\s+--hard/, label: "hard-reset" },
78
+ { pattern: /clean\s+-fd/, label: "clean-force" },
79
+ { pattern: /branch\s+-D/, label: "force-delete-branch" }
80
+ ];
81
+ function isDangerousCommand(command) {
82
+ const matched = DANGEROUS_SHELL_PATTERNS.filter((p) => p.pattern.test(command)).map((p) => p.label);
83
+ return { dangerous: matched.length > 0, labels: matched };
84
+ }
85
+ function isDangerousGitCommand(command) {
86
+ const matched = DANGEROUS_GIT_PATTERNS.filter((p) => p.pattern.test(command)).map((p) => p.label);
87
+ return { dangerous: matched.length > 0, labels: matched };
88
+ }
89
+ function assessRiskLevel(category) {
90
+ if (category === "file_read" || category === "context") return "low";
91
+ if (category === "file_write" || category === "sub_agent") return "medium";
92
+ if (category === "shell" || category === "file_delete" || category === "git" || category === "network") return "high";
93
+ return void 0;
94
+ }
95
+ function categoryToActionCategory(category) {
96
+ if (category === "file_read" || category === "context") return "read";
97
+ if (category === "file_write") return "write";
98
+ if (category === "file_delete") return "delete";
99
+ if (category === "shell") return "shell";
100
+ if (category === "network") return "network";
101
+ return "other";
102
+ }
103
+
104
+ // src/adapters/deep-agents.ts
105
+ var GovernanceBlockedError2 = class extends GovernanceBlockedError {
106
+ toolCall;
107
+ category;
108
+ constructor(verdict, toolCall, category) {
109
+ super(verdict);
110
+ this.toolCall = toolCall;
111
+ this.category = category;
112
+ }
113
+ };
114
+ function defaultMapToolCall(toolCall) {
115
+ const category = classifyTool(toolCall.tool);
116
+ const args = toolCall.args;
117
+ const scope = extractScope(args);
118
+ let intent = toolCall.tool;
119
+ if (category === "shell" && typeof args.command === "string") {
120
+ intent = `shell: ${args.command}`;
121
+ } else if (category === "git" && typeof args.command === "string") {
122
+ intent = `git ${args.command}`;
123
+ } else if (category === "file_write" && scope) {
124
+ intent = `write ${scope}`;
125
+ } else if (category === "file_delete" && scope) {
126
+ intent = `delete ${scope}`;
127
+ }
128
+ const riskLevel = assessRiskLevel(category);
129
+ let irreversible = false;
130
+ if (category === "shell" && typeof args.command === "string") {
131
+ irreversible = DANGEROUS_SHELL_PATTERNS.some((p) => p.pattern.test(args.command));
132
+ } else if (category === "git" && typeof args.command === "string") {
133
+ irreversible = DANGEROUS_GIT_PATTERNS.some((p) => p.pattern.test(args.command));
134
+ } else if (category === "file_delete") {
135
+ irreversible = true;
136
+ }
137
+ return {
138
+ intent,
139
+ tool: toolCall.tool,
140
+ scope,
141
+ args,
142
+ direction: "input",
143
+ actionCategory: categoryToActionCategory(category),
144
+ riskLevel,
145
+ irreversible
146
+ };
147
+ }
148
+ var DeepAgentsGuard = class {
149
+ name = "neuroverse-deep-agents-guard";
150
+ world;
151
+ options;
152
+ engineOptions;
153
+ mapToolCall;
154
+ activePlan;
155
+ constructor(world, options = {}) {
156
+ this.world = world;
157
+ this.options = options;
158
+ this.activePlan = options.plan;
159
+ this.engineOptions = buildEngineOptions(options, this.activePlan);
160
+ this.mapToolCall = options.mapToolCall ?? defaultMapToolCall;
161
+ }
162
+ /**
163
+ * Evaluate a tool call against governance rules.
164
+ * Returns the result without side effects.
165
+ */
166
+ evaluate(toolCall) {
167
+ const event = this.mapToolCall(toolCall);
168
+ this.engineOptions.plan = this.activePlan;
169
+ const verdict = evaluateGuard(event, this.world, this.engineOptions);
170
+ const category = classifyTool(toolCall.tool);
171
+ const result = {
172
+ allowed: verdict.status === "ALLOW",
173
+ verdict,
174
+ toolCall,
175
+ category
176
+ };
177
+ this.options.onEvaluate?.(result);
178
+ if (verdict.status === "ALLOW" && this.activePlan) {
179
+ this.trackPlanProgressInternal(event);
180
+ }
181
+ return result;
182
+ }
183
+ /**
184
+ * Evaluate and enforce governance on a tool call.
185
+ *
186
+ * @throws GovernanceBlockedError if BLOCKED
187
+ * @throws GovernanceBlockedError if PAUSED and onPause returns false
188
+ * @returns DeepAgentsGuardResult on ALLOW
189
+ */
190
+ async enforce(toolCall) {
191
+ const result = this.evaluate(toolCall);
192
+ if (result.verdict.status === "BLOCK") {
193
+ this.options.onBlock?.(result);
194
+ throw new GovernanceBlockedError2(result.verdict, toolCall, result.category);
195
+ }
196
+ if (result.verdict.status === "PAUSE") {
197
+ const approved = await this.options.onPause?.(result);
198
+ if (!approved) {
199
+ throw new GovernanceBlockedError2(result.verdict, toolCall, result.category);
200
+ }
201
+ }
202
+ return result;
203
+ }
204
+ /**
205
+ * Evaluate and execute a tool call with governance enforcement.
206
+ *
207
+ * If ALLOW: runs the executor and returns its result.
208
+ * If BLOCK: returns a governance-blocked message.
209
+ * If PAUSE: calls onPause; blocks if not approved.
210
+ *
211
+ * @param toolCall - The Deep Agents tool call to evaluate
212
+ * @param executor - The actual tool execution function
213
+ * @returns The tool execution result or a blocked message
214
+ */
215
+ async execute(toolCall, executor) {
216
+ const guardResult = this.evaluate(toolCall);
217
+ if (guardResult.verdict.status === "BLOCK") {
218
+ this.options.onBlock?.(guardResult);
219
+ return {
220
+ blocked: true,
221
+ verdict: guardResult.verdict,
222
+ reason: guardResult.verdict.reason ?? "Action blocked by governance policy."
223
+ };
224
+ }
225
+ if (guardResult.verdict.status === "PAUSE") {
226
+ const approved = await this.options.onPause?.(guardResult);
227
+ if (!approved) {
228
+ return {
229
+ blocked: true,
230
+ verdict: guardResult.verdict,
231
+ reason: guardResult.verdict.reason ?? "Action requires approval."
232
+ };
233
+ }
234
+ }
235
+ const result = await executor(toolCall);
236
+ return { result, verdict: guardResult.verdict };
237
+ }
238
+ /**
239
+ * Returns a middleware function compatible with Deep Agents' tool pipeline.
240
+ *
241
+ * The middleware intercepts tool calls before execution:
242
+ * agent.use(guard.middleware());
243
+ */
244
+ middleware() {
245
+ return async (toolCall, next) => {
246
+ await this.enforce(toolCall);
247
+ return next();
248
+ };
249
+ }
250
+ /**
251
+ * Returns a callback-handler-style object for LangChain integration.
252
+ * Compatible with Deep Agents' callback system.
253
+ */
254
+ callbacks() {
255
+ return {
256
+ handleToolStart: async (tool, input) => {
257
+ let parsedInput;
258
+ try {
259
+ parsedInput = typeof input === "string" ? JSON.parse(input) : input;
260
+ } catch {
261
+ parsedInput = { raw: input };
262
+ }
263
+ await this.enforce({ tool: tool.name, args: parsedInput });
264
+ }
265
+ };
266
+ }
267
+ /**
268
+ * Check if a shell command contains dangerous patterns.
269
+ * Useful for pre-screening before full governance evaluation.
270
+ */
271
+ static isDangerousCommand(command) {
272
+ return isDangerousCommand(command);
273
+ }
274
+ /**
275
+ * Check if a git command contains dangerous patterns.
276
+ */
277
+ static isDangerousGitCommand(command) {
278
+ return isDangerousGitCommand(command);
279
+ }
280
+ /**
281
+ * Classify a tool name into a category.
282
+ */
283
+ static classifyTool(toolName) {
284
+ return classifyTool(toolName);
285
+ }
286
+ // ─── Private ──────────────────────────────────────────────────────────────
287
+ trackPlanProgressInternal(event) {
288
+ trackPlanProgress(event, this, this.options);
289
+ }
290
+ };
291
+ async function createDeepAgentsGuard(worldPath, options) {
292
+ const world = await loadWorld(worldPath);
293
+ return new DeepAgentsGuard(world, options);
294
+ }
295
+ function createDeepAgentsGuardFromWorld(world, options) {
296
+ return new DeepAgentsGuard(world, options);
297
+ }
298
+
299
+ export {
300
+ GovernanceBlockedError2 as GovernanceBlockedError,
301
+ DeepAgentsGuard,
302
+ createDeepAgentsGuard,
303
+ createDeepAgentsGuardFromWorld
304
+ };
@@ -0,0 +1,186 @@
1
+ // src/engine/bootstrap-emitter.ts
2
+ var GATE_DEFAULTS = {
3
+ THRIVING: { color: "#0f6b3a", icon: "\u2726" },
4
+ STABLE: { color: "#1856b8", icon: "\u25CF" },
5
+ COMPRESSED: { color: "#a16207", icon: "\u25B2" },
6
+ CRITICAL: { color: "#b91c1c", icon: "\u26A0" },
7
+ MODEL_COLLAPSES: { color: "#7f1d1d", icon: "\u2715" }
8
+ };
9
+ function emitWorldDefinition(parsed) {
10
+ const issues = [];
11
+ const fm = parsed.frontmatter;
12
+ const defaultProfile = fm.default_profile ?? parsed.assumptions[0]?.id ?? "baseline";
13
+ const altProfile = fm.alternative_profile ?? parsed.assumptions[1]?.id ?? "alternative";
14
+ const world = {
15
+ world_id: fm.world_id,
16
+ name: fm.name,
17
+ thesis: parsed.thesis,
18
+ version: fm.version ?? "1.0.0",
19
+ runtime_mode: fm.runtime_mode ?? "SIMULATION",
20
+ default_assumption_profile: defaultProfile,
21
+ default_alternative_profile: altProfile,
22
+ modules: parsed.rules.map((r) => r.id),
23
+ players: {
24
+ thinking_space: true,
25
+ experience_space: true,
26
+ action_space: true
27
+ }
28
+ };
29
+ const invariants = parsed.invariants.map((inv) => ({
30
+ id: inv.id,
31
+ label: inv.label,
32
+ enforcement: inv.enforcement === "prompt" ? "prompt" : "structural",
33
+ mutable: false
34
+ }));
35
+ const profiles = {};
36
+ const parameterDefinitions = {};
37
+ for (let i = 0; i < parsed.assumptions.length; i++) {
38
+ const profile = parsed.assumptions[i];
39
+ const params = {};
40
+ for (const [key, val] of Object.entries(profile.parameters)) {
41
+ params[key] = String(val);
42
+ if (!parameterDefinitions[key]) {
43
+ parameterDefinitions[key] = {
44
+ type: typeof val === "boolean" ? "boolean" : typeof val === "number" ? "number" : "enum",
45
+ label: key.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()),
46
+ description: `Parameter: ${key}`
47
+ };
48
+ }
49
+ }
50
+ profiles[profile.id] = {
51
+ name: profile.name,
52
+ description: profile.description,
53
+ is_default_baseline: i === 0 || profile.id === defaultProfile,
54
+ is_default_alternative: i === 1 || profile.id === altProfile,
55
+ parameters: params
56
+ };
57
+ }
58
+ const assumptions = { profiles, parameter_definitions: parameterDefinitions };
59
+ const variables = {};
60
+ for (const v of parsed.stateVariables) {
61
+ const stateVar = {
62
+ type: v.type,
63
+ default: v.default,
64
+ mutable: true,
65
+ label: v.label,
66
+ description: v.description
67
+ };
68
+ if (v.type === "number") {
69
+ if (v.min !== void 0) stateVar.min = v.min;
70
+ if (v.max !== void 0) stateVar.max = v.max;
71
+ if (v.step !== void 0) stateVar.step = v.step;
72
+ }
73
+ if (v.type === "enum" && v.options) {
74
+ stateVar.options = v.options;
75
+ }
76
+ variables[v.id] = stateVar;
77
+ }
78
+ const stateSchema = { variables, presets: {} };
79
+ const rules = parsed.rules.map((r) => {
80
+ const triggers = r.triggers.map((t) => ({
81
+ field: t.field,
82
+ operator: t.operator,
83
+ value: t.value,
84
+ source: t.source
85
+ }));
86
+ const effects = r.effects.map((e) => ({
87
+ target: e.target,
88
+ operation: e.operation,
89
+ value: e.value
90
+ }));
91
+ let collapse_check;
92
+ if (r.collapse_check) {
93
+ collapse_check = {
94
+ field: r.collapse_check.field,
95
+ operator: r.collapse_check.operator,
96
+ value: r.collapse_check.value,
97
+ result: "MODEL_COLLAPSES"
98
+ };
99
+ }
100
+ const causal_translation = r.causal_translation ?? {
101
+ trigger_text: "",
102
+ rule_text: "",
103
+ shift_text: "",
104
+ effect_text: ""
105
+ };
106
+ const rule = {
107
+ id: r.id,
108
+ severity: r.severity,
109
+ label: r.label,
110
+ description: r.description ?? r.label,
111
+ order: r.order,
112
+ triggers,
113
+ effects: effects.length > 0 ? effects : void 0,
114
+ collapse_check,
115
+ causal_translation
116
+ };
117
+ return rule;
118
+ });
119
+ const viabilityClassification = parsed.gates.map((g) => {
120
+ const defaults = GATE_DEFAULTS[g.status] ?? { color: "#5c5a52", icon: "\u25CF" };
121
+ return {
122
+ status: g.status,
123
+ field: g.field,
124
+ operator: g.operator,
125
+ value: g.value,
126
+ color: defaults.color,
127
+ icon: defaults.icon
128
+ };
129
+ });
130
+ const gates = {
131
+ viability_classification: viabilityClassification,
132
+ structural_override: {
133
+ description: "Rules with severity=structural and triggered collapse_check force MODEL_COLLAPSES regardless of final margin.",
134
+ enforcement: "mandatory"
135
+ },
136
+ sustainability_threshold: 0.1,
137
+ collapse_visual: {
138
+ background: "#1c1917",
139
+ text: "#fef2f2",
140
+ border: "#b91c1c",
141
+ label: "Structural Failure"
142
+ }
143
+ };
144
+ const computedOutcomes = parsed.outcomes.map((o) => {
145
+ const outcome = {
146
+ id: o.id,
147
+ type: o.type,
148
+ label: o.label,
149
+ show_in_comparison: true
150
+ };
151
+ if (o.range) outcome.range = o.range;
152
+ if (o.display) outcome.display_as = o.display;
153
+ if (o.primary) outcome.primary = o.primary;
154
+ if (o.assignment) outcome.assignment = o.assignment;
155
+ return outcome;
156
+ });
157
+ const outcomes = {
158
+ computed_outcomes: computedOutcomes,
159
+ comparison_layout: {
160
+ primary_card: computedOutcomes.find((o) => o.primary)?.id ?? computedOutcomes[0]?.id ?? "",
161
+ status_badge: "viability_status",
162
+ structural_indicators: rules.filter((r) => r.severity === "structural").map((r) => r.id)
163
+ }
164
+ };
165
+ const metadata = {
166
+ format_version: "1.0.0",
167
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
168
+ last_modified: (/* @__PURE__ */ new Date()).toISOString(),
169
+ authoring_method: "manual-authoring"
170
+ };
171
+ const worldDefinition = {
172
+ world,
173
+ invariants,
174
+ assumptions,
175
+ stateSchema,
176
+ rules,
177
+ gates,
178
+ outcomes,
179
+ metadata
180
+ };
181
+ return { world: worldDefinition, issues };
182
+ }
183
+
184
+ export {
185
+ emitWorldDefinition
186
+ };
@@ -1,14 +1,24 @@
1
- // src/engine/plan-engine.ts
2
- function keywordMatch(eventText, step) {
3
- const stepText = [
4
- step.label,
5
- step.description ?? "",
6
- ...step.tags ?? []
1
+ // src/engine/text-utils.ts
2
+ function normalizeEventText(event) {
3
+ return [
4
+ event.intent,
5
+ event.tool ?? "",
6
+ event.scope ?? ""
7
7
  ].join(" ").toLowerCase();
8
- const keywords = stepText.split(/\s+/).filter((w) => w.length > 3);
8
+ }
9
+ function extractKeywords(text, minLength = 3) {
10
+ return text.toLowerCase().split(/\s+/).filter((w) => w.length > minLength);
11
+ }
12
+ function matchesAllKeywords(eventText, ruleText) {
13
+ const keywords = extractKeywords(ruleText);
14
+ if (keywords.length === 0) return false;
15
+ return keywords.every((kw) => eventText.includes(kw));
16
+ }
17
+ function matchesKeywordThreshold(eventText, ruleText, threshold = 0.5) {
18
+ const keywords = extractKeywords(ruleText);
9
19
  if (keywords.length === 0) return false;
10
20
  const matched = keywords.filter((kw) => eventText.includes(kw));
11
- return matched.length >= Math.ceil(keywords.length * 0.5);
21
+ return matched.length >= Math.ceil(keywords.length * threshold);
12
22
  }
13
23
  function tokenSimilarity(a, b) {
14
24
  const tokensA = new Set(a.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
@@ -21,6 +31,19 @@ function tokenSimilarity(a, b) {
21
31
  const union = (/* @__PURE__ */ new Set([...tokensA, ...tokensB])).size;
22
32
  return union > 0 ? intersection / union : 0;
23
33
  }
34
+
35
+ // src/engine/plan-engine.ts
36
+ function keywordMatch(eventText, step) {
37
+ const stepText = [
38
+ step.label,
39
+ step.description ?? "",
40
+ ...step.tags ?? []
41
+ ].join(" ");
42
+ return matchesKeywordThreshold(eventText, stepText, 0.5);
43
+ }
44
+ function tokenSimilarity2(a, b) {
45
+ return tokenSimilarity(a, b);
46
+ }
24
47
  function findMatchingStep(eventText, event, steps) {
25
48
  const pendingOrActive = steps.filter((s) => s.status === "pending" || s.status === "active");
26
49
  if (pendingOrActive.length === 0) {
@@ -39,7 +62,7 @@ function findMatchingStep(eventText, event, steps) {
39
62
  let bestScore = 0;
40
63
  for (const step of pendingOrActive) {
41
64
  const stepText = [step.label, step.description ?? "", ...step.tags ?? []].join(" ");
42
- const score = tokenSimilarity(intentText, stepText);
65
+ const score = tokenSimilarity2(intentText, stepText);
43
66
  if (score > bestScore) {
44
67
  bestScore = score;
45
68
  bestStep = step;
@@ -80,7 +103,7 @@ function checkConstraints(event, eventText, constraints) {
80
103
  continue;
81
104
  }
82
105
  if (constraint.type === "scope" && constraint.trigger) {
83
- const keywords = constraint.trigger.split(/\s+/).filter((w) => w.length > 3);
106
+ const keywords = extractKeywords(constraint.trigger);
84
107
  const violated = keywords.length > 0 && keywords.every((kw) => eventText.includes(kw));
85
108
  checks.push({
86
109
  constraintId: constraint.id,
@@ -161,11 +184,7 @@ function evaluatePlan(event, plan) {
161
184
  progress
162
185
  };
163
186
  }
164
- const eventText = [
165
- event.intent,
166
- event.tool ?? "",
167
- event.scope ?? ""
168
- ].join(" ").toLowerCase();
187
+ const eventText = normalizeEventText(event);
169
188
  const { matched, closest, closestScore } = findMatchingStep(eventText, event, plan.steps);
170
189
  if (!matched) {
171
190
  return {
@@ -206,7 +225,7 @@ function evaluatePlan(event, plan) {
206
225
  };
207
226
  }
208
227
  function buildPlanCheck(event, plan, verdict) {
209
- const eventText = [event.intent, event.tool ?? "", event.scope ?? ""].join(" ").toLowerCase();
228
+ const eventText = normalizeEventText(event);
210
229
  const { matched, closest, closestScore } = findMatchingStep(eventText, event, plan.steps);
211
230
  const { checks: constraintChecks } = checkConstraints(event, eventText, plan.constraints);
212
231
  const progress = getPlanProgress(plan);
@@ -225,6 +244,8 @@ function buildPlanCheck(event, plan, verdict) {
225
244
  }
226
245
 
227
246
  export {
247
+ normalizeEventText,
248
+ matchesAllKeywords,
228
249
  getPlanProgress,
229
250
  advancePlan,
230
251
  evaluatePlan,
@@ -0,0 +1,16 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+ var __glob = (map) => (path) => {
8
+ var fn = map[path];
9
+ if (fn) return fn();
10
+ throw new Error("Module not found in bundle: " + path);
11
+ };
12
+
13
+ export {
14
+ __require,
15
+ __glob
16
+ };
@@ -1,9 +1,20 @@
1
+ import {
2
+ evaluateGuard
3
+ } from "./chunk-W7LLXRGY.js";
4
+ import {
5
+ loadWorldFromDirectory
6
+ } from "./chunk-CTZHONLA.js";
7
+
1
8
  // src/adapters/autoresearch.ts
2
9
  var AutoresearchGovernor = class {
3
10
  config;
4
11
  state;
12
+ world;
13
+ engineOptions;
5
14
  constructor(config) {
6
15
  this.config = config;
16
+ this.world = config.world;
17
+ this.engineOptions = { trace: true };
7
18
  this.state = {
8
19
  experiments_run: 0,
9
20
  best_result: null,
@@ -33,10 +44,23 @@ var AutoresearchGovernor = class {
33
44
  }
34
45
  /**
35
46
  * Evaluate an experiment proposal against governance rules.
36
- * Returns a simplified verdict without requiring the full guard engine.
47
+ * Routes through the guard engine when a world is loaded,
48
+ * then layers on research-specific checks (budget, constraints, drift).
37
49
  */
38
50
  evaluateProposal(proposal) {
39
51
  const warnings = [];
52
+ const event = this.proposalToGuardEvent(proposal);
53
+ if (this.world) {
54
+ const verdict = evaluateGuard(event, this.world, this.engineOptions);
55
+ if (verdict.status === "BLOCK" || verdict.status === "PAUSE") {
56
+ return {
57
+ allowed: false,
58
+ reason: verdict.reason ?? `Governance ${verdict.status}: ${verdict.ruleId ?? "unknown rule"}`,
59
+ warnings,
60
+ verdict
61
+ };
62
+ }
63
+ }
40
64
  const estimatedMinutes = proposal.estimated_minutes || 5;
41
65
  if (this.state.total_compute_minutes + estimatedMinutes > this.config.computeBudgetMinutes) {
42
66
  return {
@@ -166,7 +190,12 @@ var AutoresearchGovernor = class {
166
190
  return { ...this.state };
167
191
  }
168
192
  };
193
+ async function createAutoresearchGovernor(worldPath, config) {
194
+ const world = await loadWorldFromDirectory(worldPath);
195
+ return new AutoresearchGovernor({ ...config, world, worldPath });
196
+ }
169
197
 
170
198
  export {
171
- AutoresearchGovernor
199
+ AutoresearchGovernor,
200
+ createAutoresearchGovernor
172
201
  };