Report effective agent permissions per project #237

openReady to startCreated by Claude Code (User hu_yMavF3p1) • Unassigned • Normal priority

Description

Outcome

An authenticated agent can determine what it is allowed to do in a project without attempting a mutation and reading the resulting error.

Problem

The server derives effective permissions from AgentKey (GranularPermissions, GlobalWrite, AllProjectsWrite, AllProjectsModerate, CanCreateProjects, RestrictedProjects, plus single-project ProjectId/CanWrite/CanModerate) and AgentProjectGrant (CanWrite, CanModerate), but no MCP response exposes the result. project_list returns project rows only; memory_recall returns knowledge only; the OAuth scope mcp offline_access carries no per-project authorization.

Consequences today:

  • An agent cannot tell a missing permission from a genuine failure until a write is rejected.
  • Onboarding cannot report the connection's effective scope, so the operator has no confirmation that the consent screen produced the intended grants.
  • Dashboards and planning have no read model for what a given connection may actually do.

Work

  • Extend project_list rows with the caller's effective permissions for that project: at least read, write, moderate, plus whether shared/public changes require review.
  • Expose the same derived values when a single project is queried, so a resolved projectId from .agents/conderis.json is sufficient without listing everything.
  • Include account-level capabilities that are not per-project, notably CanCreateProjects, so project_create can be checked before it is called.
  • Return a derived, read-only view. Do not expose key hashes, prefixes, other agents' grants, other owners' permissions, or any credential material.
  • Collapse the permission flags to the set actually needed while doing this. Several overlapping key shapes exist; pick one model rather than reporting on all of them.
  • State the permission contract in system_memory so agents check capability before choosing between a direct write and a proposal.

Acceptance

  • A read-only connection sees write: false and moderate: false and performs no mutation to learn it.
  • A restricted key reports permissions only for the projects it may access; non-granted projects are not listed or described.
  • One permission model resolves effective values; no parallel legacy key path is kept alive alongside it.
  • Reported permissions match what the corresponding mutation actually enforces, verified by tests that assert both together.
  • Revoking a grant or a key changes the reported permissions on the next call.
  • No response exposes another owner's or another agent's permissions.

Constraints

Pre-release, no live users. Simplify the model outright; no migration, no compatibility shim, no parallel versioned variant.

Evidence

src/ProjectMemory.Web/Data/Entities.cs (AgentKey, AgentProjectGrant), src/ProjectMemory.Web/Services/MemoryTools.cs (project_list). Observed on 2026-09-14 during OAuth onboarding of the agent Claude Code: read access was confirmed empirically, while write, moderate and project-creation rights could not be determined from any tool response.

Agent handoff

Planning task only. Read-only reporting of existing derived state; it must not add, widen or change any permission.

Connection interrupted or session ended. Reload

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.