arcane-os 0.1.0-dev.5

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 (248) hide show
  1. package/CHANGELOG.md +154 -0
  2. package/COMMERCIAL-LICENSE.md +13 -0
  3. package/LICENSE +661 -0
  4. package/NOTICE +70 -0
  5. package/README.md +448 -0
  6. package/bin/arcane-test.mjs +741 -0
  7. package/bin/arcane.mjs +5 -0
  8. package/docs/architecture.md +234 -0
  9. package/docs/compatibility.md +36 -0
  10. package/docs/event-manager.md +166 -0
  11. package/docs/platform-targets.md +108 -0
  12. package/docs/publishing.md +203 -0
  13. package/docs/reference/README.md +117 -0
  14. package/docs/reference/arcane-ollama.md +288 -0
  15. package/docs/reference/availability-and-normalization.md +123 -0
  16. package/docs/reference/behavioral-testing.md +86 -0
  17. package/docs/reference/cli.md +569 -0
  18. package/docs/reference/core/README.md +62 -0
  19. package/docs/reference/core/arcane-ai-contracts.md +873 -0
  20. package/docs/reference/core/arcane-api.md +601 -0
  21. package/docs/reference/core/arcane-entities.md +65 -0
  22. package/docs/reference/core/arcane-events.md +134 -0
  23. package/docs/reference/core/ollama-module.md +181 -0
  24. package/docs/reference/core/reference/arcane-api/ai-and-ollama.md +1909 -0
  25. package/docs/reference/core/reference/arcane-api/applications-terminal-capabilities.md +1057 -0
  26. package/docs/reference/core/reference/arcane-api/core-and-events.md +320 -0
  27. package/docs/reference/core/reference/arcane-api/filesystem-storage-preferences-appearance.md +610 -0
  28. package/docs/reference/core/reference/arcane-api/namespaces.md +1157 -0
  29. package/docs/reference/core/reference/arcane-api/platform-installation-users-system.md +1423 -0
  30. package/docs/reference/core/reference/arcane-api/session-provisioning-diagnostics-development.md +315 -0
  31. package/docs/reference/event-manager.md +957 -0
  32. package/docs/reference/inventory/package-api.json +2632 -0
  33. package/docs/reference/inventory/runtime-components.json +934 -0
  34. package/docs/reference/inventory/runtime-entities.json +26 -0
  35. package/docs/reference/inventory/runtime-modules.json +1249 -0
  36. package/docs/reference/protocols.md +242 -0
  37. package/docs/reference/runtime-components.md +1098 -0
  38. package/docs/reference/runtime-entities.md +303 -0
  39. package/docs/reference/runtime-modules.md +2010 -0
  40. package/docs/reference/sdk-api.md +4901 -0
  41. package/docs/roadmap.md +79 -0
  42. package/docs/work-amplification.md +124 -0
  43. package/node_modules/event-pubsub/CHANGELOG.md +55 -0
  44. package/node_modules/event-pubsub/MIGRATION.md +70 -0
  45. package/node_modules/event-pubsub/README.md +363 -0
  46. package/node_modules/event-pubsub/SECURITY.md +37 -0
  47. package/node_modules/event-pubsub/index.js +141 -0
  48. package/node_modules/event-pubsub/licence +21 -0
  49. package/node_modules/event-pubsub/package.json +59 -0
  50. package/node_modules/strong-type/README.md +408 -0
  51. package/node_modules/strong-type/assets/strong-type-header.png +0 -0
  52. package/node_modules/strong-type/index.js +1151 -0
  53. package/node_modules/strong-type/licence +21 -0
  54. package/node_modules/strong-type/node.js +125 -0
  55. package/node_modules/strong-type/package.json +61 -0
  56. package/package.json +95 -0
  57. package/runtime/ARCANE_RUNTIME_RELEASE.json +791 -0
  58. package/runtime/arcane/components/app-bar.html +468 -0
  59. package/runtime/arcane/components/assistant-panel.html +715 -0
  60. package/runtime/arcane/components/calculator.html +8 -0
  61. package/runtime/arcane/components/chart.html +655 -0
  62. package/runtime/arcane/components/chat.html +1225 -0
  63. package/runtime/arcane/components/conversation-view.html +13 -0
  64. package/runtime/arcane/components/dashboard-config.html +341 -0
  65. package/runtime/arcane/components/data-maintenance.html +112 -0
  66. package/runtime/arcane/components/data-view.html +92 -0
  67. package/runtime/arcane/components/directory-picker.html +197 -0
  68. package/runtime/arcane/components/document-inspector.html +252 -0
  69. package/runtime/arcane/components/file-drop.html +264 -0
  70. package/runtime/arcane/components/file-inspector.html +293 -0
  71. package/runtime/arcane/components/file-manager.html +1715 -0
  72. package/runtime/arcane/components/header.html +142 -0
  73. package/runtime/arcane/components/integration-settings.html +14 -0
  74. package/runtime/arcane/components/local-ai-status.html +360 -0
  75. package/runtime/arcane/components/markdown-document.html +1048 -0
  76. package/runtime/arcane/components/markdown-editor.html +360 -0
  77. package/runtime/arcane/components/media-embed.html +8 -0
  78. package/runtime/arcane/components/modal.html +402 -0
  79. package/runtime/arcane/components/output-panel.html +259 -0
  80. package/runtime/arcane/components/preferences-form.html +135 -0
  81. package/runtime/arcane/components/record-timeline.html +105 -0
  82. package/runtime/arcane/components/relationship-board.html +116 -0
  83. package/runtime/arcane/components/screen-capture.html +8 -0
  84. package/runtime/arcane/components/source-code-viewer.html +441 -0
  85. package/runtime/arcane/components/source-explanation.html +124 -0
  86. package/runtime/arcane/components/speech.html +365 -0
  87. package/runtime/arcane/components/summary-strip.html +177 -0
  88. package/runtime/arcane/components/table.html +77 -0
  89. package/runtime/arcane/components/task-progress.html +282 -0
  90. package/runtime/arcane/components/terminal-workspace.html +65 -0
  91. package/runtime/arcane/components/theme-editor.html +41 -0
  92. package/runtime/arcane/components/theme-switcher.html +46 -0
  93. package/runtime/arcane/components/unified-inbox.html +20 -0
  94. package/runtime/arcane/components/voice-transcription.html +476 -0
  95. package/runtime/arcane/components/weather-widget.html +8 -0
  96. package/runtime/arcane/components/web-navigator.html +239 -0
  97. package/runtime/arcane/css/communications.css +1 -0
  98. package/runtime/arcane/css/dashboard-config.css +45 -0
  99. package/runtime/arcane/css/document-site.css +981 -0
  100. package/runtime/arcane/css/layout.css +438 -0
  101. package/runtime/arcane/css/primitives.css +321 -0
  102. package/runtime/arcane/css/theme.css +112 -0
  103. package/runtime/arcane/css/utility-workspace.css +1 -0
  104. package/runtime/arcane/entities/ApiModelRecord.js +20 -0
  105. package/runtime/arcane/entities/Calculation.js +13 -0
  106. package/runtime/arcane/entities/Chat.js +581 -0
  107. package/runtime/arcane/entities/CommunicationMessage.js +29 -0
  108. package/runtime/arcane/entities/CommunicationThread.js +21 -0
  109. package/runtime/arcane/entities/Document.js +10 -0
  110. package/runtime/arcane/entities/File.js +143 -0
  111. package/runtime/arcane/entities/Image.js +135 -0
  112. package/runtime/arcane/entities/IntentEnvelope.js +834 -0
  113. package/runtime/arcane/entities/Preference.js +83 -0
  114. package/runtime/arcane/entities/TWiNPolicyDecision.js +1092 -0
  115. package/runtime/arcane/entities/TerminalSession.js +46 -0
  116. package/runtime/arcane/entities/Theme.js +107 -0
  117. package/runtime/arcane/entities/User.js +1046 -0
  118. package/runtime/arcane/entities/Weather.js +23 -0
  119. package/runtime/arcane/img/arcane-os-everywhere.png +0 -0
  120. package/runtime/arcane/img/arrow-left.png +0 -0
  121. package/runtime/arcane/img/arrow-right.png +0 -0
  122. package/runtime/arcane/img/doc.svg +5 -0
  123. package/runtime/arcane/img/folder.svg +4 -0
  124. package/runtime/arcane/img/image.svg +5 -0
  125. package/runtime/arcane/img/refresh.png +0 -0
  126. package/runtime/arcane/img/send.svg +9 -0
  127. package/runtime/arcane/img/trash.svg +5 -0
  128. package/runtime/arcane/img/upload.svg +5 -0
  129. package/runtime/arcane/modules/AI.js +2048 -0
  130. package/runtime/arcane/modules/AIPreferenceRuntime.js +32 -0
  131. package/runtime/arcane/modules/AIPreferenceTuple.js +92 -0
  132. package/runtime/arcane/modules/AIResponseLength.js +42 -0
  133. package/runtime/arcane/modules/AIResponseURLPolicy.js +626 -0
  134. package/runtime/arcane/modules/AnsiText.js +53 -0
  135. package/runtime/arcane/modules/ApiModelDatabase.js +25 -0
  136. package/runtime/arcane/modules/AppDataScope.js +245 -0
  137. package/runtime/arcane/modules/AppearancePreferences.js +28 -0
  138. package/runtime/arcane/modules/ArcaneCommunicationBridge.js +22 -0
  139. package/runtime/arcane/modules/ArcaneNavigationPolicy.js +135 -0
  140. package/runtime/arcane/modules/ArcaneNetworkPolicy.js +255 -0
  141. package/runtime/arcane/modules/AsyncBoundary.js +161 -0
  142. package/runtime/arcane/modules/BrowserTestSuite.js +326 -0
  143. package/runtime/arcane/modules/CalculatorEngine.js +20 -0
  144. package/runtime/arcane/modules/CaseEvidenceIndexer.js +134 -0
  145. package/runtime/arcane/modules/ChartLibrary.js +35 -0
  146. package/runtime/arcane/modules/ChatRecords.js +13 -0
  147. package/runtime/arcane/modules/CommunicationAppController.js +43 -0
  148. package/runtime/arcane/modules/CommunicationHub.js +16 -0
  149. package/runtime/arcane/modules/CommunicationPreferences.js +13 -0
  150. package/runtime/arcane/modules/CommunicationProviderRegistry.js +16 -0
  151. package/runtime/arcane/modules/ComponentContracts.js +586 -0
  152. package/runtime/arcane/modules/ConfiguredAIChatSession.js +288 -0
  153. package/runtime/arcane/modules/ConversationActionItems.js +488 -0
  154. package/runtime/arcane/modules/ConversationClosingReport.js +274 -0
  155. package/runtime/arcane/modules/ConversationTimebox.js +527 -0
  156. package/runtime/arcane/modules/CoreLocalModelCatalog.js +255 -0
  157. package/runtime/arcane/modules/DBLS.js +171 -0
  158. package/runtime/arcane/modules/DBOPFS.js +1154 -0
  159. package/runtime/arcane/modules/DBOPFSWorker.js +116 -0
  160. package/runtime/arcane/modules/DataMaintenance.js +91 -0
  161. package/runtime/arcane/modules/DevelopmentWorkspace.js +74 -0
  162. package/runtime/arcane/modules/DirectoryPicker.js +109 -0
  163. package/runtime/arcane/modules/DocumentNavigation.js +223 -0
  164. package/runtime/arcane/modules/Errors.js +1025 -0
  165. package/runtime/arcane/modules/GifEncoder.js +29 -0
  166. package/runtime/arcane/modules/HTMLImport.js +114 -0
  167. package/runtime/arcane/modules/InMemoryCommunicationProvider.js +14 -0
  168. package/runtime/arcane/modules/IsolatedModelQuestionRunner.js +275 -0
  169. package/runtime/arcane/modules/LocalAIReadiness.js +870 -0
  170. package/runtime/arcane/modules/LocalAIReadinessController.js +156 -0
  171. package/runtime/arcane/modules/MD.js +111 -0
  172. package/runtime/arcane/modules/Mail.js +352 -0
  173. package/runtime/arcane/modules/MailTransport.mjs +180 -0
  174. package/runtime/arcane/modules/Marked.min.js +71 -0
  175. package/runtime/arcane/modules/MemoryRecords.js +44 -0
  176. package/runtime/arcane/modules/MessageAdvisory.js +38 -0
  177. package/runtime/arcane/modules/ModelDefinition.js +189 -0
  178. package/runtime/arcane/modules/Ollama.js +74 -0
  179. package/runtime/arcane/modules/OllamaModelIdentifier.js +21 -0
  180. package/runtime/arcane/modules/OllamaSettings.js +24 -0
  181. package/runtime/arcane/modules/OpenMeteoWeatherProvider.js +14 -0
  182. package/runtime/arcane/modules/PreferenceStore.js +109 -0
  183. package/runtime/arcane/modules/QRCode.min.js +1 -0
  184. package/runtime/arcane/modules/Questionnaire.js +61 -0
  185. package/runtime/arcane/modules/RecordLinkIndex.js +24 -0
  186. package/runtime/arcane/modules/RecordPassageIndex.js +222 -0
  187. package/runtime/arcane/modules/RecordReviewStore.js +94 -0
  188. package/runtime/arcane/modules/RevocableProjectionLedger.js +1623 -0
  189. package/runtime/arcane/modules/RiskSignalAnalyzer.js +37 -0
  190. package/runtime/arcane/modules/ScamRiskPolicy.js +62 -0
  191. package/runtime/arcane/modules/ScopedOPFSCache.js +183 -0
  192. package/runtime/arcane/modules/ScreenCapture.js +20 -0
  193. package/runtime/arcane/modules/SpeechPlayback.js +581 -0
  194. package/runtime/arcane/modules/StaticDocumentCatalog.js +1248 -0
  195. package/runtime/arcane/modules/SystemAppearance.js +20 -0
  196. package/runtime/arcane/modules/SystemPlatformPresentation.js +51 -0
  197. package/runtime/arcane/modules/SystemToolRegistry.js +28 -0
  198. package/runtime/arcane/modules/TerminalClient.js +52 -0
  199. package/runtime/arcane/modules/TerminalCommandRegistry.js +50 -0
  200. package/runtime/arcane/modules/ThemeBootstrap.js +26 -0
  201. package/runtime/arcane/modules/ThemeManager.js +131 -0
  202. package/runtime/arcane/modules/TimeGuard.js +149 -0
  203. package/runtime/arcane/modules/ToolCallRouter.js +83 -0
  204. package/runtime/arcane/modules/WaitForComponent.js +102 -0
  205. package/runtime/arcane/modules/YouTubeMedia.js +16 -0
  206. package/runtime/arcane/modules/uPlot.LICENSE.txt +21 -0
  207. package/runtime/arcane/modules/uPlot.iife.min.js +2 -0
  208. package/runtime/arcane/modules/uPlot.min.css +1 -0
  209. package/runtime/arcane/security/arcane-network-policy.json +6 -0
  210. package/runtime/strong-type/index.js +352 -0
  211. package/runtime/strong-type/licence +21 -0
  212. package/runtime/strong-type/package.json +45 -0
  213. package/schemas/arcane-app-bundle.schema.json +125 -0
  214. package/schemas/arcane-app.schema.json +329 -0
  215. package/schemas/arcane-lock.schema.json +86 -0
  216. package/schemas/arcane-package.schema.json +224 -0
  217. package/schemas/cli-event.schema.json +122 -0
  218. package/schemas/event-stack.schema.json +152 -0
  219. package/schemas/native-build-plan.schema.json +176 -0
  220. package/schemas/target-adapter.schema.json +117 -0
  221. package/src/app-descriptor.mjs +500 -0
  222. package/src/cli/main.mjs +561 -0
  223. package/src/constants.mjs +31 -0
  224. package/src/dev-server.mjs +718 -0
  225. package/src/doctor.mjs +315 -0
  226. package/src/dom-event-instrumentation.mjs +594 -0
  227. package/src/errors.mjs +75 -0
  228. package/src/event-manager.mjs +1342 -0
  229. package/src/event-queue.mjs +138 -0
  230. package/src/events.mjs +219 -0
  231. package/src/index.mjs +177 -0
  232. package/src/integrated-provider-loader.mjs +432 -0
  233. package/src/native-plan.mjs +698 -0
  234. package/src/native-provider-loader.mjs +1126 -0
  235. package/src/packager/core.mjs +2691 -0
  236. package/src/process.mjs +353 -0
  237. package/src/release-bundle.mjs +2523 -0
  238. package/src/repository.mjs +90 -0
  239. package/src/runtime.mjs +452 -0
  240. package/src/scaffold.mjs +380 -0
  241. package/src/targets/index.mjs +436 -0
  242. package/src/templates/assets/app-icon.png +0 -0
  243. package/src/templates/workspace-template.mjs +388 -0
  244. package/src/testing-loader.mjs +9 -0
  245. package/src/testing.mjs +427 -0
  246. package/src/toolchain.mjs +1335 -0
  247. package/src/update-check.mjs +307 -0
  248. package/src/workspace.mjs +449 -0
