From eb9a62a5ec2eecb7895fc36d0f0f72645b0f7da7 Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Sat, 24 Oct 2026 00:17:04 +0200 Subject: [PATCH] test(19.7): accept the SC-3 group-grant override in UAT --- .../phases/19.7-generic-mcp-module/19.7-UAT.md | 15 ++++++++------- .../19.7-generic-mcp-module/19.7-VERIFICATION.md | 7 ++++++- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.planning/phases/19.7-generic-mcp-module/19.7-UAT.md b/.planning/phases/19.7-generic-mcp-module/19.7-UAT.md index f3a37d03..ec6098bd 100644 --- a/.planning/phases/19.7-generic-mcp-module/19.7-UAT.md +++ b/.planning/phases/19.7-generic-mcp-module/19.7-UAT.md @@ -3,22 +3,23 @@ status: testing phase: 19.7-generic-mcp-module source: [19.7-VERIFICATION.md] started: 2026-10-23T20:05:22.930Z -updated: 2026-10-23T20:05:22.930Z +updated: 2026-10-23T22:17:04Z --- ## Current Test -number: 1 -name: Decide on SC-3's wording: frontend tool filtering uses group grants (what user.permission enforces), not MergedPermissions (groups plus the user's own allow/deny). Accept the override below, or ask for MergedPermissions in both the route middleware and the MCP guard (a behaviour change of a core plugin). +number: 2 +name: Real MCP client against the local demo (DEPLOY.md, 'MCP endpoint', 'Locally'): add http://127.0.0.1:8097/mcp to Claude Code or Claude Desktop, sign in on /connect as a frontend user asking for backend, see only user_me; in the admin's My account start 'Link frontend account', finish on /link-admin with a fresh sign-in, reconnect (consent shows 'also act as admin '), see the journal_ tools, create a draft post and find it in the admin; unlink and see the journal_ tools disappear. expected: | - An override entry is added to this frontmatter (suggested YAML in the report), or a follow-up is opened + One connector, one OAuth sign-in; journal_ tools appear only with a verified link plus the backend scope and disappear after unlinking (the session ends, a new session lists user_me only) awaiting: user response ## Tests ### 1. Decide on SC-3's wording: frontend tool filtering uses group grants (what user.permission enforces), not MergedPermissions (groups plus the user's own allow/deny). Accept the override below, or ask for MergedPermissions in both the route middleware and the MCP guard (a behaviour change of a core plugin). expected: An override entry is added to this frontmatter (suggested YAML in the report), or a follow-up is opened -result: [pending] +result: pass +note: override accepted in 19.7-VERIFICATION.md (SC-3 group-grant wording) ### 2. Real MCP client against the local demo (DEPLOY.md, 'MCP endpoint', 'Locally'): add http://127.0.0.1:8097/mcp to Claude Code or Claude Desktop, sign in on /connect as a frontend user asking for backend, see only user_me; in the admin's My account start 'Link frontend account', finish on /link-admin with a fresh sign-in, reconnect (consent shows 'also act as admin '), see the journal_ tools, create a draft post and find it in the admin; unlink and see the journal_ tools disappear. expected: One connector, one OAuth sign-in; journal_ tools appear only with a verified link plus the backend scope and disappear after unlinking (the session ends, a new session lists user_me only) @@ -39,9 +40,9 @@ result: [pending] ## Summary total: 5 -passed: 0 +passed: 1 issues: 0 -pending: 5 +pending: 4 skipped: 0 blocked: 0 diff --git a/.planning/phases/19.7-generic-mcp-module/19.7-VERIFICATION.md b/.planning/phases/19.7-generic-mcp-module/19.7-VERIFICATION.md index 50adddf5..a71137b7 100644 --- a/.planning/phases/19.7-generic-mcp-module/19.7-VERIFICATION.md +++ b/.planning/phases/19.7-generic-mcp-module/19.7-VERIFICATION.md @@ -6,7 +6,12 @@ score: 7/8 roadmap success-criterion truths verified, 1 needs a human decision ( covered_files: [".planning/phases/19.7-generic-mcp-module/19.7-01-PLAN.md",".planning/phases/19.7-generic-mcp-module/19.7-01-SUMMARY.md",".planning/phases/19.7-generic-mcp-module/19.7-02-PLAN.md",".planning/phases/19.7-generic-mcp-module/19.7-02-SUMMARY.md",".planning/phases/19.7-generic-mcp-module/19.7-03-PLAN.md",".planning/phases/19.7-generic-mcp-module/19.7-03-SUMMARY.md",".planning/phases/19.7-generic-mcp-module/19.7-04-PLAN.md",".planning/phases/19.7-generic-mcp-module/19.7-04-SUMMARY.md",".planning/phases/19.7-generic-mcp-module/19.7-05-PLAN.md",".planning/phases/19.7-generic-mcp-module/19.7-05-SUMMARY.md",".planning/phases/19.7-generic-mcp-module/19.7-06-PLAN.md",".planning/phases/19.7-generic-mcp-module/19.7-06-SUMMARY.md",".planning/phases/19.7-generic-mcp-module/19.7-07-PLAN.md",".planning/phases/19.7-generic-mcp-module/19.7-07-SUMMARY.md",".planning/phases/19.7-generic-mcp-module/19.7-08-PLAN.md",".planning/phases/19.7-generic-mcp-module/19.7-08-SUMMARY.md",".planning/phases/19.7-generic-mcp-module/19.7-09-PLAN.md",".planning/phases/19.7-generic-mcp-module/19.7-09-SUMMARY.md","README.md","admin/openapi/admin.json","admin/src/api/schema.d.ts","admin/src/api/types.ts","admin/src/app/hotkeys.ts","admin/src/components/account/AccountContributions.vue","admin/src/components/form/RecordActions.vue","admin/src/components/ui/ConfirmDialog.vue","admin/src/components/ui/confirm.ts","admin/src/views/AccountView.vue","admin/tests/account/AccountContributions.test.ts","admin/tests/app/hotkeysEditing.test.ts","admin/tests/fixtures/lang.json","admin/tests/form/RecordActionsPrompt.test.ts","docs/backend/admin-controllers.md","docs/backend/users-and-permissions.md","docs/plugins/registration.md","docs/services/authentication.md","docs/services/mcp.md","docs/services/oauth-server.md","docs/services/routing.md","docs/site.yaml","go.mod","go.sum","modules/bouncer/README.md","modules/bouncer/auth_time_smoke_test.go","modules/bouncer/auth_time_test.go","modules/bouncer/dispatch.go","modules/bouncer/dispatch_smoke_test.go","modules/bouncer/dispatch_test.go","modules/bouncer/jwt.go","modules/bouncer/mint.go","modules/bouncer/refresh.go","modules/bouncer/registry.go","modules/cabana/README.md","modules/cabana/account_contributions.go","modules/cabana/account_contributions_hardening_test.go","modules/cabana/account_contributions_smoke_test.go","modules/cabana/account_contributions_test.go","modules/cabana/account_token_events_test.go","modules/cabana/account_tokens.go","modules/cabana/action_extensions.go","modules/cabana/actions.go","modules/cabana/admin_openapi.go","modules/cabana/administrators_harness_test.go","modules/cabana/backend_roles_admin.go","modules/cabana/backend_users_admin.go","modules/cabana/contracts.go","modules/cabana/crud.go","modules/cabana/dispatch_marker_test.go","modules/cabana/dispatch_smoke_test.go","modules/cabana/extension.go","modules/cabana/http.go","modules/cabana/openapi_conformance_test.go","modules/cabana/phase10_coverage_test.go","modules/cabana/phase10_csrf_test.go","modules/cabana/record_action_prompt_localized_test.go","modules/cabana/record_action_prompt_postgres_test.go","modules/cabana/record_action_prompt_smoke_test.go","modules/cabana/record_action_prompt_test.go","modules/cabana/schema_types.go","modules/cabana/scope_limit_for_test.go","modules/cabana/security_coverage_test.go","modules/cabana/subject_events.go","modules/cabana/subject_events_test.go","modules/cabana/token_guard.go","modules/cabana/token_resolver.go","modules/cabana/token_resolver_remote_test.go","modules/cabana/token_routes_test.go","modules/cabana/token_scope_name_test.go","modules/cabana/token_scopes.go","modules/cooler/README.md","modules/cooler/cooler.go","modules/pact/README.md","modules/pact/capabilities.go","modules/pact/capabilities_test.go","modules/pact/frontend_token_scopes_test.go","modules/pact/mcp.go","modules/phrasebook/backend/lang/en/lang.yaml","modules/phrasebook/backend/lang/pl/lang.yaml","modules/pier/README.md","modules/pier/audit.go","modules/pier/backend_guard.go","modules/pier/catalog.go","modules/pier/catalog_path_fields_test.go","modules/pier/catalog_test.go","modules/pier/config.go","modules/pier/dispatch.go","modules/pier/dispatch_hardening_test.go","modules/pier/dispatch_test.go","modules/pier/endpoint_guards_test.go","modules/pier/events.go","modules/pier/example_mcp_test.go","modules/pier/export_test.go","modules/pier/fanout_test.go","modules/pier/filter.go","modules/pier/fingerprint_test.go","modules/pier/guard_rules_test.go","modules/pier/guards.go","modules/pier/helpers_test.go","modules/pier/host.go","modules/pier/identity.go","modules/pier/identity_smoke_test.go","modules/pier/lock_scope_test.go","modules/pier/personal_binding_test.go","modules/pier/pier.go","modules/pier/prm.go","modules/pier/prompt_ceiling_test.go","modules/pier/reaper_smoke_test.go","modules/pier/reaper_test.go","modules/pier/reserve_test.go","modules/pier/session.go","modules/pier/sessions_smoke_test.go","modules/pier/sessions_test.go","modules/pier/stateless.go","modules/pier/stateless_fanout_test.go","modules/pier/stateless_smoke_test.go","modules/pier/store.go","modules/pier/store_memory.go","modules/pier/store_redis.go","modules/pier/token_events_test.go","modules/pier/tools_list_test.go","modules/pier/tracer_smoke_test.go","modules/pier/widening_test.go","modules/surf/README.md","modules/surf/dispatch_smoke_test.go","modules/surf/pier_mount_smoke_test.go","modules/surf/pier_mount_test.go","modules/surf/pier_off.go","modules/surf/pier_on.go","modules/surf/router.go","modules/surf/routetable.go","modules/surf/streaming.go","modules/surf/streaming_smoke_test.go","modules/surf/streaming_test.go","modules/towel/README.md","modules/towel/client_ip_test.go","modules/towel/context.go","modules/wristband/README.md","modules/wristband/authorize.go","modules/wristband/mcp_scopes_smoke_test.go","modules/wristband/mcp_scopes_test.go","scripts/check-phase19.7.sh"] covered_digest: "v2:sha256:8b0458a677fb6443ec7e72a71659b194af68e396fe6fd552a4b468d6cc888192" behavior_unverified: 0 -overrides_applied: 0 +overrides_applied: 1 +overrides: + - must_have: "tools/list lists only the tools the session's principals may call (frontend permissions through the merged group/user permissions, backend permissions and token scope through cabana), and a call runs through the route's own middleware" + reason: "D-35 / P-14 (19.7-CONTEXT.md, RESEARCH Open Question 4): frontend tool filtering mirrors what the user.permission middleware enforces (group grants via PrincipalByID), so tools/list equals the callable set; MergedPermissions is used by no route, and switching would change a core plugin's behaviour" + accepted_by: "Jakub Zych" + accepted_at: "2026-10-23T22:17:04Z" decision_coverage: honored: 35 total: 35