From 7c4dbb12522e9bca2634285243036dc00a2dc6bb Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Tue, 27 Oct 2026 20:10:32 +0100 Subject: [PATCH] docs(33): write out phase 33 context from the phase 32 SEO discussion --- .../33-CONTEXT.md | 158 ++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 .planning/phases/33-seo-output-audit-and-content/33-CONTEXT.md diff --git a/.planning/phases/33-seo-output-audit-and-content/33-CONTEXT.md b/.planning/phases/33-seo-output-audit-and-content/33-CONTEXT.md new file mode 100644 index 00000000..3bce5729 --- /dev/null +++ b/.planning/phases/33-seo-output-audit-and-content/33-CONTEXT.md @@ -0,0 +1,158 @@ +# Phase 33: SEO output, audit and content - Context + +**Gathered:** 2026-10-24, in the Phase 32 discussion (written out for Phase 33 on 2026-10-27) +**Status:** Ready for planning +**Participant:** Dawid (SEO specialist, delegated by Jakub for the SEO discussion); Jakub for the phase split, code layout and planning decisions. + +**Source of the decisions:** `.planning/phases/32-seo-foundation/32-CONTEXT.md`. The SEO discussion covered Phases 32 and 33 together; Jakub split the scope afterwards (Q-01, 2026-10-25). This file does not repeat or change any decision. It lists the ones Phase 33 implements, by ID, with the part that belongs to Phase 33, following the Phase 33 column of `.planning/phases/32-seo-foundation/32-DECISIONS-MAP.md`. Read the full decision text in 32-CONTEXT.md; where the two files disagree, 32-CONTEXT.md wins. + + +## Phase Boundary + +Phase 32 delivered the SEO data, rules and admin on the backend. Phase 33 makes the rendered sites emit complete SEO output from the CMS, and adds the audit that finds the remaining problems: +- the `sm-sitemap-plugin` rewrite (D-32): XML sitemap index split by type, image and News sitemaps, IndexNow, the HTML sitemap; +- the page registry in `sm-seo-plugin`; +- JSON-LD `@graph`, pagination, hreflang; +- headings, breadcrumbs; +- the shared Nuxt SEO layer and the SSR rules in the layers, with the layers and apps moved onto it; +- the crawler and the issue report; +- internal linking and auto-links, the orphan report; +- media SEO (alt, file names, formats). + +The split of responsibility from 32-CONTEXT still holds: the backend plugins own the data, rules and admin, and serve them to the frontend; the Nuxt layers render them into ``, JSON-LD, breadcrumbs, pagination and headings, enforce redirects and noindex on their routes, and guarantee server rendering. + +**Builds on:** the Phase 32 releases, as tagged versions, not a `replace` (Q-01): SummerCMS v0.5.1, `sm-seo-plugin` v0.1.0, `sm-journal-plugin` v0.2.5. The framework seams D-91 to D-93 exist and stay as they are. + +**Repos:** `sm-sitemap-plugin`, `sm-seo-plugin`, `sm-journal-plugin`, `sm-faq-plugin`, the Nuxt layers (a new SEO layer, journal, menu, FAQ), the apps. grzybyfunkcjonalne moves to the new sitemap format in the same delivery. + +**Out of scope** (as in 32-CONTEXT): e-commerce structured data and shop pages; migrating `sm-bm-app` to SSR (D-72 gives it noindex and `Disallow` only). + + + + +## Implementation Decisions + +### Planning (Jakub, 2026-10-25) +- **About 12–15 smaller plans: an exception to the lean-planning rule.** The planner must not merge them into 3–4 plans. The other project rules still apply: the plan list with a one-line scope each is shown to Jakub before PLAN.md files are written, and unit tests are the last plan. +- **Mode:** mvp (ROADMAP.md). +- **The framework still carries no SEO code (D-90).** If Phase 33 needs a new framework seam, it must be generic and additive (D-106 rules: patch tag, no breaking change); D-103 rules out a fourth seam for redirects and verification files. + +### Decisions implemented entirely in Phase 33 +Section numbers refer to 32-CONTEXT.md. + +| ID | Decision | 32-CONTEXT section | +|----|----------|--------------------| +| D-30 | Sitemap index split by type, 1000-URL files, real `lastmod` | 5 | +| D-31 | Image, News sitemaps, IndexNow | 5 | +| D-32 | The new format replaces PHP parity (breaking, confirmed); the XSLT todo goes with it | 5 | +| D-33 | Page registry in the CMS | 5 | +| D-34 | HTML sitemap | 5 | +| D-40 | URL form chosen per site | 6 | +| D-41 | Page 2 and later: robots, suffixes, H1, pillar text | 6 | +| D-42 | Numbered server-rendered links, rel prev/next, 301 and 404 rules | 6 | +| D-43 | One JSON-LD `@graph` | 7 | +| D-44 | Schema type, type-dependent fields, custom JSON-LD | 7 | +| D-45 | Publisher in the global settings | 7 | +| D-46 | Validation in admin, crawler and Rich Results link | 7 | +| D-50 | No H1 in body content, including Journal's conversion (D-96) | 8 | +| D-51 | Live heading outline and crawler checks | 8 | +| D-52 | One heading convention in the layers | 8 | +| D-55 | hreflang in head and sitemaps from one source | 9 | +| D-56 | `x-default` points to the default locale | 9 | +| D-57 | No hreflang for a missing translation | 9 | +| D-70 | Indexable pages always SSR or SSG; build guard; raw versus rendered check | 10 | +| D-71 | Real status codes, server-rendered links, content in HTML, image rules | 10 | +| D-72 | `sm-bm-app` gets noindex and `Disallow` only | 10 | +| D-80 | One link per post card | 11 | +| D-81 | No generic anchors | 11 | +| D-82 | Related posts, phrase auto-linking, suggestions, orphan report | 11 | +| D-83 | Outbound link rules | 11 | +| D-85 | Media SEO | 12 | +| D-86 | Breadcrumbs component and primary category | 12 | +| D-95 | `sm-sitemap-plugin` with its own filter interface that SEO implements | 0 | +| D-97 | One shared Nuxt SEO layer | 0 | + +### Decisions split between Phases 32 and 33 (Phase 33 part only) +Phase 32 delivered the rest of each; see the Phase 32 column of the decisions map. + +| ID | Decision | Phase 33 part | +|----|----------|---------------| +| D-03 | Global settings | Organisation or person data for JSON-LD (with D-43, D-45) | +| D-05 | Search engine verification | Serving the files at the site root from the layer (D-103) | +| D-08 | Meta robots, `X-Robots-Tag` | Sending the header on frontend-rendered pages and files (layer, D-97) | +| D-10 | All SEO manageable through MCP on `pier` | Tools for the crawler and the other Phase 33 screens | +| D-12 | Batch tools with `dry_run` | "Noindex on a page in a sitemap" conflict refined by the D-95 filter | +| D-14 | Issue report: CMS data checks plus a crawler | The built-in crawler and its checks | +| D-20 | 404 log | The layer's call to the report endpoint | +| D-20a | Where redirects execute | Nitro middleware in the layer (D-97, D-103) | +| D-20b | URL normalisation per site | Enforcement on frontend routes through the layer | +| D-20c | Strict URLs | Layer routes reading their patterns from the CMS | +| D-21 | Default robots per page kind | Pagination page 2+ (D-41) and signed-in routes (D-23) in the layer | +| D-22 | robots.txt | The `Sitemap:` default moves to the D-30 index | +| D-23 | Private frontend pages noindex | Automatic marking of signed-in routes in the layer and the user plugin's auth layer | +| D-24 | noindex, robots.txt and sitemaps consistent | Noindex, canonicalised and redirected pages leave the sitemaps; "sitemap URL blocked" warning | +| D-25 | AI bot switches, optional llms.txt | llms.txt generated from the sitemap | +| D-93 | Content descriptors in signpost | Sitemaps and the page registry consume `Records` (D-30, D-33) | +| D-94 | `sm-seo-plugin` scope | Page registry, llms.txt, JSON-LD `@graph` and breadcrumbs APIs, crawler | +| D-96 | Content plugins keep only their own fixes | Journal's H1 to H2 conversion (D-50) and schema types (D-43) | +| D-103 | Redirect decision endpoint and verification-file API only | Layer enforcement of redirects and root mapping of verification files | + +### Claude's Discretion +- HTML sitemap grouping and paging (D-34). +- Crawler implementation: Go, an in-process job through `conga`/River, politeness limits (D-14). +- Table and package names inside the plugins. +- Site-cache purge after SEO writes: Phase 32 serves effective SEO through one resolver endpoint per URL (P-15) but does not purge. Once the D-97 layer caches the resolve answer, purging through the existing site-cache purge becomes needed; plan it with D-97. + + + + +## Canonical References + +**Downstream agents MUST read these before planning or implementing.** + +### Decisions +- `.planning/phases/32-seo-foundation/32-CONTEXT.md`: full text of every decision listed above, the reference implementations (`mpseo`) and the code seams. +- `.planning/phases/32-seo-foundation/32-DECISIONS-MAP.md`: the Phase 32/33 boundary per decision. + +### What Phase 32 delivered +- `.planning/phases/32-seo-foundation/32-0*-SUMMARY.md`: what exists in `sm-seo-plugin` (models, resolver, redirects, robots.txt, verification API, `/_seo/api/v1`, MCP tools, issue report) and the framework seams (D-91 form extensions, D-92 record events, D-93 descriptors). +- `.planning/phases/32-seo-foundation/32-VERIFICATION.md`, `32-UAT.md`: open verification items. +- `.planning/phases/32-seo-foundation/deferred-items.md`: Journal bumps in the apps, plugin release posts and the demo deploy, still open after Phase 32. +- `.planning/phases/32-seo-foundation/32-UI-SPEC.md`: admin elements E1–E7; Phase 33 admin screens follow the same conventions. + +### Prior phase decisions +- `.planning/phases/16-grzybyfunkcjonalne-pl-on-reusable-blog-views/16-CONTEXT.md`: Nuxt layers, SSR with swr/ISR, URLs kept identical. +- `.planning/phases/17-blog-companions/17-CONTEXT.md`: signpost menu-item types and per-locale alternates; D-11 to D-15, the sitemap behaviour D-32 replaces. +- `.planning/phases/19.7-generic-mcp-module/19.7-CONTEXT.md`: `pier`, tools bound to admin routes. + +### Code +- `../sm-sitemap-plugin/`: `classes/generator.go`, `classes/serialize.go`, `routes.go`, `admin.go`, `models/settings.go`. +- `../sm-seo-plugin/`: the Phase 32 plugin that Phase 33 extends. +- `../sm-journal-plugin/`: `classes/format_html.go` (allows h1 today), `classes/menu_item_types.go`. +- `../vue-journal-layer/`: `nuxt.config.ts` (`@nuxtjs/seo`, sitemap source), `app/utils/seo.ts`, `app/components/Journal/Pagination.vue`, `app/journal-pages/*.vue`. +- Apps: `../sm-grzybyfunkcjonalne-app/vue-grzybyfunkcjonalne-app/nuxt.config.ts` (robots and sitemap config to move to the CMS), `../sm-demo-app/vue-demo-app/` (hand-written noindex pages), `../sm-summercmsio-app/vue-summercmsio-app` (nuxt generate), `../sm-bm-app` (D-72). +- `modules/signpost/signpost.go`, `modules/conga/`: URL registry and jobs for the crawler, IndexNow and sitemap rebuilds. + + + + +## Specific Ideas + +- Dawid's audit workflow is the reference use case: after a crawl he tells his Claude client what to fix, and it happens through MCP with a dry-run preview. Every crawler issue must be fixable through MCP (ROADMAP success criterion 3). +- Sitemaps are split by type and batched at 1000 URLs so they can be monitored file by file in GSC (D-30). +- The features are framework-wide; no site-specific shaping (32-CONTEXT, Specific Ideas). + + + + +## Deferred Ideas + +- From 32-CONTEXT: social card preview, per-redirect hit counters and validity dates, 307/308 redirects, e-commerce structured data. +- `sitemap-xslt-browser-deprecation.md` (g15office w8kupqi3) stays a separate backlog task; the D-32 rewrite touches the same code, so the plan should say whether the XSL output is removed or kept. + + + +--- + +*Phase: 33-seo-output-audit-and-content* +*Decisions gathered: 2026-10-24 (Phase 32 discussion); written out: 2026-10-27*