@neuroverseos/governance 0.4.0 → 0.4.2

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 (108) hide show
  1. package/dist/adapters/autoresearch.d.cts +2 -1
  2. package/dist/adapters/autoresearch.d.ts +2 -1
  3. package/dist/adapters/autoresearch.js +2 -2
  4. package/dist/adapters/deep-agents.d.cts +3 -2
  5. package/dist/adapters/deep-agents.d.ts +3 -2
  6. package/dist/adapters/deep-agents.js +2 -2
  7. package/dist/adapters/express.d.cts +2 -1
  8. package/dist/adapters/express.d.ts +2 -1
  9. package/dist/adapters/express.js +2 -2
  10. package/dist/adapters/github.cjs +1697 -0
  11. package/dist/adapters/github.d.cts +225 -0
  12. package/dist/adapters/github.d.ts +225 -0
  13. package/dist/adapters/github.js +27 -0
  14. package/dist/adapters/index.cjs +66 -1
  15. package/dist/adapters/index.d.cts +4 -278
  16. package/dist/adapters/index.d.ts +4 -278
  17. package/dist/adapters/index.js +18 -18
  18. package/dist/adapters/langchain.d.cts +3 -2
  19. package/dist/adapters/langchain.d.ts +3 -2
  20. package/dist/adapters/langchain.js +2 -2
  21. package/dist/adapters/mentraos.cjs +2181 -0
  22. package/dist/adapters/mentraos.d.cts +319 -0
  23. package/dist/adapters/mentraos.d.ts +319 -0
  24. package/dist/{mentraos-YFS7FMJH.js → adapters/mentraos.js} +6 -6
  25. package/dist/adapters/openai.d.cts +3 -2
  26. package/dist/adapters/openai.d.ts +3 -2
  27. package/dist/adapters/openai.js +2 -2
  28. package/dist/adapters/openclaw.d.cts +3 -2
  29. package/dist/adapters/openclaw.d.ts +3 -2
  30. package/dist/adapters/openclaw.js +2 -2
  31. package/dist/{add-LYHDZ5RL.js → add-XSANI3FK.js} +1 -1
  32. package/dist/bootstrap-contract-DcV6t-8M.d.cts +216 -0
  33. package/dist/bootstrap-contract-DcV6t-8M.d.ts +216 -0
  34. package/dist/{build-THUEYMVT.js → build-EGBGZFIJ.js} +5 -5
  35. package/dist/{chunk-MFKHTE5R.js → chunk-3AYKQHYI.js} +1 -1
  36. package/dist/chunk-3S5AD4AB.js +421 -0
  37. package/dist/{chunk-V4FZHJQX.js → chunk-A7SHG75T.js} +1 -1
  38. package/dist/{chunk-JKGPSFGH.js → chunk-AV7XJJWK.js} +1 -1
  39. package/dist/{chunk-Y6WXAPKY.js → chunk-DA5MHFRR.js} +1 -1
  40. package/dist/{chunk-7D7PZLB7.js → chunk-FS2UUJJO.js} +3 -3
  41. package/dist/{chunk-TD5GKIHP.js → chunk-FVOGUCB6.js} +1 -1
  42. package/dist/{chunk-APU4OZIP.js → chunk-GTPV2XGO.js} +67 -2
  43. package/dist/{chunk-BXLTEUS4.js → chunk-I4RTIMLX.js} +2 -2
  44. package/dist/{chunk-5JUZ4HL7.js → chunk-J2IZBHXJ.js} +3 -3
  45. package/dist/{chunk-YNYCQECH.js → chunk-QMVQ6KPL.js} +1 -1
  46. package/dist/{chunk-25XHSTPT.js → chunk-RDA7ISWC.js} +1 -1
  47. package/dist/{chunk-DWHUZUEY.js → chunk-YJ34R5NB.js} +1 -1
  48. package/dist/{chunk-UTH7OXTM.js → chunk-ZEIT2QLM.js} +3 -3
  49. package/dist/cli/neuroverse.cjs +580 -28
  50. package/dist/cli/neuroverse.js +21 -21
  51. package/dist/cli/plan.js +2 -2
  52. package/dist/cli/run.js +2 -2
  53. package/dist/{demo-66MMJTEH.js → demo-6OQYWRR6.js} +3 -3
  54. package/dist/{derive-5LOMN7GO.js → derive-7Y7YWVLU.js} +4 -4
  55. package/dist/{doctor-WIO4FLA3.js → doctor-EC5OYTI3.js} +3 -2
  56. package/dist/engine/bootstrap-emitter.cjs +241 -0
  57. package/dist/engine/bootstrap-emitter.d.cts +27 -0
  58. package/dist/engine/bootstrap-emitter.d.ts +27 -0
  59. package/dist/{bootstrap-emitter-GIMOJFOC.js → engine/bootstrap-emitter.js} +2 -2
  60. package/dist/engine/bootstrap-parser.cjs +560 -0
  61. package/dist/engine/bootstrap-parser.d.cts +96 -0
  62. package/dist/engine/bootstrap-parser.d.ts +96 -0
  63. package/dist/{bootstrap-parser-LBLGVEMU.js → engine/bootstrap-parser.js} +2 -2
  64. package/dist/engine/guard-engine.cjs +1116 -0
  65. package/dist/engine/guard-engine.d.cts +60 -0
  66. package/dist/engine/guard-engine.d.ts +60 -0
  67. package/dist/{guard-engine-N7TUIUU7.js → engine/guard-engine.js} +3 -3
  68. package/dist/engine/simulate-engine.cjs +390 -0
  69. package/dist/engine/simulate-engine.d.cts +105 -0
  70. package/dist/engine/simulate-engine.d.ts +105 -0
  71. package/dist/engine/simulate-engine.js +9 -0
  72. package/dist/{equity-penalties-WWC7UDQD.js → equity-penalties-NVBAB5WL.js} +2 -2
  73. package/dist/{explain-MUSGDT67.js → explain-HDFN4ION.js} +1 -1
  74. package/dist/{guard-W3BMQPBJ.js → guard-6KSCWT2W.js} +2 -2
  75. package/dist/{guard-contract-CLBbTGK_.d.ts → guard-contract-ddiIPlOg.d.cts} +2 -369
  76. package/dist/{guard-contract-CLBbTGK_.d.cts → guard-contract-q6HJAq3Q.d.ts} +2 -369
  77. package/dist/{improve-PJDAWW4Q.js → improve-2PWGGO5B.js} +3 -3
  78. package/dist/index.cjs +452 -0
  79. package/dist/index.d.cts +12 -492
  80. package/dist/index.d.ts +12 -492
  81. package/dist/index.js +75 -54
  82. package/dist/{lens-IP6GIZ2Q.js → lens-MHMUDCMQ.js} +92 -25
  83. package/dist/{mcp-server-OG3PPVD2.js → mcp-server-TNIWZ7B5.js} +2 -2
  84. package/dist/{playground-4BK2XQ47.js → playground-3FLDGBET.js} +2 -2
  85. package/dist/{redteam-BRZALBPP.js → redteam-HV6LMKEH.js} +2 -2
  86. package/dist/{session-SGRUT2UH.js → session-XZP2754M.js} +2 -2
  87. package/dist/{shared-CwGpPheR.d.ts → shared-DAzdfWtU.d.ts} +1 -1
  88. package/dist/{shared-BGzmYP5g.d.cts → shared-PpalGKxc.d.cts} +1 -1
  89. package/dist/{simulate-FGXKIH7V.js → simulate-VT437EEL.js} +2 -2
  90. package/dist/spatial/index.cjs +682 -0
  91. package/dist/spatial/index.d.cts +517 -0
  92. package/dist/spatial/index.d.ts +517 -0
  93. package/dist/spatial/index.js +633 -0
  94. package/dist/{test-PT44BSYG.js → test-4WTX6RKQ.js} +2 -2
  95. package/dist/types.cjs +18 -0
  96. package/dist/types.d.cts +370 -0
  97. package/dist/types.d.ts +370 -0
  98. package/dist/types.js +0 -0
  99. package/dist/{validate-Q5O5TGLT.js → validate-M52DX22Y.js} +1 -1
  100. package/dist/{world-V52ZMH26.js → world-O4HTQPDP.js} +1 -1
  101. package/dist/{world-loader-C4D3VPP3.js → world-loader-YTYFOP7D.js} +1 -1
  102. package/dist/worlds/mentraos-spatial.nv-world.md +68 -0
  103. package/package.json +52 -3
  104. package/dist/{behavioral-SPWPGYXL.js → behavioral-SLW7ALEK.js} +3 -3
  105. package/dist/{bootstrap-IP5QMC3Q.js → bootstrap-2OW5ZLBL.js} +3 -3
  106. package/dist/{chunk-7QIAF377.js → chunk-CYDMUJVZ.js} +0 -0
  107. package/dist/{chunk-QZ666FCV.js → chunk-FHXXD2TI.js} +6 -6
  108. package/dist/{configure-ai-5MP5DWTT.js → configure-ai-LL3VAPQW.js} +3 -3
