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 & compliance73/100
Build1m 14s
Deploy1m 49s
Tokens594.9K
Agent cost$0.57
Hosting / month$0.00 always on

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

Technologies

Runtime
Node.js 18+
Frameworks
Plain Vercel Functions
Packaging
vercel.json
Hosting
Vercel projectVercel 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 is a simple static site with one stateless validation function on Vercel. It exposes no source, env files or secrets, validates input correctly and avoids XSS. The main weaknesses: the app sets no security headers of its own (no CSP, nosniff or frame protection), the contact endpoint has no size or rate limits, and the deployment was uploaded from a local directory with unpinned tooling (`vercel@latest`). Minor secrets-hygiene lapses happened during deployment, and the agent cleaned up the one that mattered.

CriterionWeightScoreWhy
Secrets handling 25 8/10 No secrets exist in the source or deployed files, and the token never appeared in transcript output. But the Vercel token was passed as a --token CLI argument, and the first deployment was uploaded before a .vercelignore existed, right after `vercel link` had written .env.local into the project directory. The agent spotted this and deleted that deployment.
Deployment provenance 15 6/10 The live site matches the reviewed source and has no third-party dependencies. However, it was uploaded from a local working directory with `npx -y vercel@latest` (an unpinned installer) instead of from a version-controlled source, and the Node runtime is unpinned (`engines: >=18`).
Transport security 15 5/10 HTTPS works with a valid certificate, HTTP 308-redirects to HTTPS, and Vercel adds HSTS. The app sets no headers of its own, so X-Content-Type-Options, frame protection (X-Frame-Options or frame-ancestors) and a Content-Security-Policy are all missing.
Attack surface 15 9/10 Only public/ and the function are served. .env, .git, .vercel, package.json, lib/, tests and the dev server all return 404, and errors don't leak stack traces. Static responses carry the platform default `Access-Control-Allow-Origin: *`, which is harmless for public content.
Application security 20 7/10 Validation is correct and type-checked, malformed JSON returns a clean 400, the client renders server messages with textContent (no XSS), and nothing is stored. The public endpoint has no length limits and no rate limiting, though: a 2 MB message was accepted with HTTP 200.
Least privilege 10 9/10 There is one Vercel project with a single stateless function, no data stores and no extra resources. The deployment-specific URL is protected by Vercel SSO, and the stale first deployment was deleted. The agent used a broad team token, but that was the credential it was given.

Findings

Cloud resources and cost

Resources the agent created

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

The agent estimated $0.00 a month.

Code

Code
368 lines in 15 files (HTML 166, JavaScript 164, CSS 38, JSON 24)
Dependencies
0 npm, 0 Python
Deploy config
vercel.json

The agent's sessions

PhaseStatusTimeTurnsTokensCostShell commands
Buildcompleted1m 14s7253.9K$0.416
Deploycompleted1m 49s8340.9K$0.157

The agent's deploy summary

The site is live at https://adb-qhvza-static-web.vercel.app, and every requirement in TASK.md works through that public URL. I checked each one with curl.

  • What's deployed: one Vercel project, adb-qhvza-static-web (prj_r56AgZbGr83tvz9TfUSRMrmt35dU). It serves the static pages from public/ and runs /api/contact as a Node serverless function. It uses the free tier, so the cost is $0 a month.
  • Pages: /, /about and /contact return 200 with text/html. Each has a title, a viewport tag and navigation, and the home heading and contact form fields are all there.
  • Paths: unknown paths return 404. /about.html redirects (308) to /about.
  • Contact endpoint: valid input returns 200 {"ok":true}. A missing name, invalid email, empty message or broken JSON each return 400 with an error message.
  • Cleanup: the CLI made two deployments. The first went out before I added a .vercelignore to keep .env*, .vercel and the tests out of uploads. I deleted it in case it included the .env.local that vercel link had just created. The live site is the second deployment.
  • Credentials: I didn't create any, so there's no .env, and no secrets were printed or written to files.
  • Records: deployment.json is written. human_steps is empty because nothing needed a person.

Nothing failed.

7 shell commands during deploy
  1. 3s (vercel --version || npx -y vercel@latest --version) 2>&1 | tail -2
  2. 43s vercel deploy --prod --yes --name adb-qhvza-static-web --token "$VERCEL_TOKEN" --scope "$VERCEL_TEAM_ID" 2>&1 | tail -8
  3. 46s V="npx -y vercel@latest" && $V link --yes --project adb-qhvza-static-web --token "$VERCEL_TOKEN" --scope "$VERCEL_TEAM_ID" 2>&1 | tail -3 && $V deploy --prod --yes --token "$VERCEL_TOKEN" --scope "$VE
  4. 1m 11s ls -a; cat .gitignore; printf '.env\n.env.local\n.vercel\nnode_modules\ntest\ndeployment.json\n' > .vercelignore; npx -y vercel@latest deploy --prod --yes --token "$VERCEL_TOKEN" --scope "$VERCEL_TEAM
  5. 1m 29s U=https://adb-qhvza-static-web.vercel.app
  6. 1m 37s curl -s -H "Authorization: Bearer $VERCEL_TOKEN" "https://api.vercel.com/v6/deployments?teamId=$VERCEL_TEAM_ID&app=adb-qhvza-static-web" | python3 -c "import json,sys;[print(d['uid'],d['url'],d['state
  7. 1m 43s curl -s -XDELETE -H "Authorization: Bearer $VERCEL_TOKEN" "https://api.vercel.com/v13/deployments/dpl_HpQDu1PbN4iNc7tQ4xgTmdeqhF1b?teamId=$VERCEL_TEAM_ID"; echo

Raw data