@wenathlan/saddle 2.0.154 → 2.0.155
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/Dockerfile +112 -41
- package/README.md +58 -59
- package/browser.ts +482 -0
- package/cli.ts +274 -0
- package/distribution.ts +731 -0
- package/docker.config +29 -8
- package/docs/artifactavailability.md +2 -2
- package/docs/browser.md +18 -1
- package/docs/{containerplatforms.2.1.0.md → containerplatforms210.md} +1 -1
- package/docs/{documentmap.1.8.12.md → documentmap1812.md} +1 -1
- package/docs/extension.md +13 -2
- package/docs/libraryapi.md +1 -1
- package/docs/{ninety.modalities.md → ninetymodalities.md} +87 -4
- package/docs/{planning.ninety.md → planningninety.md} +6 -6
- package/docs/{releasenotes.1.8.13.md → releasenotes1813.md} +2 -2
- package/docs/{releasenotes.1.8.14.md → releasenotes1814.md} +1 -1
- package/docs/{repo.synthesis.1.8.16.md → reposynthesis1816.md} +1 -1
- package/docs/todo.md +2 -2
- package/docs/{todo.1.8.15.md → todo1815.md} +1 -1
- package/docs/{todo.1.8.16.md → todo1816.md} +5 -5
- package/execution.ts +677 -0
- package/foundation.ts +314 -0
- package/index.ts +35 -27
- package/isolation.ts +84 -0
- package/modes.ts +170 -0
- package/mttg.config +1 -1
- package/orchestrator.ts +49 -15
- package/package.json +90 -75
- package/qemu.config +2 -2
- package/sandbox.ts +2094 -0
- package/scheduler.ts +1 -1
- package/server.ts +52 -0
- package/tsconfig.json +11 -12
- package/virtual.ts +1105 -0
- package/virtualgpu.ts +1 -1
- package/virtualization.ts +1 -1
- package/workloadlaw.ts +293 -0
- package/dist/App.d.ts +0 -5
- package/dist/App.js +0 -52
- package/dist/Sol/Sol.d.ts +0 -3
- package/dist/Sol/Sol.js +0 -46
- package/dist/Sol/agentbrowser/agentbrowser.d.ts +0 -9
- package/dist/Sol/agentbrowser/agentbrowser.js +0 -121
- package/dist/Sol/architecture/architecture.d.ts +0 -9
- package/dist/Sol/architecture/architecture.js +0 -93
- package/dist/Sol/compute/compute.d.ts +0 -9
- package/dist/Sol/compute/compute.js +0 -22
- package/dist/Sol/console/console.d.ts +0 -15
- package/dist/Sol/console/console.js +0 -292
- package/dist/Sol/dashboard/dashboard.d.ts +0 -10
- package/dist/Sol/dashboard/dashboard.js +0 -181
- package/dist/Sol/docs/docs.d.ts +0 -9
- package/dist/Sol/docs/docs.js +0 -28
- package/dist/Sol/home/home.d.ts +0 -35
- package/dist/Sol/home/home.js +0 -239
- package/dist/Sol/integrations/integrations.d.ts +0 -9
- package/dist/Sol/integrations/integrations.js +0 -83
- package/dist/Sol/intro/intro.d.ts +0 -7
- package/dist/Sol/intro/intro.js +0 -102
- package/dist/Sol/login/login.d.ts +0 -16
- package/dist/Sol/login/login.js +0 -49
- package/dist/Sol/notfound/notfound.d.ts +0 -9
- package/dist/Sol/notfound/notfound.js +0 -15
- package/dist/Sol/onboarding/onboarding.d.ts +0 -25
- package/dist/Sol/onboarding/onboarding.js +0 -60
- package/dist/Sol/playground/playground.d.ts +0 -9
- package/dist/Sol/playground/playground.js +0 -127
- package/dist/Sol/register/register.d.ts +0 -16
- package/dist/Sol/register/register.js +0 -193
- package/dist/Sol/shell/Shell.d.ts +0 -124
- package/dist/Sol/shell/Shell.js +0 -335
- package/dist/Sol/wingets/ComputeBootladder.d.ts +0 -6
- package/dist/Sol/wingets/ComputeBootladder.js +0 -71
- package/dist/Sol/wingets/ComputeModalitycatalog.d.ts +0 -7
- package/dist/Sol/wingets/ComputeModalitycatalog.js +0 -71
- package/dist/Sol/wingets/ConsoleApibadge.d.ts +0 -7
- package/dist/Sol/wingets/ConsoleApibadge.js +0 -5
- package/dist/Sol/wingets/ConsoleEdgelaw.d.ts +0 -6
- package/dist/Sol/wingets/ConsoleEdgelaw.js +0 -36
- package/dist/Sol/wingets/ConsoleEventstimeline.d.ts +0 -19
- package/dist/Sol/wingets/ConsoleEventstimeline.js +0 -12
- package/dist/Sol/wingets/ConsoleSnapshotcontrols.d.ts +0 -8
- package/dist/Sol/wingets/ConsoleSnapshotcontrols.js +0 -8
- package/dist/Sol/wingets/ConsoleSpecpanel.d.ts +0 -21
- package/dist/Sol/wingets/ConsoleSpecpanel.js +0 -75
- package/dist/Sol/wingets/ConsoleTerminal.d.ts +0 -22
- package/dist/Sol/wingets/ConsoleTerminal.js +0 -77
- package/dist/Sol/wingets/DashboardAccountpanel.d.ts +0 -18
- package/dist/Sol/wingets/DashboardAccountpanel.js +0 -65
- package/dist/Sol/wingets/DashboardAdminpanel.d.ts +0 -6
- package/dist/Sol/wingets/DashboardAdminpanel.js +0 -90
- package/dist/Sol/wingets/DashboardAuditlog.d.ts +0 -8
- package/dist/Sol/wingets/DashboardAuditlog.js +0 -50
- package/dist/Sol/wingets/DashboardCreatesandboxform.d.ts +0 -10
- package/dist/Sol/wingets/DashboardCreatesandboxform.js +0 -71
- package/dist/Sol/wingets/DashboardEventstimeline.d.ts +0 -8
- package/dist/Sol/wingets/DashboardEventstimeline.js +0 -83
- package/dist/Sol/wingets/DashboardGlobalsandboxestable.d.ts +0 -8
- package/dist/Sol/wingets/DashboardGlobalsandboxestable.js +0 -57
- package/dist/Sol/wingets/DashboardMeshnodestable.d.ts +0 -8
- package/dist/Sol/wingets/DashboardMeshnodestable.js +0 -103
- package/dist/Sol/wingets/DashboardSandboxlist.d.ts +0 -10
- package/dist/Sol/wingets/DashboardSandboxlist.js +0 -163
- package/dist/Sol/wingets/DashboardUserstable.d.ts +0 -8
- package/dist/Sol/wingets/DashboardUserstable.js +0 -78
- package/dist/Sol/wingets/HomeEntrygate.d.ts +0 -23
- package/dist/Sol/wingets/HomeEntrygate.js +0 -73
- package/dist/Sol/wingets/HomeMetricstrip.d.ts +0 -9
- package/dist/Sol/wingets/HomeMetricstrip.js +0 -4
- package/dist/Sol/wingets/HomeRuntimediagram.d.ts +0 -1
- package/dist/Sol/wingets/HomeRuntimediagram.js +0 -22
- package/dist/Sol/wingets/LoginForm.d.ts +0 -19
- package/dist/Sol/wingets/LoginForm.js +0 -141
- package/dist/Sol/wingets/RegisterPasswordconfirm.d.ts +0 -13
- package/dist/Sol/wingets/RegisterPasswordconfirm.js +0 -16
- package/dist/Sol/wingets/RegisterPasswordmeter.d.ts +0 -19
- package/dist/Sol/wingets/RegisterPasswordmeter.js +0 -65
- package/dist/Sol/wingets/RegisterUsernamerules.d.ts +0 -11
- package/dist/Sol/wingets/RegisterUsernamerules.js +0 -16
- package/dist/Sol/wingets/index.d.ts +0 -39
- package/dist/Sol/wingets/index.js +0 -39
- package/dist/alternatives.d.ts +0 -508
- package/dist/alternatives.js +0 -950
- package/dist/api.d.ts +0 -154
- package/dist/api.js +0 -174
- package/dist/auth.d.ts +0 -268
- package/dist/auth.js +0 -476
- package/dist/automation.d.ts +0 -425
- package/dist/automation.js +0 -566
- package/dist/browser.d.ts +0 -561
- package/dist/browser.js +0 -1058
- package/dist/capacitor.config.d.ts +0 -45
- package/dist/capacitor.config.js +0 -48
- package/dist/catalog.d.ts +0 -43
- package/dist/catalog.js +0 -44
- package/dist/cli.d.ts +0 -16
- package/dist/cli.js +0 -168
- package/dist/communication.d.ts +0 -181
- package/dist/communication.js +0 -376
- package/dist/compute.d.ts +0 -1160
- package/dist/compute.js +0 -2272
- package/dist/dashboardlib.d.ts +0 -58
- package/dist/dashboardlib.js +0 -161
- package/dist/db.d.ts +0 -569
- package/dist/db.js +0 -1080
- package/dist/distribution.d.ts +0 -528
- package/dist/distribution.js +0 -810
- package/dist/drizzle.config.d.ts +0 -20
- package/dist/drizzle.config.js +0 -18
- package/dist/edgelandes.d.ts +0 -70
- package/dist/edgelandes.host.d.ts +0 -26
- package/dist/edgelandes.host.js +0 -1089
- package/dist/edgelandes.inproc.d.ts +0 -27
- package/dist/edgelandes.inproc.js +0 -952
- package/dist/edgelandes.js +0 -1133
- package/dist/edgelandes.ninety.d.ts +0 -31
- package/dist/edgelandes.ninety.js +0 -174
- package/dist/edgelandes.virtual.d.ts +0 -25
- package/dist/edgelandes.virtual.js +0 -629
- package/dist/edgeplane.d.ts +0 -121
- package/dist/edgeplane.js +0 -341
- package/dist/examplelocaljob.d.ts +0 -1
- package/dist/examplelocaljob.js +0 -14
- package/dist/execution.d.ts +0 -529
- package/dist/execution.js +0 -760
- package/dist/family.d.ts +0 -16
- package/dist/family.js +0 -42
- package/dist/familyurl.d.ts +0 -21
- package/dist/familyurl.js +0 -24
- package/dist/format.d.ts +0 -18
- package/dist/format.js +0 -59
- package/dist/foundation.d.ts +0 -172
- package/dist/foundation.js +0 -312
- package/dist/index.d.ts +0 -735
- package/dist/index.js +0 -1020
- package/dist/integration.d.ts +0 -235
- package/dist/integration.js +0 -228
- package/dist/intelligence.d.ts +0 -93
- package/dist/intelligence.js +0 -144
- package/dist/isolation.d.ts +0 -128
- package/dist/isolation.js +0 -95
- package/dist/labels.d.ts +0 -665
- package/dist/labels.js +0 -707
- package/dist/localauth.d.ts +0 -127
- package/dist/localauth.js +0 -413
- package/dist/media.d.ts +0 -343
- package/dist/media.js +0 -985
- package/dist/mesh.d.ts +0 -177
- package/dist/mesh.js +0 -468
- package/dist/modalityregistry.d.ts +0 -109
- package/dist/modalityregistry.js +0 -1386
- package/dist/modes.d.ts +0 -358
- package/dist/modes.js +0 -133
- package/dist/onboardingstate.d.ts +0 -79
- package/dist/onboardingstate.js +0 -282
- package/dist/orchestrator.d.ts +0 -1338
- package/dist/orchestrator.js +0 -4310
- package/dist/packager/targetcli.js +0 -4
- package/dist/paths.d.ts +0 -2
- package/dist/paths.js +0 -14
- package/dist/performance.d.ts +0 -415
- package/dist/performance.js +0 -826
- package/dist/quantum.d.ts +0 -809
- package/dist/quantum.js +0 -2072
- package/dist/render.d.ts +0 -380
- package/dist/render.js +0 -1072
- package/dist/runall.d.ts +0 -2
- package/dist/runall.js +0 -39
- package/dist/runtimeprobe.d.ts +0 -4
- package/dist/runtimeprobe.js +0 -8
- package/dist/sandbox.d.ts +0 -355
- package/dist/sandbox.js +0 -1721
- package/dist/sandboxenvprofile.d.ts +0 -29
- package/dist/sandboxenvprofile.js +0 -89
- package/dist/sandboxprofile.d.ts +0 -137
- package/dist/sandboxprofile.js +0 -241
- package/dist/sandboxqueue.d.ts +0 -108
- package/dist/sandboxqueue.js +0 -201
- package/dist/sandboxquota.d.ts +0 -121
- package/dist/sandboxquota.js +0 -236
- package/dist/scheduler.d.ts +0 -595
- package/dist/scheduler.js +0 -1258
- package/dist/scriptlanes.d.ts +0 -182
- package/dist/scriptlanes.js +0 -660
- package/dist/scripts.buildengine.d.ts +0 -1
- package/dist/scripts.buildengine.js +0 -39
- package/dist/scripts.securitygate.d.ts +0 -1
- package/dist/scripts.securitygate.js +0 -68
- package/dist/scripts.validateflatnative.d.ts +0 -1
- package/dist/scripts.validateflatnative.js +0 -72
- package/dist/security.d.ts +0 -500
- package/dist/security.js +0 -1169
- package/dist/seedcatalog.d.ts +0 -13
- package/dist/seedcatalog.js +0 -46
- package/dist/server.d.ts +0 -20
- package/dist/server.js +0 -53
- package/dist/speccatalog.d.ts +0 -31
- package/dist/speccatalog.js +0 -163
- package/dist/tiers.d.ts +0 -1001
- package/dist/tiers.js +0 -2169
- package/dist/utils.d.ts +0 -2
- package/dist/utils.js +0 -5
- package/dist/vaulthandoff.d.ts +0 -141
- package/dist/vaulthandoff.js +0 -444
- package/dist/virtual.d.ts +0 -640
- package/dist/virtual.js +0 -1284
- package/dist/virtualcpu.d.ts +0 -315
- package/dist/virtualcpu.js +0 -1180
- package/dist/virtualgpu.d.ts +0 -344
- package/dist/virtualgpu.js +0 -1000
- package/dist/virtualization.d.ts +0 -606
- package/dist/virtualization.js +0 -1186
- package/dist/virtualmemory.d.ts +0 -817
- package/dist/virtualmemory.js +0 -1795
- package/dist/vite.config.d.ts +0 -3
- package/dist/vite.config.js +0 -48
- package/dist/vitest.config.d.ts +0 -2
- package/dist/vitest.config.js +0 -25
- package/dist/webserver.d.ts +0 -166
- package/dist/webserver.js +0 -2226
- package/dist/workloadlaw.d.ts +0 -133
- package/dist/workloadlaw.js +0 -193
- package/manifest.json +0 -20
- package/media.ts +0 -1337
- /package/docs/{architecture.1.8.19.md → architecture1819.md} +0 -0
- /package/docs/{architecture.1.8.19.mmd → architecture1819.mmd} +0 -0
- /package/docs/{artifactresearch.1.8.9.md → artifactresearch189.md} +0 -0
- /package/docs/{batches.1816.to.1820.md → batches1816to1820.md} +0 -0
- /package/docs/{brancharchive.2026.08.18.md → brancharchive20260818.md} +0 -0
- /package/docs/{containerplatforms.1.8.17.md → containerplatforms1817.md} +0 -0
- /package/docs/{e2ugh.engine.md → e2ughengine.md} +0 -0
- /package/docs/{flatbuildresearch.1.8.11.md → flatbuildresearch1811.md} +0 -0
- /package/docs/{licenseaudit.1.8.12.md → licenseaudit1812.md} +0 -0
- /package/docs/{mobileconversionresearch.1.8.10.md → mobileconversionresearch1810.md} +0 -0
- /package/docs/{nativeidentityresearch.1.8.11.md → nativeidentityresearch1811.md} +0 -0
- /package/docs/{native.wrappers.md → nativewrappers.md} +0 -0
- /package/docs/{planning.1.8.18.md → planning1818.md} +0 -0
- /package/docs/{planning.1.8.19.md → planning1819.md} +0 -0
- /package/docs/{planning.engine.md → planningengine.md} +0 -0
- /package/docs/{releasenotes.1.8.12.md → releasenotes1812.md} +0 -0
- /package/docs/{releasenotes.1.8.15.md → releasenotes1815.md} +0 -0
- /package/docs/{releasenotes.1.8.16.md → releasenotes1816.md} +0 -0
- /package/docs/{releasenotes.1.8.17.md → releasenotes1817.md} +0 -0
- /package/docs/{releasenotes.1.8.18.md → releasenotes1818.md} +0 -0
- /package/docs/{releasenotes.1.8.19.md → releasenotes1819.md} +0 -0
- /package/docs/{reorganization.1.8.8.md → reorganization188.md} +0 -0
- /package/docs/{reorganization.1.8.9.md → reorganization189.md} +0 -0
- /package/docs/{repo.analysis.1.8.21.json → repoanalysis1821.json} +0 -0
- /package/docs/{repo.candidates.1.8.21.jsonl → repocandidates1821.jsonl} +0 -0
- /package/docs/{repo.research.1.8.16.md → reporesearch1816.md} +0 -0
- /package/docs/{repo.research.1.8.21.md → reporesearch1821.md} +0 -0
- /package/docs/{repo.selected.1.8.21.json → reposelected1821.json} +0 -0
- /package/docs/{repo.synthesis.1.8.21.md → reposynthesis1821.md} +0 -0
- /package/docs/{research.1.8.18.isolation.md → research1818isolation.md} +0 -0
- /package/docs/{research.1.8.19.virtual.browser.md → research1819virtualbrowser.md} +0 -0
- /package/docs/{scanningresearch.1.8.11.md → scanningresearch1811.md} +0 -0
- /package/docs/{securityaudit.1.8.7.md → securityaudit187.md} +0 -0
- /package/docs/{securityreferences.1.8.11.md → securityreferences1811.md} +0 -0
- /package/docs/{securityresearch.1.8.11.md → securityresearch1811.md} +0 -0
- /package/docs/{signingresearch.1.8.12.md → signingresearch1812.md} +0 -0
- /package/docs/{tauri.glib.risk.1.8.11.md → tauriglibrisk1811.md} +0 -0
- /package/docs/{todo.1.8.18.md → todo1818.md} +0 -0
- /package/docs/{todo.1.8.19.md → todo1819.md} +0 -0
- /package/docs/{toolchainresearch.1.8.9.md → toolchainresearch189.md} +0 -0
- /package/docs/{web.duplicatecleanup.md → webduplicatecleanup.md} +0 -0
- /package/docs/{web.ideas.md → webideas.md} +0 -0
- /package/docs/{workflowimprovements.2026.08.19.md → workflowimprovements20260819.md} +0 -0
package/Dockerfile
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
# syntax=docker/dockerfile:1
|
|
2
2
|
# saddle v2.0.0 grand merge — THE ONE CONTAINER FILE.
|
|
3
3
|
#
|
|
4
|
+
# build context: this file COPYs from two trees (saddle/ and the
|
|
5
|
+
# engine-ownership sibling vault/), so every build runs from the
|
|
6
|
+
# repository root with an explicit -f: docker build -f saddle/Dockerfile .
|
|
7
|
+
# (add --target saddle-runtime for the node service or --target
|
|
8
|
+
# qemu-runtime for the guest runner). building from inside saddle/
|
|
9
|
+
# breaks the vault COPY - the sibling rides the context beside this
|
|
10
|
+
# directory, never inside it.
|
|
11
|
+
#
|
|
4
12
|
# this Dockerfile carries BOTH container surfaces of the merged repository:
|
|
5
13
|
# 1. the saddle virtual-hardware engine image (the five stages below:
|
|
6
14
|
# builder, python-bridge, qemu, qemu-runtime, runtime) — the default
|
|
7
15
|
# build target, published as ghcr.io/wenathlan/saddle:vhe-<version>
|
|
8
|
-
# across three profiles and
|
|
16
|
+
# across three profiles and eleven architectures;
|
|
9
17
|
# 2. the saddle node-engine image (the saddle-build and saddle-runtime
|
|
10
18
|
# stages at the end of this file, folded from the former
|
|
11
19
|
# dockerfile.saddle) — an explicit build target
|
|
12
20
|
# (`docker build --target saddle-runtime .`), the node 26 storage and
|
|
13
21
|
# compute service published as ghcr.io/wenathlan/saddle:<version>
|
|
14
|
-
# across the
|
|
22
|
+
# across the eleven-arch family standard (amd64, amd64/v2, arm64,
|
|
23
|
+
# arm/v7, arm/v6, ppc64le, s390x, riscv64, 386, mips64le, loong64
|
|
15
24
|
# — the trixie slim base line; the stage also builds the web SPA so
|
|
16
25
|
# the image serves the self-hosted console via `node /app/webserver.ts`).
|
|
17
26
|
#
|
|
@@ -53,17 +62,22 @@
|
|
|
53
62
|
# build target (docker build / the engine docker run
|
|
54
63
|
# recipe below).
|
|
55
64
|
#
|
|
56
|
-
# platforms: linux/amd64, linux/
|
|
57
|
-
#
|
|
65
|
+
# platforms: linux/amd64, linux/amd64/v2, linux/arm64, linux/arm/v7,
|
|
66
|
+
# linux/arm/v6, linux/ppc64le, linux/s390x, linux/riscv64, linux/386,
|
|
67
|
+
# linux/mips64le and linux/loong64 through buildx --platform (the
|
|
68
|
+
# eleven-arch registry surface — the complete linux platform list
|
|
69
|
+
# docker/buildx carries, the owner's law: eleven OS architectures for
|
|
70
|
+
# every container of every application); every
|
|
58
71
|
# stage compiles for the portable baseline of its target architecture
|
|
59
|
-
# by default (x86-64 / armv8-a / power8 / z196
|
|
60
|
-
#
|
|
61
|
-
#
|
|
72
|
+
# by default (x86-64 / i686 / armv8-a / armv7-a / armv6 / power8 / z196 /
|
|
73
|
+
# rv64gc / mips64r2 / loongarch64, resolved from
|
|
74
|
+
# TARGETARCH and TARGETVARIANT) so the layers stay valid on every host
|
|
75
|
+
# and every gha-cached runner cpu; pass --build-arg VHE_MARCH=native for
|
|
62
76
|
# host-tuned local builds, or an explicit -march value when
|
|
63
77
|
# cross-building for a known deployment target.
|
|
64
78
|
#
|
|
65
79
|
# profiles: the three profiles (max, balanced, lite) are all built for
|
|
66
|
-
# all
|
|
80
|
+
# all eleven architectures; each profile carries a distinct virtual CPU
|
|
67
81
|
# identity (model name, vcpus, threads, ram) baked into /etc/virtual.
|
|
68
82
|
#
|
|
69
83
|
# the one container file (the gateway 1.1.5 standard): the compose stack
|
|
@@ -94,7 +108,7 @@
|
|
|
94
108
|
# -v vmdata:/data/vmdata -v webdata:/data/web \
|
|
95
109
|
# -v ./vm.config.json:/engine/vm.config.json:ro \
|
|
96
110
|
# -e PORT=8080 -e NODE_ENV=production -p 31280:8080 \
|
|
97
|
-
# ghcr.io/wenathlan/saddle:vhe-2.
|
|
111
|
+
# ghcr.io/wenathlan/saddle:vhe-2.0.154
|
|
98
112
|
#
|
|
99
113
|
# vheqemu (the guest runner; build it first with
|
|
100
114
|
# docker build --target qemu-runtime -t saddle/qemu:11.1.0 . because the
|
|
@@ -128,7 +142,7 @@
|
|
|
128
142
|
# -e VHE_GPU_PROFILE=b200 -e VHE_GPUS=8 -e VHE_MIG=1 \
|
|
129
143
|
# -e VHE_SMI_DRIVER=575.57.08 -e VHE_SMI_CUDA=12.9 \
|
|
130
144
|
# -e VHE_SMI_INTERVAL=30 -e VHE_SKIP_XVFB=1 -e VHE_SKIP_VALIDATE=1 \
|
|
131
|
-
# ghcr.io/wenathlan/saddle:vhe-2.
|
|
145
|
+
# ghcr.io/wenathlan/saddle:vhe-2.0.154 /bin/bash -c '
|
|
132
146
|
# while true; do
|
|
133
147
|
# /usr/local/bin/nvidia-smi "$VHE_GPU_PROFILE" "$VHE_GPUS" || true
|
|
134
148
|
# sleep "$VHE_SMI_INTERVAL"
|
|
@@ -145,7 +159,7 @@
|
|
|
145
159
|
# -v qemudata:/data/qemudata \
|
|
146
160
|
# -v ./qemubridge.py:/engine/qemubridge.py:ro \
|
|
147
161
|
# -e QMP_SOCKET=/run/vhe/vm.qmp -e PYTHONUNBUFFERED=1 \
|
|
148
|
-
# ghcr.io/wenathlan/saddle:vhe-2.
|
|
162
|
+
# ghcr.io/wenathlan/saddle:vhe-2.0.154 \
|
|
149
163
|
# python3 /engine/qemubridge.py --socket /run/vhe/vm.qmp status
|
|
150
164
|
#
|
|
151
165
|
# saddle-node (the node-engine service, the former compose.yml
|
|
@@ -159,7 +173,7 @@
|
|
|
159
173
|
# --log-driver json-file --log-opt max-size=50m --log-opt max-file=5 \
|
|
160
174
|
# --tmpfs /tmp:size=2g,mode=1777 \
|
|
161
175
|
# -e SADDLE_MEMORY_ENGINE=ram -e SBOT_PLATFORM= -e SBOT_CDN_URL= \
|
|
162
|
-
# ghcr.io/wenathlan/saddle:2.
|
|
176
|
+
# ghcr.io/wenathlan/saddle:2.0.154 \
|
|
163
177
|
# node dist/cli.js plan
|
|
164
178
|
#
|
|
165
179
|
# observability (the former prometheus scraper of the full profile)
|
|
@@ -175,7 +189,7 @@
|
|
|
175
189
|
# ever binds a hardcoded address.
|
|
176
190
|
|
|
177
191
|
# Base image contract (the gateway family policy): tags only, never a
|
|
178
|
-
# @sha256: digest. A single digest cannot serve the
|
|
192
|
+
# @sha256: digest. A single digest cannot serve the eleven-architecture
|
|
179
193
|
# matrix this image ships (the registry resolves the tag per platform),
|
|
180
194
|
# and a digest written here would be a hardcoded hash - the checksums
|
|
181
195
|
# that exist are generated by the GitHub runners and published as
|
|
@@ -204,12 +218,15 @@ ARG QEMU_VERSION="11.1.0"
|
|
|
204
218
|
FROM ${UBUNTU} AS builder
|
|
205
219
|
ARG TARGETPLATFORM
|
|
206
220
|
ARG TARGETARCH
|
|
221
|
+
ARG TARGETVARIANT
|
|
207
222
|
ARG BUILDARCH
|
|
208
223
|
ARG LLVM_VERSION
|
|
209
224
|
ARG NODE_VERSION
|
|
210
225
|
ARG MESA_VERSION
|
|
211
|
-
# empty = portable baseline resolved from TARGETARCH
|
|
212
|
-
#
|
|
226
|
+
# empty = portable baseline resolved from TARGETARCH (and TARGETVARIANT
|
|
227
|
+
# for the 32-bit arm legs) at the compile step (x86-64 / i686 / armv8-a /
|
|
228
|
+
# armv7-a / armv6 / power8 / z196 / rv64gc / mips64r2 / loongarch64);
|
|
229
|
+
# "native" is the opt-in for host-tuned local builds.
|
|
213
230
|
ARG VHE_MARCH=""
|
|
214
231
|
# NOTE: the VHE_PROFILE_* build-args are deliberately NOT declared in the
|
|
215
232
|
# builder stage. The builder compiles mesa/node/native shims which are
|
|
@@ -287,15 +304,18 @@ RUN set -eux; \
|
|
|
287
304
|
# it off, the build is rust-free.
|
|
288
305
|
|
|
289
306
|
# node 26.7.0 (current line, v8 14.6, temporal api, NODE_MODULE_VERSION 147).
|
|
290
|
-
# amd64 and arm64 install the pinned nodesource
|
|
291
|
-
# nodesource apt repo does not carry
|
|
292
|
-
#
|
|
307
|
+
# amd64 (with its amd64/v2 variant) and arm64 install the pinned nodesource
|
|
308
|
+
# deb; every architecture the nodesource apt repo does not carry (ppc64le,
|
|
309
|
+
# s390x, riscv64, loong64, mips64le, arm and 386 - the eleven-arch law's
|
|
310
|
+
# non-nodesource legs) falls back to the official nodejs.org binary tarball
|
|
311
|
+
# (mapped to the nodejs.org arch spellings: x64, armv7l, mips64el, x86),
|
|
312
|
+
# extracted straight into /usr so bin/node, include/node and
|
|
293
313
|
# lib/node_modules land exactly where the nodesource package (and the runtime
|
|
294
314
|
# stage COPY --from=builder directives) expect them. the node headers
|
|
295
315
|
# (/usr/include/node) are required by the ADDON build mode of gpumonitor.cpp.
|
|
296
316
|
RUN set -eux; \
|
|
297
317
|
nodesrc_ok="1"; \
|
|
298
|
-
case "${TARGETARCH}" in ppc64le|s390x|riscv64|loongarch64) nodesrc_ok="0" ;; esac; \
|
|
318
|
+
case "${TARGETARCH}" in ppc64le|s390x|riscv64|loong64|loongarch64|mips64le|arm|386) nodesrc_ok="0" ;; esac; \
|
|
299
319
|
if [ "$nodesrc_ok" = "1" ]; then \
|
|
300
320
|
# the version-line setup script (setup_26.x) is the nodesource
|
|
301
321
|
# distribution contract: no hardcoded digest in this file. The
|
|
@@ -312,7 +332,14 @@ RUN set -eux; \
|
|
|
312
332
|
"nodejs=${NODE_VERSION}-1nodesource1" \
|
|
313
333
|
|| apt-get install -y --no-install-recommends nodejs; \
|
|
314
334
|
else \
|
|
315
|
-
|
|
335
|
+
case "${TARGETARCH}" in \
|
|
336
|
+
amd64) nodearch="x64" ;; \
|
|
337
|
+
386|i386) nodearch="x86" ;; \
|
|
338
|
+
arm) nodearch="armv7l" ;; \
|
|
339
|
+
mips64le) nodearch="mips64el" ;; \
|
|
340
|
+
*) nodearch="${TARGETARCH}" ;; \
|
|
341
|
+
esac; \
|
|
342
|
+
tarball="node-v${NODE_VERSION}-linux-${nodearch}.tar.xz"; \
|
|
316
343
|
curl -fsSL --retry 5 --retry-all-errors -o "/tmp/${tarball}" \
|
|
317
344
|
"https://nodejs.org/dist/v${NODE_VERSION}/${tarball}"; \
|
|
318
345
|
tar -xJf "/tmp/${tarball}" -C /usr --strip-components=1; \
|
|
@@ -461,12 +488,20 @@ RUN set -eux; \
|
|
|
461
488
|
# portable baseline per architecture, with the ARCH FLAG the compiler
|
|
462
489
|
# family actually accepts: x86 and arm speak -march; the ppc64le gcc
|
|
463
490
|
# port rejects '-march=power8' ('did you mean -mcpu=power8?') so that
|
|
464
|
-
# architecture selects the -mcpu spelling; s390x accepts -march=z196
|
|
491
|
+
# architecture selects the -mcpu spelling; s390x accepts -march=z196;
|
|
492
|
+
# the eleven-arch law's remaining legs resolve their own baselines
|
|
493
|
+
# (armv7-a / armv6 by TARGETVARIANT, rv64gc, loongarch64, mips64r2,
|
|
494
|
+
# i686 for the 386 leg).
|
|
465
495
|
archflag="-march"; \
|
|
466
496
|
case "${TARGETARCH}" in \
|
|
467
497
|
arm64|aarch64) march="armv8-a" ;; \
|
|
498
|
+
arm) if [ "${TARGETVARIANT}" = "v7" ]; then march="armv7-a"; else march="armv6"; fi ;; \
|
|
468
499
|
ppc64le) march="power8"; archflag="-mcpu" ;; \
|
|
469
500
|
s390x) march="z196" ;; \
|
|
501
|
+
riscv64) march="rv64gc" ;; \
|
|
502
|
+
loong64|loongarch64) march="loongarch64" ;; \
|
|
503
|
+
mips64le) march="mips64r2" ;; \
|
|
504
|
+
386|i386) march="i686" ;; \
|
|
470
505
|
*) march="x86-64" ;; \
|
|
471
506
|
esac; \
|
|
472
507
|
if [ -n "${VHE_MARCH}" ]; then march="${VHE_MARCH}"; archflag="-march"; fi; \
|
|
@@ -655,10 +690,10 @@ ENTRYPOINT ["/usr/bin/tini", "--", "qemu-system-x86_64"]
|
|
|
655
690
|
# ships native bindings for the builder platforms - the per-arch legs never
|
|
656
691
|
# run it under QEMU. The base rides the family tag contract (tags only,
|
|
657
692
|
# never a @sha256: digest - a single digest cannot serve the
|
|
658
|
-
#
|
|
659
|
-
FROM --platform=$BUILDPLATFORM node:26.
|
|
693
|
+
# eleven-architecture matrix the registry resolves per platform).
|
|
694
|
+
FROM --platform=$BUILDPLATFORM node:26.13.0-slim AS saddle-build
|
|
660
695
|
|
|
661
|
-
ARG SADDLE_VERSION
|
|
696
|
+
ARG SADDLE_VERSION=2.0.154
|
|
662
697
|
WORKDIR /app
|
|
663
698
|
|
|
664
699
|
ENV NPM_CONFIG_LEGACY_PEER_DEPS=true
|
|
@@ -671,9 +706,7 @@ COPY saddle/ .
|
|
|
671
706
|
# so the vault sources ride the context beside the saddle and land at
|
|
672
707
|
# /vault where the import resolves (the family context fix).
|
|
673
708
|
COPY vault/ /vault
|
|
674
|
-
RUN npm run build:
|
|
675
|
-
&& node --check dist/cli.js \
|
|
676
|
-
&& npm run web:build:pages \
|
|
709
|
+
RUN npm run web:build:pages \
|
|
677
710
|
# the theme build emits the hashed SPA bundles straight at the app
|
|
678
711
|
# root (the family static-first vite contract): stage them into a
|
|
679
712
|
# clean folder so the runtime stages copy exactly the console
|
|
@@ -914,9 +947,15 @@ COPY --from=python-bridge /bridge/qemubridge.py /engine/qemubridge.py
|
|
|
914
947
|
# the engine sources and the specification files consumed at runtime
|
|
915
948
|
# (docker.config "final" stage copies the whole tree; the flat layout
|
|
916
949
|
# keeps that a single COPY layer).
|
|
917
|
-
COPY saddle/*.ts saddle/package.json saddle/tsconfig.json saddle/biome.jsonc
|
|
950
|
+
COPY saddle/*.ts saddle/package.json saddle/tsconfig.json saddle/biome.jsonc /engine/
|
|
918
951
|
COPY saddle/processors.json saddle/gpus.json saddle/cores.json saddle/boards.json saddle/vm.config.json saddle/virtualhardware.json /engine/
|
|
919
952
|
COPY saddle/qemu.config saddle/mttg.config saddle/passage.config saddle/docker.config saddle/mime.types /engine/
|
|
953
|
+
# the engine-ownership sibling: db.ts pulls labels.ts whose
|
|
954
|
+
# ../vault/labelstore.ts import resolves at /vault - the vault source
|
|
955
|
+
# rides the context beside the saddle and lands at /vault where the
|
|
956
|
+
# import resolves (the same family context fix as the saddle-build
|
|
957
|
+
# stage), so the engine webserver below finds the label store.
|
|
958
|
+
COPY vault/labelstore.ts /vault/labelstore.ts
|
|
920
959
|
|
|
921
960
|
# the web node ships inside the main container: the mesh edition (auth,
|
|
922
961
|
# sqlite database, dashboard and the browser sandbox pages) runs from the
|
|
@@ -940,8 +979,13 @@ RUN set -eux; \
|
|
|
940
979
|
mkdir -p /etc/OpenCL/vendors; \
|
|
941
980
|
case "${TARGETARCH}" in \
|
|
942
981
|
arm64|aarch64) ln -sf lvp_icd.aarch64.json /usr/share/vulkan/icd.d/lvp_icd.json ;; \
|
|
982
|
+
arm) ln -sf lvp_icd.arm.json /usr/share/vulkan/icd.d/lvp_icd.json ;; \
|
|
943
983
|
ppc64le) ln -sf lvp_icd.ppc64le.json /usr/share/vulkan/icd.d/lvp_icd.json ;; \
|
|
944
984
|
s390x) ln -sf lvp_icd.s390x.json /usr/share/vulkan/icd.d/lvp_icd.json ;; \
|
|
985
|
+
riscv64) ln -sf lvp_icd.riscv64.json /usr/share/vulkan/icd.d/lvp_icd.json ;; \
|
|
986
|
+
loong64|loongarch64) ln -sf lvp_icd.loongarch64.json /usr/share/vulkan/icd.d/lvp_icd.json ;; \
|
|
987
|
+
mips64le) ln -sf lvp_icd.mips64.json /usr/share/vulkan/icd.d/lvp_icd.json ;; \
|
|
988
|
+
386|i386) ln -sf lvp_icd.x86.json /usr/share/vulkan/icd.d/lvp_icd.json ;; \
|
|
945
989
|
*) ln -sf lvp_icd.x86_64.json /usr/share/vulkan/icd.d/lvp_icd.json ;; \
|
|
946
990
|
esac; \
|
|
947
991
|
ldconfig; \
|
|
@@ -1295,7 +1339,7 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --start-interval=5s
|
|
|
1295
1339
|
# OCI labels for registry introspection.
|
|
1296
1340
|
LABEL org.opencontainers.image.title="saddle virtual-hardware engine (the grand merge)" \
|
|
1297
1341
|
org.opencontainers.image.description="100% software virtual hardware: per-profile CPU/memory spoofing via LD_PRELOAD (max/balanced/lite), mesa 26.2.1 llvmpipe/lavapipe/rusticl, QEMU 11.1.0 TCG/MTTCG, virtual nvidia-smi adapter + NVML/CUDA shims, node 26.7.0, python bridge" \
|
|
1298
|
-
org.opencontainers.image.version="2.
|
|
1342
|
+
org.opencontainers.image.version="2.0.154" \
|
|
1299
1343
|
org.opencontainers.image.licenses="MIT" \
|
|
1300
1344
|
org.opencontainers.image.source="https://github.com/wenathlan/saddle" \
|
|
1301
1345
|
org.opencontainers.image.documentation="https://github.com/wenathlan/saddle/blob/main/README.md" \
|
|
@@ -1326,6 +1370,14 @@ VOLUME /data /cache/mesa_shader_cache
|
|
|
1326
1370
|
# pid 1.
|
|
1327
1371
|
ENTRYPOINT ["/entrypoint.sh"]
|
|
1328
1372
|
|
|
1373
|
+
# the engine service command: without a CMD the entrypoint exec "$@"
|
|
1374
|
+
# fell back to /bin/bash and the engine recipe (host 31280 -> container
|
|
1375
|
+
# 8080) bound nothing. the webserver is the console server the COPY
|
|
1376
|
+
# above landed at /engine: the default command starts it, and the
|
|
1377
|
+
# entrypoint exports PORT (8080 unless -e PORT overrides) before the
|
|
1378
|
+
# exec, so the service answers on 8080 out of the box.
|
|
1379
|
+
CMD ["node", "/engine/webserver.ts"]
|
|
1380
|
+
|
|
1329
1381
|
# ══════════════════════════════════════════════════════════════════════
|
|
1330
1382
|
# saddle node-engine stages — the storage/compute node service of the
|
|
1331
1383
|
# grand merge (folded verbatim from the former dockerfile.saddle: the
|
|
@@ -1334,9 +1386,9 @@ ENTRYPOINT ["/entrypoint.sh"]
|
|
|
1334
1386
|
# docker build --target saddle-runtime -t saddle:<version> .
|
|
1335
1387
|
# ══════════════════════════════════════════════════════════════════════
|
|
1336
1388
|
|
|
1337
|
-
FROM node:26.
|
|
1389
|
+
FROM node:26.13.0-slim AS saddle-runtime
|
|
1338
1390
|
|
|
1339
|
-
ARG SADDLE_VERSION
|
|
1391
|
+
ARG SADDLE_VERSION=2.0.154
|
|
1340
1392
|
LABEL org.opencontainers.image.title="Saddle" \
|
|
1341
1393
|
org.opencontainers.image.description="Storage-backed browser and compute engine (the grand-merge node service)" \
|
|
1342
1394
|
org.opencontainers.image.source="https://github.com/wenathlan/saddle" \
|
|
@@ -1386,20 +1438,39 @@ RUN apt-get update \
|
|
|
1386
1438
|
# degrades to a no-op at runtime - the sources are dead weight.
|
|
1387
1439
|
&& rm -rf node_modules/cpu-features/deps \
|
|
1388
1440
|
&& find node_modules -type f -name Dockerfile -delete
|
|
1389
|
-
COPY --from=saddle-build /app/dist ./dist
|
|
1390
1441
|
# the web service surface (self-hosted console): the staged spa plus the
|
|
1391
|
-
# pure-node server stack
|
|
1392
|
-
#
|
|
1393
|
-
#
|
|
1394
|
-
#
|
|
1395
|
-
#
|
|
1442
|
+
# pure-node server stack - zero npm dependencies, the node 26 runtime
|
|
1443
|
+
# carries everything (node:sqlite, node:crypto, native type stripping
|
|
1444
|
+
# for the .ts sources). the console set closes the whole import graph:
|
|
1445
|
+
# webserver.ts pulls modalityregistry.ts, edgeplane.ts and
|
|
1446
|
+
# workloadlaw.ts; edgeplane.ts pulls foundation.ts and the edgelandes
|
|
1447
|
+
# family (edgelandes.ts, edgelandeshost.ts, edgelandesinproc.ts,
|
|
1448
|
+
# edgelandesvirtual.ts, edgelandesninety.ts); db.ts pulls labels.ts
|
|
1449
|
+
# whose ../vault/labelstore.ts import resolves at /vault (the family
|
|
1450
|
+
# context fix - the vault source lands beside /app the same way the
|
|
1451
|
+
# saddle-build stage lands it). with the graph closed, node
|
|
1452
|
+
# webserver.ts starts clean; before the fix the container crashed at
|
|
1453
|
+
# boot with module-not-found.
|
|
1396
1454
|
# run the console with: docker run saddle:<version> node webserver.ts
|
|
1397
|
-
COPY --from=saddle-build /app/webserver.ts /app/db.ts /app/labels.ts /app/auth.ts /app/mesh.ts /app/sandbox.ts /app/sandboxprofile.ts /app/sandboxenvprofile.ts /app/sandboxquota.ts /app/mime.types /app/init.sql /app/schema.prisma ./
|
|
1455
|
+
COPY --from=saddle-build /app/webserver.ts /app/db.ts /app/labels.ts /app/auth.ts /app/mesh.ts /app/sandbox.ts /app/sandboxprofile.ts /app/sandboxenvprofile.ts /app/sandboxquota.ts /app/modalityregistry.ts /app/edgeplane.ts /app/workloadlaw.ts /app/foundation.ts /app/edgelandes.ts /app/edgelandeshost.ts /app/edgelandesinproc.ts /app/edgelandesvirtual.ts /app/edgelandesninety.ts /app/mime.types /app/init.sql /app/schema.prisma ./
|
|
1456
|
+
# the label store of the console stack: labels.ts (pulled by db.ts)
|
|
1457
|
+
# resolves ../vault/labelstore.ts at /vault - the same family context
|
|
1458
|
+
# fix the saddle-build stage applies.
|
|
1459
|
+
COPY --from=saddle-build /vault/labelstore.ts /vault/labelstore.ts
|
|
1398
1460
|
COPY --from=saddle-build /out/spa ./
|
|
1399
1461
|
|
|
1400
1462
|
USER node
|
|
1401
1463
|
|
|
1402
|
-
|
|
1464
|
+
# the console service doors: the webserver answers the engine api and the
|
|
1465
|
+
# staged spa on the saddle port (the source-is-library law runs the .ts
|
|
1466
|
+
# graph natively - node 26 strips the types, zero npm dependencies).
|
|
1467
|
+
ENV SADDLE_PORT=8080 \
|
|
1468
|
+
SADDLE_HOST=0.0.0.0
|
|
1469
|
+
|
|
1470
|
+
EXPOSE 8080
|
|
1471
|
+
|
|
1472
|
+
# the health probe rides the public /health route the webserver answers
|
|
1473
|
+
# (node fetch, zero wget dependency on the slim debian base).
|
|
1474
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 CMD ["node", "-e", "fetch('http://127.0.0.1:8080/health').then((r)=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]
|
|
1403
1475
|
|
|
1404
|
-
ENTRYPOINT ["node", "
|
|
1405
|
-
CMD ["help"]
|
|
1476
|
+
ENTRYPOINT ["node", "webserver.ts"]
|
package/README.md
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
-
<strong>Storage-backed jobs,
|
|
7
|
-
<strong>Binary computing engine, agent browser,
|
|
6
|
+
<strong>Storage-backed jobs, ninety sandbox modalities and portable runners for Node.js.</strong><br/>
|
|
7
|
+
<strong>Binary computing engine, agent browser, sandbox plane and packager.</strong><br/>
|
|
8
8
|
<a href="https://github.com/wenathlan/saddle/actions/workflows/ci.yml"><img src="https://github.com/wenathlan/saddle/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
|
|
9
9
|
<a href="https://github.com/wenathlan/saddle/releases/tag/v2.0.0"><img src="https://img.shields.io/badge/release-v2.0.0-d35d3d" alt="Release 2.0.0" /></a>
|
|
10
10
|
<a href="https://github.com/wenathlan/saddle/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-GPL--3.0--only-202a2f" alt="GPL 3.0 only license" /></a>
|
|
@@ -31,12 +31,12 @@ domain modules land beside the saddle domains:
|
|
|
31
31
|
| `media.ts`, `render.ts`, `quantum.ts`, `tiers.ts` | media pipeline, GPU registry, quantum simulation, tier policy |
|
|
32
32
|
| `security.ts`, `alternatives.ts` | hardening gates and the alternative-stack catalog |
|
|
33
33
|
| `index.html`, `App.tsx`, `Sol/` | the single SPA shell and the Sol theme (one tsx app with one stylesheet per theme) |
|
|
34
|
-
| `server.ts`, `sandbox.ts` | the zero-dependency self-hosted API of the 2.0.
|
|
34
|
+
| `server.ts`, `sandbox.ts` | the zero-dependency self-hosted API of the 2.0.155 grand-merge envelope (`node server.ts`; the api answers its version at `/api/v1/health`) and the browser-pure engine port |
|
|
35
35
|
| `vercel.json`, `netlify.toml` | the platform deploy adapters beside the surface they publish (the caddy ghost stays out of the tree) |
|
|
36
36
|
| `specs/*` package exports | processors, gpus, cores, boards and the qemu/mttg/passage/docker envelopes |
|
|
37
37
|
|
|
38
38
|
The full pre-merge documentation of the engine lives in
|
|
39
|
-
[docs/
|
|
39
|
+
[docs/e2ughengine.md](docs/e2ughengine.md) and its release history in
|
|
40
40
|
[CHANGELOG.md (the e2ugh lineage sections)](CHANGELOG.md (the e2ugh lineage sections)).
|
|
41
41
|
|
|
42
42
|
## Start here
|
|
@@ -48,18 +48,18 @@ npm install @wenathlan/saddle
|
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
```js
|
|
51
|
-
import {
|
|
51
|
+
import { createVirtualEngine, planreport, resolvejoin } from "@wenathlan/saddle";
|
|
52
52
|
|
|
53
|
-
const
|
|
54
|
-
const
|
|
53
|
+
const engine = createVirtualEngine({ model: "saddle-90", vcpus: 4, ramgb: 8 });
|
|
54
|
+
const report = planreport(); // { plancount: 90, live: 81, host: 9, planned: 0, plananswered: true }
|
|
55
|
+
const modalities = resolvejoin({ base: "balanced", gpu: false, network: false });
|
|
55
56
|
|
|
56
|
-
console.log(
|
|
57
|
+
console.log(engine.id, report.plananswered, modalities[0].id);
|
|
57
58
|
```
|
|
58
59
|
|
|
59
|
-
The deterministic
|
|
60
|
+
The deterministic engine tests do not require network access or real credentials:
|
|
60
61
|
|
|
61
62
|
```bash
|
|
62
|
-
node --import tsx docs/example-publicapi.ts
|
|
63
63
|
npm test
|
|
64
64
|
```
|
|
65
65
|
|
|
@@ -90,9 +90,8 @@ The historical design treats the repository and its runner as a **virtual proces
|
|
|
90
90
|
|
|
91
91
|
| Mode | Boundary | Typical use |
|
|
92
92
|
| --- | --- | --- |
|
|
93
|
-
|
|
|
93
|
+
| Library | in-process function call | The npm package consumed directly by another program. |
|
|
94
94
|
| Browser | caller-owned transport | Interactive pages, snapshots, tabs and actions. |
|
|
95
|
-
| Auto | adaptive selection | Fetch first, then browser when the caller permits it. |
|
|
96
95
|
| Headless | no visible UI | CI runners, servers and scheduled jobs. |
|
|
97
96
|
| CLI or binary | packaged entry point | Operator tools or third-party compute jobs. |
|
|
98
97
|
| Computer | storage-to-compute bridge | Bounded binary and memory processing. |
|
|
@@ -110,8 +109,9 @@ The engine coordinates serializable contracts rather than hiding providers. The
|
|
|
110
109
|
| Jobs | `engine`, `scheduler`, `inprocess` | `prepare -> process -> sync -> cleanup` |
|
|
111
110
|
| Storage | local, chunked, content-addressed, S3-compatible, GitHub Contents and file-hosting adapters | durable objects, ranges, dedupe and sync |
|
|
112
111
|
| Working set | memory bridge, modes, objects and transforms | storage-to-compute and compute-to-storage flows |
|
|
113
|
-
|
|
|
114
|
-
|
|
|
112
|
+
| Sandbox modalities | the ninety-record modality registry with the join resolver and the honest live/host/planned census | the workload never names a modality — the platform resolves the join |
|
|
113
|
+
| Edge lanes | the edgelandes lane tables (sandbox jails, language toolchains, runner seats, ram recipes, delivery protocols, storage wire speakers, virtual compositions) | ninety lanes probing the host, every run in a private temp dir under a hard deadline |
|
|
114
|
+
| Script lanes | sh interpretation, the house yaml subset and detached background runs | deterministic local execution through the universal runner |
|
|
115
115
|
| Browser | snapshots, tabs, frames, actions, fingerprint, session and replay contracts | caller-owned browser automation without a mandatory provider |
|
|
116
116
|
| Operations | queues, idempotency, saga, retry, circuit breaker, health and heartbeat | controlled execution and recovery |
|
|
117
117
|
| Protocols | JSON, NDJSON, SSE, blocks, API envelopes and MCP | transport-neutral messages |
|
|
@@ -136,9 +136,9 @@ The root entry point is transport-neutral. Node filesystem, HTTP server, persist
|
|
|
136
136
|
|
|
137
137
|
The same contracts can be surfaced as an npm library, application archive, computer runtime, desktop installer, Android APK/AAB, iOS IPA, CLI, binary, browser package, Manifest V3 extension, web/PWA artifact, LibreOffice OXT, VSIX, webhook server, MCP transport, workflow action, container image, Maven package, NuGet package or RubyGem. These surfaces are declarative target plans and caller-owned adapters around the engine; they are not separate sources of truth.
|
|
138
138
|
|
|
139
|
-
###
|
|
139
|
+
### The ninety sandbox modalities
|
|
140
140
|
|
|
141
|
-
The
|
|
141
|
+
The sandbox plane answers the ninety modality plan. `modalityregistry.ts` holds one honest record per modality — isolation family, drivers, hardening gates, boot budget, gpu and network paths, and a live/host/planned state that never pretends — and `resolvejoin` reads a workload request (base profile, gpu, network, isolation depth, boot budget) and answers the modality set that satisfies it, so the person chooses none and the platform resolves the join of all. The edgelandes lane tables wire the plan: ninety lanes probing their host runtime (the sandbox jails, the language toolchains, the runner seats, the ram recipes, the delivery protocols, the virtual hardware compositions), every run in a private temp dir under a hard deadline, an absent runtime answering a coded absence that names it. `scriptlanes.ts` rides the same law for scripts — sh plans, the house yaml subset and detached background runs through the universal runner — and `workloadlaw.ts` catalogs the heavy workload lane of every family app as a demand the same join resolver answers. The self-hosted surface publishes the census at `/api/v1/modalities` and the lane table at `/api/v1/edge/lanes`.
|
|
142
142
|
|
|
143
143
|
### Third-party compute identity
|
|
144
144
|
|
|
@@ -148,23 +148,18 @@ Saddle can be connected to GitHub, GitLab, Forgejo, Gitea, Codeberg, Docker or a
|
|
|
148
148
|
|
|
149
149
|
| Export | Purpose |
|
|
150
150
|
| --- | --- |
|
|
151
|
-
| `
|
|
152
|
-
| `
|
|
153
|
-
| `
|
|
154
|
-
| `
|
|
155
|
-
| `
|
|
156
|
-
| `
|
|
157
|
-
| `
|
|
158
|
-
| `
|
|
159
|
-
| `
|
|
160
|
-
| `withRetry` | bounded retry and abort handling |
|
|
161
|
-
| `createServer` | caller-owned HTTP surface |
|
|
162
|
-
| `batchscrape` | bounded URL groups |
|
|
163
|
-
| `crawlurl` | crawl contract with domain and budget controls |
|
|
151
|
+
| `createVirtualEngine` / `VirtualEngine` / `probeengine` | virtual machine lifecycle, health probes and metrics |
|
|
152
|
+
| `validateSpec` / `specschema` | engine specification validation and normalization |
|
|
153
|
+
| `randomPort` / `resolveHost` / `buildEndpoint` | endpoint allocation without fixed addresses |
|
|
154
|
+
| `InternalMemory` / `MetricsStore` / `enginebus` | the memory bank, the metrics store and the engine event bus |
|
|
155
|
+
| `MODALITIES` / `planreport` | the ninety-record modality registry and its honest census |
|
|
156
|
+
| `resolvejoin` / `getmodality` | the join resolver — the workload never names a modality |
|
|
157
|
+
| `edgelanes` / `edgelandesreport` | the edge lane table and its probe report |
|
|
158
|
+
| `interpretsh` / `interpretyml` / `runscriptbackground` | script lanes: sh plans, yaml plans and detached runs |
|
|
159
|
+
| `engine` / `scheduler` / `inprocess` / `eventbus` | job lifecycle, runner dispatch and events |
|
|
164
160
|
| `browseragent` | caller-owned navigation, click, type and screenshot actions |
|
|
165
161
|
| `mcpserver` / `mcptransport` | MCP tools over JSONL or HTTP |
|
|
166
162
|
| `nodeserver` | Web Request/Response handler |
|
|
167
|
-
| `engine` / `scheduler` | job lifecycle and runner dispatch |
|
|
168
163
|
| `release-assets` | SHA256SUMS, SBOM and provenance metadata for caller-selected artifacts |
|
|
169
164
|
| `releaseevidence` / `evaluateevidence` | serializable release-evidence creation and evaluation |
|
|
170
165
|
| `releasereadiness` / `evidencefromverification` | readiness assessment from caller-supplied verification evidence |
|
|
@@ -175,14 +170,14 @@ The package export map is defined by the root manifest. Runnable public examples
|
|
|
175
170
|
|
|
176
171
|
## Browser extension
|
|
177
172
|
|
|
178
|
-
The extension
|
|
173
|
+
The extension surface migrated to the devthink app with the wave 2 regrouping: it is a TypeScript-first Manifest V3 reference surface (popup, service worker, isolated content bridge, read-only page-world `pagefacts` boundary, snapshot diffs and persisted window/tab/frame context for explicit resume) that runs in the user's browser, so it is not a VM modality of the engine — its module, tracked assets and tests now live at `devthink/browserextension.ts`, the devthink root `extension*` asset family and `devthink/tests/browserextension.test.ts` (see `docs/browser.md` for the migration map).
|
|
179
174
|
|
|
180
175
|
```bash
|
|
181
|
-
# build an isolated JavaScript artifact using the version supplied by the caller or release tag
|
|
182
|
-
|
|
176
|
+
# build an isolated JavaScript artifact from the devthink app root using the version supplied by the caller or release tag
|
|
177
|
+
cd ../devthink && node --import tsx ./browserextension.ts --output build/browserextension
|
|
183
178
|
|
|
184
|
-
# load build/
|
|
185
|
-
ls build/
|
|
179
|
+
# load build/browserextension from chrome://extensions
|
|
180
|
+
ls build/browserextension/manifest.json build/browserextension/worker.js build/browserextension/content.js build/browserextension/popup.html
|
|
186
181
|
```
|
|
187
182
|
|
|
188
183
|
The base permission set is `activeTab`, `scripting` and `storage`. It does not request broad host permissions, cookies, `webRequest`, debugger access or arbitrary page code execution. Optional host escalation remains caller-owned. Releases attach `saddle.extension.<version>.zip`; cross-browser profiles remain adapter work.
|
|
@@ -193,14 +188,14 @@ The base permission set is `activeTab`, `scripting` and `storage`. It does not r
|
|
|
193
188
|
| --- | --- |
|
|
194
189
|
| Credentials | injected by the caller or repository secret; never committed or printed |
|
|
195
190
|
| Network | HTTP/HTTPS targets are validated; private-target access remains caller policy |
|
|
196
|
-
|
|
|
191
|
+
| Edge lanes | every lane runs in a private temp dir under a hard deadline; the visitor law guard holds on every run |
|
|
197
192
|
| Storage | adapters are replaceable; the core does not own a provider account |
|
|
198
193
|
| Runtime | Node-only filesystem, HTTP, Playwright and release metadata stay outside the transport-neutral root |
|
|
199
194
|
| Extension | page-world reads are bounded, token-correlated and read-only |
|
|
200
195
|
| Failure | retry, circuit breaker, idempotency and resume are configurable |
|
|
201
196
|
| Releases | version comes from the `vX.Y.Z` tag and must match `package.json` |
|
|
202
197
|
|
|
203
|
-
Version 2.0.0 (the grand merge) absorbs the e2ugh virtual-hardware engine into the saddle engine: fifteen engine modules land at the repository root (virtualcpu, virtualmemory, virtualgpu, virtualization, orchestrator, scheduler, compute, media, render, security, performance, alternatives, tiers, quantum and the engine index core), the e2ugh static console and self-hosted API live at web, the hardware catalogs (processors, gpus, cores, boards) and the four virtual-hardware config envelopes (qemu, mttg, passage, docker) ship as package exports under specs
|
|
198
|
+
Version 2.0.0 (the grand merge) absorbs the e2ugh virtual-hardware engine into the saddle engine: fifteen engine modules land at the repository root (virtualcpu, virtualmemory, virtualgpu, virtualization, orchestrator, scheduler, compute, media, render, security, performance, alternatives, tiers, quantum and the engine index core), the e2ugh static console and self-hosted API live at web, the hardware catalogs (processors, gpus, cores, boards) and the four virtual-hardware config envelopes (qemu, mttg, passage, docker) ship as package exports under specs/*. The engine surface stays dependency-free at the root (node built-ins only). Version 1.8.19 previously while reorganizing implementation ownership into twenty correlated domains behind a transport-neutral root router. The migration groups foundation nouns, execution state, API protocols, MCP adapters, automation contracts, package delivery and mode profiles without adding a privileged effect. Existing package subpaths remain available through their updated compiled targets. The denied-by-default execution, policy, handoff and internal-API contracts remain plans or receipts until a separately approved caller adapter is supplied. The current container targets the eleven-architecture family surface (`linux/amd64`, `linux/amd64/v2`, `linux/arm64`, `linux/arm/v7`, `linux/arm/v6`, `linux/ppc64le`, `linux/s390x`, `linux/riscv64`, `linux/386`, `linux/mips64le`, `linux/loong64`); release evidence, readiness and verification remain serializable and caller-owned.
|
|
204
199
|
|
|
205
200
|
## Package surfaces and release automation
|
|
206
201
|
|
|
@@ -223,7 +218,7 @@ Saddle is applying to the SignPath Foundation for open-source code signing. Unti
|
|
|
223
218
|
|
|
224
219
|
The requested policy is: **Free code signing provided by SignPath.io, certificate by SignPath Foundation**. Committers and reviewers are maintainers with write access to the public repository. Approvers are repository owners or release approvers recorded in `governance.md`. Every signed release must be built from repository source, pass the security and packaging gates, and receive manual signing approval.
|
|
225
220
|
|
|
226
|
-
The core program will not transfer information to other networked systems unless specifically requested by the user or the person installing or operating it. Browser sessions, storage adapters, runners and external services remain caller-configured and subject to their own policies. See [`
|
|
221
|
+
The core program will not transfer information to other networked systems unless specifically requested by the user or the person installing or operating it. Browser sessions, storage adapters, runners and external services remain caller-configured and subject to their own policies. See [`privacypolicy.md`](privacypolicy.md) and [`SECURITY.md`](SECURITY.md).
|
|
227
222
|
|
|
228
223
|
## GitHub Pages web surface
|
|
229
224
|
|
|
@@ -234,7 +229,7 @@ npm run web:check
|
|
|
234
229
|
VITE_BASE_PATH=/saddle npm run web:build:pages
|
|
235
230
|
```
|
|
236
231
|
|
|
237
|
-
Small public configuration and visual assets live under `web/public/`. The obsolete `web/public/__manus__` directory is intentionally absent; the development debug collector (the visitor-browser telemetry hook at the former `web/debugcollector.ts`) left the saddle
|
|
232
|
+
Small public configuration and visual assets live under `web/public/`. The obsolete `web/public/__manus__` directory is intentionally absent; the development debug collector (the visitor-browser telemetry hook at the former `web/debugcollector.ts`) left the saddle — the engine keeps no surface that watches the user's browser.
|
|
238
233
|
|
|
239
234
|
## Development
|
|
240
235
|
|
|
@@ -267,24 +262,28 @@ Remote execution, provider credentials, browser transport, persistence, proxy se
|
|
|
267
262
|
## Repository map
|
|
268
263
|
|
|
269
264
|
```text
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
265
|
+
index.ts the transport-neutral root barrel re-exporting every domain
|
|
266
|
+
foundation.ts errors, events, identifiers, hashing, jobs, artifacts and sessions
|
|
267
|
+
execution.ts the engine, the scheduler, the inprocess runner and the working-set contracts
|
|
268
|
+
virtual.ts memory bridge, modes, objects, transforms and the local adapters
|
|
269
|
+
isolation.ts execution request, decision, handoff and the internal api envelopes
|
|
270
|
+
modalityregistry.ts the ninety-record sandbox modality catalog, the join resolver and the census
|
|
271
|
+
edgelandes*.ts the edge lane tables: host jails and toolchains, inproc recipes, virtual compositions, the ninety merge seat
|
|
272
|
+
edgeplane.ts the merged lane dispatch plane and the visitor law guard
|
|
273
|
+
scriptlanes.ts sh plans, the house yaml subset and detached background runs
|
|
274
|
+
workloadlaw.ts the family workload seat: every app declares the lanes its workloads ride
|
|
275
|
+
sandbox*.ts the sandbox state, the declared sandbox profile and its environment adapter
|
|
276
|
+
virtualcpu.ts, virtualmemory.ts, virtualgpu.ts, virtualization.ts, orchestrator.ts,
|
|
277
|
+
scheduler.ts, compute.ts, media.ts, render.ts, quantum.ts, tiers.ts, security.ts,
|
|
278
|
+
performance.ts, alternatives.ts
|
|
279
|
+
the e2ugh virtual-hardware engine domains landed at the root by the grand merge
|
|
280
|
+
automation.ts, browser.ts, communication.ts, distribution.ts, integration.ts,
|
|
281
|
+
intelligence.ts, modes.ts
|
|
282
|
+
the saddle domain routing barrel files (bot, browser, delivery, integrations, profiles)
|
|
283
|
+
server.ts, webserver.ts, api.ts, cli.ts
|
|
284
|
+
the self-hosted api surfaces, the web console and the stable cli
|
|
285
|
+
Sol/ the Sol theme — the platform's web surface (one tsx app, one stylesheet per theme)
|
|
286
|
+
specs processors.json, gpus.json, cores.json, boards.json and the qemu/mttg/passage/docker/vm envelopes
|
|
288
287
|
tests/ deterministic engine and extension coverage
|
|
289
288
|
docs/ architecture, API, security, release and registry notes
|
|
290
289
|
```
|
|
@@ -293,7 +292,7 @@ The engine is TypeScript-first ESM with English JSDoc comments and a generated J
|
|
|
293
292
|
|
|
294
293
|
## Historical documentation
|
|
295
294
|
|
|
296
|
-
The repository history contains 41 root README revisions and several surface-specific records. Their durable ideas are consolidated here: storage-backed execution, bounded working sets, replaceable runners,
|
|
295
|
+
The repository history contains 41 root README revisions and several surface-specific records. Their durable ideas are consolidated here: storage-backed execution, bounded working sets, replaceable runners, browser actions, workflow delivery, multi-registry packaging, explicit recovery contracts and caller-owned integrations. Historical references that describe superseded identities, obsolete Node baselines, speculative provider quotas, unavailable hosted services or removed layouts remain historical evidence rather than current promises.
|
|
297
296
|
|
|
298
297
|
## Current scope
|
|
299
298
|
|
|
@@ -309,7 +308,7 @@ Saddle is distributed under the [GNU General Public License v3.0 only](LICENSE).
|
|
|
309
308
|
|
|
310
309
|
# Saddle Sol
|
|
311
310
|
|
|
312
|
-
Saddle is the
|
|
311
|
+
Saddle is the 90-modality sandbox platform of the DevThink family: one engine spanning compute, virtualization, media, mesh, automation and the other modalities, exposed as a self-hosted site. This Sol theme is the platform's web surface — a Vite + React SPA (console, dashboard, playground, integrations) served from the same sqlite database that `schema.prisma`, `init.sql` and `drizzle.config.ts` describe.
|
|
313
312
|
|
|
314
313
|
```bash
|
|
315
314
|
pnpm install
|