What Will They Build For You?Install .Give Your Agents LIFE.
- Give agents high-level goals.
- They coordinate fully autonomously.
- Your projects improve themselves — while you sleep.
Want more fine-grained control?
Launch an SU agent and direct them.
How do we know it works?
Because was built by .
Private access · onboarding by invitation
real transcripts, pulled from the fleet's own coordination log — agents reviewing, unblocking, and handing off to each other.
The whole story, in 13 slides.
Why multi-agent coordination is the most neglected problem in AI, what we built to solve it, and what it took. Read it here, or take the PDF.
A live demo.
An Opus agent grades a Sonnet 5 agent while a Sonnet 5, a ChatGPT agent, and a local Ornith-35B pull work items off the queue. The grader runs a rubric to file a scorecard, the scorecard breeds an idea, the idea becomes a work item on the queue, and a fleet picks it up.
A guided tour of what's inside.
Not just for code.
Manage your business.
Manage your life.
Point a fleet at anything with a goal and a signal for what "good" looks like. Research desks, operations, trading, personal projects — the same plan → work → grade loop, aimed wherever you need it.

Same loop, any domain
Define what "good" looks like as a rubric, and the fleet plans, executes, grades its own output, and improves — whether the work is shipping code or watching a market.
Extendable to the core.
State-of-the-art engineering all the way down. itself is built on these same composable primitives — so anything the system does, you can extend or replace. Build it on your machine, then share your creations with the community in the Cupboard.

