mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-11-03 04:43:11 +08:00
Introduces the seam the conceptual-simplification plan (``.claude/plans/witty-drifting-clock.md``) hangs the LazyToolBox refactor on: * ``LazyTool`` — strict-by-default proxy over ``ToolIndexEntry`` that forwards the narrow attribute surface the eager pipeline actually reads (audited at plan time: ~28 attrs + 3 methods, zero ``isinstance(_, Tool)`` checks anywhere). Mutations (``tool.hidden = True``, shed metadata, ``tool.labels = ...``) land in ``_overrides`` and survive any later materialise. ``to_dict(link_details=False)`` stays on the entry — only ``link_details=True`` (and the ``_MATERIALIZE_OK`` allow-list) parse XML. Unknown attributes raise ``NotImplementedError`` with a clear message; ``LAZY_TOOL_PERMISSIVE=1`` downgrades to warn + materialise for debugging. * ``LazyToolBox.create_tool`` — returns a ``LazyTool`` when the index already has the source; otherwise falls through to the eager ``ToolBox.create_tool`` and persists the freshly-parsed tool via ``_persist_tool_source`` so the next boot is a hit. Paired with ``load_tool_from_cache``/``add_tool_to_cache`` no-ops so the disk ``ToolCache`` doesn't shadow the seam. * ``_resolve_index_entry`` — guid → ``store.get_by_source_path`` → short-id fallback. ``_materialize_for_lazy_tool`` routes the stub→Tool promotion through the existing ``_create_tool_from_stored_source`` + ``_register_loaded_tool`` so ``_tools_by_id`` / ``_tool_versions_by_id`` / ``_tools_by_old_id`` / lineage all agree with the eager bookkeeping. The seam is **dormant** in this commit: ``LazyToolBox.__init__`` still runs its hand-written ``_init_lazy_toolbox`` mirror, so ``create_tool`` is never invoked on the boot path. A follow-up commit will flip ``__init__`` to ``super().__init__()`` and delete the duplicate panel-parsing complex (~1500 lines per Phase 2 of the plan); this commit is purely additive so the activation can be reviewed in isolation. 21 unit tests cover the forwarded surface, mutator overrides round-tripping through materialise, the ``to_dict`` fast/slow paths, strict / permissive ``__getattr__`` behavior, and the ``create_tool`` index-hit paths (guid + source_path).