@neuroverseos/governance 0.3.4 → 0.4.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 (129) hide show
  1. package/README.md +280 -405
  2. package/dist/adapters/autoresearch.cjs +63 -9
  3. package/dist/adapters/autoresearch.d.cts +2 -1
  4. package/dist/adapters/autoresearch.d.ts +2 -1
  5. package/dist/adapters/autoresearch.js +3 -3
  6. package/dist/adapters/deep-agents.cjs +63 -9
  7. package/dist/adapters/deep-agents.d.cts +3 -2
  8. package/dist/adapters/deep-agents.d.ts +3 -2
  9. package/dist/adapters/deep-agents.js +3 -3
  10. package/dist/adapters/express.cjs +63 -9
  11. package/dist/adapters/express.d.cts +2 -1
  12. package/dist/adapters/express.d.ts +2 -1
  13. package/dist/adapters/express.js +3 -3
  14. package/dist/adapters/index.cjs +961 -9
  15. package/dist/adapters/index.d.cts +4 -2
  16. package/dist/adapters/index.d.ts +4 -2
  17. package/dist/adapters/index.js +54 -17
  18. package/dist/adapters/langchain.cjs +63 -9
  19. package/dist/adapters/langchain.d.cts +3 -2
  20. package/dist/adapters/langchain.d.ts +3 -2
  21. package/dist/adapters/langchain.js +3 -3
  22. package/dist/adapters/mentraos.cjs +2181 -0
  23. package/dist/adapters/mentraos.d.cts +319 -0
  24. package/dist/adapters/mentraos.d.ts +319 -0
  25. package/dist/adapters/mentraos.js +48 -0
  26. package/dist/adapters/openai.cjs +63 -9
  27. package/dist/adapters/openai.d.cts +3 -2
  28. package/dist/adapters/openai.d.ts +3 -2
  29. package/dist/adapters/openai.js +3 -3
  30. package/dist/adapters/openclaw.cjs +63 -9
  31. package/dist/adapters/openclaw.d.cts +3 -2
  32. package/dist/adapters/openclaw.d.ts +3 -2
  33. package/dist/adapters/openclaw.js +3 -3
  34. package/dist/{add-ROOZLU62.js → add-XSANI3FK.js} +1 -1
  35. package/dist/{behavioral-MJO34S6Q.js → behavioral-SLW7ALEK.js} +4 -4
  36. package/dist/{bootstrap-CQRZVOXK.js → bootstrap-2OW5ZLBL.js} +4 -4
  37. package/dist/bootstrap-contract-DcV6t-8M.d.cts +216 -0
  38. package/dist/bootstrap-contract-DcV6t-8M.d.ts +216 -0
  39. package/dist/browser.global.js +149 -5
  40. package/dist/{build-ZHPMX5AZ.js → build-EGBGZFIJ.js} +6 -6
  41. package/dist/{chunk-A7GKPPU7.js → chunk-2VAWP6FI.js} +1 -1
  42. package/dist/{chunk-3WQLXYTP.js → chunk-3AYKQHYI.js} +2 -2
  43. package/dist/{chunk-EMQDLDAF.js → chunk-3NZMMSOW.js} +80 -2
  44. package/dist/chunk-3S5AD4AB.js +421 -0
  45. package/dist/{chunk-VXHSMA3I.js → chunk-6CV4XG3J.js} +1 -1
  46. package/dist/{chunk-BNKJPUPQ.js → chunk-A7SHG75T.js} +2 -2
  47. package/dist/{chunk-U6U7EJZL.js → chunk-AV7XJJWK.js} +2 -2
  48. package/dist/{chunk-ZWI3NIXK.js → chunk-CYDMUJVZ.js} +54 -3
  49. package/dist/{chunk-F66BVUYB.js → chunk-DA5MHFRR.js} +3 -3
  50. package/dist/{chunk-YEKMVDWK.js → chunk-FHXXD2TI.js} +7 -7
  51. package/dist/{chunk-5TPFNWRU.js → chunk-FS2UUJJO.js} +3 -3
  52. package/dist/{chunk-4FLICVVA.js → chunk-FVOGUCB6.js} +2 -2
  53. package/dist/chunk-GTPV2XGO.js +893 -0
  54. package/dist/{chunk-CTZHONLA.js → chunk-I4RTIMLX.js} +2 -2
  55. package/dist/{chunk-B6OXJLJ5.js → chunk-J2IZBHXJ.js} +4 -4
  56. package/dist/{chunk-TG6SEF24.js → chunk-OQU65525.js} +1 -1
  57. package/dist/{chunk-QXBFT7NI.js → chunk-QMVQ6KPL.js} +2 -2
  58. package/dist/{chunk-G7DJ6VOD.js → chunk-RDA7ISWC.js} +2 -2
  59. package/dist/{chunk-O5ABKEA7.js → chunk-YJ34R5NB.js} +2 -2
  60. package/dist/{chunk-PVTQQS3Y.js → chunk-YPCVY4GS.js} +31 -0
  61. package/dist/{chunk-W7LLXRGY.js → chunk-ZAF6JH23.js} +65 -10
  62. package/dist/{chunk-IS4WUH6Y.js → chunk-ZEIT2QLM.js} +4 -4
  63. package/dist/cli/neuroverse.cjs +4436 -1035
  64. package/dist/cli/neuroverse.js +40 -24
  65. package/dist/cli/plan.cjs +176 -12
  66. package/dist/cli/plan.js +2 -2
  67. package/dist/cli/run.cjs +63 -9
  68. package/dist/cli/run.js +2 -2
  69. package/dist/configure-world-XU2COHOZ.js +705 -0
  70. package/dist/{decision-flow-M63D47LO.js → decision-flow-3K4D72G4.js} +2 -2
  71. package/dist/{demo-G43RLCPK.js → demo-6OQYWRR6.js} +4 -4
  72. package/dist/{derive-LMDUTXDD.js → derive-7Y7YWVLU.js} +5 -5
  73. package/dist/{doctor-6BC6X2VO.js → doctor-NHXI7OQW.js} +3 -1
  74. package/dist/engine/bootstrap-emitter.cjs +241 -0
  75. package/dist/engine/bootstrap-emitter.d.cts +27 -0
  76. package/dist/engine/bootstrap-emitter.d.ts +27 -0
  77. package/dist/{bootstrap-emitter-Q7UIJZ2O.js → engine/bootstrap-emitter.js} +2 -2
  78. package/dist/engine/bootstrap-parser.cjs +560 -0
  79. package/dist/engine/bootstrap-parser.d.cts +96 -0
  80. package/dist/engine/bootstrap-parser.d.ts +96 -0
  81. package/dist/{bootstrap-parser-EEF36XDU.js → engine/bootstrap-parser.js} +2 -2
  82. package/dist/engine/guard-engine.cjs +1116 -0
  83. package/dist/engine/guard-engine.d.cts +60 -0
  84. package/dist/engine/guard-engine.d.ts +60 -0
  85. package/dist/engine/guard-engine.js +12 -0
  86. package/dist/engine/simulate-engine.cjs +390 -0
  87. package/dist/engine/simulate-engine.d.cts +105 -0
  88. package/dist/engine/simulate-engine.d.ts +105 -0
  89. package/dist/engine/simulate-engine.js +9 -0
  90. package/dist/{equity-penalties-SG5IZQ7I.js → equity-penalties-NVBAB5WL.js} +4 -4
  91. package/dist/{explain-RHBU2GBR.js → explain-HDFN4ION.js} +1 -1
  92. package/dist/github-TIKTWOGU.js +27 -0
  93. package/dist/{guard-AEEJNWLD.js → guard-6KSCWT2W.js} +4 -4
  94. package/dist/{guard-contract-B7lplwm9.d.cts → guard-contract-C991HDZp.d.cts} +32 -309
  95. package/dist/{guard-contract-B7lplwm9.d.ts → guard-contract-hHjTTjtR.d.ts} +32 -309
  96. package/dist/{impact-3XVDSCBU.js → impact-WIAM66IH.js} +3 -3
  97. package/dist/{improve-TQP4ECSY.js → improve-2PWGGO5B.js} +3 -3
  98. package/dist/index.cjs +682 -14
  99. package/dist/index.d.cts +231 -423
  100. package/dist/index.d.ts +231 -423
  101. package/dist/index.js +81 -58
  102. package/dist/{init-FYPV4SST.js → init-TKIJDR7I.js} +5 -1
  103. package/dist/lens-MHMUDCMQ.js +1084 -0
  104. package/dist/{mcp-server-5Y3ZM7TV.js → mcp-server-TNIWZ7B5.js} +3 -3
  105. package/dist/{playground-VZBNPPBO.js → playground-3FLDGBET.js} +3 -3
  106. package/dist/{redteam-MZPZD3EF.js → redteam-HV6LMKEH.js} +3 -3
  107. package/dist/{session-JYOARW54.js → session-XZP2754M.js} +3 -3
  108. package/dist/{shared-C_zpdvBm.d.cts → shared-DGnn1jiS.d.cts} +1 -1
  109. package/dist/{shared-Cf7yxx4-.d.ts → shared-U405h52W.d.ts} +1 -1
  110. package/dist/{simulate-LJXYBC6M.js → simulate-VT437EEL.js} +17 -4
  111. package/dist/spatial/index.cjs +682 -0
  112. package/dist/spatial/index.d.cts +517 -0
  113. package/dist/spatial/index.d.ts +517 -0
  114. package/dist/spatial/index.js +633 -0
  115. package/dist/{test-BOOR4A5F.js → test-4WTX6RKQ.js} +3 -3
  116. package/dist/{trace-PKV4KX56.js → trace-2YDNAXMK.js} +2 -2
  117. package/dist/types.cjs +18 -0
  118. package/dist/types.d.cts +370 -0
  119. package/dist/types.d.ts +370 -0
  120. package/dist/types.js +0 -0
  121. package/dist/{validate-RALX7CZS.js → validate-M52DX22Y.js} +1 -1
  122. package/dist/{world-BIP4GZBZ.js → world-O4HTQPDP.js} +1 -1
  123. package/dist/{world-loader-Y6HMQH2D.js → world-loader-YTYFOP7D.js} +1 -1
  124. package/dist/worlds/mentraos-smartglasses.nv-world.md +423 -0
  125. package/dist/worlds/mentraos-spatial.nv-world.md +68 -0
  126. package/dist/worlds/user-rules.nv-world.md +328 -0
  127. package/package.json +46 -3
  128. package/dist/guard-engine-PNR6MHCM.js +0 -10
  129. package/dist/{configure-ai-5MP5DWTT.js → configure-ai-LL3VAPQW.js} +3 -3
