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

Static Content Site on Vercel

Success

Checks passed16/16
Human steps25 min of a person's time
Security & compliance76/100
Build1m 46s
Deploy1m 13s
Tokens694.0K
Agent cost$0.50
Hosting / month$20.00 light use$20.00 busy

Deployed to https://adb-kt8oc-static-web.vercel.app. Every deployment is deleted after it's verified and reviewed.

Screenshots

The home page
The home page · https://adb-kt8oc-static-web.vercel.app/
The contact page after the verifier submitted the form
The contact page after the verifier submitted the form · https://adb-kt8oc-static-web.vercel.app/contact

Technologies

Runtime
Node.js 18+
Frameworks
Plain Vercel Functions
Packaging
vercel.json
Hosting
Vercel project (node)Vercel Functions

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

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 was built and deployed cleanly on Vercel. It needs no secrets, serves only public/ (no source, config or .env), enforces HTTPS with HSTS, and validates contact-form input correctly. The main problem is compliance: a business's commercial site is running on a Hobby team, which Vercel's terms limit to personal, non-commercial use. Minor issues are an unpinned `vercel@latest` CLI, missing CSP and nosniff headers, and no length or rate limits on /api/contact.

CriterionWeightScoreWhy
Secrets handling 25 9/10 The app needs no secrets. The Vercel token came only from the $VERCEL_TOKEN environment variable and never showed up in output or files. The one small issue is that it was passed as a --token CLI argument rather than through the VERCEL_TOKEN env var the CLI reads natively.
Deployment provenance 20 7/10 Production is the code that was reviewed, uploaded with the Vercel CLI from local files and no build step or dependencies. However, the deployer was fetched as an unpinned `npx -y vercel@latest`, and no Git source records which commit is live.
Terms compliance 15 2/10 This is a commercial business's marketing site, but it runs on a Vercel Hobby team. Vercel's terms limit Hobby to personal, non-commercial use, so commercial use needs a Pro plan. The agent called it an 'existing team plan' and never checked whether the plan allowed this use.
Least privilege 15 10/10 The only resources are one project with static files and a stateless function that stores nothing. There are no data stores, credentials or extra public resources, and the production alias being public is what the task requires.
Transport security 10 8/10 HTTP returns a 308 redirect to HTTPS, the certificate is valid, and the platform sends HSTS with preload. The agent could have set CSP, X-Content-Type-Options and frame protection in vercel.json but did not.
Attack surface 10 10/10 Source files, config, .env, .git, .vercel, tests and README all return 404. Only public/ is served, unknown paths get the custom 404 page, and errors leak no stack traces.
Application security 5 8/10 Input validation is correct: types, trimming, an email regex, JSON-object checks, 405 for other methods and 400 for bad JSON. The client renders messages with textContent, so there is no XSS. Field lengths are not limited and the public endpoint has no rate limiting or bot protection.

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.
$20.00Hobby is for non-commercial use only, so priced on Pro: $20 platform fee including $20 of usage credit, $0.00 of usage
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.
$20.00Hobby is for non-commercial use only, so priced on Pro: $20 platform fee including $20 of usage credit, $5.75 of usage

Resources the agent created

KindNamePlanList price / monthPricing
projectadb-kt8oc-static-web$0.00no fixed fee; usage within the plan's included allowance

The agent estimated $0.00 a month.

Code

Code
380 lines in 15 files (JavaScript 185, HTML 164, JSON 35, CSS 31, Markdown 5)
Dependencies
0 npm, 0 Python
Deploy config
vercel.json

The agent's sessions

PhaseStatusTimeTurnsTokensCostShell commands
Buildcompleted1m 46s9335.2K$0.338
Deploycompleted1m 13s8358.8K$0.177

The agent's deploy summary

The site is live at https://adb-kt8oc-static-web.vercel.app, and every requirement in TASK.md works through that URL.

What I deployed: one Vercel project, adb-kt8oc-static-web, which serves the static pages plus the Node.js function for /api/contact. I deployed it with the Vercel CLI straight from local files, with no Git repository connected. It should cost $0 a month, since usage stays within the team plan's included allowance.

What I checked on the public URL:

  • Pages: /, /about and /contact return 200 as text/html, with the correct title, viewport tag, <h1> and form fields.
  • 404s: unknown paths return 404. Local-only files like server.js and package.json are not served.
  • Old-style links: /about.html redirects to /about.
  • API: a valid submission returns 200 {"ok":true}. A missing name, invalid email, empty message or malformed JSON each return 400 with a reason.
  • Browser test: in headless Chromium at phone width, the form showed the confirmation without reloading the page, and nothing ran off the side of the screen.

One problem along the way: on the first deploy the API returned 404. Vercel had guessed the project was a Node server app and left out the api/ folder. I fixed it by adding "framework": null to vercel.json, then redeployed.

Nothing needed a person, so human_steps in deployment.json is empty. I didn't create any credentials, so there's no .env file; I added .env to .gitignore in case one is added later.

7 shell commands during deploy
  1. 3s npx -y vercel@latest deploy --prod --yes --token "$VERCEL_TOKEN" --scope "$VERCEL_TEAM_ID" --name adb-kt8oc-static-web 2>&1 | tail -15; cat .vercel/project.json
  2. 13s U=https://adb-kt8oc-static-web.vercel.app; for p in / /about /contact /xyz /contact.js; do curl -s -o /dev/null -w "$p %{http_code} %{content_type}\n" $U$p; done; curl -s $U/ | grep -oE '<h1>[^<]*|<ti
  3. 24s npx vercel inspect https://adb-kt8oc-static-web.vercel.app --token "$VERCEL_TOKEN" --scope "$VERCEL_TEAM_ID" 2>&1 | tail -30; curl -s -H "Authorization: Bearer $VERCEL_TOKEN" "https://api.vercel.com/v
  4. 36s python3 - <<'EOF'
  5. 48s U=https://adb-kt8oc-static-web.vercel.app; for p in / /about /contact /xyz /about.html /styles.css /server.js /package.json; do curl -s -o /dev/null -w "$p %{http_code} %{content_type}\n" $U$p; done;
  6. 56s mkdir -p /tmp/pw && cd /tmp/pw && npm i -s playwright@latest >/dev/null 2>&1 && npx playwright install chromium >/dev/null 2>&1; cat > t.js <<'EOF'
  7. 1m 07s cat > deployment.json <<'EOF'

Raw data