SkillAgentSearch skills...

Hull

A secure, capability-limited runtime for agent-native, local-first applications. Single binary, zero dependencies, runs anywhere.

Install / Use

/learn @artalis-io/Hull
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<p align="center"> <img src="hull_logo.svg" alt="Hull" width="480"> </p> <h1 align="center">Hull</h1> <p align="center"><b>H</b>ardened <b>U</b>serspace <b>L</b>ockdown <b>L</b>ayer</p>

A capability-secure, local-first runtime for programmable tools and workflows. Single binary, zero dependencies, runs anywhere.

The name reflects the architecture: Hardened — capability-secure, sandboxed execution. Userspace — single binary, no kernel modules, no cloud, runs anywhere. Lockdown — the app declares what it can touch, the runtime enforces it. Layer — sits on top of Keel (Kernel Event Engine — Lightweight), mirroring the nautical metaphor: the hull protects the keel from the sea.

Hull is a sandboxed runtime where application code runs inside declared capability boundaries — the app states what it can access (files, hosts, env vars), and the kernel enforces it. Whether the code is written by an AI agent, a human developer, or generated by a service, Hull constrains what it can do.

Write backend logic in Lua or JavaScript, frontend in HTML5, data in SQLite. hull build produces a single portable executable — under 2 MB — that runs on Linux, macOS, Windows, FreeBSD, OpenBSD, and NetBSD. AI coding agents get structured JSON access to routes, schema, tests, and HTTP responses through the built-in hull agent command — no plugins, no MCP servers, no configuration.

Why

AI coding agents solved code generation. But they created two new problems: deployment (the output is always React + Node + Postgres + cloud) and trust (who verifies what AI-generated code actually does?).

Hull solves both. Write Lua or JavaScript, hull build produces a single file. That file is the product — no cloud, no hosting, no dependencies. And because Hull apps declare their capabilities in a manifest enforced by the kernel, the user knows exactly what the app can touch. In a world where AI writes the code, the runtime must be the trust boundary. Hull is that boundary. The same properties — single-binary deployment, capability enforcement, structured tooling — make Hull equally useful for human developers building local tools and services.

Six vendored C libraries. One build command. One file. That's the entire stack. Works out of the box with Claude Code, Codex CLI, OpenCode, and any agent that can run shell commands.

Quick Start

# Build hull
make
make test

# Create a new project
./build/hull new myapp
cd myapp

# Run in development mode (hot reload)
../build/hull dev app.lua

# Build a standalone binary
../build/hull build -o myapp .

# Run it
./myapp -p 8080 -d app.db

Hull Tools

Hull ships 14 subcommands for the full development lifecycle:

| Command | Purpose | |---------|---------| | hull new <name> | Scaffold a new project with example routes and tests | | hull dev <app> | Development server with hot reload | | hull build -o <out> <dir> | Compile app into a standalone binary | | hull test <dir> | In-process test runner (no TCP, memory SQLite) | | hull agent <subcommand> | AI agent interface — routes, schema, tests, requests as JSON | | hull inspect <dir> | Display declared capabilities and signature status | | hull verify [--developer-key <key>] | Verify Ed25519 signatures and file integrity | | hull eject <dir> | Export to a standalone Makefile project | | hull keygen <name> | Generate Ed25519 signing keypair | | hull sign-platform <key> | Sign platform library with per-arch hashes | | hull manifest <app> | Extract and print manifest as JSON | | hull <app> --max-instructions N | Set per-request instruction limit (default: 100M) | | hull <app> --audit | Enable capability audit logging (JSON to stderr) | | hull <app> --max-connections N | Max concurrent connections (default: 256) | | hull <app> --body-max-size SIZE | Max request body size (default: 1m) | | hull <app> --read-timeout MS | Read timeout in milliseconds (default: 30000) | | hull <app> --workers N | Thread pool worker count (default: 4) | | hull <app> --queue-capacity N | Thread pool queue capacity (default: 64) | | hull <app> --no-compress | Disable gzip response compression | | hull migrate [app_dir] | Run pending SQL migrations | | hull migrate status | Show migration status (applied/pending) | | hull migrate new <name> | Create a new numbered migration file |

Build Pipeline

Source files (Lua/JS/HTML/CSS/static assets)
        ↓
hull build: collect → generate sorted registry (hl_app_entries[]) → compile → link → sign
        ↓
Single binary + package.sig (Ed25519 signed)

The build links against libhull_platform.a — a static archive containing Keel HTTP server, Lua 5.4, QuickJS, SQLite, mbedTLS, TweetNaCl, and the kernel sandbox. The platform library is signed separately with the gethull.dev key.

Cross-Platform Builds

Hull supports three compiler targets:

