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