@neuroverseos/nv-sim 0.1.4 → 0.1.5

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 (47) hide show
  1. package/README.md +346 -68
  2. package/dist/adapters/mirofish.js +461 -0
  3. package/dist/adapters/scienceclaw.js +750 -0
  4. package/dist/assets/index-B64NuIXu.css +1 -0
  5. package/dist/assets/index-DbzSnYxr.js +532 -0
  6. package/dist/assets/{reportEngine-BfteK4MN.js → reportEngine-DKWTrP6-.js} +1 -1
  7. package/dist/components/ConstraintsPanel.js +11 -0
  8. package/dist/components/StakeholderBuilder.js +32 -0
  9. package/dist/components/ui/badge.js +24 -0
  10. package/dist/components/ui/button.js +70 -0
  11. package/dist/components/ui/card.js +57 -0
  12. package/dist/components/ui/input.js +44 -0
  13. package/dist/components/ui/label.js +45 -0
  14. package/dist/components/ui/select.js +70 -0
  15. package/dist/engine/aiProvider.js +427 -2
  16. package/dist/engine/auditTrace.js +352 -0
  17. package/dist/engine/behavioralAnalysis.js +605 -0
  18. package/dist/engine/cli.js +1087 -13
  19. package/dist/engine/dynamicsGovernance.js +588 -0
  20. package/dist/engine/fullGovernedLoop.js +367 -0
  21. package/dist/engine/governedSimulation.js +77 -6
  22. package/dist/engine/index.js +41 -1
  23. package/dist/engine/liveVisualizer.js +2787 -360
  24. package/dist/engine/metrics/science.metrics.js +335 -0
  25. package/dist/engine/narrativeInjection.js +55 -0
  26. package/dist/engine/policyEnforcement.js +1611 -0
  27. package/dist/engine/policyEngine.js +799 -0
  28. package/dist/engine/primeRadiant.js +540 -0
  29. package/dist/engine/scenarioCapsule.js +56 -0
  30. package/dist/engine/scenarioComparison.js +463 -0
  31. package/dist/engine/scenarioLibrary.js +17 -0
  32. package/dist/engine/swarmSimulation.js +54 -1
  33. package/dist/engine/worldComparison.js +164 -0
  34. package/dist/engine/worldStorage.js +232 -0
  35. package/dist/index.html +2 -2
  36. package/dist/lib/reasoningEngine.js +290 -0
  37. package/dist/lib/simulationAdapter.js +686 -0
  38. package/dist/lib/swarmParser.js +291 -0
  39. package/dist/lib/types.js +2 -0
  40. package/dist/lib/utils.js +8 -0
  41. package/dist/runtime/govern.js +473 -0
  42. package/dist/runtime/index.js +75 -0
  43. package/dist/runtime/types.js +11 -0
  44. package/package.json +5 -2
  45. package/dist/assets/index-DHKd4rcV.js +0 -338
  46. package/dist/assets/index-SyyA3z3U.css +0 -1
  47. package/dist/assets/swarmSimulation-DHDqjfMa.js +0 -1
@@ -56,7 +56,9 @@ const liveVisualizer_1 = require("./liveVisualizer");
56
56
  const narrativeInjection_1 = require("./narrativeInjection");
57
57
  const scenarioLibrary_1 = require("./scenarioLibrary");
58
58
  const scenarioCapsule_1 = require("./scenarioCapsule");
59
+ const behavioralAnalysis_1 = require("./behavioralAnalysis");
59
60
  const fs = __importStar(require("fs"));
61
+ const child_process_1 = require("child_process");
60
62
  // ============================================
61
63
  // CLI ARGUMENT PARSING
62
64
  // ============================================
@@ -235,7 +237,7 @@ async function main() {
235
237
  }
236
238
  console.log(`\n Same events. Different rules. Different outcomes.`);
237
239
  }
238
- console.log(`\n Simulate the future. Govern the outcomes.`);
240
+ console.log(`\n Design rules. Run reality. See what changes.`);
239
241
  console.log(` neuroverse-simulations | @neuroverseos\n`);
240
242
  break;
241
243
  }
@@ -414,9 +416,8 @@ async function main() {
414
416
  console.log(" Interactive world controls ready.\n");
415
417
  console.log(" Change world rules, inject narrative events, run simulations.");
416
418
  console.log(" Press Ctrl+C to stop.\n");
417
- const { exec } = require("child_process");
418
419
  const openCmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
419
- exec(`${openCmd} ${url}`, () => { });
420
+ (0, child_process_1.exec)(`${openCmd} ${url}`, () => { });
420
421
  });
421
422
  await new Promise(() => { }); // block forever
422
423
  break;
@@ -437,7 +438,15 @@ async function main() {
437
438
  console.log(`\n Server ready: ${url}`);
438
439
  console.log(` Governance: ${url}/api/evaluate`);
439
440
  console.log(` Dashboard: ${url}`);
440
- console.log(` SSE stream: ${url}/events\n`);
441
+ console.log(` SSE stream: ${url}/events`);
442
+ console.log("");
443
+ console.log(" Session & Reporting:");
444
+ console.log(` Stats: GET ${url}/api/session`);
445
+ console.log(` Report: GET ${url}/api/session/report`);
446
+ console.log(` Report JSON: GET ${url}/api/session/report.json`);
447
+ console.log(` Reset: POST ${url}/api/session/reset`);
448
+ console.log(` Save: POST ${url}/api/session/save\n`);
449
+ console.log(" Workflow: evaluate → report → apply new rules → reset → compare");
441
450
  console.log(" Waiting for simulator connections...");
442
451
  console.log(" Press Ctrl+C to stop.\n");
443
452
  });
@@ -454,11 +463,11 @@ async function main() {
454
463
  console.log(" " + "=".repeat(60));
455
464
  // Step 1: Start governance server
456
465
  console.log(` [1/3] Starting governance server on port ${runPort}...`);
466
+ const { createAdapter: ca, ADAPTER_REGISTRY: ar } = await Promise.resolve().then(() => __importStar(require("./liveAdapter")));
457
467
  (0, liveVisualizer_1.startInteractiveServer)(runPort, (url) => {
458
468
  console.log(` [1/3] Governance ready: ${url}/api/evaluate`);
459
469
  // Step 2: Start simulator via live adapter
460
470
  console.log(` [2/3] Starting ${simId} simulator...`);
461
- const { createAdapter: ca, ADAPTER_REGISTRY: ar } = require("./liveAdapter");
462
471
  // Check if we have a registry entry, otherwise try raw command
463
472
  const adapterEntry = ar[simId];
464
473
  if (!adapterEntry) {
@@ -504,14 +513,151 @@ async function main() {
504
513
  });
505
514
  // Open viewer unless --no-viewer
506
515
  if (!noViewer) {
507
- const { exec } = require("child_process");
508
516
  const openCmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
509
- exec(`${openCmd} ${url}`, () => { });
517
+ (0, child_process_1.exec)(`${openCmd} ${url}`, () => { });
510
518
  }
511
519
  });
512
520
  await new Promise(() => { }); // block forever
513
521
  break;
514
522
  }
