<?xml version="1.0" encoding="UTF-8"?>
<!--
  dkbuilt.com sitemap. THIS is the live one; ~/PhotoSorter/seo/sitemap.xml is a stale
  pre-migration file pointing at the retired dkphotosorter.com and must never be edited
  or published in its place (CONTRACT 1).

  (No double hyphen appears anywhere below on purpose: it is illegal inside an XML comment
  and makes this whole file unparseable, which would take the sitemap off the site.)

  URL FORM. Every loc is the form that answers with a DIRECT 200 and zero redirect hops,
  verified with curl against the live site on 2026-07-29:
    * a directory gets its TRAILING SLASH. /dkphotosorter/ is 200; /dkphotosorter is a 301.
    * a file keeps its .html and gets NO trailing slash.
  web.config's Extensionless HTML rewrite also serves /dkphotosorter/faq with a 200, but the
  extension form is the one every page's own link rel=canonical names, so it is the one
  listed here. Sitemap and canonical must not disagree about which URL is preferred.

  lastmod IS MEASURED, NOT COPY-PASTED. Every value below is the date of the last commit
  that changed that page's own file, read from `git log` (one entry, short date) in the repo
  that owns it. This file used to read 2026-07-26 on every line, including pages edited on
  2026-07-28, which trains Google to ignore the field entirely.

  That is no longer a convention anyone has to keep by hand. check-site.sh's sitemap-lastmod
  step reads the same short date from git for every loc below and fails the run when the
  number of disagreements is not exactly the count it pins. Editing a page here without
  moving its lastmod, and moving a lastmod without editing the page, both go red.

  /plexrenamer/ IS LISTED as of 2026-07-29. It used to carry a robots noindex with no
  recorded reason (inherited from the hand-placed April 2026 file) while being linked from
  the homepage product grid and from 404.html and hosting DKPlexRenamer's only download.
  That noindex is gone, the page now carries a canonical naming this exact URL, and it is
  listed here. The three have to agree; if one is ever reverted, all three must be.

  404.html is deliberately NOT listed: it is the error page, and it carries a robots
  noindex with no canonical, which is the correct pattern for it.
