@neuroverseos/governance 0.3.4 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/README.md +280 -405
  2. package/dist/adapters/autoresearch.cjs +63 -9
  3. package/dist/adapters/autoresearch.d.cts +2 -1
  4. package/dist/adapters/autoresearch.d.ts +2 -1
  5. package/dist/adapters/autoresearch.js +3 -3
  6. package/dist/adapters/deep-agents.cjs +63 -9
  7. package/dist/adapters/deep-agents.d.cts +3 -2
  8. package/dist/adapters/deep-agents.d.ts +3 -2
  9. package/dist/adapters/deep-agents.js +3 -3
  10. package/dist/adapters/express.cjs +63 -9
  11. package/dist/adapters/express.d.cts +2 -1
  12. package/dist/adapters/express.d.ts +2 -1
  13. package/dist/adapters/express.js +3 -3
  14. package/dist/adapters/index.cjs +961 -9
  15. package/dist/adapters/index.d.cts +4 -2
  16. package/dist/adapters/index.d.ts +4 -2
  17. package/dist/adapters/index.js +54 -17
  18. package/dist/adapters/langchain.cjs +63 -9
  19. package/dist/adapters/langchain.d.cts +3 -2
  20. package/dist/adapters/langchain.d.ts +3 -2
  21. package/dist/adapters/langchain.js +3 -3
  22. package/dist/adapters/mentraos.cjs +2181 -0
  23. package/dist/adapters/mentraos.d.cts +319 -0
  24. package/dist/adapters/mentraos.d.ts +319 -0
  25. package/dist/adapters/mentraos.js +48 -0
  26. package/dist/adapters/openai.cjs +63 -9
  27. package/dist/adapters/openai.d.cts +3 -2
  28. package/dist/adapters/openai.d.ts +3 -2
  29. package/dist/adapters/openai.js +3 -3
  30. package/dist/adapters/openclaw.cjs +63 -9
  31. package/dist/adapters/openclaw.d.cts +3 -2
  32. package/dist/adapters/openclaw.d.ts +3 -2
  33. package/dist/adapters/openclaw.js +3 -3
  34. package/dist/{add-ROOZLU62.js → add-XSANI3FK.js} +1 -1
  35. package/dist/{behavioral-MJO34S6Q.js → behavioral-SLW7ALEK.js} +4 -4
  36. package/dist/{bootstrap-CQRZVOXK.js → bootstrap-2OW5ZLBL.js} +4 -4
  37. package/dist/bootstrap-contract-DcV6t-8M.d.cts +216 -0
  38. package/dist/bootstrap-contract-DcV6t-8M.d.ts +216 -0
  39. package/dist/browser.global.js +149 -5
  40. package/dist/{build-ZHPMX5AZ.js → build-EGBGZFIJ.js} +6 -6
  41. package/dist/{chunk-A7GKPPU7.js → chunk-2VAWP6FI.js} +1 -1
  42. package/dist/{chunk-3WQLXYTP.js → chunk-3AYKQHYI.js} +2 -2
  43. package/dist/{chunk-EMQDLDAF.js → chunk-3NZMMSOW.js} +80 -2
  44. package/dist/chunk-3S5AD4AB.js +421 -0
  45. package/dist/{chunk-VXHSMA3I.js → chunk-6CV4XG3J.js} +1 -1
  46. package/dist/{chunk-BNKJPUPQ.js → chunk-A7SHG75T.js} +2 -2
  47. package/dist/{chunk-U6U7EJZL.js → chunk-AV7XJJWK.js} +2 -2
  48. package/dist/{chunk-ZWI3NIXK.js → chunk-CYDMUJVZ.js} +54 -3
  49. package/dist/{chunk-F66BVUYB.js → chunk-DA5MHFRR.js} +3 -3
  50. package/dist/{chunk-YEKMVDWK.js → chunk-FHXXD2TI.js} +7 -7
  51. package/dist/{chunk-5TPFNWRU.js → chunk-FS2UUJJO.js} +3 -3
  52. package/dist/{chunk-4FLICVVA.js → chunk-FVOGUCB6.js} +2 -2
  53. package/dist/chunk-GTPV2XGO.js +893 -0
  54. package/dist/{chunk-CTZHONLA.js → chunk-I4RTIMLX.js} +2 -2
  55. package/dist/{chunk-B6OXJLJ5.js → chunk-J2IZBHXJ.js} +4 -4
  56. package/dist/{chunk-TG6SEF24.js → chunk-OQU65525.js} +1 -1
  57. package/dist/{chunk-QXBFT7NI.js → chunk-QMVQ6KPL.js} +2 -2
  58. package/dist/{chunk-G7DJ6VOD.js → chunk-RDA7ISWC.js} +2 -2
  59. package/dist/{chunk-O5ABKEA7.js → chunk-YJ34R5NB.js} +2 -2
  60. package/dist/{chunk-PVTQQS3Y.js → chunk-YPCVY4GS.js} +31 -0
  61. package/dist/{chunk-W7LLXRGY.js → chunk-ZAF6JH23.js} +65 -10
  62. package/dist/{chunk-IS4WUH6Y.js → chunk-ZEIT2QLM.js} +4 -4
  63. package/dist/cli/neuroverse.cjs +4436 -1035
  64. package/dist/cli/neuroverse.js +40 -24
  65. package/dist/cli/plan.cjs +176 -12
  66. package/dist/cli/plan.js +2 -2
  67. package/dist/cli/run.cjs +63 -9
  68. package/dist/cli/run.js +2 -2
  69. package/dist/configure-world-XU2COHOZ.js +705 -0
  70. package/dist/{decision-flow-M63D47LO.js → decision-flow-3K4D72G4.js} +2 -2
  71. package/dist/{demo-G43RLCPK.js → demo-6OQYWRR6.js} +4 -4
  72. package/dist/{derive-LMDUTXDD.js → derive-7Y7YWVLU.js} +5 -5
  73. package/dist/{doctor-6BC6X2VO.js → doctor-NHXI7OQW.js} +3 -1
  74. package/dist/engine/bootstrap-emitter.cjs +241 -0
  75. package/dist/engine/bootstrap-emitter.d.cts +27 -0
  76. package/dist/engine/bootstrap-emitter.d.ts +27 -0
  77. package/dist/{bootstrap-emitter-Q7UIJZ2O.js → engine/bootstrap-emitter.js} +2 -2
  78. package/dist/engine/bootstrap-parser.cjs +560 -0
  79. package/dist/engine/bootstrap-parser.d.cts +96 -0
  80. package/dist/engine/bootstrap-parser.d.ts +96 -0
  81. package/dist/{bootstrap-parser-EEF36XDU.js → engine/bootstrap-parser.js} +2 -2
  82. package/dist/engine/guard-engine.cjs +1116 -0
  83. package/dist/engine/guard-engine.d.cts +60 -0
  84. package/dist/engine/guard-engine.d.ts +60 -0
  85. package/dist/engine/guard-engine.js +12 -0
  86. package/dist/engine/simulate-engine.cjs +390 -0
  87. package/dist/engine/simulate-engine.d.cts +105 -0
  88. package/dist/engine/simulate-engine.d.ts +105 -0
  89. package/dist/engine/simulate-engine.js +9 -0
  90. package/dist/{equity-penalties-SG5IZQ7I.js → equity-penalties-NVBAB5WL.js} +4 -4
  91. package/dist/{explain-RHBU2GBR.js → explain-HDFN4ION.js} +1 -1
  92. package/dist/github-TIKTWOGU.js +27 -0
  93. package/dist/{guard-AEEJNWLD.js → guard-6KSCWT2W.js} +4 -4
  94. package/dist/{guard-contract-B7lplwm9.d.cts → guard-contract-C991HDZp.d.cts} +32 -309
  95. package/dist/{guard-contract-B7lplwm9.d.ts → guard-contract-hHjTTjtR.d.ts} +32 -309
  96. package/dist/{impact-3XVDSCBU.js → impact-WIAM66IH.js} +3 -3
  97. package/dist/{improve-TQP4ECSY.js → improve-2PWGGO5B.js} +3 -3
  98. package/dist/index.cjs +682 -14
  99. package/dist/index.d.cts +231 -423
  100. package/dist/index.d.ts +231 -423
  101. package/dist/index.js +81 -58
  102. package/dist/{init-FYPV4SST.js → init-TKIJDR7I.js} +5 -1
  103. package/dist/lens-MHMUDCMQ.js +1084 -0
  104. package/dist/{mcp-server-5Y3ZM7TV.js → mcp-server-TNIWZ7B5.js} +3 -3
  105. package/dist/{playground-VZBNPPBO.js → playground-3FLDGBET.js} +3 -3
  106. package/dist/{redteam-MZPZD3EF.js → redteam-HV6LMKEH.js} +3 -3
  107. package/dist/{session-JYOARW54.js → session-XZP2754M.js} +3 -3
  108. package/dist/{shared-C_zpdvBm.d.cts → shared-DGnn1jiS.d.cts} +1 -1
  109. package/dist/{shared-Cf7yxx4-.d.ts → shared-U405h52W.d.ts} +1 -1
  110. package/dist/{simulate-LJXYBC6M.js → simulate-VT437EEL.js} +17 -4
  111. package/dist/spatial/index.cjs +682 -0
  112. package/dist/spatial/index.d.cts +517 -0
  113. package/dist/spatial/index.d.ts +517 -0
  114. package/dist/spatial/index.js +633 -0
  115. package/dist/{test-BOOR4A5F.js → test-4WTX6RKQ.js} +3 -3
  116. package/dist/{trace-PKV4KX56.js → trace-2YDNAXMK.js} +2 -2
  117. package/dist/types.cjs +18 -0
  118. package/dist/types.d.cts +370 -0
  119. package/dist/types.d.ts +370 -0
  120. package/dist/types.js +0 -0
  121. package/dist/{validate-RALX7CZS.js → validate-M52DX22Y.js} +1 -1
  122. package/dist/{world-BIP4GZBZ.js → world-O4HTQPDP.js} +1 -1
  123. package/dist/{world-loader-Y6HMQH2D.js → world-loader-YTYFOP7D.js} +1 -1
  124. package/dist/worlds/mentraos-smartglasses.nv-world.md +423 -0
  125. package/dist/worlds/mentraos-spatial.nv-world.md +68 -0
  126. package/dist/worlds/user-rules.nv-world.md +328 -0
  127. package/package.json +46 -3
  128. package/dist/guard-engine-PNR6MHCM.js +0 -10
  129. package/dist/{configure-ai-5MP5DWTT.js → configure-ai-LL3VAPQW.js} +3 -3
