fromclaudetoprod.dev
menu
Nightly verification — not yet armedwhat this means →

My Setup

What follows is not a description of how Claude works on this site. It is the actual file — AGENTS.md, at the root of the repository — that Claude Code loads at the start of every session here. It is rendered from the same source; there is no copy. If a rule below and the site's behavior ever disagree, the site is wrong, and that gets fixed first.

Every rule carries its reason. That's the only trick in it.

AGENTS.md · rendered from sourceLIVE

Operating Contract

This is the contract Claude Code works under on fromclaudetoprod.dev. It is loaded at the start of every session, and it is rendered, unedited, on the site's My Setup page. Those are the same file. If the two ever disagree, the site is lying, and fixing that comes before anything else.

Every rule here carries its reason. A rule with a reason gets applied correctly to situations it does not literally cover. A bare rule gets followed literally and worked around the moment it is inconvenient.

What this repository is

An eight-page static site arguing that shipping production software written entirely by Claude is defensible — provided you know which security work the tool covers by default, which it covers only when asked, and which it never covers. The site practices its own argument: there is no pull request gate, and the replacement for human code review is an automated nightly process that checks results rather than diffs.

The nightly process is Phase 2 and does not exist yet. Until it does, the status indicator on every page says so.

Structure

  • app/ — routes. One folder per page, page.tsx inside. Layout, metadata routes, and error boundaries live at the top level.
  • content/ — every word a reader sees. Prose is MDX, one file per page or section. Checklist items are typed data in content/checklist.ts.
  • components/ — shared building blocks. Each has one job and knows nothing about the others beyond its props.
  • lib/ — the three modules everything else reads: site.ts (name, URL), routes.ts (the eight routes and their nav order), verification-status.ts (the status indicator's single source of truth).
  • docs/ — specs, plans, source drafts, and the docs/site/ packet. Never served.
  • tests/ — Vitest. Data tests, route-existence tests, and the contract compile test. No component or browser tests.

Commands

  • npm run dev — local server
  • npm run build — production build. This is what Vercel runs.
  • npm run check — typecheck, lint, and tests in one command.
  • npm test — tests alone

Rules, with reasons

Commits go directly to main. Every commit. No branches, no pull requests.

This is the site's premise. The homepage says Claude ships to production from a chat window with no code review; a branch-and-merge workflow in this repo would make that sentence untrue. Phase 2's nightly verification is what makes the practice defensible; until it exists, the risk is accepted and stated openly rather than hedged in the process.

Practical consequence: run npm run check and npm run build before every push. check alone is not the gate, because it does not build. A red build on main is a red production deploy.

No user input. No forms. No third-party scripts.

Every input path is attack surface the nightly job has to probe. Every external script is a dependency the nightly job cannot verify. The site has no database and no auth because it needs neither, and the absence is a property worth protecting, not a stage to grow out of.

Vercel Web Analytics is the one script that is not ours: first-party to the host, cookieless, and served from this origin (Vercel proxies it under a per-deployment path), so no runtime request leaves the origin.

The status indicator reports only a state the system can prove.

lib/verification-status.ts returns not-armed until the nightly job exists and writes real results. Never hardcode a passing state, never render a timestamp the job did not produce. A green bar before the job exists would be a fabricated trust signal on a site whose premise is that claims get verified — and it is the one screenshot that would end the argument.

No page, callout, or metadata asserts a factual claim the author cannot substantiate.

The case study route names a disclosed vulnerability in Claude Code's GitHub Action. Until the primary disclosure is in hand and read, no text on the site states its mechanism, vendor, or severity. This applies to content/, to meta descriptions, and to OG text.

On a site whose product is being the person who checks things, an incorrect attribution is the one error that cannot be absorbed.

Content edits go to content/. Layout edits go to components/ and app/.

With no diff review, the narrower the blast radius of a routine change, the better. A copy fix should never touch a React file, and a layout fix should never touch prose. If a change needs both, make two commits.

Verify against the deployed site, not the local build.

Build-scope proof is not runtime proof. A green npm run build says the code compiles. It says nothing about what Vercel served. After a push, check the deployment:

  • Preview and production URLs: vercel ls fromclaudetoprod
  • Production: fromclaudetoprod.dev once DNS is pointed; until then the *.vercel.app production alias.

Evidence of a working page is the URL, what was observed, and the date. "I verified this" with none of those is not evidence.

The docs/site/ packet is the only packet, and it stays honest.

docs/site/README.md holds the site's invariants with their reasons. change-log.md gets an entry only when a future reader would be misled without one — a behavior change, an incident, a reversed decision. Routine changes do not get entries; git history is the audit trail. A troubleshooting.md is created the day the first real failure is solved, not before. Empty files that exist to satisfy a shape train readers to skip the whole packet.

Files carrying the breadcrumb

// Docs (REQUIRED-READ-BEFORE-EDIT, UPDATE-ON-CHANGE): Site overview: /docs/site/README.md

are inside this contract: read the README before editing them, update the packet after if the change invalidates something in it. A hook reminds you; it never blocks.

Secrets live in Vercel's environment settings. Never in source, never in content/.

There are no secrets in source, because there is nothing to authenticate to. Git history is permanent and this repository may go public, so a key committed once is a key leaked forever. If Phase 2 adds secrets, they go in Vercel's project settings and are read from process.env. The nightly job's first stage will scan committed content for leaked keys; do not give it something to find.

Who does what

Claude may: edit anything in the repo, commit, push to main, run builds and tests, read Vercel deployment state.

Production is reached only by pushing main. No vercel deploy, no vercel promote, no vercel rollback from a session — a manual deploy breaks the rule that git history is the deploy log.

Claude may not without asking: add a dependency that loads at runtime in the browser, add any route that accepts input, change the Vercel project's settings, change DNS, make the repository public, force-push or rewrite history on main, edit .claude/settings.json (widening the allowlist is self-authorization), or alter this file's rules (fixing a typo is fine; changing what a rule says is a conversation).

Only the owner does: DNS, repository visibility, and arming the nightly job when it exists.

STAGE: PENDINGThe Utah game

The full Utah game story: phone → remote Claude Code session → home machine with the only database access → branch → production, and why that isolation is the entire security story. Plus the mockup-to-implementation workflow that makes it repeatable.

waiting on a diagram and the narrative draft