Files
summercms/.planning/phases/11.1-summercms-documentation-for-humans-and-ai-agents/11.1-02-SUMMARY.md
Jakub Zych f77b1d8688 docs(11.1-02): complete docs accuracy gates, theme and docs:serve plan
- SUMMARY with coverage, deviations and verification
- STATE, ROADMAP and REQUIREMENTS (DOCS-02, DOCS-04, DOCS-05, DOCS-08)
- deferred items: README summary backticks in leads
2026-09-30 22:00:46 +02:00

17 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, estimate_ref, actuals, plan_head_before, plan_head_after, coverage, duration, completed, status
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established requirements-completed estimate_ref actuals plan_head_before plan_head_after coverage duration completed status
11.1-summercms-documentation-for-humans-and-ai-agents 02 docs
docs
checkers
goldmark
chroma
theme
search
docs-serve
gate
phase provides
11.1-01 internal/docsite (Check, Build, Pages, slugIDs, headingIDs, snippet checks), summer docs:build and docs:sync
phase provides
11-08 stable module READMEs for the identifier checker
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
11.1-03
11.1-04
11.1-05
11.1-06
11.2
added patterns
github.com/alecthomas/chroma/v2 v2.27.0 (direct, D-15)
github.com/dlclark/regexp2/v2 v2.2.1 (indirect, via chroma)
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
created modified
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
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
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
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
DOCS-02
DOCS-04
DOCS-05
DOCS-08
tokens 140000, tasks 3, confidence low
tokens tasks commits
46000 3 4
9dcc101776 dd11bdb0c7
id description requirement verification human_judgment
D1 A stale pkg.Ident span in a docs page, module README or the root README fails go test, docs:build and the gate DOCS-05
kind ref status
unit internal/docsite/checks_test.go#TestIdentifierChecker pass
kind ref status
unit cmd/summer/docs_test.go#TestDocsTree pass
kind ref status
other scripts/check-phase11.1.sh --self-test (bonfire.NoSuchThing plant); go run ./cmd/summer docs:build --check --src <scratch> with lighthouse.NoSuchThing pass
false
id description requirement verification human_judgment
D2 Broken relative links and anchors fail with link: problems computed from the renderer's heading IDs DOCS-05
kind ref status
unit internal/docsite/checks_test.go#TestLinkChecker pass
false
id description requirement verification human_judgment
D3 summer and ./bin/<app> command names are checked against sets collected from the real constructors and example bonfire.Command literals DOCS-05
kind ref status
unit internal/docsite/checks_test.go#TestCommandChecker pass
kind ref status
unit cmd/summer/docs_test.go#TestDocsCommandNames pass
kind ref status
unit cmd/summer/docs_test.go#TestDocsCommandsMirrorGeneratedMain pass
false
id description requirement verification human_judgment
D4 Consuming-application names fail in sources and outputs without echoing the match DOCS-05
kind ref status
unit internal/docsite/checks_test.go#TestForbiddenChecker pass
kind ref status
other scripts/check-phase11.1.sh --forbidden and --self-test pass
false
id description requirement verification human_judgment
D5 Go fences in docs/ pages need src=; unknown callouts and non-plain docs/ headings fail DOCS-04
kind ref status
unit internal/docsite/checks_test.go#TestFencePolicy pass
false
id description requirement verification human_judgment
D6 The built site has the UI-SPEC shell, chroma highlighting, 404 page, pager edge cases and no inline script/style/handler DOCS-02
kind ref status
unit internal/docsite/theme_test.go#TestBuildSiteMarkers pass
kind ref status
unit cmd/summer/docs_test.go#TestDocsBuildRealTree pass
false
id description requirement verification human_judgment
D7 docs:serve serves on loopback, refuses non-loopback without --allow-remote, returns 404.html with 404 and never a dot-file DOCS-02
kind ref status
unit internal/docsite/theme_test.go#TestServeHandler pass
kind ref status
unit internal/docsite/theme_test.go#TestServeRefusesNonLoopback pass
kind ref status
other manual smoke: summer docs:serve on 127.0.0.1, edit rebuilds, a planted problem keeps the previous build pass
false
id description requirement verification human_judgment
D8 CLAUDE.md records D-13, names the checkers and notes deferred config-key checking DOCS-08
kind ref status
other scripts/check-phase11.1.sh --claude pass
false
id description verification human_judgment rationale
D9 Search rows, arrow keys and Enter; no theme flash in all three modes; contrast at 1280/1024/375px; no-JS layout
true 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.
30min 2026-09-30 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 <kbd>, 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 <mark> 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 <nav class="sidebar" aria-label="Documentation">, <dialog class="search" id="search"> and <button class="theme-toggle".
  • Fix: div.sidebar-panel#sidebar wraps the nav, data-index sits on #search-results, and the toggle's class is exactly theme-toggle (it shares the CSS rules).
  • Files modified: theme templates, site.css, search.js
  • Commit: dd11bdb

3. [Rule 3 - Blocking] Plan 11.1-01 tests asserted the old markup

  • Found during: Task 3
  • Issue: TestReadmeIngestion expected a bare <h2 id="usage">Usage</h2>. TestDocsAIOutputsInSync required the set of .html files to equal the page URLs, and the new 404.html broke that.
  • Fix: The first now expects the permalink and the second ignores 404.html. Neither test is weakened.
  • Files modified: internal/docsite/docsite_test.go, cmd/summer/docs_test.go
  • Commit: dd11bdb

Notes

  • go.mod gained exactly github.com/alecthomas/chroma/v2 (direct) and github.com/dlclark/regexp2/v2 (indirect). go.sum also has hash lines for chroma's own test dependencies (alecthomas/assert/v2, alecthomas/repr, hexops/gotextdiff). They are not modules of this build, and --deps passes. scripts/check-phase11.sh --hygiene still passes.
  • console counts as a shell fence language alongside sh, shell and bash, both for command checks and for highlighting.
  • Another process edited modules/lagoon/transaction*.go, scripts/check-phase10.sh, scripts/check-phase11.sh and two Phase 11 review files during this run. None of them were staged or touched. 11-REVIEW.md was left alone as instructed.

Total deviations: 3 auto-fixed (1 bug, 2 blocking). Impact: none on scope.

Issues Encountered

  • Logged to deferred-items.md: a module README summary containing inline code shows raw backticks in the page lead (plan 11.1-01's splitReadme behaviour), and internal/build/registry.go was not gofmt-clean before this plan.

Verification

  • go vet ./... and go test -short ./... are green. go test ./internal/docsite ./cmd/summer ./modules/... -count=1 (Docker included) is green, and so is go test -race ./internal/docsite.
  • scripts/check-phase11.1.sh reports --preconditions, --deps, --self-test, --docs, --forbidden and --claude all passed.
  • go run ./cmd/summer docs:serve --addr 0.0.0.0:8088 exits 1 with the refusal copy. Over HTTP on loopback, /, the pages, the assets and .md return 200, and /nope and /.summer-docs return 404 with the Page not found body. The temporary directory is removed on SIGTERM.
  • All plan acceptance greps match. git diff 9033d81 -- modules/wristband is empty.

Known Stubs

None.

User Setup Required

None.

Next Phase Readiness

Plans 11.1-03 to 11.1-05 now write content that is checked as it is written. A Go example in a docs page needs src=, identifiers and commands must exist, and links must resolve. summer docs:serve previews the site. The manual UAT rows (search interaction, theme flash, contrast, no-JS layout) remain for verification.

Self-Check: PASSED

All created files exist. Commits f460529, 5d4c1e3, d89e18b and dd11bdb are in the log.