@neuroverseos/governance 0.3.1 → 0.3.4

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 (133) hide show
  1. package/.well-known/ai-plugin.json +34 -9
  2. package/AGENTS.md +72 -24
  3. package/README.md +343 -248
  4. package/dist/adapters/autoresearch.cjs +1345 -0
  5. package/dist/adapters/autoresearch.d.cts +111 -0
  6. package/dist/adapters/autoresearch.d.ts +111 -0
  7. package/dist/adapters/autoresearch.js +12 -0
  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 +1253 -0
  13. package/dist/adapters/express.d.cts +66 -0
  14. package/dist/adapters/express.d.ts +66 -0
  15. package/dist/adapters/express.js +12 -0
  16. package/dist/adapters/index.cjs +2112 -0
  17. package/dist/adapters/index.d.cts +8 -0
  18. package/dist/adapters/index.d.ts +8 -0
  19. package/dist/adapters/index.js +68 -0
  20. package/dist/adapters/langchain.cjs +1315 -0
  21. package/dist/adapters/langchain.d.cts +89 -0
  22. package/dist/adapters/langchain.d.ts +89 -0
  23. package/dist/adapters/langchain.js +17 -0
  24. package/dist/adapters/openai.cjs +1345 -0
  25. package/dist/adapters/openai.d.cts +99 -0
  26. package/dist/adapters/openai.d.ts +99 -0
  27. package/dist/adapters/openai.js +17 -0
  28. package/dist/adapters/openclaw.cjs +1337 -0
  29. package/dist/adapters/openclaw.d.cts +99 -0
  30. package/dist/adapters/openclaw.d.ts +99 -0
  31. package/dist/adapters/openclaw.js +17 -0
  32. package/dist/add-ROOZLU62.js +314 -0
  33. package/dist/behavioral-MJO34S6Q.js +118 -0
  34. package/dist/bootstrap-CQRZVOXK.js +116 -0
  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-ZHPMX5AZ.js +342 -0
  39. package/dist/chunk-3WQLXYTP.js +91 -0
  40. package/dist/chunk-4FLICVVA.js +119 -0
  41. package/dist/chunk-4NGDRRQH.js +10 -0
  42. package/dist/chunk-5TPFNWRU.js +215 -0
  43. package/dist/chunk-5U2MQO5P.js +57 -0
  44. package/dist/chunk-6CZSKEY5.js +164 -0
  45. package/dist/chunk-7P3S7MAY.js +1090 -0
  46. package/dist/chunk-A5W4GNQO.js +130 -0
  47. package/dist/chunk-A7GKPPU7.js +226 -0
  48. package/dist/chunk-AKW5YVCE.js +96 -0
  49. package/dist/chunk-B6OXJLJ5.js +622 -0
  50. package/dist/chunk-BNKJPUPQ.js +113 -0
  51. package/dist/chunk-BQZMOEML.js +43 -0
  52. package/dist/chunk-CNSO6XW5.js +207 -0
  53. package/dist/chunk-CTZHONLA.js +135 -0
  54. package/dist/chunk-D2UCV5AK.js +326 -0
  55. package/dist/chunk-EMQDLDAF.js +458 -0
  56. package/dist/chunk-F66BVUYB.js +340 -0
  57. package/dist/chunk-FMSTRBBS.js +17 -0
  58. package/dist/chunk-G7DJ6VOD.js +101 -0
  59. package/dist/chunk-I3RRAYK2.js +11 -0
  60. package/dist/chunk-INWQHLPS.js +47 -0
  61. package/dist/chunk-IS4WUH6Y.js +363 -0
  62. package/dist/chunk-O5ABKEA7.js +304 -0
  63. package/dist/chunk-OT6PXH54.js +61 -0
  64. package/dist/chunk-PVTQQS3Y.js +186 -0
  65. package/dist/chunk-QLPTHTVB.js +253 -0
  66. package/dist/chunk-QWGCMQQD.js +16 -0
  67. package/dist/chunk-QXBFT7NI.js +201 -0
  68. package/dist/chunk-TG6SEF24.js +246 -0
  69. package/dist/chunk-U6U7EJZL.js +177 -0
  70. package/dist/chunk-VXHSMA3I.js +166 -0
  71. package/dist/chunk-W7LLXRGY.js +830 -0
  72. package/dist/chunk-YEKMVDWK.js +624 -0
  73. package/dist/chunk-ZJTDUCC2.js +194 -0
  74. package/dist/chunk-ZWI3NIXK.js +314 -0
  75. package/dist/cli/neuroverse.cjs +14379 -0
  76. package/dist/cli/neuroverse.d.cts +1 -0
  77. package/dist/cli/neuroverse.d.ts +1 -0
  78. package/dist/cli/neuroverse.js +227 -0
  79. package/dist/cli/plan.cjs +2439 -0
  80. package/dist/cli/plan.d.cts +20 -0
  81. package/dist/cli/plan.d.ts +20 -0
  82. package/dist/cli/plan.js +353 -0
  83. package/dist/cli/run.cjs +2001 -0
  84. package/dist/cli/run.d.cts +20 -0
  85. package/dist/cli/run.d.ts +20 -0
  86. package/dist/cli/run.js +143 -0
  87. package/dist/configure-ai-5MP5DWTT.js +134 -0
  88. package/dist/decision-flow-M63D47LO.js +61 -0
  89. package/dist/demo-G43RLCPK.js +469 -0
  90. package/dist/derive-LMDUTXDD.js +154 -0
  91. package/dist/doctor-6BC6X2VO.js +173 -0
  92. package/dist/equity-penalties-SG5IZQ7I.js +244 -0
  93. package/dist/explain-RHBU2GBR.js +51 -0
  94. package/dist/guard-AEEJNWLD.js +126 -0
  95. package/dist/guard-contract-B7lplwm9.d.cts +837 -0
  96. package/dist/guard-contract-B7lplwm9.d.ts +837 -0
  97. package/dist/guard-engine-PNR6MHCM.js +10 -0
  98. package/dist/impact-3XVDSCBU.js +59 -0
  99. package/dist/improve-TQP4ECSY.js +66 -0
  100. package/dist/index.cjs +7738 -0
  101. package/dist/index.d.cts +2350 -0
  102. package/dist/index.d.ts +2350 -0
  103. package/dist/index.js +479 -0
  104. package/dist/infer-world-IFXCACJ5.js +543 -0
  105. package/dist/init-FYPV4SST.js +144 -0
  106. package/dist/init-world-TI7ARHBT.js +223 -0
  107. package/dist/mcp-server-5Y3ZM7TV.js +13 -0
  108. package/dist/model-adapter-VXEKB4LS.js +11 -0
  109. package/dist/playground-VZBNPPBO.js +560 -0
  110. package/dist/redteam-MZPZD3EF.js +357 -0
  111. package/dist/session-JYOARW54.js +15 -0
  112. package/dist/shared-7RLUHNMU.js +16 -0
  113. package/dist/shared-C_zpdvBm.d.cts +60 -0
  114. package/dist/shared-Cf7yxx4-.d.ts +60 -0
  115. package/dist/simulate-LJXYBC6M.js +83 -0
  116. package/dist/test-BOOR4A5F.js +217 -0
  117. package/dist/trace-PKV4KX56.js +166 -0
  118. package/dist/validate-RALX7CZS.js +81 -0
  119. package/dist/validate-engine-7ZXFVGF2.js +7 -0
  120. package/dist/viz/assets/index-B8SaeJZZ.js +23 -0
  121. package/dist/viz/index.html +23 -0
  122. package/dist/world-BIP4GZBZ.js +376 -0
  123. package/dist/world-loader-Y6HMQH2D.js +13 -0
  124. package/dist/worlds/autoresearch.nv-world.md +230 -0
  125. package/dist/worlds/coding-agent.nv-world.md +211 -0
  126. package/dist/worlds/derivation-world.nv-world.md +278 -0
  127. package/dist/worlds/research-agent.nv-world.md +169 -0
  128. package/dist/worlds/social-media.nv-world.md +198 -0
  129. package/dist/worlds/trading-agent.nv-world.md +218 -0
  130. package/examples/social-media-sim/bridge.py +209 -0
  131. package/examples/social-media-sim/simulation.py +927 -0
  132. package/package.json +16 -3
  133. package/simulate.html +4 -336
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neuroverseos/governance",
3
- "version": "0.3.1",
3
+ "version": "0.3.4",
4
4
  "description": "Deterministic governance engine for AI agents — enforce worlds (permanent rules) and plans (mission constraints) with full audit trace",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -60,7 +60,10 @@
