Skip to content

Pivot Up to anonymous dynamic stacks#2

Merged
acoyfellow merged 10 commits into
mainfrom
feat/anonymous-first
Jun 24, 2026
Merged

Pivot Up to anonymous dynamic stacks#2
acoyfellow merged 10 commits into
mainfrom
feat/anonymous-first

Conversation

@acoyfellow

Copy link
Copy Markdown
Owner

Product pivot

Up now gives an agent a temporary dynamic Cloudflare stack before signup:

_worker.js + assets + up.json
→ Worker + Static Assets + KV + D1 + Durable Objects
→ public Temporary Account URL
→ claim the whole stack or let it expire

The original Access-protected company publisher remains explicit secondary up private mode.

Implementation

  • default up deploy <folder> [name] uses pinned Wrangler --temporary
  • local private staging snapshot with no-follow reads
  • current and deprecated Cloudflare credentials excluded through an allowlisted child environment
  • explicit Terms approval required for non-interactive use
  • generated temporary Wrangler graph for KV, D1, and SQLite Durable Objects
  • authoritative live target parsed from Wrangler output
  • Wrangler claim URL redacted and printed once by Up
  • account-wide claim and expiry semantics validated before opening
  • cross-platform claim opener and isolated state
  • node-runtime subprocess test suite

Dynamic proof

examples/binding-lab uses:

  • Worker routes
  • Static Assets
  • KV
  • D1
  • Durable Object storage

A real isolated Temporary Account returned HTTP 200 from the UI and /api/state, with values from every binding. The account was not claimed and local credentials were deleted.

Capa spike

The same Temporary Account composition was proven with Capa:

  • generated Capa Worker
  • provider credential secret
  • Up caller Worker
  • JSRPC service binding
  • real read-only API call with verdict: pass
  • caller redeploy preserving the binding
  • Capa main Stripe reaching Stripe and returning a credential-free expected 401 proof for a fake token

The homepage and docs label this honestly: runtime spike proven, click-to-connect installer next. Existing permanent Capa Workers cannot be service-bound cross-account.

The spike also found that Capa's local rewrite/distilled-runtime branch deploys but its lazy provider module is absent at runtime. Up must pin proven Capa main or a fixed immutable bundle.

OAuth cleanup

Deleted the unused duplicate personal Up CLI OAuth client and verified exactly one retained company-mode client remains. Removed the local broad OAuth credential. No Access application, policy, production route, Worker, or DNS record was changed by the cleanup.

Validation

  • bun run check
  • 17 Workers runtime tests
  • 9 CLI subprocess/security tests
  • bun run test:e2e
  • SEO/PWA audit
  • local SSR/browser E2E
  • bun run public:check
  • cmux visual review: no console/browser errors or horizontal overflow
  • tracked-secret/claim scan

Not included

  • no production promotion
  • no Capa install UI yet
  • no Queues/Hyperdrive support in Up yet
  • no R2, Workers AI, Access, Workflows, Browser Rendering, Containers, Sandboxes, or Dispatch claims for anonymous mode

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6d1353143a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread cli/up.ts
try {
await visit(root, assetsDirectory);
if (!hasIndex) throw new Error('index.html is required');
if (!dynamic) return { directory, deployTarget: directory, fileCount, dynamic, bindings };

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use CI-compatible assets deployment for static sites

When dynamic is false, Up returns the staged directory as deployTarget; in the documented non-interactive path (up deploy … --accept-cloudflare-terms) anonymousEnvironment sets CI=1, so the later wrangler deploy <directory> uses Wrangler's assets-directory PATH in CI. I checked Cloudflare's Wrangler deploy reference (developers.cloudflare.com/workers/wrangler/commands/workers/): that PATH form is for an assets directory but “currently only works only in interactive mode (so not in CI systems)”, so agent/non-interactive static deployments fail before upload even though README/SKILL instruct this flag. Generate a minimal config/--assets flow that Wrangler accepts in CI instead.

Useful? React with 👍 / 👎.

Comment thread cli/up.ts
if (!hasIndex) throw new Error('index.html is required');
if (!dynamic) return { directory, deployTarget: directory, fileCount, dynamic, bindings };

await copyStableFile(workerPath, join(directory, '_worker.js'), root);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep Worker module dependencies beside the entrypoint

For dynamic apps, visit() stages every non-_worker.js file under assets/, and this line copies only _worker.js next to wrangler.jsonc. If a Worker uses a normal module import like import { x } from './lib.js' or exports a Durable Object from another file, Wrangler bundles from the staged _worker.js path and cannot resolve the sibling module because it was moved to assets/lib.js; the deploy fails although the source folder is a valid Worker project. Preserve Worker source modules outside the assets directory or document/enforce single-file Workers.

Useful? React with 👍 / 👎.

Comment thread cli/up.ts
class_name: className,
})),
},
migrations: [{ tag: 'v1', new_sqlite_classes: classes }],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Append Durable Object migrations with unique tags

This regenerates a single v1 migration from the current up.json on every deploy. In an active Temporary Account, if an agent first deploys Room and later adds Counter (the advertised write → deploy → revise loop), Wrangler has already applied v1, and Cloudflare's Durable Objects migration docs say tags are unique and used to determine what has already been applied, so the new class is not created or the redeploy hits migration errors. Persist prior migration state or generate append-only tags for newly introduced classes.

Useful? React with 👍 / 👎.

Cut intro, Capa section, system-model, the Diátaxis docs-map, and read-next.
Homepage is now dynamic-first (bindings off the shelf), no slop.
- Decision: Up is pure orchestration of public Cloudflare primitives; private
  path re-platforms onto WFP + Static Assets + Access (deletes R2 backend).
- Hero: precise 'up deploy', opt-in bindings, restored public-exposure warning,
  honest independence note.
Deploys examples/binding-lab to a real Temporary Account, exercises KV+D1+DO over
the public URL, never claims, redacts the claim URL. Gated behind explicit
UP_RUN_LIVE_ANONYMOUS + UP_ACCEPT_CLOUDFLARE_TERMS.
…aim --show

deploy and claim no longer print the account-wide ownership link; it stays in
the local temporary-account file. Live anonymous verify receipt added. CLI tests
flipped to assert the link is withheld.
Keep homepage at two sections: Capa is a benefit-led block inside the bindings shelf
(API keys out of app code; bounded actions; clear record), honestly marked as tested
but installer not shipped. Add after-keep truth: app stays public until Access/login.
- Add fail-closed up handoff: Wrangler OAuth, exact account/Worker preflight,
  permanent deploy without auto-create, preserve attached bindings by name.
- Install a copy-ready .up/HANDOFF.md agent prompt; document Access/public and CI token boundaries.
- Show all 12 Capa service brands covering 14 checked-in bindings, with local pinned SVGs.
- Add positive, refusal, and init subprocess tests (12 CLI tests).
- Reposition hero around a live app, not a URL.
- Show all 8 Temporary Account primitives with official Cloudflare product icons and honest Up support states.
- Show all 14 Capa bindings with service logos.
- Add fail-closed post-ownership up handoff, Wrangler OAuth flow, Access/public guidance, docs, and agent prompt.
- Keep claim URLs withheld by default and verify the dynamic anonymous path live.
@acoyfellow
acoyfellow merged commit 8448e00 into main Jun 24, 2026
3 checks passed
@acoyfellow
acoyfellow deleted the feat/anonymous-first branch June 24, 2026 00:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant