Commit graph

50 commits

Author SHA1 Message Date
1b7de2c9c6
wasm/playground: cancel button, asm state-leak fix, restyle to match homepage
User-visible changes
  - Cancel button — terminates the running worker. Pyodide's slow mandelbrot
    no longer freezes the UI; click cancel and the elapsed counter freezes
    at "(cancelled @ NNNN ms)".
  - Live ms counter ticks per animation frame while a tier is busy, so the
    Pyodide tier's ~5-15 s wait is visible instead of looking hung.
  - Restyled to match lumbda.com: chunkfive wordmark, --green: #227842
    (light) / #5ec07a (dark), lumbda-logo-green.png, lowercase "lumbda"
    everywhere. Pulls fonts/chunkfive locally so the playground stays
    self-contained.

Architecture
  - All tier evaluations now run inside a Web Worker (wasm/app/worker.mjs)
    so the main thread stays responsive. Cancel = worker.terminate(); next
    eval respawns a fresh worker.
  - Loaders use new URL("./...", import.meta.url) so paths resolve against
    the loader file's own location — works identically in window and
    worker contexts, no baseURL argument needed.
  - C tier Emscripten build flipped to EXPORT_ES6=1; loader uses dynamic
    `import()` of the factory module. Integration test updated accordingly.
  - Python loader uses `import("pyodide.mjs")` (ES module) instead of
    document.createElement, which doesn't exist in workers.

Bug fixes
  - Asm tier state leak: running the same demo twice on a cached WASM
    instance produced corrupted output (every other cell on row 2+ rendered
    as " " instead of the expected shade char). Root cause: top-level eval
    passed `global_env` as the env, so closures captured stale globals;
    fixed by passing NIL — env_lookup falls back to the CURRENT global_env
    via its existing two-pass walk. Multi-run regression added to the
    functional test suite.
  - fib-ack demo: (ack 3 4) was too heavy for Pyodide (minutes). Cut to
    (ack 3 3) + (fib 20) max so every tier finishes in seconds.

Test discipline
  - Root `make test-all` now includes `wasm-test`. Adding a language
    feature without exercising it on all six implementations is no longer
    possible by accident.
  - Functional suite: 11 assertions (was 10) — adds asm multi-run stability.
  - Integration + unit: still 20 + 8.
2026-06-14 12:13:20 -04:00
9c25d46e13
home page: link to the WebAssembly playground
Adds a "Try it in your browser" section at the bottom of www/index.html
pointing to /playground/, plus a footer link for redundancy. Lands the
three-tier WASM SPA committed in 346b873 as a discoverable surface on
lumbda.com.
2026-06-14 11:49:40 -04:00
346b873247
wasm: three-tier Lumbda to WebAssembly + browser playground
Adds a parallel build of all three Lumbda implementations to WASM, a
single-page playground at www/playground/, and a verified test suite.

Tiers
  - Python: Pyodide (CPython-in-WASM) hosting lumbda.py
  - C:      Emscripten build of c/ (tree-walker + bytecode VM; jit.c
            stubbed, gc.c uses its existing no-Boehm fallback)
  - Asm:    hand-written asm/lumbda.wat — parallel impl to asm/lumbda.s.
            Reader, eval (lambda/define/if/cond/let/and/or/quote/set!),
            recursion across mutated top-level env, bump allocator with
            memory.grow, 24 primitives. ~1200 lines of raw WAT.

SPA (wasm/app/, deployed to www/playground/)
  - CodeMirror 6 editor (Scheme highlighting) on left, output on right
  - Radios: 4 demos (Mandelbrot, Fib+Ack, Sieve, self-interp meta-eval)
            x 4 tiers (Python | C | Asm | All three)
  - All-three mode renders the three tier outputs side by side with
    per-tier elapsed timing

Tests (38 verified assertions)
  - 20 unit (Node): per-tier module loads, eval smoke
  - 8 integration (Node): each demo on c+asm WASM byte-matches the
                          canonical native Python run
  - 10 functional (Playwright headless Chromium): page mounts, every
                          demo runs on every tier, all-three renders

Makefile
  - Root targets: wasm-build, wasm-test, wasm-test-fn, wasm-serve,
                  wasm-deploy, wasm-clean
  - wasm/Makefile orchestrates the three tier builds; deploy copies
    dist/ into www/playground/

Asm tier notes
  - WAT linear symbol intern + linear env lookup is MOAD-0001 at scale;
    documented in the asm/lumbda.wat header and in the SPA footer. The
    demos hit ~30 globals so the linear walks are cheap enough.
  - Bump allocator never frees (matches asm/lumbda.s heap discipline);
    memory.grow expands by 1 MB chunks. Browser tab tears down at unload.

Toolchain (developer prerequisites)
  - Emscripten 6.0.0 via emsdk at ~/git/emsdk
  - wabt 1.0.36 at ~/git/wabt
  - Playwright for functional tests (symlinked from ~/git/agnt)
2026-06-14 11:40:34 -04:00
28a76631e2
bend.html: cross-link gpu-mesh at its real remarkbox URL 2026-06-07 09:46:18 -04:00
f80371af72
bend.html: real foxhop URL + inline coordinator pattern
Two link fixes:

- Drop dead /gpu-mesh link. That wiki RST exists in our private
  repo but our remarkbox host has not landed it under a public URL
  yet. Describe coordinator pattern inline so a reader sees the
  shape without following an unreachable href.

- /ecdsa link was also wrong. Real published page lives at our
  remarkbox UUID slug. Updated to actual URL.

Closed-source reminder for future drift: foxhop research code is
NOT open source. Never link to a script path under foxhop-book; if a
concept needs explaining, inline a description instead of pointing
at our private repo.
2026-06-07 09:42:46 -04:00
9c632c4bc8
bend.html: drop dead link to private coordinator script
Earlier text linked to 'foxhop ecdsa scripts/coordinator-mesh.py' as
if reachable at a public URL. That script lives only in the private
foxhop-book repo — no public path exists. Point readers at our
foxhop.net/gpu-mesh wiki page instead (lives in remarkbox, publicly
reachable, describes the cost-routed coordinator pattern at concept
level).
2026-06-07 09:39:36 -04:00
d0a248de28
bend.html: tier override examples stay on port 8320 (BEND)
Previous override example dropped to PORT=9001 — drifted off our BEND
mnemonic. Updated so LUMBDA=python & LUMBDA=asm overrides keep our
default port. Off-BEND port override stays available for a 2nd worker
on a single host, called out as such.
2026-06-07 09:28:33 -04:00
0213a729e9
bend.html: 3-node fleet table + cost-routed coordinator note
cammy.foxhop.net (Tesla P40, sm_61) joins the 8320 bend mesh as our
3rd node. Fleet table updated; multi-host paragraph cites our
foxhop ecdsa coordinator-mesh.py pattern (greedy bin-pack by cost,
per-host factor 1.00 / 0.51 / 1.84 for 3090 / 4090 / P40, one
ThreadPoolExecutor worker per node firing concurrently against our
wire protocol).
2026-06-06 21:15:19 -04:00
8d66bc01f1
bend port flip: 9091 → 8320 (BEND mnemonic)
Port mnemonic embedded verbatim across our source files:

  8 ~= B (implied infinity B flattened; bake a cake; baby & me)
  3 ~= E (backward)
  2 ~= N (pivoted 90 degrees)
  0 ~= D (flattened)

