diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 387a28b..ae3a119 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -126,13 +126,13 @@ Requirements for v1 (the Płytarium port). Each maps to roadmap phases. "User" b ### Documentation (DOCS) - [ ] **DOCS-01**: `docs/` holds Markdown pages with strict YAML frontmatter (title, description, section, order), grouped into the Winter-mirroring sections, and every framework module under `modules/` is reachable from the sidebar through an API reference page ingested from its README -- [ ] **DOCS-02**: `summer docs:build` writes a self-contained static site (sidebar, on-page TOC, prev/next, edit-this-page link, client-side search, light/dark/system theme) and `summer docs:serve` previews it on loopback; no Node toolchain, and the only new dependency is `alecthomas/chroma/v2` for syntax highlighting (approved at the 11.1 plan-count checkpoint) +- [x] **DOCS-02**: `summer docs:build` writes a self-contained static site (sidebar, on-page TOC, prev/next, edit-this-page link, client-side search, light/dark/system theme) and `summer docs:serve` previews it on loopback; no Node toolchain, and the only new dependency is `alecthomas/chroma/v2` for syntax highlighting (approved at the 11.1 plan-count checkpoint) - [ ] **DOCS-03**: The build emits `llms.txt`, `llms-full.txt` and a clean `.md` beside every `.html` page, and a test asserts all three match the page tree -- [ ] **DOCS-04**: Every Go fence in a `docs/` page references compiled source by `src=` (Go fences in ingested module READMEs are identifier-checked only, per D-18); a test fails on a missing or drifted snippet, and referenced Examples carry `// Output:` and run under `go test ./...` -- [ ] **DOCS-05**: `go test ./...` runs checkers that fail on stale identifiers (docs pages and module READMEs), broken internal links and anchors, unknown `summer`/runtime CLI command names and forbidden consuming-application names +- [x] **DOCS-04**: Every Go fence in a `docs/` page references compiled source by `src=` (Go fences in ingested module READMEs are identifier-checked only, per D-18); a test fails on a missing or drifted snippet, and referenced Examples carry `// Output:` and run under `go test ./...` +- [x] **DOCS-05**: `go test ./...` runs checkers that fail on stale identifiers (docs pages and module READMEs), broken internal links and anchors, unknown `summer`/runtime CLI command names and forbidden consuming-application names - [ ] **DOCS-06**: A "Coming from WinterCMS" page maps Winter concepts to SummerCMS equivalents, and every SummerCMS identifier on it is checker-verified - [ ] **DOCS-07**: An `acme/blog` porting walkthrough covers models, migrations, routes, an admin controller and a console command; its code is a real in-root package under `docs/examples/blog`, verified by DOCS-04 -- [ ] **DOCS-08**: CLAUDE.md's Documentation section records that API, config or CLI changes update both the module README and the affected docs pages, and names the automated checkers +- [x] **DOCS-08**: CLAUDE.md's Documentation section records that API, config or CLI changes update both the module README and the affected docs pages, and names the automated checkers ## v2 Requirements @@ -244,13 +244,13 @@ Which phases cover which requirements. Updated during roadmap creation. | QA-04 | Phase 3 | Complete | | QA-05 | Phase 15 | Pending | | DOCS-01 | Phase 11.1 | Pending | -| DOCS-02 | Phase 11.1 | Pending | +| DOCS-02 | Phase 11.1 | Complete | | DOCS-03 | Phase 11.1 | Pending | -| DOCS-04 | Phase 11.1 | Pending | -| DOCS-05 | Phase 11.1 | Pending | +| DOCS-04 | Phase 11.1 | Complete | +| DOCS-05 | Phase 11.1 | Complete | | DOCS-06 | Phase 11.1 | Pending | | DOCS-07 | Phase 11.1 | Pending | -| DOCS-08 | Phase 11.1 | Pending | +| DOCS-08 | Phase 11.1 | Complete | **Coverage:** - v1 requirements: 85 total diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 637909c..6f03d20 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -544,14 +544,14 @@ Plans: 4. Every Go example in a `docs/` page is compiled and run by `go test ./...` (Go code in ingested module READMEs is identifier-checked, not compiled — D-18). An identifier checker and an internal link/anchor checker also run there and fail on stale names or broken links. 5. A "Coming from WinterCMS" concept map and an `acme/blog` porting walkthrough exist, and the walkthrough's code is verified under criterion 4. -**Plans:** 1/6 plans executed +**Plans:** 2/6 plans executed Plans: **Wave 1** - [x] 11.1-01-PLAN.md — Tracer: internal/docsite generator core to every output (html, .md, llms.txt, llms-full.txt, search index), README ingestion, src= snippets, `summer docs:build` and `docs:sync` **Wave 2** *(blocked on Wave 1 completion)* -- [ ] 11.1-02-PLAN.md — Accuracy gates (identifiers, links/anchors, command names, forbidden names, go-fence policy), UI-SPEC theme with chroma/v2, search, dark mode, `summer docs:serve`, phase gate, CLAUDE.md D-13 rule +- [x] 11.1-02-PLAN.md — Accuracy gates (identifiers, links/anchors, command names, forbidden names, go-fence policy), UI-SPEC theme with chroma/v2, search, dark mode, `summer docs:serve`, phase gate, CLAUDE.md D-13 rule **Wave 3** *(blocked on Wave 2 completion)* - [ ] 11.1-03-PLAN.md — Content A: Setup (incl. Coming from WinterCMS), Architecture, Plugins, Console, module Examples @@ -674,7 +674,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → | 9. Backend admin authentication and schema pipeline | 12/12 | In Progress| | | 10. Admin Vue SPA | 5/5 | Complete | 2026-09-27 | | 11. Jobs, realtime and search infrastructure | 8/8 | In Progress| | -| 11.1. SummerCMS documentation for humans and AI agents | 1/6 | In Progress| | +| 11.1. SummerCMS documentation for humans and AI agents | 2/6 | In Progress| | | 11.2. Ready to share: summercms.io website and newsletter plugin | 0/TBD | Not started | - | | 12. Płytarium API — Collections and Albums | 0/TBD | Not started | - | | 13. Płytarium API — wishlist, notifications, CSV, credentials, public routes | 0/TBD | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index 2c57913..7190e64 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -4,16 +4,16 @@ milestone: v1.0 current_phase: "11.1" current_phase_name: SummerCMS documentation for humans and AI agents (INSERTED) status: executing -stopped_at: Completed 11.1-01-PLAN.md -last_updated: "2026-09-30T19:28:23.430Z" +stopped_at: Completed 11.1-02-PLAN.md +last_updated: "2026-09-30T20:00:38.713Z" last_activity: 2026-09-30 last_activity_desc: Phase 11.1 execution started -state_head: e75490e8925112cc018899c3e212c086f423ea7f +state_head: dd11bdb0c7443b69cb1df3df4574fa6a8024cdb8 progress: total_phases: 19 completed_phases: 9 total_plans: 92 - completed_plans: 87 + completed_plans: 88 milestone_name: milestone --- @@ -29,7 +29,7 @@ See: .planning/PROJECT.md (updated 2026-09-16) ## Current Position Phase: 11.1 (SummerCMS documentation for humans and AI agents (INSERTED)) — EXECUTING -Plan: 2 of 6 +Plan: 3 of 6 Status: Ready to execute Last activity: 2026-09-30 — Phase 11.1 execution started @@ -142,6 +142,7 @@ Progress: [██████░░░░] 60% | Phase 11 P07 | 59min | 3 tasks | 40 files | | Phase 11 P08 | unknown (manual close-out) | 3 tasks | 13 files | | Phase 11.1 P01 | 15min | 3 tasks | 18 files | +| Phase 11.1 P02 | 30min | 3 tasks | 53 files | ## Accumulated Context @@ -389,6 +390,9 @@ Recent decisions affecting current work: - [Phase 11]: Phase gates accept a pending skip only by exact test name and pending text (TestBroadcastGoldens/created and /updated until Phase 12), in check-phase11.sh and check-phase10.1.sh - [Phase 11]: Phase 11-08: lagoon.AfterCommit inside a foreign plain GORM transaction warns and skips the callback instead of running it immediately; Cabana writes and SaveAlbum run in lagoon.Transaction — Lagoon cannot observe a foreign commit; running early sent uncommitted, pre-pivot or rolled-back Album state to Typesense (CR-01) - [Phase 11]: Phase 11-08: a nested lagoon.Transaction given a root handle returns an error (WR-03) — Treating it as a savepoint would commit independently while its callbacks waited on the parent buffer +- [Phase 11.1]: 11.1-02: The identifier index resolves promoted members itself; go doc does not resolve embedding and stays only as the fallback +- [Phase 11.1]: 11.1-02: docsCommands() collects app command names from the real constructors on backpack.New(&compass.Config{}); TestDocsCommandsMirrorGeneratedMain keeps it in step with internal/build +- [Phase 11.1]: 11.1-02: chroma/v2 v2.27.0 is the only new direct dependency (D-15); tokens map onto tok-* classes without chroma's HTML formatter ### Pending Todos @@ -419,6 +423,6 @@ Items acknowledged and carried forward from previous milestone close: ## Session Continuity -Last session: 2026-09-30T19:28:22.944Z -Stopped at: Completed 11.1-01-PLAN.md +Last session: 2026-09-30T20:00:38.048Z +Stopped at: Completed 11.1-02-PLAN.md Resume file: None diff --git a/.planning/phases/11.1-summercms-documentation-for-humans-and-ai-agents/11.1-02-SUMMARY.md b/.planning/phases/11.1-summercms-documentation-for-humans-and-ai-agents/11.1-02-SUMMARY.md new file mode 100644 index 0000000..522ea87 --- /dev/null +++ b/.planning/phases/11.1-summercms-documentation-for-humans-and-ai-agents/11.1-02-SUMMARY.md @@ -0,0 +1,302 @@ +--- +phase: 11.1-summercms-documentation-for-humans-and-ai-agents +plan: 02 +subsystem: docs +tags: [docs, checkers, goldmark, chroma, theme, search, docs-serve, gate] + +requires: + - phase: 11.1-01 + provides: "internal/docsite (Check, Build, Pages, slugIDs, headingIDs, snippet checks), summer docs:build and docs:sync" + - phase: 11-08 + provides: "stable module READMEs for the identifier checker" +provides: + - "docsite.Commands and Options.Commands (nil is a problem, never a silent skip)" + - "docsite.Serve, docsite.Handler, docsite.DefaultServeAddr" + - "checkers: identifier, link, command, forbidden, snippet (go fence without src=), callout, heading" + - "chroma/v2 NodeRenderer mapping tokens onto tok-kw, tok-key, tok-str, tok-com, tok-num, tok-prompt" + - "UI-SPEC theme: header, sidebar, TOC, pager, footer, search dialog, icons, 404, site.css, site.js, search.js, theme-init.js, vendored fonts" + - "summer docs:serve (--root --src --base-url --addr --allow-remote) and cmd/summer docsCommands()" + - "scripts/check-phase11.1.sh with --preconditions --deps --docs --forbidden --claude --self-test --go --all" + - "CLAUDE.md D-13 rule naming the checkers, D-17 config-key note; wristband default todo" +affects: [11.1-03, 11.1-04, 11.1-05, 11.1-06, 11.2] + +tech-stack: + added: + - "github.com/alecthomas/chroma/v2 v2.27.0 (direct, D-15)" + - "github.com/dlclark/regexp2/v2 v2.2.1 (indirect, via chroma)" + patterns: + - "Every checker reads one parse per page (parseRaw: renderer parser and slug IDs, no page context) so anchors match the rendered IDs" + - "Command sets are collected from the real constructors; a test keeps them in step with the generated app main" + - "Forbidden names are scanned in page sources before render and in every text output after render" + - "Theme markers are exact UI-SPEC strings asserted by TestBuildSiteMarkers; no inline script, style or on* attribute" + +key-files: + created: + - internal/docsite/check_identifiers.go + - internal/docsite/check_links.go + - internal/docsite/check_commands.go + - internal/docsite/check_forbidden.go + - internal/docsite/check_policy.go + - internal/docsite/highlight.go + - internal/docsite/serve.go + - internal/docsite/checks_test.go + - internal/docsite/theme_test.go + - internal/docsite/theme/templates/header.html + - internal/docsite/theme/templates/sidebar.html + - internal/docsite/theme/templates/toc.html + - internal/docsite/theme/templates/pager.html + - internal/docsite/theme/templates/footer.html + - internal/docsite/theme/templates/search.html + - internal/docsite/theme/templates/icons.html + - internal/docsite/theme/templates/404.html + - internal/docsite/theme/assets/site.js + - internal/docsite/theme/assets/search.js + - internal/docsite/theme/assets/theme-init.js + - internal/docsite/theme/assets/LICENSE-lucide.txt + - internal/docsite/theme/assets/fonts/ (8 woff2 files, LICENSE-dm-sans.txt, LICENSE-dm-mono.txt) + - scripts/check-phase11.1.sh + - .planning/todos/pending/wristband-neutral-resource-default.md + modified: + - internal/docsite/docsite.go + - internal/docsite/load.go + - internal/docsite/render.go + - internal/docsite/emit.go + - internal/docsite/docsite_test.go + - internal/docsite/theme/templates/page.html + - internal/docsite/theme/assets/site.css + - cmd/summer/docs.go + - cmd/summer/docs_test.go + - cmd/summer/main.go + - cmd/summer/main_test.go + - go.mod + - go.sum + - README.md + - CLAUDE.md + +key-decisions: + - "The identifier index resolves members promoted through types embedded in the same package; go doc does not resolve promotion, so it stays only as the fallback for anything else" + - "docsCommands() calls the constructors on backpack.New(&compass.Config{}) with nil plugins; they only capture the app, and nothing runs" + - "The forbidden-name output scan runs after a clean render; the page-source scan reports first with source file and line" + - "Callout types are checked in docs pages and module READMEs; the heading rule and the go-fence src= rule apply to docs/ pages only (D-18)" + - "Link rule for other relative repo paths applies to guide pages only; module READMEs are read on the git host first" + - "The drawer target is a div#sidebar wrapping the nav, and the search index URL sits on #search-results, so the UI-SPEC markers stay exact" + - "A pager target on the index page carries no section line" + +patterns-established: + - "Checker problem lines follow the UI-SPEC CLI table: file:line: rule: message" + - "Gate self-tests copy docs/, modules/, go.mod and go.sum into a scratch root and plant one violation per rule" + +requirements-completed: [DOCS-02, DOCS-04, DOCS-05, DOCS-08] + +estimate_ref: "tokens 140000, tasks 3, confidence low" +actuals: + tokens: 46000 + tasks: 3 + commits: 4 +plan_head_before: 9dcc10177609f22ac535d4dd9972d55f7037e6b8 +plan_head_after: dd11bdb0c7443b69cb1df3df4574fa6a8024cdb8 + +coverage: + - id: D1 + description: "A stale pkg.Ident span in a docs page, module README or the root README fails go test, docs:build and the gate" + requirement: DOCS-05 + verification: + - kind: unit + ref: "internal/docsite/checks_test.go#TestIdentifierChecker" + status: pass + - kind: unit + ref: "cmd/summer/docs_test.go#TestDocsTree" + status: pass + - kind: other + ref: "scripts/check-phase11.1.sh --self-test (bonfire.NoSuchThing plant); go run ./cmd/summer docs:build --check --src with lighthouse.NoSuchThing" + status: pass + human_judgment: false + - id: D2 + description: "Broken relative links and anchors fail with link: problems computed from the renderer's heading IDs" + requirement: DOCS-05 + verification: + - kind: unit + ref: "internal/docsite/checks_test.go#TestLinkChecker" + status: pass + human_judgment: false + - id: D3 + description: "summer and ./bin/ command names are checked against sets collected from the real constructors and example bonfire.Command literals" + requirement: DOCS-05 + verification: + - kind: unit + ref: "internal/docsite/checks_test.go#TestCommandChecker" + status: pass + - kind: unit + ref: "cmd/summer/docs_test.go#TestDocsCommandNames" + status: pass + - kind: unit + ref: "cmd/summer/docs_test.go#TestDocsCommandsMirrorGeneratedMain" + status: pass + human_judgment: false + - id: D4 + description: "Consuming-application names fail in sources and outputs without echoing the match" + requirement: DOCS-05 + verification: + - kind: unit + ref: "internal/docsite/checks_test.go#TestForbiddenChecker" + status: pass + - kind: other + ref: "scripts/check-phase11.1.sh --forbidden and --self-test" + status: pass + human_judgment: false + - id: D5 + description: "Go fences in docs/ pages need src=; unknown callouts and non-plain docs/ headings fail" + requirement: DOCS-04 + verification: + - kind: unit + ref: "internal/docsite/checks_test.go#TestFencePolicy" + status: pass + human_judgment: false + - id: D6 + description: "The built site has the UI-SPEC shell, chroma highlighting, 404 page, pager edge cases and no inline script/style/handler" + requirement: DOCS-02 + verification: + - kind: unit + ref: "internal/docsite/theme_test.go#TestBuildSiteMarkers" + status: pass + - kind: unit + ref: "cmd/summer/docs_test.go#TestDocsBuildRealTree" + status: pass + human_judgment: false + - id: D7 + description: "docs:serve serves on loopback, refuses non-loopback without --allow-remote, returns 404.html with 404 and never a dot-file" + requirement: DOCS-02 + verification: + - kind: unit + ref: "internal/docsite/theme_test.go#TestServeHandler" + status: pass + - kind: unit + ref: "internal/docsite/theme_test.go#TestServeRefusesNonLoopback" + status: pass + - kind: other + ref: "manual smoke: summer docs:serve on 127.0.0.1, edit rebuilds, a planted problem keeps the previous build" + status: pass + human_judgment: false + - id: D8 + description: "CLAUDE.md records D-13, names the checkers and notes deferred config-key checking" + requirement: DOCS-08 + verification: + - kind: other + ref: "scripts/check-phase11.1.sh --claude" + status: pass + human_judgment: false + - id: D9 + description: "Search rows, arrow keys and Enter; no theme flash in all three modes; contrast at 1280/1024/375px; no-JS layout" + verification: [] + human_judgment: true + rationale: "Backstop truths in the plan: manual UAT via summer docs:serve (no JS runner without Node). Headless Chromium screenshots at 1400px and 800px in light and dark looked right, but that is not the UAT." + +duration: 30min +completed: 2026-09-30 +status: complete +--- + +# Phase 11.1 Plan 02: Docs accuracy gates, theme and docs:serve Summary + +**Every D-11/D-12 rule now fails `go test` and `docs:build`: stale identifiers, broken links and anchors, unknown commands, consuming-application names, go fences without `src=`, unknown callouts and non-plain headings. The site has the full UI-SPEC WinterCMS-style theme with chroma/v2 highlighting, client-side search, a three-way theme toggle and `summer docs:serve`, and `scripts/check-phase11.1.sh` checks all of it.** + +## Performance + +- **Duration:** about 30 min +- **Started:** 2026-09-30T19:29Z +- **Completed:** 2026-09-30T19:59Z +- **Tasks:** 3 +- **Files modified:** 53 (38 without fonts and licences) + +## Accomplishments + +- `check_identifiers.go` uses `go/parser` to index every package under `modules/`, sub-packages included. It records funcs, types, consts, vars, methods (generic receivers stripped), fields, embedded types and interface methods, and resolves promoted members. On the real tree it checks 1,268 module spans across 24 pages and the root README with 0 misses. +- Links and anchors are checked against the heading IDs the renderer produces. Command names come from `toolCommands()` and the constructors the generated main calls (plus `lagoon.KeyGenerateCommand`, `centrifugo.Commands` and `flare.Commands`). Example `bonfire.Command` literals under `docs/examples` and `examples` are parsed, never imported. +- Consuming-application names are rejected in page sources and in every text output. The problem line never repeats the matched word. +- Theme: header (wordmark, search trigger with ``, theme toggle, Menu), grouped sidebar with API items in DM Mono, TOC column and `toc-inline` (only with 2 or more H2/H3), eyebrow/lead/page actions, callouts, heading permalinks, pager (first page Next only, last page Previous only, section line only across sections), footer with llms links, `404.html`, and 15 inline Lucide icons. DM Sans and DM Mono are vendored with their licences. Nothing loads from a third-party origin. +- `highlight.go` maps chroma tokens onto the UI-SPEC classes. Shell fences get `tok-prompt` for `$ ` (excluded from copy) and `tok-kw` for the command word. +- `search.js` loads `search-index.json` on first open. It uses AND-token matching ranked title over heading over text, shows up to 20 rows built with `createElement`/`textContent` and `` elements, and implements every UI-SPEC state message and live-region count. +- `summer docs:serve` builds into a temporary directory, serves on `127.0.0.1:8088` by default and refuses any non-loopback address without `--allow-remote`. It returns `404.html` with status 404, never serves dot-files, and rebuilds on change while keeping the last good build. +- The gate self-test plants 9 violations (identifier, missing README, drifted snippet, frontmatter typo, broken anchor, unknown command, forbidden name, go fence without `src=`, `[!DANGER]`) and each one is refused under its own rule. + +## Task Commits + +1. **Task 1: Identifier checker tracer through go test, docs:build and the gate:** `f460529` (feat) +2. **Task 2: Links, commands, forbidden names, fence policy:** `5d4c1e3` (feat). The docs-rules change was committed separately as `d89e18b` (docs: CLAUDE.md and the wristband todo) +3. **Task 3: Theme, chroma, search, dark mode, docs:serve:** `dd11bdb` (feat) + +**Plan metadata:** the docs(11.1-02) commit that adds this file + +## Files Created/Modified + +See `key-files` in the frontmatter. The main ones: +- `internal/docsite/check_*.go`: the five checker files +- `internal/docsite/highlight.go`: the fence NodeRenderer and chroma mapping. It moved out of render.go +- `internal/docsite/render.go`: heading permalinks, the callout transformer and renderer, `parseRaw` +- `internal/docsite/emit.go`: the page view (eyebrow, TOC, pager, edit and Markdown links) and `404.html` +- `internal/docsite/serve.go`: `Serve`, `Handler` and the loopback check +- `cmd/summer/docs.go`: `docsCommands()` and `docs:serve` + +## Decisions Made + +See `key-decisions` in the frontmatter. + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 1 - Bug] `go doc` does not resolve promoted members** +- **Found during:** Task 1 +- **Issue:** The plan relied on the `go doc` fallback to accept members promoted through embedding. `go doc ./modules/x Bus.ID` exits 1 for a field or method promoted from an embedded type. +- **Fix:** The index records the embedded types of each type and follows them within the package. `go doc` remains the fallback for any other miss. +- **Files modified:** internal/docsite/check_identifiers.go, internal/docsite/checks_test.go +- **Commit:** f460529 + +**2. [Rule 3 - Blocking] The exact UI-SPEC markers conflicted with the attributes they needed** +- **Found during:** Task 3 +- **Issue:** `aria-controls="sidebar"` needs an element with `id="sidebar"`, `search.js` needs the index URL, and the toggle shared an `icon-button` class. Putting those attributes on the nav, the dialog and the toggle broke the exact markers `