From 6bd2506db65013d4145cae3c8e7913e4bcaca9d9 Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Thu, 22 Oct 2026 13:37:26 +0200 Subject: [PATCH] docs(19.6.1-04): complete gap-closure plan --- .planning/ROADMAP.md | 6 +- .../19.6.1-04-SUMMARY.md | 181 ++++++++++++++++++ 2 files changed, 184 insertions(+), 3 deletions(-) create mode 100644 .planning/phases/19.6.1-backend-administrators-screen/19.6.1-04-SUMMARY.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index c829b52b..733dc5d3 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -1423,7 +1423,7 @@ Plans: 2. Privilege rules hold on the server: only a superuser can create, edit or grant superuser; an admin cannot raise their own role or permissions; the last active superuser cannot be deactivated, demoted or deleted. 3. The record-action seam on the Administrators list is usable by plugins (19.7's link action), and unit tests cover the privilege rules. -**Plans:** 4 plans +**Plans:** 4/4 plans executed Plans: **Wave 1** @@ -1436,7 +1436,7 @@ Plans: - [x] 19.6.1-03-PLAN.md — unit, Postgres and SPA tests for every rule (incl. the held-lock last-superuser race), the seam and D-21, plus the check-phase19.6.1.sh gate **Wave 4** *(gap closure)* -- [ ] 19.6.1-04-PLAN.md — close CR-01 (role-code capture onto code-declared grants) and WR-03 (wrap contributed Administrators actions with guardOutranked) +- [x] 19.6.1-04-PLAN.md — close CR-01 (role-code capture onto code-declared grants) and WR-03 (wrap contributed Administrators actions with guardOutranked) ### Phase 19.7: Generic MCP module (INSERTED) @@ -1591,7 +1591,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → | 19.4.1. Early public demo on demo.summercms.io | 5/5 | In Progress| | | 19.5. Social login in sm-user-plugin | 5/5 | Complete | 2026-10-21 | | 19.6. Two-factor auth and device flow in sm-user-plugin | 0/TBD | Not started | - | -| 19.6.1. Backend Administrators screen (INSERTED) | 3/3 | In Progress| | +| 19.6.1. Backend Administrators screen (INSERTED) | 4/4 | In Progress| | | 19.7. Generic MCP module | 0/TBD | Not started | - | | 19.8. Console commands overhaul (INSERTED) | 6/6 | In Progress| | | 20. Demo instance with every shared plugin | 0/TBD | Not started | - | diff --git a/.planning/phases/19.6.1-backend-administrators-screen/19.6.1-04-SUMMARY.md b/.planning/phases/19.6.1-backend-administrators-screen/19.6.1-04-SUMMARY.md new file mode 100644 index 00000000..fde03d40 --- /dev/null +++ b/.planning/phases/19.6.1-backend-administrators-screen/19.6.1-04-SUMMARY.md @@ -0,0 +1,181 @@ +--- +phase: 19.6.1-backend-administrators-screen +plan: 04 +subsystem: auth +tags: [cabana, roles, administrators, privilege-ceiling, pact, postgres] + +requires: + - phase: 19.6.1-01 + provides: Roles and Administrators hooks, compileActionExtensions, guardOutranked, AdministratorsControllerID + - phase: 19.6.1-02 + provides: permission locks and the Roles form that still posts a fillable code + - phase: 19.6.1-03 + provides: screensEnv harness, TestRolesLifecycle, TestActionExtensionRun, check-phase19.6.1.sh +provides: + - refuseCodeDeclaredCode on Roles create and update so a submitted code with code-declared grants is 422 user.role.code_locked + - wrapAdministratorsContributedRun so cabana runs guardOutranked before a contributed Administrators Run + - TestRolesCodeDeclaredCodeRefused and TestActionExtensionOutranked on Postgres + - DOCKER_TESTS REQUIRE names for both tests + - AdminActionExtension docs that cabana, not the contributor, owns the outranking check +affects: [19.6.1 verify-work, 19.6 D-15, 19.7 link action on Administrators] + +actuals: + tokens: 6357 + tasks: 3 + commits: 4 +plan_head_before: 422bd1e01f4f3cb87252732eb273c14fbfcaa126 +plan_head_after: e62086084b9d509b05b1e1eea510390753fe0ed8 + +tech-stack: + added: [] + patterns: + - "Roles hooks consult rolePermissions of the submitted code, not only the stored one" + - "compileActionExtensions wraps contributed Administrators Runs in cabana so guardOutranked runs inside the action transaction" + +key-files: + created: [] + modified: + - modules/cabana/backend_roles_admin.go + - modules/cabana/action_extensions.go + - modules/cabana/action_extensions_test.go + - modules/cabana/roles_postgres_test.go + - modules/cabana/action_extensions_postgres_test.go + - modules/pact/capabilities.go + - modules/pact/README.md + - modules/cabana/README.md + - docs/backend/admin-controllers.md + - scripts/check-phase19.6.1.sh + +key-decisions: + - "Roles create and update refuse any new code that rolePermissions attaches grants to, including when the editor is a superuser" + - "cabana wraps contributed Administrators Runs; guardOutranked stays unexported and contributors do not own the check" + +patterns-established: + - "A code-declared system role cannot be created or captured through the Roles screen; 422 code_locked leaves the row unchanged" + - "A contribution to summercms.cabana.users is 403 user.outranked when the target outranks the caller, before Run" + +requirements-completed: [SC-2, D-07, D-16, D-19] + +coverage: + - id: D1 + description: "Roles create and rename refuse a code that pact.Permission.Roles attaches grants to (CR-01 / G-19.6.1-1)" + requirement: "D-16" + verification: + - kind: integration + ref: "modules/cabana/roles_postgres_test.go#TestRolesCodeDeclaredCodeRefused" + status: pass + human_judgment: false + - id: D2 + description: "Contributed Administrators record actions run guardOutranked before Run (WR-03 / G-19.6.1-2)" + requirement: "D-19" + verification: + - kind: integration + ref: "modules/cabana/action_extensions_postgres_test.go#TestActionExtensionOutranked" + status: pass + human_judgment: false + - id: D3 + description: "Phase docker gate REQUIREs both new Postgres tests by name" + requirement: "D-18" + verification: + - kind: other + ref: "bash scripts/check-phase19.6.1.sh --docker" + status: pass + human_judgment: false + - id: D4 + description: "AdminActionExtension docs state that cabana applies user.outranked before Run" + requirement: "D-19" + verification: + - kind: unit + ref: "cmd/summer#TestDocsTree" + status: pass + - kind: other + ref: "go run ./cmd/summer docs:build --check" + status: pass + human_judgment: false + +duration: 18 min +completed: 2026-10-22 +status: complete +--- + +# Phase 19.6.1 Plan 04: Gap closure CR-01 and WR-03 Summary + +**Roles create/rename cannot capture a code-declared code; cabana wraps contributed Administrators Runs with guardOutranked before the contributor runs** + +## Performance + +- **Duration:** 18 min +- **Started:** 2026-10-22T11:18:00Z +- **Completed:** 2026-10-22T11:36:05Z +- **Tasks:** 3 +- **Files modified:** 10 + +## Accomplishments +- `refuseCodeDeclaredCode` on Roles create and update: a submitted code with code-declared grants is 422 `user.role.code_locked`, including for a superuser; a same-code save of a system role still succeeds +- `wrapAdministratorsContributedRun` in `compileActionExtensions`: a contribution to `AdministratorsControllerID` is 403 `user.outranked` when the target outranks the caller, and Run is not called +- `TestRolesCodeDeclaredCodeRefused` and `TestActionExtensionOutranked` are in `DOCKER_TESTS`; `scripts/check-phase19.6.1.sh --docker` passed +- pact/cabana/docs state that cabana, not the contributor, applies the Administrators outranking rule + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: refuse a Roles code-declared capture and wrap contributed Administrators Runs** - `068adaa` (fix) +2. **Task 2: Document the Administrators privilege rule on the D-14 seam** - `cb460b6` (docs) +3. **Task 3: Require the two new Postgres tests in the phase gate** - `e620860` (chore) + +**Plan metadata:** (this commit) (docs: complete plan) + +## Files Created/Modified +- `modules/cabana/backend_roles_admin.go` - `refuseCodeDeclaredCode` on create and update +- `modules/cabana/action_extensions.go` - wrap contributed Administrators Runs with `guardOutranked` +- `modules/cabana/action_extensions_test.go` - boot smoke still compiles a superuser principal +- `modules/cabana/roles_postgres_test.go` - `TestRolesCodeDeclaredCodeRefused` +- `modules/cabana/action_extensions_postgres_test.go` - `TestActionExtensionOutranked` +- `modules/pact/capabilities.go` - AdminActionExtension comment names `user.outranked` +- `modules/pact/README.md` - contribution to `summercms.cabana.users` is refused when the target outranks the caller +- `modules/cabana/README.md` - contributions targeting `AdministratorsControllerID` run `guardOutranked` before Run +- `docs/backend/admin-controllers.md` - cabana applies the outranking check before Run +- `scripts/check-phase19.6.1.sh` - DOCKER_TESTS REQUIRE both new names + +## Decisions Made +- Roles create and update refuse any new code that `rolePermissions` attaches grants to, including when the editor is a superuser +- cabana wraps contributed Administrators Runs; `guardOutranked` stays unexported and contributors do not own the check + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Safe resume] Interrupted executor left SUMMARY unwritten** +- **Found during:** Orchestrator resume after the Task spawn was cut off +- **Issue:** Tasks 1–2 were committed (`068adaa`, `cb460b6`) and the Task 3 gate-script edit was uncommitted; no SUMMARY existed. Re-dispatch would duplicate the privilege fixes. +- **Fix:** Closed out Task 3 and this SUMMARY on the main tree instead of spawning a second executor +- **Files modified:** `scripts/check-phase19.6.1.sh`, this SUMMARY +- **Verification:** named Postgres tests, docs checker, and `check-phase19.6.1.sh --docker` all passed +- **Committed in:** `e620860` (Task 3) and the metadata commit + +**2. [Plan files] `action_extensions_test.go` needed a superuser principal** +- **Found during:** Task 1 +- **Issue:** wrapping Administrators Runs made the existing boot smoke fail unless the compile-time principal is a superuser +- **Fix:** keep the boot smoke callable with a superuser principal (noted in the Task 1 commit body) +- **Files modified:** `modules/cabana/action_extensions_test.go` +- **Verification:** `go test -short ./modules/cabana/...` passed +- **Committed in:** `068adaa` (Task 1) + +--- + +**Total deviations:** 2 auto-fixed (safe resume, boot-smoke principal) +**Impact on plan:** No scope change. CR-01 and WR-03 shipped as specified. + +## Issues Encountered +The first executor spawn was interrupted after Tasks 1–2 committed. Close-out completed Task 3 and this SUMMARY without re-applying the hook/wrap changes. + +## User Setup Required +None - no external service configuration required. + +## Next Phase Readiness +Phase 19.6.1 gap closure is on disk. Ready for phase verification / UAT re-check of G-19.6.1-1 and G-19.6.1-2. + +--- +*Phase: 19.6.1-backend-administrators-screen* +*Completed: 2026-10-22*