@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.
- package/.well-known/ai-plugin.json +34 -9
- package/AGENTS.md +72 -24
- package/README.md +343 -248
- package/dist/adapters/autoresearch.cjs +1345 -0
- package/dist/adapters/autoresearch.d.cts +111 -0
- package/dist/adapters/autoresearch.d.ts +111 -0
- package/dist/adapters/autoresearch.js +12 -0
- package/dist/adapters/deep-agents.cjs +1528 -0
- package/dist/adapters/deep-agents.d.cts +181 -0
- package/dist/adapters/deep-agents.d.ts +181 -0
- package/dist/adapters/deep-agents.js +17 -0
- package/dist/adapters/express.cjs +1253 -0
- package/dist/adapters/express.d.cts +66 -0
- package/dist/adapters/express.d.ts +66 -0
- package/dist/adapters/express.js +12 -0
- package/dist/adapters/index.cjs +2112 -0
- package/dist/adapters/index.d.cts +8 -0
- package/dist/adapters/index.d.ts +8 -0
- package/dist/adapters/index.js +68 -0
- package/dist/adapters/langchain.cjs +1315 -0
- package/dist/adapters/langchain.d.cts +89 -0
- package/dist/adapters/langchain.d.ts +89 -0
- package/dist/adapters/langchain.js +17 -0
- package/dist/adapters/openai.cjs +1345 -0
- package/dist/adapters/openai.d.cts +99 -0
- package/dist/adapters/openai.d.ts +99 -0
- package/dist/adapters/openai.js +17 -0
- package/dist/adapters/openclaw.cjs +1337 -0
- package/dist/adapters/openclaw.d.cts +99 -0
- package/dist/adapters/openclaw.d.ts +99 -0
- package/dist/adapters/openclaw.js +17 -0
- package/dist/add-ROOZLU62.js +314 -0
- package/dist/behavioral-MJO34S6Q.js +118 -0
- package/dist/bootstrap-CQRZVOXK.js +116 -0
- package/dist/bootstrap-emitter-Q7UIJZ2O.js +7 -0
- package/dist/bootstrap-parser-EEF36XDU.js +7 -0
- package/dist/browser.global.js +941 -0
- package/dist/build-ZHPMX5AZ.js +342 -0
- package/dist/chunk-3WQLXYTP.js +91 -0
- package/dist/chunk-4FLICVVA.js +119 -0
- package/dist/chunk-4NGDRRQH.js +10 -0
- package/dist/chunk-5TPFNWRU.js +215 -0
- package/dist/chunk-5U2MQO5P.js +57 -0
- package/dist/chunk-6CZSKEY5.js +164 -0
- package/dist/chunk-7P3S7MAY.js +1090 -0
- package/dist/chunk-A5W4GNQO.js +130 -0
- package/dist/chunk-A7GKPPU7.js +226 -0
- package/dist/chunk-AKW5YVCE.js +96 -0
- package/dist/chunk-B6OXJLJ5.js +622 -0
- package/dist/chunk-BNKJPUPQ.js +113 -0
- package/dist/chunk-BQZMOEML.js +43 -0
- package/dist/chunk-CNSO6XW5.js +207 -0
- package/dist/chunk-CTZHONLA.js +135 -0
- package/dist/chunk-D2UCV5AK.js +326 -0
- package/dist/chunk-EMQDLDAF.js +458 -0
- package/dist/chunk-F66BVUYB.js +340 -0
- package/dist/chunk-FMSTRBBS.js +17 -0
- package/dist/chunk-G7DJ6VOD.js +101 -0
- package/dist/chunk-I3RRAYK2.js +11 -0
- package/dist/chunk-INWQHLPS.js +47 -0
- package/dist/chunk-IS4WUH6Y.js +363 -0
- package/dist/chunk-O5ABKEA7.js +304 -0
- package/dist/chunk-OT6PXH54.js +61 -0
- package/dist/chunk-PVTQQS3Y.js +186 -0
- package/dist/chunk-QLPTHTVB.js +253 -0
- package/dist/chunk-QWGCMQQD.js +16 -0
- package/dist/chunk-QXBFT7NI.js +201 -0
- package/dist/chunk-TG6SEF24.js +246 -0
- package/dist/chunk-U6U7EJZL.js +177 -0
- package/dist/chunk-VXHSMA3I.js +166 -0
- package/dist/chunk-W7LLXRGY.js +830 -0
- package/dist/chunk-YEKMVDWK.js +624 -0
- package/dist/chunk-ZJTDUCC2.js +194 -0
- package/dist/chunk-ZWI3NIXK.js +314 -0
- package/dist/cli/neuroverse.cjs +14379 -0
- package/dist/cli/neuroverse.d.cts +1 -0
- package/dist/cli/neuroverse.d.ts +1 -0
- package/dist/cli/neuroverse.js +227 -0
- package/dist/cli/plan.cjs +2439 -0
- package/dist/cli/plan.d.cts +20 -0
- package/dist/cli/plan.d.ts +20 -0
- package/dist/cli/plan.js +353 -0
- package/dist/cli/run.cjs +2001 -0
- package/dist/cli/run.d.cts +20 -0
- package/dist/cli/run.d.ts +20 -0
- package/dist/cli/run.js +143 -0
- package/dist/configure-ai-5MP5DWTT.js +134 -0
- package/dist/decision-flow-M63D47LO.js +61 -0
- package/dist/demo-G43RLCPK.js +469 -0
- package/dist/derive-LMDUTXDD.js +154 -0
- package/dist/doctor-6BC6X2VO.js +173 -0
- package/dist/equity-penalties-SG5IZQ7I.js +244 -0
- package/dist/explain-RHBU2GBR.js +51 -0
- package/dist/guard-AEEJNWLD.js +126 -0
- package/dist/guard-contract-B7lplwm9.d.cts +837 -0
- package/dist/guard-contract-B7lplwm9.d.ts +837 -0
- package/dist/guard-engine-PNR6MHCM.js +10 -0
- package/dist/impact-3XVDSCBU.js +59 -0
- package/dist/improve-TQP4ECSY.js +66 -0
- package/dist/index.cjs +7738 -0
- package/dist/index.d.cts +2350 -0
- package/dist/index.d.ts +2350 -0
- package/dist/index.js +479 -0
- package/dist/infer-world-IFXCACJ5.js +543 -0
- package/dist/init-FYPV4SST.js +144 -0
- package/dist/init-world-TI7ARHBT.js +223 -0
- package/dist/mcp-server-5Y3ZM7TV.js +13 -0
- package/dist/model-adapter-VXEKB4LS.js +11 -0
- package/dist/playground-VZBNPPBO.js +560 -0
- package/dist/redteam-MZPZD3EF.js +357 -0
- package/dist/session-JYOARW54.js +15 -0
- package/dist/shared-7RLUHNMU.js +16 -0
- package/dist/shared-C_zpdvBm.d.cts +60 -0
- package/dist/shared-Cf7yxx4-.d.ts +60 -0
- package/dist/simulate-LJXYBC6M.js +83 -0
- package/dist/test-BOOR4A5F.js +217 -0
- package/dist/trace-PKV4KX56.js +166 -0
- package/dist/validate-RALX7CZS.js +81 -0
- package/dist/validate-engine-7ZXFVGF2.js +7 -0
- package/dist/viz/assets/index-B8SaeJZZ.js +23 -0
- package/dist/viz/index.html +23 -0
- package/dist/world-BIP4GZBZ.js +376 -0
- package/dist/world-loader-Y6HMQH2D.js +13 -0
- package/dist/worlds/autoresearch.nv-world.md +230 -0
- package/dist/worlds/coding-agent.nv-world.md +211 -0
- package/dist/worlds/derivation-world.nv-world.md +278 -0
- package/dist/worlds/research-agent.nv-world.md +169 -0
- package/dist/worlds/social-media.nv-world.md +198 -0
- package/dist/worlds/trading-agent.nv-world.md +218 -0
- package/examples/social-media-sim/bridge.py +209 -0
- package/examples/social-media-sim/simulation.py +927 -0
- package/package.json +16 -3
- package/simulate.html +4 -336
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neuroverseos/governance",
|
|
3
|
-
"version": "0.3.
|
|
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": ">=
|
|
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
|
-
//
|
|
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
|
-
|
|
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
|