Files touched:
- examples/cuda-fanout/gpu-worker.lsp (*worker-port*)
- examples/cuda-fanout/bend.lsp (*bend-worker-port*)
- examples/cuda-fanout/mock-worker.py (PORT)
- examples/cuda-fanout/bench_tiers.py (asm tier fixed port)
- examples/cuda-fanout/smoke-bend.lsp + smoke-bend-asm.lsp
- examples/cuda-fanout/README.md
- www/bend.html (catalog + multi-host text)
- Makefile (PORT default + comment)

bend.html updates 3090-ai + ai (4090) fleet table to active 2-node
mesh on 8320 — qwen moves off ai, bend takes over.
2026-06-06 15:06:18 -04:00
9a547ee7df
bend.html: cuda-sim-ops-bin gains variant-sweep finding
Extends the cuda-sim-ops-bin row in our form catalog with a measured
property: kernel wall scales linearly with Σ Toffoli across circuit
variants.

foxhop ecdsa lever sweep at p=251 (n+1=9 secp256k1-toy) dispatched 6
lumbda-emitted ops.bin variants through demo_ops on a 3090. Wall vs
Toffoli per shot:

  Fermat-schoolbook  167984 Tof/shot  261.4 ms/batch
  refined-Solinas     24176 Tof/shot   26.6 ms/batch

9.83x GPU wall reduction matches 6.95x Toffoli ratio + parallel
Clifford drop. No scheduler surprise — pick any QECCOPS1 circuit,
predict GPU wall from a cheap CPU op-counter.

Links to https://www.foxhop.net/ecdsa for the upstream lever-attack
context.
2026-06-06 13:12:36 -04:00
7245f6b465
catalog + bend.html: cuda-sim-ops-bin row gains SHAKE-RNG anchor note
demo_ops in foxhop ecdsa repo now defaults --rng-mode shake (Fiat-Shamir
over op stream, ports eval_circuit::fiat_shamir_seed verbatim). Σ Toffoli
& avg Toffoli on stock ops.bin match upstream eval_circuit bit-for-bit:
15,999,651,264 / 1,773,011.000 across 141 batches (9024 shots) on a
3090. Our cuda-sim-ops-bin numbers now compare directly to upstream's
public Pareto scoreboard with no calibration constant.

Catalog row & bend.html row updated to document the shake/lfsr toggle
& the upstream-match guarantee. Throughput figure also refreshed to
1.27x at 141 batches (from prior 1.07x at 128 batches).
2026-06-06 09:58:54 -04:00
4ed8d0ca04
bend.html: new Worker health heartbeat section (between Fleet & Catalog)
Documents the (health) op + *worker-health* cache + VRAM-ranked
pick shipped in lumbda 58fd787. Three subsections:

  - Worker side: (health) op shape with measured numbers
  - Client side: cache TTL (5 s ok / 30 s down) + ranking logic
  - Failure handling: dispatch errors flip workers down;
    with-exception-handler wraps probes so a dead peer never
    aborts a multi-worker iteration

Integrated into bend.html's fleet narrative — backward-compat
note so older workers without (health) still register as
available with vram=0.

Bullets stay technical & terse; no commit hashes, no internal
implementation quirks (eq? 0 #f / Python exception propagation
stay in our commit log).
2026-06-06 09:36:53 -04:00
fc1563b4d6
bend Wave 2 — cuda-blake3-tree lands live on 3090
Agent ac6c3c7b built blake3-fanout.cu (clean-room BLAKE3 reference
adaptation, vendored under BLAKE3 team's CC0-1.0 / Apache-2.0
allowance) + test_blake3_known_answers.py harness + Makefile target
+ gpu-worker.lsp handler (handle-binary-blake3, BSB3/BSR3 magic).

Bench on 3090-ai (best-of-3, kernel-only):
  workload         kernel   throughput
  1k × 64 B          0.08 ms    ~7   GB/s
  100k × 64 B        1.87 ms    59.7 GB/s
  1M × 64 B          1.97 ms    32.5 GB/s
  1k × 1 MB         51.5  ms    20.4 GB/s

Byte-identity vs the BLAKE3 reference spec PASS at n in
{32, 1k, 10k, 100k, 1M}; covers both the single-chunk (≤1024 B)
& multi-chunk (≥1024 B) Merkle-tree paths.

Hardware policy compliance: per the 3090-only directive (commit
9e4e9b4), this row lists RTX 3090 only. The agent's 4090
measurements were dropped from the catalog & bend.html. ai
worker stays disabled.

Note the agent hit a socket error AFTER all files landed but
BEFORE it could git commit. This commit assembles its work from
the working tree, verifies the build still passes on 3090
(byte-identity + bench above), and ships.

Live forms now: 7 — shake, sim-ops-bin, sim-axis-flip,
cgbn (9 ops), secp256k1 (v3 windowed-G), radix-sort,
blake3-tree.
2026-06-05 22:07:25 -04:00
9e4e9b48f9
bend: 3090-only production default; 4090 reserved for qwen
Fox decision: don't routine-fan-out to ai.foxhop.net (4090) when
qwen LLM holds GPU residency. The radix-sort 4090 OOM caveat
surfaced today demonstrated the cost of casual co-residency —
secp daemon parked 24 GiB up front leaving 47 MiB free.

bend.lsp's *bend-workers* default already empty (single-host
fallback). Updated the docstring example to drop the ai.foxhop.net
entry; multi-host fan-out is OPT-IN per call via bend-set-workers!
or BEND_WORKERS env.

bend.html fleet section now reflects the policy:
  - 3090-ai.foxhop.net:9091  active production worker
  - ai.foxhop.net:9092       reserved for qwen; bend per workload

ai.foxhop.net worker process killed; 4090 VRAM returned to qwen
(1.6 GiB free post-kill vs 47 MiB while bend was running).

When we have a long-running parallel sweep that justifies the
4090's marginal throughput, the caller opts in explicitly. Don't
auto-route.
2026-06-05 21:55:41 -04:00
05fa922d42
bend form G — cuda-radix-sort lands live (CUB DeviceRadixSort u64)
Thin CUDA binary wrapping cub::DeviceRadixSort::SortKeys on a 64-bit
key stream. One op wired day-1 (0x01 sort-u64-asc); 0x02/0x03/0x04
slots reserved (desc, u32, key-value) for future builds.

Wire stays distinct from existing forms:
  request:  BSRT | u32 op_id | u32 n | u64[n]
  response: BSRR | u32 status | u32 n | u64[n] sorted asc

