Customer deployment contract #
deployment/manifest.json versions the installation contract; wrangler.jsonc
is its executable platform configuration. pnpm build:release builds Octane,
bundles the customer entry with Wrangler without deploying, and writes
dist/release/. The lockfile pins the build dependencies. Use the pinned Node
and pnpm versions. Rebuilds with identical inputs produce identical file hashes;
there are no timestamps or account credentials in the artifact.
The artifact contains worker/ modules, assets/ bytes, a portable
deployment.json, and manifest.json with release/configuration/schema versions,
source revision, lockfile SHA-256 and a sorted file inventory. manifest.sha256
hashes the exact UTF-8 manifest bytes, including its trailing newline. Each file
entry hashes its raw bytes with SHA-256. The digest identifies the release;
the human version is not an integrity check. A trusted release publisher must
distribute the expected manifest digest separately. Installers must verify that
digest, every file hash/size, supported schema/configuration versions and safe
relative paths before upload. An adjacent checksum is not a signature.
Publish from a clean checkout; sourceDirty flags modified tracked files during
local validation. Wrangler preserves class names (keep_names) because native
Agent facets resolve their constructors by name.
Publisher release storage #
The control-plane Worker embeds a catalog of trusted release identities and file
inventories, never release modules or asset bytes. Its private
RELEASE_ARTIFACTS R2 binding uses the flarebot-release-artifacts bucket.
Every object is addressed as releases/<manifest-sha256>/<path>; that includes
manifest.json. At load time the control plane reads the R2 manifest, verifies
its digest against the pinned ReleaseIdentity, requires its file inventory to
match the embedded trusted inventory, then reads and hashes every declared file
before an installer can perform an external customer write. Browser assets have
no binding or route to this bucket.
Before deploying a control-plane build, create the private bucket once and publish the clean artifact:
pnpm publish:release-artifacts -- --bucket=flarebot-release-artifacts
FLAREBOT_RETAINED_RELEASES=/secure/archive/dev.28 pnpm build:control-plane
pnpm exec wrangler deploy --config wrangler.control-plane.jsonc
The publish command uploads and re-reads every digest-addressed byte before it
writes the version record and releases/latest.json pointer. It refuses a
version that was previously published with a different identity (and checks the
current pointer as a migration guard). Do not give this bucket public access.
The command intentionally requires an explicit bucket; running it accesses
Cloudflare, so CI/local validation should use build:control-plane:fixture
instead.
Keep an archived dist/release directory for every desiredRelease that can
still be in flight and supply those directories through
FLAREBOT_RETAINED_RELEASES or repeated --retain=<directory> arguments when
building the next control-plane catalog. The current dist/release is always
last and therefore remains the latest-release API result. A retained catalog
entry is selected only by the complete pinned identity; a missing R2 object
fails as artifact_unavailable rather than retargeting recovery to latest.
Remove a retained entry and its R2 prefix only after no installation or workflow
can reference it. R2 object retention/production access policy is an operational
requirement; this repository does not create or delete remote resources.
The portable config uses no_bundle and paths relative to the artifact. A manual
deployment can supply --config dist/release/deployment.json --name flarebot-<installationId> and CLOUDFLARE_ACCOUNT_ID; the installer will translate
the same platform fields to the Workers API and upload these exact modules and
asset bytes. Asset-upload protocol hashes/JWTs are generated during installation;
the SHA-256 inventory is the release integrity contract, not the Cloudflare
asset-upload manifest. Deployment requires a customer-authorized account grant.
Never put that grant into the release or customer Worker.
Resources and stable identities #
| Resource | Required configuration and purpose |
|---|---|
| Customer Worker | flarebot- plus a once-generated 32-character lowercase hex installation ID; immutable across upgrades. Owns Octane SSR and runtime exports. |
| Static assets | ASSETS, bundled from dist/client; served by Workers static assets. |
| Durable Object | Binding and class PersonalAgent, instance name personal, SQLite storage in the customer account. Parent metadata, settings, memory and tasks belong here; native Conversation child facets own transcripts and workspaces. |
| Workers AI | AI; the default inference path needs no provider API key. |
| Browser Run | BROWSER; required for the v0.1 browser tools. |
| Worker Loader | LOADER; required by native Code Mode research orchestration. |
Conversation is also exported in the Worker code so native subAgent can create
its child facets. It has no top-level binding or declarative namespace entry.
Every conversation facet has separate customer-owned SQLite storage, colocated
under the personal parent. Preserve the child class name and native registry IDs
across upgrades as well as the parent namespace. The release build keeps class
names and tests both exports without provisioning a second namespace.
The parent SQLite namespace is provisioned through declarative exports. Reapplying the same
declaration preserves its namespace. Never mix exports with legacy migrations,
rename classes casually, or delete namespaces during an upgrade. Application
SQL migrations remain separate. See the Cloudflare lifecycle reference.
Browser research uses Browser Run; Worker Loader remains declared for native
Code Mode integration. Temporary shell execution requires the native Sandbox
SQLite namespace and a Containers application. The release pins
@cloudflare/sandbox@0.12.9 and its immutable public Docker Hub image, with a
lite instance type and maximum four containers. Node.js/Bun/Bash are available;
this image does not promise Python. No image build, push or customer registry
credential is required. See manifest.shell and deployment.json.containers.
The later installer must use a stable application name such as
flarebot-shell-<installationId>, upload native metadata.containers linking
Sandbox, resolve that exact Worker/class namespace, and provision/reconcile
its native Containers application. Workers Paid and a deployment grant with
Containers write permission are prerequisites. On image changes the native
application update needs an explicit rollout; Worker upload alone cannot mark an
installation ready. Verify image boot/SDK compatibility before readiness, and
preserve the owned application ID/namespace across upgrades. Do not retarget an
unrelated application on a name collision. The release contains no account IDs,
namespace IDs or deployment credentials. Full onboarding/orchestration remains
in its assigned issues.
The native API base is /accounts/{account}/containers: GET/POST
/applications, PATCH /applications/{id}, then POST
/applications/{id}/rollouts for image/configuration rollout. Match Wrangler's
verified API contract and OAuth scope discovery when implementing the installer;
these calls have not been exercised against a customer account by this issue.
See native deployment
and Sandbox configuration.
No separate D1, KV, queue, cron trigger or Workflow is provisioned. Native Agent
scheduling uses Durable Object alarms. Image/PDF uploads use the private ATTACHMENTS R2 binding for workspace spillover. The installer provisions flarebot-attachments-<installationId> and retains that binding across upgrades. Manual deployments must create a private bucket and set the portable r2_buckets entry to its name.
Configuration and account boundaries #
Required installation inputs are account ID, stable installation ID and owner
subject, exact customer/control-plane HTTPS origins, an independent customer
session secret, and an authorized deployment grant. The installer supplies
FLAREBOT_MODE=customer-runtime, FLAREBOT_ENV=production and the versioned
FLAREBOT_INSTALLATION JSON variable described in
configuration and secrets, plus FLAREBOT_SESSION_SECRET
through the Worker secrets API. These installation-specific values are excluded
from the portable release. The grant authorizes deployment only and must never
become a customer binding. An unconfigured artifact returns HTTP 503 before SSR.
The personal Agent exposes authenticated HTTP/WebSocket routes at
/agents/personal-agent/personal. Its SQLite metadata and native SDK state survive
disconnects and runtime restarts; see personal runtime for the
session boundary and client integration. Production session issuance is connected
by the later OAuth onboarding bridge. Provider keys are optional customer input,
never build inputs.
The customer entry is worker/index.ts; it imports only the generated Octane
fetch handler plus customer runtime modules. Future control-plane code/configs
must be separate entries and artifacts, never imported into this graph. The
control plane may retain ownership/account/resource/version/update metadata and
protected authorization grants, but not customer conversations, keys or files.
Observability is disabled by default to avoid capturing customer content in logs.
Upgrades reuse the recorded Worker name, namespace and instance identity. Preserve
customer variables (keep_vars) and secrets (API keep_bindings in the manifest),
check ownership/collisions before writes, and apply only supported forward schema
changes. Code rollback does not undo storage changes. Local dry-runs prove bundle
and configuration validity; account entitlement and actual provisioning require
the later installer checks. Nothing in the release build creates resources.