arcane-os 0.3.1 → 0.3.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 (153) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +86 -117
  3. package/bin/arcane-test.mjs +170 -46
  4. package/browser-runtime/ai/browser-speech-artifacts.mjs +855 -895
  5. package/browser-runtime/ai/browser-speech-providers.mjs +80 -204
  6. package/browser-runtime/ai/browser-wasm-llm-provider.mjs +627 -819
  7. package/browser-runtime/ai/browser-wasm.mjs +24 -35
  8. package/browser-runtime/ai/browser-wllama-runtime.mjs +64 -316
  9. package/browser-runtime/ai/model-controller.mjs +584 -181
  10. package/browser-runtime/ai/speech-worker-client.mjs +8 -148
  11. package/browser-runtime/ai/speech-worker-runtime.mjs +642 -374
  12. package/browser-runtime/dom-event-instrumentation.mjs +55 -147
  13. package/browser-runtime/event-manager.mjs +239 -624
  14. package/package.json +5 -6
  15. package/runtime/arcane/components/app-bar.html +3 -15
  16. package/runtime/arcane/components/assistant-panel.html +10 -10
  17. package/runtime/arcane/components/calculator.html +1 -1
  18. package/runtime/arcane/components/chat.html +1359 -135
  19. package/runtime/arcane/components/conversation-view.html +2 -2
  20. package/runtime/arcane/components/document-inspector.html +11 -17
  21. package/runtime/arcane/components/file-manager.html +13 -56
  22. package/runtime/arcane/components/markdown-document.html +82 -281
  23. package/runtime/arcane/components/markdown-editor.html +7 -10
  24. package/runtime/arcane/components/media-embed.html +6 -6
  25. package/runtime/arcane/components/screen-capture.html +4 -4
  26. package/runtime/arcane/components/source-explanation.html +2 -2
  27. package/runtime/arcane/components/speech.html +112 -68
  28. package/runtime/arcane/components/terminal-workspace.html +4 -4
  29. package/runtime/arcane/components/theme-editor.html +1 -1
  30. package/runtime/arcane/components/unified-inbox.html +2 -2
  31. package/runtime/arcane/components/voice-transcription.html +31 -21
  32. package/runtime/arcane/entities/Calculation.js +2 -3
  33. package/runtime/arcane/entities/Chat.js +228 -43
  34. package/runtime/arcane/entities/Preference.js +3 -5
  35. package/runtime/arcane/entities/Weather.js +5 -5
  36. package/runtime/arcane/modules/AI.js +1042 -427
  37. package/runtime/arcane/modules/AIProviderRuntime.js +618 -359
  38. package/runtime/arcane/modules/AIResponseLength.js +9 -19
  39. package/runtime/arcane/modules/AIRuntimeState.js +109 -72
  40. package/runtime/arcane/modules/ArcaneNavigationPolicy.js +45 -32
  41. package/runtime/arcane/modules/BrowserTestSuite.js +78 -122
  42. package/runtime/arcane/modules/CalculatorEngine.js +9 -9
  43. package/runtime/arcane/modules/CommunicationAppController.js +3 -7
  44. package/runtime/arcane/modules/ComponentContracts.js +30 -32
  45. package/runtime/arcane/modules/ConfiguredAIChatSession.js +281 -230
  46. package/runtime/arcane/modules/ConversationActionItems.js +26 -59
  47. package/runtime/arcane/modules/ConversationClosingReport.js +34 -61
  48. package/runtime/arcane/modules/ConversationTimebox.js +27 -15
  49. package/runtime/arcane/modules/DBOPFSDocumentLibrary.js +152 -344
  50. package/runtime/arcane/modules/DocumentLexicalSearch.js +25 -91
  51. package/runtime/arcane/modules/HTMLImport.js +54 -1
  52. package/runtime/arcane/modules/IsolatedModelQuestionRunner.js +40 -203
  53. package/runtime/arcane/modules/LocalAIReadiness.js +40 -60
  54. package/runtime/arcane/modules/LocalAIReadinessController.js +15 -13
  55. package/runtime/arcane/modules/MD.js +1 -45
  56. package/runtime/arcane/modules/Mail.js +51 -103
  57. package/runtime/arcane/modules/MailOutbox.mjs +95 -193
  58. package/runtime/arcane/modules/MailTransport.mjs +36 -57
  59. package/runtime/arcane/modules/ModelDefinition.js +22 -106
  60. package/runtime/arcane/modules/OpenMeteoWeatherProvider.js +39 -101
  61. package/runtime/arcane/modules/PersistentAIChatSession.js +281 -18
  62. package/runtime/arcane/modules/PreferenceStore.js +102 -30
  63. package/runtime/arcane/modules/RiskSignalAnalyzer.js +8 -9
  64. package/runtime/arcane/modules/ScopedOPFSCache.js +7 -42
  65. package/runtime/arcane/modules/ScreenCapture.js +175 -128
  66. package/runtime/arcane/modules/SpeechPlayback.js +46 -149
  67. package/runtime/arcane/modules/StaticDocumentCatalog.js +173 -407
  68. package/runtime/arcane/modules/ToolCallRouter.js +25 -12
  69. package/runtime/arcane/modules/YouTubeMedia.js +6 -5
  70. package/schemas/arcane-app-bundle.schema.json +13 -78
  71. package/schemas/arcane-app.schema.json +9 -25
  72. package/schemas/arcane-lock.schema.json +18 -151
  73. package/schemas/arcane-package.schema.json +2 -16
  74. package/schemas/native-build-plan.schema.json +119 -122
  75. package/src/app-descriptor.mjs +75 -132
  76. package/src/application-tests.mjs +200 -0
  77. package/src/cli/main.mjs +27 -46
  78. package/src/constants.mjs +3 -4
  79. package/src/dev-server.mjs +30 -324
  80. package/src/doctor.mjs +92 -154
  81. package/src/dom-event-instrumentation.mjs +55 -147
  82. package/src/errors.mjs +2 -3
  83. package/src/event-manager.mjs +239 -624
  84. package/src/event-queue.mjs +3 -3
  85. package/src/import-map.mjs +273 -1028
  86. package/src/index.mjs +14 -16
  87. package/src/installed-sdk-runtime.mjs +27 -67
  88. package/src/integrated-provider-loader.mjs +53 -382
  89. package/src/mail-api.mjs +0 -2
  90. package/src/mail-server.mjs +224 -580
  91. package/src/mail.mjs +4 -10
  92. package/src/native-plan.mjs +163 -598
  93. package/src/native-provider-loader.mjs +104 -1063
  94. package/src/packager/core.mjs +485 -3229
  95. package/src/process.mjs +5 -10
  96. package/src/release-bundle.mjs +292 -2405
  97. package/src/runtime.mjs +76 -396
  98. package/src/scaffold.mjs +30 -80
  99. package/src/sdk-browser-runtime.mjs +70 -626
  100. package/src/source-server.mjs +588 -0
  101. package/src/targets/index.mjs +78 -188
  102. package/src/templates/workspace-template.mjs +19 -135
  103. package/src/testing-loader.mjs +164 -0
  104. package/src/testing.mjs +1 -1
  105. package/src/toolchain.mjs +131 -544
  106. package/src/update-check.mjs +26 -64
  107. package/src/workspace-operation-lock.mjs +139 -430
  108. package/src/workspace-runtime.mjs +109 -1558
  109. package/src/workspace.mjs +40 -302
  110. package/browser-runtime/ARCANE_SDK_BROWSER_RELEASE.json +0 -218
  111. package/browser-runtime/ai/ARCANE_AI_BROWSER_SPEECH_COMPONENTS.json +0 -203
  112. package/browser-runtime/ai/ARCANE_AI_BROWSER_WASM_COMPONENTS.json +0 -80
  113. package/browser-runtime/ai/internal/sha256.mjs +0 -166
  114. package/docs/architecture.md +0 -344
  115. package/docs/compatibility.md +0 -36
  116. package/docs/event-manager.md +0 -294
  117. package/docs/platform-targets.md +0 -108
  118. package/docs/publishing.md +0 -201
  119. package/docs/reference/README.md +0 -185
  120. package/docs/reference/ai/browser-speech-package-authority.json +0 -835
  121. package/docs/reference/ai/browser-speech.md +0 -1295
  122. package/docs/reference/ai/browser-wasm.md +0 -530
  123. package/docs/reference/arcane-ollama.md +0 -288
  124. package/docs/reference/availability-and-normalization.md +0 -183
  125. package/docs/reference/behavioral-testing.md +0 -133
  126. package/docs/reference/cli.md +0 -779
  127. package/docs/reference/core/README.md +0 -62
  128. package/docs/reference/core/arcane-ai-contracts.md +0 -907
  129. package/docs/reference/core/arcane-api.md +0 -601
  130. package/docs/reference/core/arcane-entities.md +0 -65
  131. package/docs/reference/core/arcane-events.md +0 -134
  132. package/docs/reference/core/ollama-module.md +0 -181
  133. package/docs/reference/core/reference/arcane-api/ai-and-ollama.md +0 -1909
  134. package/docs/reference/core/reference/arcane-api/applications-terminal-capabilities.md +0 -1057
  135. package/docs/reference/core/reference/arcane-api/core-and-events.md +0 -320
  136. package/docs/reference/core/reference/arcane-api/filesystem-storage-preferences-appearance.md +0 -610
  137. package/docs/reference/core/reference/arcane-api/namespaces.md +0 -1157
  138. package/docs/reference/core/reference/arcane-api/platform-installation-users-system.md +0 -1423
  139. package/docs/reference/core/reference/arcane-api/session-provisioning-diagnostics-development.md +0 -315
  140. package/docs/reference/event-manager.md +0 -1511
  141. package/docs/reference/inventory/package-api.json +0 -3284
  142. package/docs/reference/inventory/runtime-components.json +0 -1011
  143. package/docs/reference/inventory/runtime-entities.json +0 -26
  144. package/docs/reference/inventory/runtime-modules.json +0 -1431
  145. package/docs/reference/mail.md +0 -316
  146. package/docs/reference/protocols.md +0 -719
  147. package/docs/reference/runtime-components.md +0 -1366
  148. package/docs/reference/runtime-entities.md +0 -303
  149. package/docs/reference/runtime-modules.md +0 -2965
  150. package/docs/reference/sdk-api.md +0 -6698
  151. package/docs/roadmap.md +0 -79
  152. package/docs/work-amplification.md +0 -129
  153. package/runtime/ARCANE_RUNTIME_RELEASE.json +0 -826
