Skip to content

feat(deployment): host persistent Apps on Workers for Platforms #423

Description

@Yevanchen

Summary

Use Cloudflare Workers for Platforms (WfP) as the production substrate for persistent Mosoo App deployments, and connect deployed Apps to Mosoo's existing Public Thread API instead of reducing Agent access to a text-only call.

This is intentionally separate from #281: that issue owns ephemeral preview/validation. This issue owns the production decision and implementation for long-lived, multi-tenant App releases.

Problem

The current Worker deployment path is an alpha implementation built around one ordinary Cloudflare Worker per App:

  • app-deployment-executor.service.ts accepts only a self-contained .js/.mjs entry and uploads one module.
  • app-deployment-cloudflare-client.ts sends one module, plain_text vars, and a fixed compatibility date.
  • the detector can return worker_with_assets, but the Worker executor does not upload or bind those assets.
  • compatibility flags, additional modules, platform-managed bindings, immutable releases, and atomic promotion are not represented.

The current Deployment Agent binding is also narrower than Mosoo's existing API. It injects a deployment-scoped POST /api/v1/bound/:token capability for a synchronous text call, while the Public Thread API already supports:

  • multipart file upload up to 64 MiB with POST /agents/{agentId}/files;
  • mounting uploaded files through message resources;
  • queued Runs with snapshot polling or SSE event streaming;
  • listing Thread attachments and Agent artifacts;
  • binary artifact download with GET /files/{fileId}/content.

Yevanchen/mosoo-codex-pet needs both boundaries: WfP for its full-stack Worker package and the existing Public Thread API for avatar upload, asynchronous progress, and ZIP artifact delivery. No new Agent runtime or parallel file/async protocol is required.

Proposed production shape

  1. Create one production dispatch namespace and one staging namespace, rather than a namespace per tenant or App.
  2. Put authentication, hostname/App lookup, deployment-state checks, rate limiting, and active-release routing in a platform-owned dispatch Worker.
  3. Upload every successful DeploymentRun as an immutable User Worker release, for example <app-id>:<run-id>.
  4. Upload Worker modules through multipart metadata; preserve an allowlisted compatibility_date and compatibility_flags.
  5. Upload static assets through the WfP asset upload session and attach the resulting assets binding to the User Worker.
  6. Create only explicit platform-managed bindings. Do not treat an uploaded wrangler.toml as authority to provision arbitrary Cloudflare resources.
  7. Smoke-test the new release, then atomically switch the App's active-release pointer. Keep the previous release for rollback and delete expired releases through a bounded retention policy.
  8. Run User Workers in untrusted mode with per-App CPU/subrequest limits and deployment tags. Use an outbound Worker where egress logging, filtering, or credential injection is required.
  9. Make each declared Agent binding expose the existing Public Thread API contract through a deployment-scoped, revocable integration. Reuse pkgs/public-api-client; do not create another text/file/run protocol.
  10. Keep the owner's Mosoo API token out of repository code and User Worker-visible environment. Use platform-managed credential injection or an equivalent scoped capability, while preserving Deployment deletion/revision revocation and Run attribution.

Why WfP

WfP provides the platform primitives the current implementation is rebuilding manually: a dynamic dispatch Worker, isolated multi-tenant User Workers, bindings, tags, custom limits, static assets, and an optional outbound Worker.

It also has constraints that must shape the design:

  • User Workers do not support gradual deployments, so promotion/rollback must use immutable releases plus a routing pointer.
  • untrusted mode restricts some request.cf and cache behavior.
  • outbound Workers disable direct TCP connect() for User Workers.
  • namespace/API limits, lifecycle cleanup, reconciliation, and cost still remain Mosoo responsibilities.

Acceptance criteria

  • Add an ADR and update deployment docs to distinguish persistent WfP hosting from poc(deployment): evaluate Dynamic Workers for ephemeral Agent validation #281 ephemeral validation.
  • Run a remote WfP spike in a Mosoo-owned Cloudflare account and record namespace, dispatch, User Worker, asset, binding, delete, and tag behavior.
  • Record measured request/CPU usage and expected platform cost before production enablement.
  • Deploy a bundled multi-module Worker with static assets, an assets binding, compatibility date, and allowlisted compatibility flags.
  • A failed build/upload/smoke test preserves the currently live release.
  • Promotion is atomic; rollback switches the routing pointer without rebuilding.
  • Delete/retry/reconciliation handle Cloudflare drift and clean User Workers/assets without resetting production D1.
  • Tenant isolation, custom limits, egress policy, secret handling, and revocation have automated coverage.
  • A deployed App can use the existing Mosoo Public Thread API without receiving the owner's API token.
  • Dogfood Yevanchen/mosoo-codex-pet end to end: upload an avatar, mount it as a message resource, observe the queued Run through polling or SSE, list the resulting artifact, and download the ZIP.
  • Deployment deletion or successful binding replacement revokes further Agent access; a failed deployment preserves the last successful binding.

Non-goals

Related

Mosoo references

Cloudflare references

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestneeds-validationProduct hypothesis that needs evidence before roadmap commitment

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions