seo-autopilot
World-class autonomous SEO/AEO end-to-end. Input: one ID (keyword, competitor, idea). Output: shipped + monitored page with multi-agent debate-derived strategy.
npx skills add seo-autopilot
Skill: SEO Autopilot — One ID In, Ranked Page Out
The user's contract: give one input (keyword / competitor / idea / single sentence), receive a shipped, indexed, AEO-optimized, monitored page. Zero further user touchpoints unless a 3-Strike rule fires.
This skill is the highest-level SEO entry point. Most user-facing SEO requests should route here unless the user explicitly says "just write the brief" or "don't ship yet."Read first (every run)
Before doing anything, load the standing principles:
py/skills/seo-principles/SKILL.md— every prior user comment baked into rulesseo-flow— the skill map (which skill to call when)aeo-playbook— the maturity model and 90-day plan context
The 8-phase autopilot loop
[1] DISCOVER → 4-agent debate on whether/how to chase the input
[2] DECIDE → template path (existing type) or new theme (scaffold-type)
[3] BRIEF → 1-page brief grounded in debate + competitor study
[4] PRODUCE → scaffold-page (en + locale placeholders), fill via LLM, write JSON
[5] AUDIT → run scripts/seo/audit-page.ts; auto-fix Tier 1 deterministic issues
[6] PUBLISH → git commit on main (Tycoon convention) → Cloud Run auto-deploys
[7] MONITOR → enqueue scheduled checks (7d/14d/30d) → seo-experiment-log
[8] LEARN → on day 30, write outcome to seo-learn / seo-retro
Each phase has a clear input, output, and bail condition. A phase can fail safely without dropping the others.
Phase 1 — DISCOVER (multi-agent debate)
The hardest decision is whether and how to chase the input. Single-agent reasoning produces mediocre SEO. Run a 4-agent debate in parallel:
| Agent | Role | Lens |
|---|---|---|
| Classicist | SEO purist | Google rank, keyword volume, SERP competition, backlink reality |
| AEO Specialist | AEO purist | Answer engines, citation potential, fan-out queries, off-page presence |
| CRO Strategist | Conversion lens | "If we rank, will it convert?" — is the audience commercial? |
| Competitive Intel | Top-3 in category | What do the leading players already do? Where's their gap? |
Then a synthesizer (default agent) reads all 4 positions and answers:
- GO / NO-GO: should we ship?
- Template path: which content type matches?
- Angle: what unique angle separates us from the top 3?
- i18n priority: ship en only, or batch translate immediately?
- Risk: what could make this page get deindexed (thin content, scaled-content abuse, off-topic)?
reports/seo/autopilot/--debate.md (audit trail). Continue.
If NO-GO: write a single comment to the user with the synthesized reason and stop. Don't ask follow-up questions.
Phase 2 — DECIDE
Map debate output to actions:
Existing type matches debate's template path → use it
No type matches → scaffold-type FIRST, then continue
Do not invent a new type if a stretched fit exists. "vs/
i18n decision: default ship to all 3 SEO locales (en + zh-CN + ja placeholder + auto-translate). Only delay translation if debate flagged "audience is single-locale specific" (rare).
Phase 3 — BRIEF
Write a brief file at reports/seo/autopilot/:
# Brief: <input>
Search intent
<from debate>
Top 3 currently ranking
<URLs + 1-line angle each>
Our angle (different from top 3)
<one paragraph>
Required elements
- Answer-first lede (40-60 words exact wording)
- ≥ 3 fact anchors with sources
- ≥ 5 FAQ Q+A
- ≥ 6 internal links (list specific target slugs)
- Schema type(s)
i18n
- en: ship now
- zh-CN: <ship now | placeholder | skip>
- ja: <ship now | placeholder | skip>
Measurement
- Primary metric: <impressions / clicks / citations / signups>
- Target by day 30: <specific number>
- Bail condition: <metric below X by day Y → seo-postmortem>
The brief is the contract. If Phase 4-5 deviates from it, the autopilot is broken — fix the autopilot, don't quietly diverge.
Phase 4 — PRODUCE
# From ts/
pnpm seo:new-page <type> <slug>
Then fill the JSON. Use Claude with the brief as system prompt + Tycoon's voice patterns (read 3 high-performing existing pages of the same type as few-shot examples). Do NOT free-write — every field maps to the brief.
If new type was needed, scaffold-type runs first and the autopilot pauses ONCE to allow the human-readable manual-wiring steps from scaffold-type.ts output to be applied. (This is the only allowed user touchpoint per autopilot run.)
For batch input (5+ slugs from a programmatic data source), the brief covers the SHAPE, not each instance. Each instance gets its own JSON-fill pass with brief + per-instance data.
After fill: log experiment to seo-experiment-log BEFORE shipping. Hypothesis + measure_at = today + 14 days.
Phase 5 — AUDIT
pnpm seo:audit <type>/<slug> --json
If exit code = 0 (PASS): proceed. If exit code = 1 (FAIL): auto-fix where deterministic:
- Title length > 60 → trim while preserving keyword + year
- Description length > 155 → trim
- Description first 60 chars generic → rewrite via LLM with brief constraint
- updatedAt missing → set to today
- relatedSlugs < 3 → query content-loader for sibling slugs in same type, cross-link
- faqs < 3 → fill from brief's FAQ list
If audit passes: also call aeo-audit skill for Tier 2 LLM judgment. Treat its output as "soft fixes for next iteration" — don't block initial publish on it.
Phase 6 — PUBLISH
git add ts/src/content-seo/<type>/<slug>.json \
ts/src/content-seo/<type>-zh/<slug>.json \
ts/src/content-seo/<type>-ja/<slug>.json
git commit -m "seo: ship <type>/<slug> via autopilot
- intent: <one line from brief>
- target: <metric / number from brief>
- experiment: logged with measure_at <date>"
git push origin main
Cloud Build → Cloud Run deploys. The audit-seo.yml GHA runs post-deploy — its result goes to Lark, not blocking.
After 60-180 seconds, run the Tycoon 5-step deploy verification:
gh run list— both Deploy + Build agent are completed/successcurl -sS -o /dev/null -w "%{http_code}" https://tycoon.us/returns 200/ gcloud run services describe tycoon-web --format='yaml(status.traffic)'— latestRevision percent=100- Headless Playwright screenshot of the new page (desktop + mobile)
grepthe rendered body for any TODO/placeholder leakage
Phase 7 — MONITOR
Enqueue scheduled tasks via the existing scheduler:
- Day 1: GSC URL Inspection — confirm indexed
- Day 7: GSC impressions / position — early signal
- Day 14: full GSC + GA4 — measure_at point for the experiment
- Day 30: aeo-citation-track query bucket includes the new slug — citation lift?
- Day 30: full retro: traffic + citations + conversions vs brief target
seo-experiment-log. The user does not need to monitor; if results miss target, the day-30 check fires seo-postmortem automatically.
Phase 8 — LEARN
On day 30, the autopilot calls seo-learn:
- If the page hit target: extract what worked into a pattern → playbook
- If the page missed: extract why → lessons
- Either way: this knowledge feeds back into future autopilot Phase-1 debates
World-class quality bar (non-negotiable defaults)
Every shipped page from autopilot must meet:
- [ ] Answer-first lede 40-60 words, fact-anchored (≥ 1 specific number/date/proper noun)
- [ ] Exactly one H1, sane H2/H3 hierarchy, H2s phrased as questions when natural
- [ ] ≥ 3 FAQ Q+A
- [ ] ≥ 6 internal links (relatedSlugs)
- [ ] Schema.org JSON-LD: at minimum BreadcrumbList + (FAQPage | Article | HowTo | Product)
- [ ] Visible "Last updated: YYYY-MM-DD" rendered on page
- [ ] ≥ 300 unique words (vs. boilerplate-stripped median of same type)
- [ ] No purple / indigo / violet (design system rule, also aesthetics)
- [ ] No
bg-white, no hardcoded hex (design system rule) - [ ] No clickbait title ("You Won't Believe X" → REJECT)
- [ ] No keyword stuffing (≤ 1.5% density of primary keyword)
- [ ] No internal slugs / vendor names / cost data leaked (privacy rule)
- [ ] PostHog event tracking for primary CTA on the page (if any)
- [ ] Hreflang matrix complete (all 3 SEO locales registered, even if 2 are placeholders)
- [ ] CTA goes to
signuporchat— never directly to Stripe (cold-traffic rule) - [ ] Markdown version available at
via existing renderer.md
3-Strike escalation (only allowed user touchpoint)
The autopilot escalates to user only when:
- Phase 1 debate produces 4 conflicting positions and synthesizer can't reconcile (rare — usually means input is ambiguous; user gets one clarifying question)
- Phase 5 audit fails 3 consecutive auto-fix passes (page can't be saved; show user the failing checks)
- Phase 6 deploy verification fails (revert + ask user to inspect)
feedback_ai_drives_flow: AI proposes the next action, user confirms or redirects.
Memory & continuity
- Every autopilot run writes a debate file + brief file. Future runs READ the past 5 debates for the same type as additional context — pattern-match across runs.
- The
seo-principlesSKILL is loaded EVERY run and is the source of truth for user preferences. Never re-ask things already in there. - After every run, autopilot updates
seo-principleswith any new explicit principle the user states during the run (mediated byseo-learn).
What autopilot will NOT do
- Auto-translate without human review when the locale is ja (machine ja translation quality varies; we offer it, user opts in)
- Spend gateway credits (
mcp__skillboss__chat) above $1 per page without check - Ship a page that fails any "non-negotiable defaults" check (no override, no exceptions)
- Operate on a domain other than tycoon.us / configured workspace domain — the autopilot is workspace-scoped
- Replace existing pages without the user explicitly saying "refresh" or "rewrite"
OUTPUT CONTRACT (privacy)
All published artifacts (page JSON, markdown render, llms.txt entries) follow:
- No internal vendor names, internal slugs, cost data
- No prompt strings, internal model IDs, internal skill names
- Generic capability claims OK ("AI generates the brief"); not implementation details
Quick start for the user
The user just types:
autopilot kiro
autopilot ai-data-engineer
autopilot "what's the cheapest way to use Claude in Cursor"
autopilot https://github.com/replit/ghost
Autopilot infers type from input shape and runs all 8 phases. User sees periodic progress (1-line per phase) and a final shipped link. Day 7 / 14 / 30 monitor results arrive automatically.