@@ -1,344 +0,0 @@
1
- # Architecture
2
-
3
- The CLI, future Arcane Developer graphical control panel, CI, and Codex all use
4
- one headless operation API. A client selects a named operation and consumes the
5
- same structured event stream; the GUI is not a second build system.
6
-
7
- ```text
8
- external app repository -----+
9
- |
10
- Arcane OS consumer checkout --+-- CLI / future GUI / Codex / CI
11
- |
12
- shared toolchain API
13
- |
14
- browser package or explicit target adapter
15
- ```
16
-
17
- ## Canonical ownership and portability boundary
18
-
19
- The SDK repository is the canonical source for every mechanism that can be
20
- reused by a portable Arcane application. That includes shared modules,
21
- entities, components, themes, browser runtimes, providers, workers and assets;
22
- protocol, state, startup, readiness, progress, cancellation, unload and dispose
23
- machinery; public native contracts and adapters; the development source mount;
24
- and the packaging, license, receipt and verification boundaries for those
25
- portable bytes. In particular, shared AI selected-role hydration,
26
- startup-settled state and events, fail-closed role readiness, lifecycle and
27
- cancellation contracts, and the shared chat and speech components are
28
- SDK-owned source and contracts rather than Arcane OS–owned snapshots.
29
-
30
- Every portable application artifact materializes an immutable, locked and
31
- verified projection of the SDK runtime bytes, assets, workers, licenses and
32
- public contracts it uses. It remains self-contained whether it runs as plain
33
- HTML or inside an executable wrapper. It has no runtime dependency on an
34
- Arcane OS installation, source checkout or private Arcane OS import.
35
-
36
- Arcane OS is an SDK consumer like other applications. Its orchestrator,
37
- launcher, Shell, Provisioner, system AI application and internal tools use the
38
- same SDK modules and components rather than maintaining private runtime copies.
39
- Arcane OS and Core own the privileged host implementations, app/session
40
- admission and authorization, native transport and lifecycle, launcher and
41
- Shell orchestration, and system-AI policy specific to the Shell. The SDK may
42
- publish the capability-neutral Core bridge contract and adapters, but it does
43
- not embed Core or inherit another application's policy.
44
-
45
- Each application owns its branding, prompts, data, tools, business policy,
46
- model authorities and app-specific orchestration. Apply this decision order:
47
-
48
- | Responsibility | Canonical owner |
49
- |---|---|
50
- | Reusable by any portable application | Arcane SDK |
51
- | Host privilege, launcher, Shell or app/session admission | Arcane OS / Core |
52
- | Behavior unique to one product | That application |
53
-
54
- Do not copy a reusable implementation between the SDK, Arcane OS and an app,
55
- and do not create a hidden Arcane OS source dependency. Extend one neutral SDK
56
- contract and keep product policy in the consumer.
57
-
58
- Development and distribution use different authority. The explicit
59
- `arcane dev --sdk-runtime-source <sdk-root>` development-only live source mount
60
- lets a refresh read the saved SDK source without copying it into the app.
61
- Distribution never follows that mount. It embeds and verifies the application's
62
- locked immutable SDK projection.
63
-
64
- `tools/runtime-source.json` declares SDK-canonical authority for
65
- `runtime/arcane/` and retains the prior Arcane OS source only as legacy
66
- provenance for migrated compatibility bytes. The old OS-to-SDK synchronization
67
- direction is retired and fails closed. Arcane OS must consume a locked SDK
68
- projection through the same package/source-mount boundary as other apps; its
69
- repository-side consumer cutover is coordinated separately and does not create
70
- a co-equal source.
71
-
72
- ## Workspace profiles
73
-
74
- An external workspace maps the exact runtime shipped by its locked `arcane-os`
75
- dependency. An Arcane OS checkout is an integrated SDK consumer, not the owner
76
- of portable runtime source. For live shared development, the explicit
77
- development-only SDK source mount maps the canonical SDK runtime and dependency
78
- paths into that consumer. Without the mount, the workspace uses its locked SDK
79
- projection. The development server and packager consume the same route
80
- destinations in both cases, so app imports do not change. Integrated
81
- initialization creates only app-owned files and never rewrites Arcane OS or SDK
82
- root configuration.
83
-
84
- The shared/Core development profile is a separate integrated-only scope selected
85
- with `--scope shared`. The SDK loads exactly
86
- `tools/integrated-development-provider.mjs` from the selected Arcane OS checkout
87
- as one process generation. This is a privileged host-development provider, not
88
- a source of portable SDK runtime bytes. That provider admits only one exact
89
- repository-relative focused `.test.mjs` through Arcane's canonical focused
90
- runner or Arcane's canonical development check. External workspaces cannot use
91
- the scope, and shared operations never enter app discovery, packaging, target
92
- planning, build, verification, or run paths. Provider bytes and filesystem
93
- identity are authenticated before and after the owned child operation; a
94
- generation change poisons that pairing and requires a new CLI process.
95
- Integrated app testing remains isolated to the selected `apps/<id>/test/`
96
- tree; it cannot recursively select Arcane root tests or another app's tests.
97
- External repositories retain their existing workspace-root plus selected-app
98
- test layout.
99
-
100
- ## Development and release serving boundary
101
-
102
- Arcane applications keep one browser-first plain HTML, CSS, and JavaScript
103
- baseline. A native target runs that same application and progressively enhances
104
- it through capability-gated Arcane Core access. Browser operation must not
105
- depend on Core being present. A feature that genuinely requires Core fails
106
- closed and explains its unavailability without breaking unrelated browser
107
- behavior or claiming that the capability exists.
108
-
109
- Rapid development uses `arcane dev`. The development server maps the selected
110
- application's canonical source tree and the live installed SDK/runtime routes.
111
- Each request reads the current saved source into the existing bounded response
112
- snapshot, so a browser refresh shows source changes without packaging, copying
113
- files into `dist`, or restarting the server. Restarting is not a content
114
- synchronization step; when a refresh is stale, first verify the command, URL,
115
- workspace, selected app, and resolved source route.
116
-
117
- Development is an intentionally fast feedback loop. Keep each increment small
118
- and independently understandable so its effect has one clear cause and a
119
- mistake can be isolated without untangling unrelated work. A development
120
- operation does not implicitly run tests, checks, packaging, builds, or release
121
- verification. The developer invokes a focused test or check deliberately at an
122
- explicit checkpoint; merely refreshing source does not trigger one.
123
-
124
- Executable development uses an Arcane-owned native development wrapper around
125
- the same source-serving browser surface. The wrapper is an escalated browser,
126
- not a packaged application: it loads current source files and adds only the
127
- selected application's declared, capability-gated local Arcane Core access.
128
- It preserves the browser behavior when Core is absent, fails closed for an
129
- unavailable native-only capability, and never silently substitutes a release
130
- tree. Starting or refreshing this wrapper does not package, copy to `dist`, or
131
- run tests automatically. The SDK must not describe native source development as
132
- available until this wrapper and its explicit capability boundary are actually
133
- implemented.
134
-
135
- Package and release verification use a separate explicit boundary. Run
136
- `arcane package` to generate and verify `dist/<id>`, then use
137
- `arcane run --target browser` to serve only that verified release. Distribution
138
- automatically runs the selected application's required tests before accepting,
139
- serving, or launching `dist` and fails closed on any test failure. The browser
140
- run command does not substitute source files. If source changes after
141
- packaging, the prior `dist` remains intentionally unchanged until the next
142
- explicit package operation. Never use packaged `dist` as the everyday
143
- development tree, and never treat source-serving behavior as evidence for the
144
- release artifact.
145
-
146
- ## App and release contract
147
-
148
- The first SDK version deliberately preserves Arcane's current repository-shaped
149
- URLs and release schema:
150
-
151
- ```text
152
- apps/<id>/arcane-app.json
153
- apps/<id>/arcane-package.json
154
- apps/<id>/index.html
155
- dist/<id>/ARCANE_APP_RELEASE.json
156
- ```
157
-
158
- The authored schema-2 descriptor is canonical for new apps and projects an
159
- exact schema-1 `arcane-package.json` for current consumers. Existing Arcane
160
- apps synthesize that descriptor from their schema-1 package plus the current
161
- native registry during migration.
162
-
163
- An external app's `arcane-packager.json` has three exact shared routes. They map
164
- the installed SDK runtime to `/arcane`, its vendored strong-type dependency to
165
- `/node_modules/strong-type`, and the SDK's `LICENSE`,
166
- `COMMERCIAL-LICENSE.md`, and `NOTICE` to `/licenses/arcane-os`. Development does
167
- not copy SDK runtime source into the app repository. Distribution materializes
168
- those exact locked SDK routes inside the portable artifact and verifies their
169
- immutable inventory, so the finished app has no Arcane OS runtime dependency.
170
-
171
- Release schema 1 and builder identity `arcane-app-packager-v1` remain unchanged
172
- because current Arcane native admission treats them as exact contracts. Native
173
- builders authenticate the schema-2 descriptor digest as a
174
- separate build input while exact v1 host artifacts remain unchanged.
175
-
176
- External repository delivery adds a distinct schema-1
177
- `arcane-app-release-bundle` envelope. Bundle creation accepts only a
178
- process-authenticated release receipt whose descriptor authority was an authored
179
- schema-2 `arcane-app.json`; a synthesized legacy descriptor remains valid for
180
- integrated packaging but cannot cross the external admission boundary. The
181
- archive contains exactly `ARCANE_APP_BUNDLE.json`, canonical `arcane-app.json`,
182
- `payload/ARCANE_APP_RELEASE.json`, and the release inventory beneath `payload/`
183
- in that order. The envelope adds no repository-only source or build tooling
184
- beyond that authenticated release inventory. Individual apps remain responsible
185
- for leak/source policy, and Arcane's source-free runtime gates remain separate.
186
-
187
- The byte contract is deterministic USTAR with regular 0644 files, zero owner
188
- ids and modification times, canonical UTF-8 paths and headers, exact zero
189
- padding, and exactly two terminal blocks, wrapped in one deterministic gzip
190
- member. NFC inventory paths use raw UTF-8 byte order, not host locale collation;
191
- the packager, bundle verifier, and Arcane importer share that ordering, while a
192
- pinned golden bundle digest runs across the supported Node and runner matrix.
193
-
194
- Verification parses the expanded stream without extraction, applies absolute
195
- size/cardinality and expansion-ratio ceilings, recompresses the stream to
196
- require the exact gzip encoding, and rejects appended bytes or concatenated
197
- members. Every source control, payload, staged archive, and verification input
198
- is opened no-follow as a single-link regular file, consumed at its recorded
199
- length with an EOF growth probe, and rechecked by handle and pathname identity.
200
- Every cumulative path prefix has one case-folded spelling and one file/directory
201
- kind; prefix topology conflicts and the complete portable Windows device-name
202
- set fail before creation or admission.
203
- The current SDK admits only the explicitly compatible `0.3.1` bundle
204
- generation and rejects zero-byte payload releases.
205
-
206
- Promotion retains any prior output as an identity-bound backup until the new
207
- pathname has passed a second exact-length digest and single-link identity check
208
- and its immutable receipt is bound. Pre-commit failure restores that backup
209
- only when both the promoted pathname and prior backup retain their respective
210
- full recorded identity tuples, pinned by their open handles. A replaced or
211
- in-place-changed output is never removed during rollback; it and the prior
212
- backup remain available for inspection. A missing or changed backup likewise
213
- causes rollback to preserve the valid promoted output rather than delete it.
214
- Post-commit backup or
215
- nonce-bound lock cleanup failure is surfaced as degraded cleanup and preserves
216
- the uncertain path for inspection. The receipt exposes
217
- artifact digest/bytes, descriptor canonical/file/package digests and bytes, and
218
- release manifest/policy/content digests, file count, and total payload bytes.
219
- These hashes prove internal consistency. Repository provenance or an
220
- independent signature plus an Arcane-owned authorization lock remains the
221
- separate installation authority.
222
-
223
- The reusable app-release workflow keeps caller checks and adapters in a
224
- `contents: read` build job. A fresh unprivileged job downloads the immutable
225
- upload by artifact id, checks the requested app id and complete identity with the
226
- exact called-workflow SDK, and alone supplies reusable outputs. Its conditional
227
- attestation job redownloads the same artifact id, repeats those checks against
228
- the post-upload outputs, and directly imports the dependency-free verifier from
229
- the trusted source checkout under supported Node 24 via the pinned
230
- `actions/setup-node` revision. No package-manager install, dependency
231
- resolution, caller checkout, or caller code runs while OIDC and
232
- attestation-write authority is present.
233
-
234
- ## Operation ownership
235
-
236
- An invocation defaults to one workspace, one app, one command, one target, one
237
- architecture, one format, and one signing profile. It acknowledges before long
238
- work, uses one `AbortController`, supervises child processes, and routes progress
239
- through one serialized owned event queue. Process streams apply pause/resume
240
- backpressure and heartbeats coalesce. Callback failure cancels owned work, drains
241
- the queue, and reaches the caller or CLI exit status. Packaging preserves prior
242
- output until verified replacement.
243
-
244
- Each normalized queue event is also mirrored exactly once through the shared
245
- `arcaneEvents` `EventManager`. That synchronous `event-pubsub` route is the
246
- canonical cross-cutting instrumentation surface, but it does not replace the
247
- owned asynchronous callback path or its backpressure. Time-travel history and
248
- DOM observation remain explicitly disabled unless a bounded diagnostic session
249
- enables them. See [event-manager.md](event-manager.md) for the record, redaction,
250
- DOM coverage, and effect-isolated playback boundaries.
251
-
252
- For `--scope shared`, the cardinality changes to one integrated workspace, one
253
- named operation, and either one exact test file or one development check. The
254
- same owned event queue and process supervisor provide acknowledgement, bounded
255
- stream delivery, heartbeat, cancellation, process-tree cleanup, and nonzero
256
- failure propagation. No app or target loop exists in that scope.
257
-
258
- ## Verification receipts
259
-
260
- Runtime verification binds the exact SDK version, canonical SDK source
261
- identity, runtime inventory, byte counts, and SHA-256 hashes. During the
262
- source-ownership migration it may additionally record imported Arcane OS
263
- provenance for compatibility bytes, but that field does not transfer canonical
264
- ownership. Packaging writes the full
265
- schema-1 release inventory to `ARCANE_APP_RELEASE.json`; its operation result
266
- returns a deeply immutable, process-authenticated receipt that binds the
267
- canonical location, app policy, complete inventory, content digest, and verified
268
- filesystem identities. The browser run path authenticates that receipt before
269
- serving it, and every native provider consumes release bytes through SDK-bound
270
- verified readers before verifying its app-scoped artifact. Windows and Linux
271
- retain artifact authority for same-process verification and launch. Persistent
272
- cross-process reuse still requires an authenticated Arcane broker; a path,
273
- timestamp, environment variable, or receipt file alone is not authority.
274
-
275
- The loopback server treats the mutable filesystem as an input, not as an
276
- immutable receipt. Before sending headers it reads each requested source,
277
- runtime, or packaged file into a bounded buffer, verifies the expected hash for
278
- receipt-bound files, and repeats the handle/path identity check. A response is
279
- therefore an exact verified byte snapshot even if another process writes during
280
- the request. Development serving is limited to 64 MiB per file and four active
281
- file responses, with a bounded wait queue.
282
-
283
- ## Native provider boundary
284
-
285
- The SDK implements protocol `arcane-native-build-plan/1` and the injected
286
- provider contract `arcane-native-builder/1`. Pairing is process-local; it never
287
- registers a mutable global provider or searches for a toolchain. For each
288
- supported native target, the CLI loads one fixed provider module from the
289
- explicit `--arcane-root` Arcane OS checkout. Provider code is bound to one
290
- process generation; if a pull changes any loaded provider module, the SDK fails
291
- closed and requires a fresh worker rather than combining new hashes with Node's
292
- cached old modules. One paired toolchain can perform this lifecycle:
293
-
294
- ```text
295
- doctor -> prepare -> plan -> build -> verify receipt -> run receipt
296
- ```
297
-
298
- The portable provider implements the lifecycle through verification and fails
299
- honestly on run because its result is a directory. Windows x64, Linux x64,
300
- Linux ARM64, and Android ARM64 implement same-process launch and owned
301
- cancellation when their compatible host/device requirements are present.
302
- Windows uses a retained per-build broker and authenticated host readiness. The
303
- Linux provider produces a verified amd64 or ARM64 DEB and runs a retained
304
- user-owned extraction without install or elevation. Portable, Windows, and
305
- Linux use the `unsigned-local-test` signing profile.
306
-
307
- The Android provider produces one development-signed APK. It contains no native
308
- library or ABI-specific payload, so the artifact is architecture-neutral; the
309
- `android-arm64` target instead binds the supported run path to one physical
310
- device with native ARM64 support. APK is the only Android format in this
311
- development provider. AAB, release signing, publishing, and update continuity
312
- remain outside it.
313
-
314
- The plan binds one explicit `toolchainRoot` and authenticated receipt, one app
315
- release root and receipt, its approved schema-2 descriptor digest, only its
316
- declared dependency releases, one non-overlapping output root, and one target,
317
- platform, architecture, format, and signing request. App source and workspace
318
- paths are withheld from the native provider. The provider copies release bytes
319
- through SDK-bound verified readers rather than accepting a mutable source path
320
- as authority. Build completion requires provider verification, and later
321
- verify/run calls receive the exact artifact receipt.
322
-
323
- The SDK `0.3.1` runtime requires Arcane `0.8.12` or newer. Compatibility
324
- is contractual rather than exact-version pinning: the prepared Core must meet
325
- the highest minimum declared by the runtime, selected app, and bundled app
326
- dependencies; keep each app's Arcane protocol generation; and provide every
327
- declared feature, capability, and method. Missing requirements stop before
328
- provider build; a newer compatible Core is accepted. Exact hashes
329
- remain integrity identities, not compatibility rules. The provider paths have
330
- been validated from independent workspaces. They do not copy proprietary source
331
- into the Arcane checkout.
332
-
333
- See [compatibility.md](compatibility.md) for the complete app and bundled-app
334
- admission rule and the required handling of breaking contract changes.
335
-
336
- Linux ARM64 shares the implemented Linux provider, focused tests, and a
337
- target-scoped remote evidence workflow. At Arcane revision
338
- `4382043c09285ea203aa6daba1732660966ac409`, that workflow proved native AArch64
339
- toolchain, DEB, host/Core/bridge, retained verification, sandboxed WebKit
340
- readiness, and owned process-group cancellation. The hardened Android path has
341
- exact-SHA physical ARM64/API 37 build, process/generation/nonce readiness,
342
- cancellation, uninstall, and absence evidence. Neither record establishes
343
- production signing, installation, publishing, update continuity, release
344
- acceptance, or production readiness.
@@ -1,36 +0,0 @@
1
- # Arcane application compatibility
2
-
3
- Arcane application compatibility is a capability contract, not an exact
4
- runtime-version pin. An app may run on a newer Arcane Core when the host meets
5
- all of the app's declared requirements.
6
-
7
- For the selected app and every declared bundled app, admission requires:
8
-
9
- - the requested target is declared by that app;
10
- - the host Core version is greater than or equal to
11
- `requirements.minimumCoreVersion`;
12
- - `requirements.arcaneProtocol` matches the host protocol generation;
13
- - every declared `requirements.features` entry is advertised by the host;
14
- - every declared `permissions.capabilities` entry is available; and
15
- - every declared `permissions.methods` entry is available.
16
-
17
- The effective Core floor for a build is the highest minimum declared by the
18
- SDK runtime, the selected app, and its complete bundled-app closure. The native
19
- build plan authenticates the host toolchain receipt and checks every member of
20
- that closure before a provider may read release bytes or mutate output.
21
-
22
- This permits normal non-breaking Arcane upgrades. For example, an app requiring
23
- Core `0.8.12` can run on `0.8.13` or `0.9.0` when the required protocol,
24
- features, capabilities, and methods are still present. A higher version does
25
- not override a missing contract.
26
-
27
- Breaking changes must be visible at the contract boundary. A host must not
28
- continue advertising an old protocol, feature, capability, or method when its
29
- meaning or guarantees are no longer compatible. It must instead change the
30
- protocol generation or contract identifier so admission fails closed before
31
- launch.
32
-
33
- Hashes and lock-file identities serve a different purpose. They establish
34
- which SDK runtime, release, toolchain, and artifact bytes were verified for one
35
- build state; they do not require the installed Arcane version to equal the
36
- app's minimum version forever.
@@ -1,294 +0,0 @@
1
- # Canonical SDK events and time-travel review
2
-
3
- `arcaneEvents` is the canonical synchronous SDK event authority. The module
4
- installs or reuses exactly one branded authority at `globalThis.arcaneEvents` in
5
- each JavaScript realm, even when the same source is loaded through duplicate
6
- module URLs. It is not a cross-frame, worker, process, native-host, or cloud bus.
7
-
8
- `EventManager` remains the isolated diagnostics API. `new EventManager()` and
9
- `createEventManager()` each create an independent `event-pubsub` bus whose
10
- `on()`, `emit()`, and `instrument()` handlers are strict: a synchronous listener
11
- failure propagates to that publisher. Use `arcaneEvents.subscribe()` and
12
- `createArcaneEventSource()` for canonical SDK semantic events instead.
13
-
14
- The installed global is an own, non-enumerable, non-writable, non-configurable
15
- data property. Its authority brand is
16
- `Symbol.for('arcane-os.arcane-events-authority')`, and both the brand value and
17
- public `protocol` are exactly `arcane-event-authority/1`. A later import reuses
18
- the object only when its property, brand, protocol, and required callable API
19
- descriptors are compatible. An inherited value, accessor, unbranded value,
20
- mutable descriptor, incompatible protocol, incomplete API, or failed install is
21
- rejected; the SDK never replaces or wraps a competing global.
22
-
23
- Import the dedicated host-neutral entry point:
24
-
25
- ```javascript
26
- import {
27
- arcaneEvents,
28
- createArcaneEventSource,
29
- createEventManager,
30
- projectArcaneDOMEvent,
31
- PLAYBACK_RECORD_EVENT
32
- } from 'arcane-os/event-manager';
33
- ```
34
-
35
- An SDK publisher owns one source handle for its lifetime and declares every
36
- semantic event type up front:
37
-
38
- ```javascript
39
- const controller={};
40
- const events=createArcaneEventSource(controller,{
41
- source:'app.editor',
42
- eventTypes:['document.save.completed']
43
- });
44
-
45
- const unsubscribe=arcaneEvents.subscribe('document.save.completed',occurrence=>{
46
- console.info('Saved',occurrence.detail.documentId);
47
- });
48
-
49
- const publication=events.dispatch(
50
- 'document.save.completed',
51
- Object.freeze({documentId:'example',document:liveDocument}),
52
- {
53
- operationId:'save-42',
54
- publicDetail:{documentId:'example'},
55
- cancelable:false
56
- }
57
- );
58
-
59
- projectArcaneDOMEvent(editorElement,publication.occurrence);
60
- unsubscribe();
61
- ```
62
-
63
- `createArcaneEventSource(owner,options)` is the public wrapper for
64
- `arcaneEvents.createSource(owner,options)`. `options` is the closed record
65
- `{source,eventTypes,onListenerError?}`. Each non-null object or function owner
66
- may have one active source, and the returned frozen handle exposes
67
- `{protocol,descriptor,source,instanceId,eventTypes,disposed,subscribe,on,once,
68
- addEventListener,removeEventListener,dispatch,dispatchEvent,dispose,destroy}`.
69
-
70
- `dispatch()` synchronously delivers one immutable `arcane-event-occurrence/1`
71
- to exact-type canonical subscribers, then an EventTarget-compatible view to the
72
- source's own listeners. The occurrence contains `occurrenceId`, `type`, `source`,
73
- `instanceId`, `operationId`, deeply frozen privacy-admitted `detail`,
74
- `cancelable`, live `defaultPrevented`, and `preventDefault()`. The richer
75
- compatibility detail remains local to the authority for source listeners and
76
- optional DOM projection; it is not placed on the canonical bus or in time-travel
77
- history.
78
-
79
- Source listeners retain EventTarget compatibility: function listeners receive
80
- the source owner as `this`, and the frozen compatibility view exposes that owner
81
- as both `target` and `currentTarget`. Already-frozen compatibility detail retains
82
- its identity. Other plain records and arrays are shallow-copied and frozen;
83
- rich host objects remain local and are not recursively frozen.
84
- EventTarget-shaped `addEventListener()` and `removeEventListener()` preserve
85
- native no-op admission for null or non-listener callbacks; strict `subscribe()`
86
- and `on()` still reject an invalid handler.
87
-
88
- Canonical delivery is observational. Every active listener runs in registration
89
- order. A listener failure publishes one privacy-safe
90
- `arcane.event.listener.error` occurrence and is reported through `reportError`
91
- or `console.error`; it does not undo committed domain work or make
92
- `dispatch()` throw. An optional source `onListenerError(error,errorOccurrence)`
93
- callback receives the raw failure and its canonical listener-error occurrence
94
- only at that owner-local boundary; `errorOccurrence` is `null` only when the
95
- secondary error occurrence itself could not be constructed. Subscriber
96
- promises are not awaited, so keep completion, backpressure, and asynchronous
97
- failure in the SDK-owned queue or operation that owns them. There is no second
98
- Promise-returning publication bus: `dispatch()`, cancellation admission, sticky
99
- state commits, and listener installation remain synchronous. Owned promises and
100
- `createEventQueue()` own asynchronous work, ordering, failure, and backpressure;
101
- an `AbortSignal` removes a subscription but does not claim that already-started
102
- provider, host, or queue work stopped.
103
-
104
- `arcaneEvents.subscribe(type,handler,{once=false,signal}={})` returns an
105
- idempotent unsubscribe function whose `.dispose` property is the same function.
106
- An already-aborted signal installs nothing, and abort removes the registration
107
- deterministically. Source `on()` follows the same lifecycle. EventTarget-shaped
108
- `addEventListener()`/`removeEventListener()` calls deduplicate by
109
- type/listener/capture. Calling a source's idempotent `dispose()` emits its final
110
- `arcane.event.source.disposed` occurrence, removes its registrations, and frees
111
- the owner to register a later source.
112
-
113
- Cancellation is synchronous and observational. For a cancelable occurrence,
114
- canonical or source listeners may call `preventDefault()`; `dispatch()` then
115
- returns `{occurrence,accepted:false}`. Callers decide whether cancellation gates
116
- their domain operation. `projectArcaneDOMEvent()` is a one-way compatibility
117
- projection: it creates one `CustomEvent`, adds the canonical identifiers to a
118
- frozen outer detail object, preserves any compatibility `source` value, exposes
119
- the canonical emitter as `arcaneSource`, propagates DOM cancellation back to the
120
- occurrence, and never republishes the DOM event into the authority. It returns `false`
121
- without dispatching when the occurrence is already canceled.
122
-
123
- The authority also retains `on`, `once`, `off`, `reset`, `emit`, `instrument`,
124
- and `forward` for legacy direct EventManager-style diagnostics. Those handlers
125
- are separate from canonical `subscribe()` registrations; `off()` and `reset()`
126
- cannot remove canonical or source-owned registrations. New SDK publishers must
127
- use source handles. Authority-level `dispatchEvent()` exists only as a deprecated
128
- EventTarget admission adapter for older `aiRuntimeEvents` callers.
129
-
130
- `aiRuntimeEvents` is itself deprecated. It is a frozen, state-free
131
- EventTarget-compatible view over the `AIRuntimeState` source registered with
132
- this authority; it has no listener registry, `EventTarget`, or lifecycle state
133
- of its own. New consumers use the focused AIRuntimeState subscription helpers
134
- or `arcaneEvents.subscribe()`.
135
-
136
- ## Stable authority failures
137
-
138
- `ARCANE_EVENT_ERROR_CODES` is frozen and maps every key below to the identical
139
- string value. Thrown authority errors expose that value as `error.code`:
140
-
141
- ```text
142
- ARCANE_EVENT_AUTHORITY_ACCESSOR_COLLISION
143
- ARCANE_EVENT_AUTHORITY_VALUE_COLLISION
144
- ARCANE_EVENT_AUTHORITY_DESCRIPTOR_MISMATCH
145
- ARCANE_EVENT_AUTHORITY_PROTOCOL_MISMATCH
146
- ARCANE_EVENT_AUTHORITY_API_MISMATCH
147
- ARCANE_EVENT_AUTHORITY_INSTALL_FAILED
148
- ARCANE_EVENT_SOURCE_INVALID
149
- ARCANE_EVENT_SOURCE_ALREADY_REGISTERED
150
- ARCANE_EVENT_SOURCE_DISPOSED
151
- ARCANE_EVENT_SOURCE_EVENT_TYPE_UNDECLARED
152
- ARCANE_EVENT_COMPATIBILITY_DETAIL_INVALID
153
- ARCANE_EVENT_OCCURRENCE_INVALID
154
- ARCANE_EVENT_OCCURRENCE_SEQUENCE_EXHAUSTED
155
- ARCANE_EVENT_SOURCE_SEQUENCE_EXHAUSTED
156
- ARCANE_EVENT_LISTENER_CALLBACK_FAILED
157
- ARCANE_EVENT_DOM_DETAIL_COLLISION
158
- ARCANE_EVENT_DOM_TARGET_INVALID
159
- ARCANE_EVENT_DOM_OPTIONS_INVALID
160
- ARCANE_EVENT_SUBSCRIPTION_TYPE_INVALID
161
- ARCANE_EVENT_SUBSCRIPTION_HANDLER_INVALID
162
- ARCANE_EVENT_SUBSCRIPTION_OPTIONS_INVALID
163
- ARCANE_EVENT_SUBSCRIPTION_SIGNAL_INVALID
164
- ARCANE_EVENT_DISPATCH_EVENT_INVALID
165
- ```
166
-
167
- Listener callback failure is observational: it appears as
168
- `ARCANE_EVENT_LISTENER_CALLBACK_FAILED` inside the frozen
169
- `arcane.event.listener.error` occurrence. Its frozen public detail is
170
- `{code:'ARCANE_EVENT_LISTENER_CALLBACK_FAILED',reason:'listener-threw',
171
- eventType,occurrenceId,source,instanceId,operationId}`. Source disposal publishes
172
- `arcane.event.source.disposed` with public detail
173
- `{reason:'source-disposed'}` rather than throwing from committed source dispatch.
174
-
175
- ## Enable a bounded, complete event stack
176
-
177
- Time-travel recording is disabled by default. With the flag off, the manager is
178
- only a pub/sub bus: it captures no history, source stack, or DOM activity.
179
-
180
- ```javascript
181
- const events=createEventManager({
182
- timeTravel:true,
183
- maxEvents:10_000,
184
- dom:{
185
- root:document,
186
- captureInputValues:false
187
- }
188
- });
189
- ```
190
-
191
- It can also be enabled around a diagnostic session:
192
-
193
- ```javascript
194
- arcaneEvents.enableTimeTravel({
195
- dom:{root:document,captureInputValues:false}
196
- });
197
-
198
- // Exercise the scenario.
199
-
200
- arcaneEvents.disableTimeTravel();
201
- const serialized=arcaneEvents.exportStack();
202
- ```
203
-
204
- While enabled, every isolated-manager event receives an immutable
205
- `arcane-event-stack/1` record containing the session and event ids, sequence,
206
- UTC and monotonic timestamps, source/category, correlation and causation ids,
207
- nested dispatch depth, a bounded payload snapshot, completion or failure
208
- outcome, and dispatch duration. Source stacks are `null` by default; explicitly
209
- set `captureStacks: true` only for a controlled local session. Stored strings,
210
- collections, object entries, nesting, source stacks, and error stacks remain
211
- bounded. The durable JSON shape is published as
212
- `arcane-os/schemas/event-stack.json`.
213
-
214
- The default event limit is 10,000 records. Recording retains the complete
215
- session until that limit. On the next attempted record, it appends exactly one
216
- `arcane.time-travel.overflow` marker, stops DOM observation, and disables
217
- recording. It never silently evicts a prefix or presents a partial tail as a
218
- complete session. Call `clearHistory()` before re-enabling recording. Tune
219
- `maxEvents`, `maxSnapshotDepth`, `maxSnapshotEntries`, and
220
- `maxSnapshotStringLength` for the diagnostic environment. The string limit has
221
- a minimum of 64 characters so generated structural markers remain importable.
222
- High-frequency
223
- pointer, touch, drag, scroll, and wheel events can reach the limit quickly.
224
- Arcane does not upload or persist a stack automatically.
225
-
226
- ## DOM observation
227
-
228
- When a DOM root is attached while time travel is enabled, capture-phase
229
- listeners record the standard keyboard, pointer, mouse, touch, form, focus,
230
- clipboard, drag, selection, and scroll interaction set. A `MutationObserver`
231
- records attribute, text, insertion, and removal mutations, including old values
232
- where the platform exposes them. Open shadow roots present at startup or found
233
- in inserted nodes are observed separately; composed events are deduplicated.
234
-
235
- Input values, node markup/text, and text-bearing event details are excluded by
236
- default. Password/autocomplete-password fields and elements beneath
237
- `data-arcane-private` stay redacted even when ordinary value capture is enabled.
238
- Keyboard text, composition/input `data`, arbitrary `detail`, and clipboard
239
- contents are not retained by the safe defaults. Mutation `value`, `srcdoc`,
240
- style, credential-like attributes, and every URL-bearing attribute are replaced
241
- with markers; the observed document URL is never retained. Raw added/removed
242
- node markup is replaced with a content-omitted marker unless
243
- `captureNodeMarkup: true` is explicitly selected. Event payload keys that look
244
- like credentials, tokens, cookies, passwords, secrets, or private keys are also
245
- redacted before history or export.
246
-
247
- `captureInputValues`, `captureEventDetails`, `captureNodeMarkup`, and
248
- `captureStacks` are separate, explicit diagnostic choices. They remain bounded,
249
- and private targets plus URL fields remain protected, but any enabled diagnostic
250
- content may still be sensitive. Treat recordings as local evidence and review
251
- them before sharing.
252
-
253
- Mutation observation is an audit backstop, not proof of every renderer state
254
- change. It cannot see closed shadow roots, cross-origin frames, external web
255
- content, CSSOM/canvas drawing, most property-only writes, native/kernel activity,
256
- or interactions that happened before instrumentation started. Use semantic
257
- `instrument()` events at SDK-owned mutation boundaries when exact intent and
258
- causation matter.
259
-
260
- ## Seek and playback
261
-
262
- `seek(sequence)` moves the diagnostic review cursor and emits
263
- `arcane.time-travel.seek`. It does not rewrite live DOM or application state.
264
- The safe default playback mode emits each immutable record on
265
- `arcane.time-travel.playback.record` for a debugger or review UI:
266
-
267
- ```javascript
268
- events.on(PLAYBACK_RECORD_EVENT,record=>reviewTimeline(record));
269
- await events.playback({stack:serialized,mode:'review',speed:2});
270
- ```
271
-
272
- `speed: 0` plays immediately; a positive value preserves monotonic recorded
273
- delays at that multiplier. Playback supports `AbortSignal` and emits an explicit
274
- completed, cancelled, or failed terminal event. Recording is suppressed during
275
- playback so replay cannot recursively add itself to the stack.
276
-
277
- `mode: 'events'` redispatches recorded event payloads to live subscribers. That
278
- mode can execute application effects and is only appropriate inside an isolated
279
- diagnostic harness with effectful subscribers replaced. The SDK does not
280
- synthesize trusted browser input, restore a prior DOM snapshot, resend native
281
- RPC, repeat provisioning, launch processes, write storage, or repeat network or
282
- other privileged effects.
283
-
284
- ## Browser delivery boundary
285
-
286
- The package entry point works directly in Node and through browser bundlers.
287
- The npm artifact bundles the exact `event-pubsub` and `strong-type` pair because
288
- `event-pubsub@6.1.0` uses a sibling-relative runtime import. Unbundled browser
289
- use must preserve that physical sibling layout and provide import-map entries
290
- for the public SDK entry and `event-pubsub`.
291
-
292
- The managed Arcane browser runtime ships the authenticated focused entry and its
293
- dependency closure. Its import map resolves `arcane-os/event-manager` exactly;
294
- query, fragment, and subpath variants are not alternate authority identities.