@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
@@ -31,11 +31,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var adapters_exports = {};
32
32
  __export(adapters_exports, {
33
33
  AutoresearchGovernor: () => AutoresearchGovernor,
34
+ DEFAULT_USER_RULES: () => DEFAULT_USER_RULES,
34
35
  DeepAgentsGovernanceBlockedError: () => GovernanceBlockedError5,
35
36
  DeepAgentsGuard: () => DeepAgentsGuard,
36
37
  GovernanceBlockedError: () => GovernanceBlockedError,
37
38
  GovernedToolExecutor: () => GovernedToolExecutor,
38
39
  LangChainGovernanceBlockedError: () => GovernanceBlockedError2,
40
+ MENTRA_INTENT_TAXONOMY: () => MENTRA_INTENT_TAXONOMY,
41
+ MENTRA_KNOWN_INTENTS: () => MENTRA_KNOWN_INTENTS,
42
+ MentraGovernanceBlockedError: () => GovernanceBlockedError,
43
+ MentraGovernedExecutor: () => MentraGovernedExecutor,
39
44
  NeuroVerseCallbackHandler: () => NeuroVerseCallbackHandler,
40
45
  NeuroVersePlugin: () => NeuroVersePlugin,
41
46
  OpenAIGovernanceBlockedError: () => GovernanceBlockedError3,
@@ -47,12 +52,25 @@ __export(adapters_exports, {
47
52
  createGovernanceMiddlewareFromWorld: () => createGovernanceMiddlewareFromWorld,
48
53
  createGovernedToolExecutor: () => createGovernedToolExecutor,
49
54
  createGovernedToolExecutorFromWorld: () => createGovernedToolExecutorFromWorld,
55
+ createMentraGovernedExecutor: () => createMentraGovernedExecutor,
56
+ createMentraGovernedExecutorFromWorld: () => createMentraGovernedExecutorFromWorld,
50
57
  createNeuroVerseCallbackHandler: () => createNeuroVerseCallbackHandler,
51
58
  createNeuroVerseCallbackHandlerFromWorld: () => createNeuroVerseCallbackHandlerFromWorld,
52
59
  createNeuroVersePlugin: () => createNeuroVersePlugin,
53
60
  createNeuroVersePluginFromWorld: () => createNeuroVersePluginFromWorld,
54
61
  defaultBlockMessage: () => defaultBlockMessage,
62
+ evaluateUserRules: () => evaluateUserRules,
55
63
  extractScope: () => extractScope,
64
+ getAIActionIntents: () => getAIActionIntents,
65
+ getAIDataIntents: () => getAIDataIntents,
66
+ getAIIntents: () => getAIIntents,
67
+ getExfiltrationIntents: () => getExfiltrationIntents,
68
+ getHighRiskIntents: () => getHighRiskIntents,
69
+ getIntentsByGlasses: () => getIntentsByGlasses,
70
+ getIntentsByPermission: () => getIntentsByPermission,
71
+ getMentraIntent: () => getMentraIntent,
72
+ isAIIntent: () => isAIIntent,
73
+ isIntentSupported: () => isIntentSupported,
56
74
  trackPlanProgress: () => trackPlanProgress
57
75
  });
58
76
  module.exports = __toCommonJS(adapters_exports);
@@ -484,6 +502,33 @@ function evaluateGuard(event, world, options = {}) {
484
502
  let decidingId;
485
503
  const guardsMatched = [];
486
504
  const rulesMatched = [];
505
+ if (options.emergencyOverride) {
506
+ checkInvariantCoverage(world, invariantChecks);
507
+ return buildVerdict(
508
+ "ALLOW",
509
+ void 0,
510
+ "emergency-override",
511
+ "Emergency override active \u2014 all governance rules suspended. Platform constraints still apply.",
512
+ world,
513
+ level,
514
+ invariantChecks,
515
+ guardsMatched,
516
+ rulesMatched,
517
+ includeTrace ? buildTrace(
518
+ invariantChecks,
519
+ safetyChecks,
520
+ planCheckResult,
521
+ roleChecks,
522
+ guardChecks,
523
+ kernelRuleChecks,
524
+ levelChecks,
525
+ "session-allowlist",
526
+ "emergency-override",
527
+ startTime
528
+ ) : void 0,
529
+ event.intent
530
+ );
531
+ }
487
532
  checkInvariantCoverage(world, invariantChecks);
488
533
  if (event.roleId && options.agentStates) {
489
534
  const agentState = options.agentStates.get(event.roleId);
@@ -548,7 +593,8 @@ function evaluateGuard(event, world, options = {}) {
548
593
  decidingLayer,
549
594
  decidingId,
550
595
  startTime
551
- ) : void 0
596
+ ) : void 0,
597
+ event.intent
552
598
  );
553
599
  }
554
600
  }
@@ -577,7 +623,8 @@ function evaluateGuard(event, world, options = {}) {
577
623
  decidingLayer,
578
624
  decidingId,
579
625
  startTime
580
- ) : void 0
626
+ ) : void 0,
627
+ event.intent
581
628
  );
582
629
  }
583
630
  if (options.plan) {
@@ -612,7 +659,8 @@ function evaluateGuard(event, world, options = {}) {
612
659
  decidingLayer,
613
660
  decidingId,
614
661
  startTime
615
- ) : void 0
662
+ ) : void 0,
663
+ event.intent
616
664
  );
617
665
  }
618
666
  }
@@ -641,7 +689,8 @@ function evaluateGuard(event, world, options = {}) {
641
689
  decidingLayer,
642
690
  decidingId,
643
691
  startTime
644
- ) : void 0
692
+ ) : void 0,
693
+ event.intent
645
694
  );
646
695
  }
647
696
  const guardVerdict = checkGuards(event, eventText, world, guardChecks, guardsMatched);
@@ -679,7 +728,8 @@ function evaluateGuard(event, world, options = {}) {
679
728
  decidingLayer,
680
729
  decidingId,
681
730
  startTime
682
- ) : void 0
731
+ ) : void 0,
732
+ event.intent
683
733
  );
684
734
  verdict.intentRecord = intentRecord;
685
735
  if (guardVerdict.consequence) verdict.consequence = guardVerdict.consequence;
@@ -712,7 +762,8 @@ function evaluateGuard(event, world, options = {}) {
712
762
  decidingLayer,
713
763
  decidingId,
714
764
  startTime
715
- ) : void 0
765
+ ) : void 0,
766
+ event.intent
716
767
  );
717
768
  }
718
769
  const levelVerdict = checkLevelConstraints(event, level, levelChecks);
@@ -740,7 +791,8 @@ function evaluateGuard(event, world, options = {}) {
740
791
  decidingLayer,
741
792
  decidingId,
742
793
  startTime
743
- ) : void 0
794
+ ) : void 0,
795
+ event.intent
744
796
  );
745
797
  }
746
798
  const warning = guardVerdict?.warning;
@@ -765,7 +817,8 @@ function evaluateGuard(event, world, options = {}) {
765
817
  decidingLayer,
766
818
  decidingId,
767
819
  startTime
768
- ) : void 0
820
+ ) : void 0,
821
+ event.intent
769
822
  );
770
823
  }
771
824
  function checkInvariantCoverage(world, checks) {
@@ -1142,7 +1195,7 @@ function buildTrace(invariantChecks, safetyChecks, planCheck, roleChecks, guardC
1142
1195
  }
1143
1196
  return trace;
1144
1197
  }
