@neuroverseos/governance 0.3.4 → 0.5.0

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 (104) hide show
  1. package/README.md +280 -405
  2. package/dist/adapters/autoresearch.cjs +63 -9
  3. package/dist/adapters/autoresearch.d.cts +1 -1
  4. package/dist/adapters/autoresearch.d.ts +1 -1
  5. package/dist/adapters/autoresearch.js +3 -3
  6. package/dist/adapters/deep-agents.cjs +63 -9
  7. package/dist/adapters/deep-agents.d.cts +2 -2
  8. package/dist/adapters/deep-agents.d.ts +2 -2
  9. package/dist/adapters/deep-agents.js +3 -3
  10. package/dist/adapters/express.cjs +63 -9
  11. package/dist/adapters/express.d.cts +1 -1
  12. package/dist/adapters/express.d.ts +1 -1
  13. package/dist/adapters/express.js +3 -3
  14. package/dist/adapters/index.cjs +961 -9
  15. package/dist/adapters/index.d.cts +316 -2
  16. package/dist/adapters/index.d.ts +316 -2
  17. package/dist/adapters/index.js +45 -8
  18. package/dist/adapters/langchain.cjs +63 -9
  19. package/dist/adapters/langchain.d.cts +2 -2
  20. package/dist/adapters/langchain.d.ts +2 -2
  21. package/dist/adapters/langchain.js +3 -3
  22. package/dist/adapters/openai.cjs +63 -9
  23. package/dist/adapters/openai.d.cts +2 -2
  24. package/dist/adapters/openai.d.ts +2 -2
  25. package/dist/adapters/openai.js +3 -3
  26. package/dist/adapters/openclaw.cjs +63 -9
  27. package/dist/adapters/openclaw.d.cts +2 -2
  28. package/dist/adapters/openclaw.d.ts +2 -2
  29. package/dist/adapters/openclaw.js +3 -3
  30. package/dist/{add-ROOZLU62.js → add-LYHDZ5RL.js} +1 -1
  31. package/dist/{behavioral-MJO34S6Q.js → behavioral-SPWPGYXL.js} +2 -2
  32. package/dist/{bootstrap-CQRZVOXK.js → bootstrap-IP5QMC3Q.js} +2 -2
  33. package/dist/{bootstrap-emitter-Q7UIJZ2O.js → bootstrap-emitter-GIMOJFOC.js} +1 -1
  34. package/dist/{bootstrap-parser-EEF36XDU.js → bootstrap-parser-LBLGVEMU.js} +1 -1
  35. package/dist/browser.global.js +149 -5
  36. package/dist/{build-ZHPMX5AZ.js → build-SCAWPA7E.js} +4 -4
  37. package/dist/{chunk-G7DJ6VOD.js → chunk-25XHSTPT.js} +2 -2
  38. package/dist/{chunk-A7GKPPU7.js → chunk-2VAWP6FI.js} +1 -1
  39. package/dist/{chunk-EMQDLDAF.js → chunk-3NZMMSOW.js} +80 -2
  40. package/dist/{chunk-YEKMVDWK.js → chunk-4G6WHPLI.js} +5 -5
  41. package/dist/{chunk-B6OXJLJ5.js → chunk-5JUZ4HL7.js} +2 -2
  42. package/dist/{chunk-VXHSMA3I.js → chunk-6CV4XG3J.js} +1 -1
  43. package/dist/{chunk-5TPFNWRU.js → chunk-7D7PZLB7.js} +3 -3
  44. package/dist/{chunk-ZWI3NIXK.js → chunk-7QIAF377.js} +54 -3
  45. package/dist/{chunk-CTZHONLA.js → chunk-BXLTEUS4.js} +2 -2
  46. package/dist/{chunk-O5ABKEA7.js → chunk-DWHUZUEY.js} +2 -2
  47. package/dist/{chunk-U6U7EJZL.js → chunk-JKGPSFGH.js} +2 -2
  48. package/dist/{chunk-3WQLXYTP.js → chunk-MFKHTE5R.js} +2 -2
  49. package/dist/{chunk-TG6SEF24.js → chunk-OQU65525.js} +1 -1
  50. package/dist/{chunk-4FLICVVA.js → chunk-TD5GKIHP.js} +2 -2
  51. package/dist/chunk-U6FRAEQJ.js +893 -0
  52. package/dist/{chunk-IS4WUH6Y.js → chunk-UTH7OXTM.js} +2 -2
  53. package/dist/{chunk-BNKJPUPQ.js → chunk-V4FZHJQX.js} +2 -2
  54. package/dist/{chunk-F66BVUYB.js → chunk-Y6WXAPKY.js} +3 -3
  55. package/dist/{chunk-QXBFT7NI.js → chunk-YNYCQECH.js} +2 -2
  56. package/dist/{chunk-PVTQQS3Y.js → chunk-YPCVY4GS.js} +31 -0
  57. package/dist/{chunk-W7LLXRGY.js → chunk-ZAF6JH23.js} +65 -10
  58. package/dist/cli/neuroverse.cjs +3080 -166
  59. package/dist/cli/neuroverse.js +40 -24
  60. package/dist/cli/plan.cjs +176 -12
  61. package/dist/cli/plan.js +2 -2
  62. package/dist/cli/run.cjs +63 -9
  63. package/dist/cli/run.js +2 -2
  64. package/dist/configure-world-XU2COHOZ.js +705 -0
  65. package/dist/{decision-flow-M63D47LO.js → decision-flow-3K4D72G4.js} +2 -2
  66. package/dist/{demo-G43RLCPK.js → demo-66MMJTEH.js} +3 -3
  67. package/dist/{derive-LMDUTXDD.js → derive-AUQE3L3P.js} +5 -5
  68. package/dist/{doctor-6BC6X2VO.js → doctor-EY7LKSYY.js} +2 -1
  69. package/dist/{equity-penalties-SG5IZQ7I.js → equity-penalties-WWC7UDQD.js} +3 -3
  70. package/dist/{explain-RHBU2GBR.js → explain-MUSGDT67.js} +1 -1
  71. package/dist/{guard-AEEJNWLD.js → guard-W3BMQPBJ.js} +3 -3
  72. package/dist/{guard-contract-B7lplwm9.d.ts → guard-contract-CLBbTGK_.d.cts} +91 -1
  73. package/dist/{guard-contract-B7lplwm9.d.cts → guard-contract-CLBbTGK_.d.ts} +91 -1
  74. package/dist/{guard-engine-PNR6MHCM.js → guard-engine-N7TUIUU7.js} +5 -3
  75. package/dist/{impact-3XVDSCBU.js → impact-WIAM66IH.js} +3 -3
  76. package/dist/{improve-TQP4ECSY.js → improve-PJDAWW4Q.js} +3 -3
  77. package/dist/index.cjs +230 -14
  78. package/dist/index.d.cts +72 -3
  79. package/dist/index.d.ts +72 -3
  80. package/dist/index.js +45 -43
  81. package/dist/{init-FYPV4SST.js → init-TKIJDR7I.js} +5 -1
  82. package/dist/lens-IP6GIZ2Q.js +1017 -0
  83. package/dist/{mcp-server-5Y3ZM7TV.js → mcp-server-OG3PPVD2.js} +3 -3
  84. package/dist/mentraos-LLH7KEV4.js +48 -0
  85. package/dist/{playground-VZBNPPBO.js → playground-4BK2XQ47.js} +2 -2
  86. package/dist/{redteam-MZPZD3EF.js → redteam-BRZALBPP.js} +2 -2
  87. package/dist/{session-JYOARW54.js → session-SGRUT2UH.js} +3 -3
  88. package/dist/{shared-C_zpdvBm.d.cts → shared-BGzmYP5g.d.cts} +1 -1
  89. package/dist/{shared-Cf7yxx4-.d.ts → shared-CwGpPheR.d.ts} +1 -1
  90. package/dist/{simulate-LJXYBC6M.js → simulate-FGXKIH7V.js} +17 -4
  91. package/dist/spatial/index.cjs +682 -0
  92. package/dist/spatial/index.d.cts +517 -0
  93. package/dist/spatial/index.d.ts +517 -0
  94. package/dist/spatial/index.js +633 -0
  95. package/dist/{test-BOOR4A5F.js → test-PT44BSYG.js} +2 -2
  96. package/dist/{trace-PKV4KX56.js → trace-2YDNAXMK.js} +2 -2
  97. package/dist/{validate-RALX7CZS.js → validate-Q5O5TGLT.js} +1 -1
  98. package/dist/{world-BIP4GZBZ.js → world-V52ZMH26.js} +1 -1
  99. package/dist/{world-loader-Y6HMQH2D.js → world-loader-C4D3VPP3.js} +1 -1
  100. package/dist/worlds/mentraos-smartglasses.nv-world.md +423 -0
  101. package/dist/worlds/mentraos-spatial.nv-world.md +68 -0
  102. package/dist/worlds/user-rules.nv-world.md +328 -0
  103. package/package.json +16 -3
  104. package/dist/{configure-ai-5MP5DWTT.js → configure-ai-LL3VAPQW.js} +3 -3