@@ -0,0 +1,601 @@
1
+ # Arcane API Reference
2
+
3
+ `window.Arcane` is the immutable application-facing API provided by the Arcane native host bridge. Arcane applications use the same contract when hosted by WebView2 on Microsoft NT, WebKitGTK on Linux, the Android WebView launcher bridge, or the development HTTP bridge. This is not a browser-only API: calls cross into the native Arcane runtime or platform service, and the available native operation is governed by the application's declared capabilities and host policy. This document owns the product-neutral operating-system surface; application-owned extension namespaces and methods are documented with their owning packages and participate in the same completeness check.
4
+
5
+ The Android bridge is an experimental foundation. Its source controller binds one WebView to one immutable packaged entry at the exact reserved HTTPS origin and denies non-packaged navigation and resources. A generated Android application registry derives the OS bundle version plus Shell identity, entry, and grant intersection from the canonical bundle manifest and method policy registry; each application APK independently derives its app identity and version from `apps/<id>/arcane-package.json`. One immutable host session has no caller-supplied identity, entry, version, or grant inputs. It requires the installed package version to match the expected Shell or app identity, while `version.current()` remains the OS bundle version for every session. The controller consumes that same session entry. AndroidX WebKit injects the bridge only at that origin, and the bridge admits messages only from the main frame after checking source origin, method admission, grant where required, and replay state. The controller can be installed only once and exposes a UI-thread teardown result that distinguishes removal of native bridge authority from full WebView destruction; failed destruction remains retryable, and authority-revoked controllers cannot load or install again. This teardown does not erase the shared WebView profile, cookies, DOM storage, cache, or service-worker data. The canonical Shell receives capability-free, bound-session `system.ping`, `version.current`, and `app.current` plus `platform.status` and `network.status`. Ping returns only `{ok:true}` and does not claim health, readiness, privilege, or trust. Version and application identity are provider-free reads of the immutable session; Android application trust remains `unverified` with no publisher or revocation claim. Android network status preserves the Core meaning of `{ online, interfaceCount }` by counting interfaces with non-loopback addresses, returns no interface identity or address, bounds malformed provider results, and requires no Android permission. The reviewed mailto-only `external.open` host implementation remains unavailable to the Shell because its canonical manifest does not grant that capability. Beyond the generated bootstrap and application-specific providers, methods and URI schemes fail closed. An admitted development application host may additionally expose the package-policy-filtered local-AI, chat, and speech methods through `ai.inference`; applications without that exact admission receive none of them. Generated source authority and package-version equality are not APK-signer or runtime-session authentication. This does not establish a complete Android launcher, authenticated package/session policy, signed application catalog, persistent-profile retention/deletion policy, scoped-storage resource grant, process recovery, update, or release contract.
6
+
7
+ The current debug-local-test Android distribution supersedes the earlier source-only status above: Kotlin compilation and API 35 instrumentation now pass for a HOME-eligible Shell plus 17 separately installed application APKs. Each app binds one verified packaged entry, Android identity, UID, storage scope, declared grants, and registry-derived network policy. `Arcane.applications.launch(id)` resolves only an installed generated package. Arcane Terminal alone receives the Android terminal provider, which runs bounded `/system/bin/sh` sessions under its ordinary app UID and private default working directory. This remains unsigned local evidence, not signer authentication, production release approval, update/recovery acceptance, or accessibility conformance.
8
+
9
+ Every operation returns a `Promise` unless the return column says otherwise. Rejected operations use `Arcane.Error`, which exposes `code`, `message`, `resolution`, `diagnosticId`, and technical diagnostic fields when available.
10
+
11
+ Parameter objects shown as optional may be omitted. Actual availability is also controlled by the application's declared capabilities and native policy.
12
+
13
+ Android host installation reports whether cleanup remains required and includes the teardown result after a partial setup failure. A launcher must retain that controller and retry close rather than treating every failed installation as clean.
14
+
15
+ ## Namespace, constructor, and value inventory
16
+
17
+ This inventory covers every enumerable, non-method member exposed directly or through a namespace on `window.Arcane`. Method rows in the later sections are checked separately against the live bridge. Adding, removing, or renaming a public namespace, constructor, value, or method requires the matching reference update in the same change.
18
+
19
+ | Member | Kind | Description |
20
+ |---|---|---|
21
+ | `Arcane.protocol` | Value | Exact native bridge protocol identifier, currently `"arcane/1"`. |
22
+ | `Arcane.Error` | Constructor | Normalized native/API error constructor with `code`, `message`, `resolution`, `diagnosticId`, and available technical diagnostic fields. |
23
+ | `Arcane.runtime` | Namespace | Local renderer and detected-host surface information. |
24
+ | `Arcane.events` | Namespace | Native event subscriptions and durable completion observation; see the [event inventory](arcane-events.md#event-inventory) for names, delivery, hosts, triggers, and payloads. |
25
+ | `Arcane.ai` | Namespace | Provider-neutral AI profile, model, chat, and provider-setting operations. |
26
+ | `Arcane.environment` | Namespace | App-authorized native environment-profile operations. |
27
+ | `Arcane.mail` | Namespace | Capability-gated native mail composition and delivery. |
28
+ | `Arcane.speech` | Namespace | Native speech readiness, synthesis, and transcription. |
29
+ | `Arcane.localAI` | Namespace | Native-host local-AI readiness, reconciliation, recovery, and isolated inference. |
30
+ | `Arcane.ollama` | Namespace | Admitted native Ollama inference, inventory, policy, and model-management operations. |
31
+ | `Arcane.app` | Namespace | Identity of the application bound to the current host session. |
32
+ | `Arcane.applications` | Namespace | Installed-application inventory and launch operations. |
33
+ | `Arcane.external` | Namespace | Policy-restricted requests to open external resources. |
34
+ | `Arcane.repository` | Namespace | Application repository-service namespaces. |
35
+ | `Arcane.terminal` | Namespace | Bounded native terminal-session lifecycle and input operations. |
36
+ | `Arcane.capabilities` | Namespace | Capability inventory visible to the bound application. |
37
+ | `Arcane.platform` | Namespace | Host platform and execution-evidence status. |
38
+ | `Arcane.permissions` | Namespace | Effective permission and capability status. |
39
+ | `Arcane.version` | Namespace | Arcane bundle version and installation status aliases. |
40
+ | `Arcane.machine` | Namespace | Machine status available to the bound application. |
41
+ | `Arcane.user` | Namespace | Current Arcane user identity. |
42
+ | `Arcane.requirements` | Namespace | Requirement inventory and authorized installation operations. |
43
+ | `Arcane.installation` | Namespace | Installation status, installation, and native uninstaller access. |
44
+ | `Arcane.users` | Namespace | Arcane user administration and shell configuration. |
45
+ | `Arcane.system` | Namespace | Bounded operating-system actions, metrics, health-independent ping, and failure policy. |
46
+ | `Arcane.network` | Namespace | Privacy-bounded native network status. |
47
+ | `Arcane.firewall` | Namespace | Firewall-only review, bounded audit, and explicitly confirmed development lifecycle simulation for the global deny policy. |
48
+ | `Arcane.filesystem` | Namespace | Native filesystem selection operations. |
49
+ | `Arcane.storage` | Namespace | App-scoped native key/value storage. |
50
+ | `Arcane.preferences` | Namespace | App-scoped preference reads and atomic writes. |
51
+ | `Arcane.appearance` | Namespace | Native appearance state and application. |
52
+ | `Arcane.session` | Namespace | Current Arcane session lifecycle. |
53
+ | `Arcane.provisioning` | Namespace | Provisioning-plan operations. |
54
+ | `Arcane.diagnostics` | Namespace | Bounded diagnostic summary and record retrieval. |
55
+ | `Arcane.development` | Namespace | Development-only inspection, context, setup, and tool installation. |
56
+
57
+ ## Core and events
58
+
59
+ | Method | Parameters | Return | Description |
60
+ |---|---|---|---|
61
+ | `Arcane.runtime.current()` | None | Frozen `{connected, transport, native, managedLocalAI}` | Synchronously describes this document's detected Arcane host surface without sending an RPC. |
62
+ | `Arcane.events.on(eventName, listener)` | `eventName`: event-name string or `"*"`; `listener`: callback | `() => void` unsubscribe function | Subscribes to future deliveries from the [event inventory](arcane-events.md#event-inventory). A named listener receives the event data; the wildcard listener receives `{event, data}`. |
63
+ | `Arcane.events.once(eventName, listener)` | `eventName`: event-name string; `listener`: callback | `() => void` unsubscribe function | Subscribes to the next matching delivery and removes the listener before invoking it. It does not replay an event that already occurred. |
64
+ | `Arcane.events.when(eventName, listener)` | `eventName`: `"transport.ready"` or `"core.ready"`; `listener`: callback | `() => void` unsubscribe function | Subscribes to a durable lifecycle completion. A late subscriber receives the first frozen completion payload asynchronously. |
65
+ | `Arcane.events.completed(eventName)` | `eventName`: `"transport.ready"` or `"core.ready"` | `boolean` | Synchronously reports whether this document has stored the designated durable completion. |
66
+
67
+ `transport.ready` and `core.ready` are the initial durable completions. Their
68
+ first JSON payload is snapshotted and frozen before live callbacks run; repeated
69
+ completions do not replace it. Ordinary events and `once()` remain future-only,
70
+ so progress, stream, and appearance updates are never replayed as stale state.
71
+ `transport.ready` means that this document selected a callable Arcane messaging
72
+ surface. It does not prove host health, application authority, capability grants,
73
+ publisher trust, or release readiness.
74
+
75
+ `Arcane.runtime.current()` is a local renderer snapshot, not a health,
76
+ authorization, or trust claim. `connected` means this document initialized its
77
+ selected messaging transport; it does not mean Core answered, a capability is
78
+ granted, or a dependency is ready. `native` is true for WebView2, WebKitGTK, and
79
+ Android WebView hosts. `managedLocalAI` is true only for the WebView2 and
80
+ WebKitGTK desktop host classes that can mediate Arcane-managed local services;
81
+ it does not report whether Ollama, speech, or any model is installed or healthy.
82
+ Android continues to report `managedLocalAI:false`; that value must not be
83
+ changed merely because an admitted host can proxy a user-managed Ollama
84
+ listener. The development HTTP bridge and an ordinary standalone browser both report
85
+ `native:false` and `managedLocalAI:false`; their transport values are
86
+ `development-http` and `standalone`, respectively. The native transport values
87
+ are `webview2`, `webkitgtk`, and `android-webview`. Without an app-scoped Core or
88
+ the exact Android status response described below, an application is
89
+ OpenAI-only. No renderer probes, lists, or calls an Ollama HTTP endpoint
90
+ directly.
91
+
92
+ ## Artificial intelligence and Ollama
93
+
94
+ | Method | Parameters | Return | Description |
95
+ |---|---|---|---|
96
+ | `Arcane.ai.models()` | None | [`Promise<LocalAIInventory>`](arcane-ai-contracts.md#local-ai-inventory) | Lists raw local model inventory for Settings, Terminal, and Shell diagnostics. Application model selectors use the admitted `Arcane.localAI.status().models.ollama` catalog instead. |
97
+ | `Arcane.ai.chat(request)` | `request`: [`AIChatRequest`](arcane-ai-contracts.md#ai-chat-request) | [`Promise<AIChatResult>`](arcane-ai-contracts.md#ai-chat-result) | Sends a chat request through the configured provider. |
98
+ | `Arcane.ai.profile()` | None | [`Promise<AIProfile>`](arcane-ai-contracts.md#ai-profile) | Gets the effective AI profile, including its canonical conversational response-length target. |
99
+ | `Arcane.ai.providerSettings()` | None | [`Promise<AIProviderSettingsResult>`](arcane-ai-contracts.md#ai-provider-settings-result) | Gets provider selection, credential status, and the conversational response-length target. |
100
+ | `Arcane.ai.saveProviderSettings(settings)` | `settings`: [`AIProviderSettingsInput`](arcane-ai-contracts.md#ai-provider-settings-input) | [`Promise<AIProviderSettingsResult>`](arcane-ai-contracts.md#ai-provider-settings-result) | Saves provider settings; validates the selected model when OpenAI is selected and validates a supplied replacement credential before persistence. Ollama-selected settings may retain a dormant OpenAI model for later revalidation. |
101
+ | `Arcane.ai.providerModels()` | None | [`Promise<AIProviderModelCatalog>`](arcane-ai-contracts.md#ai-provider-model-catalog) | Queries models available to the configured OpenAI account. |
102
+ | `Arcane.localAI.status()` | None | [`Promise<LocalAIStatusV2>`](arcane-ai-contracts.md#local-ai-status-v2) | Returns the native host's authoritative package-policy-filtered catalog and readiness. Desktop Core includes native resource and speech admission. An admitted Android application host may instead return `providerMode:"user-managed-loopback"`; that status has no managed lifecycle, but it merges bounded native Kokoro/Whisper role health and catalog evidence while Android speech operations use the separate `Arcane.speech` bridge. Requires `ai.inference`. |
103
+ | `Arcane.localAI.ensurePlatform()` | None | [`Promise<LocalAIPlatformResult>`](arcane-ai-contracts.md#local-ai-platform-result) | Runs the Provisioner-only post-install AI reconciliation as one exclusive operation: returns an explicitly selected, configured OpenAI state without touching Ollama, or hardware-admits, ensures, and loads the managed local model according to boot settings. Requires `provisioning.manage` and the `provisioner` app type. |
104
+ | `Arcane.localAI.recover(request)` | `request`: [`LocalAIRecoveryRequest`](arcane-ai-contracts.md#local-ai-recovery-request) | [`Promise<LocalAIRecoveryResult>`](arcane-ai-contracts.md#local-ai-recovery-result) | Requests one privileged, exclusive, start-existing-service-only recovery of selected Arcane-managed local services. Requires `ai.inference` and explicit application admission. |
105
+ | `Arcane.localAI.setParallelRequests(request)` | `request`: [`LocalAIParallelRequestsRequest`](arcane-ai-contracts.md#local-ai-parallel-request-configuration) | [`Promise<LocalAIParallelRequestsResult>`](arcane-ai-contracts.md#local-ai-parallel-request-configuration) | Solves one app-owned verified model/context's maximum directly from native model and memory/resource evidence without a product ceiling, clamps a positive request to that result (`0` requests the maximum), and changes the machine-wide managed Ollama setting only when needed. A tentative change uses one fresh stopped-service snapshot before the final value is written, then Core ensures, loads, and confirms the exact model. A restart unloads resident models. Automatic mutation currently requires the dedicated `ai.runtime.manage` capability on Microsoft NT desktop Core and operating-system authorization; Linux returns administrator-managed systemd guidance, and Android user-managed loopback sessions do not invoke it. |
106
+ | `Arcane.speech.status()` | None | [`Promise<SpeechStatus>`](arcane-ai-contracts.md#speech-status) | Reads bounded, independent Kokoro and Whisper readiness through Core or an admitted Android native host. Requires `ai.inference`. |
107
+ | `Arcane.speech.synthesize(request)` | `request`: [`SpeechSynthesisRequest`](arcane-ai-contracts.md#speech-synthesis-request) | [`Promise<SpeechSynthesisResult>`](arcane-ai-contracts.md#speech-synthesis-result) | Synthesizes bounded local speech through the native host and fixed loopback runtime. Requires `ai.inference`. |
108
+ | `Arcane.speech.transcribe(request)` | `request`: [`SpeechTranscriptionRequest`](arcane-ai-contracts.md#speech-transcription-request) | [`Promise<SpeechTranscriptionResult>`](arcane-ai-contracts.md#speech-transcription-result) | Sends bounded canonical base64 bytes labeled `audio/webm` to local Whisper through the native host. The bridge validates encoding, label, and bounds; the fixed service parses the media container. Requires `ai.inference`. |
109
+ | `Arcane.ollama.version()` | None | [`Promise<OllamaVersionResponse>`](arcane-ai-contracts.md#ollama-provider-responses) | Gets the managed Ollama version for Settings, Terminal, and Shell diagnostics. |
110
+ | `Arcane.ollama.models()` | None | [`Promise<OllamaModelsResponse>`](arcane-ai-contracts.md#ollama-provider-responses) | Lists the raw provider inventory envelope; it is not the application admission catalog. |
111
+ | `Arcane.ollama.list()` | None | [`Promise<OllamaModelsResponse>`](arcane-ai-contracts.md#ollama-provider-responses) | Alias of the raw `models()` inventory. |
112
+ | `Arcane.ollama.running()` | None | [`Promise<OllamaRunningModelsResponse>`](arcane-ai-contracts.md#ollama-provider-responses) | Lists the provider running-model envelope. |
113
+ | `Arcane.ollama.show(model, options?)` | `model`: [`OllamaModelName`](arcane-ai-contracts.md#ollama-model-name); `options?`: [`OllamaShowOptions`](arcane-ai-contracts.md#ollama-show-options) | [`Promise<OllamaShowResponse>`](arcane-ai-contracts.md#ollama-provider-responses) | Gets model metadata and configuration. |
114
+ | `Arcane.ollama.generate(request, options?)` | `request`: [`OllamaGenerateRequest`](arcane-ai-contracts.md#ollama-generate-request); `options?`: [`OllamaStreamControls`](arcane-ai-contracts.md#ollama-stream-controls) or [`OllamaChunkCallback`](arcane-ai-contracts.md#ollama-chunk-callback) | [`Promise<OllamaGenerateResponse>`](arcane-ai-contracts.md#ollama-provider-responses) | Generates text after Core re-admits the exact requested model; optionally streams chunks. |
115
+ | `Arcane.ollama.chat(request, options?)` | `request`: [`OllamaChatRequest`](arcane-ai-contracts.md#ollama-chat-request); `options?`: [`OllamaStreamControls`](arcane-ai-contracts.md#ollama-stream-controls) or [`OllamaChunkCallback`](arcane-ai-contracts.md#ollama-chunk-callback) | [`Promise<OllamaChatResponse>`](arcane-ai-contracts.md#ollama-provider-responses) | Runs native Ollama chat after the host re-admits the exact requested model, optionally streamed. An admitted Android host proxies only this inference operation to its user-managed fixed loopback service and exposes no model mutation or lifecycle operation. |
116
+ | `Arcane.ollama.embed(request)` | `request`: [`OllamaEmbedRequest`](arcane-ai-contracts.md#ollama-embed-request) | [`Promise<OllamaEmbedResponse>`](arcane-ai-contracts.md#ollama-provider-responses) | Creates embeddings after Core re-admits the exact requested model. |
117
+ | `Arcane.ollama.pull(model, options?, streamOptions?)` | `model`: [`OllamaModelName`](arcane-ai-contracts.md#ollama-model-name); `options?`: [`OllamaPullOptions`](arcane-ai-contracts.md#ollama-pull-options); `streamOptions?`: [`OllamaStreamControls`](arcane-ai-contracts.md#ollama-stream-controls) or [`OllamaChunkCallback`](arcane-ai-contracts.md#ollama-chunk-callback) | [`Promise<never>`](arcane-ai-contracts.md#raw-ollama-management-restrictions) | Direct application pull fails closed; Arcane's managed workflow owns integrity-bound preflight and admission. |
118
+ | `Arcane.ollama.push(model, options?, streamOptions?)` | `model`: [`OllamaModelName`](arcane-ai-contracts.md#ollama-model-name); `options?`: [`OllamaPushOptions`](arcane-ai-contracts.md#ollama-push-options); `streamOptions?`: [`OllamaStreamControls`](arcane-ai-contracts.md#ollama-stream-controls) or [`OllamaChunkCallback`](arcane-ai-contracts.md#ollama-chunk-callback) | [`Promise<OllamaPushResponse>`](arcane-ai-contracts.md#ollama-provider-responses) | Pushes only a model authorized by verified application policy. |
119
+ | `Arcane.ollama.create(request, options?)` | `request`: [`OllamaCreateRequest`](arcane-ai-contracts.md#ollama-create-request); `options?`: [`OllamaStreamControls`](arcane-ai-contracts.md#ollama-stream-controls) or [`OllamaChunkCallback`](arcane-ai-contracts.md#ollama-chunk-callback) | [`Promise<OllamaCreateResponse>`](arcane-ai-contracts.md#ollama-provider-responses) | Creates a package-owned verified alias only after `from`, normalized `system`, and `parameters` match policy and `files`/`adapters` are absent; other admitted fields remain provider-native. |
120
+ | `Arcane.ollama.copy(source, destination)` | `source`: [`OllamaModelName`](arcane-ai-contracts.md#ollama-model-name); `destination`: [`OllamaModelName`](arcane-ai-contracts.md#ollama-model-name) | [`Promise<never>`](arcane-ai-contracts.md#raw-ollama-management-restrictions) | Raw application alias copy is denied; managed selection owns alias mutation. |
121
+ | `Arcane.ollama.delete(model)` | `model`: [`OllamaModelName`](arcane-ai-contracts.md#ollama-model-name) | [`Promise<OllamaDeleteResponse>`](arcane-ai-contracts.md#ollama-provider-responses) | Deletes only a model authorized by verified application policy. |
122
+ | `Arcane.ollama.selection()` | None | [`Promise<ArcaneModelSelection>`](arcane-ai-contracts.md#arcane-model-selection) | Gets Arcane's managed model preference and state. |
123
+ | `Arcane.ollama.select(preference)` | `preference`: [`ArcaneModelPreference`](arcane-ai-contracts.md#arcane-model-preference) | [`Promise<ArcaneModelSelectionResult>`](arcane-ai-contracts.md#arcane-model-selection-result) | Selects a managed size preference and reconciles the model. |
124
+ | `Arcane.ollama.settings()` | None | [`Promise<ArcaneModelSelection>`](arcane-ai-contracts.md#arcane-model-selection) | Gets Ollama runtime settings. |
125
+ | `Arcane.ollama.saveSettings(settings)` | `settings`: [`ArcaneAISettingsInput`](arcane-ai-contracts.md#arcane-ai-settings-input) | [`Promise<ArcaneAISettingsResult>`](arcane-ai-contracts.md#arcane-ai-settings-result) | Saves only runtime-owned default-model, boot-load, keep-alive, and context settings. |
126
+ | `Arcane.ollama.createBrain(definition)` | `definition`: [`ArcaneBrainDefinition`](arcane-ai-contracts.md#arcane-brain-definition) | [`Promise<ArcaneBrainResult>`](arcane-ai-contracts.md#arcane-brain-result) | Creates an Arcane brain model. |
127
+ | `Arcane.ollama.serviceSettings()` | None | [`Promise<OllamaServiceSettingsState>`](arcane-ai-contracts.md#ollama-service-settings-state) | Gets managed Ollama service settings. |
128
+ | `Arcane.ollama.saveServiceSettings(settings)` | `settings`: [`OllamaServiceSettingsInput`](arcane-ai-contracts.md#ollama-service-settings-input) | [`Promise<OllamaServiceSettingsResult>`](arcane-ai-contracts.md#ollama-service-settings-result) | Saves managed service settings. |
129
+
130
+ The native AI profile always returns `responseLength` as `"low"`, `"medium"`,
131
+ or `"high"`; missing or invalid legacy persisted values safely resolve to
132
+ `"medium"`. New saves reject any other value. Conversational applications may
133
+ use this target to augment their system prompt, but specific user requests and
134
+ required application, structured-output, tool, safety, evidence, warning, or
135
+ next-step content take precedence.
136
+
137
+ `Arcane.localAI.status()` is a native-host, non-mutating discovery and
138
+ admission API. An abridged representative desktop Core schema-v2 result is:
139
+
140
+ ```json
141
+ {
142
+ "schemaVersion": 2,
143
+ "runtime": {
144
+ "kind": "arcane-core",
145
+ "nativeModelAdmission": true
146
+ },
147
+ "policy": {
148
+ "verified_only": true,
149
+ "source": "package-bound-application-policy",
150
+ "unverifiedInferenceAuthorized": false
151
+ },
152
+ "ollama": {
153
+ "available": true,
154
+ "modelCapabilitiesVerified": true,
155
+ "nativeAdmissionEnforced": true,
156
+ "errorCode": null
157
+ },
158
+ "admission": {
159
+ "policyVersion": 1,
160
+ "enforcedBy": "arcane-core",
161
+ "evaluatedModels": 1,
162
+ "admittedModels": 1,
163
+ "rejected": []
164
+ },
165
+ "speech": {
166
+ "available": true,
167
+ "reachable": true,
168
+ "synthesisAvailable": true,
169
+ "transcriptionAvailable": true,
170
+ "synthesisErrorCode": null,
171
+ "transcriptionErrorCode": null,
172
+ "errorCode": null
173
+ },
174
+ "models": {
175
+ "ollama": [
176
+ {
177
+ "id": "EXAMPLE:8b",
178
+ "name": "EXAMPLE:8b",
179
+ "provider": "ollama",
180
+ "roles": [],
181
+ "managed": true,
182
+ "installed": true,
183
+ "admitted": true,
184
+ "runnable": true,
185
+ "creatable": false,
186
+ "pullable": false,
187
+ "verified": true,
188
+ "capabilitiesVerified": true,
189
+ "available": true,
190
+ "modifiedAt": null,
191
+ "sizeBytes": 1,
192
+ "digest": null,
193
+ "family": null,
194
+ "parameterSize": null,
195
+ "quantization": null,
196
+ "compatibility": {
197
+ "policyVersion": 1,
198
+ "admitted": true,
199
+ "status": "compatible",
200
+ "code": null,
201
+ "message": "EXAMPLE:8b fits the current native resource budget.",
202
+ "resolution": null
203
+ }
204
+ }
205
+ ],
206
+ "speech": [
207
+ {
208
+ "id": "kokoro",
209
+ "name": "Kokoro",
210
+ "provider": "speech",
211
+ "roles": ["tts"],
212
+ "available": true,
213
+ "engine": "kokoro"
214
+ }
215
+ ],
216
+ "transcription": [
217
+ {
218
+ "id": "whisper-small",
219
+ "name": "Whisper Small",
220
+ "provider": "speech",
221
+ "roles": ["stt"],
222
+ "available": true,
223
+ "engine": "whisper.cpp"
224
+ }
225
+ ]
226
+ }
227
+ }
228
+ ```
229
+
230
+ The development Android variant keeps the same schema version and adds the
231
+ exact top-level discriminator `providerMode:"user-managed-loopback"`. Its
232
+ runtime kind is `android-user-managed-loopback`, `managedLocalAI` remains
233
+ false, and `models.ollama` contains only installed package-policy models that
234
+ passed the host's bounded provider inspection. The same status operation starts
235
+ a concurrent bounded native speech probe and merges its actual role health and
236
+ Kokoro/Whisper catalog into the standard speech fields without making speech
237
+ failure hide an available Ollama catalog. The separately capability-gated
238
+ `Arcane.speech` methods proxy the fixed host-owned loopback speech service for
239
+ an admitted application host. Readiness calls `Arcane.speech.status()` through that bridge, while
240
+ profile discovery consumes the merged status catalog; neither path fetches a
241
+ loopback endpoint from the renderer. Inference uses `Arcane.ollama.chat`. No renderer makes a direct
242
+ loopback request, and no recovery, pull, create, delete, start, stop, or repair
243
+ method is admitted.
244
+
245
+ Android Linux Terminal, Ollama, and model lifecycle remain user-owned. A plain loopback Ollama
246
+ listener has no caller authentication, so other local applications or
247
+ processes can call or race it. This is unsigned development behavior, not
248
+ release support, a managed-service claim, or an isolated-inference guarantee.
249
+ Android exposes no application-owned isolated-question or repository extension
250
+ unless the generated package and method policy explicitly admit it.
251
+
252
+ An admitted model's `compatibility` also carries the evaluated operation and
253
+ model, actual installed model bytes, context tokens, K/V-cache estimate,
254
+ runtime headroom, total and additional working-set requirements, available
255
+ working-set bytes, loaded and target-resident bytes, and the individual memory
256
+ and, for a pull, model-store checks. A rejected entry is returned as
257
+ `{id, compatibility}` under `admission.rejected`; its compatibility record has
258
+ `admitted:false`, `status:"incompatible"` or
259
+ `status:"evidence-unavailable"`, a stable code, bounded message and resolution,
260
+ and the evidence that was available. Rejected models do not appear in
261
+ `models.ollama`.
262
+
263
+ Core starts the bounded Ollama catalog, running-model inventory, and speech
264
+ health work together and coalesces concurrent status callers. It inspects model
265
+ metadata with bounded concurrency before admitting a candidate. A failed
266
+ service resolves as service-local status data and does not erase the other
267
+ service's result. `ollama.available` means the fixed catalog endpoint returned
268
+ a valid bounded inventory; it does not mean any model passed policy or resource
269
+ admission. Speech synthesis and transcription remain independent, and the
270
+ fixed `kokoro` and `whisper-small` identities appear only when their respective
271
+ health dependencies are ready.
272
+
273
+ ### Package policy and authoritative model discovery
274
+
275
+ The policy is authored only as
276
+ `apps/<id>/arcane-package.json.localAIModelPolicy`, carried by the verified
277
+ `ARCANE_APP_RELEASE.json` native admission record, and projected by the native
278
+ packager only into the compiled Core `APP_DESCRIPTOR.aiModelPolicy`. It is not
279
+ returned by `Arcane.app.current()`, `Arcane.capabilities.list()`, a browser
280
+ manifest, a document catalog, or another browser-facing API. Renderer code does
281
+ not consume or reconstruct it.
282
+
283
+ For `verified_only:true`, Core considers only app-declared managed candidates.
284
+ It verifies an installed alias against the exact packaged app-owned Modelfile
285
+ before native resource admission. A missing alias can appear as `creatable`
286
+ only when its already-installed base passes admission, or as `pullable` only
287
+ when registry preflight supplies the integrity-bound byte and metadata evidence
288
+ needed for pull admission. Before inference Core completes that managed
289
+ lifecycle and re-verifies the resulting alias. The current automatic path fails
290
+ closed when actual base bytes are unavailable before download.
291
+
292
+ For `verified_only:false`, the native descriptor must also grant
293
+ `ai.models.unverified.inference`. Core may additionally consider any
294
+ already-installed model, using a bounded default context when the request does
295
+ not supply one, but still admits only models whose actual bytes and metadata fit
296
+ the current native resource evidence. Unverified access is inference-only:
297
+ Core never pulls, creates, repairs, copies, pushes, or deletes an unverified
298
+ model. Policy/capability disagreement fails closed during native packaging and
299
+ again in Core.
300
+
301
+ Admission derives from actual installed model bytes and model metadata,
302
+ requested context and K/V-cache type, configured parallelism, free system and
303
+ GPU memory with safety reserves, currently loaded models and target residency,
304
+ and model-store free space for pulls. It does not use renderer-reported hardware
305
+ or a GPU-name allowlist. Missing size, context, model metadata, K/V-cache inputs,
306
+ native memory evidence, or required storage evidence rejects the model.
307
+
308
+ For a missing managed base, Core preflights only a canonical Ollama library
309
+ registry name. It bounds manifest/configuration responses, layer counts, byte
310
+ sizes, redirects, content encoding, deadlines, cache entries, and successively
311
+ ranged GGUF prefixes (at most 256 KiB). It SHA-256-verifies the configuration and
312
+ its binding to the declared model layers, then extracts only the model dimensions
313
+ needed for K/V estimation. The ranged bytes are explicitly not a full layer
314
+ digest. After admission, Ollama must finish the full-digest-verified pull and
315
+ Core must observe the installed base before alias creation, exact-definition
316
+ verification, or inference. Any unavailable or inconsistent evidence fails
317
+ closed.
318
+
319
+ Applications call the method after rendering their initial UI and populate
320
+ local-model controls from `models.ollama` in the returned order. They must not
321
+ apply a second alias, parameter-count, family, memory, or GPU filter: Core's
322
+ catalog is authoritative for that app and session. The method itself does not
323
+ change a profile, choose a remote fallback, start or repair a service, pull a
324
+ base, create an alias, or perform inference.
325
+
326
+ Desktop Core admits the status catalog at one parallel request and separately
327
+ reports `activeParallelRequests`, `maxAllowedParallelRequests`, and
328
+ `activeParallelRequestsAllowed`. Thus a policy-valid model can remain visible
329
+ with `runnable:false` when the current machine-wide count is too high. An
330
+ authorized model-selection UI can also show Core's bounded
331
+ `admission.rejected` records as disabled choices so a model is not mistaken for
332
+ uninstalled merely because it cannot currently fit. Those records remain
333
+ observations; only the dedicated privileged
334
+ `setParallelRequests()` operation can change the count and load a model.
335
+
336
+ The admitted catalog is part of local inference authorization, so the method
337
+ requires `ai.inference`. Raw inventory methods require `ai.models.read` and are
338
+ restricted to Settings, Terminal, and Shell. The admitted status API is
339
+ unavailable to Android and to an ordinary browser without an app-scoped Core.
340
+ Browser applications are OpenAI-only and must not probe or call Ollama directly.
341
+ A native standalone package has its own app-scoped Core and can use the status
342
+ method when its descriptor grants inference.
343
+
344
+ `Arcane.localAI.recover()` accepts only the own `services` field; an empty
345
+ array, duplicate or unknown identifier, additional field, or unsupported
346
+ System Platform fails before an exclusive mutation or elevation request. Core
347
+ canonicalizes a two-service request to `ollama` then `speech`. On Microsoft NT,
348
+ the fixed service identities are `ArcaneOllama` at
349
+ `C:\Program Files\Ollama\ArcaneOllamaService.exe` and `ArcaneLocalSpeech` at
350
+ `C:\Program Files\Arcane OS\bin\ArcaneLocalSpeechService.exe`. Before the first
351
+ state change, the adapter proves every requested registration's exact command,
352
+ `LocalService` account, automatic own-process start configuration, unrestricted
353
+ service SID, empty dependencies, the exact service-specific environment, and
354
+ regular fixed host. It then runs only `sc.exe start` for a verified stopped
355
+ fixed service and rechecks the registration and fixed health proof. The method
356
+ never installs, creates, reconfigures, stops, deletes, or changes an ACL. A
357
+ successful service result is returned in canonical order; `started` is `true`
358
+ only when that recovery request issued the start.
359
+
360
+ The Microsoft NT development builder places the manifest-bound
361
+ `ArcaneLocalSpeechService.exe` host and local speech runtime in the release.
362
+ Installation or repair, not this application method, validates the activated
363
+ files, registers `ArcaneLocalSpeech` at the fixed path as an automatic
364
+ own-process `LocalService` with an unrestricted service SID and no dependencies
365
+ or service environment, starts it, and requires its bounded probe. A request
366
+ against a pre-change or damaged installation still fails closed with
367
+ `LOCAL_AI_SERVICE_NOT_INSTALLED` and verified-repair guidance. Recovery never
368
+ adopts an independently launched speech executable. This is development
369
+ behavior; production signing and clean-machine promotion evidence remain
370
+ deferred.
371
+
372
+ Application-owned extension methods, schemas, repository bindings, and
373
+ isolation policy are documented with the package that owns them. Arcane Core
374
+ does not expose a generic Git API or infer application authority from this
375
+ product-neutral reference.
376
+
377
+ ## Applications, terminal, and capabilities
378
+
379
+ | Method | Parameters | Return | Description |
380
+ |---|---|---|---|
381
+ | `Arcane.app.current()` | None | `Promise<app record>` | Gets the exact bound application descriptor. Its `version` is owned by that app's `arcane-package.json`; built-in Shell and Provisioner use the OS bundle version. Android returns the immutable Shell or application-APK identity with `unverified` publisher status. |
382
+ | `Arcane.applications.list()` | None | `Promise<{verified, securityMode, publisherTrustSource, revocationStatus, applications}>` | Returns the verified installed-application catalog wrapper visible to Shell or Terminal; it is not a bare array. The RPC authority name is `apps.list`. |
383
+ | `Arcane.applications.launch(id)` | Canonical application ID from the current catalog | `Promise<{id, accepted:true}>` | Asks the host to dispatch a registered application. Acceptance does not prove that the target rendered, became ready, or remained open. The RPC authority name is `apps.launch`. |
384
+ | `Arcane.external.open(uri)` | Exact printable-ASCII URI without whitespace, fragments, backslashes, malformed escapes, or encoded controls; currently `mailto:` only | `Promise<{opened, uri}>` | Hands a validated URI to the operating system's registered default application. `opened: true` means only that the OS accepted the handoff, not that a composer opened or a message was sent. Simulation fails explicitly instead of claiming a handoff. Requires `external.open`. |
385
+ | `Arcane.mail.send({report, reportKey})` | Exact report with `type`, `subject`, `to`, and `text` and/or `html`; `reportKey` matches `[A-Za-z0-9._:-]{8,128}`; report JSON no larger than 786,432 bytes | `Promise<{requestId,status,statusCode,sent,partial,uncertain}>` | Validates and forwards one bounded request to the fixed loopback Arcane mail gateway without Core retry. The shared Mail module preflights the same native size bound. Availability requires explicit `mail.send` application admission on Microsoft NT/Linux Core hosts; Android does not project this method, and simulation fails explicitly. |
386
+ | `Arcane.terminal.start(options?)` | `options?`: `{shell="auto", cwd="", columns=120, rows=32}`; shell is `auto`, `powershell`, `cmd`, `bash`, or `sh`; columns 20–500; rows 5–200 | `Promise<{id,shell,cwd,title,columns,rows,createdAt}>` | Starts one of at most eight app-owned native terminal sessions. Requires `terminal.execute`, app id `terminal`, and a Core or Android host. |
387
+ | `Arcane.terminal.list()` | None | `Promise<{sessions: Array<{id,shell,cwd,columns,rows,createdAt,state}>}>` | Lists the current app-owned sessions; it returns a wrapper object, not a bare array. Requires `terminal.execute`, app id `terminal`, and a Core or Android host. |
388
+ | `Arcane.terminal.write(sessionId, data)` | `sessionId`: 1–128-character session identifier; `data`: 1–65,536 UTF-8 bytes | `Promise<{sessionId,accepted:true,bytes}>` | Writes one input chunk. Output is delivered separately through `terminal.output`, so subscribe before starting a session and correlate chunks by `sessionId`. |
389
+ | `Arcane.terminal.resize(sessionId, columns, rows)` | `sessionId`; `columns`: 20–500; `rows`: 5–200 | `Promise<{sessionId,columns,rows,accepted:true,emulated:true}>` | Updates the session dimensions. The current hosts record an emulated resize rather than claiming a native pseudo-terminal resize. |
390
+ | `Arcane.terminal.signal(sessionId, signal="interrupt")` | `sessionId`; `signal`: `"interrupt"` or `"terminate"` | `Promise<{sessionId,signal,accepted}>` | Requests a supported control signal. `accepted` reports process-controller acceptance, not process exit; observe `terminal.exit` for completion. |
391
+ | `Arcane.terminal.close(sessionId)` | `sessionId`: 1–128-character session identifier | `Promise<{sessionId,accepted:true}>` | Closes input and requests session termination. The resolved value acknowledges the request; observe `terminal.exit` for actual process completion. |
392
+ | `Arcane.capabilities.list()` | None | `Promise<{app, grants, methods}>` | Returns the current Core-bound application descriptor, grants, and exact allowed RPC names. Android callers use `Arcane.platform.status().capabilities`; the direct method is not projected there. |
393
+
394
+ Terminal output and lifecycle changes are event-driven. The canonical [Arcane event inventory](arcane-events.md#event-inventory) defines `terminal.output`, `terminal.exit`, and the Android `terminal.error` payload. The shared `TerminalClient` adapter correlates those deliveries with owned sessions and re-emits DOM events for reusable UI code.
395
+
396
+ ## Platform, installation, users, and system
397
+
398
+ | Method | Parameters | Return | Description |
399
+ |---|---|---|---|
400
+ | `Arcane.platform.status()` | None | `Promise<status>` | Gets native platform status. |
401
+ | `Arcane.permissions.status()` | None | `Promise<status>` | Gets permission/elevation status. |
402
+ | `Arcane.version.current()` | None | `Promise<string>` | Gets the Arcane OS bundle/host version bound to this session. It does not become an application's independently owned version and is not signer, update, or RC attestation. |
403
+ | `Arcane.version.installation()` | None | `Promise<installation status>` | Alias-like access to installation status. |
404
+ | `Arcane.machine.status()` | None | `Promise<status>` | Gets machine readiness/status. |
405
+ | `Arcane.user.current()` | None | `Promise<{identityKind, username, accountName, displayName, source}>` | Gets the privacy-minimized bound identity. Microsoft NT/Linux return a `host-account`; Android returns an anonymous `local-session` with null account identifiers. Requires `identity.read`. |
406
+ | `Arcane.requirements.list()` | None | `Promise<requirement[]>` | Lists installation requirements. |
407
+ | `Arcane.requirements.ensure(requirementIds, options?)` | Array of requirement IDs; omitted, `null`, or empty selects required requirements only; `options.userProcessInterruption` is exactly `deny` or `allow` and defaults to `deny` | `Promise<{requirements, operation, credentials}>` | Ensures the selected requirements are installed/configured. The guarded Provisioner-open Ollama reconciliation always uses `deny`; only the separately confirmed close-and-retry action uses `allow`, and the native handoff still re-proves exact process and port identity before any interruption. |
408
+ | `Arcane.installation.status()` | None | `Promise<status>` | Gets installation state. |
409
+ | `Arcane.installation.ensure()` | None | `Promise<result>` | Ensures the Arcane installation reaches its required state. |
410
+ | `Arcane.installation.openUninstaller()` | None | `Promise<{opened:true}>` | Microsoft NT Provisioner only. Opens the globally installed `C:\Program Files\Arcane OS\bin\ArcaneUninstaller.exe`; it never uninstalls through checkout-local code. `opened` means Windows accepted creation of the installed uninstaller process. The controller separately owns UAC, read-only preflight, scope review, and typed confirmation. |
411
+ | `Arcane.users.list()` | None | `Promise<{users, policy, protectedUsernames}>` | Lists supported local users plus the platform username policy and accounts the Provisioner must not convert. |
412
+ | `Arcane.users.validate(usernames)` | Username or array | `Promise<{valid, users, errors, policy}>` | Validates candidate usernames without changing an account. |
413
+ | `Arcane.users.add(usernames)` | Username or array | `Promise<{users, operation, credentials}>` | Creates/configures local Arcane users and returns sensitive temporary credentials for protected presentation. |
414
+ | `Arcane.users.activate(username)` | Username | `Promise<{user, operation, credentials}>` | Activates a staged configured user. |
415
+ | `Arcane.users.resetPassword(username)` | Username | `Promise<{user, operation, credentials}>` | Prepares a temporary credential but does not change the operating-system password; apply it with `users.applyPassword()`. |
416
+ | `Arcane.users.applyPassword(username, temporaryPassword)` | Username; exact temporary password from the current workflow | `Promise<{user, operation, credentials}>` | Performs the privileged native password mutation and forces change at next sign-in. |
417
+ | `Arcane.users.verifyShell(username)` | Username | `Promise<{user, operation, credentials}>` | Verifies the user's Arcane shell configuration. |
418
+ | `Arcane.users.restoreShell(username)` | Username | `Promise<{user, operation, credentials}>` | Restores the recorded supported shell configuration. |
419
+ | `Arcane.system.lock()` | None | `Promise<result>` | Locks the operating-system session. |
420
+ | `Arcane.system.ping()` | None | `Promise<{ok:true}>` | Confirms only that the bound host bridge admitted and answered the request. It does not claim dependency readiness, system health, privilege, signer trust, or release-candidate status. |
421
+ | `Arcane.system.metrics()` | None | `Promise<metrics>` | Gets allowed machine metrics. |
422
+ | `Arcane.system.failurePolicy()` | None | `Promise<{failFast:boolean}>` | Gets the user-wide verification behavior. `failFast` defaults to `false`; application-owned repository readers may use it to choose validated-subset warnings or immediate rejection. Settings only. |
423
+ | `Arcane.system.saveFailurePolicy(settings)` | `{failFast:boolean}` | `Promise<{failFast:boolean}>` | Saves warn-first (`false`) or fail-fast (`true`) behavior. The preference does not expose quarantined documents or relax repository-write validation. Settings only. |
424
+ | `Arcane.network.status()` | None | `Promise<{online, interfaceCount}>` | Counts interfaces with at least one non-loopback address. `online` does not claim Internet, DNS, captive-portal, route, or service reachability. |
425
+ | `Arcane.firewall.status()` | None | `Promise<FirewallStatus>` | Firewall-app-only status for the canonical policy, Arcane-owned platform plan/state, projection, audit count, limitations, supported lifecycle operations, and fail-closed `installReady`/`enableReady` evidence. Current non-simulation status is unsupported; simulation is labeled and never claims machine-wide coverage. Requires `firewall.read`. |
426
+ | `Arcane.firewall.audit(options?)` | Optional `{limit}` integer from 1 through 200 | `Promise<FirewallAudit>` | Returns bounded lifecycle and owned-state metadata, not packet payloads or complete per-packet attribution. Requires `firewall.read`. |
427
+ | `Arcane.firewall.install(expectation)` | `{expectedPolicyGeneration, expectedStateGeneration}` | `Promise<FirewallOperationResult>` | After separate user confirmation, stages the reviewed global-deny projection in deterministic development simulation. Domain projection may use bounded system DNS and admits at most 4,096 domain rules; status disables Install before confirmation when the canonical policy exceeds that native ceiling. Live mutation is unavailable. Requires `firewall.manage`. |
428
+ | `Arcane.firewall.enable(expectation)` | `{expectedPolicyGeneration, expectedStateGeneration}` | `Promise<FirewallOperationResult>` | After confirmation, enables only the exact installed, unexpired projection in simulation; it does not resolve or silently replace policy. Requires `firewall.manage`. |
429
+ | `Arcane.firewall.disable(expectation)` | `{expectedPolicyGeneration, expectedStateGeneration}` | `Promise<FirewallOperationResult>` | After confirmation, disables only Arcane-owned simulation state. Requires `firewall.manage`. |
430
+ | `Arcane.firewall.rollback(expectation)` | `{expectedPolicyGeneration, expectedStateGeneration}` | `Promise<FirewallOperationResult>` | After confirmation, restores only an unexpired retained projection for the current canonical policy when it preserves every current deny. Requires `firewall.manage`. |
431
+ | `Arcane.firewall.recover(expectation)` | `{expectedPolicyGeneration, expectedStateGeneration}` | `Promise<FirewallOperationResult>` | After confirmation, reconciles only Arcane-owned simulation state; divergence blocks other lifecycle actions. Requires `firewall.manage`. |
432
+
433
+ Core-backed `platform.status` and `machine.status` records include `execution.hostPlatform`, `execution.effectivePlatform`, `execution.simulation`, and `execution.evidenceClass`. The Android bridge returns the same execution fields with `application-host` evidence. A simulated effective platform is test evidence only; no simulation or source-only Android assertion is real-host, publisher, signing, or release-candidate evidence.
434
+
435
+ The native desktop contract retains the technical compatibility values `platform: "windows"` and `rawPlatform: "win32"`; user-facing interfaces present that family as **Microsoft NT**. `arcane/modules/SystemPlatformPresentation.js` maps the verified status to `Microsoft NT` or `Linux` and applies `arcane-kernel-nt` or `arcane-kernel-linux`, plus `data-arcane-kernel`, to the document root. Those DOM values exist only for presentation and CSS. They must never grant a capability, establish release trust, select a native adapter, or substitute for `Arcane.permissions.status()` and host-verified execution evidence.
436
+
437
+ The canonical authority registry in `machine_bundles/arcane-os-machine-bundle/src/api/method-policies.json` defines the current RPC surface. The canonical semantic definitions for the shared or contract-bound methods live in `machine_bundles/arcane-os-machine-bundle/src/api/method-contracts.json`. They are deliberately separate from method authority policy: semantic effect metadata cannot grant a capability, admit an application or host, or imply privilege. Core executes the closed input/output validators at its request and response boundaries. Android consumes separately generated semantic constants for its admitted cross-host subset and validates or constructs the corresponding results; Core alone consumes the fixed-loopback mail contract. The exact unsigned-debug Android distribution now has Kotlin build parity and API 35 Launcher, Browser, and Terminal instrumentation evidence. The registry remains a partial vertical slice: privacy-safe audit and confirmation infrastructure, definitions for the remaining Core-only methods, production signing, real-device conformance, and candidate review are still required.
438
+
439
+ ## Filesystem, storage, preferences, and appearance
440
+
441
+ | Method | Parameters | Return | Description |
442
+ |---|---|---|---|
443
+ | `Arcane.filesystem.selectDirectory(options?)` | `options?`: `{title?, initialPath?}`; title up to 200 plain-text characters; initial path must be an existing absolute directory | `Promise<{cancelled:boolean, path:string\|null}>` | Opens the native directory picker after a user action. It returns one canonical existing directory or explicit cancellation; it does not enumerate or grant access to directory contents. Requires `filesystem.directory.select`. |
444
+ | `Arcane.storage.list()` | None | `Promise<{keys:string[], usedBytes:number, maximumBytes:1048576}>` | Lists sorted keys and quota use for the current application's isolated native storage. Requires `storage.read`. |
445
+ | `Arcane.storage.get(key)` | `key`: 1–128-character app-storage key | `Promise<{key, found:boolean, value}>` | Reads one app-scoped JSON value. A missing key resolves with `found:false,value:null`. Requires `storage.read`. |
446
+ | `Arcane.storage.set(key, value)` | `key`; JSON-compatible `value` up to 131,072 encoded bytes | `Promise<{key, value, bytes, totalBytes, maximumBytes}>` | Atomically writes one app-scoped value under the 1 MiB total quota. Requires `storage.write`. |
447
+ | `Arcane.storage.delete(key)` | `key`: 1–128-character app-storage key | `Promise<{key, deleted:boolean, totalBytes, maximumBytes}>` | Deletes one app-scoped value; an absent key resolves with `deleted:false`. Requires `storage.write`. |
448
+ | `Arcane.preferences.list()` | None | `Promise<{keys:string[], usedBytes:number, maximumBytes:1048576}>` | Lists sorted keys and quota use for the current application's isolated preferences. Requires `preferences.read`. |
449
+ | `Arcane.preferences.get(key)` | `key`: 1–128-character preference key | `Promise<{key, found:boolean, value}>` | Reads one preference. A missing key resolves with `found:false,value:null`. Requires `preferences.read`. |
450
+ | `Arcane.preferences.set(key, value)` | `key`; JSON-compatible `value` up to 131,072 encoded bytes | `Promise<{key, value, bytes, totalBytes, maximumBytes}>` | Atomically writes one preference under the 1 MiB total quota. Requires `preferences.write`. |
451
+ | `Arcane.preferences.setMany(entries)` | Plain object containing one to 32 preference key/value entries | `Promise<{keys, count, bytes, totalBytes, maximumBytes}>` | Validates the complete bounded batch and writes it atomically; no preference changes when any entry is invalid. Requires `preferences.write`. |
452
+ | `Arcane.preferences.delete(key)` | `key`: 1–128-character preference key | `Promise<{key, deleted:boolean, totalBytes, maximumBytes}>` | Deletes one preference; an absent key resolves with `deleted:false`. Requires `preferences.write`. |
453
+ | `Arcane.environment.list()` | None | `Promise<{platform, pathSupported, maximumEntries, valueMaximumLength, persistence, entries}>` | Lists the native Arcane environment profile. Ordinary values are returned; protected values are exactly `•••••`. Requires `environment.read` and explicit application admission. |
454
+ | `Arcane.environment.get(name)` | `name`: environment-variable name | `Promise<{entry}>` | Gets one configured entry. This is the deliberate plaintext-reveal operation: a protected entry's real value crosses the native bridge to the authorized renderer. Requires the separate `environment.protected.read` capability. |
455
+ | `Arcane.environment.set(name, value, options?)` | `name`: environment-variable name; `value`: string up to 32,767 characters generally, but a Linux protected value is limited by the 8,191-byte encoded Secret Service payload (about 6,126 ASCII value bytes); `options.protected?`: Boolean | `Promise<{entry}>` | Creates or replaces a desktop user-scoped or Android app-scoped entry. Android rejects `PATH`; the SDK defaults sensitive-looking names to protected storage, and the returned protected value remains `•••••`. Requires `environment.write` and explicit application admission. |
456
+ | `Arcane.environment.remove(name)` | `name`: environment-variable name | `Promise<{name, deleted:true}>` | Deletes one configured entry. Requires `environment.write` and explicit application admission. |
457
+ | `Arcane.appearance.current()` | None | `Promise<{supported, platform, scheme, effectiveScheme, captionColor, textColor}>` | Gets the current native appearance state. Requires `appearance.read`; Linux currently reports `supported:false`. |
458
+ | `Arcane.appearance.apply(appearance)` | `{scheme?:"system"\|"light"\|"dark", captionColor?, textColor?}` with custom colors in `rgb(r, g, b)` form | `Promise<{supported, platform, scheme, effectiveScheme, captionColor, textColor}>` | Applies supported current-user native appearance values and returns the resulting state. Requires `appearance.write`; Linux currently reports unsupported without claiming a mutation. |
459
+
460
+ ### Environment profile contract
461
+
462
+ The public SDK is positional and constructs closed RPC parameter objects:
463
+
464
+ ```js
465
+ const inventory = await Arcane.environment.list();
466
+ const saved = await Arcane.environment.set(
467
+ 'EXAMPLE_API_KEY',
468
+ 'synthetic-development-value',
469
+ { protected: true }
470
+ );
471
+ const revealed = await Arcane.environment.get('EXAMPLE_API_KEY');
472
+ const removed = await Arcane.environment.remove('EXAMPLE_API_KEY');
473
+ ```
474
+
475
+ The corresponding native requests are exactly `{}`, `{name}`,
476
+ `{name,value,protected}`, and `{name}`. Unknown or missing fields are rejected.
477
+ `protected` is a Boolean in the native set request. If the SDK caller omits the
478
+ options object, the SDK derives that Boolean from the sensitive-name policy;
479
+ callers should pass `{protected:true}` or `{protected:false}` when their data
480
+ classification is already known.
481
+
482
+ An environment entry has this exact application-facing shape:
483
+
484
+ ```js
485
+ {
486
+ name: 'EXAMPLE_API_KEY',
487
+ scope: 'user',
488
+ protected: true,
489
+ configured: true,
490
+ value: '•••••'
491
+ }
492
+ ```
493
+
494
+ `list()` returns
495
+ `{platform,pathSupported,maximumEntries,valueMaximumLength,persistence,entries}`.
496
+ `get()` and `set()` return `{entry}`. `remove()` returns
497
+ `{name,deleted:true}`. `configured` is always `true` for a returned entry; a
498
+ missing `get()` or `remove()` rejects with `ENVIRONMENT_ENTRY_NOT_FOUND`.
499
+ Empty-string values are valid and are not deletion.
500
+
501
+ `list()` returns an ordinary entry's actual value, but replaces every protected
502
+ value with exactly five U+2022 bullet characters (`•••••`). `set()` applies the
503
+ same mask to its protected result. Only an explicit `get(name)` returns a
504
+ protected value in plaintext. That reveal is intentional and is why
505
+ `environment.get` has the separate `environment.protected.read` capability.
506
+ The value then exists in the authorized renderer and process memory; the mask is a
507
+ display and data-minimization control, not encryption or authorization.
508
+
509
+ Names must match `^[A-Za-z_][A-Za-z0-9_.-]{0,127}$`; values are strings of no
510
+ more than 32,767 characters and cannot contain a null character. A profile has
511
+ at most 256 entries. The current profiles use case-insensitive identity for
512
+ replacement and preserve the most recently supplied display spelling. Names
513
+ whose uppercase separator-delimited tokens include `KEY`, `KEYS`, `TOKEN`,
514
+ `TOKENS`, `SECRET`, `SECRETS`, `PASSWORD`, `PASSWORDS`, `PASS`, `PASSWD`, `PWD`,
515
+ `CREDENTIAL`, `CREDENTIALS`, `AUTH`, or `BEARER` are treated as sensitive. The conservative heuristic also recognizes
516
+ separated or compact API-key, access-key/access-token, auth-key/auth-token,
517
+ private-key, and client-secret variants, including `APIKEY`, `ACCESSKEY`,
518
+ `ACCESSTOKEN`, `AUTHKEY`, `AUTHTOKEN`, `PRIVATEKEY`, and `CLIENTSECRET` forms.
519
+ Matching names must be protected; `protected:false` is rejected for them.
520
+ `PATH` is executable-discovery configuration and must remain ordinary;
521
+ `environment.set` rejects `{protected:true}` for that exact name.
522
+
523
+ | Platform | Entry scope | `pathSupported` | Ordinary storage | Protected storage | `persistence` |
524
+ |---|---|---:|---|---|---|
525
+ | Microsoft NT (`windows`) | `user` | `true` | Current user's `HKCU\Environment` values with exact string-kind verification and compensating rollback | Current-user DPAPI-protected Arcane record; inventory strips protected plaintext inside the helper | `windows-current-user-environment` |
526
+ | Linux | `user` | `true` | Arcane-managed current-user profile | Freedesktop Secret Service through `secret-tool`; no plaintext fallback | `arcane-managed-current-user-environment` |
527
+ | Android | `app` | `false` | Host-package private app storage | AES-GCM ciphertext whose key is held by Android Keystore | `android-app-encrypted-environment` |
528
+
529
+ Desktop Core serializes all four environment operations through one bounded
530
+ 32-request process-local queue and one current-user cross-process lease, so an
531
+ inventory or reveal in another app-scoped Core cannot race a mutation. Core
532
+ releases and verifies the lease before returning success. A live owner returns
533
+ `ENVIRONMENT_OPERATION_BUSY`; a dead or invalid owner is preserved and returns
534
+ `ENVIRONMENT_RECOVERY_REQUIRED` rather than being reclaimed across an uncertain
535
+ two-store transition. `set()` and `remove()` also retain the global
536
+ exclusive-mutation boundary. Native set results must match the requested name,
537
+ protection decision, and exact ordinary value or protected five-bullet mask
538
+ before Core returns them.
539
+ Microsoft NT rejects a protected-record/plaintext-registry shadow. Linux binds
540
+ new protected values to a random Secret Service generation in a namespace that
541
+ does not overlap legacy entries, fsyncs the metadata file and directory before
542
+ cleaning the prior generation, and keeps legacy lookup compatibility.
543
+ Failure to verify candidate, prior-generation, or deletion cleanup rejects with
544
+ `ENVIRONMENT_PROTECTED_CLEANUP_FAILED`. Linux post-rename durability ambiguity
545
+ rejects with `ENVIRONMENT_METADATA_COMMIT_UNCERTAIN`. Native code retains
546
+ bounded cleanup and mutation-uncertainty detail internally, but the renderer's
547
+ normalized `Arcane.Error` currently exposes the public error code rather than
548
+ those internal fields. Treat either code as uncertain, refresh inventory, and
549
+ do not blindly retry. Android returns
550
+ `ANDROID_ENVIRONMENT_STORAGE_UNCERTAIN` if its synchronous profile commit cannot
551
+ prove persistence.
552
+
553
+ The Linux `secret-tool` path accepts at most 8,191 bytes for Arcane's complete
554
+ prefixed Base64 payload (6,126 ASCII value bytes; fewer for multibyte UTF-8).
555
+ Larger Linux protected values reject with
556
+ `ENVIRONMENT_PROTECTED_VALUE_TOO_LARGE`; ordinary values and other platforms
557
+ retain the general contract bound. A nonzero Secret Service lookup is treated
558
+ as storage unavailable because the CLI does not distinguish absence from an
559
+ unavailable or locked service reliably.
560
+
561
+ On Microsoft NT, an ordinary `PATH` is the current user's registry value; a
562
+ successful mutation broadcasts the platform environment-change notification,
563
+ but already-running processes do not thereby receive a rewritten environment.
564
+ On Linux, `PATH` belongs to the Arcane-managed user profile rather than silently
565
+ rewriting a shell startup file. Android does not expose a mutable operating-
566
+ system user PATH: `PATH` get, set, and remove requests are rejected and the list
567
+ metadata reports `pathSupported:false`.
568
+
569
+ The method policies admit these operations only to explicitly authorized
570
+ application IDs on Core and Android hosts. `list()` requires
571
+ `environment.read`; `get()` requires `environment.protected.read`; and `set()`
572
+ plus `remove()` require `environment.write` and run as exclusive mutations.
573
+ Desktop reads and writes also share the bounded serialized environment queue.
574
+ The owning application reference records the concrete admission and UI boundary.
575
+
576
+ Native storage and preferences resolve below
577
+ `<state-root>/Arcane OS/apps/<application-id>/` as `storage.json` and
578
+ `preferences.json`. The host-bound canonical app ID selects the folder; callers
579
+ cannot provide a different identity. Browser OPFS follows
580
+ `apps/<application-id>/...`, DBLS fallback keys use
581
+ `arcane.apps.<application-id>:`, and native browser profiles are also app-owned.
582
+ Unowned legacy global data is preserved but not guessed into an app. The complete
583
+ layout and same-origin browser limitation are maintained in the repository-only
584
+ [Application data isolation](https://github.com/TheWizardNexus/ARCANE-OS/blob/567ad110bf57a1c2d4a3daa22ae93716cc5f4d7e/docs/application-data-isolation.md); see the public [repository-access boundary](https://github.com/TheWizardNexus/ARCANE-OS/blob/567ad110bf57a1c2d4a3daa22ae93716cc5f4d7e/apps/docs/guides/repository-access.md#private-developer-material).
585
+
586
+ ## Session, provisioning, diagnostics, and development
587
+
588
+ | Method | Parameters | Return | Description |
589
+ |---|---|---|---|
590
+ | `Arcane.session.logout()` | None | `Promise<{requested:true, accepted:true, simulated:true, command, args}\|{requested:true, accepted:true, simulated:false, command, pid}>` | Requests logout of the current host operating-system session. This is not an Arcane-only application exit, and acceptance does not prove logout completed. Shell-only; requires `session.control`. |
591
+ | `Arcane.provisioning.plan(usernames)` | Username or array | `Promise<{ok, version, installation, requirements, users, usernamePolicy, elevated, simulation, blocked, steps}>` | Creates a current read-only provisioning plan without applying it. Provisioner-only; requires `provisioning.manage`. |
592
+ | `Arcane.diagnostics.recentErrors()` | None | `Promise<diagnostic[]>` | Lists up to 60 recent in-memory structured Core errors, newest first. Requires `diagnostics.read`. |
593
+ | `Arcane.diagnostics.get(diagnosticId)` | Opaque diagnostic ID from a recent error | `Promise<diagnostic>` | Gets one current in-memory diagnostic record or rejects after it is evicted. Requires `diagnostics.read`. |
594
+ | `Arcane.development.inspect(root)` | Existing absolute canonical Arcane checkout root | `Promise<{root, runtimeVersion, repository, git, tools, signing, readiness}>` | Read-only inspection of an approved development workspace. Developer-only; requires `development.read`. |
595
+ | `Arcane.development.context(root, query)` | Approved checkout root; 1–4,096-character query | `Promise<{root, query, files, totals}>` | Gets redacted context from at most ten tracked safe text files, bounded to 6,144 characters per file and 49,152 characters overall. Developer-only; requires `development.read`. |
596
+ | `Arcane.development.setup(root, taskId)` | Checkout root; `root-dependencies`, `machine-dependencies`, `git-hooks`, or `windows-signing` | `Promise<{root, taskId, completed:true, exitCode, operation}>` | Runs one inspected allowlisted development setup task with operation progress. Developer-only; requires `development.manage`. |
597
+ | `Arcane.development.installNode()` | None | `Promise<{installed, simulated, node, operation}>` | Installs and verifies the supported Node.js 22+ development runtime on Microsoft NT. Developer-only privileged mutation; requires `development.manage`. |
598
+
599
+ ## Maintenance rule
600
+
601
+ The source of truth for the application-facing native bridge API is `machine_bundles/arcane-os-machine-bundle/src/frontend/shared/arcane-api.js`. Follow the repository-only [Developer Reference Maintenance SOP](https://github.com/TheWizardNexus/ARCANE-OS/blob/567ad110bf57a1c2d4a3daa22ae93716cc5f4d7e/docs/developer-reference-sop.md) (see [Repository and download access](https://github.com/TheWizardNexus/ARCANE-OS/blob/567ad110bf57a1c2d4a3daa22ae93716cc5f4d7e/apps/docs/guides/repository-access.md#private-developer-material)): every added, removed, renamed, or changed `Arcane` member must update the exact inventory or method table, including parameters, return, and description, in the same change. Renderer-visible event changes must also update the [Arcane event inventory](arcane-events.md#event-inventory). Long-form member guides enrich these canonical rows; they do not replace or duplicate the checked inventory.