Skip to content

fix(update): avoid refreshing inactive lazy backends - #27878

Closed
paralegalia wants to merge 1 commit into
NousResearch:mainfrom
paralegalia:fix/lazy-active-anchor
Closed

fix(update): avoid refreshing inactive lazy backends#27878
paralegalia wants to merge 1 commit into
NousResearch:mainfrom
paralegalia:fix/lazy-active-anchor

Conversation

@paralegalia

Copy link
Copy Markdown

Summary

  • Treat lazy backends as active only when their anchor package is installed
  • Prevent shared helper deps like asyncpg from making Matrix look active
  • Add regression coverage for shared dependency false positives

Test plan

  • /Users/rburoz/.hermes/hermes-agent/venv/bin/python -m pytest tests/tools/test_lazy_deps.py tests/test_project_metadata.py tests/gateway/test_matrix.py::TestMatrixRequirements -q
  • /Users/rburoz/.hermes/hermes-agent/venv/bin/python - <<'PY'
    from tools import lazy_deps
    active = lazy_deps.active_features()
    print('platform.matrix active?', 'platform.matrix' in active)
    print('active_count', len(active))
    PY

@alt-glitch alt-glitch added type/bug Something isn't working comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have labels May 18, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused fix. I verified the premise against current main, and this still looks like a real hermes update bug.

Current main has platform.matrix declared as ("mautrix[encryption]==0.21.0", "aiosqlite==0.22.1", "asyncpg==0.31.0", "aiohttp-socks==0.11.0") in tools/lazy_deps.py:136, while active_features() still uses any(_is_present(s) for s in specs) at tools/lazy_deps.py:554. Since hermes_cli/main.py:7074 uses that list before refresh_active_features(prompt=False) at hermes_cli/main.py:7086, an unrelated asyncpg install can make Matrix look active.

Suggested changes

  • Please consider adding a short comment near the LAZY_DEPS map header (tools/lazy_deps.py:70) that the first spec is the feature's active-detection anchor. The PR's active_features() docstring explains it, but the invariant is easiest to miss when someone later edits the dependency tuple order.

I also checked staleness mechanics: gh pr diff 27878 --repo NousResearch/hermes-agent --color never | git apply --check --verbose - applies cleanly to current main with only line offsets.

Automated hermes-sweeper review.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the focused regression fix. The premise remains valid on current main: tools/lazy_deps.py:870 treats any installed spec as evidence that a lazy feature is active, while platform.matrix includes shared helper dependencies at tools/lazy_deps.py:175-183. hermes update consumes that result at hermes_cli/main.py:7636-7648.

Suggested changes

  • Please add a short comment near the LAZY_DEPS map header that the first spec in a multi-package tuple is the active-detection anchor. The updated active_features() docstring explains the rule, but the map is where future tuple reorderings would otherwise accidentally change it.

Automated hermes-sweeper review.

Comment thread tools/lazy_deps.py
refresh pass when pins move in :data:`LAZY_DEPS`.
"""
active = []
for feature, specs in LAZY_DEPS.items():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also document near the LAZY_DEPS map that the first spec is the active-detection anchor. This predicate makes tuple ordering behavioral, and the map is the most likely place for a later edit to accidentally change that behavior.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 13, 2026
@teknium1 teknium1 added the area/install-update Installer, updater, packaging, wheels, doctor label Jul 19, 2026
teknium1 added a commit that referenced this pull request Jul 27, 2026
…atch uv.lock

Generalizes the huggingface-hub lockstep test (#72320) to the whole
LAZY_DEPS surface: any package exact-pinned in LAZY_DEPS that the core
lock also resolves must pin the SAME version, so hermes update's lazy
refresh can never churn or downgrade a shared package out from under
its other consumers (#60783 class, #31817 class).

Together with the anchor-based activation gate (previous commit,
salvaged from #27878 by @paralegalia), this closes both halves of
#44404: features no longer false-activate from shared transitives, and
even a feature that legitimately activates cannot move a shared package
away from the locked version.
teknium1 added a commit that referenced this pull request Jul 27, 2026
…atch uv.lock

Generalizes the huggingface-hub lockstep test (#72320) to the whole
LAZY_DEPS surface: any package exact-pinned in LAZY_DEPS that the core
lock also resolves must pin the SAME version, so hermes update's lazy
refresh can never churn or downgrade a shared package out from under
its other consumers (#60783 class, #31817 class).

Together with the anchor-based activation gate (previous commit,
salvaged from #27878 by @paralegalia), this closes both halves of
#44404: features no longer false-activate from shared transitives, and
even a feature that legitimately activates cannot move a shared package
away from the locked version.
@teknium1

Copy link
Copy Markdown
Contributor

Salvaged and merged in #72361 with your authorship preserved via cherry-pick (plus a class-wide LAZY_DEPS↔uv.lock lockstep invariant on top) — you were the earliest submitter of the anchor-gating fix. Thanks @paralegalia!

@teknium1 teknium1 closed this Jul 27, 2026
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
…atch uv.lock

Generalizes the huggingface-hub lockstep test (NousResearch#72320) to the whole
LAZY_DEPS surface: any package exact-pinned in LAZY_DEPS that the core
lock also resolves must pin the SAME version, so hermes update's lazy
refresh can never churn or downgrade a shared package out from under
its other consumers (NousResearch#60783 class, NousResearch#31817 class).

Together with the anchor-based activation gate (previous commit,
salvaged from NousResearch#27878 by @paralegalia), this closes both halves of
NousResearch#44404: features no longer false-activate from shared transitives, and
even a feature that legitimately activates cannot move a shared package
away from the locked version.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/install-update Installer, updater, packaging, wheels, doctor comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants