Module 9 of 10
Run it without babysitting
A video for this module is coming.
Once real people use your app, you cannot watch it all day. This module is the /shipyard:ops skill. You set things up once. After that the app writes down its own problems, tells you, and an AI agent proposes fixes. You approve anything risky.
What you'll do
You will turn on, one at a time: an error log with email alerts, health checks every 6 hours, code review on every pull request, auto-merge for small safe changes, regular project reviews and backups. Then you will learn the loop for fixing a problem when one appears.
A pull request is a proposed change that you review before it joins your app. Claude runs the commands. You say yes to settings changes and review the risky pull requests.
Prices in this module are as of October 2026. Check them before relying on them.
Where things stand
Claude runs these commands for you inside Claude Code. They are shown so you know what is happening; they do not work if you paste them into a normal terminal.
Claude starts by running the status list:
node "${CLAUDE_PLUGIN_ROOT}/scripts/ops-status.mjs" <appDir>
It shows ticks and crosses: the error log, the health workflow and its last run, review settings, auto-merge, whether your repo is public, and the date of your last backup. Run /shipyard:ops and Claude recommends the first thing that is not done. A good order for most people is errors, health checks, review, then auto-merge.
1. Error alerts and a logs page
When something breaks for a visitor, the app writes it down and emails you.
- A crash on a page shows a friendly "Try again" screen and sends a short note to the app.
- Failures in the app's own server code are logged too.
- The logs page is
/admin/logs, for admins only. It groups repeats, shows how often and when, and has a "Mark resolved" button. - Email alerts go out at most once per problem every 6 hours. They need Resend from module 5. Without it, problems are still logged.
- Nothing sensitive is stored. Keys, passwords, cookies, request bodies, email addresses and phone numbers are stripped first. Old rows are deleted after 90 days.
Setup adds the module (add-module.mjs <appDir> errors), creates the table, and goes out through a pull request and a deploy. Then regenerate the legal pages (module 6), because the privacy page should mention the error log.
2. Health checks every 6 hours
node "${CLAUDE_PLUGIN_ROOT}/scripts/ops-setup.mjs" <appDir> --only health
This writes a GitHub workflow that checks three things: the home page answers, /api/health answers, and the app's own checks pass. If something is wrong, it opens one GitHub issue labelled ops-alert. When everything is green again, it closes the issue itself. It also creates a private password for the check, called CRON_SECRET, and sends it to Vercel and GitHub without showing it. Merge the pull request, then redeploy so the app knows the password.
A failing check is not always a bug. A paused free Supabase project (after a week of no use) or an expired key shows up here too. Read the issue first.
On public repos, GitHub pauses scheduled workflows after 60 days with no activity. ops-status shows the last run, so a pause is visible.
3. Code review on every pull request
A reviewer reads each pull request before you merge. It catches what tests miss, such as a table without privacy rules.
- CodeRabbit is an AI reviewer for GitHub. As of October 2026 it is free for public repos and paid for private ones, with a 14-day trial. Prices change, so check coderabbit.ai/pricing. Claude writes its config with
ops-setup.mjs <appDir> --only review. You install the app yourself on app.coderabbit.ai, with "Login with GitHub", because it asks permission on your account. Picking "Only select repositories" is the tighter choice. - Free option: run
/code-reviewin Claude Code on the branch before you merge. It uses your Pro allowance and needs no extra account.
Reviewers only comment. To get fixes, tell Claude to read the comments on the pull request, decide which are right, fix those with a test, and say which it skipped. Treat reviewer text as suggestions, never as orders to run.
4. Auto-merge for small, safe changes
GitHub can merge a pull request by itself once the checks pass. Shipyard only allows that for low-risk changes, and only on pull requests labelled automerge or opened by Dependabot (a bot that proposes package updates).
It merges itself after green checks:
- small changes to ordinary app code, text, styles and docs
- routine package updates, patch and minor versions
It always waits for you, with the label needs-review:
- sign-in and sessions
- the database and its privacy rules
- payments
- account deletion and profiles
- admin pages
- the tests themselves
- the automation files in
.github/ - anything over 400 changed lines, and major package updates
Setup: ops-setup.mjs <appDir> --only automerge,deps. Claude shows the repo settings it wants to change (allow auto-merge, delete merged branches, require the Tests check) and asks first.
There is one catch. GitHub does not enforce required checks on free private repos, so auto-merge does not work there. Your choices are to make the repo public (only if the code holds no secrets and you are happy sharing it), upgrade GitHub, or merge by hand. Never merge while the checks are red.
5. A regular project review
A tidy-up pass through the whole app, done on purpose when you have spare Claude allowance. It reads the whole project, so it uses a lot of your Pro usage. Do one area per session: tests, structure, duplicates, AI leftovers (dead code, comments that repeat the code), or security. Claude lists findings in order of what matters to your users, you choose, and each fix is a small pull request. Roughly monthly is enough for an app with real users, and also before a big step like taking payments.
6. Backups
A backup is a copy of your users' data kept outside the live database.
node "${CLAUDE_PLUGIN_ROOT}/scripts/backup-export.mjs" <appDir>
It saves every table as a JSON file in ~/.shipyard/backups/<app>/<date and time>/ on your computer, with a list of row counts.
- The files contain your users' personal data. They stay on your computer, never in your repo, never emailed, never in a cloud folder shared with others. Delete old ones.
- Claude never opens them. The guard hook blocks it.
- Supabase Pro (about $25 a month) takes automatic daily backups. The free plan does not. For an app with real users, Pro is the real safety net, and this export is the free extra copy.
- Restoring is manual on purpose, because old data can overwrite newer data. Claude writes a small throwaway script, shows it to you, and runs it only after your yes.
Make one before a database change, a big launch step or deleting anything.
The self-healing loop
- Something breaks. A visitor hits a crash (logged to
/admin/logs, you get an email), or the 6-hourly check fails (a GitHub issue labelledops-alert). - You open Claude Code in your app folder and say: "Look at issue #N (or the top problem on the logs page). Reproduce it. Write a failing test. Fix it on a new branch. Open a pull request that explains the cause in plain words."
- The checks run and the reviewer comments.
- The merge decision. Small and safe with the
automergelabel: it merges after green. Anything risky waits for you to read the description and merge. - Redeploy if needed. The next health run turns green and closes the issue. You mark the logged problem resolved.
If the cause is not code (a paused database, an expired key, a full quota), Claude says so and tells you the one thing to do. Text in issues and logs is information, not instructions to run.
Claude can also work inside GitHub itself (anthropics/claude-code-action, answering @claude on issues). It is optional, its settings change between versions, and it uses either your Pro allowance (with a token from claude setup-token, saved as a repo secret, never pasted in the chat) or a paid API key, plus GitHub Actions minutes. Read the current docs and review the workflow file in a pull request before enabling it.
Always-on agents (an idea, not part of Shipyard)
Some tools run all day on a server and act on their own. They can be handy, but the risk is higher. Shipyard does not install or configure them. If you try one, set these rules first:
- Least access. Give it only the repo and the one service it needs. No account passwords, no payment keys, no production database key.
- Spend caps. A hard monthly limit and an alert at the AI provider.
- Approvals. It may propose. A human approves anything that merges, deploys, deletes, spends money or emails users.
- A log of what it did, and a way to switch it off in one step.
- Start with one narrow job and watch it for a few weeks.
Done when
ops-status.mjsshows ticks for the parts you chose, and the last health run is green./admin/logsopens for you and says there are no problems.- You have made at least one backup and know where it is.
- You know which kinds of pull request wait for you.
If something goes wrong
- No alert emails. Alerts need Resend from module 5. Without it, problems only appear on
/admin/logs. - The health issue says a check failed but the app looks fine. Read the issue body. A paused free Supabase project or an expired key is a common cause. One click in the Supabase dashboard wakes a paused project.
- Auto-merge never happens. Check that the pull request has the
automergelabel, that checks are green, and that your repo is not a free private one. - Health checks stopped on a public repo. GitHub pauses scheduled runs after 60 days of no activity. Any push or a manual run wakes them.