Kints is building something for developers.
It isn’t ready to be seen yet. Leave your email and you’ll hear first when the lights come on.
// ── src/agent.ts ─────────────────────────── // kints: agents that build, in a box they can't leave import { plan, observe } from "./loop"; import { act } from "./tools"; import { Cell } from "./cell"; const POLICY = { net: "none", fs: "ro", ttl: 300 }; const MAX_STEPS = 64; export async function run(task, { signal } = {}) { const cell = await Cell.open(POLICY); try { for (let i = 0; i < MAX_STEPS; i++) { if (signal?.aborted) break; const next = await plan(task, cell.state); if (next.done) return next.result; const out = await act(cell, next.tool, next.args); task = observe(task, out); // read what it did } } finally { await cell.close(); // nothing leaves the cell. } } // ── crates/cell/src/lib.rs ───────────────── //! Cell: a sandbox an agent can't talk its way out of. pub struct Policy { pub egress: Egress, // deny by default pub root: Mount, // read-only. one scratch dir. pub cpu_ms: u64, pub mem_mb: u32, pub ttl_s: u32, // every cell dies young } pub fn spawn(cmd: &Cmd, p: &Policy) -> Result<Exit, Denied> { if cmd.wants_secret() { return Err(Denied::Secret); // keys stay out } seccomp::strict()?; Cell::new(p)?.exec(cmd) } pub const TAG: u8 = 0x6b; // "k". you knew that. // ── policies/default.toml ────────────────── # least privilege. then a little less. [egress] allow = [] # nothing leaves unless you say so [fs] root = "ro" scratch = "/work" # wiped after every run [secrets] inject = "never" # a handle, never the key [limits] cpu = "30s" memory = "512M" steps = 64 [audit] log = "every-call" # if it ran, it's written down // ── src/tools.ts ─────────────────────────── import { audit } from "./audit"; export const tools = { shell: (cell, cmd) => cell.exec(cmd, { ttl: 30 }), edit: (cell, p) => cell.fs.patch(p.path, p.diff), test: (cell) => cell.exec("make test"), // ship: not until the lights come on ship: () => { throw new Error("not yet."); }, }; export async function act(cell, name, args) { if (!Object.hasOwn(tools, name)) { return { error: `no tool named ${name}` }; } const call = audit.open(name, args); // on the record try { return await tools[name](cell, args); } finally { audit.close(call); } } // ── src/receipt.ts ───────────────────────── // every run leaves a receipt. sign it. export function receipt(run) { return sign({ task: hash(run.task), steps: run.calls.length, exit: run.exit, egress: run.egress.length, // should be 0 took: run.ms, }); } // ── scripts/build.sh ─────────────────────── #!/usr/bin/env sh set -eu # build in a cell. test in a cell. ship from a cell. LIGHTS=${LIGHTS:-off} kints cell run --net=none --ro -- make build kints cell run --net=none --ro -- make test if [ "$LIGHTS" = "off" ]; then echo "not yet." # come back soon exit 0 fi kints ship --signed # psst: curl kints.ai // ── notes.md ─────────────────────────────── // - the gap in the k is on purpose // - agents get a cell, never the keys // - deny first. allow on purpose. // - every run leaves a receipt // - every signup gets a number. be kind to them. // - view source should reward you /* if you can read this, you're early. */
It isn’t ready to be seen yet. Leave your email and you’ll hear first when the lights come on.