1145
- function buildVerdict(status, reason, ruleId, warning, world, level, invariantChecks, guardsMatched, rulesMatched, trace) {
1198
+ function buildVerdict(status, reason, ruleId, warning, world, level, invariantChecks, guardsMatched, rulesMatched, trace, eventIntent) {
1146
1199
  const evidence = {
1147
1200
  worldId: world.world.world_id,
1148
1201
  worldName: world.world.name,
@@ -1162,8 +1215,27 @@ function buildVerdict(status, reason, ruleId, warning, world, level, invariantCh
1162
1215
  if (ruleId) verdict.ruleId = ruleId;
1163
1216
  if (warning) verdict.warning = warning;
1164
1217
  if (trace) verdict.trace = trace;
1218
+ verdict.event = verdictToEvent(status, eventIntent);
1165
1219
  return verdict;
1166
1220
  }
1221
+ function verdictToEvent(status, intent) {
1222
+ const statusEventMap = {
1223
+ ALLOW: "action_allowed",
1224
+ BLOCK: "action_blocked",
1225
+ PAUSE: "action_paused",
1226
+ MODIFY: "action_modified",
1227
+ PENALIZE: "action_penalized",
1228
+ REWARD: "action_rewarded",
1229
+ NEUTRAL: "action_neutral"
1230
+ };
1231
+ return {
1232
+ type: intent || statusEventMap[status] || "unknown_action",
1233
+ actor: "agent",
1234
+ source: "guard",
1235
+ timestamp: Date.now(),
1236
+ guardStatus: status
1237
+ };
1238
+ }
1167
1239
 
1168
1240
  // src/loader/world-loader.ts
1169
1241
  async function loadWorldFromDirectory(dirPath) {
@@ -2083,14 +2155,881 @@ async function createDeepAgentsGuard(worldPath, options) {
2083
2155
  function createDeepAgentsGuardFromWorld(world, options) {
2084
2156
  return new DeepAgentsGuard(world, options);
2085
2157
  }
2158
+
2159
+ // src/worlds/mentraos-intent-taxonomy.ts
2160
+ var MENTRA_INTENT_TAXONOMY = [
2161
+ // ── Camera Domain ───────────────────────────────────────────────────────
2162
+ {
2163
+ intent: "camera_photo_capture",
2164
+ description: "Capture a single photo from the glasses camera",
2165
+ sdk_method: "session.camera.requestPhoto()",
2166
+ permission: "CAMERA",
2167
+ domain: "camera",
2168
+ supported_glasses: ["mentra_live"],
2169
+ action_category: "write",
2170
+ base_risk: "high",
2171
+ exfiltration_risk: true,
2172
+ reversible: false
2173
+ },
2174
+ {
2175
+ intent: "camera_stream_start",
2176
+ description: "Start a managed video stream (HLS) from the glasses camera",
2177
+ sdk_method: "session.camera.startManagedStream()",
2178
+ permission: "CAMERA",
2179
+ domain: "camera",
2180
+ supported_glasses: ["mentra_live"],
2181
+ action_category: "write",
2182
+ base_risk: "critical",
2183
+ exfiltration_risk: true,
2184
+ reversible: true
2185
+ },
2186
+ {
2187
+ intent: "camera_stream_stop",
2188
+ description: "Stop an active camera stream",
2189
+ sdk_method: "session.camera.stopStream()",
2190
+ permission: "CAMERA",
2191
+ domain: "camera",
2192
+ supported_glasses: ["mentra_live"],
2193
+ action_category: "write",
2194
+ base_risk: "low",
2195
+ exfiltration_risk: false,
2196
+ reversible: false
2197
+ },
2198
+ {
2199
+ intent: "camera_restream_start",
2200
+ description: "Restream camera feed to an external RTMP destination (e.g., social media)",
2201
+ sdk_method: "session.camera.startRestream()",
2202
+ permission: "CAMERA",
2203
+ domain: "camera",
2204
+ supported_glasses: ["mentra_live"],
2205
+ action_category: "network",
2206
+ base_risk: "critical",
2207
+ exfiltration_risk: true,
2208
+ reversible: true
2209
+ },
2210
+ // ── Microphone Domain ──────────────────────────────────────────────────
2211
+ {
2212
+ intent: "microphone_transcription_start",
2213
+ description: "Start receiving speech-to-text transcription events",
2214
+ sdk_method: "session.events.onTranscription()",
2215
+ permission: "MICROPHONE",
2216
+ domain: "microphone",
2217
+ supported_glasses: ["even_realities_g1", "mentra_live"],
2218
+ action_category: "read",
2219
+ base_risk: "medium",
2220
+ exfiltration_risk: true,
2221
+ reversible: true
2222
+ },
2223
+ {
2224
+ intent: "microphone_translation_start",
2225
+ description: "Start receiving translation events from spoken audio",
2226
+ sdk_method: "session.events.onTranslation()",
2227
+ permission: "MICROPHONE",
2228
+ domain: "microphone",
2229
+ supported_glasses: ["even_realities_g1", "mentra_live"],
2230
+ action_category: "read",
2231
+ base_risk: "medium",
2232
+ exfiltration_risk: true,
2233
+ reversible: true
2234
+ },
2235
+ {
2236
+ intent: "microphone_phone_passthrough",
2237
+ description: "Use phone microphone as audio input (glasses without built-in mic)",
2238
+ sdk_method: "session.audio.startPhoneMic()",
2239
+ permission: "MICROPHONE",
2240
+ domain: "microphone",
2241
+ supported_glasses: ["mentra_mach1", "vuzix_z100"],
2242
+ action_category: "read",
2243
+ base_risk: "medium",
2244
+ exfiltration_risk: true,
2245
+ reversible: true
2246
+ },
2247
+ // ── Display Domain ────────────────────────────────────────────────────
2248
+ {
2249
+ intent: "display_text_wall",
2250
+ description: "Show a single text block on the glasses display",
2251
+ sdk_method: "session.layouts.showTextWall()",
2252
+ permission: "NONE",
2253
+ domain: "display",
2254
+ supported_glasses: ["even_realities_g1", "mentra_mach1", "vuzix_z100"],
2255
+ action_category: "write",
2256
+ base_risk: "low",
2257
+ exfiltration_risk: false,
2258
+ reversible: true
2259
+ },
2260
+ {
2261
+ intent: "display_double_text_wall",
2262
+ description: "Show two text blocks (top/bottom) on the glasses display",
2263
+ sdk_method: "session.layouts.showDoubleTextWall()",
2264
+ permission: "NONE",
2265
+ domain: "display",
2266
+ supported_glasses: ["even_realities_g1", "mentra_mach1", "vuzix_z100"],
2267
+ action_category: "write",
2268
+ base_risk: "low",
2269
+ exfiltration_risk: false,
2270
+ reversible: true
2271
+ },
2272
+ {
2273
+ intent: "display_reference_card",
2274
+ description: "Show a reference card layout with structured content",
2275
+ sdk_method: "session.layouts.showReferenceCard()",
2276
+ permission: "NONE",
2277
+ domain: "display",
2278
+ supported_glasses: ["even_realities_g1"],
2279
+ action_category: "write",
2280
+ base_risk: "low",
2281
+ exfiltration_risk: false,
2282
+ reversible: true
2283
+ },
2284
+ {
2285
+ intent: "display_dashboard_card",
2286
+ description: "Show a dashboard card layout",
2287
+ sdk_method: "session.layouts.showDashboardCard()",
2288
+ permission: "NONE",
2289
+ domain: "display",
2290
+ supported_glasses: ["even_realities_g1"],
2291
+ action_category: "write",
2292
+ base_risk: "low",
2293
+ exfiltration_risk: false,
2294
+ reversible: true
2295
+ },
2296
+ {
2297
+ intent: "display_image",
2298
+ description: "Display an image on the glasses",
2299
+ sdk_method: "session.layouts.showImage()",
2300
+ permission: "NONE",
2301
+ domain: "display",
2302
+ supported_glasses: ["even_realities_g1"],
2303
+ action_category: "write",
2304
+ base_risk: "low",
2305
+ exfiltration_risk: false,
2306
+ reversible: true
2307
+ },
2308
+ // ── Dashboard Domain ──────────────────────────────────────────────────
2309
+ {
2310
+ intent: "dashboard_update_main",
2311
+ description: "Update the persistent dashboard content (compact mode)",
2312
+ sdk_method: "session.dashboard.content.setMain()",
2313
+ permission: "NONE",
2314
+ domain: "dashboard",
2315
+ supported_glasses: ["even_realities_g1", "mentra_mach1", "vuzix_z100"],
2316
+ action_category: "write",
2317
+ base_risk: "low",
2318
+ exfiltration_risk: false,
2319
+ reversible: true
2320
+ },
2321
+ {
2322
+ intent: "dashboard_update_expanded",
2323
+ description: "Update the expanded dashboard content (user-opened mode)",
2324
+ sdk_method: "session.dashboard.content.setExpanded()",
2325
+ permission: "NONE",
2326
+ domain: "dashboard",
2327
+ supported_glasses: ["even_realities_g1", "mentra_mach1", "vuzix_z100"],
2328
+ action_category: "write",
2329
+ base_risk: "low",
2330
+ exfiltration_risk: false,
2331
+ reversible: true
2332
+ },
2333
+ // ── Location Domain ───────────────────────────────────────────────────
2334
+ {
2335
+ intent: "location_access",
2336
+ description: "Access current location data from the paired phone",
2337
+ sdk_method: "session.location.get()",
2338
+ permission: "LOCATION",
2339
+ domain: "location",
2340
+ supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
2341
+ action_category: "read",
2342
+ base_risk: "medium",
2343
+ exfiltration_risk: true,
2344
+ reversible: false
2345
+ },
2346
+ {
2347
+ intent: "location_continuous_sharing",
2348
+ description: "Start continuous location updates to the app server",
2349
+ sdk_method: "session.location.startContinuous()",
2350
+ permission: "LOCATION",
2351
+ domain: "location",
2352
+ supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
2353
+ action_category: "network",
2354
+ base_risk: "high",
2355
+ exfiltration_risk: true,
2356
+ reversible: true
2357
+ },
2358
+ // ── Calendar & Notifications ──────────────────────────────────────────
2359
+ {
2360
+ intent: "calendar_read",
2361
+ description: "Read calendar events from the paired phone",
2362
+ sdk_method: "session.calendar.getEvents()",
2363
+ permission: "CALENDAR",
2364
+ domain: "calendar",
2365
+ supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
2366
+ action_category: "read",
2367
+ base_risk: "low",
2368
+ exfiltration_risk: false,
2369
+ reversible: true
2370
+ },
2371
+ {
2372
+ intent: "notifications_read",
2373
+ description: "Read phone notifications",
2374
+ sdk_method: "session.notifications.getRecent()",
2375
+ permission: "READ_NOTIFICATIONS",
2376
+ domain: "notifications",
2377
+ supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
2378
+ action_category: "read",
2379
+ base_risk: "low",
2380
+ exfiltration_risk: false,
2381
+ reversible: true
2382
+ },
2383
+ // ── Audio Domain ──────────────────────────────────────────────────────
2384
+ {
2385
+ intent: "audio_play",
2386
+ description: "Play audio through the glasses speaker",
2387
+ sdk_method: "session.audio.play()",
2388
+ permission: "NONE",
2389
+ domain: "audio",
2390
+ supported_glasses: ["mentra_live"],
2391
+ action_category: "write",
2392
+ base_risk: "low",
2393
+ exfiltration_risk: false,
2394
+ reversible: true
2395
+ },
2396
+ // ── Session Domain ────────────────────────────────────────────────────
2397
+ {
2398
+ intent: "session_data_export",
2399
+ description: "Export session data to external storage or API",
2400
+ sdk_method: "session.export()",
2401
+ permission: "NONE",
2402
+ domain: "session",
2403
+ supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
2404
+ action_category: "network",
2405
+ base_risk: "high",
2406
+ exfiltration_risk: true,
2407
+ reversible: false
2408
+ },
2409
+ // ── Tool Call Domain ──────────────────────────────────────────────────
2410
+ {
2411
+ intent: "tool_call_execute",
2412
+ description: "Execute a custom tool call defined by the app via handleToolCall",
2413
+ sdk_method: "AppServer.handleToolCall()",
2414
+ permission: "NONE",
2415
+ domain: "tool_call",
2416
+ supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
2417
+ action_category: "other",
2418
+ base_risk: "medium",
2419
+ exfiltration_risk: false,
2420
+ reversible: false
2421
+ },
2422
+ // ── AI Data Flow Domain ─────────────────────────────────────────────────
2423
+ // These intents govern what user data apps send to their AI backends.
2424
+ // They operate at the app server layer (not the glasses hardware layer),
2425
+ // so they work on all glasses models and require no hardware permission.
2426
+ {
2427
+ intent: "ai_send_transcription",
2428
+ description: "Send user speech transcription to an external AI API for processing",
2429
+ sdk_method: "app_server.ai.sendTranscription()",
2430
+ permission: "NONE",
2431
+ domain: "ai_data",
2432
+ supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
2433
+ action_category: "network",
2434
+ base_risk: "medium",
2435
+ exfiltration_risk: true,
2436
+ reversible: false
2437
+ },
2438
+ {
2439
+ intent: "ai_send_image",
2440
+ description: "Send a camera-captured image to an external AI API for vision analysis",
2441
+ sdk_method: "app_server.ai.sendImage()",
2442
+ permission: "NONE",
2443
+ domain: "ai_data",
2444
+ supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
2445
+ action_category: "network",
2446
+ base_risk: "high",
2447
+ exfiltration_risk: true,
2448
+ reversible: false
2449
+ },
2450
+ {
2451
+ intent: "ai_send_location",
2452
+ description: "Send user location data to an external AI API for context-aware processing",
2453
+ sdk_method: "app_server.ai.sendLocation()",
2454
+ permission: "NONE",
2455
+ domain: "ai_data",
2456
+ supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
2457
+ action_category: "network",
2458
+ base_risk: "medium",
2459
+ exfiltration_risk: true,
2460
+ reversible: false
2461
+ },
2462
+ {
2463
+ intent: "ai_send_calendar",
2464
+ description: "Send user calendar data to an external AI API for scheduling assistance",
2465
+ sdk_method: "app_server.ai.sendCalendar()",
2466
+ permission: "NONE",
2467
+ domain: "ai_data",
2468
+ supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
2469
+ action_category: "network",
2470
+ base_risk: "medium",
2471
+ exfiltration_risk: true,
2472
+ reversible: false
2473
+ },
2474
+ {
2475
+ intent: "ai_send_notifications",
2476
+ description: "Send user notification data to an external AI API for summarization or triage",
2477
+ sdk_method: "app_server.ai.sendNotifications()",
2478
+ permission: "NONE",
2479
+ domain: "ai_data",
2480
+ supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
2481
+ action_category: "network",
2482
+ base_risk: "medium",
2483
+ exfiltration_risk: true,
2484
+ reversible: false
2485
+ },
2486
+ // ── AI Action Domain ──────────────────────────────────────────────────
2487
+ // These intents govern actions AI takes on behalf of the user.
2488
+ // Every action here must be shown on the glasses display before execution.
2489
+ {
2490
+ intent: "ai_auto_respond_message",
2491
+ description: "AI generates and sends a message (email, SMS, chat) on the user's behalf",
2492
+ sdk_method: "app_server.ai.sendMessage()",
2493
+ permission: "NONE",
2494
+ domain: "ai_action",
2495
+ supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
2496
+ action_category: "network",
2497
+ base_risk: "high",
2498
+ exfiltration_risk: true,
2499
+ reversible: false
2500
+ },
2501
+ {
2502
+ intent: "ai_auto_purchase",
2503
+ description: "AI initiates a financial transaction (purchase, subscription, tip) on the user's behalf",
2504
+ sdk_method: "app_server.ai.purchase()",
2505
+ permission: "NONE",
2506
+ domain: "ai_action",
2507
+ supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
2508
+ action_category: "network",
2509
+ base_risk: "critical",
2510
+ exfiltration_risk: true,
2511
+ reversible: false
2512
+ },
2513
+ {
2514
+ intent: "ai_auto_schedule",
2515
+ description: "AI creates, modifies, or cancels a calendar event on the user's behalf",
2516
+ sdk_method: "app_server.ai.schedule()",
2517
+ permission: "NONE",
2518
+ domain: "ai_action",
2519
+ supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
2520
+ action_category: "write",
2521
+ base_risk: "medium",
2522
+ exfiltration_risk: false,
2523
+ reversible: true
2524
+ },
2525
+ {
2526
+ intent: "ai_auto_setting_change",
2527
+ description: "AI changes a user setting or app configuration on the user's behalf",
2528
+ sdk_method: "app_server.ai.changeSetting()",
2529
+ permission: "NONE",
2530
+ domain: "ai_action",
2531
+ supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
2532
+ action_category: "write",
2533
+ base_risk: "medium",
2534
+ exfiltration_risk: false,
2535
+ reversible: true
2536
+ },
2537
+ {
2538
+ intent: "ai_retain_session_data",
2539
+ description: "AI or app retains user session data (transcriptions, images, conversation) beyond session end",
2540
+ sdk_method: "app_server.ai.retainData()",
2541
+ permission: "NONE",
2542
+ domain: "ai_data",
2543
+ supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
2544
+ action_category: "write",
2545
+ base_risk: "high",
2546
+ exfiltration_risk: true,
2547
+ reversible: false
2548
+ },
2549
+ {
2550
+ intent: "ai_share_with_third_party",
2551
+ description: "AI or app shares user data with a third-party service beyond the declared AI provider",
2552
+ sdk_method: "app_server.ai.shareExternal()",
2553
+ permission: "NONE",
2554
+ domain: "ai_data",
2555
+ supported_glasses: ["even_realities_g1", "mentra_live", "mentra_mach1", "vuzix_z100"],
2556
+ action_category: "network",
2557
+ base_risk: "critical",
2558
+ exfiltration_risk: true,
2559
+ reversible: false
2560
+ }
2561
+ ];
2562
+ var MENTRA_KNOWN_INTENTS = MENTRA_INTENT_TAXONOMY.map((d) => d.intent);
2563
+ var MENTRA_INTENT_MAP = new Map(MENTRA_INTENT_TAXONOMY.map((d) => [d.intent, d]));
2564
+ function getMentraIntent(intent) {
2565
+ return MENTRA_INTENT_MAP.get(intent);
2566
+ }
2567
+ function getIntentsByPermission(permission) {
2568
+ return MENTRA_INTENT_TAXONOMY.filter((d) => d.permission === permission);
2569
+ }
2570
+ function getIntentsByGlasses(model) {
2571
+ return MENTRA_INTENT_TAXONOMY.filter((d) => d.supported_glasses.includes(model));
2572
+ }
2573
+ function isIntentSupported(intent, model) {
2574
+ const def = MENTRA_INTENT_MAP.get(intent);
2575
+ return def ? def.supported_glasses.includes(model) : false;
2576
+ }
2577
+ function getHighRiskIntents() {
2578
+ return MENTRA_INTENT_TAXONOMY.filter((d) => d.base_risk === "high" || d.base_risk === "critical");
2579
+ }
2580
+ function getExfiltrationIntents() {
2581
+ return MENTRA_INTENT_TAXONOMY.filter((d) => d.exfiltration_risk);
2582
+ }
2583
+ function getAIDataIntents() {
2584
+ return MENTRA_INTENT_TAXONOMY.filter((d) => d.domain === "ai_data");
2585
+ }
2586
+ function getAIActionIntents() {
2587
+ return MENTRA_INTENT_TAXONOMY.filter((d) => d.domain === "ai_action");
2588
+ }
2589
+ function getAIIntents() {
2590
+ return MENTRA_INTENT_TAXONOMY.filter((d) => d.domain === "ai_data" || d.domain === "ai_action");
2591
+ }
2592
+ function isAIIntent(intent) {
2593
+ const def = MENTRA_INTENT_MAP.get(intent);
2594
+ return def ? def.domain === "ai_data" || def.domain === "ai_action" : false;
2595
+ }
2596
+
2597
+ // src/adapters/mentraos.ts
2598
+ var DEFAULT_USER_RULES = {
2599
+ aiDataPolicy: "declared_only",
2600
+ aiActionPolicy: "confirm_all",
2601
+ aiPurchasePolicy: "confirm_each",
2602
+ aiMessagingPolicy: "confirm_each",
2603
+ dataRetentionPolicy: "app_declared",
2604
+ maxAIProviders: 5
2605
+ };
2606
+ function evaluateUserRules(intent, rules, appContext) {
2607
+ const def = getMentraIntent(intent);
2608
+ if (!def) return null;
2609
+ if (def.domain === "ai_data" && intent !== "ai_retain_session_data") {
2610
+ if (rules.aiDataPolicy === "block_all") {
2611
+ return {
2612
+ verdict: {
2613
+ status: "BLOCK",
2614
+ ruleId: "user-rule-ai-data-block",
2615
+ reason: `User rules block all AI data sends. Intent: ${intent}`,
2616
+ evidence: makeEvidence("user-rule-ai-data-block")
2617
+ },
2618
+ reason: "User has blocked all AI data sends"
2619
+ };
2620
+ }
2621
+ if (rules.aiDataPolicy === "confirm_each") {
2622
+ return {
2623
+ verdict: {
2624
+ status: "PAUSE",
2625
+ ruleId: "user-rule-ai-data-confirm",
2626
+ reason: `User rules require confirmation for every AI data send. Intent: ${intent}`,
2627
+ evidence: makeEvidence("user-rule-ai-data-confirm")
2628
+ },
2629
+ reason: "User requires confirmation for each AI data send"
2630
+ };
2631
+ }
2632
+ if (!appContext.aiProviderDeclared) {
2633
+ return {
2634
+ verdict: {
2635
+ status: "BLOCK",
2636
+ ruleId: "user-rule-undeclared-provider",
2637
+ reason: `App "${appContext.appId}" has not declared its AI provider. User rules require declared providers only.`,
2638
+ evidence: makeEvidence("user-rule-undeclared-provider")
2639
+ },
2640
+ reason: "App has not declared its AI provider"
2641
+ };
2642
+ }
2643
+ }
2644
+ if (intent === "ai_retain_session_data") {
2645
+ if (rules.dataRetentionPolicy === "never") {
2646
+ return {
2647
+ verdict: {
2648
+ status: "BLOCK",
2649
+ ruleId: "user-rule-no-retention",
2650
+ reason: `User rules block all data retention. App "${appContext.appId}" cannot retain session data.`,
2651
+ evidence: makeEvidence("user-rule-no-retention")
2652
+ },
2653
+ reason: "User has blocked all data retention"
2654
+ };
2655
+ }
2656
+ if (!appContext.dataRetentionOptedIn) {
2657
+ return {
2658
+ verdict: {
2659
+ status: "BLOCK",
2660
+ ruleId: "user-rule-retention-no-optin",
2661
+ reason: `User has not opted in to data retention for app "${appContext.appId}".`,
2662
+ evidence: makeEvidence("user-rule-retention-no-optin")
2663
+ },
2664
+ reason: "User has not opted in to data retention for this app"
2665
+ };
2666
+ }
2667
+ }
2668
+ if (intent === "ai_auto_purchase") {
2669
+ if (rules.aiPurchasePolicy === "block_all") {
2670
+ return {
2671
+ verdict: {
2672
+ status: "BLOCK",
2673
+ ruleId: "user-rule-no-purchases",
2674
+ reason: "User rules block all AI-initiated purchases.",
2675
+ evidence: makeEvidence("user-rule-no-purchases")
2676
+ },
2677
+ reason: "User has blocked all AI purchases"
2678
+ };
2679
+ }
2680
+ return {
2681
+ verdict: {
2682
+ status: "PAUSE",
2683
+ ruleId: "user-rule-purchase-confirm",
2684
+ reason: `AI wants to make a purchase. User rules require per-transaction confirmation.`,
2685
+ evidence: makeEvidence("user-rule-purchase-confirm")
2686
+ },
2687
+ reason: "User requires per-transaction confirmation for AI purchases"
2688
+ };
2689
+ }
2690
+ if (intent === "ai_auto_respond_message") {
2691
+ if (rules.aiMessagingPolicy === "block_all") {
2692
+ return {
2693
+ verdict: {
2694
+ status: "BLOCK",
2695
+ ruleId: "user-rule-no-messaging",
2696
+ reason: "User rules block all AI-initiated messaging.",
2697
+ evidence: makeEvidence("user-rule-no-messaging")
2698
+ },
2699
+ reason: "User has blocked all AI messaging"
2700
+ };
2701
+ }
2702
+ return {
2703
+ verdict: {
2704
+ status: "PAUSE",
2705
+ ruleId: "user-rule-message-confirm",
2706
+ reason: `AI wants to send a message on your behalf. User rules require per-message confirmation.`,
2707
+ evidence: makeEvidence("user-rule-message-confirm")
2708
+ },
2709
+ reason: "User requires per-message confirmation for AI messaging"
2710
+ };
2711
+ }
2712
+ if (def.domain === "ai_action" && intent !== "ai_auto_purchase" && intent !== "ai_auto_respond_message") {
2713
+ if (rules.aiActionPolicy === "block_all") {
2714
+ return {
2715
+ verdict: {
2716
+ status: "BLOCK",
2717
+ ruleId: "user-rule-no-ai-actions",
2718
+ reason: `User rules block all AI auto-actions. Intent: ${intent}`,
2719
+ evidence: makeEvidence("user-rule-no-ai-actions")
2720
+ },
2721
+ reason: "User has blocked all AI auto-actions"
2722
+ };
2723
+ }
2724
+ if (rules.aiActionPolicy === "confirm_all") {
2725
+ return {
2726
+ verdict: {
2727
+ status: "PAUSE",
2728
+ ruleId: "user-rule-action-confirm",
2729
+ reason: `AI wants to take action: ${intent}. User rules require confirmation.`,
2730
+ evidence: makeEvidence("user-rule-action-confirm")
2731
+ },
2732
+ reason: "User requires confirmation for all AI actions"
2733
+ };
2734
+ }
2735
+ if (def.base_risk === "high" || def.base_risk === "critical") {
2736
+ return {
2737
+ verdict: {
2738
+ status: "PAUSE",
2739
+ ruleId: "user-rule-high-risk-confirm",
2740
+ reason: `AI wants to take high-risk action: ${intent}. User rules require confirmation for high-risk actions.`,
2741
+ evidence: makeEvidence("user-rule-high-risk-confirm")
2742
+ },
2743
+ reason: "User requires confirmation for high-risk AI actions"
2744
+ };
2745
+ }
2746
+ }
2747
+ if (intent === "ai_share_with_third_party") {
2748
+ return {
2749
+ verdict: {
2750
+ status: "PAUSE",
2751
+ ruleId: "user-rule-third-party-confirm",
2752
+ reason: `App wants to share your data with a third party beyond its declared AI provider. Confirmation required.`,
2753
+ evidence: makeEvidence("user-rule-third-party-confirm")
2754
+ },
2755
+ reason: "Third-party data sharing requires user confirmation"
2756
+ };
2757
+ }
2758
+ return null;
2759
+ }
2760
+ function makeEvidence(ruleId) {
2761
+ return {
2762
+ worldId: "mentraos-user-rules",
2763
+ worldName: "MentraOS User Rules",
2764
+ worldVersion: "1.0.0",
2765
+ evaluatedAt: Date.now(),
2766
+ invariantsSatisfied: 0,
2767
+ invariantsTotal: 0,
2768
+ guardsMatched: [ruleId],
2769
+ rulesMatched: [],
2770
+ enforcementLevel: "strict"
2771
+ };
2772
+ }
2773
+ var MentraGovernedExecutor = class {
2774
+ world;
2775
+ engineOptions;
2776
+ options;
2777
+ planState;
2778
+ planCallbacks;
2779
+ _userRules;
2780
+ _emergencyOverride = false;
2781
+ _emergencyActivatedAt = null;
2782
+ _spatialSession = null;
2783
+ constructor(world, options = {}, userRules = DEFAULT_USER_RULES) {
2784
+ this.world = world;
2785
+ this.options = options;
2786
+ this._userRules = userRules;
2787
+ this.engineOptions = buildEngineOptions(options, options.plan);
2788
+ this.planState = { activePlan: options.plan, engineOptions: this.engineOptions };
2789
+ this.planCallbacks = {
2790
+ onPlanProgress: options.onPlanProgress,
2791
+ onPlanComplete: options.onPlanComplete
2792
+ };
2793
+ }
2794
+ /** Get the current user rules */
2795
+ get userRules() {
2796
+ return this._userRules;
2797
+ }
2798
+ /** Update user rules at runtime (e.g., user changes preferences in phone app) */
2799
+ updateUserRules(rules) {
2800
+ this._userRules = { ...this._userRules, ...rules };
2801
+ }
2802
+ /**
2803
+ * Activate emergency override — user is king.
2804
+ *
2805
+ * Bypasses all NeuroVerse governance rules (user rules, platform rules).
2806
+ * Does NOT bypass MentraOS platform constraints (hardware capability,
2807
+ * declared permissions, session isolation). You can't override physics.
2808
+ *
2809
+ * Returns the timestamp of activation for audit trail.
2810
+ */
2811
+ activateEmergencyOverride() {
2812
+ this._emergencyOverride = true;
2813
+ this._emergencyActivatedAt = Date.now();
2814
+ this.engineOptions = { ...this.engineOptions, emergencyOverride: true };
2815
+ return this._emergencyActivatedAt;
2816
+ }
2817
+ /**
2818
+ * Deactivate emergency override — governance resumes.
2819
+ * Returns the duration the override was active (ms).
2820
+ */
2821
+ deactivateEmergencyOverride() {
2822
+ if (!this._emergencyOverride || !this._emergencyActivatedAt) {
2823
+ return 0;
2824
+ }
2825
+ const duration = Date.now() - this._emergencyActivatedAt;
2826
+ this._emergencyOverride = false;
2827
+ this._emergencyActivatedAt = null;
2828
+ this.engineOptions = { ...this.engineOptions, emergencyOverride: false };
2829
+ return duration;
2830
+ }
2831
+ /** Whether emergency override is currently active */
2832
+ get isEmergencyOverrideActive() {
2833
+ return this._emergencyOverride;
2834
+ }
2835
+ /** Timestamp when emergency override was activated, or null */
2836
+ get emergencyActivatedAt() {
2837
+ return this._emergencyActivatedAt;
2838
+ }
2839
+ // ── Spatial Governance (optional) ────────────────────────────────────────
2840
+ /**
2841
+ * Attach a spatial session to this executor.
2842
+ *
2843
+ * When attached, intents are evaluated against the spatial context
2844
+ * (zone rules + handshake rules) AFTER user rules but BEFORE
2845
+ * hardware and platform checks. This is Layer 1.5.
2846
+ *
2847
+ * Pass null to detach (e.g., when leaving a zone).
2848
+ */
2849
+ setSpatialSession(session) {
2850
+ this._spatialSession = session;
2851
+ }
2852
+ /** Whether a spatial session is currently active */
2853
+ get hasSpatialSession() {
2854
+ return this._spatialSession !== null;
2855
+ }
2856
+ /** Get the current spatial session description */
2857
+ get spatialDescription() {
2858
+ return this._spatialSession?.description ?? null;
2859
+ }
2860
+ /**
2861
+ * Evaluate an intent against user rules + platform world.
2862
+ *
2863
+ * Three-layer evaluation:
2864
+ * 0. Emergency override — if active, skip governance (layers 1 + 1.5 + 3),
2865
+ * but STILL enforce platform constraints (layer 2)
2866
+ * 1. User rules check — personal governance override, can BLOCK or PAUSE
2867
+ * 1.5. Spatial governance — zone + handshake rules (optional, temporary)
2868
+ * ↑ ONLY ACTIVE when a spatial session is attached
2869
+ * 2. Hardware capability check — validates glasses support
2870
+ * ↑ THIS IS A PLATFORM CONSTRAINT — never overridden
2871
+ * 3. Platform guard engine — full world rule evaluation
2872
+ */
2873
+ evaluate(intent, appContext) {
2874
+ const intentDef = getMentraIntent(intent);
2875
+ const glassesModel = appContext.glassesModel;
2876
+ if (!this._emergencyOverride) {
2877
+ const userRulesResult = evaluateUserRules(intent, this._userRules, appContext);
2878
+ if (userRulesResult) {
2879
+ const allowed2 = false;
2880
+ const requiresConfirmation2 = userRulesResult.verdict.status === "PAUSE";
2881
+ const result2 = {
2882
+ allowed: requiresConfirmation2 ? false : false,
2883
+ requiresConfirmation: requiresConfirmation2,
2884
+ verdict: userRulesResult.verdict,
2885
+ intentDef,
2886
+ userRulesResult: { reason: userRulesResult.reason },
2887
+ appContext,
2888
+ decidingLayer: "user_rules"
2889
+ };
2890
+ if (requiresConfirmation2) {
2891
+ this.options.onPause?.(result2);
2892
+ } else {
2893
+ this.options.onBlock?.(result2);
2894
+ }
2895
+ this.options.onEvaluate?.(result2);
2896
+ return result2;
2897
+ }
2898
+ }
2899
+ if (!this._emergencyOverride && this._spatialSession) {
2900
+ const spatialResult = this._spatialSession.evaluate(intent);
2901
+ if (!spatialResult.allowed && !spatialResult.requiresConfirmation) {
2902
+ const verdict2 = {
2903
+ status: "BLOCK",
2904
+ ruleId: "spatial-zone-rule",
2905
+ reason: spatialResult.reason,
2906
+ evidence: makeEvidence("spatial-zone-rule")
2907
+ };
2908
+ const result2 = {
2909
+ allowed: false,
2910
+ requiresConfirmation: false,
2911
+ verdict: verdict2,
2912
+ intentDef,
2913
+ appContext,
2914
+ decidingLayer: "spatial"
2915
+ };
2916
+ this.options.onBlock?.(result2);
2917
+ this.options.onEvaluate?.(result2);
2918
+ return result2;
2919
+ }
2920
+ if (spatialResult.requiresConfirmation) {
2921
+ const verdict2 = {
2922
+ status: "PAUSE",
2923
+ ruleId: "spatial-zone-rule",
2924
+ reason: spatialResult.reason,
2925
+ evidence: makeEvidence("spatial-zone-rule")
2926
+ };
2927
+ const result2 = {
2928
+ allowed: false,
2929
+ requiresConfirmation: true,
2930
+ verdict: verdict2,
2931
+ intentDef,
2932
+ appContext,
2933
+ decidingLayer: "spatial"
2934
+ };
2935
+ this.options.onPause?.(result2);
2936
+ this.options.onEvaluate?.(result2);
2937
+ return result2;
2938
+ }
2939
+ }
2940
+ if (intentDef && glassesModel && !intentDef.supported_glasses.includes(glassesModel)) {
2941
+ const verdict2 = {
2942
+ status: "BLOCK",
2943
+ ruleId: "hardware-capability",
2944
+ reason: `${intent} not supported on ${glassesModel} \u2014 requires: ${intentDef.supported_glasses.join(", ")}`,
2945
+ evidence: {
2946
+ worldId: this.world.world?.world_id ?? "unknown",
2947
+ worldName: this.world.world?.name ?? "unknown",
2948
+ worldVersion: this.world.world?.version ?? "unknown",
2949
+ evaluatedAt: Date.now(),
2950
+ invariantsSatisfied: 0,
2951
+ invariantsTotal: 0,
2952
+ guardsMatched: ["hardware-capability"],
2953
+ rulesMatched: [],
2954
+ enforcementLevel: "strict"
2955
+ }
2956
+ };
2957
+ const result2 = {
2958
+ allowed: false,
2959
+ requiresConfirmation: false,
2960
+ verdict: verdict2,
2961
+ intentDef,
2962
+ appContext,
2963
+ decidingLayer: "hardware"
2964
+ };
2965
+ this.options.onBlock?.(result2);
2966
+ this.options.onEvaluate?.(result2);
2967
+ return result2;
2968
+ }
2969
+ const event = {
2970
+ intent,
2971
+ tool: intentDef?.sdk_method ?? intent,
2972
+ scope: intentDef?.domain ?? "unknown",
2973
+ actionCategory: intentDef?.action_category,
2974
+ riskLevel: intentDef?.base_risk ?? "medium",
2975
+ irreversible: intentDef ? !intentDef.reversible : false,
2976
+ args: {
2977
+ app_id: appContext.appId,
2978
+ ai_provider_declared: appContext.aiProviderDeclared ? 1 : 0,
2979
+ ai_data_types_sent: appContext.aiDataTypesSent,
2980
+ ai_retention_opted_in: appContext.dataRetentionOptedIn ? 1 : 0,
2981
+ glasses_model: glassesModel ?? "unknown",
2982
+ is_ai_intent: isAIIntent(intent) ? 1 : 0
2983
+ }
2984
+ };
2985
+ const verdict = evaluateGuard(event, this.world, this.engineOptions);
2986
+ const allowed = verdict.status === "ALLOW" || verdict.status === "REWARD";
2987
+ const requiresConfirmation = verdict.status === "PAUSE";
2988
+ if (allowed) {
2989
+ trackPlanProgress(event, this.planState, this.planCallbacks);
2990
+ }
2991
+ const result = {
2992
+ allowed,
2993
+ requiresConfirmation,
2994
+ verdict,
2995
+ intentDef,
2996
+ appContext,
2997
+ decidingLayer: this._emergencyOverride ? "emergency_override" : "platform"
2998
+ };
2999
+ if (!allowed && !requiresConfirmation) {
3000
+ this.options.onBlock?.(result);
3001
+ }
3002
+ if (requiresConfirmation) {
3003
+ this.options.onPause?.(result);
3004
+ }
3005
+ this.options.onEvaluate?.(result);
3006
+ return result;
3007
+ }
3008
+ /** Get all known intents for this adapter */
3009
+ get knownIntents() {
3010
+ return MENTRA_KNOWN_INTENTS;
3011
+ }
3012
+ };
3013
+ async function createMentraGovernedExecutor(worldPath, options = {}, userRules = DEFAULT_USER_RULES) {
3014
+ const world = await loadWorld(worldPath);
3015
+ return new MentraGovernedExecutor(world, options, userRules);
3016
+ }
3017
+ function createMentraGovernedExecutorFromWorld(world, options = {}, userRules = DEFAULT_USER_RULES) {
3018
+ return new MentraGovernedExecutor(world, options, userRules);
3019
+ }
2086
3020
  // Annotate the CommonJS export names for ESM import in node:
2087
3021
  0 && (module.exports = {
2088
3022
  AutoresearchGovernor,
3023
+ DEFAULT_USER_RULES,
2089
3024
  DeepAgentsGovernanceBlockedError,
2090
3025
  DeepAgentsGuard,
2091
3026
  GovernanceBlockedError,
2092
3027
  GovernedToolExecutor,
2093
3028
  LangChainGovernanceBlockedError,
3029
+ MENTRA_INTENT_TAXONOMY,
3030
+ MENTRA_KNOWN_INTENTS,
3031
+ MentraGovernanceBlockedError,
3032
+ MentraGovernedExecutor,
2094
3033
  NeuroVerseCallbackHandler,
2095
3034
  NeuroVersePlugin,
2096
3035
  OpenAIGovernanceBlockedError,
@@ -2102,11 +3041,24 @@ function createDeepAgentsGuardFromWorld(world, options) {
2102
3041
  createGovernanceMiddlewareFromWorld,
2103
3042
  createGovernedToolExecutor,
2104
3043
  createGovernedToolExecutorFromWorld,
3044
+ createMentraGovernedExecutor,
3045
+ createMentraGovernedExecutorFromWorld,
2105
3046
  createNeuroVerseCallbackHandler,
2106
3047
  createNeuroVerseCallbackHandlerFromWorld,
2107
3048
  createNeuroVersePlugin,
2108
3049
  createNeuroVersePluginFromWorld,
2109
3050
  defaultBlockMessage,
3051
+ evaluateUserRules,
2110
3052
  extractScope,
3053
+ getAIActionIntents,
3054
+ getAIDataIntents,
3055
+ getAIIntents,
3056
+ getExfiltrationIntents,
3057
+ getHighRiskIntents,
3058
+ getIntentsByGlasses,
3059
+ getIntentsByPermission,
3060
+ getMentraIntent,
3061
+ isAIIntent,
3062
+ isIntentSupported,
2111
3063
  trackPlanProgress
2112
3064
  });