60
60
  "files": [
61
61
  "dist",
62
62
  "dist/worlds",
63
+ "dist/viz",
64
+ "dist/browser.global.js",
63
65
  "policies",
66
+ "examples/social-media-sim",
64
67
  "simulate.html",
65
68
  "LICENSE.md",
66
69
  "README.md",
@@ -70,16 +73,26 @@
70
73
  ".well-known"
71
74
  ],
72
75
  "scripts": {
73
- "build": "tsup src/index.ts src/cli/neuroverse.ts src/cli/plan.ts src/cli/run.ts src/adapters/index.ts src/adapters/langchain.ts src/adapters/openai.ts src/adapters/openclaw.ts src/adapters/express.ts src/adapters/autoresearch.ts src/adapters/deep-agents.ts --format esm,cjs --dts --clean && cp src/worlds/*.nv-world.md dist/worlds/",
76
+ "build": "tsup src/index.ts src/cli/neuroverse.ts src/cli/plan.ts src/cli/run.ts src/adapters/index.ts src/adapters/langchain.ts src/adapters/openai.ts src/adapters/openclaw.ts src/adapters/express.ts src/adapters/autoresearch.ts src/adapters/deep-agents.ts --format esm,cjs --dts --clean && npm run build:browser && cp src/worlds/*.nv-world.md dist/worlds/ && npm run build:viz",
77
+ "build:browser": "tsup src/browser.ts --format iife --global-name NeuroVerse --outDir dist --no-dts",
78
+ "build:viz": "vite build",
79
+ "dev:viz": "vite dev",
74
80
  "prebuild": "mkdir -p dist/worlds",
75
81
  "dev": "tsup src/index.ts src/cli/neuroverse.ts --format esm,cjs --dts --watch",
82
+ "prepublishOnly": "npm run build",
76
83
  "test": "vitest run",
77
84
  "test:watch": "vitest"
78
85
  },
