<?xml version="1.0" encoding="UTF-8"?>
<!--
  The four pages that are not the Bible.

  This file used to BE /sitemap.xml. It was split on 2026-09-05, when 1,190
  scripture URLs arrived and needed a generator; /sitemap.xml is now an index
  pointing at this file and at the generated one. The reasoning below is the
  reasoning that was already here, kept because it is still true of these four
  and it is the argument somebody will want when they come to add a fifth.

  Everything else in AO1 is one person's request, one person's profile, one
  person's community or one person's story, and none of those belong in a
  search index — public/robots.txt carries the whole argument, written by the
  same hand. A sitemap listing them would be the exact opposite of what that
  file asks for.

  ===========================================================================
  WHY THIS ONE IS STILL HAND-WRITTEN AND NOT GENERATED
  ===========================================================================

  ⚠️ THIS ARGUMENT HAS A SHELF LIFE, AND IT IS SHORTER THAN IT LOOKS. Ty
  reversed the blanket noindex on 2026-09-05 — anonymous public requests are to
  be indexed. The moment that is switched on, everything below is wrong FOR
  REQUESTS and that part MUST become a Cloud Function: a build step cannot work
  there, because deploys are rare and requests are deleted continuously, and a
  sitemap advertising a request somebody deleted an hour ago is the failure
  people do not forgive. The gate that has to exist first, and the four reasons
  it does not yet, are written out in public/robots.txt.

  Note what that does NOT apply to, because the distinction is the whole reason
  this file split in two. Scripture is the opposite case in every respect: the
  text is fixed, public domain, names nobody, and cannot be deleted by the
  person who wrote it. So sitemap-bible.xml IS a build step — see
  tools/prerender.mjs — and that is not a compromise, it is the correct shape
  for content that never changes. Two kinds of content, two mechanisms, one
  index over both.

  For the four below the original instinct is still right in general and wrong
  here: content changes constantly, so a sitemap should be generated. But NONE
  OF THE CHANGING CONTENT IS PUBLIC. The complete set of URLs a signed-out
  visitor can reach and read — apart from the Bible — is the signed-out branch
  of src/App.tsx, and it is four static pages plus a handful of routes that
  render a sign-in form. There is nothing to enumerate.

  A generator would also have to read Firestore to find anything, and it could
  not: prayers, users, handles and communities are all `allow read: if
  signedIn()`. It would have to run with admin credentials, which bypass the
  rules entirely — and the shape of that query is a collection `list`, which is
  the exact shape of the two privacy holes firestore.rules has already had.
  Firestore `read` is `get` PLUS `list`, and both world-readable collections
  (`invites`, `communityDoors`) were narrowed to `allow get` on 2026-09-04
  precisely so that nobody could harvest them. A sitemap generator would be a
  sanctioned harvester of the same data, running on a schedule.

  So for these four: no build step, and no Cloud Function. A function serving
  four fixed URLs would bill an invocation every time a crawler asked, for a
  file that changes when the ROUTER changes and at no other time.

  What replaces the generator is tools/indexing.test.mjs, which runs in
  `npm test`. It reads src/App.tsx, this file and robots.txt, and fails if a
  public route is added without a decision being recorded about it. That catches
  the real failure — drift — at zero runtime cost. It caught the first one on
  the day it was written: /terms and /support have been public since 2026-09-01
  and were in neither this file nor the old robots.txt.

  ===========================================================================
  THE HOST
  ===========================================================================

  www.ao1community.com — www, not the apex, and not by preference. www is the
  hostname that is verified and serving.

  The apex used to return Firebase's "Site Not Found" because it was never added
  as a custom domain, and DNS-CUTOVER.md step 2 was the outstanding half of the
  cutover. IT IS DONE, measured 2026-09-07: curl https://ao1community.com/
  answers 301 with location https://www.ao1community.com/. As this file
  predicted, nothing here had to change.

  ===========================================================================
  &lt;lastmod&gt;, ADDED 2026-09-07 ON THE TWO URLS THAT HAVE A REAL DATE
  ===========================================================================

  The rule this file gave itself was right and was applied too widely: an
  invented date is worse than none. But /privacy and /terms are not undated.
  Each renders a visible "Last updated" line from an UPDATED constant in its own
  screen, and both say 4 September 2026. That is a content date somebody wrote
  down, not a build timestamp, so it is exactly the thing lastmod is for, and
  Google uses it to decide whether a recrawl is worth doing. A legal page that
  changes and cannot say so is a legal page Google shows the old version of.

  KEEP IT IN STEP, OR IT IS WORSE THAN NOTHING. Three files carry this date now:
  src/screens/Privacy.tsx, src/screens/Terms.tsx and this one, plus dateModified
  in the JSON&#8209;LD that tools/prerender.mjs writes. tools/indexing.test.mjs
  compares all of them and fails npm test when they drift. A lastmod that lies
  is a signal Google learns to ignore for the whole site.

  Still no date on / or /support. The home page changes whenever the app does,
  which is not a content date; the support page has no UPDATED constant to read.
  Neither would be a fact, so neither gets one.

  No &lt;priority&gt; or &lt;changefreq&gt;: Google ignores both, and four URLs
  do not need ranking against each other.
-->
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <!-- The front door. The app introducing itself, naming nobody. -->
  <url><loc>https://www.ao1community.com/</loc></url>
  <url><loc>https://www.ao1community.com/privacy</loc><lastmod>2026-09-04</lastmod></url>
  <url><loc>https://www.ao1community.com/terms</loc><lastmod>2026-09-04</lastmod></url>
  <url><loc>https://www.ao1community.com/support</loc></url>
  <!-- 2026-09-15. The get-the-app page, public/get/index.html: a static file
       outside the app, so it names nobody by construction. No lastmod, for
       the reason / has none. -->
  <url><loc>https://www.ao1community.com/get</loc></url>
</urlset>