Validated on 3090-ai.foxhop.net byte-identical to Python sorted() at
n ∈ {32, 1k, 100k, 1M, 10M}. Bench at sustained throughput:

  n           kernel_ms   Gkeys/s
  100,000     0.142       0.706
  1,000,000   0.265       3.767
  10,000,000  1.817       5.504

~4x over the published Titan baseline (1.4 Gkeys/s) at saturation,
matching CUB's expected Ampere scaling.

gpu-worker.lsp learns handle-binary-sort + BSRT magic dispatch +
maybe-register-daemon! for cuda-radix-sort (overridable via
RADIX_SORT_WORKER env). Both 3090-ai (:9091) & ai (:9092) workers
restarted; both log `ready cuda-radix-sort <- ./radix-sort`.

4090 (ai.foxhop.net) standalone --binary run OOMs on cudaMalloc when
all four daemons are co-resident (secp256k1 daemon parks ~24 GiB on
startup, leaving 47 MiB free). Pre-existing capacity constraint of
the ai host, not a form-G defect; tracked in form-G-progress.md.

CATALOG.md & www/bend.html live-forms table updated with measured
3090 numbers; Wave 1 surveyed row for G marked as promoted.
2026-06-05 21:50:05 -04:00
948bdf0e41
bend.html: streamline — collapse Wave 1 detail into table, tighten prose
Wave 1's 7 detailed entries (3 paragraphs each) become one compact
4-column table matching Waves 2/3/4. Drops ~30 lines without
losing any reference URL or speedup number.

Protocol section: 2 paragraphs → 1.
Fleet section: 4 paragraphs + table → 2 paragraphs + same table.

Net change: 284 → ~244 lines while preserving every citation and
every measurement. Reads more like a reference doc.
2026-06-05 21:46:12 -04:00
5d1ad62f51
bend catalog Wave 4 — 20 surveyed forms across new domains
Covers lattice cryptography (Kyber, Falcon), lattice reduction
(G6K tensor sieve), privacy/MPC (Ironman OTE, Piranha, Fastplay),
ZK prover internals beyond MSM/NTT (zkSpeed sumcheck, Air-FRI),
sparse direct solvers (cuDSS Cholesky), real-time DSP (Kalman
batched 1386x, particle filter), computational biology beyond
pairwise (SCAMP matrix profile, cuDTW subsequence), erasure
coding (PErasure Reed-Solomon, Rabin fingerprint), computational
geometry (gDel3D, CudaHull), ODE/PDE (RK stiff ChemKin, FEM
assembly JIT), quantum chemistry (TeraChem DFT).

Headline picks for ECDSA mission:
  - cuda-g6k-tensor-sieve   1230x — lattice attacks on biased nonces
  - cuda-zkspeed-sumcheck    801x — sumcheck for ZK proof-of-equivalence
  - cuda-kalman-batched     1386x — batched estimation for candidate
                                    sweep + bluetooth/punters tracking

Headline picks for unsandbox/permacomputer mission:
  - cuda-kalman-batched     1386x — RSSI tracking, punters surface
  - cuda-ironman-ote         237x — cross-fleet PSI/MPC
  - cuda-perasure-crs        10x  + 10 GB/s — object-storage erasure
  - cuda-scamp-matrix-profile      — journald intrusion detection
  - cuda-rabin-fingerprint   16x  + 40 Gbps — CDN/proxy cache dedup

Headline picks for undefect mission:
  - cuda-cudss-cholesky    >100x — defect-graph eigenproblems
  - cuda-cufalcon-sign    29.5x — PQ disclosure signing
  - cuda-air-fri           22.8x — verifiable-defect-scan provenance

7 filter-outs noted (MAFFT, RAxML, AmgX CG, BVH Karras LBVH, LDPC
decode, mesh decimation, discrete Gaussian sampler) — kept honest
rather than padded.

Catalog total: 5 live + ~62 surveyed across 4 Waves.
2026-06-05 21:33:49 -04:00
a4613b685e
bend.html: rewrite back to focused doc shape
Page had accreted session debugging (Form D structural finding,
opt 1/opt 3 narrative, Day-4 v4 regression notes, robustness fix
narrative, first measured sweep paragraphs). Stripped all of it.

What stays:
  - what bend is
  - start a worker
  - call it
  - wire protocol (S-exp vs binary modes + measured table)
  - fleet (2-host cluster table + brief coexistence note + cluster
    aggregate numbers)
  - catalog: live forms (5) + Wave 1 (A-G detailed) + Wave 2 + 3
    (compact tables) + why-a-form-earns-its-slot criteria
  - source pointers

What goes (back to CATALOG.md / plan docs where they belong):
  - Form D structural finding paragraph
  - Form D opt 1 + opt 3 RESULTS narrative
  - Day-4 v4 regression detail in the secp row
  - First measured ECDSA-mission sweep paragraphs
  - Robustness gap fix paragraph

Page length: 371 → ~226 lines. Reads as a reference doc again
instead of a session log.
2026-06-05 21:26:20 -04:00
dca3c2d016
bend.html: qwen runs on llama.cpp, not vllm 2026-06-05 20:59:06 -04:00
01a36f3fcd
bend.html: drop false port claim — qwen runs on GPU, not on ports 9090/9091
Earlier commit incorrectly named ports 9090+9091 as qwen LLM serving.
Agent's actual finding (ai.foxhop.net second-worker deployment) was
uid-992 Erlang Cowboy services on those ports — unsandbox infra,
not qwen. Qwen runs on the GPU itself, not on those TCP ports.

The coexistence story (our bend kernels share a 4090 with qwen
because we burn SMs for ms-at-a-time then release) stays intact;
the false port attribution removed.
2026-06-05 20:58:05 -04:00
7b67b727e1
bend.html: fleet section — cross-GPU + cluster numbers + first sweep result
Adds a new "Fleet" section between the ecdsafail workload table &
the catalog. Documents what now runs in production:

  - 2-host LAN cluster: 3090-ai:9091 + ai.foxhop.net:9092 (4090, sm_89)
  - 4090 box shares the GPU with a qwen LLM (vllm) — our bend kernels
    fit alongside because secp256k1 / CGBN workloads burn SMs only for
    milliseconds at a time, then release
  - Cross-GPU parity at small N: 0.07-0.10 ms kernel on both 3090 &
    4090 for CGBN n=100k mod-mul; both starve between calls so the
    4090's FLOPS advantage doesn't show until kernels run long enough
    to amortize wire overhead
  - Cluster aggregate: 1.6× speedup at 200 × n=1k (cap is client-side
    serialization, not workers); async fan-out unlocks the remaining 2×
  - First measured sweep through full lumbda → emit-ops-bin → bend →
    demo_ops pipeline: refined Bernstein-Yang variant cuts Σ Toffoli
    by 36.5% at p=11, within 3 pts of the p=251 reference prediction
    (-40%). Small-fixture screen confirmed faithful predictor.
  - Robustness gap fixed (handle-binary-* delete-file unconditional);
    12 guard lines across 6 sites; zero crashes since deployment.
