docs(10, 10.2): regenerate verification reports for modules/ paths
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
---
|
---
|
||||||
phase: 10-admin-vue-spa
|
phase: 10-admin-vue-spa
|
||||||
verified: 2026-09-27T18:43:00Z
|
verified: 2026-10-01T21:29:59Z
|
||||||
status: passed
|
status: human_needed
|
||||||
score: 4/4 roadmap success criteria verified (plan truths 46/46 verified; A3 closed by human UAT)
|
score: 4/4 roadmap success criteria verified by automated evidence (plan truths 46/46; 1 browser re-check of changed views pending)
|
||||||
covered_files:
|
covered_files:
|
||||||
- ".gitignore"
|
- ".gitignore"
|
||||||
- ".planning/phases/10-admin-vue-spa/10-01-PLAN.md"
|
- ".planning/phases/10-admin-vue-spa/10-01-PLAN.md"
|
||||||
@@ -144,75 +144,77 @@ covered_files:
|
|||||||
- "admin/tsconfig.json"
|
- "admin/tsconfig.json"
|
||||||
- "admin/vite.config.ts"
|
- "admin/vite.config.ts"
|
||||||
- "admin/vitest.config.ts"
|
- "admin/vitest.config.ts"
|
||||||
- "boardwalk/boardwalk.go"
|
|
||||||
- "boardwalk/boardwalk_test.go"
|
|
||||||
- "boardwalk/dist/index.html"
|
|
||||||
- "bouncer/cookie_guard_test.go"
|
|
||||||
- "bouncer/jwt.go"
|
|
||||||
- "bouncer/jwt_guard_test.go"
|
|
||||||
- "bouncer/refresh.go"
|
|
||||||
- "bouncer/refresh_test.go"
|
|
||||||
- "bouncer/registry_test.go"
|
|
||||||
- "cabana/admin_openapi.go"
|
|
||||||
- "cabana/admin_paths_test.go"
|
|
||||||
- "cabana/auth.go"
|
|
||||||
- "cabana/auth_test.go"
|
|
||||||
- "cabana/bulk_test.go"
|
|
||||||
- "cabana/commands_test.go"
|
|
||||||
- "cabana/contracts.go"
|
|
||||||
- "cabana/crud.go"
|
|
||||||
- "cabana/crud_lifecycle_test.go"
|
|
||||||
- "cabana/csrf.go"
|
|
||||||
- "cabana/export_test.go"
|
|
||||||
- "cabana/filter_options_test.go"
|
|
||||||
- "cabana/filter_schema.go"
|
|
||||||
- "cabana/form_schema.go"
|
|
||||||
- "cabana/form_schema_test.go"
|
|
||||||
- "cabana/http.go"
|
|
||||||
- "cabana/lang.go"
|
|
||||||
- "cabana/list_schema.go"
|
|
||||||
- "cabana/list_schema_test.go"
|
|
||||||
- "cabana/messages.go"
|
|
||||||
- "cabana/messages_test.go"
|
|
||||||
- "cabana/openapi_conformance_test.go"
|
|
||||||
- "cabana/phase09_contract_test.go"
|
|
||||||
- "cabana/phase10_auth_test.go"
|
|
||||||
- "cabana/phase10_coverage_test.go"
|
|
||||||
- "cabana/phase10_csrf_test.go"
|
|
||||||
- "cabana/prefix.go"
|
|
||||||
- "cabana/query_test.go"
|
|
||||||
- "cabana/refresh_revocation_test.go"
|
|
||||||
- "cabana/registry.go"
|
|
||||||
- "cabana/relation.go"
|
|
||||||
- "cabana/relation_field.go"
|
|
||||||
- "cabana/relation_field_test.go"
|
|
||||||
- "cabana/schema_types.go"
|
|
||||||
- "cabana/security_coverage_test.go"
|
|
||||||
- "cabana/security_test.go"
|
|
||||||
- "go.mod"
|
- "go.mod"
|
||||||
- "internal/build/build_test.go"
|
- "internal/build/build_test.go"
|
||||||
- "internal/build/stubs/artifacts.tmpl"
|
- "internal/build/stubs/artifacts.tmpl"
|
||||||
- "internal/tools/swagger2openapi/main.go"
|
- "internal/tools/swagger2openapi/main.go"
|
||||||
- "internal/tools/swagger2openapi/main_test.go"
|
- "internal/tools/swagger2openapi/main_test.go"
|
||||||
- "pact/capabilities.go"
|
- "modules/boardwalk/boardwalk.go"
|
||||||
- "phrasebook/backend/lang/en/lang.yaml"
|
- "modules/boardwalk/boardwalk_test.go"
|
||||||
- "phrasebook/backend/lang/pl/lang.yaml"
|
- "modules/boardwalk/dist/assets/index-CfeX_snf.css"
|
||||||
- "phrasebook/lang.go"
|
- "modules/boardwalk/dist/assets/index-J-FCndLr.js"
|
||||||
- "phrasebook/loader.go"
|
- "modules/boardwalk/dist/index.html"
|
||||||
- "phrasebook/phase10_test.go"
|
- "modules/bouncer/cookie_guard_test.go"
|
||||||
- "phrasebook/translator.go"
|
- "modules/bouncer/jwt.go"
|
||||||
- "phrasebook/translator_test.go"
|
- "modules/bouncer/jwt_guard_test.go"
|
||||||
|
- "modules/bouncer/refresh.go"
|
||||||
|
- "modules/bouncer/refresh_test.go"
|
||||||
|
- "modules/bouncer/registry_test.go"
|
||||||
|
- "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_test.go"
|
||||||
|
- "modules/cabana/contracts.go"
|
||||||
|
- "modules/cabana/crud.go"
|
||||||
|
- "modules/cabana/crud_lifecycle_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/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_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/schema_types.go"
|
||||||
|
- "modules/cabana/security_coverage_test.go"
|
||||||
|
- "modules/cabana/security_test.go"
|
||||||
|
- "modules/pact/capabilities.go"
|
||||||
|
- "modules/phrasebook/backend/lang/en/lang.yaml"
|
||||||
|
- "modules/phrasebook/backend/lang/pl/lang.yaml"
|
||||||
|
- "modules/phrasebook/lang.go"
|
||||||
|
- "modules/phrasebook/loader.go"
|
||||||
|
- "modules/phrasebook/phase10_test.go"
|
||||||
|
- "modules/phrasebook/translator.go"
|
||||||
|
- "modules/phrasebook/translator_test.go"
|
||||||
|
- "modules/surf/admin_prefix_test.go"
|
||||||
|
- "modules/surf/cors_coverage_test.go"
|
||||||
|
- "modules/surf/cors_test.go"
|
||||||
|
- "modules/surf/middleware_test.go"
|
||||||
|
- "modules/surf/router.go"
|
||||||
|
- "modules/surf/router_test.go"
|
||||||
- "scripts/check-admin-dist.sh"
|
- "scripts/check-admin-dist.sh"
|
||||||
- "scripts/check-admin-openapi.sh"
|
- "scripts/check-admin-openapi.sh"
|
||||||
- "scripts/check-phase10.sh"
|
- "scripts/check-phase10.sh"
|
||||||
- "surf/admin_prefix_test.go"
|
covered_digest: "v2:sha256:f23b588ee19dd2c8ff9456435821e3870aab30f1f869831797c679120d61c730"
|
||||||
- "surf/cors_coverage_test.go"
|
covered_files_note: "Paths are root-relative at summercms.go HEAD f2f2279. The 59 framework paths that Phase 10.2 (5e50b16) moved are listed under modules/. The two current hashed SPA bundles are now covered as well. fonoteka.go files are outside the project root and cannot be fingerprinted. They were checked at fonoteka.go HEAD e62f4fc (clean working tree) and are listed in the report body."
|
||||||
- "surf/cors_test.go"
|
|
||||||
- "surf/middleware_test.go"
|
|
||||||
- "surf/router.go"
|
|
||||||
- "surf/router_test.go"
|
|
||||||
covered_digest: "v2:sha256:d9ac088393759ff9aab5aa67b3cb4a80a04c978e48adb20618eaa71b6154a3b3"
|
|
||||||
covered_files_note: "fonoteka.go files are outside the project root and cannot be fingerprinted. They are listed in the report body (Required Artifacts) and were checked at fonoteka.go HEAD 3359a83, which is unchanged since the previous verification and has a clean working tree."
|
|
||||||
behavior_unverified: 0
|
behavior_unverified: 0
|
||||||
overrides_applied: 0
|
overrides_applied: 0
|
||||||
mvp_mode_note: "ROADMAP marks Phase 10 mode: mvp, but the goal is not a User Story. Following the Phase 1/3/5/8 precedent, the four ROADMAP success criteria are the contract and User Flow Coverage is derived from them."
|
mvp_mode_note: "ROADMAP marks Phase 10 mode: mvp, but the goal is not a User Story. Following the Phase 1/3/5/8 precedent, the four ROADMAP success criteria are the contract and User Flow Coverage is derived from them."
|
||||||
@@ -221,77 +223,63 @@ decision_coverage:
|
|||||||
total: 28
|
total: 28
|
||||||
not_honored: []
|
not_honored: []
|
||||||
re_verification:
|
re_verification:
|
||||||
previous_status: human_needed
|
previous_status: passed
|
||||||
previous_score: "4/4 roadmap success criteria (plan truths 45/46, 1 abstained non-inferable)"
|
previous_score: "4/4 roadmap success criteria verified (plan truths 46/46 verified; A3 closed by human UAT)"
|
||||||
previous_head: f47a560
|
previous_head: c7487f6
|
||||||
|
reason: "Stale. Phase 10.2 moved 59 covered paths under modules/. Phases 10.1, 11 and the Phase 9 review fixes changed covered code."
|
||||||
gaps_closed:
|
gaps_closed:
|
||||||
- "CR-01 escalation: admin POST /auth/refresh now enforces tokens_valid_after, is_activated and soft delete through bouncer.RefreshAudienceFor (be4a923, a13a121)"
|
- "Phase 10 review WR-01 (logout behind the guard did not expire a rejected cookie): logout is now mounted outside the guard and always clears the cookie (299d220). TestAdminLogoutRevokesExpiredRefreshableToken: PASS."
|
||||||
- "A3 insufficient_spec: Secure admin cookie accepted on http://localhost (closed by human UAT, 10-UAT.md test 6)"
|
|
||||||
- "All 7 human verification items approved in 10-UAT.md (status: complete)"
|
|
||||||
gaps_remaining: []
|
gaps_remaining: []
|
||||||
regressions: []
|
regressions: []
|
||||||
human_verification:
|
human_verification:
|
||||||
- test: "Decide CR-01 (refresh ignores tokens_valid_after / is_activated)"
|
- test: "Re-walk the Phase 10 admin flows in a real browser on the current build: run the fonoteka binary, open /plytadmin as a superuser and as a genres-only admin, then use the list and form of each of the five controllers (search, sort, filter, paging, save, 422 field errors), link and unlink a Collection editor, open Ustawienia, and glance at light and dark mode."
|
||||||
|
expected: "Everything still behaves as approved in 10-UAT.md tests 2 to 5. The limited admin sees only fonoteka > Genres. Lists and forms render. The editor round trip works. The Albums form now also shows the Phase 10.1 widgets and partials, and they do not break the Phase 10 form."
|
||||||
|
why_human: "10-UAT.md was approved on 2026-09-27 against c7487f6. Since then Phase 10.1 changed ListView.vue, FormView.vue, ListToolbar.vue, FormField.vue, registry.ts, router.ts and main.css, and fonoteka's Albums controller now registers plugin widgets and partials. The Phase 9 review fixes changed server-side navigation (WR-01, WR-02, WR-17). Vitest and the Postgres acceptance test pass, but D-23 keeps the real browser out of the automated suite, and the browser checks for these views (10.1-UAT.md tests 1 and 4) are still pending. Closing 10.1-UAT tests 1 and 4 with Genres, Collections and Settings included also closes this item."
|
||||||
|
- test: "Carried: decide CR-01 (refresh ignores tokens_valid_after / is_activated)"
|
||||||
expected: "Fix now or accept with override"
|
expected: "Fix now or accept with override"
|
||||||
why_human: "Security-policy decision"
|
why_human: "Security-policy decision"
|
||||||
resolution: "Fixed in quick 260927-q23 (be4a923, a13a121). TestAdminRefreshRevocation and TestRefreshAudienceForSubject re-run by the verifier: PASS. Approved in 10-UAT.md test 1."
|
resolution: "Fixed (be4a923, a13a121). TestAdminRefreshRevocation re-run this session: PASS. Approved in 10-UAT.md test 1. Still applies, still resolved."
|
||||||
- test: "Limited admin vs superuser navigation at /plytadmin"
|
- test: "Carried: Secure cookie on http://localhost (assumption A3)"
|
||||||
expected: "Limited admin sees only fonoteka > Genres, no Ustawienia; superuser sees all five plus Ustawienia"
|
|
||||||
why_human: "Real browser against the real server (D-23: no browser e2e)"
|
|
||||||
resolution: "Approved in 10-UAT.md test 2 (local fonoteka binary, superuser plus genres-only admin)."
|
|
||||||
- test: "Walkthrough of the five controllers and Ustawienia"
|
|
||||||
expected: "Lists and forms render from YAML; search, sort, filter, paging, bulk delete, save toast, 422 field errors, album relations, search_use_typesense"
|
|
||||||
why_human: "End-to-end user flow in a real browser"
|
|
||||||
resolution: "Approved in 10-UAT.md test 3."
|
|
||||||
- test: "Collection editors link/unlink round trip"
|
|
||||||
expected: "Picker 5 per page, owner excluded, Dodaj (N) disabled at 0, plural toast, confirm unlink, focus trap and Esc, no manager on create"
|
|
||||||
why_human: "Real browser round trip, focus trap and Esc"
|
|
||||||
resolution: "Approved in 10-UAT.md test 4."
|
|
||||||
- test: "Visual check in light/dark at desktop and about 900px"
|
|
||||||
expected: "Matches design/, dark sidebar, rail collapse and flyout below about 1100px"
|
|
||||||
why_human: "Visual appearance and responsive behavior"
|
|
||||||
resolution: "Approved in 10-UAT.md test 5, before and after the full-width form change (2585671)."
|
|
||||||
- test: "Secure cookie on http://localhost (assumption A3)"
|
|
||||||
expected: "Chrome and Firefox store summer_admin with default cookie_secure"
|
expected: "Chrome and Firefox store summer_admin with default cookie_secure"
|
||||||
why_human: "Browser cookie policy, non-inferable"
|
why_human: "Browser cookie policy, non-inferable"
|
||||||
resolution: "Approved in 10-UAT.md test 6."
|
resolution: "Approved in 10-UAT.md test 6. The cookie attributes (cabana auth.go) are unchanged in substance since then. Still resolved."
|
||||||
- test: "Review the 17 judgment-tier prohibitions"
|
- test: "Carried: review the 17 judgment-tier prohibitions"
|
||||||
expected: "Accept or reject the verifier's non-authoritative verdicts"
|
expected: "Accept or reject the verifier's non-authoritative verdicts"
|
||||||
why_human: "Judgment-tier prohibitions need human resolution"
|
why_human: "Judgment-tier prohibitions need human resolution"
|
||||||
resolution: "All 17 'not violated' verdicts accepted in 10-UAT.md test 7."
|
resolution: "Accepted in 10-UAT.md test 7. Re-checked against HEAD in this report and all are still not violated, so the acceptance carries over."
|
||||||
---
|
---
|
||||||
|
|
||||||
# Phase 10: Admin Vue SPA Verification Report
|
# Phase 10: Admin Vue SPA Verification Report
|
||||||
|
|
||||||
**Phase Goal:** A minimal Vue 3 + TypeScript admin SPA renders login, permission-gated navigation, lists, forms and the relation manager for Albums, Artists, Collections, Genres and Styles, typed from the generated OpenAPI document.
|
**Phase Goal:** A minimal Vue 3 + TypeScript admin SPA renders login, permission-gated navigation, lists, forms and the relation manager for Albums, Artists, Collections, Genres and Styles, typed from the generated OpenAPI document.
|
||||||
**Verified:** 2026-09-27T18:43:00Z (summercms.go HEAD c7487f6, fonoteka.go HEAD 3359a83)
|
**Verified:** 2026-10-01T21:29:59Z (summercms.go HEAD f2f2279, fonoteka.go HEAD e62f4fc)
|
||||||
**Status:** passed
|
**Status:** human_needed
|
||||||
**Re-verification:** Yes. The previous report (f47a560, human_needed) went stale when CR-01 was fixed (be4a923, a13a121) and the forms became full width (2585671).
|
**Re-verification:** Yes. The previous report (c7487f6, passed) went stale. Phase 10.2 moved its 59 framework paths under `modules/`, and later phases changed covered code.
|
||||||
|
|
||||||
**MVP note:** ROADMAP marks this phase `mode: mvp`, but the goal is not a User Story. Following the precedent of Phases 1, 3, 5 and 8, the four ROADMAP success criteria are the contract and plan `must_haves` are supporting evidence.
|
**MVP note:** ROADMAP marks this phase `mode: mvp`, but the goal is not a User Story. Following the precedent of Phases 1, 3, 5 and 8, the four ROADMAP success criteria are the contract and plan `must_haves` are supporting evidence.
|
||||||
|
|
||||||
## What changed since the previous verification
|
## What changed since the previous verification
|
||||||
|
|
||||||
| Commit | Change | Effect on this report |
|
| Source | Change to covered code | Effect on this report |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| be4a923 | `cabana/auth.go` refresh calls `bouncer.RefreshAudienceFor(r.Context(), s.users, ...)`. `s.users` is the same `lazyBackendUsers` provider the backend guard uses (`cabana/http.go`). A refusal of the subject over cookie transport expires `summer_admin`. `bouncer/refresh.go` runs `subjectPrincipal` and `issuedBeforeCutoff` after every token-only check and before minting. `Refresh` and `RefreshAudience` pass a nil hook, so their behavior is unchanged. | Closes the CR-01 escalation. The diff was read, and the named tests were re-run (see Spot-Checks). |
|
| Phase 10.2 (5e50b16, 57e7b56) | Framework packages moved to `modules/<pkg>`. Moves only, plus retargeted fixtures. | 59 covered paths re-mapped. No behavior change. |
|
||||||
| a13a121 | Adds `TestRefreshAudienceForSubject`, a `TestJWTGuardTokensValidAfter` pin, and a `TestPhase10Coverage` subtest for cookie expiry on subject refusal | Behavioral evidence for the fix |
|
| Phase 10.1 (f928194..5bbb0ad) | Runtime extension point. The SPA gains `WidgetField`, `PartialField`, `PartialHost` with an allowlisted node renderer, `pluginAssets.ts`, toolbar actions in `ListToolbar.vue`, and plugin CSS scoped per controller in `router.ts`. `ListView.vue`, `FormView.vue`, `FormField.vue` and `registry.ts` were extended. cabana gains action and asset routes. The OpenAPI document and `schema.d.ts` were regenerated (+516 / +325 lines, additive). The dist was rebuilt. | Phase 10 tests still pass, together with the new ones (Vitest went from 441 to 681). The drift gates are clean. The changed views need a browser re-check, so a human item is open. |
|
||||||
| 2585671 | `FormView.vue` and `SettingsFormView.vue` drop `mx-auto max-w-[980px]`. The dist was rebuilt. | CSS only. The dist drift gate and the 441 Vitest tests re-run clean. |
|
| Phase 11 (f7b6b0c, 93c735b, 5382947, 61da4d1) | cabana writes are commit-safe, transaction gates fail closed, the jwt.auth 401 gets a cache header, and the Phase 10 gate accepts the Phase 12 pending goldens | `go test` and the gate stages pass |
|
||||||
| c7487f6 | 10-REVIEW.md re-review (0 open critical), 10-UAT.md complete (7/7 pass), disposition updated | Human verification closed |
|
| Phase 9 review fixes (b4b8b5d..4ae272e, 2da8112) | WR-01 wildcard permissions, WR-02 drops a denied main menu item and repoints its target, WR-17 merges an admin's own permissions over the role's, WR-03 and WR-05 refuse writes and relation link/unlink that are not declared, WR-14 mounts logout outside the guard and always clears the cookie, WR-11 case-insensitive unique emails, WR-19 TxFromContext | Re-checked against the SPA's contract: the assembled acceptance test (exact nav sets, CRUD, link/unlink, logout) and the named cabana tests pass |
|
||||||
|
|
||||||
## User Flow Coverage
|
## User Flow Coverage
|
||||||
|
|
||||||
Derived user story: *As a Płytarium admin, I want to log in to /plytadmin, see only what my role permits, and manage Albums, Artists, Collections, Genres, Styles and Collection editors, so that the catalogue can be administered without the PHP backend.*
|
Derived user story: *As a Płytarium admin, I want to log in to /plytadmin, see only what my role permits, and manage Albums, Artists, Collections, Genres, Styles and Collection editors, so that the catalogue can be administered without the PHP backend.*
|
||||||
|
|
||||||
| Step | Expected | Evidence | Status |
|
| Step | Expected | Evidence (this session) | Status |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| Open /plytadmin | Embedded SPA served with base /plytadmin | `boardwalk/boardwalk.go`, `TestPhase10TracerSPA` (re-run: PASS), `check-admin-dist.sh` (re-run: dist matches a fresh build) | VERIFIED |
|
| Open /plytadmin | Embedded SPA served with base /plytadmin | `modules/boardwalk/boardwalk.go`, `TestPhase10TracerSPA` PASS, `check-admin-dist.sh` "matches a fresh build" | VERIFIED |
|
||||||
| Log in | Cookie session, no token in body | `cabana/auth.go` login, `useAuth.login`, `TestPhase10AdminAuth`, `LoginView.test.ts`; UAT test 6 (Secure cookie on localhost) | VERIFIED |
|
| Log in | Cookie session, no token in body | `modules/cabana/auth.go` login, `useAuth.login`, `LoginView.test.ts` (Vitest PASS), `TestPhase10Coverage` PASS | VERIFIED |
|
||||||
| See permitted navigation | Limited admin sees Genres only | `TestPhase10AssembledAcceptance` SC-1 (re-run: PASS); UAT test 2 | VERIFIED |
|
| See permitted navigation | Limited admin sees Genres only | `TestPhase10AssembledAcceptance` SC-1 PASS (exact nav sets) and `TestNavigationDropsDeniedParentAndRepointsTarget` PASS | VERIFIED (automated); browser re-check pending |
|
||||||
| Use five lists and forms | Schema-driven list and form, create, update | `TestPhase10AssembledAcceptance` SC-2, `TestPhase10Controllers` (re-run: PASS), ListView/FormView tests; UAT test 3 | VERIFIED |
|
| Use five lists and forms | Schema-driven list and form, create, update | `TestPhase10AssembledAcceptance` SC-2 and `TestPhase10Controllers` PASS, ListView/FormView Vitest PASS | VERIFIED (automated); browser re-check pending |
|
||||||
| Link and unlink an editor | Search candidates, link, unlink | `TestPhase10AssembledAcceptance` SC-3, `relation.smoke.test.ts`; UAT test 4 | VERIFIED |
|
| Link and unlink an editor | Search candidates, link, unlink | `TestPhase10AssembledAcceptance` SC-3 PASS, `relation.smoke.test.ts` PASS | VERIFIED (automated); browser re-check pending |
|
||||||
| Stay signed in / be signed out | Refresh keeps an active session; a reset, deactivation or deletion ends it | `TestAdminRefreshRevocation` (re-run on Postgres: 5/5 subtests PASS) | VERIFIED |
|
| Stay signed in / be signed out | Refresh keeps an active session; reset, deactivation or deletion ends it | `TestAdminRefreshRevocation` PASS | VERIFIED |
|
||||||
| Log out | Cookie expired, old cookie 401 | `TestPhase10AssembledAcceptance` (logout then /auth/me 401) | VERIFIED |
|
| Log out | Cookie expired, old cookie 401, works with an expired access token | Acceptance test (logout then /auth/me 401) and `TestAdminLogoutRevokesExpiredRefreshableToken` PASS | VERIFIED |
|
||||||
|
|
||||||
## Goal Achievement
|
## Goal Achievement
|
||||||
|
|
||||||
@@ -299,84 +287,68 @@ Derived user story: *As a Płytarium admin, I want to log in to /plytadmin, see
|
|||||||
|
|
||||||
| # | Truth | Status | Evidence |
|
| # | Truth | Status | Evidence |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| 1 | An admin logs in through the SPA and sees only the navigation items their permissions allow. | ✓ VERIFIED | Server: `TestPhase10AssembledAcceptance` asserts the limited admin's nav is exactly `fonoteka:[genres]` and the developer's is `albums,collections,genres,styles,artists`, that the limited admin gets 403 on albums, and that the limited admin gets an empty settings list. Re-run this session on testcontainers Postgres: PASS. SPA: `useNavigation.ts` stores `/navigation` verbatim. `railEntries` drops only plugins whose side menu is empty (D-11). Tests: `PluginRail.test.ts`, `SectionPanel.test.ts`, `tracer.smoke.test.ts`. Real browser: UAT test 2 approved with a superuser and a genres-only admin. The CR-01 fix makes the session end correctly on reset (`TestAdminRefreshRevocation`). |
|
| 1 | An admin logs in through the SPA and sees only the navigation items their permissions allow. | ✓ VERIFIED | Server: `TestPhase10AssembledAcceptance` (fonoteka, Postgres) asserts the limited admin's nav is exactly `fonoteka:[genres]`, the developer's is `albums,collections,genres,styles,artists`, the limited admin gets 403 on albums and an empty settings list. It passes at HEAD with the Phase 9 WR-01/WR-02/WR-17 permission changes in place. `TestNavigationDropsDeniedParentAndRepointsTarget`: PASS. SPA: `useNavigation.ts`, `PluginRail.vue` and `SectionPanel.vue` are unchanged since c7487f6. Their Vitest tests pass. |
|
||||||
| 2 | Each of the five controllers renders a working list and form generated from its JSON schema. | ✓ VERIFIED | Server: the SC-2 loop in `TestPhase10AssembledAcceptance` and `TestPhase10Controllers` (fields and columns equal the tracked YAML). Both re-run: PASS. SPA: `ListView.vue` loads `/schema/list` and the list. `FormView.vue` loads `/schema/form` and the record, then POSTs or PUTs. The full-width change (2585671) touches only the section's class attribute. Vitest re-run: 48 files, 441 passed. Real browser: UAT test 3 approved. WR-05 (loaders without try/catch) is still open as a warning. |
|
| 2 | Each of the five controllers renders a working list and form generated from its JSON schema. | ✓ VERIFIED | Server: the SC-2 loop and `TestPhase10Controllers` (fields and columns equal the tracked YAML) pass. `TestCRUDOperationsFollowDeclarations` (Phase 9 WR-03) passes, and SC-2's create and update still succeed under it. SPA: `ListView.vue` still loads `/schema/list` and the list, and `FormView.vue` still loads `/schema/form` and the record and then POSTs or PUTs. 10.1 adds toolbar actions, widgets, partials and plugin CSS on top. `ListView.test.ts` (+171 lines) and `FormView.test.ts` (+144) pass with the original Phase 10 cases intact. Vitest: 53 files, 681 passed. Browser confirmation of the changed views is the open human item. |
|
||||||
| 3 | The Collections form's relation manager lets an admin search, link and unlink an editor. | ✓ VERIFIED | Server: the SC-3 block covers candidates with the owner excluded, link, list, the linked user dropping out of the candidates, unlink, and an empty list afterwards (re-run: PASS). SPA: `RelationManager.vue` and `RelationPickerModal.vue`, registered as `relation-manager` and shown in update mode only. Tests: `RelationManager.test.ts`, `RelationPickerModal.test.ts`, `relation.smoke.test.ts`. Real browser: UAT test 4 approved. |
|
| 3 | The Collections form's relation manager lets an admin search, link and unlink an editor. | ✓ VERIFIED | Server: the SC-3 block covers candidates with the owner excluded, link, list, the linked user dropping out of the candidates, unlink, and an empty list afterwards. It passes with Phase 9 WR-05 (undeclared link/unlink refused) in place. SPA: `RelationManager.vue` and `RelationPickerModal.vue` are unchanged since c7487f6, and their tests and `relation.smoke.test.ts` pass. |
|
||||||
| 4 | API calls in the SPA use TypeScript types generated from the OpenAPI document, with no hand-maintained duplicate type. | ✓ VERIFIED | `client.ts` is `createClient<paths>` over the generated `schema.d.ts`. `admin/src` has no other `fetch(`. `types.ts` contains only aliases onto `components['schemas']`, and the hygiene gate enforces that. `check-admin-openapi.sh --check` re-run: exit 0. The CR-01 fix changed no route or response shape, and the document did not drift. Info: `controllerRoutes.ts` has a local `ControllerParams` interface. It parses route ids and is not an API payload. |
|
| 4 | API calls in the SPA use TypeScript types generated from the OpenAPI document, with no hand-maintained duplicate type. | ✓ VERIFIED | `client.ts` is `createClient<paths>` over the generated `schema.d.ts`. `admin/src` has no other `fetch(`, and `pluginAssets.ts` loads same-origin assets through elements, not a fetch. `types.ts` (+12 lines for the 10.1 types) still contains only aliases onto `components['schemas']` and `paths[...]`. `check-admin-openapi.sh --check`: exit 0. `check-phase10.sh --hygiene`: passed. |
|
||||||
|
|
||||||
**Score:** 4/4 ROADMAP truths verified (0 present-but-behavior-unverified).
|
**Score:** 4/4 ROADMAP truths verified (0 present-but-behavior-unverified).
|
||||||
|
|
||||||
### Plan must-have truths (supporting evidence)
|
### Plan must-have truths (supporting evidence)
|
||||||
|
|
||||||
There are 46 plan truths across 10-01..10-05. 45 were verified by named, passing tests or gates in the previous run, and their files are unchanged apart from the two form views and the refresh path. Those two are covered again below.
|
There are 46 plan truths across 10-01..10-05. The earlier runs verified all of them, with A3 human-observed. Their evidence is the named tests and gates, and all of those were re-run this session as part of `go test ./...` (summercms.go), the fonoteka Phase 10 acceptance tests, Vitest, the dist and OpenAPI drift gates, and the gate stages `--self-test`, `--hygiene`, `--security` and `--evidence`. All of them pass. The renamed packages carry the same tests: `modules/cabana/phase10_*_test.go`, `modules/phrasebook/phase10_test.go`, `modules/surf/admin_prefix_test.go` and the others in covered_files.
|
||||||
|
|
||||||
The 46th is backstop truth A3: browsers accept the Secure admin cookie on http://localhost. The previous run abstained on it as `insufficient_spec`. It is now closed by directly observed behavior: in UAT test 6 the user ran the fonoteka binary at http://localhost:8080/plytadmin with the default `cookie_secure`, and the session worked.
|
|
||||||
|
|
||||||
The refresh path affects truths that touch cookie refresh (10-01 cookie auth, T-10-05). These were re-checked with `TestPhase10Coverage` (PASS), `TestAdminRefreshRevocation` (PASS, Postgres) and `TestRefreshAudienceForSubject` (PASS). The quick task's removal check (run with the check hook set to nil) makes both unit tests fail, so the tests do exercise the hook.
|
|
||||||
|
|
||||||
Backstop (non-inferable) truths:
|
Backstop (non-inferable) truths:
|
||||||
|
|
||||||
| Truth | Evidence | Status |
|
| Truth | Evidence | Status |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| A1 default prefix /backend; fonoteka /plytadmin | `DefaultAdminPrefix = "/backend"`, `TestPhase10Prefix`, fonoteka `config/backend.yaml uri: /plytadmin` | VERIFIED |
|
| A1 default prefix /backend; fonoteka /plytadmin | `modules/cabana/prefix.go` `DefaultAdminPrefix`, `TestPhase10Prefix` in the passing cabana run | VERIFIED |
|
||||||
| A3 Secure cookie accepted on http://localhost | 10-UAT.md test 6: pass (observed in a real browser) | VERIFIED (human-observed) |
|
| A3 Secure cookie accepted on http://localhost | 10-UAT.md test 6 (human-observed). The cookie attributes are unchanged in substance. | VERIFIED (human-observed) |
|
||||||
| A10 30 s blacklist grace plus single-flight refresh | `config/admin.yaml blacklist_grace: 30`, `client.test.ts` single-flight cases | VERIFIED |
|
| A10 30 s blacklist grace plus single-flight refresh | `modules/cabana/auth.go` reads `admin.jwt.blacklist_grace`, fonoteka `config/admin.yaml`, `client.test.ts` (Vitest PASS) | VERIFIED |
|
||||||
| A8 pivot sort_order = array index | `admin_phase10_relations_test.go` sort_order assertions | VERIFIED |
|
| A8 pivot sort_order = array index | fonoteka `admin_phase10_relations_test.go` (package passes) | VERIFIED |
|
||||||
| fonoteka has no RelationExtendOptionsQuery | no implementation in fonoteka; the hook is proven with acme fixtures | VERIFIED |
|
| Required relation is a schema hint only | `TestPhase10RelationSave` PASS | VERIFIED |
|
||||||
| Required relation is a schema hint only | Phase 9 decision 304 tests plus `TestPhase10RelationSave` | VERIFIED |
|
| A6 dark mode follows the system only | `theme.ts`, `theme.test.ts` PASS | VERIFIED |
|
||||||
| A6 dark mode follows the system only | `theme.ts` matchMedia, `theme.test.ts`; UAT test 5 | VERIFIED |
|
| SC-4 mechanical enforcement | `check-phase10.sh --hygiene` PASS | VERIFIED |
|
||||||
| SC-4 mechanical enforcement | `check-phase10.sh` hygiene rules | VERIFIED |
|
|
||||||
|
|
||||||
### Prohibitions (judgment tier)
|
### Prohibitions (judgment tier)
|
||||||
|
|
||||||
All 17 verdicts from the previous report were "not violated", and the user accepted them in 10-UAT.md test 7. The changes since then do not touch what they cover. The CR-01 fix adds no app names, no token in a response body and no new route. The CSS change adds no `v-html` and no foreign-origin asset. The one qualified verdict from before was the 05 prohibition "High threats cite an executable test or gate", which was only formally met. It is now met outright: the T-10-05 row in 10-SECURITY-REVIEW.md cites `TestAdminRefreshRevocation` and `TestRefreshAudienceForSubject`, and its residual-risk text now describes revocation on reset, deactivation and deletion accurately, with WR-07 named as the remaining sliding-window risk.
|
All 17 verdicts were accepted in 10-UAT.md test 7. I re-checked them against the code that changed since:
|
||||||
|
|
||||||
| Plan | Prohibition | Verdict |
|
- No Płytarium or fonoteka names appear in `admin/src`, `admin/tests`, `admin/openapi` or `modules/boardwalk/dist`. A grep came back empty, and the hygiene gate passes.
|
||||||
|---|---|---|
|
- `admin/src` has no `v-html` or `innerHTML`. The 10.1 partials are built from an allowlisted node tree with `h()`, and text is always text (`partialNodes.ts`). Plugin labels and comments are still rendered as text.
|
||||||
| 01 | No Płytarium/fonoteka names in summercms.go SPA, fixtures, document or dist | not violated (human-accepted) |
|
- Plugin JS and CSS come from cabana's same-origin asset route, so nothing loads from a foreign origin.
|
||||||
| 01 | Cookie login/refresh never carries the JWT; the SPA never reads or stores it | not violated (human-accepted; the refresh cookie path still returns `token_type: cookie` only) |
|
- The cookie login and refresh paths still never return the JWT in a body.
|
||||||
| 01 | No foreign-origin fonts, icons or scripts | not violated (human-accepted) |
|
- Phase 9 WR-03 and WR-05 tighten "relation save never writes a protected FK or an out-of-scope id". They do not weaken it.
|
||||||
| 01 | Non-admin routes and the parity doc change only by dropping admin paths | not violated (human-accepted) |
|
|
||||||
| 02 | Relation save never writes a protected FK or an out-of-scope id | not violated in declared config (human-accepted; WR-02 open) |
|
All 17 remain not violated, and the human acceptance carries over.
|
||||||
| 02 | Public bundle exposes only backend::lang | not violated (human-accepted) |
|
|
||||||
| 02 | Framework never names a plugin table, pivot or FK | not violated (human-accepted) |
|
|
||||||
| 02 | Phase 9 security assertions not weakened | not violated; strengthened by the CR-01 fix, which restores T-09-04 for admin sessions |
|
|
||||||
| 03 | Plugin text rendered as text only | not violated (human-accepted) |
|
|
||||||
| 03 | No hand-written API payload shapes | not violated (human-accepted) |
|
|
||||||
| 03 | SPA does not hide or add nav, actions or fields | not violated (human-accepted) |
|
|
||||||
| 03 | Winter URLs not used verbatim | not violated (human-accepted) |
|
|
||||||
| 04 | SPA does not filter candidates itself | not violated (human-accepted) |
|
|
||||||
| 04 | localStorage holds only the sidebar preference | not violated (human-accepted) |
|
|
||||||
| 05 | Acceptance does not depend on skips, zero-test runs or hand-edited dist/types | not violated (dist and openapi drift re-run clean) |
|
|
||||||
| 05 | No app names in summercms.go tests | not violated (human-accepted) |
|
|
||||||
| 05 | High threats cite an executable test or gate | not violated (T-10-05 now cites the revocation tests) |
|
|
||||||
|
|
||||||
### Required Artifacts
|
### Required Artifacts
|
||||||
|
|
||||||
All 30 plan artifacts passed `verify.artifacts` in the previous run, and none was deleted. Changed or added since then:
|
|
||||||
|
|
||||||
| Artifact | Status | Details |
|
| Artifact | Status | Details |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `bouncer/refresh.go` (`RefreshAudienceFor`) | ✓ VERIFIED | Substantive, and wired from `cabana/auth.go:224`. `Refresh` and `RefreshAudience` keep their signatures and pass a nil hook, so the core user plugin contract is unchanged. |
|
| `admin/` SPA (views, components, state, api, app) | ✓ VERIFIED | It exists, has substance and is wired, and it is embedded via `modules/boardwalk/dist`, which matches a fresh build |
|
||||||
| `bouncer/jwt.go` (`subjectPrincipal`, `issuedBeforeCutoff`, `ErrSubjectRejected`) | ✓ VERIFIED | Shared by the guard and refresh |
|
| `admin/openapi/admin.json`, `admin/src/api/schema.d.ts`, `admin/src/api/types.ts` | ✓ VERIFIED | No drift from generation |
|
||||||
| `cabana/auth.go`, `cabana/http.go` | ✓ VERIFIED | `service.users` is the guard's `lazyBackendUsers` |
|
| `modules/boardwalk/boardwalk.go` + `dist/` | ✓ VERIFIED | `TestPhase10TracerSPA` PASS |
|
||||||
| `cabana/refresh_revocation_test.go`, `bouncer/refresh_test.go`, `bouncer/jwt_guard_test.go` | ✓ VERIFIED | Re-run: PASS |
|
| `modules/cabana/{auth,http,crud,relation,relation_field,form_schema,list_schema,filter_schema,schema_types,registry,contracts,csrf,lang,messages,prefix,admin_openapi}.go` | ✓ VERIFIED | Moved under modules/ and changed by 10.1, 11 and the Phase 9 fixes. The cabana package passes. |
|
||||||
| `admin/src/views/FormView.vue`, `SettingsFormView.vue` + `boardwalk/dist` | ✓ VERIFIED | CSS class change only; the dist matches a fresh build |
|
| `modules/bouncer/{jwt,refresh}.go` | ✓ VERIFIED | `RefreshAudienceFor` still wired from `modules/cabana/auth.go`. The new WR-14 logout helper is additive. |
|
||||||
| `../fonoteka.go/plugins/golem15/fonoteka/admin_phase10_*_test.go` | ✓ VERIFIED | Unchanged at 3359a83. Acceptance, tracer and controllers re-run: PASS |
|
| `modules/pact/capabilities.go`, `modules/phrasebook/*`, `modules/surf/router.go` | ✓ VERIFIED | Packages pass |
|
||||||
| All other artifacts from 10-01..10-05 | ✓ VERIFIED | Unchanged since the previous run |
|
| `scripts/check-phase10.sh`, `check-admin-dist.sh`, `check-admin-openapi.sh` | ✓ VERIFIED | Retargeted to `modules/` paths, and every stage run passes |
|
||||||
|
| `../fonoteka.go/plugins/golem15/fonoteka/admin_phase10_*_test.go` | ✓ VERIFIED | At e62f4fc: Acceptance, Tracer and Controllers PASS |
|
||||||
|
|
||||||
### Key Link Verification
|
### Key Link Verification
|
||||||
|
|
||||||
The previous run checked all 19 links (16 by the tool, 3 traced by hand), and all were WIRED. The one new link:
|
|
||||||
|
|
||||||
| From | To | Via | Status |
|
| From | To | Via | Status |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| `cabana/auth.go` refresh | `bouncer.RefreshAudienceFor` → the guard's `UserProvider` | `s.users` set from the same `lazyBackendUsers` value passed to `NewBackendJWTGuard` (`cabana/http.go:113,137`) | WIRED |
|
| `admin/src/api/client.ts` | generated `schema.d.ts` | `createClient<paths>`, the only `fetch(` in `admin/src` | WIRED |
|
||||||
| `bouncer/refresh.go` check hook | `subjectPrincipal` / `issuedBeforeCutoff` | closure passed as `check` to `refreshAudience`, called before `MintAudience` | WIRED |
|
| `admin/src/state/useAuth.ts` logout | `POST /auth/logout` | `modules/cabana/http.go:205`, now mounted outside the guard with `requireAjax`. The client sets `X-Requested-With` on every request (`client.ts:71`). | WIRED |
|
||||||
|
| `modules/cabana/auth.go` refresh | `bouncer.RefreshAudienceFor` → the guard's `UserProvider` | `s.users` (`lazyBackendUsers`) | WIRED |
|
||||||
|
| `admin/src/views/ListView.vue` / `FormView.vue` | `/schema/list`, `/schema/form`, records | client calls (10.1 additions on top) | WIRED |
|
||||||
|
| `RelationManager.vue` | `/relations/{name}`, `/candidates` | client calls | WIRED |
|
||||||
|
| `modules/boardwalk` | `admin` build | `go:embed dist`, drift gate | WIRED |
|
||||||
|
|
||||||
### Data-Flow Trace (Level 4)
|
### Data-Flow Trace (Level 4)
|
||||||
|
|
||||||
These are unchanged from the previous run. Every flow is ✓ FLOWING:
|
These are unchanged in structure. Every flow is ✓ FLOWING:
|
||||||
|
|
||||||
- navigation comes from `GET /navigation`, filtered on the server
|
- navigation comes from `GET /navigation`, filtered on the server
|
||||||
- list rows and columns come from the list endpoint and `/schema/list`
|
- list rows and columns come from the list endpoint and `/schema/list`
|
||||||
@@ -388,80 +360,75 @@ These are unchanged from the previous run. Every flow is ✓ FLOWING:
|
|||||||
|
|
||||||
| Behavior | Command | Result | Status |
|
| Behavior | Command | Result | Status |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| CR-01: reset, deactivation and deletion end admin refresh | `go test -count=1 -v -run '^TestAdminRefreshRevocation$' ./cabana/` | 5/5 subtests PASS (pre-reset cookie refused and expired, pre-reset Bearer refused, deactivated, soft-deleted, active still refreshes) | ✓ PASS |
|
| Vet | `go vet ./...` (summercms.go) | exit 0 | ✓ PASS |
|
||||||
| RefreshAudienceFor unit and guard pin | `go test -count=1 -run '^(TestRefreshAudienceForSubject\|TestJWTGuardTokensValidAfter)$' ./bouncer/` | ok | ✓ PASS |
|
| Full Go suite | `go test -count=1 ./...` (summercms.go), run once | Most packages ok. Eight packages failed only because testcontainers Postgres did not start within the timeout (`context deadline exceeded`, and one `internal/dev` watch timeout) while Vitest and other suites shared the machine: docs/examples/blog, internal/dev, beachcomber, bouncer, cabana, conga, lagoon/attach, lighthouse. | see re-run |
|
||||||
| Cookie refresh coverage (incl. expiry on subject refusal) | `go test -count=1 -run '^TestPhase10Coverage$' ./cabana/` | ok | ✓ PASS |
|
| Re-run of those 8 packages serially | `go test -count=1 -p 1 <8 pkgs>` | all 8 ok, exit 0 | ✓ PASS |
|
||||||
| SC-1..SC-4 assembled on Postgres plus tracer and controllers | `go test -count=1 -run '^(TestPhase10AssembledAcceptance\|TestPhase10TracerSPA\|TestPhase10Controllers)$' ./plugins/golem15/fonoteka/` (fonoteka.go) | ok 6.8s | ✓ PASS |
|
| Logout, nav, refresh, CRUD gating, Phase 10 coverage | `go test -count=1 -run '^(TestAdminLogoutRevokesExpiredRefreshableToken\|TestNavigationDropsDeniedParentAndRepointsTarget\|TestAdminRefreshRevocation\|TestPhase10Coverage\|TestCRUDOperationsFollowDeclarations)$' ./modules/cabana/` | all PASS | ✓ PASS |
|
||||||
| SPA unit/component suite | `npx vitest run` (admin) | 48 files, 441 passed | ✓ PASS |
|
| SC-1..SC-3 assembled on Postgres plus tracer and controllers | `go test -count=1 -run '^(TestPhase10AssembledAcceptance\|TestPhase10TracerSPA\|TestPhase10Controllers)$' ./plugins/golem15/fonoteka/` (fonoteka.go) | 3 PASS, ok 6.6s | ✓ PASS |
|
||||||
| Embedded dist drift | `scripts/check-admin-dist.sh` | vue-tsc clean, "boardwalk/dist matches a fresh build" | ✓ PASS |
|
| SPA unit/component suite | `npx vitest run` (admin) | 53 files, 681 passed | ✓ PASS |
|
||||||
|
| Embedded dist drift (incl. vue-tsc) | `scripts/check-admin-dist.sh` | "modules/boardwalk/dist matches a fresh build" | ✓ PASS |
|
||||||
| OpenAPI and types drift | `scripts/check-admin-openapi.sh --check` | exit 0 | ✓ PASS |
|
| OpenAPI and types drift | `scripts/check-admin-openapi.sh --check` | exit 0 | ✓ PASS |
|
||||||
| Phase gate | `scripts/check-phase10.sh --all` (orchestrator, after the changes) | exit 0, "phase10 all passed", the two pre-existing parity failures allow-listed by name | ✓ PASS |
|
| Phase gate stages | `scripts/check-phase10.sh --self-test / --hygiene / --security / --evidence` | each exit 0 | ✓ PASS |
|
||||||
|
|
||||||
### Probe Execution
|
### Probe Execution
|
||||||
|
|
||||||
No `probe-*.sh` scripts are declared or present. `check-phase10.sh` is the phase gate. The orchestrator ran it, and I re-ran its sub-gates (openapi, dist) and its key tests.
|
No `probe-*.sh` scripts are declared or present. `check-phase10.sh` is the phase gate. Its stages were run as listed above. Its `--go`, `--postgres`, `--spa`, `--openapi` and `--dist` stages were covered directly by the full Go run with the serial re-run, the fonoteka tests, Vitest and the two drift scripts.
|
||||||
|
|
||||||
### Requirements Coverage
|
### Requirements Coverage
|
||||||
|
|
||||||
| Requirement | Source Plan | Description | Status | Evidence |
|
| Requirement | Source Plan | Description | Status | Evidence |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
| ADMIN-06 | 10-01..10-05 | Minimal Vue 3 + TS SPA renders login, permission-gated navigation, lists, forms and the relation manager for the five controllers using generated types | ✓ SATISFIED | Truths 1-4, UAT 7/7. REQUIREMENTS.md marks it `[x]` and Complete. |
|
| ADMIN-06 | 10-01..10-05 | Minimal Vue 3 + TS SPA renders login, permission-gated navigation, lists, forms and the relation manager for the five controllers using generated types | ✓ SATISFIED (automated); browser re-check pending | Truths 1-4 |
|
||||||
|
|
||||||
Orphaned requirements: none. ADMIN-06 is the only ID REQUIREMENTS.md maps to Phase 10.
|
Orphaned requirements: none.
|
||||||
|
|
||||||
### Decision Coverage
|
### Decision Coverage
|
||||||
|
|
||||||
All 28 trackable CONTEXT.md decisions are honored (unchanged since the previous run).
|
All 28 trackable CONTEXT.md decisions are honored (no decision was reverted by the later phases).
|
||||||
|
|
||||||
### Anti-Patterns Found
|
### Anti-Patterns Found
|
||||||
|
|
||||||
| File | Line | Pattern | Severity | Impact |
|
| File | Pattern | Severity | Impact |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|
|
||||||
| `cabana/auth.go` | refresh | CR-01 | resolved | Fixed in be4a923 and a13a121; verified above |
|
| `modules/cabana/auth.go`, `http.go` | Phase 10 review WR-01: logout behind the guard | resolved | Fixed by Phase 9 WR-14 (299d220) |
|
||||||
| `bouncer/refresh.go`, fonoteka `golem15/user` api_controller | — | WR-08: the frontend user refresh still ignores tokens_valid_after | ⚠️ Warning | Site-user audience, outside the Phase 10 contract. Deliberately left unchanged to keep the core user plugin's contract. Needs a parity check against PHP first. |
|
| `modules/bouncer/refresh.go`, fonoteka `golem15/user` | WR-08: the site-user refresh ignores tokens_valid_after | ⚠️ Warning | Outside the Phase 10 contract. Core user plugin contract kept. |
|
||||||
| `cabana/auth.go`, `cabana/http.go` | — | WR-01: logout behind the guard does not expire a rejected cookie | ⚠️ Warning | Open, non-blocking |
|
| `modules/cabana/relation_field.go`, `crud.go` | WR-02 and WR-03 (Phase 10 review) | ⚠️ Warning | Phase 9 WR-03 and WR-05 now refuse undeclared writes and link/unlink. Not re-triaged here. |
|
||||||
| `cabana/relation_field.go`, `crud.go` | — | WR-02 and WR-03 | ⚠️ Warning | Not reachable with the current fonoteka YAML |
|
| `modules/pact/capabilities.go` | WR-04: `FilterOptions(scope)` has no ctx or db | ⚠️ Warning | Open |
|
||||||
| `pact/capabilities.go` | — | WR-04: `FilterOptions(scope)` has no ctx or db | ⚠️ Warning | Open |
|
| `admin/src/views/*.vue` | WR-05: loaders without try/catch | ⚠️ Warning | Open |
|
||||||
| `admin/src/views/*.vue` and others | — | WR-05: loaders have no try/catch | ⚠️ Warning | A network failure leaves the skeleton spinning |
|
| `ListView.vue`, `RelationManager.vue` | WR-06: no page clamp after delete or unlink | ⚠️ Warning | Open |
|
||||||
| `ListView.vue`, `RelationManager.vue` | — | WR-06: no page clamp after delete or unlink | ⚠️ Warning | Open |
|
| `modules/bouncer/refresh.go` | WR-07: the refresh window slides with no absolute cap | ⚠️ Warning | Residual risk in T-10-05 |
|
||||||
| `bouncer/refresh.go` | — | WR-07: the refresh window slides with no absolute cap | ⚠️ Warning | Named as residual risk in T-10-05 |
|
|
||||||
| — | — | IN-01..IN-10 in 10-REVIEW.md | ℹ️ Info | Open, non-blocking |
|
|
||||||
|
|
||||||
No `TBD`, `FIXME` or `XXX` markers are in any file changed since the previous verification (`bouncer/jwt.go`, `bouncer/refresh.go`, `cabana/auth.go`, `cabana/http.go`, the new tests, and the two form views). The previous run found none in the rest of the Phase 10 files.
|
None of the non-planning covered files contains an unreferenced `TBD`, `FIXME` or `XXX` marker (grep came back empty).
|
||||||
|
|
||||||
### Other observations (Info)
|
### Other observations (Info)
|
||||||
|
|
||||||
- The summercms.go working tree is clean apart from `.planning/milestone.lock`, `.planning/state.json`, `.gsd/` and `go.work.sum`. None of these is Phase 10 code. The uncommitted `examples/hello/main.go` change noted in the previous report is gone.
|
- Phase 10.1's own UAT (10.1-UAT.md) is still `status: testing` with 6 items pending. Its tests 1 and 4 overlap the open Phase 10 human item.
|
||||||
- Two fonoteka `parity` tests have failed since Phase 9 (deferred-items.md). The gate allow-lists them by name and refuses once either passes.
|
- The summercms.go working tree has an uncommitted change to `.planning/phases/10.2-.../10.2-VERIFICATION.md` that this verifier did not make (another run in progress), plus the untracked `SummerCMS landing page.zip`. Neither is Phase 10 code.
|
||||||
- The quick task saw one-off load flakes in fonoteka `golem15/user` (`TestCodes`, `TestForgotPassword`) during a parallel gate run. The orchestrator reports those tests pass when run uncached, and the final `--all` gate exited 0.
|
- The first full `go test` run was disturbed by machine load: Postgres containers timed out at startup. A fail-closed reading needs the serial re-run. If the gate is run in CI, run it on an otherwise idle machine.
|
||||||
- Phase 9 still has no VERIFICATION.md. CR-01 was the Phase 9 T-09-04 concern, and it is now resolved for the admin audience.
|
|
||||||
|
|
||||||
### Human Verification
|
### Human Verification Required
|
||||||
|
|
||||||
Complete. 10-UAT.md has `status: complete` with 7/7 passed. The user ran the fonoteka binary at http://localhost:8080/plytadmin with a superuser and a genres-only admin, and approved:
|
### 1. Browser re-walk of the Phase 10 flows on the current build
|
||||||
|
|
||||||
1. the CR-01 decision (fixed)
|
**Test:** Run the fonoteka binary and open /plytadmin. Log in as a superuser and then as a genres-only admin. For each of the five controllers, use the list and form (search, sort, filter, paging, save, 422 field errors). Link and unlink a Collection editor. Open Ustawienia. Glance at light and dark mode.
|
||||||
2. navigation for the limited admin versus the superuser
|
**Expected:** Everything still behaves as approved in 10-UAT.md tests 2 to 5. The Albums form's new 10.1 widgets and partials do not break the Phase 10 form.
|
||||||
3. the walkthrough of the five controllers and Ustawienia
|
**Why human:** Phase 10.1 changed the very views the 2026-09-27 approval covered, and D-23 keeps browser e2e out of the automated suite. Closing 10.1-UAT tests 1 and 4 with Genres, Collections and Settings included also closes this item.
|
||||||
4. the editor link/unlink round trip
|
|
||||||
5. the visual check in light and dark at desktop and responsive widths
|
|
||||||
6. A3, the Secure cookie on localhost
|
|
||||||
7. the 17 judgment-tier prohibitions
|
|
||||||
|
|
||||||
Each item is recorded as resolved in the `human_verification` frontmatter.
|
The carried items (CR-01, A3, the 17 prohibitions) remain resolved, with evidence re-run this session.
|
||||||
|
|
||||||
### Gaps Summary
|
### Gaps Summary
|
||||||
|
|
||||||
None. All four ROADMAP success criteria are verified by automated evidence re-run this session:
|
There are no gaps. All four ROADMAP success criteria hold at HEAD on automated evidence re-run this session:
|
||||||
|
|
||||||
- the assembled Postgres acceptance test
|
- `go vet` is clean
|
||||||
- 441 SPA tests
|
- every Go package passes, with eight container-startup timeouts cleared by a serial re-run
|
||||||
- the dist and OpenAPI drift gates
|
- the fonoteka Postgres acceptance test passes
|
||||||
- the CR-01 revocation tests
|
- Vitest passes, 681 of 681
|
||||||
|
- the dist and OpenAPI drift gates and four gate stages pass
|
||||||
|
|
||||||
The approved UAT covers the real-browser behavior that D-23 keeps out of automated tests. CR-01, the reason the previous run stopped at human_needed, is fixed and proven by a test that fails without the fix. The open warnings (WR-01..WR-08) and info items are non-blocking review findings. None of them falsifies a Phase 10 must-have.
|
The status is human_needed, not passed, because the human browser approvals predate the Phase 10.1 changes to ListView, FormView, the toolbar, the router and the styles. Those approvals cannot be carried over to the changed views.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
_Verified: 2026-09-27T18:43:00Z_
|
_Verified: 2026-10-01T21:29:59Z_
|
||||||
_Verifier: Claude (gsd-verifier)_
|
_Verifier: Claude (gsd-verifier)_
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
---
|
---
|
||||||
phase: 10.2-nest-framework-packages-under-modules-and-write-run-docs
|
phase: 10.2-nest-framework-packages-under-modules-and-write-run-docs
|
||||||
verified: 2026-09-28T12:11:41Z
|
verified: 2026-10-01T21:26:36Z
|
||||||
status: passed
|
status: human_needed
|
||||||
score: 7/7 must-haves verified
|
score: 5/7 must-haves verified
|
||||||
covered_files:
|
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-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-01-SUMMARY.md"
|
||||||
@@ -59,8 +59,8 @@ covered_files:
|
|||||||
- "modules/boardwalk/dist/assets/dm-sans-latin-ext-600-normal-DRtaDpgU.woff"
|
- "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-BLI3TTWz.woff"
|
||||||
- "modules/boardwalk/dist/assets/dm-sans-latin-ext-700-normal-CJIcxD6K.woff2"
|
- "modules/boardwalk/dist/assets/dm-sans-latin-ext-700-normal-CJIcxD6K.woff2"
|
||||||
- "modules/boardwalk/dist/assets/index-BAlwlQ8W.js"
|
- "modules/boardwalk/dist/assets/index-J-FCndLr.js"
|
||||||
- "modules/boardwalk/dist/assets/index-CLf0gZ3D.css"
|
- "modules/boardwalk/dist/assets/index-CfeX_snf.css"
|
||||||
- "modules/boardwalk/dist/index.html"
|
- "modules/boardwalk/dist/index.html"
|
||||||
- "modules/bonfire/README.md"
|
- "modules/bonfire/README.md"
|
||||||
- "modules/bonfire/command.go"
|
- "modules/bonfire/command.go"
|
||||||
@@ -307,25 +307,48 @@ covered_files:
|
|||||||
- "scripts/check-phase3.sh"
|
- "scripts/check-phase3.sh"
|
||||||
- "scripts/check-phase4.sh"
|
- "scripts/check-phase4.sh"
|
||||||
- "scripts/check-phase9.sh"
|
- "scripts/check-phase9.sh"
|
||||||
covered_digest: "v2:sha256:f596349d38060d89072317bddbd0096e49f059c82a2d8dcbea7b7e7aba2f5278"
|
covered_digest: "v2:sha256:c5236001a0415018a2c9071eda2ee55201881dadb06f9a3b9437c5bec10a5d91"
|
||||||
behavior_unverified: 0
|
behavior_unverified: 0
|
||||||
overrides_applied: 0
|
overrides_applied: 0
|
||||||
re_verification:
|
re_verification:
|
||||||
previous_status: gaps_found
|
previous_status: passed
|
||||||
previous_score: 6/7
|
previous_score: 7/7
|
||||||
gaps_closed:
|
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."
|
||||||
- "D-07: Each modules/<name>/ has a short code-derived README with a valid example entry point."
|
gaps_closed: []
|
||||||
gaps_remaining: []
|
gaps_remaining: []
|
||||||
regressions: []
|
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 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.
|
**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-09-28T12:11:41Z
|
**Verified:** 2026-10-01T21:26:36Z
|
||||||
**Status:** passed
|
**Status:** human_needed
|
||||||
**Re-verification:** Yes — after gap closure
|
**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
|
## Goal Achievement
|
||||||
|
|
||||||
@@ -333,87 +356,111 @@ re_verification:
|
|||||||
|
|
||||||
| # | Truth | Status | Evidence |
|
| # | Truth | Status | Evidence |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| 1 | D-01/D-02/D-06: All 18 unchanged beach packages live only at `modules/<name>/`; none remains at repository root. | ✓ VERIFIED | Enumerated all 18: each directory exists under `modules/`, no root directory exists, and each first package clause matches its beach name. |
|
| 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: The root layout remains and there is one framework `go.mod`, with no per-package module or `go.work` entry. | ✓ VERIFIED | `go.work` lists only `.` plus the four `examples/hello*` modules; `find modules -name go.mod` is empty. |
|
| 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: Framework, examples, and Fonoteka importers use nested paths; app replace directives still target this checkout. | ✓ VERIFIED | A corrected tracked-source scan over both repositories found zero root-form beach imports. All named nested imports compile; Fonoteka root and plugin `go.mod` files retain their local framework replaces. |
|
| 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: Both repositories and example module contexts vet/test on the nested graph. | ✓ VERIFIED | `scripts/check-phase10.2.sh --all` passed outside the sandbox, including framework and Fonoteka root/plugin vet/tests. Explicit example vet plus compile-only test also passed. |
|
| 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: Every module README is short, code-derived onboarding with a valid example entry point. | ✓ VERIFIED | All 18 three-line READMEs cite real code. Party now names `party.Plugin`, `party.Register`, and `party.Activate`, all defined in `modules/party/registry.go`. |
|
| 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: Root README honestly explains framework/app separation, local admin recreation, and guarded Phase 15 cutover. | ✓ VERIFIED | README points to Fonoteka's DSN/migrate/serve flow, `/plytadmin`, PHP deployment docs, and matches the Phase 15 note plus `fonoteka.go/config/backend.yaml`. |
|
| 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 Phase 10.2 gate fails closed for layout/import/README/stale-status regressions. | ✓ VERIFIED | `bash -n scripts/check-phase10.2.sh && scripts/check-phase10.2.sh --self-test` passed; its scratch cases independently plant all four forbidden states, including a tracked historical `.planning/` import that must be ignored. |
|
| 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:** 7/7 truths verified (0 present, behavior-unverified)
|
**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
|
## Required Artifacts
|
||||||
|
|
||||||
| Artifact | Expected | Status | Details |
|
| Artifact | Expected | Status | Details |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| `modules/` and `modules/festival/` | 18 nested package directories | ✓ VERIFIED | Directory-level check: 18 expected names, matching package clauses, no root shadows. |
|
| `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 moved cabana | ✓ VERIFIED | Uses `--dir modules/cabana`. |
|
| `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 | Both reference `modules/boardwalk/dist`; Vite `outDir` is `../modules/boardwalk/dist`. |
|
| `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/`. |
|
| `internal/build/stubs/plugin.tmpl` | Generated plugin imports use nested paths | ✓ VERIFIED | Imports backpack, bonfire, pact and party through `/modules/`. |
|
||||||
| `modules/*/README.md` | Accurate short module onboarding | ✓ VERIFIED | All exist, are 3 lines, contain no planning prose, and cite valid package entry points. |
|
| `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/application onboarding and honest cutover | ✓ VERIFIED | Source-checked against Fonoteka README/config and Phase 15 cutover note. |
|
| `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 | Executable; syntax, detector self-test, and full `--all` run passed. |
|
| `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
|
## Key Link Verification
|
||||||
|
|
||||||
| From | To | Via | Status | Details |
|
| From | To | Via | Status | Details |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| `modules/backpack/app.go` | `modules/festival` | Nested festival import | ✓ WIRED | Imports `git.golem15.com/golem15/summercms/modules/festival`. |
|
| `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 prescribed `modules/` paths are present in the live scripts/config. |
|
| Admin/OpenAPI/dist scripts and Vite | moved cabana/boardwalk paths | retargeted literals | ✓ WIRED | All `modules/` paths present. |
|
||||||
| `../fonoteka.go/go.mod` | this framework checkout | local replace | ✓ WIRED | `replace git.golem15.com/golem15/summercms => ../summercms.go` remains intact. |
|
| `../fonoteka.go/go.mod` (+ plugin go.mods) | this framework checkout | local replace | ✓ WIRED | `=> ../summercms.go` / `=> ../../../../summercms.go`. |
|
||||||
| Root README | per-module READMEs and Fonoteka README | links/run commands | ✓ WIRED | Root README links all 18 module documents and the Fonoteka database setup. |
|
| 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 | Each detector is called through `check_hygiene` and must reject its scratch mutation. |
|
| Phase gate | layout/import/README/status checks | `--self-test` plants | ✓ WIRED | Self-test passed. |
|
||||||
|
|
||||||
## Data-Flow Trace (Level 4)
|
## Data-Flow Trace (Level 4)
|
||||||
|
|
||||||
Not applicable. This phase moves static Go packages and adds documentation/hygiene tooling; it does not render dynamic data.
|
Not applicable. The phase moves static Go packages and adds docs and hygiene tooling; it renders no dynamic data.
|
||||||
|
|
||||||
## Behavioral Spot-Checks
|
## Behavioral Spot-Checks
|
||||||
|
|
||||||
| Behavior | Command | Result | Status |
|
| Behavior | Command | Result | Status |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| Gate detector behavior | `bash -n scripts/check-phase10.2.sh && scripts/check-phase10.2.sh --self-test` | `phase10.2 self-test passed` | ✓ PASS |
|
| Framework vet | `go vet ./...` | exit 0 | ✓ PASS |
|
||||||
| Both-repository migration graph | `scripts/check-phase10.2.sh --all` | Framework and Fonoteka root/plugin packages passed; `phase10.2 check passed` | ✓ PASS |
|
| Framework tests (single full run) | `go test ./...` | 33 ok, 2 FAIL (conga TestQueueWork, lighthouse TestBulkEmitsOnce: load timing) | see next row |
|
||||||
| Nested example consumers resolve | `go vet ./examples/hello/... ... && go test -run '^$' ./examples/hello/... ...` | hello, base, greeter, optional all completed successfully | ✓ PASS |
|
| Rerun of the two failing packages | `go test -count=1 ./modules/conga ./modules/lighthouse` | both ok | ✓ PASS |
|
||||||
| Party README entry point | `go test ./modules/party -count=1` plus source check | Package test passed; README names existing `Plugin`, `Register`, and `Activate` declarations | ✓ 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 |
|
||||||
|
|
||||||
The initial sandbox `--all` failure was environmental (read-only shared Go cache and denied localhost listeners); the unchanged full command passed outside that sandbox.
|
No command changed the working tree (`git status` showed only the pre-existing untracked zip).
|
||||||
|
|
||||||
## Probe Execution
|
## Probe Execution
|
||||||
|
|
||||||
Not applicable — the plans declare no phase probe and no conventional probe script is in scope.
|
Not applicable. The plans declare no probe, and no conventional `scripts/*/tests/probe-*.sh` is in scope.
|
||||||
|
|
||||||
## Requirements Coverage
|
## Requirements Coverage
|
||||||
|
|
||||||
No requirement IDs are assigned: both PLAN frontmatters use `requirements: []` and ROADMAP/REQUIREMENTS.md list Phase 10.2 as TBD. No orphaned Phase 10.2 requirement mapping was found.
|
No requirement IDs are assigned: both PLAN frontmatters have `requirements: []`, and ROADMAP lists Phase 10.2 Requirements as TBD. No orphaned mappings.
|
||||||
|
|
||||||
## Decision Coverage
|
## Advisory (New Scope, Unevidenced)
|
||||||
|
|
||||||
No CONTEXT.md exists for this phase, so the non-blocking decision-coverage gate was skipped.
|
| # | 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. |
|
||||||
|
|
||||||
## Test Quality Audit
|
## Anti-Patterns Found
|
||||||
|
|
||||||
No requirement-linked standalone test file is declared. The shell gate's behavioral self-test has active, fail-first scratch assertions for each detector; no disabled test patterns or circular expected-output generation were found in the phase gate.
|
| File | Line | Pattern | Severity | Impact |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| (none) | | No `TBD`/`FIXME`/`XXX` in the gate, READMEs, stubs, Vite config or admin scripts | | |
|
||||||
|
|
||||||
## Prohibitions and Anti-Patterns
|
## Human Verification Required
|
||||||
|
|
||||||
| Check | Status | Evidence |
|
### 1. Accept or reject the D-07 supersession
|
||||||
| --- | --- | --- |
|
|
||||||
| No beach-name remapping | ✓ VERIFIED | Package clauses retain all beach names. |
|
|
||||||
| No module-local `go.mod` or new `go.work` entries | ✓ VERIFIED | No `modules/**/go.mod`; workspace contains only root and hello modules. |
|
|
||||||
| No historical planning-literal rewrite | ✓ VERIFIED | Historical root-form imports remain under `.planning/`; the live gate explicitly excludes and self-tests this case. |
|
|
||||||
| No dependency additions | ✓ VERIFIED | No phase diff to root/Fonoteka Go or npm dependency manifests. |
|
|
||||||
| No invented package API in module onboarding | ✓ VERIFIED | `modules/party/README.md:3` now names real `Plugin`, `Register`, and `Activate` declarations. |
|
|
||||||
| Debt markers in phase docs/gate | ✓ VERIFIED | No unreferenced `TBD`, `FIXME`, or `XXX` comment found. |
|
|
||||||
|
|
||||||
## Human Verification
|
**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.
|
||||||
|
|
||||||
N/A — this is an infrastructure/documentation phase with no UI or runtime interaction introduced. The factual onboarding failure above is directly observable and does not need manual UAT to classify.
|
### 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
|
## Gaps Summary
|
||||||
|
|
||||||
None. The prior D-07 documentation gap is closed: Party onboarding now directs readers to the actual `Plugin`, `Register`, and `Activate` API. The layout, import graph, validation gate, and root onboarding regressions remain absent.
|
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-09-28T12:11:41Z_
|
_Verified: 2026-10-01T21:26:36Z_
|
||||||
_Verifier: the agent (gsd-verifier)_
|
_Verifier: Claude (gsd-verifier)_
|
||||||
|
|||||||
Reference in New Issue
Block a user