@@ -3,10 +3,10 @@ import {
3
3
  } from "./chunk-4NGDRRQH.js";
4
4
  import {
5
5
  parseWorldMarkdown
6
- } from "./chunk-EMQDLDAF.js";
6
+ } from "./chunk-3NZMMSOW.js";
7
7
  import {
8
8
  emitWorldDefinition
9
- } from "./chunk-PVTQQS3Y.js";
9
+ } from "./chunk-YPCVY4GS.js";
10
10
  import "./chunk-QWGCMQQD.js";
11
11
 
12
12
  // src/cli/bootstrap.ts
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  emitWorldDefinition
3
- } from "./chunk-PVTQQS3Y.js";
3
+ } from "./chunk-YPCVY4GS.js";
4
4
  import "./chunk-QWGCMQQD.js";
5
5
  export {
6
6
  emitWorldDefinition
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parseWorldMarkdown
3
- } from "./chunk-EMQDLDAF.js";
3
+ } from "./chunk-3NZMMSOW.js";
4
4
  import "./chunk-QWGCMQQD.js";
5
5
  export {
6
6
  parseWorldMarkdown
@@ -49,15 +49,25 @@ var NeuroVerse = (() => {
49
49
  let collapseStep;
50
50
  let collapseRule;
51
51
  const sortedRules = [...world.rules].sort((a, b) => a.order - b.order);
52
+ const allEvents = options.events ?? [];
53
+ const eventsByStep = Array.from({ length: steps }, () => []);
54
+ for (let i = 0; i < allEvents.length; i++) {
55
+ const stepIdx = Math.min(i, steps - 1);
56
+ eventsByStep[stepIdx].push(allEvents[i]);
57
+ }
58
+ let totalEventsConsumed = 0;
52
59
  for (let stepNum = 1; stepNum <= steps; stepNum++) {
53
60
  if (collapsed) break;
61
+ const stepEvents = eventsByStep[stepNum - 1];
54
62
  const stepResult = evaluateStep(
55
63
  stepNum,
56
64
  sortedRules,
57
65
  state,
58
66
  assumptions,
59
- world
67
+ world,
68
+ stepEvents
60
69
  );
70
+ totalEventsConsumed += stepResult.eventsApplied.length;
61
71
  simulationSteps.push(stepResult);
62
72
  if (stepResult.collapsed) {
63
73
  collapsed = true;
@@ -76,14 +86,38 @@ var NeuroVerse = (() => {
76
86
  finalViability,
77
87
  collapsed,
78
88
  collapseStep,
79
- collapseRule
89
+ collapseRule,
90
+ eventsConsumed: totalEventsConsumed
80
91
  };
81
92
  }
82
- function evaluateStep(stepNum, rules, state, assumptions, world) {
93
+ function evaluateStep(stepNum, rules, state, assumptions, world, events = []) {
83
94
  const evaluations = [];
95
+ const eventApplications = [];
84
96
  let rulesFired = 0;
85
97
  let collapsed = false;
86
98
  const firedRuleIds = /* @__PURE__ */ new Set();
99
+ for (const evt of events) {
100
+ const application = {
101
+ eventType: evt.type,
102
+ rulesTriggered: [],
103
+ effects: []
104
+ };
105
+ for (const rule of rules) {
106
+ const eventTrigger = rule.triggers.find(
107
+ (t) => t.field === "event" && t.source === "state"
108
+ );
109
+ if (!eventTrigger) continue;
110
+ const matches = evaluateOperator(evt.type, eventTrigger.operator, eventTrigger.value);
111
+ if (!matches) continue;
112
+ application.rulesTriggered.push(rule.id);
113
+ firedRuleIds.add(rule.id);
114
+ for (const effect of rule.effects ?? []) {
115
+ const applied = applyEffect(effect, state);
116
+ if (applied) application.effects.push(applied);
117
+ }
118
+ }
119
+ eventApplications.push(application);
120
+ }
87
121
  for (const rule of rules) {
88
122
  if (collapsed) {
89
123
  evaluations.push({
@@ -168,6 +202,7 @@ var NeuroVerse = (() => {
168
202
  const viability = classifyViability(state, world);
169
203
  return {
170
204
  step: stepNum,
205
+ eventsApplied: eventApplications,
171
206
  rulesEvaluated: evaluations,
172
207
  rulesFired,
173
208
  stateAfter: { ...state },
@@ -662,6 +697,67 @@ var NeuroVerse = (() => {
662
697
  if (!isNaN(num) && raw.trim() !== "") return num;
663
698
  return raw;
664
699
  }
700
+ function parseLenses(content, startLine, issues) {
701
+ const lenses = [];
702
+ const subSections = splitH2Sections(content, startLine);
703
+ for (const sub of subSections) {
704
+ const props = parseKeyValueBullets(sub.content);
705
+ const lineNum = sub.startLine;
706
+ const directives = [];
707
+ const lines = sub.content.split("\n");
708
+ let directiveIndex = 0;
709
+ for (let i = 0; i < lines.length; i++) {
710
+ const line = lines[i].trim();
711
+ if (line.startsWith(">")) {
712
+ const blockContent = line.slice(1).trim();
713
+ const colonIdx = blockContent.indexOf(":");
714
+ if (colonIdx > 0) {
715
+ const scope = blockContent.slice(0, colonIdx).trim();
716
+ let instruction = blockContent.slice(colonIdx + 1).trim();
717
+ for (let j = i + 1; j < lines.length; j++) {
718
+ const nextLine = lines[j].trim();
719
+ if (nextLine.startsWith(">")) {
720
+ const nextContent = nextLine.slice(1).trim();
721
+ const nextColon = nextContent.indexOf(":");
722
+ if (nextColon > 0 && !nextContent.slice(0, nextColon).includes(" ")) {
723
+ break;
724
+ }
725
+ instruction += " " + nextContent;
726
+ i = j;
727
+ } else {
728
+ break;
729
+ }
730
+ }
731
+ directives.push({
732
+ id: `${sub.name}_directive_${directiveIndex++}`,
733
+ scope,
734
+ instruction,
735
+ line: startLine + i
736
+ });
737
+ }
738
+ }
739
+ }
740
+ const tags = (props.tags ?? "").split(",").map((s) => s.trim()).filter(Boolean);
741
+ const defaultForRoles = (props.default_for_roles ?? props.roles ?? "").split(",").map((s) => s.trim()).filter(Boolean);
742
+ lenses.push({
743
+ id: sub.name,
744
+ name: props.name ?? sub.name,
745
+ tagline: props.tagline ?? "",
746
+ description: props.description ?? "",
747
+ tags,
748
+ formality: props.formality ?? "neutral",
749
+ verbosity: props.verbosity ?? "balanced",
750
+ emotion: props.emotion ?? "neutral",
751
+ confidence: props.confidence ?? "balanced",
752
+ defaultForRoles,
753
+ directives,
754
+ priority: props.priority ? parseInt(props.priority, 10) : 50,
755
+ stackable: props.stackable === "false" ? false : true,
756
+ line: lineNum
757
+ });
758
+ }
759
+ return lenses;
760
+ }
665
761
  function parseWorldMarkdown(markdown) {
666
762
  const issues = [];
667
763
  const { frontmatter: fmRaw, sections } = splitSections(markdown);
@@ -699,8 +795,22 @@ var NeuroVerse = (() => {
699
795
  }
700
796
  const outcomesSection = findSection("Outcomes");
701
797
  const outcomes = outcomesSection ? parseOutcomes(outcomesSection.content, outcomesSection.startLine, issues) : [];
798
+ const lensesSection = findSection("Lenses");
799
+ const lenses = lensesSection ? parseLenses(lensesSection.content, lensesSection.startLine, issues) : [];
800
+ let lensPolicy;
801
+ let lensLockPin;
802
+ if (lensesSection) {
803
+ const topContent = lensesSection.content.split(/^##\s/m)[0];
804
+ const topProps = parseKeyValueBullets(topContent);
805
+ if (topProps.policy === "locked" || topProps.policy === "role_default" || topProps.policy === "user_choice") {
806
+ lensPolicy = topProps.policy;
807
+ }
808
+ if (topProps.lock_pin) {
809
+ lensLockPin = topProps.lock_pin;
810
+ }
811
+ }
702
812
  const parsedSections = sections.map((s) => s.name);
703
- const knownSections = /* @__PURE__ */ new Set(["thesis", "invariants", "state", "assumptions", "rules", "gates", "outcomes"]);
813
+ const knownSections = /* @__PURE__ */ new Set(["thesis", "invariants", "state", "assumptions", "rules", "gates", "outcomes", "lenses"]);
704
814
  for (const section of sections) {
705
815
  if (!knownSections.has(section.name.toLowerCase())) {
706
816
  issues.push({
@@ -726,7 +836,10 @@ var NeuroVerse = (() => {
726
836
  assumptions,
727
837
  rules,
728
838
  gates,
729
- outcomes
839
+ outcomes,
840
+ lenses,
841
+ lensPolicy,
842
+ lensLockPin
730
843
  },
731
844
  issues
732
845
  };
@@ -896,6 +1009,36 @@ var NeuroVerse = (() => {
896
1009
  structural_indicators: rules.filter((r) => r.severity === "structural").map((r) => r.id)
897
1010
  }
898
1011
  };
1012
+ const validScopes = /* @__PURE__ */ new Set(["response_framing", "language_style", "content_filtering", "value_emphasis", "behavior_shaping"]);
1013
+ const lensConfigs = parsed.lenses.map((pl) => {
1014
+ const directives = pl.directives.map((d) => ({
1015
+ id: d.id,
1016
+ scope: validScopes.has(d.scope) ? d.scope : "behavior_shaping",
1017
+ instruction: d.instruction
1018
+ }));
1019
+ return {
1020
+ id: pl.id,
1021
+ name: pl.name,
1022
+ tagline: pl.tagline,
1023
+ description: pl.description,
1024
+ tags: pl.tags,
1025
+ tone: {
1026
+ formality: pl.formality || "neutral",
1027
+ verbosity: pl.verbosity || "balanced",
1028
+ emotion: pl.emotion || "neutral",
1029
+ confidence: pl.confidence || "balanced"
1030
+ },
1031
+ directives,
1032
+ defaultForRoles: pl.defaultForRoles,
1033
+ priority: pl.priority,
1034
+ stackable: pl.stackable
1035
+ };
1036
+ });
1037
+ const lensesConfig = lensConfigs.length > 0 ? {
1038
+ lenses: lensConfigs,
1039
+ ...parsed.lensPolicy ? { policy: parsed.lensPolicy } : {},
1040
+ ...parsed.lensLockPin ? { lockPin: parsed.lensLockPin } : {}
1041
+ } : void 0;
899
1042
  const metadata = {
900
1043
  format_version: "1.0.0",
901
1044
  created_at: (/* @__PURE__ */ new Date()).toISOString(),
@@ -910,6 +1053,7 @@ var NeuroVerse = (() => {
910
1053
  rules,
911
1054
  gates,
912
1055
  outcomes,
1056
+ ...lensesConfig ? { lenses: lensesConfig } : {},
913
1057
  metadata
914
1058
  };
915
1059
  return { world: worldDefinition, issues };
@@ -2,19 +2,19 @@ import {
2
2
  DeriveInputError,
3
3
  DeriveProviderError,
4
4
  deriveWorld
5
- } from "./chunk-YEKMVDWK.js";
5
+ } from "./chunk-4G6WHPLI.js";
6
6
  import {
7
7
  DERIVE_EXIT_CODES
8
8
  } from "./chunk-FMSTRBBS.js";
9
- import "./chunk-OT6PXH54.js";
10
9
  import "./chunk-INWQHLPS.js";
10
+ import "./chunk-OT6PXH54.js";
11
11
  import "./chunk-7P3S7MAY.js";
12
12
  import {
13
13
  parseWorldMarkdown
14
- } from "./chunk-EMQDLDAF.js";
14
+ } from "./chunk-3NZMMSOW.js";
15
15
  import {
16
16
  emitWorldDefinition
17
- } from "./chunk-PVTQQS3Y.js";
17
+ } from "./chunk-YPCVY4GS.js";
18
18
  import "./chunk-QWGCMQQD.js";
19
19
 
20
20
  // src/cli/build.ts
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  evaluateGuard
3
- } from "./chunk-W7LLXRGY.js";
3
+ } from "./chunk-ZAF6JH23.js";
4
4
  import {
5
5
  loadWorld
6
- } from "./chunk-CTZHONLA.js";
6
+ } from "./chunk-BXLTEUS4.js";
7
7
 
8
8
  // src/adapters/express.ts
9
9
  function methodToCategory(method) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  evaluateGuard
3
- } from "./chunk-W7LLXRGY.js";
3
+ } from "./chunk-ZAF6JH23.js";
4
4
 
5
5
  // src/engine/audit-logger.ts
6
6
  var FileAuditLogger = class {
@@ -383,6 +383,67 @@ function parseValueLiteral(raw) {
383
383
  if (!isNaN(num) && raw.trim() !== "") return num;
384
384
  return raw;
385
385
  }
386
+ function parseLenses(content, startLine, issues) {
387
+ const lenses = [];
388
+ const subSections = splitH2Sections(content, startLine);
389
+ for (const sub of subSections) {
390
+ const props = parseKeyValueBullets(sub.content);
391
+ const lineNum = sub.startLine;
392
+ const directives = [];
393
+ const lines = sub.content.split("\n");
394
+ let directiveIndex = 0;
395
+ for (let i = 0; i < lines.length; i++) {
396
+ const line = lines[i].trim();
397
+ if (line.startsWith(">")) {
398
+ const blockContent = line.slice(1).trim();
399
+ const colonIdx = blockContent.indexOf(":");
400
+ if (colonIdx > 0) {
401
+ const scope = blockContent.slice(0, colonIdx).trim();
402
+ let instruction = blockContent.slice(colonIdx + 1).trim();
403
+ for (let j = i + 1; j < lines.length; j++) {
404
+ const nextLine = lines[j].trim();
405
+ if (nextLine.startsWith(">")) {
406
+ const nextContent = nextLine.slice(1).trim();
407
+ const nextColon = nextContent.indexOf(":");
408
+ if (nextColon > 0 && !nextContent.slice(0, nextColon).includes(" ")) {
409
+ break;
410
+ }
411
+ instruction += " " + nextContent;
412
+ i = j;
413
+ } else {
414
+ break;
415
+ }
416
+ }
417
+ directives.push({
418
+ id: `${sub.name}_directive_${directiveIndex++}`,
419
+ scope,
420
+ instruction,
421
+ line: startLine + i
422
+ });
423
+ }
424
+ }
425
+ }
426
+ const tags = (props.tags ?? "").split(",").map((s) => s.trim()).filter(Boolean);
427
+ const defaultForRoles = (props.default_for_roles ?? props.roles ?? "").split(",").map((s) => s.trim()).filter(Boolean);
428
+ lenses.push({
429
+ id: sub.name,
430
+ name: props.name ?? sub.name,
431
+ tagline: props.tagline ?? "",
432
+ description: props.description ?? "",
433
+ tags,
434
+ formality: props.formality ?? "neutral",
435
+ verbosity: props.verbosity ?? "balanced",
436
+ emotion: props.emotion ?? "neutral",
437
+ confidence: props.confidence ?? "balanced",
438
+ defaultForRoles,
439
+ directives,
440
+ priority: props.priority ? parseInt(props.priority, 10) : 50,
441
+ stackable: props.stackable === "false" ? false : true,
442
+ line: lineNum
443
+ });
444
+ }
445
+ return lenses;
446
+ }
386
447
  function parseWorldMarkdown(markdown) {
387
448
  const issues = [];
388
449
  const { frontmatter: fmRaw, sections } = splitSections(markdown);
@@ -420,8 +481,22 @@ function parseWorldMarkdown(markdown) {
420
481
  }
421
482
  const outcomesSection = findSection("Outcomes");
422
483
  const outcomes = outcomesSection ? parseOutcomes(outcomesSection.content, outcomesSection.startLine, issues) : [];
484
+ const lensesSection = findSection("Lenses");
485
+ const lenses = lensesSection ? parseLenses(lensesSection.content, lensesSection.startLine, issues) : [];
486
+ let lensPolicy;
487
+ let lensLockPin;
488
+ if (lensesSection) {
489
+ const topContent = lensesSection.content.split(/^##\s/m)[0];
490
+ const topProps = parseKeyValueBullets(topContent);
491
+ if (topProps.policy === "locked" || topProps.policy === "role_default" || topProps.policy === "user_choice") {
492
+ lensPolicy = topProps.policy;
493
+ }
494
+ if (topProps.lock_pin) {
495
+ lensLockPin = topProps.lock_pin;
496
+ }
497
+ }
423
498
  const parsedSections = sections.map((s) => s.name);
424
- const knownSections = /* @__PURE__ */ new Set(["thesis", "invariants", "state", "assumptions", "rules", "gates", "outcomes"]);
499
+ const knownSections = /* @__PURE__ */ new Set(["thesis", "invariants", "state", "assumptions", "rules", "gates", "outcomes", "lenses"]);
425
500
  for (const section of sections) {
426
501
  if (!knownSections.has(section.name.toLowerCase())) {
427
502
  issues.push({
@@ -447,7 +522,10 @@ function parseWorldMarkdown(markdown) {
447
522
  assumptions,
448
523
  rules,
449
524
  gates,
450
- outcomes
525
+ outcomes,
526
+ lenses,
527
+ lensPolicy,
528
+ lensLockPin
451
529
  },
452
530
  issues
453
531
  };
@@ -1,18 +1,18 @@
1
- import {
2
- loadConfig
3
- } from "./chunk-OT6PXH54.js";
4
1
  import {
5
2
  createProvider
6
3
  } from "./chunk-INWQHLPS.js";
4
+ import {
5
+ loadConfig
6
+ } from "./chunk-OT6PXH54.js";
7
7
  import {
8
8
  validateWorld
9
9
  } from "./chunk-7P3S7MAY.js";
10
10
  import {
11
11
  parseWorldMarkdown
12
- } from "./chunk-EMQDLDAF.js";
12
+ } from "./chunk-3NZMMSOW.js";
13
13
  import {
14
14
  emitWorldDefinition
15
- } from "./chunk-PVTQQS3Y.js";
15
+ } from "./chunk-YPCVY4GS.js";
16
16
 
17
17
  // src/engine/derive-normalizer.ts
18
18
  function findSections(lines) {
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-AKW5YVCE.js";
5
5
  import {
6
6
  evaluateGuard
7
- } from "./chunk-W7LLXRGY.js";
7
+ } from "./chunk-ZAF6JH23.js";
8
8
  import {
9
9
  advancePlan,
10
10
  evaluatePlan,
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-QLPTHTVB.js";
13
13
  import {
14
14
  loadWorld
15
- } from "./chunk-CTZHONLA.js";
15
+ } from "./chunk-BXLTEUS4.js";
16
16
 
17
17
  // src/runtime/mcp-server.ts
18
18
  import { execSync } from "child_process";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-INWQHLPS.js";
4
4
  import {
5
5
  evaluateGuard
6
- } from "./chunk-W7LLXRGY.js";
6
+ } from "./chunk-ZAF6JH23.js";
7
7
 
8
8
  // src/engine/intent-classifier.ts
9
9
  function buildSystemPrompt(knownIntents) {
@@ -35,7 +35,7 @@ async function addGuard(worldDir, input) {
35
35
  };
36
36
  config.guards.push(guard);
37
37
  await writeFile(guardsPath, JSON.stringify(config, null, 2) + "\n");
38
- const { loadWorldFromDirectory } = await import("./world-loader-Y6HMQH2D.js");
38
+ const { loadWorldFromDirectory } = await import("./world-loader-C4D3VPP3.js");
39
39
  const world = await loadWorldFromDirectory(worldDir);
40
40
  const report = validateWorld(world);
41
41
  return {
@@ -83,7 +83,7 @@ async function addRule(worldDir, input) {
83
83
  };
84
84
  const rulePath = join(rulesDir, `rule-${ruleNum}.json`);
85
85
  await writeFile(rulePath, JSON.stringify(rule, null, 2) + "\n");
86
- const { loadWorldFromDirectory } = await import("./world-loader-Y6HMQH2D.js");
86
+ const { loadWorldFromDirectory } = await import("./world-loader-C4D3VPP3.js");
87
87
  const world = await loadWorldFromDirectory(worldDir);
88
88
  const report = validateWorld(world);
89
89
  return {
@@ -118,7 +118,7 @@ async function addInvariant(worldDir, input) {
118
118
  };
119
119
  config.invariants.push(invariant);
120
120
  await writeFile(invariantsPath, JSON.stringify(config, null, 2) + "\n");
121
- const { loadWorldFromDirectory } = await import("./world-loader-Y6HMQH2D.js");
121
+ const { loadWorldFromDirectory } = await import("./world-loader-C4D3VPP3.js");
122
122
  const world = await loadWorldFromDirectory(worldDir);
123
123
  const report = validateWorld(world);
124
124
  return {
@@ -20,15 +20,25 @@ function simulateWorld(world, options = {}) {
20
20
  let collapseStep;
21
21
  let collapseRule;
22
22
  const sortedRules = [...world.rules].sort((a, b) => a.order - b.order);
23
+ const allEvents = options.events ?? [];
24
+ const eventsByStep = Array.from({ length: steps }, () => []);
25
+ for (let i = 0; i < allEvents.length; i++) {
26
+ const stepIdx = Math.min(i, steps - 1);
27
+ eventsByStep[stepIdx].push(allEvents[i]);
28
+ }
29
+ let totalEventsConsumed = 0;
23
30
  for (let stepNum = 1; stepNum <= steps; stepNum++) {
24
31
  if (collapsed) break;
32
+ const stepEvents = eventsByStep[stepNum - 1];
25
33
  const stepResult = evaluateStep(
26
34
  stepNum,
27
35
  sortedRules,
28
36
  state,
29
37
  assumptions,
30
- world
38
+ world,
39
+ stepEvents
31
40
  );
41
+ totalEventsConsumed += stepResult.eventsApplied.length;
32
42
  simulationSteps.push(stepResult);
33
43
  if (stepResult.collapsed) {
34
44
  collapsed = true;
@@ -47,14 +57,38 @@ function simulateWorld(world, options = {}) {
47
57
  finalViability,
48
58
  collapsed,
49
59
  collapseStep,
50
- collapseRule
60
+ collapseRule,
61
+ eventsConsumed: totalEventsConsumed
51
62
  };
52
63
  }
53
- function evaluateStep(stepNum, rules, state, assumptions, world) {
64
+ function evaluateStep(stepNum, rules, state, assumptions, world, events = []) {
54
65
  const evaluations = [];
66
+ const eventApplications = [];
55
67
  let rulesFired = 0;
56
68
  let collapsed = false;
57
69
  const firedRuleIds = /* @__PURE__ */ new Set();
70
+ for (const evt of events) {
71
+ const application = {
72
+ eventType: evt.type,
73
+ rulesTriggered: [],
74
+ effects: []
75
+ };
76
+ for (const rule of rules) {
77
+ const eventTrigger = rule.triggers.find(
78
+ (t) => t.field === "event" && t.source === "state"
79
+ );
80
+ if (!eventTrigger) continue;
81
+ const matches = evaluateOperator(evt.type, eventTrigger.operator, eventTrigger.value);
82
+ if (!matches) continue;
83
+ application.rulesTriggered.push(rule.id);
84
+ firedRuleIds.add(rule.id);
85
+ for (const effect of rule.effects ?? []) {
86
+ const applied = applyEffect(effect, state);
87
+ if (applied) application.effects.push(applied);
88
+ }
89
+ }
90
+ eventApplications.push(application);
91
+ }
58
92
  for (const rule of rules) {
59
93
  if (collapsed) {
60
94
  evaluations.push({
@@ -139,6 +173,7 @@ function evaluateStep(stepNum, rules, state, assumptions, world) {
139
173
  const viability = classifyViability(state, world);
140
174
  return {
141
175
  step: stepNum,
176
+ eventsApplied: eventApplications,
142
177
  rulesEvaluated: evaluations,
143
178
  rulesFired,
144
179
  stateAfter: { ...state },
@@ -260,6 +295,19 @@ function renderSimulateText(result) {
260
295
  lines.push("");
261
296
  for (const step of result.steps) {
262
297
  lines.push(`STEP ${step.step}`);
298
+ if (step.eventsApplied && step.eventsApplied.length > 0) {
299
+ for (const evt of step.eventsApplied) {
300
+ lines.push(` EVENT: ${evt.eventType}`);
301
+ if (evt.rulesTriggered.length > 0) {
302
+ lines.push(` Rules triggered: ${evt.rulesTriggered.join(", ")}`);
303
+ }
304
+ for (const effect of evt.effects) {
305
+ const beforeStr = formatValue(effect.before);
306
+ const afterStr = formatValue(effect.after);
307
+ lines.push(` ${effect.target}: ${beforeStr} -> ${afterStr}`);
308
+ }
309
+ }
310
+ }
263
311
  const fired = step.rulesEvaluated.filter((r) => r.triggered);
264
312
  const skipped = step.rulesEvaluated.filter((r) => !r.triggered && !r.excluded);
265
313
  const excluded = step.rulesEvaluated.filter((r) => r.excluded);
@@ -295,6 +343,9 @@ function renderSimulateText(result) {
295
343
  lines.push(` ${key}: ${formatValue(value)}${marker}`);
296
344
  }
297
345
  lines.push("");
346
+ if (result.eventsConsumed > 0) {
347
+ lines.push(`EVENTS CONSUMED: ${result.eventsConsumed}`);
348
+ }
298
349
  lines.push(`VIABILITY: ${result.finalViability}`);
299
350
  if (result.collapsed) {
300
351
  lines.push(`COLLAPSED at step ${result.collapseStep} (rule: ${result.collapseRule})`);
@@ -96,8 +96,8 @@ async function loadBundledWorld(name = DEFAULT_BUNDLED_WORLD) {
96
96
  const { join, dirname } = await import("path");
97
97
  const { existsSync } = await import("fs");
98
98
  const { fileURLToPath } = await import("url");
99
- const { parseWorldMarkdown } = await import("./bootstrap-parser-EEF36XDU.js");
100
- const { emitWorldDefinition } = await import("./bootstrap-emitter-Q7UIJZ2O.js");
99
+ const { parseWorldMarkdown } = await import("./bootstrap-parser-LBLGVEMU.js");
100
+ const { emitWorldDefinition } = await import("./bootstrap-emitter-GIMOJFOC.js");
101
101
  const filename = `${name}.nv-world.md`;
102
102
  let packageRoot;
103
103
  try {
@@ -6,10 +6,10 @@ import {
6
6
  } from "./chunk-5U2MQO5P.js";
7
7
  import {
8
8
  evaluateGuard
9
- } from "./chunk-W7LLXRGY.js";
9
+ } from "./chunk-ZAF6JH23.js";
10
10
  import {
11
11
  loadWorld
12
- } from "./chunk-CTZHONLA.js";
12
+ } from "./chunk-BXLTEUS4.js";
13
13
 
14
14
  // src/engine/tool-classifier.ts
15
15
  var TOOL_CATEGORY_MAP = {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  evaluateGuard
3
- } from "./chunk-W7LLXRGY.js";
3
+ } from "./chunk-ZAF6JH23.js";
4
4
  import {
5
5
  loadWorld
6
- } from "./chunk-CTZHONLA.js";
6
+ } from "./chunk-BXLTEUS4.js";
7
7
 
8
8
  // src/runtime/govern.ts
9
9
  function actionToGuardEvent(action) {
@@ -6,10 +6,10 @@ import {
6
6
  } from "./chunk-5U2MQO5P.js";
7
7
  import {
8
8
  evaluateGuard
9
- } from "./chunk-W7LLXRGY.js";
9
+ } from "./chunk-ZAF6JH23.js";
10
10
  import {
11
11
  loadWorld
12
- } from "./chunk-CTZHONLA.js";
12
+ } from "./chunk-BXLTEUS4.js";
13
13
 
14
14
  // src/adapters/langchain.ts
15
15
  var GovernanceBlockedError2 = class extends GovernanceBlockedError {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  readAuditLog
3
- } from "./chunk-A7GKPPU7.js";
3
+ } from "./chunk-2VAWP6FI.js";
4
4
 
5
5
  // src/engine/impact-report.ts
6
6
  function generateImpactReport(events) {
@@ -7,10 +7,10 @@ import {
7
7
  } from "./chunk-5U2MQO5P.js";
8
8
  import {
9
9
  evaluateGuard
10
- } from "./chunk-W7LLXRGY.js";
10
+ } from "./chunk-ZAF6JH23.js";
11
11
  import {
12
12
  loadWorld
13
- } from "./chunk-CTZHONLA.js";
13
+ } from "./chunk-BXLTEUS4.js";
14
14
 
15
15
  // src/adapters/openai.ts
16
16
  var GovernanceBlockedError2 = class extends GovernanceBlockedError {