79
86
  "devDependencies": {
80
87
  "@types/node": "^25.3.3",
88
+ "@types/react": "^19.2.14",
89
+ "@types/react-dom": "^19.2.3",
90
+ "@vitejs/plugin-react": "^6.0.1",
91
+ "react": "^19.2.4",
92
+ "react-dom": "^19.2.4",
81
93
  "tsup": "^8.0.0",
82
94
  "typescript": "^5.3.0",
95
+ "vite": "^8.0.1",
83
96
  "vitest": "^2.0.0"
84
97
  },
85
98
  "keywords": [
@@ -116,7 +129,7 @@
116
129
  "url": "https://github.com/NeuroverseOS/Neuroverseos-governance.git"
117
130
  },
118
131
  "engines": {
119
- "node": ">=18"
132
+ "node": ">=20"
120
133
  },
121
134
  "homepage": "https://neuroverseos.com"
122
135
  }
package/simulate.html CHANGED
@@ -727,6 +727,7 @@
727
727
  </div>
728
728
  </div>
729
729
 
730
+ <script src="dist/browser.global.js"></script>
730
731
  <script>
731
732
  // ═══════════════════════════════════════════════════════════════════════════
732
733
  // MATRIX RAIN
@@ -766,344 +767,11 @@ function drawMatrix() {
766
767
  setInterval(drawMatrix, 50);
767
768
 
768
769
  // ═══════════════════════════════════════════════════════════════════════════
769
- // WORLD PARSER (Simplified .nv-world.md → WorldDefinition)
770
+ // ENGINE loaded from dist/browser.global.js (NeuroVerse.simulateWorld,
771
+ // NeuroVerse.parseWorldMarkdown). One engine, one execution path, no drift.
770
772
  // ═══════════════════════════════════════════════════════════════════════════
771
773
 
772
- function parseWorldMarkdown(md) {
773
- const world = {
774
- world: { world_id: '', name: '', thesis: '', version: '1.0.0', runtime_mode: 'SIMULATION',
775
- default_assumption_profile: '', default_alternative_profile: '', modules: [],
776
- players: { thinking_space: true, experience_space: true, action_space: true } },
777
- invariants: [],
778
- assumptions: { profiles: {}, parameter_definitions: {} },
779
- stateSchema: { variables: {}, presets: {} },
780
- rules: [],
781
- gates: { viability_classification: [], structural_override: { description: 'Structural violations override all gates', enforcement: 'mandatory' },
782
- sustainability_threshold: 50, collapse_visual: { background: '#1a0000', text: '#ff4444', border: '#ff0000', label: 'COLLAPSED' } },
783
- outcomes: { computed_outcomes: [], comparison_layout: { primary_card: '', status_badge: '', structural_indicators: [] } },
784
- metadata: { format_version: '1.0.0', created_at: new Date().toISOString(), last_modified: new Date().toISOString(), authoring_method: 'manual-authoring' }
785
- };
786
-
787
- // Parse frontmatter
788
- const fmMatch = md.match(/^---\n([\s\S]*?)\n---/);
789
- if (fmMatch) {
790
- const fm = fmMatch[1];
791
- const getVal = (key) => { const m = fm.match(new RegExp(key + ':\\s*(.+)')); return m ? m[1].trim() : ''; };
792
- world.world.world_id = getVal('world_id');
793
- world.world.name = getVal('name');
794
- world.world.version = getVal('version') || '1.0.0';
795
- world.world.runtime_mode = getVal('runtime_mode') || 'SIMULATION';
796
- world.world.default_assumption_profile = getVal('default_profile');
797
- world.world.default_alternative_profile = getVal('alternative_profile');
798
- }
799
-
800
- // Split sections
801
- const sections = {};
802
- let currentSection = null;
803
- for (const line of md.split('\n')) {
804
- const h1 = line.match(/^# (.+)/);
805
- if (h1) { currentSection = h1[1].trim().toLowerCase(); sections[currentSection] = ''; continue; }
806
- if (currentSection) sections[currentSection] += line + '\n';
807
- }
808
-
809
- // Thesis
810
- world.world.thesis = (sections['thesis'] || '').trim();
811
-
812
- // Invariants
813
- if (sections['invariants']) {
814
- for (const line of sections['invariants'].split('\n')) {
815
- const m = line.match(/^- `([^`]+)` — (.+?) \((\w+), (\w+)\)/);
816
- if (m) world.invariants.push({ id: m[1], label: m[2], enforcement: m[3], mutable: false });
817
- }
818
- }
819
-
820
- // State
821
- if (sections['state']) {
822
- let varId = null;
823
- const vars = {};
824
- for (const line of sections['state'].split('\n')) {
825
- const h2 = line.match(/^## (\w+)/);
826
- if (h2) { varId = h2[1]; vars[varId] = { type: 'number', default: 0, mutable: true, label: varId, description: '' }; continue; }
827
- if (!varId) continue;
828
- const kv = line.match(/^- (\w+):\s*(.+)/);
829
- if (kv) {
830
- const [, k, v] = kv;
831
- if (k === 'type') vars[varId].type = v.trim();
832
- else if (k === 'min') vars[varId].min = parseFloat(v);
833
- else if (k === 'max') vars[varId].max = parseFloat(v);
834
- else if (k === 'step') vars[varId].step = parseFloat(v);
835
- else if (k === 'default') vars[varId].default = isNaN(+v) ? v.trim() : parseFloat(v);
836
- else if (k === 'label') vars[varId].label = v.trim();
837
- else if (k === 'description') vars[varId].description = v.trim();
838
- }
839
- }
840
- world.stateSchema.variables = vars;
841
- }
842
-
843
- // Assumptions
844
- if (sections['assumptions']) {
845
- let profId = null;
846
- for (const line of sections['assumptions'].split('\n')) {
847
- const h2 = line.match(/^## (\w+)/);
848
- if (h2) { profId = h2[1]; world.assumptions.profiles[profId] = { name: '', description: '', parameters: {} }; continue; }
849
- if (!profId) continue;
850
- const kv = line.match(/^- (\w+):\s*(.+)/);
851
- if (kv) {
852
- const [, k, v] = kv;
853
- if (k === 'name') world.assumptions.profiles[profId].name = v.trim();
854
- else if (k === 'description') world.assumptions.profiles[profId].description = v.trim();
855
- else world.assumptions.profiles[profId].parameters[k] = v.trim();
856
- }
857
- }
858
- if (world.world.default_assumption_profile) {
859
- const p = world.assumptions.profiles[world.world.default_assumption_profile];
860
- if (p) p.is_default_baseline = true;
861
- }
862
- }
863
-
864
- // Rules
865
- if (sections['rules']) {
866
- const ruleBlocks = sections['rules'].split(/^## /m).filter(Boolean);
867
- let order = 0;
868
- for (const block of ruleBlocks) {
869
- const headerMatch = block.match(/^(rule-\d+):\s*(.+?)\s*\((\w+)\)/);
870
- if (!headerMatch) continue;
871
- const [, ruleId, label, severity] = headerMatch;
872
- const lines = block.split('\n');
873
- let description = '';
874
- const triggers = [];
875
- const effects = [];
876
- let collapseCheck = null;
877
- const causal = { trigger_text: '', rule_text: '', shift_text: '', effect_text: '' };
878
-
879
- for (const line of lines) {
880
- // Triggers: When field op value [source] (AND field op value [source])*
881
- const whenMatch = line.match(/^When (.+)/);
882
- if (whenMatch) {
883
- const parts = whenMatch[1].split(/\s+AND\s+/);
884
- for (const part of parts) {
885
- const tm = part.match(/(\w+)\s*(==|!=|>=|<=|>|<)\s*([\w.]+)\s*\[(\w+)\]/);
886
- if (tm) triggers.push({ field: tm[1], operator: tm[2], value: isNaN(+tm[3]) ? tm[3] : parseFloat(tm[3]), source: tm[4] });
887
- }
888
- }
889
- // Effects: Then target *= value or target += value
890
- const thenMatch = line.match(/^Then (\w+)\s*(\*=|\+=|-=|=)\s*([\w.]+)/);
891
- if (thenMatch) {
892
- const opMap = { '*=': 'multiply', '+=': 'add', '-=': 'subtract', '=': 'set' };
893
- effects.push({ target: thenMatch[1], operation: opMap[thenMatch[2]] || 'set', value: isNaN(+thenMatch[3]) ? thenMatch[3] : parseFloat(thenMatch[3]) });
894
- }
895
- // Collapse
896
- const collapseMatch = line.match(/^Collapse:\s*(\w+)\s*(==|!=|>=|<=|>|<)\s*([\w.]+)/);
897
- if (collapseMatch) {
898
- collapseCheck = { field: collapseMatch[1], operator: collapseMatch[2], value: parseFloat(collapseMatch[3]), result: 'MODEL_COLLAPSES' };
899
- }
900
- // Causal
901
- const causalMatch = line.match(/^> (\w+):\s*(.+)/);
902
- if (causalMatch) causal[causalMatch[1] + '_text'] = causalMatch[2];
903
-
904
- // Description (first non-header, non-directive line)
905
- if (!line.startsWith('When ') && !line.startsWith('Then ') && !line.startsWith('Collapse:') && !line.startsWith('>') && !line.match(/^rule-/) && line.trim() && !description) {
906
- description = line.trim();
907
- }
908
- }
909
-
910
- world.rules.push({ id: ruleId, severity, label, description, order: order++, triggers, effects, collapse_check: collapseCheck, causal_translation: causal });
911
- world.world.modules.push(ruleId);
912
- }
913
- }
914
-
915
- // Gates
916
- if (sections['gates']) {
917
- const gateColors = { 0: '#00ff41', 1: '#00cc33', 2: '#ffaa00', 3: '#ff6600', 4: '#ff4444' };
918
- const gateIcons = { 0: '\u2726', 1: '\u25CF', 2: '\u25B2', 3: '\u26A0', 4: '\u2715' };
919
- let gi = 0;
920
- for (const line of sections['gates'].split('\n')) {
921
- const gm = line.match(/^- (\w+):\s*(\w+)\s*(>=|<=|>|<|==)\s*([\d.]+)/);
922
- if (gm) {
923
- world.gates.viability_classification.push({
924
- status: gm[1], field: gm[2], operator: gm[3], value: parseFloat(gm[4]),
925
- color: gateColors[gi] || '#888', icon: gateIcons[gi] || '?'
926
- });
927
- gi++;
928
- }
929
- }
930
- }
931
-
932
- // Outcomes
933
- if (sections['outcomes']) {
934
- let outId = null;
935
- for (const line of sections['outcomes'].split('\n')) {
936
- const h2 = line.match(/^## (\w+)/);
937
- if (h2) {
938
- outId = h2[1];
939
- world.outcomes.computed_outcomes.push({ id: outId, type: 'number', label: outId, show_in_comparison: true });
940
- continue;
941
- }
942
- if (!outId) continue;
943
- const out = world.outcomes.computed_outcomes.find(o => o.id === outId);
944
- if (!out) continue;
945
- const kv = line.match(/^- (\w+):\s*(.+)/);
946
- if (kv) {
947
- if (kv[1] === 'type') out.type = kv[2].trim();
948
- if (kv[1] === 'range') { const r = kv[2].match(/([\d.-]+)-([\d.-]+)/); if (r) out.range = [parseFloat(r[1]), parseFloat(r[2])]; }
949
- if (kv[1] === 'display') out.display_as = kv[2].trim();
950
- if (kv[1] === 'label') out.label = kv[2].trim();
951
- if (kv[1] === 'primary' && kv[2].trim() === 'true') { out.primary = true; world.outcomes.comparison_layout.primary_card = outId; }
952
- }
953
- }
954
- }
955
-
956
- return world;
957
- }
958
-
959
- // ═══════════════════════════════════════════════════════════════════════════
960
- // SIMULATE ENGINE (Pure deterministic simulation)
961
- // ═══════════════════════════════════════════════════════════════════════════
962
-
963
- function evaluateOperator(fieldValue, operator, condValue) {
964
- switch (operator) {
965
- case '==': return fieldValue == condValue;
966
- case '!=': return fieldValue != condValue;
967
- case '>': return typeof fieldValue === 'number' && typeof condValue === 'number' && fieldValue > condValue;
968
- case '<': return typeof fieldValue === 'number' && typeof condValue === 'number' && fieldValue < condValue;
969
- case '>=': return typeof fieldValue === 'number' && typeof condValue === 'number' && fieldValue >= condValue;
970
- case '<=': return typeof fieldValue === 'number' && typeof condValue === 'number' && fieldValue <= condValue;
971
- default: return false;
972
- }
973
- }
974
-
975
- function evaluateTriggers(triggers, state, assumptions) {
976
- return triggers.every(t => {
977
- const source = t.source === 'assumption' ? assumptions : state;
978
- const val = source[t.field];
979
- if (val === undefined) return false;
980
- return evaluateOperator(val, t.operator, t.value);
981
- });
982
- }
983
-
984
- function applyEffect(state, effect) {
985
- const before = state[effect.target];
986
- let after = before;
987
- const val = typeof effect.value === 'number' ? effect.value : parseFloat(effect.value);
988
-
989
- switch (effect.operation) {
990
- case 'multiply': after = typeof before === 'number' ? before * val : before; break;
991
- case 'add': after = typeof before === 'number' ? before + val : before; break;
992
- case 'subtract': after = typeof before === 'number' ? before - val : before; break;
993
- case 'set': after = val; break;
994
- }
995
-
996
- state[effect.target] = typeof after === 'number' ? Math.round(after * 100) / 100 : after;
997
- return { target: effect.target, operation: effect.operation, value: effect.value, before, after: state[effect.target] };
998
- }
999
-
1000
- function classifyViability(state, world) {
1001
- const gates = world.gates?.viability_classification ?? [];
1002
- for (const gate of gates) {
1003
- const val = state[gate.field];
1004
- if (typeof val !== 'number') continue;
1005
- if (evaluateOperator(val, gate.operator, gate.value)) return gate.status;
1006
- }
1007
- return 'MODEL_COLLAPSES';
1008
- }
1009
-
1010
- function simulateWorld(world, options = {}) {
1011
- const steps = Math.min(50, Math.max(1, options.steps || 1));
1012
- const profile = options.profile || world.world.default_assumption_profile;
1013
-
1014
- // Build initial state from schema defaults
1015
- const state = {};
1016
- for (const [k, v] of Object.entries(world.stateSchema.variables)) {
1017
- state[k] = v.default;
1018
- }
1019
-
1020
- // Initialize outcome fields (primary outcome starts at 100)
1021
- for (const out of world.outcomes.computed_outcomes) {
1022
- if (out.primary && !(out.id in state)) state[out.id] = 100;
1023
- else if (!(out.id in state)) state[out.id] = out.default || 0;
1024
- }
1025
-
1026
- // Apply state overrides
1027
- if (options.stateOverrides) {
1028
- for (const [k, v] of Object.entries(options.stateOverrides)) {
1029
- state[k] = v;
1030
- }
1031
- }
1032
-
1033
- // Get assumption parameters
1034
- const assumptions = world.assumptions?.profiles?.[profile]?.parameters || {};
1035
-
1036
- const initialState = { ...state };
1037
- const simSteps = [];
1038
- let collapsed = false;
1039
- let collapseStep, collapseRule;
1040
-
1041
- for (let s = 0; s < steps; s++) {
1042
- const ruleEvals = [];
1043
- let firedThisStep = [];
1044
- let stepCollapsed = false;
1045
-
1046
- for (const rule of world.rules) {
1047
- if (collapsed) {
1048
- ruleEvals.push({ ruleId: rule.id, label: rule.label, triggered: false, excluded: true, effects: [], collapsed: false, severity: rule.severity });
1049
- continue;
1050
- }
1051
-
1052
- // Check exclusive_with
1053
- if (rule.exclusive_with && firedThisStep.includes(rule.exclusive_with)) {
1054
- ruleEvals.push({ ruleId: rule.id, label: rule.label, triggered: false, excluded: true, effects: [], collapsed: false, severity: rule.severity });
1055
- continue;
1056
- }
1057
-
1058
- const triggered = evaluateTriggers(rule.triggers, state, assumptions);
1059
- const appliedEffects = [];
1060
-
1061
- if (triggered) {
1062
- firedThisStep.push(rule.id);
1063
- for (const eff of (rule.effects || [])) {
1064
- appliedEffects.push(applyEffect(state, eff));
1065
- }
1066
-
1067
- // Check collapse
1068
- if (rule.collapse_check) {
1069
- const cv = state[rule.collapse_check.field];
1070
- if (typeof cv === 'number' && evaluateOperator(cv, rule.collapse_check.operator, rule.collapse_check.value)) {
1071
- collapsed = true;
1072
- stepCollapsed = true;
1073
- collapseStep = s + 1;
1074
- collapseRule = rule.id;
1075
- }
1076
- }
1077
- }
1078
-
1079
- ruleEvals.push({ ruleId: rule.id, label: rule.label, triggered, excluded: false, effects: appliedEffects, collapsed: stepCollapsed && triggered, severity: rule.severity });
1080
- }
1081
-
1082
- simSteps.push({
1083
- step: s + 1,
1084
- rulesEvaluated: ruleEvals,
1085
- rulesFired: ruleEvals.filter(r => r.triggered).length,
1086
- stateAfter: { ...state },
1087
- viability: classifyViability(state, world),
1088
- collapsed: stepCollapsed
1089
- });
1090
-
1091
- if (collapsed) break;
1092
- }
1093
-
1094
- return {
1095
- worldId: world.world.world_id,
1096
- worldName: world.world.name,
1097
- profile,
1098
- initialState,
1099
- steps: simSteps,
1100
- finalState: { ...state },
1101
- finalViability: classifyViability(state, world),
1102
- collapsed,
1103
- collapseStep,
1104
- collapseRule
1105
- };
1106
- }
774
+ const { simulateWorld, parseWorldMarkdown } = NeuroVerse;
1107
775
 
1108
776
  // ═══════════════════════════════════════════════════════════════════════════
1109
777
  // PRE-BUNDLED WORLDS