Context
Follow-up from PR #12258's cross-family review. While implementing #12255, the source-side SEO priority fix was straightforward: buildScripts/docs/seo/generate.mjs#PRIORITIES now maps the current identity / Benefits / Agent OS / cloud-deployment routes, and apps/portal/sitemap.xml carries the matching priority lines.
The friction came from the generated output step. Running the full sitemap generator from the #12255 branch completed successfully, but it produced unrelated <lastmod> churn across the entire sitemap. To keep #12258 reviewable and scoped, the PR preserved existing lastmod values and applied only the priority-line deltas. Claude's review approved that as non-blocking, but correctly surfaced the root generator behavior as follow-up debt.
Creation V-B-A:
buildScripts/docs/seo/generate.mjs#getSitemapXml() calls getGitLastModifiedBatch() and emits <lastmod> for every route with a file path.
- Full generator execution during #12255 changed thousands of sitemap lines unrelated to the priority-map edit, mostly
<lastmod> values.
- The committed #12258 diff had to normalize
apps/portal/sitemap.xml back to priority-only changes to avoid hiding a small SEO-priority fix in all-route timestamp churn.
- Duplicate sweep: Knowledge Base unavailable (
Failed to access collections); exact rg found closed #7742 (initial git-history <lastmod> support) and closed #7770 (example-directory lastmod accuracy), but no active ticket for diff-clean regeneration / no unrelated lastmod churn. Live gh issue list --search "sitemap lastmod getSitemapXml regeneration churn priority-only" returned [].
The Problem
Any future SEO-generator PR can hit the same trap: a small intended sitemap change becomes a noisy all-route <lastmod> diff, or the author must manually normalize generated output after the generator runs. That undermines the generated-output discipline ADR 0018 relies on: agents should be able to update the source generator, regenerate output, and review the resulting diff without a post-generation workaround.
The exact root cause still needs implementation-time V-B-A. It may be one of these, or a combination:
- the generator derives different git timestamps than the currently committed sitemap carries;
- the data-sync pipeline stamps or preserves sitemap
lastmod values differently than local generation;
- top-level / issue / release routes need a different stable timestamp source than learn-file routes;
- the release-time generation path and local CLI generation path disagree.
The ticket is not to pick a solution prematurely. It is to make the generator's regeneration behavior stable and reviewable.
The Architectural Reality
buildScripts/docs/seo/generate.mjs owns sitemap generation:
getSitemapXml() formats routes into XML and emits <lastmod> from getGitLastModifiedBatch().
buildScripts/release/prepare.mjs imports the same generator and writes apps/portal/sitemap.xml for release preparation.
apps/portal/sitemap.xml is generated output; durable fixes belong in the generator or the generation contract, not ad-hoc sitemap edits.
- Closed #7742 and #7770 established the original accuracy goal for
<lastmod>, so this follow-up must preserve accurate timestamps where possible rather than deleting <lastmod> wholesale.
The Fix
Investigate and fix the sitemap generation path so a no-op or narrow sitemap regeneration does not produce unrelated all-route <lastmod> churn.
Expected implementation shape:
- Reproduce the churn from a clean branch using the current generator and committed
apps/portal/sitemap.xml.
- Identify whether the divergence is caused by git-history lookup, top-level route handling, issue/release route handling, release/data-sync behavior, or local CLI defaults.
- Update
buildScripts/docs/seo/generate.mjs and, if needed, buildScripts/release/prepare.mjs so generated output is stable and reviewable.
- Preserve the SEO purpose of
<lastmod>: accurate content modified dates where available, explicit stable fallback where not.
- Add focused validation so future priority-only or route-only generator changes can prove they do not rewrite unrelated
lastmod lines.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
buildScripts/docs/seo/generate.mjs#getSitemapXml() |
Current generator + closed #7742/#7770 accuracy intent |
Emits stable, accurate <lastmod> values without unrelated regeneration churn |
If a route has no trustworthy source, use a documented stable fallback rather than build-time churn |
PR body / inline comments only if needed |
Reproduction before/after + focused generator check |
apps/portal/sitemap.xml |
Generated from getSitemapXml() |
No-op or priority-only regeneration does not rewrite unrelated lastmod values |
Any unavoidable churn must be explicitly justified in PR body |
PR body |
Diff proves only intended sitemap lines changed |
| Release preparation path |
buildScripts/release/prepare.mjs |
Release generation uses the same stable lastmod semantics as local CLI generation |
Document if release intentionally differs and why |
PR body |
Command evidence or source audit |
Decision Record Impact
Aligned-with ADR 0018 generated-output-source discipline. No ADR update expected unless implementation discovers the release/data-sync pipeline intentionally owns sitemap timestamps differently from generate.mjs.
Acceptance Criteria
Out of Scope
- Changing sitemap priority policy; #12255 / PR #12258 owns that.
- Removing
<lastmod> from the sitemap wholesale.
- Rewriting README / identity prose.
- Changing
llms.txt unless the same timestamp contract is discovered there.
- Release-pipeline redesign beyond the sitemap generation semantics needed here.
Avoided Traps
- Treating #12258's manual priority-only normalization as the permanent workflow.
- Solving review noise by deleting useful SEO metadata.
- Reopening the closed #7742/#7770 accuracy decisions without evidence.
- Assuming the root cause is build-time stamping before reproducing the exact generator/data-sync path.
Related
- Follow-up from: #12258
- Root issue: #12255
- Parent epic: #12225
- Historical context: #7742, #7770
- ADR 0018: Neo Identity Source-of-Truth Model / generated-output-source discipline
Origin Session ID: 87203e0b-c9ff-4a82-a67b-9a0dda760c32
Retrieval Hint: "sitemap lastmod regeneration churn getSitemapXml priority-only normalization PR 12258"
Context
Follow-up from PR #12258's cross-family review. While implementing #12255, the source-side SEO priority fix was straightforward:
buildScripts/docs/seo/generate.mjs#PRIORITIESnow maps the current identity / Benefits / Agent OS / cloud-deployment routes, andapps/portal/sitemap.xmlcarries the matching priority lines.The friction came from the generated output step. Running the full sitemap generator from the #12255 branch completed successfully, but it produced unrelated
<lastmod>churn across the entire sitemap. To keep #12258 reviewable and scoped, the PR preserved existinglastmodvalues and applied only the priority-line deltas. Claude's review approved that as non-blocking, but correctly surfaced the root generator behavior as follow-up debt.Creation V-B-A:
buildScripts/docs/seo/generate.mjs#getSitemapXml()callsgetGitLastModifiedBatch()and emits<lastmod>for every route with a file path.<lastmod>values.apps/portal/sitemap.xmlback to priority-only changes to avoid hiding a small SEO-priority fix in all-route timestamp churn.Failed to access collections); exactrgfound closed #7742 (initial git-history<lastmod>support) and closed #7770 (example-directory lastmod accuracy), but no active ticket for diff-clean regeneration / no unrelated lastmod churn. Livegh issue list --search "sitemap lastmod getSitemapXml regeneration churn priority-only"returned[].The Problem
Any future SEO-generator PR can hit the same trap: a small intended sitemap change becomes a noisy all-route
<lastmod>diff, or the author must manually normalize generated output after the generator runs. That undermines the generated-output discipline ADR 0018 relies on: agents should be able to update the source generator, regenerate output, and review the resulting diff without a post-generation workaround.The exact root cause still needs implementation-time V-B-A. It may be one of these, or a combination:
lastmodvalues differently than local generation;The ticket is not to pick a solution prematurely. It is to make the generator's regeneration behavior stable and reviewable.
The Architectural Reality
buildScripts/docs/seo/generate.mjsowns sitemap generation:getSitemapXml()formats routes into XML and emits<lastmod>fromgetGitLastModifiedBatch().buildScripts/release/prepare.mjsimports the same generator and writesapps/portal/sitemap.xmlfor release preparation.apps/portal/sitemap.xmlis generated output; durable fixes belong in the generator or the generation contract, not ad-hoc sitemap edits.<lastmod>, so this follow-up must preserve accurate timestamps where possible rather than deleting<lastmod>wholesale.The Fix
Investigate and fix the sitemap generation path so a no-op or narrow sitemap regeneration does not produce unrelated all-route
<lastmod>churn.Expected implementation shape:
apps/portal/sitemap.xml.buildScripts/docs/seo/generate.mjsand, if needed,buildScripts/release/prepare.mjsso generated output is stable and reviewable.<lastmod>: accurate content modified dates where available, explicit stable fallback where not.lastmodlines.Contract Ledger Matrix
buildScripts/docs/seo/generate.mjs#getSitemapXml()<lastmod>values without unrelated regeneration churnapps/portal/sitemap.xmlgetSitemapXml()lastmodvaluesbuildScripts/release/prepare.mjsDecision Record Impact
Aligned-with ADR 0018 generated-output-source discipline. No ADR update expected unless implementation discovers the release/data-sync pipeline intentionally owns sitemap timestamps differently from
generate.mjs.Acceptance Criteria
<lastmod>churn that forced the #12258 priority-only normalization.getSitemapXml()produces stable<lastmod>values for unchanged routes across repeated local generation runs.apps/portal/sitemap.xmlcan be regenerated without manual post-processing for a narrow priority/route change.lastmodlines.Out of Scope
<lastmod>from the sitemap wholesale.llms.txtunless the same timestamp contract is discovered there.Avoided Traps
Related
Origin Session ID: 87203e0b-c9ff-4a82-a67b-9a0dda760c32 Retrieval Hint: "sitemap lastmod regeneration churn getSitemapXml priority-only normalization PR 12258"