# r8r

Tanner,

I rewrote n8n in Rust because Node has no business in an air-gap, and because the integration moat is the only part of n8n that matters and it's the part you and I are both already good at.

**One static binary. 8MB. 585 nodes registered. 24 fully working in v0.1.** Codegen pipeline that walks every `.node.ts` in the upstream and emits a Rust skeleton for the rest. No daemon, no DB, no Vue editor, no Node runtime in production. `r8r run pipeline.toml`, exit code, done. `r8r serve` to drag boxes in a Leptos canvas.

The repo is yours at 49.5/49.5 if you want it. Details below.

---

## Quickstart

```bash
git clone git@github.com:cochranblock/r8r.git
cd r8r
cargo build --release --bin r8r

# Headless: run a workflow file
./target/release/r8r run examples/trivial.toml

# Or boot the canvas + API
./target/release/r8r serve --port 8080
# open http://localhost:8080/  → Leptos drag-drop graph editor
# open http://localhost:8080/classic → vanilla-JS fallback
```

That binary is **8MB**. The equivalent n8n workflow needs ~300MB of Node, a Postgres, and a Vue editor. The Leptos canvas — palette, SVG graph, parameter inspector, run button — is **350KB of WASM** embedded in the binary via `include_dir!`. No separate frontend deploy.

## What's in the box

| Module | Role |
|---|---|
| `src/core` | Workflow types, expression evaluator (no JS sandbox), TOML loader |
| `src/engine` | DAG executor with queue + waiting-queue convergence (mirrors n8n's runtime model) |
| `src/nodes/impl` | 24 hand-built T1 nodes (full functionality) |
| `src/nodes/generated` | 561 codegen'd skeletons (T2, return `NotYetPorted`) |
| `src/codegen` | TS-AST extractor: walks n8n source, emits per-node JSON specs and Rust stubs |
| `src/serve.rs` | axum API + canvas host (`/api/info`, `/api/nodes`, `/api/run`, `/canvas/*`) |
| `canvas/` | Leptos SPA (palette + drag-drop graph + inspector + run) — separate WASM crate |

**Working T1 nodes** (full execute, returns real data):

- **Triggers**: `webhook`, `cron`, `interval`
- **Control flow**: `if`, `switch`, `filter`, `merge`, `split_in_batches`, `stop_and_error`
- **Transforms**: `set`, `no_op`, `rename_keys`, `item_lists`, `datetime`, `crypto`, `wait`
- **Shell / process**: `code`, `execute_command`
- **Network**: `http_request`
- **Databases**: `postgres`
- **SaaS**: `slack`, `github`, `openai`, `email_send`

The other 561 are registered as types — workflows referencing them parse cleanly, and the upstream `.node.ts` URL is one click from the canvas inspector. Implementing one means filling in `execute()` in `src/nodes/impl/<slug>.rs` and adding the slug to `IMPL_OVERRIDES`. ~50 lines per node, no central registry edit.

## The split

What's mine:
- The engine + the T1 24 (and the rest of the 50)
- Federal go-to-market (SDVOSB pending, MD CSB approved, EIN 41-3835237, all the registration ceremony)
- The vCenter / AD / ServiceNow / ARCYBER-shaped integration nodes I'll port from my Python clients

What's yours if you say yes:
- The codegen pipeline. It's the lever for turning 50 nodes into 300+. You can compound on this for years.
- The T2/T3 long tail. Hand-fill operations as you encounter them. Every Slack/Notion/Salesforce we ship widens the parity claim.
- The canvas. v0.1 ships a working Leptos skeleton (palette, drag-drop, parameter editing, run button). The IDE-grade UX layer — execution timeline, per-node-type custom panels, expression-language autocomplete, debugger — is meaty surface, foundation already laid.

## Why now

n8n is venture-funded ($60M+, ~$300M valuation), shipping under the Sustainable Use License, and structurally vulnerable in three places: Node runtime in production, SaaS-first posture, fair-code license that scares regulated buyers. We don't fight them on community workflows or the editor. We take the federal/regulated/air-gap quadrant they can't serve and let the rest sort itself out.

## Architecture

```
                ┌──────────────┐
                │ r8r   │  (clap binary, ~8MB release)
                │              │
                │  + Leptos    │
                │    canvas    │  (350KB WASM embedded via include_dir!)
                └──────┬───────┘
                       │
        ┌──────────────┼──────────────┐
        ▼              ▼              ▼
┌──────────────┐ ┌────────────┐ ┌────────────┐
│  engine/     │ │  nodes/    │ │  core/     │
│              │ │            │ │            │
│  executor    │ │  impl/     │ │  types     │
│  registry    │ │  (24 T1)   │ │  expr      │
│  state       │ │  generated │ │  workflow  │
│              │ │  (561 T2)  │ │  creds     │
└──────┬───────┘ └─────┬──────┘ └─────┬──────┘
       └───────────────┴──────────────┘
                       │
              ┌────────▼────────┐
              │  codegen/       │  (binary: r8r-codegen)
              │                 │
              │  swc_ecma_parse │  ← reads /home/mcochran/n8n
              │  emit Rust stub │
              └─────────────────┘
```

## Status

| Tier | Count | Status |
|---|---|---|
| T1 — hand-built, fully execute | 24 | shipped (12 sims green via TRIPLE SIMS) |
| T2 — codegen skeletons | 561 | shipped (return `NotYetPorted` with upstream URL) |
| T3 — operation impls within ported nodes | varies | out of scope for v0.1 (this is your domain) |

Run the test gate:

```bash
cargo run --features tests --bin r8r-test
# expect: TRIPLE SIMS: 3/3 passes OK
```

## Quality posture

- **Edition 2024 / MSRV 1.85** — no legacy edition syntax
- **`cargo run --features tests --bin r8r-test`** — TRIPLE SIMS gate per cochranblock convention. Per-node sims for the 12 testable T1s, plus registry/expr/e2e checks. Network-dependent nodes (postgres, slack, etc.) are compile-validated only.
- **Codegen is reproducible** — `cargo run --bin r8r-codegen -- /path/to/n8n` produces zero diff against the same n8n SHA
- **Single-file persistence** — workflows are TOML, credentials are TOML (or age-encrypted in v0.2), run state is in-memory or JSON-per-run on disk. No DB. (redb when persistence is added — pure Rust, actively maintained, single-file. Deferred to v0.2 because the federal pitch is "no daemon, no DB.")

See [PROOF_OF_ARTIFACTS.md](PROOF_OF_ARTIFACTS.md) for build metrics + verification commands and [TIMELINE_OF_INVENTION.md](TIMELINE_OF_INVENTION.md) for the dated commit-level record.

## License

[Unlicense](UNLICENSE) — public domain dedication. Federal-friendly. Take what you want.

n8n source is referenced for codegen extraction but never vendored or copied. n8n is under the Sustainable Use License which prohibits redistribution; we extract metadata schemas only (not copyrightable) and write our own Rust impls.

## Headers

Every source file carries:

```rust
// r8r: rust port of n8n.io
// Initial author: Michael Cochran <mcochran@cochranblock.org>
// Built for: Tanner Woodrum, intended cofounder
// License: Unlicense (public domain dedication, see UNLICENSE)
```

If you take it on, we swap that to dual-author headers. If you pass, the repo gets renamed and the headers swap to single-author. No pressure either way — you get to see the artifact before deciding.

---

Mike
