arcane-os 0.5.9 → 0.5.11

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 (55) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +117 -26
  3. package/browser-runtime/ai/browser-speech-providers.mjs +1 -1
  4. package/browser-runtime/ai/browser-wasm-llm-provider.mjs +63 -39
  5. package/docs/architecture.md +303 -0
  6. package/docs/compatibility.md +38 -0
  7. package/docs/event-manager.md +263 -0
  8. package/docs/platform-targets.md +104 -0
  9. package/docs/publishing.md +126 -0
  10. package/docs/reference/README.md +206 -0
  11. package/docs/reference/ai/browser-speech.md +813 -0
  12. package/docs/reference/ai/browser-wasm.md +637 -0
  13. package/docs/reference/ai/twin-cloud.md +156 -0
  14. package/docs/reference/arcane-ollama.md +288 -0
  15. package/docs/reference/availability-and-normalization.md +224 -0
  16. package/docs/reference/behavioral-testing.md +129 -0
  17. package/docs/reference/cli.md +820 -0
  18. package/docs/reference/core/README.md +61 -0
  19. package/docs/reference/core/arcane-ai-contracts.md +907 -0
  20. package/docs/reference/core/arcane-api.md +601 -0
  21. package/docs/reference/core/arcane-entities.md +59 -0
  22. package/docs/reference/core/arcane-events.md +134 -0
  23. package/docs/reference/core/ollama-module.md +181 -0
  24. package/docs/reference/core/reference/arcane-api/ai-and-ollama.md +1909 -0
  25. package/docs/reference/core/reference/arcane-api/applications-terminal-capabilities.md +1057 -0
  26. package/docs/reference/core/reference/arcane-api/core-and-events.md +320 -0
  27. package/docs/reference/core/reference/arcane-api/filesystem-storage-preferences-appearance.md +610 -0
  28. package/docs/reference/core/reference/arcane-api/namespaces.md +1157 -0
  29. package/docs/reference/core/reference/arcane-api/platform-installation-users-system.md +1423 -0
  30. package/docs/reference/core/reference/arcane-api/session-provisioning-diagnostics-development.md +315 -0
  31. package/docs/reference/event-manager.md +1409 -0
  32. package/docs/reference/inventory/package-api.json +3194 -0
  33. package/docs/reference/inventory/runtime-components.json +1015 -0
  34. package/docs/reference/inventory/runtime-entities.json +25 -0
  35. package/docs/reference/inventory/runtime-modules.json +1367 -0
  36. package/docs/reference/mail.md +309 -0
  37. package/docs/reference/protocols.md +749 -0
  38. package/docs/reference/runtime-components.md +1529 -0
  39. package/docs/reference/runtime-entities.md +305 -0
  40. package/docs/reference/runtime-modules.md +3275 -0
  41. package/docs/reference/sdk-api.md +6733 -0
  42. package/docs/roadmap.md +79 -0
  43. package/docs/work-amplification.md +66 -0
  44. package/examples/wasm-ai-demo/README.md +80 -0
  45. package/examples/wasm-ai-demo/app.js +787 -0
  46. package/examples/wasm-ai-demo/index.html +343 -0
  47. package/examples/wasm-ai-demo/profile-tools.js +217 -0
  48. package/examples/wasm-ai-demo/profiles/BOSS.Modelfile +106 -0
  49. package/examples/wasm-ai-demo/profiles/PreCrisis.Modelfile +693 -0
  50. package/examples/wasm-ai-demo/rag/boss-library.json +3006 -0
  51. package/examples/wasm-ai-demo/rag.js +295 -0
  52. package/examples/wasm-ai-demo/server.mjs +71 -0
  53. package/package.json +11 -2
  54. package/runtime/arcane/modules/AI.js +1 -1
  55. package/runtime/arcane/modules/AIProviderRuntime.js +26 -5
