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

Static Content Site on Cloudish

Success

Checks passed16/16
Human steps00 min of a person's time
Security & compliance75/100
Build1m 17s
Deploy2m 41s
Tokens833.2K
Agent cost$0.57
Hosting / month$0.11 light use$7.84 busy

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

Screenshots

The home page
The home page · https://adb-ebio7-static-web.on.do.cloudish.ai/
The contact page after the verifier submitted the form
The contact page after the verifier submitted the form · https://adb-ebio7-static-web.on.do.cloudish.ai/contact

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 / returns HTML page_home
passed GET /about returns HTML page_about
passed GET /contact returns HTML page_contact
passed Home has an <h1> containing 'Northwind Robotics' home_content
passed About has a heading containing 'About' about_content
passed Contact has a form with name, email and message fields contact_form
passed Every page has a <title> and a viewport meta tag head_tags optional
passed Home links to /about and /contact navigation optional
passed POST /api/contact with valid input returns {ok: true} contact_api_valid
passed POST /api/contact rejects a bad email and an empty message with 400 contact_api_validation
passed Unknown paths return 404 not_found
passed Submitting the /contact form in a browser posts to /api/contact without leaving the page browser_contact_form
passed Pages load in a browser without uncaught JavaScript errors browser_no_errors 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 Northwind Robotics site is a small, dependency-free Node server that runs as a non-root user. It handles secrets well: the Cloudish key never reached logs, the build context or the image. It serves only allowlisted paths over HTTPS with HSTS, and validates contact input soundly. The main problem is compliance: a commercial site is hosted on an agent-minted, unclaimed key whose free 0.1-credit grant runs out in about 9 hours of uptime, and no human account holder has accepted the provider's terms. Smaller issues are the unpinned base image, ownership by the agent's key, missing app-set security headers, and permissive CORS added by the platform.

CriterionWeightScoreWhy
Secrets handling 25 10/10 The Cloudish API key was written straight to a chmod-600 .env file and never printed: key and claimUrl were removed with jq before output. .env was excluded from git, the Docker build context and the uploaded tarball. The app itself needs no secrets.
Deployment provenance 20 6/10 Cloudish built the image server-side from a tarball of exactly the reviewed files, and the code has no dependencies. But the base image is the floating tag node:22-alpine with no digest, and the source and deployment live under an agent-minted, unclaimed key rather than an account or repository the business controls.
Terms compliance 15 3/10 This is a commercial site hosted on an unclaimed key that only has a free 0.1-credit grant ($0.098 left). That covers about 9 hours of active runtime, after which the site returns 402/503. No human account holder has accepted the provider's terms for business use. The agent listed claiming the key and adding credits as non-blocking.
Least privilege 15 9/10 The container runs as the non-root node user, with no volume, no environment secrets and one replica. The service is publicly open, which a public marketing site needs. One minor point: the API key is a full account credential and no scoped key was used.
Transport security 10 8/10 HTTPS with a valid Let's Encrypt certificate, HTTP redirects to HTTPS with a 308, and the platform adds HSTS. The app server set no X-Content-Type-Options, frame protection or CSP, though it could have.
Attack surface 10 8/10 Every path is allowlisted, so .env, .git, server.js, package.json and the Dockerfile all return 404, and there are no directory listings or stack traces. One small extra is /healthz. The platform ingress reflects any Origin with Access-Control-Allow-Credentials: true; the app has no cookies or auth, so the impact is low.
Application security 5 8/10 Validation is solid: type checks, an email regex, a 64 KB body cap, and 400 responses for bad JSON or non-object bodies. The client uses textContent, so there is no XSS. Minor gaps: no rate limiting or per-field length limits on the public contact endpoint, and submitter emails are written to logs.

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-ebio7-static-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.73 a month.

Code

Code
289 lines in 13 files (JavaScript 179, HTML 89, JSON 24, CSS 13, Docker 8, Markdown 5)
Dependencies
0 npm, 0 Python
Deploy config
Dockerfile .dockerignore

The agent's sessions

PhaseStatusTimeTurnsTokensCostShell commands
Buildcompleted1m 17s7225.2K$0.286
Deploycompleted2m 41s12608.0K$0.2911

The agent's deploy summary

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

What I deployed:

  • API key: I created a Cloudish key named adb-ebio7-static myself. It needed no signup and is saved in .env, which is gitignored and was left out of what I uploaded.
  • App: Cloudish built the project adb-ebio7-static-web from my Dockerfile on its own servers. It runs on the smallest size (shared) and shuts down when idle.
  • HTTPS: Cloudish provides it, and plain HTTP redirects to HTTPS.

Tested through the public URL:

  • /, /about and /contact return 200 with text/html, and have the right title, viewport tag, headings and form fields.
  • Unknown paths and paths ending in .html return 404.
  • POST /api/contact returns 200 {"ok":true} for valid input. A missing name, a bad email or an empty message each return 400 with an error message.
  • In a headless Chromium browser at phone width, submitting the form showed the confirmation without reloading the page.

Cost and limits:

  • Credits are the main limit: the key came with 0.1 free credits (1 credit = $1), and 0.098 are left. The build cost about 0.002.
  • How long that lasts: about 9 hours of the app actually running. Idle time costs nothing, but once the credits run out the site stops serving pages.
  • Worst case: about $7.73 a month if the app ran around the clock, which is the figure in deployment.json. Real cost will be lower because it shuts down when idle.
  • Cold start: the first request after an idle period takes a moment while the app starts.

Needs a person (not blocking): to keep the site up longer, someone has to claim the key and add credits. I listed this under human_steps in deployment.json. A claim link can be created with the key in .env (GET https://cloudish.ai/api/v1/credits/claim); it works once and expires after 30 minutes.

11 shell commands during deploy
  1. 3s curl -sL -H 'Accept: text/markdown' https://cloudish.ai/ | head -c 200; echo; for u in llms.txt docs api; do echo "== $u"; curl -sL https://www.cloudish.ai/$u | head -c 1500; echo; done
  2. 7s curl -sL https://www.cloudish.ai/llms.txt | tail -n +15
  3. 10s curl -sL https://www.cloudish.ai/skill.md; echo; curl -sL https://www.cloudish.ai/pricing.json
  4. 14s cd /home/runner/work/_temp/adb-ebio7-static; printf '.env\n.env*\ncontext.tar.gz\n' >> .gitignore; echo '.env*' >> .dockerignore
  5. 18s cd /home/runner/work/_temp/adb-ebio7-static; source .env
  6. 22s cd /home/runner/work/_temp/adb-ebio7-static; source .env
  7. 1m 24s cd /home/runner/work/_temp/adb-ebio7-static; source .env
  8. 1m 28s cd /home/runner/work/_temp/adb-ebio7-static; source .env
  9. 1m 34s B=https://adb-ebio7-static-web.on.do.cloudish.ai
  10. 2m 05s mkdir -p /tmp/pw && cd /tmp/pw && npm init -y >/dev/null && npm i -s playwright >/dev/null 2>&1 && npx playwright install --with-deps chromium >/dev/null 2>&1; cat > t.js <<'EOF'
  11. 2m 33s cd /home/runner/work/_temp/adb-ebio7-static; source .env

Raw data