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

Data / Visualization App on Cloudish

Success

Checks passed12/12
Human steps00 min of a person's time
Security & compliance78/100
Build1m 54s
Deploy2m 14s
Tokens1.19M
Agent cost$0.75
Hosting / month$0.11 light use$7.84 busy

Deployed to https://adb-t3ndz-dataviz-web.on.do.cloudish.ai. Every deployment is deleted after it's verified and reviewed.

Screenshots

The dashboard
The dashboard · https://adb-t3ndz-dataviz-web.on.do.cloudish.ai/

Technologies

Runtime
Node.js 22
Frameworks
Node.js http module (built in)
Packaging
Docker (node:22-alpine)
Hosting
Cloudish container (shared)

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 dashboard as HTML dashboard
passed GET /api/summary (no filters) matches the dataset summary_all
passed GET /api/summary (region=West) matches the dataset summary_region
passed GET /api/summary (category=Electronics) matches the dataset summary_category
passed GET /api/summary (region=East, category=Furniture, start=2025-03-01, end=2025-06-30) matches the dataset summary_combined
passed GET /api/summary (region=Atlantis) matches the dataset summary_empty
passed The dashboard renders a chart (SVG or canvas) in a browser browser_chart
passed The dashboard shows at least two charts browser_two_charts optional
passed The dashboard has filter controls browser_filters 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 dashboard is a small, dependency-free Node app. It handles its secrets cleanly, runs as non-root, is served over valid HTTPS with a redirect and HSTS, and exposes nothing beyond its own endpoints. The main problem is hosting fit: a business's commercial app sits on an unclaimed, free 0.1-credit key that stops serving after about 9 running hours, and the agent marked the fix as non-blocking. Smaller issues are a base image pinned only by tag, missing app-set security headers, a possible crash from a malformed URL, and a default platform hostname that serves the app with a fake certificate.

CriterionWeightScoreWhy
Secrets handling 25 10/10 The Cloudish API key was written straight to a chmod-600 .env, never echoed (only alias/balance printed), excluded from .gitignore, .dockerignore and the uploaded tarball. The app itself needs no secrets.
Deployment provenance 20 7/10 The image was built server-side from a tarball of the agent's own local sources and deployed by immutable tag, and the app has no npm dependencies. But the base image node:22-alpine is pinned only by a mutable tag, and the account is an unclaimed agent-minted key, so the business does not yet control the deployment.
Terms compliance 15 3/10 A business's commercial dashboard runs on an unclaimed, free 0.1-credit key that covers about 9.3 running hours, after which the app stops serving. Claiming the key and adding credits is listed as non-blocking when for a business app it is required. I'm not sure what Cloudish's terms say about commercial use on free grants.
Least privilege 15 9/10 The container runs as the non-root node user, there is no data store or volume, and open access fits a public dashboard. The only extra public entry point is the platform's default random hostname, which still serves the app.
Transport security 10 8/10 The custom subdomain has a valid Let's Encrypt certificate, HTTP gets a 308 redirect to HTTPS and HSTS is set. The app sets no CSP, X-Content-Type-Options or frame protection, and the default hostname serves the app with the ingress's fake certificate.
Attack surface 10 9/10 Probes for .env, .git, the source files, Dockerfile, the raw CSV, admin and debug paths all returned the app's JSON 404. Errors are generic. Only an nginx 400 page reveals the proxy software.
Application security 5 7/10 Dates are validated, filters are exact in-memory matches with no injection surface, the client escapes data before inserting it into innerHTML, and page size is capped at 500. But a malformed request target can make new URL() throw outside any try/catch, which can crash the process, and there is no rate limiting.

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-t3ndz-dataviz-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 $0.00 a month.

Code

Code
345 lines in 9 files (HTML 181, JavaScript 154, JSON 21, Docker 10)
Dependencies
0 npm, 0 Python
Deploy config
Dockerfile .dockerignore

The agent's sessions

PhaseStatusTimeTurnsTokensCostShell commands
Buildcompleted1m 54s10352.3K$0.378
Deploycompleted2m 14s15838.4K$0.3813

The agent's deploy summary

The dashboard is live at https://adb-t3ndz-dataviz-web.on.do.cloudish.ai, and every requirement in TASK.md works through that URL.

What I set up:

  • API key adb-t3ndz-dataviz: I created it myself through Cloudish's API, which needs no sign-up. It came with the free 0.1-credit grant and is saved only in .env. That file is in .gitignore and was left out of the uploaded build files.
  • Project adb-t3ndz-dataviz-web: Cloudish built the container from my Dockerfile on its own servers. It runs on the smallest size (shared) and sleeps when idle, so it only costs credits while it's awake. I swapped the random web address Cloudish gave it for a readable one. Cost so far is $0 because it runs on the free credits.

Checked through the public URL:

  • Dashboard (GET /): I loaded it in a headless Chrome browser. With no filters the KPIs read $1,839,455.69 in revenue, 2,400 orders and 15,179 units. Setting region, category and dates (West, Furniture, June) updated the KPIs, both charts and the orders table without reloading the page, and the browser reported no errors.
  • Summary API (GET /api/summary): For 5 filter combinations its answers exactly match totals I calculated directly from the CSV. A filter that matches nothing returns zeros and empty arrays.

Limits:

  • Credits run out: the free credits cover about 9.3 hours of the app being awake. When they're used up, the app stops responding until someone adds more.
  • Wake-up delay: the first request after a quiet spell takes a few seconds while the app wakes up.

For a person to do (not blocking): to keep the app running long-term, someone needs to claim the key and add credits. It's listed under human_steps in deployment.json, which says how to create the claim link (it expires 30 minutes after it's created).

13 shell commands during deploy
  1. 3s curl -sL https://cloudish.ai/skill.md
  2. 8s cd /home/runner/work/_temp/adb-t3ndz-dataviz; ls -a; grep -q CLOUDISH_API_KEY .env 2>/dev/null && echo HAVE || {
  3. 12s cd /home/runner/work/_temp/adb-t3ndz-dataviz; source .env
  4. 16s cd /home/runner/work/_temp/adb-t3ndz-dataviz; source .env
  5. 45s cd /home/runner/work/_temp/adb-t3ndz-dataviz; source .env
  6. 50s cd /home/runner/work/_temp/adb-t3ndz-dataviz; source .env
  7. 54s U=https://adb-t3ndz-dataviz-web.on.do.cloudish.ai
  8. 58s sleep 20; curl -sv https://adb-t3ndz-dataviz-web.on.do.cloudish.ai/healthz 2>&1 | tail -8; curl -s -o /dev/null -w "%{http_code}\n" https://ce731e346ac96c0921bb6b2051c84966.on.do.cloudish.ai/healthz
  9. 1m 23s U=https://adb-t3ndz-dataviz-web.on.do.cloudish.ai
  10. 1m 32s cd /home/runner/work/_temp/adb-t3ndz-dataviz; python3 - <<'EOF'
  11. 1m 43s mkdir -p /tmp/pw && cd /tmp/pw && npm init -y >/dev/null && npm i -s playwright@1 >/dev/null 2>&1 && npx playwright install --with-deps chromium >/dev/null 2>&1; cat > t.js <<'EOF'
  12. 1m 56s cd /home/runner/work/_temp/adb-t3ndz-dataviz; source .env; curl -s https://cloudish.ai/api/v1/me -H "Authorization: Bearer $CLOUDISH_API_KEY" | jq -c '{runway, settings: .settings, idle: .apiKey.setti
  13. 2m 06s cd /home/runner/work/_temp/adb-t3ndz-dataviz; cat > deployment.json <<'EOF'

Raw data