@@ -0,0 +1,1409 @@
1
+ # EventManager and time-travel diagnostics
2
+
3
+ `arcaneEvents` gives Arcane SDK publishers one canonical synchronous event
4
+ authority per JavaScript realm. `EventManager` remains the constructor for an
5
+ isolated strict pub/sub bus and optional complete diagnostic timeline. Use source
6
+ handles for SDK semantic events; use isolated managers for local diagnostics,
7
+ DOM capture, export, and review.
8
+
9
+ The API is capability-first:
10
+
11
+ - ordinary pub/sub works in Node and browser JavaScript;
12
+ - duplicate module URLs reuse a `globalThis.arcaneEvents` value with the current
13
+ protocol and required callable API;
14
+ - canonical occurrences expose complete mutable normalized detail;
15
+ - source listeners receive a shallow copy of caller detail while occurrences and
16
+ diagnostic history receive a normalized copy;
17
+ - recording creates mutable, normalized `arcane-event-stack/1` records;
18
+ - browser DOM capture is opt-in and preserves readable observed content;
19
+ - review playback is safe by default; live event redispatch is explicitly effectful;
20
+ - no event stack is uploaded, persisted, bridged to Core, or sent to a cloud service
21
+ automatically.
22
+
23
+ All 31 JavaScript exports are available from both `arcane-os` and
24
+ `arcane-os/event-manager`. The bindings are identical, so choose the focused
25
+ subpath when event instrumentation is the only SDK capability you need. Node
26
+ can resolve either package entrypoint. The generated browser map intentionally
27
+ exposes only the focused `arcane-os/event-manager` entry, not the Node package
28
+ root.
29
+
30
+ ## Quick start
31
+
32
+ ```javascript
33
+ import {
34
+ arcaneEvents,
35
+ createArcaneEventSource,
36
+ createEventManager,
37
+ projectArcaneDOMEvent,
38
+ PLAYBACK_RECORD_EVENT
39
+ } from 'arcane-os/event-manager';
40
+
41
+ const events=createArcaneEventSource(editorController,{
42
+ source:'app.editor',
43
+ eventTypes:['document.save.completed']
44
+ });
45
+
46
+ const unsubscribe=arcaneEvents.subscribe('document.save.completed',occurrence=>{
47
+ console.info('Saved',occurrence.detail.documentId);
48
+ });
49
+
50
+ const publication=events.dispatch(
51
+ 'document.save.completed',
52
+ {documentId:'example',document:liveDocument},
53
+ {operationId:'save-42',publicDetail:{documentId:'example'}}
54
+ );
55
+ projectArcaneDOMEvent(editorElement,publication.occurrence);
56
+ unsubscribe();
57
+
58
+ const diagnostics=createEventManager({timeTravel:true});
59
+ const stack=diagnostics.exportStack();
60
+ diagnostics.on(PLAYBACK_RECORD_EVENT,record=>console.info(record.type));
61
+ await diagnostics.playback({stack,mode:'review',speed:0});
62
+ ```
63
+
64
+ Recording is disabled by default. Export intentionally, then call
65
+ `clearHistory()` when the retained history is no longer needed.
66
+
67
+ ## Availability and normalization
68
+
69
+ | Capability | Node | Browser renderer | Native/Core host | Remote or cloud | Normalization |
70
+ | --- | --- | --- | --- | --- | --- |
71
+ | Canonical per-realm authority and source occurrences | Yes | Yes, per window or worker realm | Only when the SDK module runs in that JavaScript realm | No automatic transport | `arcane-event-authority/1`, `arcane-event-source/1`, and `arcane-event-occurrence/1` |
72
+ | Pub/sub, semantic instrumentation, parse/export, seek, playback | Yes | Yes, through a bundler or the managed Arcane import map | Only when the SDK module runs in that JavaScript host | No automatic transport | Same synchronous API; optional complete JSON-like snapshots |
73
+ | DOM selectors and target descriptions | With DOM-like values or a test shim | Yes | No native UI observation | No | Stable diagnostic descriptors |
74
+ | DOM interaction and mutation capture | No native DOM | Yes | No | No | DOM activity becomes semantic event-stack records |
75
+ | Event-stack schema | Yes | Yes | Data contract only | Can be transported explicitly by the developer | `arcane-event-stack/1` |
76
+
77
+ In an external or integrated workspace, the managed browser map
78
+ resolves `arcane-os/event-manager` to
79
+ `./arcane/sdk/event-manager.mjs` and its private bare dependency
80
+ `event-pubsub` to
81
+ `./arcane/sdk/dependencies/event-pubsub/index.js`. The selected Arcane browser
82
+ runtime does not inject this SDK-authored module into
83
+ Shell, Provisioner, Core, or built-in apps. There is no transparent fallback to
84
+ the Node package root, `arcane/1`, HTTP, WebSocket, Ollama, or a cloud event
85
+ service.
86
+
87
+ ## Export summary
88
+
89
+ | Export | Kind | Primary capability |
90
+ | --- | --- | --- |
91
+ | `ARCANE_EVENT_STACK_PROTOCOL` | String constant | Identify the durable stack format |
92
+ | `ARCANE_EVENT_AUTHORITY_PROTOCOL` | String constant | Identify the singleton authority protocol |
93
+ | `ARCANE_EVENT_OCCURRENCE_PROTOCOL` | String constant | Identify canonical occurrences |
94
+ | `ARCANE_EVENT_SOURCE_PROTOCOL` | String constant | Identify source handles |
95
+ | `ARCANE_EVENT_AUTHORITY_BRAND` | Global symbol | Inspect the authority brand descriptor |
96
+ | `ARCANE_EVENT_AUTHORITY_KIND` | String constant | Identify an authority descriptor |
97
+ | `ARCANE_EVENT_SOURCE_KIND` | String constant | Identify a source descriptor |
98
+ | `ARCANE_EVENT_LISTENER_ERROR_EVENT` | String constant | Observe listener failures |
99
+ | `ARCANE_EVENT_SOURCE_DISPOSED_EVENT` | String constant | Observe a source's final occurrence |
100
+ | `ARCANE_EVENT_ERROR_CODES` | Object | Match authority error codes |
101
+ | `TIME_TRAVEL_SEEK_EVENT` | String constant | Observe review-cursor movement |
102
+ | `PLAYBACK_STARTED_EVENT` | String constant | Observe playback startup |
103
+ | `PLAYBACK_RECORD_EVENT` | String constant | Receive safe review records |
104
+ | `PLAYBACK_COMPLETED_EVENT` | String constant | Observe successful completion |
105
+ | `PLAYBACK_CANCELLED_EVENT` | String constant | Observe cancellation |
106
+ | `PLAYBACK_FAILED_EVENT` | String constant | Observe playback failure |
107
+ | `DOM_INTERACTION_EVENT` | String constant | Identify normalized DOM interactions |
108
+ | `DOM_MUTATION_EVENT` | String constant | Identify normalized DOM mutations |
109
+ | `DOM_OBSERVATION_STARTED_EVENT` | String constant | Identify DOM-capture startup |
110
+ | `DOM_OBSERVATION_STOPPED_EVENT` | String constant | Identify DOM-capture shutdown |
111
+ | `DEFAULT_DOM_EVENT_TYPES` | String array | Use Arcane's default DOM capture set |
112
+ | `domSelector()` | Function | Build a diagnostic DOM locator |
113
+ | `describeDOMTarget()` | Function | Normalize a DOM event target |
114
+ | `createDOMInstrumentation()` | Function | Attach interaction and mutation capture |
115
+ | `parseEventStack()` | Function | Strictly import and normalize a stack |
116
+ | `EventManager` | Class | Create an isolated bus and timeline |
117
+ | `createEventManager()` | Function | Create an `EventManager` |
118
+ | `arcaneEvents` | Branded `EventManager` authority | Observe canonical SDK events in this realm |
119
+ | `createArcaneEventSource()` | Function | Register one declared semantic source per owner |
120
+ | `projectArcaneDOMEvent()` | Function | Project one occurrence to one `CustomEvent` |
121
+ | `isArcaneEventOccurrence()` | Function | Recognize authority-created occurrences and views |
122
+
123
+ ## `EventManager`
124
+
125
+ ### Overview
126
+
127
+ Creates an isolated synchronous `event-pubsub` bus. Time-travel recording,
128
+ snapshot capture, DOM observation, import/export, cursor movement, and
129
+ playback are layered around that bus.
130
+
131
+ ### Constructor
132
+
133
+ ```javascript
134
+ new EventManager({
135
+ timeTravel=false,
136
+ dom=null,
137
+ clock=()=>new Date(),
138
+ now=performance.now-or-Date.now,
139
+ sessionId=randomUUID-or-local-id
140
+ }={})
141
+ ```
142
+
143
+ `dom` may be a root directly or an options object containing `root`. Every
144
+ recorded string event attempts to capture its source stack. Snapshot
145
+ normalization retains complete readable values and represents cycles, special
146
+ values, and capture failures without applying content or retention limits.
147
+
148
+ ### Properties
149
+
150
+ | Property | Value |
151
+ | --- | --- |
152
+ | `list` | Underlying subscriber registry from `event-pubsub` |
153
+ | `sessionId` | Current non-empty session identifier |
154
+ | `timeTravelEnabled` | Whether new string-typed events are being recorded |
155
+ | `replaying` | Whether playback is active |
156
+ | `cursor` | Current sequence selected or delivered; `0` means before the first event |
157
+ | `eventCount` | Current retained record count |
158
+ | `history` | New array containing the current mutable record objects |
159
+ | `domInstrumentation` | Attached DOM controller or `null` |
160
+
161
+ ### Methods
162
+
163
+ #### `on(type, handler, once=false)`
164
+
165
+ Registers a synchronous handler and returns the manager.
166
+
167
+ #### `once(type, handler)`
168
+
169
+ Registers a synchronous one-shot handler and returns the manager.
170
+
171
+ #### `off(type='*', handler='*')`
172
+
173
+ Removes matching subscriptions and returns the manager.
174
+
175
+ #### `reset()`
176
+
177
+ Clears subscriptions and returns the manager. It does not clear recorded history.
178
+
179
+ #### `emit(type, ...payload)`
180
+
181
+ Synchronously delivers arbitrary payload arguments. String event types are
182
+ recorded while time travel is enabled. Non-string types are delivered without a
183
+ record. Subscriber exceptions are recorded as a failed dispatch and rethrown.
184
+ Subscriber promises are not awaited.
185
+
186
+ ```javascript
187
+ events.on('ready',(documentId,revision)=>console.info(documentId,revision));
188
+ events.emit('ready','document-7',3);
189
+ ```
190
+
191
+ #### `instrument(type, payload, metadata={})`
192
+
193
+ Delivers one semantic payload and records optional `source`, `category`,
194
+ `correlationId`, and `causationId` metadata.
195
+
196
+ ```javascript
197
+ events.instrument('sync.completed',{count:12},{
198
+ source:'app:library',
199
+ category:'operation',
200
+ correlationId:'sync-9'
201
+ });
202
+ ```
203
+
204
+ #### `forward(event, metadata={})`
205
+
206
+ Requires a non-array object with a string `type`, then instruments that object as
207
+ the event's single payload. SDK operation queues use this shape to mirror their
208
+ already-normalized events through `arcaneEvents` once.
209
+
210
+ #### `enableTimeTravel({dom}={})`
211
+
212
+ Enables recording and optionally attaches DOM capture.
213
+
214
+ #### `disableTimeTravel()`
215
+
216
+ Stops attached DOM capture, records its stopped lifecycle boundary, disables
217
+ recording, and returns the manager.
218
+
219
+ #### `attachDOM(root=globalThis.document, options={})`
220
+
221
+ Stops and replaces the current DOM controller. The new controller starts
222
+ immediately when recording is enabled. Returns the controller.
223
+
224
+ #### `detachDOM()`
225
+
226
+ Stops DOM capture, clears the controller, and returns the manager.
227
+
228
+ #### `clearHistory({newSession=true}={})`
229
+
230
+ Clears history, sequence, cursor, and active-dispatch state. By default it creates a new
231
+ session identifier; pass `newSession:false` to retain the existing identifier.
232
+ History cannot be cleared during synchronous dispatch or playback.
233
+
234
+ #### `getEventStack({fromSequence=1, toSequence=Number.MAX_SAFE_INTEGER, type=null}={})`
235
+
236
+ Returns a new mutable array of current record objects within the inclusive sequence range, optionally
237
+ restricted to one exact event type.
238
+
239
+ #### `exportStack({space=2}={})`
240
+
241
+ Returns a JSON document with the current session and retained history. `space`
242
+ must be a safe integer from 0 through 10. Export does not write a file, persist,
243
+ upload, or transmit anything.
244
+
245
+ #### `seek(sequence)`
246
+
247
+ Moves the review cursor to `0` or an existing sequence, emits
248
+ `TIME_TRAVEL_SEEK_EVENT`, and returns the selected record or `null` for zero.
249
+ Seeking never rewrites DOM, storage, native state, processes, or network state.
250
+
251
+ #### `playback(options={})`
252
+
253
+ ```javascript
254
+ await events.playback({
255
+ stack:null,
256
+ fromSequence:1,
257
+ toSequence:Number.MAX_SAFE_INTEGER,
258
+ speed:0,
259
+ mode:'review',
260
+ signal,
261
+ onRecord
262
+ });
263
+ ```
264
+
265
+ Only one playback may run at a time. `stack:null` uses current history; a string
266
+ or object is passed through `parseEventStack()`. Recording is suppressed during
267
+ playback.
268
+
269
+ | Mode | Behavior | Safety |
270
+ | --- | --- | --- |
271
+ | `review` | Emits every normalized record as `PLAYBACK_RECORD_EVENT` | Default; intended for debugger and timeline UIs |
272
+ | `events` | Redispatches `record.type` with the normalized payload arguments | Effectful; use only in an isolated harness |
273
+ | `none` | Emits no per-record bus event; only invokes `onRecord` | Useful for controlled analysis |
274
+
275
+ `speed:0` delivers immediately. A positive speed preserves recorded monotonic
276
+ delays, divided by the multiplier. `onRecord(record)` may be async and is awaited.
277
+ An `AbortSignal` cancels waiting or delivery; playback emits exactly one terminal
278
+ completed, cancelled, or failed lifecycle event, rejects on cancellation/failure,
279
+ and restores `replaying` in all cases.
280
+
281
+ ### Availability and normalization
282
+
283
+ The class is host-neutral JavaScript in Node and browser module graphs. DOM capture
284
+ requires a browser-compatible root. Event values are delivered to live subscribers
285
+ unchanged; only the optional historical copy is normalized.
286
+
287
+ ### Example
288
+
289
+ ```javascript
290
+ import {EventManager} from 'arcane-os/event-manager';
291
+
292
+ const events=new EventManager({timeTravel:true});
293
+ events.emit('workspace.opened',{workspaceId:'local-demo'});
294
+ console.info(events.history[0].status); // "completed"
295
+ events.clearHistory();
296
+ ```
297
+
298
+ ## `createEventManager()`
299
+
300
+ ### Overview
301
+
302
+ Convenience factory equivalent to `new EventManager(options)`.
303
+
304
+ ### Signature
305
+
306
+ ```javascript
307
+ createEventManager(options)
308
+ ```
309
+
310
+ ### Availability and normalization
311
+
312
+ Node and browser JavaScript; identical behavior to the constructor.
313
+
314
+ ### Example
315
+
316
+ ```javascript
317
+ import {createEventManager} from 'arcane-os/event-manager';
318
+ const events=createEventManager({timeTravel:true});
319
+ ```
320
+
321
+ ## `arcaneEvents`
322
+
323
+ ### Overview
324
+
325
+ The SDK's canonical per-realm event authority. Module evaluation reads
326
+ `globalThis.arcaneEvents` and reuses it when it exposes the current protocol and
327
+ required API. Otherwise it constructs and installs a new authority as a
328
+ non-enumerable, writable, configurable data property. Installation failure uses
329
+ the stable `ARCANE_EVENT_AUTHORITY_INSTALL_FAILED` code.
330
+
331
+ ### Value
332
+
333
+ ```javascript
334
+ globalThis.arcaneEvents === arcaneEvents
335
+ arcaneEvents.protocol === 'arcane-event-authority/1'
336
+ arcaneEvents[ARCANE_EVENT_AUTHORITY_BRAND] === 'arcane-event-authority/1'
337
+ ```
338
+
339
+ ### Availability and normalization
340
+
341
+ Exactly one authority per JavaScript realm. A window, worker, frame, Node realm,
342
+ or process has its own boundary. Nothing automatically transports occurrences
343
+ to another realm, Core, a native host, or a remote service.
344
+
345
+ `subscribe(type,handler,{once=false,signal}={})` observes one exact canonical
346
+ event type. `handler` is a function or EventListener object and receives the
347
+ canonical occurrence as its sole argument. The returned idempotent unsubscribe
348
+ has `unsubscribe.dispose === unsubscribe`. An already-aborted signal installs
349
+ nothing; later abort marks the listener inactive synchronously and removes it
350
+ without corrupting an in-progress dispatch. `'*'` is not a canonical subscription
351
+ type.
352
+
353
+ `createSource(owner,{source,eventTypes,onListenerError?})` is the authority
354
+ method used by the exported
355
+ `createArcaneEventSource(owner,{source,eventTypes,onListenerError?})` wrapper.
356
+ Both return the same mutable singleton-backed source handle; neither constructs
357
+ an EventManager, EventTarget, or component-local bus.
358
+
359
+ `addEventListener()` and `removeEventListener()` expose EventTarget-shaped
360
+ canonical registration, including function/EventListener-object callbacks,
361
+ type/listener/capture deduplication, `once`, and `signal`. They return
362
+ `undefined`.
363
+
364
+ The inherited `on`, `once`, `off`, `reset`, `emit`, `instrument`, and `forward`
365
+ surface supports direct diagnostics. Its registrations are separate: source
366
+ dispatch does not re-emit raw source-local detail to direct listeners, and
367
+ direct `off()`/`reset()` cannot remove canonical or source-owned
368
+ registrations. New SDK publishers use `createArcaneEventSource()`.
369
+
370
+ ### Example
371
+
372
+ ```javascript
373
+ import {arcaneEvents} from 'arcane-os/event-manager';
374
+
375
+ const unsubscribe=arcaneEvents.subscribe('sdk.operation.completed',occurrence=>{
376
+ console.info(occurrence.occurrenceId,occurrence.detail);
377
+ });
378
+ unsubscribe();
379
+ ```
380
+
381
+ ## `createArcaneEventSource()`
382
+
383
+ ### Overview
384
+
385
+ Registers one active semantic source for a non-null object or function owner.
386
+ The options object has only `source`, `eventTypes`, and optional
387
+ `onListenerError`. Source and event names must already be trimmed lowercase
388
+ identifiers matching `^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)*$`. `eventTypes` must be
389
+ a nonempty array of unique declared types. A second active source for the same
390
+ owner fails closed.
391
+
392
+ ### Signature and result
393
+
394
+ ```text
395
+ createArcaneEventSource(owner, options)
396
+ ```
397
+
398
+ ```javascript
399
+ const source=createArcaneEventSource(owner,{
400
+ source:'sdk.document-store',
401
+ eventTypes:['document.saved'],
402
+ onListenerError(error,errorOccurrence){
403
+ reportOwnerLocalFailure(error,errorOccurrence?.occurrenceId??null);
404
+ }
405
+ });
406
+ ```
407
+
408
+ The returned handle and its descriptor are mutable. The descriptor identifies
409
+ `arcane-event-source/1`, the stable source name, an authority-sequenced opaque
410
+ `arcane-source-<base36>` instance id, and the declared event types plus the final
411
+ `arcane.event.source.disposed` event. IDs are unique only during one authority's
412
+ lifetime in one realm.
413
+
414
+ The authority descriptor is exactly
415
+ `{kind:'arcane-event-authority',protocol:'arcane-event-authority/1',realm:'current'}`.
416
+ The source descriptor is exactly
417
+ `{kind:'arcane-event-source',protocol:'arcane-event-source/1',source,instanceId,
418
+ eventTypes}`; `eventTypes` is mutable and includes the declared types followed by
419
+ `arcane.event.source.disposed`.
420
+
421
+ ### Dispatch
422
+
423
+ ```javascript
424
+ const {occurrence,accepted}=source.dispatch(
425
+ 'document.saved',
426
+ {document:liveDocument,documentId:'document-7'},
427
+ {
428
+ operationId:'save-42',
429
+ publicDetail:{documentId:'document-7'},
430
+ cancelable:true
431
+ }
432
+ );
433
+ ```
434
+
435
+ `dispatch()` is synchronous. Exact canonical subscribers run first in
436
+ registration order, followed by this source's exact `on()`/EventListener
437
+ registrations in registration order. Source listeners receive one mutable
438
+ EventTarget-shaped view whose `detail` is the locally held source detail, whose
439
+ `target` and `currentTarget` are the source owner, and whose
440
+ cancellation state is shared with the occurrence. Function listeners also
441
+ receive that owner as `this`. The public
442
+ occurrence contains:
443
+
444
+ ```javascript
445
+ {
446
+ protocol:'arcane-event-occurrence/1',
447
+ occurrenceId:'arcane-event-<base36>',
448
+ type,
449
+ source,
450
+ instanceId,
451
+ operationId, // string or null
452
+ detail, // complete normalized snapshot of source/public detail
453
+ cancelable,
454
+ get defaultPrevented(),
455
+ preventDefault()
456
+ }
457
+ ```
458
+
459
+ The mutable result is `{occurrence,accepted:!occurrence.defaultPrevented}`.
460
+ Cancellation does not roll back domain work automatically. All active listeners
461
+ run even when one prevents default or throws. Listener exceptions create one
462
+ nonrecursive `arcane.event.listener.error` occurrence and are
463
+ reported through `reportError` or `console.error`; committed source dispatch does
464
+ not throw because an observer failed. `onListenerError(error,errorOccurrence)`
465
+ is invoked synchronously only at the source-owner boundary after canonical error
466
+ publication and platform reporting. Its second argument is the canonical
467
+ listener-error occurrence, or `null` only if that secondary publication could
468
+ not be constructed. If the callback throws, its failure is reported directly
469
+ without another listener-error occurrence. The listener-error public detail is
470
+ the complete normalized snapshot of
471
+ `{code:'ARCANE_EVENT_LISTENER_CALLBACK_FAILED',reason:'listener-threw',
472
+ eventType,occurrenceId,source,instanceId,operationId,error}`; the owner callback
473
+ also receives the original error object as its first argument.
474
+
475
+ Canonical publication never awaits a listener return value and exposes no
476
+ Promise-returning publication API. Domain promises and `createEventQueue()` own
477
+ asynchronous work, ordered callback backpressure, and async failure. Synchronous
478
+ source generation, occurrence creation, sticky state commits, subscription
479
+ installation, and cancellation admission stay on the authority call stack.
480
+
481
+ `on(type,handler,{once=false,signal}={})` and `subscribe()` on the source are
482
+ aliases returning an idempotent disposable unsubscribe. `once()` is the
483
+ one-delivery form. `addEventListener()`/`removeEventListener()` use EventTarget
484
+ deduplication, ignore null or non-listener callbacks, and return `undefined`.
485
+ The stricter `on()`/`subscribe()` APIs reject invalid handlers.
486
+ `dispatchEvent(event)` is an EventTarget adapter that accepts only a declared
487
+ type, preserves cancellation, and publishes
488
+ a new canonical occurrence rather than the raw input.
489
+
490
+ `dispose()` is idempotent: the first call publishes the final noncancelable
491
+ `arcane.event.source.disposed` occurrence, removes source-owned registrations,
492
+ and returns `true`; reentrant or later calls return `false`. Dispatch or new
493
+ registration after disposal fails with `ARCANE_EVENT_SOURCE_DISPOSED`. The owner
494
+ may register a new source after disposal. Its source-local detail is
495
+ `{source,instanceId,reason:'source-disposed'}` and its public detail is
496
+ `{reason:'source-disposed'}`. `destroy()` aliases `dispose()`.
497
+
498
+ Array source detail is shallow-copied. Plain records, including
499
+ null-prototype records, are shallow-copied with their enumerable state preserved;
500
+ property reads that throw are represented as snapshot failures. Other host
501
+ objects such as DOM nodes, `File`, or `Error` remain local by identity in the
502
+ source event view. Canonical detail is a complete normalized snapshot: when
503
+ `publicDetail` is omitted it uses source detail, when both values are
504
+ records it merges them with `publicDetail` winning duplicate keys, and otherwise
505
+ it stores both under `{compatibility,publicDetail}`. Canonical detail is also what
506
+ enters optional EventManager history.
507
+
508
+ ### Availability and normalization
509
+
510
+ **Node and browser/bundler, within the current JavaScript realm.** This wrapper
511
+ reuses `globalThis.arcaneEvents`; it creates no second bus or asynchronous work
512
+ owner. Admission, publication, cancellation, and teardown remain synchronous.
513
+
514
+ ### Example
515
+
516
+ ```javascript
517
+ import {createArcaneEventSource} from 'arcane-os/event-manager';
518
+
519
+ const source=createArcaneEventSource({}, {
520
+ source:'sdk.example',
521
+ eventTypes:['sdk.example.completed']
522
+ });
523
+ source.dispatch('sdk.example.completed',{}, {publicDetail:{status:'completed'}});
524
+ source.dispose();
525
+ ```
526
+
527
+ ## `projectArcaneDOMEvent()`
528
+
529
+ ### Overview
530
+
531
+ Projects one authority-created occurrence to one `CustomEvent`. This is a
532
+ one-way DOM adapter; DOM dispatch never republishes into
533
+ `arcaneEvents`.
534
+
535
+ ### Signature and result
536
+
537
+ ```text
538
+ projectArcaneDOMEvent(target, occurrence, options)
539
+ ```
540
+
541
+ ```javascript
542
+ projectArcaneDOMEvent(target,occurrence,{
543
+ type=occurrence.type,
544
+ bubbles=false,
545
+ composed=false,
546
+ cancelable=occurrence.cancelable
547
+ }={})
548
+ ```
549
+
550
+ The authority retrieves the centrally held source detail, creates a
551
+ mutable outer projection detail, and additively supplies `occurrenceId`, `source`,
552
+ `arcaneSource`, `instanceId`, and `operationId`. `arcaneSource` is always the
553
+ canonical emitter identity. A caller-owned source-detail `source` value is
554
+ preserved; when absent, `source` is added as an alias of `arcaneSource`. A
555
+ conflicting caller-owned reserved metadata value fails
556
+ with `ARCANE_EVENT_DOM_DETAIL_COLLISION`. If the occurrence is already canceled,
557
+ the function skips DOM dispatch and returns `false`. Otherwise it dispatches
558
+ exactly one event, propagates DOM cancellation to a cancelable occurrence, and
559
+ returns the combined acceptance result.
560
+
561
+ ### Availability and normalization
562
+
563
+ **Browser DOM or a DOM-compatible host with `CustomEvent` and
564
+ `dispatchEvent`.** Only an occurrence created by this realm's authority is
565
+ accepted. Projection is synchronous and one-way and creates no listener state.
566
+
567
+ ### Example
568
+
569
+ ```javascript
570
+ import {projectArcaneDOMEvent} from 'arcane-os/event-manager';
571
+
572
+ projectArcaneDOMEvent(button,publication.occurrence,{bubbles:true});
573
+ ```
574
+
575
+ ## `isArcaneEventOccurrence()`
576
+
577
+ ### Overview
578
+
579
+ Returns `true` only for a canonical occurrence or source event view
580
+ created by the current realm's authority. It does not authenticate hostile
581
+ same-realm code; the brand and protocol are realm-local protocol markers.
582
+
583
+ ### Signature and result
584
+
585
+ ```text
586
+ isArcaneEventOccurrence(value)
587
+ ```
588
+
589
+ Returns a boolean; a structurally similar foreign value returns `false`.
590
+
591
+ ### Availability and normalization
592
+
593
+ **Node and browser/bundler, within the current JavaScript realm.** Recognition
594
+ is synchronous and identity-based, with no parsing, cloning, or transport.
595
+
596
+ ### Example
597
+
598
+ ```javascript
599
+ import {isArcaneEventOccurrence} from 'arcane-os/event-manager';
600
+
601
+ console.log(isArcaneEventOccurrence(publication.occurrence));
602
+ ```
603
+
604
+ ## `ARCANE_EVENT_AUTHORITY_BRAND`
605
+
606
+ ### Overview
607
+
608
+ Global registry symbol used as a protocol marker on a created authority.
609
+
610
+ ### Value and import
611
+
612
+ ```text
613
+ const ARCANE_EVENT_AUTHORITY_BRAND
614
+ ```
615
+
616
+ Its exact value is `Symbol.for('arcane-os.arcane-events-authority')`.
617
+
618
+ ### Availability and normalization
619
+
620
+ **Node and browser/bundler.** A created authority receives this ordinary
621
+ enumerable, writable, configurable symbol property. It is a realm-local protocol
622
+ marker, not transport or authenticity.
623
+
624
+ ### Example
625
+
626
+ ```javascript
627
+ import {ARCANE_EVENT_AUTHORITY_BRAND,arcaneEvents} from 'arcane-os/event-manager';
628
+ console.log(arcaneEvents[ARCANE_EVENT_AUTHORITY_BRAND]);
629
+ ```
630
+
631
+ ## `ARCANE_EVENT_AUTHORITY_KIND`
632
+
633
+ ### Overview
634
+
635
+ Stable kind discriminator for the authority descriptor.
636
+
637
+ ### Value and import
638
+
639
+ ```text
640
+ const ARCANE_EVENT_AUTHORITY_KIND
641
+ ```
642
+
643
+ Its exact value is `arcane-event-authority`.
644
+
645
+ ### Availability and normalization
646
+
647
+ **Node and browser/bundler.** Reading it creates no authority or listener.
648
+
649
+ ### Example
650
+
651
+ ```javascript
652
+ import {ARCANE_EVENT_AUTHORITY_KIND,arcaneEvents} from 'arcane-os/event-manager';
653
+ console.log(arcaneEvents.descriptor.kind===ARCANE_EVENT_AUTHORITY_KIND);
654
+ ```
655
+
656
+ ## `ARCANE_EVENT_AUTHORITY_PROTOCOL`
657
+
658
+ ### Overview
659
+
660
+ Stable protocol discriminator for compatible per-realm authorities.
661
+
662
+ ### Value and import
663
+
664
+ ```text
665
+ const ARCANE_EVENT_AUTHORITY_PROTOCOL
666
+ ```
667
+
668
+ Its exact value is `arcane-event-authority/1`.
669
+
670
+ ### Availability and normalization
671
+
672
+ **Node and browser/bundler.** A global value with this protocol and all required
673
+ authority methods is reused. Other values are replaced when the global property
674
+ can be defined; otherwise installation fails with
675
+ `ARCANE_EVENT_AUTHORITY_INSTALL_FAILED`.
676
+
677
+ ### Example
678
+
679
+ ```javascript
680
+ import {ARCANE_EVENT_AUTHORITY_PROTOCOL,arcaneEvents} from 'arcane-os/event-manager';
681
+ console.log(arcaneEvents.protocol===ARCANE_EVENT_AUTHORITY_PROTOCOL);
682
+ ```
683
+
684
+ ## `ARCANE_EVENT_ERROR_CODES`
685
+
686
+ ### Overview
687
+
688
+ Mutable registry of event-authority failure-code names.
689
+
690
+ ### Value and import
691
+
692
+ ```text
693
+ const ARCANE_EVENT_ERROR_CODES
694
+ ```
695
+
696
+ Every key maps to its identical string value; thrown authority failures expose
697
+ the matching value as `error.code`.
698
+
699
+ ### Availability and normalization
700
+
701
+ **Node and browser/bundler.** The object is an exported code lookup, not a
702
+ registration surface. Every current key maps to its identical string value.
703
+
704
+ ### Example
705
+
706
+ ```javascript
707
+ import {ARCANE_EVENT_ERROR_CODES} from 'arcane-os/event-manager';
708
+ console.log(ARCANE_EVENT_ERROR_CODES.ARCANE_EVENT_SOURCE_DISPOSED);
709
+ ```
710
+
711
+ ## `ARCANE_EVENT_LISTENER_ERROR_EVENT`
712
+
713
+ ### Overview
714
+
715
+ Canonical observational event emitted when an event listener throws.
716
+
717
+ ### Value and import
718
+
719
+ ```text
720
+ const ARCANE_EVENT_LISTENER_ERROR_EVENT
721
+ ```
722
+
723
+ Its exact value is `arcane.event.listener.error`.
724
+
725
+ ### Availability and normalization
726
+
727
+ **Node and browser/bundler.** Its mutable public detail carries the exact failure
728
+ code, source occurrence identifiers, and a complete normalized error snapshot.
729
+ Its shape is
730
+ `{code:'ARCANE_EVENT_LISTENER_CALLBACK_FAILED',reason:'listener-threw',
731
+ eventType,occurrenceId,source,instanceId,operationId,error}`. Publication is
732
+ synchronous and nonrecursive.
733
+
734
+ ### Example
735
+
736
+ ```javascript
737
+ import {ARCANE_EVENT_LISTENER_ERROR_EVENT,arcaneEvents} from 'arcane-os/event-manager';
738
+ const unsubscribe=arcaneEvents.subscribe(ARCANE_EVENT_LISTENER_ERROR_EVENT,console.log);
739
+ ```
740
+
741
+ ## `ARCANE_EVENT_OCCURRENCE_PROTOCOL`
742
+
743
+ ### Overview
744
+
745
+ Stable protocol discriminator for canonical occurrences.
746
+
747
+ ### Value and import
748
+
749
+ ```text
750
+ const ARCANE_EVENT_OCCURRENCE_PROTOCOL
751
+ ```
752
+
753
+ Its exact value is `arcane-event-occurrence/1`.
754
+
755
+ ### Availability and normalization
756
+
757
+ **Node and browser/bundler.** Occurrences are mutable realm-owned identity values
758
+ with complete normalized public detail and synchronous cancellation state.
759
+
760
+ ### Example
761
+
762
+ ```javascript
763
+ import {ARCANE_EVENT_OCCURRENCE_PROTOCOL} from 'arcane-os/event-manager';
764
+ console.log(publication.occurrence.protocol===ARCANE_EVENT_OCCURRENCE_PROTOCOL);
765
+ ```
766
+
767
+ ## `ARCANE_EVENT_SOURCE_DISPOSED_EVENT`
768
+
769
+ ### Overview
770
+
771
+ Final noncancelable occurrence published during a source's first disposal.
772
+
773
+ ### Value and import
774
+
775
+ ```text
776
+ const ARCANE_EVENT_SOURCE_DISPOSED_EVENT
777
+ ```
778
+
779
+ Its exact value is `arcane.event.source.disposed`.
780
+
781
+ ### Availability and normalization
782
+
783
+ **Node and browser/bundler.** Canonical detail is the normalized merged value
784
+ `{source,instanceId,reason:'source-disposed'}`. Delivery precedes source-listener cleanup;
785
+ reentrant or later disposal publishes nothing and returns `false`.
786
+
787
+ ### Example
788
+
789
+ ```javascript
790
+ import {ARCANE_EVENT_SOURCE_DISPOSED_EVENT} from 'arcane-os/event-manager';
791
+ source.once(ARCANE_EVENT_SOURCE_DISPOSED_EVENT,console.log);
792
+ source.dispose();
793
+ ```
794
+
795
+ ## `ARCANE_EVENT_SOURCE_KIND`
796
+
797
+ ### Overview
798
+
799
+ Stable kind discriminator for source descriptors.
800
+
801
+ ### Value and import
802
+
803
+ ```text
804
+ const ARCANE_EVENT_SOURCE_KIND
805
+ ```
806
+
807
+ Its exact value is `arcane-event-source`.
808
+
809
+ ### Availability and normalization
810
+
811
+ **Node and browser/bundler.** Reading it does not register or dispose a source.
812
+
813
+ ### Example
814
+
815
+ ```javascript
816
+ import {ARCANE_EVENT_SOURCE_KIND} from 'arcane-os/event-manager';
817
+ console.log(source.descriptor.kind===ARCANE_EVENT_SOURCE_KIND);
818
+ ```
819
+
820
+ ## `ARCANE_EVENT_SOURCE_PROTOCOL`
821
+
822
+ ### Overview
823
+
824
+ Stable protocol discriminator for source handles and descriptors.
825
+
826
+ ### Value and import
827
+
828
+ ```text
829
+ const ARCANE_EVENT_SOURCE_PROTOCOL
830
+ ```
831
+
832
+ Its exact value is `arcane-event-source/1`.
833
+
834
+ ### Availability and normalization
835
+
836
+ **Node and browser/bundler.** One handle belongs to one active owner in one
837
+ realm and declares every publishable type before use.
838
+
839
+ ### Example
840
+
841
+ ```javascript
842
+ import {ARCANE_EVENT_SOURCE_PROTOCOL} from 'arcane-os/event-manager';
843
+ console.log(source.protocol===ARCANE_EVENT_SOURCE_PROTOCOL);
844
+ ```
845
+
846
+ ## `parseEventStack()`
847
+
848
+ ### Overview
849
+
850
+ Strictly imports a JSON string or data object, rejects ambiguous or malformed
851
+ structures, and returns mutable null-prototype normalized data objects. Validation
852
+ includes exact document/record keys, canonical timestamps, session and record
853
+ identity, status-dependent completion fields, complete nested values, increasing
854
+ sequences, and causal parent consistency.
855
+
856
+ ### Signature
857
+
858
+ ```javascript
859
+ parseEventStack(source)
860
+ ```
861
+
862
+ The parser binds every imported record to its enclosing document: protocol and
863
+ session must match, ids must equal `${sessionId}:${sequence}`, sequences and timing
864
+ must be valid, status must agree with completion/error fields, and parent,
865
+ depth, and causation data must form a valid earlier-record relationship. Unknown
866
+ keys, missing keys, sparse arrays, forged identities, and incomplete records are
867
+ rejected instead of repaired.
868
+
869
+ ### Availability and normalization
870
+
871
+ Pure host-neutral JavaScript. It performs no I/O and does not revive tagged values
872
+ into executable JavaScript types.
873
+
874
+ ### Example
875
+
876
+ ```javascript
877
+ import {parseEventStack} from 'arcane-os/event-manager';
878
+
879
+ const document=parseEventStack(receivedText);
880
+ for(const record of document.events)console.info(record.sequence,record.type);
881
+ ```
882
+
883
+ ## `createDOMInstrumentation()`
884
+
885
+ ### Overview
886
+
887
+ Creates a mutable, opt-in browser controller that records capture-phase DOM
888
+ interactions and `MutationObserver` changes through an event manager. It observes
889
+ the supplied root and, by default, open shadow roots already present or later
890
+ inserted.
891
+
892
+ ### Signature
893
+
894
+ ```javascript
895
+ createDOMInstrumentation({
896
+ eventManager,
897
+ root=globalThis.document,
898
+ eventTypes=DEFAULT_DOM_EVENT_TYPES,
899
+ MutationObserver=globalThis.MutationObserver,
900
+ captureMutations=true,
901
+ observeOpenShadowRoots=true
902
+ }={})
903
+ ```
904
+
905
+ The returned controller exposes `root`, `start()`, `stop({emitLifecycle=true}={})`,
906
+ `active`, `cleanupPending`, and `observedRootCount`. Start and stop are idempotent.
907
+ Startup rolls back partially attached listeners on failure; shutdown retries
908
+ listener/observer cleanup and exposes a pending cleanup state when a resource
909
+ still cannot be removed.
910
+
911
+ ### Captured content
912
+
913
+ Interaction records include readable event fields, target values (including file
914
+ lists), target and composed-path descriptors, and event flags. Mutation records
915
+ include complete attribute values, character data, and added or removed node
916
+ content. Document root descriptions include the current URL and title. The
917
+ instrumentation preserves those values completely.
918
+
919
+ DOM capture is not complete application-state capture. It cannot observe closed
920
+ shadow roots, cross-origin frames, CSSOM/canvas rendering, most property-only
921
+ writes, native/kernel actions, external content, or activity before startup.
922
+
923
+ ### Availability and normalization
924
+
925
+ Browser/DOM renderer only, or a compatible test shim. Records use the same
926
+ host-neutral event-stack format as semantic events.
927
+
928
+ ### Example
929
+
930
+ ```javascript
931
+ import {createEventManager} from 'arcane-os/event-manager';
932
+
933
+ const events=createEventManager({timeTravel:true});
934
+ const dom=events.attachDOM(document);
935
+
936
+ // Exercise the scenario.
937
+ dom.stop();
938
+ const text=events.exportStack();
939
+ events.clearHistory();
940
+ ```
941
+
942
+ ## `domSelector()`
943
+
944
+ ### Overview
945
+
946
+ Builds a diagnostic selector from ids, `data-arcane-id`, `data-testid`, tag names,
947
+ and sibling positions. `:document` and `:shadow-root` identify roots; ` >>> ` marks
948
+ an open-shadow boundary and is not a standard `querySelector()` combinator.
949
+
950
+ ### Signature
951
+
952
+ ```javascript
953
+ domSelector(target, root)
954
+ ```
955
+
956
+ ### Availability and normalization
957
+
958
+ Browser DOM or DOM-like test values. Returns a string or `null`.
959
+
960
+ ### Example
961
+
962
+ ```javascript
963
+ import {domSelector} from 'arcane-os/event-manager';
964
+ console.info(domSelector(button,document));
965
+ ```
966
+
967
+ ## `describeDOMTarget()`
968
+
969
+ ### Overview
970
+
971
+ Returns a mutable descriptor for a document, shadow root, text node, element,
972
+ global object, or generic event target. Element descriptors include selector, tag,
973
+ id, role, name, type, and complete markup or text content. Text-node descriptors
974
+ include their complete text content.
975
+
976
+ ### Signature
977
+
978
+ ```javascript
979
+ describeDOMTarget(target, root)
980
+ ```
981
+
982
+ ### Availability and normalization
983
+
984
+ Browser DOM or DOM-like test values. Returns a mutable descriptor or `null`.
985
+
986
+ ### Example
987
+
988
+ ```javascript
989
+ import {describeDOMTarget} from 'arcane-os/event-manager';
990
+ console.info(describeDOMTarget(document.activeElement,document));
991
+ ```
992
+
993
+ ## `DEFAULT_DOM_EVENT_TYPES`
994
+
995
+ ### Overview
996
+
997
+ A mutable array of 44 keyboard, composition, pointer, mouse, touch, form, focus,
998
+ clipboard, drag, selection, scroll, and wheel event names used by default DOM
999
+ instrumentation.
1000
+
1001
+ ### Value
1002
+
1003
+ ```javascript
1004
+ const DEFAULT_DOM_EVENT_TYPES = [/* 44 event names */]
1005
+ ```
1006
+
1007
+ ### Availability and normalization
1008
+
1009
+ Importable in Node and browsers; operational only with DOM event targets.
1010
+
1011
+ ### Example
1012
+
1013
+ ```javascript
1014
+ import {DEFAULT_DOM_EVENT_TYPES} from 'arcane-os/event-manager';
1015
+ const eventTypes=DEFAULT_DOM_EVENT_TYPES.filter(type=>type!=='pointermove');
1016
+ ```
1017
+
1018
+ ## `ARCANE_EVENT_STACK_PROTOCOL`
1019
+
1020
+ ### Overview
1021
+
1022
+ Identifies the versioned event-stack JSON contract.
1023
+
1024
+ ### Value
1025
+
1026
+ ```javascript
1027
+ ARCANE_EVENT_STACK_PROTOCOL === 'arcane-event-stack/1'
1028
+ ```
1029
+
1030
+ ### Availability and normalization
1031
+
1032
+ All JavaScript hosts; exact string, never negotiated or silently upgraded.
1033
+
1034
+ ### Example
1035
+
1036
+ ```javascript
1037
+ if(document.protocol!==ARCANE_EVENT_STACK_PROTOCOL)throw new Error('Unsupported stack');
1038
+ ```
1039
+
1040
+ ## `TIME_TRAVEL_SEEK_EVENT`
1041
+
1042
+ ### Overview
1043
+
1044
+ Names the cursor event. Its payload is `{sessionId,sequence,record}`. The event is
1045
+ delivered synchronously but is not added to the diagnostic history.
1046
+
1047
+ ### Value
1048
+
1049
+ ```javascript
1050
+ TIME_TRAVEL_SEEK_EVENT === 'arcane.time-travel.seek'
1051
+ ```
1052
+
1053
+ ### Availability and normalization
1054
+
1055
+ Node and browser event managers; normalized payload, no state restoration.
1056
+
1057
+ ### Example
1058
+
1059
+ ```javascript
1060
+ events.on(TIME_TRAVEL_SEEK_EVENT,({sequence})=>timeline.select(sequence));
1061
+ events.seek(0);
1062
+ ```
1063
+
1064
+ ## `PLAYBACK_STARTED_EVENT`
1065
+
1066
+ ### Overview
1067
+
1068
+ Names the lifecycle event emitted with
1069
+ `{sessionId,count,fromSequence,toSequence,speed,mode}` before playback delivery.
1070
+
1071
+ ### Value
1072
+
1073
+ ```javascript
1074
+ PLAYBACK_STARTED_EVENT === 'arcane.time-travel.playback.started'
1075
+ ```
1076
+
1077
+ ### Availability and normalization
1078
+
1079
+ Node and browser event managers; synchronous lifecycle notification.
1080
+
1081
+ ### Example
1082
+
1083
+ ```javascript
1084
+ events.on(PLAYBACK_STARTED_EVENT,({count})=>console.info(`Reviewing ${count}`));
1085
+ ```
1086
+
1087
+ ## `PLAYBACK_RECORD_EVENT`
1088
+
1089
+ ### Overview
1090
+
1091
+ Names the per-record event used by `mode:'review'` playback. Its only payload is
1092
+ the mutable normalized record.
1093
+
1094
+ ### Value
1095
+
1096
+ ```javascript
1097
+ PLAYBACK_RECORD_EVENT === 'arcane.time-travel.playback.record'
1098
+ ```
1099
+
1100
+ ### Availability and normalization
1101
+
1102
+ Node and browser event managers; the payload remains a normalized record.
1103
+
1104
+ ### Example
1105
+
1106
+ ```javascript
1107
+ events.on(PLAYBACK_RECORD_EVENT,record=>timeline.append(record));
1108
+ await events.playback({mode:'review'});
1109
+ ```
1110
+
1111
+ ## `PLAYBACK_COMPLETED_EVENT`
1112
+
1113
+ ### Overview
1114
+
1115
+ Names the successful terminal event. Payload:
1116
+ `{sessionId,delivered,cursor,completed:true}`.
1117
+
1118
+ ### Value
1119
+
1120
+ ```javascript
1121
+ PLAYBACK_COMPLETED_EVENT === 'arcane.time-travel.playback.completed'
1122
+ ```
1123
+
1124
+ ### Availability and normalization
1125
+
1126
+ Node and browser event managers; mutable result payload.
1127
+
1128
+ ### Example
1129
+
1130
+ ```javascript
1131
+ events.once(PLAYBACK_COMPLETED_EVENT,result=>console.info(result.delivered));
1132
+ ```
1133
+
1134
+ ## `PLAYBACK_CANCELLED_EVENT`
1135
+
1136
+ ### Overview
1137
+
1138
+ Names the cancelled terminal event. Payload:
1139
+ `{sessionId,delivered,cursor,completed:false,error}`. Playback still rejects with
1140
+ the original cancellation reason.
1141
+
1142
+ ### Value
1143
+
1144
+ ```javascript
1145
+ PLAYBACK_CANCELLED_EVENT === 'arcane.time-travel.playback.cancelled'
1146
+ ```
1147
+
1148
+ ### Availability and normalization
1149
+
1150
+ Node and browser event managers; mutable normalized error snapshot in the event payload.
1151
+
1152
+ ### Example
1153
+
1154
+ ```javascript
1155
+ events.once(PLAYBACK_CANCELLED_EVENT,({delivered})=>console.info(delivered));
1156
+ controller.abort('review closed');
1157
+ ```
1158
+
1159
+ ## `PLAYBACK_FAILED_EVENT`
1160
+
1161
+ ### Overview
1162
+
1163
+ Names the failed terminal event. It uses the same failed result shape as
1164
+ cancelled playback, and the original failure rejects `playback()`.
1165
+
1166
+ ### Value
1167
+
1168
+ ```javascript
1169
+ PLAYBACK_FAILED_EVENT === 'arcane.time-travel.playback.failed'
1170
+ ```
1171
+
1172
+ ### Availability and normalization
1173
+
1174
+ Node and browser event managers; mutable normalized error snapshot in the event payload.
1175
+
1176
+ ### Example
1177
+
1178
+ ```javascript
1179
+ events.once(PLAYBACK_FAILED_EVENT,({error})=>console.error(error.message));
1180
+ ```
1181
+
1182
+ ## `DOM_INTERACTION_EVENT`
1183
+
1184
+ ### Overview
1185
+
1186
+ Identifies captured DOM interactions. Payload includes the DOM event type,
1187
+ normalized target and composed path, event flags, readable event details, and a
1188
+ captured target value when one is available.
1189
+
1190
+ ### Value
1191
+
1192
+ ```javascript
1193
+ DOM_INTERACTION_EVENT === 'arcane.dom.interaction'
1194
+ ```
1195
+
1196
+ ### Availability and normalization
1197
+
1198
+ Produced only by browser/DOM instrumentation; stored as a host-neutral record.
1199
+
1200
+ ### Example
1201
+
1202
+ ```javascript
1203
+ const clicks=events.getEventStack({type:DOM_INTERACTION_EVENT});
1204
+ ```
1205
+
1206
+ ## `DOM_MUTATION_EVENT`
1207
+
1208
+ ### Overview
1209
+
1210
+ Identifies normalized attribute, character-data, and child-list mutations. A
1211
+ mutation captured immediately after an interaction may carry that interaction's
1212
+ record id as its causation id.
1213
+
1214
+ ### Value
1215
+
1216
+ ```javascript
1217
+ DOM_MUTATION_EVENT === 'arcane.dom.mutation'
1218
+ ```
1219
+
1220
+ ### Availability and normalization
1221
+
1222
+ Produced only by browser `MutationObserver`; stored as a host-neutral record.
1223
+
1224
+ ### Example
1225
+
1226
+ ```javascript
1227
+ for(const record of events.getEventStack({type:DOM_MUTATION_EVENT})){
1228
+ console.info(record.payload[0].mutationType);
1229
+ }
1230
+ ```
1231
+
1232
+ ## `DOM_OBSERVATION_STARTED_EVENT`
1233
+
1234
+ ### Overview
1235
+
1236
+ Identifies successful DOM capture startup. Payload is
1237
+ `{root,eventTypes,captureMutations,observeOpenShadowRoots}`.
1238
+
1239
+ ### Value
1240
+
1241
+ ```javascript
1242
+ DOM_OBSERVATION_STARTED_EVENT === 'arcane.dom.observation.started'
1243
+ ```
1244
+
1245
+ ### Availability and normalization
1246
+
1247
+ Browser/DOM instrumentation lifecycle record.
1248
+
1249
+ ### Example
1250
+
1251
+ ```javascript
1252
+ events.once(DOM_OBSERVATION_STARTED_EVENT,details=>console.info(details.eventTypes.length));
1253
+ ```
1254
+
1255
+ ## `DOM_OBSERVATION_STOPPED_EVENT`
1256
+
1257
+ ### Overview
1258
+
1259
+ Identifies normal DOM capture shutdown. Payload is `{root}`.
1260
+
1261
+ ### Value
1262
+
1263
+ ```javascript
1264
+ DOM_OBSERVATION_STOPPED_EVENT === 'arcane.dom.observation.stopped'
1265
+ ```
1266
+
1267
+ ### Availability and normalization
1268
+
1269
+ Browser/DOM instrumentation lifecycle record.
1270
+
1271
+ ### Example
1272
+
1273
+ ```javascript
1274
+ events.once(DOM_OBSERVATION_STOPPED_EVENT,()=>console.info('DOM capture stopped'));
1275
+ events.disableTimeTravel();
1276
+ ```
1277
+
1278
+ ## Event-stack document and record shapes
1279
+
1280
+ `exportStack()` and `parseEventStack()` use this document shape:
1281
+
1282
+ ```javascript
1283
+ {
1284
+ protocol:'arcane-event-stack/1',
1285
+ sessionId:'diagnostic-session',
1286
+ createdAt:'2026-08-24T03:00:00.000Z',
1287
+ events:[/* mutable normalized records */]
1288
+ }
1289
+ ```
1290
+
1291
+ Every record has exactly these fields:
1292
+
1293
+ ```javascript
1294
+ {
1295
+ protocol,
1296
+ sessionId,
1297
+ id, // `${sessionId}:${sequence}`
1298
+ sequence, // positive, strictly increasing safe integer
1299
+ timestamp, // canonical UTC ISO timestamp
1300
+ monotonicMs, // finite, non-negative number
1301
+ type,
1302
+ source,
1303
+ category, // string or null
1304
+ correlationId, // string or null
1305
+ causationId, // string or null
1306
+ parentSequence, // positive sequence or null
1307
+ depth, // nested synchronous dispatch depth
1308
+ stack, // complete captured string or null
1309
+ payload, // normalized array of delivered arguments
1310
+ metadata, // normalized object
1311
+ status, // 'dispatching', 'completed', or 'failed'
1312
+ completedAt, // canonical timestamp or null
1313
+ durationMs, // non-negative number or null
1314
+ error // normalized error or null
1315
+ }
1316
+ ```
1317
+
1318
+ Nested synchronous dispatch records its parent sequence and depth and derives a
1319
+ causation id when one is not supplied. A record initially appears as `dispatching`
1320
+ and is replaced with a completed or failed mutable record when synchronous
1321
+ delivery finishes.
1322
+
1323
+ Snapshot normalization preserves complete content. It reads enumerable own
1324
+ properties, represents a property read that throws as `snapshot-failed`,
1325
+ preserves cycles as `$ref`, and applies tagged forms for non-finite numbers,
1326
+ bigint, symbols, functions, dates, regular expressions, errors, maps, sets, typed
1327
+ arrays, and array buffers. The resulting record objects are mutable. Tagged
1328
+ values are diagnostic data, not executable values, and playback does not revive
1329
+ them.
1330
+
1331
+ Capture remains subordinate to live delivery. A proxy trap, invalid special
1332
+ value, or other snapshot failure becomes a `snapshot-failed` value when possible.
1333
+ If diagnostic capture itself cannot construct a record, the live synchronous
1334
+ event is still delivered. A subscriber failure remains authoritative and is
1335
+ re-thrown after the SDK makes a best effort to finalize its failed record.
1336
+
1337
+ <details>
1338
+ <summary>Protocol and schema details</summary>
1339
+
1340
+ The durable protocol is exactly `arcane-event-stack/1`. It is independent of the
1341
+ Core `arcane/1` host protocol and the CLI event-stream protocol. Import the schema
1342
+ from `arcane-os/schemas/event-stack.json`; it uses JSON Schema draft 2020-12.
1343
+
1344
+ ```javascript
1345
+ import schema from 'arcane-os/schemas/event-stack.json' with {type:'json'};
1346
+ ```
1347
+
1348
+ Protocol versions are not negotiated or normalized automatically. A remote tool
1349
+ must explicitly transport the JSON, preserve it as untrusted input, and call
1350
+ `parseEventStack()` before use. Playback does not resend
1351
+ native RPC, repeat provisioning, synthesize trusted browser input, or restore a
1352
+ kernel/application snapshot.
1353
+
1354
+ </details>
1355
+
1356
+ ## Errors and recovery
1357
+
1358
+ | Operation | Error | Recovery |
1359
+ | --- | --- | --- |
1360
+ | Authority cannot be installed | `ARCANE_EVENT_AUTHORITY_INSTALL_FAILED` | Make the realm global extensible before first import |
1361
+ | Source owner/options/name/event types/callback invalid | `ARCANE_EVENT_SOURCE_INVALID` | Use one owner, exact data options, valid names, and a nonempty unique list of declared types |
1362
+ | Owner already has an active source | `ARCANE_EVENT_SOURCE_ALREADY_REGISTERED` | Reuse or dispose the current handle |
1363
+ | Source is disposing or disposed | `ARCANE_EVENT_SOURCE_DISPOSED` | Stop publishing or create a new source after disposal completes |
1364
+ | Source publishes/listens to an undeclared type | `ARCANE_EVENT_SOURCE_EVENT_TYPE_UNDECLARED` | Add the exact type to `eventTypes` before source creation |
1365
+ | Occurrence/options invalid | `ARCANE_EVENT_OCCURRENCE_INVALID` | Use the authority-created occurrence and documented dispatch options |
1366
+ | Realm occurrence sequence exhausted | `ARCANE_EVENT_OCCURRENCE_SEQUENCE_EXHAUSTED` | Start a new JavaScript realm |
1367
+ | Realm source sequence exhausted | `ARCANE_EVENT_SOURCE_SEQUENCE_EXHAUSTED` | Start a new JavaScript realm |
1368
+ | Canonical listener throws | `ARCANE_EVENT_LISTENER_CALLBACK_FAILED` in a listener-error occurrence | Fix the observer; committed domain dispatch remains successful |
1369
+ | Subscription type invalid | `ARCANE_EVENT_SUBSCRIPTION_TYPE_INVALID` | Use a nonempty trimmed name matching the authority event-name grammar; canonical wildcard subscription is not admitted |
1370
+ | Subscription handler invalid | `ARCANE_EVENT_SUBSCRIPTION_HANDLER_INVALID` | Use a function or EventListener object |
1371
+ | Subscription options invalid | `ARCANE_EVENT_SUBSCRIPTION_OPTIONS_INVALID` | Use a data-only `{once?,signal?}` record with a boolean `once` value |
1372
+ | Subscription signal invalid | `ARCANE_EVENT_SUBSCRIPTION_SIGNAL_INVALID` | Pass an AbortSignal-compatible value or omit `signal` |
1373
+ | EventTarget adapter input lacks a valid type or data detail | `ARCANE_EVENT_DISPATCH_EVENT_INVALID` | Pass an Event or an Event-like data object; do not use accessors |
1374
+ | DOM target invalid | `ARCANE_EVENT_DOM_TARGET_INVALID` | Supply a target with `dispatchEvent` in a realm with `CustomEvent` support |
1375
+ | DOM options invalid | `ARCANE_EVENT_DOM_OPTIONS_INVALID` | Use only `type`, `bubbles`, `composed`, and `cancelable`, with boolean flags |
1376
+ | DOM detail conflicts with authority identifiers | `ARCANE_EVENT_DOM_DETAIL_COLLISION` | Remove conflicting `occurrenceId`, `arcaneSource`, `instanceId`, or `operationId` fields; a source-detail `source` is preserved |
1377
+ | Constructor flags, clocks, or session id invalid | `TypeError` | Correct types and keep session id non-empty |
1378
+ | Clock returns invalid timestamp or monotonic value | `TypeError` | Supply a valid UTC-compatible clock and finite non-negative monotonic clock |
1379
+ | Metadata is not an object; forwarded event is invalid | `TypeError` | Pass an object and a string event type |
1380
+ | Subscriber throws | Original error is rethrown | Treat synchronous handlers as part of the publisher's failure boundary |
1381
+ | Clear during dispatch/playback | `Error` | Wait for the active operation to finish |
1382
+ | Stack JSON/shape/order/identity/timing/causality invalid | `TypeError` | Reject unknown, incomplete, or forged input; do not partially use it |
1383
+ | Stack range or playback mode/callback invalid | `TypeError` | Correct the options |
1384
+ | Export indentation, seek position, or playback speed invalid | `RangeError` | Use documented ranges |
1385
+ | Playback already active | `Error` | Await or cancel the current playback |
1386
+ | Playback aborts or a callback/subscriber fails | Promise rejects after terminal lifecycle event | Handle rejection and inspect the mutable normalized terminal error snapshot |
1387
+ | DOM manager/root/options invalid or MutationObserver unavailable | `TypeError` | Correct capability/options or set `captureMutations:false` |
1388
+
1389
+ ## Behavioral tests
1390
+
1391
+ The executable contract is covered by:
1392
+
1393
+ - `test/event-manager.test.mjs`: synchronous bus behavior, causal recording,
1394
+ complete snapshots, safe capture failures, special-value normalization,
1395
+ strict forged-import rejection, cursor behavior, review and event playback,
1396
+ cancellation, central queue mirroring, mutable authority reuse, complete rich
1397
+ source detail, source order/lifecycle, dispatch-safe unsubscribe,
1398
+ EventTarget adapters, one-way DOM projection, and observational listener
1399
+ failures;
1400
+ - `test/dom-event-instrumentation.test.mjs`: browser interaction/mutation capture,
1401
+ open-shadow observation, complete content, lifecycle, and cleanup;
1402
+ - `test/contracts.test.mjs`: published schema and package-export stability;
1403
+ - `test/reference-completeness.test.mjs`: public export and MDN-reference coverage.
1404
+
1405
+ Run the behavioral suite through the repository's normal gate:
1406
+
1407
+ ```shell
1408
+ npm run check
1409
+ ```