gateproof

Make agent work falsifiable.

prd.ts defines intent. Gates verify reality. CI ships only with evidence.

$ bun add gateproof
gate.ts
      import { Gate, Act, Assert } from "gateproof";
import { setFilepathRuntime, CloudflareSandboxRuntime, createFilepathObserveResource } from "gateproof";
import { getSandbox } from "@cloudflare/sandbox";

setFilepathRuntime(new CloudflareSandboxRuntime({
  getSandbox: (cfg) => getSandbox(env.Sandbox, `agent-${cfg.name}`),
}));

const result = await Gate.run({
  name: "waitlist-signup",
  observe: createFilepathObserveResource(container, "waitlist-feature"),
  act: [Act.agent({
    name: "waitlist-feature",
    agent: "claude-code",
    model: "claude-opus-4-6",
    task: "Add the waitlist: landing form that POSTs to /api/waitlist, persist email in KV, show thank-you and current count.",
    timeoutMs: 300_000,
  })],
  assert: [
    Assert.hasAction("commit"),
    Assert.hasAction("done"),
    Assert.authority({
      canCommit: true,
      canSpawn: false,
      forbiddenTools: ["delete_file"],
    }),
  ],
  stop: { maxMs: 300_000 },
});

if (result.status !== "success") process.exit(1);
    

Agent gates

Spawn AI agents in isolated Cloudflare Sandbox containers. Observe their NDJSON event stream. Assert governance policies against their actual behavior — commits, tool calls, spawns.

Run an agent gate

PRD-driven loops

Define intent as stories with gates. Run them in dependency order. If a gate fails, an agent fixes the code and the loop re-runs — until all gates pass or you hit max iterations.

Run in a loop

Authority assertions

Assert.authority() checks what the agent actually did against what you allowed. Did it commit when forbidden? Spawn child agents? Use a banned tool? The gate fails.

API reference

Observe from production

Point a gate at Cloudflare Analytics or Workers Logs. Run actions (browser, exec), collect logs, assert on evidence.

gate.ts
      import { Gate, Act, Assert } from "gateproof";
import { CloudflareProvider } from "gateproof/cloudflare";

const provider = CloudflareProvider({
  accountId: process.env.CLOUDFLARE_ACCOUNT_ID!,
  apiToken: process.env.CLOUDFLARE_API_TOKEN!,
});

const result = await Gate.run({
  name: "signup-e2e",
  observe: provider.observe({ backend: "analytics", dataset: "worker_logs" }),
  act: [Act.browser({ url: "https://app.example.com/signup" })],
  assert: [Assert.hasAction("user_created"), Assert.noErrors()],
  stop: { maxMs: 15_000 },
});
if (result.status !== "success") process.exit(1);
    

PRD loops

Define stories with gates. An agent (OpenCode Zen, set OPENCODE_ZEN_API_KEY) iterates until every gate passes.

prd.ts
      import { definePrd, runPrdLoop, createOpenCodeAgent } from "gateproof/prd";

// Set OPENCODE_ZEN_API_KEY or pass apiKey
const agent = createOpenCodeAgent({
  apiKey: process.env.OPENCODE_ZEN_API_KEY,
  model: "gpt-5.3-codex",
});

const prd = definePrd({
  stories: [
    { id: "user-signup", title: "User can sign up", gateFile: "./gates/signup.gate.ts", scope: { allowedPaths: ["src/routes/**"] } },
    { id: "email-verify", title: "Email verification works", gateFile: "./gates/email.gate.ts", dependsOn: ["user-signup"] },
  ],
});

await runPrdLoop(prd, { agent, maxIterations: 7 });