Deploy Checklist
Run through this before pushing to main (a push deploys production
automatically — the Vercel project is git-connected). Steps 1-3 are enforced
by CI (code_quality.yml), but running them locally first keeps broken
commits off main.
1. Production build
bun run build
Must finish without errors. This is the standard deployment build Vercel
runs; it syncs the static content directories into public/ first.
2. Content and URL validation
node scripts/validate-content.mjs
bun run build:export
bun run parity
Front matter contracts, trust pages (/contact/, /privacy/), llms.txt
sections, 404 recovery links, and the OpenAPI source are all checked by
validate-content.mjs; the parity diff verifies every published URL in the
frozen manifest (scripts/parity/manifest.json) still resolves with no
canonical drift.
3. API surface validation (spec vs. built output)
python3 scripts/validate_api_output.py out
This validates the exported out/ output (from bun run build:export
above), and fails on drift between
openapi.json and reality:
openapi.json,search.json,/api/v1/posts.json,/api/v1/books.json, and/.well-known/api-catalogparse as JSON.- Every concrete path documented in the OpenAPI spec exists in the build, and
every operation has a unique
operationId, a description, and responses. search.jsonitems match the spec’sSearchItemschema:kindis in the spec’s enum (post/book/loop), tags are{name, slug}objects,views/reading_minutesare integer-or-null, no duplicate URLs, and every post URL has a built page./api/v1/*envelopes are correct (api_version,kind,countmatches), URLs are absolute, dates are ISO, posts are newest-first, and everymarkdown_urltwin actually exists in the build.llms.txtkeeps its “When to use this site” guidance and the 404 page keeps its agent recovery links.
If you change the shape of any JSON endpoint, update openapi.json in the
same commit - this script is what makes that contract binding.
4. Post-deploy live checks
After the Vercel deployment finishes (~1-2 min after the push):
curl -s -o /dev/null -w "%{http_code}\n" https://subramanya.ai/some-path-that-does-not-exist
Must print 404.
for u in /openapi.json /api/v1/site.json /api/v1/posts.json /api/v1/books.json /api/v1/tags.json /search.json /llms.txt /contact/ /privacy/ /docs/api-deprecation-policy/ /.well-known/api-catalog /sitemap.xml /feed.xml; do printf "%-30s %s\n" "$u" "$(curl -s -o /dev/null -w '%{http_code} %{content_type}' https://subramanya.ai$u)"; done
Every row must be 200 with the right content type (application/json for
the JSON endpoints, text/markdown for any index.md twin you spot-check).
Optionally, re-run the agent-readiness audit:
npx is-agentic subramanya.ai
Note: the audit service caches reports and throttles rescans, so a fresh score can lag a deploy by a while.