Pular para o conteúdo

City-page FAQ rollout (faq-sync, faq-rollout.sh)

City-page FAQ rollout

Classic city pages (/estado/{uf}/{cidade}/, 10,479 pages) render a deterministic FAQ section (#perguntas-frequentes), a factual definition lead (#city-lead) and matching FAQPage + BreadcrumbList JSON-LD, extending the #251 leilões-hub pattern (“question-shaped content is what AI Overviews and answer engines quote”) to the money pages.

Everything is built from data the page already renders — IBGE population / area / PIB per capita, the broker count, the leilões result count — by citypage.BuildFAQs / citypage.BuildLead (site/citypage/faq.go, unit-tested). No LLM, no searches, no invented numbers; the schema text equals the visible text verbatim by construction. Pages with fewer than three answerable facts and noindex placeholders get no FAQ; the lead renders everywhere. Measurement: row 6 of AI-ANSWER-BASELINE-2026-11-06.md, added only after the first batches are recrawled.

Timing doctrine: the rollout starts only after the ~Nov 12 WoW verdict, on the operator’s explicit call. Nothing here moves a lastmod before that.

Terminal window
# Plan batch 1 (dry): GSC earners first — the report shows counts + ordering
go run . faq-sync --gsc <export> --limit 400 --out cache/faq/batch-1.json
# Regen those cities, rebuild the sitemap (stable lastmods), deploy through the gate
scripts/faq-rollout.sh site/cache/faq/batch-1.json
# Or walk the whole country unattended (deterministic state/city order, ~27 batches)
scripts/faq-national-rollout.sh [--limit 400] [--states SP,RJ] [--max-batches 30]

faq-sync selects a row when its rendered page is missing on disk or does not carry the #perguntas-frequentes marker, so served pages are skipped and repeated runs resume where the last batch ended — no bookkeeping file. --gsc orders by impressions (earners first); without it the scope is national in deterministic order. Manifest rows are consumed by regenerate-city-pages --manifest unchanged.

Mutation budget

Each deployed batch ≈ --limit pages + ~51 sitemap files (a batch spread across the lexical shard range rewrites every shard’s lastmods) + 1 agent-status ≈ 452 mutations < the 500 gate — no --approve-large-deploy sign-off needed. 10,479 pages ÷ 400 ≈ 27 batches.

Per-batch operator procedure

Follow the rebase-state-group shape:

  1. Review site/cache/deploy/last-diff.json against the batch: estado/ prefixes + root (sitemap) + agent-status only.
  2. Dated batch record on the #198 ledger first, capture the comment URL.
  3. Snapshot public/ (tar from site/).
  4. Operator checkpoint — explicit go-ahead per batch (or once for the national loop, with per-batch diffs still reviewed).
  5. scripts/faq-rollout.sh site/cache/faq/<manifest>.json
  6. Post-gates: go run . audit-metadata, go run . build-freshness --remote, and the next 03:00 build should read ~0 mutations.

Expected diff noise: pre-re-base pages may show extra hunks (stored RightRep banner strips legitimately; see HANDOFF-LEILOES-SECTION-2026-11-05.md).

Golden-verification recipe (what was checked on 2026-11-06)

In a clean HEAD worktree with only this change applied:

  • FAQ-absent case (builders forced nil): diff vs pre-change build shows only the lead, the speakable selector and the BreadcrumbList node — byte identical otherwise (html/template blank-line hygiene).
  • Full case: FAQPage mainEntity text == visible <h3>/<p> verbatim (python check), all ld+json blocks parse, breadcrumbs positions 1–4, scripts/validate-schema.py clean.
  • Determinism: regenerating the same cities twice is byte-identical (md5). Cities without leilões data drop the leilão question (4 items instead of 5).