# ============================================================ # RSL - Really Simple Licensing 1.0 # Global directive (not scoped to any user-agent group). Crawlers must # retrieve and comply with these terms before processing site content. # Spec: https://rslstandard.org/rsl # ============================================================ License: https://built2winweb.com/license.xml # ============================================================ # CONTENT SIGNALS (Cloudflare Content Signals Policy) # search = appear in a traditional search index (links + excerpts) # ai-input = use content in real-time generative answers (RAG) # ai-train = use content to train or fine-tune a model # # All three are YES. This site WANTS to be read, cited and surfaced by # AI assistants - that is the entire point of the agent surface it # publishes (MCP, A2A, NLWeb, llms.txt). Signals are declarative, not # enforcement. The RSL License directive above carries the legal terms. # ============================================================ User-agent: * Content-Signal: search=yes, ai-input=yes, ai-train=no Allow: / # ------------------------------------------------------------ # LANGUAGE VARIANTS (?lang=xx) — NOT CRAWLED. Added 2026-09-13. # # WHY THIS IS HERE AND WHY IT IS NOT THE MISTAKE DOCUMENTED FURTHER DOWN # Read the "Pruned URL families" note below before touching this. That note # says, correctly, not to robots-block a URL that carries a meta tag Google has # to FETCH in order to obey. The ?lang= variants are the opposite case, on # every point that mattered there: # # - They carry no noindex. They serve and a # rel=canonical pointing at the bare English URL. Nothing is being asked of # Googlebot that a block would prevent it from hearing. # - The consolidation has ALREADY happened. Search Console reports 6,583 of # them as "Alternate page with proper canonical tag" -- Google has read the # canonical, accepted it, and excluded them. There is no deindexing left to # do that this block could defeat. # - Their "follow" value is nil. The outgoing links on a ?lang= page are # either the same ten header destinations every English page already links, # or more ?lang= URLs. No link equity reaches anywhere it was not already # going. # # WHAT IT COSTS AND WHAT IT BUYS # The sitemap carries 28,779 URLs. Every one of them is reachable in eleven # languages through the switcher, so the crawlable surface was about 316,000 # URLs, of which roughly 287,000 can never rank because they canonicalise away. # Meanwhile Cloudflare rate limiting answers 429 after ~70 requests in ~10s per # IP (measured 2026-09-13: the 71st sequential request tripped it, Retry-After # 10). Googlebot cannot crawl a 316,000-URL site through a 70-per-10s gate, and # Search Console shows the result -- 679 "Server error (5xx)", 36,953 "Crawled # - currently not indexed", 14,125 "Discovered - currently not indexed", and # breadcrumb-eligible items down from ~9,000 in June to 57. # # This is exactly the lever the pruned-families note names: "reduce the NUMBER # of these variants". It reduces them to zero for crawlers while leaving every # translation working for the people who click the switcher. # # WHY TWO PATTERNS, AND WHY NOT "&lang=". # "/*?lang=" catches the ordinary case, where lang is the first parameter. # The obvious companion, "/*&lang=", DOES NOT WORK -- verified against a # Google-spec parser (protego), which allows /a/?utm=1&lang=es straight # through it. "/*?*lang=" is the one that matches a lang parameter in any # position, and it still requires a query string, so it cannot accidentally # catch a path segment that happens to contain "lang=". Do not "simplify" # this to a single "&" rule; it silently stops blocking anything with a # tracking parameter in front of the language. # Under RFC 9309 the longest match wins, and both are longer than "Allow: /". # # TO REVERT: delete the two Disallow lines, and drop rel="nofollow" from the # switcher anchors in includes/site-header.php, index.php, web-design.php, # web-design-city.php, article-layout.php and state-of-ai-agent-readiness.php. # ------------------------------------------------------------ Disallow: /*?lang= Disallow: /*?*lang= # ------------------------------------------------------------ # Machine-readable discovery documents (added 2026-08-08) # CRITICAL: these MUST out-rank the "Disallow: /*.json$" rule further # down. Under RFC 9309 the longest matching pattern wins, and every # path here is longer than the 8-character "/*.json$", so these win. # Without them robots.txt was forbidding every manifest the site # publishes - agents.json, openapi.json, server.json and the entire # .well-known tree (agent-card, acp, mcp, agent-skills, permissions). # A perfect manifest on a disallowed path is an invisible manifest. # ------------------------------------------------------------ Allow: /.well-known/ Allow: /agents.json$ Allow: /agents.txt$ Allow: /openapi.json$ Allow: /server.json$ Allow: /license.xml$ Allow: /llms.txt$ Allow: /llms-full.txt$ Allow: /AGENTS.md$ Allow: /sitemap.md$ # Editing backups (*.bak-*). .htaccess already 403s these, so every fetch is a # wasted round trip. The .well-known variant is spelled out in full because the # blanket "Allow: /.well-known/" above is a longer match and would win otherwise. Disallow: /*.bak* Disallow: /.well-known/*.bak* # Allow essential assets Allow: /fa/css/ Allow: /fa/webfonts/ Allow: /js/ Allow: /*.webp$ Allow: /*.css$ Allow: /*.js$ # Allow IndexNow key file (must be publicly crawlable for verification) Allow: /b2w9a4f3c7e1d8b6e5f2a0c3d7e9f1b4.txt # Disallow cache — hundreds of JSON files waste crawl budget Disallow: /cache/ # Disallow sensitive and non-content directories Disallow: /state_blocks/ Disallow: /tmp/ Disallow: /logs/ Disallow: /admin/ Disallow: /PHPMailer/ Disallow: /PHPMailer-6.8.0/ Disallow: /stripe-php-14.10.0/ Disallow: /vendor/ Disallow: /composer/ # Disallow non-public utility scripts Disallow: /generate_cities.py Disallow: /generate_city_details.php Disallow: /split-city-details.php Disallow: /test_place_id.php Disallow: /test_weather.php Disallow: /debug.php Disallow: /ctr-graph.php Disallow: /InvoiceSystem.php Disallow: /send_invoice.php Disallow: /create_stripe_session.php Disallow: /stripe_success.php Disallow: /send_contact_email.php Disallow: /notify-indexnow.php # Disallow raw data files Disallow: /*.csv$ Disallow: /*.json$ Disallow: /*.zip$ # ------------------------------------------------------------ # Decorative trust badges - crawl-budget sink (added 2026-08-01) # Cloudflare AI Crawl Control showed Claude-SearchBot pulling these # files ~1,350x / 3.7 MB in 24h, re-fetching despite # Cache-Control: max-age=31536000, immutable. They already carry # X-Robots-Tag: noindex,nofollow via .htaccess, so they have zero # index value and nothing is lost by blocking the fetch. # Longer path match beats the "Allow: /*.webp$" rule above. # ------------------------------------------------------------ Disallow: /goodfirms.webp Disallow: /yelp.webp Disallow: /sitelock.webp Disallow: /trustpilot.webp Disallow: /norton.webp Disallow: /bbb.webp Disallow: /google.webp Disallow: /upwork.webp Disallow: /hostinger.webp Disallow: /pcs.webp Disallow: /blank.gif # ------------------------------------------------------------ # Pruned URL families - state/city variants # # The 31 "Disallow: //*/" lines that used to sit here were REMOVED on # 2026-09-06, deliberately. Please read this before putting them back. # # Those same 31 families are served by # config/pruned-slugs.php. Blocking them here meant Googlebot never fetched # them, and a page that is never fetched is a page whose meta tag is never # read. The block defeated BOTH halves of that tag: # # noindex - never seen, so the URLs could still be indexed URL-only from any # external link. The block did not reliably deindex anything. # follow - never seen, so no link equity moved through these pages to the # national page each one points at. That flow is the whole reason # the tag says "follow", and it was silently doing nothing. # # The crawl-budget saving was real (Cloudflare AI Crawl Control measured 0 # referrals across 4,798 of these paths) and giving it up is the cost of this # change. It buys reliable deindexing and restores internal authority to the # national pages, which is where the rankings actually are. # # If crawl budget becomes the bigger problem again, the lever is to reduce the # NUMBER of these variants, not to block URLs carrying a meta tag Google has to # fetch in order to obey. # ------------------------------------------------------------ # ============================================================ # AI / LLM CRAWLERS — explicitly welcomed so the full site can be # read, cited, and surfaced by AI search engines and assistants. # Same protections as the default group (sensitive dirs stay blocked). # ============================================================ User-agent: GPTBot User-agent: OAI-SearchBot User-agent: ChatGPT-User User-agent: ClaudeBot User-agent: Claude-SearchBot User-agent: Claude-User User-agent: anthropic-ai User-agent: Claude-Web User-agent: PerplexityBot User-agent: Perplexity-User User-agent: Google-Extended User-agent: Applebot-Extended User-agent: Amazonbot User-agent: Meta-ExternalAgent User-agent: CCBot User-agent: Bytespider User-agent: cohere-ai User-agent: YouBot Content-Signal: search=yes, ai-input=yes, ai-train=no Allow: / # ------------------------------------------------------------ # LANGUAGE VARIANTS (?lang=xx) — NOT CRAWLED here too. Added 2026-09-13. # Full reasoning is on the identical pair in the "User-agent: *" group above; # it is not repeated here. The short version: every ?lang= URL canonicalises to # the bare English URL, so an AI crawler that follows one is reading a duplicate # of a page it can already reach, and eleven of them per page is what put the # crawlable surface at ~316,000 URLs against a 429 gate. Blocking them costs no # content coverage -- the same pages remain fully open in English. # ------------------------------------------------------------ Disallow: /*?lang= Disallow: /*?*lang= # ------------------------------------------------------------ # Machine-readable discovery documents (added 2026-08-08) # CRITICAL: these MUST out-rank the "Disallow: /*.json$" rule further # down. Under RFC 9309 the longest matching pattern wins, and every # path here is longer than the 8-character "/*.json$", so these win. # Without them robots.txt was forbidding every manifest the site # publishes - agents.json, openapi.json, server.json and the entire # .well-known tree (agent-card, acp, mcp, agent-skills, permissions). # A perfect manifest on a disallowed path is an invisible manifest. # ------------------------------------------------------------ Allow: /.well-known/ Allow: /agents.json$ Allow: /agents.txt$ Allow: /openapi.json$ Allow: /server.json$ Allow: /license.xml$ Allow: /llms.txt$ Allow: /llms-full.txt$ Allow: /AGENTS.md$ Allow: /sitemap.md$ # Editing backups (*.bak-*). .htaccess already 403s these, so every fetch is a # wasted round trip. The .well-known variant is spelled out in full because the # blanket "Allow: /.well-known/" above is a longer match and would win otherwise. Disallow: /*.bak* Disallow: /.well-known/*.bak* Disallow: /cache/ Disallow: /state_blocks/ Disallow: /tmp/ Disallow: /logs/ Disallow: /admin/ Disallow: /vendor/ Disallow: /composer/ Disallow: /PHPMailer/ Disallow: /PHPMailer-6.8.0/ Disallow: /stripe-php-14.10.0/ Disallow: /*.csv$ Disallow: /*.json$ Disallow: /*.zip$ Disallow: /goodfirms.webp Disallow: /yelp.webp Disallow: /sitelock.webp Disallow: /trustpilot.webp Disallow: /norton.webp Disallow: /bbb.webp Disallow: /google.webp Disallow: /upwork.webp Disallow: /hostinger.webp Disallow: /pcs.webp Disallow: /blank.gif # ------------------------------------------------------------ # Pruned URL families - state/city variants # # The 31 "Disallow: //*/" lines that used to sit here were REMOVED on # 2026-09-06, deliberately. Please read this before putting them back. # # Those same 31 families are served by # config/pruned-slugs.php. Blocking them here meant Googlebot never fetched # them, and a page that is never fetched is a page whose meta tag is never # read. The block defeated BOTH halves of that tag: # # noindex - never seen, so the URLs could still be indexed URL-only from any # external link. The block did not reliably deindex anything. # follow - never seen, so no link equity moved through these pages to the # national page each one points at. That flow is the whole reason # the tag says "follow", and it was silently doing nothing. # # The crawl-budget saving was real (Cloudflare AI Crawl Control measured 0 # referrals across 4,798 of these paths) and giving it up is the cost of this # change. It buys reliable deindexing and restores internal authority to the # national pages, which is where the rankings actually are. # # If crawl budget becomes the bigger problem again, the lever is to reduce the # NUMBER of these variants, not to block URLs carrying a meta tag Google has to # fetch in order to obey. # ------------------------------------------------------------ # AI guide files (for LLMs / AI assistants — not a robots directive, informational) # LLM-Content: https://built2winweb.com/llms.txt # LLM-Content: https://built2winweb.com/llms-full.txt # Sitemap # ARD (Agentic Resource Discovery): points agents and readiness scanners # straight at the capability manifest instead of guessing the path. Agentmap: https://built2winweb.com/.well-known/ai-catalog.json Sitemap: https://built2winweb.com/sitemap.xml Sitemap: https://built2winweb.com/news/sitemap.xml # The AI website builder lives on its own host and carries its own sitemap. # Cross-host Sitemap lines are allowed in robots.txt (sitemaps.org, "Sitemaps & Cross Submits"). Sitemap: https://aiwebbuilding.built2winweb.com/sitemap.xml