523
+ case "world-from-doc": {
524
+ // Generate a world file from a plain-English document
525
+ const docPath = args[1];
526
+ if (!docPath) {
527
+ console.error("\n Usage: npx nv-sim world-from-doc <file>\n");
528
+ console.error(" Reads a document (.md, .txt, .pdf) and generates a world definition.\n");
529
+ console.error(" Examples:");
530
+ console.error(" npx nv-sim world-from-doc policy.md");
531
+ console.error(" npx nv-sim world-from-doc regulations.txt --output my-world.json");
532
+ console.error(" cat rules.txt | npx nv-sim world-from-doc -\n");
533
+ process.exit(1);
534
+ }
535
+ const fs = await Promise.resolve().then(() => __importStar(require("fs")));
536
+ const path = await Promise.resolve().then(() => __importStar(require("path")));
537
+ let docText;
538
+ if (docPath === "-") {
539
+ // Read from stdin
540
+ const chunks = [];
541
+ for await (const chunk of process.stdin) {
542
+ chunks.push(Buffer.from(chunk));
543
+ }
544
+ docText = Buffer.concat(chunks).toString("utf-8");
545
+ }
546
+ else {
547
+ const resolved = path.resolve(docPath);
548
+ if (!fs.existsSync(resolved)) {
549
+ console.error(`\n Error: File not found: ${resolved}\n`);
550
+ process.exit(1);
551
+ }
552
+ docText = fs.readFileSync(resolved, "utf-8");
553
+ }
554
+ console.log(`\n NV-SIM — World File Generator\n`);
555
+ console.log(` Reading: ${docPath === "-" ? "stdin" : docPath}`);
556
+ console.log(" " + "=".repeat(60));
557
+ // Parse the document into a world definition
558
+ const lines = docText.split("\n").map(l => l.trim()).filter(l => l.length > 0);
559
+ const worldId = args.includes("--id") ? args[args.indexOf("--id") + 1] : path.basename(docPath, path.extname(docPath)).replace(/\s+/g, "_").toLowerCase();
560
+ // Extract thesis (first paragraph or heading)
561
+ let thesis = "";
562
+ const invariants = [];
563
+ const gates = [];
564
+ const stateVars = [];
565
+ let invCount = 0;
566
+ let gateCount = 0;
567
+ for (const line of lines) {
568
+ const lower = line.toLowerCase();
569
+ // Skip markdown headers but use them for context
570
+ if (line.startsWith("#")) {
571
+ if (!thesis)
572
+ thesis = line.replace(/^#+\s*/, "");
573
+ continue;
574
+ }
575
+ // First non-header line as thesis if not set
576
+ if (!thesis && line.length > 10) {
577
+ thesis = line;
578
+ continue;
579
+ }
580
+ // Detect rules: lines starting with block/prevent/limit/require/allow etc
581
+ if (/^(block|prevent|prohibit|ban|stop|forbid|no\b|don.t|limit|cap|restrict)/i.test(lower)) {
582
+ invCount++;
583
+ invariants.push({
584
+ id: `INV-${String(invCount).padStart(3, "0")}`,
585
+ description: line.replace(/^[-*•]\s*/, ""),
586
+ enforceable: true,
587
+ });
588
+ }
589
+ else if (/^(require|must|shall|ensure|mandate)/i.test(lower)) {
590
+ invCount++;
591
+ invariants.push({
592
+ id: `INV-${String(invCount).padStart(3, "0")}`,
593
+ description: line.replace(/^[-*•]\s*/, ""),
594
+ enforceable: true,
595
+ });
596
+ }
597
+ else if (/^(allow|permit|enable)/i.test(lower)) {
598
+ invCount++;
599
+ invariants.push({
600
+ id: `INV-${String(invCount).padStart(3, "0")}`,
601
+ description: line.replace(/^[-*•]\s*/, ""),
602
+ enforceable: false,
603
+ });
604
+ }
605
+ else if (/^(warn|alert|flag|monitor|watch)/i.test(lower)) {
606
+ gateCount++;
607
+ gates.push({
608
+ id: `GATE-${String(gateCount).padStart(3, "0")}`,
609
+ label: line.replace(/^[-*•]\s*/, ""),
610
+ condition: lower,
611
+ severity: /critical|extreme|emergency/i.test(lower) ? "critical" : "warning",
612
+ });
613
+ }
614
+ else if (/^[-*•]\s*/.test(line)) {
615
+ // Bullet points are probably rules
616
+ invCount++;
617
+ invariants.push({
618
+ id: `INV-${String(invCount).padStart(3, "0")}`,
619
+ description: line.replace(/^[-*•]\s*/, ""),
620
+ enforceable: true,
621
+ });
622
+ }
623
+ }
624
+ if (!thesis)
625
+ thesis = "Governance rules from " + (docPath === "-" ? "document" : docPath);
626
+ const worldDef = {
627
+ thesis,
628
+ state_variables: stateVars,
629
+ invariants,
630
+ gates,
631
+ };
632
+ // Wrap in SavedWorld format so enforce can consume it directly
633
+ const { createSavedWorld: createWorld } = await Promise.resolve().then(() => __importStar(require("./worldStorage")));
634
+ const savedWorld = createWorld(worldId, worldDef, "document", {
635
+ description: `Generated from ${docPath === "-" ? "stdin" : docPath}`,
636
+ });
637
+ // Output
638
+ const outputPath = args.includes("--output") ? args[args.indexOf("--output") + 1] : null;
639
+ const json = JSON.stringify(savedWorld, null, 2);
640
+ if (outputPath) {
641
+ fs.writeFileSync(outputPath, json, "utf-8");
642
+ console.log(`\n Generated: ${outputPath}`);
643
+ }
644
+ else {
645
+ console.log("\n" + json);
646
+ }
647
+ console.log(`\n Summary:`);
648
+ console.log(` Thesis: ${thesis}`);
649
+ console.log(` Invariants: ${invariants.length}`);
650
+ console.log(` Gates: ${gates.length}`);
651
+ console.log(`\n This world file is saved for reuse.`);
652
+ console.log(` You don't need this step — enforce accepts .txt directly:`);
653
+ console.log(` npx nv-sim enforce trading ${docPath === "-" ? "policy.txt" : docPath}`);
654
+ if (outputPath) {
655
+ console.log(`\n But since you saved it, you can also:`);
656
+ console.log(` npx nv-sim enforce trading ${outputPath}`);
657
+ }
658
+ console.log("");
659
+ break;
660
+ }
515
661
  case "preset": {
516
662
  const presetId = args[1];
517
663
  if (!presetId) {
@@ -540,6 +686,864 @@ async function main() {
540
686
  console.log(" Usage: npx nv-sim preset <preset_id>\n");
541
687
  break;
542
688
  }
689
+ // ============================================
690
+ // WORLD SAVE / LOAD / LIST
691
+ // ============================================
692
+ case "world:save": {
693
+ const sourcePreset = args[1];
694
+ const outputPath = args[2] || `${sourcePreset || "world"}.nv-world.json`;
695
+ const nameArg = args.find(a => a.startsWith("--name="))?.slice(7);
696
+ if (!sourcePreset) {
697
+ console.error(" Usage: npx nv-sim world:save <preset|file.json> [output.nv-world.json] [--name=My World]");
698
+ console.error(" Available presets: trading, strait_of_hormuz, gas_price_spike, ai_regulation_crisis");
699
+ process.exit(1);
700
+ }
701
+ try {
702
+ const { resolveWorld } = await Promise.resolve().then(() => __importStar(require("./worldComparison")));
703
+ const { createSavedWorld, saveWorldToFile } = await Promise.resolve().then(() => __importStar(require("./worldStorage")));
704
+ const resolved = resolveWorld(sourcePreset);
705
+ const name = nameArg || resolved.title;
706
+ const saved = createSavedWorld(name, resolved.world, sourcePreset, {
707
+ description: `Saved from CLI: ${resolved.title}`,
708
+ });
709
+ await saveWorldToFile(saved, outputPath);
710
+ console.log(`\n World saved: ${outputPath}`);
711
+ console.log(` Name: ${saved.name}`);
712
+ console.log(` Thesis: ${saved.world.thesis}`);
713
+ console.log(` Rules: ${saved.world.invariants.length} invariants, ${(saved.world.gates ?? []).length} gates`);
714
+ console.log(` ID: ${saved.id}\n`);
715
+ }
716
+ catch (err) {
717
+ console.error(` Failed to save world: ${err instanceof Error ? err.message : err}`);
718
+ process.exit(1);
719
+ }
720
+ break;
721
+ }
722
+ case "world:load": {
723
+ const filePath = args[1];
724
+ if (!filePath) {
725
+ console.error(" Usage: npx nv-sim world:load <file.nv-world.json>");
726
+ process.exit(1);
727
+ }
728
+ try {
729
+ const { loadWorldFromFile } = await Promise.resolve().then(() => __importStar(require("./worldStorage")));
730
+ const world = await loadWorldFromFile(filePath);
731
+ console.log(`\n World loaded: ${filePath}`);
732
+ console.log(` Name: ${world.name}`);
733
+ console.log(` Thesis: ${world.world.thesis}`);
734
+ console.log(` Base: ${world.basePreset}`);
735
+ console.log(` Rules: ${world.world.invariants.length} invariants, ${(world.world.gates ?? []).length} gates`);
736
+ console.log(` Created: ${world.createdAt}`);
737
+ console.log(` ID: ${world.id}\n`);
738
+ console.log(" INVARIANTS:");
739
+ for (const inv of world.world.invariants) {
740
+ console.log(` [${inv.enforceable ? "ENFORCED" : "ADVISORY"}] ${inv.description}`);
741
+ }
742
+ if (world.world.gates?.length) {
743
+ console.log("\n GATES:");
744
+ for (const gate of world.world.gates) {
745
+ console.log(` [${gate.severity.toUpperCase()}] ${gate.label}: ${gate.condition}`);
746
+ }
747
+ }
748
+ console.log();
749
+ }
750
+ catch (err) {
751
+ console.error(` Failed to load world: ${err instanceof Error ? err.message : err}`);
752
+ process.exit(1);
753
+ }
754
+ break;
755
+ }
756
+ case "world:list": {
757
+ const { getAvailableWorlds, explainWorldGovernance } = await Promise.resolve().then(() => __importStar(require("./worldComparison")));
758
+ const worlds = getAvailableWorlds();
759
+ console.log(`\n NV-SIM — Available Worlds\n`);
760
+ console.log(" " + "=".repeat(60));
761
+ for (const w of worlds) {
762
+ console.log(`\n ${w.id}`);
763
+ console.log(` ${w.title}`);
764
+ console.log(` ${w.thesis.slice(0, 80)}${w.thesis.length > 80 ? "..." : ""}`);
765
+ console.log(` ${w.invariantCount} rules, ${w.gateCount} gates`);
766
+ }
767
+ console.log(`\n Total: ${worlds.length} worlds available\n`);
768
+ console.log(" Use: npx nv-sim worlds <worldA> <worldB> to compare");
769
+ console.log(" Use: npx nv-sim world:save <preset> to save as JSON\n");
770
+ break;
771
+ }
772
+ case "world:compare": {
773
+ // Compare two saved world files
774
+ const fileA = args[1];
775
+ const fileB = args[2];
776
+ if (!fileA || !fileB) {
777
+ console.error(" Usage: npx nv-sim world:compare <worldA.json> <worldB.json>");
778
+ process.exit(1);
779
+ }
780
+ try {
781
+ const { loadWorldFromFile, saveWorldToStorage } = await Promise.resolve().then(() => __importStar(require("./worldStorage")));
782
+ const worldA = await loadWorldFromFile(fileA);
783
+ const worldB = await loadWorldFromFile(fileB);
784
+ // Temporarily register in storage so resolveWorld can find them
785
+ saveWorldToStorage(worldA);
786
+ saveWorldToStorage(worldB);
787
+ console.log(`\n NV-SIM — World File Comparison\n`);
788
+ console.log(` World A: ${worldA.name} (${fileA})`);
789
+ console.log(` World B: ${worldB.name} (${fileB})`);
790
+ console.log(" " + "=".repeat(60));
791
+ const compResult = await (0, worldComparison_1.runWorldComparison)(worldA.id, worldB.id, {
792
+ onProgress: (label, phase) => console.log(` ${label}: ${phase}...`),
793
+ });
794
+ const { generateComparisonImpact } = await Promise.resolve().then(() => __importStar(require("./worldComparison")));
795
+ const impact = generateComparisonImpact(compResult);
796
+ printWorldComparisonResults(compResult, impact);
797
+ }
798
+ catch (err) {
799
+ console.error(` Comparison failed: ${err instanceof Error ? err.message : err}`);
800
+ process.exit(1);
801
+ }
802
+ break;
803
+ }
804
+ // ============================================
805
+ // PRIME RADIANT — Full Policy Enforcement System
806
+ // ============================================
807
+ case "radiant":
808
+ case "prime": {
809
+ const presetId = (args[1] && !args[1].startsWith("--")) ? args[1] : undefined;
810
+ const mode = args.includes("--compare") ? "compare" : args.includes("--world") ? "world" : "simulate";
811
+ console.log(`\n PRIME RADIANT — Policy Enforcement System\n`);
812
+ console.log(` "govern() controls actions. governDynamics() controls outcomes."\n`);
813
+ console.log(" " + "=".repeat(60));
814
+ const { createPrimeRadiant, PRIME_RADIANT_PRESETS } = await Promise.resolve().then(() => __importStar(require("./primeRadiant")));
815
+ // Resolve preset or use default
816
+ const presetKey = presetId && (presetId in PRIME_RADIANT_PRESETS)
817
+ ? presetId
818
+ : "university_crisis";
819
+ const preset = PRIME_RADIANT_PRESETS[presetKey];
820
+ const narrativeEvents = (0, narrativeInjection_1.parseInjectArgs)(args);
821
+ console.log(` Preset: ${presetKey}`);
822
+ const radiant = createPrimeRadiant({
823
+ scenario: preset.scenario,
824
+ policyText: preset.policyText,
825
+ stakeholders: preset.stakeholders,
826
+ narrativeEvents: narrativeEvents.length > 0 ? narrativeEvents : undefined,
827
+ });
828
+ if (mode === "world") {
829
+ // MODE 1: Build world
830
+ console.log(` Mode: WORLD BUILDER\n`);
831
+ const world = radiant.buildWorld();
832
+ console.log(` Policy Health: ${world.health.healthScore}/100`);
833
+ console.log(` Total Rules: ${world.coverageReport.totalRules}`);
834
+ console.log(` Enforced: ${world.coverageReport.enforcedRules}`);
835
+ console.log(` Advisory: ${world.coverageReport.advisoryRules}`);
836
+ console.log(` Dynamics: ${world.coverageReport.dynamicsRulesDetected}`);
837
+ console.log(` Thesis: ${world.world.thesis}`);
838
+ if (world.coverageReport.uncoveredCritical.length > 0) {
839
+ console.log(`\n UNCOVERED CRITICAL VARIABLES:`);
840
+ for (const v of world.coverageReport.uncoveredCritical) {
841
+ console.log(` - ${v}`);
842
+ }
843
+ }
844
+ console.log(`\n INVARIANTS:`);
845
+ for (const inv of world.world.invariants) {
846
+ console.log(` [${inv.enforceable ? "ENFORCED" : "ADVISORY"}] ${inv.description}`);
847
+ }
848
+ if (world.world.gates && world.world.gates.length > 0) {
849
+ console.log(`\n GATES:`);
850
+ for (const gate of world.world.gates) {
851
+ console.log(` [${gate.severity.toUpperCase()}] ${gate.label}`);
852
+ }
853
+ }
854
+ }
855
+ else if (mode === "compare") {
856
+ // MODE 3: Decision Intelligence
857
+ console.log(` Mode: DECISION INTELLIGENCE\n`);
858
+ const options = preset.policyOptions;
859
+ console.log(` Comparing ${options.length} policy options...\n`);
860
+ for (const opt of options) {
861
+ console.log(` ${opt.id.padEnd(20)} ${opt.label}`);
862
+ }
863
+ console.log();
864
+ const result = await radiant.compareOptions(options);
865
+ // Print decision brief
866
+ console.log(result.decisionBrief);
867
+ // Print dynamics details
868
+ console.log(`\n DYNAMICS GOVERNANCE`);
869
+ console.log(" " + "-".repeat(50));
870
+ for (const optResult of result.optionResults) {
871
+ const d = optResult.simulation.dynamicsGovernance;
872
+ console.log(` ${optResult.optionLabel}:`);
873
+ console.log(` Interventions: ${d.totalInterventions} (propagation: ${d.propagationLimits}, amplification: ${d.amplificationDampens}, cascade: ${d.cascadeBreakers}, trust: ${d.trustBoosts}, cooling: ${d.coolingPeriods})`);
874
+ console.log(` Peak outrage: ${(d.peakOutrage * 100).toFixed(0)}% | Peak polarization: ${(d.peakPolarization * 100).toFixed(0)}% | Avg trust: ${(d.averageTrust * 100).toFixed(0)}%`);
875
+ }
876
+ // Print recommendation
877
+ console.log(`\n RECOMMENDATION: ${result.recommendation.optionLabel}`);
878
+ console.log(` Confidence: ${(result.recommendation.confidence * 100).toFixed(0)}%`);
879
+ console.log(` ${result.recommendation.rationale}`);
880
+ }
881
+ else {
882
+ // MODE 2: Governed Simulation
883
+ console.log(` Mode: GOVERNED SIMULATION\n`);
884
+ console.log(` Running dual-layer governance...`);
885
+ console.log(` Layer A: govern() — per-action, per-agent`);
886
+ console.log(` Layer B: governDynamics() — per-round, system-level\n`);
887
+ const result = await radiant.runGovernedSimulation();
888
+ const g = result.governed;
889
+ const b = result.baseline;
890
+ const d = result.delta;
891
+ // System state timeline
892
+ console.log(` STATE EVOLUTION`);
893
+ console.log(" " + "-".repeat(60));
894
+ console.log(` ${"Round".padEnd(8)} ${"Trust".padEnd(10)} ${"Outrage".padEnd(10)} ${"Polar.".padEnd(10)} ${"Cascade".padEnd(10)} ${"Trajectory"}`);
895
+ for (const snap of g.stateTimeline) {
896
+ const round = g.rounds.find(r => r.round === snap.round);
897
+ console.log(` ${String(snap.round).padEnd(8)} ${(snap.trust * 100).toFixed(0).padStart(4)}% ${(snap.outrage * 100).toFixed(0).padStart(4)}% ${(snap.polarization * 100).toFixed(0).padStart(4)}% ${(snap.cascadeRisk * 100).toFixed(0).padStart(4)}% ${round?.dynamicsTrajectory ?? "-"}`);
898
+ }
899
+ // Action governance
900
+ console.log(`\n ACTION GOVERNANCE (Layer A)`);
901
+ console.log(" " + "-".repeat(50));
902
+ const ag = g.actionGovernance;
903
+ console.log(` Evaluations: ${ag.totalEvaluations}`);
904
+ console.log(` Allowed: ${ag.allowed} | Blocked: ${ag.blocked} | Modified: ${ag.modified} | Paused: ${ag.paused}`);
905
+ console.log(` Avg reduction: ${(ag.avgReduction * 100).toFixed(0)}% | Rules fired: ${ag.rulesFired}`);
906
+ // Dynamics governance
907
+ console.log(`\n DYNAMICS GOVERNANCE (Layer B)`);
908
+ console.log(" " + "-".repeat(50));
909
+ const dg = g.dynamicsGovernance;
910
+ console.log(` Total interventions: ${dg.totalInterventions}`);
911
+ console.log(` Propagation limits: ${dg.propagationLimits}`);
912
+ console.log(` Amplification damps: ${dg.amplificationDampens}`);
913
+ console.log(` Cascade breakers: ${dg.cascadeBreakers}`);
914
+ console.log(` Trust boosts: ${dg.trustBoosts}`);
915
+ console.log(` Cooling periods: ${dg.coolingPeriods}`);
916
+ console.log(` Peak outrage: ${(dg.peakOutrage * 100).toFixed(0)}%`);
917
+ console.log(` Peak polarization: ${(dg.peakPolarization * 100).toFixed(0)}%`);
918
+ console.log(` Peak cascade risk: ${(dg.peakCascadeRisk * 100).toFixed(0)}%`);
919
+ console.log(` Average trust: ${(dg.averageTrust * 100).toFixed(0)}%`);
920
+ // Delta
921
+ console.log(`\n GOVERNANCE IMPACT (vs ungoverned baseline)`);
922
+ console.log(" " + "=".repeat(50));
923
+ console.log(` Trust: ${d.trustDelta > 0 ? "+" : ""}${(d.trustDelta * 100).toFixed(0)} points (${(b.finalState.trust * 100).toFixed(0)}% → ${(g.finalState.trust * 100).toFixed(0)}%)`);
924
+ console.log(` Polarization: ${d.polarizationDelta < 0 ? "" : "+"}${(d.polarizationDelta * 100).toFixed(0)} points (${(b.finalState.polarization * 100).toFixed(0)}% → ${(g.finalState.polarization * 100).toFixed(0)}%)`);
925
+ console.log(` Outrage: ${d.outrageDelta < 0 ? "" : "+"}${(d.outrageDelta * 100).toFixed(0)} points (${(b.finalState.outrage * 100).toFixed(0)}% → ${(g.finalState.outrage * 100).toFixed(0)}%)`);
926
+ console.log(` Cascade risk: ${d.cascadeRiskDelta < 0 ? "" : "+"}${(d.cascadeRiskDelta * 100).toFixed(0)} points (${(b.finalState.cascadeRisk * 100).toFixed(0)}% → ${(g.finalState.cascadeRisk * 100).toFixed(0)}%)`);
927
+ console.log(` System health: ${d.healthDelta > 0 ? "+" : ""}${d.healthDelta} (${b.systemHealthScore}/100 → ${g.systemHealthScore}/100)`);
928
+ console.log(` Trajectory: ${d.trajectoryShift}`);
929
+ console.log(` Effectiveness: ${(d.governanceEffectiveness * 100).toFixed(0)}%`);
930
+ // Inflection points
931
+ if (g.inflectionPoints.length > 0) {
932
+ console.log(`\n INFLECTION POINTS`);
933
+ console.log(" " + "-".repeat(50));
934
+ for (const ip of g.inflectionPoints) {
935
+ console.log(` ${ip}`);
936
+ }
937
+ }
938
+ // Narrative
939
+ console.log(`\n NARRATIVE`);
940
+ console.log(" " + "-".repeat(50));
941
+ const words = result.narrative.split(" ");
942
+ let line = " ";
943
+ for (const word of words) {
944
+ if (line.length + word.length > 72) {
945
+ console.log(line);
946
+ line = " " + word;
947
+ }
948
+ else {
949
+ line += (line.trim() ? " " : "") + word;
950
+ }
951
+ }
952
+ if (line.trim())
953
+ console.log(line);
954
+ }
955
+ console.log(`\n ${"=".repeat(60)}`);
956
+ console.log(` govern() controls actions.`);
957
+ console.log(` governDynamics() controls outcomes.`);
958
+ console.log(` ${"=".repeat(60)}`);
959
+ console.log(`\n Design rules. Run reality. See what changes.`);
960
+ console.log(` neuroverse-simulations | @neuroverseos\n`);
961
+ break;
962
+ }
963
+ // ============================================
964
+ // MIROFISH — Governed Agent Simulation
965
+ // ============================================
966
+ case "mirofish": {
967
+ console.log(`\n MIROFISH SIMULATION — Governed by NeuroVerse\n`);
968
+ console.log(` MiroFish + NeuroVerse Governance Layer`);
969
+ console.log(` MiroFish generates emergent agent behavior.`);
970
+ console.log(` NeuroVerse enforces rules, constraints, and system stability in real time.\n`);
971
+ console.log(" " + "=".repeat(60));
972
+ const { runMiroFishComparison } = await Promise.resolve().then(() => __importStar(require("../adapters/mirofish")));
973
+ const mfMode = args.includes("--compare") ? "compare" : "governed";
974
+ if (mfMode === "compare") {
975
+ console.log(` Mode: GOVERNED vs UNGOVERNED COMPARISON\n`);
976
+ console.log(` Running simulation...`);
977
+ const comparison = runMiroFishComparison();
978
+ const gov = comparison.governed;
979
+ const ungov = comparison.ungoverned;
980
+ const gs = gov.metrics.systemState;
981
+ const us = ungov.metrics.systemState;
982
+ console.log(`\n Scenario: ${comparison.scenario}`);
983
+ console.log(" " + "=".repeat(60));
984
+ // Metric comparison
985
+ console.log(`\n ${"Metric".padEnd(30)} ${"Governed".padEnd(15)} ${"Ungoverned".padEnd(15)} ${"Delta"}`);
986
+ console.log(" " + "-".repeat(75));
987
+ const mfMetrics = [
988
+ ["Trust", gs.trust, us.trust],
989
+ ["Polarization", gs.polarization, us.polarization],
990
+ ["Outrage", gs.outrage, us.outrage],
991
+ ["Cascade Risk", gs.cascadeRisk, us.cascadeRisk],
992
+ ["Amplification", gs.amplification, us.amplification],
993
+ ];
994
+ for (const [label, gv, uv] of mfMetrics) {
995
+ const delta = gv - uv;
996
+ const deltaStr = `${delta > 0 ? "+" : ""}${(delta * 100).toFixed(0)}`;
997
+ console.log(` ${label.padEnd(30)} ${(gv * 100).toFixed(0).padStart(5)}% ${(uv * 100).toFixed(0).padStart(5)}% ${deltaStr.padStart(5)}`);
998
+ }
999
+ console.log(`\n ${"".padEnd(30)} ${"Governed".padEnd(15)} ${"Ungoverned"}`);
1000
+ console.log(" " + "-".repeat(60));
1001
+ console.log(` ${"Verdict".padEnd(30)} ${gov.verdict.padEnd(15)} ${ungov.verdict}`);
1002
+ console.log(` ${"Actions Blocked".padEnd(30)} ${String(gov.totalBlocked).padEnd(15)} ${0}`);
1003
+ console.log(` ${"Actions Modified".padEnd(30)} ${String(gov.totalModified).padEnd(15)} ${0}`);
1004
+ console.log(` ${"Trajectory".padEnd(30)} ${gov.metrics.trajectory.padEnd(15)} ${ungov.metrics.trajectory}`);
1005
+ // State timeline
1006
+ console.log(`\n STATE EVOLUTION (Trust)`);
1007
+ console.log(" " + "-".repeat(60));
1008
+ console.log(` ${"Round".padEnd(8)} ${"Governed".padEnd(15)} ${"Ungoverned".padEnd(15)} ${"Gap"}`);
1009
+ for (let i = 0; i < gov.timeline.length; i++) {
1010
+ const gt = gov.timeline[i].systemState.trust;
1011
+ const ut = ungov.timeline[i].systemState.trust;
1012
+ const gap = gt - ut;
1013
+ console.log(` ${String(i + 1).padEnd(8)} ${(gt * 100).toFixed(0).padStart(5)}% ${(ut * 100).toFixed(0).padStart(5)}% ${(gap > 0 ? "+" : "") + (gap * 100).toFixed(0).padStart(4)}`);
1014
+ }
1015
+ // Science state comparison
1016
+ const govSci = gov.metrics.scienceState;
1017
+ const ungovSci = ungov.metrics.scienceState;
1018
+ console.log(`\n SYSTEM ASSESSMENT`);
1019
+ console.log(" " + "-".repeat(60));
1020
+ console.log(` Governed: ${govSci.overallAssessment}`);
1021
+ console.log(` Ungoverned: ${ungovSci.overallAssessment}`);
1022
+ console.log(`\n This simulation was generated by MiroFish.`);
1023
+ console.log(` NeuroVerse governance altered the system trajectory in real time.`);
1024
+ }
1025
+ else {
1026
+ // Single governed run
1027
+ console.log(` Mode: GOVERNED SIMULATION\n`);
1028
+ const { createMiroFishWrapper, generateDemoSimulation } = await Promise.resolve().then(() => __importStar(require("../adapters/mirofish")));
1029
+ const demo = generateDemoSimulation();
1030
+ const wrapper = createMiroFishWrapper({ enabled: true });
1031
+ console.log(` Scenario: ${demo.scenario}\n`);
1032
+ for (let i = 0; i < demo.rounds.length; i++) {
1033
+ const round = demo.rounds[i];
1034
+ let blocked = 0;
1035
+ let modified = 0;
1036
+ const approved = [];
1037
+ for (const action of round) {
1038
+ const result = wrapper.interceptAction(action);
1039
+ if (result.wasBlocked)
1040
+ blocked++;
1041
+ else if (result.wasModified)
1042
+ modified++;
1043
+ if (!result.wasBlocked)
1044
+ approved.push(result.governed ?? action);
1045
+ }
1046
+ const cycleResult = wrapper.completeCycle({ cycle: i + 1, actions: approved });
1047
+ const m = wrapper.getMetrics();
1048
+ const flags = blocked > 0 ? ` [${blocked} blocked]` : "";
1049
+ console.log(` Round ${String(i + 1).padEnd(3)} | trust: ${(m.systemState.trust * 100).toFixed(0).padStart(3)}% | cascade: ${(m.systemState.cascadeRisk * 100).toFixed(0).padStart(3)}% | ${cycleResult.trajectory}${flags}`);
1050
+ }
1051
+ const final = wrapper.getMetrics();
1052
+ console.log(`\n FINAL STATE`);
1053
+ console.log(" " + "=".repeat(50));
1054
+ console.log(` Trust: ${(final.systemState.trust * 100).toFixed(0)}%`);
1055
+ console.log(` Cascade Risk: ${(final.systemState.cascadeRisk * 100).toFixed(0)}%`);
1056
+ console.log(` Blocked: ${final.actionStats.blocked}`);
1057
+ console.log(` Modified: ${final.actionStats.modified}`);
1058
+ console.log(` Assessment: ${final.scienceState.overallAssessment}`);
1059
+ }
1060
+ console.log(`\n ${"=".repeat(60)}`);
1061
+ console.log(` Governed MiroFish Simulation | NeuroVerse Governance Layer`);
1062
+ console.log(` ${"=".repeat(60)}`);
1063
+ console.log(`\n neuroverse-simulations | @neuroverseos\n`);
1064
+ break;
1065
+ }
1066
+ // ============================================
1067
+ // SCIENCE — Governed Scientific Discovery
1068
+ // ============================================
1069
+ case "science": {
1070
+ console.log(`\n SCIENCECLAW SIMULATION — Governed by NeuroVerse\n`);
1071
+ console.log(` Powered by ScienceClaw | Governed by NeuroVerse`);
1072
+ console.log(` ScienceClaw generates autonomous scientific discovery.`);
1073
+ console.log(` NeuroVerse enforces reproducibility, provenance, and research integrity.\n`);
1074
+ console.log(" " + "=".repeat(60));
1075
+ const { createScienceClawAdapter, generateDemoInvestigation } = await Promise.resolve().then(() => __importStar(require("../adapters/scienceclaw")));
1076
+ const { SCIENCE_METRICS, interpretScienceState } = await Promise.resolve().then(() => __importStar(require("./metrics/science.metrics")));
1077
+ const demo = generateDemoInvestigation();
1078
+ const mode = args.includes("--compare") ? "compare" : "simulate";
1079
+ if (mode === "compare") {
1080
+ // Governed vs ungoverned comparison
1081
+ console.log(` Mode: GOVERNED vs UNGOVERNED COMPARISON\n`);
1082
+ // Run governed
1083
+ console.log(` Running GOVERNED investigation...`);
1084
+ const governed = createScienceClawAdapter();
1085
+ const govResult = governed.runGovernedInvestigation(demo.artifactCycles, demo.matchesByCycle);
1086
+ // Run ungoverned (empty policy)
1087
+ console.log(` Running UNGOVERNED investigation...`);
1088
+ const ungoverned = createScienceClawAdapter({ policyText: "" });
1089
+ const ungovResult = ungoverned.runGovernedInvestigation(demo.artifactCycles, demo.matchesByCycle);
1090
+ // Print comparison
1091
+ console.log(`\n COMPARISON: Governed vs Ungoverned Discovery`);
1092
+ console.log(" " + "=".repeat(60));
1093
+ console.log(` ${"Metric".padEnd(30)} ${"Governed".padEnd(15)} ${"Ungoverned".padEnd(15)} ${"Delta"}`);
1094
+ console.log(" " + "-".repeat(75));
1095
+ const metrics = [
1096
+ ["Trust (Reproducibility)", govResult.finalState.trust, ungovResult.finalState.trust],
1097
+ ["Polarization (Fragmentation)", govResult.finalState.polarization, ungovResult.finalState.polarization],
1098
+ ["Outrage (Publication Pressure)", govResult.finalState.outrage, ungovResult.finalState.outrage],
1099
+ ["Cascade Risk (False Positives)", govResult.finalState.cascadeRisk, ungovResult.finalState.cascadeRisk],
1100
+ ["Amplification (Citation Echo)", govResult.finalState.amplification, ungovResult.finalState.amplification],
1101
+ ];
1102
+ for (const [label, gov, ungov] of metrics) {
1103
+ const delta = gov - ungov;
1104
+ const deltaStr = `${delta > 0 ? "+" : ""}${(delta * 100).toFixed(0)}`;
1105
+ console.log(` ${label.padEnd(30)} ${(gov * 100).toFixed(0).padStart(5)}% ${(ungov * 100).toFixed(0).padStart(5)}% ${deltaStr.padStart(5)}`);
1106
+ }
1107
+ console.log(`\n ${"".padEnd(30)} ${"Governed".padEnd(15)} ${"Ungoverned"}`);
1108
+ console.log(" " + "-".repeat(60));
1109
+ console.log(` ${"Verdict".padEnd(30)} ${govResult.verdict.padEnd(15)} ${ungovResult.verdict}`);
1110
+ console.log(` ${"Cycles".padEnd(30)} ${String(govResult.totalCycles).padEnd(15)} ${ungovResult.totalCycles}`);
1111
+ console.log(` ${"Artifacts Blocked".padEnd(30)} ${String(govResult.actionGovernance.blocked).padEnd(15)} ${ungovResult.actionGovernance.blocked}`);
1112
+ console.log(` ${"Interventions".padEnd(30)} ${String(govResult.dynamicsGovernance.totalInterventions).padEnd(15)} ${ungovResult.dynamicsGovernance.totalInterventions}`);
1113
+ // Science state interpretation — side by side
1114
+ const sciState = govResult.finalScienceState;
1115
+ const ungovSciState = ungovResult.finalScienceState;
1116
+ console.log(`\n SCIENCE STATE`);
1117
+ console.log(" " + "-".repeat(70));
1118
+ console.log(` ${"".padEnd(30)} ${"Governed".padEnd(20)} ${"Ungoverned"}`);
1119
+ console.log(" " + "-".repeat(70));
1120
+ console.log(` ${"Hypothesis Fragmentation".padEnd(30)} ${sciState.hypothesisFragmentation.padEnd(20)} ${ungovSciState.hypothesisFragmentation}`);
1121
+ console.log(` ${"Publication Pressure".padEnd(30)} ${sciState.publicationPressure.padEnd(20)} ${ungovSciState.publicationPressure}`);
1122
+ console.log(` ${"Reproducibility".padEnd(30)} ${sciState.reproducibilityConfidence.padEnd(20)} ${ungovSciState.reproducibilityConfidence}`);
1123
+ console.log(` ${"Citation Health".padEnd(30)} ${sciState.citationHealth.padEnd(20)} ${ungovSciState.citationHealth}`);
1124
+ console.log(` ${"False Positive Risk".padEnd(30)} ${sciState.falsePositiveRisk.padEnd(20)} ${ungovSciState.falsePositiveRisk}`);
1125
+ console.log(` ${"Discovery Velocity".padEnd(30)} ${sciState.discoveryVelocity.padEnd(20)} ${ungovSciState.discoveryVelocity}`);
1126
+ console.log(`\n Governed: ${sciState.overallAssessment}`);
1127
+ console.log(` Ungoverned: ${ungovSciState.overallAssessment}`);
1128
+ console.log(`\n This simulation was generated by ScienceClaw.`);
1129
+ console.log(` NeuroVerse governance altered the research trajectory in real time.`);
1130
+ }
1131
+ else {
1132
+ // Single governed investigation
1133
+ console.log(` Mode: GOVERNED INVESTIGATION\n`);
1134
+ console.log(` Running governed investigation (${demo.artifactCycles.length} artifact cycles)...\n`);
1135
+ const adapter = createScienceClawAdapter({
1136
+ onCycleComplete: (result) => {
1137
+ const state = result.scienceState;
1138
+ const flags = result.riskFlags.length > 0 ? ` [${result.riskFlags.length} flags]` : "";
1139
+ console.log(` Cycle ${String(result.cycle).padEnd(3)} | approved: ${result.artifactsApproved} blocked: ${result.artifactsBlocked} | ${result.dynamics.trajectory}${flags}`);
1140
+ },
1141
+ onConvergence: (cycle, assessment) => {
1142
+ console.log(`\n >>> CONVERGENCE at cycle ${cycle}: ${assessment}`);
1143
+ },
1144
+ onHalt: (reason, cycle) => {
1145
+ console.log(`\n >>> HALTED at cycle ${cycle}: ${reason}`);
1146
+ },
1147
+ });
1148
+ const result = adapter.runGovernedInvestigation(demo.artifactCycles, demo.matchesByCycle);
1149
+ // State timeline
1150
+ console.log(`\n STATE EVOLUTION`);
1151
+ console.log(" " + "-".repeat(70));
1152
+ console.log(` ${"Cycle".padEnd(8)} ${"Trust".padEnd(10)} ${"Fragment".padEnd(10)} ${"Pressure".padEnd(10)} ${"Cascade".padEnd(10)} ${"Trajectory"}`);
1153
+ for (const snap of result.stateTimeline) {
1154
+ const round = result.cycles.find(c => c.cycle === snap.round);
1155
+ console.log(` ${String(snap.round).padEnd(8)} ${(snap.trust * 100).toFixed(0).padStart(4)}% ${(snap.polarization * 100).toFixed(0).padStart(4)}% ${(snap.outrage * 100).toFixed(0).padStart(4)}% ${(snap.cascadeRisk * 100).toFixed(0).padStart(4)}% ${round?.dynamics.trajectory ?? "-"}`);
1156
+ }
1157
+ // Summary
1158
+ console.log(`\n INVESTIGATION SUMMARY`);
1159
+ console.log(" " + "=".repeat(50));
1160
+ console.log(` Verdict: ${result.verdict.toUpperCase()}`);
1161
+ console.log(` Cycles: ${result.totalCycles}`);
1162
+ console.log(` Artifacts: ${result.actionGovernance.totalEvaluations} evaluated`);
1163
+ console.log(` Approved: ${result.actionGovernance.approved}`);
1164
+ console.log(` Blocked: ${result.actionGovernance.blocked}`);
1165
+ console.log(` Modified: ${result.actionGovernance.modified}`);
1166
+ console.log(` Interventions: ${result.dynamicsGovernance.totalInterventions}`);
1167
+ console.log(` Propagation: ${result.dynamicsGovernance.propagationLimits}`);
1168
+ console.log(` Amplification: ${result.dynamicsGovernance.amplificationDampens}`);
1169
+ console.log(` Cascade Break: ${result.dynamicsGovernance.cascadeBreakers}`);
1170
+ console.log(` Trust Boost: ${result.dynamicsGovernance.trustBoosts}`);
1171
+ console.log(` Cooling: ${result.dynamicsGovernance.coolingPeriods}`);
1172
+ // Final science state
1173
+ console.log(`\n FINAL SCIENCE STATE`);
1174
+ console.log(" " + "-".repeat(50));
1175
+ const sciState = result.finalScienceState;
1176
+ console.log(` ${sciState.overallAssessment}`);
1177
+ console.log(` Reproducibility: ${sciState.reproducibilityConfidence}`);
1178
+ console.log(` Citation Health: ${sciState.citationHealth}`);
1179
+ console.log(` False Positives: ${sciState.falsePositiveRisk}`);
1180
+ }
1181
+ console.log(`\n ${"=".repeat(60)}`);
1182
+ console.log(` Powered by ScienceClaw. Governed by NeuroVerse.`);
1183
+ console.log(` ${"=".repeat(60)}`);
1184
+ console.log(`\n neuroverse-simulations | @neuroverseos\n`);
1185
+ break;
1186
+ }
1187
+ case "enforce": {
1188
+ // ==============================================
1189
+ // POLICY ENFORCEMENT — Iterative Governance Lab
1190
+ //
1191
+ // "Design rules. Run reality. See what changes."
1192
+ //
1193
+ // Same scenario, different rules, measurable divergence.
1194
+ // ==============================================
1195
+ const { createEnforcementSession, formatEnforcementReport, exportEnforcementReportJSON, formatGuidedNextSteps, formatPolicyDiagnostics, formatRuleImpactAttribution, detectSystemArchetype, createSavedExperiment, formatMultiPatchComparison, loadExperimentLibrary, formatExperimentLineage, formatSimilarExperiments, formatBestKnownStrategy, governedDetectArchetype, governedSynthesizeStrategy, governedFindSimilar } = await Promise.resolve().then(() => __importStar(require("./policyEnforcement")));
1196
+ const { createSavedWorld, forkWorld, loadWorldFromFile } = await Promise.resolve().then(() => __importStar(require("./worldStorage")));
1197
+ const { parseRulesFromText, validatePolicy, policyToWorld, applyQuickFix } = await Promise.resolve().then(() => __importStar(require("./policyEngine")));
1198
+ const presetArg = (args[1] && !args[1].startsWith("--")) ? args[1] : "trading";
1199
+ const outputJson = args.includes("--json");
1200
+ const outputFile = args.find(a => a.startsWith("--output="))?.split("=")[1];
1201
+ // Support multiple --patch flags: --patch POL-001 --patch POL-002
1202
+ const patchDiagIds = [];
1203
+ for (let i = 0; i < args.length; i++) {
1204
+ if (args[i] === "--patch" && args[i + 1] && !args[i + 1].startsWith("--")) {
1205
+ patchDiagIds.push(args[i + 1]);
1206
+ }
1207
+ else if (args[i].startsWith("--patch=")) {
1208
+ patchDiagIds.push(args[i].split("=")[1]);
1209
+ }
1210
+ }
1211
+ const patchDiagId = patchDiagIds[0];
1212
+ const compareMode = args.includes("--compare");
1213
+ const saveExperiment = args.includes("--save");
1214
+ const saveLabel = args.find(a => a.startsWith("--save="))?.split("=")[1];
1215
+ // Accept .json world files AND .txt/.md policy documents
1216
+ const inputFiles = args.filter(a => (a.endsWith(".json") || a.endsWith(".txt") || a.endsWith(".md")) && a !== outputFile);
1217
+ const worldFiles = inputFiles.filter(a => a.endsWith(".json"));
1218
+ const policyDocFiles = inputFiles.filter(a => a.endsWith(".txt") || a.endsWith(".md"));
1219
+ console.log(`\n POLICY ENFORCEMENT SYSTEM`);
1220
+ console.log(` ${"=".repeat(60)}`);
1221
+ console.log(` Design rules. Run reality. See what changes.\n`);
1222
+ console.log(` NeuroVerse is a control layer. You define the rules.`);
1223
+ console.log(` The simulation shows what happens when those rules are enforced.\n`);
1224
+ // Resolve the base scenario
1225
+ let baseRequest;
1226
+ let basePaths;
1227
+ let baseWorldDef;
1228
+ let scenarioTitle;
1229
+ if (presetArg === "trading" || presetArg === "flash_crash") {
1230
+ baseRequest = governedSimulation_1.TRADING_DEMO.scenario;
1231
+ basePaths = [...governedSimulation_1.TRADING_DEMO.paths];
1232
+ baseWorldDef = governedSimulation_1.TRADING_DEMO.world;
1233
+ scenarioTitle = "Flash Crash — Algorithmic Cascade";
1234
+ }
1235
+ else {
1236
+ const template = scenarioCapsule_1.SCENARIO_TEMPLATES[presetArg];
1237
+ if (!template || !template.world?.inline_definition) {
1238
+ console.error(` Unknown preset: ${presetArg}`);
1239
+ console.error(` Available: trading, ${Object.keys(scenarioCapsule_1.SCENARIO_TEMPLATES).join(", ")}`);
1240
+ process.exit(1);
1241
+ }
1242
+ baseRequest = {
1243
+ scenario: template.scenario,
1244
+ stakeholders: template.stakeholders,
1245
+ assumptions: template.assumptions,
1246
+ constraints: template.constraints,
1247
+ depth: "full",
1248
+ swarm: { enabled: true, rounds: 5, reaction_model: "mixed" },
1249
+ };
1250
+ basePaths = [
1251
+ {
1252
+ id: "path_primary",
1253
+ label: "Primary Response",
1254
+ description: "The most likely course of action given the scenario",
1255
+ projected_outcome: "Moderate disruption with cascading effects",
1256
+ probability: 0.6,
1257
+ risk: "high",
1258
+ tradeoffs: ["Speed vs. thoroughness", "Short-term vs. long-term"],
1259
+ benefits_stakeholders: template.stakeholders.filter((s) => s.disposition === "supportive").map((s) => s.id),
1260
+ harms_stakeholders: template.stakeholders.filter((s) => s.disposition === "hostile").map((s) => s.id),
1261
+ },
1262
+ {
1263
+ id: "path_defensive",
1264
+ label: "Defensive Posture",
1265
+ description: "Conservative approach prioritizing stability over opportunity",
1266
+ projected_outcome: "Reduced damage but slower recovery",
1267
+ probability: 0.7,
1268
+ risk: "moderate",
1269
+ tradeoffs: ["Safety vs. opportunity cost", "Coordination cost vs. independence"],
1270
+ benefits_stakeholders: template.stakeholders.filter((s) => s.disposition !== "hostile").map((s) => s.id),
1271
+ harms_stakeholders: [],
1272
+ },
1273
+ ];
1274
+ baseWorldDef = template.world.inline_definition;
1275
+ scenarioTitle = template.title;
1276
+ }
1277
+ console.log(` Scenario: ${scenarioTitle}`);
1278
+ // Create session
1279
+ const session = createEnforcementSession(scenarioTitle, baseRequest, basePaths);
1280
+ // Convert policy documents (.txt/.md) to world files
1281
+ const convertedWorlds = [];
1282
+ if (policyDocFiles.length > 0) {
1283
+ console.log(` Converting ${policyDocFiles.length} policy document(s) to world files...\n`);
1284
+ for (const docFile of policyDocFiles) {
1285
+ try {
1286
+ let docText = fs.readFileSync(docFile, "utf-8");
1287
+ // --patch: auto-apply a quick fix before converting
1288
+ if (patchDiagId) {
1289
+ const preParsed = parseRulesFromText(docText);
1290
+ const preHealth = validatePolicy(preParsed);
1291
+ const targetDiag = preHealth.diagnostics.find(d => d.id === patchDiagId);
1292
+ if (targetDiag?.quickFix) {
1293
+ console.log(` Applying fix ${patchDiagId}: ${targetDiag.quickFix.label}`);
1294
+ docText = applyQuickFix(docText, targetDiag.quickFix);
1295
+ console.log(` Patched. Running with fixed rules.\n`);
1296
+ }
1297
+ else if (targetDiag) {
1298
+ console.log(` ${patchDiagId} found but has no quick fix available.\n`);
1299
+ }
1300
+ else {
1301
+ console.log(` ${patchDiagId} not found in diagnostics for ${docFile}.\n`);
1302
+ }
1303
+ }
1304
+ const parsed = parseRulesFromText(docText);
1305
+ const health = validatePolicy(parsed);
1306
+ const worldDef = policyToWorld(parsed);
1307
+ const docName = docFile.replace(/^.*[\\/]/, "").replace(/\.\w+$/, "");
1308
+ const world = createSavedWorld(docName, worldDef, presetArg, { description: `Generated from ${docFile}` });
1309
+ console.log(` ${docFile} → "${docName}"`);
1310
+ console.log(` World: ${worldDef.invariants.length} invariants, ${worldDef.gates.length} gates`);
1311
+ // GitHub-style policy review — show diagnostics with quick fixes
1312
+ console.log(formatPolicyDiagnostics(health, parsed, docFile));
1313
+ // If errors would block simulation, warn but continue
1314
+ if (!health.canSimulate) {
1315
+ console.error(` ✗ ${docFile} has blocking errors — skipping.`);
1316
+ console.error(` Fix the issues above and run again.\n`);
1317
+ continue;
1318
+ }
1319
+ convertedWorlds.push(world);
1320
+ }
1321
+ catch (e) {
1322
+ console.error(` Failed to convert ${docFile}: ${e.message}`);
1323
+ }
1324
+ }
1325
+ }
1326
+ // Build ordered list of worlds to test: JSON files first, then converted docs
1327
+ const worldsToRun = [];
1328
+ for (const jsonFile of worldFiles) {
1329
+ try {
1330
+ const w = await loadWorldFromFile(jsonFile);
1331
+ worldsToRun.push({ label: jsonFile, world: w });
1332
+ }
1333
+ catch (e) {
1334
+ console.error(` Failed to load ${jsonFile}: ${e.message}`);
1335
+ }
1336
+ }
1337
+ for (const cw of convertedWorlds) {
1338
+ worldsToRun.push({ label: cw.name, world: cw });
1339
+ }
1340
+ // If user provided files (JSON or docs), run them. Otherwise, run progressive rule sets.
1341
+ if (worldsToRun.length > 0) {
1342
+ console.log(` Running ${worldsToRun.length} world(s)...\n`);
1343
+ for (let i = 0; i < worldsToRun.length; i++) {
1344
+ try {
1345
+ const world = worldsToRun[i].world;
1346
+ console.log(` Run ${i + 1}: "${world.name}" (${world.world.invariants.length} rules, ${(world.world.gates ?? []).length} gates)`);
1347
+ const run = await session.run(world);
1348
+ console.log(` → Stability: ${(run.result.governed.metrics.stabilityScore * 100).toFixed(0)}% Collapse: ${(run.result.governed.metrics.collapseProbability * 100).toFixed(0)}% Effectiveness: ${(run.result.comparison.governanceEffectiveness * 100).toFixed(0)}%`);
1349
+ }
1350
+ catch (e) {
1351
+ console.error(` Failed to run "${worldsToRun[i].label}": ${e.message}`);
1352
+ }
1353
+ }
1354
+ }
1355
+ else {
1356
+ // Progressive enforcement: no rules → light rules → full rules
1357
+ console.log(` Running progressive enforcement (3 iterations)...\n`);
1358
+ // Run 1: No rules (baseline world)
1359
+ const noRulesWorld = createSavedWorld("No Rules", { thesis: baseWorldDef.thesis, state_variables: baseWorldDef.state_variables ?? [], invariants: [], gates: [] }, presetArg, { description: "Baseline — no governance rules applied" });
1360
+ console.log(` Run 1: "No Rules" (0 invariants, 0 gates)`);
1361
+ const run1 = await session.run(noRulesWorld);
1362
+ console.log(` → Stability: ${(run1.result.governed.metrics.stabilityScore * 100).toFixed(0)}% Collapse: ${(run1.result.governed.metrics.collapseProbability * 100).toFixed(0)}% Effectiveness: ${(run1.result.comparison.governanceEffectiveness * 100).toFixed(0)}%`);
1363
+ // Run 2: Light rules (pick first 2 invariants)
1364
+ const lightInvariants = baseWorldDef.invariants.slice(0, 2);
1365
+ const lightWorld = createSavedWorld("Light Governance", { thesis: baseWorldDef.thesis, state_variables: baseWorldDef.state_variables ?? [], invariants: lightInvariants, gates: [] }, presetArg, { description: "Partial rules — testing minimal governance" });
1366
+ console.log(` Run 2: "Light Governance" (${lightInvariants.length} invariants, 0 gates)`);
1367
+ const run2 = await session.run(lightWorld);
1368
+ console.log(` → Stability: ${(run2.result.governed.metrics.stabilityScore * 100).toFixed(0)}% Collapse: ${(run2.result.governed.metrics.collapseProbability * 100).toFixed(0)}% Effectiveness: ${(run2.result.comparison.governanceEffectiveness * 100).toFixed(0)}%`);
1369
+ // Run 3: Full rules
1370
+ const fullWorld = createSavedWorld("Full Governance", baseWorldDef, presetArg, { description: "All rules active — full governance enforcement" });
1371
+ console.log(` Run 3: "Full Governance" (${baseWorldDef.invariants.length} invariants, ${(baseWorldDef.gates ?? []).length} gates)`);
1372
+ const run3 = await session.run(fullWorld);
1373
+ console.log(` → Stability: ${(run3.result.governed.metrics.stabilityScore * 100).toFixed(0)}% Collapse: ${(run3.result.governed.metrics.collapseProbability * 100).toFixed(0)}% Effectiveness: ${(run3.result.comparison.governanceEffectiveness * 100).toFixed(0)}%`);
1374
+ }
1375
+ // Generate report
1376
+ const report = session.generateReport();
1377
+ if (outputJson || outputFile) {
1378
+ const json = exportEnforcementReportJSON(report);
1379
+ if (outputFile) {
1380
+ fs.writeFileSync(outputFile, json, "utf-8");
1381
+ console.log(`\n Report saved to: ${outputFile}`);
1382
+ }
1383
+ else {
1384
+ console.log(json);
1385
+ }
1386
+ }
1387
+ else {
1388
+ console.log(formatEnforcementReport(report));
1389
+ // Behavioral analysis — what agents did differently under governance
1390
+ for (const run of session.runs) {
1391
+ console.log(`\n ── Behavioral Analysis: Run ${run.iteration} (${run.world.name}) ──`);
1392
+ console.log((0, behavioralAnalysis_1.formatBehavioralAnalysis)(run.result.behavioralAnalysis));
1393
+ }
1394
+ // Rule impact attribution — show which rules shaped the outcome
1395
+ const attribution = formatRuleImpactAttribution(report);
1396
+ if (attribution) {
1397
+ console.log(attribution);
1398
+ }
1399
+ // System archetype insight — governed AI detects system patterns
1400
+ const archetypeGov = await governedDetectArchetype(report);
1401
+ const archetypeInsight = archetypeGov.result;
1402
+ if (archetypeInsight) {
1403
+ console.log(archetypeInsight);
1404
+ // Show governance trace for archetype detection
1405
+ console.log(` ┌─ Governed AI ────────────────────────────────┐`);
1406
+ console.log(` │ Actor: ${archetypeGov.actor.padEnd(40)}│`);
1407
+ console.log(` │ Action: ${"detect_archetype".padEnd(39)}│`);
1408
+ console.log(` │ Constraints: ${String(archetypeGov.trace.constraints.length).padEnd(34)}│`);
1409
+ console.log(` │ Passed: ${String(archetypeGov.trace.passed).padEnd(39)}│`);
1410
+ console.log(` └──────────────────────────────────────────────┘`);
1411
+ }
1412
+ // Load experiment library for knowledge features
1413
+ const experimentLibrary = loadExperimentLibrary();
1414
+ const bestRun = report.runs[report.divergence.bestIteration - 1];
1415
+ const currentMetrics = bestRun
1416
+ ? { stability: bestRun.metrics.stabilityScore, effectiveness: bestRun.comparison.governanceEffectiveness }
1417
+ : { stability: 0, effectiveness: 0 };
1418
+ // Find similar experiments + best known strategy — ALL governed
1419
+ if (experimentLibrary.length > 0 && bestRun) {
1420
+ const runArchetype = archetypeInsight
1421
+ ? (archetypeInsight.match(/behaves like: (.+)/)?.[1] ?? null)
1422
+ : null;
1423
+ // Governed similarity search
1424
+ const similarGov = await governedFindSimilar(runArchetype, currentMetrics, experimentLibrary);
1425
+ if (similarGov.result) {
1426
+ console.log(similarGov.result);
1427
+ console.log(` ┌─ Governed AI ────────────────────────────────┐`);
1428
+ console.log(` │ Actor: ${similarGov.actor.padEnd(40)}│`);
1429
+ console.log(` │ Action: ${"compare_experiments".padEnd(39)}│`);
1430
+ console.log(` │ Constraints: ${String(similarGov.trace.constraints.length).padEnd(34)}│`);
1431
+ console.log(` │ Passed: ${String(similarGov.trace.passed).padEnd(39)}│`);
1432
+ console.log(` └──────────────────────────────────────────────┘`);
1433
+ }
1434
+ // Governed strategy synthesis
1435
+ const strategyGov = await governedSynthesizeStrategy(runArchetype, currentMetrics, experimentLibrary);
1436
+ if (strategyGov.result) {
1437
+ console.log(strategyGov.result);
1438
+ console.log(` ┌─ Governed AI ────────────────────────────────┐`);
1439
+ console.log(` │ Actor: ${strategyGov.actor.padEnd(40)}│`);
1440
+ console.log(` │ Action: ${"synthesize_strategy".padEnd(39)}│`);
1441
+ console.log(` │ Constraints: ${String(strategyGov.trace.constraints.length).padEnd(34)}│`);
1442
+ console.log(` │ Passed: ${String(strategyGov.trace.passed).padEnd(39)}│`);
1443
+ console.log(` └──────────────────────────────────────────────┘`);
1444
+ }
1445
+ }
1446
+ // --compare: show side-by-side before/after when used with --patch
1447
+ if (compareMode && patchDiagId && report.runs.length >= 1) {
1448
+ const run = report.runs[report.runs.length - 1];
1449
+ const baseStab = report.runs.length > 1 ? report.runs[0].metrics.stabilityScore : 0.5;
1450
+ const baseEff = report.runs.length > 1 ? report.runs[0].comparison.governanceEffectiveness : 0;
1451
+ const baseCollapse = report.runs.length > 1 ? report.runs[0].metrics.collapseProbability : 0.15;
1452
+ // Multi-patch comparison
1453
+ if (patchDiagIds.length > 1) {
1454
+ // Build comparison data from available runs
1455
+ const patchResults = patchDiagIds.map((pid, idx) => {
1456
+ const patchRun = idx < report.runs.length ? report.runs[idx] : run;
1457
+ return {
1458
+ patchId: pid,
1459
+ stability: patchRun.metrics.stabilityScore,
1460
+ effectiveness: patchRun.comparison.governanceEffectiveness,
1461
+ collapse: patchRun.metrics.collapseProbability,
1462
+ };
1463
+ });
1464
+ console.log(formatMultiPatchComparison(patchResults, {
1465
+ stability: baseStab,
1466
+ effectiveness: baseEff,
1467
+ collapse: baseCollapse,
1468
+ }));
1469
+ }
1470
+ else {
1471
+ // Single patch comparison
1472
+ console.log(" BEFORE vs AFTER (--compare)");
1473
+ console.log(" " + "-".repeat(70));
1474
+ console.log(` Patch applied: ${patchDiagId}`);
1475
+ console.log("");
1476
+ console.log(" Metric Before (baseline) After (patched)");
1477
+ console.log(" " + "─".repeat(60));
1478
+ console.log(` Stability ${(baseStab * 100).toFixed(0).padStart(3)}% ${(run.metrics.stabilityScore * 100).toFixed(0).padStart(3)}%`);
1479
+ console.log(` Effectiveness ${(baseEff * 100).toFixed(0).padStart(3)}% ${(run.comparison.governanceEffectiveness * 100).toFixed(0).padStart(3)}%`);
1480
+ console.log(` Collapse risk ${(baseCollapse * 100).toFixed(0).padStart(3)}% ${(run.metrics.collapseProbability * 100).toFixed(0).padStart(3)}%`);
1481
+ const stabDelta = run.metrics.stabilityScore - baseStab;
1482
+ const effDelta = run.comparison.governanceEffectiveness - baseEff;
1483
+ console.log("");
1484
+ console.log(` Net change: ${stabDelta >= 0 ? "+" : ""}${(stabDelta * 100).toFixed(0)} stability, ${effDelta >= 0 ? "+" : ""}${(effDelta * 100).toFixed(0)} effectiveness`);
1485
+ if (stabDelta > 0 && effDelta > 0) {
1486
+ console.log(" The fix improved both dimensions. Apply it permanently.");
1487
+ }
1488
+ else if (stabDelta > 0 && effDelta <= 0) {
1489
+ console.log(" Stability improved but effectiveness didn't. The fix may be too conservative.");
1490
+ }
1491
+ else if (stabDelta <= 0 && effDelta > 0) {
1492
+ console.log(" Effectiveness improved but stability dropped. The fix may need guardrails.");
1493
+ }
1494
+ console.log("");
1495
+ }
1496
+ }
1497
+ // --save: persist this experiment with lineage tracking
1498
+ if (saveExperiment || saveLabel) {
1499
+ const rulesFile = policyDocFiles.length > 0 ? policyDocFiles[0] : null;
1500
+ // Find parent experiment — most recent experiment for same scenario
1501
+ const parentExp = experimentLibrary.length > 0
1502
+ ? experimentLibrary.filter(e => e.scenario === report.scenario).pop() ?? null
1503
+ : null;
1504
+ const experiment = createSavedExperiment(report, rulesFile, patchDiagIds, parentExp);
1505
+ const savePath = saveLabel
1506
+ ? `experiments/${saveLabel}.json`
1507
+ : `experiments/${experiment.id}.json`;
1508
+ try {
1509
+ fs.mkdirSync("experiments", { recursive: true });
1510
+ fs.writeFileSync(savePath, JSON.stringify(experiment, null, 2));
1511
+ console.log("");
1512
+ console.log(" EXPERIMENT SAVED");
1513
+ console.log(" " + "-".repeat(70));
1514
+ console.log(` Saved to: ${savePath}`);
1515
+ console.log(` ID: ${experiment.id}`);
1516
+ console.log(` Scenario: ${experiment.scenario}`);
1517
+ console.log(` Generation: ${experiment.lineage.generation}`);
1518
+ console.log(` Stability: ${(experiment.metrics.stability * 100).toFixed(0)}% Effectiveness: ${(experiment.metrics.effectiveness * 100).toFixed(0)}%`);
1519
+ if (experiment.archetype) {
1520
+ console.log(` Archetype: ${experiment.archetype}`);
1521
+ }
1522
+ if (experiment.lineage.parentId) {
1523
+ const imp = experiment.lineage.improvementFromParent;
1524
+ console.log(` Derived from: ${experiment.lineage.parentId}`);
1525
+ console.log(` Improvement: ${imp.stability >= 0 ? "+" : ""}${(imp.stability * 100).toFixed(0)} stability, ${imp.effectiveness >= 0 ? "+" : ""}${(imp.effectiveness * 100).toFixed(0)} effectiveness`);
1526
+ if (experiment.lineage.patchesFromParent.length > 0) {
1527
+ console.log(` Patches applied: ${experiment.lineage.patchesFromParent.join(", ")}`);
1528
+ }
1529
+ }
1530
+ // Show lineage chain
1531
+ const updatedLibrary = [...experimentLibrary, experiment];
1532
+ console.log(formatExperimentLineage(experiment, updatedLibrary));
1533
+ console.log(" Compare experiments later:");
1534
+ console.log(` npx nv-sim enforce trading --compare-experiments ${savePath}`);
1535
+ console.log("");
1536
+ }
1537
+ catch {
1538
+ console.log(`\n Could not save experiment to ${savePath}`);
1539
+ }
1540
+ }
1541
+ // Show guided next steps (skip for JSON output)
1542
+ const usedCustomFiles = inputFiles.length > 0;
1543
+ console.log(await formatGuidedNextSteps(report, usedCustomFiles));
1544
+ }
1545
+ break;
1546
+ }
543
1547
  case "help":
544
1548
  case "--help":
545
1549
  case "-h":
@@ -558,15 +1562,38 @@ async function main() {
558
1562
  --compare to test across multiple worlds
559
1563
  scenarios List all available scenarios
560
1564
  worlds <a> <b> Same agents, different rule environments
1565
+ enforce [preset] Policy enforcement lab — iterative rule testing
1566
+ Run same scenario with different rules, see divergence
1567
+ --json to output JSON report
1568
+ --output=file.json to save report
1569
+ Pass world files: nv-sim enforce trading a.json b.json
561
1570
  chaos [preset] Stress test — find the breaking point
562
1571
  visualize Interactive scenario control platform
563
1572
  serve | govern Start local governance runtime
564
1573
  --port N (default: 3456)
565
1574
  run <simulator> Run external simulator with governance
566
1575
  e.g., nv-sim run mirofish
1576
+ radiant [preset] Prime Radiant — full policy enforcement system
1577
+ Dual-layer: govern() + governDynamics()
1578
+ --world MODE 1: build & validate world
1579
+ --compare MODE 3: decision intelligence (N options)
1580
+ (default) MODE 2: governed simulation with comparison
1581
+ mirofish MiroFish agent simulation with governance
1582
+ --compare Governed vs ungoverned comparison
1583
+ science Science mode — governed autonomous discovery
1584
+ --compare Governed vs ungoverned comparison
1585
+ world-from-doc <file> Generate world rules from a document
1586
+ --output file.json --id my-world
567
1587
  analyze <file> Analyze a simulation from file or stdin
568
1588
  presets List available preset scenarios
569
- help Show this help message
1589
+
1590
+ WORLD MANAGEMENT:
1591
+
1592
+ world:save <preset> [output.json] Save a world as JSON file
1593
+ --name="My World Name"
1594
+ world:load <file.json> Inspect a saved world file
1595
+ world:list List all available worlds
1596
+ world:compare <a.json> <b.json> Compare two saved world files
570
1597
 
571
1598
  PRESETS:
572
1599
 
@@ -590,8 +1617,38 @@ async function main() {
590
1617
  npx nv-sim scenario bank_run --compare # Cross-world comparison
591
1618
  npx nv-sim scenarios # List all scenarios
592
1619
  npx nv-sim analyze simulation.json
1620
+ npx nv-sim world-from-doc policy.md # Generate world from document
1621
+ npx nv-sim world-from-doc rules.txt --output world.json
1622
+ npx nv-sim world:save trading my-world.json # Save world to file
1623
+ npx nv-sim world:load my-world.json # Inspect a saved world
1624
+ npx nv-sim world:compare a.json b.json # Compare two world files
1625
+
1626
+ POLICY ENFORCEMENT:
1627
+
1628
+ npx nv-sim enforce # Progressive: no rules → light → full
1629
+ npx nv-sim enforce strait_of_hormuz # Same, with geopolitical preset
1630
+ npx nv-sim enforce trading a.json b.json # Compare custom world files
1631
+ npx nv-sim enforce --output=report.json # Save report as JSON
1632
+
1633
+ PRIME RADIANT:
1634
+
1635
+ npx nv-sim radiant # Full governed simulation
1636
+ npx nv-sim radiant university_crisis # University crisis preset
1637
+ npx nv-sim radiant financial_crisis --compare # Decision intelligence mode
1638
+ npx nv-sim radiant geopolitical_crisis --world # World builder mode
1639
+ npx nv-sim radiant scientific_discovery # Science discovery preset
1640
+
1641
+ MIROFISH MODE:
593
1642
 
594
- Simulate the future. Govern the outcomes.
1643
+ npx nv-sim mirofish # Governed agent simulation
1644
+ npx nv-sim mirofish --compare # Governed vs ungoverned comparison
1645
+
1646
+ SCIENCE MODE:
1647
+
1648
+ npx nv-sim science # Governed investigation demo
1649
+ npx nv-sim science --compare # Governed vs ungoverned comparison
1650
+
1651
+ Design rules. Run reality. See what changes.
595
1652
  `);
596
1653
  break;
597
1654
  }
@@ -699,18 +1756,20 @@ function printComparisonResults(result, worldId) {
699
1756
  }
700
1757
  }
701
1758
  }
1759
+ // Behavioral analysis — what agents did differently
1760
+ console.log((0, behavioralAnalysis_1.formatBehavioralAnalysis)(result.behavioralAnalysis));
702
1761
  // Key message
703
1762
  console.log(`\n ${"=".repeat(60)}`);
704
1763
  console.log(` NeuroVerse doesn't just stop bad actions.`);
705
1764
  console.log(` It changes the structure of the system itself.`);
706
1765
  console.log(` ${"=".repeat(60)}`);
707
- console.log(`\n Simulate the future. Govern the outcomes.`);
1766
+ console.log(`\n Design rules. Run reality. See what changes.`);
708
1767
  console.log(` neuroverse-simulations | @neuroverseos\n`);
709
1768
  }
710
1769
  // ============================================
711
1770
  // WORLD COMPARISON OUTPUT
712
1771
  // ============================================
713
- function printWorldComparisonResults(r) {
1772
+ function printWorldComparisonResults(r, impact) {
714
1773
  const a = r.worldA;
715
1774
  const b = r.worldB;
716
1775
  const d = r.delta;
@@ -743,6 +1802,21 @@ function printWorldComparisonResults(r) {
743
1802
  console.log(" " + "-".repeat(50));
744
1803
  console.log(` World A: ${a.governanceStats.engineLoaded ? "@neuroverseos/governance" : "heuristic"} — ${a.governanceStats.totalEvaluations} evals (${a.governanceStats.verdicts.allow} allow, ${a.governanceStats.verdicts.block} block, ${a.governanceStats.verdicts.pause} pause)`);
745
1804
  console.log(` World B: ${b.governanceStats.engineLoaded ? "@neuroverseos/governance" : "heuristic"} — ${b.governanceStats.totalEvaluations} evals (${b.governanceStats.verdicts.allow} allow, ${b.governanceStats.verdicts.block} block, ${b.governanceStats.verdicts.pause} pause)`);
1805
+ // Impact analysis (when available)
1806
+ if (impact) {
1807
+ console.log(`\n IMPACT ANALYSIS`);
1808
+ console.log(" " + "=".repeat(50));
1809
+ console.log(` Stability delta: ${impact.stabilityDelta}`);
1810
+ console.log(` Cascade risk delta: ${impact.cascadeRiskDelta}`);
1811
+ console.log(` Volatility delta: ${impact.volatilityDelta}`);
1812
+ console.log(` Interventions A: ${impact.totalInterventionsA} (${impact.blockedActionsA} blocked)`);
1813
+ console.log(` Interventions B: ${impact.totalInterventionsB} (${impact.blockedActionsB} blocked)`);
1814
+ console.log(`\n KEY FINDINGS:`);
1815
+ for (const finding of impact.keyFindings) {
1816
+ console.log(` • ${finding}`);
1817
+ }
1818
+ console.log(`\n Powered by ${impact.poweredBy}`);
1819
+ }
746
1820
  // Narrative
747
1821
  console.log(`\n ANALYSIS`);
748
1822
  console.log(" " + "=".repeat(50));
@@ -763,7 +1837,7 @@ function printWorldComparisonResults(r) {
763
1837
  console.log(` Same agents. Different rules.`);
764
1838
  console.log(` The world shapes the outcome.`);
765
1839
  console.log(` ${"=".repeat(60)}`);
766
- console.log(`\n Simulate the future. Govern the outcomes.`);
1840
+ console.log(`\n Design rules. Run reality. See what changes.`);
767
1841
  console.log(` neuroverse-simulations | @neuroverseos\n`);
768
1842
  }
769
1843
  // ============================================
@@ -829,7 +1903,7 @@ function printChaosResults(r) {
829
1903
  }
830
1904
  console.log(` Tested with nv-sim chaos (${r.runsCompleted} runs, ${(r.durationMs / 1000).toFixed(1)}s)`);
831
1905
  console.log(` ${"=".repeat(60)}`);
832
- console.log(`\n Simulate the future. Govern the outcomes.`);
1906
+ console.log(`\n Design rules. Run reality. See what changes.`);
833
1907
  console.log(` neuroverse-simulations | @neuroverseos\n`);
834
1908
  }
835
1909
  main().catch((err) => {