fix(backend): drop the wasted workflow join on the expert credential-enforcement path, and cover picker-credential seeding
Three advisory findings from the autoreview of #14415 (approved, 0 blockers). None blocks that PR; all three are real and cheap enough to be worth a follow-up rather than a comment nobody reads again.
A wasted workflow join on the credential-enforcement hot path — backend/api/features/experts/credentials.py:297. expert_allowed_credential_ids runs on every expert-attributed execution, every copilot block run and every MCP tool call, and reaches the expert through _owned_expert, which eager-loads the Workflows -> LibraryAgent join. That join feeds only _seed_if_needed, which early-returns once credentialsSeededAt is set — so in the steady state it is fetched and discarded on every call, and the cost grows with the number of installed workflows. Fetch the expert without the include for the grant lookup, and load workflows only when credentialsSeededAt is None.
A duplicate expert fetch in find_library_agent — backend/copilot/tools/find_library_agent.py:124. On the direct agent_id path, require_installed_workflow resolves the scope through get_expert, and session_workflow_scope then issues an identical get_expert in the same tool call. Resolving once and threading the scope into the post-search filtering means changing require_installed_workflow's return from ErrorResponse | None to carry the scope, which is why it is not a drive-by fix.
The picker-credential seeding branch of _derive_from_workflows is never exercised — backend/api/features/experts/credentials.py:111. Every test of that function stubs get_graph to None or to a raise, so _picker_credential_ids never runs: a regression in provider/field extraction or in the owned_ids/is_system gating would go uncaught here. It is not a leak — executor-side enforcement is tested, so a miss surfaces as a visible "missing credentials" rather than as access — but the seed is the mechanism the posted ownership rules rely on ("seeded once from its workflows then curated by hand"), so it should have a test of its own. A stubbed GraphModel with one auto-credentials node and a matching owned credential, asserting the picker id is seeded while ungranted and system ids are excluded.
Source: Significant-Gravitas/AutoGPT