File-authored Agents
A file-authored agent keeps its declarative behavior in a folder and compiles that folder into an immutable, content-addressed Agent Artifact. Production execution binds the artifact to a Runtime Revision and pins that exact pair to the conversation thread.
The runnable example is in
apps/examples/file-agent-chat.
It uses gpt-4.1-mini and exercises the generated Node server through kuralle chat.
Author the folder
Section titled “Author the folder”agent/ instructions.md # required agent.json # serializable identity, model, and limit fields tools/**/*.ts flows/**/*.flow.json # or *.ts policies.ts skills/<name>/SKILL.md skills/<name>/references/** references/** workspace/** subagents/<id>/**Those nine names are the complete slot set (ROOT_SLOTS in
@kuralle-agents/build). An unknown slot fails the build, as do symlinks,
case-fold collisions, malformed exports or skills, recognizable credentials, and
quota violations. policies.ts must export at least one policy phase —
input, output, tool, refine, or validate.
Tool, flow, and policy modules are parsed during discovery and statically imported only by the generated runtime bundle; the control plane never executes uploaded TypeScript.
flows/*.flow.json files are declarative FlowDefinition graphs. The compiler validates each one
strictly and embeds it inline in the artifact — a bad flow fails the build and names the dotted
issue path. TypeScript modules under flows/ still compile to capability references resolved from
the host runtime.
references/** becomes a read-only /references mount. workspace/** is copied exactly once into
the thread-private /workspace mount — Node keys that directory by tenant, thread, and agent, while
a Cloudflare thread Durable Object owns its own SQLite workspace. Artifact metadata is kept outside
the visible mount, and model writes stay disabled unless the host opts in. Skill bodies and
resources remain progressively loaded content.
Build the immutable Node deployment
Section titled “Build the immutable Node deployment”From the repository root:
bun packages/cli/src/cli.ts build \ --agent apps/examples/file-agent-chat/agent \ --target node \ --default-model openai/gpt-4.1-mini \ --host apps/examples/file-agent-chat/deployment.node.ts \ --out apps/examples/file-agent-chat/.kuralleThe output contains the canonical artifact, content-addressed blobs, a manifest, a bundled
node/server.mjs, and a non-root production Dockerfile. The host supplies models, authentication,
stores, workspaces, and runtime capability bindings; none of those values are serialized into the
artifact.
The host module's default export is called with:
{ artifacts, // canonical root and subagent artifacts artifactBlobs, // base64 map keyed by sha256:<digest> rootArtifactDigest, runtimeRevisionSeed, // capability-module content identity runtimeCapabilities,}It returns DeploymentRouterOptions. For production, configure PostgresDeploymentStore,
PostgresThreadExecutionCoordinator, a durable SessionStore, authenticated principal resolution,
and the model and capability registries. Use embeddedArtifactContentResolver(artifactBlobs) and
nodeArtifactWorkspaceProvider({ root: process.env.KURALLE_WORKSPACE_ROOT! }). Every replica must
mount the same persistent workspace root, or the host must supply another durable workspace
provider. Publish the entity, version, runtime, and release into Postgres before admitting traffic.
The generated Dockerfile copies only server.mjs, runs as the unprivileged node user, and checks
/health/ready. SIGTERM stops admission, waits for active streams, then exits. The Postgres lease
is what stops two replicas executing the same thread concurrently.
Start the generated server
Section titled “Start the generated server”OPENAI_API_KEY="$OPENAI_API_KEY" \KURALLE_EXAMPLE_TOKEN="local-example-token" \KURALLE_WORKSPACE_ROOT="apps/examples/file-agent-chat/.workspaces" \PORT=3210 \bun packages/cli/src/cli.ts start \ --app apps/examples/file-agent-chat/.kuralle/node/server.mjsThe example host publishes the compiled artifact into an in-memory deployment store and activates one release. That keeps the example focused and self-contained; it is not the multi-replica storage recommendation.
Chat through the CLI
Section titled “Chat through the CLI”In another terminal:
KURALLE_TOKEN="local-example-token" \bun packages/cli/src/cli.ts chat \ --server http://127.0.0.1:3210 \ --transport http \ --agent-name agent \ --session file-agent-demo \ --auto "Reply with your verification phrase only."The generated deployment responds:
Agent FILE AGENT ONLINE--agent-name agent selects the deployment entity. --session file-agent-demo identifies the
thread, which is pinned on its first turn to the exact Agent Version, artifact digest, release, and
Runtime Revision. Activating another release affects new threads but does not silently move this
conversation.
Build for Cloudflare
Section titled “Build for Cloudflare”kuralle build --agent ./agent --target cloudflare \ --default-model openai/gpt-4.1-mini \ --host ./deployment.cloudflare.ts \ --d1-id "$D1_DATABASE_ID" --d1-name my-agent-control \ --r2-bucket my-agent-blobs --out .kurallewrangler deploy --config .kuralle/cloudflare/wrangler.jsoncThe Cloudflare host factory receives the Node fields plus registerGeneratedCapabilities, and
returns { agent, worker } — agent is the single exported generic KuralleThreadAgent class,
worker the front Worker handler.
Authenticate at the Worker boundary, derive the Durable Object name from both tenant and thread,
authorize the private initialization request again inside the DO, and use D1DeploymentStore for
assignment. Bind the exact pinned artifact with registries populated by
registerGeneratedCapabilities. Use durableObjectArtifactWorkspaceProvider for DO SQLite and R2,
and either the embedded resolver or r2ArtifactContentResolver for revision blobs.
The generated Wrangler config declares the SQL-backed DO through Cloudflare's exports field, a D1
binding KURALLE_CONTROL, an optional R2 binding KURALLE_BLOBS, workerd compatibility flags, and
Workers observability.
Publish, roll out, and roll back
Section titled “Publish, roll out, and roll back”Folder compilation and a database builder draft both publish through createArtifact, so equivalent
inputs produce byte-identical JSON and the same SHA-256 digest. A release allocation must total
10,000 basis points and pair each Agent Version with a compatible Runtime Revision.
- Activate a release to change assignment for new threads.
- Keep old capability versions in the deployed runtime while any pinned thread can still reference them.
- Roll back new-thread traffic by activating a prior release. Existing thread pins do not move.
- Treat Worker or container rollback separately from release rollback. A code rollback is unsafe if it removes a runtime revision a pin still names.
- Cloudflare DO SQLite migrations are forward operations. Test migration and Worker rollback combinations before a production rollout.
Observe and operate
Section titled “Observe and operate”Every runtime span carries tenant, entity and version, artifact digest, release, runtime revision, environment and branch, and config and secret generations. Conversation audit events are persisted in the dedicated audit store and retain an inline crash-safe copy — audit is not inferred from traces.
Alert on readiness failures, lease renewal failures, binding or content verification failures, stream errors, DO initialization conflicts, D1 and R2 errors, and drain timeouts. Logs must not contain prompts, workspace bytes, tool arguments, tokens, or resolved secrets by default. Retain the build manifest, artifact JSON, runtime bundle digest, migration tag, and release record for every deployment.
Move the host to production storage
Section titled “Move the host to production storage”Replace the example's in-memory deployment/session stores and process-local lease with Postgres implementations before running multiple replicas. Keep schema changes in your application's existing migration workflow. See Agent Definitions in Your Database for Postgres, Prisma, Drizzle, Neon, and Cloudflare control-plane patterns.
Related
Section titled “Related”- Agent Plugins — third-party capability bundles this agent can load at runtime
- Skills — how the
skills/folder is progressively disclosed - CLI —
kuralle build,start, andchat - Deployment — artifacts, revisions, and thread pinning
- Agent Definitions in Your Database — production control plane