``LazyToolBox.to_dict(in_panel=False)`` was serving entries straight from
the index, bypassing ``FilterFactory`` — so admin and user toolbox
filters silently didn't apply on the lazy path.
Introduce a typed ``ToolFilterContext`` protocol that documents the
attribute surface filters can read; both ``Tool`` and ``ToolIndexEntry``
satisfy it. ``ToolIndexEntry`` grows ``require_login``, ``tool_type``,
and ``tags`` so the stock filters (``_not_hidden``,
``_handle_authorization``) work against the entry without materialising
a Tool. ``_handle_authorization`` does the ``DataManagerTool`` admin
check inline (reads ``tool_type`` and ``context.trans.app.config``),
which avoids needing an ``allow_user_access`` method on the entry.
``LazyToolBox.to_dict`` now runs ``_build_filter_method`` against every
entry — the same code path the eager toolbox uses.