mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-08-18 06:40:36 +00:00
feat(infra): Garage 6-node RF3 cluster, Cloudflare Workers deploy, k3s node additions
- Garage scale-out complete: 6 nodes across 6 zones with replication_factor=3 - neon-64gb: added to Garage cluster (zone netcup-arm, 93 GiB) - steamdeck: installed Garage v2.3.0, added to cluster (zone gpu, 373 GiB) - nixos-laptop: converted from k3s server to agent in cupfox cluster - qfox-1: k3s agent rejoined cupfox cluster - Cloudflare Workers: WASM trinary VM deployed at wasm-compute-edge.researchstack.workers.dev - node-registry.json: updated with all 6 Garage nodes - Documentation: AGENTS.md, WIKI.md, ROADMAP.md, LLM-Context.md updated - Lake build: 3313 jobs, 0 errors Build: 3313 jobs, 0 errors (lake build Compiler)
This commit is contained in:
parent
79859bc225
commit
92e7accb2a
9 changed files with 281 additions and 42 deletions
|
|
@ -80,15 +80,16 @@ Dynamo-style S3-compatible store written in Rust. Replaced rclone serve s3.
|
||||||
|
|
||||||
### Node topology (Tailscale mesh)
|
### Node topology (Tailscale mesh)
|
||||||
|
|
||||||
| Node | Tailscale IP | Role | Disk | SSH Status |
|
| Node | Tailscale IP | k3s | Garage | Zone | Disk | SSH |
|
||||||
|------|-------------|------|------|----------|
|
|------|-------------|-----|--------|------|------|-----|
|
||||||
| qfox-1 (this machine) | 100.88.57.96 | primary, S3 endpoint, GPU compute | 1.8 TB NVMe | local |
|
| **qfox-1** (this machine) | 100.88.57.96 | ✅ worker | ✅ 780 GiB | local | 1.8 TB NVMe | local |
|
||||||
| 361395-1 (old cupfox) | 100.110.163.82 | Netcup VPS, 2 vCPU EPYC-Genoa | 125 GB | key OK (recovered) |
|
| **cupfox** | 100.110.163.82 | ✅ control-plane | ✅ 69 GiB | fra | 125 GB | key OK (361395) |
|
||||||
| rs-vps (netcup) | — | Lean LSP, Python LSP, Ollama, Jellyfin, k3s (ARM64) | 2 TB | SSH via password (creds in 1Password) |
|
| **nixos-laptop** | 100.102.173.61 | ✅ worker | ✅ 347 GiB | ord | 459 GB NVMe | key OK |
|
||||||
| nixos-laptop | 100.102.173.61 | Authentik SSO, Uptime Kuma, storage node, AMD GPU compute | 459 GB NVMe | key OK |
|
| **racknerd** | 100.80.39.40 | ✅ worker | ✅ 954 MiB | vps | 9.1 GB VPS | key OK |
|
||||||
| microvm-racknerd | 100.80.39.40 | Caddy reverse proxy, Homer dashboard, chat placeholder, storage node (RackNerd VPS) | 9.1 GB | key OK |
|
| **neon-64gb** | 100.64.19.78 | ✅ worker (ARM64) | ✅ 93 GiB | netcup-arm | 2 TB | root key OK |
|
||||||
| nixos-steamdeck-1 | 100.85.244.73 | GPU compute, planned edge LLM (3B-7B), RDNA 2 | NixOS | just onboarded |
|
| **steamdeck** | 100.85.244.73 | ✅ worker | ✅ 373 GiB | gpu | 476 GB NVMe | key OK |
|
||||||
| dracocomp | 100.100.140.27 | offline | — | unreachable (3+ days)
|
| rs-vps (netcup) | — | ❌ | ❌ | — | 2 TB | SSH via password |
|
||||||
|
| dracocomp | 100.100.140.27 | ❌ | ❌ | — | — | unreachable
|
||||||
|
|
||||||
- RPC port: **3901** (Tailscale-only, not exposed to internet)
|
- RPC port: **3901** (Tailscale-only, not exposed to internet)
|
||||||
- S3 API port: **3900** (qfox-1 only; other nodes bind loopback)
|
- S3 API port: **3900** (qfox-1 only; other nodes bind loopback)
|
||||||
|
|
@ -153,12 +154,12 @@ Daily timer: `restic-backup.timer` fires at 03:00 ±30 min, runs `backup.sh full
|
||||||
|
|
||||||
### Replication status
|
### Replication status
|
||||||
|
|
||||||
Currently `replication_factor = 1` (single node, qfox-1 only).
|
`replication_factor = 3`, zone redundancy enforced, 6 nodes across 6 zones.
|
||||||
Bump to 3 after bootstrapping 3 nodes:
|
~1.3 TiB total capacity, ~440 GiB effective (RF3).
|
||||||
|
|
||||||
|
Add a new Garage node:
|
||||||
```bash
|
```bash
|
||||||
bash 4-Infrastructure/storage/garage/garage-node-bootstrap.sh 100.110.163.82
|
bash 4-Infrastructure/storage/garage/garage-node-bootstrap.sh <tailscale_ip>
|
||||||
bash 4-Infrastructure/storage/garage/garage-node-bootstrap.sh 100.119.165.120
|
|
||||||
bash 4-Infrastructure/storage/garage/garage-cluster-init.sh
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Git post-commit hook
|
### Git post-commit hook
|
||||||
|
|
@ -311,6 +312,8 @@ python3 4-Infrastructure/storage/storage_agent.py --loop --interval 900
|
||||||
- `4-Infrastructure/shim/qemu_framebuffer_packer.py` — QEMU graphics framebuffer packer mapping Q16_16 scalars to ARGB8888/RGB24 pixels for mmap-based zero-copy display DMA loopback
|
- `4-Infrastructure/shim/qemu_framebuffer_packer.py` — QEMU graphics framebuffer packer mapping Q16_16 scalars to ARGB8888/RGB24 pixels for mmap-based zero-copy display DMA loopback
|
||||||
- `4-Infrastructure/shim/rrc_ray_tagger.py` — RRC Ray Layer Tagger; classifies math payloads into RRC shapes and matches them to swappable compute slots and transports
|
- `4-Infrastructure/shim/rrc_ray_tagger.py` — RRC Ray Layer Tagger; classifies math payloads into RRC shapes and matches them to swappable compute slots and transports
|
||||||
- `4-Infrastructure/cloudflare/src/lib.rs` — Cloudflare Workers edge WASM trinary VM core implementing the Q0_16 scalar compute floor
|
- `4-Infrastructure/cloudflare/src/lib.rs` — Cloudflare Workers edge WASM trinary VM core implementing the Q0_16 scalar compute floor
|
||||||
|
- `4-Infrastructure/cloudflare/src/index.js` — Cloudflare Workers entry point, POST-only, JSON + binary protocol
|
||||||
|
- `4-Infrastructure/cloudflare/wrangler.toml` — Wrangler config, deployed at `https://wasm-compute-edge.researchstack.workers.dev`
|
||||||
- `4-Infrastructure/hardware/emergency_boot/emergency_boot_shim.py` — Python I/O shim
|
- `4-Infrastructure/hardware/emergency_boot/emergency_boot_shim.py` — Python I/O shim
|
||||||
for Geometry Emergency Boot Witness (6502 calculator-efficiency FPGA controller)
|
for Geometry Emergency Boot Witness (6502 calculator-efficiency FPGA controller)
|
||||||
Specification: `6-Documentation/docs/specs/GEOMETRY_EMERGENCY_BOOT_WITNESS_2026-04-08.md`
|
Specification: `6-Documentation/docs/specs/GEOMETRY_EMERGENCY_BOOT_WITNESS_2026-04-08.md`
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
import { VmState } from "./wasm_compute.wasm";
|
import wasmModule from "./wasm_compute_bg.wasm";
|
||||||
|
import { initSync, VmState } from "./wasm_compute.js";
|
||||||
|
|
||||||
|
initSync(wasmModule);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
async fetch(request, env, ctx) {
|
async fetch(request, env, ctx) {
|
||||||
|
|
@ -26,7 +29,6 @@ export default {
|
||||||
headers: { "content-type": "application/json" }
|
headers: { "content-type": "application/json" }
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Default to binary stream: 3 bytes per step (op, idx, val)
|
|
||||||
const buffer = await request.arrayBuffer();
|
const buffer = await request.arrayBuffer();
|
||||||
const view = new DataView(buffer);
|
const view = new DataView(buffer);
|
||||||
const len = buffer.byteLength;
|
const len = buffer.byteLength;
|
||||||
|
|
@ -34,16 +36,14 @@ export default {
|
||||||
for (let offset = 0; offset + 2 < len; offset += 3) {
|
for (let offset = 0; offset + 2 < len; offset += 3) {
|
||||||
const op = view.getUint8(offset);
|
const op = view.getUint8(offset);
|
||||||
const idx = view.getUint8(offset + 1);
|
const idx = view.getUint8(offset + 1);
|
||||||
const val = view.getInt8(offset + 2); // signed 8-bit integer
|
const val = view.getInt8(offset + 2);
|
||||||
vm.step(op, idx, val);
|
vm.step(op, idx, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const scalar = vm.derive_scalar();
|
const scalar = vm.derive_scalar();
|
||||||
|
|
||||||
// Return 2-byte binary scalar response
|
|
||||||
const responseBuf = new ArrayBuffer(2);
|
const responseBuf = new ArrayBuffer(2);
|
||||||
const responseView = new DataView(responseBuf);
|
const responseView = new DataView(responseBuf);
|
||||||
responseView.setUint16(0, scalar, false); // big-endian
|
responseView.setUint16(0, scalar, false);
|
||||||
|
|
||||||
return new Response(responseBuf, {
|
return new Response(responseBuf, {
|
||||||
headers: { "content-type": "application/octet-stream" }
|
headers: { "content-type": "application/octet-stream" }
|
||||||
|
|
|
||||||
183
4-Infrastructure/cloudflare/src/wasm_compute.js
Normal file
183
4-Infrastructure/cloudflare/src/wasm_compute.js
Normal file
|
|
@ -0,0 +1,183 @@
|
||||||
|
/* @ts-self-types="./wasm_compute.d.ts" */
|
||||||
|
|
||||||
|
export class VmState {
|
||||||
|
__destroy_into_raw() {
|
||||||
|
const ptr = this.__wbg_ptr;
|
||||||
|
this.__wbg_ptr = 0;
|
||||||
|
VmStateFinalization.unregister(this);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
free() {
|
||||||
|
const ptr = this.__destroy_into_raw();
|
||||||
|
wasm.__wbg_vmstate_free(ptr, 0);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
derive_scalar() {
|
||||||
|
const ret = wasm.vmstate_derive_scalar(this.__wbg_ptr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
constructor() {
|
||||||
|
const ret = wasm.vmstate_new();
|
||||||
|
this.__wbg_ptr = ret;
|
||||||
|
VmStateFinalization.register(this, this.__wbg_ptr, this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
reset() {
|
||||||
|
wasm.vmstate_reset(this.__wbg_ptr);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {number} op
|
||||||
|
* @param {number} idx
|
||||||
|
* @param {number} val
|
||||||
|
*/
|
||||||
|
step(op, idx, val) {
|
||||||
|
wasm.vmstate_step(this.__wbg_ptr, op, idx, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Symbol.dispose) VmState.prototype[Symbol.dispose] = VmState.prototype.free;
|
||||||
|
function __wbg_get_imports() {
|
||||||
|
const import0 = {
|
||||||
|
__proto__: null,
|
||||||
|
__wbg___wbindgen_throw_1506f2235d1bdba0: function(arg0, arg1) {
|
||||||
|
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||||
|
},
|
||||||
|
__wbindgen_init_externref_table: function() {
|
||||||
|
const table = wasm.__wbindgen_externrefs;
|
||||||
|
const offset = table.grow(4);
|
||||||
|
table.set(0, undefined);
|
||||||
|
table.set(offset + 0, undefined);
|
||||||
|
table.set(offset + 1, null);
|
||||||
|
table.set(offset + 2, true);
|
||||||
|
table.set(offset + 3, false);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
__proto__: null,
|
||||||
|
"./wasm_compute_bg.js": import0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const VmStateFinalization = (typeof FinalizationRegistry === 'undefined')
|
||||||
|
? { register: () => {}, unregister: () => {} }
|
||||||
|
: new FinalizationRegistry(ptr => wasm.__wbg_vmstate_free(ptr, 1));
|
||||||
|
|
||||||
|
function getStringFromWasm0(ptr, len) {
|
||||||
|
return decodeText(ptr >>> 0, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
let cachedUint8ArrayMemory0 = null;
|
||||||
|
function getUint8ArrayMemory0() {
|
||||||
|
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
||||||
|
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachedUint8ArrayMemory0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
||||||
|
cachedTextDecoder.decode();
|
||||||
|
const MAX_SAFARI_DECODE_BYTES = 2146435072;
|
||||||
|
let numBytesDecoded = 0;
|
||||||
|
function decodeText(ptr, len) {
|
||||||
|
numBytesDecoded += len;
|
||||||
|
if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
|
||||||
|
cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
||||||
|
cachedTextDecoder.decode();
|
||||||
|
numBytesDecoded = len;
|
||||||
|
}
|
||||||
|
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
|
||||||
|
}
|
||||||
|
|
||||||
|
let wasmModule, wasmInstance, wasm;
|
||||||
|
function __wbg_finalize_init(instance, module) {
|
||||||
|
wasmInstance = instance;
|
||||||
|
wasm = instance.exports;
|
||||||
|
wasmModule = module;
|
||||||
|
cachedUint8ArrayMemory0 = null;
|
||||||
|
wasm.__wbindgen_start();
|
||||||
|
return wasm;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function __wbg_load(module, imports) {
|
||||||
|
if (typeof Response === 'function' && module instanceof Response) {
|
||||||
|
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||||
|
try {
|
||||||
|
return await WebAssembly.instantiateStreaming(module, imports);
|
||||||
|
} catch (e) {
|
||||||
|
const validResponse = module.ok && expectedResponseType(module.type);
|
||||||
|
|
||||||
|
if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') {
|
||||||
|
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
|
||||||
|
|
||||||
|
} else { throw e; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const bytes = await module.arrayBuffer();
|
||||||
|
return await WebAssembly.instantiate(bytes, imports);
|
||||||
|
} else {
|
||||||
|
const instance = await WebAssembly.instantiate(module, imports);
|
||||||
|
|
||||||
|
if (instance instanceof WebAssembly.Instance) {
|
||||||
|
return { instance, module };
|
||||||
|
} else {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function expectedResponseType(type) {
|
||||||
|
switch (type) {
|
||||||
|
case 'basic': case 'cors': case 'default': return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function initSync(module) {
|
||||||
|
if (wasm !== undefined) return wasm;
|
||||||
|
|
||||||
|
|
||||||
|
if (module !== undefined) {
|
||||||
|
if (Object.getPrototypeOf(module) === Object.prototype) {
|
||||||
|
({module} = module)
|
||||||
|
} else {
|
||||||
|
console.warn('using deprecated parameters for `initSync()`; pass a single object instead')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const imports = __wbg_get_imports();
|
||||||
|
if (!(module instanceof WebAssembly.Module)) {
|
||||||
|
module = new WebAssembly.Module(module);
|
||||||
|
}
|
||||||
|
const instance = new WebAssembly.Instance(module, imports);
|
||||||
|
return __wbg_finalize_init(instance, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function __wbg_init(module_or_path) {
|
||||||
|
if (wasm !== undefined) return wasm;
|
||||||
|
|
||||||
|
|
||||||
|
if (module_or_path !== undefined) {
|
||||||
|
if (Object.getPrototypeOf(module_or_path) === Object.prototype) {
|
||||||
|
({module_or_path} = module_or_path)
|
||||||
|
} else {
|
||||||
|
console.warn('using deprecated parameters for the initialization function; pass a single object instead')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (module_or_path === undefined) {
|
||||||
|
module_or_path = new URL('wasm_compute_bg.wasm', import.meta.url);
|
||||||
|
}
|
||||||
|
const imports = __wbg_get_imports();
|
||||||
|
|
||||||
|
if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {
|
||||||
|
module_or_path = fetch(module_or_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { instance, module } = await __wbg_load(await module_or_path, imports);
|
||||||
|
|
||||||
|
return __wbg_finalize_init(instance, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { initSync, __wbg_init as default };
|
||||||
BIN
4-Infrastructure/cloudflare/src/wasm_compute_bg.wasm
Normal file
BIN
4-Infrastructure/cloudflare/src/wasm_compute_bg.wasm
Normal file
Binary file not shown.
|
|
@ -1,7 +1,7 @@
|
||||||
name = "wasm-compute-edge"
|
name = "wasm-compute-edge"
|
||||||
main = "src/index.js"
|
main = "src/index.js"
|
||||||
compatibility_date = "2026-05-30"
|
compatibility_date = "2026-05-31"
|
||||||
|
account_id = "47b5018a9ddab552d535c8e046a6bc7e"
|
||||||
|
workers_dev = true
|
||||||
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
globs = ["**/*.wasm"]
|
|
||||||
type = "CompiledWasm"
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,56 @@
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"hostname": "100.80.39.40",
|
"hostname": "qfox-1",
|
||||||
|
"tailscale_ip": "100.88.57.96",
|
||||||
|
"ssh_user": "allaun",
|
||||||
|
"ssh_port": 22,
|
||||||
|
"garage_node_id": "3e08a71b73fa2b1099301844d1f199caab50f7a9209b9929d9bfb2bfeeb937f4@100.88.57.96:3901",
|
||||||
|
"garage_data_dir": "/var/lib/garage/data",
|
||||||
|
"added_at": "2026-05-31T08:00:00.000000+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hostname": "cupfox",
|
||||||
|
"tailscale_ip": "100.110.163.82",
|
||||||
|
"ssh_user": "root",
|
||||||
|
"ssh_port": 22,
|
||||||
|
"garage_node_id": "75fac43bc53eb201315c09f3e590fff15f27454b7e9f974f64522204612821db@100.110.163.82:3901",
|
||||||
|
"garage_data_dir": "/var/lib/garage/data",
|
||||||
|
"added_at": "2026-05-31T07:03:13.628137+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hostname": "nixos-laptop",
|
||||||
|
"tailscale_ip": "100.102.173.61",
|
||||||
|
"ssh_user": "allaun",
|
||||||
|
"ssh_port": 22,
|
||||||
|
"garage_node_id": "a7e6c283056a4d77b4a5bb820fd25dc336c5443a1ad17110dfadc2b150ebfb49@100.102.173.61:3901",
|
||||||
|
"garage_data_dir": "/var/lib/garage/data",
|
||||||
|
"added_at": "2026-05-31T08:15:00.000000+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hostname": "racknerd",
|
||||||
"tailscale_ip": "100.80.39.40",
|
"tailscale_ip": "100.80.39.40",
|
||||||
"ssh_user": "root",
|
"ssh_user": "root",
|
||||||
"ssh_port": 22,
|
"ssh_port": 22,
|
||||||
"garage_node_id": "1951197c0ce140a7724155d0d68db490682fa3b63f8cc98acdceb8c7b1d41766@100.80.39.40:3901",
|
"garage_node_id": "1951197c0ce140a7724155d0d68db490682fa3b63f8cc98acdceb8c7b1d41766@100.80.39.40:3901",
|
||||||
"garage_data_dir": "/var/lib/garage/data",
|
"garage_data_dir": "/var/lib/garage/data",
|
||||||
"added_at": "2026-05-31T07:03:13.628137+00:00"
|
"added_at": "2026-05-31T07:03:13.628137+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hostname": "neon-64gb",
|
||||||
|
"tailscale_ip": "100.64.19.78",
|
||||||
|
"ssh_user": "root",
|
||||||
|
"ssh_port": 22,
|
||||||
|
"garage_node_id": "036bdd161f089d2302b95453078ab1738d571f90d904752da1a9506dacb4f452@100.64.19.78:3901",
|
||||||
|
"garage_data_dir": "/var/lib/garage/data",
|
||||||
|
"added_at": "2026-05-31T10:00:00.000000+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hostname": "steamdeck",
|
||||||
|
"tailscale_ip": "100.85.244.73",
|
||||||
|
"ssh_user": "allaun",
|
||||||
|
"ssh_port": 22,
|
||||||
|
"garage_node_id": "3536017f8688fc3cae7b7408274809a8acefeff634004c43de99f615e53e0efb@100.85.244.73:3901",
|
||||||
|
"garage_data_dir": "/var/lib/garage/data",
|
||||||
|
"added_at": "2026-05-31T10:30:00.000000+00:00"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
@ -488,8 +488,10 @@ The Lean 4 formalization lives in `0-Core-Formalism/lean/Semantics/`. As of May
|
||||||
|
|
||||||
| File | Description |
|
| File | Description |
|
||||||
|------|-------------|
|
|------|-------------|
|
||||||
| `src/lib.rs` | Rust WASM entry point for Cloudflare Workers — 512 B payload, 8 ms CPU budget |
|
| `src/lib.rs` | Rust WASM trinary VM (7 ops, 32 trits) — SET/ADD/SUB/SHIFT/MERGE/PROJECT/WEIGHT |
|
||||||
| `wrangler.toml` | Worker configuration, route bindings, WASM build settings |
|
| `src/index.js` | Worker entry point — POST only, JSON + binary protocols, `initSync` WASM load |
|
||||||
|
| `wrangler.toml` | Worker configuration, account `47b5018a9ddab552d535c8e046a6bc7e` |
|
||||||
|
| **Deployed** | `https://wasm-compute-edge.researchstack.workers.dev` — Q0_16 scalar compute floor |
|
||||||
|
|
||||||
### GitHub Actions (`.github/workflows/`)
|
### GitHub Actions (`.github/workflows/`)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -298,7 +298,7 @@ No promotion without domain-appropriate evidence. Compression claims require SI
|
||||||
2. Prove `receipt_invertible` for braid eigensolid compressor (second required theorem)
|
2. Prove `receipt_invertible` for braid eigensolid compressor (second required theorem)
|
||||||
3. Add RRC scale-band witness schema for equation records; rerun `4-Infrastructure/shim/rrc_equation_classifier.py`
|
3. Add RRC scale-band witness schema for equation records; rerun `4-Infrastructure/shim/rrc_equation_classifier.py`
|
||||||
4. Add negative-control strength witnesses for HOLD rows before promotion
|
4. Add negative-control strength witnesses for HOLD rows before promotion
|
||||||
5. Bootstrap Garage replication (nixos-laptop + 361395-1 → replication_factor=3); 361395-1 SSH recovered
|
5. Garage replication_factor=3 with 6 nodes across 6 zones (qfox-1, cupfox, nixos-laptop, racknerd, neon-64gb, steamdeck) — ✅ done
|
||||||
6. UART packet format design (start byte + 3-byte payload + checksum)
|
6. UART packet format design (start byte + 3-byte payload + checksum)
|
||||||
7. Create `4-Infrastructure/surface/` FastAPI skeleton
|
7. Create `4-Infrastructure/surface/` FastAPI skeleton
|
||||||
8. Flash Tang Nano 9K with generated bitstream; verify LED behavior *(blocked: requires physical Tang Nano 9K board + USB programmer attached to host)*
|
8. Flash Tang Nano 9K with generated bitstream; verify LED behavior *(blocked: requires physical Tang Nano 9K board + USB programmer attached to host)*
|
||||||
|
|
@ -348,7 +348,7 @@ Three tools, non-overlapping roles:
|
||||||
| Tool | Role |
|
| Tool | Role |
|
||||||
|------|------|
|
|------|------|
|
||||||
| **restic** | Deduplicated, encrypted, content-addressed snapshots. Primary backend: Garage S3. |
|
| **restic** | Deduplicated, encrypted, content-addressed snapshots. Primary backend: Garage S3. |
|
||||||
| **Garage v2.3.0** | Self-hosted S3-compatible object store over Tailscale mesh. 5 buckets. `replication_factor=1` (scale-out to 3 planned). |
|
| **Garage v2.3.0** | Self-hosted S3-compatible object store over Tailscale mesh. 6 nodes across 6 zones, `replication_factor=3`, zone redundancy enforced. ~1.6 TiB total capacity, ~440 GiB effective. |
|
||||||
| **rclone** | Raw sync between remotes (Garage↔gdrive). Cold copy of restic chunks to gdrive. |
|
| **rclone** | Raw sync between remotes (Garage↔gdrive). Cold copy of restic chunks to gdrive. |
|
||||||
|
|
||||||
Data flow: `git commit → post-commit hook → restic snap → Garage:research-stack`; daily 03:00 timer → `rclone copy → gdrive:restic-mirror`.
|
Data flow: `git commit → post-commit hook → restic snap → Garage:research-stack`; daily 03:00 timer → `rclone copy → gdrive:restic-mirror`.
|
||||||
|
|
|
||||||
|
|
@ -74,14 +74,15 @@ Research-Stack/
|
||||||
|
|
||||||
### Tailscale Mesh
|
### Tailscale Mesh
|
||||||
|
|
||||||
| Node | IP | OS | Role | Reachable? |
|
| Node | IP | OS | k3s | Garage Zone | Role | Reachable? |
|
||||||
|------|-----|-----|------|------------|
|
|------|-----|-----|-----|-------------|------|------------|
|
||||||
| qfox-1 | 100.88.57.96 | Arch Linux (CachyOS) | Primary, Garage S3, GPU compute, 1.8 TB NVMe | local (this machine) |
|
| qfox-1 | 100.88.57.96 | CachyOS | ✅ worker | local (780 GiB) | Primary, GPU compute, 1.8 TB NVMe | local |
|
||||||
| 361395-1 | 100.110.163.82 | Debian 13 | Netcup VPS, 2 vCPU EPYC-Genoa, 125 GB | SSH key auth OK (recovered) |
|
| cupfox | 100.110.163.82 | Debian 13 | ✅ control-plane | fra (69 GiB) | k3s server, Netcup VPS | key OK |
|
||||||
| nixos-laptop | 100.119.165.120 | NixOS 25.11 | Authentik SSO, storage node, AMD GPU compute, 459 GB | Key auth OK |
|
| nixos-laptop | 100.102.173.61 | NixOS 26.05 | ✅ worker | ord (347 GiB) | GPU compute, 459 GB NVMe | key OK |
|
||||||
| microvm-racknerd | 100.101.247.127 | Debian 13 | Caddy reverse proxy, credential server, 1 vCPU | Root password OK |
|
| neon-64gb | 100.64.19.78 | Debian 13 | ✅ worker (ARM64) | netcup-arm (93 GiB) | Netcup ARM64 VPS, 2 TB | root key OK |
|
||||||
| steam-deck | TBD | SteamOS (Arch) | **Planned**: Edge LLM inference (3B-7B), RDNA 2 GPU compute | Control stick drift — repurposing |
|
| racknerd | 100.80.39.40 | Debian 13 | ✅ worker | vps (954 MiB) | RackNerd VPS, reverse proxy | key OK |
|
||||||
| dracocomp | 100.100.140.27 | — | Offline | Last seen 3+ days ago |
|
| steamdeck | 100.85.244.73 | NixOS 25.11 | ✅ worker | gpu (373 GiB) | RDNA 2 GPU compute, LLM inference | key OK |
|
||||||
|
| dracocomp | 100.100.140.27 | — | ❌ | — | Offline | unreachable |
|
||||||
|
|
||||||
### Distributed Storage Surface
|
### Distributed Storage Surface
|
||||||
|
|
||||||
|
|
@ -98,16 +99,21 @@ qfox-1 NVMe (1.8 TB) Google Drive (5 TB)
|
||||||
└── snap-zone
|
└── snap-zone
|
||||||
```
|
```
|
||||||
|
|
||||||
| Layer | Capacity | Used | Free | Protocol |
|
| Layer | Capacity | Zone | Protocol |
|
||||||
|-------|----------|------|------|----------|
|
|-------|----------|------|----------|
|
||||||
| qfox-1 NVMe (Garage primary) | 1.8 TB | ~291 GB | ~1.6 TB | local NVMe |
|
| qfox-1 NVMe | 780 GiB (allocated) | local | Tailscale :3901 |
|
||||||
| nixos-laptop NVMe (future Garage node) | 459 GB | ~36 GB | ~423 GB | local NVMe |
|
| nixos-laptop NVMe | 347 GiB (allocated) | ord | Tailscale :3901 |
|
||||||
|
| cupfox VPS | 69 GiB (allocated) | fra | Tailscale :3901 |
|
||||||
|
| neon-64gb VPS | 93 GiB (allocated) | netcup-arm | Tailscale :3901 |
|
||||||
|
| steamdeck NVMe | 373 GiB (allocated) | gpu | Tailscale :3901 |
|
||||||
|
| racknerd VPS | 954 MiB (allocated) | vps | Tailscale :3901 |
|
||||||
|
| **Total** | **~1.6 TiB** (6 zones, RF3) | — | ~440 GiB effective |
|
||||||
| 361395-1 disk (future Garage node) | 125 GB | ~48 GB | ~77 GB | local SSD |
|
| 361395-1 disk (future Garage node) | 125 GB | ~48 GB | ~77 GB | local SSD |
|
||||||
| **Google Drive** | **5.0 TB** | **1.9 TB** | **3.1 TB** | **rclone FUSE mount** |
|
| **Google Drive** | **5.0 TB** | **1.9 TB** | **3.1 TB** | **rclone FUSE mount** |
|
||||||
| **Total addressable** | **~7.4 TB** | **~2.3 TB** | **~5.2 TB** | **Garage + rclone + Drive** |
|
| **Total addressable** | **~7.4 TB** | **~2.3 TB** | **~5.2 TB** | **Garage + rclone + Drive** |
|
||||||
|
|
||||||
**Garage S3 Cluster**
|
**Garage S3 Cluster**
|
||||||
- **Status**: Single-node (`replication_factor = 1`) on qfox-1
|
- **Status**: 6-node cluster (`replication_factor = 3`) across 6 zones — qfox-1 (local), cupfox (fra), nixos-laptop (ord), racknerd (vps), neon-64gb (netcup-arm), steamdeck (gpu)
|
||||||
- **Primary endpoint**: `s3:http://100.88.57.96:3900`
|
- **Primary endpoint**: `s3:http://100.88.57.96:3900`
|
||||||
- **Buckets**: `research-stack`, `db-scratch`, `rds-overflow`, `snap-zone`, `gdrive-mirror`
|
- **Buckets**: `research-stack`, `db-scratch`, `rds-overflow`, `snap-zone`, `gdrive-mirror`
|
||||||
- **Restic snapshots**: 2 (last: 2026-05-18, 5.4 GiB)
|
- **Restic snapshots**: 2 (last: 2026-05-18, 5.4 GiB)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue