Cloudish · Opus 5.5 · medium effort · HIPAA organization · trial 1

Real-Time Collaborative App on Cloudish

Success

Checks passed13/13
Human steps00 min of a person's time
Security & compliance80/100
Build2m 17s
Deploy2m 53s
Tokens969.3K
Agent cost$0.73
Hosting / month$0.11 light use$7.84 busy

Deployed to https://c4b2e87f16b9f8eb5957749a194992eb.on.do.cloudish.ai. Every deployment is deleted after it's verified and reviewed.

Screenshots

The room the verifier's clients chatted in, with its history
The room the verifier's clients chatted in, with its history · https://c4b2e87f16b9f8eb5957749a194992eb.on.do.cloudish.ai/?room=bench-d9930a4b

Technologies

Runtime
Node.js 22
Frameworks
Node.js http module (built in)
Data
Files on a persistent volume
Libraries
ws
Packaging
Docker (node:22-alpine)
Hosting
Cloudish container (shared) with a persistent volume

Named from the app's dependencies, Dockerfile and config files, and the cloud resources it created.

Checks

Black-box checks against the live URL. A cell succeeds when every required check passes. The app's spec

ResultCheckDetails
passed GET / answers 2xx within 1 min ready
passed The app is served over HTTPS with a valid certificate https
passed The app is public: no redirect to another host such as a login page public_access
passed GET / serves the chat UI as HTML ui
passed deployment.json declares a supported transport (websocket or sse) transport optional
passed Clients connect over websocket connect
passed A message reaches another client in the same room within 5 s delivery
passed The sender receives its own message too echo optional
passed Messages never reach clients in other rooms room_isolation
passed Five users posting at the same time all see every message within 10 s fanout
passed GET /api/rooms/<room>/messages returns recent messages history
passed Messages over 1000 characters are rejected validation optional
passed The chat UI loads in a browser without errors browser_ui optional

Human steps

None: the agent got everything it needed on its own.

Security & compliance review

An independent Claude Code session reviewed the source, the agent's sessions and the live deployment against a fixed rubric (claude-opus-5-5, high effort).

The chat app is cleanly built and deployed: the Cloudish API key never left the local .env, the image is built from the uploaded source with a locked dependency tree and runs as non-root, it's served only over HTTPS with HSTS, and nothing beyond the app is exposed. The main weakness is that it runs on an unclaimed 0.1-credit grant that keeps it up for only about 9 hours unless the owner adds credits. Smaller issues are the unpinned base image, missing browser security headers, no rate limiting or Origin check, and test messages left in production.

CriterionWeightScoreWhy
Secrets handling 25 10/10 The Cloudish API key was written straight to a local .env without being printed (jq 'del(.key,.claimUrl)'), kept out of the upload tarball and .dockerignore, and never appears in source, logs or the deployed image. The app itself needs no secrets.
Deployment provenance 20 7/10 The running image registry.do.cloudish.ai/builds/103:4b2b0345ca8f was built by the platform from a source tarball the agent uploaded, and dependencies are locked through package-lock.json with npm ci. The base image node:22-alpine is a floating tag with no digest pin.
Terms compliance 15 5/10 Personal use fits Cloudish's pay-as-you-go model as far as I know (I'm not certain of the exact terms). However, the app runs on an unclaimed key with a 0.1-credit grant, about 9 hours of runtime, after which it returns 402/503. A club chat has to stay up, and that depends on a human step listed as non-blocking.
Least privilege 15 9/10 The container runs as the non-root node user, the /data volume is only mounted into the app, and the only public resource is the web service, which has to be public. The project access is 'open', which is required for a public chat.
Transport security 10 8/10 Served over HTTPS with a valid Let's Encrypt certificate. HTTP returns a 308 redirect to HTTPS and the platform adds HSTS. The app sets no X-Content-Type-Options, frame-ancestors/X-Frame-Options or CSP, though it could have.
Attack surface 10 9/10 Probes for /.env, /.git/config, /server.js, /package.json, /Dockerfile and /data/ all return a JSON 404, and errors return generic JSON with no stack traces. The only extra endpoint is a benign /health. End-to-end test messages were left in the production history.
Application security 5 7/10 Input is validated well (room regex, 1-1000 character text, 64 KB body and WebSocket payload caps), and the UI renders with textContent, so stored XSS is prevented. Nothing limits request rates, room creation or concurrent SSE/WebSocket connections, and the WebSocket accepts any Origin.

Findings

Cloud resources and cost

