
On temphomefinder.com, a code gate decides which AI-researched county zoning pages get built. As of October 10, 2026 it has rejected 33 of the 124 counties researched, and the live sitemap lists exactly the 91 that passed.
That sounds like a gate working. It mostly is. But when I re-ran its logic against every research file, I found 9 published pages that say no more than the 33 it blocked. This post covers what the gate checks, why pages failed, and the hole in it.
What does TempHome Finder publish, and where do the pages come from?
TempHome Finder is my national temporary housing directory. Its centerpiece is one page per county answering a single question: can you live in an RV on your own lot while your house is rebuilt?
The county list comes from research/priority-counties.csv: 200 counties ranked by FEMA disaster declarations over ten years. AI coding agents researched them, mostly in batches of 12, almost all on September 11, 2026. Each county becomes a JSON file in research/compiled/, and there are 124 of them.
The compiler has one rule I am glad I wrote early. If a file claims RV occupancy is allowed, conditional or prohibited without an ordinance URL behind it, the script forces the answer back to “unknown.” No source, no answer.
What does the publish gate actually check?
The gate is one function, shouldPublishCountyPage in src/lib/zoning/slugs.ts. A county passes if it is phone-verified, or if it is compiled and its ordinance_section field is not empty. It must then pass a “swap test”: at least one field that would be wrong if you swapped in another county’s name.
The swap test accepts any of six fields: permit name, permit fee, maximum days, ordinance section, planning office phone, or a post-disaster note longer than 20 characters.
How many pages passed in each batch?
I ran the gate against each 12-county batch exactly as the files stood in that batch’s commit. Results ranged from 2 of 12 to 12 of 12.
| Batch commit (Sept 11, 2026) | Passed at commit | Rejected |
|---|---|---|
| Deep research, 12 counties (262f7a5) | 12 of 12 | 0 |
| Batch “21/20” (d717e07) | 9 of 12 | 3 |
| Second “batch 3” (a7a8b05) | 10 of 12 | 2 |
| FEMA batch 4 (0fceb97) | 11 of 12 | 1 |
| FEMA batch 5 (54c7e9e) | 2 of 12 | 10 |
| FEMA batch 6 (e34bb1d) | 9 of 12 | 3 |
| FEMA batch 7 (cc64b84) | 3 of 12 | 9 |
| FEMA batch 8 (7db874d) | 7 of 12 | 5 |
| All 124 files today | 91 | 33 |
Batch 8 is the one I would have guessed at: 7 of 12. Its five rejects are all Louisiana parishes where the research file says no ordinance was found online. Louisiana carries most of the rejects overall: 23 of its 48 researched parishes fail.
Rejection was not final. A commit that added 28 unresearched county stubs had 2 of 28 passing. Later batches went back to those counties, and today all 28 pass. The gate became the research queue.
Would the rejected pages really have been interchangeable?
Google’s spam policies define scaled content abuse as “creating large amounts of unoriginal content that provides little to no value to users, no matter how it’s created.” The first example listed is “using generative AI tools or other similar tools to generate many pages without adding value for users.”
So I rebuilt the meta description each rejected page would have shipped with. The page template writes it from four fields: occupancy, permit, duration and post-disaster rule. Of the 33 rejected counties, 28 produce the same sentence, word for word:
Temporary RV occupancy is unknown. Permit: unknown. Duration: not stated in available sources. After disaster: not stated.
That is 28 pages differing only by county name. They are the pattern in Google’s first example. The 33 rejects produce just 6 distinct descriptions; the 91 passing pages produce 70.
27 of the 33 rejects record no ordinance source at all. Their honest content is one line: call the parish. That line is useful, but it belongs on the state page, not on 28 URLs.
What happens to a county below the gate?
It never becomes a URL. The same spam policy section ends: “If you’re hosting such content on your site, exclude it from Search.” I traced every route a county could take into Search and checked each against the live site.
- The static build only generates counties the gate passes.
- The sitemap reads the same list. The live sitemap has 192 URLs, and 91 of them are county pages, matching the gate’s count exactly.
- A direct request for a rejected county returns 404 with a noindex tag. I checked Avoyelles Parish and Brevard County: both 404.
- The 3,144 counties in the national seed file are all “unverified,” so none of them build. Neither do the 76 priority counties nobody has researched yet.
The state pages still list rejected counties in their tables, without a link. That is the right place for “not yet researched.”
Doesn’t a swap test stop interchangeable pages?
This is what I assumed, and it is wrong. The swap test checks that a field is filled in. It does not check what the field says.
Look at the order of operations. A compiled county only reaches the swap test if ordinance_section is non-empty. A non-empty ordinance_section passes the swap test by itself. So for 121 of the 124 files, the whole gate is one question: is there any text in that field?
Nine published pages have the same all-unknown answer as the 28 rejects. One is phone-verified. The other eight passed on text like this, copied from their files:
- Iberville Parish: “Chapter 9 (definitions only; no occupancy provisions located)”
- Washington County, Florida: “Land Development Code (RV provision)”, with no ordinance URL
- Union County, Florida: “Ordinance 24-03 (RV Moratorium)”, with no ordinance URL
The first one says, in the field meant to prove a source, that no source was located. The gate counted it as a source. The Iberville page is live today with the identical all-unknown meta description.
The opposite error happened too. Brevard County’s file records residential RV use as prohibited, with a Municode link, but no section number. A “prohibited” answer is useful to a reader. The gate rejected it.
Can you trust the agent’s batch report?
Not as a count. Google’s guidance on generative AI content says “it is critical to manually factcheck and review all AI-generated content for accuracy and trustworthiness before publishing.” It adds that “this review also applies to metadata like <title> elements, meta description elements, structured data, and alternate texts for images.”
Each batch ended with a results file written by the agent. I compared three of them with what the code decides:
| Batch | Agent’s report | Gate’s decision |
|---|---|---|
| 5 | 3 of 12 ordinance-backed | 2 of 12 (Brevard rejected) |
| 6 | 7 of 12 publishable; Union and Washington “not publishable” | 9 of 12 (both published) |
| 8 | 7 of 12 | 7 of 12 |
The batch 6 report flagged Washington County as “no URL, forced to unknown.” The agent then filled the field anyway, and the gate published it. Had I reviewed the report instead of the gate’s output, I would have missed both pages.
The repo’s gate test did not catch this either. scripts/test-county-gate.js runs five hand-typed counties, all expected to pass. It never reads a real research file.
Has the gate helped or hurt search traffic?
I don’t know. The site is live and serving cached, public pages, but I have no Search Console data in front of me for these pages. I won’t guess at it.
If you have read my related posts on auditing 95 AI-written blog posts and on a fuel calculator that out-earned 53 generated city pages, this is the step before both. Those measured pages after they shipped. A gate decides which pages exist at all.
How should you build a publish gate for generated pages?
- Gate on the answer, not the citation. If every answer field is unknown, the page fails, whatever the source field says.
- Count distinct outputs before you deploy. Render each page’s meta description from the data and count the unique ones. If many pages share one string, those pages fail.
- Test the gate on real files. Run it over your actual research folder in CI, and keep a known-empty file in the fixtures that must fail.
- Count from code, not reports. The number in the agent’s summary is a claim. The number in your sitemap is the fact.
- Make rejected pages unreachable. Keep them out of the static build and the sitemap, and return 404 for direct requests. Then check that your sitemap’s page count equals the gate’s pass count.
- Treat the reject list as the research queue. A county that fails gets more research or a phone call, not a softer gate.
Related: programmatic city pages vs a calculator tool in Search Console data, an AI content style rule that backfired under test, and a verification gate on agent-built game levels.
Sources
- Google Search Central, Spam policies for Google web search, scaled content abuse (page updated 2026-08-28).
- Google Search Central, Google Search’s guidance on using generative AI content on your website (page updated 2026-10-01).
- The temphomefinder.com repository (research files, gate code and git history) and live site, checked October 10, 2026.