2026-06-05 20:52:43 -04:00
3a8c66a148
examples/cuda-fanout: Day-4 v4 stack landed (byte-clean, -12% vs v3); daemon flips to v3 --window-w 4
Day-4 task per fox: stack v3 windowed-G ladder (Day-3) with v2 Montgomery
batch inversion (Day-2). Idea: Day-3 cut scalar_mul, residual ModInv now
matters — which is what Day-2 needed to win.

Result:
- v4 (--window-w 4 --batch-inv) lands byte-identical vs coincurve at
  n in {32, 1000, 10000, 100000, 1000000}.
- 3090-ai best-of-3 @ n=1M: v1 7.86 / v3 13.83 / v4 12.16 Mkeys/s.
- v4 regresses -12% vs v3 because v2's Phase B/D walks run one thread
  per block (3906 active threads at n=1M; 3090 has ~125k concurrent
  thread budget). v3's per-thread ModInv saturates 1M parallel threads
  on 82 SMs — the threading model beats the smaller field-mult count.
- HARD-RULE triggered: v4 < 1.10x v3 → no v4 promotion.

Daemon flip per task brief option A:
- start-daemon now takes optional extra-args; register-daemon!,
  maybe-register-daemon! pass them through.
- *secp-daemon-extra-args* = '("--window-w" "4") activates v3 in the
  spawned secp256k1 daemon. cuda-shake-fanout and cuda-bignum-cgbn
  spawn unchanged.

Deployed:
- 3090-ai: rebuilt secp256k1-batch-mul, restarted via /tmp/launch.sh.
  Worker log shows [v3-window-w4] on smoke at n=16 and n=200.
- ai.foxhop.net (4090): same. sm_89, libgmp at ~/local/gmp.

Smoke test: small BSCP request to each worker over TCP, byte-identical
vs coincurve. Both PASS.

Catalog (CATALOG.md, www/bend.html): promoted v3 throughput to
13.83 Mkeys/s @ n=1M, recorded v4 regression and warp-scan Phase B/D
as Day-5+ refactor.

Progress doc: plans/form-A-day4-progress.md.
2026-06-05 19:07:00 -04:00
718a93ff2d
www: strip private www.foxhop.net/ecdsa.html links; promote v3 in index
foxhop CLAUDE.md update: www.foxhop.net is private (book.foxhop.net
source + research artifacts). URLs like https://www.foxhop.net/ecdsa.html
do not exist & must not appear in public posts or external links.
Public-facing copy of ECDSA work belongs on foxhop.net wiki (remarkbox
RST pages), not as static HTML under www.foxhop.net/.

Stripped two external links:

  bend.html  — "secp256k1 point-addition challenge work at
               foxhop.net/ecdsa" → "(research artifact, internal repo)"
  index.html — same pattern → "internal ECDSA research"

Also brought index.html catalog highlight in sync with Day-3:
  was: secp256k1 batched point-mul (6.5 Gkeys/s on a 4090, surveyed)
  now: 13.6 Mkeys/s on a 3090, ~309x coincurve CPU

The 4090 projection moves out of the lead because we now have a
measured number on our actual hardware.
2026-06-05 18:20:23 -04:00
424051b7a4
catalog: cuda-secp256k1 v3 windowed-G — 13.60 Mkeys/s @ n=1M (1.73x v1)
Form A Day-3 shipped at lumbda ecfe27a. Windowed-G ladder (w=4,
16-entry G-table built once via batch-inverse on the 15 Z-coords)
landed clean.

Bench on 3090, n=1M (best-of-3, --no-batch-inv):
  v1 (Day-1)      127.04 ms  →   7.87 Mkeys/s
  v3 (Day-3 w=4)   73.54 ms  →  13.60 Mkeys/s  (1.73x v1, ~309x coincurve)

Byte-identity PASS at n in {32, 1000, 10000, 100000, 1000000} plus
known-small edge cases (k in {1, 2, 3, 7, 0xdeadbeef, n-1, n, 2^128-1}).

Daemon default still serves v1; --window-w 4 flag selects v3
explicitly. Fox's call on flipping the daemon default.

Day-4 plan: stack v3 + Day-2 batch-inv. v3 cut scalar_mul; the
residual inversion cost now actually matters, which is what Day-2
needed to win.

Three agents still in flight: walker promotion (#39), lever
generator (#40), ai.foxhop.net second worker (#30).
2026-06-05 18:16:08 -04:00
95b3b1af21
catalog: Form D opt 3 landed; both pivots converge on compute-saturation
Form D Option 3 (QECCOPS2 packed op format) shipped at foxhop
commit 90484ca. Numbers:

  n_batches  unpacked  packed  speedup
       16    5842 ms   5428    1.076x
       64    6226 ms   5830    1.068x
      128    6604 ms   6201    1.065x

On-disk shrink: 716 MB → 307 MB (2.33x). Storage win, not compute win.

Critical diagnostic correction from the opt 3 agent: the 3.5x
bandwidth projection was WRONG because ops_loader.c already
narrowed u64 → u32 on load, so in-VRAM Op was already 28 B, not
56 B. Max realistic VRAM-reduction was 28 → 24 B = 1.17x best
case. The measured 1.07x matches: per-shot state traffic (qubits
+ bits per thread) is ~85x larger than the op stream, which
warp-broadcasts through L1/L2. Op-stream bandwidth was not the
bottleneck.

Both Form D pivots (opt 1 axis-flip, opt 3 packing) converged on
the same finding: the 3090 is compute-saturated at ~250 Mops/s on
the kickmix circuit, not bandwidth-saturated. Algorithm + layout
tweaks already extracted; the real next macro-lever is multi-GPU
fan-out across the fleet (3090-ai + ai.foxhop.net 4090 + future
nodes, each saturating its own ceiling in parallel).

cuda-sim-axis-flip remains LIVE as a tool with specific use:
many-candidates × few-shots search-loop early-screen. ops.bin
packing remains useful for fleet rsync (3.5x smaller payloads
across the LAN matters when shipping candidate variants).
2026-06-05 14:16:20 -04:00
262607f438
catalog: cuda-sim-axis-flip live, bandwidth diagnosis flipped
Form D opt 1 (axis-flip refactor) shipped at foxhop 1f7ac9d.
Per-candidate parallelism over per-shot delivers 217 Mops/s at
K=32 candidates × M=4 shots on a 3090, byte-identical with the
CPU reference at every (K, M) pair we measured.

Key finding inside the numbers: the bandwidth-bound diagnosis
flagged in the Form D structural-finding doc was WRONG. Both
axes (per-shot N=128 and per-candidate K=32 M=4) saturate at the
SAME ~220-250 Mops/s on the 3090. Per-shot wins by 14% at full
saturation; axis flip wins by 23.7x at small M because it fills
SMs in one launch instead of leaving them idle.

So the axis kernel is the right tool for lumbda's many-candidates
× few-shots search-loop early-screen pattern — not a replacement
for the per-shot kernel.

Form D opt 3 (ops.bin packing) still in flight. Since compute
saturates before bandwidth on this device, packing may not
deliver expected gain. Letting that agent finish so we have
empirical numbers either way.

Live forms now: 5
  cuda-shake-fanout           ~12x host hashlib @ 1M
  cuda-sim-ops-bin            1.07x @ 128 batches (kickmix per-shot)
  cuda-bignum-cgbn            1.28 Gops/s mod-mul @ 1M (256-bit)
  cuda-secp256k1-batched-mul  6.51 Mkeys/s @ 100k (148x coincurve)
  cuda-sim-axis-flip          217 Mops/s @ K=32 M=4 (kickmix per-candidate)
2026-06-05 14:12:56 -04:00
7695163e1a
catalog: promote CGBN + secp256k1 to live, record measured throughput
Form A (cuda-secp256k1-batched-mul) shipped earlier this session at
commit 7661788. Form B (cuda-bignum-cgbn) extended to all 9 ops at
21bd26a. Both now serving on 3090-ai gpu-worker:9091 alongside the
shake form.

Catalog Live forms table:
  cuda-bignum-cgbn          | 1.28 Gops/s kernel mod-mul @ n=1M, 256-bit
                              (~256x GMP CPU single-thread); 9 ops total
  cuda-secp256k1-batched-mul| 6.51 Mkeys/s @ n=100k (~148x coincurve CPU);
                              Day-2 Montgomery batch inversion projected
                              toward FixedPaul's 6.5 Gkeys/s on 4090

Wire magics now in use:
  BSHK/BSHR — cuda-shake-fanout
  BCGB/BCGR — cuda-bignum-cgbn
  BSCP/BSCR — cuda-secp256k1-batched-mul
  (BSTB/BSTR reserved for cuda-clifford-stabilizer; parked per
   structural finding — our circuit has no H/S gates)

Form D pivots (axis-flip sim_gpu.cu + ops.bin packing) still in
flight; CATALOG.md + bend.html will gain rows once they ship.

Notable defect surfaced during Form A build: widely-cited secp256k1
generator y-coordinate
  0x483ADA7726A47B0DAFFA10ED2E11458A823D0E1D89DCAB14C7C39D9F8B97C20A
does NOT satisfy y^2 = x^3 + 7 mod p. Real Gy =
  0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
Cross-tutorial propagation. UNDF candidate logged.
2026-06-05 14:10:37 -04:00
277250ecfa
bend Form D structural finding — pivot to axis-flip + ops.bin packing
Form D build agent discovered: our point-add circuit contains no
Hadamard or S gates (only X/CX/CCX/CZ/CCZ/SWAP/R/HMR/Z/NEG).
State never leaves the computational basis. Aaronson-Gottesman
tableau compression buys nothing when superposition does not
exist; reduces to exactly what sim_gpu.cu already does at one
bit per qubit per shot.

Toffoli fraction measured 13.87% (well under the 40% threshold
the planner flagged). The 1.07x cuda-sim-ops-bin ceiling traces
to memory-bandwidth on per-shot striped state — not algorithm.

STABSim-class wins remain valid for QEC / surface-code work where
H + S exist; that's a future workload.

Two replacement directions queued:
  1. axis-flip sim_gpu.cu — per-candidate parallelism over per-shot.
     ~3 days. Reuses BSHK new op_id; no AG tableau.
  2. ops.bin packing — 56→16 B per op halves global-memory traffic.
     Addresses the actual bottleneck.

Catalog + public bend.html both updated. Form D progress doc at
examples/cuda-fanout/plans/form-D-build-progress.md documents the
structural reasoning in full.
2026-06-05 14:03:03 -04:00
a33ae4331d
bend catalog Wave 3 — 15 surveyed forms (2026-06-05)
Adds 15 new GPU primitive forms across domains not covered by
Waves 1-2: ZK/SNARK provers, pairing crypto, tensor network
contraction, sparse LA, CV primitives, numerical solvers,
generic belief propagation, MD/CFD, convex opt, DSP beyond cuFFT,
DB aggregations, graph theory beyond triangle/PageRank.

Top hits by relevance to our missions:

  * cuda-mfcc-spectral (97x) — punters-cc, BT-DISC forensics, real-time CC pipeline. unsandbox HIGH.
  * cuda-batched-lp-simplex (95x over CPLEX) — Prime Mission workstation-to-queue balancing. unsandbox HIGH.
  * cuda-betweenness-centrality-weighted (30-150x) — workaholic-node detection on dependency DAG, MOAD-0001 model. undefect HIGH.
  * cuda-hungarian-lap (400M-var LAP ~13s) — workstation balancing. unsandbox HIGH.
  * cuda-msm-bls12-381 (27.86x) — Pippenger shares branchless modmul shape with our reversible secp256k1 inner loop. ECDSA HIGH.
  * cuda-tensornet-contract (tensor QR 100x vs Xeon 8480+) — alt to stabilizer/kickmix sim path; MPS/PEPS evaluates reversible secp256k1 circuits beyond Clifford. ECDSA HIGH.
  * cuda-loopy-bp-mrf (45x) — LBP substrate for FuzzingBrain probabilistic analysis. undefect HIGH.
  * cuda-ega-gpu-aggregation (6-29x) — defect-corpus aggregation at planetary scale; telemetry queue aggregation. undefect HIGH + unsandbox HIGH.

Plus highlight numbers: FluidX3D LBM 100-200x vs ANSYS Fluent,
CUDASW++4.0 5.71 TCUPS on H100 for sequence alignment, ICICLE-Snark
the fastest Groth16 today.

Wave 3 filter-outs noted: AMGX, GROMACS, NVOFA, junction-tree BP,
batched L-BFGS — all below 10x or insufficiently general.

CATALOG.md mirrors the table for in-repo reading; bend.html
renders the public version with reference URLs.
2026-06-05 13:18:06 -04:00
a17c114263
bend.html: dedicated page + 27-form catalog with published speedups
Splits a dense bend section out of index.html (now 6 lines: tagline,
example, three highlights, CTA) into a new public page at
lumbda.com/bend.html carrying:

  * full wire protocol (S-exp + binary BSHK modes)
  * tier-choice table (Py / C / asm × S-exp / binary)
  * real workload table from foxhop ecdsafail measurements
  * 2 live forms + 7 surveyed forms (Wave 1: secp256k1 batch-mul,
    CGBN bignum, Pollard rho, Stim-on-GPU stabilizer, Bernstein-Yang
    inverse, NTT, CUB sort/scan)
  * 20 surveyed forms (Wave 2) sorted by speedup descending —
    minhash 600-1000x, cuckoo filter 378x, ChaCha20 400 GB/s,
    SAT 93x, Dilithium PQ 57.7x, BLAKE3 tree, cuFFT batched,
    Bloom filter modern, GEMM FP8, hash-join 1.8T tuples/s on
    1024xA100, cuGraph 38B TEPS, TRUST triangle 1T TEPS, nvCOMP 2.2x
  * skipped section listing forms that don't pass the threshold,
    so the catalog stays honest about what GPU dominates vs not
  * cited canonical references for every entry

CATALOG.md mirrors the same data — single source of truth in repo;
bend.html renders the same metadata for public reading.

Build order remains: A cuda-secp256k1-batched-mul, D Clifford
stabilizer, B CGBN bignum.
2026-06-05 13:02:31 -04:00
78ff89fb8b
bend: cuda-sim-ops-bin handler + per-call CPU/GPU telemetry
gpu-worker.lsp gains a cuda-sim-ops-bin op handler that spawns
demo_ops from www.foxhop.net/ecdsa/cuda via spawn-process-stdio,
drains stdout, & parses our (cuda-sim-result ...) portal back.

Each call now emits two log lines:
;;; bend RECV cuda-sim-ops-bin ops=PATH n-batches=N t-ms=...
;;; bend DONE cuda-sim-ops-bin n-batches=N wall-ms=W cpu-ms=C gpu-ms=G mismatches=0 gpu/cpu=R

so we can tell how fast bend jobs run on CPU vs GPU per call.

CLAUDE.md & www/index.html mention this integration is now live
end-to-end across our fleet.
2026-06-05 10:18:11 -04:00
01ea93f68f
binary wire mode: 12x faster than host hashlib at 1M inputs
The S-expression wire format was the bottleneck at huge payload sizes
-- 23.8 s end-to-end for 1M x 16 B inputs on the Python tier, while
the actual CUDA kernel finishes the same workload in ~47 ms. The
hex-S-exp parser ate everything between.

New binary wire mode (magic 'BSHK' prefix; payload is the daemon's
binary portal format verbatim) bypasses S-expression parsing entirely.
Worker writes the blob to disk, calls daemon process-bin, reads result,
prepends 'BSHR' magic, replies.

Measured 3090-ai, daemon warm, localhost:

  workload      Py S-exp    Py binary   C S-exp    C binary
  100 x 16 B     3.43 ms     0.74 ms    0.40 ms    0.15 ms
  1k x 16 B     23.24 ms     0.76 ms    2.77 ms    0.22 ms
  10k x 16 B   218.82 ms     1.27 ms    CLIFF      0.88 ms
  100k x 16 B  2,219 ms     10.18 ms    CLIFF     10.35 ms
  1M x 16 B   23,811 ms    159    ms    CLIFF    157    ms

150x speedup at 1M inputs on Python tier. C tier S-exp CLIFFs
between 1k and 10k inputs (reader payload limit); binary mode
bypasses the CLIFF entirely. At 100k+ inputs both tiers converge
since file I/O + CUDA kernel dominates over wire framing.

Host comparison: hashlib.shake_256 over 1M tiny inputs takes ~2 s
on a single Python core. Bend via binary worker = 157 ms = 12x
faster than host. Bend now wins at huge workloads, not just heavy
ones.

Implementation:

  lumbda.py
    * tcp-send/tcp-recv switched to latin-1 (1:1 byte mapping)
      so binary payloads pass through cleanly. UTF-8 was mangling
      bytes with replacement chars.
    * write-binary-file / read-binary-file primitives.

  c/builtins.c
    * write-binary-file / read-binary-file matching Python tier.

  examples/cuda-fanout/wire.lsp
    * wire-send-raw / wire-recv-raw helpers that frame a raw
      payload string without S-expression serialization.

  examples/cuda-fanout/gpu-worker.lsp
    * handle-binary-shake: write portal blob, daemon process-bin,
      read result, wire-send 'BSHR' + bytes.
    * handle-one dispatches on first 4 bytes of payload: 'BSHK'
      goes to binary path, anything else stays S-exp.

  examples/cuda-fanout/bench_tiers.py
    * make_payload_binary builds the BSHK protocol payload.
    * --binary flag in CLI.

  www/index.html
    * full S-exp + binary comparison table.
    * 'bend now beats host hashlib at huge workloads' headline finding.
2026-06-05 09:40:45 -04:00
d69e8ed859
asm tier: delete-file + worker now fully functional; 3-tier bench
Three defects fixed today on the asm tier worker path:

1. Multi-line "..." docstrings crashed asm tier's scheme_read.
   wire.lsp, bend.lsp, gpu-worker.lsp had docstrings spanning
   several lines; replaced with ;; comments before each define.
   asm tier loads these cleanly now.

2. asm tier lacked delete-file. handle-cuda-shake-fanout called
   it to clean up temp portal files. Added bi_delete_file via
   SYS_UNLINK = 87 syscall (~20 LoC asm). BI_DELETEFILE constant
   slotted after sibling-agent's BI_STRTOSYM.

3. All Scheme files in examples/cuda-fanout/ now ASCII-only.
   Earlier em-dash / × / → / μ tripped asm tier's reader in
   subtle ways during file load. iconv pass + sed fixes.

Result: all three tiers complete the bench through their own
cliff. New 3-tier table:

  workload              Python      C tier      asm tier
  small (3 × 16 B)       1.27 ms    0.16 ms     0.21 ms
  small (100 × 16 B)     3.43 ms    0.40 ms     1.99 ms
  medium (1000)         23.24 ms    2.77 ms     CLIFF
  med (10k)            218.82 ms    CLIFF       CLIFF
  huge (50k)         1,099 ms       CLIFF       CLIFF
  huge (100k)        2,219 ms       CLIFF       CLIFF
  huge (1M)         23,811 ms       CLIFF       CLIFF

asm tier at 0.21 ms beats Python by 6× at smallest workload,
matches C at the bottom (~30% slower). asm cliffs at 1000;
C tier cliffs at 10k. Both cliffs are reader/buffer limits
inside the tier, not network or kernel. CUDA kernel itself
finishes 1M × 16B in ~47 ms — three orders of magnitude under
any tier's wire cost at huge scale.

bench_tiers.py made cliff-resilient: respawns worker on per-
workload failure & continues, so the full row prints for every
tier instead of bailing on first cliff.

www/index.html: full 3-column table + honest framing of when
each tier earns its slot.
2026-06-05 09:24:26 -04:00
e1fe20c5b9
wire.lsp: recv-exact O(n²) → O(n); bench reports linear Python scaling
wire.lsp's recv-exact previously accumulated received chunks via
`(string-append acc chunk)` in a loop — quadratic on payload size.
Replaced with a chunk-list accumulator + single `(apply string-append
…)` at the end. Lumbda's string-append knows total length up front
& allocates once.

Python tier now scales linearly across input counts (~22 µs per input):

  workload             Python      C tier
  small  (3 × 16 B)    1.25 ms    0.16 ms    8× C win
  small  (100 × 16 B)  3.39 ms    0.40 ms    8× C win
  medium (1000)        23.52 ms   2.60 ms    9× C win
  med    (10k)         220.15 ms  (cliff)
  huge   (50k)         1,100 ms   (cliff)
  huge   (100k)        2,225 ms   (cliff)
  huge   (1M)          23,811 ms  (cliff)

C tier cliffs somewhere between 1k & 10k inputs per call — its reader
hits a payload limit we still need to track down. CUDA kernel for
1M × 16B finishes in ~47 ms on this 3090, so at huge sizes the wire
cost dominates regardless of tier.

Web page updated with the linear-scaling table & honest framing: at
small inputs C wins by 9×; at huge inputs the right next move is a
binary wire mode parallel to the daemon's already-binary portal
format. Stalls are gone.
2026-06-05 08:55:43 -04:00
373c8ea0d3
bench + www: honest huge-workload numbers + wire bottleneck found
Added a write-to-string-shim.lsp for asm tier (which lacks the
native builtin); asm launch script pre-defines *argv* + loads the
shim so wire.lsp's wire-send finds a write-to-string definition.
Python/C tiers keep the native builtin — the shim is opt-in.

Bench extended with two huge workloads (100k × 16 B, 1M × 16 B).

Real numbers, 3090-ai, daemon warm, both ends localhost:

  workload              Python    C tier   C win
  small (3 × 16 B)       1.16 ms   0.14 ms   8.3×
  small (100 × 16 B)     3.39 ms   0.42 ms   8.1×
  medium (1000 × 16 B)  23.26 ms   2.67 ms   8.7×
  huge (100k × 16 B)    2,220 ms   STALL     n/a
  huge (1M × 16 B)     24,338 ms   STALL     n/a

THE FINDING: at huge sizes, the bottleneck is the S-expression
text wire format, not the CUDA kernel. shake256-fanout finishes
1M × 16B in ~47 ms; the Python worker takes 24 SECONDS end-to-end
because wire.lsp's recv-exact accumulates chunks via string-append
in a loop — O(n²) at multi-MB payload sizes. C tier fails outright.

The right fix is binary wire framing between client + worker,
parallel to the binary portal format the daemon + leaf already use.
That's a separate piece of work; today's Web page edit calls it out
honestly so visitors know when bend is the right tool.

asm tier worker hosting still has process-management quirks
(doesn't survive nohup detachment in this environment); bench
ships with --skip-asm by default in this run.
2026-06-05 08:50:36 -04:00
f24afcc5d9
bench + www: real numbers — C tier ~9× faster than Python as worker host
Wrote examples/cuda-fanout/bench_tiers.py — spawns a worker per
tier, fires N TCP round-trips at three workload sizes through the
warm daemon, reports median + p99.

Measured on 3090-ai, daemon warm:

  workload             Python   C tier   C win
  small  (3 × 16 B)    1.27 ms  0.14 ms  9.1×
  small  (100 × 16 B)  3.46 ms  0.41 ms  8.4×
  medium (1000 × 16 B) 23.51 ms 2.67 ms  8.8×

Ratio stays at ~9× across the grid — the per-byte cost of
Python's S-expression reader/printer compared to the C tier's
reader. Justifies the LUMBDA=c default landed in the previous
commit.

asm tier worker starts up & listens (after the launch script
predefines *argv* '()), but bench script saw malformed responses on
this run — likely a write-to-string format difference between asm
& Python/C reader. Leaving for follow-up; published numbers cover
the tiers that completed end-to-end.

www/index.html bend section gains the measured table under a new
'Tier choice for the worker host' subsection. Replaces the earlier
hand-wavy ~10× claim with the actual measured numbers.
2026-06-05 08:39:31 -04:00
14edb57cd4
make gpu-worker: default to C tier
C tier is ~10× faster than Python tier on wire orchestration & has
the same primitives shipped this session. Python tier still available
for development debugging via LUMBDA=python; asm via LUMBDA=asm.

Auto-builds the chosen tier (c-build or asm-build) before launching
so a fresh clone runs cleanly without 'make c-build && make gpu-worker'
two-step.

Web page Start-a-GPU-worker subsection updated to match.
2026-06-05 08:34:43 -04:00
f119f581a1
Makefile + www: make gpu-worker target & start-worker docs
Adds a one-shot target so any host with nvcc can stand up a bend
worker without remembering the launch incantation.

  make gpu-worker
    → make -C examples/cuda-fanout shake256-fanout
    → writes examples/cuda-fanout/launch.lsp (wire + worker + main)
    → cd examples/cuda-fanout
    → python3 -u ../../lumbda.py launch.lsp --port 9091

  make gpu-worker LUMBDA=c PORT=9001     # C tier host on port 9001
  make gpu-worker LUMBDA=asm             # asm tier host

Uses python3 -u so the worker's status lines ("gpu-worker:
ready …", "listening on port 9091") appear live; bypasses Python's
default stdout buffering that masked them during development.

www/index.html bend section gains a 'Start a GPU worker' subsection
with the same make targets so the website visitor doesn't need to
spelunk the repo to find them.

Also adds gpu-worker, gpu-worker-bin, gpu-worker-test to .PHONY.
2026-06-05 08:19:51 -04:00
9410816bdc
www: bend section on lumbda.com
New section between Portal and EML universality proof. Brief
explanation of the bend primitive + a worked code example showing:

  - tiny inputs stay local (cost below threshold)
  - heavy inputs ship to a GPU worker (cost above threshold)
  - one tier-portable (bend …) macro, with bend-call as the asm form

Mentions the measured 1.5–10× wins against host hashlib on the
SHAKE256 fan-out workload, calls out the ~100 MB break-even
threshold so visitors know when bend pays off.

Cites the cuda-fanout README + integration design for callers who
want the wire contract and per-tier hosting story.

License: AGPLv3, matching the rest of the site.
2026-06-05 08:16:56 -04:00
5566865815 logo: revert artwork to source orientation (was over-flipped)
Source PNG from the MPS lumbda-logos product is already an inverted λ
(hooks at top-left + bottom-right, V-body). My prior commit applied
vertical + horizontal flips on top of that, which undid the inversion
and produced a right-side-up calligraphic λ — the opposite of what
the artwork was drawn to express.

Regenerate both PNG variants (lumbda-logo.png black,
lumbda-logo-green.png #227842) directly from the source with no
flips. Only transform: alpha-from-brightness so anti-aliased edges
survive over any background.

Homepage img src picks up ?v=2 so any browser with the flipped
version in disk cache re-fetches. Logo size stays 3.33× the
wordmark font (10.66rem). PDF + HTML rebuilt — embed-images.py
base64-inlines the new PNG into the HTML automatically.
2026-04-19 17:42:14 -04:00
ecf0c89de2 www + whitepaper: adopt custom λ mark from MPS, green, 3× wordmark size
Fetched the lumbda-logos artwork from
media.unturf.com/c/fbd3d473-.../lumbda-logos (a MakePostSell product),
applied both flips (vertical + horizontal, = 180°) at bake time so the
PNG ships oriented correctly without any CSS transform dance, and
recolored non-background pixels to brand green (#227842) with alpha
derived from pixel brightness so anti-aliased edges stay smooth.

Two PNG variants ship under whitepaper/diagrams/:
  * lumbda-logo.png        dark ink for print contexts
  * lumbda-logo-green.png  #227842 for web

www/ carries symlinks to both.

Homepage (www/index.html): replaces the CSS-rendered λ with an
<img class="lambda-mark"> element sized 9.6rem — 3× the 3.2rem
wordmark font — stacked below "lumbda." on its own line.

Whitepaper (whitepaper/lumbda-whitepaper.rst): adds the logo as the
first figure above the permacomputer-logo, 24% width, centered.
Regenerated PDF + HTML; embed-images.py base64-inlines the new file
automatically so the HTML stays single-file.

CI (.gitlab-ci.yml): generalizes the symlink resolver from two
explicit `cp -L` calls into a `find www -type l` loop, so every
current and future symlinked asset deploys without per-file CI edits.
2026-04-19 17:32:43 -04:00
9acfe40404 www: λ mark rotated 180deg (two 90° turns), not vertical flip 2026-04-19 17:24:25 -04:00
2fccdddf44 www: stack logo vertically — wordmark on top, λ mark beneath
λ in front was reading as a "Y" attached to the wordmark ("ylumbda.").
Move the mark under the wordmark as a standalone logo below the name.
Sitting alone, the flipped λ doesn't get recruited into the first
letter and reads as its own glyph — a lambda turned on its head.
2026-04-19 17:20:24 -04:00
f0dbf62cef www: single #227842 brand green for λ mark, period, links, CTAs
Collapse --accent (was blue #0b5394) into the same green as the
period. One color now marks everything that says "lumbda": the λ
logo, the declarative period, link underlines, and the CTA buttons.
Dark-mode variant lightened to #5ec07a so the green reads on
#161613.
2026-04-19 17:17:38 -04:00
26c6cca6da www: logo — distinct oversized flipped λ beside "lumbda.", green period
Previous design folded the flipped λ inside the wordmark as the "l".
That read as a cute substitution but didn't work as a brand mark.
Split them: the λ now stands on its own, rotated upside-down, 5rem
(larger than the 3.2rem wordmark), so it reads as a logo symbol
separate from the text.

Wordmark restores a proper lowercase "l" in "lumbda" — readable,
copy-pasteable, searchable. Trailing period picks up a new --green
design token (#2a8a3a light / #6fd68a dark) so the declarative stop
also reads as growth — matches the permacomputer ethos.

Layout: flex logo-row with baseline alignment and a small gap; the λ
hangs from the wordmark's cap-line for a balanced mark-and-wordmark
composition.
2026-04-19 17:12:51 -04:00
8a51e1fd7f www: logo becomes "lumbda." with a vertically-flipped λ for the l
Wordmark now renders λumbda. — flipped λ stands in for the "l",
visual pun on lambda (the primitive the language shells around),
trailing period as declarative closure. All-lowercase, accent-colored
period. aria-label="lumbda." keeps screen readers reading the name
correctly; the λ and the period both carry aria-hidden.
2026-04-19 17:05:05 -04:00
718f878f7d www: HTML whitepaper + prose rewrite avoiding "to be" and "the"
CLAUDE.md rewritten to avoid the verb "to be" and to prefer "a"/"our"
over "the" when a thing counts as one of many or as shared. Same rule
applied to www/index.html (tagline now "feedback as a primitive", body
prose cleaned of is/are/be, table header now "What a tier buys",
section heads trimmed of definite articles). Monospace body stays,
ChunkFive titles stay.

Whitepaper now ships in two formats:

  * Makefile target `make whitepaper-html` runs rst2html5 with
    embedded minimal.css + responsive.css (docutils bundled), then
    injects the same uncloseai.js module script that the homepage
    carries, and stamps a meaningful <title>. 180 KB self-contained.
  * PDF build target renamed to `make whitepaper-pdf`;
    `make whitepaper` now builds both.

www/lumbda-whitepaper.html symlinks to the generated HTML (same
pattern as the PDF symlink). .gitlab-ci.yml resolves both symlinks to
real files before rsync so the proxy gets byte-identical copies.

Homepage now exposes both formats side-by-side via two .cta buttons
and the footer lists HTML + PDF.
2026-04-19 16:23:56 -04:00
af02e9b1c0 www: canonical slug /lumbda-whitepaper.pdf + embed uncloseai.js
Rename www/whitepaper.pdf → www/lumbda-whitepaper.pdf (symlink target
unchanged; slug now descriptive for search/citation). Update the CTA
and footer links in index.html, plus the .gitlab-ci.yml symlink-resolve
step. Companion Caddyfile redirect in proxy.unturf.com keeps old
/whitepaper.pdf links working via 301.

Add <script src="https://uncloseai.com/uncloseai.js" type="module"> to
<head>, matching www.unturf.com + timehexon.com pattern — brings the
permacomputer chat/AI integration to lumbda.com's front door.
2026-04-19 16:17:43 -04:00
af3e308a95 www: ChunkFive for logo/titles; normalize asm references to "GNU asm"
ChunkFive webfont (woff2 + woff, ~43 KB total) dropped into
www/fonts/chunkfive/; style.css adds @font-face with font-display:swap
and applies the family to header h1 (3.2rem logo) and main h2
(1.5rem section titles). Monospace body text unchanged. Font files
reused from www.unturf.com; SIL OFL.

index.html: "x86_64 assembly interpreter" and table-row labels
"Pure x86_64 assembly" / "Assembly + naive mark-sweep GC" now read
"GNU asm" — precise and consistent with how we talk about the tier
elsewhere.
2026-04-19 16:08:02 -04:00
e2a74832ef www/: static docroot for lumbda.com
Minimal, monospace, readable. Works as a drop-in docroot for
any static server (nginx, caddy, python -m http.server, etc.).
Light/dark mode via prefers-color-scheme. No JS, no fonts, no
third-party anything.

Files:
  www/index.html    landing page (tagline, get-it, four-tier
                    table, portal summary, EML proof blurb,
                    license, whitepaper CTA)
  www/style.css     ~150 lines, CSS vars for theming
  www/robots.txt    allow everything
  www/404.html      referenced by servers that support custom
                    error pages
  www/whitepaper.pdf -> ../whitepaper/lumbda-whitepaper.pdf
                    (symlink — one source of truth, rebuilds
                    via `make whitepaper` auto-propagate)

Smoke-tested with python3 -m http.server: 200 on /,
Content-Type: application/pdf for /whitepaper.pdf,
Content-Length matches the current 2.67 MB PDF,
/robots.txt serves, /nonexistent returns 404.

No new build step — docroot is pure static files the existing
whitepaper target already produces. A web server configured
with docroot=www/ and fallback 404.html has a working lumbda.com
today.
2026-04-19 11:21:56 -04:00