docs(12.1-05): close plan 05 with SUMMARY after the executor died before writing it

This commit is contained in:
Jakub Zych
2026-10-05 16:51:31 +02:00
parent 93f0171e9c
commit 4e4ce40dbb
5 changed files with 333 additions and 15 deletions

View File

@@ -0,0 +1,319 @@
---
phase: 12.1-user-plugin-admin-screens
plan: 05
subsystem: testing
tags: [cabana, pact, sm-user-plugin, admin, vitest, check-phase12.1, security-review, coverage, privileged-groups]
requires:
- phase: 12.1-user-plugin-admin-screens
provides: "plans 01 to 04: framework contracts at v0.1.3, the three admin screens, T-12-18 / D-30 guards, smoke tests, validation seed"
provides:
- "TestPhase121Threats in cabana (T-12.1-01 to T-12.1-15) and in sm-user-plugin (T-12.1-18..25, 27..31, 34, 38, 39; T-12-18 cited)"
- "scripts/check-phase12.1.sh fail-closed gate (self-test, go, security, removal, coverage, spa, openapi, dist, docs, hygiene, app, evidence, all)"
- "SPA unit tests including the five UI-SPEC backstops"
- "12.1-SECURITY-REVIEW.md (threats_open 0) and signed-off 12.1-VALIDATION.md (nyquist_compliant true)"
affects: [gsd-verify-work, sm-user-plugin publication, fonoteka.go push]
actuals:
tokens: 141472 # chars/4: framework c076b4c^..93f0171 (101051) + plugin 4693155..2b04cda (40353) + fonoteka.go 35a727f..93b8b75 (68)
tasks: 3
commits: 7
plan_head_before: 52f864ebfc58a488037e60b27a778df8c4158f08
plan_head_after: 93f0171e9c0eb798a61d5d71082873d1b3e8c4c6
plugin_repo: sm-user-plugin (../fonoteka.go/plugins/golem15/user)
plugin_commits: 7
plugin_head_before: 469315510809f703fc315aceaa9ef902794a0237
plugin_head_after: 2b04cda3ff8c4375ca4206f6ae751a6221db0483
app_repo: fonoteka.go (../fonoteka.go)
app_commits: 2
app_head_before: 35a727f1ddfde0a443cf203193bf3705fe3158a1
app_head_after: 93b8b758d540e5edb5095c8ed99998e57d4150d8
tech-stack:
added: []
patterns:
- "Phase gate: go test -json detector refuses fail, skip, zero tests, non-JSON, missing named prefix; removal is anchor-exact mutate / assert-fail / cmp restore"
- "One TestPhase121Threats per repository, subtest named by threat id; high/critical threats also have a removal row"
key-files:
created:
- scripts/check-phase12.1.sh
- modules/cabana/phase121_threats_test.go
- modules/cabana/phase121_bulk_test.go
- modules/cabana/phase121_record_test.go
- modules/cabana/phase121_rowstate_test.go
- modules/cabana/phase121_forbidden_test.go
- modules/cabana/phase121_preview_test.go
- modules/cabana/phase121_fields_test.go
- modules/cabana/phase121_permission_test.go
- modules/cabana/phase121_relation_lock_test.go
- modules/cabana/phase121_list_test.go
- modules/cabana/phase121_schema_boot_test.go
- admin/tests/list/BulkActionsMenu.test.ts
- admin/tests/list/RowStateBadges.test.ts
- admin/tests/form/RecordActions.test.ts
- admin/tests/form/PreviewView.test.ts
- admin/tests/form/PreviewField.test.ts
- admin/tests/form/PermissionEditorField.test.ts
- admin/tests/form/PasswordField.test.ts
- admin/tests/form/FormErrorBanner.test.ts
- ../fonoteka.go/plugins/golem15/user/phase121_security_test.go
- ../fonoteka.go/plugins/golem15/user/admin_users_edge_test.go
- ../fonoteka.go/plugins/golem15/user/admin_groups_edge_test.go
- ../fonoteka.go/plugins/golem15/user/admin_organisations_edge_test.go
- ../fonoteka.go/plugins/golem15/user/admin_registration_test.go
- .planning/phases/12.1-user-plugin-admin-screens/12.1-SECURITY-REVIEW.md
modified:
- modules/pact/capabilities_test.go
- admin/tests/list/ListToolbar.test.ts
- admin/tests/list/DataTable.test.ts
- admin/tests/list/ListView.test.ts
- admin/tests/form/RelationField.test.ts
- admin/tests/form/FormView.test.ts
- admin/tests/form/formState.test.ts
- admin/tests/form/registry.test.ts
- admin/tests/app/winterUrl.test.ts
- admin/tests/app/router.test.ts
- docs/backend/forms.md
- docs/backend/relation-manager.md
- .planning/phases/12.1-user-plugin-admin-screens/12.1-VALIDATION.md
- ../fonoteka.go/plugins/golem15/user/classes/admin_actions.go
- ../fonoteka.go/plugins/golem15/user/classes/privileged.go
- ../fonoteka.go/plugins/golem15/user/models/user.go
key-decisions:
- "Security review was self-performed by the executor (no reviewer agent on this runtime); threats_open 0; five findings_for_decision recorded, not closed silently"
- "pending: push sm-user-plugin — condition (c) failed: git ls-remote --tags origin v0.1.3 is empty. Conditions (a)(b)(d) hold. Nothing was pushed."
- "No follow-up framework tag: git diff --name-only v0.1.3 HEAD -- modules cmd admin/src lists only Go tests and testdata"
- "Two plugin production fixes during tests (FX-1 clean statement, FX-2 group filter value); FX-3 is a test-only strengthening of T-12.1-24"
patterns-established:
- "Last plan of a phase: named threat tests, 80% coverage floor, removal harness, SECURITY-REVIEW, VALIDATION sign-off, then one plugin push point gated on a published framework tag"
requirements-completed: [SC-5]
coverage:
- id: D1
description: "Named threat tests in both repos and a fail-closed --security stage"
requirement: SC-5
verification:
- kind: integration
ref: "modules/cabana/phase121_threats_test.go#TestPhase121Threats"
status: pass
- kind: integration
ref: "../fonoteka.go/plugins/golem15/user/phase121_security_test.go#TestPhase121Threats"
status: pass
- kind: other
ref: "scripts/check-phase12.1.sh --self-test && --security"
status: pass
human_judgment: false
- id: D2
description: "Go unit/integration coverage at or above 80% for pact, cabana, and the user plugin packages root, classes, controllers, models, updates"
requirement: SC-5
verification:
- kind: other
ref: "scripts/check-phase12.1.sh --coverage (pact 100.0, cabana 86.6, plugin root 89.1, classes 89.0, controllers 83.0, models 95.7, updates 90.2)"
status: pass
human_judgment: false
- id: D3
description: "SPA unit tests including the five UI-SPEC backstops; OpenAPI, dist, docs, hygiene"
requirement: SC-5
verification:
- kind: unit
ref: "admin/tests/list/ListView.test.ts#backstop: focus returns to the bulk menu trigger"
status: pass
- kind: unit
ref: "admin/tests/app/winterUrl.test.ts#backstop: mapWinterUrl maps preview/:id"
status: pass
- kind: unit
ref: "admin/tests/list/RowStateBadges.test.ts#backstop: a row state outside the fixed set"
status: pass
- kind: unit
ref: "admin/tests/form/PermissionEditorField.test.ts#backstop: radio/checkbox emission and locked row"
status: pass
- kind: unit
ref: "admin/tests/form/RelationField.test.ts#backstop: a locked option cannot be chosen"
status: pass
- kind: other
ref: "scripts/check-phase12.1.sh --spa --openapi --dist --docs --hygiene"
status: pass
human_judgment: false
- id: D4
description: "Removal harness proves high/critical protections including D-30 FormBeforeUpdate and FormBeforeDelete"
requirement: SC-5
verification:
- kind: other
ref: "scripts/check-phase12.1.sh --removal (27 rows, RC-23 T-12.1-38, RC-24 T-12.1-39)"
status: pass
human_judgment: false
- id: D5
description: "Security review maps T-12.1-01..40 and T-12.1-SC; validation signed off; plugin push pending on origin tag"
requirement: SC-5
verification:
- kind: other
ref: "scripts/check-phase12.1.sh --evidence && --all"
status: pass
human_judgment: true
rationale: "End-of-phase visual walk of the three screens in light and dark mode, and the D-30 email/password/delete feel, cannot be asserted by unit tests (plan 05 Task 3 human-check)."
duration: 103min
completed: 2026-10-05
status: complete
---
# Phase 12.1: User plugin admin screens — Plan 05 Summary
**Fail-closed `scripts/check-phase12.1.sh`, named threat tests in both repos, SPA backstops, 80%+ coverage, security review with zero open threats, and validation signed off. Plugin push is pending because `v0.1.3` is not on origin.**
## Performance
- **Duration:** 103 min (executor 14:30–16:13 local). The previous session finished every production commit and died before this SUMMARY; this file closes that illegal partial-plan state.
- **Started:** 2026-10-05T12:30:31Z
- **Completed:** 2026-10-05T14:13:50Z (production commits); SUMMARY closed out 2026-10-05T15:00:00Z
- **Tasks:** 3 of 3
- **Files modified:** 37 in summercms.go, 17 in sm-user-plugin, 2 pointer bumps in fonoteka.go
## Accomplishments
- One named threat test per repository. Cabana `TestPhase121Threats` covers T-12.1-01 to T-12.1-15. Plugin `TestPhase121Threats` covers T-12.1-18 to T-12.1-25, 27 to 31, 34, 38 and 39, and cites T-12-18 by that id.
- `scripts/check-phase12.1.sh` is executable and fail-closed. `--all` passed in 11 min 47 s. `--removal` passed 27 rows in 6 min 29 s and left both trees clean.
- Statement coverage: `modules/pact` 100.0%, `modules/cabana` 86.6%; plugin root 89.1%, `classes` 89.0%, `controllers` 83.0%, `models` 95.7%, `updates` 90.2%.
- Five UI-SPEC backstops have named vitest cases (bulk-menu focus, preview URL mapping, unknown row state, permission-editor emission, locked relation options).
- `12.1-SECURITY-REVIEW.md`: 41 threat ids match the five plans, `threats_open: 0`, D-30 and T-12-18 sections present. `12.1-VALIDATION.md`: `nyquist_compliant: true`, no TBD row.
## Task Commits
### summercms.go
| Task | Commit | Subject |
|------|--------|---------|
| 1 | `c076b4c` | test(12.1-05): threat test for the Phase 12.1 framework contracts and the first gate stages |
| 2 | `2e94cbf` | test(12.1-05): unit tests for bulk and record actions, row state, forbidden, preview and the form seams |
| 3 | `84efdc0` | test(12.1-05): unit tests for the Phase 12.1 SPA components |
| 3 | `aced6c7` | test(12.1-05): unit tests for the list, form, preview and routing behaviours of Phase 12.1 in the SPA |
| 3 | `3190b1c` | test(12.1-05): complete the Phase 12.1 gate with the removal, coverage, app and evidence stages |
| 3 | `83feeef` | docs(12.1-05): state the limits of relation locks and locked permission codes |
| 3 | `93f0171` | docs(12.1-05): security review and validation sign-off for Phase 12.1 |
Framework head before `52f864e`, after `93f0171`. Tag `v0.1.3` (`df5cace`) is an ancestor. No production Go or SPA source under `modules`, `cmd`, or `admin/src` changed after the tag.
### sm-user-plugin
| Task | Commit | Subject |
|------|--------|---------|
| 1 | `ba43ad9` | test: pin every mitigated Phase 12.1 threat of the admin screens in TestPhase121Threats |
| 2 | `f496959` | fix: read privileged membership and the admin actions through a clean statement (T-12.1-38, T-12.1-39) |
| 2 | `43fabfa` | fix: a group filter value that is not a group id lists nobody (D-23) |
| 2 | `493a3ff` | test: unit tests for the admin class functions, the models and the admin registration |
| 2 | `a848aa1` | test: edge cases of the Users, User Groups and Organisations admin controllers |
| 2 | `7991b53` | test: extend the permission resolver table, the admin migration history and the API token refusals |
| 3 | `2b04cda` | test: T-12.1-24 also marshals a user with last_seen and permissions |
Plugin head before `4693155`, after `2b04cda`. Tree clean. 21 commits ahead of origin `0fe5b91`. Remote head was `0fe5b91` at the start of Task 2 and still `0fe5b91` at close-out: this plan pushed nothing.
### fonoteka.go
| Purpose | Commit | Subject |
|---------|--------|---------|
| Task 2 pointer | `ed78e6e` | build: bump sm-user-plugin (unit tests, the group filter value and the clean-statement fix) |
| Task 3 pointer | `93b8b75` | build: bump sm-user-plugin (T-12.1-24 marshals the user model) |
Application pointer equals plugin HEAD `2b04cda`. fonoteka.go was not pushed.
## Gate output (recorded 2026-10-05)
| Stage | Time | Result |
|-------|------|--------|
| `--self-test` | 2 s | PASS |
| `--go` | 87–130 s | PASS |
| `--security` | 84 s | PASS |
| `--coverage` | 111 s | PASS (numbers above) |
| `--spa` | 52 s | PASS (71 files, 1013 tests with typecheck) |
| `--openapi` | 11 s | PASS |
| `--dist` | 19–22 s | PASS |
| `--docs` | 8 s | PASS |
| `--hygiene` | <1 s | PASS |
| `--app` | 290–325 s | PASS |
| `--evidence` | <1 s | PASS |
| `--all` | 11 min 47 s | PASS |
| `--removal` | 6 min 29 s (27 rows) | PASS; both trees clean afterwards |
Renaming one named plugin test by hand made `--security` exit non-zero with `refuse: missing named test`; the rename was reverted (T-12.1-35).
## Publication (T-12.1-40)
Checked after the review and `--all` on the final heads. Plugin remote head noted at the start of step (5): `0fe5b91b632a0ab784f3cecd2d5cf168528062ac`.
| Condition | Held | Evidence |
|-----------|------|----------|
| (a) gate passed | yes | `--all` PASS |
| (b) threats_open 0 | yes | `12.1-SECURITY-REVIEW.md` |
| (c) `git ls-remote --tags origin v0.1.3` lists the tag | **no** | empty |
| (d) no framework production code after the tag | yes | `git diff --name-only v0.1.3 HEAD -- modules cmd admin/src` is tests and testdata only |
**pending: push sm-user-plugin** because (c) failed. Push framework `master` and annotated tag `v0.1.3` first (pending since plan 02). Then push sm-user-plugin master (never force). Then **push fonoteka.go** (user step). No follow-up framework tag is needed from this plan.
## Decisions Made
- Reviewer line is the executor self-review, matching 08-10 and Phase 12, because this runtime cannot spawn the security-review agent.
- H-01 and H-02 (relation-lock vs manager; locked permission value outside the mode) were documented in `docs/backend/relation-manager.md` and `docs/backend/forms.md` rather than changing tagged production code.
- Five findings left for the owner (FD-1 to FD-5): organisation_role on unlink, lock vs relation manager, boolean permission JSON, host `admin.jwt.secret`, and whether deactivate/ban should follow D-30.
## Deviations from Plan
### Auto-fixed Issues
**1. FX-1 — privileged membership read cloned a dirty statement**
- **Found during:** Task 2 / removal of T-12.1-38
- **Issue:** `classes.fresh` chained `WithContext` onto a lazy `NewDB` session and cloned the caller's conditions; `IsPrivilegedMember` could answer false for a privileged member
- **Fix:** build the empty statement first (`f496959`)
- **Verification:** `TestIsPrivilegedMember`, `TestAdminActions`; removal RC-25
- **Committed in:** `f496959`
**2. FX-2 — group filter 500 on a non-id value**
- **Found during:** Task 2 edge tests (D-23)
- **Issue:** `filter[groups]=abc` made the Users list answer 500
- **Fix:** a value that is not a positive whole number lists nobody (`43fabfa`)
- **Verification:** `TestAdminUsersGroupFilterValue`; removal RC-26
- **Committed in:** `43fabfa`
**3. FX-3 — T-12.1-24 removal survived on API payloads only**
- **Found during:** Task 3 `--removal` RC-18
- **Issue:** the subtest only read field-by-field API payloads, so removing `json:"-"` on `LastSeen` still passed
- **Fix:** also marshal the model (`2b04cda`)
- **Verification:** RC-18 and RC-27 now fail as required
- **Committed in:** `2b04cda`
---
**Total deviations:** 3 auto-fixed (2 production plugin fixes, 1 test strengthening). No framework production code. No scope creep.
## Issues Encountered
The first executor session completed every plan-05 production commit (`93f0171` last) and exhausted context before writing SUMMARY.md. Resume closed that gap instead of re-executing the 250k-token plan.
## User Setup Required
None - no external service configuration required.
Pending owner actions (not setup): push `v0.1.3` to origin, then sm-user-plugin, then fonoteka.go. Human visual UAT of the three screens is `/gsd-verify-work 12.1`.
## Next Phase Readiness
- Automated evidence for SC-5 is in place. Phase stays pending until human verification of the three screens.
- Plugin and application remain local-only until the framework tag is on origin.
- FD-1..FD-5 in the security review are owner decisions, not blockers for this plan.
## Self-Check: PASSED
- [x] All three tasks executed and committed
- [x] Gate `--all` and `--removal` recorded passing
- [x] Coverage floor met
- [x] Threat ids in the review match the five plans (41)
- [x] Publication recorded as pending with the failed condition
- [x] SUMMARY.md created
---
*Phase: 12.1-user-plugin-admin-screens*
*Completed: 2026-10-05*

View File

@@ -54,7 +54,7 @@ removal_gate: "scripts/check-phase12.1.sh --removal"
| `scripts/check-phase12.1.sh --app` | 290 to 325 s (five workspace modules) |
| `scripts/check-phase12.1.sh --evidence` | under 1 s |
| `scripts/check-phase12.1.sh --all` | 11 min 47 s |
| `scripts/check-phase12.1.sh --removal` | 4 min 13 s for 26 rows (27 rows now) |
| `scripts/check-phase12.1.sh --removal` | 4 min 13 s (26 rows) to 6 min 29 s (27 rows, final heads) |
---