@@ -0,0 +1,682 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/spatial/index.ts
21
+ var spatial_exports = {};
22
+ __export(spatial_exports, {
23
+ APPLE_UNION_SQUARE: () => APPLE_UNION_SQUARE,
24
+ BLUE_BOTTLE_HAYES: () => BLUE_BOTTLE_HAYES,
25
+ CHASE_CENTER: () => CHASE_CENTER,
26
+ DEFAULT_PARTICIPANT_CONSTRAINTS: () => DEFAULT_PARTICIPANT_CONSTRAINTS,
27
+ DEFAULT_ZONE_RULES: () => DEFAULT_ZONE_RULES,
28
+ EXAMPLE_ZONES: () => EXAMPLE_ZONES,
29
+ MY_HOME: () => MY_HOME,
30
+ SFMOMA: () => SFMOMA,
31
+ UCSF_MEDICAL: () => UCSF_MEDICAL,
32
+ WEWORK_SOMA: () => WEWORK_SOMA,
33
+ ZONE_TEMPLATES: () => ZONE_TEMPLATES,
34
+ activateEmergencyOverride: () => activateEmergencyOverride,
35
+ applyHandshakeToSession: () => applyHandshakeToSession,
36
+ applyZoneToSession: () => applyZoneToSession,
37
+ constraintsToRules: () => constraintsToRules,
38
+ createOptIn: () => createOptIn,
39
+ createSession: () => createSession,
40
+ endSession: () => endSession,
41
+ evaluateSpatial: () => evaluateSpatial,
42
+ evaluateSpatialEmergency: () => evaluateSpatialEmergency,
43
+ exitZone: () => exitZone,
44
+ joinHandshake: () => joinHandshake,
45
+ leaveHandshake: () => leaveHandshake,
46
+ mergeRules: () => mergeRules,
47
+ startHandshake: () => startHandshake
48
+ });
49
+ module.exports = __toCommonJS(spatial_exports);
50
+
51
+ // src/spatial/types.ts
52
+ var DEFAULT_ZONE_RULES = {
53
+ camera: "allowed",
54
+ microphone: "allowed",
55
+ aiDataSend: "allowed",
56
+ aiActions: "allowed",
57
+ aiRecommendations: "allowed",
58
+ locationSharing: "allowed",
59
+ aiOverlay: "allowed",
60
+ dataRetention: "allowed",
61
+ commercialAI: "allowed",
62
+ bystanderProtection: "standard"
63
+ };
64
+ var DEFAULT_PARTICIPANT_CONSTRAINTS = {
65
+ cameraMinimum: "allowed",
66
+ microphoneMinimum: "allowed",
67
+ aiDataSendMinimum: "allowed",
68
+ aiRecommendationsMinimum: "allowed",
69
+ dataRetentionMinimum: "allowed",
70
+ bystanderProtectionMinimum: "standard"
71
+ };
72
+
73
+ // src/spatial/engine.ts
74
+ var CAMERA_ORDER = ["allowed", "confirm_each", "blocked"];
75
+ var MIC_ORDER = ["allowed", "confirm_each", "blocked"];
76
+ var AI_DATA_ORDER = ["allowed", "declared_only", "confirm_each", "blocked"];
77
+ var AI_ACTION_ORDER = ["allowed", "confirm_all", "blocked"];
78
+ var AI_REC_ORDER = ["allowed", "non_commercial", "blocked"];
79
+ var LOCATION_ORDER = ["allowed", "confirm_each", "blocked"];
80
+ var OVERLAY_ORDER = ["allowed", "non_obstructive", "blocked"];
81
+ var RETENTION_ORDER = ["allowed", "session_only", "blocked"];
82
+ var COMMERCIAL_ORDER = ["allowed", "blocked"];
83
+ var BYSTANDER_ORDER = ["standard", "elevated", "strict"];
84
+ function mostRestrictive(a, b, order) {
85
+ const idxA = order.indexOf(a);
86
+ const idxB = order.indexOf(b);
87
+ return idxA >= idxB ? a : b;
88
+ }
89
+ function mergeRules(a, b) {
90
+ return {
91
+ camera: mostRestrictive(a.camera, b.camera, CAMERA_ORDER),
92
+ microphone: mostRestrictive(a.microphone, b.microphone, MIC_ORDER),
93
+ aiDataSend: mostRestrictive(a.aiDataSend, b.aiDataSend, AI_DATA_ORDER),
94
+ aiActions: mostRestrictive(a.aiActions, b.aiActions, AI_ACTION_ORDER),
95
+ aiRecommendations: mostRestrictive(a.aiRecommendations, b.aiRecommendations, AI_REC_ORDER),
96
+ locationSharing: mostRestrictive(a.locationSharing, b.locationSharing, LOCATION_ORDER),
97
+ aiOverlay: mostRestrictive(a.aiOverlay, b.aiOverlay, OVERLAY_ORDER),
98
+ dataRetention: mostRestrictive(a.dataRetention, b.dataRetention, RETENTION_ORDER),
99
+ commercialAI: mostRestrictive(a.commercialAI, b.commercialAI, COMMERCIAL_ORDER),
100
+ bystanderProtection: mostRestrictive(a.bystanderProtection, b.bystanderProtection, BYSTANDER_ORDER),
101
+ custom: [...a.custom ?? [], ...b.custom ?? []]
102
+ };
103
+ }
104
+ function constraintsToRules(c) {
105
+ return {
106
+ ...DEFAULT_ZONE_RULES,
107
+ camera: c.cameraMinimum,
108
+ microphone: c.microphoneMinimum,
109
+ aiDataSend: c.aiDataSendMinimum,
110
+ aiRecommendations: c.aiRecommendationsMinimum,
111
+ dataRetention: c.dataRetentionMinimum,
112
+ bystanderProtection: c.bystanderProtectionMinimum
113
+ };
114
+ }
115
+ function createOptIn(zone, userOverrides = {}, method = "tap_confirm") {
116
+ const sessionId = `spatial-${zone.zoneId}-${Date.now()}`;
117
+ const overrideRules = {
118
+ ...DEFAULT_ZONE_RULES,
119
+ ...userOverrides
120
+ };
121
+ const effectiveRules = mergeRules(zone.rules, overrideRules);
122
+ return {
123
+ zoneId: zone.zoneId,
124
+ optedInAt: Date.now(),
125
+ method,
126
+ acceptedRules: zone.rules,
127
+ userOverrides,
128
+ effectiveRules,
129
+ sessionId
130
+ };
131
+ }
132
+ function startHandshake(initiator, initiatorId, zoneId) {
133
+ const handshakeId = `handshake-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
134
+ const now = Date.now();
135
+ const participant = {
136
+ participantId: initiatorId,
137
+ publishedConstraints: initiator,
138
+ joinedAt: now,
139
+ acknowledged: true
140
+ };
141
+ return {
142
+ handshakeId,
143
+ participants: [participant],
144
+ negotiatedRules: constraintsToRules(initiator),
145
+ zoneId,
146
+ createdAt: now,
147
+ lastNegotiatedAt: now,
148
+ state: "active"
149
+ };
150
+ }
151
+ function joinHandshake(handshake, constraints, participantId) {
152
+ const now = Date.now();
153
+ const newParticipant = {
154
+ participantId,
155
+ publishedConstraints: constraints,
156
+ joinedAt: now,
157
+ acknowledged: false
158
+ };
159
+ const participants = [...handshake.participants, newParticipant];
160
+ const negotiatedRules = negotiateHandshake(participants);
161
+ return {
162
+ ...handshake,
163
+ participants,
164
+ negotiatedRules,
165
+ lastNegotiatedAt: now
166
+ };
167
+ }
168
+ function leaveHandshake(handshake, participantId) {
169
+ const participants = handshake.participants.filter(
170
+ (p) => p.participantId !== participantId
171
+ );
172
+ if (participants.length < 2) {
173
+ return {
174
+ ...handshake,
175
+ participants,
176
+ state: "dissolved",
177
+ lastNegotiatedAt: Date.now(),
178
+ negotiatedRules: participants.length === 1 ? constraintsToRules(participants[0].publishedConstraints) : DEFAULT_ZONE_RULES
179
+ };
180
+ }
181
+ return {
182
+ ...handshake,
183
+ participants,
184
+ negotiatedRules: negotiateHandshake(participants),
185
+ lastNegotiatedAt: Date.now()
186
+ };
187
+ }
188
+ function negotiateHandshake(participants) {
189
+ if (participants.length === 0) return DEFAULT_ZONE_RULES;
190
+ let result = constraintsToRules(participants[0].publishedConstraints);
191
+ for (let i = 1; i < participants.length; i++) {
192
+ const participantRules = constraintsToRules(participants[i].publishedConstraints);
193
+ result = mergeRules(result, participantRules);
194
+ }
195
+ return result;
196
+ }
197
+ function createSession() {
198
+ return {
199
+ sessionId: `session-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
200
+ effectiveRules: DEFAULT_ZONE_RULES,
201
+ state: "discovering",
202
+ startedAt: Date.now(),
203
+ endedAt: null,
204
+ events: []
205
+ };
206
+ }
207
+ function applyZoneToSession(session, zone, optIn) {
208
+ const event = {
209
+ type: "zone_opted_in",
210
+ zoneId: zone.zoneId,
211
+ timestamp: Date.now()
212
+ };
213
+ const baseRules = session.handshake ? session.handshake.negotiatedRules : DEFAULT_ZONE_RULES;
214
+ const effectiveRules = mergeRules(baseRules, optIn.effectiveRules);
215
+ return {
216
+ ...session,
217
+ zone,
218
+ optIn,
219
+ effectiveRules,
220
+ state: session.handshake ? "handshake_active" : "opted_in",
221
+ events: [...session.events, event]
222
+ };
223
+ }
224
+ function applyHandshakeToSession(session, handshake) {
225
+ const event = {
226
+ type: "handshake_negotiated",
227
+ handshakeId: handshake.handshakeId,
228
+ timestamp: Date.now()
229
+ };
230
+ const baseRules = session.optIn ? session.optIn.effectiveRules : DEFAULT_ZONE_RULES;
231
+ const effectiveRules = mergeRules(baseRules, handshake.negotiatedRules);
232
+ return {
233
+ ...session,
234
+ handshake,
235
+ effectiveRules,
236
+ state: "handshake_active",
237
+ events: [...session.events, event]
238
+ };
239
+ }
240
+ function exitZone(session) {
241
+ if (!session.zone) return session;
242
+ const event = {
243
+ type: "zone_exited",
244
+ zoneId: session.zone.zoneId,
245
+ timestamp: Date.now()
246
+ };
247
+ const effectiveRules = session.handshake ? session.handshake.negotiatedRules : DEFAULT_ZONE_RULES;
248
+ return {
249
+ ...session,
250
+ zone: void 0,
251
+ optIn: void 0,
252
+ effectiveRules,
253
+ state: session.handshake ? "handshake_active" : "discovering",
254
+ events: [...session.events, event]
255
+ };
256
+ }
257
+ function endSession(session) {
258
+ return {
259
+ ...session,
260
+ state: "ended",
261
+ endedAt: Date.now(),
262
+ effectiveRules: DEFAULT_ZONE_RULES
263
+ };
264
+ }
265
+ var INTENT_TO_RULE = {
266
+ // Camera intents
267
+ "photo_capture": "camera",
268
+ "stream_start": "camera",
269
+ "restream_start": "camera",
270
+ // Microphone intents
271
+ "transcription_start": "microphone",
272
+ "translation_start": "microphone",
273
+ "phone_passthrough_start": "microphone",
274
+ // AI data intents
275
+ "ai_send_transcription": "aiDataSend",
276
+ "ai_send_image": "aiDataSend",
277
+ "ai_send_location": "aiDataSend",
278
+ // AI action intents
279
+ "ai_auto_action": "aiActions",
280
+ "ai_auto_purchase": "aiActions",
281
+ "ai_auto_respond_message": "aiActions",
282
+ // AI overlay intents
283
+ "display_text_wall": "aiOverlay",
284
+ "display_double_text_wall": "aiOverlay",
285
+ "display_image": "aiOverlay",
286
+ // Data retention
287
+ "ai_retain_session_data": "dataRetention",
288
+ // Location
289
+ "location_get_current": "locationSharing",
290
+ "location_start_tracking": "locationSharing",
291
+ // Third-party sharing
292
+ "ai_share_with_third_party": "aiDataSend"
293
+ };
294
+ function evaluateSpatial(intent, session) {
295
+ const ruleKey = INTENT_TO_RULE[intent];
296
+ if (!ruleKey) {
297
+ return {
298
+ allowed: true,
299
+ requiresConfirmation: false,
300
+ blockedBy: "none",
301
+ reason: "Intent not governed by spatial rules",
302
+ rule: "none"
303
+ };
304
+ }
305
+ const effectiveValue = session.effectiveRules[ruleKey];
306
+ if (effectiveValue === "blocked") {
307
+ const zoneBlocks = session.zone && session.optIn?.effectiveRules[ruleKey] === "blocked";
308
+ const handshakeBlocks = session.handshake && session.handshake.negotiatedRules[ruleKey] === "blocked";
309
+ let blockedBy = "none";
310
+ if (zoneBlocks && handshakeBlocks) blockedBy = "zone+handshake";
311
+ else if (zoneBlocks) blockedBy = "zone";
312
+ else if (handshakeBlocks) blockedBy = "handshake";
313
+ const source = blockedBy === "zone" ? `zone "${session.zone?.name}"` : blockedBy === "handshake" ? `handshake (${session.handshake?.participants.length} participants)` : blockedBy === "zone+handshake" ? `zone "${session.zone?.name}" + handshake` : "spatial rules";
314
+ return {
315
+ allowed: false,
316
+ requiresConfirmation: false,
317
+ blockedBy,
318
+ reason: `${intent} blocked by ${source}: ${ruleKey} = blocked`,
319
+ rule: ruleKey
320
+ };
321
+ }
322
+ if (effectiveValue === "confirm_each" || effectiveValue === "confirm_all" || effectiveValue === "non_obstructive" || effectiveValue === "non_commercial" || effectiveValue === "session_only" || effectiveValue === "declared_only") {
323
+ return {
324
+ allowed: false,
325
+ requiresConfirmation: true,
326
+ blockedBy: "none",
327
+ reason: `${intent} requires confirmation: ${ruleKey} = ${effectiveValue}`,
328
+ rule: ruleKey
329
+ };
330
+ }
331
+ return {
332
+ allowed: true,
333
+ requiresConfirmation: false,
334
+ blockedBy: "none",
335
+ reason: `${intent} allowed by spatial rules`,
336
+ rule: ruleKey
337
+ };
338
+ }
339
+ function activateEmergencyOverride(session) {
340
+ const event = {
341
+ type: "zone_exited",
342
+ zoneId: session.zone?.zoneId ?? "emergency",
343
+ timestamp: Date.now()
344
+ };
345
+ return {
346
+ ...session,
347
+ effectiveRules: DEFAULT_ZONE_RULES,
348
+ // Everything allowed
349
+ state: "active",
350
+ events: [...session.events, event]
351
+ };
352
+ }
353
+ function evaluateSpatialEmergency(_intent) {
354
+ return {
355
+ allowed: true,
356
+ requiresConfirmation: false,
357
+ blockedBy: "none",
358
+ reason: "Emergency override active \u2014 all spatial rules bypassed",
359
+ rule: "emergency"
360
+ };
361
+ }
362
+ var ZONE_TEMPLATES = {
363
+ /** Coffee shop — relaxed, but no recording without asking */
364
+ cafe: {
365
+ ...DEFAULT_ZONE_RULES,
366
+ camera: "confirm_each",
367
+ microphone: "allowed",
368
+ aiRecommendations: "non_commercial",
369
+ bystanderProtection: "elevated"
370
+ },
371
+ /** Hospital — strict, PHI-aware, no unauthorized recording */
372
+ healthcare: {
373
+ ...DEFAULT_ZONE_RULES,
374
+ camera: "blocked",
375
+ microphone: "confirm_each",
376
+ aiDataSend: "confirm_each",
377
+ aiActions: "blocked",
378
+ aiRecommendations: "blocked",
379
+ locationSharing: "blocked",
380
+ dataRetention: "blocked",
381
+ commercialAI: "blocked",
382
+ bystanderProtection: "strict"
383
+ },
384
+ /** Retail store — allow browsing AI, block price surveillance */
385
+ retail: {
386
+ ...DEFAULT_ZONE_RULES,
387
+ camera: "confirm_each",
388
+ aiRecommendations: "non_commercial",
389
+ commercialAI: "blocked",
390
+ bystanderProtection: "elevated"
391
+ },
392
+ /** Office / workplace — allow productivity AI, restrict recording */
393
+ workplace: {
394
+ ...DEFAULT_ZONE_RULES,
395
+ camera: "blocked",
396
+ microphone: "confirm_each",
397
+ aiDataSend: "declared_only",
398
+ dataRetention: "session_only",
399
+ bystanderProtection: "elevated"
400
+ },
401
+ /** Concert / live event — no recording, no streaming */
402
+ entertainment: {
403
+ ...DEFAULT_ZONE_RULES,
404
+ camera: "blocked",
405
+ microphone: "blocked",
406
+ aiOverlay: "non_obstructive",
407
+ dataRetention: "blocked",
408
+ bystanderProtection: "strict"
409
+ },
410
+ /** Library / museum — quiet, no recording, non-obstructive only */
411
+ education: {
412
+ ...DEFAULT_ZONE_RULES,
413
+ camera: "blocked",
414
+ microphone: "blocked",
415
+ aiOverlay: "non_obstructive",
416
+ aiRecommendations: "non_commercial",
417
+ commercialAI: "blocked",
418
+ bystanderProtection: "elevated"
419
+ },
420
+ /** Religious space — absolute privacy and respect */
421
+ religious: {
422
+ ...DEFAULT_ZONE_RULES,
423
+ camera: "blocked",
424
+ microphone: "blocked",
425
+ aiDataSend: "blocked",
426
+ aiActions: "blocked",
427
+ aiRecommendations: "blocked",
428
+ aiOverlay: "blocked",
429
+ dataRetention: "blocked",
430
+ commercialAI: "blocked",
431
+ bystanderProtection: "strict"
432
+ },
433
+ /** Home — fully permissive (user's own space) */
434
+ home: {
435
+ ...DEFAULT_ZONE_RULES
436
+ },
437
+ /** Public transit — moderate restrictions */
438
+ transit: {
439
+ ...DEFAULT_ZONE_RULES,
440
+ camera: "confirm_each",
441
+ microphone: "allowed",
442
+ bystanderProtection: "elevated"
443
+ }
444
+ };
445
+
446
+ // src/spatial/zones/example-zones.ts
447
+ var BLUE_BOTTLE_HAYES = {
448
+ zoneId: "zone-bluebottle-hayes-001",
449
+ name: "Blue Bottle Coffee \u2014 Hayes Valley",
450
+ publisher: {
451
+ name: "Blue Bottle Coffee",
452
+ type: "business",
453
+ verified: true
454
+ },
455
+ rules: {
456
+ ...ZONE_TEMPLATES.cafe,
457
+ // Blue Bottle addition: no AI product recommendations (respect the craft)
458
+ custom: [{
459
+ id: "no-product-recs",
460
+ description: "No AI-generated product recommendations in our space",
461
+ targetIntent: "ai_recommend_product",
462
+ effect: "block",
463
+ rationale: "We curate our own experience. Ask our baristas, not your AI."
464
+ }]
465
+ },
466
+ discovery: { method: "auki_anchor", anchorId: "auki-bb-hayes-001", confidence: 0.95 },
467
+ type: "hospitality",
468
+ requiresOptIn: false,
469
+ rationale: "A coffee shop where people work, talk, and think. We protect the vibe and the people in it.",
470
+ rulesUpdatedAt: Date.now(),
471
+ version: "1.0.0"
472
+ };
473
+ var UCSF_MEDICAL = {
474
+ zoneId: "zone-ucsf-medical-001",
475
+ name: "UCSF Medical Center \u2014 Main Campus",
476
+ publisher: {
477
+ name: "UCSF Health",
478
+ type: "institution",
479
+ verified: true
480
+ },
481
+ rules: {
482
+ ...ZONE_TEMPLATES.healthcare,
483
+ custom: [
484
+ {
485
+ id: "phi-in-network",
486
+ description: "No patient health information may be sent to AI providers outside the UCSF network",
487
+ targetIntent: "ai_send_transcription",
488
+ effect: "block",
489
+ rationale: "HIPAA compliance. PHI stays in-network."
490
+ },
491
+ {
492
+ id: "no-clinical-ai-action",
493
+ description: "AI cannot take autonomous clinical actions",
494
+ targetIntent: "ai_auto_action",
495
+ effect: "block",
496
+ rationale: "Clinical decisions require licensed physician confirmation."
497
+ }
498
+ ]
499
+ },
500
+ discovery: { method: "ble_beacon", beaconId: "ucsf-main-lobby-001", rssi: -65 },
501
+ type: "healthcare",
502
+ requiresOptIn: true,
503
+ rationale: "A hospital where patients, families, and staff deserve absolute privacy. Recording is prohibited. AI actions require clinical oversight. Patient data never leaves our network.",
504
+ rulesUpdatedAt: Date.now(),
505
+ version: "2.0.0"
506
+ };
507
+ var APPLE_UNION_SQUARE = {
508
+ zoneId: "zone-apple-unisonq-001",
509
+ name: "Apple Union Square",
510
+ publisher: {
511
+ name: "Apple Inc.",
512
+ type: "business",
513
+ verified: true
514
+ },
515
+ rules: {
516
+ ...ZONE_TEMPLATES.retail,
517
+ camera: "blocked",
518
+ // No photos of displays / unreleased products
519
+ custom: [
520
+ {
521
+ id: "no-price-comparison",
522
+ description: "No AI-powered real-time price comparison while in store",
523
+ targetIntent: "ai_compare_prices",
524
+ effect: "block",
525
+ rationale: "Respect our retail experience. Compare prices on your own time."
526
+ },
527
+ {
528
+ id: "no-product-scanning",
529
+ description: "No AI scanning of unreleased or display products",
530
+ targetIntent: "ai_send_image",
531
+ effect: "block",
532
+ rationale: "Display products may include unreleased items under NDA."
533
+ }
534
+ ]
535
+ },
536
+ discovery: { method: "ble_beacon", beaconId: "apple-usq-main-001", rssi: -60 },
537
+ type: "retail",
538
+ requiresOptIn: false,
539
+ rationale: "A retail experience designed to be explored in person. No AI product scanning, no real-time price comparison, no unauthorized recording of displays.",
540
+ rulesUpdatedAt: Date.now(),
541
+ version: "1.0.0"
542
+ };
543
+ var CHASE_CENTER = {
544
+ zoneId: "zone-chase-center-001",
545
+ name: "Chase Center",
546
+ publisher: {
547
+ name: "Chase Center / GSW",
548
+ type: "business",
549
+ verified: true
550
+ },
551
+ rules: {
552
+ ...ZONE_TEMPLATES.entertainment,
553
+ custom: [{
554
+ id: "no-event-recording",
555
+ description: "No audio or video recording of live performances",
556
+ targetIntent: "stream_start",
557
+ effect: "block",
558
+ rationale: "Live performance rights. Recording violates artist/league agreements."
559
+ }]
560
+ },
561
+ discovery: { method: "geofence", lat: 37.768, lng: -122.3877, radiusMeters: 200 },
562
+ type: "entertainment",
563
+ requiresOptIn: true,
564
+ rationale: "A live event venue. No recording of performances. No streaming. AR overlays must not obstruct the live experience. Strict bystander protection for 18,000+ attendees.",
565
+ rulesUpdatedAt: Date.now(),
566
+ version: "1.0.0"
567
+ };
568
+ var WEWORK_SOMA = {
569
+ zoneId: "zone-wework-soma-001",
570
+ name: "WeWork \u2014 SoMa",
571
+ publisher: {
572
+ name: "WeWork",
573
+ type: "business",
574
+ verified: true
575
+ },
576
+ rules: {
577
+ ...ZONE_TEMPLATES.workplace,
578
+ aiDataSend: "allowed",
579
+ // Productivity AI is the whole point
580
+ aiOverlay: "allowed",
581
+ // AR workspace tools welcome
582
+ custom: [{
583
+ id: "no-competitor-intel",
584
+ description: "No AI analysis of other tenants' visible screens or conversations",
585
+ targetIntent: "ai_send_image",
586
+ effect: "confirm",
587
+ rationale: "Shared workspace. Respect other tenants' IP and privacy."
588
+ }]
589
+ },
590
+ discovery: { method: "auki_anchor", anchorId: "auki-wework-soma-floor3", confidence: 0.92 },
591
+ type: "workplace",
592
+ requiresOptIn: false,
593
+ rationale: "A shared workspace where productivity AI is welcome but recording is restricted. Other tenants' work is their own \u2014 no AI should analyze it.",
594
+ rulesUpdatedAt: Date.now(),
595
+ version: "1.0.0"
596
+ };
597
+ var SFMOMA = {
598
+ zoneId: "zone-sfmoma-001",
599
+ name: "SFMOMA",
600
+ publisher: {
601
+ name: "San Francisco Museum of Modern Art",
602
+ type: "institution",
603
+ verified: true
604
+ },
605
+ rules: {
606
+ ...ZONE_TEMPLATES.education,
607
+ aiRecommendations: "allowed",
608
+ // "Tell me about this painting" is great
609
+ aiDataSend: "declared_only",
610
+ // AI art analysis is part of the experience
611
+ custom: [{
612
+ id: "no-flash-no-stream",
613
+ description: "No flash photography or live streaming of exhibitions",
614
+ targetIntent: "stream_start",
615
+ effect: "block",
616
+ rationale: "Protect the art and the experience of other visitors."
617
+ }]
618
+ },
619
+ discovery: { method: "nfc_tap", tagId: "sfmoma-entrance-nfc-001" },
620
+ type: "education",
621
+ requiresOptIn: false,
622
+ rationale: "A museum where AI can enhance the art experience (tell me about this piece) but recording and streaming are prohibited. No commercial AI recommendations.",
623
+ rulesUpdatedAt: Date.now(),
624
+ version: "1.0.0"
625
+ };
626
+ var MY_HOME = {
627
+ zoneId: "zone-home-user-001",
628
+ name: "Home",
629
+ publisher: {
630
+ name: "You",
631
+ type: "individual",
632
+ verified: false
633
+ },
634
+ rules: {
635
+ ...ZONE_TEMPLATES.home
636
+ // Home is your space — fully permissive by default
637
+ // You can tighten it if you want (e.g., "no AI recording when guests are over")
638
+ },
639
+ discovery: { method: "geofence", lat: 37.7749, lng: -122.4194, radiusMeters: 50 },
640
+ type: "residential",
641
+ requiresOptIn: false,
642
+ rationale: "Your home. Your rules. Everything is allowed by default. Tighten as needed.",
643
+ rulesUpdatedAt: Date.now(),
644
+ version: "1.0.0"
645
+ };
646
+ var EXAMPLE_ZONES = [
647
+ BLUE_BOTTLE_HAYES,
648
+ UCSF_MEDICAL,
649
+ APPLE_UNION_SQUARE,
650
+ CHASE_CENTER,
651
+ WEWORK_SOMA,
652
+ SFMOMA,
653
+ MY_HOME
654
+ ];
655
+ // Annotate the CommonJS export names for ESM import in node:
656
+ 0 && (module.exports = {
657
+ APPLE_UNION_SQUARE,
658
+ BLUE_BOTTLE_HAYES,
659
+ CHASE_CENTER,
660
+ DEFAULT_PARTICIPANT_CONSTRAINTS,
661
+ DEFAULT_ZONE_RULES,
662
+ EXAMPLE_ZONES,
663
+ MY_HOME,
664
+ SFMOMA,
665
+ UCSF_MEDICAL,
666
+ WEWORK_SOMA,
667
+ ZONE_TEMPLATES,
668
+ activateEmergencyOverride,
669
+ applyHandshakeToSession,
670
+ applyZoneToSession,
671
+ constraintsToRules,
672
+ createOptIn,
673
+ createSession,
674
+ endSession,
675
+ evaluateSpatial,
676
+ evaluateSpatialEmergency,
677
+ exitZone,
678
+ joinHandshake,
679
+ leaveHandshake,
680
+ mergeRules,
681
+ startHandshake
682
+ });