fix: plugin-install modules no longer start the update journeys they never reach

Replaying the last 131 non-merge main commits (4787e4d56f) through the
classifier: main selects e2e_upgrade 5 / e2e_desktop_update 3, the CI branch
12 / 10. Four of the seven new hits per lane touched only plugins_cmd.py or
plugins_cmd_install.py. migrate_all_homes reaches them only when a home's
configured memory provider left core (the catalog install); no upgrade or
Desktop update journey configures one, so those suites cannot observe the
change, and the unit lane already runs on every .py edit. Measured on a
fresh home: memory_provider_migration, pm/plugins_state, agent/memory_provider
and plugins/memory run; plugins_cmd_install executes only its module body,
plugins_cmd is never imported.

Kept, because a fresh-home update runs them: memory_provider_migration.py
(migrate_all_homes on every source build), plugins/memory/__init__.py (the
post-update Honcho profile sync), pm/install.py (sealed() /
lazy_installs_allowed() gate every update's default-tool install), and
scripts/build/ (frontend-common.mjs is imported by freshness/web/tui/desktop).
After: 8 / 6. A guard test fails if the journey-home migration starts running
plugin-install code, the signal to route those modules again.
This commit is contained in:
Teknium
2026-10-05 22:28:10 -07:00
parent 50bff6b151
commit fdae2fc175
2 changed files with 36 additions and 7 deletions

View File

@@ -290,12 +290,13 @@ _UPDATE_DEPENDENCIES = (
"hermes_cli/_subprocess_compat.py", # update git env, process-tree kill, PM git exposure
"hermes_cli/local_runtime/processes.py", # bounded probes' spawn_server/job custody
"agent/deadline.py", # bounded probes' process-tree timeout cleanup
# migrate_all_homes' second-hop provider/profile/install decisions.
# migrate_all_homes' second-hop provider/profile decisions, run on every update. Its
# plugin-install branch (plugins_cmd, plugins_cmd_install) runs only for a home whose
# configured memory provider left core; no update journey's home has one, so those
# modules stay with the unit lane (tests/ci/test_update_transitive_routing.py).
"agent/memory_provider.py",
"hermes_cli/plugins_cmd_install.py",
"hermes_cli/plugins_cmd.py",
"pm/plugins_state.py",
"pm/install.py",
"pm/install.py", # also sealed()/lazy_installs_allowed(): every update's default-tool install
"hermes_cli/desktop_build_lock.py",
"hermes_cli/memory_provider_migration.py",
"hermes_cli/left_core_migration.py", # source_build migrates plugins that left core

View File

@@ -4,9 +4,12 @@ These are scoped call edges, not a claim that a recursive static import walk
identifies the executed dependency closure of every lazy branch.
"""
import sys
from pathlib import Path
import pytest
from tests.ci.test_update_ci_routing import _ci_run, _consumers_reached, _real_classifier
from tests.ci.test_update_ci_routing import _REPO, _ci_run, _consumers_reached, _real_classifier
# bounded_probe_run -> spawn_server, kill_process_tree -> deadline; the
@@ -16,8 +19,6 @@ from tests.ci.test_update_ci_routing import _ci_run, _consumers_reached, _real_c
"hermes_cli/local_runtime/processes.py",
"agent/deadline.py",
"agent/memory_provider.py",
"hermes_cli/plugins_cmd_install.py",
"hermes_cli/plugins_cmd.py",
"pm/plugins_state.py",
"pm/install.py",
"hermes_cli/backup.py",
@@ -29,3 +30,30 @@ def test_second_hop_update_change_dispatches_real_update_consumers(path):
run = _ci_run(lanes)
for lane in ("e2e_upgrade", "e2e_desktop_update"):
assert all(_consumers_reached(run, lane).values()), f"{path}: {lane} never reaches its consumers"
# Off the update lanes (review K132346-ci-cost: 4 of 7 replayed main commits that newly started
# both update journeys touched only these): the journeys cannot observe code their update never runs.
_PLUGIN_INSTALL = ("hermes_cli/plugins_cmd.py", "hermes_cli/plugins_cmd_install.py")
def test_update_migration_on_a_journey_home_runs_no_plugin_install_code():
"""The journeys' homes configure no memory provider that left core. If the migration ever runs
plugin-install code there, the journeys exercise it: route these modules again."""
from hermes_cli.memory_provider_migration import migrate_all_homes
ran: set[tuple[str, str]] = set()
def profile(frame, event, _arg):
if event == "call":
ran.add((Path(frame.f_code.co_filename).resolve().as_posix(), frame.f_code.co_name))
sys.setprofile(profile)
try:
assert migrate_all_homes() == []
finally:
sys.setprofile(None)
files = {f for f, name in ran if name != "<module>"}
assert (_REPO / "hermes_cli/memory_provider_migration.py").resolve().as_posix() in files
hit = [rel for rel in _PLUGIN_INSTALL if (_REPO / rel).resolve().as_posix() in files]
assert hit == [], f"the update runs {hit} on a journey home"