A pot is a whole project
A pot groups a hive of agents with their plans, memory, and settings into one self-contained project you can create from a repo, deploy to the cloud, or share on the Cupboard. Its genome is a blueprint; its state is a git repo.
# a pot = a blueprint (its genome) + a git repo + member harnesses + a knowledge pack # stand one up from an existing repo — it clones, detects the stack, and # seeds the matching knowledge so the agents start out oriented: pot:create_from_repo [email protected]:acme/api.git # …or from a blueprint, deployed straight to the cloud (or left local): pot:create blueprint: coding deployment: latitude · NYC · m4-metal-small knowledge: fastapi-conventions # add the harnesses that share this pot's memory: pot:add-member web # the dashboard pot:add-member worker # the queue consumer # the pot's shape lives in .papercusp/blueprint.yaml → see Blueprints # every change promotes dev → staging → main only when the tests pass
A blueprint defines how a pot works
A blueprint is the genome every agent in the pot inherits — the roles and the models they run on, the spine that routes work between them, reactive overlays, finalize gates, cost knobs, and how the blueprint grades and improves itself in the gym. Extend a built-in or write your own.
# .papercusp/blueprint.yaml — a coding pipeline. Extend a built-in, or write your own.
id: coding-pipeline
extends: base
workItem: { kind: feature, idPrefix: F }
dispatch: { concurrency: 4, priority: plan-order } # 4 features at once, in plan order
roles: # who's on the fleet, and the model each runs
- { id: director, description: "Emits the next verb each turn." }
- { id: scoper, model: opus, tools: [read, grep] }
- { id: worker, model: sonnet, tools: [edit, bash, test] }
- { id: validator, model: sonnet, tools: [bash, test] }
- { id: reviewer, model: opus, capabilities: [approve, request-changes] }
- { id: debugger, model: sonnet, tools: [read, bash], reactive: true }
- { id: curator, description: "Captures durable learnings on finalize." }
- { id: documenter, description: "Updates the docs on finalize." }
spine: # the director emits a verb; the edge routes it
decider: director
maxTurns: 200
default: { to: idle }
edges:
NEXT_SCOPER: { to: role, role: scoper }
NEXT_WORKER: { to: role, role: worker }
NEXT_VALIDATOR: { to: role, role: validator }
NEXT_REVIEWER: { to: role, role: reviewer }
DONE: { to: done }
ESCALATE: { to: escalate, reasonFrom: arg }
IDLE: { to: idle }
reactive: # a read-only debugger before a 3rd retry —
- role: debugger # without derailing the pipeline
when: { beforeRole: worker, minAttempts: 3, unless: debug-note }
preempt: false
gates: # the finalize recipe once a feature lands
finalize:
onDone: [curator, documenter]
onEscalate: [curator]
gym: # every blueprint declares how it's graded + improved
signals: [regressionsFromTests, plantedBugCaught]
rubric: { model: claude-opus-4-8, weights: { correctness: 0.5, process: 0.25, quality: 0.25 } }
knobs:
maxCostUsd: 25
releaseGate: { enabled: true } # promote dev → staging → main only when green
Like a library — for agents
A template is like a library, but for the agents that build with it. It ships the code a capability needs and a structured way to prompt the agents that use it — the decisions they must make, the rules they can't break, and a tiered build guide — so an agent picks it up and knows how to compose it, not just which files to drop. An app template scaffolds a whole project; an aspect template drops one capability into an app you already have.
# a template is a directory — the code, and how to build with it templates/papercusp-search/ components/ # the code it ships — the "library" half template.yaml # decision points + the rules a build must satisfy GUIDE.md # the build prompt, tiered MUST / SHOULD / FREE checks/ # tests that must pass before it counts as installed
The decision points and the guide are the prompt an agent composes against — questions it answers first, and rules a check enforces:
# template.yaml — the structured prompt the building agent reads
id: papercusp-search
scope: aspect
components: [search-index, search-box, result-list] # the code it ships
decisionPoints: # the agent answers these before it builds
- id: corpus
prompt: "Which entities are searchable, and what does a hit open?"
- id: freshness
prompt: "Re-index on write or on a schedule? What p95 target?"
checks: # must go green before it counts as installed
- { id: latency, run: checks/latency.test.ts }
- { id: reindex, run: checks/reindex.test.ts }
musts: # rules the build cannot violate
- { rule: "results return in under 50ms p95", enforcedBy: latency }
- { rule: "the index rebuilds on every write", enforcedBy: reindex }
A shelf of official templates ships preinstalled — the same ones PaperCusp is built from.
# materialize a template into a pot — from the Cupboard shelf, or templates:new-app. # a whole-app template scaffolds a new pot; an aspect template adds one capability. templates:new-app template: papercusp-webapp # a whole app: scaffold + a builder agent templates:new-app template: papercusp-search # an aspect: its code + build-guide, ready to compose # ── whole-app templates (preinstalled) ────────────────────────── # papercusp-agentic-desktop-app desktop app + the agent judgment plane # papercusp-desktop-app plain desktop app — Tauri + embedded Postgres # papercusp-webapp the browser twin — Next.js host, no agents # ── aspect templates (preinstalled) ───────────────────────────── # papercusp-search hybrid lexical + semantic retrieval # papercusp-ui operator-style SPA kit — grids, dock layout # papercusp-data-layer app-owned embedded Postgres + typed write gates # papercusp-ops-pots the agent judgment plane — a hive + an -ops hive # papercusp-release-pipeline channels, signing, updater feeds, build matrix # papercusp-tauri-desktop-shell the deterministic desktop chassis # papercusp-web-host the Next.js web chassis
Wire in an outside system
A plugin is a typed object — no wrapper function. It contributes MCP tools the fleet calls, declarative reflexes that fire those tools, its own API routes, lifecycle hooks, and a live terminal pane. Connect Linear, Slack, or your own service and the fleet drives it like any other capability.
import type { Plugin } from "@papercusp/plugin-sdk"
import { Hono } from "hono"
const linear: Plugin = {
name: "linear",
version: "1.0.0",
papercusp: "^0.1",
// declarative permissions — the fleet only ever gets what's listed here
capabilities: [
"http:fetch:api.linear.app",
"events:listen:work_items:complete",
],
// 1 — MCP tools the fleet can call, exactly like any built-in tool
tools: {
"linear:sync": syncIssue,
"linear:close": closeIssue,
},
// 2 — reflexes: a declarative rule fires one of this plugin's own tools
reactions: [
{ id: "close-on-done", on: "work_items:complete", fire: "linear:close",
args: (e) => ({ id: e.result.data.externalId }) },
],
// 3 — mount a real API route (a Hono app at /api/plugins/linear/*)
apiRoutes: new Hono().post("/webhook", handleWebhook),
}
export default linear
Bundle tools to share
Group related tools into one versioned, runtime-less pack. Publish it on the Cupboard and any pot installs the whole set at once, ready to compose into bigger tools. A pack ships tools plus pure data: the event families its tools emit, and the tools or events it depends on — resolved at install time. The reflexes that wire them up still ride a plugin.
// a pack is a runtime-less bundle of tools — kind:"pack".
// (the loader rejects UI, reactions, and hooks on a pack: those ride a plugin.)
import type { Plugin } from "@papercusp/plugin-sdk"
const pack: Plugin = {
kind: "pack",
name: "repo-hygiene",
version: "1.2.0",
papercusp: "^0.1",
capabilities: ["repo:read"],
tools: {
"repo:stale-branches": staleBranches, // typed + capability-gated
"repo:orphan-files": findOrphans,
"repo:dead-code": findDeadCode,
},
// pure DATA, so a runtime-less pack may carry it: declare the event
// family a tool emits and it merges into the fleet's events:catalog —
// any agent can await it, any reaction can key off it.
provides: {
events: [{
family: "repo-hygiene:sweep-done",
keyTemplate: "repo-hygiene:sweep-done:",
params: [{ name: "repo", required: true, describe: "repo the sweep ran on" }],
describe: "a hygiene sweep finished for ",
}],
},
// dependencies resolve at install time against the Cupboard catalog —
// a missing provider blocks the install, unless marked optional.
dependencies: {
events: [{ family: "git-activity:push-seen", optional: true }],
},
}
export default pack
Ship hard-won knowledge
Package the conventions and lessons a project has learned into a knowledge pack. Install it into a new pot and its agents start out already knowing how you work — scoped and typed so recall stays sharp.
# a knowledge pack is a directory: a manifest + one file per learning. knowledge-packs/fastapi-conventions/ manifest.yaml pin-tests-to-a-transaction.md errors-are-problem-json.md prefer-ruff-over-flake8.md # manifest.yaml id: fastapi-conventions title: FastAPI house style version: 2.0.0 # pin-tests-to-a-transaction.md — frontmatter, then the lesson itself --- title: Pin each test to a rolled-back transaction kind: feedback # user · feedback · project · reference --- Wrap every test in a DB transaction and roll it back on teardown — never share state between tests. # install it from the Cupboard → new agents in that pot # start out already knowing how you work.
Add a capability with a typed schema
A tool is a typed function the agents can call through the MCP server — a validated input schema, a capability gate, usage guidance, and a run function with a rich context.
defineTool({
name: "repo:stale-branches",
description: "List branches with no commits in the last N days.",
capability: "repo:read", // gated per role
input: z.object({
days: z.number().default(30),
exclude: z.array(z.string()).default(["main", "release/*"]),
}),
guidance: { when: "before a cleanup pass", notWhen: "mid-release" },
run: async ({ days, exclude }, ctx) => {
const stale = await ctx.git.branchesOlderThan(days, exclude)
return { count: stale.length, branches: stale }
},
})
And agents compose existing tools into new ones — calling them exactly the way they call any tool — so the harness extends itself.
// a composed tool: one new capability built from existing ones,
// publishable to the Cupboard like any other tool
defineTool({
name: "repo:cleanup",
description: "Prune stale branches and orphaned files in one pass.",
capability: "repo:write",
input: z.object({ days: z.number().default(30) }),
run: async ({ days }, { tools }) => {
const stale = await tools.repo.staleBranches({ days })
const orphans = await tools.repo.orphanFiles()
return { pruned: stale.count + orphans.length }
},
})
Every tool declares its effect — and a write tool can be dry-run first, so an agent (or you) previews exactly what it would change before anything commits.
defineTool({
name: "repo:cleanup",
effect: "write", // read | write — write tools can preview
capability: "repo:write",
input: z.object({ days: z.number().default(30) }),
run: async ({ days }, ctx) => { /* … */ },
})
// preview the mutation without touching anything:
code:run { script: "return repo.cleanup({ days: 60 })", dryRun: true }
// → the writes it WOULD make, nothing committed
Agents orchestrate many tools in one code:run script — one round-trip instead of many — and a script worth keeping is saved as a recipe any other agent can find and re-run. With ~550 tools in the catalog, an agent finds the right one by intent.
// one script, many tools, one round-trip — kept as a reusable recipe
code:run { script: `
const stale = await tools.repo.staleBranches({ days: 60 })
const orphans = await tools.repo.orphanFiles()
return { pruned: stale.count + orphans.length }
` }
// → runs now, and is saved: recipes:search { query: "prune repo" }
// don't know the tool's name? find it by what you want to do:
tools:find { query: "delete stale git branches" }
// → ranks the ~550-tool catalog by intent; tools:invoke runs the match
React to what the fleet does — declaratively
Everything the system does emits an event. Define a reaction as data — on an event, when a condition holds over it, fire an action — and publish it to the Cupboard. The condition grammar is the advanced part: dot-path tests over the event, all / any nesting, and k-of-n thresholds, so most reflexes never touch code.
# a reaction is data: on an event → when a condition holds → fire a tool.
# it rides a plugin (or a blueprint's `reactive`), portable via the Cupboard.
reactions:
# a shipped bug locks in a regression test
- id: bug-locks-regression
on: work_items:complete
when: { args.kind: bug }
fire: work_items:create
args: { kind: task, title: "Regression test for {args.id}" }
# page a human the moment a critical or security bug is filed
- id: page-on-critical-bug
on: work_items:create
when:
all:
- { args.kind: bug }
- any:
- { args.severity: { in: [critical, major] } }
- { args.tags: { contains: security } }
fire: coord:escalate
args: { severity: blocker, summary: "critical bug filed: {args.title}" }
The same grammar composes the other direction — an agent can await a whole tree of events, sleeping until it's satisfied instead of polling, with all / any / k-of-n nesting and per-event conditions.
// sleep until the release is truly out — a composite of real events
await events.await({
spec: { all: [
{ event: "release:green:papercusp" }, // the gate went green
{ any: [
{ event: "release:deployed:abc123" }, // the deploy landed…
{ event: "git-sync:committed:abc123" }, // …or at least committed
] },
{ some: { require: 2, of: [ // and 2 of 3 services are back
{ event: "service:up:operator" },
{ event: "service:up:gateway" },
{ event: "service:up:vite" },
] } },
] },
timeout_sec: 3600,
note: "release fully out",
})
An agent emits its own event with the events:emit tool — and any reaction or events.await can key off it, so the fleet's signals compose end to end.
Define your own first-class entity
The fleet tracks features, bugs, and tasks out of the box — but you can declare an entity type of your own, with a typed payload and its own self-improvement surface. Define a "bet" or a "forecast" and it inherits the whole machine: a work queue, scorecards, and a gym that grades and tunes how the fleet produces it.
// declare it with meta:define-datatype — a new kind of work
// the fleet tracks, and improves at
defineDatatype({
name: "bet",
tier: "generic-kind", // or first-class: its own SQL table
workItemKind: "bet-analysis",
payload: z.object({ // typed + validated on every write
venue: z.enum(["kalshi", "polymarket"]),
market: z.string(),
edge: z.number(), // our price − the market's
stake: z.number(),
}),
// the part that makes it self-improving, not just tracked:
selfImprovement: {
scorecard: [
{ metric: "calibration", weight: 0.6 }, // was the edge real?
{ metric: "risk-control", weight: 0.4 },
],
gym: { // the fleet tunes how it prices bets
signals: [brierScore, realizedPnl],
rubric: { model: "claude-opus-4-8" },
},
},
})
Make “good” a versioned artifact
A rubric is the shared standard the fleet grades its own work against — not a vibe, a spec. Each criterion says how the thing should work, how to check it, and what drift looks like. Agents file evidence-backed scorecards against it, and the trend tells you whether quality is climbing or slipping.
# the standard every output is graded against —
# proposed, ratified, then versioned like code
rubrics.propose({
rubricId: "api-endpoint-quality",
characteristic: "http-surface",
criteria: [
{ key: "error-shape",
model: "4xx / 5xx bodies are RFC-7807 problem+json",
method: "hit each route with a bad request; assert the body",
driftMarkers:"a bare string, or an HTML error page" },
{ key: "idempotency",
model: "PUT / DELETE are safe to retry",
method: "fire the same write twice; final state must match",
driftMarkers:"a second call double-applies" },
],
ratingScale: ["healthy", "degraded", "broken"], // each rating needs evidence
})
What Will They Build For You?
is in private access while we onboard partners one at a time. Tell us what you'd point it at, and we'll set you up.
Request private access
Leave your email and a line about what you'd point at — we onboard partners one at a time and will reach out.
Thanks — we'll be in touch at .
Couldn't reach the server. Please try again, or ping us on Discord.
We'll only use this to set up your access.






























