<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url><loc>https://gala.ltd/</loc><priority>1.0</priority></url>
  <url><loc>https://gala.ltd/services</loc><priority>0.9</priority></url>
  <url><loc>https://gala.ltd/pricing</loc><priority>0.9</priority></url>
  <url><loc>https://gala.ltd/how-it-works</loc><priority>0.8</priority></url>
  <url><loc>https://gala.ltd/faq</loc><priority>0.8</priority></url>
  <url><loc>https://gala.ltd/agentible</loc><priority>0.9</priority></url>
  <url><loc>https://gala.ltd/pt</loc><priority>0.9</priority></url>
  <url><loc>https://gala.ltd/launch</loc><priority>0.5</priority></url>
  <!-- /reference/dental IS NOT HERE AND THAT IS THE FIX, not an omission.
       Measured 21 Oct 2026: it was in this file AND served
       <meta name="robots" content="noindex">, which is a sitemap telling a
       crawler to fetch a page that then tells it not to index — one of the two
       had to go.

       THE noindex IS THE CORRECT ONE. The page is "Northgate Dental", a
       fictitious practice: it carries a full Dentist record with opening
       hours, a named employee and a priced treatment catalogue, and its own
       first line says NOT A REAL PRACTICE. The disclaimer is in the prose and
       in disambiguatingDescription; the @type and the offers are the part an
       assistant lifts and attributes. Submitting that to a crawler asks the
       whole machine-readable web to index a local business that does not
       exist, which is the one thing this house refuses — and it is the same
       reason /model/ and /lab/ are noindex and absent from this file. A worked
       model of a business is not a business.

       So the entry is removed and the page keeps answering 200 to anyone who
       follows a link to it, which is all a reference implementation needs. -->
  <url><loc>https://gala.ltd/terms</loc><priority>0.6</priority></url>
  <!-- THE GATE. /qualify explains what a business brings in order to have a
       Gala — twelve answers about itself, one topic each, good for a year. It
       belongs in search for the same reason the course pages do and the stores
       do not: nothing on it is priced, nothing is sold, and it describes no
       business but ours. It is a static page under public/qualify/, so it has
       no route in server.js, no key in LEARNER and no rewrite in vercel.json —
       the CDN serves it, and this row is the only thing that points at it. -->
  <url><loc>https://gala.ltd/qualify</loc><priority>0.9</priority></url>
  <!-- THE /for/ FAMILY — one flat namespace of things a business already has.
       Four platform pages plus the page that compares them. Each is a static
       file under public/for/, each carries WebPage + Dataset + FAQPage, each
       names no business and no amount, and no script runs on any of them.

       THEY WERE BUILT, INDEXABLE AND UNREACHABLE, which is why this block
       exists. Counted on production 21 Oct 2026, with controls that had to
       hit: 21 url rows here, /qualify present once and /cbse six times,
       /for/ present ZERO times — and zero links to any /for/ page from /,
       from /qualify/ or from /agentible, against 3 href= on /qualify/ as the
       control that the sweep could look. A page written to be found, carrying
       a Dataset and a FAQPage, that appears in no sitemap and is linked from
       nothing we publish, is the empty badge we keep measuring other people
       shipping.

       A /for/ PAGE IS FINISHED WHEN IT IS THREE THINGS, and this row is only
       the second of them:
         1. served          — public/for/<slug>/index.html answers 200
         2. in this file    — a url row, below
         3. linked from a page that is ITSELF in this file — /qualify/ carries
                              the four, in its "what you get for it" section
       A page reachable only by sitemap is a page with no standing, so (3) is
       not a nicety. Prove all three with a fetch rather than an exit code:
       `node ops/for-reach.mjs` counts them, with a control beside each,
       because a grep for /for/ that returns zero and a grep that could not
       open this file are byte-identical results.

       NOTHING IN A COMMENT HERE WRITES THE loc TAG OUT IN FULL, which looks
       like fussiness and is not. Every sweep that asks "how many addresses
       does this file publish" greps for the tag, and three mentions of it in
       prose made that count 28 against a real 25 the first time it was run on
       production. An XML parser is unaffected; every instrument built out of
       grep is. Say "url row" in prose and the two agree.

       THE TRAILING SLASH IS NOT COSMETIC. Every one of these pages declares
       its own rel=canonical with the slash on, so a url row without one would
       put this file and the page in disagreement about its address.

       THE SLUG IS NEVER TYPED FOR A TRADE PAGE. These four are platforms and
       have no register row. A trade page's slug lives once on
       agentible.niches.public_slug (db/for-slugs.sql) and reaches code through
       the generated module webmcp/for-slugs.js — niche_id `physiotherapy`,
       address `/for/physical-therapy/`, because an American physical
       therapist never says physiotherapy and a URL is a page a searcher either
       reaches or does not. -->
  <url><loc>https://gala.ltd/for/</loc><priority>0.9</priority></url>
  <url><loc>https://gala.ltd/for/etsy/</loc><priority>0.8</priority></url>
  <url><loc>https://gala.ltd/for/instagram/</loc><priority>0.8</priority></url>
  <url><loc>https://gala.ltd/for/pinterest/</loc><priority>0.8</priority></url>
  <url><loc>https://gala.ltd/for/gbp/</loc><priority>0.8</priority></url>
  <!-- THE SCHOOL COURSES. Measured 8 Oct 2026: seven board pages and
       thirty-nine subject readers were live, public and carried no noindex,
       and this file named none of them - the strings cbse, ssc and grade
       appeared zero times in it, in llms.txt and in agents.md, while a
       control string known to be in all three did hit, so the sweep is known
       to have looked. They are learning pages with nothing priced on them,
       so unlike the stores they belong in search.
       THE SEVEN LEVELS ARE LISTED AND THE THIRTY-NINE SUBJECTS ARE NOT, and
       that is not an oversight. These seven already exist as seven
       hand-written rewrite groups in webmcp/vercel.json, so naming them here
       is the same decision written down twice rather than a new list. The
       subject readers are served by ONE wildcard rewrite over whatever the
       register holds - 36 CBSE and 21 SSC counted 21 Oct 2026, which was 3 SSC
       a fortnight ago - so writing the fifty-seven out here would be a second
       list of a figure that moves, which is the
       one thing invariant 0 forbids. They are named as a pattern in
       /agents.md and in /llms.txt, and /api/shelf enumerates every one of
       them with its path, counted per request. -->
  <url><loc>https://gala.ltd/cbse/grade-7</loc><priority>0.8</priority></url>
  <url><loc>https://gala.ltd/cbse/grade-8</loc><priority>0.8</priority></url>
  <url><loc>https://gala.ltd/cbse/grade-9</loc><priority>0.8</priority></url>
  <url><loc>https://gala.ltd/cbse/grade-10</loc><priority>0.8</priority></url>
  <url><loc>https://gala.ltd/cbse/grade-11</loc><priority>0.8</priority></url>
  <url><loc>https://gala.ltd/cbse/grade-12</loc><priority>0.8</priority></url>
  <url><loc>https://gala.ltd/ssc/class-7</loc><priority>0.8</priority></url>
  <url><loc>https://gala.ltd/ssc/class-8</loc><priority>0.8</priority></url>
  <url><loc>https://gala.ltd/ssc/class-9</loc><priority>0.8</priority></url>
  <url><loc>https://gala.ltd/ssc/class-10</loc><priority>0.8</priority></url>
</urlset>
