@wenathlan/saddle 2.0.6 → 2.0.151
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 +70 -24
- package/LICENSE +0 -0
- package/README.md +19 -3
- package/alternatives.ts +0 -0
- package/biome.jsonc +127 -0
- package/boards.json +2 -2
- package/compute.ts +4 -4
- package/cores.json +2 -2
- package/docker.config +16 -9
- package/docs/.gitkeep +0 -0
- package/docs/CONVERSA.txt +0 -0
- package/docs/actionrecorder.md +0 -0
- package/docs/actionsincident.md +0 -0
- package/docs/alternatives.md +0 -0
- package/docs/architecture-1.8.19.md +0 -0
- package/docs/architecture-1.8.19.mmd +0 -0
- package/docs/architecture-1.8.19.png +0 -0
- package/docs/architecture.md +3 -3
- package/docs/artifactavailability.md +0 -0
- package/docs/artifactresearch-1.8.9.md +0 -0
- package/docs/assets/architecture.svg +0 -0
- package/docs/assets/saddle-browser-trace.webp +0 -0
- package/docs/assets/saddle-hero-bridge.webp +0 -0
- package/docs/assets/saddle-mark.webp +0 -0
- package/docs/assets/saddle-runtime-map.webp +0 -0
- package/docs/assets/saddlemark.svg +0 -0
- package/docs/batches-1816-1820.md +0 -0
- package/docs/brancharchive-2026-08-18.md +0 -0
- package/docs/branchaudit.md +0 -0
- package/docs/browser.md +0 -0
- package/docs/capabilityreport.md +0 -0
- package/docs/comparativeaudit.md +0 -0
- package/docs/consolidation.md +0 -0
- package/docs/containerplatforms-1.8.17.md +0 -0
- package/docs/containerplatforms-2.1.0.md +73 -0
- package/docs/documentmap-1.8.12.md +0 -0
- package/docs/e2ugh-engine.md +0 -0
- package/docs/ecosystemplan.md +0 -0
- package/docs/enginearchitecture.md +0 -0
- package/docs/example-localjob.ts +0 -0
- package/docs/extension.md +0 -0
- package/docs/featureaudit.md +0 -0
- package/docs/flatbuildresearch-1.8.11.md +0 -0
- package/docs/gapmatrix.md +0 -0
- package/docs/hardware.md +0 -0
- package/docs/libraryapi.md +0 -0
- package/docs/licenseaudit-1.8.12.md +0 -0
- package/docs/logs/examplesession.json +54 -0
- package/docs/memoryengine.md +0 -0
- package/docs/mobileconversionresearch-1.8.10.md +0 -0
- package/docs/modes.md +0 -0
- package/docs/native-wrappers.md +38 -0
- package/docs/nativeidentityresearch-1.8.11.md +0 -0
- package/docs/optimization.md +0 -0
- package/docs/packageaudit185.md +0 -0
- package/docs/performance.md +0 -0
- package/docs/planning.1.8.18.md +0 -0
- package/docs/planning.1.8.19.md +0 -0
- package/docs/planning.engine.md +186 -0
- package/docs/platformpipelineaudit.md +0 -0
- package/docs/platformpipelines.md +0 -0
- package/docs/productindex.md +0 -0
- package/docs/registryresearch.md +0 -0
- package/docs/release.md +0 -0
- package/docs/release17notes.md +0 -0
- package/docs/release181notes.md +0 -0
- package/docs/release182notes.md +0 -0
- package/docs/release184notes.md +0 -0
- package/docs/release185notes.md +0 -0
- package/docs/release18notes.md +0 -0
- package/docs/releaseassets.md +0 -0
- package/docs/releasenotes-1.8.12.md +0 -0
- package/docs/releasenotes-1.8.13.md +0 -0
- package/docs/releasenotes-1.8.14.md +0 -0
- package/docs/releasenotes-1.8.15.md +0 -0
- package/docs/releasenotes-1.8.16.md +0 -0
- package/docs/releasenotes-1.8.17.md +0 -0
- package/docs/releasenotes-1.8.18.md +0 -0
- package/docs/releasenotes-1.8.19.md +0 -0
- package/docs/reorganization-1.8.8.md +0 -0
- package/docs/reorganization-1.8.9.md +0 -0
- package/docs/repo-analysis-1.8.21.json +0 -0
- package/docs/repo-candidates-1.8.21.jsonl +0 -0
- package/docs/repo-research-1.8.16.md +0 -0
- package/docs/repo-research-1.8.21.md +0 -0
- package/docs/repo-selected-1.8.21.json +0 -0
- package/docs/repo-synthesis-1.8.16.md +0 -0
- package/docs/repo-synthesis-1.8.21.md +0 -0
- package/docs/research-1.8.18-isolation.md +0 -0
- package/docs/research-1.8.19-virtual-browser.md +0 -0
- package/docs/roadmapp2p3.md +0 -0
- package/docs/s3compatible.md +0 -0
- package/docs/saddle.archive.1.8.17.tar.gz.gpg +0 -0
- package/docs/scanningresearch-1.8.11.md +0 -0
- package/docs/security.md +0 -0
- package/docs/securityaudit-1.8.7.md +0 -0
- package/docs/securityreferences-1.8.11.md +0 -0
- package/docs/securityresearch-1.8.11.md +0 -0
- package/docs/signingresearch-1.8.12.md +0 -0
- package/docs/signingwithoutcertificates.md +0 -0
- package/docs/signpathapplication.md +0 -0
- package/docs/sitemap.md +0 -0
- package/docs/tauri-glib-risk-1.8.11.md +0 -0
- package/docs/todo-1.8.15.md +0 -0
- package/docs/todo-1.8.16.md +0 -0
- package/docs/todo-1.8.18.md +0 -0
- package/docs/todo-1.8.19.md +0 -0
- package/docs/todo.md +0 -0
- package/docs/toolchainresearch-1.8.9.md +0 -0
- package/docs/toolchains.md +0 -0
- package/docs/usage.md +0 -0
- package/docs/viability.md +0 -0
- package/docs/virtualization.md +0 -0
- package/docs/web-duplicatecleanup.md +0 -0
- package/docs/web-ideas.md +0 -0
- package/docs/workflowimprovements-2026-08-19.md +0 -0
- package/docs/workflowinputs.md +0 -0
- package/docs/workflowoperations.md +0 -0
- package/gpumonitor.cpp +0 -0
- package/gpus.json +1 -1
- package/index.ts +15 -15
- package/manifest.json +20 -0
- package/media.ts +0 -0
- package/modalityregistry.ts +156 -0
- package/mttg.config +1 -1
- package/orchestrator.ts +5 -2
- package/package.json +147 -97
- package/passage.config +2 -2
- package/performance.ts +0 -0
- package/processors.json +1 -1
- package/qemu.config +2 -2
- package/qemubridge.py +0 -0
- package/quantum.ts +0 -0
- package/render.ts +0 -0
- package/scheduler.ts +0 -0
- package/security.ts +0 -0
- package/tiers.ts +9 -3
- package/tsconfig.json +22 -17
- package/virtualcpu.ts +1 -0
- package/virtualgpu.ts +1 -0
- package/virtualhardware.c +0 -0
- package/virtualhardware.json +2 -2
- package/virtualization.ts +0 -0
- package/virtualizationcore.cpp +0 -0
- package/virtualmemory.ts +0 -0
- package/vm.config.json +3 -3
- package/biome.json +0 -153
- package/dist/acquisition.d.ts +0 -359
- package/dist/acquisition.d.ts.map +0 -1
- package/dist/acquisition.js +0 -629
- package/dist/acquisition.js.map +0 -1
- package/dist/alternatives.d.ts +0 -509
- package/dist/alternatives.d.ts.map +0 -1
- package/dist/alternatives.js +0 -951
- package/dist/alternatives.js.map +0 -1
- package/dist/automation.d.ts +0 -426
- package/dist/automation.d.ts.map +0 -1
- package/dist/automation.js +0 -561
- package/dist/automation.js.map +0 -1
- package/dist/browser.d.ts +0 -562
- package/dist/browser.d.ts.map +0 -1
- package/dist/browser.js +0 -1057
- package/dist/browser.js.map +0 -1
- package/dist/capacitor.config.d.ts +0 -13
- package/dist/capacitor.config.d.ts.map +0 -1
- package/dist/capacitor.config.js +0 -26
- package/dist/capacitor.config.js.map +0 -1
- package/dist/cli.d.ts +0 -17
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -111
- package/dist/cli.js.map +0 -1
- package/dist/communication.d.ts +0 -192
- package/dist/communication.d.ts.map +0 -1
- package/dist/communication.js +0 -418
- package/dist/communication.js.map +0 -1
- package/dist/compute.d.ts +0 -1161
- package/dist/compute.d.ts.map +0 -1
- package/dist/compute.js +0 -2273
- package/dist/compute.js.map +0 -1
- package/dist/distribution.d.ts +0 -529
- package/dist/distribution.d.ts.map +0 -1
- package/dist/distribution.js +0 -811
- package/dist/distribution.js.map +0 -1
- package/dist/execution.d.ts +0 -530
- package/dist/execution.d.ts.map +0 -1
- package/dist/execution.js +0 -761
- package/dist/execution.js.map +0 -1
- package/dist/format.d.ts +0 -19
- package/dist/format.d.ts.map +0 -1
- package/dist/format.js +0 -60
- package/dist/format.js.map +0 -1
- package/dist/foundation.d.ts +0 -176
- package/dist/foundation.d.ts.map +0 -1
- package/dist/foundation.js +0 -309
- package/dist/foundation.js.map +0 -1
- package/dist/index.d.ts +0 -735
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -1020
- package/dist/index.js.map +0 -1
- package/dist/integration.d.ts +0 -236
- package/dist/integration.d.ts.map +0 -1
- package/dist/integration.js +0 -236
- package/dist/integration.js.map +0 -1
- package/dist/intelligence.d.ts +0 -94
- package/dist/intelligence.d.ts.map +0 -1
- package/dist/intelligence.js +0 -145
- package/dist/intelligence.js.map +0 -1
- package/dist/isolation.d.ts +0 -129
- package/dist/isolation.d.ts.map +0 -1
- package/dist/isolation.js +0 -96
- package/dist/isolation.js.map +0 -1
- package/dist/media.d.ts +0 -344
- package/dist/media.d.ts.map +0 -1
- package/dist/media.js +0 -986
- package/dist/media.js.map +0 -1
- package/dist/modes.d.ts +0 -359
- package/dist/modes.d.ts.map +0 -1
- package/dist/modes.js +0 -134
- package/dist/modes.js.map +0 -1
- package/dist/operations.d.ts +0 -67
- package/dist/operations.d.ts.map +0 -1
- package/dist/operations.js +0 -94
- package/dist/operations.js.map +0 -1
- package/dist/orchestrator.d.ts +0 -1339
- package/dist/orchestrator.d.ts.map +0 -1
- package/dist/orchestrator.js +0 -4308
- package/dist/orchestrator.js.map +0 -1
- package/dist/packager/targetcli.js +0 -4
- package/dist/performance.d.ts +0 -416
- package/dist/performance.d.ts.map +0 -1
- package/dist/performance.js +0 -827
- package/dist/performance.js.map +0 -1
- package/dist/quantum.d.ts +0 -810
- package/dist/quantum.d.ts.map +0 -1
- package/dist/quantum.js +0 -2073
- package/dist/quantum.js.map +0 -1
- package/dist/render.d.ts +0 -381
- package/dist/render.d.ts.map +0 -1
- package/dist/render.js +0 -1073
- package/dist/render.js.map +0 -1
- package/dist/scheduler.d.ts +0 -596
- package/dist/scheduler.d.ts.map +0 -1
- package/dist/scheduler.js +0 -1259
- package/dist/scheduler.js.map +0 -1
- package/dist/security.d.ts +0 -501
- package/dist/security.d.ts.map +0 -1
- package/dist/security.js +0 -1170
- package/dist/security.js.map +0 -1
- package/dist/server.d.ts +0 -21
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js +0 -52
- package/dist/server.js.map +0 -1
- package/dist/tiers.d.ts +0 -1002
- package/dist/tiers.d.ts.map +0 -1
- package/dist/tiers.js +0 -2165
- package/dist/tiers.js.map +0 -1
- package/dist/virtual.d.ts +0 -641
- package/dist/virtual.d.ts.map +0 -1
- package/dist/virtual.js +0 -1285
- package/dist/virtual.js.map +0 -1
- package/dist/virtualcpu.d.ts +0 -316
- package/dist/virtualcpu.d.ts.map +0 -1
- package/dist/virtualcpu.js +0 -1180
- package/dist/virtualcpu.js.map +0 -1
- package/dist/virtualgpu.d.ts +0 -345
- package/dist/virtualgpu.d.ts.map +0 -1
- package/dist/virtualgpu.js +0 -1000
- package/dist/virtualgpu.js.map +0 -1
- package/dist/virtualization.d.ts +0 -607
- package/dist/virtualization.d.ts.map +0 -1
- package/dist/virtualization.js +0 -1187
- package/dist/virtualization.js.map +0 -1
- package/dist/virtualmemory.d.ts +0 -818
- package/dist/virtualmemory.d.ts.map +0 -1
- package/dist/virtualmemory.js +0 -1796
- package/dist/virtualmemory.js.map +0 -1
- package/dist/webscrape.d.ts +0 -720
- package/dist/webscrape.d.ts.map +0 -1
- package/dist/webscrape.js +0 -2697
- package/dist/webscrape.js.map +0 -1
- package/docs/example-publicapi.ts +0 -7
- package/web/extension/manifest.json +0 -23
- package/web/readme.md +0 -382
- package/web/tsconfig.json +0 -25
package/Dockerfile
CHANGED
|
@@ -10,7 +10,10 @@
|
|
|
10
10
|
# stages at the end of this file, folded from the former
|
|
11
11
|
# dockerfile.saddle) — an explicit build target
|
|
12
12
|
# (`docker build --target saddle-runtime .`), the node 26 storage and
|
|
13
|
-
# compute service published as ghcr.io/wenathlan/saddle:<version
|
|
13
|
+
# compute service published as ghcr.io/wenathlan/saddle:<version>
|
|
14
|
+
# across the four-arch family standard (amd64, arm64, ppc64le, s390x
|
|
15
|
+
# — the trixie slim base line; the stage also builds the web SPA so
|
|
16
|
+
# the image serves the self-hosted console via `node /app/webserver.ts`).
|
|
14
17
|
#
|
|
15
18
|
# saddle v2 (grand merge) - virtual hardware engine, multi-stage, multi-arch image.
|
|
16
19
|
#
|
|
@@ -91,7 +94,7 @@
|
|
|
91
94
|
# -v vmdata:/data/vmdata -v webdata:/data/web \
|
|
92
95
|
# -v ./vm.config.json:/engine/vm.config.json:ro \
|
|
93
96
|
# -e PORT=8080 -e NODE_ENV=production -p 31280:8080 \
|
|
94
|
-
# ghcr.io/wenathlan/saddle:vhe-2.
|
|
97
|
+
# ghcr.io/wenathlan/saddle:vhe-2.1.6
|
|
95
98
|
#
|
|
96
99
|
# vheqemu (the guest runner; build it first with
|
|
97
100
|
# docker build --target qemu-runtime -t saddle/qemu:11.1.0 . because the
|
|
@@ -125,7 +128,7 @@
|
|
|
125
128
|
# -e VHE_GPU_PROFILE=b200 -e VHE_GPUS=8 -e VHE_MIG=1 \
|
|
126
129
|
# -e VHE_SMI_DRIVER=575.57.08 -e VHE_SMI_CUDA=12.9 \
|
|
127
130
|
# -e VHE_SMI_INTERVAL=30 -e VHE_SKIP_XVFB=1 -e VHE_SKIP_VALIDATE=1 \
|
|
128
|
-
# ghcr.io/wenathlan/saddle:vhe-2.
|
|
131
|
+
# ghcr.io/wenathlan/saddle:vhe-2.1.6 /bin/bash -c '
|
|
129
132
|
# while true; do
|
|
130
133
|
# /usr/local/bin/nvidia-smi "$VHE_GPU_PROFILE" "$VHE_GPUS" || true
|
|
131
134
|
# sleep "$VHE_SMI_INTERVAL"
|
|
@@ -142,7 +145,7 @@
|
|
|
142
145
|
# -v qemudata:/data/qemudata \
|
|
143
146
|
# -v ./qemubridge.py:/engine/qemubridge.py:ro \
|
|
144
147
|
# -e QMP_SOCKET=/run/vhe/vm.qmp -e PYTHONUNBUFFERED=1 \
|
|
145
|
-
# ghcr.io/wenathlan/saddle:vhe-2.
|
|
148
|
+
# ghcr.io/wenathlan/saddle:vhe-2.1.6 \
|
|
146
149
|
# python3 /engine/qemubridge.py --socket /run/vhe/vm.qmp status
|
|
147
150
|
#
|
|
148
151
|
# saddle-node (the node-engine service, the former compose.yml
|
|
@@ -156,7 +159,7 @@
|
|
|
156
159
|
# --log-driver json-file --log-opt max-size=50m --log-opt max-file=5 \
|
|
157
160
|
# --tmpfs /tmp:size=2g,mode=1777 \
|
|
158
161
|
# -e SADDLE_MEMORY_ENGINE=ram -e SBOT_PLATFORM= -e SBOT_CDN_URL= \
|
|
159
|
-
# ghcr.io/wenathlan/saddle:2.
|
|
162
|
+
# ghcr.io/wenathlan/saddle:2.1.6 \
|
|
160
163
|
# node dist/cli.js plan
|
|
161
164
|
#
|
|
162
165
|
# observability (the former prometheus scraper of the full profile)
|
|
@@ -636,6 +639,44 @@ ENTRYPOINT ["/usr/bin/tini", "--", "qemu-system-x86_64"]
|
|
|
636
639
|
# ---------------------------------------------------------------------------
|
|
637
640
|
# stage 5: runtime (final, default target, the vhe/vhegpu docker run recipes)
|
|
638
641
|
# ---------------------------------------------------------------------------
|
|
642
|
+
# saddle-build: the node-engine build stage (defined here, before the
|
|
643
|
+
# vhe runtime, so BOTH container surfaces can consume its output: the
|
|
644
|
+
# vhe runtime copies the built web SPA beside the console server at
|
|
645
|
+
# /engine and the saddle-runtime stage copies the engine dist plus the
|
|
646
|
+
# same staged SPA - one build, two consumers). The stage runs native
|
|
647
|
+
# (never under QEMU): its outputs are platform-independent static/js
|
|
648
|
+
# payloads.
|
|
649
|
+
|
|
650
|
+
# the build stage pins to the native build platform ($BUILDPLATFORM): its
|
|
651
|
+
# outputs (the engine dist, pure js, and the web SPA, static assets) are
|
|
652
|
+
# architecture-independent, while the tailwind/lightningcss pipeline only
|
|
653
|
+
# ships native bindings for the builder platforms - the per-arch legs never
|
|
654
|
+
# run it under QEMU. The base rides the family tag contract (tags only,
|
|
655
|
+
# never a @sha256: digest - a single digest cannot serve the
|
|
656
|
+
# four-architecture matrix the registry resolves per platform).
|
|
657
|
+
FROM --platform=$BUILDPLATFORM node:26.8.1-slim AS saddle-build
|
|
658
|
+
|
|
659
|
+
ARG SADDLE_VERSION
|
|
660
|
+
WORKDIR /app
|
|
661
|
+
|
|
662
|
+
ENV NPM_CONFIG_LEGACY_PEER_DEPS=true
|
|
663
|
+
|
|
664
|
+
COPY package.json package-lock.json ./
|
|
665
|
+
RUN npm ci --ignore-scripts --legacy-peer-deps
|
|
666
|
+
COPY . .
|
|
667
|
+
RUN npm run build:engine \
|
|
668
|
+
&& node --check dist/cli.js \
|
|
669
|
+
&& npm run web:build:pages \
|
|
670
|
+
# the theme build emits the hashed SPA bundles straight at the app
|
|
671
|
+
# root (the family static-first vite contract): stage them into a
|
|
672
|
+
# clean folder so the runtime stages copy exactly the console
|
|
673
|
+
# surface - the shell, the hashed js/css bundles and the icon and
|
|
674
|
+
# manifest assets the shell references. the extension popup
|
|
675
|
+
# stylesheet is the one root css that never belongs to the spa.
|
|
676
|
+
&& mkdir -p /out/spa \
|
|
677
|
+
&& cp index.html *.js *.css *.svg *.webmanifest /out/spa/ \
|
|
678
|
+
&& rm -f /out/spa/popup.css
|
|
679
|
+
|
|
639
680
|
FROM ${UBUNTU} AS runtime
|
|
640
681
|
ARG TARGETARCH
|
|
641
682
|
ARG NODE_VERSION
|
|
@@ -866,15 +907,24 @@ COPY --from=python-bridge /bridge/qemubridge.py /engine/qemubridge.py
|
|
|
866
907
|
# the engine sources and the specification files consumed at runtime
|
|
867
908
|
# (docker.config "final" stage copies the whole tree; the flat layout
|
|
868
909
|
# keeps that a single COPY layer).
|
|
869
|
-
COPY *.ts package.json tsconfig.json biome.
|
|
910
|
+
COPY *.ts package.json tsconfig.json biome.jsonc jsdom.d.ts /engine/
|
|
870
911
|
COPY processors.json gpus.json cores.json boards.json vm.config.json virtualhardware.json /engine/
|
|
871
|
-
COPY qemu.config mttg.config passage.config docker.config /engine/
|
|
912
|
+
COPY qemu.config mttg.config passage.config docker.config mime.types /engine/
|
|
872
913
|
|
|
873
914
|
# the web node ships inside the main container: the mesh edition (auth,
|
|
874
915
|
# sqlite database, dashboard and the browser sandbox pages) runs from the
|
|
875
916
|
# same image, so one container serves the engine AND the web surface.
|
|
876
|
-
# run it with: docker run ghcr.io/wenathlan/saddle node /engine/
|
|
877
|
-
COPY
|
|
917
|
+
# run it with: docker run ghcr.io/wenathlan/saddle node /engine/webserver.ts
|
|
918
|
+
# (the console server is a root engine source - the COPY *.ts line above
|
|
919
|
+
# already lands it at /engine together with its console stack, and the
|
|
920
|
+
# extension denylist of its static resolver keeps every .ts/.json/.sql
|
|
921
|
+
# source unreachable).
|
|
922
|
+
# the built web SPA (vite, staged by saddle-build): the theme build emits
|
|
923
|
+
# the hashed bundles straight at the app root, so the staged spa lands
|
|
924
|
+
# beside the console server at /engine and webserver.ts serves it from
|
|
925
|
+
# its own module directory - the unified React interface that absorbed
|
|
926
|
+
# the former static pages.
|
|
927
|
+
COPY --from=saddle-build /out/spa /engine/
|
|
878
928
|
|
|
879
929
|
RUN set -eux; \
|
|
880
930
|
chmod 0755 /usr/local/bin/nvidia-smi /usr/local/bin/aetherforge; \
|
|
@@ -1238,7 +1288,7 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --start-interval=5s
|
|
|
1238
1288
|
# OCI labels for registry introspection.
|
|
1239
1289
|
LABEL org.opencontainers.image.title="saddle virtual-hardware engine (the grand merge)" \
|
|
1240
1290
|
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" \
|
|
1241
|
-
org.opencontainers.image.version="2.
|
|
1291
|
+
org.opencontainers.image.version="2.1.6" \
|
|
1242
1292
|
org.opencontainers.image.licenses="MIT" \
|
|
1243
1293
|
org.opencontainers.image.source="https://github.com/wenathlan/saddle" \
|
|
1244
1294
|
org.opencontainers.image.documentation="https://github.com/wenathlan/saddle/blob/main/README.md" \
|
|
@@ -1277,20 +1327,7 @@ ENTRYPOINT ["/entrypoint.sh"]
|
|
|
1277
1327
|
# docker build --target saddle-runtime -t saddle:<version> .
|
|
1278
1328
|
# ══════════════════════════════════════════════════════════════════════
|
|
1279
1329
|
|
|
1280
|
-
FROM node:26.8.1-
|
|
1281
|
-
|
|
1282
|
-
ARG SADDLE_VERSION
|
|
1283
|
-
WORKDIR /app
|
|
1284
|
-
|
|
1285
|
-
ENV NPM_CONFIG_LEGACY_PEER_DEPS=true
|
|
1286
|
-
|
|
1287
|
-
COPY package.json package-lock.json ./
|
|
1288
|
-
RUN npm ci --ignore-scripts --legacy-peer-deps
|
|
1289
|
-
COPY . .
|
|
1290
|
-
RUN npm run build:engine \
|
|
1291
|
-
&& node --check dist/cli.js
|
|
1292
|
-
|
|
1293
|
-
FROM node:26.8.1-bookworm-slim AS saddle-runtime
|
|
1330
|
+
FROM node:26.8.1-slim AS saddle-runtime
|
|
1294
1331
|
|
|
1295
1332
|
ARG SADDLE_VERSION
|
|
1296
1333
|
LABEL org.opencontainers.image.title="Saddle" \
|
|
@@ -1337,6 +1374,15 @@ RUN apt-get update \
|
|
|
1337
1374
|
&& rm -rf node_modules/cpu-features/deps \
|
|
1338
1375
|
&& find node_modules -type f -name Dockerfile -delete
|
|
1339
1376
|
COPY --from=saddle-build /app/dist ./dist
|
|
1377
|
+
# the web service surface (self-hosted console): the staged spa plus the
|
|
1378
|
+
# pure-node server stack (webserver.ts, db.ts, labels.ts, auth.ts,
|
|
1379
|
+
# mesh.ts, sandbox.ts, sandboxprofile.ts, sandboxenvprofile.ts,
|
|
1380
|
+
# sandboxquota.ts, mime.types, init.sql, schema.prisma) - zero npm
|
|
1381
|
+
# dependencies, the node 26 runtime carries everything (node:sqlite,
|
|
1382
|
+
# node:crypto, native type stripping for the .ts sources).
|
|
1383
|
+
# run the console with: docker run saddle:<version> node webserver.ts
|
|
1384
|
+
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 ./
|
|
1385
|
+
COPY --from=saddle-build /out/spa ./
|
|
1340
1386
|
|
|
1341
1387
|
USER node
|
|
1342
1388
|
|
package/LICENSE
CHANGED
|
File without changes
|
package/README.md
CHANGED
|
@@ -30,7 +30,9 @@ domain modules land beside the saddle domains:
|
|
|
30
30
|
| `scheduler.ts`, `compute.ts`, `performance.ts` | job queues, batch compute and benchmark planning |
|
|
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.151 grand-merge envelope (`node server.ts`; the api answers its version at `/api/v1/health`) and the browser-pure engine port |
|
|
35
|
+
| `vercel.json`, `netlify.toml` | the platform deploy adapters beside the surface they publish (the caddy ghost stays out of the tree) |
|
|
34
36
|
| `specs/*` package exports | processors, gpus, cores, boards and the qemu/mttg/passage/docker envelopes |
|
|
35
37
|
|
|
36
38
|
The full pre-merge documentation of the engine lives in
|
|
@@ -57,7 +59,7 @@ console.log(context.summary);
|
|
|
57
59
|
The deterministic examples and tests do not require network access or real credentials:
|
|
58
60
|
|
|
59
61
|
```bash
|
|
60
|
-
node --import tsx
|
|
62
|
+
node --import tsx docs/example-publicapi.ts
|
|
61
63
|
npm test
|
|
62
64
|
```
|
|
63
65
|
|
|
@@ -232,7 +234,7 @@ npm run web:check
|
|
|
232
234
|
VITE_BASE_PATH=/saddle npm run web:build:pages
|
|
233
235
|
```
|
|
234
236
|
|
|
235
|
-
Small public configuration and visual assets live under `web/public/`. The development collector
|
|
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 together with the scrape lanes — the engine keeps no surface that watches the user's browser.
|
|
236
238
|
|
|
237
239
|
## Development
|
|
238
240
|
|
|
@@ -300,3 +302,17 @@ Version 1.8.19 organizes the existing engine into twenty documented, dependency-
|
|
|
300
302
|
## License
|
|
301
303
|
|
|
302
304
|
Saddle is distributed under the [GNU General Public License v3.0 only](LICENSE).
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
# The Sol theme
|
|
309
|
+
|
|
310
|
+
# Saddle Sol
|
|
311
|
+
|
|
312
|
+
Saddle is the 20-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
|
+
|
|
314
|
+
```bash
|
|
315
|
+
pnpm install
|
|
316
|
+
pnpm dev
|
|
317
|
+
```
|
|
318
|
+
|
package/alternatives.ts
CHANGED
|
File without changes
|
package/biome.jsonc
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// the family biome baseline: identical across the apps, the identity only names the app.
|
|
2
|
+
{
|
|
3
|
+
"$schema": "https://biomejs.dev/schemas/2.6.3/schema.json",
|
|
4
|
+
"vcs": {
|
|
5
|
+
"enabled": true,
|
|
6
|
+
"clientKind": "git",
|
|
7
|
+
"useIgnoreFile": true
|
|
8
|
+
},
|
|
9
|
+
"files": {
|
|
10
|
+
"includes": [
|
|
11
|
+
"**/*.ts",
|
|
12
|
+
"**/*.tsx",
|
|
13
|
+
"**/*.js",
|
|
14
|
+
"**/*.mjs",
|
|
15
|
+
"**/*.cjs",
|
|
16
|
+
"**/*.css",
|
|
17
|
+
"**/*.json",
|
|
18
|
+
"!**/dist",
|
|
19
|
+
"!**/distpackage",
|
|
20
|
+
"!**/target",
|
|
21
|
+
"!**/node_modules",
|
|
22
|
+
"!**/bun.lock",
|
|
23
|
+
"!**/*.min.js",
|
|
24
|
+
"!**/docs",
|
|
25
|
+
"!**/tests/tmp",
|
|
26
|
+
"!**/tests/code",
|
|
27
|
+
"!**/Sol/dist"
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
"formatter": {
|
|
31
|
+
"enabled": true,
|
|
32
|
+
"indentStyle": "space",
|
|
33
|
+
"indentWidth": 2,
|
|
34
|
+
"lineWidth": 120,
|
|
35
|
+
"lineEnding": "lf"
|
|
36
|
+
},
|
|
37
|
+
"linter": {
|
|
38
|
+
"enabled": true,
|
|
39
|
+
"rules": {
|
|
40
|
+
"preset": "recommended",
|
|
41
|
+
"correctness": {
|
|
42
|
+
"noUnusedVariables": "warn",
|
|
43
|
+
"noUnsafeOptionalChaining": "warn",
|
|
44
|
+
"useExhaustiveDependencies": "warn",
|
|
45
|
+
"noUnusedImports": "warn",
|
|
46
|
+
"noUnusedPrivateClassMembers": "warn",
|
|
47
|
+
"noUnusedFunctionParameters": "warn",
|
|
48
|
+
"noConstantCondition": "warn",
|
|
49
|
+
"noVoidTypeReturn": "warn"
|
|
50
|
+
},
|
|
51
|
+
"a11y": {
|
|
52
|
+
"useButtonType": "warn",
|
|
53
|
+
"noStaticElementInteractions": "warn",
|
|
54
|
+
"useSemanticElements": "warn",
|
|
55
|
+
"useAriaPropsSupportedByRole": "warn"
|
|
56
|
+
},
|
|
57
|
+
"suspicious": {
|
|
58
|
+
"noExplicitAny": "warn",
|
|
59
|
+
"noArrayIndexKey": "warn",
|
|
60
|
+
"noControlCharactersInRegex": "warn",
|
|
61
|
+
"noRedeclare": "warn",
|
|
62
|
+
"noAssignInExpressions": "warn",
|
|
63
|
+
"noShadowRestrictedNames": "warn",
|
|
64
|
+
"noDuplicateElseIf": "warn",
|
|
65
|
+
"noImplicitAnyLet": "warn",
|
|
66
|
+
"noTsIgnore": "warn",
|
|
67
|
+
"noGlobalIsNan": "warn"
|
|
68
|
+
},
|
|
69
|
+
"style": {
|
|
70
|
+
"noNonNullAssertion": "warn",
|
|
71
|
+
"useTemplate": "warn",
|
|
72
|
+
"useExponentiationOperator": "warn",
|
|
73
|
+
"useConst": "warn"
|
|
74
|
+
},
|
|
75
|
+
"complexity": {
|
|
76
|
+
"useLiteralKeys": "warn",
|
|
77
|
+
"useOptionalChain": "warn",
|
|
78
|
+
"noUselessContinue": "warn",
|
|
79
|
+
"noUselessUndefinedInitialization": "warn",
|
|
80
|
+
"noUselessEscapeInRegex": "warn"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"javascript": {
|
|
85
|
+
"formatter": {
|
|
86
|
+
"quoteStyle": "double",
|
|
87
|
+
"semicolons": "always",
|
|
88
|
+
"trailingCommas": "all",
|
|
89
|
+
"arrowParentheses": "always"
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"css": {
|
|
93
|
+
"parser": {
|
|
94
|
+
"tailwindDirectives": true
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"overrides": [
|
|
98
|
+
{
|
|
99
|
+
"includes": ["**/*"],
|
|
100
|
+
"linter": {
|
|
101
|
+
"rules": {
|
|
102
|
+
"suspicious": {
|
|
103
|
+
"noDebugger": "off"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"includes": ["tests/workflowcheck.ts"],
|
|
110
|
+
"linter": {
|
|
111
|
+
"rules": {
|
|
112
|
+
"suspicious": {
|
|
113
|
+
"noTemplateCurlyInString": "off"
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
],
|
|
119
|
+
"assist": {
|
|
120
|
+
"enabled": true,
|
|
121
|
+
"actions": {
|
|
122
|
+
"source": {
|
|
123
|
+
"useSortedKeys": "off"
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
package/boards.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"date": "2026-08-22",
|
|
8
8
|
"dateFirstDoctrine": "The observer validates all specifications against the latest stable releases available on 2026-08-22.",
|
|
9
9
|
"toolchain": {
|
|
10
|
-
"node": "26.
|
|
10
|
+
"node": "26.12.0 Current",
|
|
11
11
|
"nodeAlt": "24.19.0 LTS",
|
|
12
12
|
"typescript": "7.0.2",
|
|
13
13
|
"python": "3.14.7",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
}
|
|
89
89
|
},
|
|
90
90
|
"name": "boards.json",
|
|
91
|
-
"version": "2.0.
|
|
91
|
+
"version": "2.0.127",
|
|
92
92
|
"title": "saddle - Virtual Motherboard Database (retail boards + platform reference sockets)",
|
|
93
93
|
"sources": [
|
|
94
94
|
"pool:boards.json [S6, 20 retail boards]",
|
package/compute.ts
CHANGED
|
@@ -2554,7 +2554,7 @@ export function buildvmcrdmanifest(opts?: {
|
|
|
2554
2554
|
'metadata:',
|
|
2555
2555
|
` name: ${plural}.${group}`,
|
|
2556
2556
|
'spec:',
|
|
2557
|
-
|
|
2557
|
+
` group: ${group}`,
|
|
2558
2558
|
' scope: Namespaced',
|
|
2559
2559
|
' names:',
|
|
2560
2560
|
` plural: ${plural}`,
|
|
@@ -2562,7 +2562,7 @@ export function buildvmcrdmanifest(opts?: {
|
|
|
2562
2562
|
` kind: ${kind}`,
|
|
2563
2563
|
' shortNames: [vm, evm]',
|
|
2564
2564
|
' versions:',
|
|
2565
|
-
|
|
2565
|
+
` - name: ${version}`,
|
|
2566
2566
|
' served: true',
|
|
2567
2567
|
' storage: true',
|
|
2568
2568
|
' subresources:',
|
|
@@ -2618,8 +2618,8 @@ export function buildvmcrdmanifest(opts?: {
|
|
|
2618
2618
|
'',
|
|
2619
2619
|
].join('\n');
|
|
2620
2620
|
const sample = [
|
|
2621
|
-
|
|
2622
|
-
|
|
2621
|
+
`apiVersion: ${group}/${version}`,
|
|
2622
|
+
`kind: ${kind}`,
|
|
2623
2623
|
'metadata:',
|
|
2624
2624
|
' name: demo-vm',
|
|
2625
2625
|
' namespace: saddle',
|
package/cores.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"metadata": {
|
|
3
3
|
"id": "cores.json",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.127",
|
|
5
5
|
"date": "2026-08-22",
|
|
6
6
|
"datestamp": "2026-08-22T00:00:00Z",
|
|
7
7
|
"observer": "third person observer notes the hybrid core inventory reflects production silicon as of 2026-08-22",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
]
|
|
37
37
|
},
|
|
38
38
|
"stack": {
|
|
39
|
-
"node": "26.
|
|
39
|
+
"node": "26.12.0 Current",
|
|
40
40
|
"nodeAlt": "24.19.0 LTS",
|
|
41
41
|
"typescript": "7.0.2",
|
|
42
42
|
"python": "3.14.7",
|
package/docker.config
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"meta": {
|
|
3
3
|
"name": "docker.config",
|
|
4
4
|
"title": "saddle - Docker Engine and Containerization Configuration",
|
|
5
|
-
"version": "2.
|
|
5
|
+
"version": "2.1.6",
|
|
6
6
|
"date": "2026-08-22",
|
|
7
7
|
"language": "en",
|
|
8
8
|
"sources": [
|
|
@@ -106,11 +106,14 @@
|
|
|
106
106
|
"platforms": {
|
|
107
107
|
"architectures": [
|
|
108
108
|
"linux/amd64",
|
|
109
|
-
"linux/arm64"
|
|
109
|
+
"linux/arm64",
|
|
110
|
+
"linux/ppc64le",
|
|
111
|
+
"linux/s390x"
|
|
110
112
|
],
|
|
111
113
|
"primary": "linux/amd64",
|
|
112
|
-
"qemuEmulation":
|
|
113
|
-
"nativeBuild": true
|
|
114
|
+
"qemuEmulation": true,
|
|
115
|
+
"nativeBuild": true,
|
|
116
|
+
"note": "the four-arch family standard (amd64, arm64, ppc64le, s390x) the one container file and the publish lanes carry; amd64 builds native, the other legs ride QEMU emulation; unknown/* stays rejected as not runnable"
|
|
114
117
|
},
|
|
115
118
|
"runtimeBase": {
|
|
116
119
|
"nodeImage": "node:26.7.0-alpine",
|
|
@@ -468,9 +471,11 @@
|
|
|
468
471
|
"multiArch": {
|
|
469
472
|
"platforms": [
|
|
470
473
|
"linux/amd64",
|
|
471
|
-
"linux/arm64"
|
|
474
|
+
"linux/arm64",
|
|
475
|
+
"linux/ppc64le",
|
|
476
|
+
"linux/s390x"
|
|
472
477
|
],
|
|
473
|
-
"command": "docker buildx build --platform linux/amd64,linux/arm64 --cache-from type=gha --cache-to type=gha,mode=max --push -t ghcr.io/vhe/sandbox:29.7.2 ."
|
|
478
|
+
"command": "docker buildx build --platform linux/amd64,linux/arm64,linux/ppc64le,linux/s390x --cache-from type=gha --cache-to type=gha,mode=max --push -t ghcr.io/vhe/sandbox:29.7.2 ."
|
|
474
479
|
},
|
|
475
480
|
"actionsWorkflowUses": [
|
|
476
481
|
"docker/setup-buildx-action@v4.3.0",
|
|
@@ -618,7 +623,7 @@
|
|
|
618
623
|
"labels": {
|
|
619
624
|
"org.opencontainers.image.title": "saddle-v6",
|
|
620
625
|
"org.opencontainers.image.description": "Saddle v6 virtualization orchestrator with QEMU 11.1.0, Node 22 LTS, Python 3.13.5, MTTG, Passage, OVMF",
|
|
621
|
-
"org.opencontainers.image.version": "2.
|
|
626
|
+
"org.opencontainers.image.version": "2.1.6",
|
|
622
627
|
"org.opencontainers.image.created": "2026-08-22T00:00:00Z",
|
|
623
628
|
"org.opencontainers.image.authors": "Saddle Core <core@saddle.dev>",
|
|
624
629
|
"org.opencontainers.image.url": "https://saddle.dev",
|
|
@@ -630,7 +635,7 @@
|
|
|
630
635
|
"org.opencontainers.image.base.name": "debian:bookworm-slim",
|
|
631
636
|
"org.opencontainers.image.base.digest": "sha256:bookworm-slim-pinned-2026-08-22",
|
|
632
637
|
"saddle": {
|
|
633
|
-
"com.saddle.version": "2.
|
|
638
|
+
"com.saddle.version": "2.1.6",
|
|
634
639
|
"com.saddle.engine": "qemu-11.1.0",
|
|
635
640
|
"com.saddle.modes": "32",
|
|
636
641
|
"com.saddle.forge.mirrors": "github,gitea,forgejo",
|
|
@@ -655,7 +660,9 @@
|
|
|
655
660
|
"target": "runtime-base",
|
|
656
661
|
"platforms": [
|
|
657
662
|
"linux/amd64",
|
|
658
|
-
"linux/arm64"
|
|
663
|
+
"linux/arm64",
|
|
664
|
+
"linux/ppc64le",
|
|
665
|
+
"linux/s390x"
|
|
659
666
|
],
|
|
660
667
|
"cacheFrom": [
|
|
661
668
|
"type=gha",
|
package/docs/.gitkeep
CHANGED
|
File without changes
|
package/docs/CONVERSA.txt
CHANGED
|
File without changes
|
package/docs/actionrecorder.md
CHANGED
|
File without changes
|
package/docs/actionsincident.md
CHANGED
|
File without changes
|
package/docs/alternatives.md
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/docs/architecture.md
CHANGED
|
@@ -104,7 +104,7 @@ Line counts are the shipped files (v2 carryover plus the v3/v5/v6 additions); ev
|
|
|
104
104
|
| `libs/gpumonitor.cpp` | 1543 | C++26 four-mode build: CLI smi-adapter, NVML/libcuda shim, N-API addon, forge mode (Plan/validate/qemu_argv, Mttg work-stealing mirror) | 12 hooks |
|
|
105
105
|
| `libs/virtualhardware.c` | 1011 | C11 LD_PRELOAD core: open-family interception, vhe_translate, inotify regeneration thread, xorshift32 drift, constructor 101 | 12 hooks |
|
|
106
106
|
|
|
107
|
-
Data files: `gpus.json` 2408, `processors.json` 2217, `vm.config.json` 1910, `cores.json` 1801, `mttg.config` 1548, `boards.json` 1517, `passage.config` 1330, `qemu.config` 1061, `virtualhardware.json` 739, `docker.config` 768. Web node (`web/`, the v6 edition plus the v7 wave): `sandbox.
|
|
107
|
+
Data files: `gpus.json` 2408, `processors.json` 2217, `vm.config.json` 1910, `cores.json` 1801, `mttg.config` 1548, `boards.json` 1517, `passage.config` 1330, `qemu.config` 1061, `virtualhardware.json` 739, `docker.config` 768. Web node (`web/`, the v6 edition plus the v7 wave): `sandbox.ts` 1433 is the browser-pure engine port (bank, procfs payloads, the 89-char smi table, mesa summaries, boot dmesg and the command dispatcher), `server.ts` 640 serves the console plus the `/api/v1` contract (health, spec catalogs, sandbox lifecycle, exec) over `node:http`, `index.html` 646 renders the spec panel, terminal and bus timeline, adapters `vercel.json`/`netlify.toml`/`caddyfile` (static edge, api reverse proxied) and `readme.md` 120; the v7 wave completes the node with `db.ts` (sqlite persistence for users, sessions and sandboxes), `auth.ts` (scrypt password hashing, timing-safe verification, cookie sessions), `mesh.ts` (HMAC-SHA256 signed clone-to-main calls with replay windows), the `login.html`/`register.html`/`dashboard.html` pages, `package.json`/`Dockerfile` (image `ghcr.io/wenathlan/e2ugh (main image, web/ included)`; node pinned by the root `.nvmrc`), the database definition kept flat as `schema.prisma` plus `init.sql`, and `mime.types`. Total repository: about 62,200 lines across 83 tracked files (the v2 carryover plus the v3 domains, the v5 media/test waves and the v6 web edition; the `tests/` suite alone is 3,674 lines across eleven files).
|
|
108
108
|
|
|
109
109
|
## 3a. v3 redistribution: features live in domains
|
|
110
110
|
|
|
@@ -129,7 +129,7 @@ Tests live in the `tests/` directory (one of the five allowed directories) and r
|
|
|
129
129
|
|
|
130
130
|
## 3c. Web node architecture (v7)
|
|
131
131
|
|
|
132
|
-
The web node is a static edge plus one self-hosted process. Clones (Vercel and Netlify static deploys of the `web/` pages, redeployed from the `pages.yml` zip -9 bundle) ship only immutable assets: the console, the auth pages and `sandbox.
|
|
132
|
+
The web node is a static edge plus one self-hosted process. Clones (Vercel and Netlify static deploys of the `web/` pages, redeployed from the `pages.yml` zip -9 bundle) ship only immutable assets: the console, the auth pages and `sandbox.ts`, which runs the whole engine client-side and keeps working with no backend. The main node (`node web/server.ts` behind the `caddyfile` on devthink.pro, packaged as `ghcr.io/wenathlan/e2ugh (main image, web/ included)`) owns everything stateful: `db.ts` opens the sqlite file (`schema.prisma`/`init.sql` define it, kept flat per the two-level contract), `auth.ts` is the auth authority - scrypt password hashing with per-user salts, timing-safe verification and server-side sessions delivered as `HttpOnly` cookies - and `mesh.ts` verifies the HMAC-SHA256 signature (method, path, body digest, timestamp, bounded replay window) that every clone attaches to forwarded calls before routing. The design is deliberately anti-serverless: no function runs on the edge platforms, clones hold no secrets and no database, and unauthenticated clones receive 401 from the main node instead of any partial authority.
|
|
133
133
|
|
|
134
134
|
## 4. One bus, one state machine, one metrics store
|
|
135
135
|
|
|
@@ -209,7 +209,7 @@ Per-target delivery notes (one line each, from the collapsed topic docs):
|
|
|
209
209
|
| Target | How the same library is consumed |
|
|
210
210
|
| --- | --- |
|
|
211
211
|
| desktop | EgUi lab UI over the in-process factory; every control honors the 44 px touch target |
|
|
212
|
-
| web | browser bundle shipped as the `web/` console (v6): `sandbox.
|
|
212
|
+
| web | browser bundle shipped as the `web/` console (v6): `sandbox.ts` mirrors the verified bank, `server.ts` serves it and `/api/spec`; zero dependencies keep the graph tree-shakeable |
|
|
213
213
|
| extension | browser extension service worker; endpoints bind a random port, never localhost |
|
|
214
214
|
| cli | planner CLI: `node --experimental-strip-types index.ts` reading `vm.config.toml` |
|
|
215
215
|
| android | container/wasm module surface through the JVM bridge; arm64 native runner images |
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/docs/branchaudit.md
CHANGED
|
File without changes
|
package/docs/browser.md
CHANGED
|
File without changes
|
package/docs/capabilityreport.md
CHANGED
|
File without changes
|
package/docs/comparativeaudit.md
CHANGED
|
File without changes
|
package/docs/consolidation.md
CHANGED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Container platform decision for 2.1.0
|
|
2
|
+
|
|
3
|
+
## Scope
|
|
4
|
+
|
|
5
|
+
Version 2.1.0 expands the Saddle node-engine OCI image (the `saddle-runtime`
|
|
6
|
+
target of the one container file, published by the `publish ghcr` workflow)
|
|
7
|
+
from a three-platform Linux manifest index to the four-architecture family
|
|
8
|
+
surface: `linux/amd64`, `linux/arm64`, `linux/ppc64le`, and `linux/s390x`.
|
|
9
|
+
The selection unifies the container surfaces of the grand merge: the saddle
|
|
10
|
+
lineage shipped amd64/arm64/ppc64le (the 1.8.17 decision, see
|
|
11
|
+
[containerplatforms-1.8.17.md](containerplatforms-1.8.17.md)) and the e2ugh
|
|
12
|
+
lineage published all four architectures for the virtual-hardware engine
|
|
13
|
+
(`publish ghcr vhe`). One product, one registry, one architecture surface:
|
|
14
|
+
the s390x leg joins the node engine from the e2ugh side of the family.
|
|
15
|
+
|
|
16
|
+
## Platform matrix
|
|
17
|
+
|
|
18
|
+
`linux/amd64` stays because it is the primary GitHub runner architecture and
|
|
19
|
+
the local smoke-test platform. `linux/arm64`, `linux/ppc64le` and
|
|
20
|
+
`linux/s390x` stay (or join) because the vhe engine of the same repository
|
|
21
|
+
already builds, publishes and verifies those architectures under QEMU
|
|
22
|
+
emulation - the publish ghcr vhe lane proves the build path - and the
|
|
23
|
+
node-engine build is a strict subset of that work (npm tooling, no mesa,
|
|
24
|
+
no qemu compilation).[1] [2]
|
|
25
|
+
|
|
26
|
+
`linux/arm/v7` and `linux/386` remain deferred because no inspected Node 26
|
|
27
|
+
base manifest exposes them. `windows/amd64` remains deferred (see the 1.8.17
|
|
28
|
+
decision): the Dockerfile uses Debian Linux stages and a Windows container
|
|
29
|
+
needs a Windows-specific base image, runner and smoke tests. `unknown/*`
|
|
30
|
+
remains rejected: OCI `unknown` descriptors are not a runnable target and
|
|
31
|
+
must not be advertised as a Saddle container platform.
|
|
32
|
+
|
|
33
|
+
## Base image prerequisite (the s390x gap of the bookworm-slim variant)
|
|
34
|
+
|
|
35
|
+
The current node-engine stages build `FROM node:26.8.1-bookworm-slim`. The
|
|
36
|
+
manifest index of that tag (inspected through the Docker Hub registry API on
|
|
37
|
+
2026-09-06, the same view `docker manifest inspect` reads) exposes exactly
|
|
38
|
+
`linux/amd64`, `linux/arm64` and `linux/ppc64le` - the bookworm-slim variant
|
|
39
|
+
does not publish an s390x entry. The Node 26 tags that DO carry s390x are
|
|
40
|
+
the default-distro (Debian trixie) variants: `node:26.8.1` and
|
|
41
|
+
`node:26.8.1-slim`. The four-arch publication therefore requires the
|
|
42
|
+
`saddle-build` and `saddle-runtime` FROM lines of the one container file to
|
|
43
|
+
move to a trixie-based variant (for example `node:26.8.1-slim`, keeping the
|
|
44
|
+
slim profile) before the first 2.1.0 publish run; until that base swap
|
|
45
|
+
lands, the buildx s390x leg cannot resolve its base manifest and the publish
|
|
46
|
+
job fails at the platform-resolution step. That Dockerfile change belongs to
|
|
47
|
+
the same 2.1.0 wave as this decision document (it is recorded here because
|
|
48
|
+
the container file is not part of this workflow-restoration change set).
|
|
49
|
+
|
|
50
|
+
## Workflow design
|
|
51
|
+
|
|
52
|
+
The `publish ghcr` workflow registers QEMU (arm64, ppc64le, s390x emulation)
|
|
53
|
+
before Buildx, scans a loadable `linux/amd64` image (GitHub-hosted runners
|
|
54
|
+
cannot load a multi-platform image into the default local image store, so
|
|
55
|
+
the scan build stays single-platform while the publication is pushed
|
|
56
|
+
directly to GHCR), pushes all four Linux variants through one Buildx
|
|
57
|
+
invocation, and verifies the registry manifest index for the four
|
|
58
|
+
architectures before the amd64 label and CLI smoke test.[2] The publish lane
|
|
59
|
+
also carries the restored idempotency gates: the resolve job (tag ==
|
|
60
|
+
package.json == published release, plus the e2ugh "already shipped"
|
|
61
|
+
tag/HEAD guard) so a duplicate release firing no-ops instead of repushing.
|
|
62
|
+
|
|
63
|
+
## Publication claims
|
|
64
|
+
|
|
65
|
+
The version 2.1.0 release notes and registry documentation may claim only
|
|
66
|
+
the four verified Linux variants after the pushed image index is inspected.
|
|
67
|
+
They must not claim Windows support, an `unknown` platform, or a universal
|
|
68
|
+
OS image.
|
|
69
|
+
|
|
70
|
+
## References
|
|
71
|
+
|
|
72
|
+
[1]: https://docs.docker.com/build/building/multi-platform/ "Docker multi-platform builds"
|
|
73
|
+
[2]: https://docs.docker.com/build/ci/github-actions/multi-platform/ "Multi-platform image with GitHub Actions"
|