-->
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url><loc>https://dkbuilt.com/</loc><lastmod>2026-07-29</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>

  <!-- DKPhotoSorter -->
  <url><loc>https://dkbuilt.com/dkphotosorter/</loc><lastmod>2026-07-29</lastmod><changefreq>weekly</changefreq><priority>0.9</priority></url>
  <url><loc>https://dkbuilt.com/dkphotosorter/faq.html</loc><lastmod>2026-07-29</lastmod><changefreq>monthly</changefreq><priority>0.7</priority></url>
  <url><loc>https://dkbuilt.com/dkphotosorter/privacy.html</loc><lastmod>2026-07-29</lastmod><changefreq>yearly</changefreq><priority>0.3</priority></url>
  <url><loc>https://dkbuilt.com/dkphotosorter/terms.html</loc><lastmod>2026-07-29</lastmod><changefreq>yearly</changefreq><priority>0.3</priority></url>
  <url><loc>https://dkbuilt.com/dkphotosorter/organize-iphone-photos-on-windows-by-location.html</loc><lastmod>2026-07-29</lastmod><changefreq>monthly</changefreq><priority>0.8</priority></url>
  <url><loc>https://dkbuilt.com/dkphotosorter/organize-photos-by-location.html</loc><lastmod>2026-07-29</lastmod><changefreq>monthly</changefreq><priority>0.8</priority></url>
  <url><loc>https://dkbuilt.com/dkphotosorter/organize-travel-vacation-photos.html</loc><lastmod>2026-07-29</lastmod><changefreq>monthly</changefreq><priority>0.8</priority></url>
  <url><loc>https://dkbuilt.com/dkphotosorter/dkphotosorter-vs-photomove.html</loc><lastmod>2026-07-29</lastmod><changefreq>monthly</changefreq><priority>0.7</priority></url>
  <url><loc>https://dkbuilt.com/dkphotosorter/dkphotosorter-vs-excire.html</loc><lastmod>2026-07-29</lastmod><changefreq>monthly</changefreq><priority>0.7</priority></url>
  <url><loc>https://dkbuilt.com/dkphotosorter/dkphotosorter-vs-digikam.html</loc><lastmod>2026-07-29</lastmod><changefreq>monthly</changefreq><priority>0.7</priority></url>
  <url><loc>https://dkbuilt.com/dkphotosorter/guides/how-to-organize-thousands-of-photos.html</loc><lastmod>2026-07-29</lastmod><changefreq>monthly</changefreq><priority>0.7</priority></url>
  <url><loc>https://dkbuilt.com/dkphotosorter/guides/organize-photos-no-gps-ai.html</loc><lastmod>2026-07-29</lastmod><changefreq>monthly</changefreq><priority>0.7</priority></url>

  <!-- DKPlexRenamer -->
  <url><loc>https://dkbuilt.com/plexrenamer/</loc><lastmod>2026-07-29</lastmod><changefreq>monthly</changefreq><priority>0.8</priority></url>

  <!-- DKMagnetVault -->
  <url><loc>https://dkbuilt.com/dkmagnetvault/</loc><lastmod>2026-07-29</lastmod><changefreq>monthly</changefreq><priority>0.8</priority></url>
  <url><loc>https://dkbuilt.com/dkmagnetvault/guide.html</loc><lastmod>2026-07-29</lastmod><changefreq>monthly</changefreq><priority>0.6</priority></url>
  <url><loc>https://dkbuilt.com/dkmagnetvault/terms.html</loc><lastmod>2026-07-29</lastmod><changefreq>yearly</changefreq><priority>0.3</priority></url>

  <!-- DKSpoonVault -->
  <url><loc>https://dkbuilt.com/dkspoonvault/</loc><lastmod>2026-07-29</lastmod><changefreq>monthly</changefreq><priority>0.8</priority></url>
  <url><loc>https://dkbuilt.com/dkspoonvault/guide.html</loc><lastmod>2026-07-29</lastmod><changefreq>monthly</changefreq><priority>0.6</priority></url>
  <url><loc>https://dkbuilt.com/dkspoonvault/terms.html</loc><lastmod>2026-07-29</lastmod><changefreq>yearly</changefreq><priority>0.3</priority></url>

  <!-- DK Security Lab. Three pages, added 2026-08-13: the section home plus the YouTube API
       Services privacy policy and terms of service for the DK Security Lab Uploader. The channel
       and the tool were named SentinelTutorial on those pages until 2026-08-14; that rename changed
       the displayed name only, so the URL path and the three loc values below are deliberately
       unchanged. The section is NOT in the homepage product grid, because it is not a paid product;
       these loc values are how the pages are discoverable. Directory form for the index, .html form
       for the other two, per the URL FORM rule above. -->
  <url><loc>https://dkbuilt.com/sentineltutorial/</loc><lastmod>2026-09-04</lastmod><changefreq>monthly</changefreq><priority>0.5</priority></url>
  <url><loc>https://dkbuilt.com/sentineltutorial/privacy.html</loc><lastmod>2026-08-14</lastmod><changefreq>yearly</changefreq><priority>0.3</priority></url>
  <url><loc>https://dkbuilt.com/sentineltutorial/terms.html</loc><lastmod>2026-08-14</lastmod><changefreq>yearly</changefreq><priority>0.3</priority></url>

  <!-- DKSL Analytics Reader. Two pages, added 2026-09-03. The Reader is a SEPARATE OAuth
       application from the DK Security Lab Uploader above, with its own OAuth client and its own
       scope. Each application's own pages are where the scope it holds is written down, and this
       comment does not repeat either one, so that neither copy can drift from the page that owns
       it.
       Google requires a published privacy policy and terms URL per application, so the Reader
       gets its own pair rather than sharing the Uploader's. These two loc values are the strings
       to enter on the Google Auth Platform Branding page for Cloud project dksl-analytics, which
       is why they must answer with a direct 200: .html form, no trailing slash, per the URL FORM
       rule above. lastmod is each page's own last commit date, as everywhere
       else in this file. -->
  <url><loc>https://dkbuilt.com/sentineltutorial/analytics-privacy.html</loc><lastmod>2026-09-04</lastmod><changefreq>yearly</changefreq><priority>0.3</priority></url>
  <url><loc>https://dkbuilt.com/sentineltutorial/analytics-terms.html</loc><lastmod>2026-09-04</lastmod><changefreq>yearly</changefreq><priority>0.3</priority></url>
</urlset>
