bend: dual-port worker (8320 wire + 8321 http) — playground onramp
Each gpu-worker.lsp now listens on both wire-TCP (existing :8320) and HTTP/1.1+CORS (new :8321), sharing one handle-request dispatcher. Lets a tab on https://lumbda.com/playground/ POST to its own machine via http://localhost:8321/ — browsers permit localhost from HTTPS origins without TLS, so no proxy, no cert, no fox-owned infra required for the decentralized run-your-own-bend story. main() forks at startup: child runs http-run-loop on :8321, parent keeps existing run-loop on :8320. Adding a new op-head to handle-request exposes it over both transports automatically. Binary modes (BSHK/BCGB/BSCP/BSRT/BSB3) stay wire-only — they exist for native callers who already cache the binary locally; browser callers send S-expression recipes the worker dispatches the same way. Two latent defects fixed to make CPU-only and Python-tier hosts work: - vram-used-mib now file-exists? guards /usr/bin/nvidia-smi. Python tier's spawn-process-stdio raises FileNotFoundError on missing binary, not returning #f as the prior code expected, which crashed every worker on a CPU-only laptop. - fork-self return discriminated via (number? pid) not (eq? pid 0). Python tier's (eq? 0 #f) returns #t because == conflates int 0 with bool False; pre-existing run-loop has the same risk but C/asm tier (identity eq?) masks it for the production case. Phase 2 (server-side factory ops: compile uploaded .lsp recipes into .bin before bending — the foxhop champion-circuit workflow) deferred until authentication lands; today a worker on the public internet would let any caller occupy our GPU. Operational Caddy + DNS proposals in plans/bend-http-deploy.md cover the personal-remote-access endpoint chain (proxy.unturf.com edge → ai.foxhop.net Caddy → 3090-ai:8321) gated by trusted-IP allowlist — applied separately. Also codifies the playground "CSS Grid only, never flexbox" rule in CLAUDE.md: all www/ and wasm/ stylesheets are already grid-only; documenting the invariant so future edits don't drift. Tests: smoke-bend-http.sh — (ping)→(ok pong), unknown-op fallback, OPTIONS CORS preflight — all PASS. Wire path unchanged, verified round-trip via 8-digit-prefix framing.
This commit is contained in:
parent
e34fb1f7dc
commit
88e16c0ce2
8 changed files with 771 additions and 30 deletions
71
CLAUDE.md
71
CLAUDE.md
|
|
@ -35,6 +35,48 @@ Then ask fox about our mission.
|
|||
- Every implementation (Python, C, GNU asm) carries a dedicated architecture diagram
|
||||
- When explaining architecture, draft or reference a dot diagram first
|
||||
|
||||
## Web styling — CSS Grid only, never flexbox
|
||||
|
||||
Every page in `www/` and `wasm/` (homepage, whitepaper, playground,
|
||||
REPL, bend demo, 404) lays out multi-child regions with **CSS Grid**.
|
||||
Flexbox is **banned** as a layout primitive. One layout language across
|
||||
every page; no mode-switching in our head while we read or edit.
|
||||
|
||||
**Forbidden** anywhere in our CSS (source or generated):
|
||||
|
||||
- `display: flex`, `display: inline-flex`
|
||||
- `flex-direction`, `flex-wrap`, `flex-flow`
|
||||
- `flex-grow`, `flex-shrink`, `flex-basis`, shorthand `flex:`
|
||||
- `order` (use grid-area / source order instead)
|
||||
|
||||
**Allowed** (works for grid too — keep on grid containers only):
|
||||
|
||||
- `gap`, `row-gap`, `column-gap`
|
||||
- `align-items`, `justify-items`, `place-items`
|
||||
- `align-content`, `justify-content`, `place-content`
|
||||
- `align-self`, `justify-self`, `place-self`
|
||||
|
||||
**Patterns that look like they need flex but don't:**
|
||||
|
||||
- Horizontal toolbar → `display: grid; grid-auto-flow: column; gap: …`
|
||||
- Tab row → same as above; sticky positioning composes fine
|
||||
- Centered single child → `display: grid; place-items: center`
|
||||
- Sidebar + main → `display: grid; grid-template-columns: auto 1fr`
|
||||
- Wrapping chip cloud → `display: grid; grid-template-columns: repeat(auto-fit, minmax(N, max-content))`
|
||||
|
||||
Every source CSS file under `www/` and `wasm/{app,repl,dist,dist-repl}/`
|
||||
opens with the banner `/* No flexbox. Every multi-child layout uses
|
||||
CSS Grid. */`. Keep that banner intact when editing; add it when
|
||||
introducing a new stylesheet.
|
||||
|
||||
**Audit before commit** when CSS changed:
|
||||
|
||||
```bash
|
||||
grep -rn 'display:[[:space:]]*\(inline-\)\?flex\|flex-direction\|flex-wrap\|flex-grow\|flex-shrink\|flex-basis' www/ wasm/ && exit 1 || echo "grid-only OK"
|
||||
```
|
||||
|
||||
A hit fails our audit. Convert to grid before committing.
|
||||
|
||||
## Implementations
|
||||
|
||||
| Impl | Path | Build | Test | REPL |
|
||||
|
|
@ -48,12 +90,18 @@ Then ask fox about our mission.
|
|||
|
||||
`examples/cuda-fanout/` ships `(bend ...)` — runtime decides per call
|
||||
whether to evaluate locally or ship to a CUDA worker over our wire
|
||||
protocol. Two wire modes:
|
||||
protocol. **Each worker listens on two ports out of the box:**
|
||||
|
||||
- **S-expression mode** (text) — for small payloads. Slow above ~1k
|
||||
inputs because parser cost dominates.
|
||||
- **Binary mode** (magic `BSHK` + raw bytes) — for huge payloads. 150x
|
||||
faster than S-exp at 1M inputs; bends past host hashlib by 12x.
|
||||
- **8320 — wire-TCP** (length-prefixed S-expressions + binary magic
|
||||
`BSHK`/`BCGB`/`BSCP`/`BSRT`/`BSB3` blobs). The native path: used
|
||||
by `bend.lsp`, asm clients, and anything that can open a raw
|
||||
socket. Fastest. Binary mode is 150× faster than S-exp at 1M inputs.
|
||||
- **8321 — HTTP/1.1 + CORS** (POST body is the S-expression, response
|
||||
body is the result text). The browser path: lets a tab on
|
||||
`https://lumbda.com/playground/` POST to `http://localhost:8321/`
|
||||
via the browser's localhost-exception (no TLS required, no proxy
|
||||
needed). Same `handle-request` dispatcher fires on both ports, so
|
||||
every op-head ships once and lights up on both transports.
|
||||
|
||||
Workers run on any tier (`make gpu-worker LUMBDA={c,python,asm}`).
|
||||
C tier ~9x faster than Python on small calls; binary mode equalizes
|
||||
|
|
@ -67,6 +115,19 @@ to dispatch real-scale candidate scoring to a GPU worker. The Phase B
|
|||
1-8 secp256k1 arithmetic landed on the foxhop side this session, so
|
||||
the substrate has every piece it needs.
|
||||
|
||||
**Phase 2 (deferred until auth lands):** server-side factory ops
|
||||
that take an `.lsp` recipe via HTTP, compile a `.bin` on the worker
|
||||
filesystem, then bend it. Killer use case: upload a foxhop champion
|
||||
ECDSA circuit recipe from the playground/REPL and get the result
|
||||
back from a GPU cluster. Blocked on authentication — today a worker
|
||||
without auth would let any caller occupy our GPU.
|
||||
|
||||
**Run your own bend** (the decentralized story we encourage): any
|
||||
user runs `make gpu-worker LUMBDA=python` on their machine and
|
||||
pastes `http://localhost:8321/` into the playground bend field.
|
||||
CPU works (kernels fall back to host execution); GPU faster. No
|
||||
fox-owned infra required.
|
||||
|
||||
## Test Suites
|
||||
|
||||
- Python unit/integration: `tests.py` (571 tests)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue