token-max-factory
Point-and-shoot programmatic SEO/GEO page factory — scan ANY website, then expand it into hundreds of validated token-max pages (2,800-3,400 words, 90%+ unique, GEO answer-first) via a universal Archon workflow. Use when the user says "token max", "site factory", "point and shoot
Install
npx skills add https://github.com/TheSmokeDev/geo-skills/tree/main/skills/token-max-factory
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install thesmokedev-geo-skills@llmmart
git clone https://github.com/TheSmokeDev/geo-skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole thesmokedev/geo-skills collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
token-max-factory — Universal Point-and-Shoot Content Factory
Drives the token-max-site-factory engine through Archon. Most programmatic SEO fails as thin duplicate content or hallucinated local "facts" — this factory attacks both with hard validation gates and a packet system where the packet is the ONLY fact source.
Before generation, require an owner-intent decision. Use the repository's
prompt-packs/dataforseo-intelligence/07-owner-intent-map.md when live search
evidence is available. Every cluster must be upgrade, create, consolidate,
or hold; TokenMax only receives approved create owners and bounded upgrades.
Hard boundary (never violate): the factory NEVER deploys, touches DNS, Search Console, sitemaps, or indexing. Generation ends at a clean validation report in the target repo's worktree. Shipping is a separate human-approved lane. A preflight node re-verifies this contract on every run.
Prerequisites (one-time)
# Archon CLI (free, MIT) — macOS/Linux:
curl -fsSL https://archon.diy/install | bash
# Windows PowerShell: irm https://archon.diy/install.ps1 | iex
# The engine (free, MIT):
git clone https://github.com/TheSmokeDev/token-max-site-factory
# or, via the Archon marketplace: archon workflow install token-max-site-factory
The writer runs on YOUR coding-agent subscription: codex at xhigh reasoning
by default; claude via explicit install --allow-claude. No SEO APIs, no
paid data vendors.
Quality contract (defaults, per page)
2,800-3,400 words (hard fail <2,700) · pairwise + cross-corpus shingle/Jaccard overlap ≤0.10 · ≥8 H2 · ≥4 AI-citable blockquotes · ≥5 FAQ questions · text-to-HTML ≥0.15 · unique title/meta · packet = only fact source · vertical prohibited-claim regexes.
Point-and-shoot: onboard a new site
cd token-max-site-factory
python engine/token_max_site_factory.py new-site --site <id> --target-repo <path> # 1. scaffold config
python engine/token_max_site_factory.py scan --site <id> --allow-network # 2. scan live site + local repo (the ONLY network step, manual)
# 3. edit sites/<id>/site.yaml — start from sites/example/site.yaml; see references/site-config.md
python engine/token_max_site_factory.py install --site <id> --run-input "pilot-10" # 4. stamp workflow shim + marker into target repo
cd <target-repo> && archon workflow run token-max-site-factory-<id> --no-worktree # 5. run
Prove one gold-standard owner page, then a representative 10-page pilot BEFORE any tranche. Tranches ≤300 pages (pairwise overlap is O(n²)). Review the worktree diff + report, merge, deploy through the site's own lane.
Choose program.scale in site.yaml:
starter: single operator/site and bounded pilot;growth: requires audience, conversion goal, evidence owner, success metrics, primary query, and canonical route owner;enterprise: additionally requires named reviewers and authority sources.
Scale adds governance and receipts, not permission to weaken gates. Community or Reddit research may justify one reviewed owner page, never an automated modifier page family.
Running on Archon 0.5.0 — CRITICAL gotchas
- Run input is BAKED at install time (
install --run-input "..."). 0.5.0 bash nodes do NOT receive the user message (regression; fixed on Archon's dev branch). To change what a run does, re-runinstallwith a new--run-input. Input grammar:pilot-10,<phase>,<phase>-tranche-300,--topics a,b --entities x,y --limit 20,--dry-run. - Never put dollar-sign shell variables in workflow YAML — 0.5.0 blanks
EVERY dollar token in inline node scripts. On-disk scripts
(
engine/tmsf.sh) are safe. The template is already dollar-free; keep it that way. - Archon's bash may be WSL bash — the template's if/else picks the
Windows vs
/mnt/c/...path form automatically. - Prefer
--detachfor long runs:archon workflow run <name> --no-worktree --detach— survives the launching shell. Track via the batch ledger, not the console. - Stale "running" rows block relaunch ("Workflow already active on this
path"). Fix:
archon workflow status→archon workflow abandon <run-id>(DB-only; safe when the process is dead). until_bashexit-1 "error" log lines during loops are normal — that's the "not done yet" signal; the loop is fine.
Resume & recovery (state is on disk, always resume-safe)
- Resume anything: re-run the same
archon workflow runcommand.prepare --resume --resume-existing-outputsfolds in every page already on disk. Never delete<artifacts>/state/batch.json. - Run died after generation finished? Finish deterministically, no Archon:
cd <target-repo> python <factory>/engine/token_max_site_factory.py validate --site <id> # hard gate python <factory>/engine/token_max_site_factory.py emit --site <id> # html sites; noop for markdown python <factory>/engine/token_max_site_factory.py report --site <id> - Ledger check:
remaining --site <id>or read<artifacts>/state/batch.jsonstatuses (pending_generation → generated/regenerated/held_back).
Verification checklist (after every batch)
<artifacts>/reports/validation.json→ok: true, 0 held back, 0 overlaps.<artifacts>/reports/batch-report.md— word counts in band and public states false. Check the siblingbatch-report.receipts.jsonfor SHA-256 config, prompt, batch, validation, source, and output receipts.- HTML sites: spot-open an emitted page; confirm canonical + FAQPage JSON-LD; if the site has its own head-baking tooling, prove it changes NOTHING on factory pages (emitted heads carry rel=canonical → skipped).
- Confirm pre-existing content lanes untouched (
git statuson the live tree).
Prompt profiles
local-service-seo, multi-location-enterprise, saas-b2b,
ecommerce-category, and regulated-insurance (California insurance rules as
the worked regulated example). New vertical = new profile in
prompts/profiles/ + site claim_rules_md.
No images are generated anywhere — text-forward by design (GEO extraction favors extractable text).
References
references/site-config.md— the full site.yaml schema, annotated- Engine
README.md— runbook + troubleshooting - Engine
WORKFLOW.md— the Archon marketplace package doc
Files (geo-skills)
-
references
-
site-config.md 7.1 KB
# site.yaml — full annotated schema One file per target site at `<factory>/sites/<site_id>/site.yaml`. Unknown top-level keys are REJECTED (typo protection). `bootstrap` snapshots the resolved config into the run's artifacts dir, so in-flight runs are immune to edits. Start from `sites/example/site.yaml` in the engine repo. ```yaml site_id: mysite # must match the directory name domain: mysite.com canonical_host: https://www.mysite.com target_repo_root: /path/to/mysite-repo # used by install + scan only; runs use cwd # --- output --- page_format: markdown # markdown | html | nextjs_content output_template: "content/{entity}/{topic_file_key}.md" # repo-relative; html sites: final .html path route_template: "/{entity}/{topic_route_segment}" # extensionless if the host uses cleanUrls staging_template: "" # html/nextjs sites ONLY: where the writer's markdown goes html_template: "" # html sites ONLY: repo-relative template with slots # {{TITLE}} {{META_DESCRIPTION}} {{CANONICAL}} {{JSONLD}} {{BODY_HTML}} {{LANG}} build_verify_command: "" # optional post-emit check run by the emit node locales: [en] # exactly one locale per run; propagated into packet/routes/rendering batch_kind: mysite-token-max # ledger identity; keep stable across runs provider: codex # claude requires install --allow-claude model_reasoning_effort: xhigh artifacts_dir: .token-max-artifacts/mysite/pilot # repo-relative, inside the worktree program: # governance tightens as scale increases scale: starter # starter | growth | enterprise business_model: local-service audience: local buyers comparing qualified providers conversion_goal: request a consultation evidence_owner: owner-operator reviewers: [owner] # required for enterprise success_metrics: [qualified organic inquiries] intent_contract: # required for growth and enterprise primary_query: my service route_owner: /services/my-service inventory: entities: # WHO the pages are about (cities, locations, products...) adapter: static_list # static_list (csv/json: name,slug + free columns) | ts_array (TS export regex) path: sites/mysite/facts/entities.csv # sites/... = factory-relative; else target-repo-relative topics: # WHAT each page covers — topics × entities = the page matrix - key: my-service aliases: [service] # accepted in run inputs file_key: my-service # filename slot route_segment: my-service # URL slot label: my service # prose label title_label: My Service # Title Case slot intent: who this page serves and why primary_decision: the one decision the page enables must_answer: [q1, q2, q3] # goes into the writer packet pilot_entities: [slug-a, slug-b] # ordered first; rest sort by population desc, then name sitemap_url: "" # scan override; default <canonical_host>/sitemap.xml crawl: { max_pages: 200, delay_seconds: 1.0, timeout_seconds: 15 } facts_files: [] # extra source-facts csv/json (listed in page sources) phases: # named presets — these are the run-input vocabulary pilot: { topics: "my-service", entities: pilot, limit: 10 } core: { aliases: [phase2], topics: "my-service,other", entities: all, limit: 500 } # run inputs: "pilot", "pilot-25", "core", "core-tranche-300", "--dry-run", "--limit N", # "--topics a,b", "--entities x,y", "all-entities" default_phase: pilot # what a bare/empty run input does frontmatter: # .format() slots: {entity_<field>}, {topic_label}, title_template: "{topic_title_label} in {entity_name}" # {topic_title_label}, {domain}... description_template: "{entity_name} {topic_label} guide." published: "" # empty = blank in frontmatter updated: "" prompt_profile: local-service-seo # local-service-seo | multi-location-enterprise | saas-b2b # ecommerce-category | regulated-insurance claim_rules_md: | # site-specific rules appended to the materialized writer prompt - Never invent prices, statistics, office locations, or local events. authority_sources: # cited official sources handed to the writer - { label: "...", url: "https://...", use: "what it's for" } quality: # ALL default to the proven production values — override sparingly target_words_min: 2800 target_words_max: 3400 hard_min_words: 2700 min_h2: 8 min_faq_questions: 5 min_ai_citable_passages: 4 min_source_links: 0 # enterprise enforces at least 1 named authority URL per page min_text_html_ratio: 0.15 max_pairwise_overlap: 0.10 max_cross_overlap: 0.10 shingle_size: 9 max_retries: 3 prohibited_patterns: # vertical regexes (compiled re.I|re.S); base set my_banned_claim: 'guarantee[ds]?\s+(outcome|result)' # (em_dash/guarantee/template_admission) always on utility_section_patterns: # stripped before overlap scoring (sources/related sections) - '##\s+Sources[\s\S]*?(?=\n## |\Z)' cross_corpus_roots: [content, other/corpus] # anti-rhyme corpora; .html files are tag-stripped cross_corpus_glob: "**/*.md" writer_contract: # prose musts injected into every packet must_include: [...] must_not_include: [...] comparison_corpus: {} # informational paths shown to the writer live_mutation: # preflight asserts ALL false — do not touch allow_deploy: false allow_dns: false allow_gsc: false allow_indexing: false ``` `growth` config loading fails without audience, conversion goal, evidence owner, success metrics, primary query, and route owner. `enterprise` additionally fails without reviewers and at least one authority source. The report emits `batch-report.receipts.json`; required reviewer receipts remain empty and all deployment/indexing/ranking/citation states remain false for the separate release lane to prove. ## Batch ledger vocabulary (state/batch.json) Page fields keep the original production lane's names for parity: `city` = entity slug, `product` = topic key. Statuses: `pending_generation → generated / regenerated / held_back`. `held_back` pages carry `validation_failures[]` + a `regenerate_with` hint and re-enter the writer loop until clean or `max_retries` exhausted. ## Engine CLI (all take --site <id>; batch/output paths default from artifacts_dir) `new-site` `scan [--allow-network]` `install [--run-input ...] [--allow-claude]` `bootstrap --input "..."` `preflight` `prepare` `prepare-from-input` `next-page` `packet --page-id X` `remaining [--exit-zero-when-done]` `pending-ids` `mark-generated --page-id X [--status regenerated]` `validate [--mark-held-back --no-fail] [--min-* overrides]` `validation-ok` `emit` `report` `scan-local-content`
-
-
SKILL.md 7 KB
--- name: token-max-factory description: Point-and-shoot programmatic SEO/GEO page factory — scan ANY website, then expand it into hundreds of validated token-max pages (2,800-3,400 words, 90%+ unique, GEO answer-first) via a universal Archon workflow. Use when the user says "token max", "site factory", "point and shoot", "expand this site", "generate city pages", "scan and expand", "programmatic pages for a site", "onboard a site to the factory", or "run the factory". Covers onboarding new sites, running and resuming batches, the Archon 0.5.0 gotchas, and verification. Requires the free Archon CLI version 0.5.0 or newer and the token-max-site-factory engine repo. --- # token-max-factory — Universal Point-and-Shoot Content Factory Drives the [token-max-site-factory](https://github.com/TheSmokeDev/token-max-site-factory) engine through [Archon](https://archon.diy). Most programmatic SEO fails as thin duplicate content or hallucinated local "facts" — this factory attacks both with hard validation gates and a packet system where the packet is the ONLY fact source. Before generation, require an owner-intent decision. Use the repository's `prompt-packs/dataforseo-intelligence/07-owner-intent-map.md` when live search evidence is available. Every cluster must be `upgrade`, `create`, `consolidate`, or `hold`; TokenMax only receives approved `create` owners and bounded upgrades. **Hard boundary (never violate):** the factory NEVER deploys, touches DNS, Search Console, sitemaps, or indexing. Generation ends at a clean validation report in the target repo's worktree. Shipping is a separate human-approved lane. A preflight node re-verifies this contract on every run. ## Prerequisites (one-time) ```bash # Archon CLI (free, MIT) — macOS/Linux: curl -fsSL https://archon.diy/install | bash # Windows PowerShell: irm https://archon.diy/install.ps1 | iex # The engine (free, MIT): git clone https://github.com/TheSmokeDev/token-max-site-factory # or, via the Archon marketplace: archon workflow install token-max-site-factory ``` The writer runs on YOUR coding-agent subscription: codex at `xhigh` reasoning by default; claude via explicit `install --allow-claude`. No SEO APIs, no paid data vendors. ## Quality contract (defaults, per page) 2,800-3,400 words (hard fail <2,700) · pairwise + cross-corpus shingle/Jaccard overlap ≤0.10 · ≥8 H2 · ≥4 AI-citable blockquotes · ≥5 FAQ questions · text-to-HTML ≥0.15 · unique title/meta · packet = only fact source · vertical prohibited-claim regexes. ## Point-and-shoot: onboard a new site ```bash cd token-max-site-factory python engine/token_max_site_factory.py new-site --site <id> --target-repo <path> # 1. scaffold config python engine/token_max_site_factory.py scan --site <id> --allow-network # 2. scan live site + local repo (the ONLY network step, manual) # 3. edit sites/<id>/site.yaml — start from sites/example/site.yaml; see references/site-config.md python engine/token_max_site_factory.py install --site <id> --run-input "pilot-10" # 4. stamp workflow shim + marker into target repo cd <target-repo> && archon workflow run token-max-site-factory-<id> --no-worktree # 5. run ``` Prove one gold-standard owner page, then a representative 10-page pilot BEFORE any tranche. Tranches ≤300 pages (pairwise overlap is O(n²)). Review the worktree diff + report, merge, deploy through the site's own lane. Choose `program.scale` in `site.yaml`: - `starter`: single operator/site and bounded pilot; - `growth`: requires audience, conversion goal, evidence owner, success metrics, primary query, and canonical route owner; - `enterprise`: additionally requires named reviewers and authority sources. Scale adds governance and receipts, not permission to weaken gates. Community or Reddit research may justify one reviewed owner page, never an automated modifier page family. ## Running on Archon 0.5.0 — CRITICAL gotchas 1. **Run input is BAKED at install time** (`install --run-input "..."`). 0.5.0 bash nodes do NOT receive the user message (regression; fixed on Archon's dev branch). To change what a run does, re-run `install` with a new `--run-input`. Input grammar: `pilot-10`, `<phase>`, `<phase>-tranche-300`, `--topics a,b --entities x,y --limit 20`, `--dry-run`. 2. **Never put dollar-sign shell variables in workflow YAML** — 0.5.0 blanks EVERY dollar token in inline node scripts. On-disk scripts (`engine/tmsf.sh`) are safe. The template is already dollar-free; keep it that way. 3. **Archon's bash may be WSL bash** — the template's if/else picks the Windows vs `/mnt/c/...` path form automatically. 4. **Prefer `--detach` for long runs**: `archon workflow run <name> --no-worktree --detach` — survives the launching shell. Track via the batch ledger, not the console. 5. **Stale "running" rows block relaunch** ("Workflow already active on this path"). Fix: `archon workflow status` → `archon workflow abandon <run-id>` (DB-only; safe when the process is dead). 6. **`until_bash` exit-1 "error" log lines during loops are normal** — that's the "not done yet" signal; the loop is fine. ## Resume & recovery (state is on disk, always resume-safe) - **Resume anything:** re-run the same `archon workflow run` command. `prepare --resume --resume-existing-outputs` folds in every page already on disk. Never delete `<artifacts>/state/batch.json`. - **Run died after generation finished?** Finish deterministically, no Archon: ```bash cd <target-repo> python <factory>/engine/token_max_site_factory.py validate --site <id> # hard gate python <factory>/engine/token_max_site_factory.py emit --site <id> # html sites; noop for markdown python <factory>/engine/token_max_site_factory.py report --site <id> ``` - Ledger check: `remaining --site <id>` or read `<artifacts>/state/batch.json` statuses (`pending_generation → generated/regenerated/held_back`). ## Verification checklist (after every batch) 1. `<artifacts>/reports/validation.json` → `ok: true`, 0 held back, 0 overlaps. 2. `<artifacts>/reports/batch-report.md` — word counts in band and public states false. Check the sibling `batch-report.receipts.json` for SHA-256 config, prompt, batch, validation, source, and output receipts. 3. HTML sites: spot-open an emitted page; confirm canonical + FAQPage JSON-LD; if the site has its own head-baking tooling, prove it changes NOTHING on factory pages (emitted heads carry rel=canonical → skipped). 4. Confirm pre-existing content lanes untouched (`git status` on the live tree). ## Prompt profiles `local-service-seo`, `multi-location-enterprise`, `saas-b2b`, `ecommerce-category`, and `regulated-insurance` (California insurance rules as the worked regulated example). New vertical = new profile in `prompts/profiles/` + site `claim_rules_md`. No images are generated anywhere — text-forward by design (GEO extraction favors extractable text). ## References - `references/site-config.md` — the full site.yaml schema, annotated - Engine `README.md` — runbook + troubleshooting - Engine `WORKFLOW.md` — the Archon marketplace package doc
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.