--- phase: 11.1-summercms-documentation-for-humans-and-ai-agents plan: 04 type: execute wave: 4 depends_on: ["11.1-03"] files_modified: - docs/site.yaml - docs/index.md - docs/setup/coming-from-wintercms.md - docs/database/models.md - docs/database/migrations.md - docs/database/queries-and-pagination.md - docs/database/relations.md - docs/database/casts-and-validation.md - docs/database/attachments.md - docs/database/transactions.md - docs/backend/admin-controllers.md - docs/backend/forms.md - docs/backend/lists-and-filters.md - docs/backend/relation-manager.md - docs/backend/users-and-permissions.md - docs/backend/settings.md - docs/backend/partials-and-widgets.md - docs/backend/admin-spa.md - docs/services/configuration.md - docs/services/events.md - docs/services/routing.md - docs/services/rate-limiting.md - docs/services/authentication.md - docs/services/oauth-server.md - docs/services/mail.md - docs/services/localization.md - docs/services/storage.md - docs/services/outbound-http.md - docs/services/jobs.md - docs/services/realtime.md - docs/services/push.md - docs/services/search.md - docs/services/parity-testing.md - docs/services/frontend-and-ajax.md - modules/conga/example_test.go - modules/conga/export_docs_test.go - modules/lagoon/example_test.go - modules/lagoon/export_docs_test.go - modules/lagoon/attach/example_test.go - modules/compass/example_test.go - modules/surf/example_test.go - modules/wire/example_test.go - modules/bouncer/example_test.go - modules/wristband/example_test.go - modules/postcard/example_test.go - modules/phrasebook/example_test.go - modules/cabana/example_test.go - modules/fetchguard/example_test.go - modules/lighthouse/example_test.go - modules/lighthouse/export_docs_test.go - modules/flare/example_test.go - modules/beachcomber/example_test.go - modules/beachcomber/export_docs_test.go - modules/tide/example_test.go - cmd/summer/docs_test.go autonomous: true requirements: [DOCS-01, DOCS-04, DOCS-06] assumption_delta_decision: no-change user_setup: [] estimate: tokens: 150000 raw_tokens: 150000 tasks: 3 confidence: low must_haves: truths: - "Per D-08, site.yaml lists the sections in the order Setup, Architecture, Plugins, Backend, Database, Services, Console, API reference, and TestDocsRequiredPages asserts exactly that order." - "Per D-08, the Backend section covers admin auth, forms, lists, the relation manager and settings; Database covers models, migrations, relations, casts and validation; Services covers events, config, mail, i18n, jobs, realtime, search, storage, rate limiting and HTTP routing with auth groups, plus push (flare), outbound HTTP (fetchguard), the OAuth server (wristband), parity testing (tide) and lagoon transactions with after-commit work." - "The Services section has a 'Frontend and AJAX (not provided)' page that explains the headless model (JSON API, realtime, the frontend as a separate application) and states that CMS pages, themes, components, the AJAX framework and Snowboard are not provided." - "Per D-09, every concept map row in docs/setup/coming-from-wintercms.md whose topic now has a guide page links that page, and the Not provided rows link the Frontend and AJAX page." - "Per D-07, every Go fence in these pages is a src= copy: an Example with `// Output:` using memory, log or null drivers where the API runs without Postgres, or a docs:start region in a helper that a `TestDocs*` test runs against the module's existing Docker Postgres harness (skipped only under -short, like the module's other database tests)." - "Per D-11 and D-17, no page quotes the wristband default resource URL or any consuming-application name, and no snippet is taken from wristband source comments; wristband snippets come from modules/wristband/example_test.go." - "The realtime, push, jobs, search and transactions pages describe the Phase 11 behaviour as shipped: broadcasts enqueued in the write transaction and published only after commit, WithoutBroadcasting suppression per model type, search sync after commit gated by a kill-switch with SearchIDs as candidates to re-check in SQL, push only to https hosts on push.allowed_hosts without redirects, and AfterCommit refusing to run external work inside a foreign transaction." - "No module API changes in this plan; an awkward API is described as it is and logged under .planning/todos/pending/." - "TestDocsTree, TestDocsRequiredPages and TestDocsAIOutputsInSync pass on the real tree after each task." - statement: "The Backend, Database and Services pages are accurate to the modules and useful to a WinterCMS developer (manual review against the module READMEs)." verification: backstop prohibitions: - requirement_id: DOCS-06 category: transparency status: resolved verification: judgment resolution: "The Frontend and AJAX page and the concept map's Not provided rows state the gaps; guide pages link them." reason: "Porters plan work from the docs; an implied feature that does not exist costs them a rewrite." statement: "The docs must not describe a WinterCMS feature that SummerCMS does not provide as if it were available." - requirement_id: DOCS-05 category: safety status: resolved verification: judgment resolution: "Pages state the secure defaults recorded in the module READMEs (mandatory STARTTLS, loopback-only proxies, allowlisted push hosts, SQL re-gate of search results) and mark insecure options as development-only." reason: "Operators copy configuration from docs; a page that presents an insecure option as the normal setting weakens every deployment." statement: "The docs must not present an insecure setting (plain SMTP, disabled TLS, a non-loopback preview, unfiltered search results) as the default or recommended configuration." artifacts: - path: "docs/services/jobs.md" provides: "jobs guide (conga)" contains: "conga." - path: "docs/services/frontend-and-ajax.md" provides: "not-provided page for the WinterCMS frontend, AJAX framework and Snowboard" contains: "Snowboard" - path: "docs/database/transactions.md" provides: "lagoon.Transaction and AfterCommit guide" contains: "lagoon.AfterCommit" - path: "modules/conga/export_docs_test.go" provides: "test-only access to the conga Postgres harness for docs regions" contains: "package conga" key_links: - from: "docs/services/jobs.md" to: "modules/conga/example_test.go" via: "go fence src= reference" pattern: "src=modules/conga/example_test\\.go#" - from: "modules/conga/example_test.go" to: "modules/conga/export_docs_test.go" via: "TestDocs* runs the region helper on the exported harness DB" pattern: "TestDocs" - from: "docs/setup/coming-from-wintercms.md" to: "docs/services/frontend-and-ajax.md" via: "Not provided rows link the page" pattern: "frontend-and-ajax\\.md" --- Write framework content B: the Database, Backend and Services sections, including the Phase 11 infrastructure (jobs with conga, realtime with lighthouse and its Centrifugo driver, Web Push with flare, search with beachcomber, the parity recorder in tide) and lagoon transactions with after-commit work, plus the "Frontend and AJAX (not provided)" page. Every Go fence is a verified copy of code that runs under `go test ./...`. Purpose: complete D-08's section list and the D-09 concept map links. Per the Phase 11 summaries, the module names are conga, lighthouse (with lighthouse/centrifugo), flare, beachcomber (with beachcomber/typesense) and tide; the identifier checker stays the source of truth at execution time. Output: 31 pages, three new site.yaml sections, `example_test.go` files for 17 packages, four test-only harness exports, and the updated concept map and required-pages test. @~/.claude/gsd-core/workflows/execute-plan.md @~/.claude/gsd-core/templates/summary.md @.planning/STATE.md @.planning/phases/11.1-summercms-documentation-for-humans-and-ai-agents/11.1-CONTEXT.md @.planning/phases/11.1-summercms-documentation-for-humans-and-ai-agents/11.1-RESEARCH.md @.planning/phases/11.1-summercms-documentation-for-humans-and-ai-agents/11.1-03-SUMMARY.md @.planning/phases/11-jobs-realtime-and-search-infrastructure/11-CONTEXT.md @CLAUDE.md @docs/site.yaml @docs/setup/coming-from-wintercms.md Authoring rules (same as plan 11.1-03; the checkers enforce them): strict frontmatter with one-sentence descriptions of at most 160 characters; first body line `# `; ASCII headings without links or code; identifiers as backticked `pkg.Ident` spans; module links by README path; Go fences written empty with `src=` and filled by `go run ./cmd/summer docs:sync`; neutral names (`acme`, `blog`); Winter tone; describe APIs as they are. Stage only each task's files. Database-bound snippets (D-07 "compiled and run"): when the code needs Postgres, write it as a helper function in the module's `example_test.go` (external `<m>_test` package) wrapped in `// docs:start <name>` / `// docs:end <name>`, and call the helper from a `TestDocs<Name>` test in the same file. The test gets a database from the module's existing internal harness through a new `export_docs_test.go` in the internal package (Go's export_test pattern: an exported test-only wrapper around `lagoonDB`/`dedicatedDB`, `migratedDB`, `testApp` and similar, read from modules/<m>/postgres_test.go). It skips under `testing.Short()` like the module's other database tests and fails, not skips, when Docker is missing in a full run (the harness TestMain already behaves this way). Prefer runnable Examples with the memory, log or null drivers where they exist (lighthouse memory driver, postcard memory driver, beachcomber null engine). Files gap plan 11-08 changed (modules/lagoon/transaction.go, transaction_test.go, README.md, modules/cabana/crud.go, relation.go, modules/beachcomber/sync_test.go) are read-only for this plan. Earlier phase gates also scan some of these module directories: scripts/check-phase10.sh --hygiene greps modules/boardwalk, modules/cabana and modules/phrasebook, and scripts/check-phase11.sh --hygiene greps modules/conga, modules/lighthouse, modules/flare and modules/beachcomber, both for application names and Polish catalogue words (see APPNAME_RE in scripts/check-phase11.sh). Example text in those directories uses acme/blog vocabulary only; a Polish plural example in phrasebook uses words such as post, posty, postów. </context> <tasks> <task type="tracer"> <name>Task 1: Tracer: the Jobs page shows a dispatched job that really runs, and the concept map links it</name> <precondition>.planning/phases/11-jobs-realtime-and-search-infrastructure/11-08-SUMMARY.md exists (lagoon transaction and after-commit changes committed)</precondition> <files>docs/site.yaml, docs/services/jobs.md, modules/conga/example_test.go, modules/conga/export_docs_test.go, docs/setup/coming-from-wintercms.md, cmd/summer/docs_test.go</files> <read_first> - modules/conga/README.md and `go doc -all ./modules/conga` - modules/conga/postgres_test.go (TestMain, adminDB, migratedDB, testApp) and modules/conga/manager_test.go (how Dispatch is exercised) - .planning/phases/11-jobs-realtime-and-search-infrastructure/11-01-SUMMARY.md and 11-02-SUMMARY.md - .planning/phases/11-jobs-realtime-and-search-infrastructure/11-CONTEXT.md (the job manager, workers and scheduler decisions) - docs/setup/coming-from-wintercms.md (queued jobs row) </read_first> <action> Prove the database-bound snippet path end to end on one Services page before the bulk. 1. `docs/site.yaml`: add `services` ("Services") after `plugins` (and before `console`), in the same change as its first page. 2. `modules/conga/export_docs_test.go` (package `conga`): export test-only wrappers over the existing harness (for example `func DocsApp(t *testing.T) (*backpack.App, *gorm.DB)` built from `migratedDB` and `testApp`). 3. `modules/conga/example_test.go` (package `conga_test`): a runnable `Example` for declaring a typed job with `conga.Job` (no database needed), ending with `// Output:`; and a region helper (for example `docs:start dispatch`) that dispatches a job inside a transaction and reads its `summer_jobs` status, called from `TestDocsDispatch`, which uses the exported harness, skips under `-short`, and asserts the job completes. 4. `docs/services/jobs.md` (order 110): declaring jobs, registering them through `pact.HasJobs`, dispatching in the caller's transaction, the `summer_jobs` record and its statuses (in queue, in progress, complete, error, stopped), progress and cancellation, workers in `serve` versus `queue:work --queue`, `queue.work_in_serve`, `queue:clear`, and a link to Plugins, Scheduling. Two `go src=modules/conga/example_test.go#...` fences filled by `summer docs:sync`. 5. `docs/setup/coming-from-wintercms.md`: link the queued-jobs row to `../services/jobs.md`. 6. `TestDocsRequiredPages`: append `services/jobs`. </action> <verify> <automated>go vet ./... && go test ./modules/conga -run '^(Example.*|TestDocsDispatch)$' -count=1 -v && go test ./cmd/summer -run '^(TestDocsTree|TestDocsRequiredPages)$' -count=1 -v</automated> <fails_when>non-zero exit, a "--- FAIL" or "--- SKIP: TestDocsDispatch" line, or "no tests to run"</fails_when> </verify> <acceptance_criteria> - `go test ./modules/conga -run '^TestDocsDispatch$' -count=1 -v` prints `--- PASS: TestDocsDispatch` (Docker available, not -short). - `grep -c 'src=modules/conga/example_test.go#' docs/services/jobs.md` prints at least 2. - `grep -n 'services/jobs.md' docs/setup/coming-from-wintercms.md` finds a match. - `grep -n '// docs:start' modules/conga/example_test.go` finds a match. - `go run ./cmd/summer docs:build --check` exits 0. </acceptance_criteria> <done>The Jobs page is live in a new Services section with one runnable Example and one database-backed region that a test runs, and the concept map points to it.</done> </task> <task type="auto"> <name>Task 2: Database section and the core Services pages (configuration, events, routing, rate limiting, authentication, OAuth, mail, localization)</name> <files>docs/site.yaml, docs/database/models.md, docs/database/migrations.md, docs/database/queries-and-pagination.md, docs/database/relations.md, docs/database/casts-and-validation.md, docs/database/attachments.md, docs/database/transactions.md, docs/services/configuration.md, docs/services/events.md, docs/services/routing.md, docs/services/rate-limiting.md, docs/services/authentication.md, docs/services/oauth-server.md, docs/services/mail.md, docs/services/localization.md, modules/lagoon/example_test.go, modules/lagoon/export_docs_test.go, modules/lagoon/attach/example_test.go, modules/compass/example_test.go, modules/surf/example_test.go, modules/wire/example_test.go, modules/bouncer/example_test.go, modules/wristband/example_test.go, modules/postcard/example_test.go, modules/phrasebook/example_test.go, cmd/summer/docs_test.go</files> <read_first> - modules/lagoon/README.md (after 11-08), modules/compass/README.md, modules/festival/README.md, modules/surf/README.md, modules/wire/README.md, modules/bouncer/README.md, modules/wristband/README.md, modules/postcard/README.md, modules/phrasebook/README.md, modules/towel/README.md - `go doc -all` for lagoon, lagoon/attach, compass, surf, wire, bouncer, wristband, postcard, phrasebook - modules/lagoon/postgres_test.go (TestMain, lagoonDB, dedicatedDB; ICU pl-PL database idiom) - modules/festival/example_test.go (plan 11.1-03; reuse its region for the events page) - .planning/phases/11-jobs-realtime-and-search-infrastructure/11-08-SUMMARY.md (AfterCommit behaviour in foreign transactions, nested Transaction rule) - .planning/todos/pending/wristband-neutral-resource-default.md (do not quote the default) </read_first> <action> Per D-08 (Database: models, migrations, relations, casts, validation; Services: config, events, i18n, mail, rate limiting, HTTP routing and auth groups): 1. `docs/site.yaml`: add `database` ("Database") before `services`. 2. Database pages (orders 10-70), each with at least one verified Go fence: - `models.md`: GORM structs with lagoon helpers, mass assignment with `lagoon.Fill` and its allow-list, hidden fields in serialization, lifecycle hooks, the models-leaf rule. - `migrations.md`: gormigrate migrations per plugin through `pact.HasMigrations`, `migrate`, `migrate:rollback --plugin`, `migrate:status`, ordering by file name, `make:migration`. - `queries-and-pagination.md`: `lagoon.OrderBy` with a caller allow-list, `lagoon.Paginate` and its response shape. - `relations.md`: GORM associations, join tables with `lagoon.RegisterJoinTable`, soft-delete cascades. - `casts-and-validation.md`: JSON columns, encrypted columns and the application key, `lagoon.Validate` with Laravel-style rule strings. - `attachments.md`: `attach` file attachments on models, blob keys, thumbnails, deletion after commit. - `transactions.md`: `lagoon.Transaction`, `lagoon.AfterCommit` (runs after commit; skipped with a warning inside a foreign plain `*sql.Tx`; a nested `lagoon.Transaction` over a root handle fails), `lagoon.OnDatabase` for boot-time work, and why side effects (broadcasts, search sync) wait for commit. Database-bound snippets follow the region-plus-`TestDocs*` rule with `modules/lagoon/export_docs_test.go` exposing the lagoon harness; pure helpers (Validate, OrderBy allow-list checks, Fill) are runnable Examples. 3. Services pages (orders 10-80): - `configuration.md`: `compass` layering, per-environment dirs, `SUMMER_` overrides, plugin defaults, dot-path access, `compass.Config.Persist`; runnable Example over a temp config dir. - `events.md`: `festival.Bus` listeners, priorities, stop-when-handled, collected results; reuse the festival region from plan 11.1-03 or add one. - `routing.md`: routes from `pact.HasRoutes`, groups and auth groups, constraints (`surf.Where`, `surf.WhereIn` style), named middleware, body limits, CORS, recovery, `route:list`, JSON responses with `wire`; runnable Examples with `httptest`. - `rate-limiting.md`: throttle buckets, named buckets from `surf.BucketProvider`, trusted proxies and client IP. - `authentication.md`: `bouncer` JWT minting and verification, guards, the blacklist, password hashing; runnable Example that mints and verifies with a test-only secret. - `oauth-server.md`: `wristband` metadata, dynamic client registration, authorization code with PKCE, consent, refresh rotation over application storage. Do not quote the default resource URL; tell the application to set it. Snippets only from `modules/wristband/example_test.go`. - `mail.md`: `postcard` templates and layouts in plugins, drivers memory/log/smtp, mandatory STARTTLS by default with plain SMTP as an explicit development-only opt-in; runnable Example with the memory driver. - `localization.md`: `phrasebook` catalogs, fallback order, `:name` interpolation, CLDR plurals, request locale in `towel`; runnable Example. 4. Append the 15 page URLs to `TestDocsRequiredPages`. 5. Run `go run ./cmd/summer docs:sync` and `go run ./cmd/summer docs:build --check`; fix every problem in the pages. </action> <verify> <automated>go vet ./... && go test ./modules/lagoon/... ./modules/compass ./modules/surf ./modules/wire ./modules/bouncer ./modules/wristband ./modules/postcard ./modules/phrasebook -run '^(Example|TestDocs)' -count=1 && go test ./cmd/summer -run '^(TestDocsTree|TestDocsRequiredPages|TestDocsAIOutputsInSync)$' -count=1</automated> <fails_when>non-zero exit, a "--- FAIL" line, or "no tests to run"</fails_when> </verify> <acceptance_criteria> - `ls docs/database/*.md | wc -l` prints 7 and `ls docs/services/*.md | wc -l` prints 9. - `grep -l '// Output:' modules/lagoon/example_test.go modules/compass/example_test.go modules/surf/example_test.go modules/wire/example_test.go modules/bouncer/example_test.go modules/wristband/example_test.go modules/postcard/example_test.go modules/phrasebook/example_test.go | wc -l` prints 8. - `grep -n 'lagoon.AfterCommit' docs/database/transactions.md` finds a match. - `grep -c 'src=modules/wristband/' docs/services/oauth-server.md` prints at least 1 and `! grep -n 'src=modules/wristband/server.go\|src=modules/wristband/stores.go\|src=modules/wristband/client_issue.go' docs/services/oauth-server.md` (no match). - `grep -n 'STARTTLS' docs/services/mail.md` finds a match. - `go run ./cmd/summer docs:build --check` exits 0 and `scripts/check-phase11.1.sh --forbidden` passes. </acceptance_criteria> <done>Database and the core Services pages are in the sidebar with running examples, the transaction page matches the 11-08 behaviour, and the real-tree checks and the forbidden-name gate pass.</done> </task> <task type="auto"> <name>Task 3: Backend section, the remaining Services pages, the Frontend and AJAX page, and concept-map links</name> <files>docs/site.yaml, docs/index.md, docs/setup/coming-from-wintercms.md, docs/backend/admin-controllers.md, docs/backend/forms.md, docs/backend/lists-and-filters.md, docs/backend/relation-manager.md, docs/backend/users-and-permissions.md, docs/backend/settings.md, docs/backend/partials-and-widgets.md, docs/backend/admin-spa.md, docs/services/storage.md, docs/services/outbound-http.md, docs/services/realtime.md, docs/services/push.md, docs/services/search.md, docs/services/parity-testing.md, docs/services/frontend-and-ajax.md, modules/cabana/example_test.go, modules/fetchguard/example_test.go, modules/lighthouse/example_test.go, modules/lighthouse/export_docs_test.go, modules/flare/example_test.go, modules/beachcomber/example_test.go, modules/beachcomber/export_docs_test.go, modules/tide/example_test.go, cmd/summer/docs_test.go</files> <read_first> - modules/cabana/README.md, modules/boardwalk/README.md, modules/pact/README.md (admin interfaces, SettingsItem, AdminAction, partial and asset interfaces) - modules/cabana/testdata/ (YAML fixtures that can be referenced by src= instead of hand-written YAML) - modules/lighthouse/README.md, modules/lighthouse/centrifugo (go doc), modules/flare/README.md, modules/beachcomber/README.md, modules/beachcomber/typesense (go doc), modules/fetchguard/README.md, modules/tide/README.md - modules/lighthouse/postgres_test.go and modules/beachcomber/postgres_test.go (harness helpers to export) - .planning/phases/11-jobs-realtime-and-search-infrastructure/11-03-SUMMARY.md, 11-04-SUMMARY.md, 11-05-SUMMARY.md, 11-06-SUMMARY.md - .planning/phases/10.1-runtime-admin-extension-point/ summaries (partials, widgets, assets, toolbar actions) - docs/setup/coming-from-wintercms.md </read_first> <action> Per D-08 (Backend: admin auth, forms, lists, relation manager, settings; Services: realtime, search, storage) and D-09: 1. `docs/site.yaml`: add `backend` ("Backend") after `plugins` and before `database`, so the final order is setup, architecture, plugins, backend, database, services, console, api. Make `TestDocsRequiredPages` also assert this exact section order. 2. Backend pages (orders 10-80): `admin-controllers.md` (`pact.AdminController`, config_form.yaml and config_list.yaml, the JSON admin API, hooks, toolbar actions, `make:admin-controller`), `forms.md` (fields.yaml, field types, options providers, spans, read-only and context fields), `lists-and-filters.md` (columns.yaml, sorting, pagination options, filter scopes), `relation-manager.md`, `users-and-permissions.md` (admin JWT and cookie auth, permissions, `admin:create`, `admin:reset-password`), `settings.md` (`pact.SettingsItem` settings pages), `partials-and-widgets.md` (server-rendered partials, client assets, widget and toolbar actions from Phase 10.1), `admin-spa.md` (`boardwalk`, the `backend.uri` prefix, OpenAPI-generated types). YAML examples use `yaml src=` references to real cabana test fixtures where one exists; Go snippets come from `modules/cabana/example_test.go` (schema compilation or controller declaration that runs without a database). 3. Services pages (orders 90-160): `storage.md` (upload buckets, bucket URLs, `attach` link), `outbound-http.md` (`fetchguard` private-address blocking, host, size and timeout limits), `realtime.md` (`lighthouse` drivers and `realtime.driver`, channel naming rules, the authorizer registry, `lighthouse.Mount` with surfaces, model broadcasts enqueued in the write transaction and published after commit, `lighthouse.WithoutBroadcasting` and `Emit`, the Centrifugo driver's token and subscribe routes, `websockets:health`), `push.md` (`flare` Web Push with VAPID, https-only allowlisted hosts, no redirects, `websockets:generate-vapid-keys`, `websockets:test-push`), `search.md` (`beachcomber` Searchable models, engines and `search.driver`, after-commit sync gated by a kill-switch, `SearchIDs` results as candidates that the application re-checks in SQL, the Typesense engine), `parity-testing.md` (`tide` record and replay, normalized diffs, broadcast goldens, the `parity:*` commands), `frontend-and-ajax.md` (title "Frontend and AJAX (not provided)": SummerCMS is headless; CMS pages, themes, layouts, components, the AJAX framework and Snowboard are not provided; build the frontend as a separate application against the JSON API and realtime channels; link routing, authentication and realtime). Realtime and search snippets are runnable Examples on the memory driver and null engine; database-bound broadcast or sync snippets use the region-plus-`TestDocs*` rule with `export_docs_test.go` in lighthouse and beachcomber. 4. `docs/setup/coming-from-wintercms.md`: link every row whose topic now has a guide page (models, migrations, backend controllers, forms and lists, routes, middleware, config, lang, events, mail, settings, broadcasting, search, HTTP client) and point the Not provided rows at `../services/frontend-and-ajax.md`. `docs/index.md`: add the Backend, Database and Services entry points. 5. Append the 15 page URLs to `TestDocsRequiredPages`. 6. Run `go run ./cmd/summer docs:sync` and `go run ./cmd/summer docs:build --check`; fix every problem in the pages. </action> <verify> <automated>go vet ./... && go test ./modules/cabana ./modules/fetchguard ./modules/lighthouse/... ./modules/flare ./modules/beachcomber/... ./modules/tide -run '^(Example|TestDocs)' -count=1 && go test ./cmd/summer -run '^(TestDocsTree|TestDocsRequiredPages|TestDocsAIOutputsInSync|TestDocsBuildRealTree)$' -count=1</automated> <fails_when>non-zero exit, a "--- FAIL" line, or "no tests to run"</fails_when> <automated>scripts/check-phase11.1.sh --docs && scripts/check-phase11.1.sh --forbidden && scripts/check-phase10.sh --hygiene && scripts/check-phase11.sh --hygiene</automated> <fails_when>non-zero exit or a line starting "refuse:"</fails_when> </verify> <acceptance_criteria> - `ls docs/backend/*.md | wc -l` prints 8 and `ls docs/services/*.md | wc -l` prints 16. - `grep -n 'Snowboard' docs/services/frontend-and-ajax.md` finds a match. - `grep -c 'frontend-and-ajax.md' docs/setup/coming-from-wintercms.md` prints at least 1. - `grep -n 'WithoutBroadcasting' docs/services/realtime.md` finds a match and `grep -n 'SearchIDs' docs/services/search.md` finds a match. - `go test ./cmd/summer -run '^TestDocsRequiredPages$' -count=1 -v` prints `--- PASS: TestDocsRequiredPages` with the section-order assertion. - `go run ./cmd/summer docs:build --check` exits 0. </acceptance_criteria> <done>All eight D-08 sections are in the sidebar in Winter order, the Phase 11 services are documented as shipped with running examples, the not-provided frontend is explicit, and the concept map links every guide.</done> </task> </tasks> <threat_model> ## Trust Boundaries | Boundary | Description | |----------|-------------| | docs pages → operators | Operators copy security-relevant configuration (mail TLS, push hosts, search re-gating, OAuth resource) from these pages | | module sources → published snippets | src= copies publish source text, including comments | ## STRIDE Threat Register | Threat ID | Category | Component | Severity | Disposition | Mitigation Plan | |-----------|----------|-----------|----------|-------------|-----------------| | T-11.1-13 | Information disclosure (policy) | docs/services/oauth-server.md snippets | medium | mitigate | Snippets only from modules/wristband/example_test.go (acceptance grep forbids src= into wristband server.go, stores.go, client_issue.go); forbidden-name check over outputs | | T-11.1-14 | Tampering (misconfiguration) | docs/services mail, push, search, realtime pages | medium | mitigate | Pages state the shipped secure defaults (STARTTLS, allowlisted https push hosts, SQL re-gate of SearchIDs, secret-checked subscribe proxy) and mark insecure options development-only; safety prohibition reviewed at verify | | T-11.1-15 | Denial of service (test isolation) | export_docs_test.go harness wrappers | low | mitigate | Wrappers reuse each module's dedicated-database harness; no shared or developer database is touched | | T-11.1-SC | Tampering | npm/pip/cargo/go installs | high | accept | This plan adds no module or package | </threat_model> <verification> - `go vet ./... && go test ./... -count=1` green with Docker (the TestDocs* database tests run, not skip). - `go run ./cmd/summer docs:build --check` exits 0; `scripts/check-phase11.1.sh --docs --forbidden` pass. </verification> <success_criteria> - SC1: all Winter-mirroring sections present with every framework module reachable from the sidebar. - SC4: every Go example in these pages is compiled and run by `go test ./...`. - SC5 (partial): the concept map links every guide page and the not-provided page. </success_criteria> ## Artifacts this phase produces - Pages: `docs/database/{models,migrations,queries-and-pagination,relations,casts-and-validation,attachments,transactions}.md`, `docs/backend/{admin-controllers,forms,lists-and-filters,relation-manager,users-and-permissions,settings,partials-and-widgets,admin-spa}.md`, `docs/services/{configuration,events,routing,rate-limiting,authentication,oauth-server,mail,localization,storage,outbound-http,jobs,realtime,push,search,parity-testing,frontend-and-ajax}.md`. - site.yaml sections: `backend`, `database`, `services` (final order setup, architecture, plugins, backend, database, services, console, api). - Examples and docs tests in `modules/{conga,lagoon,lagoon/attach,compass,surf,wire,bouncer,wristband,postcard,phrasebook,cabana,fetchguard,lighthouse,flare,beachcomber,tide}/example_test.go`; `TestDocs*` database-backed snippet tests; test-only harness exports `modules/{conga,lagoon,lighthouse,beachcomber}/export_docs_test.go`. - Updated `docs/setup/coming-from-wintercms.md`, `docs/index.md`, `TestDocsRequiredPages` with the section-order assertion. <output> Create `.planning/phases/11.1-summercms-documentation-for-humans-and-ai-agents/11.1-04-SUMMARY.md` when done </output>