arcane-os 0.1.0 → 0.1.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 (31) hide show
  1. package/NOTICE +10 -0
  2. package/browser-runtime/ARCANE_SDK_BROWSER_RELEASE.json +80 -4
  3. package/browser-runtime/ai/ARCANE_AI_BROWSER_WASM_COMPONENTS.json +69 -0
  4. package/browser-runtime/ai/browser-wasm-llm-provider.mjs +1151 -0
  5. package/browser-runtime/ai/browser-wasm.mjs +44 -0
  6. package/browser-runtime/ai/browser-wllama-runtime.mjs +390 -0
  7. package/browser-runtime/ai/internal/sha256.mjs +166 -0
  8. package/browser-runtime/ai/model-controller.mjs +581 -0
  9. package/browser-runtime/ai/wllama/LICENCE +21 -0
  10. package/browser-runtime/ai/wllama/index.mjs +3494 -0
  11. package/browser-runtime/ai/wllama/llama.cpp-LICENSE +21 -0
  12. package/browser-runtime/ai/wllama/wllama.wasm +0 -0
  13. package/docs/publishing.md +23 -18
  14. package/docs/reference/README.md +9 -5
  15. package/docs/reference/ai/browser-wasm.md +335 -0
  16. package/docs/reference/availability-and-normalization.md +17 -0
  17. package/docs/reference/behavioral-testing.md +8 -0
  18. package/docs/reference/cli.md +86 -3
  19. package/docs/reference/event-manager.md +15 -6
  20. package/docs/reference/inventory/package-api.json +84 -4
  21. package/docs/reference/protocols.md +113 -14
  22. package/docs/reference/sdk-api.md +244 -11
  23. package/package.json +8 -5
  24. package/runtime/ARCANE_RUNTIME_RELEASE.json +1 -1
  25. package/schemas/arcane-lock.schema.json +17 -6
  26. package/src/dev-server.mjs +2 -1
  27. package/src/doctor.mjs +1 -1
  28. package/src/import-map.mjs +25 -1
  29. package/src/sdk-browser-runtime.mjs +134 -17
  30. package/src/templates/workspace-template.mjs +6 -0
  31. package/src/workspace.mjs +7 -1
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023-2026 The ggml authors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -16,19 +16,22 @@ dependency and invoke its local CLI with `npm exec -- arcane`. A separate
16
16
  global installer, standalone SDK executable, NuGet package, Homebrew formula,
17
17
  or OS package is not part of this release surface.
18
18
 
19
- `Check` validates the source once, then one unprivileged producer packs one
20
- `.tgz` under pinned Node and npm versions. The producer writes a canonical
21
- manifest containing the source SHA, clean-checkout flag, package inventory,
22
- byte length, SHA-256, npm SHA-1 shasum, and SHA-512 integrity. Windows x64,
23
- Linux x64, and a real macOS arm64 runner use the declared Node `22.23.2` floor
24
- and each download that same Actions
25
- artifact by immutable artifact id. They never repack it. Each runner verifies
26
- the receipt, installs the tarball into a disposable project, exercises
19
+ `Check` validates only package-publication authority once: package metadata,
20
+ the executable and `.gitattributes` boundary, both authenticated runtime
21
+ receipts, and the focused npm identity/channel/provenance contract. One
22
+ unprivileged producer then packs one `.tgz` under pinned Node and npm versions.
23
+ The producer writes a canonical manifest containing the source SHA,
24
+ clean-checkout flag, package inventory, byte length, SHA-256, npm SHA-1 shasum,
25
+ and SHA-512 integrity. One Ubuntu x64 consumer at the declared Node `22.23.2`
26
+ floor downloads that Actions artifact by immutable artifact id, verifies the
27
+ receipt, installs the tarball into a disposable project, exercises
27
28
  `npm exec --offline -- arcane`, and runs one small capability contract through
28
- the installed package's `arcane-test.mjs`. A final readiness job verifies the
29
- same artifact's identity, integrity, shasum, license inventory, and content
30
- boundary once. Browser/process simulations, Pages, Examples, and presentation
31
- work are post-registry follow-through rather than npm publication gates.
29
+ the installed package's `arcane-test.mjs`. It never repacks. A final readiness
30
+ job verifies the same artifact's identity, integrity, shasum, license inventory,
31
+ and content boundary once. Golden snapshots, broad integration/regression and
32
+ platform matrices, browser/process simulations, Pages, Examples, and
33
+ presentation work are normal or post-registry checks rather than npm
34
+ publication gates.
32
35
 
33
36
  `publish-dev.yml` can run only when manually dispatched from `main` in
34
37
  `TheWizardNexus/arcane-os-sdk`. Dispatch requires an authorized npm content
@@ -72,8 +75,9 @@ as `arcane-os@0.1.0-dev.5` and verifies the locked runtime. A local directory
72
75
 
73
76
  The first-version bootstrap established these permanent audit boundaries:
74
77
 