@@ -0,0 +1,216 @@
1
+ /**
2
+ * Bootstrap Contract — Markdown → WorldDefinition Compilation Types
3
+ *
4
+ * Defines the input/output contract for `neuroverse bootstrap`.
5
+ *
6
+ * Input: .nv-world.md file (structured markdown)
7
+ * Output: WorldDefinition (passed to validate, guard, or compileWorldToZip)
8
+ *
9
+ * The markdown format is:
10
+ * - YAML frontmatter for world identity and metadata
11
+ * - H1 sections for each block (Thesis, Invariants, State, etc.)
12
+ * - Structured sub-sections within each block
13
+ * - Deterministically parseable — no LLM, no heuristics
14
+ *
15
+ * Exit codes:
16
+ * 0 = SUCCESS (compiled cleanly)
17
+ * 1 = FAIL (parse errors, missing required sections)
18
+ * 3 = ERROR (file not found, invalid input)
19
+ */
20
+ type ParseSeverity = 'error' | 'warning' | 'info';
21
+ /**
22
+ * A single parse issue found during markdown compilation.
23
+ */
24
+ interface ParseIssue {
25
+ /** Line number in the source markdown (1-based) */
26
+ line: number;
27
+ /** Which section the issue was found in */
28
+ section: string;
29
+ /** Human-readable message */
30
+ message: string;
31
+ /** Severity */
32
+ severity: ParseSeverity;
33
+ }
34
+ /**
35
+ * The result of parsing a .nv-world.md file.
36
+ */
37
+ interface BootstrapResult {
38
+ /** Whether compilation succeeded (no errors) */
39
+ success: boolean;
40
+ /** Source file path */
41
+ sourcePath: string;
42
+ /** All parse issues */
43
+ issues: ParseIssue[];
44
+ /** Parsed sections (for debugging) */
45
+ parsedSections: string[];
46
+ /** Duration */
47
+ durationMs: number;
48
+ }
49
+ /**
50
+ * YAML frontmatter parsed from the markdown header.
51
+ */
52
+ interface ParsedFrontmatter {
53
+ world_id: string;
54
+ name: string;
55
+ version?: string;
56
+ runtime_mode?: string;
57
+ default_profile?: string;
58
+ alternative_profile?: string;
59
+ }
60
+ /**
61
+ * A parsed invariant from the Invariants section.
62
+ */
63
+ interface ParsedInvariant {
64
+ id: string;
65
+ label: string;
66
+ enforcement: string;
67
+ mutable: boolean;
68
+ line: number;
69
+ }
70
+ /**
71
+ * A parsed state variable from the State section.
72
+ */
73
+ interface ParsedStateVariable {
74
+ id: string;
75
+ type: 'number' | 'enum' | 'boolean';
76
+ default: string | number | boolean;
77
+ label: string;
78
+ description: string;
79
+ min?: number;
80
+ max?: number;
81
+ step?: number;
82
+ options?: string[];
83
+ line: number;
84
+ }
85
+ /**
86
+ * A parsed assumption profile from the Assumptions section.
87
+ */
88
+ interface ParsedAssumptionProfile {
89
+ id: string;
90
+ name: string;
91
+ description: string;
92
+ parameters: Record<string, string | number | boolean>;
93
+ line: number;
94
+ }
95
+ /**
96
+ * A parsed trigger from a rule.
97
+ */
98
+ interface ParsedTrigger {
99
+ field: string;
100
+ operator: string;
101
+ value: string | number | boolean;
102
+ source: 'state' | 'assumption';
103
+ }
104
+ /**
105
+ * A parsed effect from a rule.
106
+ */
107
+ interface ParsedEffect {
108
+ target: string;
109
+ operation: string;
110
+ value: number | boolean | string;
111
+ }
112
+ /**
113
+ * A parsed rule from the Rules section.
114
+ */
115
+ interface ParsedRule {
116
+ id: string;
117
+ label: string;
118
+ severity: string;
119
+ description?: string;
120
+ order: number;
121
+ triggers: ParsedTrigger[];
122
+ effects: ParsedEffect[];
123
+ collapse_check?: {
124
+ field: string;
125
+ operator: string;
126
+ value: number;
127
+ };
128
+ causal_translation?: {
129
+ trigger_text: string;
130
+ rule_text: string;
131
+ shift_text: string;
132
+ effect_text: string;
133
+ };
134
+ line: number;
135
+ }
136
+ /**
137
+ * A parsed gate from the Gates section.
138
+ */
139
+ interface ParsedGate {
140
+ status: string;
141
+ field: string;
142
+ operator: string;
143
+ value: number;
144
+ line: number;
145
+ }
146
+ /**
147
+ * A parsed outcome from the Outcomes section.
148
+ */
149
+ interface ParsedOutcome {
150
+ id: string;
151
+ type: string;
152
+ range?: [number, number];
153
+ display?: string;
154
+ label: string;
155
+ primary?: boolean;
156
+ assignment?: string;
157
+ line: number;
158
+ }
159
+ /**
160
+ * A parsed lens directive from the Lenses section.
161
+ */
162
+ interface ParsedLensDirective {
163
+ id: string;
164
+ scope: string;
165
+ instruction: string;
166
+ line: number;
167
+ }
168
+ /**
169
+ * A parsed lens from the Lenses section.
170
+ * Each lens is an H2 subsection with key-value properties and directives.
171
+ */
172
+ interface ParsedLens {
173
+ id: string;
174
+ name: string;
175
+ tagline: string;
176
+ description: string;
177
+ tags: string[];
178
+ /** Tone: formality, verbosity, emotion, confidence */
179
+ formality: string;
180
+ verbosity: string;
181
+ emotion: string;
182
+ confidence: string;
183
+ /** Which roles this lens is the default for */
184
+ defaultForRoles: string[];
185
+ /** Behavioral directives */
186
+ directives: ParsedLensDirective[];
187
+ /** Priority when stacking (higher = applied later) */
188
+ priority: number;
189
+ /** Whether it can be stacked with other lenses */
190
+ stackable: boolean;
191
+ line: number;
192
+ }
193
+ /**
194
+ * The full parsed intermediate representation.
195
+ */
196
+ interface ParsedWorld {
197
+ frontmatter: ParsedFrontmatter;
198
+ thesis: string;
199
+ invariants: ParsedInvariant[];
200
+ stateVariables: ParsedStateVariable[];
201
+ assumptions: ParsedAssumptionProfile[];
202
+ rules: ParsedRule[];
203
+ gates: ParsedGate[];
204
+ outcomes: ParsedOutcome[];
205
+ lenses: ParsedLens[];
206
+ lensPolicy?: 'locked' | 'role_default' | 'user_choice';
207
+ lensLockPin?: string;
208
+ }
209
+ declare const BOOTSTRAP_EXIT_CODES: {
210
+ readonly SUCCESS: 0;
211
+ readonly FAIL: 1;
212
+ readonly ERROR: 3;
213
+ };
214
+ type BootstrapExitCode = (typeof BOOTSTRAP_EXIT_CODES)[keyof typeof BOOTSTRAP_EXIT_CODES];
215
+
216
+ export { BOOTSTRAP_EXIT_CODES as B, type ParsedWorld as P, type ParseIssue as a, type BootstrapExitCode as b, type BootstrapResult as c, type ParsedAssumptionProfile as d, type ParsedEffect as e, type ParsedFrontmatter as f, type ParsedGate as g, type ParsedInvariant as h, type ParsedOutcome as i, type ParsedRule as j, type ParsedStateVariable as k, type ParsedTrigger as l };
@@ -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-FHXXD2TI.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
- import {
13
- parseWorldMarkdown
14
- } from "./chunk-EMQDLDAF.js";
15
12
  import {
16
13
  emitWorldDefinition
17
- } from "./chunk-PVTQQS3Y.js";
14
+ } from "./chunk-YPCVY4GS.js";
15
+ import {
16
+ parseWorldMarkdown
17
+ } from "./chunk-3NZMMSOW.js";
18
18
  import "./chunk-QWGCMQQD.js";
19
19
 
20
20
  // src/cli/build.ts
@@ -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 {
@@ -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-I4RTIMLX.js";
13
13
 
14
14
  // src/adapters/langchain.ts
15
15
  var GovernanceBlockedError2 = class extends GovernanceBlockedError {
@@ -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
  };