seo: publish complete sitemap covering the five human-facing pages - #36
Conversation
…arvested round-5 candidate)
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
📝 WalkthroughWalkthroughThe sitemap now includes four public routes. A Node test suite validates sitemap structure, canonical URLs, stale paths, ordering, duplicates, and the ChangesSitemap coverage
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/test-sitemap.mjs`:
- Around line 80-103: Update sitemapIssues to validate that the complete
document has one properly enclosing <urlset> element, rejecting any <url> blocks
outside its opening and closing tags before extracting blocks and locs. In the
stale-path fixture generation around the relevant append logic, insert fixture
<url> blocks inside the existing </urlset> closing tag rather than appending
them afterward.
- Around line 141-144: Update the robots.txt assertion in the “robots.txt keeps
pointing at the sitemap” test to match a complete active Sitemap directive line,
requiring the expected URL at the start of an uncommented line with appropriate
line boundaries. Do not allow matches inside comments or unrelated text.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: fb8a291a-9dd2-4587-b413-e562a3253ac6
📒 Files selected for processing (3)
package.jsonpublic/sitemap.xmlscripts/test-sitemap.mjs
| if ((xml.match(/<urlset\b/g) || []).length !== 1 || (xml.match(/<\/urlset>/g) || []).length !== 1) { | ||
| issues.push("sitemap must contain exactly one urlset element"); | ||
| } | ||
|
|
||
| // Every url block must carry exactly one <loc> and nothing else (no | ||
| // lastmod/changefreq/priority or foreign elements: the schema stays | ||
| // urlset -> url -> loc only). | ||
| const blocks = [...xml.matchAll(/<url>([\s\S]*?)<\/url>/g)].map((match) => match[1]); | ||
| for (const block of blocks) { | ||
| const locMatch = block.match(/<loc>([^<]+)<\/loc>/); | ||
| if (!locMatch) { | ||
| issues.push(`url block must carry a <loc> element: ${JSON.stringify(block.trim())}`); | ||
| continue; | ||
| } | ||
| const remainder = block.replace(locMatch[0], "").trim(); | ||
| if (remainder) { | ||
| issues.push(`url block must not carry elements beyond <loc>: ${JSON.stringify(remainder)}`); | ||
| } | ||
| } | ||
|
|
||
| const locs = parseLocs(xml); | ||
| if (blocks.length !== locs.length) { | ||
| issues.push(`expected ${blocks.length} url blocks to carry exactly one <loc> each, found ${locs.length}`); | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Reject <url> blocks outside <urlset>.
Lines 80-103 count tags without validating their nesting. An empty <urlset> followed by all expected <url> blocks can pass sitemapIssues, but it is not a valid sitemap document.
Line 155 also appends stale-path blocks after </urlset>. Insert these fixture blocks before the closing tag. Parse or strictly match the complete urlset body before extracting <url> and <loc> elements.
Also applies to: 154-165
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/test-sitemap.mjs` around lines 80 - 103, Update sitemapIssues to
validate that the complete document has one properly enclosing <urlset> element,
rejecting any <url> blocks outside its opening and closing tags before
extracting blocks and locs. In the stale-path fixture generation around the
relevant append logic, insert fixture <url> blocks inside the existing </urlset>
closing tag rather than appending them afterward.
| test("robots.txt keeps pointing at the sitemap", () => { | ||
| const robots = readFileSync(new URL(`../${ROBOTS_PATH}`, import.meta.url), "utf8"); | ||
| assert.ok(robots.includes("Sitemap: https://tinystudio.io/sitemap.xml"), "robots.txt must keep the Sitemap directive"); | ||
| }); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Match an active Sitemap directive.
Line 143 passes when the expected text appears in a comment or unrelated text. A crawler then receives no sitemap directive while this test passes.
Match a complete, uncommented directive line instead.
Proposed fix
- assert.ok(robots.includes("Sitemap: https://tinystudio.io/sitemap.xml"), "robots.txt must keep the Sitemap directive");
+ assert.match(
+ robots,
+ /^Sitemap:\s+https:\/\/tinystudio\.io\/sitemap\.xml\s*$/m,
+ "robots.txt must keep the Sitemap directive"
+ );📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| test("robots.txt keeps pointing at the sitemap", () => { | |
| const robots = readFileSync(new URL(`../${ROBOTS_PATH}`, import.meta.url), "utf8"); | |
| assert.ok(robots.includes("Sitemap: https://tinystudio.io/sitemap.xml"), "robots.txt must keep the Sitemap directive"); | |
| }); | |
| test("robots.txt keeps pointing at the sitemap", () => { | |
| const robots = readFileSync(new URL(`../${ROBOTS_PATH}`, import.meta.url), "utf8"); | |
| assert.match( | |
| robots, | |
| /^Sitemap:\s+https:\/\/tinystudio\.io\/sitemap\.xml\s*$/m, | |
| "robots.txt must keep the Sitemap directive" | |
| ); | |
| }); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/test-sitemap.mjs` around lines 141 - 144, Update the robots.txt
assertion in the “robots.txt keeps pointing at the sitemap” test to match a
complete active Sitemap directive line, requiring the expected URL at the start
of an uncommented line with appropriate line boundaries. Do not allow matches
inside comments or unrelated text.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2e142f48d4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| <loc>https://tinystudio.io/</loc> | ||
| </url> | ||
| <url> | ||
| <loc>https://tinystudio.io/audit</loc> |
There was a problem hiding this comment.
Align sitemap entries with the declared canonicals
These four new entries use extensionless URLs, but every corresponding page declares and tests the .html form as its canonical URL (scripts/check-site.mjs:1295-1300). Crawlers therefore receive conflicting canonical signals from the sitemap and page metadata, undermining the SEO purpose of this change, while EXPECTED_LOCS locks that conflict into CI. Use the four .html URLs here and in the test, or change all page canonicals coherently.
Useful? React with 👍 / 👎.
…ktrees against current main (#118) Judges the five round-5 candidate worktrees (tinystudio-io-sitemap-{1..5}, retired 2026-08-09 at stage attempts per retired-cycles.md) for the finding that public/sitemap.xml did not cover the five human-facing pages. Every worktree sits at detached HEAD aa64d7d with the same uncommitted shape (sitemap.xml +12, package.json wiring, untracked test-sitemap.mjs, stray .pyc deletion) - the 'finished, uncommitted diffs' premise was stale in a different way than the product-contract round: the winner's uncommitted tree IS the shipped tree. Winner: tinystudio-io-sitemap-5, whose three product files are byte-identical to harvested commit 2e142f4 (branch seo/complete-sitemap-five-pages), merged as PR #36 (cd9184c) with an empty tree diff. Candidates 1 and 4 share the shipped sitemap.xml order; candidates 2 and 3 are alternative loc orderings; their guard drafts (70-155 lines) are subsumed by the shipped 217-line guard (robots, trailing-slash, order-lock and known-bad-shape fixtures). public/sitemap.xml and scripts/test-sitemap.mjs remain byte-identical to the winner's files on current origin/main; package.json differs only by later unrelated changes (description rename, test:contract, wrangler bump). Full suite green on current head 18128e8: check passed, headings 6/6, sitemap 7/7, worker 55/55, ui 16/16, contract 8/8. Nothing further to change; round closed with a reason.
What
Harvests the abandoned round-5 sitemap candidate worktree (
tinystudio-io-sitemap-5) onto freshorigin/main.The sitemap only listed the root,
/offer.mdand/llms.txt, so four of the five human-facing pages (/audit,/agents,/pricing,/specimen) were invisible to crawlers even thoughrobots.txtallows them all.Changes
public/sitemap.xml— adds the four missing human-facing pages, completing the five-page surface plus the two machine-readable mirrors (offer.md,llms.txt). URLs use the clean extensionless paths the worker serves; only the root carries a trailing slash.scripts/test-sitemap.mjs— new regression test locking the exact ordered loc set, urlset schema shape, robots.txt directive, and rejection of stale paths (/brief-requested,/agent-desk) and schema drift; proven against embedded known-bad fixtures.package.json— wirestest:sitemapinto thetestchain.Verification
npm run check— TinyStudio.io checks passed.npm test— check + headings (6) + sitemap (7) + worker (53) + ui (15), all pass, 0 fail.git diff --check— clean.Summary by CodeRabbit
New Features
Bug Fixes
Tests