75
- 1. Push the intended clean `main` commit and require the complete Check workflow,
76
- including the exact-artifact Windows/Linux/macOS matrix, to pass.
78
+ 1. Push the intended clean `main` commit and require the npm-critical Check
79
+ workflow—package authority, one producer, one installed Linux capability
80
+ smoke, and one identity/legal verifier—to pass.
77
81
  2. Review the uploaded tarball inventory, manifest, checksum, and license
78
82
  notices. Ensure the Arcane OS monorepo package is private so it cannot publish
79
83
  the same npm name accidentally.
@@ -189,8 +193,9 @@ work and do not change the canonical source branch.
189
193
  ## Work-amplification record
190
194
 
191
195
  The release graph is one checked `main` SHA and one npm release candidate. One
192
- source-validation job runs the suite once; one producer creates the tarball;
193
- three small installed-package consumers execute those exact bytes on Windows,
194
- Linux, and macOS; and one readiness job verifies identity and legal inventory.
196
+ package-authority job runs the narrow source policy and publication contract;
197
+ one producer creates the tarball; one Ubuntu consumer executes those exact
198
+ installed bytes; and one readiness job verifies identity and legal inventory.
195
199
  OIDC publication reuses that successful exact-SHA artifact without rebuilding.
196
- Pages and broader presentation work follow registry verification separately.
200
+ Platform matrices, full product regressions, Pages, and broader presentation
201
+ work remain outside registry publication and run separately when warranted.
@@ -19,6 +19,7 @@ high-level page links to the relevant deep section instead of repeating it.
19
19
  | Use the Node.js package API | [SDK JavaScript API](sdk-api.md) |
20
20
  | Publish central events, capture bounded time-travel history, or observe the DOM | [EventManager and event-stack reference](event-manager.md) |
21
21
  | Use the `arcane` command | [CLI reference](cli.md) |
