- pact.HasAccountContributions compiled at Activate; GET /account/contributions
and POST /account/contributions/{name}/actions/{action} behind interactiveOnly
(AccountContributionView, AccountContributionActionView, AccountActionResultView)
- RecordAction.prompt (RecordActionPrompt) for a pact.AdminRecordAction with a
Prompt; the record action route accepts payload only for such an action
(trimmed JSON string, non-empty, capped at max_length) and hands it to Run as
Value through CRUDService.RecordActionWithValue; a prompt without a label
fails boot
- fireSubjectChanged: pact.MCPSubjectChanged for revoked tokens, Administrators
saves that changed role, permissions or superuser, Roles saves that changed
grants, deactivation and deletion
- phrases backend::lang.form.action_prompt_required/_too_long (en, pl)
- smoke tests TestAccountContributionsSmoke and TestRecordActionPromptSmoke;
TestRecordActionPromptRun on Postgres; route inventories, CSRF walk and
OpenAPI conformance cases extended for the two routes
- regenerated admin/openapi/admin.json and admin/src/api/schema.d.ts; cabana
README, docs/backend/{admin-controllers,users-and-permissions}.md
- surf.Router.MountStream and recoverStream: a raw, unbuffered route kind
whose http.Flusher reaches the client; panic after the first byte only
aborts the body
- surf.MCPBuildTag and the mountPier hook: mcp.enabled is inert without the
summercms_mcp tag until it is true, then boot fails naming the tag
(pier_off.go is the untagged side)
- wristband parseAuthorizeScopes takes the server's allowed set built from
Options.ScopesSupported; the default set is unchanged
- cooler.KeyPrefix exported for the MCP module's Redis keys
- smoke tests TestStreamingRouteSmoke, TestPierMountSmoke, TestMCPScopesSmoke
- surf, wristband and cooler READMEs, docs/services/{routing,oauth-server}.md
- bouncer.Dispatch, WithDispatch, Dispatched: context-only pre-resolved
principal marker honoured by Registry.Middleware for listed guard names
- cabana.ResolveBackend honours a backend-kind marker; additive
ResolveBackendToken, ScopeLimitFor and BackendPrincipal resolvers
- surf.Router.Handler and compileHandlers: one compiled chain per route,
shared by BuildRouter validation and compile
- smoke tests TestDispatchSmoke, TestDispatchedSmoke, TestDispatchMarkerSmoke
- READMEs and docs/services/{authentication,routing}.md updated
- settingsSectionOf returns the current entry's category group (null for one-entry categories)
- SettingsPanel mirrors the plugin side menu, collapse included
- AppShell shows it on settings forms and settings-linked controllers without own navigation
- docs/backend/settings.md describes moving between settings pages
The docker stage must refuse a tree that drops TestRolesCodeDeclaredCodeRefused or TestActionExtensionOutranked.
Co-authored-by: Cursor <cursoragent@cursor.com>
- cabana, not the contributor, applies guardOutranked before a contributed Run
- A contribution to summercms.cabana.users is 403 user.outranked when the target outranks the caller
Co-authored-by: Cursor <cursoragent@cursor.com>
- Roles create and update refuse a submitted code that code-declared grants attach to
- compileActionExtensions wraps contributed Administrators Runs with guardOutranked
- Prove both holes on Postgres; keep the boot smoke callable with a superuser principal
Co-authored-by: Cursor <cursoragent@cursor.com>
- 19.6.1-VALIDATION.md: per-task map green, Wave 0 ticked with the files
as built, wave_0_complete true
- deferred-items.md: lagoon's model validator skips string min/max;
granted does not expand a held leading wildcard
Fail-closed stages go, docker, admin, docs and sc1 with the detectors of
check-phase19.5.sh: every Docker-free and Postgres rule test by required
name, the SC-1 regression tests, the vitest and browser files, the
OpenAPI and dist checks, the consuming-application name check and the
SC-1 commit check. --all reports NOT RUN docker only without a daemon
(a failure with PHASE1961_REQUIRE_DOCKER=1); --self-test proves the
detectors and that rule.
- trigger.test.ts: triggerState and applyTriggers
- FormView: disable, absent-controller and hide-tab backstops, the live
announcement
- PermissionEditorField and formState: record-locked rows, notes and the
payload omission, record lock over request lock, read-only screens
- PreviewView: hide removes, disable shows no note
- browser record-actions-wrap at 1024px; vitest.browser.config.ts gains
the Tailwind plugin so the footer is laid out with the admin's CSS
- TestFieldTriggerBoot (-short): every compileTrigger and checkTriggers
refusal names controller, field and trigger; disable and hide reach the
localized schema; settings and relation forms refuse the key
- TestPermissionRecordLocks (-short): the save rule in radio and checkbox
modes, no lock lookup on create, meta only for stored records with a
provider
- TestRolesCodeDeclaredLocks (Postgres): locked_by_code grants on a role,
a save without them, locked_self on the own record
- TestAdministratorsLastSuperuser (D-09): A and B reduce each other on the
five paths while a test transaction holds the guard's advisory lock until
pg_locks shows both requests waiting; one succeeds, one gets last_superuser
- TestAdministratorsLastSuperuserConcurrent: ten unsynchronized rounds
- TestAdministratorsLifecycle (D-10) and TestAdministratorsRevocation (D-12),
two-row bulk selections included
- TestActionExtensionBoot (-short) and TestActionExtensionRun (D-14, D-15)
- TestRolesLifecycle (D-16, D-17), TestRolesPermissionCeiling (D-07)
- TestBackendScreensActivation (-short, D-01, D-04)
actionDB returned the Unscoped instance of the action's session, whose
conditions accumulate, so a bulk activate, deactivate or restore of two
applicable rows wrote only the first (the second update matched
"id = A AND id = B") while still counting it. A bulk deactivate
therefore left the other administrators active and signed in (D-10,
D-12). actionDB now ends with a plain Session, so every query starts
anew. Found by TestAdministratorsLifecycle.
The form's min:4 rule never applied: the model validator skips string
min and max. storePassword now refuses a typed password under 4
characters with a 422 on the field, next to the 72-byte check (D-11).
Found by TestAdministratorsPasswordAndIdentity.
- administrators_harness_test.go: newScreensEnv with extra plugins, seedAdmin,
seedRole, login, isolateSuperusers, row snapshots and error decoders; the
harness moved out of backend_screens_smoke_test.go and gained cleanup
- export_test.go: SuperuserLockKey for the last-superuser race
- TestAdministratorsSuperuserFlag (D-05) through the assembled handler
- fields.yaml trigger (action disable|hide, field, condition checked|unchecked) compiled to FormField.Trigger
- boot errors for malformed triggers, controlling fields that are not a switch or checkbox, and triggers in repeater rows, settings and relation forms
- Administrators permissions overrides are disabled while Superuser is on (D-06)
- SPA: trigger.ts (triggerState, applyTriggers), FORM_TRIGGER_NOTES, the trigger note in FormField, FormView tabs/banner/payload after triggers, PreviewView hide only
- regenerated admin OpenAPI and schema.d.ts; rebuilt modules/boardwalk/dist; docs and README