Files
summercms/.planning/phases/10.2-nest-framework-packages-under-modules-and-write-run-docs/10.2-VERIFICATION.md

467 lines
28 KiB
Markdown

---
phase: 10.2-nest-framework-packages-under-modules-and-write-run-docs
verified: 2026-10-01T21:26:36Z
status: human_needed
score: 5/7 must-haves verified
covered_files:
- ".planning/phases/10.2-nest-framework-packages-under-modules-and-write-run-docs/10.2-01-PLAN.md"
- ".planning/phases/10.2-nest-framework-packages-under-modules-and-write-run-docs/10.2-01-SUMMARY.md"
- ".planning/phases/10.2-nest-framework-packages-under-modules-and-write-run-docs/10.2-02-PLAN.md"
- ".planning/phases/10.2-nest-framework-packages-under-modules-and-write-run-docs/10.2-02-SUMMARY.md"
- "README.md"
- "admin/vite.config.ts"
- "cmd/summer/main.go"
- "cmd/summer/main_test.go"
- "cmd/summer/parity.go"
- "cmd/summer/parity_contract_test.go"
- "cmd/summer/parity_test.go"
- "cmd/summer/runtime.go"
- "examples/hello/hello_test.go"
- "examples/hello/main.go"
- "examples/hello/plugins/base/plugin.go"
- "examples/hello/plugins/greeter/plugin.go"
- "examples/hello/plugins/greeter/plugin_test.go"
- "examples/hello/plugins/optional/plugin.go"
- "internal/build/build.go"
- "internal/build/build_test.go"
- "internal/build/stubs/artifacts.tmpl"
- "internal/build/stubs/plugin.tmpl"
- "internal/build/stubs/registry.tmpl"
- "modules/backpack/README.md"
- "modules/backpack/app.go"
- "modules/backpack/app_test.go"
- "modules/backpack/services.go"
- "modules/backpack/services_test.go"
- "modules/boardwalk/README.md"
- "modules/boardwalk/boardwalk.go"
- "modules/boardwalk/boardwalk_test.go"
- "modules/boardwalk/dist/assets/dm-mono-latin-400-normal--0xN8mdc.woff"
- "modules/boardwalk/dist/assets/dm-mono-latin-400-normal-4GdczIuU.woff2"
- "modules/boardwalk/dist/assets/dm-mono-latin-500-normal-CN8Miw6E.woff"
- "modules/boardwalk/dist/assets/dm-mono-latin-500-normal-DRMDZjhP.woff2"
- "modules/boardwalk/dist/assets/dm-mono-latin-ext-400-normal-1aZr6b2b.woff"
- "modules/boardwalk/dist/assets/dm-mono-latin-ext-400-normal-C2zvOubV.woff2"
- "modules/boardwalk/dist/assets/dm-mono-latin-ext-500-normal-BtRyHRi6.woff2"
- "modules/boardwalk/dist/assets/dm-mono-latin-ext-500-normal-Dw3M13d8.woff"
- "modules/boardwalk/dist/assets/dm-sans-latin-400-normal-BwCSEQnW.woff"
- "modules/boardwalk/dist/assets/dm-sans-latin-400-normal-CW0RaeGs.woff2"
- "modules/boardwalk/dist/assets/dm-sans-latin-500-normal-B9HHJjqV.woff2"
- "modules/boardwalk/dist/assets/dm-sans-latin-500-normal-Dr3UlScf.woff"
- "modules/boardwalk/dist/assets/dm-sans-latin-600-normal-Aqo67rzb.woff2"
- "modules/boardwalk/dist/assets/dm-sans-latin-600-normal-BmdmIIQ2.woff"
- "modules/boardwalk/dist/assets/dm-sans-latin-700-normal-CUSSCpQX.woff"
- "modules/boardwalk/dist/assets/dm-sans-latin-700-normal-DvUfVpUG.woff2"
- "modules/boardwalk/dist/assets/dm-sans-latin-ext-400-normal-BjWJ59Pq.woff"
- "modules/boardwalk/dist/assets/dm-sans-latin-ext-400-normal-BtiwyxMk.woff2"
- "modules/boardwalk/dist/assets/dm-sans-latin-ext-500-normal-BJfUCQsA.woff2"
- "modules/boardwalk/dist/assets/dm-sans-latin-ext-500-normal-DR84L5F-.woff"
- "modules/boardwalk/dist/assets/dm-sans-latin-ext-600-normal-4vooXBpG.woff2"
- "modules/boardwalk/dist/assets/dm-sans-latin-ext-600-normal-DRtaDpgU.woff"
- "modules/boardwalk/dist/assets/dm-sans-latin-ext-700-normal-BLI3TTWz.woff"
- "modules/boardwalk/dist/assets/dm-sans-latin-ext-700-normal-CJIcxD6K.woff2"
- "modules/boardwalk/dist/assets/index-J-FCndLr.js"
- "modules/boardwalk/dist/assets/index-CfeX_snf.css"
- "modules/boardwalk/dist/index.html"
- "modules/bonfire/README.md"
- "modules/bonfire/command.go"
- "modules/bonfire/command_test.go"
- "modules/bonfire/output.go"
- "modules/bonfire/output_test.go"
- "modules/bonfire/prompts.go"
- "modules/bonfire/prompts_test.go"
- "modules/bonfire/root.go"
- "modules/bonfire/widgets.go"
- "modules/bouncer/README.md"
- "modules/bouncer/audience_test.go"
- "modules/bouncer/backend_guard_test.go"
- "modules/bouncer/blacklist.go"
- "modules/bouncer/blacklist_test.go"
- "modules/bouncer/context.go"
- "modules/bouncer/context_test.go"
- "modules/bouncer/cookie_guard_test.go"
- "modules/bouncer/guard.go"
- "modules/bouncer/jwt.go"
- "modules/bouncer/jwt_guard_test.go"
- "modules/bouncer/jwt_test.go"
- "modules/bouncer/mint.go"
- "modules/bouncer/mint_test.go"
- "modules/bouncer/password.go"
- "modules/bouncer/password_test.go"
- "modules/bouncer/phase07_coverage_test.go"
- "modules/bouncer/refresh.go"
- "modules/bouncer/refresh_test.go"
- "modules/bouncer/registry.go"
- "modules/bouncer/registry_coverage_test.go"
- "modules/bouncer/registry_test.go"
- "modules/cabana/README.md"
- "modules/cabana/admin_openapi.go"
- "modules/cabana/admin_paths_test.go"
- "modules/cabana/auth.go"
- "modules/cabana/auth_test.go"
- "modules/cabana/bulk_test.go"
- "modules/cabana/commands.go"
- "modules/cabana/commands_test.go"
- "modules/cabana/contracts.go"
- "modules/cabana/crud.go"
- "modules/cabana/crud_lifecycle_test.go"
- "modules/cabana/crud_test.go"
- "modules/cabana/csrf.go"
- "modules/cabana/export_test.go"
- "modules/cabana/filter_options_test.go"
- "modules/cabana/filter_schema.go"
- "modules/cabana/form_schema.go"
- "modules/cabana/form_schema_test.go"
- "modules/cabana/http.go"
- "modules/cabana/lang.go"
- "modules/cabana/list_schema.go"
- "modules/cabana/list_schema_test.go"
- "modules/cabana/messages.go"
- "modules/cabana/messages_test.go"
- "modules/cabana/metadata_settings_test.go"
- "modules/cabana/navigation.go"
- "modules/cabana/openapi_conformance_test.go"
- "modules/cabana/phase09_contract_test.go"
- "modules/cabana/phase10_auth_test.go"
- "modules/cabana/phase10_coverage_test.go"
- "modules/cabana/phase10_csrf_test.go"
- "modules/cabana/prefix.go"
- "modules/cabana/query.go"
- "modules/cabana/query_test.go"
- "modules/cabana/refresh_revocation_test.go"
- "modules/cabana/registry.go"
- "modules/cabana/relation.go"
- "modules/cabana/relation_field.go"
- "modules/cabana/relation_field_test.go"
- "modules/cabana/relation_test.go"
- "modules/cabana/schema.go"
- "modules/cabana/schema_types.go"
- "modules/cabana/security_coverage_test.go"
- "modules/cabana/security_test.go"
- "modules/cabana/settings.go"
- "modules/cabana/testdata/list/all_columns.yaml"
- "modules/cabana/testdata/list/all_filters.yaml"
- "modules/compass/README.md"
- "modules/compass/config.go"
- "modules/compass/config_test.go"
- "modules/compass/env.go"
- "modules/compass/env_test.go"
- "modules/compass/persist.go"
- "modules/compass/persist_test.go"
- "modules/festival/README.md"
- "modules/festival/bus.go"
- "modules/festival/bus_test.go"
- "modules/fetchguard/README.md"
- "modules/fetchguard/fetch.go"
- "modules/fetchguard/fetch_coverage_test.go"
- "modules/fetchguard/fetch_test.go"
- "modules/fetchguard/ip.go"
- "modules/fetchguard/ip_test.go"
- "modules/fetchguard/policy.go"
- "modules/lagoon/README.md"
- "modules/lagoon/attach/app_test.go"
- "modules/lagoon/attach/bucket.go"
- "modules/lagoon/attach/bucket_test.go"
- "modules/lagoon/attach/file.go"
- "modules/lagoon/attach/file_test.go"
- "modules/lagoon/attach/lifecycle_test.go"
- "modules/lagoon/attach/migrations.go"
- "modules/lagoon/attach/static.go"
- "modules/lagoon/attach/static_test.go"
- "modules/lagoon/attach/thumb.go"
- "modules/lagoon/attach/thumb_test.go"
- "modules/lagoon/backend_admin_migrations.go"
- "modules/lagoon/backend_admin_migrations_test.go"
- "modules/lagoon/commands.go"
- "modules/lagoon/connection.go"
- "modules/lagoon/connection_test.go"
- "modules/lagoon/encrypted.go"
- "modules/lagoon/encrypted_test.go"
- "modules/lagoon/fill.go"
- "modules/lagoon/fill_fuzz_test.go"
- "modules/lagoon/fill_test.go"
- "modules/lagoon/hidden_marshal_test.go"
- "modules/lagoon/jsonable.go"
- "modules/lagoon/jsonable_test.go"
- "modules/lagoon/keygen.go"
- "modules/lagoon/keygen_test.go"
- "modules/lagoon/laravel_decrypt.go"
- "modules/lagoon/laravel_decrypt_test.go"
- "modules/lagoon/lifecycle.go"
- "modules/lagoon/lifecycle_test.go"
- "modules/lagoon/migrations.go"
- "modules/lagoon/migrations_test.go"
- "modules/lagoon/order.go"
- "modules/lagoon/order_test.go"
- "modules/lagoon/paginate.go"
- "modules/lagoon/paginate_test.go"
- "modules/lagoon/postgres_test.go"
- "modules/lagoon/relations.go"
- "modules/lagoon/relations_test.go"
- "modules/lagoon/validate.go"
- "modules/lagoon/validate_test.go"
- "modules/pact/README.md"
- "modules/pact/capabilities.go"
- "modules/pact/capabilities_test.go"
- "modules/party/README.md"
- "modules/party/registry.go"
- "modules/party/registry_test.go"
- "modules/phrasebook/README.md"
- "modules/phrasebook/backend/lang/en/lang.yaml"
- "modules/phrasebook/backend/lang/pl/lang.yaml"
- "modules/phrasebook/lang.go"
- "modules/phrasebook/lang/en/validate.yaml"
- "modules/phrasebook/lang/pl/validate.yaml"
- "modules/phrasebook/loader.go"
- "modules/phrasebook/phase10_test.go"
- "modules/phrasebook/translator.go"
- "modules/phrasebook/translator_test.go"
- "modules/postcard/README.md"
- "modules/postcard/assets/default.htm"
- "modules/postcard/drivers.go"
- "modules/postcard/mailer.go"
- "modules/postcard/mailer_test.go"
- "modules/postcard/mailpit_test.go"
- "modules/postcard/smtp_test.go"
- "modules/postcard/templates.go"
- "modules/postcard/templates_test.go"
- "modules/surf/README.md"
- "modules/surf/admin_prefix_test.go"
- "modules/surf/bodylimit.go"
- "modules/surf/bodylimit_test.go"
- "modules/surf/clientip.go"
- "modules/surf/clientip_test.go"
- "modules/surf/cors.go"
- "modules/surf/cors_coverage_test.go"
- "modules/surf/cors_test.go"
- "modules/surf/limiter.go"
- "modules/surf/limiter_coverage_test.go"
- "modules/surf/limiter_store.go"
- "modules/surf/limiter_test.go"
- "modules/surf/locale_from_principal.go"
- "modules/surf/locale_from_principal_test.go"
- "modules/surf/middleware_test.go"
- "modules/surf/params.go"
- "modules/surf/params_test.go"
- "modules/surf/routelist_command.go"
- "modules/surf/router.go"
- "modules/surf/router_test.go"
- "modules/surf/routetable.go"
- "modules/surf/routetable_coverage_test.go"
- "modules/surf/routetable_test.go"
- "modules/surf/serve.go"
- "modules/surf/serve_test.go"
- "modules/tide/README.md"
- "modules/tide/capture_test.go"
- "modules/tide/diff.go"
- "modules/tide/diff_contract_test.go"
- "modules/tide/diff_test.go"
- "modules/tide/fixture.go"
- "modules/tide/flow.go"
- "modules/tide/flow_contract_test.go"
- "modules/tide/flow_test.go"
- "modules/tide/headers_test.go"
- "modules/tide/manifest.go"
- "modules/tide/manifest_contract_test.go"
- "modules/tide/manifest_test.go"
- "modules/tide/normalize.go"
- "modules/tide/normalize_test.go"
- "modules/tide/proxy.go"
- "modules/tide/proxy_security_test.go"
- "modules/tide/proxy_test.go"
- "modules/tide/record.go"
- "modules/tide/replay.go"
- "modules/tide/report.go"
- "modules/tide/roundtrip_test.go"
- "modules/tide/rules.go"
- "modules/tide/rules_test.go"
- "modules/tide/testdata/one-route-spec.yaml"
- "modules/tide/variables.go"
- "modules/towel/README.md"
- "modules/towel/context.go"
- "modules/towel/context_test.go"
- "modules/wire/README.md"
- "modules/wire/response.go"
- "modules/wire/response_coverage_test.go"
- "modules/wire/response_test.go"
- "modules/wristband/README.md"
- "modules/wristband/authorize.go"
- "modules/wristband/authorize_test.go"
- "modules/wristband/client_issue.go"
- "modules/wristband/consent.go"
- "modules/wristband/consent_test.go"
- "modules/wristband/crypto.go"
- "modules/wristband/phase08_coverage_test.go"
- "modules/wristband/redirect_html.go"
- "modules/wristband/register.go"
- "modules/wristband/registration_test.go"
- "modules/wristband/server.go"
- "modules/wristband/server_test.go"
- "modules/wristband/stores.go"
- "modules/wristband/token.go"
- "modules/wristband/token_test.go"
- "scripts/check-admin-dist.sh"
- "scripts/check-admin-openapi.sh"
- "scripts/check-phase10.2.sh"
- "scripts/check-phase10.sh"
- "scripts/check-phase2.sh"
- "scripts/check-phase3.sh"
- "scripts/check-phase4.sh"
- "scripts/check-phase9.sh"
covered_digest: "v2:sha256:c5236001a0415018a2c9071eda2ee55201881dadb06f9a3b9437c5bec10a5d91"
behavior_unverified: 0
overrides_applied: 0
re_verification:
previous_status: passed
previous_score: 7/7
reason: "Report went stale: two covered dist bundles were renamed by Phase 10.1 rebuilds, and later commits changed covered files, including the root README and module READMEs."
gaps_closed: []
gaps_remaining: []
regressions:
- "D-07: module READMEs are no longer short one-paragraph files. Commit 3142aeb and the CLAUDE.md Documentation rule from commit fafb12f replaced them with long standard-structure READMEs of 62-211 lines. This looks like an intentional, user-authored change, so it needs a human decision."
- "D-08: the root README no longer names fonoteka.go, the admin-login recreate flow, /plytadmin or the Phase 15 cutover. Commit 70d3c39 ('docs: generic root README') replaced it to follow the CLAUDE.md rule that framework READMEs never name a consuming application. This also looks intentional and needs a human decision."
advisory:
- finding: "go test ./... failed in two packages outside Phase 10.2 (modules/conga TestQueueWork/serve_worker: River notifier listener timed out after 10s; modules/lighthouse TestBulkEmitsOnce: got 0 publications, want 1). Both passed when rerun in isolation."
category: other
reason: "Timing flakes under concurrent load (another verifier was running Docker-backed tests at the same time). Phase 11 owns these packages, not Phase 10.2. Fix by making their timeouts tolerate load."
evidence_status: "rerun in isolation passed: go test -count=1 ./modules/conga ./modules/lighthouse"
human_verification:
- test: "Decide whether the Phase 11.1 / CLAUDE.md README standard supersedes D-07 ('each modules/<name>/README.md is a short one-paragraph README')."
expected: "If accepted, add the D-07 override below to this file's frontmatter. If not, plan a gap closure. That closure would conflict with the CLAUDE.md Documentation rule, which requires the standard structure: H1, summary, import line, Overview, Features, Usage, API reference, Dependencies, Testing."
why_human: "The literal must-have is false at HEAD, but the deviation comes from a later user-authored project rule. Only the developer can accept a superseded must-have."
- test: "Decide whether the generic root README (commit 70d3c39) supersedes D-08's fonoteka.go, admin-login recreate and Phase 15 cutover content."
expected: "If accepted, add the D-08 override below. The README still covers what remains compatible with the 'never name a consuming application' rule: the framework is a single module, applications use a local replace during development, every module README is linked, there is a runnable examples/hello quick start, and the README has no stale 'nothing runs' claim."
why_human: "The literal must-have is false at HEAD, and restoring it would break the CLAUDE.md rule that framework READMEs never name a consuming application. The developer has to decide which one wins."
---
# Phase 10.2: Nest Framework Packages Under Modules and Write Run Docs: Verification Report
**Phase Goal:** The 18 beach-named framework packages live under `modules/<name>/` with the same names and a single root `go.mod`; importers in summercms.go, examples, and fonoteka.go use `git.golem15.com/golem15/summercms/modules/<name>`; each module has a short README; the root README is honest run/onboarding docs.
**Verified:** 2026-10-01T21:26:36Z
**Status:** human_needed
**Re-verification:** Yes. The previous report (passed, 7/7) went stale because covered files moved or changed after it was written.
## Stale covered files: where they went
| Old path | Fate | Current path |
| --- | --- | --- |
| `modules/boardwalk/dist/assets/index-BAlwlQ8W.js` | Deleted in `107d820` (10.1-02 admin rebuild), then renamed by later content-hashed rebuilds (`a5e7dac`, `6b0ac15`, `849a9ff`, `5bbb0ad`) | `modules/boardwalk/dist/assets/index-J-FCndLr.js` |
| `modules/boardwalk/dist/assets/index-CLf0gZ3D.css` | Deleted in `107d820`, replaced in `9df9fae` | `modules/boardwalk/dist/assets/index-CfeX_snf.css` |
Both successors are the bundles `modules/boardwalk/dist/index.html` references at HEAD. The other 301 entries still exist at the same paths. A cross-check against `git log --grep='(10.2' --name-only` found no Phase 10.2 implementation file missing from the list. The only commit path not in the list is the pre-move `backpack/app.go`, which now lives at `modules/backpack/app.go` and is listed.
## Goal Achievement
### Observable Truths
| # | Truth | Status | Evidence |
| --- | --- | --- | --- |
| 1 | D-01/D-02/D-06: the 18 beach packages live only under `modules/<name>/` with unchanged package names, and none is a directory at repo root. | ✓ VERIFIED | All 18 directories exist under `modules/`. Each package clause matches its beach name. No root shadow exists, and `check-phase10.2.sh --layout` exits 0. The four modules added later (beachcomber, conga, flare, lighthouse) follow the same layout. |
| 2 | D-03: `admin/`, `cmd/`, `examples/`, `internal/`, `scripts/`, `go.mod` and `README.md` stay at root; there is one framework `go.mod`, and `go.work` uses only `.` and `./examples/hello*`. | ✓ VERIFIED | Root listing confirmed. `find modules -name go.mod` is empty. `go.work` lists `.` plus the four `examples/hello*` modules. |
| 3 | D-04/D-05: every importer in summercms.go, examples and fonoteka.go uses `.../summercms/modules/<name>`, and the replace directives still target this checkout. | ✓ VERIFIED | `git grep` for root-form beach imports outside `.planning/` found no matches. `check-phase10.2.sh --imports` (both repos) exits 0. `../fonoteka.go/go.mod` and both plugin `go.mod` files keep `replace git.golem15.com/golem15/summercms => .../summercms.go`. |
| 4 | D-05: `go vet ./...` and `go test ./...` are green in summercms.go, and the same pair plus the plugin modules is green in fonoteka.go. | ✓ VERIFIED | Framework: `go vet ./...` exits 0. In the single full `go test ./...` run, 33 packages passed and 2 failed with timing flakes outside Phase 10.2 (conga, lighthouse). Both passed when rerun alone (see Advisory). fonoteka.go: vet and test over `./... ./plugins/golem15/fonoteka/... ./plugins/golem15/user/...` exit 0. Example modules: vet and compile-only test exit 0. |
| 5 | D-07: each `modules/<name>/README.md` is a short one-paragraph README stating what the package is, who imports it and one example entry point, with no architecture essays or planning prose. | ? UNCERTAIN (superseded) | All 18 READMEs exist, contain no planning prose and no consuming-application names, and the docs checker confirms every identifier they cite exists. They are no longer short, though: 62-211 lines each, rewritten by `3142aeb` to the standard structure the CLAUDE.md Documentation rule (`fafb12f`) requires. The literal must-have is false, and the change looks intentional and user-authored. A human decision is required (see the suggested override). |
| 6 | D-08: the root README states framework-only (app is sibling fonoteka.go), explains the two-repo go.work replace, points at fonoteka.go to recreate the admin login, includes an honest Phase 15 cutover, and links the module READMEs. | ? UNCERTAIN (superseded) | Still true: the framework-only description, the module-path-plus-local-replace pattern, links to all module READMEs, a runnable `examples/hello` quick start with migrate/serve, and no stale "nothing runs" claim. No longer true: it does not name fonoteka.go, `/plytadmin` or the Phase 15 cutover. Commit `70d3c39` removed them deliberately to follow the CLAUDE.md rule that framework READMEs never name a consuming application. A human decision is required. |
| 7 | The fail-closed 10.2 gate refuses leftover root beach directories, root-form beach imports, a missing module README and a stale "nothing runs" README. | ✓ VERIFIED | `bash -n scripts/check-phase10.2.sh && scripts/check-phase10.2.sh --self-test` printed `phase10.2 self-test passed`. Live `--layout`, `--imports`, `--readmes` and `--status` each exit 0. |
**Score:** 5/7 truths verified, 0 present but behavior-unverified, 2 uncertain (superseded by later user decisions; human decision requested)
### Suggested overrides (not applied; developer acceptance required)
**This looks intentional.** To accept the deviations, add to this file's frontmatter:
```yaml
overrides:
- must_have: "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."
reason: "Superseded by the CLAUDE.md Documentation rule (fafb12f) and commit 3142aeb: module READMEs follow the standard structure (H1, summary, import line, Overview, Features, Usage, API reference, Dependencies, Testing) and the docs checker verifies every identifier they name."
accepted_by: "{name}"
accepted_at: "{ISO timestamp}"
- must_have: "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."
reason: "Superseded by commit 70d3c39 (generic root README) and the CLAUDE.md rule that framework READMEs never name a consuming application; app-specific run and cutover docs belong to the application repo."
accepted_by: "{name}"
accepted_at: "{ISO timestamp}"
```
## Required Artifacts
| Artifact | Expected | Status | Details |
| --- | --- | --- | --- |
| `modules/` and `modules/festival/` | 18 nested package directories | ✓ VERIFIED | 18 expected names present, package clauses match, no root shadows. |
| `scripts/check-admin-openapi.sh` | OpenAPI scans the moved cabana | ✓ VERIFIED | `--dir modules/cabana` (line 32). |
| `scripts/check-admin-dist.sh` / `admin/vite.config.ts` | Boardwalk dist wiring | ✓ VERIFIED | The script diffs against `modules/boardwalk/dist`; Vite has `outDir: '../modules/boardwalk/dist'`. |
| `internal/build/stubs/plugin.tmpl` | Generated plugin imports use nested paths | ✓ VERIFIED | Imports backpack, bonfire, pact and party through `/modules/`. |
| `modules/*/README.md` | Module onboarding | ⚠️ PRESENT, NOT SHORT | All exist and are accurate (the docs checker passes), but they no longer match D-07's "short" wording (truth 5). |
| `README.md` | Framework onboarding, two-repo layout, admin-login recreate, honest cutover | ⚠️ PARTIAL BY DESIGN | Generic framework onboarding. The app-specific parts were removed by a later rule (truth 6). |
| `scripts/check-phase10.2.sh` | Fail-closed hygiene and Go gate | ✓ VERIFIED | Syntax check, self-test and all four hygiene modes pass. |
## Key Link Verification
| From | To | Via | Status | Details |
| --- | --- | --- | --- | --- |
| `modules/backpack/app.go` | `modules/festival` | nested import | ✓ WIRED | Line 8 imports `git.golem15.com/golem15/summercms/modules/festival`. |
| Admin/OpenAPI/dist scripts and Vite | moved cabana/boardwalk paths | retargeted literals | ✓ WIRED | All `modules/` paths present. |
| `../fonoteka.go/go.mod` (+ plugin go.mods) | this framework checkout | local replace | ✓ WIRED | `=> ../summercms.go` / `=> ../../../../summercms.go`. |
| Root README | per-module READMEs | links | ✓ WIRED | The modules table links all 22 module READMEs (18 from 10.2 plus 4 added later). |
| Phase gate | layout/import/README/status checks | `--self-test` plants | ✓ WIRED | Self-test passed. |
## Data-Flow Trace (Level 4)
Not applicable. The phase moves static Go packages and adds docs and hygiene tooling; it renders no dynamic data.
## Behavioral Spot-Checks
| Behavior | Command | Result | Status |
| --- | --- | --- | --- |
| Framework vet | `go vet ./...` | exit 0 | ✓ PASS |
| Framework tests (single full run) | `go test ./...` | 33 ok, 2 FAIL (conga TestQueueWork, lighthouse TestBulkEmitsOnce: load timing) | see next row |
| Rerun of the two failing packages | `go test -count=1 ./modules/conga ./modules/lighthouse` | both ok | ✓ PASS |
| Docs tree check | `go test ./cmd/summer -run TestDocsTree -count=1` | ok | ✓ PASS |
| Docs build check | `go run ./cmd/summer docs:build --check` | `docs:build: no problems found` | ✓ PASS |
| App repo vet/test | `cd ../fonoteka.go && go vet/test ./... ./plugins/golem15/fonoteka/... ./plugins/golem15/user/...` | exit 0 / exit 0 | ✓ PASS |
| Examples | `go vet` + `go test -run '^$'` over the four `examples/hello*` modules | exit 0 | ✓ PASS |
| Gate self-test | `bash -n scripts/check-phase10.2.sh && scripts/check-phase10.2.sh --self-test` | `phase10.2 self-test passed` | ✓ PASS |
| Gate hygiene | `scripts/check-phase10.2.sh --layout / --imports / --readmes / --status` | all exit 0 | ✓ PASS |
No command changed the working tree (`git status` showed only the pre-existing untracked zip).
## Probe Execution
Not applicable. The plans declare no probe, and no conventional `scripts/*/tests/probe-*.sh` is in scope.
## Requirements Coverage
No requirement IDs are assigned: both PLAN frontmatters have `requirements: []`, and ROADMAP lists Phase 10.2 Requirements as TBD. No orphaned mappings.
## Advisory (New Scope, Unevidenced)
| # | Finding | Category | Why Advisory |
| --- | --- | --- | --- |
| 1 | conga/lighthouse tests flake under concurrent Docker load | other | Outside Phase 10.2. The packages pass in isolation and their files are not covered by this phase. |
## Anti-Patterns Found
| File | Line | Pattern | Severity | Impact |
| --- | --- | --- | --- | --- |
| (none) | | No `TBD`/`FIXME`/`XXX` in the gate, READMEs, stubs, Vite config or admin scripts | | |
## Human Verification Required
### 1. Accept or reject the D-07 supersession
**Test:** Compare D-07 ("short one-paragraph module README") with the CLAUDE.md Documentation rule and the current `modules/*/README.md` files.
**Expected:** Accept by adding the D-07 override above, or reject and plan a gap closure. A gap closure would conflict with CLAUDE.md.
**Why human:** Only the developer can accept that a later project rule replaces a phase must-have.
### 2. Accept or reject the D-08 supersession
**Test:** Compare D-08 (fonoteka.go, admin-login recreate, Phase 15 cutover in the root README) with commit `70d3c39` and the rule that framework READMEs never name a consuming application.
**Expected:** Accept by adding the D-08 override above (app-specific run and cutover docs then live in the application repo), or reject.
**Why human:** Restoring D-08 literally would break a standing CLAUDE.md rule, so the developer has to pick which one wins.
## Gaps Summary
There are no implementation gaps. The structural goal holds at HEAD: the nested `modules/` layout, a single `go.mod`, nested imports in both repositories, green vet and tests (aside from two load flakes outside the phase), and a working fail-closed gate. The two documentation must-haves (D-07 short module READMEs, D-08 app-specific root README) no longer hold as written. Later, deliberate, user-authored commits and the CLAUDE.md Documentation rule replaced them. They are routed to the developer as override decisions rather than gaps, because closing them literally would break current project rules.
_Verified: 2026-10-01T21:26:36Z_
_Verifier: Claude (gsd-verifier)_