@@ -0,0 +1,560 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/engine/bootstrap-parser.ts
21
+ var bootstrap_parser_exports = {};
22
+ __export(bootstrap_parser_exports, {
23
+ parseWorldMarkdown: () => parseWorldMarkdown
24
+ });
25
+ module.exports = __toCommonJS(bootstrap_parser_exports);
26
+ function splitSections(markdown) {
27
+ const lines = markdown.split("\n");
28
+ let frontmatter = "";
29
+ let bodyStart = 0;
30
+ if (lines[0]?.trim() === "---") {
31
+ const endIdx = lines.indexOf("---", 1);
32
+ if (endIdx > 0) {
33
+ frontmatter = lines.slice(1, endIdx).join("\n");
34
+ bodyStart = endIdx + 1;
35
+ }
36
+ }
37
+ const sections = [];
38
+ let currentSection = null;
39
+ const contentLines = [];
40
+ for (let i = bodyStart; i < lines.length; i++) {
41
+ const line = lines[i];
42
+ if (line.startsWith("# ")) {
43
+ if (currentSection) {
44
+ currentSection.content = contentLines.join("\n").trim();
45
+ sections.push(currentSection);
46
+ contentLines.length = 0;
47
+ }
48
+ currentSection = {
49
+ name: line.replace(/^#\s+/, "").trim(),
50
+ content: "",
51
+ startLine: i + 1
52
+ // 1-based
53
+ };
54
+ } else if (currentSection) {
55
+ contentLines.push(line);
56
+ }
57
+ }
58
+ if (currentSection) {
59
+ currentSection.content = contentLines.join("\n").trim();
60
+ sections.push(currentSection);
61
+ }
62
+ return { frontmatter, sections };
63
+ }
64
+ function parseFrontmatter(yaml, issues) {
65
+ const result = {};
66
+ for (const line of yaml.split("\n")) {
67
+ const trimmed = line.trim();
68
+ if (!trimmed || trimmed.startsWith("#")) continue;
69
+ const colonIdx = trimmed.indexOf(":");
70
+ if (colonIdx === -1) continue;
71
+ const key = trimmed.slice(0, colonIdx).trim();
72
+ const value = trimmed.slice(colonIdx + 1).trim();
73
+ result[key] = value;
74
+ }
75
+ if (!result.world_id) {
76
+ issues.push({ line: 1, section: "frontmatter", message: "Missing world_id in frontmatter", severity: "error" });
77
+ }
78
+ if (!result.name) {
79
+ issues.push({ line: 1, section: "frontmatter", message: "Missing name in frontmatter", severity: "error" });
80
+ }
81
+ return {
82
+ world_id: result.world_id ?? "",
83
+ name: result.name ?? "",
84
+ version: result.version,
85
+ runtime_mode: result.runtime_mode,
86
+ default_profile: result.default_profile,
87
+ alternative_profile: result.alternative_profile
88
+ };
89
+ }
90
+ function parseThesis(content, startLine, issues) {
91
+ const thesis = content.trim();
92
+ if (!thesis) {
93
+ issues.push({ line: startLine, section: "Thesis", message: "Thesis section is empty", severity: "error" });
94
+ }
95
+ return thesis;
96
+ }
97
+ function parseInvariants(content, startLine, issues) {
98
+ const invariants = [];
99
+ const lines = content.split("\n");
100
+ for (let i = 0; i < lines.length; i++) {
101
+ const line = lines[i].trim();
102
+ if (!line.startsWith("- ")) continue;
103
+ const lineNum = startLine + i + 1;
104
+ const match = line.match(
105
+ /^-\s+`([^`]+)`\s*[—–-]\s*(.+?)(?:\s*\(([^)]+)\))?\s*$/
106
+ );
107
+ if (match) {
108
+ const id = match[1];
109
+ const label = match[2].trim();
110
+ const parens = match[3] ?? "structural, immutable";
111
+ const enforcement = parens.includes("prompt") ? "prompt" : parens.includes("operational") ? "operational" : "structural";
112
+ const mutable = parens.includes("mutable") && !parens.includes("immutable");
113
+ invariants.push({ id, label, enforcement, mutable, line: lineNum });
114
+ } else {
115
+ const fallback = line.match(/^-\s+\*\*([^*]+)\*\*\s*[—–-]\s*(.+)/);
116
+ if (fallback) {
117
+ const id = fallback[1].toLowerCase().replace(/\s+/g, "_");
118
+ const label = fallback[2].trim();
119
+ invariants.push({ id, label, enforcement: "structural", mutable: false, line: lineNum });
120
+ } else {
121
+ issues.push({ line: lineNum, section: "Invariants", message: `Could not parse invariant: "${line}"`, severity: "warning" });
122
+ }
123
+ }
124
+ }
125
+ if (invariants.length === 0) {
126
+ issues.push({ line: startLine, section: "Invariants", message: "No invariants found", severity: "error" });
127
+ }
128
+ return invariants;
129
+ }
130
+ function parseStateVariables(content, startLine, issues) {
131
+ const variables = [];
132
+ const subSections = splitH2Sections(content, startLine);
133
+ for (const sub of subSections) {
134
+ const props = parseKeyValueBullets(sub.content);
135
+ const lineNum = sub.startLine;
136
+ const type = props.type;
137
+ if (!type) {
138
+ issues.push({ line: lineNum, section: "State", message: `Variable "${sub.name}" missing type`, severity: "error" });
139
+ continue;
140
+ }
141
+ let defaultVal = props.default ?? "";
142
+ if (type === "number") {
143
+ defaultVal = parseFloat(String(defaultVal)) || 0;
144
+ } else if (type === "boolean") {
145
+ defaultVal = String(defaultVal).toLowerCase() === "true";
146
+ }
147
+ const variable = {
148
+ id: sub.name,
149
+ type,
150
+ default: defaultVal,
151
+ label: props.label ?? sub.name,
152
+ description: props.description ?? "",
153
+ line: lineNum
154
+ };
155
+ if (type === "number") {
156
+ if (props.min !== void 0) variable.min = parseFloat(props.min);
157
+ if (props.max !== void 0) variable.max = parseFloat(props.max);
158
+ if (props.step !== void 0) variable.step = parseFloat(props.step);
159
+ }
160
+ if (type === "enum" && props.options) {
161
+ variable.options = props.options.split(",").map((s) => s.trim());
162
+ }
163
+ variables.push(variable);
164
+ }
165
+ return variables;
166
+ }
167
+ function parseAssumptions(content, startLine, issues) {
168
+ const profiles = [];
169
+ const subSections = splitH2Sections(content, startLine);
170
+ for (const sub of subSections) {
171
+ const props = parseKeyValueBullets(sub.content);
172
+ const name = props.name ?? sub.name;
173
+ const description = props.description ?? "";
174
+ const parameters = {};
175
+ for (const [key, val] of Object.entries(props)) {
176
+ if (key === "name" || key === "description") continue;
177
+ if (val === "true") parameters[key] = true;
178
+ else if (val === "false") parameters[key] = false;
179
+ else if (!isNaN(Number(val)) && val.trim() !== "") parameters[key] = Number(val);
180
+ else parameters[key] = val;
181
+ }
182
+ profiles.push({
183
+ id: sub.name,
184
+ name,
185
+ description,
186
+ parameters,
187
+ line: sub.startLine
188
+ });
189
+ }
190
+ return profiles;
191
+ }
192
+ function parseRules(content, startLine, issues) {
193
+ const rules = [];
194
+ const subSections = splitH2Sections(content, startLine);
195
+ for (let ruleIdx = 0; ruleIdx < subSections.length; ruleIdx++) {
196
+ const sub = subSections[ruleIdx];
197
+ const lineNum = sub.startLine;
198
+ const headingMatch = sub.name.match(/^([^:]+):\s*(.+?)(?:\s*\(([^)]+)\))?\s*$/);
199
+ const id = headingMatch ? headingMatch[1].trim() : `rule-${String(ruleIdx + 1).padStart(3, "0")}`;
200
+ const label = headingMatch ? headingMatch[2].trim() : sub.name;
201
+ const severity = headingMatch?.[3]?.trim() ?? "degradation";
202
+ const lines = sub.content.split("\n");
203
+ let description = "";
204
+ const triggers = [];
205
+ const effects = [];
206
+ let collapseCheck;
207
+ const causalParts = {};
208
+ for (let i = 0; i < lines.length; i++) {
209
+ const line = lines[i].trim();
210
+ if (line.startsWith("When ")) {
211
+ const triggerStr = line.slice(5);
212
+ const parts = triggerStr.split(/\s+AND\s+/i);
213
+ for (const part of parts) {
214
+ const trigger = parseTriggerExpression(part.trim());
215
+ if (trigger) triggers.push(trigger);
216
+ else issues.push({ line: lineNum + i, section: "Rules", message: `Could not parse trigger: "${part}"`, severity: "warning" });
217
+ }
218
+ } else if (line.startsWith("Then ")) {
219
+ const effectStr = line.slice(5);
220
+ const parts = effectStr.split(",");
221
+ for (const part of parts) {
222
+ const effect = parseEffectExpression(part.trim());
223
+ if (effect) effects.push(effect);
224
+ else issues.push({ line: lineNum + i, section: "Rules", message: `Could not parse effect: "${part}"`, severity: "warning" });
225
+ }
226
+ } else if (line.startsWith("Collapse:")) {
227
+ const collapseStr = line.slice(9).trim();
228
+ const collapse = parseCollapseExpression(collapseStr);
229
+ if (collapse) collapseCheck = collapse;
230
+ else issues.push({ line: lineNum + i, section: "Rules", message: `Could not parse collapse: "${collapseStr}"`, severity: "warning" });
231
+ } else if (line.startsWith("> ")) {
232
+ const causalMatch = line.match(/^>\s*(trigger|rule|shift|effect):\s*(.+)/i);
233
+ if (causalMatch) {
234
+ causalParts[causalMatch[1].toLowerCase()] = causalMatch[2].trim();
235
+ }
236
+ } else if (line && !line.startsWith("-") && !line.startsWith("#")) {
237
+ if (!description) description = line;
238
+ else description += " " + line;
239
+ }
240
+ }
241
+ if (triggers.length === 0) {
242
+ issues.push({ line: lineNum, section: "Rules", message: `Rule "${id}" has no triggers (missing "When" line)`, severity: "warning" });
243
+ }
244
+ if (effects.length === 0) {
245
+ issues.push({ line: lineNum, section: "Rules", message: `Rule "${id}" has no effects (missing "Then" line)`, severity: "warning" });
246
+ }
247
+ const causal_translation = Object.keys(causalParts).length > 0 ? {
248
+ trigger_text: causalParts.trigger ?? "",
249
+ rule_text: causalParts.rule ?? "",
250
+ shift_text: causalParts.shift ?? "",
251
+ effect_text: causalParts.effect ?? ""
252
+ } : void 0;
253
+ rules.push({
254
+ id,
255
+ label,
256
+ severity,
257
+ description: description || void 0,
258
+ order: ruleIdx + 1,
259
+ triggers,
260
+ effects,
261
+ collapse_check: collapseCheck,
262
+ causal_translation,
263
+ line: lineNum
264
+ });
265
+ }
266
+ return rules;
267
+ }
268
+ function parseTriggerExpression(expr) {
269
+ const match = expr.match(
270
+ /^(\w+)\s*(==|!=|>=|<=|>|<|in)\s*(.+?)\s*\[(state|assumption)\]\s*$/
271
+ );
272
+ if (!match) return null;
273
+ const field = match[1];
274
+ const operator = match[2];
275
+ let value = match[3].trim();
276
+ const source = match[4];
277
+ value = parseValueLiteral(value);
278
+ return { field, operator, value, source };
279
+ }
280
+ function parseEffectExpression(expr) {
281
+ const compound = expr.match(/^(\w+)\s*(\*=|\+=|-=)\s*(.+)$/);
282
+ if (compound) {
283
+ const target = compound[1];
284
+ const op = compound[2];
285
+ const value = parseValueLiteral(compound[3].trim());
286
+ const operationMap = {
287
+ "*=": "multiply",
288
+ "+=": "add",
289
+ "-=": "subtract"
290
+ };
291
+ return { target, operation: operationMap[op], value };
292
+ }
293
+ const assignment = expr.match(/^(\w+)\s*=\s*(.+)$/);
294
+ if (assignment) {
295
+ const target = assignment[1];
296
+ const value = parseValueLiteral(assignment[2].trim());
297
+ const operation = typeof value === "boolean" ? "set_boolean" : "set";
298
+ return { target, operation, value };
299
+ }
300
+ return null;
301
+ }
302
+ function parseCollapseExpression(expr) {
303
+ const cleaned = expr.replace(/\s*→.*$/, "").trim();
304
+ const match = cleaned.match(/^(\w+)\s*(==|!=|>=|<=|>|<)\s*([\d.]+)$/);
305
+ if (!match) return null;
306
+ return {
307
+ field: match[1],
308
+ operator: match[2],
309
+ value: parseFloat(match[3])
310
+ };
311
+ }
312
+ function parseGates(content, startLine, issues) {
313
+ const gates = [];
314
+ const lines = content.split("\n");
315
+ for (let i = 0; i < lines.length; i++) {
316
+ const line = lines[i].trim();
317
+ if (!line.startsWith("- ")) continue;
318
+ const lineNum = startLine + i + 1;
319
+ const match = line.match(/^-\s+(\w+):\s*(\w+)\s*(==|!=|>=|<=|>|<)\s*([\d.]+)/);
320
+ if (match) {
321
+ gates.push({
322
+ status: match[1],
323
+ field: match[2],
324
+ operator: match[3],
325
+ value: parseFloat(match[4]),
326
+ line: lineNum
327
+ });
328
+ } else {
329
+ issues.push({ line: lineNum, section: "Gates", message: `Could not parse gate: "${line}"`, severity: "warning" });
330
+ }
331
+ }
332
+ if (gates.length === 0) {
333
+ issues.push({ line: startLine, section: "Gates", message: "No gates found", severity: "error" });
334
+ }
335
+ return gates;
336
+ }
337
+ function parseOutcomes(content, startLine, issues) {
338
+ const outcomes = [];
339
+ const subSections = splitH2Sections(content, startLine);
340
+ for (const sub of subSections) {
341
+ const props = parseKeyValueBullets(sub.content);
342
+ const outcome = {
343
+ id: sub.name,
344
+ type: props.type ?? "number",
345
+ label: props.label ?? sub.name,
346
+ line: sub.startLine
347
+ };
348
+ if (props.range) {
349
+ const rangeParts = props.range.split("-").map(Number);
350
+ if (rangeParts.length === 2 && !isNaN(rangeParts[0]) && !isNaN(rangeParts[1])) {
351
+ outcome.range = [rangeParts[0], rangeParts[1]];
352
+ }
353
+ }
354
+ if (props.display) outcome.display = props.display;
355
+ if (props.primary) outcome.primary = props.primary === "true";
356
+ if (props.assignment) outcome.assignment = props.assignment;
357
+ outcomes.push(outcome);
358
+ }
359
+ return outcomes;
360
+ }
361
+ function splitH2Sections(content, baseStartLine) {
362
+ const lines = content.split("\n");
363
+ const sections = [];
364
+ let current = null;
365
+ const contentLines = [];
366
+ for (let i = 0; i < lines.length; i++) {
367
+ const line = lines[i];
368
+ if (line.startsWith("## ")) {
369
+ if (current) {
370
+ current.content = contentLines.join("\n").trim();
371
+ sections.push(current);
372
+ contentLines.length = 0;
373
+ }
374
+ current = {
375
+ name: line.replace(/^##\s+/, "").trim(),
376
+ content: "",
377
+ startLine: baseStartLine + i + 1
378
+ };
379
+ } else if (current) {
380
+ contentLines.push(line);
381
+ }
382
+ }
383
+ if (current) {
384
+ current.content = contentLines.join("\n").trim();
385
+ sections.push(current);
386
+ }
387
+ return sections;
388
+ }
389
+ function parseKeyValueBullets(content) {
390
+ const result = {};
391
+ for (const line of content.split("\n")) {
392
+ const trimmed = line.trim();
393
+ const match = trimmed.match(/^-\s+(\w[\w\s]*?):\s*(.+)$/);
394
+ if (match) {
395
+ result[match[1].trim().toLowerCase().replace(/\s+/g, "_")] = match[2].trim();
396
+ }
397
+ }
398
+ return result;
399
+ }
400
+ function parseValueLiteral(raw) {
401
+ if (raw === "true") return true;
402
+ if (raw === "false") return false;
403
+ if (raw.startsWith('"') && raw.endsWith('"') || raw.startsWith("'") && raw.endsWith("'")) {
404
+ return raw.slice(1, -1);
405
+ }
406
+ const num = Number(raw);
407
+ if (!isNaN(num) && raw.trim() !== "") return num;
408
+ return raw;
409
+ }
410
+ function parseLenses(content, startLine, issues) {
411
+ const lenses = [];
412
+ const subSections = splitH2Sections(content, startLine);
413
+ for (const sub of subSections) {
414
+ const props = parseKeyValueBullets(sub.content);
415
+ const lineNum = sub.startLine;
416
+ const directives = [];
417
+ const lines = sub.content.split("\n");
418
+ let directiveIndex = 0;
419
+ for (let i = 0; i < lines.length; i++) {
420
+ const line = lines[i].trim();
421
+ if (line.startsWith(">")) {
422
+ const blockContent = line.slice(1).trim();
423
+ const colonIdx = blockContent.indexOf(":");
424
+ if (colonIdx > 0) {
425
+ const scope = blockContent.slice(0, colonIdx).trim();
426
+ let instruction = blockContent.slice(colonIdx + 1).trim();
427
+ for (let j = i + 1; j < lines.length; j++) {
428
+ const nextLine = lines[j].trim();
429
+ if (nextLine.startsWith(">")) {
430
+ const nextContent = nextLine.slice(1).trim();
431
+ const nextColon = nextContent.indexOf(":");
432
+ if (nextColon > 0 && !nextContent.slice(0, nextColon).includes(" ")) {
433
+ break;
434
+ }
435
+ instruction += " " + nextContent;
436
+ i = j;
437
+ } else {
438
+ break;
439
+ }
440
+ }
441
+ directives.push({
442
+ id: `${sub.name}_directive_${directiveIndex++}`,
443
+ scope,
444
+ instruction,
445
+ line: startLine + i
446
+ });
447
+ }
448
+ }
449
+ }
450
+ const tags = (props.tags ?? "").split(",").map((s) => s.trim()).filter(Boolean);
451
+ const defaultForRoles = (props.default_for_roles ?? props.roles ?? "").split(",").map((s) => s.trim()).filter(Boolean);
452
+ lenses.push({
453
+ id: sub.name,
454
+ name: props.name ?? sub.name,
455
+ tagline: props.tagline ?? "",
456
+ description: props.description ?? "",
457
+ tags,
458
+ formality: props.formality ?? "neutral",
459
+ verbosity: props.verbosity ?? "balanced",
460
+ emotion: props.emotion ?? "neutral",
461
+ confidence: props.confidence ?? "balanced",
462
+ defaultForRoles,
463
+ directives,
464
+ priority: props.priority ? parseInt(props.priority, 10) : 50,
465
+ stackable: props.stackable === "false" ? false : true,
466
+ line: lineNum
467
+ });
468
+ }
469
+ return lenses;
470
+ }
471
+ function parseWorldMarkdown(markdown) {
472
+ const issues = [];
473
+ const { frontmatter: fmRaw, sections } = splitSections(markdown);
474
+ const frontmatter = parseFrontmatter(fmRaw, issues);
475
+ const findSection = (name) => sections.find((s) => s.name.toLowerCase() === name.toLowerCase());
476
+ const thesisSection = findSection("Thesis");
477
+ const thesis = thesisSection ? parseThesis(thesisSection.content, thesisSection.startLine, issues) : "";
478
+ if (!thesisSection) {
479
+ issues.push({ line: 0, section: "Thesis", message: "Missing # Thesis section", severity: "error" });
480
+ }
481
+ const invariantsSection = findSection("Invariants");
482
+ const invariants = invariantsSection ? parseInvariants(invariantsSection.content, invariantsSection.startLine, issues) : [];
483
+ if (!invariantsSection) {
484
+ issues.push({ line: 0, section: "Invariants", message: "Missing # Invariants section", severity: "error" });
485
+ }
486
+ const stateSection = findSection("State");
487
+ const stateVariables = stateSection ? parseStateVariables(stateSection.content, stateSection.startLine, issues) : [];
488
+ if (!stateSection) {
489
+ issues.push({ line: 0, section: "State", message: "Missing # State section", severity: "warning" });
490
+ }
491
+ const assumptionsSection = findSection("Assumptions");
492
+ const assumptions = assumptionsSection ? parseAssumptions(assumptionsSection.content, assumptionsSection.startLine, issues) : [];
493
+ if (!assumptionsSection) {
494
+ issues.push({ line: 0, section: "Assumptions", message: "Missing # Assumptions section", severity: "warning" });
495
+ }
496
+ const rulesSection = findSection("Rules");
497
+ const rules = rulesSection ? parseRules(rulesSection.content, rulesSection.startLine, issues) : [];
498
+ if (!rulesSection) {
499
+ issues.push({ line: 0, section: "Rules", message: "Missing # Rules section", severity: "warning" });
500
+ }
501
+ const gatesSection = findSection("Gates");
502
+ const gates = gatesSection ? parseGates(gatesSection.content, gatesSection.startLine, issues) : [];
503
+ if (!gatesSection) {
504
+ issues.push({ line: 0, section: "Gates", message: "Missing # Gates section", severity: "warning" });
505
+ }
506
+ const outcomesSection = findSection("Outcomes");
507
+ const outcomes = outcomesSection ? parseOutcomes(outcomesSection.content, outcomesSection.startLine, issues) : [];
508
+ const lensesSection = findSection("Lenses");
509
+ const lenses = lensesSection ? parseLenses(lensesSection.content, lensesSection.startLine, issues) : [];
510
+ let lensPolicy;
511
+ let lensLockPin;
512
+ if (lensesSection) {
513
+ const topContent = lensesSection.content.split(/^##\s/m)[0];
514
+ const topProps = parseKeyValueBullets(topContent);
515
+ if (topProps.policy === "locked" || topProps.policy === "role_default" || topProps.policy === "user_choice") {
516
+ lensPolicy = topProps.policy;
517
+ }
518
+ if (topProps.lock_pin) {
519
+ lensLockPin = topProps.lock_pin;
520
+ }
521
+ }
522
+ const parsedSections = sections.map((s) => s.name);
523
+ const knownSections = /* @__PURE__ */ new Set(["thesis", "invariants", "state", "assumptions", "rules", "gates", "outcomes", "lenses"]);
524
+ for (const section of sections) {
525
+ if (!knownSections.has(section.name.toLowerCase())) {
526
+ issues.push({
527
+ line: section.startLine,
528
+ section: section.name,
529
+ message: `Unrecognized section "${section.name}" \u2014 will be ignored`,
530
+ severity: "info"
531
+ });
532
+ }
533
+ }
534
+ const hasErrors = issues.some((i) => i.severity === "error");
535
+ if (!frontmatter.world_id || !thesis) {
536
+ if (hasErrors) {
537
+ return { world: null, issues };
538
+ }
539
+ }
540
+ return {
541
+ world: {
542
+ frontmatter,
543
+ thesis,
544
+ invariants,
545
+ stateVariables,
546
+ assumptions,
547
+ rules,
548
+ gates,
549
+ outcomes,
550
+ lenses,
551
+ lensPolicy,
552
+ lensLockPin
553
+ },
554
+ issues
555
+ };
556
+ }
557
+ // Annotate the CommonJS export names for ESM import in node:
558
+ 0 && (module.exports = {
559
+ parseWorldMarkdown
560
+ });
@@ -0,0 +1,96 @@
1
+ import { P as ParsedWorld, a as ParseIssue } from '../bootstrap-contract-DcV6t-8M.cjs';
2
+
3
+ /**
4
+ * Bootstrap Parser — .nv-world.md → ParsedWorld
5
+ *
6
+ * Deterministic markdown parser for the NeuroVerse world authoring format.
7
+ * No LLM calls. No heuristics. Pattern matching on structured markdown.
8
+ *
9
+ * ## Markdown Format (.nv-world.md)
10
+ *
11
+ * ```markdown
12
+ * ---
13
+ * world_id: my-world
14
+ * name: My World
15
+ * version: 1.0.0
16
+ * default_profile: baseline
17
+ * alternative_profile: alternative
18
+ * ---
19
+ *
20
+ * # Thesis
21
+ * The structural claim this world tests...
22
+ *
23
+ * # Invariants
24
+ * - `invariant_id` — Label text (structural, immutable)
25
+ * - `another_id` — Another label (structural, immutable)
26
+ *
27
+ * # State
28
+ * ## variable_name
29
+ * - type: number
30
+ * - min: 0
31
+ * - max: 100
32
+ * - step: 5
33
+ * - default: 50
34
+ * - label: Human Label
35
+ * - description: What this variable represents
36
+ *
37
+ * ## another_variable
38
+ * - type: enum
39
+ * - options: option_a, option_b, option_c
40
+ * - default: option_a
41
+ * - label: Another Variable
42
+ * - description: Description here
43
+ *
44
+ * # Assumptions
45
+ * ## baseline
46
+ * - name: Baseline Scenario
47
+ * - description: The default conditions
48
+ * - param_key: param_value
49
+ *
50
+ * ## alternative
51
+ * - name: Alternative Scenario
52
+ * - description: What changes
53
+ * - param_key: different_value
54
+ *
55
+ * # Rules
56
+ * ## rule-001: Rule Label (structural)
57
+ * Description of what this rule does.
58
+ *
59
+ * When field == "value" [state] AND other_field > 50 [assumption]
60
+ * Then target *= 0.30, other_target = false
61
+ * Collapse: field < 0.03
62
+ *
63
+ * > trigger: Trigger text here
64
+ * > rule: Rule text here
65
+ * > shift: Shift text here
66
+ * > effect: Effect text here
67
+ *
68
+ * # Gates
69
+ * - THRIVING: effective_margin >= 40
70
+ * - STABLE: effective_margin >= 20
71
+ * - COMPRESSED: effective_margin >= 10
72
+ * - CRITICAL: effective_margin > 3
73
+ * - MODEL_COLLAPSES: effective_margin <= 3
74
+ *
75
+ * # Outcomes
76
+ * ## outcome_id
77
+ * - type: number
78
+ * - range: 0-100
79
+ * - display: percentage
80
+ * - label: Outcome Label
81
+ * - primary: true
82
+ * ```
83
+ */
84
+
85
+ /**
86
+ * Parse a .nv-world.md string into a ParsedWorld.
87
+ *
88
+ * Returns the parsed world and a list of issues.
89
+ * Callers should check issues for severity === 'error' before proceeding.
90
+ */
91
+ declare function parseWorldMarkdown(markdown: string): {
92
+ world: ParsedWorld | null;
93
+ issues: ParseIssue[];
94
+ };
95
+
96
+ export { parseWorldMarkdown };