Files
summercms/.planning/phases/10.2-nest-framework-packages-under-modules-and-write-run-docs/10.2-02-PLAN.md
2026-09-28 01:46:23 +02:00

226 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
phase: 10.2-nest-framework-packages-under-modules-and-write-run-docs
plan: "02"
type: execute
wave: 2
depends_on: ["10.2-01"]
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
- scripts/check-phase10.2.sh
autonomous: true
requirements: []
estimate:
tokens: 80000
raw_tokens: 40000
tasks: 3
confidence: low
must_haves:
truths:
- "D-07: Each modules/<name>/ has a short README.md of one paragraph stating what the package is, who imports it, and one example entry point (Package.Type or file). No architecture essays and no pasted planning-doc prose."
- "D-08: Root README.md states this repo is framework only (app is sibling fonoteka.go), explains the two-repo go.work replace during development, tells an operator how to recreate the Phase 10 admin login by pointing at fonoteka.go for DSN/migrate/serve, includes an honest not-yet cutover drawn from .planning/notes/go-vs-php-on-plytarium.md (Phase 15 PHP flip), and links modules/<name>/README.md instead of listing beach names at root."
- "The fail-closed 10.2 gate refuses leftover root beach directories, leftover root-form beach imports in tracked .go/.tmpl/.sh, a missing module README, and a root README that still claims nothing runs."
- "D-05 remains true after the docs work: go vet ./... and go test ./... stay green in both repos including fonoteka plugin modules."
artifacts:
- path: modules/backpack/README.md
provides: one-paragraph backpack onboarding
- path: modules/cabana/README.md
provides: one-paragraph cabana onboarding
- path: README.md
provides: framework onboarding, two-repo layout, admin-login recreate, honest cutover
- path: scripts/check-phase10.2.sh
provides: fail-closed layout/import/README/vet-test gate with --self-test
key_links:
- from: README.md
to: modules/*/README.md
via: root README points at per-module files instead of an inline beach-name list
pattern: modules/
- from: README.md
to: ../fonoteka.go/README.md
via: DSN, migrate, and serve live in the app repo
pattern: fonoteka.go
- from: scripts/check-phase10.2.sh
to: README.md
via: refuse if the stale pre-alpha Status sentence is still present
pattern: "--self-test"
prohibitions:
- "Do not invent a production deploy runbook; operator procedure stays in the PHP docs/deploy/plytarium.com.md until Phase 15 (D-08)."
- "Do not paste .planning/ notes, ROADMAP, or CONTEXT into module READMEs (D-07)."
- "Do not rewrite fonoteka.go/README.md in this plan (intended split: that file stays a short run card)."
- "Do not add Go or npm dependencies."
- "Do not remap beach names onto Winter system/backend/cms."
---
## Phase Goal
Write run docs for the nested modules and a fail-closed hygiene gate so a newcomer can onboard from the root README and the layout cannot silently regress.
<objective>
After 10.2-01 is green, write eighteen short module READMEs from the code (D-07), replace the root README (D-08), and ship scripts/check-phase10.2.sh plus both-repo vet/test as the last-plan unit/hygiene gate.
Purpose: The current root README still claims nothing runs. That is false after Phase 10. Module READMEs and an honest cutover section are the onboarding surface; the gate is Dimension 8 evidence (no VALIDATION.md this run).
Output: modules/&lt;name&gt;/README.md × 18, rewritten README.md, scripts/check-phase10.2.sh.
Repo: summercms.go only for the doc files; the gate also runs ../fonoteka.go tests. Commit docs separately from any leftover code fix; never add co-author tags.
</objective>
<execution_context>
@~/.claude/gsd-core/workflows/execute-plan.md
@~/.claude/gsd-core/templates/summary.md
</execution_context>
<context>
@CLAUDE.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/10.2-nest-framework-packages-under-modules-and-write-run-docs/10.2-01-SUMMARY.md
@.planning/todos/pending/per-module-readmes-after-nest.md
@.planning/todos/pending/rewrite-summercms-readme.md
@.planning/todos/pending/nest-framework-packages-under-modules.md
@.planning/notes/go-vs-php-on-plytarium.md
@README.md
@../fonoteka.go/README.md
@scripts/check-phase4.sh
@scripts/check-phase9.sh
<interfaces>
10.2-01 left packages at modules/&lt;name&gt;/ with import prefix git.golem15.com/golem15/summercms/modules/&lt;name&gt;. Root stay-put dirs are admin/, cmd/, examples/, internal/, scripts/. App binary, DSN, migrate and serve commands live in ../fonoteka.go (see that README: SUMMER_DATABASE__DSN, summer build, ./bin/fonoteka migrate, ./bin/fonoteka serve, pl-PL Postgres). Phase 10 admin URL for fonoteka is backend.uri /plytadmin. Cutover facts come only from .planning/notes/go-vs-php-on-plytarium.md.
</interfaces>
</context>
## Artifacts this phase produces
- `modules/<name>/README.md` for backpack, boardwalk, bonfire, bouncer, cabana, compass, festival, fetchguard, lagoon, pact, party, phrasebook, postcard, surf, tide, towel, wire, wristband
- Rewritten root `README.md` (framework-only, two-repo replace, admin-login recreate, Phase 15 not-yet cutover, links to module READMEs)
- `scripts/check-phase10.2.sh` with `--self-test` and `--all`
- Gate checks (not new Go test names): leftover root beach dir; leftover root-form beach import; missing module README; stale root Status sentence; `go vet`/`go test` both repos
<tasks>
<task type="auto">
<name>Task 1: Write one short README.md per modules/&lt;name&gt; from the code</name>
<files>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</files>
<read_first>.planning/todos/pending/per-module-readmes-after-nest.md; .planning/todos/pending/nest-framework-packages-under-modules.md; modules/backpack/app.go; modules/boardwalk/boardwalk.go; modules/bonfire/; modules/bouncer/; modules/cabana/; modules/compass/config.go; modules/festival/bus.go; modules/fetchguard/; modules/lagoon/; modules/pact/; modules/party/; modules/phrasebook/; modules/postcard/; modules/surf/; modules/tide/; modules/towel/; modules/wire/response.go; modules/wristband/; README.md</read_first>
<action>Per D-07, after the nest is green, do an explore-quality pass over the code in each modules/&lt;name&gt;/ (exported types and the primary .go file, plus a quick git grep of who imports git.golem15.com/golem15/summercms/modules/&lt;name&gt;). Write modules/&lt;name&gt;/README.md for all 18 names listed in files.
Each file is one paragraph: what the package is for, who imports it (framework peers and/or ../fonoteka.go plugins), and one example entry point such as festival.Bus, compass.Config, cabana.Activate, boardwalk.Handler, surf.BuildRouter, or the owning .go file. No architecture essays. Do not copy .planning/ notes, ROADMAP, or phase plans into these files. Do not invent APIs that are not in the tree. Do not add a per-package go.mod.</action>
<verify>
<automated>test -f modules/festival/README.md &amp;&amp; test -f modules/cabana/README.md &amp;&amp; test -f modules/compass/README.md &amp;&amp; wc -l modules/*/README.md | awk 'BEGIN{bad=0} $2!="total" &amp;&amp; ($1&lt;2 || $1&gt;40){bad=1; print} END{exit bad}'</automated>
<fails_when>non-zero exit; any of the 18 modules/*/README.md missing; a README is under 2 lines or over 40 lines (essay or stub)</fails_when>
</verify>
<acceptance_criteria>
- `for n in backpack boardwalk bonfire bouncer cabana compass festival fetchguard lagoon pact party phrasebook postcard surf tide towel wire wristband; do test -f modules/$n/README.md || exit 1; done` exits 0.
- Each README names at least one exported identifier or file (grep for a `.` type or a `.go` filename).
- `grep -l 'D-0' modules/*/README.md` prints nothing (no planning-decision paste).
</acceptance_criteria>
<done>Eighteen short module READMEs exist, each derived from the code, each naming an entry point.</done>
</task>
<task type="auto">
<name>Task 2: Replace root README.md with framework onboarding, login recreate, and honest cutover</name>
<files>README.md</files>
<read_first>.planning/todos/pending/rewrite-summercms-readme.md; .planning/notes/go-vs-php-on-plytarium.md; README.md; ../fonoteka.go/README.md; .planning/todos/pending/per-module-readmes-after-nest.md; CLAUDE.md</read_first>
<action>Per D-08, replace README.md. Required sections, in this order:
1. What this repo is: SummerCMS Go framework only. The application is the sibling ../fonoteka.go (or fonoteka.go next to this repo). This tree is not the app binary.
2. Two-repo layout: development uses a go.work / replace of git.golem15.com/golem15/summercms onto this checkout (cite ../fonoteka.go/go.mod and examples/hello/go.mod). Single go.mod here (D-03). Framework libraries live under modules/.
3. Recreate the Phase 10 admin login that already worked: point at fonoteka.go for DSN (SUMMER_DATABASE__DSN), pl-PL Postgres, `summer build`, `./bin/fonoteka migrate`, `./bin/fonoteka serve`. Admin SPA is embed.FS in that binary; fonoteka backend.uri is /plytadmin. Do not list a summer serve of this repo as the way to open admin. Do not invent extra flags.
4. Honest cutover: drawn only from .planning/notes/go-vs-php-on-plytarium.md. Working local admin login is not a DNS flip of plytarium.com. Flip is Phase 15 after jobs/search (11) and remaining API routes (12-14). Until then, pointing production at this binary would take the public Nuxt app and MCP offline. Operator procedure stays in the PHP docs/deploy/plytarium.com.md. Do not write a production runbook.
5. Modules: point at modules/&lt;name&gt;/README.md instead of listing beach names as root directories. A short link list to the 18 README files is enough.
Keep a short Why Go / v1-target pointer if useful (existing .planning/notes/why-go-not-scala.md and v1-target-plytarium.md). Remove the current Status sentence that claims nothing runs. Do not paste planning docs. Do not add secrets or a sample production DSN.</action>
<verify>
<automated>test -f README.md &amp;&amp; grep -q 'fonoteka.go' README.md &amp;&amp; grep -q 'modules/' README.md &amp;&amp; grep -q 'plytadmin' README.md &amp;&amp; grep -q 'Phase 15' README.md &amp;&amp; grep -q 'docs/deploy/plytarium.com.md' README.md</automated>
<fails_when>non-zero exit; any required grep prints no matching line</fails_when>
</verify>
<acceptance_criteria>
- README.md contains the strings `fonoteka.go`, `modules/`, `SUMMER_DATABASE__DSN` or a clear pointer to the fonoteka.go Database setup section, `plytadmin`, `Phase 15`, and `docs/deploy/plytarium.com.md`.
- README.md does not contain the current Status sentence from the rewrite-summercms-readme todo (the one that says planning-and-research and that nothing runs).
- README.md does not contain a step-by-step nginx/systemd production deploy procedure.
- README.md links at least one `modules/&lt;name&gt;/README.md` path.
</acceptance_criteria>
<done>Root README onboards a developer to the two-repo layout, the already-working admin login via fonoteka.go, and an honest Phase 15 cutover, and it points at module READMEs.</done>
</task>
<task type="auto">
<name>Task 3: Unit and hygiene gate — scripts/check-phase10.2.sh plus both-repo go test</name>
<files>scripts/check-phase10.2.sh</files>
<read_first>scripts/check-phase4.sh; scripts/check-phase9.sh; scripts/check-phase10.sh; README.md; .planning/todos/pending/nest-framework-packages-under-modules.md; .planning/todos/pending/per-module-readmes-after-nest.md; .planning/todos/pending/rewrite-summercms-readme.md</read_first>
<action>Add scripts/check-phase10.2.sh (bash, set -euo pipefail, executable bit). Model the detector style on scripts/check-phase9.sh / scripts/check-phase4.sh, not the Phase 10 SPA stages. Modes: --self-test and --all (and optional single-stage flags if that keeps the script readable).
--all must fail closed when any of these is true:
1. Any of the 18 beach names is a directory at the summercms.go repo root.
2. Any tracked `*.go`, `*.tmpl`, or `*.sh` in this repo or ../fonoteka.go still contains a root-form beach import (`git.golem15.com/golem15/summercms/` + name, with no `/modules/` segment). Build the needle from a NAMES array plus the module prefix so the script file is not itself a hit; skip this script and skip `.planning/`. Do not scan historical PLAN.md files.
3. Any modules/&lt;name&gt;/ for those 18 names lacks README.md.
4. Root README.md still contains the stale Status sentence named in the rewrite-summercms-readme todo.
5. `go vet ./...` or `go test ./...` fails in summercms.go, or `go vet ./... ./plugins/golem15/fonoteka/... ./plugins/golem15/user/...` or the matching `go test` fails in ../fonoteka.go.
--self-test: bash -n; in a scratch copy, plant each of (1)-(4) one at a time and refuse unless the script exits non-zero and the stderr names that rule (leftover root dir, old import, missing README, stale Status). Do not run the full both-repo go test inside --self-test.
Reuse the same go vet / go test commands that already worked in 10.2-01 Task 3. Do not invoke check-phase10.sh SPA, OpenAPI, or dist stages. No new dependencies.</action>
<verify>
<automated>bash -n scripts/check-phase10.2.sh &amp;&amp; scripts/check-phase10.2.sh --self-test &amp;&amp; scripts/check-phase10.2.sh --all</automated>
<fails_when>non-zero exit; --self-test output lacks a passed line or contains "refuse:" for the clean tree; --all prints "refuse:" or a package FAIL</fails_when>
</verify>
<acceptance_criteria>
- `test -x scripts/check-phase10.2.sh` succeeds.
- `--self-test` exits 0 on the committed tree and has planted-failure coverage for leftover root dir, old import, missing module README, and stale root Status.
- `--all` exits 0 on the committed tree.
- A one-off `mkdir backpack` at repo root followed by the layout stage (or --all) exits non-zero; remove the dir after.
</acceptance_criteria>
<done>The 10.2 gate fails closed on layout, import, README, and stale-status regressions, and both repos stay vet/test green.</done>
</task>
</tasks>
<threat_model>
## Trust Boundaries
| Boundary | Description |
|----------|-------------|
| Operator → root README | Onboarding text can send someone at production or leak a procedure that is not ours yet |
| Hygiene script → working tree | A gate that greps missing old paths, or that matches its own needle, goes green or red for the wrong reason |
| Module README → public git | Pasted planning notes would publish deferred/internal decisions |
## STRIDE Threat Register
| Threat ID | Category | Component | Severity | Disposition | Mitigation Plan |
|-----------|----------|-----------|----------|-------------|-----------------|
| T-10.2-06 | Information Disclosure | README.md cutover / login sections | high | mitigate | Point at fonoteka.go for DSN/migrate/serve; no production runbook; cite PHP docs/deploy/plytarium.com.md; no sample secrets (D-08) |
| T-10.2-07 | Tampering | scripts/check-phase10.2.sh | high | mitigate | Fail closed on leftover root beach dirs, root-form imports, missing module READMEs, and the stale Status sentence; --self-test plants each rule |
| T-10.2-08 | Information Disclosure | modules/*/README.md | low | accept | Explore-quality one-paragraph files; D-07 forbids planning-doc paste; residual risk is a bland public description of exported types |
| T-10.2-09 | Repudiation | --self-test skipped | medium | mitigate | --all is not a substitute for --self-test; Task 3 verify runs both; a self-test that accepts a plant must refuse |
| T-10.2-SC | Tampering | npm/pip/cargo installs | high | mitigate | Docs and a bash gate only; no package-manager installs |
</threat_model>
<verification>
`scripts/check-phase10.2.sh --self-test` then `--all`. --all includes both-repo `go vet`/`go test`. A leftover beach directory at repo root, a root-form beach import, a missing module README, or the stale root Status sentence must exit non-zero.
</verification>
<success_criteria>
- Eighteen module READMEs and a rewritten root README satisfy D-07 and D-08.
- scripts/check-phase10.2.sh fails closed on the four hygiene/docs signals and keeps both repos green.
</success_criteria>
<output>
Create `.planning/phases/10.2-nest-framework-packages-under-modules-and-write-run-docs/10.2-02-SUMMARY.md` when done.
</output>