37 KiB
Embedded Node Surface Specification
Version: 0.1
Status: Draft for reusable deployment
Target nodes: Racknerd, Netcup, Architect, Hutter, local edge nodes
Protocol reference: docs/specs/OMNITOKEN_GCL_REDESIGN.md
GCL revision reference: docs/specs/GCL_TOPOLOGY_REVISION_SPEC.md
Principle: A node is a small observer chart, not a full general-purpose stack.
The kernel contract is a GCL nanokernel; Linux is only one possible carrier.
Purpose
This spec defines a reusable embedded surface for low-resource nodes. The node keeps only the local machinery required to join the atlas, expose a minimal API, recover itself, and mount external state. Bulk data, datasets, archives, and large working sets are provided by Google Drive topological storage through an ENE-managed mount.
The surface does not require Linux as its conceptual kernel. The portable kernel contract is the GCL nanokernel: the smallest executable transition unit that admits work, routes state, checks recovery transitions, emits receipts, and exposes the node as an observer chart. Linux, LFS, NixOS, unikernels, bare-metal firmware, or a VM monitor may host that contract, but they are substrate choices rather than the mathematical center.
The intended result is a small, repeatable node shape:
GCL nanokernel + read-only carrier + tiny writable state + compressed API + recovery
This avoids deploying the full Research Stack onto nodes that are better used as
lightweight coordinate charts. RackNerd is the first GCL-Edge: a constrained
edge node whose primary job is to host the GCL nanokernel, expose recovery and
health, and carry topology phases without running the full research stack.
Operationally, RackNerd is an appliance server: it has a narrow managed surface,
bounded local state, explicit update channels, and no expectation that operators
log in to run arbitrary workloads.
Builder, Warden, and Judge behavior are not deployed as separate software layers. They are topology phases carried by the general node surface:
- Builder is the topology's constructive/forward phase.
- Warden is the topology's inhibitory/verification phase.
- Judge is the topology's adjudication/settlement phase.
Historical builder, warden, and judge state, receipts, and validation routines are topology artifacts. A node may expose these phases through topology capabilities, but there is no standalone Builder, Warden, or Judge runtime boundary in the embedded profile.
Design Constraints
Every conforming node MUST:
- Preserve SSH or recovery console access during upgrades.
- Boot without Google Drive being available.
- Treat the GDrive mount as optional external state, never as the root of trust.
- Expose a plain recovery health endpoint even if the compressed API fails.
- Keep writable local state small, explicit, and backed up.
- Admit work through RGFlow/compression policy before local execution.
- Support atomic image or service rollback.
Every conforming node SHOULD:
- Use a compressed read-only root or read-only service bundle.
- Use tmpfs for transient logs and scratch.
- Store persistent node identity under a single state directory.
- Keep large data in mounted topological storage.
- Prefer push/pull artifacts over building locally.
Appliance Server Model
An appliance server is a node operated as a sealed function rather than as a
general-purpose host. The RackNerd GCL-Edge appliance exposes only the surface
needed to join the atlas, emit receipts, answer health/status probes, carry
topology phases, and recover itself.
Appliance invariants:
- The primary runtime is
rs-surface-api.service. - Builder, Warden, and Judge are topology phases inside the surface.
- Legacy full-stack services remain masked unless a rescue procedure explicitly says otherwise.
- Local mutation is restricted to
/var/lib/rs-surface, bounded spools, rollback slots, and explicit topology artifacts. - Software changes enter through in-place nanokernel updates, A/B release updates, or provider rescue pivots.
- The node is not a build worker, dataset host, database server, or ad hoc shell box.
The appliance may still use Debian, systemd, SSH, and Tailscale as carrier facilities. Those facilities serve the appliance contract; they do not redefine the node as a general VM.
Surface Layers
+------------------------------------------------------------+
| Atlas clients / controller |
+------------------------------------------------------------+
| Compressed WebSocket API + plain /health fallback |
+------------------------------------------------------------+
| Admission layer: RGFlow, compression policy, attestation |
+------------------------------------------------------------+
| MNN routing: adaptive path formation (local/atlas/reject) |
+------------------------------------------------------------+
| Topology phases: builder, warden, judge |
+------------------------------------------------------------+
| Local actions: route, attest, compress, status, recovery |
+------------------------------------------------------------+
| State: /var/lib/rs-surface + optional GDrive mount |
+------------------------------------------------------------+
| Carrier: Linux, LFS, Nix, unikernel, firmware, VM monitor |
+------------------------------------------------------------+
The MNN (Morphic Neural Network) routing layer sits between admission and local actions. It uses:
- Goal-aware routing (health, attest, compress, route, recover)
- State-constrained decisions (memory, CPU, recovery mode, trust score)
- Carrier-agnostic adaptation (works with any shell)
- Cost-aware optimization (energy, time, bandwidth)
- Historical learning (adaptive morphic topology)
See docs/specs/MORPHIC_NEURAL_NETWORK_ROUTING_SPEC.md for the complete MNN specification.
The surface is intentionally carrier-agnostic. Debian can host it first; later nodes may boot directly into an embedded image or a GCL-native runtime. The important object is the topological substrate: the set of admitted primitives that the GCL nanokernel can expose safely on a given carrier.
Topological Substrate Primitive Exposure
A node does not need KVM to become a topological device. KVM, QEMU, Linux processes, unikernels, firmware loops, and serial controllers are all carriers. The GCL nanokernel is responsible for exposing the primitive vocabulary that matters to the atlas.
Every appliance SHOULD expose a primitive descriptor:
GET /primitives
WS op 10: primitives
The descriptor names:
- The substrate class.
- The carrier used to host the substrate.
- Whether primitives are exposed through the kernel surface.
- Compute slots and memory reserve.
- Primitive names, such as
attest,compress,rgflow,route,plan_route,vector_filter,delta_batch,merkle_mmr,content_chunk,wiki,fractal_fold,meta_autotype, andreceipt. - Optional accelerators, such as AVX-512, BF16, VNNI, VAES, VPCLMULQDQ, or SHA-NI.
The primitive descriptor is descriptive, not a permission grant. Admission, topology phases, and receipt checks still decide whether a requested transition is lawful.
Nanokernel Route Planning Primitive
The nanokernel route planner is a bounded pre-admission selector:
WS op 11: plan_route
It applies:
payload
-> metaprobe payload signature
-> MS3C/S3C shell codon
-> sequence/GCL motif/informaton surface selection
-> RGFlow persistence check
-> compression route tuple
The returned tuple has:
surface
motif
witness
compressor
This tuple is not execution authority. It is a route-prior hint consumed by GCL admission. The required gate remains:
OBSERVE -> BIND -> ROUTE -> SIGMA_CHECK -> POLICY_CHECK -> DAG_CHECK -> VERIFY -> RECEIPT
If FAMM marks the shell region as saturated failure, the planner SHOULD downrank or refuse similar route teeth before local execution.
The typed Lean vocabulary for this contract lives in:
0-Core-Formalism/lean/Semantics/Semantics/GCLTopologyRevision.lean
That module fixes the distinction between route hints and authority: a
RouteHint cannot directly authorize execution, even if it comes from MS3C,
metaprobe, RGFlow, Sparkle, or a node primitive.
ENE Wiki Primitive
The ENE wiki primitive is a MediaWiki-like knowledge surface without a full MediaWiki runtime:
WS op 12: wiki
It supports compact JSON requests:
{"op":"put","title":"GCL","text":"See [[MS3C]] [[Category:Topology]]"}
{"op":"get","title":"GCL"}
{"op":"search","query":"topology"}
{"op":"backlinks","title":"MS3C"}
{"op":"recent","limit":20}
The implementation is infra/ene_wiki_layer.py. It stores revision history,
links, categories, backlinks, and recent changes in SQLite. Every write emits:
- an ENE
BaseArchiveRecord-style object usingsource_type=json_catalog; - a Unified JSON-L event using
src=eneandop=upsert; - a deterministic receipt hash;
- a schema-compatible
packagesupsert.
This keeps the wiki layer inside the ENE substrate instead of creating a separate application authority.
ENE Fractal Fold Primitive
The fractal fold primitive is the canonical ENE surface for self-similar recursive storage and retrieval:
WS op 13: fractal_fold
It supports compact JSON requests:
{"op":"put","name":"payload","text":"...","chunk_size":4096,"branching_factor":4}
{"op":"put_graphml","name":"research_graph","data_b64":"..."}
{"op":"navigate","root_hash":"...","leaf_index":31}
{"op":"proof","root_hash":"...","leaf_index":31}
{"op":"verify","root_hash":"..."}
{"op":"graph_entity","root_hash":"...","graph_node_id":"n31"}
{"op":"graph_neighbors","root_hash":"...","graph_node_id":"n31"}
The implementation is infra/ene_fractal_fold.py. It stores a recursive hash
tree in SQLite. Leaves use Gray-code folded addresses; navigation projects
folded addresses onto a golden-spiral chart and descends by manifold-distance
pruning. With fixed branching factor, entity retrieval is O(log n) in the
number of leaves. Damage is detectable because leaves and parents are checked
through fractal parent/child hash consistency.
GraphML is treated as a concept surface. Each GraphML node becomes one fractal
leaf carrying graph_node_id, name, family, domain, folded address,
golden-spiral coordinate, and outgoing neighbors. This lets ENE retrieve graph
concepts by the same fractal path used for raw payload chunks.
ENE Meta-Autotype Primitive
The meta-autotype primitive handles unknown or fragmented ingestion surfaces:
WS op 14: meta_autotype
It supports:
{"name":"unknown_payload","text":"..."}
{"name":"unknown_payload","data_b64":"..."}
The implementation is infra/ene_meta_autotype.py. It deterministically emits
contingent fields with inferred type, confidence, extraction rule, bind class,
and receipt. These fields are not authority; they are provisional topology
until a defined ingestion surface binds them through the normal GCL gate.
Bind Policy
The profile's api.bind field is normative:
api.bind |
Runtime bind host |
|---|---|
localhost |
127.0.0.1 |
tailscale |
api.tailscale_ip or top-level tailscale_ip |
public |
0.0.0.0 |
RS_SURFACE_HOST may override this during smoke tests, but production units
SHOULD omit it so the profile controls exposure. If api.bind is tailscale
and no Tailscale IP is present, the surface MUST fail closed rather than bind
publicly.
KVM Carrier Addressing
Most deployment nodes are themselves virtual machines, so KVM must be treated as an optional nested carrier rather than assumed bare metal. A node with no KVM can still be a first-class topological substrate by exposing primitives directly through the GCL nanokernel.
KVM addressing has three separate layers:
host virtual pointer -> KVM memslot -> guest physical address -> guest CS:RIP
The guest physical address is not host physical memory. It is an address in a
userspace-owned memslot registered with KVM_SET_USER_MEMORY_REGION.
Minimal KVM surfaces MUST record:
- Whether
/dev/kvmexists and is openable. - Whether
KVM_CREATE_VM,KVM_CREATE_VCPU, andKVM_RUNsucceed. - The memslot number.
- The guest physical base.
- The guest entry address.
- The I/O or MMIO pulse channel used for recovery output.
Carrier classification:
| Class | Meaning | Required behavior |
|---|---|---|
kvm_native |
Hardware virtualization is directly available | Run KVM carrier |
kvm_nested |
KVM works inside a VM | Run KVM carrier with slower-exit budget |
kvm_unavailable |
/dev/kvm missing or denied |
Fall back to QEMU TCG or hosted process |
kvm_restricted |
VM starts but required exits fail | Refuse or quarantine carrier |
KVM MUST NOT become the root of trust. It is only a carrier for admitted GCL state. If KVM is unavailable, the node should expose the recovery surface and topological primitives through another carrier.
GCL Nanokernel Contract
GCL is the nanokernel of a node: the smallest trusted control surface that can perform a bounded transition and produce a receipt. It is not required to be the hardware kernel in the Unix sense. It is the invariant-preserving layer that decides what the carrier is allowed to do.
Local repo usage treats a nanokernel as:
- A tiny executable unit.
- Local state.
- Message passing.
- Bounded transition.
- Receipt.
For morphic topology, the nanokernel also assigns candidate niches for morphic scalars. Assignment is a measurement hypothesis, not final permission; the topology phases and AngrySphinx-style checks still decide whether collapse is admissible.
GCL MUST provide:
- Node identity and local observer-frame metadata.
- Admission control for requested operations.
- RGFlow/compression policy hooks.
- Route selection or local execution refusal.
- Attestation of state transitions.
- Recovery transition checks.
- A plain health signal independent of the compressed API.
GCL SHOULD be small enough to port across carriers. A Linux-hosted daemon, an initramfs recovery binary, a unikernel service, a microcontroller firmware, or a tiny VM monitor shim can all be valid GCL nanokernel carriers if they satisfy the same contract.
The carrier MAY provide:
- Process isolation.
- Filesystems and mounts.
- TCP/IP, WireGuard, Tailscale, or serial transport.
- Timers and watchdogs.
- Hardware drivers.
The carrier MUST NOT be the root of trust for atlas decisions. Those decisions belong to GCL.
Layer 0 Handoff Target
The long-term target is for the GCL nanokernel to become Layer 0: the first meaningful runtime after firmware/provider boot. In that mode, Linux is no longer the node's operating environment. Linux is only a bootstrap loader, hardware discovery tool, artifact fetcher, and emergency recovery substrate.
The intended destructive handoff is:
provider firmware / VPS boot
-> minimal Linux loader
-> verify signed Layer 0 image + last-good receipt
-> kexec handoff
-> GCL nanokernel Layer 0
-> topology primitives, receipts, recovery pulse
After handoff, the current Linux userspace may be intentionally discarded. That is the point: legacy services, model routers, ad hoc shell state, package sprawl, and ordinary daemon assumptions should not survive into Layer 0.
Kexec Role
kexec is the preferred bridge when the provider requires a normal Linux boot
but the node wants to replace Linux without a full firmware reboot. The loader
kernel prepares memory, validates the Layer 0 artifact, then transfers control
to the GCL image.
The Layer 0 image may initially be a tiny Linux/initramfs appliance, unikernel, or purpose-built kernel. What matters is not the implementation label; what matters is that the GCL nanokernel owns the primitive boundary and emits receipts before admitting work.
Layer 0 Gates
A node MUST NOT perform a destructive handoff until all gates pass:
- Provider rescue console or reinstall path is confirmed.
- A rollback boot entry or previous working image exists.
- The Layer 0 image is signed or hash-pinned.
- The loader can emit a pre-handoff receipt.
- The Layer 0 image can emit a console, serial, or provider-visible health pulse without Tailscale.
- The Layer 0 image can answer
/healthor the Omnitoken recovery equivalent. - Node identity and topology artifacts are preserved or intentionally sealed.
- The operator has an out-of-band recovery window.
Until those gates exist, destructive_handoff_allowed MUST remain false in
node profiles. Hosted rs-surface-api.service remains the safe Phase 0
appliance.
Profiles SHOULD make the handoff mechanically checkable by declaring:
{
"layer0_image": {
"path": "/boot/gcl/layer0-netcup.img",
"sha256": "TBD",
"signature": "/boot/gcl/layer0-netcup.img.sig",
"public_key": "/etc/rs-surface/layer0.pub",
"cmdline": "console=ttyS0 gcl.node=netcup-router gcl.mode=layer0"
},
"rollback": {
"boot_entry": "debian-loader-last-good",
"previous_image": "/boot/gcl/layer0-netcup.previous.img",
"provider_rescue": "netcup-rescue-console"
}
}
sha256: "TBD" is valid only while destructive_handoff_allowed is false.
Before enabling destructive handoff, the image digest and signature path MUST
refer to real artifacts.
Preservation Set
Even when the Linux userspace is wiped, these concepts survive the handoff:
- Node identity.
- Last-good receipt.
- Recovery pulse.
- Topology artifacts such as
judge.tardy, MMR roots, and node profile. - Primitive descriptor.
- Provider recovery instructions.
Everything else is disposable unless the profile explicitly preserves it.
JupiterBox and Omnitoken Carrier
For constrained nodes, the preferred GCL carrier envelope is JupiterBox and the preferred wire/codon layer is Omnitoken.
JupiterBox provides the box boundary:
- A bounded execution envelope.
- A small routing identity.
- A multiplexing slot for swarm traffic.
- A place to attach recovery and last-good metadata.
- A carrier abstraction that can run over Linux, serial, Tailscale, I2P, or a future non-Linux substrate.
Omnitoken provides the packet language:
- Finite operation names instead of open strings.
- Small typed fields for value, timestamp, tags, and checksum.
- Fragmentation/reassembly for larger payloads.
- A bridge into existing swarm transport and MIMO routing.
- A natural path to codon compression on tiny RAM targets.
The normal embedded surface can expose WebSocket for compatibility, but the inner frame SHOULD be Omnitoken-compatible:
carrier transport
-> JupiterBox envelope
-> Omnitoken/GCL frame
-> operation payload
On large carriers, the stack may be:
WebSocket or Tailscale TCP -> JupiterBox -> Omnitoken -> GCL op
On tiny carriers, the stack may collapse to:
serial frame -> Omnitoken codon -> GCL op
Or, on an IBM-II-class software Ethernet surface:
Ethernet-looking shell -> 2-byte Omnitoken scalar/LUT selector -> GCL op
The Ethernet controller does not need to implement IP. It only validates the
local shell boundary, extracts the invariant (domain, scalar) pair, and lets
GCL decide admission.
This is how the same node surface can scale from Racknerd down toward an 8 KB RAM target. The carrier changes; the GCL operation vocabulary does not.
8 KB RAM Shape
At the smallest target, JupiterBox is not a container in the Linux sense. It is a fixed memory envelope:
RX frame 512 B
TX frame 512 B
GCL registers 512 B
route table 1 KB
compression 1 KB
recovery log 1 KB
stack 512 B
free margin 3 KB
The tiny target MUST NOT require JSON, HTTP, WebSocket, TLS, malloc, a filesystem, or dynamic loading. It only needs enough Omnitoken/GCL vocabulary to say:
health
status
attest
rgflow-admit
compress
route
snapshot
recover
Filesystem Contract
Required Local Paths
| Path | Mode | Purpose |
|---|---|---|
/opt/rs-surface |
read-only preferred | Surface daemon, static assets, API schema |
/etc/rs-surface/node.json |
read-only or managed | Node identity and role profile |
/var/lib/rs-surface |
persistent writable | Identity, tokens, last-good marker, tiny state |
/var/log/rs-surface |
tmpfs or capped persistent | Ring logs and boot reports |
/run/rs-surface |
tmpfs | Sockets, pid files, ephemeral cache |
/mnt/topological-storage |
optional mount | GDrive/rclone topological storage |
Required Persistent State
/var/lib/rs-surface/
node-id
authorized_keys
api-token.hash
ed25519-node.key
last-good.json
boot-count
state.sqlite optional, small
recovery/
last-failure.log
rollback-target
Persistent state MUST stay small enough to archive and restore quickly.
External State
Google Drive topological storage SHOULD be mounted at:
/mnt/topological-storage
Recommended remote layout:
gdrive:topological_storage/
nodes/<node-id>/
inbox/
outbox/
artifacts/
snapshots/
logs/
shared/
datasets/
models/
manifests/
dictionaries/
Nodes MUST tolerate the mount being absent. On mount failure, the node remains in normal mode with degraded storage, or enters recovery mode only if local state is also invalid.
Runtime Modes
Normal Mode
Normal mode runs the compressed API and the minimal local action set.
Required services:
rs-surface-api
rs-surface-heartbeat
rs-storage-mount optional/degraded if unavailable
Allowed operations:
health
status
metrics
attest
compress
rgflow
route
mount-status
snapshot
enter-recovery
Recovery Mode
Recovery mode is deliberately boring. It MUST NOT depend on custom compression, RGFlow, GDrive, or the normal API.
Required recovery services:
dropbear or sshd
plain HTTP /health
rollback command
mount inspection
log dump
authorized_keys restore
Allowed operations:
GET /health
GET /boot-report
POST /rollback
POST /mark-good
POST /reboot-normal
Recovery mode MUST be able to run with only local disk and network.
API Contract
Plain HTTP Fallback
Every node MUST expose:
GET /health
Minimal response:
{
"ok": true,
"node": "racknerd-510bd9c",
"mode": "normal",
"surface_version": "0.1",
"storage": "mounted|degraded|absent",
"last_good": true
}
Compressed WebSocket Endpoint
Normal mode SHOULD expose:
GET /ws
The WebSocket transport carries custom binary frames. The custom layer is inside WebSocket for compatibility with browsers, proxies, and standard debugging tools.
Frame format:
byte 0 version currently 1
byte 1 flags bitfield
byte 2 codec 0 none, 1 zstd, 2 lz4, 3 hutter, 4 rgflow-zstd
byte 3 op finite operation id
u32le 4..7 request_id
u32le 8..11 payload_len
u32le 12..15 crc32_payload
bytes 16..N payload
bytes N..M optional ed25519 signature when flags.sig = 1
Operation IDs:
| ID | Operation | Notes |
|---|---|---|
| 0 | health |
same meaning as /health |
| 1 | status |
node status and local budgets |
| 2 | metrics |
capped telemetry |
| 3 | attest |
hash/sign payload |
| 4 | compress |
run compression policy |
| 5 | rgflow |
admission/classification |
| 6 | route |
forward or queue task |
| 7 | mount_status |
report external storage state |
| 8 | snapshot |
write tiny local snapshot |
| 9 | enter_recovery |
authenticated only |
Payloads are canonical JSON unless the operation explicitly declares a binary body. Binary bodies MUST include a JSON envelope with content hash, codec, and size.
Compression Policy
Compression is not automatic for every frame. The node chooses the cheapest lawful path:
| Payload | Codec |
|---|---|
| Tiny control frames | none |
| Repeated telemetry | zstd with shared dictionary |
| Hot local API frames | lz4 or none |
| Attestation bundles | zstd |
| Semantic or dataset payloads | RGFlow admission, then zstd |
| Unknown/high entropy payloads | reject, route, or store externally |
No node should spend more CPU compressing a payload than it saves in network, memory, or storage cost. On tiny nodes, the first optimization is often to avoid local work and route it elsewhere.
GDrive Mount Contract
The mount provider SHOULD be rclone, managed by ENE credentials.
Recommended mount command shape:
rclone mount Gdrive:topological_storage /mnt/topological-storage \
--read-only \
--vfs-cache-mode minimal \
--dir-cache-time 5m \
--poll-interval 1m \
--buffer-size 4M \
--vfs-read-chunk-size 4M \
--vfs-read-chunk-size-limit 32M
Tiny nodes SHOULD default to read-only mounts. Writes go through an explicit outbox path or a controller-mediated upload:
/mnt/topological-storage/nodes/<node-id>/outbox/
If write support is required, use a bounded local spool:
/var/lib/rs-surface/spool/
The spool MUST have a byte cap and MUST degrade gracefully when full.
Node Profile
Each node has a small JSON profile:
{
"surface_version": "0.1",
"node_id": "racknerd-510bd9c",
"role": "gcl-edge",
"mode_default": "normal",
"operational_model": "appliance",
"memory_budget_mb": 715,
"disk_budget_gb": 9,
"local_state_budget_mb": 128,
"api": {
"plain_health_port": 8080,
"websocket_port": 8080,
"bind": "tailscale",
"tailscale_ip": "100.103.54.58"
},
"storage": {
"provider": "gdrive",
"mount_point": "/mnt/topological-storage",
"remote": "Gdrive:topological_storage",
"required_for_boot": false,
"write_mode": "outbox",
"spool_budget_mb": 128
},
"capabilities": [
"health",
"status",
"metrics",
"attest",
"compress",
"rgflow",
"route",
"nanokernel",
"topology",
"builder",
"warden",
"judge",
"mount_status",
"snapshot",
"recovery"
],
"disabled": [
"full_git_checkout",
"local_training",
"local_build",
"large_database",
"legacy_warden_service",
"legacy_tardy_service",
"legacy_substrate_index_service",
"legacy_compression_gateway_service"
]
}
Profiles are deployable across nodes by changing only identity, budgets, and capabilities.
Upgrade and Rollback
The surface supports both in-place nanokernel updates and A/B-style deployment
even when hosted on Debian. RackNerd as GCL-Edge SHOULD use the smallest safe
upgrade path:
- In-place nanokernel upgrade: routine changes to the GCL control surface, profile, topology phase wiring, or small service-unit corrections.
- In-place carrier kernel upgrade: routine Linux kernel package updates on the Debian carrier when SSH/Tailscale and provider rescue fallback are ready.
- A/B release upgrade: larger release bundles, carrier changes, storage layout changes, or updates where the previous release must remain bootable.
- Rescue pivot: host repair, root filesystem work, SSH/Tailscale recovery, or anything that might make the node unreachable.
In-Place Nanokernel Upgrade
The in-place path keeps the running OS, SSH access, Tailscale identity, topology state, and legacy-service masks intact. It updates only the GCL nanokernel carrier files:
/opt/rs-surface/current/server.py
/etc/rs-surface/node.json
/var/lib/rs-surface/last-good.json
Operator entrypoint:
sudo infra/embedded_surface/gcl_edge_in_place_upgrade.sh upgrade \
/tmp/rs-surface-upgrade/server.py \
/tmp/rs-surface-upgrade/node.json
In-place upgrade steps:
- Stage the new
server.pyandnode.jsonoutside the live paths. - Compile-check Python and parse-check JSON.
- Start the candidate server on a temporary localhost port.
- Run
/healthagainst the candidate. - Copy current live files into
/var/lib/rs-surface/rollback/inplace-<timestamp>/. - Install the candidate files atomically into the live paths.
- Run
systemctl daemon-reloadand restartrs-surface-api.service. - Run post-start
/health. - Mark
last-good.jsononly after health succeeds.
If restart or health fails, restore the rollback copy, restart the service, and health-check again:
sudo infra/embedded_surface/gcl_edge_in_place_upgrade.sh rollback \
/var/lib/rs-surface/rollback/inplace-<timestamp>
An in-place update MUST NOT repartition disks, format filesystems, replace the bootloader, alter SSH authorization, reset Tailscale identity, or unmask the legacy Builder/Warden/Judge runtimes. Builder, Warden, and Judge are topology phases of the GCL nanokernel surface; they are not restored as standalone services.
In-Place Carrier Kernel Upgrade
When "kernel" means the Linux carrier kernel rather than the GCL nanokernel, RackNerd MAY still update in place, but only as a controlled reboot operation. This path is for normal Debian security/kernel package updates, not topology rewrites.
Carrier kernel in-place steps:
- Confirm provider rescue mode is available and SSH authorization is intact.
- Capture current boot state:
uname -a,lsblk -f,findmnt /,systemctl is-enabled rs-surface-api.service. - Confirm
/boothas enough free space and keep at least one previous kernel. - Apply the kernel package update without removing old kernels.
- Run
update-grubor the carrier's bootloader refresh command. - Reboot during a maintenance window.
- Verify SSH/Tailscale,
/health, andrs-surface-api.serviceafter boot. - Only then prune stale kernels.
If the node fails to return, use provider rescue mode and the saved boot state to restore the previous kernel entry or pivot back to the last-good surface. Carrier kernel updates MUST NOT unmask legacy services or convert Builder, Warden, or Judge back into standalone processes.
A/B Release Upgrade
For larger upgrades, use release directories:
/opt/rs-surface/releases/
surface-20260425T170000/
surface-20260425T180000/
current -> releases/surface-20260425T180000
previous -> releases/surface-20260425T170000
A/B upgrade steps:
- Upload new release to
/opt/rs-surface/releases/<version>. - Verify hashes and required files.
- Start new API on a temporary port.
- Run local health and atlas health probes.
- Move
currentsymlink. - Restart normal service.
- Mark last-good only after post-start health succeeds.
A/B rollback steps:
- Stop current service.
- Move
currenttoprevious. - Restart service.
- Enter recovery mode if rollback health fails.
Bootable embedded images use the same logic with surface-A.squashfs and
surface-B.squashfs.
Minimal Deployment Phases
Phase 0: Debian-Hosted Surface
Use the existing host OS as the recovery substrate.
Debian
systemd service: rs-surface-api
optional rclone mount
disabled legacy services
This is the safest first target for RackNerd and Netcup.
Phase 1: Compressed Service Bundle
Package /opt/rs-surface/current as a compressed artifact and deploy the same
bundle across nodes.
Phase 2: Embedded Root Surface
Move to read-only root or squashfs image, with local writable overlay for
/var/lib/rs-surface.
Phase 3: Boot Pivot
Only after recovery mode is proven, the node may boot directly into the embedded surface.
Phase 4: Layer 0 Kexec Handoff
Use Linux only as a loader. The loader verifies the signed Layer 0 GCL image,
emits a pre-handoff receipt, then uses kexec to transfer control to the
nanokernel-owned runtime. This phase may wipe the old userspace assumptions, so
it is gated by provider rescue, rollback image, and Layer 0 health pulse.
Racknerd Initial Profile
Observed on 2026-04-25:
host: racknerd-510bd9c
os: Debian GNU/Linux 13 trixie
cpu: 1 vCPU
memory: 715 MiB
swap: 767 MiB
root disk: 9.1 GiB, about 6.8 GiB free
tailscale: 100.103.54.58
RackNerd SHOULD run Phase 0 first as GCL-Edge:
disable: warden.service, tardy.service, substrate-index.service, compression-gateway.service
keep: SSH, Tailscale, recovery shell
add: rs-surface-api, rs-surface-heartbeat, optional rclone mount
avoid: local builds, full Research Stack checkout, large local databases
GCL-Edge means:
- GCL nanokernel carrier is the primary runtime.
- Builder/Warden/Judge exist only as topology phases.
- SSH, Tailscale, and recovery health are preserved above everything else.
- Full-stack services are not restored on the node.
Recommended Racknerd budgets:
api RSS budget: 32-64 MiB
mount/cache budget: 64 MiB
local state budget: 128 MiB
spool budget: 128 MiB
free disk floor: 1 GiB
Netcup Appliance Profile
Observed on 2026-04-27:
host: netcup-router
os: Debian GNU/Linux 13 trixie
kernel: 6.12.74+deb13+1-amd64
cpu: 2 vCPU AMD EPYC-Genoa, AVX-512 available
memory: 3.8 GiB
swap: none
root disk: 125 GiB, about 87 GiB free
tailscale: 100.85.1.50
public ip: 46.232.249.226
kvm: unavailable
Netcup SHOULD run as a mirror appliance rather than a general shell host:
keep: SSH, Tailscale, qemu-guest-agent, fail2ban, rs-surface-api
disable: tardy.service, openwebui-moe-router.service
stop: topology_node.py, swarm_surface.py
avoid: local builds, local training, unbounded web/router services, large databases
The Netcup appliance role is to keep the mirror/relay/storage chart available while freeing CPU and memory for admitted computation. The surface itself should remain tiny: health/status/metrics, topology phase receipts, RGFlow admission, and bounded outbox storage. Compute work is admitted through the surface and should run as explicit bounded jobs, not as always-on stack services.
Recommended Netcup budgets:
api RSS budget: 32-64 MiB
relay/spool budget: 512 MiB
local state budget: 512 MiB
admitted compute: up to 2 vCPU / 3 GiB when idle
free disk floor: 10 GiB
Netcup does not need /dev/kvm to be useful. Its best use is a hosted
topological substrate: the GCL nanokernel exposes primitive operations directly
on the Debian carrier, and AVX-512 accelerates admitted vector transitions.
EPYC Genoa Topological Device Notes
Netcup's EPYC Genoa carrier deserves special handling. It exposes a small but high-value vector topology:
cpu topology: 2 vCPU, 1 NUMA node
per-vCPU cache: 32 KiB L1d, 32 KiB L1i, 1 MiB L2, 32 MiB L3
vector width: AVX-512
useful extensions: AVX-512 VNNI, BF16, VBMI/VBMI2, VPOPCNTDQ, VAES, VPCLMULQDQ, SHA-NI
carrier limit: no /dev/kvm
Treat this as an epyc-genoa-vector-substrate: a topological device optimized
for wide deterministic transforms over compact batches. The appliance surface
should advertise Genoa as primitive substrate capacity without letting vector
jobs become resident daemons.
Kernel-exposed primitives:
attest
compress
rgflow
route
snapshot
vector_filter
delta_batch
merkle_mmr
content_chunk
receipt
Preferred admitted work:
- RGFlow vector filtering over batches.
- Delta-GCL compression and dictionary scoring.
- Structural attestation, Merkle/MMR receipt generation, and SHA-heavy scans.
- Content-defined chunking and mirror deduplication.
- BF16/VNNI experiments that fit under the appliance memory cap.
Scheduling rules:
- Keep
rs-surface-api.servicesmall and latency-stable. - Reserve at least 768 MiB for the carrier, SSH/Tailscale, cache, and rollback.
- Admit at most two CPU slots by default.
- Prefer short batch jobs with explicit receipts over long-lived compute daemons.
- Pin or shard jobs by vCPU when testing cache-sensitive kernels, because the observed L3 slices are not shared across the two exposed vCPUs.
- Do not require KVM for substrate work; route only VM-specific experiments
away from Netcup unless
/dev/kvmappears in a future provider configuration.
Acceptance Checks
A node conforms to this spec when:
/healthworks without GDrive mounted./wsacceptshealth,status, andmount_status.- The node can enter and leave recovery mode.
- GDrive mount failure does not break SSH or
/health. - Local persistent state remains below its budget.
- Legacy heavyweight services are absent or disabled on constrained nodes.
- An upgrade can be rolled back without manual file editing.
Layer 0 handoff adds stricter acceptance checks:
- The loader can boot normally and refuse an unsigned Layer 0 image.
- The loader can
kexecinto a non-production test image and return through provider rescue. - The Layer 0 image emits a recovery pulse without Linux userspace.
- The Layer 0 image exposes the primitive descriptor.
- The old Linux userspace can be discarded without losing node identity, last-good receipt, or topology artifacts.
Non-Goals
This surface does not provide:
- Full Git hosting.
- Local model training.
- Local large dataset storage.
- Local package builds on tiny nodes.
- Recovery that depends on custom compression or GDrive.
Those functions belong on larger atlas points or in topological storage.