| Compiler | Target | Binary Type | |----------|--------|-------------| | gcc / clang | Linux | ELF | | gcc / clang | macOS | Mach-O | | cosmocc | Any x86_64/aarch64 | APE (Actually Portable Executable) |

Cosmopolitan APE binaries run on Linux, macOS, Windows, FreeBSD, OpenBSD, and NetBSD from a single file. Hull builds multi-architecture platform archives (make platform-cosmo) so the resulting APE binary is a true fat binary for both x86_64 and aarch64.

Architecture

┌─────────────────────────────────────────────┐
│  Application Code (Lua / JS)                │  ← Developer writes this
├─────────────────────────────────────────────┤
│  WASM Compute Plugins (WAMR)                │  ← Sandboxed data-plane computation
├─────────────────────────────────────────────┤
│  GPU Compute Shaders (wgpu-native)          │  ← Parallel data processing (optional)
├─────────────────────────────────────────────┤
│  Standard Library (stdlib/)                 │  ← cors, ratelimit, csrf, auth, jwt, session
├─────────────────────────────────────────────┤
│  Runtimes (Lua 5.4 + QuickJS)              │  ← Sandboxed interpreters
├─────────────────────────────────────────────┤
│  Capability Layer (src/hull/cap/)           │  ← C enforcement boundary
│  fs, db, crypto, time, env, http, gpu, tool │  ← audit logging (--audit)
├─────────────────────────────────────────────┤
│  Hull Core                                  │  ← Manifest, sandbox, signatures, VFS
├─────────────────────────────────────────────┤
│  Keel HTTP Server (vendor/keel/)            │  ← Event loop + routing + async + thread pool
│                                             │  ← gzip compression + client connection pool
├─────────────────────────────────────────────┤
│  Kernel Sandbox (pledge + unveil)           │  ← OS enforcement
└─────────────────────────────────────────────┘

Each layer only talks to the one directly below it. Application code cannot bypass the capability layer.

Standard Library

Hull ships a full set of middleware and utility modules for building secure backends:

| Module | Lua | JS | Purpose | |--------|-----|-----|---------| | cors | hull.middleware.cors | hull:middleware:cors | CORS headers + preflight handling | | ratelimit | hull.middleware.ratelimit | hull:middleware:ratelimit | In-memory rate limiting with configurable windows | | csrf | hull.middleware.csrf | hull:middleware:csrf | Stateless CSRF token generation/verification | | auth | hull.middleware.auth | hull:middleware:auth | Session-based and JWT-based authentication middleware | | session | hull.middleware.session | hull:middleware:session | Server-side sessions backed by SQLite | | cookie | hull.cookie | hull:cookie | Cookie parse/serialize helpers | | jwt | hull.jwt | hull:jwt | JWT sign/verify (HMAC-SHA256) | | template | hull.template | hull:template | HTML template engine with inheritance, includes, filters | | csv | hull.csv | hull:csv | CSV parse/encode (RFC 4180) | | search | hull.search | hull:search | Full-text search (SQLite FTS5) | | rbac | hull.middleware.rbac | hull:middleware:rbac | Role-based access control | | logger | hull.middleware.logger | hull:middleware:logger | Request logging with logfmt output and request IDs | | transaction | hull.middleware.transaction | hull:middleware:transaction | Wraps handlers in SQLite BEGIN IMMEDIATE..COMMIT | | idempotency | hull.middleware.idempotency | hull:middleware:idempotency | Idempotency-Key middleware with response caching | | outbox | hull.middleware.outbox | hull:middleware:outbox | Transactional outbox for reliable webhook delivery | | inbox | hull.middleware.inbox | hull:middleware:inbox | Inbox deduplication for incoming events/webhooks | | validate | hull.validate | hull:validate | Declarative input validation with schema rules | | form | hull.form | hull:form | URL-encoded form body parsing | | i18n | hull.i18n | hull:i18n | Internationalization: locale detection, translations, formatting | | health | hull.middleware.health | hull:middleware:health | Health check + readiness endpoints | | etag | hull.middleware.etag | hull:middleware:etag | ETag response helpers with 304 Not Modified | | json | hull.json | (built-in) | JSON encode/decode |

All middleware modules follow the same factory pattern: module.middleware(opts) returns a function (req, res) -> 0|1 where 0 = continue, 1 = short-circuit.

Background Timers

app.every(ms, fn) and app.daily("HH:MM", fn) register repeating background callbacks. Timer callbacks run on the event loop thread with full async support — hull.sleep(), http.fetch(), and db.* all work inside timers.

-- Flush outbox every 30 seconds
app.every(30000, function()
    outbox.flush()
end)

-- Clean up expired sessions daily at 2am UTC
app.daily("02:00", function()
    session.
View on GitHub
GitHub Stars17
CategoryDevelopment
Updated13d ago
Forks1

Languages

C

Security Score

90/100

Audited on Mar 28, 2026

No findings