22
+ | Generate named browser imports or inspect the authenticated physical runtime | [`arcane import-map`](cli.md#arcane-import-map) and [browser runtime delivery](protocols.md#browser-runtime-delivery) |
22
23
  | Choose browser, native, cloud, or cross-host behavior | [Availability and normalization](availability-and-normalization.md) |
23
24
  | Import a shipped renderer module | [Runtime module catalog](runtime-modules.md) |
24
25
  | Use a shared entity | [Runtime entity modules](runtime-entities.md) and [exact export contracts](core/arcane-entities.md) |
@@ -26,6 +27,7 @@ high-level page links to the relevant deep section instead of repeating it.
26
27
  | Call `globalThis.Arcane` | [Arcane Core API](core/arcane-api.md) |
27
28
  | Subscribe to native events | [Arcane event reference](core/arcane-events.md) |
28
29
  | Use provider-neutral AI | [Arcane AI contracts](core/arcane-ai-contracts.md) |
30
+ | Run a caller-authenticated local LLM in the browser | [Browser-WASM local AI](ai/browser-wasm.md) |
29
31
  | Use Arcane Ollama | [Arcane Ollama guide](arcane-ollama.md) |
30
32
  | Understand transports and protocol switching | [Protocol and host architecture](protocols.md) |
31
33
  | Run contract and behavior tests | [Behavioral testing](behavioral-testing.md) |
@@ -36,7 +38,7 @@ This repository contains two related, explicitly versioned surfaces:
36
38
 
37
39
  | Surface | Source identity | Meaning |
38
40
  | --- | --- | --- |
39
- | SDK and CLI | `arcane-os` `0.1.0-dev.5` | The Node.js toolchain and package exports in this checkout. |
41
+ | SDK and CLI | `arcane-os` `0.1.1` | The Node.js toolchain plus the browser-only `arcane-os/ai/browser-wasm` entrypoint in this checkout. |
40
42
  | Browser runtime | Arcane OS commit `567ad110bf57a1c2d4a3daa22ae93716cc5f4d7e`, bundle `0.8.12`, protocol `arcane/1` | The exact 155-file runtime snapshot shipped under `runtime/`. |
41
43
  | Core reference snapshot | Arcane OS commit `567ad110bf57a1c2d4a3daa22ae93716cc5f4d7e`, protocol `arcane/1` | The application-facing Core contract derived into `docs/reference/core/`. Canonical inventory and focused-member content was verified unchanged at Arcane OS `main` commit `13f3ce0ae34f77a3495331c8b4c30b1bb105f8ed`; SDK-local provenance, link, and package-boundary annotations are added explicitly. |
42
44
 
@@ -72,11 +74,13 @@ Public reference entries follow the established Arcane documentation model:
72
74
 
73
75
  ## Public runtime inventory
74
76
 
75
- The Node package exposes 158 semantic JavaScript records across 11 JavaScript
77
+ The package exposes 163 semantic JavaScript records across 12 JavaScript
76
78
  entrypoints, plus eight JSON Schemas, its exact runtime manifest, and package
77
- metadata. The [machine-readable package inventory](inventory/package-api.json)
78
- and [SDK member reference](sdk-api.md) are checked bidirectionally against every
79
- declared JavaScript export.
79
+ metadata. Ten entrypoints are Node.js control-plane surfaces,
80
+ `arcane-os/event-manager` runs in Node and browsers, and
81
+ `arcane-os/ai/browser-wasm` is browser-only. The [machine-readable package
82
+ inventory](inventory/package-api.json) and [SDK member reference](sdk-api.md)
83
+ are checked bidirectionally against every declared JavaScript export.
80
84
 
81
85
  The seven update-check records are explicit on-demand checks; they do not poll,
82
86
  download, install, or self-update.
@@ -0,0 +1,335 @@
1
+ # Browser-WASM local AI
2
+
3
+ Use this browser-only entrypoint when an application deliberately owns a local
4
+ GGUF model authority and wants provider-neutral LLM lifecycle, chat, streaming,
5
+ cancellation, and structural tool-call results without an Arcane Core host.
6
+ For ordinary hosted applications, start with the [Arcane AI
7
+ contracts](../core/arcane-ai-contracts.md) and `globalThis.Arcane.ai`. This
8
+ page is the focused local-browser path beneath the normalized AI decision
9
+ guide.
10
+
11
+ The wiring example assumes a scaffolded or materialized Arcane application
12
+ with SDK `0.1.1`'s authenticated runtime tree and 86-entry browser import map.
13
+ `arcane/DBOPFS` is a managed browser-map specifier, not an npm package export.
14
+ See [browser runtime delivery](../protocols.md#browser-runtime-delivery) before
15
+ using the example in a custom host or bundler.
16
+
17
+ ```javascript
18
+ import DBOPFS from 'arcane/DBOPFS';
19
+ import {
20
+ createArcaneAI,
21
+ createBrowserModelSource,
22
+ createBrowserWasmLlmProvider,
23
+ createDbopfsModelStore
24
+ } from 'arcane-os/ai/browser-wasm';
25
+
26
+ const MODEL = Object.freeze({
27
+ id:'my-reviewed-model',
28
+ name:'model-q4.gguf',
29
+ immutableUrl:'https://models.example/revisions/4f7c/model-q4.gguf',
30
+ bytes:123456789,
31
+ sha256:'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
32
+ licenseSpdx:'Apache-2.0',
33
+ sourceRevision:'4f7c'
34
+ });
35
+
36
+ const dbopfs = globalThis.dbopfs || new DBOPFS({applicationId:'my-app'});
37
+ await dbopfs.readyPromise;
38
+ const source = createBrowserModelSource(MODEL);
39
+ const store = createDbopfsModelStore({dbopfs});
40
+ const provider = createBrowserWasmLlmProvider({source, store});
41
+ const ai = createArcaneAI({provider, loadPolicy:'manual'});
42
+
43
+ // Put this behind an explicit user action: it can download MODEL.bytes bytes.
44
+ async function loadReviewedModel() {
45
+ return ai.load({threads:1, contextTokens:4096, gpuLayers:0});
46
+ }
47
+ ```
48
+
49
+ The browser-WASM runtime closure packages the authenticated
50
+ `@wllama/wllama` `3.6.0` ESM and WebAssembly runtime plus the Wllama and
51
+ llama.cpp MIT license texts. It
52
+ packages no model weights, model catalog, CDN fallback, native provider, speech
53
+ synthesis, or transcription. Callers supply the exact model authority. `bytes`
54
+ is the expected positive byte length, not inline model data.
55
+
56
+ ## Lifecycle at a glance
57
+
58
+ `createArcaneAI()` owns one LLM controller. Its default `loadPolicy` is
59
+ `on-demand`; the first request may download and initialize the model. Use
60
+ `manual` when a user action, resource review, or progress UI must precede load.
61
+
62
+ | Operation | Result |
63
+ | --- | --- |
64
+ | `ai.status()` | Frozen `{llm: status}` wrapper. |
65
+ | `ai.load(options)` | Flat LLM status after load. |
66
+ | `ai.llm.chat(request)` / `ai.fetchRequest(request)` | Validated OpenAI-like completion. |
67
+ | `ai.llm.stream(request)` | Frozen async-iterator handle with `result` and `cancel(reason)`. |
68
+ | `ai.streamRequest(request)` | Consumes the stream and returns text or `{toolName: argumentJsonString}`. |
69
+ | `ai.unload()` | Cancels active work, releases the Wllama session, and returns flat unloaded status; verified DBOPFS cache remains. |
70
+ | `ai.dispose()` | Permanently disposes the controller; explicit `store.remove(source)` is required to delete cached model bytes. |
71
+
72
+ The controller emits `statechange` and `progress` through
73
+ `addEventListener()`, `removeEventListener()`, or `on()`. Event `detail` is the
74
+ current frozen status. Provider states are `unloaded`, `loading`, `ready`,
75
+ `unloading`, and `error`.
76
+
77
+ ## Model authority and cache admission
78
+
79
+ `createBrowserModelSource()` requires `id`, `name`, `immutableUrl`, `bytes`,
80
+ `sha256`, `licenseSpdx`, and `sourceRevision`. The URL must be absolute HTTPS
81
+ without credentials or a fragment. Revision-floating `main`, `master`, and
82
+ `latest` path segments are rejected. `name` is one filename. `bytes` is a
83
+ positive safe integer and `sha256` is exactly 64 hexadecimal characters.
84
+
85
+ `licenseSpdx` and `sourceRevision` are required provenance labels supplied by
86
+ the caller; the SDK does not independently prove the license or derive the
87
+ revision from the URL. Redirects are followed and the final URL must remain
88
+ HTTPS. Byte length and SHA-256 remain the actual admission authority.
89
+
90
+ The DBOPFS adapter stores model bytes and then commits an
91
+ `arcane.ai.browser-wasm.model.v2` completion manifest. It reopens and fully
92
+ rehashes the bytes before returning an installed receipt and again before every
93
+ verified cache reuse. Missing, malformed, stale, wrong-length, or wrong-digest
94
+ entries are removed. `load({offline:true})` never performs a model request; it
95
+ uses a fully rehashed cache or rejects with `ARCANE_AI_MODEL_OFFLINE_MISS`.
96
+
97
+ `localOnly:true` describes inference after load. It does not mean a cache miss
98
+ cannot download. Source downloads use CORS, omit credentials and referrer,
99
+ disable HTTP caching, and honor `AbortSignal`.
100
+
101
+ ## Streaming, cancellation, and tools
102
+
103
+ ```javascript
104
+ const abort = new AbortController();
105
+ const stream = ai.llm.stream({
106
+ localOnly:true,
107
+ signal:abort.signal,
108
+ messages:[{role:'user', content:'Summarize this text.'}],
109
+ maxTokens:128
110
+ });
111
+
112
+ const cancelButton = document.querySelector('[data-cancel-local-ai]');
113
+ const cancel = () => abort.abort('user cancelled');
114
+ cancelButton.addEventListener('click', cancel, {once:true});
115
+ try {
116
+ for await (const chunk of stream) renderChunk(chunk);
117
+ const completion = await stream.result;
118
+ renderCompletion(completion);
119
+ } catch (error) {
120
+ if (error?.code !== 'ARCANE_AI_REQUEST_ABORTED') throw error;
121
+ renderCancelled();
122
+ } finally {
123
+ cancelButton.removeEventListener('click', cancel);
124
+ }
125
+ ```
126
+
127
+ An active cancellation rejects as `ARCANE_AI_REQUEST_ABORTED`. Requests are
128
+ serialized; provider status exposes `busy` and `queued`. Supported request
129
+ generation fields include temperature, top-K, top-P, min-P, repeat penalty,
130
+ maximum tokens, seed, and stop sequences. Load settings separately include
131
+ `contextTokens`, `batchTokens`, `microBatchTokens`, `threads`, and GPU-layer
132
+ count. WebGPU is optional; cross-origin isolation and hardware fields are
133
+ observations, not readiness promises.
134
+
135
+ Tool definitions, tool choice, parallel-tool-call preference, and JSON or JSON
136
+ Schema structured-output requests are passed to Wllama. Returned tool calls are
137
+ validated and surfaced as structural data. Argument payloads remain JSON
138
+ strings. The SDK never invokes a handler or executes a tool; application code
139
+ must review policy, validate arguments, choose whether to execute, and submit a
140
+ later tool result.
141
+
142
+ ## Errors and unavailable states
143
+
144
+ Invalid configuration can throw `TypeError` or `RangeError`. Operational
145
+ failures expose a stable `.code`; the internal error class is not exported.
146
+ Handle the narrow code needed by the current operation and treat other failures
147
+ as unavailable.
148
+
149
+ | Area | Stable codes |
150
+ | --- | --- |
151
+ | Source and download | `ARCANE_AI_MODEL_SOURCE_INVALID`, `ARCANE_AI_MODEL_SOURCE_UNAVAILABLE`, `ARCANE_AI_MODEL_DOWNLOAD_FAILED`, `ARCANE_AI_MODEL_REDIRECT_BLOCKED`, `ARCANE_AI_MODEL_SIZE_MISMATCH`, `ARCANE_AI_MODEL_DIGEST_MISMATCH` |
152
+ | Cache and storage | `ARCANE_AI_MODEL_CACHE_REJECTED`, `ARCANE_AI_MODEL_OFFLINE_MISS`, `ARCANE_AI_STORAGE_UNAVAILABLE`, `ARCANE_AI_STORAGE_READ_FAILED`, `ARCANE_AI_STORAGE_DELETE_FAILED` |
153
+ | Lifecycle | `ARCANE_AI_UNAVAILABLE`, `ARCANE_AI_NOT_READY`, `ARCANE_AI_LOAD_FAILED`, `ARCANE_AI_UNLOAD_FAILED`, `ARCANE_AI_DISPOSE_FAILED`, `ARCANE_AI_DISPOSED`, `ARCANE_AI_OPERATION_SUPERSEDED` |
154
+ | Requests | `ARCANE_AI_REQUEST_ABORTED`, `ARCANE_AI_REQUEST_FAILED`, `ARCANE_AI_INVALID_PROVIDER_RESULT`, `ARCANE_AI_LOCAL_ONLY_UNAVAILABLE`, `ARCANE_AI_ADAPTER_PROTOCOL_MISMATCH` |
155
+ | Diagnostics | `ARCANE_AI_PROBE_FAILED` |
156
+
157
+ `capabilities()` reports browser observations such as WebAssembly, OPFS,
158
+ WebGPU, secure context, cross-origin isolation, and hardware concurrency.
159
+ Feature-detect them. The authoritative Chrome behavior passes without
160
+ cross-origin isolation, so that flag is not a hard gate. `probe()` exercises
161
+ packaged Wllama backend operations only while unloaded; it neither admits nor
162
+ downloads a model.
163
+
164
+ ## BROWSER_WASM_RUNTIME_AUTHORITY
165
+
166
+ ### Overview
167
+
168
+ Deep-frozen identity for the shipped browser runtime. Its protocol is
169
+ `arcane-ai-browser-wasm/1`; the provider adapter uses
170
+ `arcane-ai-adapter/1`. It records Wllama `3.6.0`, the embedded llama.cpp
171
+ revision, authenticated module/WASM byte lengths and SHA-256 values, licenses,
172
+ and the disabled compatibility-runtime and remote-model-helper policy.
173
+
174
+ ### Value and import
175
+
176
+ ```text
177
+ const BROWSER_WASM_RUNTIME_AUTHORITY
178
+ ```
179
+
180
+ ### Availability and normalization
181
+
182
+ **Browser metadata; safely inspectable without loading a model.** The value is
183
+ an immutable receipt, not a provider instance, model catalog, or capability
184
+ grant.
185
+
186
+ ### Example
187
+
188
+ ```javascript
189
+ import {BROWSER_WASM_RUNTIME_AUTHORITY} from 'arcane-os/ai/browser-wasm';
190
+
191
+ console.log(BROWSER_WASM_RUNTIME_AUTHORITY.protocol);
192
+ console.log(BROWSER_WASM_RUNTIME_AUTHORITY.package.version); // 3.6.0
193
+ ```
194
+
195
+ ## createArcaneAI()
196
+
197
+ ### Overview
198
+
199
+ Creates the application-facing facade around a provider or an existing LLM
200
+ controller. Use this as the primary browser-local API; construct the source,
201
+ store, and Wllama provider beneath it.
202
+
203
+ ### Signature and result
204
+
205
+ ```text
206
+ createArcaneAI({ llm=null, provider=null, loadPolicy='on-demand' }={})
207
+ ```
208
+
209
+ At least one `llm` or `provider` is required; when both are supplied, `llm`
210
+ takes precedence. `loadPolicy` is `on-demand` or `manual`. The frozen result
211
+ contains `llm`, `runtime`, `status`, `load`,
212
+ `unload`, `probe`, `fetchRequest`, `streamRequest`, and `dispose`.
213
+
214
+ ### Availability and normalization
215
+
216
+ **Browser.** It normalizes provider lifecycle and request observation without
217
+ selecting a model, changing browser permissions, contacting Arcane Core, or
218
+ creating a fallback provider.
219
+
220
+ ### Example
221
+
222
+ ```javascript
223
+ const ai = createArcaneAI({provider, loadPolicy:'manual'});
224
+ const off = ai.llm.on('statechange', event => renderStatus(event.detail));
225
+ await ai.load({offline:true});
226
+ off();
227
+ ```
228
+
229
+ ## createBrowserModelSource()
230
+
231
+ ### Overview
232
+
233
+ Validates caller-owned model provenance and creates the one cancellable HTTPS
234
+ download source accepted by this provider.
235
+
236
+ ### Signature and result
237
+
238
+ ```text
239
+ createBrowserModelSource(descriptor, { fetchImpl=null }={})
240
+ ```
241
+
242
+ The frozen source includes `kind`, the seven canonical descriptor fields,
243
+ `descriptor`, and `open({signal})`. `open()` returns a readable response body,
244
+ requested/final URLs, and `cancel()`; it does not admit bytes to the cache.
245
+
246
+ ### Availability and normalization
247
+
248
+ **Browser Fetch with CORS.** URL and metadata syntax are normalized; exact
249
+ length and SHA-256 are enforced when the store installs the stream.
250
+
251
+ ### Example
252
+
253
+ ```javascript
254
+ const source = createBrowserModelSource(MODEL);
255
+ console.log(source.id, source.bytes, source.sha256);
256
+ ```
257
+
258
+ ## createBrowserWasmLlmProvider()
259
+
260
+ ### Overview
261
+
262
+ Creates the local-only Wllama provider from genuine source and store objects
263
+ created by this module. Structural lookalikes are rejected.
264
+
265
+ ### Signature and result
266
+
267
+ ```text
268
+ createBrowserWasmLlmProvider({ source, store, loadDefaults={}, logger=console }={})
269
+ ```
270
+
271
+ The frozen result exposes protocol and provider identity, model metadata,
272
+ `capabilities`, `status`, `load`, `unload`, `chat`, `stream`, `streamChat`,
273
+ `use`, `probe`, and `dispose`. Direct provider `load()` returns `{model,status}`;
274
+ the facade `ai.load()` returns the flat controller status.
275
+
276
+ ### Availability and normalization
277
+
278
+ **Browser with WebAssembly and verified DBOPFS model bytes.** Inference is local
279
+ after load. WebGPU is optional and defaults to zero GPU layers unless the caller
280
+ selects otherwise.
281
+
282
+ ### Example
283
+
284
+ ```javascript
285
+ const provider = createBrowserWasmLlmProvider({
286
+ source,
287
+ store,
288
+ loadDefaults:{threads:1, contextTokens:4096, gpuLayers:0}
289
+ });
290
+ console.log(provider.status().state); // unloaded
291
+ ```
292
+
293
+ ## createDbopfsModelStore()
294
+
295
+ ### Overview
296
+
297
+ Adapts an existing DBOPFS instance without renaming or replacing its public
298
+ methods. The adapter owns verified model-file and completion-manifest behavior.
299
+
300
+ ### Signature and result
301
+
302
+ ```text
303
+ createDbopfsModelStore({ dbopfs, tableName='arcane_ai_browser_models' }={})
304
+ ```
305
+
306
+ The frozen result contains `kind`, `tableName`, the original `adapter`, and
307
+ `ready`, `openVerified`, `install`, `ensure`, and `remove`. `ensure()` returns a
308
+ file, completion manifest, and cache state `verified` or `installed`.
309
+
310
+ ### Availability and normalization
311
+
312
+ **Browser with a ready DBOPFS instance and OPFS.** Cache receipts are local
313
+ integrity evidence. They are not transferable capability tokens and do not
314
+ prove model license rights.
315
+
316
+ ### Example
317
+
318
+ ```javascript
319
+ const store = createDbopfsModelStore({dbopfs});
320
+ await store.ready();
321
+ const cached = await store.openVerified(source);
322
+ console.log(cached ? 'verified cache' : 'cache miss');
323
+ ```
324
+
325
+ ## Related reference
326
+
327
+ - [Canonical `createArcaneAI()` entry](../sdk-api.md#createarcaneai) and the
328
+ sibling [`BROWSER_WASM_RUNTIME_AUTHORITY`](../sdk-api.md#browserwasmruntimeauthority),
329
+ [`createBrowserModelSource()`](../sdk-api.md#createbrowsermodelsource),
330
+ [`createBrowserWasmLlmProvider()`](../sdk-api.md#createbrowserwasmllmprovider),
331
+ and [`createDbopfsModelStore()`](../sdk-api.md#createdbopfsmodelstore) entries
332
+ - [Browser-local normalization boundary](../availability-and-normalization.md#browser-local-provider-adapter)
333
+ - [Authenticated browser runtime delivery](../protocols.md#browser-runtime-delivery)
334
+ - [Browser-WASM behavior evidence](../behavioral-testing.md#behavioral-coverage-model)
335
+ - [DBOPFS runtime module](../runtime-modules.md#dbopfsjs)
@@ -29,6 +29,7 @@ version; WebKitGTK availability must not be generalized to macOS.
29
29
  | Scaffold, inspect, test, package, bundle, build, verify, or run an app | `arcane` CLI or `arcane-os` package functions | **Node**; native targets invoke one explicit provider | CLI events and SDK errors/results are normalized by versioned SDK contracts. Native artifact receipts remain target-specific inside a common receipt lifecycle. |
30
30
  | Publish application events or review a bounded event history | `arcane-os/event-manager` | **Node** and **Browser**; optional DOM capture needs a browser DOM or compatible host | Live listeners receive original arguments. Recorded payloads and metadata become bounded, redacted, deeply frozen `arcane-event-stack/1` snapshots. The stack format is local diagnostic data, not a host transport. |
31
31
  | Build browser UI and app-local behavior | `/arcane/modules/*.js`, shared entities, and components | **Browser**; many modules also run inside every native renderer | Pure modules own their result contracts. Modules that call `Arcane` inherit the bridge boundary described below. |
32
+ | Run a caller-selected local LLM entirely in a browser renderer | `arcane-os/ai/browser-wasm` through `createArcaneAI()` | **Browser** only; WebAssembly and OPFS/DBOPFS are required, WebGPU is optional, and a cache miss uses the caller's admitted HTTPS model URL unless `offline:true` | The facade normalizes lifecycle, status, streaming, cancellation, and structural tool-call visibility. Model URL, byte length, SHA-256, license identifier, and revision remain explicit caller authority. |
32
33
  | Read host identity, capabilities, storage, preferences, appearance, or platform state | `globalThis.Arcane` | **Cross-host** where the method is implemented and admitted | Promise behavior and `Arcane.Error` are normalized. Result fields are normalized unless the method explicitly documents a platform-dependent snapshot. |
33
34
  | Use local AI without coupling app code to Ollama HTTP | `Arcane.localAI`, `Arcane.ai`, or `/arcane/modules/Ollama.js` | Primarily **Native**; Android exposes a narrower admitted inference projection | Admission, errors, and managed-operation events are normalized. Direct Ollama response envelopes remain **Provider-native**. |
34
35
  | Use OpenAI from the renderer profile | `/arcane/modules/AI.js` | **Cloud** from an allowed browser/native renderer | High-level AI chat/text behavior is normalized by the module; raw provider diagnostics and some response detail remain provider-specific. No automatic cloud fallback is inferred from local failure. |
@@ -77,6 +78,22 @@ deeply frozen, and strictly importable as `arcane-event-stack/1`. DOM
77
78
  instrumentation adds browser diagnostics only; it does not replay browser
78
79
  state. See [EventManager and time-travel review](event-manager.md).
79
80
 
81
+ ### Browser-local provider adapter
82
+
83
+ [`arcane-os/ai/browser-wasm`](ai/browser-wasm.md) exposes the same
84
+ `arcane-ai-adapter/1` LLM lifecycle used by `createArcaneAI()`, while its
85
+ packaged Wllama engine and caller-supplied model run inside the browser. This
86
+ surface does not require an Arcane Core method grant because it does not call a
87
+ Core host. Browser Fetch, CORS, storage policy, secure-context behavior, and
88
+ resource limits still apply.
89
+
90
+ `localOnly:true` describes inference after load; it does not promise that load
91
+ is offline. A normal cache miss downloads from the exact caller-supplied HTTPS
92
+ URL. `load({offline:true})` permits only an existing cache entry whose model
93
+ bytes are fully rehashed, otherwise it rejects with
94
+ `ARCANE_AI_MODEL_OFFLINE_MISS`. Tool calls are result data for application
95
+ review and dispatch; the SDK never executes them.
96
+
80
97
  ### Arcane bridge-normalized
81
98
 
82
99
  Core-backed calls return promises and reject with `Arcane.Error`. Transport
@@ -37,6 +37,7 @@ release acceptance.
37
37
  | EventManager and event stacks | Live pub/sub ordering and payload identity, nested causation, immutable/redacted snapshots, strict import, bounded overflow, seek, all playback modes/lifecycle outcomes, cancellation, and DOM start/stop/privacy behavior. | Real user journeys and browser layout belong in a browser harness; event-stack review never proves that external side effects can be replayed. |
38
38
  | CLI | Commands parse, acknowledge, select one scope, produce normalized human/JSON/NDJSON output, propagate cancellation/failure, and reject invalid cardinality. | Native build/run requires the selected real provider and host. |
39
39
  | Browser runtime modules | Every shipped ESM module parses and its export inventory matches the catalog; pure helpers run focused success/error cases. | DOM, OPFS, media, and Web Component journeys use a browser harness. |
40
+ | Browser-WASM local AI | The exact five-export namespace, runtime authority, model-source validation, DBOPFS adapter contract, provider/facade lifecycle, lazy/manual policy, abort normalization, and structural-only tool behavior run with bounded deterministic providers. | The publication gate installs the packed SDK into a real Chrome app, loads the authenticated Wllama 3.6.0 JS/WASM assets, performs a cold exact-length/SHA-256 model install, real inference, in-flight cancellation, unload, and a verified offline reload with zero model requests. It is an explicit heavyweight capability gate, not an implicit model download in every local `npm run check`. |
40
41
  | Core bridge docs | Canonical namespace/method/event/entity inventories match their one-per-member guides and required sections. | Live Core conformance belongs in Arcane OS because Core implementation is not shipped as SDK source. |
41
42
  | Arcane Ollama wrapper | Missing-host error, method forwarding, text/readiness normalization, unload request, and stream-option forwarding run against a deterministic fake `Arcane.ollama`. | Real managed-service, model download/create, GPU/resource admission, and service restart require an admitted Arcane host. |
42
43
  | Native providers | Plan/provider protocol, explicit target, receipt authentication, artifact reader, and unavailable-path honesty are tested with bounded fixtures. | Exact Windows, Linux, or Android artifact verification and launch must run on that actual platform/architecture. |
@@ -53,6 +54,13 @@ client contract. They must assert the exact request sent to the fake and the
53
54
  normalized result returned to the application. A fake provider never counts as
54
55
  native host, artifact, installation, or model-service evidence.
55
56
 
57
+ The browser-WASM guide follows the same rule: it shows exact model authority
58
+ and wiring, but leaves the download/load call behind an explicit user action.
59
+ The authoritative browser contract separately proves that admitted bytes are
60
+ hashed before DBOPFS completion metadata is committed, cached bytes are rehashed
61
+ before offline reuse, `AbortSignal` settles as `ARCANE_AI_REQUEST_ABORTED`, and
62
+ tool-call arguments are surfaced without invoking application handlers.
63
+
56
64
  ## Host and normalization cases
57
65
 
58
66
  Cross-host APIs should cover at least these cases at their owning layer:
@@ -16,6 +16,7 @@ and exits nonzero on failure. Machine output is defined by
16
16
  | `arcane new <id>` | Creates one external app workspace. |
17
17
  | `arcane init [id]` | Initializes one app in an external or integrated workspace without rewriting unrelated files. |
18
18
  | `arcane doctor` | Reads and reports Node/tooling, SDK runtime, workspace, optional Arcane source recognition, and supported managed ArcaneOllama readiness. |
19
+ | `arcane import-map` | Authenticates and refreshes one app's managed browser import map and matching HTML entry. |
19
20
  | `arcane dev` | Starts one owned browser development server for one selected app. |
20
21
  | `arcane test` | Runs one app test boundary or one explicit integrated shared test file. |
21
22
  | `arcane check` | Validates one app boundary or the canonical integrated shared check. |
@@ -162,6 +163,88 @@ failure into a failed doctor result.
162
163
  npm exec -- arcane doctor --workspace . --arcane-root "../Arcane OS"
163
164
  ```
164
165
 
166
+ ## `arcane import-map`
167
+
168
+ ### Overview
169
+
170
+ Authenticates one selected application's physical browser runtime, generates
171
+ its standard browser import map, and commits the map artifact and matching
172
+ managed HTML entry as one bounded refresh.
173
+
174
+ ```text
175
+ arcane import-map [--workspace <directory>] [--app <id>]
176
+ ```
177
+
178
+ `--workspace` defaults to the current directory. `--app` selects one app when
179
+ the workspace does not already identify exactly one. The command accepts no
180
+ positional arguments and supports app scope only. `arcane-os import-map` is the
181
+ identical executable alias.
182
+
183
+ The generated artifact is
184
+ `apps/<id>/modules/arcane.importmap.json`. Its exact JSON is also installed in
185
+ the app entry as `<script type="importmap" data-arcane-import-map>` before
186
+ module loading. In SDK `0.1.1`, the authenticated physical-v1 runtime produces
187
+ 86 entries and intentionally has no package-root mapping.
188
+
189
+ ### Result and safety
190
+
191
+ Success returns the normal selected-workspace wrapper:
192
+
193
+ ```javascript
194
+ {
195
+ workspaceRoot,
196
+ workspaceMode, // 'external' or 'integrated'
197
+ appId,
198
+ importMap:{
199
+ appId,
200
+ artifactPath,
201
+ artifactRelativePath,
202
+ entryPath,
203
+ imports,
204
+ entryCount:86,
205
+ excludedModules:['modules/CaseEvidenceIndexer.js'],
206
+ files:[
207
+ {role:'artifact',path,bytes,sha256},
208
+ {role:'entry',path,bytes,sha256}
209
+ ],
210
+ cleanupWarnings,
211
+ committed:true
212
+ }
213
+ }
214
+ ```
215
+
216
+ The two file records bind the committed byte length and SHA-256 for the artifact
217
+ and HTML entry. A post-commit observer failure preserves delivery as a successful
218
+ receipt with `eventDelivery.status === 'degraded'` and
219
+ `ARCANE_EVENT_DELIVERY_FAILED`; it does not roll back valid application bytes.
220
+ Packaging refuses a committed refresh that reports cleanup warnings.
221
+
222
+ The canonical integrated-legacy workspace has a deliberate compatibility
223
+ result instead of an artifact: `importMap.skipped` is `true`,
224
+ `importMap.compatibility` is `'integrated-legacy'`, and the reason states that
225
+ the physical two-route browser runtime is retained.
226
+
227
+ `new` and `init` generate the map during scaffolding. `dev` refreshes it once
228
+ before binding; non-dry-run `package` and browser `build` refresh it before
229
+ collection. Paired native packaging refreshes each packaged app. `test`,
230
+ `check`, `verify`, `bundle`, and browser `run` do not regenerate it. There is no
231
+ watcher, polling, scheduled refresh, download, or self-update behavior.
232
+
233
+ There is no supported `--dry-run` for `import-map`: do not pass that parser-wide
234
+ flag because this command performs the real commit. Import-map-specific failures
235
+ use `ARCANE_IMPORT_MAP_INVALID`, `ARCANE_IMPORT_MAP_UNRESOLVED`, or
236
+ `ARCANE_IMPORT_MAP_COLLISION`; packaging can additionally report
237
+ `ARCANE_IMPORT_MAP_CLEANUP_FAILED`. Workspace, policy, usage, busy, and
238
+ cancellation failures retain their normal SDK codes.
239
+
240
+ ### Example
241
+
242
+ ```bash
243
+ npm exec -- arcane import-map --workspace . --app hello-world --output json
244
+ ```
245
+
246
+ Deep details: [authenticated browser delivery and receipts](protocols.md#browser-runtime-delivery).
247
+
165
248
  ## `arcane dev`
166
249
 
167
250
  ### Overview
@@ -471,9 +554,9 @@ Success returns:
471
554
  ```javascript
472
555
  {
473
556
  packageName:'arcane-os',
474
- currentVersion:'0.1.0-dev.4',
475
- registryVersion:'0.1.0-dev.5',
476
- tag:'dev',
557
+ currentVersion:'0.1.0',
558
+ registryVersion:'0.1.1',
559
+ tag:'latest',
477
560
  status:'update-available', // or 'current' or 'ahead'
478
561
  updateAvailable:true,
479
562
  registry:'https://registry.npmjs.org',