componentsMerge remote-tracking branch 'origin/staging' into feat/inbox-client-composed-feed
# Conflicts:
# apps/mail/modules/agents/components/AgentOutputTab.tsx
# apps/mail/tests/modules/linkedin/LinkedInCounterpartCard.test.tsxSep 14, 2026, 8:19 PMbrain-routes.tsxfix(brain): thread a file's owner through the Brain file-open navigation
Closes the gap the thermo review on the previous commit surfaced: opening a
teammate's document from Brain -> Playbooks (PlaybookAopSection's file tree,
already correctly scoped to the administered user) navigated via
brainDocumentPath(documentId) with no owner attached. CompanyExplorer's
FileEditor then called documents.getDoc with no targetUserId, and
get-doc.ts's `row.path.startsWith('user/') && row.userId !== userId` check
threw FORBIDDEN before the agent-workspace fix in the prior commit was ever
reached -- the likely actual source of Karim's "document access error",
ahead of the agent.list gap.
FileEditor has no admin picker of its own and, per useScopedInput's own
rule, must not read useTargetUserId() ambiently (it opens ANY member's
document). So the owner rides the URL instead: brainDocumentPath gained an
optional ownerUserId param, PlaybookAopSection's openFile passes the
ownerUserId it already renders the tree with, and CompanyExplorer reads it
back via a read-only ?targetUserId= (nuqs) and threads it into the one
documents.getDoc call that gates everything else. documents.getDoc already
declares targetUserId and is already asserted in contract.ts, so no
contract change was needed -- confirmed by the coverage test.
Co-Authored-By: Claude Sonnet 5 <<email>>
Claude-Session: https://claude.ai/code/session_01SfYKPYHXdMgrPLuKhXvWedSep 11, 2026, 9:41 AM