# GoLive [English](README.md) · [简体中文](README.zh-CN.md) · [日本語](README.ja.md) · [한국어](README.ko.md) · [Español](README.es.md) · [Português (Brasil)](README.pt-BR.md) · [Deutsch](README.de.md) **Take your agent-built product live: hosting, database, auth, domain, email, payments — on your own accounts. Then hand it over, or tear it all down.** Your coding agent can build an app in minutes. Getting it to real users still means accounts, hosting, databases, domains, secrets and connected services. GoLive is the open-source Agent Skill for that work: it **detects what your app needs, plans the exact changes, asks for your approval, applies them with your own logins, and verifies what actually works** — then records what it created, re-checks it for drift on demand, and can remove it again. Automate the parts providers expose. Guide you through the parts that need a human. Verify what can be observed, and make unfinished work clear. No GoLive account, hosted backend or product telemetry. > **Early alpha · 0.1.0-alpha.8** > Disposable live tests now cover six journeys: **hosting** (Vercel, Netlify), **database** > (Supabase, Neon), **custom-domain DNS** (Porkbun, GoDaddy), **transactional email** (Resend), > **test-mode payments** (Stripe) and **Supabase authentication**, plus the `teardown` uninstall > path. The ownership document and the on-demand `golive status` drift check are implemented > with test coverage (`golive status` also ran read-only in a live validation), while the broader > [roadmap](#the-full-go-live-checklist-and-roadmap) is our direction, not a claim that it is all built. ## Before you hand over production access Whether to give an agent your provider accounts comes down to four questions. These are this project's answers, with the limits stated where they exist. - **You still approve every write.** Nothing reaches a real account without a plan you have seen and approved: `apply` refuses without that plan's id and `--yes`, and it re-checks the plan's identity before writing, so a changed release or config invalidates the old approval. DNS writes need `--confirm-dns`, deletions need `--confirm-destroy`, and live-mode steps — live payments, production data, a real account — need `--confirm-live`, which now includes a project's **first production deploy**, because approving a plan alone used to be enough to write production for the first time. Credential values are read only in-process, never printed, and never in arguments, plans, state or reports; the file golive stores them in is plaintext at mode 0600 outside your repo, not a keychain. One limit worth naming: those flags are arguments the agent passes on your behalf, and an agent already logged in to your provider can write there with no golive plan at all. [Trust, access and control](docs/TRUST.md) separates what the code enforces from what is only an instruction the agent is asked to follow. - **A run stops rather than pushing on.** `apply` stops at the first failed check, missing confirmation, missing prerequisite or provider that contradicts the plan. Later steps do not run, and the next `apply` resumes at that step. [Recovery](docs/RECOVERY.md#the-run-stopped) covers reading the failure, which steps resume, and the cases that need a reviewed decision first. - **Rollback is narrow, opt-in and never automatic.** A failed check never triggers a rollback. `release.rollback: true` plans one step that re-points production at an earlier deployment golive itself recorded; a deployment built by a dashboard, a Git push or a pull request is not a target, and it touches no data, DNS, payment or email resource. Only Netlify supports these re-points today — on Vercel you correct production in the dashboard (Vercel's adapter has no read of what production serves). Promotion and rollback are implemented and mock-covered, **not live-validated**. - **Nothing is left behind silently — which is not the same as nothing being left behind.** `golive teardown` removes only resources it can prove it created, re-reads the DNS zone and the host project after deleting, and names every leftover it cannot remove — Supabase and Neon projects, the Resend sending domain, a zone or host project it cannot read — as a handoff saying what remains and how to remove it by hand. A removal also forgets the baseline golive recorded for that resource, so `golive status` does not report golive's own teardown as drift. Those answers in full: [trust, access and control](docs/TRUST.md) and [recovery](docs/RECOVERY.md). The [architecture](docs/ARCHITECTURE.md) is the product contract, [provider scope](docs/PROVIDERS.md) says what each provider can do today, the [validation record](docs/VALIDATION.md) separates what has been exercised live from what is only mock-covered, and [distribution](docs/DISTRIBUTION.md) covers installation and updates. [Install](#install) · [Use GoLive](#use-golive) · [See the workflow](#what-a-run-looks-like) · [Alpha scope](#what-this-alpha-supports) · [Roadmap](#the-full-go-live-checklist-and-roadmap) · [Contribute](CONTRIBUTING.md) ## Install You need **Node.js 20+**, npm/npx, Git, and a coding agent that can load skills and run commands. Installation has been checked for Codex and Claude Code; other clients are unverified. **Install once for all your projects.** Run this from any directory: ```bash npx skills add https://github.com/mikehasa/golive-skill --skill golive --global ``` Select your agent when prompted: use the arrow keys to move, Space to select, and Enter to confirm. That screen is waiting for input; installation continues after you confirm. To skip the agent picker, use the command for your agent: ```bash # Codex npx skills add https://github.com/mikehasa/golive-skill --skill golive --global --agent codex --yes # Claude Code npx skills add https://github.com/mikehasa/golive-skill --skill golive --global --agent claude-code --yes ``` For installation in just one project, run from that project's repository and omit `--global`. **Or paste this into your coding agent:** ```text Install the GoLive skill globally so I can use it across projects: npx skills add https://github.com/mikehasa/golive-skill --skill golive --global Target the agent I'm using: add --agent codex --yes for Codex, or --agent claude-code --yes for Claude Code. Keep --global. If the agent isn't clear, ask me which one. Verify the installation with: node /scripts/golive.mjs version --json Tell me if I need to reload skills or start a new session. Stop after installation; don't connect accounts or deploy yet. ``` The install includes the instructions, provider references and prebuilt runtime. It does not connect accounts or deploy anything. See [installation and updates](docs/DISTRIBUTION.md) for noninteractive agent flags, runtime verification and the optional own installer. ### Install from npm The same skill is published to npm as `golive@0.1.0-alpha.8` (dist-tags `alpha` and `latest`), which installs it offline, with no Git or Skills CLI involved: ```bash # Codex npx golive@alpha install --agent codex # Claude Code npx golive@alpha install --agent claude ``` Add `--global` to install into your home directory (`~/.agents/skills/golive` or `~/.claude/skills/golive`) instead of the current project; `--agent claude-code`, the spelling the Skills CLI channel uses, is accepted as well. The installer copies the complete skill the package ships with, refuses an existing destination, and never connects provider accounts. **Both channels carry the same release.** The npm package publishes the version in this repository, including the standalone installer helpers, so an npm installation is an owned copy that updates in place. The earlier `0.1.0-alpha.0` snapshot has no updater: remove that copy and reinstall, or use the GitHub channel, which manages its own installs. The npm package also exposes the terminal CLI: the golive commands `npx golive@alpha help`, `version`, `update-check`, `credentials`, `detect`, `menu`, `init`, `doctor`, `plan`, `teardown`, `apply`, `verify`, `status` and `handoff` (`apply` needs the approved plan ID and explicit confirmation), plus the installer commands `install`, `install-status`, `update`, `rollback`, `update-policy` and `recover-lock` for the copies it owns. See [installation and updates](docs/DISTRIBUTION.md#alternative-installation-the-npm-package) for the channel's exact limits. ### Install from ClawHub (OpenClaw) If you use [OpenClaw](https://docs.openclaw.ai), the same skill is listed on [ClawHub](https://clawhub.ai/mikehasa/skills/golive), its public registry: ```bash npx clawhub@latest install golive # into ./skills, recorded in .clawhub/lock.json npx clawhub@latest update golive # later updates stay with ClawHub ``` ClawHub installs into the current directory's `skills/` folder rather than an agent's global skills directory, so it suits an OpenClaw workspace; Codex and Claude Code are the clients this project verifies, through the two channels above. The registry keeps its own metadata (`_meta.json`, `skill-card.md`, `.clawhub/`) beside the bundle, which golive's own integrity check ignores. See [installation and updates](docs/DISTRIBUTION.md#clawhub-openclaw-registry) for the channel's limits. ## Use GoLive Open your app repository in your coding agent. After installation, reload skills or start a new session if GoLive does not appear. The skill's name is **`golive`**. For the standalone installation above, type one of these **in your agent's chat**: | Agent | Example prompt | | --- | --- | | [Codex](https://learn.chatgpt.com/docs/build-skills#how-chatgpt-and-codex-use-skills) | `$golive Help me take this app live.` | | [Claude Code](https://code.claude.com/docs/en/skills) | `/golive Help me take this app live.` | You can also ask in plain language: ```text Use the golive skill to take this app live. Keep the providers it already uses. Show me the destination accounts and plan before changing anything. ``` GoLive inspects the app, asks about missing providers, and presents the destination accounts and plan for your approval before making provider changes. These are chat prompts. `golive skill` is not a command. Installing through `npx skills add` does not add a `golive` command to your terminal; the agent runs the included CLI from the installed skill directory. The [npm package](#install-from-npm) can also install the skill offline and exposes that CLI as `npx golive@alpha `; its terminal commands run individual operations rather than the conversational skill workflow. ## What a run looks like An illustrative conversation for an app that already uses Supabase: > **You:** Use golive to take this app live. Use test resources for now. > > **Agent:** This app uses Supabase. Where would you like to host it? > > 1. **Vercel** — built-in hosting workflow; live-tested with Supabase. > 2. **Netlify** — built-in hosting workflow; the live-tested pairing is Netlify + Neon. > 3. **Other** — tell me your provider; I'll try a guided setup using its official tools and docs. > > **You:** Vercel. > > **Agent:** We'll keep Supabase. Does this app already have a Supabase project, > or should we create a new test project? > > **You:** Create a new one. > > **Agent:** Run `vercel login` and `supabase login` in a separate terminal window. > I'll check which account and organization are connected when you're done. > > **You:** Done. > > **Agent:** Here's the plan: create a new test frontend project in your selected Vercel team, > create its database in your selected Supabase organization, transfer the required environment > values, and deploy. I'll show the actual destination names and IDs, resource settings and cost > information with the plan. Approve before I apply it. > > **You:** Approved. > > **Agent:** The deployment is live. Here is the URL, the verification report, and anything still > unverified. Next we'll test the app's own signup and data flows. When you're done with this test > project, `golive teardown` plans its removal for your approval before anything is deleted. GoLive keeps the provider choices already in your app and asks about missing pieces. You handle signups, browser logins, identity checks and purchases. If an API key is needed on macOS, a native hidden-input dialog explains why it is asking and where the key will be saved. Its value goes directly to the local credentials file, never to chat or command output. Other platforms use your own editor as a fallback. A later change to the plan needs another approval; connecting auth or a domain may require a follow-up after the first deploy. **Using another provider?** The skill has a general guided flow: check the provider's official CLI, an available official MCP integration or API, then guide you through its dashboard if needed. The agent still shows the destination, changes and cost before asking for approval, and checks what it can afterward. This is **best-effort guidance**, with no guarantee of completion or the same verification coverage as a built-in adapter. If a step cannot be completed or verified, you get the specific blocker and next action. See [guided provider scope](docs/PROVIDERS.md#guided-providers). ## What this alpha supports **Two hosting choices: Vercel and Netlify. Two database choices: Supabase and Neon.** | Live-tested path | What was exercised | | --- | --- | | **Vercel + Supabase** | Provisioning, environment wiring, deployment, authenticated CRUD and access isolation | | **Netlify + Neon** | Provisioning, environment wiring, deployment, Postgres connectivity, two-session API checks and browser CRUD | | **Vercel + Porkbun (custom domain)** | Domain attachment, an approved DNS record write under `--confirm-dns`, ownership verification and HTTPS serving on a disposable subdomain | | **Vercel + GoDaddy (custom domain)** | The same journey on a second subdomain, including the ownership TXT challenge Vercel requested after attaching | | **Vercel + Resend (email)** | Sending-domain setup, DNS records, domain verification and a real send through the app's own environment key (delivered; the fresh subdomain landed in spam) | | **Vercel + Stripe (test payments)** | Test-mode keys and webhook registration, an unsigned-request rejection, and a real test-card payment delivered as a signature-verified event | | **Supabase Auth (SMTP + password recovery)** | Custom-SMTP write read back with the raised auth email rate limit, and the whole recovery rotation on the seeded test account — accepted request, identical answer for an unknown address, spent token refused on replay, new password signing in and the old one refused | These were approved disposable runs on existing accounts; completed test resources were deleted afterward, and recent runs' disposable projects and records are cleaned up under the same supervision. Cross-pairings have mocked coverage, not equivalent live proof. Supabase CLI-login reuse separately passed read-only verification; the complete deployment test used an explicit token. A new user's first-account setup and every application framework have not been validated. The lifecycle commands have their own evidence: `golive teardown` was live-exercised on a disposable Netlify project (blocked without `--confirm-destroy`, then removed, the account's site list unchanged apart from it) and earlier runs removed the GoDaddy and Porkbun records golive had written, revoked the Resend sending keys it had issued and removed the Stripe test-mode endpoint it had registered. `golive status` ran read-only against a live project; `golive handoff --write` ran on a disposable Vercel-only fixture: both artifacts were written and audited (a provenance tag on every claim row, the ownership proof and the teardown gate named, no credential-shaped value in the document, its JSON twin, state or config), and the project was removed afterwards through the approved teardown flow — the stack was host-only, so the document's other-provider rows remain mock-covered. See [observed validation](docs/VALIDATION.md) for the evidence. Experimental adapters also exist for Supabase Auth configuration, the Supabase Auth signup journey, its password recovery and account isolation, and Cloudflare DNS. Supabase Auth settings — signup, email confirmation, minimum password length, the mailer it uses, plus the site URL and redirect allowlist — are automated through an approved plan and re-read for evidence, and that path passed a disposable live run: the policy write held in the read-back (`password minimum length: 6 → 12`) and `auth-policy` ended with the built-in-mailer advisory as its only finding. The opt-in signup journey (`auth.e2e`) passed the same run: one approved step seeded a real test account (`auth:test-user`, needs `--confirm-live`), the address could not sign in before confirming (`email_not_confirmed`), and the `auth-signup`/`auth-session` checks proved the signup email, the enforced confirmation, the confirmed login, the session token and the anonymous refusal. Two limits stay: the confirmation was applied through the Auth admin API rather than the seeded account's own email click, and inbox delivery is human-confirmed by design — golive never sees the inbox. A later approved run on a disposable fixture (a deployed Vercel site whose declared route answers 401 without a session, plus one RLS-protected table) exercised both app-side legs: an anonymous GET of `auth.protectedPath` answered 401 and the signed-in probe read that table as the authenticated user, so the probe's bearer fix is no longer mock-covered. What that evidence cannot show: that run's table line is a count rather than table names, and any 401 counted as protected — a WAF or maintenance page would read the same; both were fixed afterwards (issue #30: the probe names the tables it read, and a refused protected path is corroborated against the public root, with mocked coverage and no live re-run yet). Password recovery is **live-validated on the same provider**: the same 2026-09-24 run carried `auth.smtp: resend` (the custom-SMTP write and the raised auth email rate limit, both read back) and `auth.recovery: true`, whose one approved step (`auth:recovery`, needs `--confirm-live`) rotated that recorded test account's password through the provider's own recovery calls — request the email, mint the link with the admin API, exchange it for a session, set the new password with that session — and the `auth-recovery` check passed every leg: the request was accepted, an address with no account got the same answer (no account enumeration), the spent token was refused on replay, the new password signed in and the one it replaced did not. The inbox click and any captcha stay with the human (the `auth:recovery-email` handoff says so), the SMTP password is write-only (the provider answers a hash, so the read-back proves the settings, not a delivery), and the account was confirmed through the Auth admin API rather than the owner's click. Account isolation is implemented on the same provider too: `auth.isolation: true` with `auth.identityPath` and `auth.isolationPath` adds one approved step (`auth:isolation`, needs `--confirm-live`) that seeds a **second** real test account — the address derived from `auth.testEmail`, the password again only in that run's memory — and confirms it through the provider's admin API (no second inbox click: the journey is about the app's data, not delivery). The `auth-isolation` check then signs in as both accounts and reads the app's own two declared routes on the production URL: both must refuse an anonymous caller (a 200 is a critical finding), each account's identity route must answer with its own user id and never the other's, and the rows route must return only the caller's own rows — checked with one unique marker row per account written **through that route** with the account's session and read back, so another account's marker in the answer is a cross-account read and fails critically. When the routes are not declared, the non-blocking `auth:isolation-routes` handoff hands the app-code task over; a 404 or a refused session skips with that task named, never as a pass. Account isolation is **implemented and mock-covered, not live-validated yet** — its live run comes separately. The recovery run's own output contained two defects, both fixed here with mocked regressions: `teardown` reported the owner's *adopted* sending domain as created by golive (an empty creation-marker list made `[].every()` true, so every recorded domain read as golive's), and the `auth:recovery-email` handoff showed a standalone `verify` skip as its evidence while state recorded that step done. Its third finding — Resend kept reporting that domain verified while the records it listed were absent from the zone's authoritative nameserver — is fixed by [#52](https://github.com/mikehasa/golive-skill/issues/52): `email-verified` now resolves the records the provider itself lists for the domain before passing (a verified domain whose records are gone fails, a record golive wrote inside the propagation window only warns, and a provider that cannot list them skips rather than passing), and the email plan keeps the `email:dns` step or handoff for records that do not resolve, so a stale flag can no longer hide them. Mock-covered; not re-exercised live. The DNS, email and test-mode payment paths listed above are the tested ones, with the custom-domain runs using Porkbun and GoDaddy record writes; **Cloudflare DNS specifically is not a validated alpha path yet**, and other auth providers stay guided. See [provider scope](docs/PROVIDERS.md) and [observed validation](docs/VALIDATION.md). ## The full go-live checklist and roadmap A working URL is the beginning. Depending on the app, going live can mean all of the following. **GoLive should work out which items apply, help you finish them, and show evidence for the result.** A static site should not be asked to set up a database; a paid SaaS should not stop at a deployed homepage. This is our product roadmap as a launch checklist. Checkmarks and strikethroughs mark **specific live-tested milestones**, not a finished category or a completed checklist for your app. **✅ Live-tested** · **🚧 In progress / experimental** (code exists; complete journey pending) · **🗺️ Planned** ### Ship the app - [x] ✅ **Frontend hosting:** ~~Prove deployment on Vercel and Netlify.~~ Build, deploy and verify the intended project on the two tested paths. - [x] ✅ **Database:** ~~Prove provisioning and connection with Supabase and Neon.~~ The tested paths include environment wiring and application CRUD checks. - [x] ✅ **Environment wiring:** ~~Connect hosting and database credentials on both tested paths.~~ Broader secret rotation and environment lifecycle management remain planned. - [ ] 🗺️ **Backend / servers:** dedicated API services, containers, persistent servers, runtime configuration and health checks. App routes already deploy through the supported hosts. - [ ] 🗺️ **Schema and data:** reviewed migrations, safe rollout, environment separation and app data checks. These were separately supervised in live tests; a reusable workflow is still planned. - [ ] 🗺️ **File and object storage:** buckets, uploads, access rules, signed URLs and lifecycle policies. ### Make it a complete product - [ ] 🚧 **Authentication:** signup, login, sessions, password recovery and account isolation. Supabase auth policy (signup, email confirmation, minimum password length, mailer) and the site URL/redirect allowlist are written through an approved plan, re-read for evidence and verified by the `auth-policy`/`auth-redirects` checks — exercised in an approved disposable run, where the policy write held at a twelve-character minimum. The opt-in journey (`auth.e2e: true`) passed the same run: the `auth:test-user` step seeded a real test account, that address could not sign in before confirming, and the `auth-signup`/`auth-session` checks proved the signup email, the enforced confirmation, the confirmed login and the session token — **live-validated for Supabase across disposable projects, where the confirmation came through the Auth admin API instead of the seeded email click, inbox delivery stayed human-confirmed, and a later run proved a declared protected path (an anonymous 401) and a signed-in read of an RLS-protected table, reported as a count rather than a table name**. Password recovery is **live-validated on the same provider** (`auth.recovery: true` adds the `auth:recovery` step and the `auth-recovery` check, which proved no account enumeration, a one-time token and the replaced password on a disposable project; the confirmation came through the Auth admin API, the inbox click stays human-confirmed, and two output defects that run found — a false "created by golive" ownership claim and a handoff evidence text contradicting the recorded step — are fixed with mocked regressions). Account isolation — the other half, and the one earlier runs could not exercise — is implemented and mock-covered the same way: `auth.isolation: true` with `auth.identityPath` and `auth.isolationPath` adds the `auth:isolation` step (a second real test account, confirmed through the provider's admin API and recorded by id and address) and the `auth-isolation` check, which signs in as both accounts and proves on the app's own routes that neither can read the other's identity or rows (a cross-account read fails critically; an undeclared or 404 route skips with the app-code task). Its live run comes separately too. Other auth providers stay guided. - [ ] 🗺️ **OAuth / social login / SSO:** client registration, consent screens, scopes, callback URLs and provider reviews. Current auth-provider setup is guided. - [x] ✅ **Payments and subscriptions:** ~~Prove test-mode checkout and webhook acceptance with Stripe.~~ A real test-card payment delivered a signature-verified `checkout.session.completed` event. A new read-only `stripe-live-payment` check reads the most recent succeeded live PaymentIntent, the live webhook endpoint that would receive it and the matching delivery event, and reports any refund; it is implemented and mock-covered but not live-validated yet. Live-mode readiness, entitlements, refunds and subscription events still need validation. - [x] ✅ **Transactional email:** ~~Prove sending-domain setup, verification and real delivery with Resend.~~ A send through the app's own environment key was delivered (to spam on a fresh subdomain, no DMARC yet). With `auth.smtp: resend` the `auth:smtp` step also writes the auth project's custom SMTP — Resend's host/port/user, the sender the app already uses, and an SMTP password taken from a sending key golive issued (the email journey's key, or one it issues for SMTP alone) — and raises the project's own auth email rate limit (`rate_limit_email_sent`) to 30 per hour (or `auth.emailRateLimitPerHour`) in the same write, because the provider keeps that limit with custom SMTP. `auth-policy` then reports `custom SMTP via Resend` instead of warning about the built-in mailer. The password is write-only (the provider answers a hash), so the read-back confirms the settings and a real auth email is the only full proof. **Live-validated on a disposable project (2026-09-24)**: the same run wrote the custom SMTP and read it back (`smtp.resend.com`, port 465, user `resend`, sender `auth@mail.trytofu.xyz`) together with `auth email rate limit: 2 → 30 per hour`, issued the SMTP key by itself and revoked it in teardown, and `auth-policy` then read `custom SMTP via Resend` with 30 auth emails/hour — settings and rate limit only, since the password itself can never be read back. Bounce handling, richer message content and actual inbox delivery (human-confirmed by design, and doubtful on that run's domain — see [issue #52](https://github.com/mikehasa/golive-skill/issues/52)) still need validation. - [x] ✅ **Domains / DNS / HTTPS:** ~~Prove domain attachment, DNS wiring and HTTPS serving on host+DNS pairs.~~ Tested: Vercel attachment with Porkbun and GoDaddy record writes under `--confirm-dns`, ownership verification and HTTPS 200 on disposable subdomains. The Cloudflare DNS adapter, redirects and further host pairings still need live validation. - [ ] 🗺️ **SMS and push notifications:** sender registration, credentials, permissions and delivery checks. - [ ] 🗺️ **Third-party and AI services:** API access, scopes, callbacks, quotas and functional tests. Missing environment variables are detected today; service-specific workflows are planned. - [ ] 🗺️ **Background work:** cron schedules, queues, workers, retries and failed-job recovery. - [ ] 🗺️ **Cache, search and realtime:** caches, search/vector indexes and realtime services when needed. ### Launch with confidence, then keep it running - [ ] 🗺️ **Security and abuse controls:** access policies, exposed credentials, security headers, rate limits and bot protection. Scoped RLS/advisor and credential-pattern checks exist today. - [ ] 🗺️ **Monitoring and alerts:** error tracking, logs, uptime and actionable alerts. Provider suggestions are guided today; verified setup is planned. On-demand drift checks exist (`golive status`, below) — continuous monitoring and alerting do not. Sentry is implemented as an automated monitoring provider — adapter, host env wiring and the `sentry-ingest` check, mock-covered with no live run yet. - [ ] 🚧 **Product analytics:** event validation and consent/data settings, beyond today's guided provider suggestions. PostHog analytics is wired through an approved plan — the app's analytics project is adopted or selected (a create is planned when nothing matches), and the `posthog-ingest` check proves ingest by sending one synthetic event and reading it back through PostHog's own query API — live-validated on a disposable project (2026-09-30). Host env writing, consent settings and the app's own event flows stay open; the create/delete path of a golive-created project is mock-covered only. - [ ] 🚧 **CI/CD and safe releases:** previews, release checks, promotion, rollback and drift detection, building on today's approved CLI deployments. **Deployment identity — implemented, not live-validated:** each successful deploy records the provider's own identity for the deployment it made (`deployed::id` = `|||