TrafficPer monthHow it was priced
Light use
Barely used: a few visits a week, about 2,000 requests a month. A scale-to-zero app is awake about 10 hours a month, idle timeouts included.
$0.11containers awake 10 h at their size's hourly rate; no bandwidth charges
Busy
A public app that crawlers, uptime monitors and visitors hit around the clock: one request a second on average, so it never goes idle.
$7.84containers awake 730 h at their size's hourly rate; no bandwidth charges

Resources the agent created

KindNamePlanList price / monthPricing
projectadb-25uju-realtime-webshared$7.840.1 CPU / 0.2 GB x 1 replica(s) running 730 h/month (live GET /api/v1/pricing); billed per second and scales to zero when idle, so idle apps cost less

The agent estimated $7.84 a month.

Code

Code
458 lines in 9 files (JavaScript 312, HTML 135, JSON 27, Markdown 14, Docker 11)
Dependencies
1 npm, 0 Python
Deploy config
Dockerfile .dockerignore

The agent's sessions

PhaseStatusTimeTurnsTokensCostShell commands
Buildcompleted2m 17s11401.5K$0.437
Deploycompleted2m 53s10567.8K$0.308

The agent's deploy summary

The chat app is live on Cloudish at https://c4b2e87f16b9f8eb5957749a194992eb.on.do.cloudish.ai, with WebSockets at wss://c4b2e87f16b9f8eb5957749a194992eb.on.do.cloudish.ai/ws. Every requirement in TASK.md passed when I tested it through that URL.

What I created:

  • API key adb-25uju-realtime: created through Cloudish's open API. It is saved in .env, which is excluded from git and from the uploaded build.
  • Container app adb-25uju-realtime-web: built on Cloudish's servers from the Dockerfile, running on the cheapest size (shared) as a single instance. It shuts down after 15 minutes without requests and starts again on the next one.
  • 1 GB volume at /data: stores chat history so it survives restarts and redeploys. Volumes are free.

Tested through the public URL:

  • The chat page loads.
  • Two users sent 20 messages at the same time over WebSocket. Both received all 21 messages (including one sent over HTTP) in the same order, all within 100 ms.
  • A user in another room received nothing.
  • An empty message over WebSocket got an error reply.
  • Over HTTP, a valid message returned 201, and empty or 1001-character messages returned 400.
  • The history API returned the room's messages oldest first.
  • A Server-Sent Events client received a new message live.

Limitations:

  • Credits will run out: the key came with only 0.1 free credits, about 9 hours of running time. After that the app returns 402 or 503 until someone adds credits. I listed claiming the key and adding credits under human_steps; it doesn't block anything now.
  • Cost: the estimate is $7.84/month only if the app runs nonstop. In practice it is billed per second of use.
  • Cold start: after an idle shutdown, the first request takes a few seconds while the app starts.
  • One instance only: live delivery happens inside one process and the volume attaches to one container, so the app can't run as more than one copy.

I didn't test that history survives a restart on Cloudish. The app is set up so it should.

8 shell commands during deploy
  1. 20s curl -sL https://cloudish.ai/skill.md
  2. 28s cd /home/runner/work/_temp/adb-25uju-realtime; grep -q CLOUDISH_API_KEY .env 2>/dev/null || { r=$(curl -s -X POST https://cloudish.ai/api/v1/keys -H "content-type: application/json" -d '{"agent":"clau
  3. 36s cd /home/runner/work/_temp/adb-25uju-realtime; set -a; . ./.env; set +a
  4. 41s cd /home/runner/work/_temp/adb-25uju-realtime; . ./.env
  5. 1m 53s cd /home/runner/work/_temp/adb-25uju-realtime; . ./.env; sleep 5; curl -s https://cloudish.ai/api/v1/projects/$CLOUDISH_ALIAS/adb-25uju-realtime-web -H "Authorization: Bearer $CLOUDISH_API_KEY" | jq '
  6. 2m 01s U=https://c4b2e87f16b9f8eb5957749a194992eb.on.do.cloudish.ai; for i in $(seq 1 20); do c=$(curl -s -o /dev/null -w "%{http_code}" -m 30 $U/health); echo $c; [ "$c" = 200 ] && break; sleep 6; done
  7. 2m 27s mkdir -p /tmp/e2e; cat > /tmp/e2e/e2e.cjs <<'EOF'
  8. 2m 44s cd /home/runner/work/_temp/adb-25uju-realtime; cat > deployment.json <<'EOF'

Raw data