From 9fe2f5e795720a5747aa5fa537dedf2fe449cb21 Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Mon, 28 Sep 2026 15:55:53 +0200 Subject: [PATCH] docs(quick-260928-lf2): rewrite module READMEs and root README --- .planning/STATE.md | 3 +- .../260928-lf2-PLAN.md | 269 ++++++++++++++++++ .../260928-lf2-SUMMARY.md | 128 +++++++++ 3 files changed, 399 insertions(+), 1 deletion(-) create mode 100644 .planning/quick/260928-lf2-rewrite-module-readmes-and-root-readme-a/260928-lf2-PLAN.md create mode 100644 .planning/quick/260928-lf2-rewrite-module-readmes-and-root-readme-a/260928-lf2-SUMMARY.md diff --git a/.planning/STATE.md b/.planning/STATE.md index bb36c8a..a900749 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -32,7 +32,7 @@ See: .planning/PROJECT.md (updated 2026-09-16) Phase: 9 — Backend admin authentication and schema pipeline Plan: Not started Status: Ready to plan -Last activity: 2026-09-28 — Phase 10.2 complete, transitioned to Phase 9 +Last activity: 2026-09-28 - Completed quick task 260928-lf2: Rewrite module READMEs and root README as professional app-agnostic docs Progress: [██████░░░░] 60% @@ -363,6 +363,7 @@ None yet. |---|-------------|------|--------|-----------| | 260927-q23 | fix CR-01: /auth/refresh must enforce tokens_valid_after and is_activated | 2026-09-27 | be4a923 | [260927-q23-fix-cr-01-auth-refresh-must-enforce-toke](./quick/260927-q23-fix-cr-01-auth-refresh-must-enforce-toke/) | | 2 | make admin SPA edit/create and settings forms full width | 2026-09-27 | 2585671 | — | +| 260928-lf2 | Rewrite module READMEs and root README as professional app-agnostic docs | 2026-09-28 | fafb12f | [260928-lf2-rewrite-module-readmes-and-root-readme-a](./quick/260928-lf2-rewrite-module-readmes-and-root-readme-a/) | ## Deferred Items diff --git a/.planning/quick/260928-lf2-rewrite-module-readmes-and-root-readme-a/260928-lf2-PLAN.md b/.planning/quick/260928-lf2-rewrite-module-readmes-and-root-readme-a/260928-lf2-PLAN.md new file mode 100644 index 0000000..a834e05 --- /dev/null +++ b/.planning/quick/260928-lf2-rewrite-module-readmes-and-root-readme-a/260928-lf2-PLAN.md @@ -0,0 +1,269 @@ +--- +phase: quick-260928-lf2 +plan: 01 +type: execute +wave: 1 +depends_on: [] +files_modified: + - modules/backpack/README.md + - modules/boardwalk/README.md + - modules/bonfire/README.md + - modules/bouncer/README.md + - modules/cabana/README.md + - modules/compass/README.md + - modules/festival/README.md + - modules/fetchguard/README.md + - modules/lagoon/README.md + - modules/pact/README.md + - modules/party/README.md + - modules/phrasebook/README.md + - modules/postcard/README.md + - modules/surf/README.md + - modules/tide/README.md + - modules/towel/README.md + - modules/wire/README.md + - modules/wristband/README.md + - README.md + - CLAUDE.md +autonomous: true +requirements: [QUICK-260928-lf2] + +estimate: + tokens: 260000 + raw_tokens: 260000 + tasks: 3 + confidence: low + +must_haves: + truths: + - "Each of the 18 module READMEs follows the approved template: H1 name, one-sentence summary, the import line, then Overview, Features, Usage, API reference, optional Configuration and CLI commands, Dependencies, Testing, in that order" + - "No module README and not the root README names a consuming application; examples use neutral names such as blog and acme" + - "Every package-qualified identifier (for example surf.BuildRouter) and every bare mixed-case backticked identifier in a module README resolves through go doc against that module" + - "Every relative Markdown link in README.md and modules/*/README.md points at a path that exists" + - "The root README reads as a framework README: what SummerCMS is, key concepts, requirements, a quick start on examples/hello, the repository layout, an 18-row modules table, the module path plus local replace pattern, development commands, and links to .planning/notes" + - "CLAUDE.md has a Documentation section, outside every GSD-managed marker block, that requires module README updates in the same change as any modules/ API, config, CLI or dependency change" + - "No Go file changes; go vet ./... and go test ./... stay green" + artifacts: + - path: "modules//README.md (x18)" + provides: "Professional, app-agnostic per-module documentation built from the real exported API" + contains: "## API reference" + - path: "README.md" + provides: "Generic SummerCMS (Go) framework README with modules table" + contains: "](modules/wristband/README.md)" + - path: "CLAUDE.md" + provides: "Documentation rule keeping module READMEs current" + contains: "## Documentation" + key_links: + - from: "README.md modules table" + to: "modules//README.md" + via: "one relative link per module, purpose text matching the module README summary sentence" + pattern: "\\]\\(modules/[a-z]+/README\\.md\\)" + - from: "modules//README.md identifiers" + to: "exported API of git.golem15.com/golem15/summercms/modules/" + via: "go doc resolution check" + pattern: "go doc ./modules/" + - from: "CLAUDE.md Documentation section" + to: "modules/*/README.md and the root README modules table" + via: "same-change update rule" + pattern: "## Documentation" +--- + + + + + + + + + +Rewrite the 18 three-line module READMEs under `modules/` into professional, app-agnostic docs that describe what each package exports today, turn the root `README.md` from an application runbook into a generic SummerCMS (Go) framework README, and add a CLAUDE.md rule that keeps module READMEs current. + +This implements the user-approved design at `/home/jin/.claude/plans/in-phase-10-2-we-enchanted-candy.md` faithfully (template, rules, root README outline, CLAUDE.md rule, commit split, verification). That design is locked: do not add, drop or reorder template sections, and do not skip any verification check. + +Purpose: framework consumers (and agents) get accurate per-module docs; the framework repo stops describing one consuming application, matching the two-repository boundary. +Output: 18 rewritten module READMEs, a rewritten root README, a new CLAUDE.md Documentation section, three docs commits. No Go code changes. + + + +@~/.claude/gsd-core/workflows/execute-plan.md +@~/.claude/gsd-core/templates/summary.md + + + +@/home/jin/.claude/plans/in-phase-10-2-we-enchanted-candy.md +@/media/nvme/dev/golem15/summercms.io/summercms/summercms.go/CLAUDE.md +@/media/nvme/dev/golem15/summercms.io/summercms/summercms.go/README.md +@/media/nvme/dev/golem15/summercms.io/summercms/summercms.go/scripts/check-phase10.2.sh +@/media/nvme/dev/golem15/summercms.io/summercms/summercms.go/examples/hello/go.mod +@/media/nvme/dev/golem15/summercms.io/summercms/summercms.go/examples/hello/summer.yaml +@/media/nvme/dev/golem15/summercms.io/summercms/summercms.go/admin/package.json + +Repo root (all commands run from here): `/media/nvme/dev/golem15/summercms.io/summercms/summercms.go`. Module path: `git.golem15.com/golem15/summercms`. The Bash tool runs bash even though the login shell is fish. + +## Module README template (locked, from the approved design) + +``` +# + + + +`import "git.golem15.com/golem15/summercms/modules/"` + +## Overview +2–4 sentences: the responsibility, where it sits in the framework, and its WinterCMS counterpart if one exists. + +## Features +Bullets built from the real exported API. + +## Usage +A short, correct Go snippet using real exported identifiers, checked against the source. + +## API reference +A table of the main exported types and functions with one-line descriptions. It stays selective: no dump of every symbol. + +## Configuration (only if the module reads compass keys / env vars) +## CLI commands (only if it registers cobra commands, e.g. lagoon, cabana, surf route:list) +## Dependencies +Other summercms modules and third-party libraries it imports, taken from its import list. + +## Testing +How to run its tests (`go test ./modules//...`), plus any build tag or testcontainers requirement (lagoon postgres tests, postcard mailpit). +``` + +The parenthetical notes after "Configuration" and "CLI commands" are template guidance, not heading text: the headings are exactly `## Configuration` and `## CLI commands`. + +## Rules (locked) + +- Never name a consuming application (the names in the forbidden-name grep below). Say "the application" or "host application", and use neutral example names (`blog`, `acme`). +- Every identifier in a README must exist in the package. Verify with `go doc ./modules/` and `grep`. +- Leave out any optional section that does not apply rather than padding it. + +## Facts gathered at plan time (verify, do not trust blindly) + +- Go packages: the 18 modules plus one subpackage, `modules/lagoon/attach` (import `git.golem15.com/golem15/summercms/modules/lagoon/attach`). `phrasebook/lang`, `phrasebook/backend/lang`, `boardwalk/dist` and `postcard/assets` are embedded asset trees, not packages. +- No module uses `//go:build` tags. +- `testdata/` exists in `cabana` and `tide`. +- testcontainers-go is used by tests in `bouncer`, `cabana`, `lagoon` (including `lagoon/attach`) and `postcard` (Mailpit). Those tests need Docker and skip under `go test -short`. +- Non-test files that register CLI commands: `modules/cabana/commands.go`, `modules/lagoon/commands.go`, `modules/lagoon/keygen.go`, `modules/surf/serve.go`, `modules/surf/routelist_command.go`. `modules/pact/capabilities.go` declares the command capability contract only. +- Likely Configuration candidates (confirm by grepping non-test sources for config key reads and `os.Getenv`): cabana (admin.* / backend.*), compass (the loader itself and the `SUMMER_` env overlay), fetchguard (http.fetch.*), lagoon (database.dsn, app.key, app.previous_keys), phrasebook (app.locale, app.fallback_locale), postcard (mail.*), surf. +- `summer` CLI commands (cmd/summer): build, dev, plugin:add, make:plugin, make:model, make:migration, make:command, make:job, make:admin-controller, parity:proxy, parity:record, parity:replay. Built app binaries get migrate, migrate:rollback, migrate:status, key:generate, serve, route:list, admin:create, admin:reset-password from the modules. +- `examples/hello` builds binary `hello` into `examples/hello/bin/` (gitignored); its config has no database section. `examples/hello/go.mod` shows the local `replace git.golem15.com/golem15/summercms => ../..` pattern. +- `admin/package.json` scripts: dev, build, typecheck, test, gen:api. +- `.planning/notes/` holds six notes; two have the forbidden application token in their filename, so the root README must link the notes directory and the four app-neutral notes (why-go-not-scala.md, apparatus-dissolved-into-framework.md, plugin-layout-winter-directories.md, oauth2-wristband-direct-port.md) only. +- `scripts/check-phase10.2.sh --readmes` requires all 18 module READMEs to exist; `--status` refuses the old pre-alpha status line in README.md. + +## Module batches (source size balanced; for Task 1 fan-out) + +- Batch A: cabana, backpack, towel, wire, festival, party +- Batch B: tide, lagoon (with lagoon/attach), bonfire, boardwalk, compass, pact +- Batch C: wristband, surf, bouncer, phrasebook, postcard, fetchguard + + + + + + Task 1: Rewrite the 18 module READMEs from the real exported API + modules/backpack/README.md, modules/boardwalk/README.md, modules/bonfire/README.md, modules/bouncer/README.md, modules/cabana/README.md, modules/compass/README.md, modules/festival/README.md, modules/fetchguard/README.md, modules/lagoon/README.md, modules/pact/README.md, modules/party/README.md, modules/phrasebook/README.md, modules/postcard/README.md, modules/surf/README.md, modules/tide/README.md, modules/towel/README.md, modules/wire/README.md, modules/wristband/README.md + /home/jin/.claude/plans/in-phase-10-2-we-enchanted-candy.md (template, rules, verification), the "Module README template", "Rules" and "Facts gathered at plan time" sections of this plan's context block. + +Per module, research before writing, in this order: (a) run `go doc -all ./modules/` (and `go doc -all ./modules/lagoon/attach` for lagoon) and read the full output; (b) read the module's non-test `.go` sources (list them with `find modules/ -maxdepth 1 -name '*.go' ! -name '*_test.go'`); for the four largest packages (cabana, tide, lagoon, wristband) read the entry-point files go doc points at and grep the remaining files for config key reads, `os.Getenv`, command registrations and exported constructors instead of reading every file end to end; (c) collect the import list with `go list -f '{{join .Imports "\n"}}' ./modules/` (plus `./modules/lagoon/attach`) and split it into summercms modules, third-party libraries and stdlib; (d) check for `testdata/`, `//go:build` tags, testcontainers or Mailpit usage and `testing.Short()` gates in the `_test.go` files. + +Then write `modules//README.md` following the template exactly: H1 is the bare module name; one summary sentence; the backticked import line; `## Overview` (2–4 sentences, including the WinterCMS counterpart when one exists, e.g. compass vs Winter config, lagoon vs Winter models/migrations, cabana vs Winter backend controllers/behaviors, bonfire vs artisan console, party vs Winter PluginBase/PluginManager); `## Features` bullets from the exported API; `## Usage` with one short Go snippet using real exported identifiers whose argument lists match the go doc signatures; `## API reference` as a selective Markdown table (identifier, one-line description); `## Configuration` only when the module reads config keys or env vars (list each key, its default and what it controls, all confirmed in source); `## CLI commands` only for modules that register commands (cabana, lagoon, surf: list each command name and its flags from the source); `## Dependencies` from the import list (write "Standard library only." if there are none beyond stdlib); `## Testing` with `go test ./modules//...`, and for bouncer, cabana, lagoon and postcard state that the integration tests start containers through testcontainers-go, need Docker, and are skipped by `go test -short ./modules//...`. Document `lagoon/attach` inside the lagoon README (its own import line and table rows in API reference), not as a separate README. + +Writing conventions that make the automated checks meaningful: outside code blocks, write Go identifiers package-qualified (`surf.BuildRouter`, `backpack.App`, `bonfire.Flag.Repeatable`, `attach.Publish`) so the resolver can check them; only backtick a capitalised word when it is a Go identifier of that module (put HTTP methods, header values and prose words in plain text); link other modules with relative paths such as `../surf/README.md`. Per the locked rules: no consuming-application names anywhere, neutral example names (`blog`, `acme`) in snippets and config examples, no secret-looking example values (use placeholders like `change-me` or ``), and no padding of sections that do not apply. + +Pilot then fan out: write `modules/wire/README.md` first and run all four verify checks below against it; adjust the approach until it passes. Then, when a subagent spawner is available, run the three batches from the context block in parallel with 3 general-purpose agents (6 modules each); give each agent this task's research steps, the template, the rules, the writing conventions and the finished wire README as the reference example, and tell them to write files only (no git). When no spawner is available, process the batches sequentially yourself. Afterwards review all 18 for consistency: same heading set and order, same table column headers (Identifier | Description), same Testing phrasing for the Docker-backed modules, summary sentences that each fit on one line. + +Commit only the 18 README paths, staged by explicit path (the working tree holds unrelated planning changes, so never stage everything): one commit with subject `docs(modules): rewrite module READMEs`, or one commit per batch with that same subject, as the approved design allows. No co-author trailer in any commit message (project and user rule). + + + cd /media/nvme/dev/golem15/summercms.io/summercms/summercms.go && ! grep -riE 'fonoteka|płytarium|plytarium|plytadmin' modules/*/README.md && echo NAMES OK + cd /media/nvme/dev/golem15/summercms.io/summercms/summercms.go && fail=0; for d in modules/*/; do n=$(basename "$d"); r="$d/README.md"; head -1 "$r" | grep -qx "# $n" || { echo "TITLE $n"; fail=1; }; grep -qF "\`import \"git.golem15.com/golem15/summercms/modules/$n\"\`" "$r" || { echo "IMPORT $n"; fail=1; }; grep -E '^## ' "$r" | sed 's/^## //' | paste -sd';' | grep -qxE 'Overview;Features;Usage;API reference(;Configuration)?(;CLI commands)?;Dependencies;Testing' || { echo "SECTIONS $n"; fail=1; }; grep -qF "go test ./modules/$n/..." "$r" || { echo "TESTCMD $n"; fail=1; }; done; for n in cabana lagoon surf; do grep -qx '## CLI commands' "modules/$n/README.md" || { echo "CLI $n"; fail=1; }; done; for n in bouncer cabana lagoon postcard; do grep -qF -- '-short' "modules/$n/README.md" || { echo "SHORT $n"; fail=1; }; done; [ $fail = 0 ] && echo STRUCTURE OK; exit $fail + cd /media/nvme/dev/golem15/summercms.io/summercms/summercms.go && fail=0; mods="$(ls modules | paste -sd'|')|attach"; for r in modules/*/README.md; do n=$(basename "$(dirname "$r")"); for t in $(grep -oE "\b($mods)\.[A-Z][A-Za-z0-9_]*(\.[A-Z][A-Za-z0-9_]*)?" "$r" | sort -u); do p=${t%%.*}; s=${t#*.}; d=./modules/$p; [ "$p" = attach ] && d=./modules/lagoon/attach; go doc "$d" "$s" >/dev/null 2>&1 || { echo "UNRESOLVED $r: $t"; fail=1; }; done; for t in $(grep -oE '`[A-Z][a-z][A-Za-z0-9]*(\.[A-Z][A-Za-z0-9]*)?`' "$r" | tr -d '`' | sort -u); do go doc "./modules/$n" "$t" >/dev/null 2>&1 || { echo "UNRESOLVED $r: bare $t"; fail=1; }; done; done; [ $fail = 0 ] && echo IDENTS OK; exit $fail + cd /media/nvme/dev/golem15/summercms.io/summercms/summercms.go && fail=0; for r in modules/*/README.md; do d=$(dirname "$r"); for l in $(grep -oE '\]\([^)#[:space:]]+' "$r" | sed 's/^](//' | grep -vE '^(https?|mailto):'); do [ -e "$d/$l" ] || { echo "BROKEN $r -> $l"; fail=1; }; done; done; [ $fail = 0 ] && echo LINKS OK; exit $fail + cd /media/nvme/dev/golem15/summercms.io/summercms/summercms.go && bash scripts/check-phase10.2.sh --readmes && echo READMES EXIST + + All 18 module READMEs follow the locked template and section order, name no consuming application, resolve every checked identifier through go doc, have no broken relative links, document CLI commands for cabana/lagoon/surf and the Docker/-short behaviour for bouncer/cabana/lagoon/postcard, and are committed as `docs(modules): rewrite module READMEs` (one commit or one per batch) with no co-author trailer. + + + + Task 2: Rewrite the root README as a generic SummerCMS (Go) framework README + README.md + README.md (current), the 18 new modules/*/README.md summary sentences, cmd/summer/main.go and cmd/summer/runtime.go (command names), internal/build/build.go (what summer build generates and where the binary goes), examples/hello/summer.yaml, examples/hello/config/app.yaml, examples/hello/go.mod, admin/package.json, the file list of .planning/notes/. + +Replace `README.md` entirely, following the approved outline in this order: (1) what SummerCMS is: a Go content management framework inspired by WinterCMS, built as a single compiled binary; (2) key concepts: compiled plugins registered at build time, YAML-driven admin forms and lists, a headless API, the scaffolding CLI; (3) requirements: Go 1.27, PostgreSQL, Node.js only for working on the admin SPA, Docker for the testcontainers-backed integration tests; (4) quick start using `examples/hello` and the `summer` CLI (install with `go install ./cmd/summer`, then `summer build` inside `examples/hello`, then run the built binary with `serve` and `migrate`, pointing it at Postgres through the `SUMMER_`-prefixed database DSN env var that compass and lagoon actually read); (5) repository layout covering `admin/`, `cmd/`, `examples/`, `internal/`, `modules/`, `scripts/` with one line each; (6) a modules table with columns Module | Purpose, one row per module (all 18, alphabetical), the Module cell linking `modules//README.md` and the Purpose cell reusing that README's summary sentence; (7) using SummerCMS in an application: require the module path `git.golem15.com/golem15/summercms` and use a local `replace git.golem15.com/golem15/summercms => ../summercms.go` directive during development, shown with a neutral example module such as `acme`, and point at `examples/hello/go.mod` as the working reference; (8) development: `go vet ./...`, `go test ./...`, `go test -short ./...` for the fast loop without Docker, and the admin SPA npm scripts from admin/package.json run with `npm --prefix admin run