ProtectedisChecks whether the given scope is in the agent's assigned-scope list via __mj.AIAgentSearchScope. Used to enforce the SearchScopeAccess='Assigned' deny-list rule. Returns true when at least one matching row exists with Status='Active'; false otherwise.
ProtectedloadLoads all SearchScopePermission rows scoped to the given SearchScope. Caller-supplied ContextUser ensures the RunView runs under the same identity the rest of the request is using.
Resolves the effective permission. All UUID comparisons go through UUIDsEqual to remain case-insensitive across SQL Server / PostgreSQL.
Resolves the effective SearchScope permission for a (user, scope, agent) triple.
Resolution order (later steps only run if the earlier did not produce a definitive answer):
The user-direct-None rule (step 2) is intentional: an admin who explicitly denies a user on a scope should not have that decision overridden by a role membership the user happens to also hold. Role-level None entries are not authoritative because they are usually authored as a placeholder (e.g., to make a row exist before granting it later) and would create surprising lockouts when a user joins a role.