7.6 KiB
7.6 KiB
Tasks — Sitemap completion
Every checkbox MUST reflect work actually done in this change. Do not retroactively tick.
0. Pre-flight (non-negotiable)
- 0.1 Confirm clean working tree (
git statusreports nothing) and no in-flight worktrees with uncommitted work (git worktree listthengit statusin each) - 0.2 If any worktrees exist under
.claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against. - 0.3 Confirm the package set in
MANIFEST.mdmatchesfind packages -maxdepth 3 -name package.jsoncount. Drift here means a prior change archived without regenerating the manifest.
Audit Note (2026-05-02)
Status: DEFERRED. packages/api/sitemap/src/ only contains core, errors, schemas, utils — no extensions/, incremental/, or compression/ directories. SitemapImageExtension, SitemapVideoExtension, IncrementalSitemapBuilder, and compressSitemap helpers are all absent. 0% of work is done.
1. Spec authoring
- 1.1 Read
../suaveplan/enterprise/sitemap.mdend-to-end - 1.2 Read
openspec/specs/sitemap/spec.md(if it exists) — currently absent; this change introduces the canonical capability spec for the four new surfaces - 1.3 Read
openspec/AGENTS.mdSections 13 and 14 - 1.4 Draft
proposal.mdfromopenspec/templates/proposal.md - 1.5 Fill
## Source mappingtable with upstream line ranges - 1.6 Draft
specs/sitemap/spec.mdfromopenspec/templates/spec-delta.md - 1.7 Every requirement carries a
**Verified by:**line - 1.8
openspec change validate sitemap-completionexits with no errors
2. Implementation — image extension
- 2.1 Port
SitemapImageExtensionfrompackages/universal/sitemap/src/extensions/image-sitemap.ts(L1-L111) intopackages/api/sitemap/src/extensions/image-sitemap/image-sitemap.ts - 2.2 Reuse existing
SitemapImageSchemafrompackages/api/sitemap/src/schemas/sitemap.schema.tsfor input validation - 2.3 Throw
SitemapErrorwith codeIMAGE_VALIDATION_FAILEDon Zod failure - 2.4 Sibling
.md(≥200 words, basic + advanced examples)
3. Implementation — video extension
- 3.1 Port
SitemapVideoExtensionfrompackages/universal/sitemap/src/extensions/video-sitemap.ts(L1-L182) intopackages/api/sitemap/src/extensions/video-sitemap/video-sitemap.ts - 3.2 Reuse existing
SitemapVideoSchemafor input validation - 3.3 Throw
SitemapErrorwith codeVIDEO_VALIDATION_FAILEDon Zod failure - 3.4 Sibling
.md
4. Implementation — incremental builder
- 4.1 Port
IncrementalSitemapBuilderfrompackages/universal/sitemap/src/incremental/incremental-builder.ts(L1-L213) intopackages/api/sitemap/src/incremental/incremental-builder/incremental-builder.ts - 4.2 Replace direct
fs.promises.writeFilewith injectableWritableStorageLikefrom@suaveplan/types - 4.3 Replace
Date.now()with injectableClock - 4.4 Implement rollover at
urlsPerSitemap(default 50_000) ORmaxBytes(default 50 1024 1024) — whichever first - 4.5 Emit one
SitemapIndexentry per rollover; carry final index assembly throughfinalize() - 4.6 When
compress: true, pipe each rollover output throughcompressSitemapand append.gzextension - 4.7 Add
INCREMENTAL_ROLLOVER_FAILEDtoSITEMAP_CODESvia existingdefineCodescall - 4.8 Sibling
.md
5. Implementation — gzip compressor
- 5.1 Port
compressSitemap/compressSitemapIndex/decompressGzipSitemapfrompackages/universal/sitemap/src/compression/sitemap-compressor.ts(L1-L91) intopackages/api/sitemap/src/compression/sitemap-compressor/sitemap-compressor.ts - 5.2 Use
fflate(already in catalog) for gzip; verify gzip magic bytes1f 8bin output - 5.3 Stamp the gzip header
mtimefield from injectableClock(defaults to() => 0for deterministic test fixtures) - 5.4 Add
COMPRESSION_FAILEDtoSITEMAP_CODES - 5.5 Sibling
.md
6. Wiring
- 6.1 Update
packages/api/sitemap/src/index.tsto re-export the four new modules and their types - 6.2 Add subpath exports
./extensions/image-sitemap/image-sitemap,./extensions/video-sitemap/video-sitemap,./incremental/incremental-builder/incremental-builder,./compression/sitemap-compressor/sitemap-compressortopackages/api/sitemap/package.json - 6.3 Update root
README.md## Modulessection to link the four new co-located.mds
7. Tests
- 7.1
packages/api/sitemap/src/extensions/image-sitemap/image-sitemap.test.ts— adds image, multiple images, all optional fields, Zod rejection - 7.2
packages/api/sitemap/src/extensions/video-sitemap/video-sitemap.test.ts— adds video, all optional fields, contentLoc / playerLoc mutual exclusion handling, Zod rejection - 7.3
packages/api/sitemap/src/incremental/incremental-builder/incremental-builder.test.ts— append URLs in batches; rollover at 50k URLs; rollover at 50 MiB; finalfinalize()produces a valid sitemap index XML - 7.4
packages/api/sitemap/src/incremental/incremental-builder/incremental-builder.spec-conformance.test.ts— injectedWritableStorageLikereceives the right paths; injectedClockcontrols mtime;compress: trueproduces gzip-magic output - 7.5
packages/api/sitemap/src/compression/sitemap-compressor/sitemap-compressor.test.ts— gzip round-trip; magic bytes1f 8bpresent; mtime deterministic;decompressGzipSitemaprecovers the original XML byte-for-byte - 7.6 Every
it(...)carries{ timeout: 5000 }(30000 for the rollover-at-50k test, which appends 50_000 URLs)
8. Documentation
- 8.1 Sibling
.mdfor every new implementation.ts(≥200 words, basic + advanced examples, full API reference) - 8.2 README links the four new
.mds under## Modules
9. Pre-archive verification (the 5-gate triple)
- 9.1
bun run check— Biome 0/0/0 across the monorepo - 9.2
bunx turbo lint typecheck test --filter=@suaveplan/sitemap— green - 9.3
bunx turbo test:coverage --filter=@suaveplan/sitemap— 100/100/100/100 - 9.4
bun scripts/openspec-conformance.ts @suaveplan/sitemap— exit 0, noerrorfindings - 9.5
bunx turbo build --filter=@suaveplan/sitemap— green
10. Pre-archive 7-row checklist (AGENTS.md Section 13)
- 10.1 Generics threaded;
expectTypeOfassertions onIncrementalSitemapBuilderOptionsliteral-type fields - 10.2 Zod schemas wired at every public boundary (
SitemapImageSchema,SitemapVideoSchema,IncrementalSitemapBuilderOptionsSchema) - 10.3 New error codes thrown from at least one production path (
IMAGE_VALIDATION_FAILED,VIDEO_VALIDATION_FAILED,INCREMENTAL_ROLLOVER_FAILED,COMPRESSION_FAILED) - 10.4 Strict-mode tested: rollover at exactly 50,000 URLs vs 49,999; rollover at exactly 50 MiB vs 50 MiB - 1 byte
- 10.5 OTel counters / histograms emitted (
sitemap.incremental.rollover_count,sitemap.compression.bytes_in,sitemap.compression.bytes_out); asserted with a real in-memoryMeterProvider - 10.6 Lifecycle dedup:
IncrementalSitemapBuilder.finalize()is idempotent — calling it twice produces the same index XML and does not double-emit storage writes - 10.7 No retroactive tick — every box reflects work done in this change
11. Archive
- 11.1 Fold spec delta into
openspec/specs/sitemap/spec.md(creating it if absent) - 11.2 Move
openspec/changes/sitemap-completion/→openspec/archive/<yyyy-mm-dd>-sitemap-completion/ - 11.3 Refresh
MANIFEST.md