arcane-os 0.3.0 → 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 +27 -0
  2. package/README.md +86 -117
  3. package/bin/arcane-test.mjs +170 -46
  4. package/browser-runtime/ai/browser-speech-artifacts.mjs +887 -909
  5. package/browser-runtime/ai/browser-speech-providers.mjs +96 -152
  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 -146
  11. package/browser-runtime/ai/speech-worker-runtime.mjs +643 -363
  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 +1050 -427
  37. package/runtime/arcane/modules/AIProviderRuntime.js +658 -363
  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 +40 -62
  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 +112 -779
  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 -187
  120. package/docs/reference/ai/browser-speech-package-authority.json +0 -835
  121. package/docs/reference/ai/browser-speech.md +0 -1252
  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 -677
  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 -2960
  150. package/docs/reference/sdk-api.md +0 -6694
  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,677 +0,0 @@
1
- # Protocol and host architecture
2
-
3
- This is the deep reference behind the compact availability notes elsewhere.
4
- Application developers should start with the
5
- [availability and normalization guide](availability-and-normalization.md), call
6
- one documented API, and treat the protocols below as implementation detail.
7
-
8
- ## Layer map
9
-
10
- ```text
11
- application code
12
- |-- Node SDK API ----------------- arcane-cli-events/1 + SDK receipts
13
- |-- EventManager ----------------- synchronous bus + arcane-event-stack/1
14
- |-- browser-local AI ------------- WebGPU/WASM/Workers/DBOPFS; no Core grant
15
- `-- globalThis.Arcane
16
- |-- development host -------- development HTTP bridge
17
- |-- Microsoft NT native ----- WebView2 host bridge
18
- |-- Linux native ------------ WebKitGTK host bridge
19
- `-- Android native ---------- Android WebView message bridge
20
- |
21
- `-- Arcane Core/provider boundary
22
- |-- platform services
23
- |-- ArcaneOllama loopback service
24
- `-- explicitly selected cloud APIs
25
- ```
26
-
27
- Each downward boundary can add authority and platform capability. None can be
28
- inferred merely from a function existing in shared JavaScript.
29
-
30
- ## SDK package and CLI protocols
31
-
32
- The npm package API is ordinary Node.js ESM. The CLI and programmatic toolchain
33
- share one headless operation implementation. Long-running operations accept
34
- before blocking work, own their task, stream structured events with bounded
35
- backpressure, emit progress or heartbeats, support cancellation where the
36
- underlying operation can do so safely, and surface failure through rejection or
37
- a nonzero CLI status.
38
-
39
- Machine output uses `arcane-cli-events/1`. Native planning and providers use:
40
-
41
- - `arcane-target-adapter/1` for target adapters;
42
- - `arcane-native-build-plan/1` for immutable native plans;
43
- - `arcane-native-builder/1` for injected native builders;
44
- - `arcane-integrated-toolchain/1` for the fixed integrated shared/Core provider.
45
-
46
- These protocols normalize orchestration and evidence. They do not normalize a
47
- Windows EXE, Linux DEB, Android APK, and portable directory into the same
48
- artifact kind.
49
-
50
- Managed browser imports have three supported control-plane entrypoints. The CLI
51
- uses `arcane import-map`; Node callers use
52
- `executeOperation('import-map', options)` or
53
- `createToolchain(defaults).importMap(options)`. These are three routes to the
54
- same app-scoped operation, not three import-map formats. There is no exported
55
- `importMapApplication()` function, `generateImportMap()` function, or
56
- `arcane-os/import-map` package subpath.
57
-
58
- ## Central events and time-travel data
59
-
60
- `arcane-os/event-manager` is host-neutral JavaScript. Its live event path is
61
- synchronous, in-process `event-pubsub`; it does not select WebView2,
62
- WebKitGTK, Android, HTTP, Core, or a kernel boundary. Optional history uses the
63
- strict `arcane-event-stack/1` data format. That protocol names an immutable
64
- diagnostic document, not a network channel and not the `arcane/1` Core RPC
65
- protocol.
66
-
67
- Live listeners receive the original arguments. Recording separately snapshots
68
- payloads and metadata with explicit depth, entry, string, and history limits;
69
- redaction is enabled by default. Exported stacks can be moved between Node and
70
- browser hosts because `parseEventStack()` validates and canonicalizes the data
71
- before playback. Review mode emits immutable records, events mode deliberately
72
- re-emits recorded event types, and neither mode restores external host side
73
- effects or DOM state.
74
-
75
- <details>
76
- <summary>Event-stack identity, overflow, and trust boundary</summary>
77
-
78
- Each document carries `protocol`, `sessionId`, `createdAt`, and ordered
79
- `events`. Each record repeats the protocol/session and carries sequence,
80
- timing, nesting/causation, source/category, payload, metadata, status, and
81
- failure evidence. At `maxEvents`, the manager appends one terminal
82
- `arcane.time-travel.overflow` marker, disables recording, and stops DOM
83
- observation; this explicit marker is why a valid overflow document may contain
84
- `maxEvents + 1` records. Import is strict, rejects extra or unsafe structure,
85
- and grants no Core capability, app admission, or provider authority.
86
-
87
- </details>
88
-
89
- See [EventManager and time-travel review](event-manager.md) for the callable
90
- surface, DOM privacy defaults, playback modes, and recovery behavior.
91
-
92
- ## Browser runtime delivery
93
-
94
- External and modern integrated workspaces keep the same application URLs and a
95
- browser-standard import map. Each selected app owns
96
- `apps/<id>/modules/arcane.importmap.json`; the exact canonical JSON is also
97
- embedded in its HTML entry as a managed `<script type="importmap"
98
- data-arcane-import-map>`. The map follows `<base>` and precedes module scripts,
99
- classic scripts, and module preloads, so application code can use stable named
100
- imports such as:
101
-
102
- ```javascript
103
- import ollama from 'arcane/Ollama';
104
- ```
105
-
106
- The authenticated physical-v1 tree lives entirely beneath `arcane/`. SDK
107
- `0.3.0` projects it from two canonical release receipts:
108
-
109
- | Canonical receipt | Source authority and protocol | Receipt inventory |
110
- | --- | --- | --- |
111
- | `runtime/ARCANE_RUNTIME_RELEASE.json` | `sdk-canonical`; `arcane/1`; builder `arcane-sdk-runtime-v1` | 161 files; 4,159,000 bytes; content SHA-256 `5dab0c9cadd9e5ca97f90ab63ce755940318198d5b1efc0b7b666de4075302e9` |
112
- | `browser-runtime/ARCANE_SDK_BROWSER_RELEASE.json` | `arcane-os-sdk`; `arcane-sdk-browser-runtime/1`; builder `arcane-sdk-browser-runtime-v1` | 26 files; 9,548,478 bytes; content SHA-256 `0d41531e9a2d6ce97a357eeeebde5fbac8af59639a52f4f682717097b13dc6dc` |
113
-
114
- The runtime receipt is the current byte authority. Its Arcane OS
115
- `c540014afe69f14cf5ae60493b7295f36dbcec64` / bundle `0.8.12` record is
116
- `legacyProjection` provenance, not a second or newer runtime authority. The
117
- browser receipt binds `event-pubsub` `6.1.0`, `strong-type` `2.0.0`, and
118
- `@wllama/wllama` `3.6.0`, as well as the browser entry
119
- `arcane-os/event-manager`. Runtime dependencies stay under
120
- `arcane/dependencies/`; the SDK event and browser-AI closure stays under
121
- `arcane/sdk/`. This URL-key separation prevents runtime and SDK dependency
122
- versions from aliasing one another.
123
-
124
- Those two receipt inventories contain 187 entries in total. That sum is a
125
- release-inventory fact, not an import-map entry count and not an assertion about
126
- one maintained example. The `0.3.0` map deterministically roots every admitted
127
- top-level runtime ESM plus the authenticated SDK browser roots, then follows
128
- those roots for runtime entities and dependency compatibility. Application
129
- source imports do not select a fixed entry count. Its public operation receipt is the
130
- authority for the exact `imports`, `entryCount`, and `excludedModules`;
131
- reached-file traversal is internal and is not exposed in that receipt. The
132
- managed graph exposes `arcane-os/event-manager`, `arcane-os/ai/browser-wasm`,
133
- and `arcane-os/ai/browser-speech`; dependency compatibility mappings are added
134
- only when authenticated runtime or SDK root traversal observes them.
135
-
136
- The focused physical targets remain stable when their bindings are reached:
137
-
138
- | Browser specifier | Physical target |
139
- | --- | --- |
140
- | `arcane-os/event-manager` | `./arcane/sdk/event-manager.mjs` |
141
- | `arcane-os/ai/browser-wasm` | `./arcane/sdk/ai/browser-wasm.mjs` |
142
- | `arcane-os/ai/browser-speech` | `./arcane/sdk/ai/browser-speech.mjs` |
143
- | `event-pubsub` | `./arcane/sdk/dependencies/event-pubsub/index.js` |
144
- | `./node_modules/strong-type/index.js` | `./arcane/dependencies/strong-type/index.js` |
145
-
146
- There is no `arcane-os` package-root mapping, bare `strong-type` mapping, or
147
- catch-all `arcane/` prefix. Host-internal `CaseEvidenceIndexer.js` is explicitly
148
- excluded; classic scripts, workers, stylesheets, and other non-ESM assets use
149
- their documented URL or host loading contract rather than invented package
150
- bindings. Development serves the selected app plus the authenticated tree.
151
- Packaging copies the same map, app entry, and physical bytes into `dist/<id>`;
152
- targets never resolve through the consumer workspace's root `node_modules/`.
153
-
154
- `generateImportMap()` is an internal toolchain operation, not a package export.
155
- Its package path accepts the configured entry plus the deterministic included
156
- `.html`/`.htm` document inventory. One transaction writes the artifact and the
157
- same managed JSON into every admitted document. The receipt binds
158
- `documentPaths`, `documentCount`, and `files`: artifact first, configured entry
159
- second, then additional documents as `role:"document"`. The public CLI keeps
160
- its existing two-option command and supplies only the selected entry; packaging
161
- owns multi-page discovery.
162
-
163
- An external package and development server expose the authenticated runtime
164
- inventory at `/ARCANE_RUNTIME_PROJECTION.json`:
165
-
166
- ```javascript
167
- {
168
- schemaVersion: 1,
169
- kind: 'arcane-app-runtime-projection',
170
- sdkVersion,
171
- pathPrefix: 'arcane/',
172
- fileCount,
173
- totalBytes,
174
- contentSha256,
175
- files: [{path, bytes, sha256}]
176
- }
177
- ```
178
-
179
- The projection contains public paths relative to its declared
180
- `pathPrefix:'arcane/'` (for example, `modules/...` and `sdk/...`), byte lengths,
181
- and SHA-256 values and is itself bound by the packaged release inventory. It does
182
- not expose the private `/ARCANE_APP_RELEASE.json` or replace the underlying
183
- runtime/browser receipts. Missing, changed, forged, duplicated, or internally
184
- inconsistent projection data fails `ARCANE_RUNTIME_PROJECTION_INVALID`.
185
-
186
- External `validateWorkspace()` results also expose a frozen `sdkInstallation`
187
- authority with exactly `dependencyName`, `packageSource`,
188
- `canonicalPackageRoot`, `packageName`, `packageVersion`, `runtimeRoot`,
189
- `browserRuntimeRoot`, `runtimeManifest`, and `browserRuntimeManifest`. A
190
- workspace may use the canonical dependency name or one exact npm alias such as
191
- `npm:arcane-os@0.3.0`; the physical package manifest must still identify
192
- exactly as `arcane-os@0.3.0`. Canonical-plus-alias duplicates, multiple aliases,
193
- links/junctions, indirect package roots, or version drift fail closed.
194
-
195
- The imported module can be pure browser logic, standard-Web-API logic, or a
196
- client of `globalThis.Arcane`. Import-map resolution is not a new Arcane wire
197
- protocol, Core capability, network authority, or provider fallback. Import
198
- transport and host RPC remain separate layers.
199
-
200
- The canonical integrated-legacy Arcane OS root is the documented exception. It
201
- retains its physical `/arcane` and `/node_modules/strong-type` routes, returns
202
- an `integrated-legacy` skip receipt, and does not create the managed map pair.
203
-
204
- <details>
205
- <summary>Refresh lifecycle and two-file commit behavior</summary>
206
-
207
- Scaffolding (`new` and `init`) creates the map. `dev` refreshes once before
208
- binding. Non-dry-run `package`, browser `build`, and paired native packaging
209
- refresh before collecting source. `test`, `check`, `verify`, `bundle`, and
210
- browser `run` do not refresh. Dry-run packaging/build validates an existing map
211
- without rewriting it, and `import-map` itself has no supported dry-run.
212
-
213
- Generation stages the artifact and HTML entry beside their destinations,
214
- checks directory and file identity under the workspace-operation lock, and
215
- uses backups to restore the prior pair after a handled pre-commit failure.
216
- Success reports `committed: true` and SHA-256/byte-length records for both
217
- files. Cleanup failures after commit remain warnings on the valid receipt;
218
- packaging rejects them rather than publishing ambiguous state. This is a
219
- bounded handled-error transaction, not a claim of one filesystem-atomic rename
220
- for both files and not a durable crash journal.
221
-
222
- No app watches, polls, downloads, or self-updates this map. An active operation's
223
- heartbeat is event telemetry only and never regenerates browser state.
224
-
225
- </details>
226
-
227
- <details>
228
- <summary>SDK 0.3.0 browser-runtime admission and exact receipt fields</summary>
229
-
230
- `arcane.lock.json.sdkBrowserRuntime` persists the trusted manifest path,
231
- `manifestSha256`, `contentSha256`, `builder`, `sdkVersion`, and `source` record.
232
- For SDK `0.3.0`, the manifest itself records:
233
-
234
- ```text
235
- manifest: node_modules/arcane-os/browser-runtime/ARCANE_SDK_BROWSER_RELEASE.json
236
- fileCount: 26
237
- totalBytes: 9548478
238
- contentSha256: 0d41531e9a2d6ce97a357eeeebde5fbac8af59639a52f4f682717097b13dc6dc
239
- builder: arcane-sdk-browser-runtime-v1
240
- sdkVersion: 0.3.0
241
- source.protocol: arcane-sdk-browser-runtime/1
242
- source.browserEntry: arcane-os/event-manager
243
- ```
244
-
245
- The verifier computes `manifestSha256` over the exact installed manifest and
246
- binds that value in its process-local receipt and the workspace lock; it must
247
- not be substituted with `contentSha256`. The `source` record also binds the
248
- `arcane-os-sdk` authority/repository and the exact `event-pubsub` 6.1.0,
249
- `strong-type` 2.0.0, and `@wllama/wllama` 3.6.0 package identities. Before a
250
- workspace tree is admitted, the same-process verifier returns
251
- `schemaVersion`, `kind`, `canonicalLocation`, `rootIdentity`, `manifestPath`,
252
- `manifestSha256`, `manifestIdentity`, `builder`, `sdkVersion`, `source`,
253
- `files`, `fileCount`, `totalBytes`, `contentSha256`, `identities`,
254
- `sourceIdentities`, and `directories`. Those object-identity-bound verifier
255
- receipts are authority inside the issuing process; reconstructing the same JSON
256
- does not recreate authority.
257
-
258
- </details>
259
-
260
- ## Portable AI provider runtime
261
-
262
- Application code should select a normalized role, not an internal protocol.
263
- The exported
264
- [`getAIProviderRuntime()` singleton](runtime-modules.md#aiproviderruntimejs)
265
- comes from authenticated runtime bytes and owns independent `llm`, `stt`, and
266
- `tts` selections. SDK `0.3.0` ships browser-WASM LLM and browser
267
- speech provider/2 adapters and also adapts selected legacy OpenAI LLM/STT/TTS,
268
- Core-backed Ollama LLM, and admitted Core speech STT/TTS routes into provider/2;
269
- other native, Core, or cloud routes require an externally supplied compatible
270
- adapter. The singleton itself is not an authentication or capability token. It
271
- normalizes inspection, model authority,
272
- load/unload/dispose, cancellation, stream cleanup, status, and startup
273
- barriers. Each selected provider retains its real execution requirements.
274
- `localOnly` fails closed, and failure in one role never authorizes a Core,
275
- cloud, or different-provider fallback.
276
-
277
- For a browser-only LLM,
278
- [`arcane-os/ai/browser-wasm`](ai/browser-wasm.md) exposes `createArcaneAI()`
279
- and an adapter into the same provider-neutral lifecycle. For browser speech,
280
- [`arcane-os/ai/browser-speech`](ai/browser-speech.md) creates independent
281
- Whisper STT and Kokoro TTS providers that register directly with the normalized
282
- runtime. The SDK supplies mechanism; applications retain model/runtime choice,
283
- provenance, licenses, prompts, tools, voices, and disclosure policy.
284
-
285
- ### Browser-WASM LLM lifecycle
286
-
287
- The shipped browser receipt contains the authenticated Wllama JavaScript/WASM
288
- engine and its provider/cache/controller mechanism. It contains no model
289
- weights, default model catalog, CDN fallback, native provider, speech model, or
290
- application profile. The caller supplies each model as a source authority with
291
- a nonempty ordered file list, so monolithic and split GGUF models use the same
292
- contract. HTTPS redirects are followed and the final HTTPS URL is recorded.
293
- Exact bytes are bound only by the optional expected byte lengths and SHA-256
294
- values whose matching fieldwise security checks are enabled.
295
-
296
- On load, the DBOPFS store admits all ordered members and commits the completion
297
- manifest last. A normal cache miss may fetch only the caller-supplied immutable
298
- HTTPS sources; `offline:true` performs no model request and admits only a
299
- compatible completed cache, otherwise it rejects with
300
- `ARCANE_AI_MODEL_OFFLINE_MISS`. Unload releases the active Wllama session but
301
- does not silently delete the app-owned cache.
302
-
303
- SDK `0.3.0` requires WebGPU. Load requests full offload with exactly 99,999 GPU
304
- layers and admits the model only after observing an adapter, full layer offload,
305
- buffer and queue work, and a settled fence. `navigator.gpu` presence alone is
306
- not readiness. There is no CPU fallback, partial-offload success mode, or
307
- silent switch to native/Core/cloud inference.
308
-
309
- ### Browser speech lifecycle
310
-
311
- The browser-speech package contains plain-JavaScript authority, DBOPFS store,
312
- provider, client, and Worker machinery. It redistributes no Whisper, Kokoro,
313
- ONNX, model, voice, third-party license, or corresponding-source payload.
314
- Default warn-first integrations use `createBrowserSpeechAuthority()` with a
315
- version-pinned npm/package runtime entry and optional upstream `wasmPaths`;
316
- the selected runtime then downloads models and voices through its normal
317
- provider fetch and browser cache behavior after explicit `load()`.
318
-
319
- `createBrowserSpeechArtifactGraph()` remains the explicit secure/offline option.
320
- It declares one caller-selected immutable closure with an explicit entrypoint
321
- and every auxiliary ESM, WASM, model, data, and voice file bound by canonical
322
- path, materialized media type, optional source media type, byte length, SHA-256,
323
- immutable starting source/revision, optional redirect-final-origin inventory,
324
- license declaration, and canonical graph identity.
325
-
326
- Graph construction rejects ambiguous paths and routes, mutable source
327
- authorities, undeclared or unmatched static imports, dynamic imports, fetches,
328
- Cache Storage opens, module Workers, undeclared executable-string construction,
329
- and incomplete file reachability. `edges.cacheOpens[]` binds the exact module,
330
- occurrence, policy, cache name, and readable non-JavaScript target paths. The
331
- two admitted transforms are the exact audited `Function("return this")()`
332
- compatibility site and typed-array constructor sites later bound to intrinsic
333
- typed-array prototypes.
334
-
335
- A source download rejects redirects by default. A file may opt in with a
336
- nonempty, graph-identity-bound `redirectFinalOrigins` inventory; only that file
337
- uses Fetch redirect following, and the final response must expose one declared
338
- HTTPS origin without credentials or a fragment. The immutable starting URL
339
- remains the source authority, and the final path, query, or signed/expiring URL
340
- is never persisted or admitted as authority. Fetch exposes only the final CORS
341
- response, so browser code cannot inspect or authenticate intermediate redirect
342
- hops. The store then checks the declared source media type, exact length, and
343
- SHA-256, persists and rehashes every file, rescans the closed module graph, and
344
- commits the completion manifest last.
345
-
346
- A valid warm admission performs no source request; it rehashes and rescans every
347
- cached file and returns `artifact-graph-dbopfs-cache-verified`. Strict
348
- `offline:true` never calls the source fetch function and returns only
349
- `artifact-graph-offline-dbopfs-cache-verified`; a miss rejects with
350
- `ARCANE_AI_ARTIFACT_GRAPH_OFFLINE_CACHE_MISS` /
351
- `artifact-graph-offline-cache-miss`. Cold and warm admissions are exactly
352
- `artifact-graph-network-dbopfs-verified` and
353
- `artifact-graph-dbopfs-cache-verified`. Both cached paths bind redirect origins
354
- and source media type through graph/manifest identity but never reuse a prior
355
- final URL.
356
-
357
- Every admission then uses module-captured native Blob URL functions, ignoring
358
- the legacy caller `objectUrlFactory`, and reads back each unique `blob:` URL to
359
- verify its exact identity, media type, byte length, and SHA-256 before
360
- execution. A fresh cryptographic guard capability binds every rewritten graph
361
- call for that materialization; it is not caller input, persisted authority, or
362
- part of the graph identity.
363
-
364
- The speech Worker establishes a private `MessageChannel` on its first load and
365
- routes subsequent request, progress, and cancellation settlement through that
366
- port. In explicit `secure:true` graph mode, scanned runtime edges are rewritten
367
- through one authenticated guard.
368
- Fetch and each declared cache-open edge can read only exact graph routes backed
369
- by already verified object URLs; raw fetch/cache calls and cache writes reject.
370
- The Worker also denies Function-family constructor escape, string timers,
371
- IndexedDB, OPFS, and raw `BroadcastChannel`, `EventSource`, `RTCPeerConnection`,
372
- `ShadowRealm`, `SharedWorker`, `WebSocket`, `WebSocketStream`, `WebTransport`,
373
- `Worker`, `XMLHttpRequest`, `eval`, and `importScripts` capability. Declared
374
- nested module Workers start through the SDK role Worker and receive the same
375
- authenticated graph. Default warn-first operation uses the direct runtime/model
376
- authority instead; these capability restrictions are not installed and the
377
- selected upstream runtime keeps ordinary browser fetch/cache behavior. An exact
378
- secure-graph runtime request alias, including Kokoro's audited
379
- mutable voice request, is a local route to caller-authenticated bytes and is
380
- never a source or network authority.
381
-
382
- Worker operations use `arcane-ai-speech-worker/1`. The public Worker client
383
- admits only `load`, `use`, `status`, `unload`, and `dispose`; the transport host
384
- additionally admits only its internal `cancel` control. Every other operation
385
- rejects with code `ARCANE_AI_INVALID_REQUEST`, message
386
- `The speech worker operation is not part of its protocol.`, and role-specific
387
- reason `stt-worker-operation-unknown` or `tts-worker-operation-unknown`.
388
- Failures use the separate
389
- `arcane-ai-speech-worker-error/1` envelope. Its exact own-key set is
390
- `code,message,protocol,reason`, all four must be data properties, and its
391
- registered code, fixed message, reason, role, and operation must agree. A
392
- foreign, incomplete, extra-keyed, accessor-bearing, cross-role, or
393
- cross-operation error envelope is rejected and terminates that role Worker.
394
- Nested module Workers use
395
- `arcane-ai-browser-speech-artifact-module-worker/1` and report bootstrap
396
- rejection only as `artifact-module-worker-bootstrap-rejected`.
397
-
398
- The exact redirect and source-media error registry is published in the
399
- [browser-speech reference](ai/browser-speech.md#graph-reasoncode-rule); graph
400
- errors retain the mechanical exact code pairing
401
- `ARCANE_AI_` plus the uppercased, underscore-normalized reason.
402
-
403
- Kokoro is configured through `namespace.env.wasmPaths`; Transformers is
404
- configured through `namespace.env.backends.onnx.wasm.wasmPaths`. Warn-first
405
- mode may use a caller-selected version-pinned upstream directory and preserves
406
- the runtime's browser cache. Secure graph mode uses materialized runtime files
407
- and its verified outer cache fields. Optional `numThreads` is caller-owned and
408
- Transformers-STT-only; a Kokoro declaration rejects with
409
- `ARCANE_AI_KOKORO_ENV_NUM_THREADS_FIELD_NOT_EXPOSED` /
410
- `kokoro-env-num-threads-field-not-exposed`. Missing or rejected namespace
411
- shapes fail closed with distinct `*-unavailable` and
412
- `*-assignment-rejected` reasons for each verified setting; the Worker never
413
- substitutes a different namespace. The caller also owns dtype, STT input sample
414
- rate, TTS output sample rate, default voice, and the complete voice inventory;
415
- the SDK selects no hardware default, runtime, model, or fallback.
416
-
417
- The SDK is not the distributor of the selected upstream speech packages or
418
- provider assets and does not republish their legal/source payloads. The
419
- component record at `browser-runtime/ai/ARCANE_AI_BROWSER_SPEECH_COMPONENTS.json`
420
- documents resolution only; it is not an execution or publication gate.
421
-
422
- Whisper `stt` and Kokoro `tts` each own catalog, inspect, status, load, request,
423
- unload, and dispose state. They load, cancel, unload, fail, and recover
424
- independently from the LLM and from one another. Cancellation after Worker use
425
- begins terminates that role's Worker slot and returns the provider to unloaded;
426
- a later use must load it again. If shared STT `Blob` decoding is cancelled
427
- before Worker use, the request rejects while the loaded provider remains ready.
428
- Speech failure neither disables text chat nor retries through another local,
429
- native, or cloud provider. The provider/Worker layer is event-neutral: it
430
- exposes promises, `AbortSignal`, precise lifecycle/status records, and one
431
- caller progress callback, but owns no event bus or listener registry. Progress
432
- is the provider-neutral record
433
- `{phase,completed,total,unit,heartbeat}`; role is encoded in Worker phase names,
434
- not added as a second field.
435
-
436
- ### Persistent chat and document context
437
-
438
- The SDK runtime owns
439
- [`DBOPFSDocumentLibrary`](runtime-modules.md#dbopfsdocumentlibraryjs),
440
- [`DocumentLexicalSearch`](runtime-modules.md#documentlexicalsearchjs), and
441
- [`PersistentAIChatSession`](runtime-modules.md#persistentaichatsessionjs).
442
- Document bootstrap is explicit and schema-driven, commits a completed
443
- generation last, and returns bounded search results with partial read failures
444
- disclosed. `evaluate()` can instead score a caller-owned source set without
445
- persisting its bodies, under separate corpus/scoring/output/document budgets.
446
- A chat session never searches the corpus unless the application
447
- deliberately wires a document context builder into the request; generated
448
- document context remains labeled untrusted.
449
-
450
- Persistent chat maintains bounded live model context plus `ChatEntity`
451
- history/memory according to the caller's persistence choice. A turn with
452
- `persist:false` remains coherent in the live session without entering durable
453
- history or memory. `createArcaneAI(...).createChatSession(options)` binds the
454
- session and automatic memory work to that same selected LLM controller; it does
455
- not select a second provider or storage fallback.
456
-
457
- ### Cancellation and structural tools
458
-
459
- Cancellation is part of the provider lifecycle, not just a UI decision.
460
- `AbortSignal`, the normalized role cancel operation, and stream-handle
461
- `cancel(reason)` propagate to the selected provider. Browser-WASM inference
462
- requires positive llama cancellation acknowledgement when cancellation is
463
- required. Browser speech cancellation terminates a Worker only after Worker use
464
- has begun; cancellation during shared browser decoding leaves the loaded Worker
465
- ready. Unload always cancels active role work before releasing that role's
466
- execution state, and superseded late results are rejected rather than committed
467
- or retried through another provider.
468
-
469
- Interactive request ownership is latest-request-wins independently for each
470
- role. A new valid request that reaches admission aborts the active role request
471
- and waits for its provider promise settlement; stream replacement additionally
472
- requires confirmed bounded handle cleanup. Only the newest waiting request may
473
- start after settlement, and request-specific generations prevent superseded
474
- callbacks from clearing or restoring newer state. The runtime revalidates
475
- selected-provider readiness and never reloads, switches, or falls back
476
- implicitly. Generic provider-promise settlement is not a claim that underlying
477
- work stopped; only a provider's documented positive acknowledgement or
478
- destructive worker teardown can prove that stronger fact.
479
-
480
- `startAIRuntime({startTranscription:false})` is the default startup boundary for
481
- STT. It declines to request a startup STT load; it does not unload a role already
482
- started through another explicit lifecycle action. A selected unloaded
483
- transcription provider remains selected and unloaded until a user lifecycle
484
- intent or explicit `startTranscription:true` opt-in asks the provider owner to
485
- load it. Neither state observation nor either shared speech component imports a
486
- model or selects a fallback. `speech.html` and `voice-transcription.html` consume
487
- one shared `createSTTActivationController()` contract for selected, unloaded,
488
- loading, unloading, error, and ready presentation plus cancelable user intent.
489
- Both keep capture fail-closed until sticky STT state is exactly ready.
490
-
491
- Each shared speech component owns an `AbortController` for its STT request and
492
- passes its signal through `AI.fetchSTT()`. `voice-transcription.html` also adds
493
- that signal to the existing injected `transcribe(file,context)` callback
494
- context. Cancel, readiness loss, superseding capture, and component teardown
495
- abort the owned signal and suppress late delivery. Whether the provider's
496
- underlying computation stops remains governed by its own cancellation contract.
497
- User TTS unmute calls `AI.setSpeechMuted(false)` before
498
- or with its load intent so the runtime records the unmuted lifecycle preference;
499
- mute calls `AI.setSpeechMuted(true)`, cancels active synthesis, and unloads TTS.
500
- The selected TTS model catalog owns `defaultVoice`. AI.js uses a saved OpenAI
501
- voice only for the OpenAI route and never forwards it to Core or browser Kokoro.
502
-
503
- LLM tool calls are structural result data only. The SDK never executes a
504
- handler. The application owns schema validation, authorization, side-effect
505
- policy, dispatch, and the matching tool-result turn.
506
-
507
- <details>
508
- <summary>Portable AI protocol disclosure</summary>
509
-
510
- The normalized runtime protocol is `arcane-ai-runtime/2`; registered adapters
511
- implement `arcane-ai-provider/2` and must prove matching model authority before
512
- load. The browser-WASM component receipt is `arcane-ai-browser-wasm/2`; its
513
- direct controller adapter uses `arcane-ai-adapter/1`, and
514
- `adaptV1LlmProvider()` projects that surface into the provider/2 LLM role.
515
- Browser speech stores identify themselves as
516
- `arcane-ai-browser-speech-artifacts/1`. Legacy authorities retain
517
- `arcane-ai-model-authority/1`. Authenticated browser-speech graphs use
518
- `arcane-ai-browser-speech-artifact-graph/1`, kind
519
- `browser-speech-authenticated-artifact-graph`, and a canonical SHA-256 graph
520
- identity. Those identifiers describe validation and lifecycle contracts; none
521
- is by itself a capability grant, publisher-authenticity claim, or complete
522
- cache receipt.
523
-
524
- These identifiers normalize lifecycle records. They do not erase provider
525
- availability: browser providers still require their browser capabilities,
526
- native providers still require an admitted host and Core method, and cloud
527
- providers still require explicit selection, network policy, and credentials.
528
-
529
- </details>
530
-
531
- ## Arcane application protocol
532
-
533
- `globalThis.Arcane.protocol` is `arcane/1`. The shared API wraps transport
534
- selection, request ids, JSON-safe values, promise settlement, `Arcane.Error`,
535
- and renderer events. The current transport snapshot is synchronous:
536
-
537
- ```javascript
538
- const {connected, transport, native, managedLocalAI} =
539
- globalThis.Arcane.runtime.current();
540
- ```
541
-
542
- Transport values are `webview2`, `webkitgtk`, `android-webview`,
543
- `development-http`, and `standalone`. `connected` means a callable transport
544
- was initialized. It does not prove that Core answered, the method is admitted,
545
- or a dependency is ready.
546
-
547
- ## Native host transports
548
-
549
- ### Microsoft NT / WebView2
550
-
551
- The renderer uses the WebView2 host messaging surface. The host binds one app
552
- identity and native policy to the session before Core dispatch. Microsoft NT
553
- can expose managed-service and privileged platform operations that do not exist
554
- in an ordinary browser.
555
-
556
- ### Linux / WebKitGTK
557
-
558
- The renderer uses the WebKitGTK host bridge with the same application-facing
559
- `Arcane` protocol. Linux can implement the same normalized methods through
560
- different host code. Some administrator-owned service settings intentionally
561
- return unsupported/manual guidance rather than imitating Microsoft NT mutation.
562
-
563
- ### Android / Android WebView
564
-
565
- Android injects a main-frame, origin-bound bridge for the packaged application.
566
- Its generated registry binds application identity, package version, entry,
567
- grants, and method policy. Android exposes a narrower surface, including an
568
- admitted user-managed local-AI chat projection where configured. Desktop model
569
- management is not projected merely because a user-managed Ollama listener is
570
- reachable.
571
-
572
- ### macOS
573
-
574
- No macOS target, native bridge, Core host, artifact, or run contract is exposed
575
- by this SDK version. A browser may still run browser-only application code, but
576
- that does not create a native Arcane host or satisfy a native capability.
577
-
578
- ## Development and remote HTTP transport
579
-
580
- The development HTTP bridge makes the same application-facing request shape
581
- available without pretending the browser is a native host. It is a development
582
- transport, not a production isolation or authority boundary. A remotely
583
- operated client can use an expressly configured web transport only when the
584
- host, origin, application identity, and policy admit it; Arcane does not silently
585
- swap native calls to arbitrary remote HTTP endpoints.
586
-
587
- When transport changes while the public method remains the same, request
588
- settlement and public errors stay normalized. Host-specific availability and
589
- result detail remain documented by the method.
590
-
591
- ## Core dispatch and capability admission
592
-
593
- The host binds the caller's application identity. Core checks the exact method,
594
- required capability, allowed application type/id, privilege, mutation
595
- exclusivity, request bounds, and relevant package policy. Renderer-supplied app
596
- ids or grants never replace that bound identity.
597
-
598
- `Arcane.capabilities.list()` is the Core-side application preflight. It reports
599
- current grants and admitted methods but does not reserve authority for a later
600
- call. Each call is checked again.
601
-
602
- ## Arcane Ollama protocol path
603
-
604
- The safe application path is:
605
-
606
- ```text
607
- renderer Ollama.js or Arcane.ollama
608
- -> arcane/1 host request
609
- -> Core capability and package-policy admission
610
- -> managed ArcaneOllama loopback service
611
- -> bounded Ollama HTTP operation
612
- ```
613
-
614
- Applications never connect directly to `localhost:11434`. Core owns loopback
615
- endpoint selection, method admission, request/response limits, stream ids,
616
- chunk events, model-policy checks, native resource admission, and managed
617
- mutation workflows.
618
-
619
- Direct Ollama methods preserve the bounded provider-native success envelope.
620
- Arcane normalizes the outer promise/error and stream lifecycle. `chatText`,
621
- `generateText`, and `readiness` are helper-level normalizers.
622
-
623
- ## Explicit cloud provider path
624
-
625
- `arcane/AI` can use an explicitly selected and configured cloud
626
- profile over HTTPS. That path is not Core transport fallback. The module adapts
627
- the selected provider into its high-level application behavior, while provider
628
- diagnostics and optional fields can remain provider-specific. Native policy and
629
- network policy still govern a native renderer's outbound access.
630
-
631
- Local failure never authorizes cloud disclosure. The user or owning application
632
- must select and configure the cloud provider explicitly.
633
-
634
- ## Events, streaming, and cancellation
635
-
636
- Renderer-visible Core events are listed in
637
- [the Arcane event reference](core/arcane-events.md). Durable
638
- `transport.ready` and `core.ready` completions can be observed after the fact
639
- with `Arcane.events.when()`. Ordinary progress, stream, terminal, and appearance
640
- events are future-only.
641
-
642
- Ollama streaming correlates chunks to the originating request. A renderer
643
- abort or timeout can stop observation without proving that a non-cooperative
644
- host mutation stopped. Method guides state whether Core cooperatively cancels,
645
- whether partial provider state can remain, and which status call must be
646
- refreshed before retry.
647
-
648
- ## Cross-kernel normalization boundary
649
-
650
- The common contract ends where platform truth must remain different:
651
-
652
- - API names, promise/error behavior, admission, request bounds, and public
653
- operation events are normalized;
654
- - host availability, privilege model, installation/service mechanism, native
655
- artifact kind, and some diagnostic/result fields remain platform-specific;
656
- - unsupported platforms fail or return a documented unsupported state; they do
657
- not run an unrelated browser implementation as a substitute;
658
- - this SDK version admits a selected checkout and Core only after the current
659
- native plan's exact protocol, version, feature, capability, method, provider,
660
- and identity-bound receipt checks all pass;
661
- - that current-build admission does not promise that a future SDK will accept
662
- this Core or that this SDK will accept a future Core.
663
-
664
- ## Receipt and generation boundaries
665
-
666
- SDK runtime, app releases, import-map artifact/entry pairs, bundles, native
667
- plans, providers, and artifacts use identity-bound receipts. The import-map
668
- receipt binds each committed relative path, byte length, and SHA-256 in
669
- addition to its exact imports, entry count, exclusions, and cleanup state. A
670
- runtime or release receipt binds the exact location, filesystem identity,
671
- bytes/inventory hashes, policy, toolchain, platform/architecture, signer/trust
672
- result where applicable, and generation. Mutation invalidates the receipt
673
- before bytes or authority change.
674
-
675
- Process-local receipts do not authorize reuse across Shell, Core, providers, or
676
- other processes. Cross-process reuse requires an authenticated shared host or
677
- broker with retained handles and peer-process/generation binding.