Automate three steps before you automate thirteen.
On 30 October, the new-site launch chain was split into 13 steps. The first version ran three of them: build, wait for approval, release. The code budget was 145 lines. A working shortest chain shows where the other ten steps attach.
For anyone running several export sites alone, that order saves more time than a full rollout.

What the shortest chain proved
Build and release already had working code. The missing piece was the runner that connects them. The first version only adds an executor: create tasks in dependency order, start them, collect results.
| State | Entered when | Next |
|---|---|---|
| blocked | A high-risk task is created | Approval moves it to queued, rejection to canceled |
| queued | A low-risk task is created, or approval arrives | A worker picks it up and moves it to running |
| running | Work starts | Success moves it to succeeded, an error to failed |
| succeeded | The worker returns cleanly | Downstream steps unlock |
| failed | The worker raises | It stays put until a person retries |
| canceled | Approval is rejected | Nothing else runs |
An unapproved release sits in blocked. Once approved it moves to queued, runs, and lands in succeeded. Any exception leaves the task in failed.
The value is not the clicks saved. It is a queryable record of who changed production, and when.
Thirteen steps, three gates
| Step | Action | Risk | Gate |
|---|---|---|---|
| S1 | Domain pre-check | Low | None |
| S2 | Register domain and set DNS | High | G1 purchase approval |
| S3 | Allocate disk and memory | Low | Above threshold goes to G2 |
| S4 | Initialize environment | Low | None |
| S5 | Build site | Low | None |
| S6 | Release to production | High | G3 launch approval |
| S7 | Submit to indexes | Low | None |
| S8 | Daily content | Low | None |
| S9 | GEO tuning | Low | None |
| S10 | Outbound links | High | G4 send approval |
| S11 | Health checks and repair | Low | None |
| S12 | Customer replies | Low | High intent goes to a person |
| S13 | Competitor review | Low | None |
The three gates cover three kinds of action: buying a domain, exceeding a budget, and touching production. If a gate stays closed, the steps below it do not run.
The test for asking a person
A step can run unattended when three conditions hold. The result is reversible. A second run does not create a second side effect. One command can prove success. If any condition fails, add a gate.
Five actions always need a person: releasing to production, buying a domain, exceeding a budget, bulk deletion, and sending something outside the company. The first two spend money and cannot be undone. The third changes the spending ceiling. The last two reach other people.
Each approval carries a hash of its payload and expires after 24 hours. Change one parameter and the hash changes, so the old approval no longer applies. The check blocks the case where the approved job and the executed job differ.
Idempotency keys and their grain
An idempotency key is the step's identity card. Run the same key twice, and the second run should do nothing.
| Step | Key | Grain |
|---|---|---|
| Domain check | Site plus domain | Domain |
| Register and DNS | Site plus domain | Domain |
| Resource allocation | Site plus date | Day |
| Environment init | Site plus date | Day |
| Build | Site plus first 12 chars of content hash | Content |
| Release | Site plus release id | Release |
| Index submission | Site plus date | Day |
| Daily content | Site plus date | Day |
| GEO | Site plus ISO week | Week |
| Outbound | Site plus channel plus week | Channel by week |
| Health check | Site plus date | Day |
| Customer reply | Site plus ticket id | Ticket |
| Competitor review | Site plus ISO week | Week |
The wrong grain causes two failures. With a date key, an unchanged site rebuilds every day and releases pile up. With a site-only key, changed content never rebuilds. A content hash rebuilds only when the content changes.
There is one acceptance test. Run the whole chain twice on the same day. The second run should add no records.
The budget was off by one line
The review draft added up to 368 lines against a 377-line ceiling. It looked fine. Adding the files one by one gave 378, one line over.
Two options. Cut the first version to 145 lines and move the control-layer edits to the next batch. Or delete 10 lines elsewhere to make room.
We took the first. Deleting working code to hit a line count makes the ledger look better and leaves the next person guessing why a section is missing.
Workers also get their own directory and their own budget. They call external APIs, so their line count grows by stage. Packing them into the orchestration layer only recreates the same one-line argument later.
Failures stay where they are
The six states include no skip. A failed task stays failed. It can be retried. It cannot pretend to succeed and let the chain continue. A heartbeat timeout moves running back to queued so another machine can pick it up.
The reason is simple. If a failed build is skipped, the release step can publish an empty directory. Stopping costs a wait. Skipping costs a blank page in front of a customer.
The limit is documented too. The control layer has no failed-to-queued transition, so a retry can only re-enter a queued task. On a full-chain rerun, the release id from the earlier build was never stored, so the operator resumes with an explicit version id. That fix belongs to the next batch.
Where this fits
| Sites | Launch rhythm | What to do |
|---|---|---|
| 1 to 2 | Twice a year | Publish by hand, keep a release ledger |
| 3 to 5 | A new site each month | Run the three-step chain |
| More than 5 | Work every week | Add the remaining ten steps |
Two preconditions matter. Without a staging preview, do not automate production releases. Without someone on call, do not turn on automatic publishing. Automation removes repeated actions. It does not remove responsibility.
FAQ
What should a site automation start with
Start with state records, not workers. If you cannot answer whether a task exists, where it stopped, and who approved it, automation only spreads the mess faster.
Does an approval gate slow launches down
The gate only covers five high-risk actions. Ordinary builds and health checks run directly. A release task checks approval every 2 seconds for up to 1 hour. With no decision, it stays blocked.
Will a failed step be skipped automatically
No. It stays failed until a person acts. A heartbeat timeout only returns running to queued. Nothing is skipped, and nothing is marked successful without a result.
Is this worth it for three sites
Build the release ledger and rollback first. With fewer than one launch a month, the runner costs more to maintain than it saves. Add the chain after two or more launches a month.
Last updated: 2026-10-31